diff --git a/source/docs/gen-hw.txt b/source/docs/gen-hw.txt index e69de29..3fbd63f 100644 --- a/source/docs/gen-hw.txt +++ b/source/docs/gen-hw.txt @@ -0,0 +1,715 @@ + + 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. + diff --git a/source/docs/genvdp.txt b/source/docs/genvdp.txt index e69de29..48f91a3 100644 --- a/source/docs/genvdp.txt +++ b/source/docs/genvdp.txt @@ -0,0 +1,1654 @@ + + Sega Genesis VDP documentation + Version 1.5f (08/10/00) + + by Charles MacDonald + WWW: http://cgfm2.emuviews.com + + Unpublished work Copyright 2000 Charles MacDonald + + + This document is very preliminary and subject to change. + + + Changes from the last version: + + (v1.5f) + - Minor update on 68k -> VDP DMA transfers. (section 11) + (v1.5e) + - More information on VDP register sets. + - Added preliminary section numbers and table of contents. + - Revised todo list. + (v1.5d) + - Fixed sprite size byte layout. + - Listed a few games that overlap low and high priority sprites. + - Mentioned game problems regarding data port access. + (v1.5c) + - Verified DMA transfer wrapping. + - Fixed MSB/LSB mixup in DMA fill description. + - Added zero length DMA behavior. + - Mentioned results of writing during fills. + - Added VRAM address register wrapping. + (v1.5) + - Added shadow / hilight info. + - Added HV counter information. + - Added notes on odd byte access. + - Expanded register list. + - Rewrote DMA section. + - Did a little work on priority and patterns. + (v1.4) + - Described 8-bit port writes. + - Expanded VDP register programming section. + - Rewrote description of external interrupts. + - Removed 8-bit VRAM fill section. + - Added VDP pinout. + - Changed introduction and overview sections. + - Removed display size list. + - Added interrupts description. + (v1.3) + - Fixed sprite limitation count. + - Added details on blanking flags in status register. + - Added status register section. + - Added notes on VSRAM/CRAM fills. + - Added scrolling section. + - Added description of backdrop color register. + - Added description of mode set #3 register. + (v1.2) + - Completed most of the DMA section. + - Added sprite masking information. + - Verified bits 5-0 of reg 23 have no effect on VRAM fills. + - Fixed CD4 description. + (v1.1) + - Verified CD4 does not affect a 68K->VDP DMA transfer. + - Verified code and address registers retain their state after half of + a command word is written to the control port. + - Added display mode list. + - Added specific VDP RAM type info. + - Added sprite section. + - Verified register writes reset the pending flag. + - Added VDP port map. + - Verified byteswap behavior for VRAM writes. + - Verified no illegal codes allowed for CRAM writes. + - Verified A15-A7 of VSRAM address is ignored. + - Verified A0 of CRAM address is ignored. + - Verified A0 of VSRAM address is ignored. + - Verified writing to 'extra' VSRAM addresses has no effect. + - Verified ignored command word bits. + - Finalized info on palette control bit. + - Started basic control port decoding section. + - Added register #0, #1 descriptions. + - Mentioned plane A clipping in window register descriptions. + (v1.0) + - Initial draft. + + 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) + + ---------------------------------------------------------------------------- + Table of Contents + ---------------------------------------------------------------------------- + + 0.) Introduction + 1.) Overview + 2.) Display Modes + 3.) VDP port map + 4.) Interrupts + 5.) HV Counter + 6.) Status Register + 7.) VDP ports + 8.) VRAM + 9.) CRAM + 10.) VSRAM + 11.) DMA + 12.) Patterns + 13.) Background Layers + 14.) Priority + 15.) Sprites + 16.) Shadow / Hilight mode + 17.) VDP registers + 18.) VDP Pinout + + + ---------------------------------------------------------------------------- + 0.) Introduction + ---------------------------------------------------------------------------- + + This is a compilation of my notes on the Sega Genesis video display + processor. + + I wanted to write this because the existing information on the VDP is + very inadequate. Many of the subtle quirks and bugs are not explained. + + I'd like to thank the following people in alphabetical order for + providing information and being helpful: + + Bart Trzynadlowski + Christian Schiller + Flavio Morsoletto + Omar Cornut + Stephane Dallongeville + + Also thanks to Sardu and Steve Snake for genecyst and KGen98, which + were both used for devloping test programs. + + I am interested in finding somebody who has a Sega Genesis copier and + would be willing to run some test programs and report the results. + + ---------------------------------------------------------------------------- + 1.) Overview + ---------------------------------------------------------------------------- + + The Genesis VDP is derived from the Master System VDP, which in turn + was derived from the Texas Instruments TMS9918. As a result, the VDP is + programmed much like it's earlier counterparts. + + Interestingly enough, none of the Sega produced VDP's are similar to the + later VDP models made by Yamaha, which were also based upon the TMS9918. + + ---------------------------------------------------------------------------- + 2.) Display Modes + ---------------------------------------------------------------------------- + + To clarify naming conventions, here is a list of display modes used by + the various video chips mentioned: + + Mode 0 - TMS9918 specific + Mode 1 - TMS9918 specific + Mode 2 - TMS9918 specific + Mode 3 - TMS9918 specific + Mode 4 - SMS mode + Mode 5 - Genesis mode + + Supported mode list: + + TMS9918 - Modes 0, 1, 2, 3 + SMS - Modes 0, 1, 2, 3, 4 + Genesis - Modes 4, 5 (possibly 0 and others as well) + + If anybody has some information about how the Game Gear would fit into + this list, let me know. I assume it's identical to the SMS, but I don't + know about the TMS9918 compatability. (if any) + + ---------------------------------------------------------------------------- + 3.) VDP port map + ---------------------------------------------------------------------------- + + The VDP occupies addresses C00000h to C0001Fh. + + C00000h - Data port (8=r/w, 16=r/w) + C00002h - Data port (mirror) + C00004h - Control port (8=r/w, 16=r/w) + C00006h - Control port (mirror) + C00008h - HV counter (8/16=r/o) + C0000Ah - HV counter (mirror) + C0000Ch - HV counter (mirror) + C0000Eh - HV counter (mirror) + C00011h - SN76489 PSG (8=w/o) + C00013h - SN76489 PSG (mirror) + C00015h - SN76489 PSG (mirror) + C00017h - SN76489 PSG (mirror) + + ---------------------------------------------------------------------------- + 4.) Interrupts + ---------------------------------------------------------------------------- + + The VDP generates all interrupts for the 68000. The only hardware + interrupts available are 2, 4, and 6. + + Vertical interrupts + ------------------- + + If bit 5 (IE0) of register #1 is set, then a level 6 interrupt will occur + when the V counter is at line E0h, roughly at H counter cycle 08h. At this + point in time, the vertical interrupt occurance flag (bit 7) will be set + in the status register. + + Line interrupts + --------------- + + The VDP has a counter that is decremented on every line. When the counter + has expired, and if bit 4 (IE1) of register #0 is set, then a level 4 + interrupt will occur. + + The counter is loaded with the contents of register #10 in the following + situations: + + - Line zero of the frame. + - When the counter has expired. + - Lines 225 through 261. (note that line 224 is not included) + + The counter is *not* loaded when register #10 is written to. + + Note that line interrupts are processed *before* vertical interrupts + within a scanline. If you trigger a line interrupt to occur on line E0h, + then the level 4 line interrupt will be taken by the 68000, not the + level 6 vertical interrupt. + + External interrupts + ------------------- + + Pin 7 of each of the three I/O ports is called the TH pin. It is connected + to the VDP. When the state of TH is changed, the following events happen: + + - If bit 7 of the control register for the associated I/O port is set, + and bit 3 of register #11 (IE2) is set, then the VDP will generate + a level 2 interrupt. + + - If bit 1 of VDP register #0 is set, the contents of the HV counter will + be latched. + + A common use for these features are in a light gun game. The light gun + can change the state of TH, which will freeze the HV counter, and then + the level 2 interrupt subroutine can read the HV counter and also + communicate with the light gun to get information like what buttons + were pressed. This is pretty much how Sega's 'Menacer' device works. + The Konami 'Justifier' light gun works on similar principles. + + I don't know if the HV counter resumes normal operation after the first + read, or if the HV counter latch bit has to be cleared and set again. + + Some games will enable the HV counter latch and never read the HV counter, + let alone use any special peripherals. (Shadow of the Beast II) + + You cannot force an external interrupt by changing the state of TH + through software. (e.g. in the normal sequence of reading the gamepad, + TH is set and cleared - this does not cause an interrupt if interrupts + are enabled) + + The data direction for TH (which corresponds to bit 6 of the data and + control registers) must be configured as an input for a peripheral + to cause an interrupt. + + ---------------------------------------------------------------------------- + 5.) HV Counter + ---------------------------------------------------------------------------- + + The HV counter returns the vertical and horizontal position of the + television's raster beam. + + Reading the HV counter will return the following data: + + VC7 VC6 VC5 VC4 VC3 VC2 VC1 VC0 (D15-D08) + HC8 HC7 HC6 HC5 HC4 HC3 HC2 HC1 (D07-D00) + + VCx = Vertical position in lines. + HCx = Horizontal position in pixels. + + According to the manual, VC0 is replaced with VC8 when in interlace mode 2. + + For 8-bit reads, the even byte (e.g. C00008h) returns the V counter, and + the odd byte (e.g. C00009h) returns the H counter. + + The V counter counts up from 00h to EAh, then it jumps back to E5h and + continues counting up to FFh. This allows it to cover the entire 262 line + display. + + The H counter counts up from 00h to E9h, then it jumps back to 93h and + continues counting up to FFh. This allows it to cover an entire 342 pixel + line. + + The H counter description is based upon known information about the SMS + VDP's H counter. The SMS has a 256x192 display, and each line consists of + 342 pixels. (that includes blanking, retrace, etc.) The description + *could* be accurate for the Genesis' 32-cell display mode. This is not + the case for the 40-cell display, where I would assume the H counter jumps + back farther at a later point in the count-up. + + In terms of emulation, I have found that turning the elapsed 68000 cycle + count into a pixel offset for the current scan line seems to provide a + reasonable return value for the H counter. However, I am quite positive + a single scanline consists of more pixels than just 256 or 320, and + in addition the 'jump-back' described above is not taken into account. + In all honesty this is a hack, not a solution. + + I would appreciate any additional information on the HV counter. + + ---------------------------------------------------------------------------- + 6.) Status Register + ---------------------------------------------------------------------------- + + Reading the control port returns a 16-bit word that allows you to observe + various states of the VDP and physical display. + + d15 - Always 0 + d14 - Always 0 + d13 - Always 1 + d12 - Always 1 + d11 - Always 0 + d10 - Always 1 + d9 - FIFO Empty + d8 - FIFO Full + d7 - Vertical interrupt pending + d6 - Sprite overflow on current scan line + d5 - Sprite collision + d4 - Odd frame + d3 - Vertical blanking + d2 - Horizontal blanking + d1 - DMA in progress + d0 - PAL mode flag + + Presumably bit 0 is set when the system display is PAL; however this same + information can be read from the version register (part of the I/O + register group - not the VDP), so maybe this bit reflects the state of + having a 240-line display enabled. + + Bit 1 is set for the duration of a DMA operation. This is only useful for + fills and copies, since the 68000 is frozen during 68k -> VDP transfers. + + Bit 2 returns the real-time status of the horizontal blanking signal. + It is set at H counter cycle E4h and cleared at H counter cycle 08h. + + Bit 3 returns the real-time status of the vertical blanking signal. + It is set on line E0h, at H counter cycle AAh, and cleared on line FFh, + at H counter cycle AAh. + + (Note: For both blanking flag descriptions, the H counter values are + very likely different for 32-cell and interlaced displays; they were + taken from a test with a 40-cell screen.) + + Bit 4 is set when the display is interlaced, and in the odd frame, + otherwise it is cleared in the even frame. This applies to both + interlace modes. + + Bit 5 is set when any sprites have non-transparent pixels overlapping one + another. This may hold true for sprites outside of the display area too. + This bit is most likely cleared at the end of the frame. + + Bit 6 is set when too many sprites are on the current scan line, meaning + when the VDP parses the 21st sprite in 40-cell mode or the 17th sprite in + 32-cell mode from the sprite list. + This bit is most likely cleared at the end of the frame. + + Bit 7 is set when a vertical interrupt occurs. This happens at line E0h, + roughly after H counter cycle 08h. I do not know under what conditions + it is cleared, presumably at the end of the frame. Reading the control + port does not clear this bit. (this could be incorrect) + + Bit 8 and 9 (FULL and EMPTY flags, respectively) are related to the FIFO; + here's what Flavio Morsoletto has to say about their use: + + "The FIFO can hold up to four 16-bit words while the VDP's busy + parsing data from VRAM. Once the 68K has written the fourth word, + FULL is raised. If the processor attempts to write one more time, it + will be frozen (/DTACK high) until the FIFO unit manages to deliver + the first stacked word to its rightful owner. EMPTY only goes 1 when + there is nothing on the stack. The intermediate state is signaled by + both of them showing 0." + + This situation only occurs during the active display period, as the + data port can be written to as many times as needed during blanking. + + I've noticed most emulators keep the EMPTY flag set, so it appears as + if the FIFO was always empty instead of being in the neutral state. This + is probably for games that would normally check and find the FIFO in a + neutral state, then write data and expect to poll the FULL flag afterwards. + + ---------------------------------------------------------------------------- + 7.) VDP ports + ---------------------------------------------------------------------------- + + The VDP is programmed entirely through the control and data ports. + Data written to the control port is formatted, so the VDP will know + how to interpret the data it recieves. + + You can divide control port data into two categories; 16-bit register sets + and 32-bit command words. + + Programming VDP registers + ------------------------- + + Any one of the 23 VDP registers can be programmed by writing 16 bits of + data to the control port. The data written has the following format: + + 1 0 ? R04 R03 R02 R01 R00 (D15-D8) + D07 D06 D05 D04 D03 D02 D01 D00 (D7-D0) + + Rxx = VDP register select (00-1F) + Dxx = VDP register data (00-FF) + + Writing to non-existant VDP registers has no effect. + + Bits 15 and 14 must be set to 1 and 0 respectively, otherwise the write + will be treated as the first half of a command word. The state of bit 13 + does not matter. + + Here's an example of programming one register: + + ; Set border color to palette $3, index $F + move.w #$873F, $00C00004 + + Since the 68000 treats 32-bit memory access as two 16-bit operations, + you can program two registers at once: + + ; Set split point bits for both window registers + move.w #$91809280, $00C00004 + + Accessing VDP RAM + ----------------- + + You can access VRAM, CRAM, or VSRAM by writing a 32-bit command word to + the control port. The data written has the following format: + + CD1 CD0 A13 A12 A11 A10 A09 A08 (D31-D24) + A07 A06 A05 A04 A03 A02 A01 A00 (D23-D16) + ? ? ? ? ? ? ? ? (D15-D8) + CD5 CD4 CD3 CD2 ? ? A15 A14 (D7-D0) + + CDx = VDP code (0-3F) + Axx = VDP address (00-FFFF) + + The state of D15 through D8, D3, and D2 are ignored. + + The VDP has an address and code register. They are used in conjunction to + handle data port accesses. The address register provides an offset into + VDP RAM to write or read data from. The code register specifies if + data port accesses will be reads or writes, and the kind of VDP RAM + to perform these operations on. + + In order for the VDP to know if the first or second 16-bit half of the + command word has been written to the control port, it maintains an internal + write-pending flag. This flag is updated when these conditions are met: + + - It is set when the first half of the command word is written. + - It is cleared when the second half of the command word is written. + - It is cleared when the data port is written to or read from. + - It is cleared when the control port is read. + + It is perfectly valid to write the first half of the command word only. + In this case, _only_ A13-A00 and CD1-CD0 are updated to reflect the new + values, while the remaining address and code bits _retain_ their former + value. + + You cannot write to a VDP register if the pending flag is set to one, + since the VDP is expecting the 2nd half of a command word. + + Writing to a VDP register will clear the code register. Games that rely + on this are Golden Axe II (will display missing SEGA logo) and Sonic 3D. + (will show intro movie in wrong colors for a few frames) It is not known + if the address register is cleared as well, but the TMS9918 manual + indicates that this is so, perhaps it applies to the Genesis as well. + + Here is a table of code register settings: + + Bits CD3-CD0 + 0000b : VRAM read + 0001b : VRAM write + 0011b : CRAM write + 0100b : VSRAM read + 0101b : VSRAM write + 1000b : CRAM read + + You cannot write data after setting up a read operation, or read data + after setting up a write operation. The write or read is ignored. + + CD4 is only set for the the VRAM copy DMA mode. + For data port accesses and 68k to VDP DMA, the state of CD4 is ignored. + + Setting CD5 will trigger a DMA operation. + + 8-bit port access + ----------------- + + Doing an 8-bit write to the control or data port is interpreted by + the VDP as a 16-bit word, with the data written used for both halfs + of the word. + + For instance, the following code writes 87h to VDP register #7: + + ; VDP sees data as 8787h + move.b #$87, $00C00004 + + This also applies to the data port. The following code sets CRAM entry + zero to pink: + + ; VDP sees data as 0E0Eh + move.l #$C0000000, $00C00004 + move.b #$0E, $00C00000 + + It's important to realize that a distinction between 8-bit and 16-bit VRAM + fills do not exist. There is only one type of fill, and depending on how + you write to the data port will determine the kind of data used in the fill. + + Odd addresses (e.g. C00007h, C00001h) function identically to even addresses + in the case of 8-bit writes. For instance, writing data to anywhere within + C00004h-C00007h would go to the control port. + + Miscellaneous + ------------- + + I've found that some games will write VDP register data to the data port, + after the code and address registers have been set to zero. I've confirmed + that this is simply a bug on the programmer's behalf, you cannot program + the VDP registers in this way. + + Games that do this include Alien Soldier and Eternal Champions. + + Some games also set up VRAM reads and try to write to VRAM; this is + also pointless as data written after a VRAM read command is issued + is ignored by the VDP. The unlicensed version of Populous does + this, along with Golden Axe II. + + ---------------------------------------------------------------------------- + 8.) VRAM + ---------------------------------------------------------------------------- + + The VDP is connected to 64K of video RAM. It is accessed as 65535 8-bit + bytes or 32768 16-bit words through the data port. + + VRAM is multipurpose; it can store pattern data, horizontal scroll data, + sprite tables, and background name tables. + + When writing 16-bit data to VRAM, having address bit 0 set will swap + the upper and lower bytes of the data written. + + The address register wraps past address FFFFh. + + ---------------------------------------------------------------------------- + 9.) CRAM + ---------------------------------------------------------------------------- + + The VDP has 64x9 bits of on-chip color RAM. It is accessed as 64 16-bit + words through the data port. Each word has the following format: + + ----bbb-ggg-rrr- + + r = Red component (0-7) + g = Green component (0-7) + b = Blue component (0-7) + + This allows for a total of 512 possible colors, with 64 colors stored + in CRAM at any given time. + + When accessing CRAM, only address bits 6 through 1 are valid. The high-order + address bits are ignored. Since CRAM is word-wide, address bit zero has + no effect. + + The address register wraps past address 7Fh. + + ---------------------------------------------------------------------------- + 10.) VSRAM + ---------------------------------------------------------------------------- + + The VDP has 40x10 bits of on-chip vertical scroll RAM. It is accessed as + 40 16-bit words through the data port. Each word has the following format: + + ------yyyyyyyyyy + + y = Vertical scroll factor (0-3FFh) + + When accessing VSRAM, only address bits 6 through 1 are valid. + The high-order address bits are ignored. Since VSRAM is word-wide, address + bit zero has no effect. + + Even though there are 40 words of VSRAM, the address register will wrap + when it passes 7Fh. Writes to the addresses beyond 50h are ignored. + + ---------------------------------------------------------------------------- + 11.) DMA + ---------------------------------------------------------------------------- + + The VDP can be programmed to move data into, copy, and fill sections of + VDP RAM, meaning VRAM, CRAM, and VSRAM. These functions are referred to + as Direct Memory Access. (DMA) + + Overview + -------- + + Bits 7 and 6 of register #23 select the type of DMA operation: + + D7 D6 + 0 ? : 68K -> VDP RAM transfer (D6 is bit 24 of source address) + 1 0 : VRAM fill + 1 1 : VRAM copy + + Bit 4 of register #1 will enable DMA operations when set. + + Some games will attempt to do DMA when it is disabled, including Phelios + and Rocket Knight Adventures. + + When doing 68K -> VDP RAM transfers, the 68000 is frozen. For VRAM fills + and copies, the 68000 runs normally, but you can only read the control + port, HV counter, and write to the PSG register. + + Writing to the control or data port during a VRAM fill seems to corrupt + the VDP registers and VRAM. + + When the length field is set to zero, the length is treated as FFFFh. + + 68000 to VDP RAM + ---------------- + + This is used to transfer data out of the 68000's address space into VRAM, + CRAM, or VSRAM. + + Registers 19, 20, specify how many 16-bit words to transfer: + + #19: L07 L06 L05 L04 L03 L02 L01 L00 + #20: L15 L14 L13 L12 L11 L10 L08 L08 + + Note that a length of 7FFFh equals FFFFh bytes transferred, and a length + of FFFFh = 1FFFF bytes transferred. + + Registers 21, 22, 23 specify the source address on the 68000 side: + + #21: S08 S07 S06 S05 S04 S03 S02 S01 + #22: S16 S15 S14 S13 S12 S11 S10 S09 + #23: 0 S23 S22 S21 S20 S19 S18 S17 + + If the source address goes past FFFFFFh, it wraps to FF0000h. + (Actually, it probably wraps at E00000h, but there's no way to tell as + the two addresses are functionally equivelant) + + When doing a transfer to CRAM, the operation is aborted once the address + register is larger than 7Fh. The only known game that requires this is + Batman & Robin, which will have palette corruption in levels 1 and 3 + otherwise. This rule may possibly apply to VSRAM transfers as well. + + A transfer is started when the following command word is written: + + CD1 CD0 A13 A12 A11 A10 A09 A08 (D31-D24) + A07 A06 A05 A04 A03 A02 A01 A00 (D23-D16) + ? ? ? ? ? ? ? ? (D15-D8) + 1 0 0 CD2 ? ? A15 A14 (D7-D0) + + CD2-CD0 specify the type of VDP RAM to write to: + + 001b - VRAM + 011b - CRAM + 101b - VSRAM + + The following events occur after the command word is written: + + - 68000 is frozen. + - VDP reads a word from source address. + - Source address is incremented by 2. + - VDP writes word to VRAM, CRAM, or VSRAM. + (For VRAM, the data is byteswapped if the address register has bit 0 set) + - Address register is incremented by the value in register #15. + - Repeat until length counter has expired. + - 68000 resumes operation. + + When a transfer is done out of the ROM area ($000000-3FFFFF), the machine + will lock up unless the write that triggers the DMA operation is done + using RAM. + + Usually this means putting the command word or the latter half of the + command word in RAM and moving that into the control port, putting + the command word on the stack and moving that into the control port, + or having the instruction that moves the command word into the control + port execute out of RAM. + + VRAM fill + --------- + + VRAM fills are used to repeatedly write a given data value to multiple + sequential addresses in VRAM. + + Registers 19, 20, specify how many 8-bit bytes to fill: + + #19: L07 L06 L05 L04 L03 L02 L01 L00 + #20: L15 L14 L13 L12 L11 L10 L08 L08 + + The address bits in registers 21, 22, 23 are ignored: + + #21: ? ? ? ? ? ? ? ? + #22: ? ? ? ? ? ? ? ? + #23: 1 0 ? ? ? ? ? ? + + A VRAM fill is started when the following command word is written: + + 0 1 A13 A12 A11 A10 A09 A08 (D31-D24) + A07 A06 A05 A04 A03 A02 A01 A00 (D23-D16) + ? ? ? ? ? ? ? ? (D15-D8) + 1 0 0 0 ? ? A15 A14 (D7-D0) + + Any write to the data port will then start a VRAM fill. The LSB of the + data is written to the address specified, then the MSB is written to + the adjacent address. The address register is incremented by the value + in VDP register 15, and the upper 8 bits are written again to the next + adjacent address, and so on. + + Here is some "C" pseudocode to illustrate a VRAM fill: + + void vram_fill(int data) + { + /* Write lower byte to address specified */ + vram[address] = (data >> 0) & 0xFF; + + do { + /* Write upper byte to adjacent address */ + vram[address ^ 1] = (data >> 8) & 0xFF; + + /* Increment address register */ + address += vdp_reg[15]; + } while(--length) + } + + Games that require accurate VRAM fill emulation include Thunder Force IV, + Contra Hard Corps, Revenge of Shinobi, Taiga Drama, and Sword of Vermillion. + + VRAM copy + --------- + + VRAM copies are used to copy blocks of VRAM data. + + Registers 19, 20, specify how many 8-bit bytes to copy: + + #19: L07 L06 L05 L04 L03 L02 L01 L00 + #20: L15 L14 L13 L12 L11 L10 L08 L08 + + The address bits in register 23 are ignored. + Registers 21, 22 specify the source address in VRAM: + + #21: S07 S06 S05 S04 S03 S02 S01 S00 + #22: S15 S14 S13 S12 S11 S10 S09 S08 + #23: 1 1 ? ? ? ? ? ? + + A VRAM copy is started when the following command word is written: + + 0 0 A13 A12 A11 A10 A09 A08 (D31-D24) + A07 A06 A05 A04 A03 A02 A01 A00 (D23-D16) + ? ? ? ? ? ? ? ? (D15-D8) + 1 1 0 0 ? ? A15 A14 (D7-D0) + + The VDP will read a byte from the source address which is then incremented + by one. The data will then be written to the destination address, which + is incremented by register #15. + + Games that use VRAM copies include Aleste, Bad Omen, and Viewpoint. + + Transfer capacity + ----------------- + + The VDP can access memory a certain number of times on each line of the + display. This is severely limited during the active display period, since + the VDP also needs to update the screen, leaving less memory accesses + left for DMA. + + According to the manual, here's a table that describes the transfer + rates of each of the three DMA types: + + DMA Mode Width Display Transfer Count + ----------------------------------------------------- + 68K > VDP 32-cell Active 16 + Blanking 167 + 40-cell Active 18 + Blanking 205 + VRAM Fill 32-cell Active 15 + Blanking 166 + 40-cell Active 17 + Blanking 204 + VRAM Copy 32-cell Active 8 + Blanking 83 + 40-cell Active 9 + Blanking 102 + + 'Active' is the active display period, 'Blanking' is either the vertical + blanking period or when the display is forcibly blanked via register #1. + + The above transfer counts are all in bytes, unless the destination is + CRAM or VSRAM for a 68K > VDP transfer, in which case it is in words. + + Miscellaneous + ------------- + + I don't know if the source address register and length counter are actually + updated during a DMA operation. I doubt it, but in theory you could have + a sequence like this: + + move.l #$94109300, $00C00004 ; length = 4k words + move.l #$96009500, $00C00004 + move.l #$97708F02, $00C00004 ; src = E00000h, inc = 02h + move.w #$40000003, $00C00004 ; VRAM write to C000h + ; 8k is transferred to VRAM C000h from RAM E00000h + + move.w #$60000003, $00C00004 ; VRAM write to E000h + ; 8k is transferred to VRAM E000h from RAM E02000h + + You can make VRAM fills affect CRAM or VSRAM by changing the CD2-CD0 bits + to the appropriate RAM type, just like how 68K -> VDP transfers work. + Due to the limited way this was tested, I can't say how exactly the fill + data is written; CRAM and VSRAM are word-wide, while VRAM is byte-wide, + to there's bound to be some differences. I'd assume the results are + the same as normal byte-wide data port access, where both the LSB and + MSB of each word are set to the same 8-bit data written. + + In the case of a VRAM fill, the CD2-CD0 bits are set to the same value + required for a VRAM write. In the same vein, VRAM copies have the code + bits set to the same setting as a VRAM read. Maybe changing the code + register would allow copies within CRAM and VSRAM? Or perhaps the code + bits only select the source address? (Not that a CRAM > VRAM copy is + particularly useful, but there you go.) + + ---------------------------------------------------------------------------- + 12.) Patterns + ---------------------------------------------------------------------------- + + All background and sprite graphics are made up of patterns. A pattern is + an 8x8 or 8x16 (interlace mode 2 only) pixel block that is made up of + fifteen colors. + + Patterns are stored in VRAM. Each pixel is represented by four bits, + meaning there are four bytes (4 bits * 8 pixels = 4 bytes) per line of + the pattern, and 32 or 64 bytes per pattern, depending if the pattern + is 8x8 or 8x16. + + Unlike other VRAM data that is stored in a specific table, patterns can + be placed anywhere. Even in the parts of other tables that aren't being + used, like a name table or sprite attribute table. + + A pixel within a pattern that uses value zero isn't shown. It acts as a + transparency indicator. + + ---------------------------------------------------------------------------- + 13.) Background Layers + ---------------------------------------------------------------------------- + + The VDP manages two background layers, called plane A and plane B. + + Name Tables + ----------- + + There are three tables stored in video RAM that define the layout for + planes A, B, and W. + + Each table is a matrix of 16-bit words. Each word has the following format: + + pccvhnnnnnnnnnnn + + p = Priority flag + c = Palette select + v = Vertical flip + h = Horizontal flip + n = Pattern name + + The pattern name is the upper 11 bits of the physical address of pattern + in video RAM. Bit zero of the name is ignored in interlace mode 2. + + The vertical and horizontal flip flags tell the VDP to draw the pattern + flipped in either direction. + + The palette select allows the pattern to be shown in one of four + 16-color palettes. + + The priority flag is described later. + + The name tables for plane A and B share the same dimensions. The name + table size cannot exceed 8192 bytes, so while a 64x64 or 128x32 name + table is allowed, a size of 128x128 or 64x128 is invalid. + + The name table for plane W is 32x32 in 32-cell mode, and 64x32 in 40-cell + mode. This size is fixed and is entirely dependant on the display width. + + Window + ------ + + The window plane operates differently from plane A or B. It can be thought + of a 'replacement' for plane A which is used under certain conditions. + That said, plane A cannot be displayed in any area where plane W is + located, it is impossible for them to overlap. + + Registers 17 and 18 define an area which the window is restricted to. + + In terms of priority and intensity calculation for shadow / hilight mode, + plane W is treated _exactly_ the same as plane A. + + Horizontal Scrolling + -------------------- + + The horizontal scroll table holds the scroll value for every line of + both planes A and B, that can be positioned anywhere within video RAM. + + Each entry of the scroll table is a 16-bit word. It has the following + format: + + ------xxxxxxxxxx + + x = Horizontal scroll value (0-3FFh) + + Bits D15 through D10 are ignored by the VDP. + + The lower three bits of the scroll value provide a pixel offset into each + column comprised of one pattern. The upper seven bits provide an offset + into each column of the name table (0-127). + + When the scroll value is larger than the width of the playfield, the + display wraps horizontally. + + Scroll values for planes A and B are stored in an interleaved fashion. + Entry #0 of the table is for plane A, entry #1 is for plane B, and this + repeats for the entire length of the table. + + The manual says the scroll table is 960 bytes in size, + and this seems like an accurate figure, considering the scroll table + address bits suggest the table can be 1024 bytes. + + However, I do not know what happens in double-resolution interlace + mode. To provide a scroll entry for both planes on every line, a total + of 1920 bytes would be needed. (480 lines x 2 planes x 2 bytes per line) + + Here is some "C" pseudocode to illustrate how the VDP reads the scroll + table depnding on the settings of bits 0 and 1 of register #11: + + void get_scroll(int line, int *scroll_a, int *scroll_b) + { + switch(vdp_reg[11] & 3) + { + case 0x00: /* Full screen */ + *scroll_a = *(word *)vram[hscb + 0]; + *scroll_b = *(word *)vram[hscb + 2]; + break; + + case 0x01: /* First eight lines */ + *scroll_a = *(word *)vram[hscb + ((line & 7) * 2) + 0]; + *scroll_b = *(word *)vram[hscb + ((line & 7) * 2) + 2]; + break; + + case 0x02: /* Every row */ + *scroll_a = *(word *)vram[hscb + ((line & ~7) * 2) + 0]; + *scroll_b = *(word *)vram[hscb + ((line & ~7) * 2) + 2]; + break; + + case 0x03: /* Every line */ + *scroll_a = *(word *)vram[hscb + (line * 2) + 0]; + *scroll_b = *(word *)vram[hscb + (line * 2) + 2]; + break; + } + } + + A scroll mode setting of 01b is not valid; however the unlicensed version + of Populous uses it. This mode is identical to per-line scrolling, however + the VDP will only read the first sixteen entries in the scroll table for + every line of the display. + + ---------------------------------------------------------------------------- + 14.) Priority + ---------------------------------------------------------------------------- + + The VDP manages a fairly complex system of priorities between the two + background layers and sprites. The basic ordering is: + + + (back) (front) + A > B > C > D > E' > F' > G' + + ' = Denotes high priority + A = Backdrop color + B = Low priority plane B + C = Low priority plane A + D = Low priority sprites + E = High priority plane B + F = High priority plane A + G = High priority sprites + + The sprite priority bit does not affect inter-sprite priority, only the + relation between background data. Low priority sprites *can* overlap high + priority sprites. Games that do this to mask other sprites include + Castlevania Bloodlines, Raiden Trad, and Alien Soldier. + + ---------------------------------------------------------------------------- + 15.) Sprites + ---------------------------------------------------------------------------- + + The Genesis can display a total of eighty 32x32 15-color sprites. + There are of course various restrictions on the display capacity, based + on current configuration of the VDP. + + Sprite Attribute Table + ---------------------- + + All sprite data is stored in a region of VRAM called sprite attribute table. + The table is 640 bytes in size. Each 8-byte entry has the following format: + + Index + 0 : ------yy yyyyyyyy + Index + 2 : ----hhvv + Index + 3 : -lllllll + Index + 4 : pccvhnnn nnnnnnnn + Index + 6 : ------xx xxxxxxxx + + y = Vertical coordinate of sprite + h = Horizontal size in cells (00b=1 cell, 11b=4 cells) + v = Vertical size in cells (00b=1 cell, 11b=4 cells) + l = Link field + p = Priority + c = Color palette + v = Vertical flip + h = Horizontal flip + n = Sprite pattern start index + x = Horizontal coordinate of sprite + + Linking + ------- + + The VDP draws sprites in a front-to-back order, starting with sprite zero. + The 7-bit link field in each list entry is an index to the next entry of + the sprite that will be drawn. If the link field is zero, then no more + sprites will be drawn after the current sprite. Here's an example: + + Sprite #00 has a link field of 2 + Sprite #01 has a link field of 7 + Sprite #02 has a link field of 4 + Sprite #03 has a link field of 0 + Sprite #04 has a link field of 3 + Sprite #05 has a link field of 2 + + In this case, sprites #00, #02, #04, #03 will be drawn, in that order. + + Coordinate System + ----------------- + + Sprites are positioned in a virtual 512x512 space. The display starts at + coordinate 128, 128, and takes up a space equal to the size of the physical + display. (usually 256x224 or 320x224) This system is convenient for + programmers; unwanted sprites can easily be hidden off screen, and sprites + can be shown partially at the top and left screen edges. + + Sprite masking, mode 1 + ---------------------- + + If a sprite has an X coordinate of zero, and has a Y coordinate that + is within range of the display, then all sprites of lower priority + will not be displayed on the lines which the sprite takes up. + + The height of the sprite is determined by the vertical size bits in + the sprite attributes; other factors like horizontal size, pattern data + used, priority bit, and color palette have no effect. + + For instance, an 8x32 sprite at coordinates 0, 128, that was sprite #4 + in the list would stop all sprites onwards for lines zero to 31 from + being shown. However, sprites #0 through #3 could still be displayed + in this area. + + Sprite masking, mode 2 + ---------------------- + + If a sprite has an X coordinate of one, the former rule is invalid. Low + priority sprites will only be masked if a sprite with an X coordinate of + zero _also_ has a sprite with an X coordinate of one on the _same_ line. + + This 'mode' is enabled when the VDP first parses a sprite with an X + coordinate of one. It is reset at the end of the frame. + + To my knowledge, the only game which uses this masking mode is Galaxy + Force II. Because of this, I cannot ensure my description is accurate for + other games which may use it. + + Sprite Drawing Limitations + -------------------------- + + The VDP will stop drawing sprites under the following conditions: + + - The 80th sprite has been drawn in 40-cell mode. + - The 64th sprite has been drawn in 32-cell mode. + - Twenty sprites on the same scanline have been drawn in 40 cell mode. + - Sixteen sprites on the same scanline have been drawn in 32 cell mode. + - 320 pixels worth of sprite data has been drawn on the same scanline + in 40 cell mode. + - 256 pixels worth of sprite data has been drawn on the same scanline + in 32 cell mode. + - The currently drawn sprite has a link field of zero. + + Sprites that are outside of the physical display area are still taken + into account. + + Link settings that create an 'infinite loop' or that have self-referencing + will not cause any unforseen problem, these kinds of loops will be broken + out of when the above sprite limitations are eventually reached. + + Because so many sprites can be shown on a single line, some games will + fill the entire display with sprites for a 'fake' third background layer. + Games that do this include 'Red Zone' by Zyrinx. + + ---------------------------------------------------------------------------- + 16.) Shadow / Hilight mode + ---------------------------------------------------------------------------- + + Shadow / hilight mode allows more colors to be displayed on screen. + + These additional colors are selected based upon the priority settings + for a background tile or sprite, and when certain kinds of sprite pixels + overlap background pixels. + + Background + ---------- + + Background tiles are shown at half intensity, or at normal intensity + if their priority bit is set. + + In the latter case, this affects all other graphics elements in the + region (usually 8x8) that the tile takes up, regardless of the tile + containing opaque pixels or not. Meaning that the backdrop color, other + background plane, and sprites will be forcibly shown at normal intensity + in a given area if a background tile has it's priority bit set. + + For instance, Ranger-X has both background layers and all sprites set + to low priority. A column in plane A uses high priority transparent + tiles. The result is that any sprites passing within that column, as + well as the plane B tiles that scroll behind it, are all shown at + normal intensity. + + Sprites + ------- + + Depending on the priority setting, sprites are shown at normal or half + intensity just like background tiles. + + Colors 0Eh, 1Eh, 2Eh, are always shown at normal intensity regardless of + priority. I'd say this a bug rather than a feature. + + Any pixel in a sprite that uses colors 3Eh or 3Fh is treated specially: + + Pixels with color 3Eh are not drawn. Instead, the underlying pixel + (from the backdrop or background) will be shown at half intensity. + + If the pixel to be overwritten is already at half intensity, then + nothing will happen. + + Pixels with color 3Fh are not drawn. Instead, the underlying pixel + (from the backdrop or background) will be shown at double intensity. + + Backdrop + -------- + + The backdrop is shown at half intensity, while the overscan region outside + of the display area is always shown at normal intensity. + + If a background tile has high priority, then the corresponding 8x8 block + of the backdrop color will be shown at normal intensity. It does not matter + if the background tile is fully opaque or not. + + Operator sprites will affect the backdrop color as well. + + Details + ------- + + It isn't known exactly how the colors are generated in shadow / hilight + mode. Currently all emulators make the half and double intensity colors + exactly half and double brightness of the current palette. + + This is not correct. At least the double intensity palette is actually + not much brighter than the normal palette. You can see a good example + of this by running any game using hilight sprites in an emulator + side-by-side to the same game running on a real Genesis. + + However, I haven't been able to figure out the colors exactly. In + particular, the introduction screen for Sonic 3D will only look correct + if the colors are exactly half and double, while this is certainly wrong + for other games. + + I've verified that the contents of CRAM entries 3Eh and 3Fh do not + affect the intensity of shadow and hilight pixels used in sprites. + + Any information on the colors used in shadow / hilight mode would be + appreciated. + + ---------------------------------------------------------------------------- + 17.) VDP registers + ---------------------------------------------------------------------------- + + All the register names are taken from the manual. + + $00 - Mode Set Register No. 1 + ----------------------------- + + d7 - No effect + d6 - No effect + d5 - No effect + d4 - IE1 (Horizontal interrupt enable) + d3 - 1= Invalid display setting + d2 - Palette select + d1 - M3 (HV counter latch enable) + d0 - Display disable + + Bit 4 will enable horizontal interrupts when set. + + When bit 2 is cleared, only bits 1, 5, and 9 are taken into account + when the VDP generates color data from each word of CRAM. (meaning + the LSB of each RGB component is the only bit used) This reduces the + available color palette from 512 to 8 colors. + + Bit 1 will cause the HV counter to be latched when a level 2 interrupt + is generated. The HV counter will resume normal operation when this bit + is cleared. (untested, need more info) + + Setting bit 0 actually turns off all display generation, as opposed to the + screen blanking feature which simply shows the backdrop color. + + $01 - Mode Set Register No. 2 + ----------------------------- + + d7 - TMS9918 / Genesis display select + d6 - DISP (Display Enable) + d5 - IE0 (Vertical Interrupt Enable) + d4 - M1 (DMA Enable) + d3 - M2 (PAL / NTSC) + d2 - SMS / Genesis display select + d1 - 0 (No effect) + d0 - 0 (See notes) + + Bit 7 seemingly puts the display in a TMS9918-like state when set, similar + to one of it's text display modes. Each 8x8 block is filled with a solid + color from the palette, and has no pattern data. The sprites seem to be + active. I couldn't select any of the other TMS9918 modes through the + usual TMS9918 mode bits. It would appear all the colors are actually + affected by CRAM, instead of using a fixed color set. + + Bit 6 will blank the display when cleared. Any line that is blanked is + filled with the backdrop color. During this time, you can freely access + VDP memory with no limitations on the number of writes per line. + + Bit 5 will enable vertical blanking interrupts when set. + + Bit 4 will enable DMA operations when set. Otherwise, nothing will happen + when a DMA command is sent to the VDP. + + Bit 3 will select between a PAL (240) and NTSC (224 lines) display. + + Bit 2 toggles between the Master System (mode 4) and Genesis (mode 5) + display modes. While in mode 4, none of the registers which normally + affect the Genesis work; and the unused registers (8, 9 - can't test 6) now + function. The mode bits which select TMS9918 modes on a real SMS have + no function here. (This is why the SMS game F16 Fighter will not work + with a Power Base Converter, it uses some of the TMS9918 modes in-game) + + The one exception is register $0C. You can set up a 320x192 display, + but the leftmost eight columns read 'garbage' data for the name table + attributes. Enabling interlace makes the display unstable. (and this + is partially true for a 320x192 picture, which shakes slightly) I'd + advise you set $0C to zero to enable a 256x192 display, which is the + normal SMS resolution. The Genesis always generates a 224 line picture; + the 192 lines in SMS mode are centered in the middle of the screen. + + I could not get the top row or right column lock features to work while + in SMS mode. Apart from this bit, the M3 pin on the cartridge connector + also puts the machine into SMS mode, which may fully enable all video + features. + + Bit 0 has an interesting effect; horizontal scrolling is disabled, and + it would almost seem like the horizontal scroll value modifies the + horizontal retrace / blanking / sync start and end positions around; the + middle of the display is blanked out, and will scroll left or right. + (note the blanked area scrolls - not the background) Moving too far in + one direction, so the blanked area is offscreen, totally corrupts the + display. + + Combining bits 7 (TMS9918 mode) and 2 (SMS mode) have no effect. + + $02 - Pattern Name Table Address for Scroll A + --------------------------------------------- + + Bits 5-3 of this register correspond to bits A15-A13 of the name table + address for plane A. + + $03 - Pattern Name Table Address for Window + --------------------------------------------- + + Bits 5-1 of this register correspond to bits A15-A11 of the name table + address for the window. + + In 40-cell mode, A11 is always forced to zero. + + $04 - Pattern Name Table Address for Scroll B + --------------------------------------------- + + Bits 2-0 of this register correspond to bits A15-A11 of the name table + address for plane B. + + $05 - Sprite Attribute Table Base Address + ----------------------------------------- + + Bits 6-0 of this register correspond to bits A15-A09 of the sprite + attribute table. + + In 40-cell mode, A09 is always forced to zero. + + $07 - Backdrop Color + -------------------- + + Bits 5-0 of this register select a palette entry to be used as the + backdrop color. + + The backdrop color is displayed in the following places: + + - The overscan area around the physical display + - Any line where the display enable bit has been cleared + + You can think of the display being filled with the backdrop color, and + then everything else being drawn over it. Any gaps where no pixels were + drawn will show the backdrop color. + + Even though palette entries 00h, 10h, 20h, and 30h cannot be used by + any patterns, these entries can be used for the backdrop color. + + $0A - H Interrupt Register + -------------------------- + + Bits 7-0 specify the value to be loaded in the counter; for complete + details see the "Interrupts" section. + + $0B - Mode Set Register No. 3 + ----------------------------- + + d7 - 0 (No effect) + d6 - 0 (No effect) + d5 - 0 (No effect) + d4 - 0 (No effect) + d3 - IE2 + d2 - VSCR + d1 - HSCR + d0 - LSCR + + Bit 3 will enable external interrupts, caused by the TH pin being set + to input mode and having the TH interrupt enable bit set. (Both of these + are controlled by the Genesis' I/O registers) + + Bit 2 selects between full screen vertical scrolling when clear, and + 2-cell column based vertical scrolling when set. + + Bits 1 and 0 determine how the VDP will parse the horizontal scroll table + when it is rendering display lines: + + HSCR LSCR + 0 0 - Full screen scroll + 0 1 - Line scroll + 1 0 - Cell scroll + 1 1 - Line scroll + + $0C - Mode Set Register No. 4 + ----------------------------- + + d7 - RS0 + d6 - 0 (No effect) + d5 - ? (See notes) + d4 - 0 (No effect) + d3 - S/TE + d2 - LSM1 + d1 - LSM0 + d0 - RS1 + + LSMx table: + 00 : No interlace + 01 : Interlace (Normal resolution) + 10 : No interlace + 11 : Interlace (Double resolution) + + RSx table: + 00 : Display is 32 cells wide + 01 : Display is 40 cells wide + 10 : Invalid display setting + 11 : Display is 40 cells wide + + Changes made to LSM0, LSM1 do not take effect until the display is no + longer in the active scan period. + + All other bits can be modified with changes taking effect immediately at + any point in the display frame. + + You should normally set the RSx bits to 00b or 11b. The unlicensed version + of Populous sets up a 40 cell display with a setting of 01b - technically + valid, but the display is distorted a bit. + + Bit 5 seems to affect the display when used in conjunction with RS0, but + only in the same way as the display appears when using a setting of 01b. + I've tried every combination of bit 6 along with the RSx bits, and the + physical width of the display was never different from 32 or 40 cells. + + $0D - H Scroll Data Table Base Address + -------------------------------------- + + Bits 5-0 of this register correspond to bits A15-A10 of the horizontal + scroll data table address. + + $0F - Auto Increment Data + ------------------------- + + Bits 7-0 specify the value to be added to the VDP's address register + after every read or write to the data port. + + A setting of zero means the address register is not incremented. + + $10 - Scroll Size + ----------------- + + d7 - 0 (No effect) + d6 - 0 (No effect) + d5 - VSZ1 + d4 - VSZ0 + d3 - 0 (No effect) + d2 - 0 (No effect) + d1 - HSZ1 + d0 - HSZ0 + + This register defines the size of the name tables for planes A and B. + Both fields can be set to the following values: + + 0 0 32 cells + 0 1 64 cells + 1 0 Invalid + 1 1 128 cells + + If the HSZ bits are set to 10b (invalid), then the first row of the name + table is shown for every line of the display. + + + $11 - Window H Position + ----------------------- + + d7 - RIGT + d6 - 0 (No effect) + d5 - 0 (No effect) + d4 - WHP5 + d3 - WHP4 + d2 - WHP3 + d1 - WHP2 + d0 - WHP1 + + This register will affect the window shown on the current line, if + the current line does not fall into the vertical range specified by + register $12. + + The WHP field defines the horizontal range of the window, in units + of two cells. (16 pixels) + + Setting the WHP field to zero disables the window. + Any nonzero value indicates how many 2-cell columns wide the window + plane is. (0=no window, 1=2 cells, 2=4 cells, 3=6 cells, etc.) + + When RIGT=0, the window is shown from column zero to the column + specified by the WHP field. + + For instance, if RIGT=0 and WHP=4, the window is displayed on columns + zero up to (and including) column seven. + + When RIGHT=1, the window is shown from the column specified in the WHP + field up to the last column in the display meaning column 31 or 39 + depending on the screen width setting. + + For instance, if RIGT=1 and WHP=4, the window is displayed on columns + eight up to (and including) column 31 or 39. + + Having WHP set to zero and RIGHT=1 is a legal setting; it means the + window is shown from column zero up to the last column in the display, + meaning the entire line is taken up by the window plane. + + There is a bug in the window processing. This occurs when the window is + showing partially on the left side of the screen, specifically when + the VDP is drawing the 2-cell column from plane A that immediately proceeds + the last column the window was drawn on. (i.e. WHP+1) + + If the lower four bits of the horizontal scroll value for the current + scan line are zero, then the name table attribute data for the current + column are fetched correctly. + + If the lower four bits of the horizontal scroll value for the current + scan line are nonzero, the name table attribute data are fetched from + next column. (WHP+2) + + In effect, you'll have N columns of the window plane, 1 column that has + identical patterns as the next column, then the remainder of the display + is drawn correctly. + + Here's a diagram to illustrate this: + w = window tiles + abc = tile columns + + D3-D0 of scroll value == 0 + wwwwwwwwwwwwwwwwaabbccddeeffgghh + + D3-D0 of scroll value != 0 + wwwwwwwwwwwwwwwwbbbbccddeeffgghh + + This register can be modified with changes taking effect immediately at + any point in the display frame. + + Plane A is not shown in any column where plane W is shown; they cannot + overlap. + + $12 - Window V Position + ----------------------- + + d7 - DOWN + d6 - 0 (No effect) + d5 - 0 (No effect) + d4 - WVP4 + d3 - WVP3 + d2 - WVP2 + d1 - WVP1 + d0 - WVP0 + + If the current scanline does not fall within the range specified by + register $12, then register $11 determines where the window is shown + for the remainder of the display. + + The WVP field defines the vertical range of the window, in units + of eight lines. + + Setting the WVP field to zero disables the window. + Any nonzero value indicates a vertical range for the window to appear + in. (0=no window, 1=lines 0-$7, 2= lines 0-$F, 3= lines 0-$17, etc.) + + When DOWN=0, the window is shown from line zero to the line specified + by the WVP field. + + For instance, if DOWN=0 and WVP=4, the window is displayed on lines + zero up to (and including) line $1F. + + When DOWN=1, the window is shown from the line specified in the WVP + field up to the last line in the display. + + For instance, if DOWN=1 and WVP=4, the window is displayed on lines $1F + up to (and including) the last line in the display. + + Having WVP set to zero and DOWN=1 is a legal setting; it means the + window is shown from line zero up to the last line in the display, + meaning the entire screen is taken up by the window plane. + + Plane A is not shown in any line where plane W is shown; they cannot + overlap. + + ---------------------------------------------------------------------------- + 18.) VDP Pinout + ---------------------------------------------------------------------------- + + This is applicable to the 315-5313 chip used in the early versions of + the original Genesis model. + + 1-8 - SD0-SD7 (VRAM data bus) + 10 - SE0 (VRAM) + 11 - SC (VRAM) + 12 - RAS (VRAM) + 13 - CAS (VRAM) + 15 - WE0 (VRAM) + 16 - OE (VRAM) + 17 - GND + 26 - AGC + 27 - R (Red video output) + 28 - G (Green video output) + 29 - B (Blue video output) + 30 - AVC + 31-38 - AD0-AD7 (VRAM address bus) + 39 - YS + 40 - SPA/8 + 41 - VSYNC (Vertical sync) + 42 - C-SYNC (Composite sync) + 43 - HSYNC (Horizontal sync) + 44 - HL (from control port HL pin) + 45 - SEL0 (from M3 on cartridge connector - forces mode 4 graphics) + 46 - PAL (PAL / NTSC select) + 47 - RESET (68000) + 49 - CLK1 (68000) + 48 - SEL1 (?) + 50 - SBCR + 51 - CLK0 + 52 - MCLK (53.64165 MHz) + 53 - EDCLK + 54 - VDD + 54-70 - CD0-CD15 (68000 data bus) + 71-93 - CA0-CA22 (68000 address bus (A23-A1)) + 94 - AVS + 95 - PSG (SN76489 PSG sound output) + 97 - GND + 98 - INT + 99 - BR + 100 - BGAK + 101 - BG + 102 - MRE0 + 103 - INTAK + 104 - IPL1 (68000) + 105 - IPL2 (68000) + 106 - IREQ + 107 - RD (68000) + 108 - WR (68000) + 109 - MI + 110 - AS (68000) + 111 - UDS (68000) + 112 - LDS (68000) + 113 - R/W + 114 - DTAK (68000) + 115 - UWR (68000) + 116 - LWR (68000) + 118 - CAS0 (VRAM) + 117 - OE0 (VRAM) + 119 - RAS0 (VRAM) + 128 - VDD + + ============================================================================ + + To-do test list + + - Last column wrapping (40 cell mode only?) + - Columns being offset by the horizontal scroll value (d3-d0) + - How line scrolling is managed in interlace mode 2 + - How sprite Y positions and VSRAM values are used in interlace mode 2 + - Vertical interrupt supression via line interrupts + - Reverse sprite stage in CV + - Mid frame sprite table changes (can't be done I think; sprite table + changes aren't seen by VDP, though changing the sprite table address + will cause a switch) + - Large sprite pattern overflow + - Result of copy and fill operations overflowing + - Result of copy operations overlapping + - Use of HV counter latch in the 6-in-1 pak. + - Source and length registers being updated during DMA + - Confirm invalid code use + - Default status flag settings + - Sprite collisions and overflows outside of the physical display area + - How many times a sprite collision and overflow can occur (per line/frame?) + + And for timing, based on the HV counter: + + - Vertical counter increment + - Horizontal blanking flag clear and set + - Vertical blank flag clear and set + - Horizontal interrupt occurance + - Vertical interrupt occurance + - Invalid periods for vertical counter + - Invalid periods for horizontal counter (test with 6-in-1 pak) + - Start/stop of physical display (use sprite collision on either edge)