Quite well, thank you.
Now, before I begin I should mention that the extended memory and mouse support in SCI is baked into the interpreter itself, and in SCI32 so are the VGA and VESA video drivers. Oddly, the keyboard is not. But anyway!
An SCI DRV
file is a piece of standalone code that is loaded on startup and provides a set of standardized routines for the interpreter to call, even if a given feature isn’t technically supported such as palette rotation in EGA or most things on PC speaker. Their format is actually pretty straightforward.
The first four bytes of the file are a single instruction that jumps to the entry point routine. Whenever a driver function is called for, the BP
register is set to the requested function and that jump is called. The entry point routine then uses a lookup table, indexed on BP
, to call the requested function, and returns. Easy as pie, really. But that leaves the format.
The next four bytes are the number 0x87654321
. Yeah, backwards. I know, wild times. This would be used to check if a given DRV
file really is a valid driver, but SCI11 at least seems not to care.
Following is a byte that specifies what type of driver we’re talking about. The install/setup program uses this to determine which list to show it in. It’s otherwise useless, especially with my own install program. From zero to seven, these types are: video, music, voice, input, keyboard, communication, mouse, and memory.
The rest of the data can go basically anywhere — they’re Pascal-style (length-prefixed) strings that should specify their file name and description, but some of them are named dude
and one is
. Just a single space. And the descriptions? You wouldn’t be able to tell VGA320.DRV
apart from VGA320BW.DRV
if you followed this information ‘cos they both say they’re “VGA or IBM PS2, Models 25 & 30 – 256 Colors”. Except one of them is optimized for grayscale-only monitors. So yeah.
Next up is the EXTDRV marker, 0xFEDCBA98
, directly followed by a four-byte value whose meaning depends on the type. Again, not actually used, purely for external bookkeeping.
Value | Video | Keyboard | Sound |
---|---|---|---|
1 | MDA | IBM | Speaker |
2 | Hercules | Tandy | AdLib |
4 | CGA | NEC | Sound Blaster/DAC |
8 | PC Jr. | Creative Music System | |
10 | Tandy | Tandy 3-Voice | |
20 | EGA | Tandy DAC | |
40 | MCGA | PS/1 3-Voice | |
80 | VGA | PS/1 DAC | |
100 | CGA two-color | Sound Blaster Pro | |
200 | CGA four-color | MPU-401 | |
400 | Explorer | Disney Sound Source | |
800 | CD-Audio | ||
1000 | ProAudio FM | ||
2000 | ProAudio DAC | ||
4000 | Windows Sound Source | ||
8000 | No MIDI |
These values can be combined, so MTBLAST.DRV
for example reports 0x204
, or “MPU-401 with Sound Blaster DAC”. Of course, this would only make sense for the sound drivers but what can you do?
After this, the actual driver code resumes with the dispatch table, a list of function pointers to each of the features the driver supports. Some may point to null functions, but none of them are themselves null
. Because that’d be bad. Directly after this is all the general-purpose variable memory that the driver may need, all preset. For example VGA320.DRV
has a standard palette and “wait hand” cursor of its own that it throws up initially.
There are three functions that all drivers must have. The rest depends on their type. These are Detect, Initialize, and Terminate, in that order. The first simply returns a few metrics. For video it’s the number of colors, for music it’s the device ID (to decide which channels to play) and how many voices it can handle. The Initialize function actually sets up the device, switching video modes and setting up timers or what have you. What Terminate does ought to be obvious.
And that’s how SCI drivers work.