For mapping the register writes, there's MAME implementations of the Spectrum PDQ, Thunder IV, and a CRTC:
nubus_specpdq.cpp
thunder4gx.cpp
supermac.cpp
None perfectly matching the II, but since they all used similar (or identical) chipsets, I suspect the II should be almost the same. @Arbee do you have insights?
nubus().install_writeonly_device(slotspace+0xc00000, slotspace+0xc0000f, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::clockgen_w)));
nubus().install_device(slotspace+0xc40000, slotspace+0xc8ffff, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::registers_r)), emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::registers_w)));
nubus().install_device(slotspace+0xcc0000, slotspace+0xcc1fff, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::accel_r)), emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::accel_w)));
nubus().install_device(slotspace+0xd00000, slotspace+0xd000ff, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::ramdac_r)), emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::ramdac_w)));
This is real hardware emulation with the ROM code loaded. AFAIK they've all been reversed and don't emulate complete behavior, though, so it won't be gospel on how real hardware reacts in every situation. But the memory maps should be correct.This is interesting. Are these meant to fully emulate the hardware (ie. the ROM code wouldn't know the difference from a real board) or is it limited (ie. the control panel thinks it's a real card but direct memory access to registers wouldn't work exactly the same)?
Cool stuff! I remember seeing a mention in the SuperMac ROM thread but didn't look at it.

There's 6 MB of VRAM on the card, from slotspace + 0 to slotspace + 0x5fffff. So the pixel clock generator is at 0xc00000, the general registers are at 0xc40000, the blitter is at 0xcc0000, and the DAC is at 0xd00000.I'm looking at the Mame Thunder4GX code. @Arbee I assume this is where the register handlers are installed? nubus_thunder4gx_device::device_start() line 179 with the calls:
Code:nubus().install_writeonly_device(slotspace+0xc00000, slotspace+0xc0000f, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::clockgen_w))); nubus().install_device(slotspace+0xc40000, slotspace+0xc8ffff, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::registers_r)), emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::registers_w))); nubus().install_device(slotspace+0xcc0000, slotspace+0xcc1fff, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::accel_r)), emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::accel_w))); nubus().install_device(slotspace+0xd00000, slotspace+0xd000ff, emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::ramdac_r)), emu::rw_delegate(*this, FUNC(nubus_thunder4gx_device::ramdac_w)));
Looks like it's shifted by 4 bits? Like for the clockgen_w, it's at slotspace + 0xc00000 which would be within the frame buffer I would think? As opposed to slotspace + 0xc000000 which is what I would have expected. (I did not look at the install_device code... only just glancing at this - I should probably look at all of the code first before asking questions but being really lazy here).
There's 6 MB of VRAM on the card, from slotspace + 0 to slotspace + 0x5fffff. So the pixel clock generator is at 0xc00000, the general registers are at 0xc40000, the blitter is at 0xcc0000, and the DAC is at 0xd00000.
Ahh, right. Most cards' ROMs/drivers don't use the super slot space even if the hardware allows it because super slot space pretty much doesn't exist in 24-bit mode.Ok. So this looks like the standard slot space. I was looking at the super slot space based on the offsets @MacOSMonkey mentioned earlier so that’s what confused me.
Offset 0 (boardID) / -64(a6):
Board ID: $523
Offset 2 (vendorUse1) / -62(a6):
Unknown: 0b1000 / $8
Bit-depth: $4 (24-bit)
Offset 3 (vendorUse2) / -61(a6):
Physical Resolution: $13 (1024x768)
Offset 4 (vendorUse3) / -60(a6):
Monitor: $42 (SuperMatch 21-T XL)
Offset 5 (vendorUse4) / -59(a6):
Video Mode: $8D (Mode 141 - 1024x768)
Offset 6 (vendorUse5) / -58(a6):
Unknown: 0b10000100 / $84
Offset 7 (vendorUse6) / -57(a6):
Unknown: 0b00101100 / $2C
Ahh, right. Most cards' ROMs/drivers don't use the super slot space even if the hardware allows it because super slot space pretty much doesn't exist in 24-bit mode.
Alright I connected my card back up again, and set it for 1024x768. I get the following bits in sPRAM, this time I think I have them mapped correctly to the sPRAM APIs and the disassembly offsets:
Code:Offset 0 (boardID) / -64(a6): Board ID: $523 Offset 2 (vendorUse1) / -62(a6): Unknown: 0b1000 / $8 Bit-depth: $4 (24-bit) Offset 3 (vendorUse2) / -61(a6): Physical Resolution: $13 (1024x768) Offset 4 (vendorUse3) / -60(a6): Monitor: $42 (SuperMatch 21-T XL) Offset 5 (vendorUse4) / -59(a6): Video Mode: $8D (Mode 141 - 1024x768) Offset 6 (vendorUse5) / -58(a6): Unknown: 0b10000100 / $84 Offset 7 (vendorUse6) / -57(a6): Unknown: 0b00101100 / $2C
EDIT: After futzing, the unknown value after Physical Resolution is definitely the monitor type.
I think this is still wrong though, vendorUse1 should be offset further. Is Offset 1 with the bit-depth data controlled by the OS and not part of the sPRAM?
Alright I connected my card back up again, and set it for 1024x768. I get the following bits in sPRAM, this time I think I have them mapped correctly to the sPRAM APIs and the disassembly offsets:
Code:Offset 0 (boardID) / -64(a6): Board ID: $523 Offset 2 (vendorUse1) / -62(a6): Unknown: 0b1000 / $8 Bit-depth: $4 (24-bit) Offset 3 (vendorUse2) / -61(a6): Physical Resolution: $13 (1024x768) Offset 4 (vendorUse3) / -60(a6): Monitor: $42 (SuperMatch 21-T XL) Offset 5 (vendorUse4) / -59(a6): Video Mode: $8D (Mode 141 - 1024x768) Offset 6 (vendorUse5) / -58(a6): Unknown: 0b10000100 / $84 Offset 7 (vendorUse6) / -57(a6): Unknown: 0b00101100 / $2C
EDIT: After futzing, the unknown value after Physical Resolution is definitely the monitor type.
I think this is still wrong though, vendorUse1 should be offset further. Is Offset 1 with the bit-depth data controlled by the OS and not part of the sPRAM?


Huh, interesting. Why didn't I have that idea before?Bolle - have you tried swapping the ROMs on those boards? The 1600 just looks like a relayout of the 1360 board.
Makes sense why it never seems to change on my machine.I don’t know the answer to the vendorUse1 question but for vendorUse6, the disassembly seems to show the code is setting flags in that byte based on the environment like slot manager version, quick draw 32 support, etc.
Ah! Those are the magic words I was trying to skim for in the documentation. I think my eyes skipped right over the middle of that paragraph.Yes, vendorUse1 is set by Monitors control panel and contains the bit depth that will be requested in a setMode call. There's no expectation that the card does anything with this byte. It is still part of the slot PRAM record though.
There's a comment in DC&D about this also.
View attachment 76414
Those offsets look correct. Here is slot PRAM record as I use it.
View attachment 76410
Envious. I’ll have a look to see if there’s anything obvious in the ROM differences. There are some 1600x1200 references hidden in the II ROM so maybe it’s also been patched out similarly.Huh, interesting. Why didn't I have that idea before?
It works just fine, the card that came as a "1360" will display 1600x1200/24bit with the ROM from the 1600 while the 1360 ROM limits both cards to 1600x1200/8bit.
Guess I've got two 1600s now.![]()
Huh, interesting. Why didn't I have that idea before?
It works just fine, the card that came as a "1360" will display 1600x1200/24bit with the ROM from the 1600 while the 1360 ROM limits both cards to 1600x1200/8bit.
Guess I've got two 1600s now.![]()