2007-08-11 09:55:23 +02:00
|
|
|
|
|
|
|
Sega Genesis hardware notes
|
|
|
|
Version 0.8 (03/02/01)
|
|
|
|
|
|
|
|
by Charles MacDonald
|
|
|
|
WWW: http://cgfm2.emuviews.com
|
|
|
|
|
|
|
|
Unpublished work Copyright 2000, 2001 Charles MacDonald
|
|
|
|
|
|
|
|
Here is a compilation of some notes I've written up on the Sega Genesis
|
|
|
|
hardware. Everything described herein has been checked on the real thing,
|
|
|
|
though that doesn't necessarily mean my testing methods were flawless. :)
|
|
|
|
|
|
|
|
Version history
|
|
|
|
---------------
|
|
|
|
[0.8]
|
|
|
|
- Added information on the SVP chip used in Virtua Racing. (section 4.2)
|
|
|
|
- Added information on EEPROM storage. (section 4.1)
|
|
|
|
- Changed miscellaneous section around.
|
|
|
|
[0.7]
|
|
|
|
- Added more information about access to the Z80 bus. (section 2.2)
|
|
|
|
- Updated the VDP register information, and removed some things
|
|
|
|
that were specific to VDP programming. (section 1.1)
|
|
|
|
- Added some background about the PSG. (section 4)
|
|
|
|
[0.6]
|
|
|
|
- Rewrote the 68000 memory map description. (section 1)
|
|
|
|
- Rewrote the Z80 memory map description. (section 2.1)
|
|
|
|
- Added memory access section. (section 1.2)
|
|
|
|
- Added a few miscellaneous topics. (section 4)
|
|
|
|
[0.5]
|
|
|
|
- Added more Z80 banking information.
|
|
|
|
- Added unused VDP address return values from the Z80 side.
|
|
|
|
- Added example of how to start up the Z80 on power-up.
|
|
|
|
- Added information on Phantasy Star 4 from Jeff Quinn.
|
|
|
|
- Added list of consoles that support Mark-III compatibility mode.
|
|
|
|
- Fixed a few typos.
|
|
|
|
[0.4]
|
|
|
|
- Added more details on 68000 and Z80 memory map.
|
|
|
|
- Added more information on VDP addresses.
|
|
|
|
- Added some thoughts on Phantasy Star 4.
|
|
|
|
[0.3]
|
|
|
|
- Added more information on I/O registers. (section 3)
|
|
|
|
- Fixed a few typos pointed out by Tim Meekins.
|
|
|
|
[0.2]
|
|
|
|
- Added section on I/O port programming and gamepads
|
|
|
|
[0.1]
|
|
|
|
- Initial release
|
|
|
|
|
|
|
|
Table of Contents
|
|
|
|
|
|
|
|
1.) 68000 memory map
|
|
|
|
1.1) VDP registers
|
|
|
|
1.2) Memory access quirks
|
|
|
|
1.3) Clock speeds
|
|
|
|
2.) Sound hardware overview
|
|
|
|
2.1) Z80 memory map
|
|
|
|
2.2) RESET and BUSREQ registers
|
|
|
|
2.3) Banking
|
|
|
|
2.4) Interrupts
|
|
|
|
3.) Input and Output
|
|
|
|
3.1) Programming I/O ports
|
|
|
|
3.2) Gamepad specifics
|
|
|
|
4.) Miscellaneous
|
|
|
|
4.1) EEPROM
|
|
|
|
4.2) Virtua Racing
|
|
|
|
4.3) Phantasy Star 4
|
|
|
|
4.4) Other topics
|
|
|
|
5.) Credits
|
|
|
|
6.) Disclaimer
|
|
|
|
|
|
|
|
|
|
|
|
1.) 68000 memory map
|
|
|
|
|
|
|
|
000000-3FFFFFh : ROM
|
|
|
|
400000-7FFFFFh : Unused (1)
|
|
|
|
800000-9FFFFFh : Unused (2)
|
|
|
|
A00000-A0FFFFh : Z80 address space (3)
|
|
|
|
A10000-A1001Fh : I/O
|
|
|
|
A10020-BFFFFFh : Internal registers and expansion (4)
|
|
|
|
C00000-DFFFFFh : VDP (5)
|
|
|
|
E00000-FFFFFFh : RAM (6)
|
|
|
|
|
|
|
|
1. Reads return the MSB of the next instruction to be fetched, with the
|
|
|
|
LSB set to zero. Writes do nothing.
|
|
|
|
|
|
|
|
2. Reading or writing any address will lock up the machine.
|
|
|
|
This area is used for the 32X adapter.
|
|
|
|
|
|
|
|
3. Addresses A08000-A0FFFFh mirror A00000-A07FFFh, so the 68000 cannot
|
|
|
|
access it's own banked memory. All addresses are valid except for
|
|
|
|
the VDP which is at A07F00-A07FFFh and A0FF00-A0FFFFh, writing or
|
|
|
|
reading those addresses will lock up the machine.
|
|
|
|
|
|
|
|
4. Reading some addresses lock up the machine, others return the MSB
|
|
|
|
of the next instruction to be fetched with the LSB is set to zero.
|
|
|
|
|
|
|
|
The latter applies when reading A11100h (except for bit 0 reflects
|
|
|
|
the state of the bus request) and A11200h.
|
|
|
|
|
|
|
|
Valid addresses in this area change depending on the peripherals
|
|
|
|
and cartridges being used; the 32X, Sega CD, and games like Super
|
|
|
|
Street Fighter II and Phantasy Star 4 use addresses within this range.
|
|
|
|
|
|
|
|
5. The VDP is mirrored at certain locations from C00000h to DFFFFFh. In
|
|
|
|
order to explain what addresses are valid, here is a layout of each
|
|
|
|
address bit:
|
|
|
|
|
|
|
|
MSB LSB
|
|
|
|
110n n000 nnnn nnnn 000m mmmm
|
|
|
|
|
|
|
|
'1' - This bit must be 1.
|
|
|
|
'0' - This bit must be 0.
|
|
|
|
'n' - This bit can have any value.
|
|
|
|
'm' - VDP addresses (00-1Fh)
|
|
|
|
|
|
|
|
For example, you could read the status port at D8FF04h or C0A508h,
|
|
|
|
but not D00084h or CF00008h. Accessing invalid addresses will
|
|
|
|
lock up the machine.
|
|
|
|
|
|
|
|
6. The RAM is 64K in size and is repeatedly mirrored throughout the entire
|
|
|
|
range it appears in. Most games only access it at FF0000-FFFFFFh.
|
|
|
|
|
|
|
|
1.1) VDP registers
|
|
|
|
|
|
|
|
The lower five bits of the address specify what memory mapped VDP register
|
|
|
|
to access:
|
|
|
|
|
|
|
|
00h : Data port
|
|
|
|
02h : Data port
|
|
|
|
04h : Control port (1)
|
|
|
|
06h : Control port
|
|
|
|
08h : HV counter (2)
|
|
|
|
0Ah : HV counter
|
|
|
|
0Ch : HV counter
|
|
|
|
0Eh : HV counter
|
|
|
|
11h : SN76489 PSG (3)
|
|
|
|
13h : SN76489 PSG
|
|
|
|
15h : SN76489 PSG
|
|
|
|
17h : SN76489 PSG
|
|
|
|
18h : Unused (4)
|
|
|
|
1Ah : Unused
|
|
|
|
1Ch : Unused
|
|
|
|
1Eh : Unused
|
|
|
|
|
|
|
|
1. For reads, the upper six bits of the status flags are set to the
|
|
|
|
value of the next instruction to be fetched. Bit 6 is always zero.
|
|
|
|
For example:
|
|
|
|
|
|
|
|
move.w $C00004, d0 ; Next word is $4E71
|
|
|
|
nop ; d0 = -1-- 11?? ?0?? ????
|
|
|
|
|
|
|
|
When reading the status flags through the Z80's banked memory area,
|
|
|
|
the upper six bits are set to one.
|
|
|
|
|
|
|
|
2. Writing to the HV counter will cause the machine to lock up.
|
|
|
|
|
|
|
|
3. Reading the PSG addresses will cause the machine to lock up.
|
|
|
|
|
|
|
|
Doing byte-wide writes to even PSG addresses has no effect.
|
|
|
|
|
|
|
|
If you want to write to the PSG via word-wide writes, the data
|
|
|
|
must be in the LSB. For instance:
|
|
|
|
|
|
|
|
move.b (a4)+, d0 ; PSG data in LSB
|
|
|
|
move.w d0, $C00010 ; Write to PSG
|
|
|
|
|
|
|
|
4. Reading the unused addresses returns the next instruction to be fetched.
|
|
|
|
For example:
|
|
|
|
|
|
|
|
move.w $C00018, d0 ; Next word is $4E71
|
|
|
|
nop ; d0 = $4E71
|
|
|
|
|
|
|
|
When reading these addresses through the Z80's banked memory area,
|
|
|
|
the value returned is always FFh.
|
|
|
|
|
|
|
|
Writing to C00018h and C0001Ah has no effect.
|
|
|
|
|
|
|
|
Writing to C0001Ch and C0001Eh seem to corrupt the internal state
|
|
|
|
of the VDP. Here's what each bit does: (assuming word-wide writes)
|
|
|
|
|
|
|
|
8E9Fh : These bits cause brief flicker in the current 8 pixels
|
|
|
|
being drawn when the write occurs.
|
|
|
|
|
|
|
|
5040h : These bits blank the display like bit 6 of register #1 when set.
|
|
|
|
|
|
|
|
2000h : This bit makes every line show the same random garbage data.
|
|
|
|
|
|
|
|
0100h : This bit makes random pattern data appear in the upper eight
|
|
|
|
and lower ten lines of the display, with the normal 224 lines
|
|
|
|
in the middle untouched. For those of you interested, the
|
|
|
|
display is built up like so:
|
|
|
|
|
|
|
|
224 lines for the active display
|
|
|
|
10 lines unused (can show pattern data here with above bit)
|
|
|
|
3 lines vertical blank (no border color shown)
|
|
|
|
3 lines vertical retrace (no picture shown at all)
|
|
|
|
13 lines vertical blank (no border color shown)
|
|
|
|
8 lines unused (can show pattern data here with above bit)
|
|
|
|
|
|
|
|
I know that comes up to 261 lines and not 262. But that's
|
|
|
|
all my monitor shows.
|
|
|
|
|
|
|
|
Turning the display off makes the screen roll vertically,
|
|
|
|
and random pattern data is displayed in all lines when
|
|
|
|
this bit is set.
|
|
|
|
|
|
|
|
0020h : This bit causes the name table and pattern data shown to
|
|
|
|
become corrupt. Not sure if the VRAM is bad or the VDP is
|
|
|
|
just showing the wrong data.
|
|
|
|
|
|
|
|
1.2) Memory access quirks
|
|
|
|
|
|
|
|
Byte-wide writes
|
|
|
|
|
|
|
|
Writing to the VDP control or data ports is interpreted as a 16-bit
|
|
|
|
write, with the LSB duplicated in the MSB. This is regardless of writing
|
|
|
|
to an even or odd address:
|
|
|
|
|
|
|
|
move.w #$A5, $C00003 ; Same as 'move.w #$A5A5, $C00002'
|
|
|
|
move.w #$87, $C00004 ; Same as 'move.w #$8787, $C00004'
|
|
|
|
|
|
|
|
Byte-wide reads
|
|
|
|
|
|
|
|
Reading from even VDP addresses returns the MSB of the 16-bit data,
|
|
|
|
and reading from odd address returns the LSB:
|
|
|
|
|
|
|
|
move.b $C00008, d0 ; D0 = V counter
|
|
|
|
move.b $C00001, d0 ; D0 = LSB of current VDP data word
|
|
|
|
move.b $C0001F, d0 ; D0 = $71
|
|
|
|
nop
|
|
|
|
move.b $C00004, d0 ; D0 = MSB of status flags
|
|
|
|
|
|
|
|
Word-wide writes
|
|
|
|
|
|
|
|
When doing word-wide writes to Z80 RAM, only the MSB is written, and
|
|
|
|
the LSB is ignored:
|
|
|
|
|
|
|
|
0000: AA BB CC DD ; Z80 memory
|
|
|
|
move.w #$1234, $A00000 ; do a word-wide write
|
|
|
|
0000: 12 BB CC DD ; result
|
|
|
|
|
|
|
|
Word-wide reads
|
|
|
|
|
|
|
|
A word-wide read from Z80 RAM has the LSB of the data duplicated in the MSB.
|
|
|
|
|
|
|
|
0000: AA BB CC DD ; Z80 memory
|
|
|
|
move.w $A00000, d0 ; do a word-wide read
|
|
|
|
d0 = $AAAA ; result
|
|
|
|
|
|
|
|
1.3) Clock speeds
|
|
|
|
|
|
|
|
These are for an NTSC Sega Genesis console.
|
|
|
|
|
|
|
|
680000 = 7.67 MHz
|
|
|
|
YM2612 = 7.67 MHz
|
|
|
|
Z80 = 3.58 MHz
|
|
|
|
SN76489 = 3.58 MHz
|
|
|
|
|
|
|
|
If anyone has information about timing for PAL consoles, please let me know.
|
|
|
|
|
|
|
|
2) Sound hardware overview
|
|
|
|
|
|
|
|
The following components used for sound generation:
|
|
|
|
|
|
|
|
- Zilog Z80 CPU
|
|
|
|
- 8k static RAM
|
|
|
|
- Yamaha YM2612 FM sound generator
|
|
|
|
- SN76489 PSG
|
|
|
|
|
|
|
|
2.1) Z80 memory map
|
|
|
|
|
|
|
|
0000-1FFFh : RAM
|
|
|
|
2000-3FFFh : RAM (mirror)
|
|
|
|
4000-5FFFh : YM2612 (1)
|
|
|
|
6000-60FFh : Bank address register (2)
|
|
|
|
6100-7EFFh : Unused (3)
|
|
|
|
7F00-7FFFh : VDP (4)
|
|
|
|
8000-FFFFh : Bank area
|
|
|
|
|
|
|
|
1. The YM2612 has two address lines, so it is available at 4000-4003h and
|
|
|
|
is mirrored repeatedly up to 5FFFh.
|
|
|
|
|
|
|
|
2. Writes go to the bank address register, reads return FFh.
|
|
|
|
The value returned applies to both the 68000 and Z80.
|
|
|
|
|
|
|
|
3. Writes are ignored, reads return FFh.
|
|
|
|
The value returned applies to both the 68000 and Z80.
|
|
|
|
|
|
|
|
4. Only addresses 7F00-7F1Fh are valid, writes to 7F20-7FFFh will
|
|
|
|
lock up the machine.
|
|
|
|
|
|
|
|
Z80 access to the VDP has the same results as doing byte-wide reads
|
|
|
|
and writes as described in section 1.2. So only the HV counter and
|
|
|
|
PSG can be used effectively.
|
|
|
|
|
|
|
|
All I/O ports return FFh, and writing to them has no effect. The Thunder
|
|
|
|
Force games read port BFh in the IRQ subroutine, this would appear to be
|
|
|
|
a misunderstanding on the programmer's behalf.
|
|
|
|
|
|
|
|
The 68000 can write to A06000h to set up the bank address.
|
|
|
|
|
|
|
|
2.2) RESET and BUSREQ registers
|
|
|
|
|
|
|
|
Bit 0 of A11100h (byte access) or bit 8 of A11100h (word access) controls
|
|
|
|
the Z80's /BUSREQ line.
|
|
|
|
|
|
|
|
Writing 1 to this bit will request the Z80 bus. You can then release
|
|
|
|
the bus later on by writing 0.
|
|
|
|
|
|
|
|
Reading this bit will return 0 if the bus can be accessed by the 68000,
|
|
|
|
or 1 if the Z80 is still busy.
|
|
|
|
|
|
|
|
If the Z80 is reset, or if it is running (meaning the 68000 does not
|
|
|
|
have the bus) it will also return 1. The only time it will switch from
|
|
|
|
1 to 0 is right after the bus is requested, and if the Z80 is still
|
|
|
|
busy accessing memory or not.
|
|
|
|
|
|
|
|
Bit 0 of A11200h (byte access) or bit 8 of A11200h (word access) controls
|
|
|
|
the Z80's /RESET line.
|
|
|
|
|
|
|
|
Writing 0 to this bit will start the reset process. The Z80 manual says you
|
|
|
|
have to assert the /RESET line for three Z80 clock cycles as a reset does
|
|
|
|
not happen instantly.
|
|
|
|
|
|
|
|
Writing 1 to this bit will stop the reset process. At this point, the Z80
|
|
|
|
will start executing from address 0000h onwards.
|
|
|
|
|
|
|
|
The /RESET line is shared with the YM2612. For as long as the Z80 is reset,
|
|
|
|
the YM2612 cannot be used.
|
|
|
|
|
|
|
|
The Z80 bus can only be accessed by the 68000 when the Z80 is running
|
|
|
|
and the 68000 has the bus. (as opposed to the Z80 being reset, and/or
|
|
|
|
having the bus itself)
|
|
|
|
|
|
|
|
Otherwise, reading $A00000-A0FFFF will return the MSB of the next
|
|
|
|
instruction to be fetched, and the LSB will be set to zero. Writes
|
|
|
|
are ignored. This even applies to the VDP area that would normally
|
|
|
|
lock up the machine.
|
|
|
|
|
|
|
|
Interestingly enough, you can still access $A10000-A1001F during this
|
|
|
|
time, which seems to be contradictory to some documentation which says
|
|
|
|
you can only access the I/O region when the 68000 has the bus.
|
|
|
|
|
|
|
|
On power-up, the Z80 will be reset and will have the bus.
|
|
|
|
If you want to load a Z80 program and run it, do the following:
|
|
|
|
|
|
|
|
- Stop the reset process
|
|
|
|
- Request bus
|
|
|
|
- Load Z80 program
|
|
|
|
- Start the reset process
|
|
|
|
- Release bus
|
|
|
|
- Stop the reset process
|
|
|
|
|
|
|
|
2.3) Banking
|
|
|
|
|
|
|
|
The Z80 can access the 68000's address space through a banking mechanism
|
|
|
|
which maps 32k pages to 8000-FFFFh on the Z80 side.
|
|
|
|
|
|
|
|
Most games do this to get at large data chunks like YM2612 DAC samples.
|
|
|
|
However, you can access anything else the 68000 can. (I've tried reading
|
|
|
|
the version register and setting the VDP border color this way with
|
|
|
|
success - in fact some 32X sample code shows the PWM sound generator
|
|
|
|
programmed by the Z80 through banking)
|
|
|
|
|
|
|
|
To specify which 32k section you want to access, write the upper nine
|
|
|
|
bits of the complete 24-bit address into bit 0 of the bank address
|
|
|
|
register, which is at 6000h (Z80) or A06000h (68000), starting with
|
|
|
|
bit 15 and ending with bit 23.
|
|
|
|
|
|
|
|
For example:
|
|
|
|
|
|
|
|
ld ix, $6000 ;
|
|
|
|
xor a ;
|
|
|
|
ld (ix), a ; Bit 15 = 0
|
|
|
|
ld (ix), a ; Bit 16 = 0
|
|
|
|
ld (ix), a ; Bit 17 = 0
|
|
|
|
ld (ix), a ; Bit 18 = 0
|
|
|
|
ld (ix), a ; Bit 19 = 0
|
|
|
|
ld (ix), a ; Bit 20 = 0
|
|
|
|
ld (ix), a ; Bit 21 = 0
|
|
|
|
inc a ;
|
|
|
|
ld (ix), a ; Bit 22 = 1
|
|
|
|
ld (ix), a ; Bit 23 = 1
|
|
|
|
|
|
|
|
After this routine executes, Z80 addresses 8000-FFFFh now correspond
|
|
|
|
to 68000 addresses C00000-C07FFFh.
|
|
|
|
|
|
|
|
In my own tests, I've been unable to do the following:
|
|
|
|
|
|
|
|
- Read banked 68000 RAM. (returns FFh)
|
|
|
|
- Find result of partial writes to the bank address register.
|
|
|
|
- Have the Z80 read A00000-A0FFFF through the banked memory area.
|
|
|
|
(locks up the machine)
|
|
|
|
|
|
|
|
Steve Snake informed me that reading 68000 RAM is possible, but is not
|
|
|
|
a recommended practice by Sega. Perhaps only some models of the Genesis
|
|
|
|
allow for it.
|
|
|
|
|
|
|
|
2.4) Interrupts
|
|
|
|
|
|
|
|
The Z80 runs in interrupt mode 1, where an interrupt causes a RST 38h.
|
|
|
|
However, interrupt mode 0 can be used as well, since FFh will be read
|
|
|
|
off the bus.
|
|
|
|
|
|
|
|
The Z80 will recieve an IRQ from the VDP on scanline E0h. This happens
|
|
|
|
once per frame, every frame, regardless of frame interrupts being
|
|
|
|
disabled by the 68000.
|
|
|
|
|
|
|
|
If the Z80 has interrupts disabled when the frame interrupt is supposed
|
|
|
|
to occur, it will be missed, rather than made pending.
|
|
|
|
|
|
|
|
There is no way to trigger an NMI unless the Genesis has been switched
|
|
|
|
into Mark 3 compatability mode, and this only means the NMI line is
|
|
|
|
mapped to the cartridge port, it's not controllable through software.
|
|
|
|
|
|
|
|
3.0) Input and Output
|
|
|
|
|
|
|
|
The Genesis has three general purpose I/O ports. Devices like gamepads,
|
|
|
|
modems, light guns, etc. can be used with them.
|
|
|
|
|
|
|
|
Here's a read-out of the I/O registers in their default state. Each
|
|
|
|
one can be read at an even address (e.g. A1000Dh == A1000Ch) as well.
|
|
|
|
|
|
|
|
A10001h = A0 Version register
|
|
|
|
|
|
|
|
A10003h = 7F Data register for port A
|
|
|
|
A10005h = 7F Data register for port B
|
|
|
|
A10007h = 7F Data register for port C
|
|
|
|
|
|
|
|
A10009h = 00 Ctrl register for port A
|
|
|
|
A1000Bh = 00 Ctrl register for port B
|
|
|
|
A1000Dh = 00 Ctrl register for port C
|
|
|
|
|
|
|
|
A1000Fh = FF TxData register for port A
|
|
|
|
A10011h = 00 RxData register for port A
|
|
|
|
A10013h = 00 S-Ctrl register for port A
|
|
|
|
|
|
|
|
A10015h = FF TxData register for port B
|
|
|
|
A10017h = 00 RxData register for port B
|
|
|
|
A10019h = 00 S-Ctrl register for port B
|
|
|
|
|
|
|
|
A1001Bh = FF TxData register for port C
|
|
|
|
A1001Dh = 00 RxData register for port C
|
|
|
|
A1001Fh = 00 S-Ctrl register for port C
|
|
|
|
|
|
|
|
Bit 7 of the Data registers can be read or written.
|
|
|
|
Any bit that is set as an input will return '1'.
|
|
|
|
Any bit that is set as an output will return the value last written.
|
|
|
|
|
|
|
|
Bits 7-0 of the Ctrl registers can be read or written.
|
|
|
|
|
|
|
|
Bits 7-0 of the TxData registers can be read or written.
|
|
|
|
|
|
|
|
The RxData register will always return zero.
|
|
|
|
|
|
|
|
Bits 7-4 of the S-Ctrl registers can be read or written.
|
|
|
|
|
|
|
|
3.1) Programming I/O ports
|
|
|
|
|
|
|
|
In the context of this description, I'll assume the device plugged in is a
|
|
|
|
gamepad. However, other periperhals like multi-taps, modems, mice, light
|
|
|
|
guns, etc, exist.
|
|
|
|
|
|
|
|
Here's a pin-out of the connector:
|
|
|
|
|
|
|
|
Pin 1 - UP
|
|
|
|
Pin 2 - DOWN
|
|
|
|
Pin 3 - LEFT
|
|
|
|
Pin 4 - RIGHT
|
|
|
|
Pin 5 - Vcc
|
|
|
|
Pin 6 - TL
|
|
|
|
Pin 7 - TH
|
|
|
|
Pin 8 - GND
|
|
|
|
Pin 9 - TR
|
|
|
|
|
|
|
|
Each I/O port has several associated registers. I'll only cover the
|
|
|
|
data and control registers, as the others are used for serial and
|
|
|
|
parallel communication.
|
|
|
|
|
|
|
|
The data register corresponds to the I/O port pins like so:
|
|
|
|
|
|
|
|
Bit 7 - (Not connected)
|
|
|
|
Bit 6 - TH
|
|
|
|
Bit 5 - TL
|
|
|
|
Bit 4 - TR
|
|
|
|
Bit 3 - RIGHT
|
|
|
|
Bit 2 - LEFT
|
|
|
|
Bit 1 - DOWN
|
|
|
|
Bit 0 - UP
|
|
|
|
|
|
|
|
A '0' means a button has been pressed, and '1' means a button has been
|
|
|
|
released.
|
|
|
|
|
|
|
|
Bit 7 isn't connected to any pin on the I/O port. It will latch a value
|
|
|
|
written to it, as shown:
|
|
|
|
|
|
|
|
move.b $A10003, d0 ; D0 = $7F
|
|
|
|
move.b #$80, $A10003 ; Bit 7 = 1
|
|
|
|
move.b $A10003, d0 ; D0 = $FF
|
|
|
|
move.b #$00, $A10003 ; Bit 7 = 0
|
|
|
|
move.b $A10003, d0 ; D0 = $7F
|
|
|
|
|
|
|
|
Bits 6-0 of the control register define what bits of the data register
|
|
|
|
are inputs or outputs. Gamepads use TH as an output and the remaining
|
|
|
|
pins as input, so a value of $40 would be written to the control register.
|
|
|
|
|
|
|
|
3.2) Gamepad specifics
|
|
|
|
|
|
|
|
A gamepad maps the directional pad to the pins mentioned earlier
|
|
|
|
(left, right, up, down), and multiplexes the four buttons (A, B, C, Start)
|
|
|
|
through the TL and TR pins.
|
|
|
|
|
|
|
|
The TH pin controls which pairs of buttons (either A, Start or C, B) are
|
|
|
|
output through TL and TR by the multiplexer chip.
|
|
|
|
|
|
|
|
In order to read all the buttons, A program will set TH = 1, read the data
|
|
|
|
port, set TH = 0, and read the port again. The data returned is as follows:
|
|
|
|
|
|
|
|
TH = 0 : ?0SA00DU
|
|
|
|
TH = 1 : ?1CBRLDU
|
|
|
|
|
|
|
|
? = Whatever was last written to bit 7.
|
|
|
|
S = Start
|
|
|
|
A = Button A
|
|
|
|
B = Button B
|
|
|
|
C = Button C
|
|
|
|
U = Up
|
|
|
|
D = Down
|
|
|
|
L = Left
|
|
|
|
R = Right
|
|
|
|
|
|
|
|
A 6-button gamepad allows the extra buttons to be read based on how
|
|
|
|
many times TH is switched from 1 to 0 (and not 0 to 1). Observe the
|
|
|
|
following sequence:
|
|
|
|
|
|
|
|
TH = 1 : ?1CBRLDU 3-button pad return value
|
|
|
|
TH = 0 : ?0SA00DU 3-button pad return value
|
|
|
|
TH = 1 : ?1CBRLDU 3-button pad return value
|
|
|
|
TH = 0 : ?0SA0000 D3-0 are forced to '0'
|
|
|
|
TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0
|
|
|
|
TH = 0 : ?0SA1111 D3-0 are forced to '1'
|
|
|
|
|
|
|
|
M = Mode
|
|
|
|
X = Button X
|
|
|
|
Y = Button Y
|
|
|
|
Z = Button Z
|
|
|
|
|
|
|
|
From this point on, the standard 3-button pad values will be returned
|
|
|
|
if any further TH transitions are done.
|
|
|
|
|
|
|
|
If TH isn't modified in about 8192 (probably less than that) 68000 CPU
|
|
|
|
cycles, a 'time-out' will occur and the sequence to read 6-button values
|
|
|
|
can be done again. Games usually poll the gamepad once per frame,
|
|
|
|
which is always enough for the time-out to occur.
|
|
|
|
|
|
|
|
I believe checking if D3-D0 are all set or clear (as shown in the list
|
|
|
|
above) would be another method to verify if 6-button or 3-button pad data
|
|
|
|
was being returned.
|
|
|
|
|
|
|
|
Some games may access the gamepad in a way that causes 6-button values
|
|
|
|
to be returned when 3-button values are expected. To get around this,
|
|
|
|
the MODE button can be held down when powering-up the console, and
|
|
|
|
the 6-button gamepad will respond like a 3-button one.
|
|
|
|
|
|
|
|
4.) Miscellaneous
|
|
|
|
|
|
|
|
The following are miscellaneous topics.
|
|
|
|
|
|
|
|
4.1) EEPROM
|
|
|
|
|
|
|
|
Some cartridges use a Xicor X24C01 EEPROM chip. The chip is programmed
|
|
|
|
in a serial fashion (it has only two wires), and has 128 8-bit bytes
|
|
|
|
of storage.
|
|
|
|
|
|
|
|
Games using EEPROM have the backup data string at offset $1B0 in the
|
|
|
|
cartridge header area formatted like so:
|
|
|
|
|
|
|
|
0001B0: 52 41 E8 40 00 20 00 01 00 20 00 01
|
|
|
|
|
|
|
|
The Sega manual describes how the above data should be interpreted.
|
|
|
|
In this case, it corresponds to a device mapped to odd memory addresses,
|
|
|
|
occupying the byte at $200001.
|
|
|
|
|
|
|
|
The only games I know of which use an EEPROM chip are:
|
|
|
|
|
|
|
|
- Wonderboy 3 / Monster World IV
|
|
|
|
- Rockman Megaworld
|
|
|
|
- Megaman: The Wily Wars
|
|
|
|
|
|
|
|
4.2) Virtua Racing
|
|
|
|
|
|
|
|
The Virtua Racing cartridge has 2MB ROM, 128K RAM, and a custom DSP chip
|
|
|
|
called the 'Sega Virtua Processor' (SVP), which is manufactured by Sega.
|
|
|
|
To the best of my knowledge, the SVP chip has internal ROM and possibly
|
|
|
|
internal RAM.
|
|
|
|
|
|
|
|
The main purpose of the SVP is to render polygons as 8x8 patterns, which
|
|
|
|
the game program transfers to VRAM from the 128K RAM area using DMA.
|
|
|
|
|
|
|
|
The VR cartridge has the following memory map:
|
|
|
|
|
|
|
|
000000-1FFFFFh : Program ROM (2MB)
|
|
|
|
200000-2FFFFFh : Unused
|
|
|
|
300000-31FFFFh : On-cart RAM (128K)
|
|
|
|
320000-3FFFFFh : (?)
|
|
|
|
390000-39FFFFh : (?)
|
|
|
|
3A0000-3AFFFFh : (?)
|
|
|
|
|
|
|
|
The SVP chip has registers mapped in the I/O space:
|
|
|
|
|
|
|
|
A15000.w - Can read and write commands
|
|
|
|
A15005.b - Reading bit 0 acts like a status flag (SVP busy?)
|
|
|
|
A15006.w - Unknown ($0000, $0001, $000A written)
|
|
|
|
A15008.w - Unknown ($0000, $0001, $0000 written)
|
|
|
|
|
|
|
|
Commands are two bytes in size, and are read and written to A15000h.
|
|
|
|
|
|
|
|
FFFFh - Command reset (?) (done before any access)
|
|
|
|
'SV' - Command init (?) (written before SVP communication)
|
|
|
|
'OK' - Command OK (?) (written after 'SV')
|
|
|
|
'Tx' - Where 'x' equals the following value based on the command
|
|
|
|
selected in the test menu:
|
|
|
|
0 - "DSP ROM RD" and
|
|
|
|
"DSP RAM OVER WRITE"
|
|
|
|
1 - "DSP DRAM R/W"
|
|
|
|
2 - "DSP IRAM R/W"
|
|
|
|
4 - "DSP POINTER"
|
|
|
|
|
|
|
|
To emulate the SVP chip, somebody needs to figure out how to dump the
|
|
|
|
internal ROM (the test menu shows that it has a DSP ROM reading option,
|
|
|
|
perhaps sending a certain command to the SVP makes it map it's internal
|
|
|
|
ROM within the $300000-$3FFFFF area) and figure out how the DSP works.
|
|
|
|
|
|
|
|
All of the above information came from physically examining a VR cartridge,
|
|
|
|
and from disassembling the test menu code. (found at $1B000 for those
|
|
|
|
of you who are interested)
|
|
|
|
|
|
|
|
4.3) Phantasy Star 4
|
|
|
|
|
|
|
|
Phantasy Star 4 is a 24 megabit game with 16k of battery backed RAM
|
|
|
|
mapped to $200001-$203FFF. (odd addresses used) It has ROM in the same
|
|
|
|
area where the RAM is. I've observed that the game will always write
|
|
|
|
$01 to $A130F1 before accessing the RAM, and then write $00 when
|
|
|
|
done. It could be that bit 0 of $A130F1 controls ROM/RAM banking at
|
|
|
|
that location.
|
|
|
|
|
|
|
|
Jeff Quinn has tested this and confirmed it to work, and also reported
|
|
|
|
an area of the game where supporting banked SRAM is important; when
|
|
|
|
your characters encounter a GEROTLUX below the town of Tyler on Dezolis,
|
|
|
|
the game will try to access the ROM data that is obscured by SRAM.
|
|
|
|
|
|
|
|
4.4) Other topics
|
|
|
|
|
|
|
|
- The 68000 RESET instruction has no effect.
|
|
|
|
|
|
|
|
- If the VDP is not accessed often enough, it will (appear) to lock up.
|
|
|
|
I'm not sure what the cause is, but any control port access is enough
|
|
|
|
to keep it going. Maybe some of the internal VDP memory is composed
|
|
|
|
of DRAM cells that lose their data after a while. This happens in
|
|
|
|
the Mark III compatability mode as well as mode 4 and mode 5.
|
|
|
|
|
|
|
|
- The status of the YM2612 can be read at any of it's four addresses.
|
|
|
|
Since only address zero is documented as valid, it could be that the
|
|
|
|
other addresses may return an incorrect result in some situations.
|
|
|
|
|
|
|
|
- The PSG is compatible with the Texas Instruments SN76489. It is actually
|
|
|
|
on the same physical chip as the VDP, and it's output comes directly
|
|
|
|
out of the VDP to be mixed with the YM2612. Sega did the same thing
|
|
|
|
with the System C2 (possibly System 18) and SMS VDPs as well.
|
|
|
|
|
|
|
|
Can anyone contribute some information about the Genesis security
|
|
|
|
and operating system ROM features? I know of a few:
|
|
|
|
|
|
|
|
- Games must write the text 'SEGA' to A14000h if the lower four
|
|
|
|
bits of the version register return 01h.
|
|
|
|
- Writing 01h to A14101h disables the OS ROM and swaps in the cart ROM.
|
|
|
|
- The OS ROM checks for 'SEGA' or ' SEGA' at offset 100h in the cart ROM.
|
|
|
|
|
|
|
|
Here's a list of consoles that support the Mark III compatability mode.
|
|
|
|
|
|
|
|
- Sega Mega Drive
|
|
|
|
- Sega Mega Drive 2
|
|
|
|
- Sega Genesis
|
|
|
|
- Sega Genesis 2
|
|
|
|
|
|
|
|
And ones that do not:
|
|
|
|
|
|
|
|
- Genesis 3 (Majesco)
|
|
|
|
|
|
|
|
If anyone has tested this with the Nomad, CDX, MegaJet, etc., please
|
|
|
|
let me know.
|
|
|
|
|
|
|
|
5.) Credits
|
|
|
|
|
|
|
|
I would like to thank the following people for contributing information:
|
|
|
|
|
|
|
|
Bart Trzynadlowski, Christian Schiller, Flavio Morsoletto, Jeff Quinn,
|
|
|
|
Mike Gordon, Naflign, Omar Cornut, Steve Snake, and Tim Meekins.
|
|
|
|
|
|
|
|
Contributors to the Sega Programming FAQ.
|
|
|
|
Gringoz for the Genesis schematics.
|
|
|
|
|
|
|
|
6.) Disclaimer
|
|
|
|
|
|
|
|
If you use any information from this document, please credit me
|
|
|
|
(Charles MacDonald) and optionally provide a link to my webpage
|
|
|
|
(http://cgfm2.emuviews.com/) so interested parties can access it.
|
|
|
|
|
|
|
|
The credit text should be present in the accompanying documentation of
|
|
|
|
whatever project which used the information, or even in the program
|
|
|
|
itself (e.g. an about box)
|
|
|
|
|
|
|
|
Regarding distribution, you cannot put this document on another
|
|
|
|
website, nor link directly to it.
|
|
|
|
|