Z80 bus + I/O mapping redux
Posted: Fri Apr 26, 2019 1:42 pm
Found conflicting information, wanted to clarify what's current and ask some more.
References:
* viewtopic.php?t=347
* http://www.sega-16.com/forum/showthread ... ng-Sega-CD
* http://www.tmeeco.eu/BitShit/CMDHW.TXT
bgvanbur states the Z80 can write to 68K main-CPU RAM (e00000-ffffff), but reads return 0xff.
It's further comments that reads return different values on different systems.
Stef finds that writes do not work. Steve Snake says they used to on the earliest models.
I wonder Stef tested this by reading back what the Z80 wrote from the 68K. If not, that'd explain why writes appeared to fail.
But it's still pathological why writes would succeed, but reads would fail.
Even more surprising is that a100xx accesses seem to work, as long as the Z80 acquires the bus first.
You probably see where I'm going, but then ... what happens if the Z80 accesses a0xxxx (eg the Z80 region)?
Thankfully from the CPU perspective, a08000-a0ffff mirrors a00000-a07fff, otherwise you could create an infinite loop in emulators.
But I wonder if that would really work? Can the Z80 read from $8000, with the bank select set so it reads from the 68K $a00000, which would then read from the Z80 $0000, which would then return Z80 RAM?
While I'm on this topic ... does anyone have non-conflicting answers for the axxxxx region? Currently, I have:
* a00000-a0ffff => [8-bit bus] Z80 (A15 is ignored)
* a10000-a10fff => [8-bit bus] Peripherals (A8-A15 is ignored)
** a10002,a10004,a10006 => (controller 1, controller 2, extension) port data
** a10008,a1000a,a1000c => (controller 1, controller 2, extension) port control
* a11000-a11fff => [8-bit bus] Z80 enable/disable (A0-A7 is ignored)
** a11100 => APU request
** a11200 => APU enable
* a12000-a12fff => [bus size depends on the hardware, 8-bit for Sega CD] Expansion port (Sega CD)
* a13000-a13fff => [bus size depends on the hardware, 8-bit for all cartridges I know of] Cartridge (mappers usually)
* c00000-dfffff => [16-bit bus] VDP (when A4=0) + [8-bit bus] PSG (when A4=1)
** if any bits in A5-A7 or A16-A18 are set, the machine deadlocks
** A8-A15 are ignored (mirrors)
** reading with A4 set (PSG) deadlocks the machine
** writing to the VDP counters deadlocks the machine
* a14000-a14fff => [8-bit bus] TMSS
** a14000 and a14002 enable the VDP by writing 'SEGA' to them
** a14100.d0=1 disables TMSS and enables the ROM
Sometimes I read that a10000-a10fff (12-bit range) is really just a10000-a100ff (8-bit range.) Might these blocks go further and fill in bxxxxx as well?
Charles MacDonald went into lots of detail on even-byte, odd-byte, word reads/writes to the c00000-dfffff region. But what about the a00000-bfffff region? Say a game writes a byte to a10003, D0-D7 goes to controller port 1 data, great. But if a game writes to byte to a10002, what happens? The 68K used in the Genesis per 68000UM.pdf states that D8-D15=D0-D7 for byte writes, and that A0 isn't used. Do the I/O ports bother to check /LDS and ignore even byte writes? Or do they just silently go through? What about word writes? I presume those will work fine and pass through D0-D7.
And the really big question ... how exactly do unaligned 16-bit accesses work? I'm told it throws a bus error exception. But how does that work on a bus access? If you're in the middle of executing an instruction, does it just abort the whole instruction instantly and jump the PC to the exception vector address? If not, then does the bus just return bad data until the instruction completes, and then it throws the exception?
References:
* viewtopic.php?t=347
* http://www.sega-16.com/forum/showthread ... ng-Sega-CD
* http://www.tmeeco.eu/BitShit/CMDHW.TXT
bgvanbur states the Z80 can write to 68K main-CPU RAM (e00000-ffffff), but reads return 0xff.
It's further comments that reads return different values on different systems.
Stef finds that writes do not work. Steve Snake says they used to on the earliest models.
I wonder Stef tested this by reading back what the Z80 wrote from the 68K. If not, that'd explain why writes appeared to fail.
But it's still pathological why writes would succeed, but reads would fail.
Even more surprising is that a100xx accesses seem to work, as long as the Z80 acquires the bus first.
You probably see where I'm going, but then ... what happens if the Z80 accesses a0xxxx (eg the Z80 region)?
Thankfully from the CPU perspective, a08000-a0ffff mirrors a00000-a07fff, otherwise you could create an infinite loop in emulators.
But I wonder if that would really work? Can the Z80 read from $8000, with the bank select set so it reads from the 68K $a00000, which would then read from the Z80 $0000, which would then return Z80 RAM?
While I'm on this topic ... does anyone have non-conflicting answers for the axxxxx region? Currently, I have:
* a00000-a0ffff => [8-bit bus] Z80 (A15 is ignored)
* a10000-a10fff => [8-bit bus] Peripherals (A8-A15 is ignored)
** a10002,a10004,a10006 => (controller 1, controller 2, extension) port data
** a10008,a1000a,a1000c => (controller 1, controller 2, extension) port control
* a11000-a11fff => [8-bit bus] Z80 enable/disable (A0-A7 is ignored)
** a11100 => APU request
** a11200 => APU enable
* a12000-a12fff => [bus size depends on the hardware, 8-bit for Sega CD] Expansion port (Sega CD)
* a13000-a13fff => [bus size depends on the hardware, 8-bit for all cartridges I know of] Cartridge (mappers usually)
* c00000-dfffff => [16-bit bus] VDP (when A4=0) + [8-bit bus] PSG (when A4=1)
** if any bits in A5-A7 or A16-A18 are set, the machine deadlocks
** A8-A15 are ignored (mirrors)
** reading with A4 set (PSG) deadlocks the machine
** writing to the VDP counters deadlocks the machine
* a14000-a14fff => [8-bit bus] TMSS
** a14000 and a14002 enable the VDP by writing 'SEGA' to them
** a14100.d0=1 disables TMSS and enables the ROM
Sometimes I read that a10000-a10fff (12-bit range) is really just a10000-a100ff (8-bit range.) Might these blocks go further and fill in bxxxxx as well?
Charles MacDonald went into lots of detail on even-byte, odd-byte, word reads/writes to the c00000-dfffff region. But what about the a00000-bfffff region? Say a game writes a byte to a10003, D0-D7 goes to controller port 1 data, great. But if a game writes to byte to a10002, what happens? The 68K used in the Genesis per 68000UM.pdf states that D8-D15=D0-D7 for byte writes, and that A0 isn't used. Do the I/O ports bother to check /LDS and ignore even byte writes? Or do they just silently go through? What about word writes? I presume those will work fine and pass through D0-D7.
And the really big question ... how exactly do unaligned 16-bit accesses work? I'm told it throws a bus error exception. But how does that work on a bus access? If you're in the middle of executing an instruction, does it just abort the whole instruction instantly and jump the PC to the exception vector address? If not, then does the bus just return bad data until the instruction completes, and then it throws the exception?