SNES hardware notes by Charles MacDonald WWW: http://cgfm2.emuviews.com Unpublished work Copyright 2003 Charles MacDonald This document is in a very preliminary state and is subject to change. Most everything within has been tested and verified on a SNES but please be aware that my testing methods or interpretations of results could be flawed. I can't guarantee that everything is 100% accurate. Last updated 09/17/03 [09/17/03] - Added the cartridge information section. - Added some details on the screen layout. [08/27/03] - Fixed some typos - Added CGRAM information - Added notes about valid times to access OAM [08/25/03] - Added some sprite information [08/22/03] - Added mouse information - Added multitap information - Changed joypad section [08/20/03] - Initial release Table of contents 1. Various notes 2. CGRAM 3. Sprites 3. Hardware version registers 4. I/O hardware 5. Register reference 6. Cartridge information 7. Assistance needed 8. Credits and acknowledgements 9. Disclaimer ---------------------------------------------------------------------------- Various notes ---------------------------------------------------------------------------- V-Blank occurance flag - Bit 7 of $4212 is set at line $00E1 and cleared at line $0000 in 224-line mode. - Bit 7 of $4212 is set at line $00F0 and cleared at line $0000 in 239-line mode. Joypad automatic scanning flag - Bit 0 of $4212 is set at line $00E1 and cleared at line $00E4 in 224-line mode. - Bit 0 of $4212 is set at line $00F0 and cleared at line $00F3 in 239-line mode. Non-maskable interrupts According to the 65816 manual, the NMI signal is an edge-sensitive input, so that only a high to low transition on the NMI pin will cause an interrupt to occur. Leaving it high, low, or having a low to high transition has no effect. I'm going to assume the PPU normally holds NMI high and brings it low to trigger an interrupt. The PPU will pull NMI low at line $00E8 in 224-line mode or line $00F7 in 239-line mode. It will remain low until either $4210 is read, or a new frame starts, at which point the PPU will bring NMI high again. The inverted state of the NMI signal from the PPU can be read through bit 7 of $4210, where 0= no NMI has been requested, 1= an NMI is pending. After reading this register, the PPU resets the NMI signal by pulling it high. Bit 7 of $4200 doesn't affect how the PPU manages NMIs at all, it is just a gate between the NMI output of the PPU and the NMI input of the CPU. When set, NMIs can be generated. When cleared, the CPU ignores the state of the NMI pin. Here are some details of specific situations: When there is a pending NMI, toggling bit 7 of $4200 does not create any additional interrupts. Bit 7 of $4210 will be set in the NMI routine when it executes. After the NMI routine finishes, bit 7 will remain set (assuming $4210 wasn't read) until the start of the next frame. This will not cause more NMIs to occur as they are only triggered by high-to-low transitions, having the NMI pin remain low does not do anything. Bit 7 of $4210 reflects the NMI status independantly of bit 7 of $4200. Interlaced display When bit 0 of $2133 is set, the screen becomes interlaced regardless of the BG mode setting. When the screen is interlaced, the following applies: - For BG modes 0,1,2,3,4,7 each line of the background is repeated in the even and odd frames for single-density interlace. (224 or 239 lines shown) - For BG modes 5,6 each line of the background is unique for the even and odd frames for double-density interlace. (448 or 478 lines shown) Screen layout For an NTSC non-interlaced display, each frame consists of 262 lines. Depending on the screen height, these lines are divided into the following groups: Section 224-line mode 239-line mode Active display 224 239 Bottom blanking 12 15 Vertical sync 3 3 Top blanking 23 5 Total 262 262 Active display is the portion of the screen where graphics are displayed. Bottom blanking is the bottom border after the active display shown at the very bottom of the display. Lines are filled with black. Vertical sync is the period between the bottom and top borders which is off-screen. Lines are filled with a darker black color than in the blanking areas. Top blanking is the border after the vertical sync period shown at the very top of the display. Lines are filled with black. ---------------------------------------------------------------------------- CGRAM ---------------------------------------------------------------------------- Overview The PPU has 512 bytes of on-chip RAM called CGRAM which holds palette data. CGRAM is divided into 256 2-byte entries that define a single color. Each entry has the following format: MSB LSB -bbbbbgggggrrrrr b = Blue component (0=black, 31=bright) g = Green component (0=black, 31=bright) r = Red component (0=black, 31=bright) - = Unused bit. The background can use the first 128 colors in BG modes 0,1,2,5,6, and all 256 colors in BG modes 3,4,7 when not in direct color mode. Sprites always use the latter 128 colors. Specific details about palette use and selection for each mode will be described later. The PPU provides several registers for using CGRAM: $2121 - CGRAM address $2122 - CGRAM data port (write) $213B - CGRAM data port (read) CGRAM access The PPU has a 9-bit address register which gives a byte offset into CGRAM. Writing to $2121 loads the CPU data into bits 8-1 of the address register and clears bit 0, forcing an even address to be set. Each time $213B is read, the byte at the current offset pointed to by the address register is returned to the CPU, and the address register is incremented by one. Each time $2122 is written to the address register is incremented by one. If the address register is even during a write, the CPU data is stored in a latch. If the address register is odd, the latched data becomes the LSB and the new data written becomes the MSB of a 16-bit word. This word is written to the current address, with bit 0 of the address register ignored. The address register will wrap from $01FF to $0000 due to reading $213B or writing to $2122. You can mix reads and writes freely. Valid access times When the screen is forcibly blanked or in the V-Blank period, CGRAM can be read and written. I haven't tested access during H-Blank yet. Here are my observations about CGRAM access during the active display period: - Writing to CGRAM always results in the last word written to the data port being written to address 0,1 regardless of the address register setting. You could think of address bits 8-1 as always being fixed to zero during this time. - Reading from CGRAM returns a random mix of bytes from CGRAM and data that wasn't stored in CGRAM. The address register has no effect on where the data comes from. - When the screen is turned on, the previously set value in the address register not changed. Following reads or writes with the screen off affect the address originally selected. CGRAM access examples Here are some examples of unexpected behavior. Assume CGRAM contains the bytes $AA, $BB, $CC, $DD at address $0000 for each test: - Set address to $0000 - Write $45 CGRAM is not updated, and the LSB latch contains $45 - Set address to $0000 - Read $2138 - Write #$45 The bytes $CC, $45 are written to address $0000. $CC was the last value in the LSB latch, and a single byte write triggers a write to CGRAM as the previous read made the address register odd. ---------------------------------------------------------------------------- Sprites ---------------------------------------------------------------------------- The PPU can manage up to 128 sprites. Sprites use 16-color 8x8 tiles, the same as used by the backgrounds. The sprite size can range from 1x1 tiles up to 8x8 tiles, with several variations in between. The attributes for each sprite are stored in 544 bytes of on-chip RAM called OAM or "Object Attribute Memory". The OAM can be thought of having two sections, a 512-byte table that has 128 x 4-byte entries, and a 32-byte table used as 128 x 2-bit entries. The PPU provides several registers for sprite control: $2101 - OAM control $2102 - OAM address LSB $2103 - OAM address MSB $2104 - OAM data port (write) $2138 - OAM data port (read) The OAM control register defines various aspects about the sprites: D7 : Sprite size, bit 2 D6 : Sprite size, bit 1 D5 : Sprite size, bit 0 D4 : Sprite name offset, bit 1 D3 : Sprite name offset, bit 0 D2 : Sprite pattern table base, bit 2 D1 : Sprite pattern table base, bit 1 D0 : Sprite pattern table base, bit 0 The sprite pattern table is where the tile data for sprites is fetched from. The table is 16K in size and can be positioned on 16K boundaries. Bits 2-0 of this register correspond to bits 16-14 of the VRAM address. As there is only 64K of VRAM, bit 2 has no effect. Pattern data read from $10000-$1FFFF is instead read from $00000-$0FFFF due to mirroring. When a sprite has bit 8 of it's name field set so that it reads patterns out of the upper 8K of the 16K table (tiles 256-511), bits 4, 3 of this register are added to bits 14 and 13 of the VRAM address. If the resulting address is bigger than $10000 then data is read from $00000 onwards due to mirroring. The same holds true if the address is bigger than $20000, due to wrapping. The sprite sizes are as follows: D7 D6 D5 Small Large 0 0 0 8x8 16x16 0 0 1 8x8 32x32 0 1 0 8x8 64x64 0 1 1 16x16 32x32 1 0 0 16x16 64x64 1 0 1 32x32 64x64 1 1 0 16x32 32x64 1 1 1 16x32 32x32 The last two settings are undocumented but appear to function normally. Overview The CPU interface to the OAM appears as a 1024-byte array. Here's a memory map: $0000-$01FF : 512 bytes, used as 128 x 4-byte entries $0200-$03FF : 32 bytes, mirrored every 32 bytes (so mirrored 16 times) Reading and writing from the mirrored areas are valid. OAM access The PPU has a 10-bit address register which gives a byte offset into OAM. Writing to $2102 will load the CPU data into bits 8-1 of the address register. Writing to $2103 will load bit 0 of the CPU data into bit 9 of the address register. Writing to $2102 or $2103 will clear bit 0 of the address register so an even address is always selected. You can write to $2102 and $2103 in any order, or write to just one or the other to update part or all of the address. Each time $2138 is read, the byte at the current offset pointed to by the address register is returned to the CPU, and the address register is incremented by one. Each time $2104 is written to the address register is incremented by one. If the address register is even during a write, the CPU data is stored in a latch. If the address register is odd, the latched data becomes the LSB and the new data written becomes the MSB of a 16-bit word. This word is written to the current address, with bit 0 of the address register ignored. This only affects writing to offsets $0000-$01FF. The 32 byte table at $0200-$03FF will be updated for a write to even or odd addresses. Writes to even addresses still update the LSB latch, however. The address register will wrap from $03FF to $0000 due to reading $2138 or writing to $2104. You can mix reads and writes freely. Valid access times When the screen is forcibly blanked or in the V-Blank period, OAM can be read and written. I haven't tested access during H-Blank yet. It would seem that the address register is used for some internal operation during the active display period, which involves incrementing it. Here are my observations: - Writing to OAM during this time results in the data being written to consecutively larger addresses, starting at a random offset and with a random amount of skipped bytes between the data. The address register has no effect on where the data goes. - Reading from OAM returns data from consecutively larger addresses, starting at a random offset and with a random amount of skipped bytes between the data. The address register has no effect on where the data goes. - Setting the address register to a known value and waiting a few scanlines with the screen turned on results in data being read or written to a larger address than the one originally set. - Writing to the address register on the same scanline where a sprite is being displayed has no effect on the sprite. I would assume during the active display period, the address register can't be updated by the CPU as it is being used by the PPU exclusively. OAM access examples Here are some examples of unexpected behavior. Assume OAM contains the bytes $AA, $BB, $CC, $DD at address $0000 for each test: - Set address to $0000 - Write $45 OAM is not updated, and the LSB latch contains $45 - Set address to $0000 - Read $2138 - Write #$45 The bytes $CC, $45 are written to address $0000. $CC was the last value in the LSB latch, and a single byte write triggers a write to OAM as the previous read made the address register odd. - Set address to $0000 - Write #$12 - Write #$00 to $2103 - Write #$34 OAM is not updated. The second write only loads the LSB latch as the write to $2103 cleared bit 0 of the address register. ---------------------------------------------------------------------------- Hardware version registers ---------------------------------------------------------------------------- Here are the version register return values and chip markings for my original model NTSC SNES: Register Value Chip $4210 $01 Nintendo S-CPU 5A22-01 $213E $01 Nintendo S-PPU1 5C77-01 $213F $01 Nintendo S-PPU2 5C78-01 ---------------------------------------------------------------------------- I/O hardware ---------------------------------------------------------------------------- The SNES has two 7-pin joypad ports. Here's a diagram of the faceplate of the SNES to show the pin configuration: 1P port 2P port (Power light) ( o o o | o o o o ] [ o o o o | o o o ) 7 6 5 4 3 2 1 1 2 3 4 5 6 7 Pin # Description S-CPU pin (1P) S-CPU pin (2P) Pin 1 +5V n/a n/a Pin 2 Output strobe 35 36 Pin 3 Output 37 37 (common between both ports) Pin 4 Serial input 1 32 28 Pin 5 Serial input 2 33 27 Pin 6 Bidirectional 25 26 Pin 7 Ground n/a n/a Each pin is accessible through the various hardware registers as follows: 1P port - Read $4016 to pulse pin 2. - Writing to bit 0 of $4016 controls pin 3. - Reading bit 0 of $4016 returns data from pin 4. - Reading bit 1 of $4016 returns data from pin 5. - Pin 6 is connected to bit 6 of $4201 (WRIO) and $4213 (RDIO). 2P port - Read $4017 to pulse pin 2. - Writing to bit 0 of $4016 controls pin 3. - Reading bit 0 of $4017 returns data from pin 4. - Reading bit 1 of $4017 returns data from pin 5. - Pin 6 is connected to bit 7 of $4201 (WRIO) and $4213 (RDIO). 2P pin 6 is also connected to S-PPU2 pin 29. This is most likely the external input signal that can be used to latch the H/V counter. A lightgun such as the Super Scope or Konami Justifier would use pulse pin 6 of the 2P port to make the PPU2 latch the H/V counter when it detects the raster beam. The second serial input from pin 5 and bidirectional pin 6 are unused by the joypad and mouse. The Hudson Super Multitap may be the only peripheral to use them, see the multitap section for more details. The standard way most peripherals work is to write 1 then 0 to bit 0 of $4016 to reset the devices in the 1P and 2P ports. You can then read bit 0 of $4016 and $4017 multiple times to return data serially, starting with the MSB down to the LSB. I/O port The SNES is described as having an 8-bit bidirectional I/O port. I don't know if this physically corresponds to the expansion port on the bottom of the control deck, or if the CPU just has an I/O port built in and some or all of the port pins are used. Writing to $4201 (WRIO) sets the data to be output through the I/O port. Any bit that is also set to 1 will allow the corresponding pin to act as an input, and data from that pin can be read through $4213 (RDIO). The only uses I know of for the I/O port are as follows: - Any value written to $4201 can be read back through $4213. - As bit 7 of $4201 controls pin 6 of the 2P port, which is also shared with the external signal input of the PPU to latch the H/V counter, writing 1 then 0 to bit 7 of $4201 will latch the H/V counter. While bit 7 is set to 0, the latch will always hold the same value and reading $2137 will not change the latched value. If you want to poll the H/V counter using $2137, set bit 7 back to 1 for it to work properly. - Pin 6 of the 1P or 2P port is used as an output to control the Hudson Super Multitap. See the multitap section for more details. ---------------------------------------------------------------------------- Automatic reading ---------------------------------------------------------------------------- The SNES has a feature to automatically read the four serial input pins and store them into a set of registers during V-Blank. This can be done without the CPU having to manually write and read $4016 / $4017, saving time for other tasks. When bit 0 of $4200 is set, at the start of V-Blank (depending on the screen height) the SNES will automatically do the following steps: - Write 1 then 0 to bit 0 of $4016. - Read $4016 and $4017 sixteen times, storing the return values from bits 0 and 1 into eight registers like so: - 16 bits from bit 0 of $4016 are stored in $4218 (LSB) and $4219 (MSB) - 16 bits from bit 1 of $4016 are stored in $421C (LSB) and $421D (MSB) - 16 bits from bit 0 of $4017 are stored in $421A (LSB) and $421B (MSB) - 16 bits from bit 1 of $4017 are stored in $421E (LSB) and $421F (MSB) This process takes three scanlines to complete. Bit 0 of $4212 shows the scanning status, where 1= the SNES is still reading data, 0= the SNES has finished or automatic scanning was not enabled. The use I've seen in games and demos is to wait for this bit to be set, and then cleared in the NMI handler. ---------------------------------------------------------------------------- Hudson Super Multitap ---------------------------------------------------------------------------- The multitap plugs into the 1P or 2P port. It has four connectors to plug additional joypads into, and has a switch for selecting a multiplayer or compatability mode. In compatability mode (switch = 2P) the joypad plugged in to connector #1 works like a standard pad. All remaining connectors are ignored, pin 6 is ignored in terms of selecting which set of joypad data to return, and no extra data is returned in the second serial input. In multiplayer mode (switch = 3P-5P) the first serial input returns data from the joypad in connector #1 or #3, and the second serial input returns data from the joypad in connector #2 or #4. Pin 6 of the 1P or 2P port is used to select connectors #1 and #3 when set to 1, or #2 and #4 when set to 0. ---------------------------------------------------------------------------- SNES joypad ---------------------------------------------------------------------------- The SNES joypad uses two 4021 ICs, which are 8-stage static shift registers. They are cascaded together to form a 16-bit shift register that stores the state of the directional pad and buttons, allowing the SNES to read out the state of the joypad serially. The button states will be loaded into the shift register when bit 0 of $4016 is set to 1 and then 0. This happens to both control pads as they share a common pin. Each time $4016 or $4017 is read, the shift register for the 1P or 2P pad advances by one, outputting a bit which can be read in bit 0 of $4016 or $4017 respectively. The tail end of the shift register is filled with a one on each shift. After the sixteenth time $4016 or $4017 has been read, all consecutive reads will return one due to the shift register being completely filled with ones. This will go on forever until the shift register is loaded again by writing 1 then 0 to $4016. If at any time $4016 is left at 1, reading either joypad will always return the state of the first input, which is the 'B' button. This won't stop until $4016 is set to zero again. Here is the order of button states read out through $4016 or $4017: Read 1 - Button B Read 9 - Button A Read 2 - Button Y Read 10 - Button X Read 3 - Button Select Read 11 - Button L Read 4 - Button Start Read 12 - Button R Read 5 - Up Read 13 - '0' Read 6 - Down Read 14 - '0' Read 7 - Left Read 15 - '0' Read 8 - Right Read 16 - '0' All reads after read 16 will return 1. All buttons are 1= pressed, 0= released. If no joypad is plugged in, then zero is always read from $4016 or $4017. A game can check if a joypad is connected by seeing if any reads beyond the 16th one return '1', otherwise there is no joypad. As far as I can tell, the joypad does not return any data through pin 5 (which always returns zero) and any setting of pin 6 will not affect the joypad operation. ---------------------------------------------------------------------------- SNES mouse ---------------------------------------------------------------------------- The SNES mouse works in a similar fashion to the joypad. It has a custom 18-pin chip called the "SFM1" which returns data about the mouse status serially to the SNES. Writing 1, then 0 to bit 0 of $4016 will reset the SFM1 and subsequent reads from $4016 or $4017 (depending on which port the mouse is plugged into) will return the mouse state data. Leaving bit 0 of $4016 set to 1 will result in zero always being read back. The mouse data is as follows: Read 1 - '0' Read 17 - Y sign Read 2 - '0' Read 18 - Y movement bit 6 (?) Read 3 - '0' Read 19 - Y movement bit 5 Read 4 - '0' Read 20 - Y movement bit 4 Read 5 - '0' Read 21 - Y movement bit 3 Read 6 - '0' Read 22 - Y movement bit 2 Read 7 - '0' Read 23 - Y movement bit 1 Read 8 - '0' Read 24 - Y movement bit 0 Read 9 - Right button Read 25 - X sign Read 10 - Left button Read 26 - X movement bit 6 (?) Read 11 - '0' Read 27 - X movement bit 5 Read 12 - '0' Read 28 - X movement bit 4 Read 13 - '0' Read 29 - X movement bit 3 Read 14 - '0' Read 30 - X movement bit 2 Read 15 - '0' Read 31 - X movement bit 1 Read 16 - '1' Read 32 - X movement bit 0 All reads after read 32 will return 1. The left/right buttons are 1= pressed, 0= released. The Y and X sign are 1= up/left movement, 0= down/right movement. The sign bits do not change until the mouse is moved in a opposite direction. So moving the mouse up, and leaving it stationary would keep the Y sign bit set to 1. The Y and X movement fields indicate how rapidly the mouse was moved in a particular direction. This is usually $00-$1F, but extremely rapid movements can yield higher values. I haven't been able to get values large enough to indicate there is a seventh movement bit, but there may likely be one. Both fields are zero when there is no movement. As far as I can tell, the mouse does not return any data through pin 5 (which always returns zero) and any setting of pin 6 will not affect the mouse operation. ---------------------------------------------------------------------------- Register reference ---------------------------------------------------------------------------- $2180 - WRAM data port $2181 - WRAM offset (bits 7-0 are offset bits 7-0) $2182 - WRAM offset (bits 7-0 are bits 15-8) $2183 - WRAM offset (bit 0 is offset bit 16, bits 7-1 are unused) Registers $2181-$2183 define a 17-bit offset in WRAM. Reading or writing $2180 will return a byte from or write a byte to WRAM, and automatically increment the WRAM offset by one. The offset wraps from $01FFFF to $000000. Reading $2180, $2181, or $2183 returns the last value on the data bus, which is usually the last byte of the opcode fetched. For example, this value would be $21 for 'lda $2181', or $00 for 'lda [$00]' when the pointer at $00 is $2181. ---------------------------------------------------------------------------- Cartridge information ---------------------------------------------------------------------------- Cartridge pinout Solder side Component side MCK - 01 32 - /RAMSEL EXPAND - 02 33 - REFRESH PA6 - 03 34 - PA7 /PARD - 04 35 - /PAWR GND - 05 36 - GND A11 - 06 37 - A12 A10 - 07 38 - A13 A9 - 08 39 - A14 A8 - 09 40 - A15 A7 - 10 41 - A16 A6 - 11 42 - A17 A5 - 12 43 - A18 A4 - 13 44 - A19 A3 - 14 45 - A20 A2 - 15 46 - A21 A1 - 16 47 - A22 A0 - 17 48 - A23 /IRQ - 18 49 - /ROMSEL D0 - 19 50 - D4 D1 - 20 51 - D5 D2 - 21 52 - D6 D3 - 22 53 - D7 /RD - 23 54 - /WR CIC0 - 24 55 - CIC1 CIC2 - 25 56 - CIC3 /RESET - 26 57 - SYSCK +5V - 27 58 - +5V PA0 - 28 59 - PA1 PA2 - 29 60 - PA3 PA4 - 30 61 - PA5 SOUND-L - 31 62 - SOUND-R Pin assignments A23-0 - CPU address bus D7-0 - CPU data bus /WR - CPU write strobe /RD - CPU read strobe /IRQ - CPU IRQ input. Allows on-cart hardware to interrupt the CPU. /RESET - When the system is reset (power-up or hard reset) this goes low. Could be used to reset additional on-cart hardware. /RAMSEL - Goes low on accesses to WRAM at the following addresses: 00-3F:0000-1FFF 80-BF:0000-1FFF 7E-7F:0000-FFFF /ROMSEL - Goes low on access to cartridge ROM at the following addresses: 00-3F:8000-FFFF 40-7D:0000-FFFF 80-BF:8000-FFFF C0-FF:0000-FFFF PA7-0 - Address bus for $2100-$21FF range in banks $00-$3F/$80-$BF (B-Bus) /PAWR - Write strobe for B-Bus /PARD - Read strobe for B-Bus MCK - 21.47727 MHz master clock SYSCK - Unknown, is an output from the CPU. SOUND-L - Audio input to be mixed with left channel output SOUND-R - Audio input to be mixed with right channel output THROUGH - Connected to pin 24 of the expansion port. REFRESH - Unknown, is an output from the CPU also connected to WRAM. This is most likely to manage DRAM refresh. CIC3-0 - To CIC chip on cartridge Details For more information about the CIC chip, please see the following: - U.S. Patent no. 4,799,635 (NES specific) - http://home.freeuk.com/markk/Consoles/SNES_Lockout.txt The only hardware I know of which uses the two sound input pins is the Super Gameboy and Super Gameboy 2. The SNES has two address busses, the A-Bus which is used by the CPU, ROM, WRAM, etc. and the B-Bus which is used by the PPU1, PPU2, APU I/O ports, and WRAM. When the SNES does DMA, it can transfer data from the A-Bus to the B-Bus or vice-versa, but not to the same bus. This holds true even for WRAM, which is connected to both the A-Bus and B-Bus. I would guess the B-Bus signals are brought out to the cartridge connector so any on-cart hardware could map it's own registers within that region, allowing for DMA from the A-Bus to it. Exactly what range of B-Bus addresses are open for expansion purposes is unknown. Cartridge information Here's some information about several cartridges I've examined: Name: Lagoon Board: SHVC-1A3B-12 Type: LoROM / 16 megabits / 8K SRAM This cartridge has a 74LS139 for address decoding and a 8K SRAM chip. 00-1F:8000-FFFF : Program ROM 20-3F:8000-FFFF : Unmapped 40-6F:0000-FFFF : Unmapped 70-7D:0000-FFFF : SRAM 7E-7F:0000-FFFF : Work RAM 80-9F:8000-FFFF : Program ROM A0-BF:8000-FFFF : Unmapped C0-EF:0000-FFFF : Unmapped F0-FF:0000-FFFF : SRAM - A23 and A15 are ignored, so banks $80-FF are a mirror of $00-7F. - SRAM is mirrored repeatedly in the areas it's assigned to. - When accessing an unmapped region, neither the ROM or SRAM are enabled. Name: Pilotwings Board: SHVC-1BON-02 Type: LoROM / 8 megabits / DSP-1 This cartridge has a 74LS139 for address decoding and a NEC uPD77C25 DSP which Nintendo labels as the "DSP-1" custom chip. It also has a oscillator and 74HCU04 to provide a clock signal, but I don't know what speed the DSP actually runs at. 00-1F:8000-FFFF : Program ROM 20-2F:8000-FFFF : Unmapped 30-3F:8000-BFFF : DSP data register (r/w) 30-3F:C000-FFFF : DSP status register (r/o) 40-7D:0000-FFFF : Unmapped 7E-7F:0000-FFFF : Work RAM 80-9F:8000-FFFF : Program ROM A0-AF:8000-FFFF : Unmapped 80-BF:8000-BFFF : DSP data register (r/w) 80-BF:C000-FFFF : DSP status register (r/o) C0-FF:0000-FFFF : Unmapped - A23 and A15 are ignored, so banks $80-FF are a mirror of $00-7F. - DSP pins INT, SCK, /SIEN, /SOEN are all tied to +5V and are unused. - When accessing an unmapped region, neither the ROM or DSP are enabled. Name: Killer Instinct Board: SHVC-1JON-20 Type: HiROM / 32 megabits The mask ROM socket on the PCB has the following pin assignments: +---\/---+ A20 -|01 36|- +5V A21 -|02 35|- A23 A17 -|03 34|- +5V A18 -|04 33|- /ROMSEL (ROM /CS) A15 -|05 32|- A19 A12 -|06 31|- A14 A7 -|07 30|- A13 A6 -|08 29|- A8 A5 -|09 28|- A9 A4 -|10 27|- A11 A3 -|11 26|- A16 A2 -|12 25|- A10 A1 -|13 24|- /RD (ROM /OE) A0 -|14 23|- D7 D0 -|15 22|- D6 D1 -|16 21|- D5 D2 -|17 20|- D4 GND -|18 19|- D3 +--------+ - A22 is unconnected. - This game uses a MX23C3201 4096Kx8 mask ROM. I can't find a datasheet for this chip, so I'm not sure what pin 35 (A23) is used for. It could be an inverted chip select so the ROM is only mapped to banks $40-$7E and $C0-$FF, but that's just a guess. ---------------------------------------------------------------------------- Assistance needed ---------------------------------------------------------------------------- If any games have a legitimate use of writing to OAM or reading OAM or CGRAM during the active display period, I'd like to hear about the details of how the data is used. So far it's been confirmed that Uniracers writes to OAM this way, maybe there are others. ---------------------------------------------------------------------------- Credits and acknowlegements ---------------------------------------------------------------------------- - ToToTek Multimedia for the Game Doctor SF7. (www.tototek.com) - neviksti for the SNES starter kit. (available at nesdev.parodius.com) - John Weidman, CaitSith2, neviksti, for the SNES schematic scans. - Gilligan for the SNES documentation. - Qwertie for the SNES documentation. - anomie for the post about SNES peripherals at the SNES9X development forum, pointing out errors, and suggesting tests. - Overload for clarifying some details about the mouse. - Chris MacDonald for testing and support. ---------------------------------------------------------------------------- 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.