Any expert device driver developers out there?

Anything not about Mac emulation.

Moderators: Cat_7, Ronald P. Regensburg

Post Reply
marciot42
Inquisitive Elf
Posts: 39
Joined: Wed Feb 26, 2014 2:21 pm

Any expert device driver developers out there?

Post by marciot42 »

Hello all,

Short Version:

I am wondering whether there is anyone out there with experience with writing device drivers on classic Macs? I have encountered a strange situation where a device driver (a desk accessory, really), keeps getting periodically flushed from the Device Manager's list of active device drivers, only to show up again moments later. I am curious if anyone knows a reason why this might be happening.

Long Version:

I've trying to develop a VNC remote desktop server for the Macintosh Plus. I've had a proof-of-concept for a while now, but the devil is in the details. Aside from general MacTCP stability issues, one thing that has taken me down a rabbit hole is figuring out how to control the mouse. A later implementations of VNC, ChromiVNC, controls the mouse by writing directly to the low-level variables, MTemp (0x828), RawMouse (0x082C) and CrsrNew (0x08CE). This technique does work on the Mac Plus, so it is possible to move the mouse around just fine.

To simulate clicking, ChromiVNC posts an event to the event queue and writes to the low level variable MBState (0x0172) to indicate the button is being held down. This is where the process breaks down on the Mac Plus. Dragging, and more critically, selecting menus from the menu bar does not work. I spend a lot of time disassembling toolbox calls and found out that the crux of the problem is that the "Button" trap continually overwrites the MBState with a copy of the button state read directly from the VIA register. Curiously, under OS 8 on later Macs, it behaves differently -- my guess is that the trap was modified to only copy the value over if it is changed, perhaps to allow programs to easily simulate clicks by writing to MBState.

So I tried the obvious of patching the Button trap and found that it was not sufficient to allow dragging or menu selection. Perhaps MenuSelect, DragWindow and DragTheRgn jump directly to the Button routine rather than going through the trap mechanism. So, short of patching the ROMs, being able to simulate holding the mouse via low-memory globals seems unlikely on the Mac Plus.

I thought this was the end of my VNC ambitions, but then the rabbit hole got deeper. In browsing through Inside Macintosh Volume I, I came across a brief two page description of a Journaling Mechanism that was supposedly used by the Guided Tour disk on the Macintosh (there is also a writeup of it here). It basically described a way to record application events and to play them back, something that is done in the Guided Tour to demonstrate the use of the mouse. It also mentioned that the Macintosh team had a desk accessory to generate fictitious user interaction to stress test the Mac UI. So, with this knowledge, I set out to recreate the mythical desk accessory and succeeded... sort of.

The Journaling Mechanism works via the low-memory variables JournalFlag and JournalRef. The former indicates whether the journaling driver is recording, playing back events, or idling; while the JournalRef is a reference number for the device driver or desk accessory doing the journaling. What I found out is that my journaling desk accessory would only record or playback events for a short while before stopping. After some tinkering, I learned something was periodically resetting the JournalFlag to zero, thus disabling the journaling.

So while I now had a way to fully control the mouse, but not for long -- sometimes it would shut off almost immediately, sometimes after several seconds!

This set me further down the rabbit hole. Since the problem didn't occur reliably, there was no way to trace it using a regular debugger. Eventually, I hacked the source to a Macintosh emulator to tell me precisely the instruction where the JournalFlag was being overwritten. It was happening in the _Control call of the Device Manager. More interestingly, the _Control routine needs to consult the Unit Table (a list of registered device drivers) to find which driver to dispatch the journaling call to. If it cannot find the driver, it resets the JournalFlag to zero, which is what would happen with my desk accessory.

By using my trick of hacking the emulator to report changes to a particular memory location, I found that something was periodically removing my desk accessory from the unit table, only to add it a couple of moments later. This happened continuously whenever the desk accessory was running, regardless of whether it was journaling or not. If it was journaling, and this coincided with an event, the Journaling Mechanism would find that the Journal Driver was missing and would clear the JournalFlag.

So, in short... AAAAAAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHH! So frustrating...

Anyhow, this is where I am right now. Several miles down the rabbit hole...
User avatar
adespoton
Forum All-Star
Posts: 4227
Joined: Fri Nov 27, 2009 5:11 am
Location: Emaculation.com
Contact:

Re: Any expert device driver developers out there?

Post by adespoton »

It doesn't really answer your question, and I'm by no means a 68k device driver developer, but could this device driver flush be part of how the system ensures nothing blocks the core loop?

If it's being flushed and then coming back, there must be some index somewhere that's being loaded, unless it's really flushing and polling regularly. I can't imagine any OS developer being happy with that solution, but it might be worth following back up-stream...?
Post Reply