Fullsnes - Nocash SNES Specs ---------------------------- Origin: https://problemkaputt.de/fullsnes.txt nocash SNES hardware specifications, extracted from no$sns v1.6 SNES Hardware Specifications --> SNES I/O Map --> SNES Memory --> SNES DMA Transfers --> SNES Picture Processing Unit (PPU) --> SNES Audio Processing Unit (APU) --> SNES Maths Multiply/Divide --> SNES Controllers --> SNES Cartridges --> SNES Hotel Boxes and Arcade Machines --> SNES Unpredictable Things --> SNES Timings --> SNES Pinouts --> CPU 65XX Microprocessor About --> About/Credits SNES I/O Map ------------ First some bytes 0000h..1FFFh - WRAM - Mirror of first 8Kbyte of WRAM (at 7E0000h-7E1FFFh) 2000h..20FFh - N/A - Unused PPU Picture Processing Unit (Write-Only Ports) 2100h - INIDISP - Display Control 1 8xh 2101h - OBSEL - Object Size and Object Base (?) 2102h - OAMADDL - OAM Address (lower 8bit) (?) 2103h - OAMADDH - OAM Address (upper 1bit) and Priority Rotation (?) 2104h - OAMDATA - OAM Data Write (write-twice) (?) 2105h - BGMODE - BG Mode and BG Character Size (xFh) 2106h - MOSAIC - Mosaic Size and Mosaic Enable (?) 2107h - BG1SC - BG1 Screen Base and Screen Size (?) 2108h - BG2SC - BG2 Screen Base and Screen Size (?) 2109h - BG3SC - BG3 Screen Base and Screen Size (?) 210Ah - BG4SC - BG4 Screen Base and Screen Size (?) 210Bh - BG12NBA - BG Character Data Area Designation (?) 210Ch - BG34NBA - BG Character Data Area Designation (?) 210Dh - BG1HOFS - BG1 Horizontal Scroll (X) (write-twice) / M7HOFS (?,?) 210Eh - BG1VOFS - BG1 Vertical Scroll (Y) (write-twice) / M7VOFS (?,?) 210Fh - BG2HOFS - BG2 Horizontal Scroll (X) (write-twice) (?,?) 2110h - BG2VOFS - BG2 Vertical Scroll (Y) (write-twice) (?,?) 2111h - BG3HOFS - BG3 Horizontal Scroll (X) (write-twice) (?,?) 2112h - BG3VOFS - BG3 Vertical Scroll (Y) (write-twice) (?,?) 2113h - BG4HOFS - BG4 Horizontal Scroll (X) (write-twice) (?,?) 2114h - BG4VOFS - BG4 Vertical Scroll (Y) (write-twice) (?,?) 2115h - VMAIN - VRAM Address Increment Mode (?Fh) 2116h - VMADDL - VRAM Address (lower 8bit) (?) 2117h - VMADDH - VRAM Address (upper 8bit) (?) 2118h - VMDATAL - VRAM Data Write (lower 8bit) (?) 2119h - VMDATAH - VRAM Data Write (upper 8bit) (?) 211Ah - M7SEL - Rotation/Scaling Mode Settings (?) 211Bh - M7A - Rotation/Scaling Parameter A & Maths 16bit operand(FFh)(w2) 211Ch - M7B - Rotation/Scaling Parameter B & Maths 8bit operand (FFh)(w2) 211Dh - M7C - Rotation/Scaling Parameter C (write-twice) (?) 211Eh - M7D - Rotation/Scaling Parameter D (write-twice) (?) 211Fh - M7X - Rotation/Scaling Center Coordinate X (write-twice) (?) 2120h - M7Y - Rotation/Scaling Center Coordinate Y (write-twice) (?) 2121h - CGADD - Palette CGRAM Address (?) 2122h - CGDATA - Palette CGRAM Data Write (write-twice) (?) 2123h - W12SEL - Window BG1/BG2 Mask Settings (?) 2124h - W34SEL - Window BG3/BG4 Mask Settings (?) 2125h - WOBJSEL - Window OBJ/MATH Mask Settings (?) 2126h - WH0 - Window 1 Left Position (X1) (?) 2127h - WH1 - Window 1 Right Position (X2) (?) 2128h - WH2 - Window 2 Left Position (X1) (?) 2129h - WH3 - Window 2 Right Position (X2) (?) 212Ah - WBGLOG - Window 1/2 Mask Logic (BG1-BG4) (?) 212Bh - WOBJLOG - Window 1/2 Mask Logic (OBJ/MATH) (?) 212Ch - TM - Main Screen Designation (?) 212Dh - TS - Sub Screen Designation (?) 212Eh - TMW - Window Area Main Screen Disable (?) 212Fh - TSW - Window Area Sub Screen Disable (?) 2130h - CGWSEL - Color Math Control Register A (?) 2131h - CGADSUB - Color Math Control Register B (?) 2132h - COLDATA - Color Math Sub Screen Backdrop Color (?) 2133h - SETINI - Display Control 2 00h? PPU Picture Processing Unit (Read-Only Ports) 2134h - MPYL - PPU1 Signed Multiply Result (lower 8bit) (01h) 2135h - MPYM - PPU1 Signed Multiply Result (middle 8bit) (00h) 2136h - MPYH - PPU1 Signed Multiply Result (upper 8bit) (00h) 2137h - SLHV - PPU1 Latch H/V-Counter by Software (Read=Strobe) 2138h - RDOAM - PPU1 OAM Data Read (read-twice) 2139h - RDVRAML - PPU1 VRAM Data Read (lower 8bits) 213Ah - RDVRAMH - PPU1 VRAM Data Read (upper 8bits) 213Bh - RDCGRAM - PPU2 CGRAM Data Read (Palette)(read-twice) 213Ch - OPHCT - PPU2 Horizontal Counter Latch (read-twice) (01FFh) 213Dh - OPVCT - PPU2 Vertical Counter Latch (read-twice) (01FFh) 213Eh - STAT77 - PPU1 Status and PPU1 Version Number 213Fh - STAT78 - PPU2 Status and PPU2 Version Number Bit7=0 APU Audio Processing Unit (R/W) 2140h - APUI00 - Main CPU to Sound CPU Communication Port 0 (00h/00h) 2141h - APUI01 - Main CPU to Sound CPU Communication Port 1 (00h/00h) 2142h - APUI02 - Main CPU to Sound CPU Communication Port 2 (00h/00h) 2143h - APUI03 - Main CPU to Sound CPU Communication Port 3 (00h/00h) 2144h..217Fh - APU Ports 2140-2143h mirrored to 2144h..217Fh WRAM Access 2180h - WMDATA - WRAM Data Read/Write (R/W) 2181h - WMADDL - WRAM Address (lower 8bit) (W) 00h 2182h - WMADDM - WRAM Address (middle 8bit) (W) 00h 2183h - WMADDH - WRAM Address (upper 1bit) (W) 00h 2184h..21FFh - Unused region (open bus) / Expansion (B-Bus) - 2200h..3FFFh - Unused region (open bus) / Expansion (A-Bus) - CPU On-Chip I/O Ports 4000h..4015h - Unused region (open bus) ;\These ports have - 4016h/Write - JOYWR - Joypad Output (W) ; long waitstates 00h 4016h/Read - JOYA - Joypad Input Register A (R) ; (1.78MHz cycles) - 4017h/Read - JOYB - Joypad Input Register B (R) ; (all other ports - 4018h..41FFh - Unused region (open bus) ;/are 3.5MHz fast) - CPU On-Chip I/O Ports (Write-only) (Read=open bus) 4200h - NMITIMEN- Interrupt Enable and Joypad Request 00h 4201h - WRIO - Joypad Programmable I/O Port (Open-Collector Output) FFh 4202h - WRMPYA - Set unsigned 8bit Multiplicand (FFh) 4203h - WRMPYB - Set unsigned 8bit Multiplier and Start Multiplication (FFh) 4204h - WRDIVL - Set unsigned 16bit Dividend (lower 8bit) (FFh) 4205h - WRDIVH - Set unsigned 16bit Dividend (upper 8bit) (FFh) 4206h - WRDIVB - Set unsigned 8bit Divisor and Start Division (FFh) 4207h - HTIMEL - H-Count Timer Setting (lower 8bits) (FFh) 4208h - HTIMEH - H-Count Timer Setting (upper 1bit) (01h) 4209h - VTIMEL - V-Count Timer Setting (lower 8bits) (FFh) 420Ah - VTIMEH - V-Count Timer Setting (upper 1bit) (01h) 420Bh - MDMAEN - Select General Purpose DMA Channel(s) and Start Transfer 0 420Ch - HDMAEN - Select H-Blank DMA (H-DMA) Channel(s) 0 420Dh - MEMSEL - Memory-2 Waitstate Control 0 420Eh..420Fh - Unused region (open bus) - CPU On-Chip I/O Ports (Read-only) 4210h - RDNMI - V-Blank NMI Flag and CPU Version Number (Read/Ack) 0xh 4211h - TIMEUP - H/V-Timer IRQ Flag (Read/Ack) 00h 4212h - HVBJOY - H/V-Blank flag and Joypad Busy flag (R) (?) 4213h - RDIO - Joypad Programmable I/O Port (Input) - 4214h - RDDIVL - Unsigned Division Result (Quotient) (lower 8bit) (0) 4215h - RDDIVH - Unsigned Division Result (Quotient) (upper 8bit) (0) 4216h - RDMPYL - Unsigned Division Remainder / Multiply Product (lower 8bit) 4217h - RDMPYH - Unsigned Division Remainder / Multiply Product (upper 8bit) 4218h - JOY1L - Joypad 1 (gameport 1, pin 4) (lower 8bit) 00h 4219h - JOY1H - Joypad 1 (gameport 1, pin 4) (upper 8bit) 00h 421Ah - JOY2L - Joypad 2 (gameport 2, pin 4) (lower 8bit) 00h 421Bh - JOY2H - Joypad 2 (gameport 2, pin 4) (upper 8bit) 00h 421Ch - JOY3L - Joypad 3 (gameport 1, pin 5) (lower 8bit) 00h 421Dh - JOY3H - Joypad 3 (gameport 1, pin 5) (upper 8bit) 00h 421Eh - JOY4L - Joypad 4 (gameport 2, pin 5) (lower 8bit) 00h 421Fh - JOY4H - Joypad 4 (gameport 2, pin 5) (upper 8bit) 00h 4220h..42FFh - Unused region (open bus) - CPU DMA, For below ports, x = Channel number 0..7 (R/W) (additional DMA control registers are 420Bh and 420Ch, see above) 43x0h - DMAPx - DMA/HDMA Parameters (FFh) 43x1h - BBADx - DMA/HDMA I/O-Bus Address (PPU-Bus aka B-Bus) (FFh) 43x2h - A1TxL - HDMA Table Start Address (low) / DMA Curr Addr (low) (FFh) 43x3h - A1TxH - HDMA Table Start Address (high) / DMA Curr Addr (high)(FFh) 43x4h - A1Bx - HDMA Table Start Address (bank) / DMA Curr Addr (bank)(xxh) 43x5h - DASxL - Indirect HDMA Address (low) / DMA Byte-Counter (low) (FFh) 43x6h - DASxH - Indirect HDMA Address (high) / DMA Byte-Counter (high)(FFh) 43x7h - DASBx - Indirect HDMA Address (bank) (FFh) 43x8h - A2AxL - HDMA Table Current Address (low) (FFh) 43x9h - A2AxH - HDMA Table Current Address (high) (FFh) 43xAh - NTRLx - HDMA Line-Counter (from current Table entry) (FFh) 43xBh - UNUSEDx - Unused byte (read/write-able) (FFh) 43xCh+ - Unused region (open bus) - 43xFh - MIRRx - Mirror of 43xBh (R/W) (FFh) 4380h..5FFFh - Unused region (open bus) - Further Memory 6000h..7FFFh - Expansion (eg. Battery Backed RAM, in HiROM cartridges) 8000h..FFFFh - Cartridge ROM Note: The right column shows the initial value on Reset, values in brackets are left unchanged upon Reset (but do contain the specified value upon initial Power-up). Audio Registers (controlled by the SPC700 CPU, not by the Main CPU) --> SNES APU Memory and I/O Map Expansion Overview 0000h-003Fh Cheat Device: Pro Action Replay 1-3: I/O Ports; overlapping WRAM 2000h-2007h MSU1: Media Streaming Unit (homebrew) 2184h-218Fh Copier: Super UFO models Pro-7 and Pro-8 2188h-2199h Satellaview Receiver Unit (connected to Expansion Port) 21C0h-21C3h More or less "used" by Nintendo's "SNES Test" cartridge 21C0h-21DFh Exertainment (exercise bicycle) (connected to Expansion Port) 21D0h-21E5h Sony Super Disc prototype: CDROM Controller & BIOS Cart RAM lock 21FCh-21FFh Nocash Debug Extension (char_out and 21mhz_timer in no$sns emu) 2200h-230Eh SA-1 (programmable 65C816 CPU) I/O Ports 2400h-2407h Nintendo Power (flashcard) (bank 00h only, no mirrors) 2800h-2801h S-RTC Real Time Clock I/O Ports 2800h-2810h Copier: FDC I/O Ports CCL (Supercom Partner & Pro Fighter) 2C00h-2FFFh Cheat Device: X-Terminator 2: SRAM (32Kbytes, in banks 00h-1Fh) 3000h-32FFh GSU-n (programmable RISC CPU) I/O Ports 3000h-37FFh SA-1 (programmable 65C816 CPU) on-chip I-RAM 3800h-3804h ST018 (Seta) (pre-programmed ARM CPU) (maybe also FF40h..FF63h) 4100h Nintendo Super System (NSS) DIP-Switches (on game cartridge) 4800h-4807h S-DD1 Data Decompression chip 4800h-4842h SPC7110 Data Decompression chip (optionally with RTC-4513) 5000h-5FFFh Satellaview MCC mem ctrl (sixteen 1bit I/O ports banks 00h-0Fh) 5000h-5FFFh Satellaview 32Kbyte SRAM (eight 4Kbyte-chunks in banks 10h-17h) 58xxh Copier: Venus (Multi Game Hunter) 5Fxxh Copier: Gamars Super Disk 6000h-7FFFh SRAM Battery Backed Static RAM (in HiROM cartridges) (bank 3xh) 6000h-7FFFh SGB Super Gameboy I/O Ports 6000h-7FFFh DSP-n on HiROM boards (pre-programmed NEC uPD77C25 CPU) 7F40h-7FAFh CX4 I/O Ports (with 3K SRAM at 6000h..6BFFh) 7FF0h-7FF7h OBC1 OBJ Controller I/O Ports (with 8K SRAM at 6000h..7FFFh) 8000h-FFFFh Cartridge ROM (including header/exception vectors at FFxxh) 8000h Pirate X-in-1 Multicart 32K-ROM bank (mapping 20 small games) 8000h-FFFFh Copier: Various models map ROM, I/O, SRAM, DRAM in ROM area 8000h-8101h Cheat Device: Game Genie I/O Ports (in ROM banks 00h and FFh) A000h-A007h Cheat Device: Pro Action Replay 2: I/O Control (in HiROM area) FFE0h-FFFFh Exception Vectors (variable in SA-1 and CX4) (fixed in GSU) FFE8h-FFEAh Cheat Device: X-Terminator 1-2: I/O Ports (in LoROM area) FFF0h-FFF3h Tri-Star/Super 8: NES Joypad 1-2, BIOS-disable, A/V-select xF8000h-3FFFFFh DSP-n on LoROM boards (pre-programmed NEC uPD77C25 CPU) 600000h-6F7FFFh DSP-n on 2Mbyte-LoROM boards (planned/prototype only) 600000h-67FFFFh ST010/ST011 Command/Status/Parameters I/O Ports 680000h-6FFFFFh ST010/ST011 On-chip Battery-backed RAM 700000h-7xxxxxh SRAM Battery Backed Static RAM (in LoROM cartridges) 808000h-BFFFFFh Bootleg Copy-Protection I/O Ports C00000h-FFFFFFh Satellaview FLASH Cartridges (Detect/Write/Erase commands) C00000h-Cn7FFFh JRA PAT Backup FLASH Memory (Detect/Write/Erase commands) C08000h-FFFFFFh Satellaview-like FLASH Data Packs in LoROM Cartridges E00000h-FFFFFFh Satellaview-like FLASH Data Packs in HiROM Cartridges E00000h-E0FFFFh X-Band Modem 64K SRAM (in two 32Kx8 chips) FBC000h-FBC1BFh X-Band Modem I/O Ports (mainly in this area) FFFF00h-FFFFFFh Pirate X-in-1 multicart mapper I/O port SNES Memory ----------- --> SNES Memory Map --> SNES Memory Control Work RAM (WRAM) Work RAM is mapped directly to the CPU bus, and can be additionally accessed indirectly via I/O ports (mainly for DMA transfer purposes). --> SNES Memory Work RAM Access Video Memory (OAM/VRAM/CGRAM) All video memory can be accessed only during V-Blank, or Forced Blank. Video memory isn't mapped to the CPU bus, and can be accessed only via I/O ports (for bigger transfers, this would be usually done via DMA). --> SNES Memory OAM Access (Sprite Attributes) --> SNES Memory VRAM Access (Tile and BG Map) --> SNES Memory CGRAM Access (Palette Memory) Access during H-Blank doesn't seem to work too well - it is possible to change palette entries during H-Blank, but seems to work only during a few clock cycles, not during the full H-blank period. Sound RAM Sound RAM is mapped to a separate SPC700 CPU, not to the Main CPU. Accordingly, Sound RAM cannot be directly accessed by the Main CPU (nor by DMA). Instead, data transfers must be done by using some CPU-to-CPU software communication protocol. Upon Reset, this done by a Boot-ROM on the SPC700 side. For details, see: --> SNES APU Main CPU Communication Port DMA Transfers DMA can be used to quickly transfer memory blocks to/from most memory locations (except Sound RAM isn't accessible via DMA, and WRAM-to-WRAM transfers don't work). --> SNES DMA Transfers SNES Memory Map --------------- The SNES uses a 24bit address bus (000000h-FFFFFFh). These 24bit addresses are often divided into 8bit bank numbers (00h-FFh) plus 16bit offset (0000h-FFFFh). Some of these banks are broken into two 32Kbyte halves (0000h-7FFFh=System Area, 8000h-FFFFh=Cartridge ROM). Moreover, memory is divided into WS1 and WS2 areas, which can be configured to have different waitstates. Overall Memory Map Bank Offset Content Speed 00h-3Fh:0000h-7FFFh System Area (8K WRAM, I/O Ports, Expansion) see below 00h-3Fh:8000h-FFFFh WS1 LoROM (max 2048 Kbytes) (64x32K) 2.68MHz (00h:FFE0h-FFFFh) CPU Exception Vectors (Reset,Irq,Nmi,etc.) 2.68MHz 40h-7Dh:0000h-FFFFh WS1 HiROM (max 3968 Kbytes) (62x64K) 2.68MHz 7Eh-7Fh:0000h-FFFFh WRAM (Work RAM, 128 Kbytes) (2x64K) 2.68MHz 80h-BFh:0000h-7FFFh System Area (8K WRAM, I/O Ports, Expansion) see below 80h-BFh:8000h-FFFFh WS2 LoROM (max 2048 Kbytes) (64x32K) max 3.58MHz C0h-FFh:0000h-FFFFh WS2 HiROM (max 4096 Kbytes) (64x64K) max 3.58MHz Internal memory regions are WRAM and memory mapped I/O ports. External memory regions are LoROM, HiROM, and Expansion areas. Additional memory (not mapped to CPU addresses) (accessible only via I/O): OAM (512+32 bytes) (256+16 words) VRAM (64 Kbytes) (32 Kwords) Palette (512 bytes) (256 words) Sound RAM (64 Kbytes) Sound ROM (64 bytes BIOS Boot ROM) System Area (banks 00h-3Fh and 80h-BFh) Offset Content Speed 0000h-1FFFh Mirror of 7E0000h-7E1FFFh (first 8Kbyte of WRAM) 2.68MHz 2000h-20FFh Unused 3.58MHz 2100h-21FFh I/O Ports (B-Bus) 3.58MHz 2200h-3FFFh Unused 3.58MHz 4000h-41FFh I/O Ports (manual joypad access) 1.78MHz 4200h-5FFFh I/O Ports 3.58MHz 6000h-7FFFh Expansion 2.68MHz For details on the separate I/O ports (and Expansion stuff), see: --> SNES I/O Map Cartridge ROM Capacity The 24bit address bus allows to address 16MB, but wide parts are occupied by WRAM and I/O mirrors, which leaves only around 11.9MB for cartridge ROM in WS1/WS2 LoROM/HiROM regions (or more when also using Expansion regions and gaps in I/O area). In most cartridges, WS1 and WS2 are mirrors of each other, and most games do use only the LoROM, or only the HiROM areas, resulting in following capacities: LoROM games --> max 2MByte ROM (banks 00h-3Fh, with mirror at 80h-BFh) HiROM games --> max 4MByte ROM (banks 40h-7Dh, with mirror at C0h-FFh) There are several ways to overcome that limits: Some LoROM games map additional "LoROM" banks into HiROM area (BigLoROM), or into WS2 area (SpecialLoROM). Some HiROM games map additional HiROM banks into WS2 area (ExHiROM). And some cartridges do use bank switching (eg. SA-1, S-DD1, SPC7110, and X-in-1 multicarts). 32K LoROM (32K ROM banks with System Area in the same bank) ROM is broken into non-continous 32K blocks. The advantage is that one can access ROM and System Area (I/O ports and WRAM) without needing to change the CPU's current DB and PB register settings. HiROM (plain 64K ROM banks) HiROM mapping provides continous ROM addresses, but doesn't include I/O and WRAM regions "inside" of the ROM-banks. The upper halves of the 64K-HiROM banks are usually mirrored to the corresponding 32K-LoROM banks (that is important for mapping the Interrupt and Reset Vectors from 40FFE0h-40FFFFh to 00FFE0h-00FFFFh). Battery-backed SRAM Battery-backed SRAM is used for saving game positions in many games. SRAM size is usually 2Kbyte, 8Kbyte, or 32Kbyte (or more than 32Kbyte in a few games). There are two basic SRAM mapping schemes, one for LoROM games, and one for HiROM games: HiROM ---> SRAM at 30h-3Fh,B0h-BFh:6000h-7FFFh ;small 8K SRAM bank(s) LoROM ---> SRAM at 70h-7Dh,F0h-FFh:0000h-7FFFh ;big 32K SRAM bank(s) SRAM is usually also mirrored to both WS1 and WS2 areas. SRAM in bank 30h-3Fh is often also mirrored to 20h-2Fh (or 10h-1Fh in some cases). SRAM in bank 70h-7Dh is sometimes crippled to 70h-71h or 70h-77h, or extended to 60h-7Dh, and sometimes also mirrored to offset 8000h-FFFFh. A-Bus and B-Bus Aside from the 24bit address bus (A-Bus), the SNES is having a second 8bit address bus (B-bus), used to access certain I/O ports. Both address busses are sharing the same data bus, but each bus is having its own read and write signals. The CPU can access the B-Bus at offset 2100h-21FFh within the System Area (ie. for CPU accesses, the B-Bus is simply a subset of the A-Bus). The DMA controller can access both B-Bus and A-Bus at once (ie. it can output source & destination addresses simultaneously to the two busses, allowing it to "read-and-write" in a single step, instead of using separate "read-then-write" steps). Bank Switching Most SNES games are satisfied with the 24bit address space. Bank switching is used only in a few games with special chips: S-DD1, SA-1, and SPC7110 chips (with mappable 1MByte-banks) Satellaview FLASH carts (can enable/disable ROM, PSRAM, FLASH) Nintendo Power FLASH carts (can map FLASH and SRAM to desired address) Pirate X-in-1 multicart mappers (mappable offset in 256Kbyte units) Cheat devices (and X-Band modem) can map their BIOS and can patch ROM bytes Copiers can map internal BIOS/DRAM/SRAM and external Cartridge memory Hotel Boxes (eg. SFC-Box) can map multiple games/cartridges And, at the APU side, one can enable/disable the 64-byte boot ROM. SNES Memory Control ------------------- 420Dh - MEMSEL - Memory-2 Waitstate Control (W) 7-1 Not used 0 Access Cycle for Memory-2 Area (0=2.68MHz, 1=3.58MHz) (0 on reset) Memory-2 consists of address 8000h-FFFFh in bank 80h-BFh, and address 0000h-FFFFh in bank C0h-FFh. 3.58MHz high speed memory requires 120ns or faster ROMs/EPROMs. 2.68MHz memory requires 200ns or faster ROMs/EPROMs. 2.684658 MHz = 21.47727 MHz / 8 ;same access time as WRAM 3.579545 MHz = 21.47727 MHz / 6 ;faster access than WRAM Programs that do use the 3.58MHz setting should also indicate this in the Cartridge header at [FFD5h].Bit4. --> SNES Cartridge ROM Header Forced Blank Allows to access video memory at any time. See INIDISP Bit7, Port 2100h. SNES Memory Work RAM Access --------------------------- The SNES includes 128Kbytes of Work RAM, which can be accessed in several ways: The whole 128K are at 7E0000h-7FFFFFh. The first 8K are also mirrored to xx0000h-xx1FFFh (xx=00h..3Fh and 80h..BFh) Moreover (mainly for DMA purposes) it can be accessed via Port 218xh. 2180h - WMDATA - WRAM Data Read/Write (R/W) 7-0 Work RAM Data Simply reads or writes the byte at the address in [2181h-2183h], and does then increment the address by one. Note: Despite of the fast access time on 2180h reads (faster than 7E0000h-7FFFFFh reads), there is no prefetching involved (reading 2180h always returns the currently addressed byte, even if one mixes it with writes to 2180h or to 7E0000h-7FFFFFh). 2181h - WMADDL - WRAM Address (lower 8bit) (W) 2182h - WMADDM - WRAM Address (middle 8bit) (W) 2183h - WMADDH - WRAM Address (upper 1bit) (W) 17bit Address (in Byte-steps) for addressing the 128Kbytes of WRAM via 2180h. DMA Notes WRAM-to-WRAM DMA isn't possible (neither in A-Bus to B-Bus direction, nor vice-versa). Externally, the separate address lines are there, but the WRAM chip is unable to process both at once. Timing Notes Note that WRAM is accessed at 2.6MHz. Meaning that all variables, stack, and program code in RAM will be slow. The SNES doesn't include any fast RAM. However, there are a few tricks to get "3.5MHz RAM": * Sequential read from WRAM via [2180h] is 3.5MHz fast, and has auto-increment. * DMA registers at 43x0h-43xBh provide 8x12 bytes of read/write-able "memory". * External RAM could be mapped to 5000h-5FFFh (but usually it's at slow 6000h). * External RAM could be mapped to C00000h-FFFFFFh (probably rarely done too). Other Notes The B-Bus feature with auto-increment is making it fairly easy to boot the SNES without any ROM/EPROM by simply writing program bytes to WRAM (and mirroring it to the Program and Reset vector to ROM area): --> SNES Xboo Upload (WRAM Boot) Interestingly, the WRAM-to-ROM Area mirroring seems to be stable even when ROM Area is set to 3.5MHz Access Time - so it's unclear why Nintendo has restricted normal WRAM Access to 2.6MHz - maybe some WRAM chips are slower than others, or maybe they become unstable at certain room temperatures. SNES Memory OAM Access (Sprite Attributes) ------------------------------------------ 2102h/2103h - OAMADDL/OAMADDH - OAM Address and Priority Rotation (W) 15 OAM Priority Rotation (0=OBJ #0, 1=OBJ #N) (OBJ with highest priority) 9-14 Not used 7-1 OBJ Number #N (for OBJ Priority) ;\bit7-1 are used for two purposes 8-0 OAM Address (for OAM read/write) ;/ This register contains of a 9bit Reload value and a 10bit Address register (plus the priority flag). Writing to 2102h or 2103h does change the lower 8bit or upper 1bit of the Reload value, and does additionally copy the (whole) 9bit Reload value to the 10bit Address register (with address Bit0=0 so next access will be an even address). Caution: During rendering, the PPU is destroying the Address register (using it internally for whatever purposes), after rendering (at begin of Vblank, ie. at begin of line 225/240, but only if not in Forced Blank mode) it reinitializes the Address from the Reload value; the same reload occurs also when deactivating forced blank anytime during the first scanline of vblank (ie. during line 225/240). 2104h - OAMDATA - OAM Data Write (W) 2138h - RDOAM - OAM Data Read (R) 1st Access: Lower 8bit (even address) 2nd Access: Upper 8bit (odd address) Reads and Writes to EVEN and ODD byte-addresses work as follows: Write to EVEN address --> set OAM_Lsb = Data ;memorize value Write to ODD address<200h --> set WORD[addr-1] = Data*256 + OAM_Lsb Write to ANY address>1FFh --> set BYTE[addr] = Data Read from ANY address --> return BYTE[addr] The address is automatically incremented after every read or write access. OAM Size is 220h bytes (addresses 220h..3FFh are mirrors of 200h..21Fh). OAM Content --> SNES PPU Sprites (OBJs) SNES Memory VRAM Access (Tile and BG Map) ----------------------------------------- 2115h - VMAIN - VRAM Address Increment Mode (W) 7 Increment VRAM Address after accessing High/Low byte (0=Low, 1=High) 6-4 Not used 3-2 Address Translation (0..3 = 0bit/None, 8bit, 9bit, 10bit) 1-0 Address Increment Step (0..3 = Increment Word-Address by 1,32,128,128) The address translation is intended for bitmap graphics (where one would have filled the BG Map by increasing Tile numbers), technically it does thrice left-rotate the lower 8, 9, or 10 bits of the Word-address: Translation Bitmap Type Port [2116h/17h] VRAM Word-Address 8bit rotate 4-color; 1 word/plane aaaaaaaaYYYxxxxx --> aaaaaaaaxxxxxYYY 9bit rotate 16-color; 2 words/plane aaaaaaaYYYxxxxxP --> aaaaaaaxxxxxPYYY 10bit rotate 256-color; 4 words/plane aaaaaaYYYxxxxxPP --> aaaaaaxxxxxPPYYY Where "aaaaa" would be the normal address MSBs, "YYY" is the Y-index (within a 8x8 tile), "xxxxx" selects one of the 32 tiles per line, "PP" is the bit-plane index (for BGs with more than one Word per plane). For the intended result (writing rows of 256 pixels) the Translation should be combined with Increment Step=1. For Mode 7 bitmaps one could eventually combine step 32/128 with 8bit/10bit rotate: 8bit-rotate/step32 aaaaaaaaXXXxxYYY --> aaaaaaaaxxYYYXXX 10bit-rotate/step128 aaaaaaXXXxxxxYYY --> aaaaaaxxxxYYYXXX Though the SNES can't access enought VRAM for fullscreen Mode 7 bitmaps. Step 32 (without translation) is useful for updating BG Map columns (eg. after horizontal scrolling). 2116h - VMADDL - VRAM Address (lower 8bit) (W) 2117h - VMADDH - VRAM Address (upper 8bit) (W) VRAM Address for reading/writing. This is a WORD address (2-byte steps), the PPU could theoretically address up to 64K-words (128K-bytes), in practice, only 32K-words (64K-bytes) are installed in SNES consoles (VRAM address bit15 is not connected, so addresses 8000h-FFFFh are mirrors of 0-7FFFh). After reading/writing VRAM Data, the Word-address can be automatically incremented by 1,32,128 (depending on the Increment Mode in Port 2115h) (Note: the Address Translation feature is applied only "temporarily" upon memory accesses, it doesn't affect the value in Port 2116h-17h). Writing to 2116h/2117h does prefetch 16bit data from the new address (for later reading). 2118h - VMDATAL - VRAM Data Write (lower 8bit) (W) 2119h - VMDATAH - VRAM Data Write (upper 8bit) (W) Writing to 2118h or 2119h does simply modify the LSB or MSB of the currently addressed VRAM word (with optional Address Translation applied). Depending on the Increment Mode the address does (or doesn't) get automatically incremented after the write. 2139h - RDVRAML - VRAM Data Read (lower 8bit) (R) 213Ah - RDVRAMH - VRAM Data Read (upper 8bit) (R) Reading from these registers returns the LSB or MSB of an internal 16bit prefetch register. Depending on the Increment Mode the address does (or doesn't) get automatically incremented after the read. The prefetch register is filled with data from the currently addressed VRAM word (with optional Address Translation applied) upon two situations: Prefetch occurs AFTER changing the VRAM address (by writing 2116h/17h). Prefetch occurs BEFORE incrementing the VRAM address (by reading 2139h/3Ah). The "Prefetch BEFORE Increment" effect is some kind of a hardware glitch (Prefetch AFTER Increment would be more useful). Increment/Prefetch in detail: 1st Send a byte from OLD prefetch value to the CPU ;-this always 2nd Load NEW value from OLD address into prefetch register;\these only if 3rd Increment address so it becomes the NEW address ;/increment occurs Increments caused by writes to 2118h/19h don't do any prefetching (the prefetch register is left totally unchanged by writes). In practice: After changing the VRAM address (via 2116h/17h), the first byte/word will be received twice, further values are received from properly increasing addresses (as a workaround: issue a dummy-read that ignores the 1st or 2nd value). VRAM Content --> SNES PPU Video Memory (VRAM) SNES Memory CGRAM Access (Palette Memory) ----------------------------------------- 2121h - CGADD - Palette CGRAM Address (Color Generator Memory) (W) Color index (0..255). This is a WORD-address (2-byte steps), allowing to access 256 words (512 bytes). Writing to this register resets the 1st/2nd access flipflop (for 2122h/213Bh) to 1st access. 2122h - CGDATA - Palette CGRAM Data Write (W) 213Bh - RDCGRAM - Palette CGRAM Data Read (R) 1st Access: Lower 8 bits (even address) 2nd Access: Upper 7 bits (odd address) (upper 1bit = PPU2 open bus) Reads and Writes to EVEN and ODD byte-addresses work as follows: Write to EVEN address --> set Cgram_Lsb = Data ;memorize value Write to ODD address --> set WORD[addr-1] = Data*256 + Cgram_Lsb Read from ANY address --> return BYTE[addr] The address is automatically incremented after every read or write access. CGRAM Content (and CGRAM-less Direct Color mode) --> SNES PPU Color Palette Memory (CGRAM) and Direct Colors SNES DMA Transfers ------------------ The SNES includes eight DMA channels, which can be used for H-DMA or GP-DMA. --> SNES DMA and HDMA Start/Enable Registers --> SNES DMA and HDMA Channel 0..7 Registers --> SNES DMA and HDMA Notes H-DMA (H-Blank DMA) H-DMA transfers are automatically invoked on H-Blank, each H-DMA is limited to a single unit (max 4 bytes) per scanline. This is commonly used to manipulate PPU I/O ports (eg. to change scroll offsets). Related registers can found here: --> SNES I/O Map --> SNES Picture Processing Unit (PPU) GP-DMA (General Purpose DMA) GP-DMA can manually invoked by software, allowing to transfer larger amounts of data (max 10000h bytes). This is commonly used to transfer WRAM or ROM (on A-Bus side) to/from WRAM, OAM, VRAM, CGRAM (on B-Bus side). Related registers are: --> SNES Memory Work RAM Access --> SNES Memory OAM Access (Sprite Attributes) --> SNES Memory VRAM Access (Tile and BG Map) --> SNES Memory CGRAM Access (Palette Memory) SNES DMA and HDMA Start/Enable Registers ---------------------------------------- DMA and HDMA Transfer order is Channel 0 first... Channel 7 last HDMA has higher prio than DMA HDMA is running even during Forced Blank. 420Bh - MDMAEN - Select General Purpose DMA Channel(s) and Start Transfer (W) 7-0 General Purpose DMA Channel 7-0 Enable (0=Disable, 1=Enable) When writing a non-zero value to this register, general purpose DMA will be started immediately (after a few clk cycles). The CPU is paused during the transfer. The transfer can be interrupted by H-DMA transfers. If more than 1 bit is set in MDMAEN, then the separate transfers will be executed in order channel 0=first through 7=last. The MDMAEN bits are cleared automatically at transfer completion. Do not use channels for GP-DMA which are activated as H-DMA in HDMAEN. 420Ch - HDMAEN - Select H-Blank DMA (H-DMA) Channel(s) (W) 7-0 H-DMA Channel 7-0 Enable (0=Disable, 1=Enable) ... SNES DMA and HDMA Channel 0..7 Registers ---------------------------------------- For below ports, x = Channel number (0-7) 43x0h - DMAPx - DMA/HDMA Parameters (R/W) 7 Transfer Direction (0=A:CPU to B:I/O, 1=B:I/O to A:CPU) 6 Addressing Mode (0=Direct Table, 1=Indirect Table) (HDMA only) 5 Not used (R/W) (unused and unchanged by all DMA and HDMA) 4-3 A-BUS Address Step (0=Increment, 2=Decrement, 1/3=Fixed) (DMA only) 2-0 Transfer Unit Select (0-4=see below, 5-7=Reserved) DMA Transfer Unit Selection: Mode Bytes B-Bus 21xxh Address ;Usage Examples... 0 = Transfer 1 byte xx ;eg. for WRAM (port 2180h) 1 = Transfer 2 bytes xx, xx+1 ;eg. for VRAM (port 2118h/19h) 2 = Transfer 2 bytes xx, xx ;eg. for OAM or CGRAM 3 = Transfer 4 bytes xx, xx, xx+1, xx+1 ;eg. for BGnxOFS, M7x 4 = Transfer 4 bytes xx, xx+1, xx+2, xx+3 ;eg. for BGnSC, Window, APU.. 5 = Transfer 4 bytes xx, xx+1, xx, xx+1 ;whatever purpose, VRAM maybe 6 = Transfer 2 bytes xx, xx ;same as mode 2 7 = Transfer 4 bytes xx, xx, xx+1, xx+1 ;same as mode 3 A HDMA transfers ONE unit per scanline (=max 4 bytes). General Purpose DMA has a 16bit length counter, allowing to transfer up to 10000h bytes (ie. not 10000h units). 43x1h - BBADx - DMA/HDMA I/O-Bus Address (PPU-Bus aka B-Bus) (R/W) For both DMA and HDMA: 7-0 B-Bus Address (selects an I/O Port which is mapped to 2100h-21FFh) For normal DMA this should be usually 04h=OAM, 18h=VRAM, 22h=CGRAM, or 80h=WRAM. For HDMA it should be usually some PPU register (eg. for changing scroll offsets midframe). 43x2h - A1TxL - HDMA Table Start Address (low) / DMA Current Addr (low) (R/W) 43x3h - A1TxH - HDMA Table Start Address (hi) / DMA Current Addr (hi) (R/W) 43x4h - A1Bx - HDMA Table Start Address (bank) / DMA Current Addr (bank) (R/W) For normal DMA: 23-16 CPU-Bus Data Address Bank (constant, not incremented/decremented) 15-0 CPU-Bus Data Address (incremented/decremented/fixed, as selected) For HDMA: 23-16 CPU-Bus Table Address Bank (constant, bank number for 43x8h/43x9h) 15-0 CPU-Bus Table Address (constant, reload value for 43x8h/43x9h) 43x5h - DASxL - Indirect HDMA Address (low) / DMA Byte-Counter (low) (R/W) 43x6h - DASxH - Indirect HDMA Address (hi) / DMA Byte-Counter (hi) (R/W) 43x7h - DASBx - Indirect HDMA Address (bank) (R/W) For normal DMA: 23-16 Not used 15-0 Number of bytes to be transferred (1..FFFFh=1..FFFFh, or 0=10000h) (This is really a byte-counter; with a 4-byte "Transfer Unit", len=5 would transfer one whole Unit, plus the first byte of the second Unit.) (The 16bit value is decremented during transfer, and contains 0000h on end.) For HDMA in direct mode: 23-0 Not used (in this mode, the Data is read directly from the Table) For HDMA in indirect mode: 23-16 Current CPU-Bus Data Address Bank (this must be set by software) 16-0 Current CPU-Bus Data Address (automatically loaded from the Table) 43x8h - A2AxL - HDMA Table Current Address (low) (R/W) 43x9h - A2AxH - HDMA Table Current Address (high) (R/W) For normal DMA: 15-0 Not used For HDMA: - Current Table Address Bank (taken from 43x4h) 15-0 Current Table Address (reloaded from 43x2h/43x3h) (incrementing) 43xAh - NTRLx - HDMA Line-Counter (from current Table entry) (R/W) For normal DMA: 7-0 Not used For HDMA: 7 Repeat-flag ;\(loaded from Table, and then 6-0 Number of lines to be transferred ;/decremented per scanline) 43xBh - UNUSEDx - Unused Byte (R/W) 7-0 Not used (read/write-able) Can be used as a fast RAM location (but NOT as a fixed DMA source address for memfill). Storing any value in this register seems to have no effect on the transfer (and the value is left intact, not modified by DMA nor direct nor indirect HDMAs). 43xCh..43xEh - Unused region (open bus) Unused. Reading returns garbage (open bus), writing seems to have no effect, even when trying to "disturb" HDMAs. 43xFh - MIRRx - Read/Write-able mirror of 43xBh (R/W) Mirror of 43xBh. HDMA Table Formats (in Direct and Indirect Mode) In Direct Mode, the table consists of entries in following format: 1 byte Repeat-flag & line count N bytes Data (where N=unit size, if repeat=1: multiplied by line count) In Indirect Mode, the table consists of entries in following format: 1 byte Repeat-flag & line count 2 bytes 16bit pointer to N bytes of Data (where N = as for Direct HDMA) In either mode: The "repeat-flag & line count" bytes can be: 00h Terminate this HDMA channel (until it restarts in next frame) 01h..80h Transfer 1 unit in 1 line, then pause for next "X-01h" lines 81h..FFh Transfer X-80h units in X-80h lines ("repeat mode") The "count" and "pointer" values are always READ from the table. The "data" values are READ or WRITTEN depending on the transfer direction. The transfer step is always INCREMENTING for HDMA (for both the table itself, as well as for any indirectly addressed data blocks). SNES DMA and HDMA Notes ----------------------- Starting HDMA midframe Activating HDMA (via port 420Ch) should be usually done only during VBlank (so that the hardware can reload the HDMA registers automatically at end of Vblank). Otherwise, when starting HDMA midframe (outside of Vblank), then one must manually reload the HDMA registers. For example, during Vblank, init HDMA registers as so: 420Ch=00h ;stop all HDMA channels 43x0h=02h ;transfer two bytes to [bbus+0], and [bbus+0] 43x1h=88h ;dummy bbus destination address (unused port 2188h) 42x4h=abus.src.bank ;with pointing to "02h,77h,55h,00h" 42x8h=abus.src.offs.lo ;ie. repeat/pause 2 scanlines (02h), transfer 42x9h=abus.src.off.hi ;one data unit (77h,55h), and after the pause, 42xAh=01h ;remain count ;finish the transfer (00h). The HDMA starting point seems to depend on whether any HDMA channels were already active in the current frame. The two scenarios (each with above example values) are: Case 1 - (420Ch was still zero) - First HDMA in current frame Start one (or more) HDMA channel(s) somewhere midframe (eg. in line 128), and watch the src/remain values in 43x8h..43xAh. This will behave as expected (src increases, and remain decreases from 02h downto 00h). Case 2 - (420Ch was already nonzero) - Further HDMA in current frame Start another HDMA channel (some scanlines later, after the above transfer). This will behave differently: It's decreasing remain count in 43xAh from 55h downwards, ie. the HDMA does apparently start with "do_transfer=1" (for whatever reason), causing it to transfer 02h,77h as data, and then fetch 55h as repeat count for next scanlines. Note: One game does start HDMAs midframe is Super Ghouls 'N Ghosts. [XXX Case 2 may need more research, and isn't yet accurately emulated in no$sns] External DMA The SNES Cartridge Slot doesn't have any special DRQ/DACK pins for DMA handshaking purposes; DMA from cartridge memory is just implemented as normal memory access (so the cartridge must respond to DMAs within normal memory access time; which is fixed 8 master cycles per byte for DMA). Unknown if the data decompression chips (S-DD1 and SPC7110) are implemented the same way, or if they do use any "hidden" DMA handshaking mechanisms (they might be too slow to supply bytes within 8 master cycles, and at least one of them seems to decode DMA channel numbers; possibly by sensing writes to 420Bh?). SNES Picture Processing Unit (PPU) ---------------------------------- --> SNES PPU Control --> SNES PPU BG Control --> SNES PPU Rotation/Scaling --> SNES PPU Window --> SNES PPU Color-Math --> SNES PPU Timers and Status --> SNES PPU Interrupts --> SNES PPU Resolution --> SNES PPU Offset-Per-Tile Mode Video Memory (OAM/VRAM/CGRAM) --> SNES PPU Sprites (OBJs) --> SNES PPU Video Memory (VRAM) --> SNES PPU Color Palette Memory (CGRAM) and Direct Colors All video memory can be accessed only during V-Blank, or Forced Blank. Video memory isn't mapped to the CPU bus, and be accessed only via I/O ports. --> SNES Memory OAM Access (Sprite Attributes) --> SNES Memory VRAM Access (Tile and BG Map) --> SNES Memory CGRAM Access (Palette Memory) The above OAM/VRAM/CGRAM I/O ports are usually accessed via DMA, --> SNES DMA Transfers Pinouts --> SNES Audio/Video Connector Pinouts --> SNES Pinouts PPU Chips Background Priority Chart Mode0 Mode1 Mode2 Mode3 Mode4 Mode5 Mode6 Mode7 - BG3.1a - - - - - - OBJ.3 OBJ.3 OBJ.3 OBJ.3 OBJ.3 OBJ.3 OBJ.3 OBJ.3 BG1.1 BG1.1 BG1.1 BG1.1 BG1.1 BG1.1 BG1.1 - BG2.1 BG2.1 - - - - - - OBJ.2 OBJ.2 OBJ.2 OBJ.2 OBJ.2 OBJ.2 OBJ.2 OBJ.2 BG1.0 BG1.0 BG2.1 BG2.1 BG2.1 BG2.1 - BG2.1p BG2.0 BG2.0 - - - - - - OBJ.1 OBJ.1 OBJ.1 OBJ.1 OBJ.1 OBJ.1 OBJ.1 OBJ.1 BG3.1 BG3.1b BG1.0 BG1.0 BG1.0 BG1.0 BG1.0 BG1 BG4.1 - - - - - - - OBJ.0 OBJ.0 OBJ.0 OBJ.0 OBJ.0 OBJ.0 OBJ.0 OBJ.0 BG3.0 BG3.0a BG2.0 BG2.0 BG2.0 BG2.0 - BG2.0p BG4.0 BG3.0b - - - - - - Backdrop Backdrop Backdrop Backdrop Backdrop Backdrop Backdrop Backdrop Whereas, .N per-tile priority setting (in BG Map and OAM entries) .Np per-pixel priority setting (for 128-color BG2 in Mode7) .Na/b per-screen priority bit (in port 2105h) (plus .N as usually) SNES PPU Control ---------------- 2100h - INIDISP - Display Control 1 (W) 7 Forced Blanking (0=Normal, 1=Screen Black) 6-4 Not used 3-0 Master Brightness (0=Screen Black, or N=1..15: Brightness*(N+1)/16) In Forced Blank, VRAM, OAM and CGRAM can be freely accessed (otherwise it's accessible only during Vblank). Even when in forced blank, the TV Set keeps receiving Vsync/Hsync signals (thus producing a stable black picture). And, the CPU keeps receiving Hblank/Vblank signals (so any enabled video NMIs, IRQs, HDMAs are kept generated). Forced blank doesn't apply immediately... so one must wait whatever (maybe a scanline) before VRAM can be freely accessed... or is it only vice-versa: disabling forced blank doesn't apply immediately/shows garbage pixels? 212Ch - TM - Main Screen Designation (W) 212Dh - TS - Sub Screen Designation (W) 7-5 Not used 4 OBJ (0=Disable, 1=Enable) 3 BG4 (0=Disable, 1=Enable) 2 BG3 (0=Disable, 1=Enable) 1 BG2 (0=Disable, 1=Enable) 0 BG1 (0=Disable, 1=Enable) - Backdrop (Always enabled) Allows to enable/disable video layers. The Main screen is the "normal" display. The Sub screen is used only for Color Math and for 512-pixel Hires Mode. 2133h - SETINI - Display Control 2 (W) 7 External Synchronization (0=Normal, 1=Super Impose and etc.) 6 EXTBG Mode (Screen expand) ENABLE THE DATA SUPPLIED FROM THE EXTERNAL LSI. FOR THE SFX, ENABLE WHEN THE SCREEN WITH PRIORITY IS USED ON MODE-7. 5-4 Not used 3 Horizontal Pseudo 512 Mode (0=Disable, 1=Enable) (SHIFT SUBSCREEN HALF DOT TO THE LEFT) 2 BG V-Direction Display (0=224 Lines, 1=239 Lines) (for NTSC/PAL) 1 OBJ V-Direction Display (0=Low, 1=High Resolution/Smaller OBJs) IN THE INTERLACE MODE, SELECT EITHER OF 1-DOT PER LINE OR 1-DOT REPEATED EVERY 2-LINES. IF "1" IS WRITTEN, THE OBJ SEEMS REDUCED HALF VERTICALLY IN APPEARANCE. 0 V-Scanning (0=Non Interlace, 1=Interlace) (See Port 2105h) SNES PPU BG Control ------------------- 2105h - BGMODE - BG Mode and BG Character Size (W) 7 BG4 Tile Size (0=8x8, 1=16x16) ;\(BgMode0..4: variable 8x8 or 16x16) 6 BG3 Tile Size (0=8x8, 1=16x16) ; (BgMode5: 8x8 acts as 16x8) 5 BG2 Tile Size (0=8x8, 1=16x16) ; (BgMode6: fixed 16x8?) 4 BG1 Tile Size (0=8x8, 1=16x16) ;/(BgMode7: fixed 8x8) 3 BG3 Priority in Mode 1 (0=Normal, 1=High) 2-0 BG Screen Mode (0..7 = see below) The BG Screen Modes are: Mode BG1 BG2 BG3 BG4 0 4-color 4-color 4-color 4-color ;Normal 1 16-color 16-color 4-color - ;Normal 2 16-color 16-color (o.p.t) - ;Offset-per-tile 3 256-color 16-color - - ;Normal 4 256-color 4-color (o.p.t) - ;Offset-per-tile 5 16-color 4-color - - ;512-pix-hires 6 16-color - (o.p.t) - ;512-pix plus Offs-p-t 7 256-color EXTBG - - ;Rotation/Scaling Mode 7 supports rotation/scaling and EXTBG (but doesn't support hv-flip). Mode 5/6 don't support screen addition/subtraction. CG Direct Select is support on BG1 of Mode 3/4, and on BG1/BG2? of Mode 7. 2106h - MOSAIC - Mosaic Size and Mosaic Enable (W) Allows to divide the BG layer into NxN pixel blocks, in each block, the hardware picks the upper-left pixel of each block, and fills the whole block by the color - thus effectively reducing the screen resolution. 7-4 Mosaic Size (0=Smallest/1x1, 0Fh=Largest/16x16) 3 BG4 Mosaic Enable (0=Off, 1=On) 2 BG3 Mosaic Enable (0=Off, 1=On) 1 BG2 Mosaic Enable (0=Off, 1=On) 0 BG1 Mosaic Enable (0=Off, 1=On) Horizontally, the first block is always located on the left edge of the TV screen. Vertically, the first block is located on the top of the TV screen. When changing the mosaic size mid-frame, the hardware does first finish current block (using the old vertical size) before applying the new vertical size. Technically, vertical mosaic is implemented as so: subtract the veritical index (within the current block) from the vertical scroll register (BGnVOFS). 2107h - BG1SC - BG1 Screen Base and Screen Size (W) 2108h - BG2SC - BG2 Screen Base and Screen Size (W) 2109h - BG3SC - BG3 Screen Base and Screen Size (W) 210Ah - BG4SC - BG4 Screen Base and Screen Size (W) 7-2 SC Base Address in VRAM (in 1K-word steps, aka 2K-byte steps) 1-0 SC Size (0=One-Screen, 1=V-Mirror, 2=H-Mirror, 3=Four-Screen) (0=32x32, 1=64x32, 2=32x64, 3=64x64 tiles) (0: SC0 SC0 1: SC0 SC1 2: SC0 SC0 3: SC0 SC1 ) ( SC0 SC0 SC0 SC1 SC1 SC1 SC2 SC3 ) Specifies the BG Map addresses in VRAM. The "SCn" screens consists of 32x32 tiles each. Ignored in Mode 7 (Base is always zero, size is always 128x128 tiles). 210Bh/210Ch - BG12NBA/BG34NBA - BG Character Data Area Designation (W) 15-12 BG4 Tile Base Address (in 4K-word steps) 11-8 BG3 Tile Base Address (in 4K-word steps) 7-4 BG2 Tile Base Address (in 4K-word steps) 3-0 BG1 Tile Base Address (in 4K-word steps) Ignored in Mode 7 (Base is always zero). 210Dh - BG1HOFS - BG1 Horizontal Scroll (X) (W) and M7HOFS 210Eh - BG1VOFS - BG1 Vertical Scroll (Y) (W) and M7VOFS 210Fh - BG2HOFS - BG2 Horizontal Scroll (X) (W) 2110h - BG2VOFS - BG2 Vertical Scroll (Y) (W) 2111h - BG3HOFS - BG3 Horizontal Scroll (X) (W) 2112h - BG3VOFS - BG3 Vertical Scroll (Y) (W) 2113h - BG4HOFS - BG4 Horizontal Scroll (X) (W) 2114h - BG4VOFS - BG4 Vertical Scroll (Y) (W) 1st Write: Lower 8bit ;\1st/2nd write mechanism uses "BG_old" 2nd Write: Upper 2bit ;/ Note: Port 210Dh/210Eh are also used as M7HOFS/M7VOFS, these registers have a similar purpose, but internally they are separate registers: Writing to 210Dh does BOTH update M7HOFS (via M7_old mechanism), and also updates BG1HOFS (via BG_old mechanism). In the same fashion, 210Eh updates both M7VOFS and BG1VOFS. BGnHOFS = (Current<<8) | (Prev&~7) | ((Reg>>8)&7); Prev = Current; or BGnVOFS = (Current<<8) | Prev; Prev = Current; SNES PPU Rotation/Scaling ------------------------- 211Ah - M7SEL - Rotation/Scaling Mode Settings (W) 7-6 Screen Over (see below) 5-2 Not used 1 Screen V-Flip (0=Normal, 1=Flipped) ;\flip 256x256 "screen" 0 Screen H-Flip (0=Normal, 1=Flipped) ;/ Screen Over (when exceeding the 128x128 tile BG Map size): 0=Wrap within 128x128 tile area 1=Wrap within 128x128 tile area (same as 0) 2=Outside 128x128 tile area is Transparent 3=Outside 128x128 tile area is filled by Tile 00h 211Bh - M7A - Rotation/Scaling Parameter A (and Maths 16bit operand) (W) 211Ch - M7B - Rotation/Scaling Parameter B (and Maths 8bit operand) (W) 211Dh - M7C - Rotation/Scaling Parameter C (W) 211Eh - M7D - Rotation/Scaling Parameter D (W) 1st Write: Lower 8bit ;\1st/2nd write mechanism uses "M7_old" 2nd Write: Upper 8bit ;/ Signed 16bit values in 1/256 pixel units (1bit sign, 7bit integer, 8bit fraction). 210Dh - M7HOFS/BG1HOFS - BG1 Horizontal Scroll (X) (W) 210Eh - M7VOFS/BG1VOFS - BG1 Vertical Scroll (Y) (W) 211Fh - M7X - Rotation/Scaling Center Coordinate X (W) 2120h - M7Y - Rotation/Scaling Center Coordinate Y (W) 1st Write: Lower 8bit ;\1st/2nd write mechanism uses "M7_old" 2nd Write: Upper 5bit ;/ Signed 13bit values in pixel units (1bit sign, 12bit integer, 0bit fraction). Formula Formula for Rotation/Enlargement/Reduction in Matrix Form: ( VRAM.X ) = ( M7A M7B ) * ( SCREEN.X+M7HOFS-M7X ) + ( M7X ) ( VRAM.Y ) ( M7C M7D ) ( SCREEN.Y+M7VOFS-M7Y ) ( M7Y ) Parameters: M7A=+COS(angle)*ScaleX, M7B=+SIN(angle)*ScaleX M7C=-SIN(angle)*ScaleY, M7D=+COS(angle)*ScaleY M7X,M7Y = Center Coordinate M7HOFS,M7VOFS = Scroll Offset SCREEN.X = Display (Target) X-Coordinate: (0..255) XOR (xflip*FFh) SCREEN.Y = Display (Target) Y-Coordinate: (1..224 or 1..239) XOR (yflip*FFh) VRAM.X,Y = BG Map (Source) Coordinates (in 1/256 pixel units) To calculate VRAM coordinates for any SCREEN coordinates: IF xflip THEN SCREEN.X=((0..255) XOR FFh), ELSE SCREEN.X=(0..255) IF yflip THEN SCREEN.Y=((1..224/239) XOR FFh), ELSE SCREEN.Y=(1..224/239) ORG.X = (M7HOFS-M7X) AND NOT 1C00h, IF ORG.X<0 THEN ORG.X=ORG.X OR 1C00h ORG.Y = (M7VOFS-M7Y) AND NOT 1C00h, IF ORG.Y<0 THEN ORG.Y=ORG.Y OR 1C00h VRAM.X = ((M7A*ORG.X) AND NOT 3Fh) + ((M7B*ORG.Y) AND NOT 3Fh) + M7X*100h VRAM.Y = ((M7C*ORG.X) AND NOT 3Fh) + ((M7D*ORG.Y) AND NOT 3Fh) + M7Y*100h VRAM.X = VRAM.X + ((M7B*SCREEN.Y) AND NOT 3Fh) + (M7A*SCREEN.X) VRAM.Y = VRAM.Y + ((M7D*SCREEN.Y) AND NOT 3Fh) + (M7C*SCREEN.X) After calculating the left-most pixel of a scanline, the following pixels on that scanline can be also calculated by increasing VRAM coordinates as so: IF xflip THEN VRAM.X=VRAM.X-M7A, ELSE VRAM.X=VRAM.X+M7A IF xflip THEN VRAM.Y=VRAM.Y-M7C, ELSE VRAM.Y=VRAM.Y+M7C (The result is same as on hardware, although the real hardware doesn't seem to use that method, instead it seems to contain an excessively fast multiply unit that recalculates (M7A*SCREEN.X) and (M7C*SCREEN.X) on every pixel.) The VRAM coordinates are then: bit0-7=Fraction, bit8-10=pixel index (within a tile), bit11-17=map index (within BG map), bit18-and-up=nonzero when exceeding BG map size (do "screen over" handling). M7A/M7B Port Notes Port 211Bh/211Ch can be also used for general purpose math multiply: --> SNES Maths Multiply/Divide When in BG Mode 7, general purpose multiply works only during V-Blank and Forced-Blank. During drawing period at SCREEN.Y=0..224/239 (including SCREEN.Y=0, and during all 340 dots including H-Blank), MPYL/M/H receives two multiplication results per pixel (one per half-pixel): MPY = M7A * ORG.X / 8 ;at SCREEN.X=-3.0 MPY = M7D * ORG.Y / 8 ;at SCREEN.X=-2.5 MPY = M7B * ORG.Y / 8 ;at SCREEN.X=-2.0 MPY = M7C * ORG.X / 8 ;at SCREEN.X=-1.5 MPY = M7B * ((SCREEN.Y-MOSAIC.Y) XOR (yflip*FFh))/ 8 ;at SCREEN.X=-1.0 MPY = M7D * ((SCREEN.Y-MOSAIC.Y) XOR (yflip*FFh))/ 8 ;at SCREEN.X=-0.5 MPY = M7A * ((SCREEN.X AND FFh) XOR (xflip*FFh)) / 8 ;at SCREEN.X=0.0..336.0 MPY = M7C * ((SCREEN.X AND FFh) XOR (xflip*FFh)) / 8 ;at SCREEN.X=0.5..336.5 MPY = M7A * (M7B/100h) ;during in V-Blank and Forced-Blank Note: The "/8" suggests that the hardware strips the lower 3bit, however, before summing up the multiply results, it DOES strip the lower 6bit (hence the AND NOT 3Fh in the formula). M7HOVS/M7VOFS Port Notes Port 210Dh/210Eh are also used as BG1HOFS/BG1VOFS, these registers have a similar purpose, but internally they are separate registers: Writing to 210Dh does BOTH update M7HOFS (via M7_old mechanism), and also updates BG1HOFS (via BG_old mechanism). In the same fashion, 210Eh updates both M7VOFS and BG1VOFS. M7xx - Write-twice mechanism for Mode 7 Writing a byte to one of the write-twice M7'registers does: M7_reg = new * 100h + M7_old M7_old = new M7_old is an internal 8bit register, shared by 210Dh-210Eh and 211Bh-2120h. EXTBG EXTBG is an "external" BG layer (replacing BG2???) enabled via SETINI.6. On the SNES, the 8bit external input is simply shortcut with one half of the PPUs 16bit data bus. So, when using EXTBG in BG Mode 0-6, one will just see garbage. However, in BG Mode 7, it's receiving the same 8bit value as the current BG1 pixel - but, unlike BG1, with bit7 treated as priority bit (and only lower 7bit used as BG2 pixel color). SNES PPU Sprites (OBJs) ----------------------- 2101h - OBSEL - Object Size and Object Base (W) 7-5 OBJ Size Selection (0-5, see below) (6-7=Reserved) Val Small Large 0 = 8x8 16x16 ;Caution: 1 = 8x8 32x32 ;In 224-lines mode, OBJs with 64-pixel height 2 = 8x8 64x64 ;may wrap from lower to upper screen border. 3 = 16x16 32x32 ;In 239-lines mode, the same problem applies 4 = 16x16 64x64 ;also for OBJs with 32-pixel height. 5 = 32x32 64x64 6 = 16x32 32x64 (undocumented) 7 = 16x32 32x32 (undocumented) (Ie. a setting of 0 means Small OBJs=8x8, Large OBJs=16x16 pixels) (Whether an OBJ is "small" or "large" is selected by a bit in OAM) 4-3 Gap between OBJ 0FFh and 100h (0=None) (4K-word steps) (8K-byte steps) 2-0 Base Address for OBJ Tiles 000h..0FFh (8K-word steps) (16K-byte steps) Accessing OAM --> SNES Memory OAM Access (Sprite Attributes) OAM (Object Attribute Memory) Contains data for 128 OBJs. OAM Size is 512+32 Bytes. The first part (512 bytes) contains 128 4-byte entries for each OBJ: Byte 0 - X-Coordinate (lower 8bit) (upper 1bit at end of OAM) Byte 1 - Y-Coordinate (all 8bits) Byte 2 - Tile Number (lower 8bit) (upper 1bit within Attributes) Byte 3 - Attributes Attributes: Bit7 Y-Flip (0=Normal, 1=Mirror Vertically) Bit6 X-Flip (0=Normal, 1=Mirror Horizontally) Bit5-4 Priority relative to BG (0=Low..3=High) Bit3-1 Palette Number (0-7) (OBJ Palette 4-7 can use Color Math via CGADSUB) Bit0 Tile Number (upper 1bit) After above 512 bytes, additional 32 bytes follow, containing 2-bits per OBJ: Bit7 OBJ 3 OBJ Size (0=Small, 1=Large) Bit6 OBJ 3 X-Coordinate (upper 1bit) Bit5 OBJ 2 OBJ Size (0=Small, 1=Large) Bit4 OBJ 2 X-Coordinate (upper 1bit) Bit3 OBJ 1 OBJ Size (0=Small, 1=Large) Bit2 OBJ 1 X-Coordinate (upper 1bit) Bit1 OBJ 0 OBJ Size (0=Small, 1=Large) Bit0 OBJ 0 X-Coordinate (upper 1bit) And so on, next 31 bytes with bits for OBJ4..127. Note: The meaning of the OBJ Size bit (Small/Large) can be defined in OBSEL Register (Port 2101h). SNES PPU Video Memory (VRAM) ---------------------------- BG Map (32x32 entries) Each BG Map Entry consists of a 16bit value as such: Bit 0-9 - Character Number (000h-3FFh) Bit 10-12 - Palette Number (0-7) Bit 13 - BG Priority (0=Lower, 1=Higher) Bit 14 - X-Flip (0=Normal, 1=Mirror horizontally) Bit 15 - Y-Flip (0=Normal, 1=Mirror vertically) In the "Offset-per-Tile" modes (Mode 2,4,6), BG3 entries are different: Bit 15 Apply offset to H/V (0=H, 1=V) ;-Mode 4 only Bit 14 Apply offset to BG2 ;\Mode 2 (... and Mode 6, though Bit 13 Apply offset to BG1 ;/ Mode 6 has only BG1 ?) Bit 12-10 Not used Bit 9-0 Scroll offset to be applied to BG1/BG2 Lower 3bit of HORIZONTAL offsets are ignored. In mode7, BG Maps are 128x128, and only the lower 8bit are used as BG map entries: Bit15-8 Not used (contains tile-data; no relation to the BG-Map entry) Bit7-0 Character Number (00h-FFh) (without XYflip or other attributes) VRAM 8x8 Pixel Tile Data (BG and OBJ) Each 8x8 tile occupies 16, 32, or 64 bytes (for 4, 16, or 256 colors). BG tiles can be 4/16/256 colors (depending on BG Mode), OBJs are always 16 color. Color Bits (Planes) Upper Row ........... Lower Row Plane 0 stored in bytes 00h,02h,04h,06h,08h,0Ah,0Ch,0Eh ;\for 4/16/256 colors Plane 1 stored in bytes 01h,03h,05h,07h,09h,0Bh,0Dh,0Fh ;/ Plane 2 stored in bytes 10h,12h,14h,16h,18h,1Ah,1Ch,1Eh ;\for 16/256 colors Plane 3 stored in bytes 11h,13h,15h,17h,19h,1Bh,1Dh,1Fh ;/ Plane 4 stored in bytes 20h,22h,24h,26h,28h,2Ah,2Ch,2Eh ;\ Plane 5 stored in bytes 21h,23h,25h,27h,29h,2Bh,2Dh,2Fh ; for 256 colors Plane 6 stored in bytes 30h,32h,34h,36h,38h,3Ah,3Ch,3Eh ; Plane 7 stored in bytes 31h,33h,35h,37h,39h,3Bh,3Dh,3Fh ;/ In each byte, bit7 is left-most, bit0 is right-most. Plane 0 is the LSB of color number. The only exception are Mode 7 BG Tiles, which are stored as 8bit pixels (without spreading the bits across several bit-planes), and, BG VRAM is divided into BG Map at even byte addresses, and Tiles at odd addresses, an 8x8 tiles thus uses the following bytes (64 odd bytes within a 128 byte region): Vertical Rows Left-most .......... Right-Most Upper Row in bytes 01h,03h,05h,07h,09h,0Bh,0Dh,0Fh ;\ 2nd Row in bytes 11h,13h,15h,17h,19h,1Bh,1Dh,1Fh ; 3rd Row in bytes 21h,23h,25h,27h,29h,2Bh,2Dh,2Fh ; 4th Row in bytes 31h,33h,35h,37h,39h,3Bh,3Dh,3Fh ; 256-color 5th Row in bytes 41h,43h,45h,47h,49h,4Bh,4Dh,4Fh ; Mode 7 6th Row in bytes 51h,53h,55h,57h,59h,5Bh,5Dh,5Fh ; 7th Row in bytes 61h,63h,65h,67h,69h,6Bh,6Dh,6Fh ; Bottom Row in bytes 71h,73h,75h,77h,79h,7Bh,7Dh,7Fh ;/ 16x16 (and bigger) Tiles BG tiles can be up to 16x16 pixels in size, and OBJs up to 64x64. In both cases, the big tiles are combined of multiple 8x8 pixel tiles, whereas VRAM is organized as "two-dimensional" array of 16x64 BG Tiles and 16x32 OBJ Tiles: The BG Map or OAM entry contain the Tile number (N) for the upper-left 8x8 tile. The tile(s) right of that tile are N+1 (and N+2, N+3, etc). The tile(s) under that tile are N+10h (and N+20h, N+30h, etc). 32x32 pixel OBJ Tile 000h Tile000h, Tile001h, Tile002h, Tile003h Tile010h, Tile011h, Tile012h, Tile013h Tile020h, Tile021h, Tile022h, Tile023h Tile030h, Tile031h, Tile032h, Tile033h The hex-tile numbers could be thus thought of as "Yyxh", with "x" being the 4bit x-index, and "Yy" being the y-index in the array. For OBJ tiles, the are no carry-outs from "x+1" to "y", nor from "y+1" to "Y". Whilst BG tiles are processing carry-outs. For example: 16x16 BG Tile 1FFh 16x16 OBJ Tile 1FFh Tile1ffh Tile200h Tile1ffh Tile1f0h Tile20fh Tile210h Tile10fh Tile100h Accessing VRAM --> SNES Memory VRAM Access (Tile and BG Map) SNES PPU Color Palette Memory (CGRAM) and Direct Colors ------------------------------------------------------- CGRAM Palette Entries 15 Not used (should be zero) (read: PPU2 Open Bus) 14-10 Blue 9-5 Green 4-0 Red For accessing CGRAM, see: --> SNES Memory CGRAM Access (Palette Memory) CGRAM Palette Indices 00h Main Backdrop color (used when all BG/OBJ pixels are transparent) 01h-FFh 256-color BG palette (when not using direct-color mode) 01h-7Fh 128-color BG palette (BG2 in Mode 7) 01h-7Fh Eight 16-color BG palettes 01h-1Fh Eight 4-color BG palettes (except BG2-4 in Mode 0) 21h-3Fh Eight 4-color BG palettes (BG2 in Mode 0 only) 41h-5Fh Eight 4-color BG palettes (BG3 in Mode 0 only) 61h-7Fh Eight 4-color BG palettes (BG4 in Mode 0 only) 81h-FFh Eight 16-color OBJ palettes (half of them with color-math disabled) N/A Sub Backdrop color (not in CGRAM, set via COLDATA, Port 2132h) Direct Color Mode 256-color BGs (ie. BG1 in Mode 3,4,7) can be optionally set to direct-color mode (via 2130h.Bit0; this bit hides in one of the Color-Math registers, although it isn't related to Color-Math). The 8bit Color number is interpreted as "BBGGGRRR", the 3bit Palette number (from the BG Map) contains LSBs as "bgr", together they are forming a 15bit color "BBb00:RRRr0:GGGg0". Whereas the "bgr" can defined only per tile (not per pixel), and it can be defined only in BG Modes 3-4 (Mode 7 has no palette attributes in BG Map). Color Bit7-0 all zero --> Transparent ;-Color "Black" is Transparent! Color Bit7-6 Blue Bit4-3 ;\ Palette Bit 2 Blue Bit2 ; 5bit Blue N/A Blue Bit1-0 (always zero) ;/ Color Bit5-3 Green Bit4-2 ;\ Palette Bit 1 Green Bit1 ; 5bit Green N/A Green Bit0 (always zero) ;/ Color Bit2-0 Red Bit4-2 ;\ Palette Bit 0 Red Bit1 ; 5bit Red N/A Red Bit0 (always zero) ;/ To define Black, either set the Backdrop to Black (works only if there are no layers behind BG1), or use a dark non-transparent "near-black" color (eg. 01h=Dark Red, 09h=Dark Brown). Screen Border Color The Screen Border is always Black (no matter of CGRAM settings and Sub Screen Backdrop Color). NTSC 256x224 images are (more or less) fullscreen, so there should be no visible screen border (however, a 2-3 pixel border may appear at the screen edges if the screen isn't properly centered). Both PAL 256x224 and PAL 256x239 images images will have black upper and lower screen borders (a fullscreen PAL picture would be around 256x264, which isn't supported by the SNES). Forced Blank Color In Forced Blank, the whole screen is Black (no matter of CGRAM settings, Sub Screen Backdrop Color, and Master Brightness settings). Vsync/Hsync are kept generated (sending a black picture with valid Sync signals to the TV set). SNES PPU Window --------------- The window feature allows to disable BG/OBJ layers in selected regions, and also to alter Color-Math effects in selected regions. 2126h - WH0 - Window 1 Left Position (X1) (W) 2127h - WH1 - Window 1 Right Position (X2) (W) 2128h - WH2 - Window 2 Left Position (X1) (W) 2129h - WH3 - Window 2 Right Position (X2) (W) Specifies the horizontal boundaries of the windows. Note that there are no vertical boundaries (these could be implemented by manipulating the window registers via IRQ and/or HDMA). 7-0 Window Position (00h..0FFh; 0=leftmost, 255=rightmost) The "inside-window" region extends from X1 to X2 (that, including the X1 and X2 coordinates), so the window width is X2-X1+1. If the width is zero (or negative), then the "inside-window" becomes empty, and the whole screen will be treated "outside-window". 2123h - W12SEL - Window BG1/BG2 Mask Settings (W) 2124h - W34SEL - Window BG3/BG4 Mask Settings (W) 2125h - WOBJSEL - Window OBJ/MATH Mask Settings (W) Bit 2123h 2124h 2125h 7-6 BG2 BG4 MATH Window-2 Area (0..1=Disable, 1=Inside, 2=Outside) 5-4 BG2 BG4 MATH Window-1 Area (0..1=Disable, 1=Inside, 2=Outside) 3-2 BG1 BG3 OBJ Window-2 Area (0..1=Disable, 1=Inside, 2=Outside) 1-0 BG1 BG3 OBJ Window-1 Area (0..1=Disable, 1=Inside, 2=Outside) Allows to select if the window area is inside or outside the X1,X2 coordinates, or to disable the area. 212Ah/212Bh - WBGLOG/WOBJLOG - Window 1/2 Mask Logic (W) Bit 212Ah 212Bh 7-6 BG4 - Window 1/2 Mask Logic (0=OR, 1=AND, 2=XOR, 3=XNOR) 5-4 BG3 - Window 1/2 Mask Logic (0=OR, 1=AND, 2=XOR, 3=XNOR) 3-2 BG2 MATH Window 1/2 Mask Logic (0=OR, 1=AND, 2=XOR, 3=XNOR) 1-0 BG1 OBJ Window 1/2 Mask Logic (0=OR, 1=AND, 2=XOR, 3=XNOR) Allows to merge the Window 1 and 2 areas into a single "final" window area (which is then used by TMW, TSW, and CGWSEL). The OR/AND/XOR/XNOR logic is applied ONLY if BOTH window 1 and 2 are enabled (in WxxSEL registers). If only one window is enabled, then that window is used as is as "final" area. If both are disabled, then the "final" area will be empty. Note: "XNOR" means "1 XOR area1 XOR area2" (ie. the inverse of the normal XOR result). 212Eh - TMW - Window Area Main Screen Disable (W) 212Fh - TSW - Window Area Sub Screen Disable (W) 7-5 Not used 4 OBJ (0=Enable, 1=Disable) ;\"Disable" forcefully disables the layer 3 BG4 (0=Enable, 1=Disable) ; within the window area (otherwise it is 2 BG3 (0=Enable, 1=Disable) ; enabled or disabled as selected in the 1 BG2 (0=Enable, 1=Disable) ; master enable bits in port 212Ch/212Dh) 0 BG1 (0=Enable, 1=Disable) ;/ - Backdrop (Always enabled) Allows to disable video layers within the window region. SNES PPU Color-Math ------------------- Main Screen / Sub Screen Enable Main Screen and Sub Screen BG/OBJ can be enabled via Port 212Ch/212Dh (see PPU Control chapter). When using the Window feature, they can be additionally disabled in selected areas via Port 212Eh/212Fh. The Backdrops are always enabled as both Main and Sub screen. Of which, the Sub screen backdrop can be effectively disabled (made fully transparent) by setting its color to Black. The PPU computes the Front-most Non-transparent Main-Screen Pixel, and Front-most Non-transparent Sub-Screen Pixel (or if there's none, it uses the Mainscreen or Subscreen Backdrop color). 2130h - CGWSEL - Color Math Control Register A (W) 7-6 Force Main Screen Black (3=Always, 2=MathWindow, 1=NotMathWin, 0=Never) 5-4 Color Math Enable (0=Always, 1=MathWindow, 2=NotMathWin, 3=Never) 3-2 Not used 1 Sub Screen BG/OBJ Enable (0=No/Backdrop only, 1=Yes/Backdrop+BG+OBJ) 0 Direct Color (for 256-color BGs) (0=Use Palette, 1=Direct Color) 2131h - CGADSUB - Color Math Control Register B (W) 7 Color Math Add/Subtract (0=Add; Main+Sub, 1=Subtract; Main-Sub) 6 Color Math "Div2" Half Result (0=No divide, 1=Divide result by 2) 5 Color Math when Main Screen = Backdrop (0=Off, 1=On) ;\ 4 Color Math when Main Screen = OBJ/Palette4..7 (0=Off, 1=On) ; OFF: Show - Color Math when Main Screen = OBJ/Palette0..3 (Always=Off) ; Raw Main, 3 Color Math when Main Screen = BG4 (0=Off, 1=On) ; or 2 Color Math when Main Screen = BG3 (0=Off, 1=On) ; ON: Show 1 Color Math when Main Screen = BG2 (0=Off, 1=On) ; Main+/-Sub 0 Color Math when Main Screen = BG1 (0=Off, 1=On) ;/ Half-Color (Bit6): Ignored if "Force Main Screen Black" is used, also ignored on transparent subscreen pixels (those use the fixed color as sub-screen backdrop without division) (whilst 2130.1 uses the fixed color as non-transparent one, which allows division). Bit0-5: Seem to affect MAIN SCREEN layers: Disable = Display RAW Main Screen as such (without math) Enable = Apply math on Mainscreen (Ie. 212Ch enables the main screen, 2131h selects if math is applied on it) 2132h - COLDATA - Color Math Sub Screen Backdrop Color (W) This 8bit port allows to manipulate some (or all) bits of a 15bit RGB value. Examples: Black: write E0h (R,G,B=0), Cyan: write 20h (R=0) and DFh (G,B=1Fh). 7 Apply Blue (0=No change, 1=Apply Intensity as Blue) 6 Apply Green (0=No change, 1=Apply Intensity as Green) 5 Apply Red (0=No change, 1=Apply Intensity as Red) 4-0 Intensity (0..31) The Sub Screen Backdrop Color is used when all sub screen layers are disabled or transparent, in this case the "Div2" Half Color Math isn't applied (ie. 2131h.Bit6 is ignored); there is one exception: If "Sub Screen BG/OBJ Enable" is off (2130h.Bit1=0), then the "Div2" isn't forcefully ignored. For a FULLY TRANSPARENT backdrop: Set this register to Black (adding or subtracting black has no effect, and, with "Div2" disabled/ignored, the raw Main screen is displayed as is). Color Math Color Math can be disabled by setting 2130h.Bit4-5, or by clearing 2131h.Bit0-5. When it is disabled, only the Main Screen is displayed, and the Sub Screen has no effect on the display. Color Math occurs only if the front-most Main Screen pixel has math enabled (via 2131h.Bit0-5.), and only if the front-most Sub Screen pixel has same or higher (XXX or is it same or lower -- or is it ANY priority?) priority than the Main Screen pixel. Same priority means that, for example, BG1 can be mathed with itself: BG1+BG1 gives double-brightness (or same brightness when Div2 is enabled), and, BG1-BG1 gives Black. Addition/Subtraction is done per R,G,B color fragment, the results can be (optionally) divided by 2, and are then saturated to Max=31 and Min=0). Force Main Screen Black This feature forces the whole Main Screen (including Backdrop) to become black, so, normally, the whole screen becomes black. However, color addition can be still applied (but, with the "Div2" not being applied). Whereas, although it looks all black, the Main Screen is still divided into black BG1 pixels, black BG2 pixels, and so on. Of which, one can disable Color Math for some of the pixels. Color Subtraction has no effect (since the pixels can't get blacker than black). Hires and Pseudo 3-Layer Math In Hires modes (BG Mode 5,6 and Pseudo Hires via SETINI), the main/sub screen pixels are rendered as half-pixels of the high-resolution image. The TV picture is so blurry, that the result will look quite similar to Color Addition with Div2 - some games (Jurassic Park and Kirby's Dream Land 3) are actually using it for that purpose; the advantage is that one can additionally apply COLDATA addition to (both) main/sub-screen layers, ie. the result looks like "(main+sub)/2+coldata". SNES PPU Timers and Status -------------------------- 2137h - SLHV - Latch H/V-Counter by Software (R) 7-0 Not used (CPU Open Bus; usually last opcode, 21h for "MOV A,[2137h]") Reading from this register latches the current H/V counter values into OPHCT/OPVCT, Ports 213Ch and 213Dh. Reading here works "as if" dragging IO7 low (but it does NOT actually output a LOW level to IO7 on joypad 2). 213Ch - OPHCT - Horizontal Counter Latch (R) 213Dh - OPVCT - Vertical Counter Latch (R) There are three situations that do load H/V counter values into the latches: Doing a dummy-read from SLHV (Port 2137h) by software Switching WRIO (Port 4201h) Bit7 from 1-to-0 by software Lightgun High-to-Low transition (Pin6 of 2nd Controller connector) All three methods are working only if WRIO.Bit7 is (or was) set. If so, data is latched, and (in all three cases) the latch flag in 213Fh.Bit6 is set. 1st read Lower 8bit 2nd read Upper 1bit (other 7bit PPU2 open bus; last value read from PPU2) There are two separate 1st/2nd-read flipflops (one for OPHCT, one for OPVCT), both flipflops can be reset by reading from Port 213Fh (STAT78), the flipflops aren't automatically reset when latching occurs. H Counter values range from 0 to 339, with 22-277 being visible on the screen. V Counter values range from 0 to 261 in NTSC mode (262 is possible every other frame when interlace is active) and 0 to 311 in PAL mode (312 in interlace?), with 1-224 (or 1-239(?) if overscan is enabled) visible on the screen. 213Eh - STAT77 - PPU1 Status and Version Number (R) 7 OBJ Time overflow (0=Okay, 1=More than 8x34 OBJ pixels per scanline) 6 OBJ Range overflow (0=Okay, 1=More than 32 OBJs per scanline) 5 Master/Slave Mode (PPU1.Pin25) (0=Normal=Master) 4 Not used (PPU1 open bus) (same as last value read from PPU1) 3-0 PPU1 5C77 Version Number (only version 1 exists as far as I know) The overflow flags are cleared at end of V-Blank, but NOT during forced blank! The overflow flags are set (regardless of OBJ enable/disable in 212Ch), at following times: Bit6 when V=OBJ.YLOC/H=OAM.INDEX*2, bit7 when V=OBJ.YLOC+1/H=0. 213Fh - STAT78 - PPU2 Status and Version Number (R) 7 Current Interlace-Frame (0=1st, 1=2nd Frame) 6 H/V-Counter/Lightgun/Joypad2.Pin6 Latch Flag (0=No, 1=New Data Latched) 5 Not used (PPU2 open bus) (same as last value read from PPU2) 4 Frame Rate (PPU2.Pin30) (0=NTSC/60Hz, 1=PAL/50Hz) 3-0 PPU2 5C78 Version Number (version 1..3 exist as far as I know) Reading from this register also resets the latch flag (bit6), and resets the two OPHCT/OPVCT 1st/2nd-read flipflops. Lightgun Coordinates The screen coordinates (X,Y; with 0,0 = upper left) are related as so: Super Scope X=OPHCNT-40, Y=OPVCT-1 (games support software calibration) Justifier 1 X=OPHCNT-??, Y=OPVCT-? (games support software calibration) Justifier 2 X=OPHCNT-??, Y=OPVCT-? (games support software calibration) M.A.C.S. X=OPHCNT-76, Y=OPVCT-41 (hardcoded, mechanical calibration) Drawing starts at H=22, V=1 (which explains parts of the offsets). Horizontal offsets greater than 22 are explained by signal switching/transmission delays. The huge vertical offset of the M.A.C.S. gun is caused by the lightpen being mounted above of the barrel (rather than inside of it) (and apparently not parallel to it, since V>Y instead of V SNES Controllers SuperScope (Lightgun) --> SNES Controllers Konami Justifier (Lightgun) --> SNES Controllers M.A.C.S. (Lightgun) SNES PPU Interrupts ------------------- 4200h - NMITIMEN - Interrupt Enable and Joypad Request (W) 7 VBlank NMI Enable (0=Disable, 1=Enable) (Initially disabled on reset) 6 Not used 5-4 H/V IRQ (0=Disable, 1=At H=H + V=Any, 2=At V=V + H=0, 3=At H=H + V=V) 3-1 Not used 0 Joypad Enable (0=Disable, 1=Enable Automatic Reading of Joypad) Disabling IRQs (via bit4-5) does additionally acknowledge IRQs. There's no such effect when disabling NMIs (via bit7). 4207h/4208h - HTIMEL/HTIMEH - H-Count Timer Setting (W) 15-9 Not used 8-0 H-Count Timer Value (0..339) (+/-1 in long/short lines) (0=leftmost) The H/V-IRQ flag in Bit7 of TIMEUP, Port 4211h gets set when the H-Counter gets equal to the H-Count register value. 4209h/420Ah - VTIMEL/VTIMEH - V-Count Timer Setting (W) 15-9 Not used 8-0 V-Count Timer Value (0..261/311, NTSC/PAL) (+1 in interlace) (0=top) The H/V-IRQ flag in Bit7 of TIMEUP, Port 4211h gets set when the V-Counter gets equal to the V-Count register value. 4210h - RDNMI - V-Blank NMI Flag and CPU Version Number (R) (Read/Ack) 7 Vblank NMI Flag (0=None, 1=Interrupt Request) (set on Begin of Vblank) 6-4 Not used 3-0 CPU 5A22 Version Number (version 2 exists) The NMI flag gets set at begin of Vblank (this happens even if NMIs are disabled). The flag gets reset automatically at end of Vblank, and gets also reset after reading from this register. The SNES has only one NMI source (vblank), and the NMI flag is automatically reset (on vblank end), so there's normally no need to read/acknowledge the flag, except one special case: If one does disable and re-enable NMIs, then an old NMI may be executed again; acknowledging avoids that effect. The CPU includes another internal NMI flag, which gets set when "[4200h].7 AND [4210h].7" changes from 0-to-1, and gets cleared when the NMI gets executed (which should happen around after the next opcode) (if a DMA transfer is in progress, then it is somewhere after the DMA, in that case the NMI can get executed outside of the Vblank period, ie. at a time when [4210h].7 is no longer set). 4211h - TIMEUP - H/V-Timer IRQ Flag (R) (Read/Ack) 7 H/V-Count Timer IRQ Flag (0=None, 1=Interrupt Request) 6-0 Not used The IRQ flag is automatically reset after reading from this register (except when reading at the very time when the IRQ condition is true (which lasts for 4-8 master cycles), then the CPU receives bit7=1, but register bit7 isn't cleared). The flag is also automatically cleared when disabling IRQs (by setting 4200h.Bit5-4 to zero). Unlike NMI handlers, IRQ handlers MUST acknowledge IRQs, otherwise the IRQ gets executed again (ie. immediately after the RTI opcode). 4212h - HVBJOY - H/V-Blank flag and Joypad Busy flag (R) 7 V-Blank Period Flag (0=No, 1=VBlank) 6 H-Blank Period Flag (0=No, 1=HBlank) 5-1 Not used 0 Auto-Joypad-Read Busy Flag (1=Busy) (see 4200h, and 4218h..421Fh) The Hblank flag gets toggled in ALL scanlines (including during Vblank/Vsync). Both Vblank and Hblank are always toggling (even during Forced Blank, and no matter if IRQs or NMIs are enabled). Other IRQ Sources IRQs can be also triggered via Cartridge Slot and Expansion Port. This is done by cartridges with SA-1 and GSU chips (CX4 carts do also have an IRQ line, although the existing games don't seem to use it). SNES PPU Resolution ------------------- Physical Resolution The physical resolution (of the TV Screen) is: 256x224 for 60Hz (NTSC) consoles 256x264 for 50Hz (PAL) consoles The 50Hz/60Hz cannot be changed by software (it can be only changed by modding some pins on the mainboard). Normal Picture Resolution The vertical resolution is software-selectable, 224 or 239 lines: 256x224 near-fullscreen on 60Hz (NTSC) consoles (or Tiny Picture at 50Hz) 256x239 not-really-fullscreen on 50Hz (PAL) consoles (or Overscan at 60Hz) Most commonly the resolution is selected matching to the frame rate. With 60Hz Overscan the upper/lower lines are normally not visible (but may be useful to ensure that there is absolutely no upper/lower border visible, which may be important for avoiding flickering in interlace mode, especially with bright pictures; in contrast to the black screen border). 50Hz Tiny Picture would be a simple solution for porting 224-lines NTSC games to PAL, though it produces extra-big upper/lower borders. High-Resolution Modes There are some methods to double the resolution horizontally and/or vertically: True High-Resolution (BG Mode 5,6) (optionally with SETINI.0) ... Pseudo Horizontal High-Resolution (SETINI.3) ... Pseudo Vertical High-Resolution (SETINI.0) (Interlace) ... OBJ High-Resolution (SETINI.1) ... Hires Notes Horizontal BG Scrolling is always counted in full-pixels; so true-hires cannot be scrolled in half-pixel units (whilst pseudo hires may be scrolled in half-pixels by exchanging main/sub-screen layers and using different scroll offsets for each layer). Vertical BG Scrolling is counted in half-pixels (only when using true hv-hires). Mosaic is always counted in full-pixels; so a mosaic size of 1x1 (which is normally same as mosaic disabled) acts as 2x1 half-pixels in true h-hires mode (and as 2x2 half-pixels in true hv-hires mode, reportedly?) (and as 1x2 in pseudo v-hires, presumably?). Although h-hires uses main/subscreen for the half-pixels, both main/subscreen pixels are forced to use Color 0 as backdrop color (rather than using COLDATA setting as subscreen backdrop) (this applies for both true+pseudo hires). Window X1/X2 coordinates are always counted in full-pixels (reportedly with an odd glitch in hires mode?). OBJ X/Y coordinates are always counted in full-pixels. Hires Appearance Horizontal hires may appear blurred on most TV sets (due to the quality of the video signal and TV-screen, and, when not using a RGB-cable, of the composite color clock). For example, non-continous white pixels (W) on black background may appear as gray pixels (g): Source Pixels ---> TV-Screen Pixels WW W WW W W WW g WW ggg WWW W WW W W WWW g WW ggg To reproduce that by software: CenterPix=(LeftPix+CenterPix*2+RightPix)/4. Using the above example on a red background looks even worse: the "g" and "ggg" portions may be barely visible (appear as slightly pastelized red shades). Vertical hires is producing a flickering image: The scanlines jump up/down after each frame (and, due to a hardware glitch: the topmost lines also jump left/right on PAL consoles). The effect is most annoying with hard-contrast images (eg. black/white text/lines, or bright pixels close to upper/lower screen borders), it may look less annoying with blurry images (eg. photos, or anti-alized text/lines). Some modern TV sets might be buffering the even/odd frames in internal memory, and display them as flicker-free hires image(?) Hires Software Air Strike Patrol (mission overview) (whatever mode? with Interlace) Bishoujo Wrestler Retsuden (some text) (512x448, BgMode5+Interlace) Ball Bullet Gun (in lower screen half) (512x224, BgMode5) Battle Cross (in game) (but isn't hires?) (512x224, BgMode1+PseudoH)(Bug?) BS Radical Dreamers (user name input only) (512x224, BgMode5) Chrono Trigger (crash into Lavos sequence) (whatever mode? with Interlace) Donkey Kong Country 1 (Nintendo logo) (512x224, BgMode5) G.O.D. (intro & lower screen half) (512x224, BgMode5) Jurassic Park (score text) (512x224, BgMode1+PseudoH+Math) Kirby's Dream Land 3 (leaves in 1st door) (512x224, BgMode1+PseudoH) Lufia 2 (credits screen at end of game) (whatever mode?) Moryo Senki Madara 2 (text) (512x224, BgMode5) Power Drive (in intro) (512x448, BgMode5+Interlace) Ranma 1/2: Chounai Gekitou Hen (256x448, BgMode1+InterlaceBug) RPM Racing (in intro and in game) (512x448, BgMode5+Interlace) Rudra no Hihou (RnH/Treasure of the Rudras)(512x224, BgMode5) Seiken Densetsu 2 (Secret of Mana) (setup) (512x224, BgMode5) Seiken Densetsu 3 (512x224, BgMode5) Shock Issue 1 & 2 (homebrew eZine) (512x224, BgMode5) SNES Test Program (by Nintendo) (Character Test includes BgMode5/BgMode6) Super Play Action Football (text) (512x224, BgMode5) World Cup Striker (intro/menu) (512x224, BgMode5) And, reportedly (may be incorrect, unknown how to see hires in that games): Dragonball Z Super Butoden 2-3 (when you start it up in the black screen?) Notes: Ranma is actually only 256x224 (but does accidentally have interlace enabled, which causes some totally useless flickering). Jurassic/Kirby are misusing PseudoH for "blending" the main+sub screen layers (via the blurry TV picture); this allows to use Color Math for coldata additions (ie. resulting in 3-color blending: main+sub+coldata). 3D Software --> SNES 3D Glasses SNES PPU Offset-Per-Tile Mode ----------------------------- XXX - Under construction (see Anomie's docs for now) Offset-Per-Tile Mode is used by following Programs Chrono Trigger (title screen, intro's "Black Omen" appearing) Star Fox/Starwing (to "rotate" the landscape background) Tetris Attack Yoshi's Island (dizziness effect, wavy lava) SNES Audio Processing Unit (APU) -------------------------------- Overview --> SNES APU Memory and I/O Map --> SNES APU Block Diagram SPC700 CPU --> SNES APU SPC700 CPU Overview --> SNES APU SPC700 CPU Load/Store Commands --> SNES APU SPC700 CPU ALU Commands --> SNES APU SPC700 CPU Jump/Control Commands I/O Ports --> SNES APU SPC700 I/O Ports --> SNES APU Main CPU Communication Port --> SNES APU DSP BRR Samples --> SNES APU DSP BRR Pitch --> SNES APU DSP ADSR/Gain Envelope --> SNES APU DSP Volume Registers --> SNES APU DSP Control Registers --> SNES APU DSP Echo Registers Pinouts/Misc --> SNES APU Low Level Timings --> SNES Audio/Video Connector Pinouts --> SNES Pinouts APU Chips SNES APU Memory and I/O Map --------------------------- SPC700 Memory Map 0000h..00EFh RAM (typically used for CPU pointers/variables) 00F0h..00FFh I/O Ports (writes are also passed to RAM) 0100h..01FFh RAM (typically used for CPU stack) 0200h..FFBFh RAM (code, data, dir-table, brr-samples, echo-buffer, etc.) FFC0h..FFFFh 64-byte Boot ROM or RAM (selectable via Port 00F1h) Audio-related Registers on Main CPU The main CPU has four write-only 8bit outputs, and (mapped to the same addresses) four read-only 8bit inputs: 2140h - APUI00 - Main CPU to Sound CPU Communication Port 0 2141h - APUI01 - Main CPU to Sound CPU Communication Port 1 2142h - APUI02 - Main CPU to Sound CPU Communication Port 2 2143h - APUI03 - Main CPU to Sound CPU Communication Port 3 The registers are used to communicate with Port 00F4h..00F7h on the SPC700 CPU (on power-up, this is done using a 64-byte BIOS in the SPC700). Note: All CPU-APU communications are passed through these registers by software, there are no additional communication methods (like IRQs). SPC700 I/O Ports The SPC700 CPU includes 16 memory mapper ports at address 00F0h..00FFh: 00F0h - TEST - Testing functions (W) 0Ah 00F1h - CONTROL - Timer, I/O and ROM Control (W) 80h 00F2h - DSPADDR - DSP Register Index (R/W) (FFh) 00F3h - DSPDATA - DSP Register Data (R/W) (DSP[7Fh]) 00F4h - CPUIO0 - CPU Input and Output Register 0 (R and W) R=00h,W=00h 00F5h - CPUIO1 - CPU Input and Output Register 1 (R and W) R=00h,W=00h 00F6h - CPUIO2 - CPU Input and Output Register 2 (R and W) R=00h,W=00h 00F7h - CPUIO3 - CPU Input and Output Register 3 (R and W) R=00h,W=00h 00F8h - AUXIO4 - External I/O Port P4 (S-SMP Pins 34-27) (R/W) (unused) FFh 00F9h - AUXIO5 - External I/O Port P5 (S-SMP Pins 25-18) (R/W) (unused) FFh 00FAh - T0DIV - Timer 0 Divider (for 8000Hz clock source) (W) (FFh) 00FBh - T1DIV - Timer 1 Divider (for 8000Hz clock source) (W) (FFh) 00FCh - T2DIV - Timer 2 Divider (for 64000Hz clock source) (W) (FFh) 00FDh - T0OUT - Timer 0 Output (R) (00h) 00FEh - T1OUT - Timer 1 Output (R) (00h) 00FFh - T2OUT - Timer 2 Output (R) (00h) DSP Registers The 128 DSP Registers are indirectly accessed via SPC700 Ports 00F2h/00F3h. ("x" can be 0..7, for selecting one of the 8 voices, or of the 8 filters). x0h - VxVOLL - Left volume for Voice 0..7 (R/W) x1h - VxVOLR - Right volume for Voice 0..7 (R/W) x2h - VxPITCHL - Pitch scaler for Voice 0..7, lower 8bit (R/W) x3h - VxPITCHH - Pitch scaler for Voice 0..7, upper 6bit (R/W) x4h - VxSRCN - Source number for Voice 0..7 (R/W) x5h - VxADSR1 - ADSR settings for Voice 0..7, lower 8bit (R/W) x6h - VxADSR2 - ADSR settings for Voice 0..7, upper 8bit (R/W) x7h - VxGAIN - Gain settings for Voice 0..7 (R/W) x8h - VxENVX - Current envelope value for Voice 0..7 (R) x9h - VxOUTX - Current sample value for Voice 0..7 (R) xAh - NA - Unused (8 bytes of general-purpose RAM) (R/W) xBh - NA - Unused (8 bytes of general-purpose RAM) (R/W) 0Ch - MVOLL - Left channel master volume (R/W) 1Ch - MVOLR - Right channel master volume (R/W) 2Ch - EVOLL - Left channel echo volume (R/W) 3Ch - EVOLR - Right channel echo volume (R/W) 4Ch - KON - Key On Flags for Voice 0..7 (W) 5Ch - KOFF - Key Off Flags for Voice 0..7 (R/W) 6Ch - FLG - Reset, Mute, Echo-Write flags and Noise Clock (R/W) 7Ch - ENDX - Voice End Flags for Voice 0..7 (R) (W=Ack) 0Dh - EFB - Echo feedback volume (R/W) 1Dh - NA - Unused (1 byte of general-purpose RAM) (R/W) 2Dh - PMON - Pitch Modulation Enable Flags for Voice 1..7 (R/W) 3Dh - NON - Noise Enable Flags for Voice 0..7 (R/W) 4Dh - EON - Echo Enable Flags for Voice 0..7 (R/W) 5Dh - DIR - Sample table address (R/W) 6Dh - ESA - Echo ring buffer address (R/W) 7Dh - EDL - Echo delay (ring buffer size) (R/W) xEh - NA - Unused (8 bytes of general-purpose RAM) (R/W) xFh - FIRx - Echo FIR filter coefficient 0..7 (R/W) Register 80h..FFh are read-only mirrors of 00h..7Fh. Technically, the DSP registers are a RAM-like 128-byte buffer; and are copied to internal registers when needed. At least some registers (KON and FLG) seem to have changed-flags (and the buffer-values are processed only when the flag is set), ENDX seems to be a real register (not using the RAM-like buffer). Upon Reset, FLG is internally set to E0h (but reading the buffered DSP[6Ch] value return garbage. The 17 status register are updated (a few cycles after reset) to ENDX=FFh, ENVx=00h, OUTx=00h. Aside from ENDX/ENVx/OUTx, all other DSP registers contain garbage. Upon Power-up, that garbage randomly "tends" to some patterns, but those patterns change from day to day (some examples: one day all registers were set to 43h, on other days, the eight FIRx were all FFh, and other registers had whichever values). APU RAM Upon power-up, APU RAM tends to contain a stable repeating 64-byte pattern: 32x00h, 32xFFh (that, for APUs with two Motorola MCM51L832F12 32Kx8 SRAM chips; other consoles may use different chips with different garbage/patterns). After Reset, the boot ROM changes [0000h..0001h]=Entrypoint, and [0002h..00EFh]=00h). SNES APU Block Diagram ---------------------- DSP Voice Block Diagram (n=voice, 0..7) OUTx(n-1) PITCHn PMON | ADSRn/ENV |____MUL___| | DIR*256 | +-------------------------------> ENVxn +SRCn*4 | | .-----------------> OUTxn _____ _______ __V___ | | _____ | | | BRR | | BRR | | _____ | |VOLnL| | RAM |--->|Decoder|--->| Time |---o '-->| | | .-->| MUL |---> Ln |_____| |_______| |______| \ | MUL | | | |_____| ______ NONn o--->| |---+---+ _____ | Noise| |_____| | |VOLnR| | Time |---o '-->| MUL |---> Rn |______| |_____| ^ | FLG DSP Mixer/Reverb Block Diagram (c=channel, L/R) ________ _____ _____ c0 --->| ADD | |MVOLc| Master Volume | | c1 --->| Output |--------------------->| MUL |---------------->| | c2 --->| Mixing | |_____| | | c3 --->| | _____ | ADD |--> c c4 --->| | |EVOLc| Echo Volume | | c5 --->| | Feedback .------>| MUL |---------------->| | c6 --->| | Volume | |_____| |_____| c7 --->|________| _____ | _________________ | EFB | | | | EON ________ | MUL |<---+---------------------| Add FIR Sum | c0 -:->| | |_____| |_________________| c1 -:->| | | _|_|_|_|_|_|_|_|_ c2 -:->| | | | MUL FIR7..0 | c3 -:->| | | ESA=Addr, EDL=Len |_7_6_5_4_3_2_1_0_| c4 -:->| ADD | __V__ FLG _______________ _|_|_|_|_|_|_|_|_ c5 -:->| Echo | | | ECEN | Echo Buffer c | | FIR Buffer c | c6 -:->| Mixing |-->| ADD |--:-->| RAM |-->| (Hardware regs) | c7 -:->|________| |_____| |_______________| |_________________| Newest --> Oldest Newest --> Oldest External Sound Output & Input _____ _____ ___________ _______ _______ | | | | | Pre- | | | | Post- | | DSP |-->| D/A |-->| Amplifier |-->| Analog|-->| Ampl. |--> Multi-Out |_____| |_____| |___________| | Mixer | | | (Stereo Out) | | | | (with | | Cartridge Slot Stereo In --->| | | phase |--> TV Modulator | | | | inver-| (Mono Out) | Expansion Port Stereo In --->| | | sion) | | |_______| | |--> Expansion Port | /MUTE signal | | | (Mono Out) '------------------------------->----' |_______| Note: The Cartridge Audio input is used only by SGB and MSU1. Unknown if it is also used by X-Band modem (for injecting dial/connection sounds)? The Expansion port input might be used by the Satellaview (?) and SNES CD prototype. The Nintendo Super System (NSS) also allows to mute the SNES sound via its Z80 CPU. SNES APU SPC700 CPU Overview ---------------------------- The sound unit is controlled by a S-SMP chip: an 8bit CPU that uses Sony's SPC700 instruction set. The SPC700's opcodes and it's three main registers (A,X,Y) are clearly inspired by 6502 instruction set, although the opcodes are numbered differently, and it has some new/changed instructions. Aside from the SNES sound processor, the SPC700 is also found in Sony's CXP8nnnn single-chip microprocessors. Another variant, called SPC700 alpha II, is also found in their CXP7nnnn chips, which have only 211 opcodes (two less than the normal SPC700). Registers A 8bit accumulator X 8bit index Y 8bit index SP 8bit stack pointer (addresses memory at 0100h..01FFh) PSW 8bit flags YA 16bit combination of Y=MSB, and A=LSB PC 16bit program counter Flags (PSW) Bit7 N Sign Flag (0=Positive, 1=Negative) Bit6 V Overflow Flag (0=None, 1=Overflow) Bit5 P Zero Page Location (0=00xxh, 1=01xxh) Bit4 B Break Flag (0=Reset, 1=BRK opcode; set BRK opcode) Bit3 H Half-carry (0=Borrow, or no-carry, 1=Carry, or no-borrow) Bit2 I Interrupt Enable (0=Disable, 1=Enable) (no function in SNES APU) Bit1 Z Zero Flag (0=Non-zero, 1=Zero) Bit0 C Carry Flag (0=Borrow, or no-carry, 1=Carry, or no-borrow) Addressing Modes Native Syntax Nocash Syntax aa [aa] ;\addresses memory at [0000..00FF] aa+X [aa+X] ; (or at [0100..01FF when flag P=1) aa+Y [aa+Y] ; (aa+X and aa+Y wrap within that area, (X) [X] ; ie. addr = (aa+X) AND 0FFh) (Y) [Y] ;/ aaaa [aaaa] ;\ aaaa+X [aaaa+X] ; addresses memory at [0000..FFFF] aaaa+Y [aaaa+Y] ;/ [aa]+Y [[aa]+Y] ;-Byte[Word[aa]+Y] ;\double-indirect (using [aa+X] [[aa+X]] ;-Byte[Word[aa+X]] ;/16bit pointer in RAM) aa.b [aa].b ;-Bit0..7 of address [0000..00FF] (8bit addr) aaa.b [aaa].b ;-Bit0..7 of address [0000..1FFF] (13bit addr) stack (push/pop/call/ret) ;-addresses memory at [0100..01FF] (SP+100h) Formatting of Command Descriptions Native Syntax Nocash Syntax Opcode Clk Expl NVPBHIZC SNES APU SPC700 CPU Load/Store Commands --------------------------------------- Register Manipulation MOV A,#nn MOV A,nn E8 nn 2 A=nn N.....Z. MOV X,#nn MOV X,nn CD nn 2 X=nn N.....Z. MOV Y,#nn MOV Y,nn 8D nn 2 Y=nn N.....Z. MOV A,X MOV A,X 7D 2 A=X N.....Z. MOV X,A MOV X,A 5D 2 X=A N.....Z. MOV A,Y MOV A,Y DD 2 A=Y N.....Z. MOV Y,A MOV Y,A FD 2 Y=A N.....Z. MOV X,SP MOV X,SP 9D 2 X=SP N.....Z. MOV SP,X MOV SP,X BD 2 SP=X ;at 0100..01FF ........ Memory Load MOV A,aa MOV A,[aa] E4 aa 3 A=[aa] N.....Z. MOV A,aa+X MOV A,[aa+X] F4 aa 4 A=[aa+X] N.....Z. MOV A,!aaaa MOV A,[aaaa] E5 aa aa 4 A=[aaaa] N.....Z. MOV A,!aaaa+X MOV A,[aaaa+X] F5 aa aa 5 A=[aaaa+X] N.....Z. MOV A,!aaaa+Y MOV A,[aaaa+Y] F6 aa aa 5 A=[aaaa+Y] N.....Z. MOV A,(X) MOV A,[X] E6 3 A=[X] N.....Z. MOV A,(X)+ MOV A,[X]+ BF 4 A=[X], X=X+1 N.....Z. MOV A,[aa]+Y MOV A,[[aa]+Y] F7 aa 6 A=[[aa]+Y] N.....Z. MOV A,[aa+X] MOV A,[[aa+X]] E7 aa 6 A=[[aa+X]] N.....Z. MOV X,aa MOV X,[aa] F8 aa 3 X=[aa] N.....Z. MOV X,aa+Y MOV X,[aa+Y] F9 aa 4 X=[aa+Y] N.....Z. MOV X,!aaaa MOV X,[aaaa] E9 aa aa 4 X=[aaaa] N.....Z. MOV Y,aa MOV Y,[aa] EB aa 3 Y=[aa] N.....Z. MOV Y,aa+X MOV Y,[aa+X] FB aa 4 Y=[aa+X] N.....Z. MOV Y,!aaaa MOV Y,[aaaa] EC aa aa 4 Y=[aaaa] N.....Z. MOVW YA,aa MOVW YA,[aa] BA aa 5 YA=Word[aa] N.....Z. Memory Store MOV aa,#nn MOV [aa],nn 8F nn aa 5 [aa]=nn (read) ........ MOV aa,bb MOV [aa],[bb] FA bb aa 5 [aa]=[bb] (no read) ........ MOV aa,A MOV [aa],A C4 aa 4 [aa]=A (read) ........ MOV aa,X MOV [aa],X D8 aa 4 [aa]=X (read) ........ MOV aa,Y MOV [aa],Y CB aa 4 [aa]=Y (read) ........ MOV aa+X,A MOV [aa+X],A D4 aa 5 [aa+X]=A (read) ........ MOV aa+X,Y MOV [aa+X],Y DB aa 5 [aa+X]=Y (read) ........ MOV aa+Y,X MOV [aa+Y],X D9 aa 5 [aa+Y]=X (read) ........ MOV !aaaa,A MOV [aaaa],A C5 aa aa 5 [aaaa]=A (read) ........ MOV !aaaa,X MOV [aaaa],X C9 aa aa 5 [aaaa]=X (read) ........ MOV !aaaa,Y MOV [aaaa],Y CC aa aa 5 [aaaa]=Y (read) ........ MOV !aaaa+X,A MOV [aaaa+X],A D5 aa aa 6 [aaaa+X]=A (read) ........ MOV !aaaa+Y,A MOV [aaaa+Y],A D6 aa aa 6 [aaaa+Y]=A (read) ........ MOV (X)+,A MOV [X]+,A AF 4 [X]=A, X=X+1 (no read) ........ MOV (X),A MOV [X],A C6 4 [X]=A (read) ........ MOV [aa]+Y,A MOV [[aa]+Y],A D7 aa 7 [[aa]+Y]=A (read) ........ MOV [aa+X],A MOV [[aa+X]],A C7 aa 7 [[aa+X]]=A (read) ........ MOVW aa,YA MOVW [aa],YA DA aa 5 Word[aa]=YA (read lsb)........ Most of the Memory Store opcodes are implemented like ALU opcodes (ie. as RMW opcodes, issuing a dummy read from the destination address). In result, they are a bit slower than necessary, and they can trigger read-sensitive I/O ports (namely the TnOUT registers in the SNES). Only exceptions are opcodes AFh and FAh (which don't include any dummy read), and opcode DAh (which performs the dummy read only on the LSB of the 16bit Word). Push/Pop PUSH A PUSH A 2D 4 [SP]=A, SP=SP-1 ........ PUSH X PUSH X 4D 4 [SP]=X, SP=SP-1 ........ PUSH Y PUSH Y 6D 4 [SP]=Y, SP=SP-1 ........ PUSH PSW PUSH PSW 0D 4 [SP]=Flags, SP=SP-1 ........ POP A POP A AE 4 SP=SP+1, A=[SP] ........ POP X POP X CE 4 SP=SP+1, X=[SP] ........ POP Y POP Y EE 4 SP=SP+1, Y=[SP] ........ POP PSW POP PSW 8E 4 SP=SP+1, Flags=[SP] NVPBHIZC SNES APU SPC700 CPU ALU Commands -------------------------------- 8bit ALU Operations OR a,b OR a,b 00+x ... .. a=a OR b N.....Z. AND a,b AND a,b 20+x ... .. a=a AND b N.....Z. EOR a,b XOR a,b 40+x ... .. a=a XOR b N.....Z. CMP a,b CMP a,b 60+x ... .. a-b N.....ZC ADC a,b ADC a,b 80+x ... .. a=a+b+C NV..H.ZC SBC a,b SBC a,b A0+x ... .. a=a-b-not C NV..H.ZC Above OR/AND/EOR/CMP/ADC/SBC can be used with following operands: cmd A,#nn cmd A,nn x+08 nn 2 A,nn cmd A,(X) cmd A,[X] x+06 3 A,[X] cmd A,aa cmd A,[aa] x+04 aa 3 A,[aa] cmd A,aa+X cmd A,[aa+X] x+14 aa 4 A,[aa+X] cmd A,!aaaa cmd A,[aaaa] x+05 aa aa 4 A,[aaaa] cmd A,!aaaa+X cmd A,[aaaa+X] x+15 aa aa 5 A,[aaaa+X] cmd A,!aaaa+Y cmd A,[aaaa+Y] x+16 aa aa 5 A,[aaaa+Y] cmd A,[aa]+Y cmd A,[[aa]+Y] x+17 aa 6 A,[[aa]+Y] cmd A,[aa+X] cmd A,[[aa+X]] x+07 aa 6 A,[[aa+X]] cmd aa,bb cmd [aa],[bb] x+09 bb aa 6 [aa],[bb] cmd aa,#nn cmd [aa],nn x+18 nn aa 5 [aa],nn cmd (X),(Y) cmd [X],[Y] x+19 5 [X],[Y] Compare can additionally have the following forms: CMP X,#nn CMP X,nn C8 nn 2 X-nn N.....ZC CMP X,aa CMP X,[aa] 3E aa 3 X-[aa] N.....ZC CMP X,!aaaa CMP X,[aaaa] 1E aa aa 4 X-[aaaa] N.....ZC CMP Y,#nn CMP Y,nn AD nn 2 Y-nn N.....ZC CMP Y,aa CMP Y,[aa] 7E aa 3 Y-[aa] N.....ZC CMP Y,!aaaa CMP Y,[aaaa] 5E aa aa 4 Y-[aaaa] N.....ZC Note: There's also a compare and jump if non-zero command (see jumps). 8bit Increment/Decrement and Rotate/Shift Commands ASL a SHL a 00+x .. .. Left shift, bit0=0 N.....ZC ROL a RCL a 20+x .. .. Left shift, bit0=C N.....ZC LSR a SHR a 40+x .. .. Right shift, bit7=0 N.....ZC ROR a RCR a 60+x .. .. Right shift, bit7=C N.....ZC DEC a DEC a 80+x .. .. a=a-1 N.....Z. INC a INC a A0+x .. .. a=a+1 N.....Z. The Increment/Decrement and Rotate/Shift commands can have following forms: cmd A cmd A x+1C 2 A cmd X cmd X x+1D-80 2 X ;\increment/decrement only cmd Y cmd Y x+DC-80 2 Y ;/(not rotate/shift) cmd aa cmd [aa] x+0B aa 4 [aa] cmd aa+X cmd [aa+X] x+1B aa 5 [aa+X] cmd !aaaa cmd [aaaa] x+0C aa aa 5 [aaaa] Note: There's also a decrement and jump if non-zero command (see jumps). 16bit ALU Operations ADDW YA,aa ADDW YA,[aa] 7A aa 5 YA=YA+Word[aa] NV..H.ZC SUBW YA,aa SUBW YA,[aa] 9A aa 5 YA=YA-Word[aa] NV..H.ZC CMPW YA,aa CMPW YA,[aa] 5A aa 4 YA-Word[aa] N.....ZC INCW aa INCW [aa] 3A aa 6 Word[aa]=Word[aa]+1 N.....Z. DECW aa DECW [aa] 1A aa 6 Word[aa]=Word[aa]-1 N.....Z. DIV YA,X DIV YA,X 9E 12 A=YA/X, Y=YA MOD X NV..H.Z. MUL YA MUL YA CF 9 YA=Y*A, NZ on Y only N.....Z. For ADDW/SUBW, H is carry from bit11 to bit12. 1bit ALU Operations CLR1 aa.b CLR [aa].b b*20+12 aa 4 [aa].bit_b=0 ........ SET1 aa.b SET [aa].b b*20+02 aa 4 [aa].bit_b=1 ........ NOT1 aaa.b NOT [aaa].b EA aa ba 5 invert [aaa].bit_b ........ MOV1 aaa.b,C MOV [aaa].b,C CA aa ba 6 [aaa].bit_b=C ........ MOV1 C,aaa.b MOV C,[aaa].b AA aa ba 4 C=[aaa].bit_b .......C OR1 C,aaa.b OR C,[aaa].b 0A aa ba 5 C=C OR [aaa].bit_b .......C OR1 C,/aaa.b OR C,not[].b 2A aa ba 5 C=C OR not[aaa].bit_b .......C AND1 C,aaa.b AND C,[aaa].b 4A aa ba 4 C=C AND [aaa].bit_b .......C AND1 C,/aaa.b AND C,not[].b 6A aa ba 4 C=C AND not[aaa].bit_b .......C EOR1 C,aaa.b XOR C,[aaa].b 8A aa ba 5 C=C XOR [aaa].bit_b .......C CLRC CLR C 60 2 C=0 .......0 SETC SET C 80 2 C=1 .......1 NOTC NOT C ED 3 C=not C .......C CLRV CLR V,H E0 2 V=0, H=0 .0..0... Special ALU Operations DAA A DAA A DF 3 BCD adjust after ADC N.....ZC DAS A DAS A BE 3 BCD adjust after SBC N.....ZC XCN A XCN A 9F 5 A = (A>>4) | (A<<4) N.....Z. TCLR1 !aaaa TCLR [aaaa],A 4E aa aa 6 [aaaa]=[aaaa]AND NOT A N.....Z. TSET1 !aaaa TSET [aaaa],A 0E aa aa 6 [aaaa]=[aaaa]OR A N.....Z. For TCLR/TSET, Z+N flags are set as for "CMP A,[aaaa]" (before [aaaa] gets changed). Reportedly, TCLR/TSET can access only 0000h..7FFFh, that is nonsense. SNES APU SPC700 CPU Jump/Control Commands ----------------------------------------- Conditional Jumps BPL dest JNS dest 10 rr 2/4 if N=0 --> JR dest ........ BMI dest JS dest 30 rr 2/4 if N=1 --> JR dest ........ BVC dest JNO dest 50 rr 2/4 if V=0 --> JR dest ........ BVS dest JO dest 70 rr 2/4 if V=1 --> JR dest ........ BCC dest JNC dest 90 rr 2/4 if C=0 --> JR dest ........ BCS dest JC dest B0 rr 2/4 if C=1 --> JR dest ........ BNE dest JNZ dest D0 rr 2/4 if Z=0 --> JR dest ........ BEQ dest JZ dest F0 rr 2/4 if Z=1 --> JR dest ........ BBS aa.b,dest JNZ [aa].b,dest b*20+03 aa rr 5/7 if [aa].bit_b=1 -> ........ BBC aa.b,dest JZ [aa].b,dest b*20+13 aa rr 5/7 if [aa].bit_b=0 -> ........ CBNE aa,dest CJNE A,[aa],d 2E aa rr 5/7 if A<>[aa] --> ........ CBNE aa+X,dest CJNE A,[aa+X],d DE aa rr 6/8 if A<>[aa+X] --> ........ DBNZ Y,dest DJNZ Y,dest FE rr 4/6 Y=Y-1, if Y<>0 --> ........ DBNZ aa,dest DJNZ [aa],dest 6E aa rr 5/7 [aa]=[aa]-1, if .. ........ Aliases: JZ=JE, JNZ=JNE, JC=JAE, JNC=JB. Normal Jumps/Calls BRA dest JR dest 2F rr 4 PC=PC+/-rr ........ JMP !aaaa JMP aaaa 5F aa aa 3 PC=aaaa ........ JMP [!aaaa+X] JMP [aaaa+X] 1F aa aa 6 PC=Word[a+X] ........ CALL !aaaa CALL aaaa 3F aa aa 8 [S-1]=PC,S=S-2,PC=aaaa ........ TCALL n CALL [FFnn] n1 ;n=0..F 8 Push PC, PC=[FFDE-n*2] ........ PCALL uu PCALL FFnn 4F nn 6 Push PC, PC=FF00..FFFF ........ RET RET 6F 5 PC=[S+1],S=S+2 ........ RET1 RETI 7F 6 Pop Flags, PC NVPBHIZC BRK BRK 0F 8 Push $+1,PSW,PC=[FFDE] ...1.0.. /RESET /RESET - ? PC=[FFFEh] ..00.0.. Note: Calls are pushing the exact retadr (unlike 6502, which pushes retadr-1). Wait/Delay/Control NOP NOP 00 2 do nothing ........ SLEEP SLEEP EF ? Halts the processor ........ STOP STOP FF ? Halts the processor ........ CLRP CLR P 20 2 P=0 ;zero page at 00aa ..0..... SETP SET P 40 2 P=1 ;zero page at 01aa ..1..... EI EI A0 3 I=1 ;interrupt enable .....1.. DI DI C0 3 I=0 ;interrupt disable .....0.. Note: The SNES APU doesn't have any interrupt sources, so SLEEP/STOP will hang the CPU forever, and DI/EI have no effect (other than changing to I-flag in PSW). SNES APU SPC700 I/O Ports ------------------------- 00F0h - TEST - Testing functions (W) 0 Timer-Enable (0=Normal, 1=Timers don't work) 1 RAM Write Enable (0=Disable/Read-only, 1=Enable SPC700 & S-DSP writes) 2 Crash SPC700 (0=Normal, 1=Crashes the CPU) 3 Timer-Disable (0=Timers don't work, 1=Normal) 4-5 Waitstates on RAM Access (0..3 = 0/1/4/9 cycles) (0=Normal) 6-7 Waitstates on I/O and ROM Access (0..3 = 0/1/4/9 cycles) (0=Normal) Default setting is 0Ah, software should never change this register. Normal memory access time is 1 cycle (adding 0/1/4/9 waits gives access times of 1/2/5/10 cycles). Using 4 or 9 waits doesn't work with some opcodes (0 or 1 waits seem to work stable). Internal cycles (those that do not access RAM, ROM, nor I/O) are either using the RAM or I/O access time (see notes at bottom of this chapter). 00F1h - CONTROL - Timer, I/O and ROM Control (W) 0-2 Timer 0-2 Enable (0=Disable, set TnOUT=0 & reload divider, 1=Enable) 3 Not used 4 Reset Port 00F4h/00F5h Input-Latches (0=No change, 1=Reset to 00h) 5 Reset Port 00F6h/00F7h Input-Latches (0=No change, 1=Reset to 00h) Note: The CPUIO inputs are latched inside of the SPC700 (at time when the Main CPU writes them), above two bits allow to reset these latches. 6 Not used 7 ROM at FFC0h-FFFFh (0=RAM, 1=ROM) (writes do always go to RAM) On power on or reset, it seems to be set to B0h. 00F2h - DSPADDR - DSP Register Index (R/W) 0-7 DSP Register Number (usually 00h..7Fh) (80h..FFh are read-only mirrors) 00F3h - DSPDATA - DSP Register Data (R/W) 0-7 DSP Register Data (read/write the register selected via Port 00F2h) 00F4h - CPUIO0 - CPU Input and Output Register 0 (R and W) 00F5h - CPUIO1 - CPU Input and Output Register 1 (R and W) 00F6h - CPUIO2 - CPU Input and Output Register 2 (R and W) 00F7h - CPUIO3 - CPU Input and Output Register 3 (R and W) These registers are used in communication with the 5A22 S-CPU. There are eight total registers accessed by these four addresses: four write-only output ports to the S-CPU and four read-only input ports from the S-CPU. 0-7 Data written to/read from corresponding register on main 5A22 CPU If the SPC700 writes to an output port while the S-CPU is reading it, the S-CPU will read the logical OR of the old and new values. Possibly the same thing happens the other way around, but the details are unknown? 00F8h - AUXIO4 - External I/O Port P4 (S-SMP Pins 34-27) (R/W) (unused) 00F9h - AUXIO5 - External I/O Port P5 (S-SMP Pins 25-18) (R/W) (unused) Writing changes the output levels. Reading normally returns the same value as the written value; unless external hardware has pulled the pins LOW or HIGH. Reading from AUXIO5 additionally produces a short /P5RD read signal (Pin17). 0-7 Input/Output levels (0=Low, 1=High) In the SNES, these pins are unused (not connected), so the registers do effectively work as if they'd be "RAM-like" general purpose storage registers. 00FAh - T0DIV - Timer 0 Divider (for 8000Hz clock source) (W) 00FBh - T1DIV - Timer 1 Divider (for 8000Hz clock source) (W) 00FCh - T2DIV - Timer 2 Divider (for 64000Hz clock source) (W) 0-7 Divider (01h..FFh=Divide by 1..255, or 00h=Divide by 256) If timers are enabled (via Port 00F1h), then the TnOUT registers are incremented at the selected rate (ie. the 8kHz or 64kHz clock source, divided by the selected value). 00FDh - T0OUT - Timer 0 Output (R) 00FEh - T1OUT - Timer 1 Output (R) 00FFh - T2OUT - Timer 2 Output (R) 0-3 Incremented at the rate selected via TnDIV (reset to 0 after reading) 4-7 Not used (always zero) SPC700 Waitstates on Internal Cycles Below lists the number of I/O-Waitstates applied on Internal Cycles of SPC700 opcodes 00h..FFh (that implies: any further Internal Cycles have RAM-Waitstates). 00..1F 0,3,0,1,0,0,0,1,0,0,1,0,0,1,0,2, 2,3,0,3,1,1,1,1,0,0,0,1,0,0,0,1 20..3F 0,3,0,1,0,0,0,1,0,0,1,0,0,1,3,2, 0,3,0,3,1,1,1,1,0,0,0,1,0,0,0,3 40..5F 0,3,0,1,0,0,0,1,0,0,0,0,0,1,0,3, 2,3,0,3,1,1,1,1,0,0,0,1,0,0,0,0 60..7F 0,3,0,1,0,0,0,1,0,1,0,0,0,1,2,1, 0,3,0,3,1,1,1,1,1,1,1,1,0,0,0,1 80..9F 0,3,0,1,0,0,0,1,0,0,1,0,0,0,1,0, 2,3,0,3,1,1,1,1,0,0,1,1,0,0,10,3 A0..BF 1,3,0,1,0,0,0,1,0,0,0,0,0,0,1,1, 0,3,0,3,1,1,1,1,0,0,1,1,0,0,1,1 C0..DF 1,3,0,1,0,0,0,1,0,0,1,0,0,0,1,7, 2,3,0,3,1,1,1,1,0,1,0,1,0,0,4,1 E0..FF 0,3,0,1,0,0,0,1,0,0,0,0,0,1,1,0, 0,3,0,3,1,1,1,1,0,1,0,1,0,0,3,0 Note: For conditional jumps (with condition=true), add 2 additional cylces. That is, the above list_entries are meant to be used like so: number_of_I/O_waits = list_entry number_of_RAM_waits = total_number_of_internal_cycles - list_entry For example, Opcode 00h (NOP) has one internal cycle (and it's having RAM timings). Opcode 01h (TCALL) has 3 internal cycles (and all 3 of them have I/O timings). SNES APU Main CPU Communication Port ------------------------------------ 2140h - APUI00 - Main CPU to Sound CPU Communication Port 0 (R/W) 2141h - APUI01 - Main CPU to Sound CPU Communication Port 1 (R/W) 2142h - APUI02 - Main CPU to Sound CPU Communication Port 2 (R/W) 2143h - APUI03 - Main CPU to Sound CPU Communication Port 3 (R/W) 7-0 APU I/O Data (Write: Data to APU, Read: Data from APU) Caution: These registers should be written only in 8bit mode (there is a hardware glitch that can cause a 16bit write to [2140h..2141h] to destroy [2143h], this might happen only in some situations, like when the cartridge contains too many ROM chips which apply too much load on the bus). Uploader Wait until Word[2140h]=BBAAh kick=CCh ;start-code for first command for block=1..num_blocks Word[2142h]=dest_addr ;usually 200h or higher (above stack and I/O ports) Byte[2141h]=01h ;command=transfer (can be any non-zero value) Byte[2140h]=kick ;start command (CCh on first block) Wait until Byte[2140h]=kick for index=0 to length-1 Byte[2141h]=[src_addr+index] ;send data byte Byte[2140h]=index.lsb ;send index LSB (mark data available) Wait until Byte[2140h]=index.lsb ;wait for acknowledge (see CAUTION) next index kick=(index+2 AND FFh) OR 1 ;-kick for next command (must be bigger than next block ;(if any) ; last index+1, and must be non-zero) [2142h]=entry_point ;entrypoint, must be below FFC0h (ROM region) [2141h]=00h ;command=entry (must be zero value) [2140h]=kick ;start command Wait until Byte[2140h]=kick ;wait for acknowledge CAUTION: The acknowledge for the last data byte lasts only for a few clock cycles, if the uploader is too slow then it may miss it (for example if it's interrupted); as a workaround, disable IRQs and NMIs during upload, or replace the last "wait for ack" by hardcoded delay. Boot ROM Disassembly FFC0 CD EF mov x,EF ;\ FFC2 BD mov sp,x ; zerofill RAM at [0001h..00EFh] FFC3 E8 00 mov a,00 ; (ie. excluding I/O Ports at F0h..FFh) @@zerofill_lop: ; (though [00h..01h] destroyed below) FFC5 C6 mov [x],a ; (also sets stacktop to 01EFh, kinda FFC6 1D dec x ; messy, nicer would be stacktop 01FFh) FFC7 D0 FC jnz @@zerofill_lop ;/ FFC9 8F AA F4 mov [F4],AA ;\notify Main CPU that APU is ready FFCC 8F BB F5 mov [F5],BB ;/for communication @@wait_for_cc: ;\ FFCF 78 CC F4 cmp [F4],CC ; wait for initial "kick" value FFD2 D0 FB jnz @@wait_for_cc ;/ FFD4 2F 19 jr main ;--- @@transfer_data: @@wait_for_00: ;\ FFD6 EB F4 mov y,[F4] ;index (should become 0) ; FFD8 D0 FC jnz @@wait_for_00 ;/ @@transfer_lop: FFDA 7E F4 cmp y,[F4] FFDC D0 0B jnz FFE9 -------> FFDE E4 F5 mov a,[F5] ;get data FFE0 CB F4 mov [F4],y ;ack data FFE2 D7 00 mov [[00]+y],a ;store data FFE4 FC inc y ;addr lsb FFE5 D0 F3 jnz @@transfer_lop FFE7 AB 01 inc [01] ;addr msb @@ FFE9 10 EF jns @@transfer_lop ;strange... FFEB 7E F4 cmp y,[F4] FFED 10 EB jns @@transfer_lop ;- - - main: FFEF BA F6 movw ya,[F6] ;\copy transfer (or entrypoint) FFF1 DA 00 movw [00],ya ;addr ;/address to RAM at [0000h] FFF3 BA F4 movw ya,[F4] ;cmd:kick FFF5 C4 F4 mov [F4],a ;ack kick FFF7 DD mov a,y ;cmd FFF8 5D mov x,a ;cmd FFF9 D0 DB jnz @@transfer_data FFFB 1F 00 00 jmp [0000+x] ;in: A=0, X=0, Y=0, SP=EFh, PSW=02h ;--- FFFE C0 FF dw FFC0 ;reset vector Notes Many games are jumping to ROM:FFC0h in order to "reset" the SPC700 back to the transmission phase. Some programs are also injumping to ROM:FFC9h (eg. mic_'s "The 700 Club" demo is using that address as dummy-entrypoint after each transfer block; until applying the actual entrypoint after the last block). Some games may "wrap" from opcodes at RAM:FFBFh to opcodes at ROM:FFC0h. Only known example is World Cup Striker, which contains following code at FFBCh in RAM: "MOV A,80h, MOV [F1h],A", that ensures ROM enabled, and does then continue at FFC0h in ROM (in this specific case, emulators can cheat by handling wraps in their PortF1h handler, rather than checking for PC>=FFC0h after every single opcode fetch). SNES APU DSP BRR Samples ------------------------ x4h - VxSRCN - Source number for Voice 0..7 (R/W) 0-7 Instrument number (index in DIR table) Points to the BRR Start & Loop addresses (via a table entry at VxSRCN*4+DIR*100h), used when voices are Keyed-ON or Looped. 5Dh - DIR - Sample table address (R/W) 0-7 Sample Table Address (in 256-byte steps) (indexed via VxSRCN) The table can contain up to 256 four-byte entries (max 1Kbyte). Each entry is: Byte 0-1 BRR Start Address (used when voice is Keyed-ON) Byte 2-3 BRR Restart/Loop Address (used when end of BRR data reached) Changing DIR or VxSRCN has no immediate effect (until/unless voices are newly Looped or Keyed-ON). Bit Rate Reduction (BRR) Format The sample data consists of 9-byte block(s). The first byte of each block is: 7-4 Shift amount (0=Silent, 12=Loudest, 13-15=Reserved) 3-2 Filter number (0=None, 1..3=see below) 1-0 Loop/End flags (0..3=see below) The next 8 bytes contain two samples (or nibbles) each: 7-4 First Sample (signed -8..+7) 3-0 Second Sample (signed -8..+7) The Loop/End bits can have following values: Code 0 = Normal (continue at next 9-byte block) Code 1 = End+Mute (jump to Loop-address, set ENDx flag, Release, Env=000h) Code 2 = Ignored (same as Code 0) Code 3 = End+Loop (jump to Loop-address, set ENDx flag) The Shift amount is used to convert the 4bit nibbles to 15bit samples: sample = (nibble SHL shift) SAR 1 Accordingly, shift=0 is rather useless (since it strips the low bit). When shift=13..15, decoding works as if shift=12 and nibble=(nibble SAR 3). The Filter bits allow to select the following filter modes: Filter 0: new = sample Filter 1: new = sample + old*0.9375 Filter 2: new = sample + old*1.90625 - older*0.9375 Filter 3: new = sample + old*1.796875 - older*0.8125 More precisely, the exact formulas are: Filter 0: new = sample Filter 1: new = sample + old*1+((-old*1) SAR 4) Filter 2: new = sample + old*2+((-old*3) SAR 5) - older+((older*1) SAR 4) Filter 3: new = sample + old*2+((-old*13) SAR 6) - older+((older*3) SAR 4) When creating BRR data, take care that "new" does never exceed -3FFAh..+3FF8h, otherwise a number of hardware glitches will occur: If new>+7FFFh then new=+7FFFh (but, clipped to +3FFFh below) ;\clamp 16bit If new<-8000h then new=-8000h (but, clipped to ZERO below) ;/(dirt-effect) If new=(+4000h..+7FFFh) then new=(-4000h..-1) ;\clip 15bit If new=(-8000h..-4001h) then new=(-0..-3FFFh) ;/(lost-sign) If new>+3FF8h OR new<-3FFAh then overflows can occur in Gauss section The resulting 15bit "new" value is then passed to the Gauss filter, and additionally re-used for the next 1-2 sample(s) as "older=old, old=new". BRR Notes The first 9-byte BRR sample block should always use Filter 0 (so it isn't disturbed by uninitialized old/older values). Same for the first block at the Loop address (unless the old/older values of the initial-pass should happen to match the ending values of the looped-passes). SNES APU DSP BRR Pitch ------------------------ x2h - VxPITCHL - Pitch scaler for Voice 0..7, lower 8bit (R/W) x3h - VxPITCHH - Pitch scaler for Voice 0..7, upper 6bit (R/W) 0-13 Sample rate (0=stop, 3FFFh=fastest) (1000h = 32000Hz) 14-15 Not used (read/write-able) Defines the BRR sample rate. This register (and PMON) does affect only the BRR sample frequency (but not on the Noise frequency, which is defined - and shared for all voices - in the FLG register). 2Dh - PMON - Pitch Modulation Enable Flags for Voice 1..7 (R/W) Pitch modulation allows to generate "Frequency Sweep" effects by mis-using the amplitude from channel (x-1) as pitch factor for channel (x). 0 Not used 1-7 Flags for Voice 1..7 (0=Normal, 1=Modulate by Voice 0..6) For example, output a very loud 1Hz sine-wave on channel 4 (with Direct Gain=40h, and with Left/Right volume=0; unless you actually want to output it to the speaker). Then additionally output a 2kHz sine wave on channel 5 with PMON.Bit5 set. The "2kHz" sound should then repeatedly sweep within 1kHz..3kHz range (or, for a more decent sweep in 1.8kHz..2.2kHz range, drop the Gain level of channel 4). Pitch Counter The pitch counter is adjusted at 32000Hz rate as follows: Step = VxPitch ;range 0..3FFFh (0..128 kHz) IF PMON.Bit(x)=1 AND (x>0) ;pitch modulation enable Factor = VxOUTX(x-1) ;range -4000h..+3FFFh (prev voice amplitude) Factor = (Factor SAR 4)+400h ;range +000h..+7FFh (factor = 0.00 .. 1.99) Step = (Step * Factor) SAR 10 ;range 0..7FEEh (0..256 kHz) XXX somewhere here, STEP (or the COUNTER-RESULT) is cropped to 128kHz max) XX? Counter = Counter + Step ;range 0..FFFFh, carry=next BRR block Counter.Bit15-12 indicates the current sample (within a BRR block). Counter.Bit11-3 are used as gaussian interpolation index. Maximum Sound Frequency The pitch counter generates sample rates up to 128kHz. However, the Mixer and DAC are clocked at 32kHz, so the higher rates will skip (or interpolate) samples rather than outputting all samples. The 32kHz output rate means that one can produce max 16kHz tones. 4-Point Gaussian Interpolation Interpolation is applied on the 4 most recent 15bit BRR samples (new,old,older,oldest), using bit4-11 of the pitch counter as interpolation index (i=00h..FFh): out = ((gauss[0FFh-i] * oldest) SAR 10) ;-initial 16bit value out = out + ((gauss[1FFh-i] * older) SAR 10) ;-no 16bit overflow handling out = out + ((gauss[100h+i] * old) SAR 10) ;-no 16bit overflow handling out = out + ((gauss[000h+i] * new) SAR 10) ;-with 16bit overflow handling out = out SAR 1 ;-convert 16bit result to 15bit The Gauss table contains the following values (in hex): 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;\ 001,001,001,001,001,001,001,001,001,001,001,002,002,002,002,002 ; 002,002,003,003,003,003,003,004,004,004,004,004,005,005,005,005 ; 006,006,006,006,007,007,007,008,008,008,009,009,009,00A,00A,00A ; 00B,00B,00B,00C,00C,00D,00D,00E,00E,00F,00F,00F,010,010,011,011 ; 012,013,013,014,014,015,015,016,017,017,018,018,019,01A,01B,01B ; entry 01C,01D,01D,01E,01F,020,020,021,022,023,024,024,025,026,027,028 ; 000h..0FFh 029,02A,02B,02C,02D,02E,02F,030,031,032,033,034,035,036,037,038 ; 03A,03B,03C,03D,03E,040,041,042,043,045,046,047,049,04A,04C,04D ; 04E,050,051,053,054,056,057,059,05A,05C,05E,05F,061,063,064,066 ; 068,06A,06B,06D,06F,071,073,075,076,078,07A,07C,07E,080,082,084 ; 086,089,08B,08D,08F,091,093,096,098,09A,09C,09F,0A1,0A3,0A6,0A8 ; 0AB,0AD,0AF,0B2,0B4,0B7,0BA,0BC,0BF,0C1,0C4,0C7,0C9,0CC,0CF,0D2 ; 0D4,0D7,0DA,0DD,0E0,0E3,0E6,0E9,0EC,0EF,0F2,0F5,0F8,0FB,0FE,101 ; 104,107,10B,10E,111,114,118,11B,11E,122,125,129,12C,130,133,137 ; 13A,13E,141,145,148,14C,150,153,157,15B,15F,162,166,16A,16E,172 ;/ 176,17A,17D,181,185,189,18D,191,195,19A,19E,1A2,1A6,1AA,1AE,1B2 ;\ 1B7,1BB,1BF,1C3,1C8,1CC,1D0,1D5,1D9,1DD,1E2,1E6,1EB,1EF,1F3,1F8 ; 1FC,201,205,20A,20F,213,218,21C,221,226,22A,22F,233,238,23D,241 ; 246,24B,250,254,259,25E,263,267,26C,271,276,27B,280,284,289,28E ; 293,298,29D,2A2,2A6,2AB,2B0,2B5,2BA,2BF,2C4,2C9,2CE,2D3,2D8,2DC ; 2E1,2E6,2EB,2F0,2F5,2FA,2FF,304,309,30E,313,318,31D,322,326,32B ; entry 330,335,33A,33F,344,349,34E,353,357,35C,361,366,36B,370,374,379 ; 100h..1FFh 37E,383,388,38C,391,396,39B,39F,3A4,3A9,3AD,3B2,3B7,3BB,3C0,3C5 ; 3C9,3CE,3D2,3D7,3DC,3E0,3E5,3E9,3ED,3F2,3F6,3FB,3FF,403,408,40C ; 410,415,419,41D,421,425,42A,42E,432,436,43A,43E,442,446,44A,44E ; 452,455,459,45D,461,465,468,46C,470,473,477,47A,47E,481,485,488 ; 48C,48F,492,496,499,49C,49F,4A2,4A6,4A9,4AC,4AF,4B2,4B5,4B7,4BA ; 4BD,4C0,4C3,4C5,4C8,4CB,4CD,4D0,4D2,4D5,4D7,4D9,4DC,4DE,4E0,4E3 ; 4E5,4E7,4E9,4EB,4ED,4EF,4F1,4F3,4F5,4F6,4F8,4FA,4FB,4FD,4FF,500 ; 502,503,504,506,507,508,50A,50B,50C,50D,50E,50F,510,511,511,512 ; 513,514,514,515,516,516,517,517,517,518,518,518,518,518,519,519 ;/ The gauss table is slightly bugged: Theoretically, each four values (gauss[000h+i], gauss[0FFh-i], gauss[100h+i], gauss[1FFh-i]) should sum up to 800h, but in practice they do sum up to 7FFh..801h. Of which, 801h can cause math overflows. For example, when outputting three or more "-8 SHL 12" BRR samples with Filter 0, some interpolation results will be +3FF8h (instead of -4000h). When adding the four new,old,older,oldest values there's some partial overflow handling: The 1st addition can't overflow, the 2nd addition can overflow (when i=0..1Fh), the 3rd addition can overflow (when i=20h..FFh). Of which, the 2nd one bugs, the 3rd one is saturated to Min=-8000h/Max=+7FFFh (giving -4000h/+3FFFh after the final SAR 1). Waveform Examples Incoming BRR Data ---> Interpolated Data _ _ _ _ | | | | | | | | . . . . Nibbles=79797979, Shift=12, Filter=0 | | | | | | | | ---> / \ / \ / \ / \ HALF-volume ZIGZAG-wave | |_| |_| |_| |_ ' ' ' ' ___ ___ | | | | .'. .'. Nibbles=77997799, Shift=12, Filter=0 | | | | ---> / \ / \ FULL-volume SINE-wave | |___| |___ ' '.' '. _______ ___ | | .' '. Nibbles=77779999, Shift=12, Filter=0 | | ---> / \ SQUARE wave (with rounded edges) | |_______ ' '.____ _______ ___ | | .' '. | | Nibbles=77778888, Shift=12, Filter=0 | | ---> / \ | | OVERFLOW glitch on -4000h*801h | |_______ ' '.|_|_ _____ _ __ | |_ _| .' ''. .' Nibbles=7777CC44, Shift=12, Filter=0 | |___| ---> / '..' CUSTOM wave-form | ' ___ __ | |___| | _ \ ! / . \ ! / Nibbles=77DE9HZK, Shift=3M, Filter=V |_ ____| _| ---> - + - + - + - SOLAR STORM wave-form __| |______|___ / ! \ ' / ! \ SNES APU DSP ADSR/Gain Envelope ------------------------------- x5h - VxADSR1 - ADSR settings for Voice 0..7, lower 8bit (R/W) x6h - VxADSR2 - ADSR settings for Voice 0..7, upper 8bit (R/W) 0-3 4bit Attack rate ;Rate=N*2+1, Step=+32 (or Step=+1024 when Rate=31) 4-6 3bit Decay rate ;Rate=N*2+16, Step=-(((Level-1) SAR 8)+1) 7 ADSR/Gain Select ;0=Use VxGAIN, 1=Use VxADSR (Attack/Decay/Sustain) 8-12 5bit Sustain rate ;Rate=N, Step=-(((Level-1) SAR 8)+1) 13-15 3bit Sustain level ;Boundary=(N+1)*100h N/A 0bit Release rate ;Rate=31, Step=-8 (or Step=-800h when BRR-end) If a voice is Keyed-ON: Enter Attack mode, set Level=0, and increase level. At Level>=7E0h: Switch from Attack to Decay mode (and clip level to max=7FFh if level>=800h). At Level<=Boundary: Switch from Decay to Sustain mode. If the voice is Keyed-OFF (or the BRR sample contains the Key-Off flag): Switch from Attack/Decay/Sustain/Gain mode to Release mode. x7h - VxGAIN - Gain settings for Voice 0..7 (R/W) When VxADSR1.Bit7=1 (Attack/Decay/Sustain Mode): 0-7 Not used (instead, Attack/Decay/Sustain parameters are used) When VxADSR1.Bit7=0 and VxGAIN.Bit7=0 (Direct Gain): 0-6 Fixed Volume (Envelope Level = N*16, Rate=Infinite) ;Volume=N*16/800h 7 Must be 0 for this mode When VxADSR1.Bit7=0 and VxGAIN.Bit7=1 (Custom Gain): 0-4 Gain rate (Rate=N) 5-6 Gain mode (see below) 7 Must be 1 for this mode In the latter case, the four Gain Modes are: Mode 0 = Linear Decrease ;Rate=N, Step=-32 (if Level<0 then Level=0) Mode 1 = Exp Decrease ;Rate=N, Step=-(((Level-1) SAR 8)+1) Mode 2 = Linear Increase ;Rate=N, Step=+32 Mode 3 = Bent Increase ;Rate=N, If Level<600h then Step=+32 else Step=+8 In all cases, clip E to 0 or 0x7ff rather than wrapping. The Direct/Custom Gain modes are overriding Attack/Decay/Sustain modes (when Keyed-ON), Release (when Keyed-OFF) keeps working as usually. x8h - VxENVX - Current envelope value for Voice 0..7 (R) 0-6 Upper 7bit of the 11bit envelope volume (0..127) 7 Not used (zero) Technically, this register IS writable. But whatever value you write will be overwritten at 32000 Hz. x9h - VxOUTX - Current sample value for Voice 0..7 (R) This returns the high byte of the current sample for this voice, after envelope volume adjustment but before VxVOL[LR] is applied. 0-7 Upper 8bit of the current 15bit sample value (-128..+127) Technically, this register IS writable. But whatever value you write will be overwritten at 32000 Hz. ADSR/Gain (and Noise) Rates The various ADSR/Gain/Noise rates are defined as 5bit rate values (or 3bit/4bit values which are converted to 5bit values as described above). The meaning of these 5bit values is as follows (the table shows the number of 32000Hz sample units it takes until the next Step is applied): 00h=Stop 04h=1024 08h=384 0Ch=160 10h=64 14h=24 18h=10 1Ch=4 01h=2048 05h=768 09h=320 0Dh=128 11h=48 15h=20 19h=8 1Dh=3 02h=1536 06h=640 0Ah=256 0Eh=96 12h=40 16h=16 1Ah=6 1Eh=2 03h=1280 07h=512 0Bh=192 0Fh=80 13h=32 17h=12 1Bh=5 1Fh=1 Note: All values are "1,3,5 SHL n". Hardware-wise they are probably implemented as 3bit counters, driven at 32kHz, 16kHz, 8kKz, etc. (depending on the shift amount); accordingly, when entering a new ADSR phase, the location of the 1st step may vary depending on when the hardware generates the next 8kHz cycles, for example. Gain Notes Even in Gain modes, the hardware does internally keep track of whether it is in Attack/Decay/Sustain phase: In attack phase it switches to Decay at Level>=7E0h. In Decay phase it switches to Sustain at Level<=Boundary (though accidently reading a garbage boundary value from VxGAIN.Bit7-5 instead of from VxADSR2.Bit7-5). Whereas, switching phases doesn't have any audible effect, it just marks the hardware as being in a new phase (and, if software disables Gain-Mode by setting VxADSR1.Bit7, then hardware will process the current phase). Direct Gain mode can be used to set a fixed volume, or to define the starting point for a different mode (in the latter case, mind that the hardware processes I/O ports only once per sample, so, after setting Direct Gain mode: wait at least 32 cpu cycles before selecting a different mode). Misc Notes Save the new value, *clipped* to 11 bits, to determine the increment for GAIN Bent Increase mode next sample. Note that a negative value for the new value will result in the clipped version being greater than 0x600. SNES APU DSP Volume Registers ----------------------------- 0Ch - MVOLL - Left channel master volume (R/W) 1Ch - MVOLR - Right channel master volume (R/W) 0-7 Volume (-127..+127) (negative = phase inverted) (sample=sample*vol/128) Value -128 causes multiply overflows (-8000h*-80h=-400000h). x0h - VxVOLL - Left volume for Voice 0..7 (R/W) x1h - VxVOLR - Right volume for Voice 0..7 (R/W) 0-7 Volume (-128..+127) (negative = phase inverted) (sample=sample*vol/128) Value -128 can be safely used (unlike as for all other volume registers, there is no overflow; because ADSR/Gain does lower the incoming sample to max=sample*7FFh/800h). Output Mixer sum = sample0*V0VOLx SAR 6 ;\ sum = sum + sample1*V0V1Lx SAR 6 ; sum = sum + sample2*V0V2Lx SAR 6 ; with 16bit overflow handling sum = sum + sample3*V0V3Lx SAR 6 ; (after each addition) sum = sum + sample4*V0V4Lx SAR 6 ; sum = sum + sample5*V0V5Lx SAR 6 ; sum = sum + sample6*V0V6Lx SAR 6 ; sum = sum + sample7*V0V7Lx SAR 6 ; sum = (sum*MVOLx SAR 7) ; sum = sum + (fir_out*EVOLx SAR 7) ;/ if FLG.MUTE then sum = 0000h sum = sum XOR FFFFh ;-final phase inversion (as done by built-in post-amp) SNES APU DSP Control Registers ------------------------------ 4Ch - KON - Key On Flags for Voice 0..7 (R/W) (W) 0-7 Flags for Voice 0..7 (0=No change, 1=Key On) Writing 1 to the KON bit will set the envelope to 0, the state to Attack, and will start the channel from the beginning (see DIR and VxSRCN). Note that this happens even if the channel is already playing (which may cause a click/pop), and that there are 5 'empty' samples before envelope updates and BRR decoding actually begin. 5Ch - KOFF - Key Off Flags for Voice 0..7 (R/W) (W) 0-7 Flags for Voice 0..7 (0=No change, 1=Key Off) Setting 1 to the KOFF bit will transition the voice to the Release state. Thus, the envelope will decrease by 8 every sample (regardless of the VxADSR and VxGAIN settings) until it reaches 0, where it will stay until the next KON. 6Ch - FLG - Reset, Mute, Echo-Write flags and Noise Clock (R/W) The initial value on Reset is E0h (KeyedOff/Muted/EchoWriteOff/NoiseStopped), although reading the FLG register after reset will return a garbage value. 0-4 Noise frequency (0=Stop, 1=16Hz, 2=21Hz, ..., 1Eh=16kHz, 1Fh=32kHz) 5 Echo Buffer Writes (0=Enable, 1=Disable) (doesn't disable echo-reads) 6 Mute Amplifier (0=Normal, 1=Mute) (doesn't stop internal processing) 7 Soft Reset (0=Normal, 1=KeyOff all voices, and set Envelopes=0) Disabling Echo-Writes doesn't affect Echo-Reads (ie. echo buffer is still output, unless Echo Volume L+R or FIR0..7 are set to zero). Mute affects only the external amplifier (internally all sound/echo generation is kept operating). 7Ch - ENDX - Voice End Flags for Voice 0..7 (R) (W=Ack) 0-7 Flags for Voice 0..7 (0=Keyed ON, 1=BRR-End-Bit encountered) Any write to this register will clear ALL bits, no matter what value is written. On reset, all bits are cleared. Though bits may get set shortly after reset or shortly after manual-write (once when the BRR decoder reaches an End-code). Note that the bit is set at the START of decoding the BRR block, not at the end. Recall that BRR processing, and therefore the setting of bits in this register, continues even for voices in the Release state. 3Dh - NON - Noise Enable Flags for Voice 0..7 (R/W) Allows to enable Noise on one or more channels, however, there is only one noise-generator (and only one noise frequency) shared for all voices. The 5bit noise frequency is defined in FLG register (see above), and works same as the 5bit ADSR rates (see ADSR chapter for details). The NON bits are: 0-7 Flags for Voice 0..7 (0=Output BRR Samples, 1=Output Noise) The noise generator produces 15bit output level (range -4000h..+3FFFh; initially -4000h after reset). At the selected noise rate, the level is updated as follows: Level = ((Level SHR 1) AND 3FFFh) OR ((Level.Bit0 XOR Level.Bit1) SHL 14) Caution: Even in noise mode, the hardware keeps decoding BRR sample blocks, and, when hitting a BRR block with End Code 1 (End+Mute), it will switch to Release state with Envelope=0, thus immediately terminating the Noise output. To avoid that, set VxSRCN to an endless looping dummy BRR block. Note: The VxPITCH registers have no effect on noise frequency, and Gaussian interpolation isn't applied on noise. KON/KOFF Notes These registers seem to be polled only at 16000 Hz, when every other sample is due to be output. Thus, if you write two values in close succession, usually but not always only the second value will have an effect: ; assume KOFF = 0, but no voices playing mov $f2, #$4c ; KON = 1 then KON = 2 mov $f3, #$01 ; -> *usually* only voice 2 is keyed on. If both are, mov $f3, #$02 ; voice 1 will be *2* samples ahead rather than one. and ; assume various voices playing mov $f2, #$5c ; KOFF = $ff then KOFF = 0 mov $f3, #$ff mov $f3, #$00 ; -> *usually* all voices remain playing FLG bit 7, however, is polled every sample and polled for each voice. These registers and FLG bit 7 interact as follows: 1. If FLG bit 7 or the KOFF bit for the channel is set, transition to the Release state. If FLG bit 7 is set, also set the envelope to 0. 2. If the 'internal' value of KON has the channel's bit set, perform the KON actions described above. 3. Set the 'internal' value of KON to 0. This has a number of consequences: * KON effectively takes effect 'on write', even though a non-zero value can be read back much later. KOFF and FLG.7, on the other hand, exert their influence constantly until a new value is written. * Writing KON while KOFF or FLG.7 will not result in any samples being output by the channel. The channel is keyed on, but it is turned off again 2 samples later. Since there is a 5 sample delay after KON before the channel actually beings processing, the net effect is no output. * However, if KOFF is cleared within 63 SPC700 cycles of the KON write above, the channel WILL be keyed on as normal. If KOFF is cleared betwen 64 and 127 SPC700 cycles later, the channel MIGHT be keyed on with decreasing probability depending on how many cycles before the KON/KOFF poll the KON write occurred. * Setting both KOFF and KON for a channel will turn the channel off much faster than just KOFF alone, since the KON will set the envelope to 0. This can cause a click/pop, though. xAh - NA - Unused (8 bytes of general-purpose RAM) (R/W) xBh - NA - Unused (8 bytes of general-purpose RAM) (R/W) 1Dh - NA - Unused (1 byte of general-purpose RAM) (R/W) xEh - NA - Unused (8 bytes of general-purpose RAM) (R/W) These registers seem to have no function at all. Data written to them seems to have no effect on sound output, the written values seem to be left intact (ie. they aren't overwritten by voice or echo status information). SNES APU DSP Echo Registers --------------------------- 2Ch - EVOLL - Left channel echo volume (R/W) 3Ch - EVOLR - Right channel echo volume (R/W) 0-7 Volume (-128..+127) (negative = phase inverted) (sample=sample*vol/128) This is the adjustment applied to the FIR filter outputs before mixing with the main signal (after master volume adjustment). 0Dh - EFB - Echo feedback volume (R/W) Specifies the feedback volume (the volume at which the echo-output is mixed back to the echo-input). 0-7 Volume (-128..+127) (negative = phase inverted) (sample=sample*vol/128) Medium values (like 40h) produce "normal" echos (with decreasing volume on each repetition). Value 00h would produce a one-shot echo, value 7Fh would repeat the echo almost infinitely (assuming that FIRx leaves the overall volume unchanged). 4Dh - EON - Echo Enable Flags for Voice 0..7 (R/W) 0-7 Flags for Voice 0..7 (0=Direct Output, 1=Echo (and Direct) Output) When the bit is set and echo buffer write is enabled, this voice will be mixed into the sample to be written to the echo buffer for later echo processing. 6Dh - ESA - Echo ring buffer address (R/W) 0-7 Echo Buffer Base Address (in 256-byte steps) The echo buffer consists of one or more 4-byte entries: Byte 0: Lower 7bit of Left sample (stored in bit1-7) (bit0=unused/zero) Byte 1: Upper 8bit of Left sample (stored in bit0-7) Byte 2: Lower 7bit of Right sample (stored in bit1-7) (bit0=unused/zero) Byte 3: Upper 8bit of Right sample (stored in bit0-7) At 32000Hz rate, the oldest 4-byte entry is removed (and passed on to the FIR filter), and, if echo-writes are enabled in FLG register, the removed entry is then overwritten by new values (from the Echo Mixer; consisting of all Voices enabled in EON, plus echo feedback). Changes to the ESA register are are realized (almost) immediately: After changing ESA, the hardware may keep access 1-2 samples at [OldBase+index], and does then continue at [NewBase+index] (with index being increased as usually, or reset to 0 when Echo Size has ellapsed). 7Dh - EDL - Echo delay (ring buffer size) (R/W) Specifies the size of the Echo RAM buffer (and thereby the echo delay). Additionally to that RAM buffer, there is a 8x4-byte buffer in the FIR unit. 0-3 Echo Buffer Size (0=4 bytes, or 1..15=Size in 2K-byte steps) (max=30K) 4-7 Not used (read/write-able) (ie. 16 ms steps) (max=240ms) Caution: It may take up to about 240ms until the hardware realizes changes to the EDL register; ie. when re-allocating the buffer size, the hardware may keep writing up to 30Kbytes according to the old size. See Echo Buffer Notes below. Echo Buffer Notes Note that the ESA register is accessed 32 cycles before the value is used for a write; at a sample level, this causes writes to appear to be delayed by at least a full sample before taking effect. The EDL register value is only used under certain conditions: * Write the echo buffer at sample 'idx' (cycles 29 and 30) * If idx==0, set idx_max = EDL<<9 (cycle 30-ish) * Increment idx. If idx>=idx_max, idx=0 (cycle 30-ish) This means that it can take up to .25s for a newly written value to actually take effect, if the old value was 0x0f and the new value is written just after the cycle 30 in which buffer index 0 was written. xFh - FIRx - Echo FIR filter coefficient 0..7 (R/W) 0-7 Echo Coefficient for 8-tap FIR filter (-80h..+7Fh) Value -128 should not be used for any of the FIRx registers (to avoid multiply overflows). To avoid addition overflows: The sum of POSITIVE values in first seven registers (FIR0..FIR6) should not exceed +7Fh, and the sum of NEGATIVE values should not exceed -7Fh. The sum of all eight registers (FIR0..FIR7) should be usually around +80h (for leaving the overall output volume unchanged by the FIR unit; instead, echo volumes are usually adjusted via EFB/EVOLx registers). The FIR formula is: addr = (ESA*100h+ram_index*4) AND FFFFh ;-Echo RAM read/write addr buf[(i-0) AND 7] = EchoRAM[addr] SAR 1 ;-input 15bit from Echo RAM sum = buf[(i-7) AND 7]*FIR0 SAR 6 ;oldest ;\ sum = sum + buf[(i-6) AND 7]*FIR1 SAR 6 ; calculate 16bit sum of sum = sum + buf[(i-5) AND 7]*FIR2 SAR 6 ; oldest 7 values, these sum = sum + buf[(i-4) AND 7]*FIR3 SAR 6 ; additions are done sum = sum + buf[(i-3) AND 7]*FIR4 SAR 6 ; without overflow sum = sum + buf[(i-2) AND 7]*FIR5 SAR 6 ; handling sum = sum + buf[(i-1) AND 7]*FIR6 SAR 6 ;/ sum = sum + buf[(i-0) AND 7]*FIR7 SAR 6 ;newest ;-with overflow handling if overflow occurred in LAST addition: saturate to min/max=-8000h/+7FFFh audio_output=NormalVoices+((sum*EVOLx) SAR 7) ;-output to speakers echo_input=EchoVoices+((sum*EFB) SAR 7) ;-feedback to echo RAM echo_input=echo_input AND FFFEh ;-isolate 15bit/bit0=0 if echo write enabled: EchoRAM[addr]=echo_input ;-write (if enabled in FLG) i = i + 1 ;-FIR index for next sample ram_index=ram_index+1 ;-RAM index for next sample decrease remain, if remain=0, reload remain from EDL and set ram_index=0 Note that the left and right stereo channels are filtered separately (no crosstalk), but with identical coefficients. Filter Examples FIR0 FIR1 FIR2 FIR3 FIR4 FIR5 FIR6 FIR7 EFB FF 08 17 24 24 17 08 FF 40 Echo with Low-pass (bugged) 7F 00 00 00 00 00 00 00 7F Echo (nearly endlessly repeated) 7F 00 00 00 00 00 00 00 40 Echo (repeat w. decreasing vol) 7F 00 00 00 00 00 00 00 00 Echo (one-shot) Note: The "bugged" example (with the sum of FIR0..FIR6 exceeding +7Fh) is from official (!) specs (and thus possibly actually used by some games(?)). Echo Overflows Setting FIRx, EFB, or EVOLx to -128 does probably cause multiply overflows? SNES APU Low Level Timings -------------------------- Register and RAM Access Timing Chart On every CPU cycle, the hardware can access 3 bytes from RAM (2 DSP accesses, and 1 CPU access), and 4 bytes from DSP Register Array (3 DSP accesses, and 1 CPU access), plus some special DSP Registers (ENDX/FLG). Audio is generated at 32000Hz Rate (every 32 CPU cycles): Time <--- RAM Access ---> <---- Register Array ----> <--Extra--> T0 [V0BRR.2nd.dta1] -- ,V0VOLL ,V2SRCN T1 [V1SRCN/DIR.lsb/msb] V0VOLR ,V1PITCHL ,V1ADSR1 ENDX.0, Timer0,1,2 T2 [V1BRR.1st.hdr/dta0] V0ENVX ,V1PITCHH ,V1ADSR2 V1:FLG.7 T3 [V1BRR.2nd.dta1] V0OUTX ,V1VOLL ,V3SRCN T4 [V2SRCN/DIR.lsb/msb] V1VOLR ,V2PITCHL ,V2ADSR1 ENDX.1 T5 [V2BRR.1st.hdr/dta0] V1ENVX ,V2PITCHH ,V2ADSR2 V2:FLG.7 T6 [V2BRR.2nd.dta1] V1OUTX ,V2VOLL ,V4SRCN T7 [V3SRCN/DIR.lsb/msb] V2VOLR ,V3PITCHL ,V3ADSR1 ENDX.2 T8 [V3BRR.1st.hdr/dta0] V2ENVX ,V3PITCHH ,V3ADSR2 V3:FLG.7 T9 [V3BRR.2nd.dta1] V2OUTX ,V3VOLL ,V5SRCN T10 [V4SRCN/DIR.lsb/msb] V3VOLR ,V4PITCHL ,V4ADSR1 ENDX.3 T11 [V4BRR.1st.hdr/dta0] V3ENVX ,V4PITCHH ,V4ADSR2 V4:FLG.7 T12 [V4BRR.2nd.dta1] V3OUTX ,V4VOLL ,V6SRCN T13 [V5SRCN/DIR.lsb/msb] V4VOLR ,V5PITCHL ,V5ADSR1 ENDX.4 T14 [V5BRR.1st.hdr/dta0] V4ENVX ,V5PITCHH ,V5ADSR2 V5:FLG.7 T15 [V5BRR.2nd.dta1] V4OUTX ,V5VOLL ,V7SRCN T16 [V6SRCN/DIR.lsb/msb] V5VOLR ,V6PITCHL ,V6ADSR1 ENDX.5 T17 [V6BRR.1st.hdr/dta0] V5ENVX ,V6PITCHH ,V6ADSR2 V6:FLG.7, Timer2 T18 [V6BRR.2nd.dta1] V5OUTX ,V6VOLL ,V0SRCN T19 [V7SRCN/DIR.lsb/msb] V6VOLR ,V7PITCHL ,V7ADSR1 ENDX.6 T20 [V7BRR.1st.hdr/dta0] V6ENVX ,V7PITCHH ,V7ADSR2 V7:FLG.7 T21 [V7BRR.2nd.dta1] V6OUTX ,V7VOLL ,V1SRCN T22 [V0SRCN/DIR.lsb/msb] V7VOLR ,V0PITCHL ,V0ADSR1 ENDX.7 T23 [RdEchoLeft.lsb/msb] V7ENVX ,V0PITCHH ,FIR0 T24 [RdEchoRight.lsb/msb] V7OUTX ,FIR1 ,FIR2 T25 --- ;SRAM./OE=no FIR3 ,FIR4 ,FIR5 T26 [V0BRR.1st.hdr/dta0] FIR6 ,FIR7 ,--- T27 --- ;SRAM./OE=yes?! MVOLL ,EVOLL ,EFB T28 --- ;SRAM./OE=yes?! MVOLR ,EVOLR ,PMON T29 --- ;SRAM./OE=no NON ,EON ,DIR FLG.5 T30 [WrEchoLeft.lsb/msb] EDL ,ESA ,KON? FLG.5 T31 [WrEchoRight.lsb/msb] KOFF ,FLG.LSB ,V0ADSR2 FLG.0-4,V0:FLG.7,KON Note: In Gain-Mode, above reads VxGAIN instead of VxADSR2. KON and KOFF are processed only each 64 clk cycles (each 2nd pass). The SPC and DSP chips are started via same /RESET and clocked via same 2.048MHz signal, causing the SPC Timers to be incremented in sync with DSP timings: at T1 and T17 (unless one pauses the SPC Timers via TEST register). Additionally (non-RAM-array): ENDX 8bits KON-changed 1bit FLG.MSBs 3bit (or maybe/rather it's full 8bit, including LSBs?) Internal Signals LRCK is HIGH during T0..T15, and LOW during T16..T31. APU Signals Time 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 1 (Tnn) LRCK ---________________________________________________------ (DSP.Pin43) MX1 _-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-- (DSP.Pin3) MX2 __-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-__- (DSP.Pin4) MX3 __'__'__'__'__'__'__'__'__'__'__'__'__'__'__'__'__'__'__' (DSP.Pin5) /WE --C--C--C--C--C--C--C--C--C--C--C--C--C--C--CEECEEC--C--C (SRAM.Pin27) /OE DDCDDCDDCDDCDDCDDCDDCDDCEECEECddCDDCddCddCddC--C--CDDCDDC (SRAM.Pin22) /CE0 DDCDDCDDCDDCDDCDDCDDCDDC--C--C--CDDCddCddC--C--C--CDDCDDC (SRAM.Pin20a) /CE1 --C--C--C--C--C--C--C--CEECEEC--C--C--C--C--CEECEEC--C--C (SRAM.Pin20b) Whereas: "-" High "_" Low "'" Very short High (near falling edges of MX2) "C" CPU access ;-(occurs when MX2=High) "EE" Echo access ;\ "DD" DSP access (DIR/BRR) ; (occurs when MX2=Low) "dd" DSP access (dummy) ;/ For /CE0 and /CE1: Assume DIR/BRR in lower 32K, Echo in upper 32K RAM. The "DD" and "dd" signals seem to be always going Low (even when no new BRR/DIR data is needed). SNES Maths Multiply/Divide -------------------------- 4202h - WRMPYA - Set unsigned 8bit Multiplicand (W) 4203h - WRMPYB - Set unsigned 8bit Multiplier and Start Multiplication (W) Set WRMPYA (or leave it unchanged, if it already contains the desired value), then set WRMPYB, wait 8 clk cycles, then read the 16bit result from Port 4216h-4217h. For some reason, the hardware does additionally set RDDIVL=WRMPYB, and RDDIVH=00h. 4204h - WRDIVL - Set unsigned 16bit Dividend (lower 8bit) (W) 4205h - WRDIVH - Set unsigned 16bit Dividend (upper 8bit) (W) 4206h - WRDIVB - Set unsigned 8bit Divisor and Start Division (W) Set WRDIVL/WRDIVH (or leave it unchanged, if it already contains the desired value), then set WRDIVB, wait 16 clk cycles, then read the 16bit result and/or 16bit remainder from Port 4214h-4217h. Division by zero returns Result=FFFFh, Remainder=Dividend. Note: Almost all commercial SNES games are zero-filling I/O ports upon initialization, thereby causing division by zero (so, debuggers should ignore division errors). 4214h - RDDIVL - Unsigned Division Result (Quotient) (lower 8bit) (R) 4215h - RDDIVH - Unsigned Division Result (Quotient) (upper 8bit) (R) See Ports 4204h-4206h (divide). Destroyed by 4203h (multiply). 4216h - RDMPYL - Unsigned Division Remainder / Multiply Product (lo.8bit) (R) 4217h - RDMPYH - Unsigned Division Remainder / Multiply Product (up.8bit) (R) See Ports 4204h-4206h (divide), and 4202h-4203h (multiply). Timing Notes The 42xxh Ports are clocked by the CPU Clock, meaning that one needs the same amount of "wait" opcodes no matter if the CPU Clock is 3.5MHz or 2.6MHz. When reading the result, the "MOV r,[421xh]" opcode does include 3 cycles (spent on reading the 3-byte opcode), meaning that one needs to insert only 5 cycles for MUL and only 13 for DIV. Some special cases: If the the upper "N" bits of 4202h are all zero, then it seems that one may wait "N" cycles less. If memory REFRESH occurs (once and when), then the result seems to be valid within even less wait opcodes. The maths operations are started only on WRMPYB/WRDIVB writes (not on WRMPYA/WRDIVL/WRDIVH writes; unlike the PPU maths which start on any M7A/M7B write). === PPU Ports === Below Ports 21xxh are PPU registers. The registers are also used for rotation/scaling effects in BG Mode 7. In BG Mode 0-6 they can be used freely for multiplications. In Mode 7 they are usable ONLY during V-Blank and Forced-Blank (during the Mode 7 Drawing & H-Blank periods, they return garbage in MPYL/MPYM/MPYH, and of course writing math-parameters to M7A/M7B would also mess-up the display). 211Bh - M7A - Rotation/Scaling Parameter A (and Maths 16bit operand) (W) 1st Write: Lower 8bit of signed 16bit Multiplicand ;\1st/2nd write mechanism 2nd Write: Upper 8bit of signed 16bit Multiplicand ;/uses "M7_old" (Mode7) 211Ch - M7B - Rotation/Scaling Parameter B (and Maths 8bit operand) (W) Any Write: Signed 8bit Multiplier ;-also affects "M7_old" After writing to 211Bh or 211Ch, the result can be read immediately from 2134h-2136h (the 21xxh Ports are rapidly clocked by the PPU, there's no delay needed when reading via "MOV A,[211Ch]" or via "MOV A,[1Ch]" (with D=2100h), both works even when the CPU runs at 3.5MHz). 2134h - MPYL - Signed Multiply Result (lower 8bit) (R) 2135h - MPYM - Signed Multiply Result (middle 8bit) (R) 2136h - MPYH - Signed Multiply Result (upper 8bit) (R) See Ports 211Bh-211Ch. Notes Some cartridges contain co-processors with further math functions: --> SNES Cartridges SNES Controllers ---------------- I/O Ports --> SNES Controllers I/O Ports - Automatic Reading --> SNES Controllers I/O Ports - Manual Reading Controller IDs --> SNES Controllers Hardware ID Codes --> SNES Controllers Detecting Controller Support of ROM-Images Standard Controllers --> SNES Controllers Joypad --> SNES Controllers Mouse (Two-button Mouse) --> SNES Controllers Multiplayer 5 (MP5) (Five Player Adaptor) Light Guns --> SNES Controllers SuperScope (Lightgun) --> SNES Controllers Konami Justifier (Lightgun) --> SNES Controllers M.A.C.S. (Lightgun) Other controllers --> SNES Controllers Twin Tap --> SNES Controllers Miracle Piano --> SNES Controllers NTT Data Pad (joypad with numeric keypad) --> SNES Controllers X-Band Keyboard --> SNES Controllers Tilt/Motion Sensors --> SNES Controllers Lasabirdie (golf club) --> SNES Controllers Exertainment (bicycle exercising machine) --> SNES Controllers Pachinko --> SNES Controllers Other Inputs Other devices that connect to the controller port --> SNES Add-On Turbo File (external backup memory for storing game positions) --> SNES Add-On Barcode Battler (barcode reader) --> SNES Add-On SFC Modem (for JRA PAT) --> SNES Add-On Voice-Kun (IR-transmitter/receiver for use with CD Players) Other Add-Ons --> SNES 3D Glasses Pinouts --> SNES Controllers Pinouts SNES Controllers I/O Ports - Automatic Reading ---------------------------------------------- 4218h/4219h - JOY1L/JOY1H - Joypad 1 (gameport 1, pin 4) (R) 421Ah/421Bh - JOY2L/JOY2H - Joypad 2 (gameport 2, pin 4) (R) 421Ch/421Dh - JOY3L/JOY3H - Joypad 3 (gameport 1, pin 5) (R) 421Eh/421Fh - JOY4L/JOY4H - Joypad 4 (gameport 2, pin 5) (R) Register Serial Default Bit Transfer Purpose Number______Order______(Joypads)_____ 15 1st Button B (1=Low=Pressed) 14 2nd Button Y 13 3rd Select Button 12 4th Start Button 11 5th DPAD Up 10 6th DPAD Down 9 7th DPAD Left 8 8th DPAD Right 7 9th Button A 6 10th Button X 5 11th Button L 4 12th Button R 3 13th 0 (High) 2 14th 0 (High) 1 15th 0 (High) 0 16th 0 (High) Before reading above ports, set Bit 0 in port 4200h to request automatic reading, then wait until Bit 0 of port 4212h gets set-or-cleared? Once 4200h enabled, seems to be automatically read on every retrace? Be sure that Out0 in Port 4016h is zero (otherwise the shift register gets stuck on the first bit, ie. all 16bit will be equal to the B-button state. AUTO JOYPAD READ ---------------- When enabled, the SNES will read 16 bits from each of the 4 controller port data lines into registers $4218-f. This begins between H=32.5 and H=95.5 of the first V-Blank scanline, and ends 4224 master cycles later. Register $4212 bit 0 is set during this time. Specifically, it begins at H=74.5 on the first frame, and thereafter some multiple of 256 cycles after the start of the previous read that falls within the observed range. Reading $4218-f during this time will read back incorrect values. The only reliable value is that no buttons pressed will return 0 (however, if buttons are pressed 0 could still be returned incorrectly). Presumably reading $4016/7 or writing $4016 during this time will also screw things up. SNES Controllers I/O Ports - Manual Reading ------------------------------------------- 4016h/Write - JOYWR - Joypad Output (W) 7-3 Not used 2 OUT2, Output on CPU Pin 39 (seems to be not connected) (1=High) 1 OUT1, Output on CPU Pin 38 (seems to be not connected) (1=High) 0 OUT0, Output on CPU Pin 37 (Joypad Strobe) (both gameports, pin 3) Out0-2 are found on CPU Pins 37-39, of which only Out0 seems to be connected. Note: The NSS (arcade cabinet) uses OUT2 to signalize Game Over to the Z80 coprocessor. 4016h/Read - JOYA - Joypad Input Register A (R) 7-2 Not used 1 Input on CPU Pin 33, connected to gameport 1, pin 5 (JOY3) (1=Low) 0 Input on CPU Pin 32, connected to gameport 1, pin 4 (JOY1) (1=Low) Reading from this register automatically generates a clock pulse on CPU Pin 35, which is connected to gameport 1, pin 2. 4017h/Read - JOYB - Joypad Input Register B (R) 7-5 Not used 4 Input on CPU Pin 31, connected to GND (always 1=LOW) (1=Low) 3 Input on CPU Pin 30, connected to GND (always 1=LOW) (1=Low) 2 Input on CPU Pin 29, connected to GND (always 1=LOW) (1=Low) 1 Input on CPU Pin 28, connected to gameport 2, pin 5 (JOY4) (1=Low) 0 Input on CPU Pin 27, connected to gameport 2, pin 4 (JOY2) (1=Low) Reading from this register automatically generates a clock pulse on CPU Pin 36, which is connected to gameport 2, pin 2. 4201h - WRIO - Joypad Programmable I/O Port (Open-Collector Output) (W) 7-0 I/O PORT (0=Output Low, 1=HighZ/Input) 7 Joypad 2 Pin 6 / PPU Lightgun input (should be usually always 1=Input) 6 Joypad 1 Pin 6 5-0 Not connected (except, used by SFC-Box; see Hotel Boxes) Note: Due to the weak high-level, the raising "edge" is raising rather slowly, for sharper transitions one may need external pull-up resistors. 4213h - RDIO - Joypad Programmable I/O Port (Input) (R) 7-0 I/O PORT (0=Low, 1=High) When used as Input via 4213h, set the corresponding bits in 4201h to HighZ. I/O Signals 0..7 are found on CPU Pins 19..26 (in that order). IO-6 connects to Pin 6 of Controller 1. IO-7 connects to Pin 6 of Controller 2, this pin is also shared for the light pen strobe. Wires are connected to IO-0..5, but the wires disappear somewhere in the multi-layer board (and might be dead-ends), none of them is output to any connectors (not to the Controller ports, not to the cartridge slot, and not to the EXT port). SNES Controllers Hardware ID Codes ---------------------------------- Controller ID Bits (13th-16th bit, or extended: 13th-24th bit) 13th ... 24th Hex Type 0000.00000000 0.00 No controller connected 0000.11111111 0.FF Normal Joypad (probably also 3rd-party joypads/joysticks) 0001 1 Mouse 0010 2 ? Unknown (if any) 0011 3 SFC Modem (used by JRA PAT) 0100 4 NTT Data Controller Pad (used by JRA PAT) .... 5-C Unknown (if any) 1101 D Voice-Kun (IR-transmitter/receiver, for CD Players) 1110.xxxxxxxx E.xx Third-Party Devices (see below) 1110.000000xx E.0x Epoch Barcode Battler II (detection requires DELAYS?!) 1110.01010101 E.55 Konami Justifier 1110.01110111 E.77 Sunsoft Pachinko Controller 1110.11111110 E.FE ASCII Turbo File Twin in STF mode 1110.11111111 E.FF ASCII Turbo File Twin in TFII mode (or Turbo File Adapter) 1111 F Nintendo Super Scope N/A N/A M.A.C.S. (no ID, returns all bits = trigger button) Note: The Multiplayer 5 can be also detected (using a different mechansim than reading bits 13th-16th). Devices with unknown IDs (if they do have any special controller IDs at all) Lasabirdie ;\ Twin Tap ; these should have custom IDs? Miracle Piano ; X-Band Keyboard ;/ Exertainment ;-connects to expansion port (thus no controller id) BatterUP ;\ TeeV Golf ; these might return StuntMaster ; normal "joypad" ID? Nordic Quest ; Hori SGB Commander (in normal mode / in SGB mode) ; Nintendo Joysticks ;/ SNES Controllers Detecting Controller Support of ROM-Images ----------------------------------------------------------- Below are some methods to detect controller support by examining ROM-images. The methods aren't fail-proof, but may be useful to track-down controller support in many games. Detection Method Summary Type Method Joypad Mouse String "START OF MOUSE BIOS", or opcodes (see below) Multiplayer 5 String "START OF MULTI5 BIOS" Super Scope String "START OF SCOPE BIOS", or Title= Lasabirdie String "GOLF_READY!" X-Band Keyboard String "ZSAW@",x,x,"CXDE$#" (keyboard translation table) Turbo File (STF) String "FAT0SHVC" Turbo File (TFII) Opcodes "MOV Y,000Fh/MOV A,[004017h]/DEC Y/JNZ $-5" Exertainment Opcodes "MOV [21C1h],A/MOV A,0Bh/MOV [21C4h],A/MOV X,20F3h" Barcode Battler Opcodes "INC X/CMP X,(00)0Ah/JNC $-6(-1)/RET/36xNOP/RET" Voice-Kun Opcodes "MOV [004201h],A/CLR P,20h/MOV A,D/INC A" Justifier Title="LETHAL ENFORCERS " M.A.C.S. Title="MAC:Basic Rifle " Twin Tap Title="QUIZ OH SUPER " Miracle Piano Title="MIRACLE " NTT Data Pad Title="NTT JRA PAT " SFC Modem Title="NTT JRA PAT " Pachinko Title=CB,AF,BB,C2,CA,DF,C1,DD,CB,AF,BB,C2,CA,DF,C1,DD,xx(6) BatterUP - ;\ TeeV Golf - ; these are probably simulating standard joypads StuntMaster - ; (and thus need no detection) Nordic Quest - ;/ START OF xxx BIOS Strings These strings were included in Nintendo's hardware driver source code files, the strings themselves have no function (so one could simply remove them), but Nintendo prompted developers to keep them included. They are typically arranged like so: "START OF xxx BIOS" [bios program code...] "NINTENDO SHVC xxx BIOS VER x.xx" "END OF xxx BIOS" Whereas, the version string may be preceeded by "MODIFIED FROM ", and "VER" may be "Ver" in some cases, sometimes without space between "Ver" and "x.xx". In case of custom code one may omit the version string or replace it by "MY BIOS VERSION" or so, but one should include the "START/END OF xxx BIOS" strings to ease detection. Multiplayer 5 Games that do SUPPORT the hardware should contain following string: "START OF MULTI5 BIOS" Games that do DETECT the hardware should contain following string: "START OF MULTI5 CONNECT CHECK" Games that contain only the "CHECK" part (but not the "BIOS" part) may REJECT to operate with the hardware. Some MP5 games (eg. "Battle Cross") do lack the "START OF ..." strings. Mouse Games that do SUPPORT the hardware should contain following string: "START OF MOUSE BIOS" Some Mouse games (eg. Arkanoid Doh It Again) do lack the "START OF ..." strings. For such games, checking following opcodes may help: MOV Y,0Ah/LOP:/MOV A,[(00)4016h+X]/DEC Y/JNZ LOP/MOV A,[(00)4016h+X] The official mouse BIOS uses 24bit "004016h+X" (BF 16 40 00), Arkanoid uses 16bit "4016h+X" (BD 16 40). Warning: Automatically activiting mouse-emulation for mouse-compatible games isn't a very good idea: Some games expect the mouse in port 1, others in port 2, so there's a 50% chance to pick the wrong port. Moreover, many games are deactivating normal joypad input when sensing a connected mouse, so automatic mouse emulation will also cause automatic problems with normal joypad input. SuperScope Games that do SUPPORT the hardware should (but usually don't) contain following string: "START OF SCOPE BIOS" In practice, the string is included only in "Yoshi's Safari" whilst all other (older and newer) games contain entirely custom differently implemented program code without ID strings, making it more or less impossible to detect SuperScope support. One workaround would be to check known Title strings: "BATTLE CLASH " "METAL COMBAT " "T2 ARCADE " "BAZOOKA BLITZKRIEG " "OPERATION THUNDERBOLT" "TINSTAR " "Hunt for Red October " "SPACE BAZOOKA " "X ZONE " "LAMBORGHINI AMERICAN " "SUPER SCOPE 6 " "YOSHI'S SAFARI " "Lemmings 2,The Tribes" Lasabirdie Games that do support the hardware should contain "GOLF_READY!" string (used to verify the ID received from the hardware). Turbo File Twin in STF Mode Games that do support the hardware should contain "FAT0" and SHVC" strings, which are usually (maybe always) stored as continous "FAT0SHVC" string. Turbo File Twin in TFII Mode or Turbo File Adapter There aren't any specific ASCII Strings. However, most (or all) games contain the "MOV Y,000F, MOV A,[004017], DEC Y, JNZ $-5" opcode sequence (exactly like so, ie. with Y=16bit, and address=24bit). NSRT Header Some ROM-images do contain information about supported controllers in NSRT Headers. In practice, most ROM-images don't have that header (but can be "upgraded" by Nach's NSRT tool). --> SNES Cartridge ROM-Image Headers and File Extensions The NSRT format isn't officially documented. The official way to create headers seems to be to contact the author (Nach), ask him to add controller flags for a specific game, download the updated version of the NSRT tool, use it to update your ROM-image, and then you have the header (which consists of undocumented, and thereby rather useless values). SNES Controllers Joypad ----------------------- Joypad Bits 1st Button B (0=High=Released, 1=Low=Pressed) 2nd Button Y (0=High=Released, 1=Low=Pressed) 3rd Button Select (0=High=Released, 1=Low=Pressed) 4th Button Start (0=High=Released, 1=Low=Pressed) 5th Direction Up (0=High=Released, 1=Low=Pressed) 6th Direction Down (0=High=Released, 1=Low=Pressed) 7th Direction Left (0=High=Released, 1=Low=Pressed) 8th Direction Right (0=High=Released, 1=Low=Pressed) 9th Button A (0=High=Released, 1=Low=Pressed) 10th Button X (0=High=Released, 1=Low=Pressed) 11th Button L (0=High=Released, 1=Low=Pressed) 12th Button R (0=High=Released, 1=Low=Pressed) 13th ID Bit3 (always 0=High) 14th ID Bit2 (always 0=High, except 1=Low for NTT Data Pad) 15th ID Bit1 (always 0=High) 16th ID Bit0 (always 0=High) 17th and up Padding (always 1=Low) (or 0=High when no pad connected) Joypad Physical Appearance __--L--_________________--R--__ Button Colors: / _ \ PAL and Japan North America | _| |_ (X) | X = Blue X = Gray | |_ _| SLCT STRT (Y) (A) | Y = Green Y = Gray | |_| (B) | A = Red A = Purple \_________.-----------._________/ B = Yellow B = Purple Joypad/Joystick Variants There are numerous variants from various companies, some including extra features like auto-fire. Advanced Control Pad (Mad Catz) (joypad with autofire or so) Angler (?) Functionally identical to the ASCII Pad (optional "stick" in dpad) asciiGrip (ASCII) (normal joypad for single-handed use) asciiPad (ASCIIWARE) (joypad with autofire and slowmotion) Capcom Pad Soldier (Capcom) (standard pad in bent/squeezed/melted design) Competition Pro (Competition Pro) (joypad with autofire and slowmotion) Competition Pro (Competition Pro) (slightly redesigned standard joypad) Conqueror 2 (QuickShot?) (joystick with autofire, programmable buttons) Cyberpad (Quickshot?) (6-shaped pad, programmable, autofile, slow motion) Dual Turbo (Akklaim) (set of 2 wireless joypads with autofire or so) Energiser (?) (very odd shaped pad, programmable, auto fire, slow motion) Fighter Stick SN (?) (desktop joystick, with autofire or so) Gamemaster (Triton) (edgy-shaped pad, one programmable button) High Frequency Control Pad (High Frequency) (normal pad, wrong button colors) Invader 2 (QuickShot?) (joypad with autofire) JS-306 Power Pad Tilt (Champ) (joypad with autofire, slowmotion, tilt-mode) Multisystem 6 (Competition Pro) (pad supports Genesis and SNES) Nigal Mouncefill Fly Wheel (Logic 3) (wheel-shaped, tilt-sensor instead dpad) NTT Data Pad (for JRA PAT) (joypad with numeric keypad) (special ID) Pro Control 6 (Naki) (joypad, programmable & whatever extra features) Pro-Player (?) (joystick) Score Master (Nintendo) (desktop joystick with autofire or so) SF-3 (Honey Bee) (very flat normal pad with autofire) SGB Controller (?) (joypad ...) SN Propad SN Propad 2 SN Propad 6 SN-6 (Gamester) (standard joypad clone) Specialized Fighter Pad (ASCIIWARE) (autofire, L/R as "normal" buttons) Speedpad (?) (joypad, one auto-switch, L/R buttons as "normal" buttons) Super Control Pad (?) (standard joypad clone, plus 3-position switch?) Super Joy Card (Hudson) (standard joypad with auto-fire or so) Supercon (QuickShot) (standard joypad, odd shape, odd start/select buttons) Superpad (InterAct) (standard joypad clone) Superpad (noname) (standard joypad) TopFighter (?) (desktop joystick, programmable, LCD panel, auto-fire, slowmo) Turbo Touch 360 (Triax) (joypad with autofire) V356 (Recoton) (normal joypad, with whatever 3-position switch) noname joypads (normal joypad clones without nintendo text nor snes logo) joypad (Konami) (wireless joypad, no extra functions) (dish-shaped receiver) joypads (Game Partner) (set of 2 wireless joypads with autofire or so) AK7017828 or so??? (Game Partner) (joypad, slow motion, auto fire) Noname pad (Tomee) (standard joypad clone) SNES+MD? (Nakitek) (joypad with whatever special features) Capcom Fighter Power Stick Super Advantage Joystick SGB Commander (HORI) Battle Pachislot Controller (Sammy) (joypad for "one-armed bandit" games) Power Plug (Tyco) Auto-fire adaptor, plugs between any joypad/joystick and snes console. SNES Controllers Mouse (Two-button Mouse) ----------------------------------------- Mouse Connection The mouse can be connected to Controller Port 1 or 2. Default seems to be Port 1 for most games. Exception: Satellaview FLASH games should default to Port 2 (the joypad controlled BS-X BIOS doesn't work with mouse plugged into Port 1). Mario Paint accepts it ONLY in Port 1, other games may accept either port (maybe there are also some that accept only Port 2?). Two-player games (eg. Operation Thunderbolt) may accept two mice to be connected. Some games (eg. Super Bomberman Panic Bomber World) refuse to run if a mouse is connected. The mouse should not be connected to Multiplayer 5 adaptors (which allow only 17mA per controller, whilst the mouse requires 50mA). Supported Games --> SNES Controllers Mouse Games Mouse Bits 1st..8th Unused (always 0=High) 9th Right Button (0=High=Released, 1=Low=Pressed) 10th Left Button (0=High=Released, 1=Low=Pressed) 11th Sensitivity Bit1 (0=High=Zero) ;\0=slow, 1=normal, 2=fast 12th Sensitivity Bit0 (0=High=Zero) ;/ 13th ID Bit3 (always 0=High) 14th ID Bit2 (always 0=High) 15th ID Bit1 (always 0=High) 16th ID Bit0 (always 1=Low) 17th Vertical Direction (0=High=Down, 1=Low=Up) 18th Vertical Offset Bit6 (0=High=Zero) ;\ 19th Vertical Offset Bit5 (0=High=Zero) ; 20th Vertical Offset Bit4 (0=High=Zero) ; this is a 7bit 21th Vertical Offset Bit3 (0=High=Zero) ; UNSIGNED value 22th Vertical Offset Bit2 (0=High=Zero) ; (00h=No motion) 23th Vertical Offset Bit1 (0=High=Zero) ; 24th Vertical Offset Bit0 (0=High=Zero) ;/ 25th Horizontal Direction (0=High=Right, 1=Low=Left) 26th Horizontal Offset Bit6 (0=High=Zero) ;\ 27th Horizontal Offset Bit5 (0=High=Zero) ; 28th Horizontal Offset Bit4 (0=High=Zero) ; this is a 7bit 29th Horizontal Offset Bit3 (0=High=Zero) ; UNSIGNED value 30th Horizontal Offset Bit2 (0=High=Zero) ; (00h=No motion) 31th Horizontal Offset Bit1 (0=High=Zero) ; 32th Horizontal Offset Bit0 (0=High=Zero) ;/ 33th and up Padding (always 1=Low) Note that the motion values consist of a Direction Bit and an UNSIGNED 7bit offset (ie. not a signed 8bit value). After reading, the 7bit offsets are automatically reset to zero (whilst the direction bits do reportedly stay unchanged unless/until the mouse is moved in opposite direction). Mouse Support ID-String Games that support the mouse should contain the string "START OF MOUSE BIOS" somewhere in the ROM-image. Mouse Sensitivity The Mouse Resolution is specified as "50 counts/inch (+/-10%)". There are three selectable Sensitivity (Threshold) settings: 0 - slow - linear fixed level (1:1) 1 - normal - exponential -?- levels (1:1 to ?:1) (?:1=smaller than 6:1) 2 - fast - exponential six levels (1:1 to 6:1) Setting 0 returns raw mickeys (so one must implement effects like double-speed threshold by software). Settings 1-2 can be used directly as screen-pixel offsets. To change the sensitivity (for port n=0 or n=1): [4016h]=01h ;set STB=1 dummy=[4016h+n] ;issue CLK pulse while STB=1 <-- increments the value, [4016h]=00h ;set STB=0 or wraps from 2 to 0 ;Thereafter, one should read the Sensitivity bits, typically like so: [4016h]=01h ;set STB=1 ;\another STB on/off, for invoking reading [4016h]=00h ;set STB=0 ;/(not sure if this part is required) for i=11 to 0, dummy=[4016h+n], next i ;skip first 12 bits for i=1 to 0, sensitivity.bit(i)=[4016h+n], next i ;read 2 sensitivity bits ;Repeat the above procedure until the desired sensitivity value is reached. Caution: According to Nintendo, the internal threshold factors aren't initialized until the change-sensitivty procedure is executed at least once (ie. after power-up, or after sensing a newly connected mouse, one MUST execute the change-sensitivity procedure, EVEN if the mouse does return the desired 2bit sensitivity code). SNES Controllers Mouse Games ---------------------------- The SNES Mouse is supported by many games, whereas most of them (except Mario Paint) can be also used with normal joypads. Games that support the SNES Mouse (the list may be incomplete) Acme Animation Factory Alice Paint Adventure Arkanoid: Doh It Again Bishoujo Senshi Sailor Moon S Kondowa Puzzle de Oshioikiyo! (Japan only) Brandish 2: Expert (Japan only) BreakThru! Civilization Cameltry (called On The Ball in North America and the UK) Cannon Fodder Dai3ji Super Robot Taisen (Japan only) Dai4ji Super Robot Taisen (Japan only) Doom Dokyusei 2 (Japan only) Dragon Knight 4 (Japan only) Eye of the Beholder Farland Story 2 (Japan only) Fun and Games Galaxy Robo (Japan only) Hiouden: Mamono-tachi tono Chikai (Japan only) Jurassic Park (mouse MUST be in slot 2) King Arthur's World Koutetsu No Kishi (Japan only) Koutetsu No Kishi 2 (Japan only) Koutetsu No Kishi 3 (Japan only) Lamborghini American Challenge Lemmings 2: The Tribes Lord Monarch (Japan only) The Lord of the Rings Mario and Wario (Japan only) Mario Paint (1992) Mario's Super Picross (Japan only) Mario's Early Years: Pre-School Mega Lo Mania Might and Magic III Motoko-chan no Wonder Kitchen (Japan only) Nobunaga's Ambition On the ball Operation Thunderbolt Pieces Populous II Power Monger Revolution X San Goku Shi Seishi: Tenbu Spirits (Japan only) Shien's Revenge SimAnt Snoopy Concert Sound Fantasy (unreleased) Spellcraft (unreleased) Super Caesars Palace Super Game Boy Super Castles (Japan only) Super Noah's Ark 3D Super Pachi-slot Mahjong Super Robot Wars 3 Super Solitaire Terminator 2: The Arcade Game Tin Star Tokimeki Memorial (Japan only) Troddlers Utopia Vegas Stakes Warrior of Rome III (unreleased) Wolfenstein 3D Wonder Project J Zan 2: Spirits (Japan only) Zan 3: Spirits (Japan only) Plus (!): Kaite Tsukutte Asoberu Dezaemon (Japan only) Pro Action Replay Mk3 Kakinoki Shogi (1995) ASCII Corporation (JP) Spell Craft: Aspects of Valor (1993) ... same as "Spellcraft (unreleased)"? (in Spellcraft: mouse works in-game only, not in title screen) Moreover, the "SNES Test Program" (1991 by Nintendo) includes a Mouse test. SNES Controllers Multiplayer 5 (MP5) (Five Player Adaptor) ---------------------------------------------------------- The MP5 plugs into one Controller Port on the SNES (typically Port 2), and has 4 ports for controllers to be plugged into it (labeled 2 through 5). It also has an override switch which makes it pass through Pad 2 and ignore everything else. Reading Controller Data [4016h].Bit0=1 ;-strobe on (to player 1-5) [4016h].Bit0=0 ;-strobe off (to player 1-5) read any number of bits from [4016h].Bit0 ;-read Player 1 data read any number of bits from [4017h].Bit0/Bit1 ;-read Player 2/3 data [4201h].Bit7=0 ;-select Player 4/5 read any number of bits from [4017h].Bit0/Bit1 ;-read Player 4/5 data [4201h].Bit7=1 ;(prepare here for next frame) ;-select Player 2/3 do no further access until next frame (allow [4201h].Bit7=1 to stabilize) The strobe on/off part, and reading first 16bits for player 1-3 is usually done via automatic reading (whereas, Player 3 data will obviously show up in "JOY4" register, not in "JOY3" register). Whilst reading further player 1-3 bits, and all player 4-5 bits is done via manual reading. As shown above, player 2-3 should be always read before 4-5, for two reasons: At least some MP5 devices may respond slowly on 0-to-1 transitions of [4201h].Bit7 (unless the device contains a pull-up resistor). Some MP5's (namely the Tribal Tap) are always passing CLK to player 2 (in that case player 2 data would be shifted-out when accessing player 4-5 data). Detecting the MP5 Hardware Below can be used to detect MP5 in ports 1 (n=0) and 2 (n=1). Games do usually check both ports (and show an error messages when sensing a MP5 in port 1). [4016h].Bit0=1 ;-strobe on (force MP5 Bit1=1) read 8 bits from [4016h+n].Bit1 to byte A ;-read byte A [4016h].Bit0=0 ;-strobe off (normal data mode) read 8 bits from [4016h+n].Bit1 to byte B ;-read byte B if A=FFh and B<>FFh then MP5=present ;-verify result If there's no MP5 connected, then A and B will be typically 00h (since most controllers don't use [4017h].Bit1, exceptions are Turbo File, SFC Modem, Voice-Kun, and X-Band Keyboard). If a MP5 is connected, then A will be FFh, and B will be first 8bit of data from joypad 3 or 5 (which can't be FFh since one can't push all four DPAD directions at once). Also note that there is nothing preventing the MP5 from functioning perfectly when plugged in to Port 1, except that the game must use bit 6 of $4201 instead of bit 7 to set IOBit and must use the Port 1 registers instead of the Port 2 registers. With 2 MP5 units, one could actually create an 8-player game. Supported/Unsupported Games/Hardware The Multiplayer is supported by more than 100 games, but incompatible with almost everything except normal joypads. --> SNES Controllers Multiplayer 5 - Unsupported Hardware --> SNES Controllers Multiplayer 5 - Supported Games Multitap/Multiplayer Adaptor Versions 2or3? Way Multiplay Adaptor (Gamester LMP) (with only 2 (or 3?) sockets) 5 Player Game Plug (Laing) (same polygonal case as SN-5) HORI Multitap HSM-07 (HORI) (4 "top-loading" connectors) HORI Super Tetris 3 (HORI) (red case, otherwise same as HORI HSM-07) Multi Adaptor Auto (Partyroom21) Multi Player Adaptor (unknown manufacturer) (roughly PS1 shaped) Multi-Player Adaptor (Super Power) (same case as Multiplay Adaptor from LMP) Multiplay Adaptor (Gamester LMP) (square gray case, "crown" shaped LMP logo) SN-5 Multitap (Phase 9) (same polygonal case as Super 5 QJ/Super 5-Play) SNES MultiPlayer 5 Schematic Diagram (1st May 1992) (Nintendo) (book2.pdf) Super 5 QJ (same polygonal case as SN-5) Super 5 Multi-Player Adapter by Innovation (same polygonal case as SN-5) Super 5-Play (Performance) (same polygonal case as SN-5) Super Link by BPS (Bullet Proof Software) (same case as HORI HSM-07) Super Multitap (noname) (polyshaped, but different than the SN-5 case) Super Multitap (Hudson) (long slim device with 4 connectors on front panel) Super Multitap 2 (Hudson) (square device with yellow Bomberman face) Super Multitap Honest (same polygonal case as SN-5) Tribal-Tap 5 (Nakitek) (same case as Multiplay Adaptor from LMP) Tribal Tap, 6 Player Adaptor (Naki) Tribal Tap, 6 Player Adaptor (Fire) (same as Naki, but without Naki logo) SNES MultiPlayer 5 - Schematic Diagram (Rev 2.3) 1st May 1992 _________ _________ |74HCT4053| | 74HC241 | | | /MODE5P--->|/OE | ??? --->|VEE /EN|<------STB--------------->|IN OUT|---> STB'BCD | _ _ _ | STB'A--->|IN OUT|---> DETECT IO'SEL --->|SELX X1|------>CLK1-------------->|IN OUT|---> CLK'B CLK --->|X _ _ _X0|------>CLK0-------------->|IN _ _OUT|---> CLK'CD IO'SEL --->|SELY Y1|<-------------------------|OUT IN|<--- IN0'A IN0 <---|Y _ _ _Y0|<-------------------------|OUT IN|<--- IN0'C IO'SEL --->|SELZ Z1|<-------------------------|OUT IN|<--- IN01 IN1 <---|Z Z0|<-------------------------|OUT IN|<--- IN0'D | | ??? --->|OE | |_________| |_________| _________ _________ | 74HC126 | |4-Channel| CLK --->|IN OUT|---> CLK1 VCC --->|2P Switch|---> /MODE5P STB'A --->|OE _ _ | GND --->|5P _ _ _ | CLK1 --->|IN OUT|---> CLK'A GND --->|2P |---> VCC'BCD ??? --->|OE _ _ | VCC --->|5P _ _ _ | STB --->|IN OUT|---> STB'A IN1'A --->|2P |---> IN01 ??? --->|OE _ _ | IN0'B --->|5P _ _ _ | GND --->|IN OUT|---> IN1 IO'A <---|2P |<--- IO DETECT --->|OE | IO'SEL <---|5P | |_________| |_________| __________________________________________ | (Female)(............Male.............)| GND ------[10K]----- DETECT |Pin SNES PORT2 PORT3 PORT4 PORT5 | VCC ------[10K]----- IO'SEL |1 VCC VCC VCC'BCD VCC'BCD VCC'BCD| VCC ------[10K]----- CLK1 |2 CLK CLK'A CLK'B CLK'CD CLK'CD | VCC ------[10K]----- CLK0 |3 STB STB'A STB'BCD STB'BCD STB'BCD| VCC ------[10K]----- IN0'A |4 IN0 IN0'A IN0'B IN0'C IN0'D | VCC ------[10K]----- IN01 |5 IN1 IN1'A - - - | VCC'BCD ------[10K]----- IN0'C |6 IO IO'A - - - | VCC'BCD ------[10K]----- IN0'D |7 GND GND GND GND GND | VCC'BCD -- to the OUT0 pin; not verified), then it's probably really a fake. The Tribal Tap schematic should be reportedly looking somehow like so: .-----. .-----. VCC--[RP]-------CLK---> 1|IN0 '-' VCC|20 <---VCC VCC--[RP]--------IO---> 2|IN1 16L8 OUT7|19 --->IN0 (out-only) VCC--[RP]-----IN0'A---> 3|IN2 PAL I/O6|18 --->IN1 VCC--[RP]-----IN1'A---> 4|IN3 I/O5|17 --->STB'A VCC--[RP]---/MODE6P---> 5|IN4 I/O4|16 --->IO'A VCC--[RP]-----IN0'B---> 6|IN5 I/O3|15 --->CLK'B VCC--[RP]---/MODE2P---> 7|IN6 I/O2|14 --->CLK'CDE VCC--[RP]-----IN0'D---> 8|IN7 I/O1|13 --->STB'BCDE VCC--[RP]-----IN0'C---> 9|IN8 OUT0|12 <---IN0'E (out-only???) GND -->10|GND IN9|11 <---/STB----[R]---VCC '-------------' .----------. .-------. .-------. |3-position| | S9013 | | S9013 | .-[R]-STB |switch 2P|--/MODE2P | E|-->VCC'BCDE | E|---GND | GND--| 5P|--NC | NPN B|<--/MODE2P | NPN B|<-------+ | 6P|--/MODE6P | C|---SNES.VCC | C|-->/STB | '----------' '-------' '-------' '-[R]-GND .------------------------------------------------------. | (Female)(.............Male........................)| ???--|LED>--??? |Pin SNES PORT2 PORT3 PORT4 PORT5 PORT6 | |1 VCC VCC VCC'BCDE VCC'BCDE VCC'BCDE VCC'BCDE| further resistors |2 CLK CLK CLK'B CLK'CDE CLK'CDE CLK'CDE | ??? |3 STB STB'A STB'BCDE STB'BCDE STB'BCDE STB'BCDE| |4 IN0 IN0'A IN0'B IN0'C IN0'D IN0'E | (not installed) |5 IN1 (IN1'A) - - - - | diodes ??? |6 IO (IO'A) - - - - | |7 GND GND GND GND GND GND | '------------------------------------------------------' Note: The PCB has wires to all 7 pins of PORT2, but the installed connector has only 5 pins, so, in practice, IN1'A and IO'A are not connected. SNES Controllers Multiplayer 5 - Unsupported Hardware ----------------------------------------------------- The Multiplayer 5 is incompatible with almost everything except normal joypads/joysticks. The only other things that do work are Twin Taps, and maybe also the NTT Data Pad (unless it exceeds 17mA, and unless games do refuse it as device with "unknown" controller ID). Unsupported Hardware in MP5 controller slots (due to missing signals) Lightguns Turbo File SFC Modem Voice-Kun X-Band Keyboard A second MP5 plugged into the first MP5 Prohibited Hardware The hardware/combinations listed below are "prohibited" (and aren't supported by any offical/licensed games). Nethertheless, they should be working in practice, hopefully without immediately catching fire or blowing the fuse (but might act unstable or cause some overheating in some situations; results vary depending on hardware/production variants, room temperature, used CPU/PPU/APU load, individual or official safety measures, and on type/amount of connected cartridges/controllers). Prohibited Hardware in MP5 controller slots (due to exceeding 17mA per slot) Mouse (requires 50mA) Devices with unknown controller IDs (which might exceed 17mA) Maybe also various unlicensed wireless/autofire joypads/joysticks Prohibited Hardware in CARTRIDGE slot (due to overall power consumption) Cartridges with GSU-n (programmable RISC CPU) (aka Super FX/Mario Chip) Maybe also things like X-Band modem and Cheat Devices Prohibited Hardware in BOTH controller ports (unspecified reason) Two MP5's (connected to port 1 and 2) (maybe also power consumption related) Prohibited Hardware in FIRST controller port (just by convention) MP5 in port 1 (instead of port 2) (would mess-up the port 2-5 numbering) SNES Controllers Multiplayer 5 - Supported Games ------------------------------------------------ Multiplayer 5 Games Game Languages Players Bakukyuu Renpatsu!! Super B-Daman ("battle mode") (J) 4 Bakutou Dochers: Bumps-jima wa Oosawagi ("battle mode") (J) 4 Barkley Shut Up and Jam! / Barkey no Power Dunk (E,J) 4 Battle Cross (supports only 5 joypads; player 6 always inactive) (J) 5 Battle Jockey (J) 4 Bill Walsh College Football (E) 4 Chibi Maruko-chan: Mezase! Minami no Island!! (J) 4 College Slam (E) 4 Crystal Beans From Dungeon Explorer (J) 3 Dino Dini's Soccer! (E,F,G) ?? Dragon: The Bruce Lee Story (E) 3 Dream Basketball: Dunk & Hoop (only 5, not 6) (J) 5 Dynamic Stadium (J) 4 Elite Soccer / World Cup Striker (E,F,G,J) 4 ESPN National Hockey Night (E) 5 FIFA International Soccer (E,J) 4 FIFA Soccer 96 (E,F,G,I,S,SW) 4 FIFA Soccer 97: Gold Edition / FIFA 97: Gold Edition (E,F,G,I,S,SW) 5 FIFA 98: Road to World Cup (E,F,G,I,S,SW) 5 Finalset (J) 4 Fire Striker / Holy Striker (E,J) 4 Fever Pitch Soccer / Head-On Soccer (E,F,G,I,S) 4 From TV Animation Slam Dunk: SD Heat Up!! (J) 5 Go! Go! Dodge League (J) 4 HammerLock Wrestling/Tenryuu Genichirou no Pro Wrestling Revol. (E,J) 4 Hanna Barbera's Turbo Toons (E) 5 Hat Trick Hero 2 (J) 4 Hebereke no Oishii Puzzle wa Irimasenka (J) 5 Human Grand Prix III: F1 Triple Battle (J) 3 Human Grand Prix IV: F1 Dream Battle (J) 3 Hungry Dinosaurs / Harapeko Bakka (E,J) ?? International Superstar Soccer Deluxe/Jikkyou World Soccer 2 (E,J) 4 J.League Excite Stage '94 / Capcom's Soccer Shootout (E,J) 4 J.League Excite Stage '95 (J) 4 J.League Excite Stage '96 (J) 4 J.League Soccer Prime Goal (J) ? J.League Super Soccer '95 Jikkyo Stadium (J) 4 J.R.R. Tolkien's The Lord of the Rings: Volume 1 (E,G) 4 Jikkyou Power Pro Wrestling '96: Max Voltage (only 4, not 5) 5? (J) 4 Jimmy Connors Pro Tennis Tour (japanese version only?) (E,F,G,J) 4 JWP Joshi Pro Wrestling: Pure Wrestle Queens (J) 4 Kingyo Chuuihou! Tobidase! Game Gakuen (J) 3 Kunio-kun no Dodge Ball Da yo Zenin Shuugou! (J) 4 Looney Tunes B-Ball / Looney Tunes Basketball (E) 4 Madden NFL '94 / NFL Pro Football '94 (E,J) 4 Madden NFL 95 (E) 4 Madden NFL 96 (E) 5 Madden NFL 97 (E) 4 Madden NFL 98 (E) 5 Micro Machines (E) 4 Micro Machines 2: Turbo Tournament (E) 4 Mizuki Shigeru no Youkai Hyakkiyakou (J) 4 Multi Play Volleyball (J) 4 Natsume Championship Wrestling (E) 4 N-Warp Daisakusen (homebrew) (requires 2 multitaps) (E) 8 NBA Give 'n Go / NBA Jikkyou Basket: Winning Dunk (E,J) 4 NBA Hang Time (E) 4 NBA Jam (E,J) 4 NBA Jam: Tournament Edition (E,J) 4 NBA Live 95 (E,J) 5 NBA Live 96 (E) 5 NBA Live 97 (E) 5 NBA Live 98 (E) 5 NCAA Final Four Basketball (E) 4 NCAA Football (E) 4 NFL Quarterback Club / NFL Quarterback Club '95 (E,J) 5 NFL Quarterback Club 96 (E,J) 5 NHL '94 / NHL Pro Hockey '94 (E,J) 5 NHL '94 / NHL Pro Hockey '94 (E,J) 5 NHL '95 (E) ? NHL '96 (E) ? NHL '97 (E) ? NHL '98 (E) 5 Olympic Summer Games (E) 5 Peace Keepers, The / Rushing Beat Shura (E,J) 4 Pieces / Jigsaw Party (E,J) 5 Rap Jam: Volume One (E,F,S) 4 Saturday Night Slam Masters / Muscle Bomber: Body Explosion (E,J) 4 Secret of Mana / Seiken Densetsu 2 (E,F,G,J) 3 Secret of Mana 2 / Seiken Densetsu 3 (with patch by Parlance) (E,J,patch) 3 Shijou Saikyou no Quiz Ou Ketteisen Super (uses 4 twin taps) (J) 8 Shin Nihon Pro Wrestling: Chou Senshi in Tokyo Dome (J) 4 Shin Nihon Pro Wrestling Kounin: '94 Battlefield in Tokyo Dome (J) 4 Shin Nihon Pro Wrestling Kounin: '95 Tokyo Dome Battle 7 (J) 4 Smash Tennis / Super Family Tennis (E,J) 4 Sporting News Power Baseball, The (E) 4 Sterling Sharpe: End 2 End (E) 4 Street Hockey '95 (E) 4 Street Racer (E,J) 4 Sugoi Hebereke (J) 4 Sugoro Quest++: Dicenics (J) 4 Super Bomberman (E,J) 4 Super Bomberman: Panic Bomber World (J) 4 Super Bomberman 2 (E,J) 4 Super Bomberman 3 (E,J) 5 Super Bomberman 4 (J) 5 Super Bomberman 5 (J) 5 Super Fire Pro Wrestling: Queen's Special (J) ? Super Fire Pro Wrestling Special (J) ? Super Fire Pro Wrestling X (J) ? Super Formation Soccer 94: World Cup Edition (J) ? Super Formation Soccer 95: della Serie A (J) ? Super Formation Soccer 96: World Club Edition (J) ? Super Formation Soccer II (J) ? Super Ice Hockey / Super Hockey '94 (E,J) ? Super Kyousouba: Kaze no Sylphid (J) ? Super Power League (J) ? Super Puyo Puyo Tsu: Remix (J) 4 Super Slam Dunk / Magic Johnson no Super Slam Dunk! (E,J) ? Super Tekkyuu Fight! (J) ? Super Tetris 3 (J) 4 Syndicate (E,F,G,J) 4 Tiny Toon Adventures: Wacky Sports/Dotabata Daiundoukai (E,J) 4 Top Gear 3000 / Planet's Champ TG 3000, The (E,J) 4 Vegas Stakes / Las Vegas Dream in Golden Paradise (E,J) 4 Virtual Soccer / J.League Super Soccer (E,J) 5 Vs. Collection (J) ? Wedding Peach (J) 3 WWF Raw (E) 4 Yuujin no Furi Furi Girls (J) 4 Zero 4 Champ RR (J) ? Zero 4 Champ RR-Z (J) ? Plus... Momotaro Dentetsu Happy (1996) Hudson Soft (JP) Bomberman B-Daman: 4 players (via Battle) Kiteretsu Daihyakka - Choujikuu Sugoroku: 5 players J.League '96 Dream Stadium: 4 players Corrections: Elite Soccer/World Cup Striker: 5 players (Using the "Multiple Players" option while setting up for a game, you can assign different people to different controllers.) FIFA International Soccer: 5 players FIFA Soccer 96: This actually supports 5 players, not four. Pause the game and access the controllers with a multi-tap connected... up to five can join in. Madden NFL '94: 5 players Madden NFL '95: 5 players Madden NFL '97: 5 players Does this really support the multi-tap? Dino Dini's Soccer J.League Soccer Prime Goal NHL '95 through '97 SNES Controllers SuperScope (Lightgun) -------------------------------------- SUPER SCOPE Front Sight Sight Tube Receiver (connect to / _______ / ___ / controller slot 2) =-- |__.-.__|( _______|___|_______ \ \_______________/ __/ | _______________ | /___.___________.___/ | | | | : : | | | | : Slot 1 : Slot 2 | | TV SET | | : : | | | | : : | | | | V V | |_______________| | |___________________| |__|_|_|_|_|_|_|__| Transmitter / Release Pause / Slot 1 / Slot 2 Fire / Power Switch (Off/On/Turbo) _____ / / / / / / \\____\____._______,___._______,,__,,_.._________ || ^ \\\\\///// \ || _____/ ||___ ________________________ / \ \\ <-Cursor _/ / \ \ __/ / \ \ \ /______ \ \ \ _________\ \_____\ /___/ <-- Shoulder Rest Batteries Takes six "AA" batteries. Which do reportedly last only for a few hours. Super Scope Bits 1st Fire Button (0=High=Released, 1=Low=Pressed/Newly Pressed) 2nd Cursor Button (0=High=Released, 1=Low=Pressed) 3rd Turbo Switch (0=Normal/PowerOn, 1=Turbo/PowerOn) 4th Pause Button (0=High=Released, 1=Low=Newly Pressed) 5th..6th Extra ID Bits (always 0=High) 7th Offscreen (0=High=Okay, 1=Low=CRT-Transmission Error) 8th Noise (0=High=Okay, 1=Low=IR-Transmission Error) 9th..12th Extra ID Bits (always 1=Low) 13th..16th ID Bits (always 1=Low=One) (0Fh) 17th and up Unused (always 1=Low) For obtaining the H/V position & latch flag (Ports 213Ch,213Dh,213Fh), see: --> SNES PPU Timers and Status Games compatible with the Super Scope Battle Clash (US) (EU) / Space Bazooka (JP) (1992) Nintendo Bazooka Blitzkrieg (US) (1992) Bandai Hunt for Red October (used for bonus games) (US) (EU) (JP) Lamborghini American Challenge (used in special game mode) (US) (EU) (1993) Lemmings 2 (US) (EU) (JP) (1994) Psygnosis (at game start: aim at crosshair) Metal Combat: Falcon's Revenge (includes OBC1 chip) (US) (1993) Operation Thunderbolt (US) (1994) Taito Super Scope 6 (bundled with the hardware) (Blastris & LazerBlazer) (1992) Terminator 2 - T2: The Arcade Game (US) (EU) (JP) (1993) Carolco/LJN Tin Star (US) (1994) Nintendo X-Zone (US) (EU) (1992) Kemco Yoshi's Safari (US) (EU) (JP) (1993) Nintendo Moreover, the "SNES Test Program" (1991 by Nintendo) includes a Super Scope test, and, reportedly, there's also a special Super Scope test cartridge (?) Notes The SuperScope has two modes of operation: normal mode and turbo mode. The current mode is controlled by a switch on the unit, and is indicated by the 3rd bit. Note however that the 3rd bit is only updated when the Fire button is pressed (ie. the 1st bit is set). Thus, when you turn turbo on the 3rd bit remains clear until you shoot, and similarly when turbo is deactivated the bit remains set until you fire. In either mode, the Pause bit will be set for the first strobe after the pause button is pressed, and then will be clear for subsequent strobes until the button is pressed again. However, the pause button is ignored if either cursor or fire are down(?). In either mode, the Cursor bit will be set while the Cursor button is pressed. In normal mode, the Fire bit operates like Pause: it is on for only one strobe. In turbo mode, it remains set as long as the button is held down. When Fire/Cursor are set, Offscreen will be set if the gun did not latch during the previous strobe and cleared otherwise (Offscreen is not altered when Fire/Cursor are both clear). If the Fire button is being held when turbo mode is activated, the gun sets the Fire bit and begins latching. If the Fire button is being held when turbo mode is deactivated, the next poll will have Fire clear but the Turbo bit will stay set (because it isn't be updated until pressing fire the next time). The PPU latch operates as follows: When Fire or Cursor is set, IOBit is set to 0 when the gun sees the TV's electron gun, and left a 1 otherwise. Thus, if the SNES also leaves it one (bit7 of 4201h), the PPU Counters will be latched at that point. This would also imply that bit7 of 4213h will be 0 at the moment the SuperScope sees the electron gun. Since the gun depends on the latching behaviour of IOBit, it will only function properly when plugged into Port 2. If plugged into Port 1 instead, everything will work except that there will be no way to tell where on the screen the gun is pointing. When creating graphics for the SuperScope, note that the color red is not detected. For best results, use colors with the blue component over 75% and/or the green component over 50%. Data2 is presumably not connected, but this is not known for sure. SNES Controllers Konami Justifier (Lightgun) -------------------------------------------- -_______________________-- | : :....: \_/\ |________________:__:....: / \________________\.:....; O \_ <---- O = Start Button |_ _____ | \| ) |/\ \ <---- ) = Trigger \___/ | | | | |_____| RJ12-socket ____/ \________ Cable (to SNES controller port) (for second gun) Blue Gun --> connects to SNES (and has 6pin RJ12 socket for second gun) Pink Gun --> connects to 6pin RJ12 socket of first gun Justifier Bits 1st..12th Unused (always 0=High) 13th..16th ID Bit3-0 (MSB first, 1=Low=One, always 0Eh = 1110b) 17th..24th Extra ID Bit7-0 (MSB first, 1=Low=One, always 55h = 01010101b) 25th Gun 1 Trigger (1=Low=Pressed?) 26th Gun 2 Trigger (1=Low=Pressed?) 27th Gun 1 Start Button (1=Low=Pressed?) 28th Gun 2 Start Button (1=Low=Pressed?) 29th Previous Frame was H/V-latching Gun1/2 (1=Low=Gun1, 0=High=Gun2) 30th..32th Unused (always 0=High) 33th and up Unused (always 1=Low) For obtaining the H/V position & latch flag (Ports 213Ch,213Dh,213Fh), see: --> SNES PPU Timers and Status Note that the 29th bit toggles even when Gun2 is not connected. SNES Justifier Game(s) Lethal Enforcers (bundled with the hardware) (1993) Konami (US) (EU) (JP) IOBit is used just like for the SuperScope. However, since two guns may be plugged into one port, which gun is actually connected to IOBit changes each time Latch cycles. Also note, the Justifier does not wait for the trigger to be pulled before attempting to latch, it will latch every time it sees the electron gun. Bit 6 of $213F may be used to determine if the Justifier was pointed at the screen or not. Data2 is presumably not connected, but this is not known for sure. Nardz: "Actually when I was a kid, I bought the SNES Justifier Battle Clash package. The Weird thing about it is that The package had A Sega Justifier in it, but it came with this SNES/Sega Adapter, which pluged into your SNES and the Sega Justifier would plug into the back of the connector." -- But, Battle Clash is a Super Scope game, not a Justifier game??? The pinouts of the 6pin RJ12-socket are unknown. Sega Version There's also an identically looking Blue Gun for Sega (but with 9pin joystick connector). The Pink Gun can be used with both SNES and Sega Blue Gun versions. SNES Controllers M.A.C.S. (Lightgun) ------------------------------------ Multi-Purpose Arcade Combat Simulator (M.A.C.S.) This lightgun was used by the US Army to introduce beginners how to kill real people. It was also shown on career days at high schools to win new recruits. The hardware consists of a small lightpen attached to a M16 rifle. Software cartridges exist for C64 and SNES. Lightpen _____ ____....-----\ _ |_____| #\\ ________________ |______________\//______________ ___"__"__# -------"""""" |--| | |___#__#__#_ | | Trigger __ | " " # |_|------..._________________|--|_ ___ | '--.__ | | | \ \ \ '--.___| |_ _ _ _|_/_/ \ | | \ \ |_____| \ \ |___/ I/O Ports The lightgun connects to the lightpen input on 2nd controller port. Aside from the HV-Latches, it uses only one I/O signal: 4017h.Bit0 Trigger Button (1=LOW=Pressed) That is, only a single bit (no serial data transfer with CLK/STB signals). A standard joypad attached to 1st controller port allows to calibrate the lightpen (via Select button). For obtaining the H/V position & latch flag (Ports 213Ch,213Dh,213Fh), see: --> SNES PPU Timers and Status SNES Software MACS Basic Rifle Marksmanship v1.1e (v1.2a) (1993) Sculptured Software (US) MACS Basic Rifle Marksmanship v1994.0 (1994?) MACS Moving Target Simulator (?) (1993) Sculptured Software (US) Note: Version "1.1e" is displayed in the title screen, whilst the version string at ROM offset 05819h identifies it as version "1.2a". The program code looks crude and amateurish, and (as indicated by the corrupted ROM header) it never passed through Nintendo's Seal of Quality process. SNES Controllers Twin Tap ------------------------- The Twin Tap from Partyroom21 (aka Yonezawa PR21) is a special controller for 8-player quiz games. The Twin Tap itself consists of 7pin SNES controller connector with two cables, and a push-button on each cable-end (one button per player). For the 8-player mode, four Twin Taps need to be connected to a multiplayer adaptor (such like Partyroom21's own "Multi Adaptor Auto"). The Twin Tap is supported by Shijou Saikyou no Quiz Ou Ketteisen Super (1992) TBS/Partyroom21/S'pal (JP) Transfer Protocol 1st Button 2 (or 4/6/8) (1=Low=Pressed) (would be "B" on joypads) 2nd Button 1 (or 3/5/7) (1=Low=Pressed) (would be "Y" on joypads) 3rd..12th Unknown 13th..16th Unknown (would be ID Bit3..0 on other SNES controllers) 17th..24th Unknown (would be Extended ID Bit7..0 on other SNES controllers) 25th and up Unknown Judging from disassembled game code, the 4bit ID might be 00h or 0Eh, in the latter case, there be also a unique Extended ID value. SNES Controllers Miracle Piano ------------------------------ Miracle Piano Teaching System (The Software Toolworks) --> SNES Controllers Miracle Piano Controller Port --> SNES Controllers Miracle Piano MIDI Commands --> SNES Controllers Miracle Piano Instruments --> SNES Controllers Miracle Pinouts and Component List __ _________________________________________________________ __ | |:::::::::::: MIRACLE .. .. .. .. .. ::::::::::::| | | |:::::::::::: .. .. .. .. .. ::::::::::::| | | |:::::::::::: # # # # : .. .. .. .. ::::::::::::| | | |:::::::::::: # # # # : .. .. .. ::::::::::::| | | |_________________________________________________________| | | | U U | U U U | U U | U U U | U U | U U U | U U | U U U | | | | | U U | U U U | U U | U U U | U U | U U U | U U | U U U | | |Keys | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |__|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|__| C D E F G A H C D E F G A H C D E F G A H C D E F G A H C Notes <-------------><------------><------------><------------>X Octaves 36..47 48..59 | 60..71 72..83 84 Key Numbers | Middle C 49 Piano Keys (29 White Keys, 20 Black Keys) (4 octaves, plus next higher C) 1 Foot Pedal (Sustain) 8 Push Buttons (Mode/Volume Selection) SNES Controllers Miracle Piano Controller Port ---------------------------------------------- Miracle Controller Port Transfer Read Direction (invoked by SHORT Strobe signal) 1st Data Present Flag (0=High=None, 1=Low=Yes) 2nd..9th Data Bit7..0 (MSB First, inverted 1=LOW=Zero) 10th..12th Unknown 13th..16th Unknown (would be ID Bit3..0 on other SNES controllers) 17th and up Unknown Write Direction (invoked by LONG Strobe signal, data output on STROBE line) 1st..8th Data Bit7..0 (MSB First, 0=LOW=Zero) Observe that read/write direction depends on length of initial Strobe signal (so games that are reading joypad with other strobe-lengths might mess up things). 10th bit and up (including the 4bit Controller ID) might be garbage (depending on how the 8051 CPU in the keyboard handles the data transfer). However, with appropriate timings, detecting a Miracle could be done via the "Firmware version request" MIDI command. Note: The NES and SNES Miracle software expects the piano keyboard connected to Port 1, and a normal joypad connected to Port 2. miracle_recv_byte [004016h]=01h ;strobe on delay (strobe=1 for 102 master clks) ;short delay = READ mode [004016h]=00h ;strobe off data_present_flag = [004016h].bit0 ;data present flag (1=LOW=Yes) for i=7 to 0 data.bit(i)=NOT [004016h].bit0 ;data bits (MSB first, 1=LOW=Zero) next i miracle_send_byte [004016h]=01h ;strobe on (start bit) delay (strobe=1 for 528 master clks) ;long delay = WRITE mode for i=7 to 0 [004016h].bit0=data.bit(i) ;data bits (MSB first, 1=HIGH=One) dummy=[004016h] ;issue short CLK pulse next i [004016h]=00h ;strobe off (stop/idle) delay (strobe=0 for min 160 master clks) ;medium delay SNES Controllers Miracle Piano MIDI Commands -------------------------------------------- The Miracle is always using MIDI messages (no matter if the messages are transferred through MIDI or RS232 or NES/SNES/Genesis controller cables). Below lists the supported MIDI messages (including "Undocumented" messages, which are used by the Miracle's SNES software, although they aren't mentioned in the Miracle's Owner's Manual). MIDI Information Sent FROM/TO The Miracle keyboard Expl. Dir Hex Note off (Undocumented) W 8#h,,00h ;same as Note ON with velo=00h Note on/off command R/W 9#h,, Main volume level W B0h,07h, Sustain on/off command R/W B#h,40h, Local control on/off W B0h,7Ah, All notes off W B#h,7Bh,00h Patch change command (*) R ?? C#h, ;TO keyboard = Undocumented Miracle button action R F0h,00h,00h,42h,01h,01h,,F7h Unknown (Undocumented) W F0h,00h,00h,42h,01h,02h,,F7h ;??? Keyboard buffer overflow R F0h,00h,00h,42h,01h,03h,01h,F7h Midi buffer overflow R F0h,00h,00h,42h,01h,03h,02h,F7h Firmware version request W F0h,00h,00h,42h,01h,04h,F7h Miracle firmware version R F0h,00h,00h,42h,01h,05h,,,F7h Patch split command W F0h,00h,00h,42h,01h,06h,0#h,,,F7h Unknown (Undocumented) W F0h,00h,00h,42h,01h,07h,F7h ;??? All LEDs on command W F0h,00h,00h,42h,01h,08h,F7h LEDs to normal command W F0h,00h,00h,42h,01h,09h,F7h Reset (Undocumented) W FFh Direction: R=From keyboard, W=To keyboard Notes: (*) Patch change FROM Keyboard is sent only in Library mode. N#h Hex-code with #=channel (#=0 from keyb, #=0..7 to keyb) Key (FROM Miracle: 24h..54h) (TO Miracle: 18h..54h/55h?) Velocity (01h..7Fh, or 00h=Off) Volume (00h=Lowest, 7Fh=Full) Flag (00h=Off, 7Fh=On) Instrument (00h..7Fh) for all notes Instrument (00h..7Fh) for notes 24?/36-59, lower patch number Instrument (00h..7Fh) for notes 60-83/84?, upper patch number . Version (from version 1.0 to 99.99) button on/off (bit0-2:button number, bit3:1=on, bit4-7:zero) Data from piano is always sent on first channel (#=0). Sending data to piano can be done on first 8 channels (#=0..7), different instruments can be assigned to each channel. Although undocumented, the SNES software does initialize 16 channels (#=0..0Fh), unknown if the hardware does support/ignore those extra channels (from the instrument table: it sounds as if one could use 16 single-voice channels or 8 dual-voice channels). SNES Controllers Miracle Piano Instruments ------------------------------------------ Available Patches (aka Instruments) The following patches are available through both Library Select Mode and MIDI control: 000 Grand Piano 032 Marimba 064 Synth Bells 096 Tube Bells' 001 Detuned Piano 033 Glockenspiel' 065 Vox 1 097 Frogs/Ducks 002 FM Piano 034 Kalimba' 066 Vox 2 098 Banjo' 003 Dyno 035 Tube Bells 067 Vox 3 099 Shakuhachi' 004 Harpsichord 036 Steel Drums 068 Mod Synth 100 Piano' 005 Clavinet 037 Log Drums' 069 Pluck Synth 101 Vibraphone' 006 Organ 038 Strings 1 070 Hard Synth 102 FM Piano' 007 Pipe Organ 039 Pizzicato 071 Syntar 103 Clock Belis' 008 Steel Guitar 040 Strings 2 072 Effects 1 * 104 Harpsichord' 009 12-StringGuitar 041 Violin 1' 073 Effects 2 * 105 Clavinet' 010 Guitar 042 Trumpet' 074 Percussion 1 * 106 Organ' 011 Banjo 043 Trumpets 075 Percussion 2 * 107 Pipe Organ' 012 Mandolin 044 Horn' 076 Percussion 3 * 108 Metal Guitar' 013 Koto' 045 Horns 077 Sine Organ' 109 Stick' 014 Jazz Guitar' 046 Trombone' 078 Organ # 110 Guitar' 015 Clean Guitar' 047 Trombones 079 Pipe Organ # 111 Xylophone' 016 Chorus Guitar 048 CupMuteTrumpet' 080 Harpsichord # 112 Marimba' 017 Fuzz Guitar 049 Sfz Brass 1 081 Synth Pad 1 113 Syn Trombone' 018 Stop Guitar 050 Sfz Brass 2 082 Synth Pad 2 114 Syn Trumpet' 019 Harp' 051 Saw Synth 083 Synth Pad 3 115 Sfz Brass 1' 020 Detuned Harp 052 Tuba' 084 Synth Pad 4 116 Sfz Brass 2' 021 Upright Bass' 053 Harmonica 085 Synth Pad 5 117 Saw Synth' 022 Slap Bass' 054 Flute' 086 Synth Pad 6 118 Church Bells' 023 Electric Bass' 055 Pan Flute' 087 Synth Pad 7 119 Marcato' 024 Moog 056 Calliope 088 Synth Pad 8 120 Marcato 025 Techno Bass 057 Shakuhachi 089 Synth Pad 9 121 Violin 2' 026 Digital Waves 058 Clarinet' 090 Synth Pad 10 122 Strings 3 027 Fretless Bass' 059 Oboe' 091 Synth Pad 11 123 Synth Bells' 028 Stick Bass 060 Bassoon' 092 Synth Pad 12 124 Techno Bass' 029 Vibraphone 061 Sax' 093 Synth Pad 13 125 Mod Synth' 030 MotorVibraphone 062 Church Bells 094 Synth Pad 14 126 Pluck Synth' 031 Xylophone 063 Big Bells 095 Synth Pad 15 127 Hard Synth' Notes: ' These programs are single voice, which lets The Miracle play up to 16 notes simultaneously. All other programs are dual voice, which lets it play up to 8 notes simultaneously. * 072..076 See below for a list of Effects/Percussion sounds. # 078..080 To be true to the nature of the sampled instrument, these patches do not respond to velocity. Effects and Percussion Patches When selecting instruments 072..076 (Effects 1-2 and Percussion 1-3), a number of different sounds are mapped to each six keyboard keys/notes: Note Effects 1 Effects 2 Percussion 1 Percussion 2 Percussion 3 30-35 Jet Yes (ding) - - Ratchet 36-4l Gunshot No (buzz) Kick Drum Rim Shot Snap 1 42-47 RoboDeath Applause Snare Exotic Snap 2 48-53 Whoosh Dogbark Toms Congas Dripdrum 1 54-59 Punch Door creak Cymbal Timbale Dripdrum 2 60-65 Slap Door slam Closed Hat Cowbell Wet clink 66-71 Duck Boom Open Hat Bongos Talk Drum 72-77 Ow! 1 Car skid Ride Whistle Agogo 78-83 Ow! 2 Goose Shaker Clave Explosion Note: The piano keys are numbered 36..84 (so notes 30..35 can be used only through MIDI messages, not via keyboard). SNES Controllers Miracle Pinouts and Component List --------------------------------------------------- 25pin SUBD connector (J6) 1 PC/Amiga/Mac RS232 GND (also wired to RTS) 2 PC/Amiga/Mac RS232 RxD 3 PC/Amiga/Mac RS232 TxD 7 NES/SNES/Genesis GND 10 NES/SNES/Genesis Data 13 NES/SNES/Genesis Strobe 14 Sense SENSE0 (0=MIDI Output off, 1=MIDI Output on) 15 Sense SENSE1 (0=9600 Baud; for RS232, 1=31250 Baud; for MIDI) 19 NES/SNES/Genesis Clock all other pins = not connected For PC/Mac RS232 wire SENSE0=GND, SENSE1=GND Miracle NES and SNES Cartridges According to the ROM Headers: The SNES cartridge contains 512Kbyte Slow/LoROM, and no SRAM (nor other storage memory). The NES cartridge contains MMC1 mapper, 256Kbyte PRG-ROM, 64Kbyte CHR-ROM, and no SRAM (nor other storage memory). Miracle Piano Component List (Main=Mainboard Section, Snd=Sound Engine) U1 Snd 16pin TDA7053 (stereo amplifier for internal speakers) U2 Snd 8pin NE5532 (dual operational amplifier) U3 Snd 16pin LM13700 or LM13600 (unclear in schematic) (dual amplifier) U4 Snd 14pin LM324 (quad audio amplifier) U5 Main 3pin LM78L05 (converts +10V to VLED, supply for 16 LEDs) U6 Main 14pin 74LS164 serial-in, parallel-out (to 8 LEDs) U7 Main 14pin 74LS164 serial-in, parallel-out (to another 8 LEDs) U8 Main 5pin LM2931CT (converts +12V to +10V, and supply for Power LED) U9 Main 3pin LM78L05 (converts +10V to +5REF) U10 Snd 14pin TL084 (JFET quad operational amplifier) U11 Snd 40pin J004 (sound chip, D/A converter with ROM address generator) U12 Snd 32pin S631001-200 (128Kx8, Sound ROM for D/A conversion) U13 Main 3pin LM78L05 (converts +10V to VCC, supply for CPU and logic) U14 Main 40pin AS0012 (ASIC) Keyboard Interface Chip (with A/D for velocity) U15 Main 40pin 8032 (8051-compatible CPU) (with Y1=12MHz) U16 Snd 40pin AS0013 (ASIC) U17 Main 28pin 27C256 EPROM 32Kx8 (Firmware for CPU) U18 Main 28pin 6264 SRAM 8Kx8 (Work RAM for CPU) U19 Main 16pin LT1081 Driver for RS232 voltages U20 Main 8pin 6N138 opto-coupler for MIDI IN signal S1-8 Main 2pin Push Buttons S9 Main 3pin Power Switch (12V/AC) J1 Main 3pin 12V AC Input (1 Ampere) J2 Main 2pin Sustain Pedal Connector (polarity is don't care) J3 Snd 2pin RCA Jack Right J4 Snd 2pin RCA Jack Left J5 Snd 5pin Headphone jack with stereo switch (mutes internal speakers) J6 Main 25pin DB25 connector (RS232 and SNES/NES/Genesis controller port) J7 Main 5pin MIDI Out (DIN) J8 Main 5pin MIDI In (DIN) JP1 Main 16pin Keyboard socket right connector JP2 Main 16pin Keyboard socket left connector JP3 Snd 4pin Internal stereo speakers connector Note: The official original schematics are released & can be found in internet. SNES Controllers NTT Data Pad (joypad with numeric keypad) ---------------------------------------------------------- Special joypad with numeric keypad, for use with SFC Modem: --> SNES Add-On SFC Modem (for JRA PAT) NTT Data Controller Pad - 27-buttons (including the 4 direction keys) _______________ __--L--___/ \__--R--__ / _ (<)(>) (=) \ | _| |_ (1)(2)(3)(*)(C) (X) | | |_ _| (4)(5)(6)(#)(.) (Y) (A) | | |_| (7)(8)(9)( 0 ) (B) | | | \__________.---------------._________/ NTT Data Controller Pad Bits 1st Bit31 Button (B) (0=High=Released, 1=Low=Pressed) 2nd Bit30 Button (Y) (0=High=Released, 1=Low=Pressed) 3rd Bit29 Button (<) Select (0=High=Released, 1=Low=Pressed) 4th Bit28 Button (>) Start (0=High=Released, 1=Low=Pressed) 5th Bit27 Direction Up (0=High=Released, 1=Low=Pressed) 6th Bit26 Direction Down (0=High=Released, 1=Low=Pressed) 7th Bit25 Direction Left (0=High=Released, 1=Low=Pressed) 8th Bit24 Direction Right (0=High=Released, 1=Low=Pressed) 9th Bit23 Button (A) (0=High=Released, 1=Low=Pressed) 10th Bit22 Button (X) (0=High=Released, 1=Low=Pressed) 11th Bit21 Button (L) (0=High=Released, 1=Low=Pressed) 12th Bit20 Button (R) (0=High=Released, 1=Low=Pressed) 13th Bit19 ID Bit3 (always 0=High) 14th Bit18 ID Bit2 (always 1=Low) 15th Bit17 ID Bit1 (always 0=High) 16th Bit16 ID Bit0 (always 0=High) 17th Bit15 Button (0) (0=High=Released, 1=Low=Pressed) 18th Bit14 Button (1) (0=High=Released, 1=Low=Pressed) 19th Bit13 Button (2) (0=High=Released, 1=Low=Pressed) 20th Bit12 Button (3) (0=High=Released, 1=Low=Pressed) 21th Bit11 Button (4) (0=High=Released, 1=Low=Pressed) 22th Bit10 Button (5) (0=High=Released, 1=Low=Pressed) 23th Bit9 Button (6) (0=High=Released, 1=Low=Pressed) 24th Bit8 Button (7) (0=High=Released, 1=Low=Pressed) 25th Bit7 Button (8) (0=High=Released, 1=Low=Pressed) 26th Bit6 Button (9) (0=High=Released, 1=Low=Pressed) 27th Bit5 Button (*) (0=High=Released, 1=Low=Pressed) 28th Bit4 Button (#) (0=High=Released, 1=Low=Pressed) 29th Bit3 Button (.) Dot (0=High=Released, 1=Low=Pressed) 30th Bit2 Button (C) Clear (0=High=Released, 1=Low=Pressed) 31th Bit1 Unknown/Unused (unknown, probably always 1 or always 0) 32th Bit0 Button (=) End (0=High=Released, 1=Low=Pressed) 33th and up Padding (unknown, probably always 1 or always 0) Note: The "(=)" button is sunken, somewhat preventing accidently pressing it. SNES Controllers X-Band Keyboard -------------------------------- The X-Band keyboard is a (rare) optional add-on for the X-Band Modem, intended to allow faster chatting/mailing as with the joypad controlled on-screen keyboard. Keyboard Layout The keyboard has a black case, 84 keys, an X-Band logo in upper left, and connection cable (to SNES controller port) attached in upper-right. ___________________________________________________________________ | >< Num Caps Scroll | | BAND Lock Lock Lock | | ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ | | | | | | | | | | | | | | | L |Sel|Sta| R | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| | | |Can|1! |2@ |3# |4$ |5% |6^ |7& |8* |9( |0) |-_ |=+ | <-- | X | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|_______|___| | | |Switc| Q | W | E | R | T | Y | U | I | O | P |[{ |]} | | Y | | | |_____|___|___|___|___|___|___|___|___|___|___|___|___| |___| | | |Caps | A | S | D | F | G | H | J | K | L |;: |'" | Enter | A | | | |______|___|___|___|___|___|___|___|___|___|___|___|________|___| | | |Shift | Z | X | C | V | B | N | M |,< |.> |/? |Shift |UP | B | | | |________|___|___|___|___|___|___|___|___|___|___|______|___|___| | | |`~ | |>< |Ctr| |Ctr|>< |\| |LT |DN |RT | | | |___|___|___|___|_______________________|___|___|___|___|___|___| | |___________________________________________________________________| Normal Controller Access (via STB and DATA0) 1st-12th Unknown/unused 13th-16th Unknown/unused (should be usually a 4bit ID) 17th-24th Unknown/unused (should be sometimes extended 8bit ID) 25th and up Unknown/unused Note: If the keyboard data is transferred in sync with STB, then "17th and up" are the LSBs of the 2bit keyboard data pairs (though it might also be in sync with falling IOBIT, rather than with STB). Keyboard Access (read_scancodes) (via IOBIT and DATA0 & DATA1) Below might be required to be preceeded by reading normal 16bit controller data (eg. via auto-joypad-reading) (ie. unknown if below needs leading STB signal, and preceeding 16xCLK signals). [004201]=7Fh ;-set IOBIT=0 id=getbits(8) ;-read ID byte (must be 78h, aka "x") if CAPS=OFF [004201]=FFh ;-set IOBIT=1 (when CAPS=OFF) (CAPS LED) num=getbits(4) ;-read num scancodes if num>0 then for i=1 to num ;\ [dst]=getbits(8) ; read that scancodes (if any) dst=dst+1 ; next i ;/ [004201]=FFh ;set IOBIT=1 ;-set IOBIT=1 Note: When reading the ID bits, BIOS sets IOBIT=1 after reading the first 2bit group (purpose unknown). When reading ONLY the ID (without reading following scancodes), then the scancodes do remain in the keyboard queue. getbits(n) for i=1 to n/2 ;\ delay (loop 7 times or so) ; read 2bits at once, LSB first x=(x SHR 2) OR ([004017h] SHL 6) ; next ;/ x=(x XOR FFh) SHR (8-n) ;-invert & move result to LSBs Scancode Summary nn normal key F0h,nn normal key released E0h,nn special key E0h,F0h,nn special key released Normal Scancodes (without prefix) ____0xh____1xh___2xh___3xh___4xh___5xh___6xh___7xh_____8xh_____9xh___ x0h --- --- --- --- --- --- --- NUM-0 --- <90h>? x1h --- CTR1? C N ,< --- --- NUM-. --- <91h>? x2h --- SHF1? X B K '" --- NUM-2 --- <92h>? x3h --- --- D H I --- --- NUM-5 --- <93h>? x4h --- CTR2? E G O [{ --- NUM-6 NUM-SUB <94h>? x5h --- Q 4$ Y 0) =+ --- NUM-8 --- <95h>? x6h --- 1! 3# 6^ 9( --- BS CANCEL JOY-A <96h>? x7h --- --- --- --- --- --- --- NUM-DIV JOY-B <97h>? x8h --- --- --- --- --- CAPS --- --- JOY-X <98h>? x9h --- --- SPACE --- .> SHF2? NUM-1 NUM-RET JOY-Y <99h>? xAh --- Z V M /? ENTER --- NUM-3 JOY-L <9Ah>? xBh --- S F J L ]} NUM-4 --- JOY-R <9Bh>? xCh --- A T U ;: \| NUM-7 NUM-ADD SELECT <9Ch>? xDh SWITCH W R 7& P \| --- NUM-9 START <9Dh>? xEh `~ 2@ 5% 8* -_ --- --- NUM-MUL <8Eh>? --- xFh --- --- --- --- --- --- --- --- <8Fh>? --- Special Scancodes (with E0h-prefix) E0h,5Ah JOY-A (alternate to normal scancode 86h) E0h,6Bh LEFT E0h,72h DOWN E0h,74h RIGHT E0h,75h UP Notes The Numeric-Keypad (NUM) isn't present on the existing X-Band keyboard. There is probably only one of the two backslash keys (5Ch/5Dh) and only one of the two Button-A keys (86h/E0h,5Ah) implemented. There are three keyboard LEDs (Num,Caps,Scroll) visible in upper right on some photos (not visible on other photos; either due to bad photo quality, or maybe some keyboards have no LEDs). The Caps LED is controlled via software (unknown if Num/Scroll LEDs can be controlled, too). There are several "unused" keys (which aren't used by the BIOS), unknown if/which scancodes are assigned to them (12 noname keys in upper left, 1 noname key in lower left, two control keys, and two xband logo keys). For the two shift keys it's also unknown which one has which scancode. Unknown if the japanese BIOS includes support for japanese symbols, and unknown if there was a keyboard released in japan. (Note: With an emulated US keyboard, the Japanese BIOS does realize cursor/enter keys, it does also store typed ASCII characters in a ring-buffer at [3BB6+x]; but, for whatever reason, does then ignore those characters). SNES Controllers Tilt/Motion Sensors ------------------------------------ There are a few SNES controllers with Tilt/Motion Sensors, most or all of them are emulating normal SNES joypad button/direction signals, which is making them compatible with existing games, but also means that the SNES receives only digital data (pressed/released) rather than anlogue (slow/fast) data. Alltogether, the controllers appear to be more uncomfortable than useful. BatterUP (1994) (Sports Sciences Inc.) The BatterUP is a 24-inch foam-covered plastic baseball bat for Sega Genesis and Super Nintendo. Reportedly, it "doesn't sense swing speed or location, only timing" (whatever that means, probably simulating a button-pressed signal at the time when swinging the bat). Aside from the swing/motion sensor, the middle of the bat contains joypad buttons. ___ / \ BatterUP _________________ | | | [] | Some versions (probably for | | | [] START | SEGA or so) have a "C" button, | | <-- blue foam .| UP | and no X/Y/SELECT buttons. | | .' | [] [] | | | .' | LEFT RIGHT | Purpose of the 4 DIP switches |_____| .........' | :::: [] | is unknown (maybe sensitivity, | .' | | DIPs DOWN [] | or assigning the swing-sensor | '.' | DPAD | SELECT| to a specific joypad-button?) | .' | <-- buttons --> | A[] | | : | | | \_'_/ ......... | B[] | | | '. \ / | | '. \ X[] / | | <-- handle '. \ / | | \ Y[] / | | \_______/ | | \_/ '.______ cable (to console's controller port) Games compatible with the SNES version (according to instruction manual?): Cal Ripken Jr. Baseball, 1992 Mindscape ESPN Baseball Tonight, 1994 Sony Imagesoft Hardball III, 1994 Accolade Ken Griffey Jr. Presents Major League Baseball, 1994 Nintendo Ken Griffey, Jr.'s Winning Run, 1996 Nintendo MLBPA Baseball, 1994 EA Sports Sports Illustrated Championship Football and Baseball, 1993 Malibu Games Super Baseball, 1994 EA Techmo Super Batter Up, 1993 Namco TeeV Golf (1993/1995) (Sports Sciences Inc.) The TeeV Golf hardware consists of a wireless (battery-powered) golf club, and a rectangular box which is supposed to be set on the floor. There's a mimmicked (half) golf ball in the middle of the box. According to photos, there are two rows of six "red dots" on the box (these might be nonfunctional decorative elements, or important LEDs/sensors for motion tracking?), some kind of a BIOS cartridge or so (which seems to contain something customized for specific games), and two connection cables (one to the consoles controller port, and one forwarded to a joypad). ....................................... cables ___________:___________ (to joypad | O O O O O O |__ and to | .'''''. TeeV : | <-- BIOS console) | : _ : Golf : | cartridge Golf Club | : (_) : :__| or so (with 2 AA batteries) | :.......: | (with "PGA ___________ | O O :.O O.: O O | Tour Golf" | :\ __ |Mode1 : ''''' : Mode2| text on it) | : : | |_______:_______:_______| | : : | _____________________ | : :__|=======================|_____________________| |__________:/ According to the box: The TeeV SNES version is compatible with PGA Tour Golf (unknown if that refers to the whole PGA series, and unknown if there are other games supported; other games might possibly require other "BIOS" cartridges). The PGA Tour Golf BIOS cartridge does probably translate motion data to a specially timed sequence of joypad button pressed/released signals. There are TeeV versions for SNES, Sega Genesis, and PC. The US Patent number for the TeeV hardware is 4971325 (with the addition of "other patents pending"). StuntMaster (VictorMaxx) Advertised as "3-D Virtual Reality Headset". "Despite what the box says, the StuntMaster VR is not a 3D display. It contains one extremely grainy low resolution LCD screen in the center of the goggles. If you put it on, it hurts your face. The display singes your retinas with an intensely fuzzy, hard-to-focus-on image. The head tracking mechanism is nothing more than a stick you clip to your shoulder (see picture above) which slides through a loop on the side of the headset. When you turn your head, the StuntMaster detects the stick sliding in the loop and translates this into a left or right button press on a control pad, assuming you've actually hooked it up to the controller port of your SNES or Genesis. Remember the "point-of-view instantly scrolls or rotates with the turn of your head" quote? I'd love to see that happen in Super Mario World. Obviously, it couldn't actually work unless the game were programmed for that functionality in advance. Unless, of course, you're playing Doom and you want to turn left or right by moving your head." 1 +6V 2 GND 3 Joypad (SNES:DTA, SEGA:Right In) 4 Joypad (SNES:CLK, SEGA:N/A) 5 Joypad (SNES:STB, SEGA:Left In) 6 GND 7 VCC (SNES:+5V, SEGA:N/A?) (for Joypad?) 8 N/A 9 GND 10 Video in (NTSC composite) 11 Joypad (SNES:DTA, SEGA:Right Out) 12 Joypad (SNES:STB, SEGA:Left Out) 13 GND 14 Audio in (Left) 15 Audio in (Right) Resolution: 240x86 color triads Field of View: 17 degrees Weight: circa 2.5 pounds Nordic Quest (interactive ski-exerciser) (Nordic Track) The Nordic Quest is an add-on for treadmills (walking-exercising machines) from Nordic Track. Unlike normal treadmills, the Nordic Track one features two handles attached to a string, which the user pulls back and forth during exercising (similar to nordic walking/skiing sticks). The Nordic Quest includes replacement handles with DPAD (left handle) and buttons (right handle), allowing to play "virtually any" joypad controlled games during exercising; there aren't any special "nordic" games for the controller, instead it can be used for games like golf, car-racing, and flight simulations (as illustrated on the box). The exercising intensity is claimed to affect the game speed - unknown how this works - maybe by toggling the DPAD on/off, or maybe by toggling the Start (pause) button on/off? JS-306 Power Pad Tilt (Champ) (joypad with autofire, slowmotion, tilt-mode) A regular joypad with normal DPAD, the tilt-sensors can be optionally used instead of the DPAD. Nigal Mouncefill Fly Wheel (Logic 3) (wheel-shaped, tilt-sensor instead dpad) An odd wheel-shaped controller with tilt-sensors instead of DPAD. SNES Controllers Lasabirdie (golf club) --------------------------------------- The Lasabirdie is a golf club made in 1995 by Ricoh. Supported by only one game (which came shipped with the device): Lasabirdie - Get in the Hole (1995) Ricoh/Good House (JP) Lasabirdie "Golf Mat" and "Golf Club" _______________________________ __ |...............................| insert two / / |: :| AA batteries / / <-- handle |: # Golf Ball # :| | / / (rather |: # _ / # :| | / / short) |: # (_) # # :| V / / |: # # :| ______/ / |: # # :| | / _|:.............................:| \ / <-- yellow laser symbol / | LT RT UP DN A B RICOH | \___/ | |_______________________________| | / <---- cable (to SNES controller port 2) | <-- laser beam The so-called Golf Mat is actually a (not very flat) plastic box, with a mimmicked (half) golf ball mounted on it, the three black fields (shown as ### in the ASCII drawing) might contain laser sensors, the front panel has six buttons: Left/Pause, Right, Up, Down, A/Start and B/Cancel. For additional/better menu controls, one can connect a normal joypad to SNES port 1. Below describes the overall transfer protocol. Unknown if/how/what kind of motion, speed, and/or direction information is transmitted via that protocol. Lasabirdie Controller Data (connected to Port 2) 1st Button B (CANCEL) (1=Low=Pressed) 2nd Button DOWN (1=Low=Pressed) 3rd..6th Nibble Data bit3-0 (1=Low=One?) (MSB first) 7th Nibble Available (toggles CLK like) 8th Packet Available (1=Low=Yes) 9th Button A (START) (1=Low=Pressed) 10th Button UP (1=Low=Pressed) 11th Button LEFT (PAUSE) (1=Low=Pressed) 12th Button RIGHT (1=Low=Pressed) 13th..16th ID Bit3-0 (unknown) ;read, but not checked by software 17th..24th Extra ID Bit7-0 (unknown) ;read, but not checked by software 25th and up Unknown/Unused (probably all one, or all zero ?) Command Bytes Command bytes are used to select a specific packet, and (during the packet transfer) to select nibbles within the previously selected packet: 20h select "GOLF_READY!" ID string packet 22h select version string packet 30h select whatever data packet? 3Fh select whatever data packet? 40h..55h sent while receiving nibbles number 0..21 5Fh terminate transfer (or re-select default packet type?) Bytes are output via Port 4201h at a fixed baudrate of circa 10000 bits/second: output 1 start bit ("0") output 8 data bits (MSB first) output 2 stop bits ("0","0") release line (output "1", until the next byte transferred in next frame) Exact time per bit is 2140 master cycles (10036 bps at 21.47727MHz NTSC clock). Packets Packets consist of 11 bytes, transferred in 22 nibbles (of 4bit each). For whatever reason, the software receives only one nibble per frame, so a complete packet-transfer takes about 0.36 seconds. The bits are transferred MSB first (bit3,bit2,bit1,bit0), whilst nibbles are transferred LSB first (bit3-0, bit7-4). The 11-byte packets can contain following data: "GOLF_READY!" ;-ID-string packet ;\without checksum FFh,FFh,0,0,0,0,0,0,0,0,0 ;-Empty packet ;/ 9 chars, 1 unknown, 1 chksum ;-Version-string ;\with checksum 10 data bytes, 1 chksum ;-Normal packet ;/ The checksum (if it is present) is calculated by summing up all 10 data bytes, and adding MSB+LSB of the resulting 16bit sum (ie. sum=sum+sum/100h). The version string packet contains 9 characters (unknown content), one unused byte (unknown value), and the checksum byte. Other packet(s) contain whatever controller/motion data (unknown content). Below is the procedure for receiving a packet (before doing that, one should first select a packet, eg. send_byte(20h) for receiving the ID string). if [421Ah].bit8 = 0 then exit ;-exit if no packet available for i=0 to 21 old_state = [421Ah].bit9 @@wait_lop: send_byte(40h+i) wait_vblank if [421Ah].bit9 <> old_state then jmp @@wait_done wait_vblank if [421Ah].bit9 <> old_state then jmp @@wait_done jmp @@wait_lop @@wait_done: nibble=([421Ah] SHR 10) AND 0Fh if (i AND 1)=0 then buf[i/2]=nibble, else buf[i/2]=buf[i/2]+nibble*10h next i send_byte(5Fh) ;-terminate transfer or so SNES Controllers Exertainment (bicycle exercising machine) ---------------------------------------------------------- The Exertainment is an exercising machine made by Life Fitness. It consists of a stationary bicycle, a monitor with TV tuner, a SNES game cartridge, and a SNES console with some extra hardware plugged into its Expansion Port. Technical Info --> SNES Controllers Exertainment - I/O Ports --> SNES Controllers Exertainment - RS232 Controller --> SNES Controllers Exertainment - RS232 Data Packets & Configuration --> SNES Controllers Exertainment - RS232 Data Packets Login Phase --> SNES Controllers Exertainment - RS232 Data Packets Biking Phase Drawings --> SNES Controllers Exertainment - Drawings Supported Games Cannondale Cup (1993) CEG/American Softworks/RadicalEntertainment (US) Exertainment Mountain Bike Rally (1994) LifeFitness/RadicalEntertainment (US) Exertainment Mountain Bike Rally & Speed Racer (combo cart) (1995) (USA) Exertainment Mountain Bike Rally & Speed Racer (combo cart) (prototype) (EU) Aside from the games, all three Exertainment cartridges are including a "Program Manager", allowing to view/edit user profiles, and, in the old cart from 1994 only - also including some "mini games" called Workout and Fit Test). Cannondale Cup is essentially same as Mountain Bike Rally, it is sending Exertainment packets (including for checking for the "LIFEFITNES(s)" ID), but it lacks the Program Manager, and even the actual game doesn't seem to react to actions on the exertainment hardware(?). Playing normal SNES games during exercising isn't supported (the SNES cartridge slot isn't externally accessible, and, selecting the pedal resistance requires special program code in the game cartridge). The Mountain Bike game works with/without the Exertainment hardware (with the Exertainment features being shown only if the hardware is present). Joypad Controls Joypad like controls are attached to the handlebars, featuring the same 12bit button/direction signals as normal joypads. In fact, there should be two such joypads, both mapped as "player 1" input (ie. both wired to Port 4218h). Turning the handlebars isn't possible, instead, steering is done via DPAD Left/Right buttons. Whereas, for the Mountain Bike game, steering is needed only for gaining optional bonus points. Other Controls Pedaling speed/force info is probably sent via Port 21C0h Data Packets. The front panel has six buttons - unknown if the buttons states are sent to the SNES - Volume & Program Up/Down and Picture-in-picture are possibly wired directly to the TV set unit, the Menu button is possibly wired to SNES Reset signal(?) Exertainment Expansion Port Unit - PCB Component List info from byuu U1 40pin TL16C550AN CF62055 N9304 2342265 TI ;-RS232 controller U2 20pin PEEL18CV8P CTM22065 333FB ;-some PAL (sticker "K41A-12802-0000") U3 20pin 74HC374N (addr.msb & serial) ;\two 8bit latches (13bit SRAM address, U4 20pin 74HC374N (addr.lsb) ;/and the 3bit serial-port outputs) U5 28pin LH5268A-10LL 9348 SHARP ;-8Kx8 SRAM U6 16pin ADM232LJN 9403 OF31824 ;-RS232 voltage converter BATT1 CR2032 ;-battery (for SRAM) P2 4pin short cable to rear 623K-6P4C;-SIO (1=LED?, 2=CLK?, 3=DTA?, 4=/SEL?) P3 3pin long cable to front 616M-4P4C;-RS232 (1=GND, 2=N/A, 3=TX, 4=RX) Px 28pin Connector to SNES expansion port (at bottom of SNES console) SNES Controllers Exertainment - I/O Ports ----------------------------------------- Exertainment I/O Port Summary (Expansion Port Unit) 21C0h.0 TL16C550AN - RX Data FIFO (R) ;\when (?) 21C0h.0 TL16C550AN - TX Data FIFO (W) ; DLAB=0 (?) 21C1h.0 TL16C550AN - Interrupt Control (R/W) ;/ 00h 21C0h.1 TL16C550AN - Baudrate Divisor Latch LSB, Bit0-7 (R/W) ;\when (-) 21C1h.1 TL16C550AN - Baudrate Divisor Latch MSB, Bit8-15 (R/W) ;/DLAB=1 (-) 21C2h TL16C550AN - Interrupt Status (R) 01h 21C2h TL16C550AN - FIFO Control (W) 00h 21C3h TL16C550AN - Character Format Control (R/W) ;<--- Bit7=DLAB 00h 21C4h TL16C550AN - Handshaking Control (R/W) 00h 21C5h TL16C550AN - RX/TX Status (R) (Write=reserved for testing) 60h 21C6h TL16C550AN - Handshaking Status (R) (Write=unknown/reserved) 0xh 21C7h TL16C550AN - Scratch (R/W) (-) 21C8h 74HC374N (U3) - RAM address MSBs and SPI-style Serial Port (W) (-) 21C9h Not used 21CAh 74HC374N (U4) - RAM address LSBs (W) (-) 21CBh Not used 21CCh RAM (U5) data byte to/from selected RAM addr (R/W) (battery backed) 21CDh Not used 21CEh Not used 21CFh ? initially set to 00h (not changed thereafter) (W) ;\maybe one of 21Dxh Not used ; these resets 21DFh ? initially set to 80h (not changed thereafter) (W) ;/the TL16C550AN? 21C0h..21C7h - TL16C550AN (U1) (RS232 Controller) --> SNES Controllers Exertainment - RS232 Controller --> SNES Controllers Exertainment - RS232 Data Packets & Configuration --> SNES Controllers Exertainment - RS232 Data Packets Login Phase --> SNES Controllers Exertainment - RS232 Data Packets Biking Phase 21C8h - 74HC374N (U3) - RAM address MSBs and SPI-style Serial Port (W) 0 Serial Port Select (0=Select, 1=Idle) 1 Serial Port Data (transferred LSB first) 2 Serial Port Clock (0=Idle) (data must be stable on 0-to-1 transition) 3-7 Upper 5bit of 13bit RAM address (see Ports 21CAh/21CCh) Used to send two 16bit values (20F3h and 0470h) during initialization (and to send more data later on). This controls some OSD video controller (possibly also the picture-in-picture function). Used values are: 20xxh = set address (00h..EFh = yloc*18h+xloc) (24x10 chars) 20Fxh = set address (F0h..F3h = control registers 0..3) 1C20h = ascii space with attr=1Ch ? 1E20h = ascii space with attr=1Eh ? 1Exxh = ascii chars ":" and "0..9" and "A..Z" (standard ascii codes) 1Exxh = lowercase chars "a..z" (at "A..Z"+80h instead of "A..Z"+20h) 0000h = value used for control regs 0 and 1 0111h = value used for control reg 2 0070h,0077h,0470h = values used for control reg 3 Unknown if/which bicycle versions are actually using the OSD feature, maybe it has been an optional or unreleased add-on. OSD output is supported in the Program Manager's Workout & Fit Test, apparently NOT for drawing the OSD layer on top of the SNES layer, probably rather for displaying OSD while watching TV programs. Note: The general purpose "/OUT1" bit (RS232 port 21C4h.Bit2) is also output via the serial port connector (purpose is unknown, might be OSD related, or TV enable, or LED control, or whatever). 21C8h - 74HC374N (U3) - RAM address MSBs and SPI-style Serial Port (W) 21CAh - 74HC374N (U4) - RAM address LSBs (W) 21CCh - SRAM (U5) - RAM data byte to/from selected RAM address (R/W) Port 21CAh.Bit0-7 = RAM Address Bit0-7 (W) ;\13bit address, 0000h..1FFFh Port 21C8h.Bit3-7 = RAM Address Bit8-12 (W) ;/ Port 21C8h.Bit0-2 = See Serial Port description (W) Port 21CCh.Bit0-7 = RAM Data Bit0-7 (R/W) Used to access battery-backed 8Kbyte SRAM in the expansion port unit. Note: There are additional 2Kbytes of SRAM in the Mountain Bike game cartridge (mapped to 700000h). 21CFh (W) initially set to 00h (not changed thereafter) 21DFh (W) initially set to 80h (not changed thereafter) Used to configure/reset whatever stuff during initialization (not used thereafter). Maybe one of these ports resets the TL16C550AN? SNES Controllers Exertainment - RS232 Controller ------------------------------------------------ Texas Instruments TL16C550AN - Asynchronous Communications Element (ACE) The ACE uses eight I/O addresses (mapped to 21C0h-21C7h in the SNES), the meaning of the first two addresses depends on the "DLAB" bit (which can be changed via 21C3h.Bit7). 21C0h (when DLAB=0) - TL16C550AN - RX Data FIFO (R) 0-7 Data (with 16-byte FIFO) 21C0h (when DLAB=0) - TL16C550AN - TX Data FIFO (W) 0-7 Data (with 16-byte FIFO) 21C1h (when DLAB=0) - TL16C550AN - Interrupt Control (R/W) 0 Received Data Available Interrupt (0=Disable, 1=Enable) 1 Transmitter Holding Register Empty Interrupt (0=Disable, 1=Enable) 2 Receiver Line Status Interrupt (0=Disable, 1=Enable) 3 Modem Status Interrupt (0=Disable, 1=Enable) 4-7 Not used (always zero) 21C0h (when DLAB=1) - TL16C550AN - Baudrate Divisor Latch LSB, Bit0-7 (R/W) 21C1h (when DLAB=1) - TL16C550AN - Baudrate Divisor Latch MSB, Bit8-15 (R/W) 0-7 Divisor Latch LSB/MSB, should be set to "divisor = XIN / (baudrate*16)" 21C2h - TL16C550AN - Interrupt Status (R) 0 Interrupt Pending Flag (0=Pending, 1=None) 1-3 Interrupt ID, 3bit (0..7=see below) (always 00h when Bit0=1) 4-5 Not used (always zero) 6 FIFOs Enabled (always zero in TL16C450 mode) ;\these bits have same 7 FIFOs Enabled (always zero in TL16C450 mode) ;/value as "FIFO Enable" The 3bit Interrupt ID can have following values: ID Prio Expl. 00h 4 Handshaking inputs CTS,DSR,RI,DCD have changed (Ack: Read 21C6h) 01h 3 Transmitter Holding Register Empty (Ack: Write 21C0h or Read 21C2h) 02h 2 RX FIFO has reached selected trigger level (Ack: Read 21C0h) 03h 1 RX Overrun/Parity/Framing Error, or Break Interrupt (Ack: Read 21C5h) 06h 2 RX FIFO non-empty & wasn't processed for longer time(Ack: Read 21C0h) Interrupt ID values 04h,05h,07h are not used. 21C2h - TL16C550AN - FIFO Control (W) 0 FIFO Enable (0=Disable, 1=Enable) (Enables access to FIFO related bits) 1 Receiver FIFO Reset (0=No Change, 1=Clear RX FIFO) 2 Transmitter FIFO Reset (0=No Change, 1=Clear TX FIFO) 3 DMA Mode Select (Mode for /RXRDY and /TXRDY) (0=Mode 0, 1=Mode 1) 4-5 Not used (should be zero) 6-7 Receiver FIFO Trigger (0..3 = 1,4,8,14 bytes) 21C3h - TL16C550AN - Character Format Control (R/W) 0-1 Character Word Length (0..3 = 5,6,7,8 bits) 2 Number of Stop Bits (0=1bit, 1=2bit; for 5bit chars: only 1.5bit) 3 Parity Enable (0=None, 1=Enable Parity or 9th data bit) 4-5 Parity Type/9th Data bit (0=Odd, 1=Even, 2=Set9thBit, 3=Clear9thBit) 6 Set Break (0=Normal, 1=Break, Force SOUT to Low) 7 Divisor Latch Access (0=Normal I/O, 1=Divisor Latch I/O) (DLAB) 21C4h - TL16C550AN - Handshaking Control (R/W) 0 Output Level for /DTR pin (Data Terminal Ready) (0=High, 1=Low) 1 Output Level for /RTS pin (Request to Send) (0=High, 1=Low) 2 Output Level for /OUT1 pin (General Purpose) (0=High, 1=Low) 3 Output Level for /OUT2 pin (General Purpose) (0=High, 1=Low) 4 Loopback Mode (0=Normal, 1=Testmode, loopback TX to RX) 5-7 Not used (always zero) 21C5h - TL16C550AN - RX/TX Status (R/W, but should accessed as read-only) 0 RX Data Ready (DR) (0=RX FIFO Empty, 1=RX Data Available) 1 RX Overrun Error (OE) (0=Okay, 1=Error) (RX when RX FIFO Full) 2 RX Parity Error (PE) (0=Okay, 1=Error) (RX parity bad) 3 RX Framing Error (FE) (0=Okay, 1=Error) (RX stop bit bad) 4 RX Break Interrupt (BI) (0=Normal, 1=Break) (RX line LOW for long time) 5 Transmitter Holding Register (THRE) (1=TX FIFO is empty) 6 Transmitter Empty (TEMT) (0=No, 1=Yes, TX FIFO and TX Shift both empty) 7 At least one Overrun/Parity/Framing Error in RX FIFO (0=No, 1=Yes/Error) Bit7 is always zero in TL16C450 mode. Bit1-3 are automatically cleared after reading. In FIFO mode, bit2-3 reflect to status of the current (=oldest) character in the FIFO (unknown/unclear if bit2-3 are also auto-cleared when in FIFO mode). 21C6h - TL16C550AN - Handshaking Status (R/W? - should accessed as read-only) 0 Change flag for /CTS pin (Clear to Send) ;\change flags (0=none, 1 Change flag for /DSR pin (Data Set Ready) ; 1=changed since last 2 Change flag for /RI pin (Ring Indicator) ; read) (automatically 3 Change flag for /DCD pin (Data Carrier Detect) ;/cleared after reading) 4 Input Level on /CTS pin (Clear to Send) ;\ 5 Input Level on /DSR pin (Data Set Ready) ; current levels 6 Input Level on /RI pin (Ring Indicator) ; (inverted ?) 7 Input Level on /DCD pin (Data Carrier Detect) ;/ 21C7h - TL16C550AN - Scratch (R/W) 0-7 General Purpose Storage (eg. read/write-able for chip detection) Note The TL16C550AN doesn't seem to support a TX FIFO Full flag, nor automatic RTS/CTS handshaking. Note on Nintendo DSi (newer handheld console, not SNES related) The DSi's AR6002 wifi chip is also using a TL16C550AN-style UART (for TTY debug messages). SNES Controllers Exertainment - RS232 Data Packets & Configuration ------------------------------------------------------------------ From Bike to SNES (16 bytes: ATT code, command, 13-byte-data, checksum) Bike Packet 01h ;\these might both contain same bike data, Bike Packet 02h ;/both required to be send (else SNES hangs) Bike Packet 03h ;<-- confirms/requests pause mode Bike Packet 08h Login Part 1 (ID string) Bike Packet 09h PPU Status Request (with ignored content) Bike Packet 0Ah Login Part 3 (reply to random values) Bike Packet 0Ch Login Part 5 (fixed values 00,FF,00,0C,..) From SNES to Bike (13 bytes: ACK code, command, 10-byte-data, checksum) SNES Packet 00h Idle (zerofilled) or PPU Status Response (with "RAD" string) SNES Packet 01h Biking Start (start biking; probably resets time/distance) SNES Packet 02h Biking Active (biking) SNES Packet 03h Biking Pause (pause biking) SNES Packet 04h Biking Exit (finish or abort biking) SNES Packet 05h User Parameters SNES Packet 06h Biking ? SNES Packet 07h Biking ? SNES Packet 08h Biking ? SNES Packet 09h Login Part 2 (random values) SNES Packet 0Bh Login Part 4 (based on received data) SNES Packet 0Dh Login Part 6 (login okay) SNES Packet 0Fh Logout (login failed, or want new login) SNES Packet 0Ah,0Ch,0Eh (?) (unused?) Packet Details --> SNES Controllers Exertainment - RS232 Data Packets Login Phase --> SNES Controllers Exertainment - RS232 Data Packets Biking Phase RS232 Character Format The character format is initialized as [21C3h]=3Bh, which means, 1 start bit, 8 data bits, sticky parity, 1 stop bit, or, in other words: 1 start bit, 9 data bits, no parity, 1 stop bit The sticky parity bit (aka 9th data bit) should be set ONLY in the Bike's ATT characters (133h), all other data (and ACK codes) should have that bit cleared. RS232 Baudrate The baudrate is aimed at 9600 bits/sec. The ACE Baudrate Divisor is set to 0023h aka 35 decimal (in both NTSC and PAL versions), with the ACE being driven by the 5.3MHz Dot Clock. The resulting exact timings are: NTSC: 5.36931750MHz/35/16 = 9588.067 Hz PAL: 5.32034250MHz/35/16 = 9500.612 Hz Notes: The Dot Clock has some slight stuttering on long dots during hblank (but doesn't disturb the baudrate too much). The PAL baudrate doesn't match too well, however, it is the divisor setting closest to 9600 baud. RS232 Handshaking The RS232 connector has only 3 pins (RX, TX, GND). The RTS/CTS handshaking signals are thus not used (nor are any Xon/Xoff handshaking characters used). However, there is some sort of handshaking: The "From Bike" packets are preceeded by a ATT (Attention) character (value 133h, with 9th data bit set, aka sticky parity bit set), this allows to resynchronize to packet-start boundaries in case of lost data bytes. In the other direction, the "From SNES" packets should be sent only in response to successfully received "From Bike" packets. The packets are small enough to fit into the 16-byte FIFOs of the ACE chip. The baudrate is a bit too low to send 16-byte packets in every frame, so the Bike is apparently pinging out packets at some lower rate. Note: The SNES software accepts the ATT (Attention) characters only if [21C5h] returns exactly E5h (data present, TX fifo empty, and "error" flags indicating the received parity bit being opposite as normal). RS232 Interrupts The ACE Interrupts are left unused: the IRQ pin is probably not connected to SNES, ACE interrupts are disabled via [21C1h]=00h, and ACE interrupt ID in [21C2h] isn't polled by software. SNES Controllers Exertainment - RS232 Data Packets Login Phase -------------------------------------------------------------- Login Phase Bike Packet 08h Login Part 1 (ID string) SNES Packet 09h Login Part 2 (random values) Bike Packet 0Ah Login Part 3 (reply to random values) SNES Packet 0Bh Login Part 4 (based on received data) Bike Packet 0Ch Login Part 5 (fixed values 00,FF,00,0C,..) SNES Packet 0Dh Login Part 6 (login okay) (communication phase...) SNES Packet 0Fh Logout (login failed, or want new login) Login should be done on power-up. And, the SNES software does occassionally logout and re-login (eg. when starting a new game from within main menu). PPU Status Request Bike Packet 09h PPU Status Request (with ignored content) SNES Packet 00h PPU Status Response (with "RAD" string) PPU Status can be transferred during Login or Communication Phase, unknown if/when/why the bike is actually doing that (the data is rather useless, except maybe for use as random seed). From Bike Packet 08h Login Part 1 (ID string) ATT Attention Code (133h, with 9th bit aka parity set = packet start) 00h Command (LSB=08h, MSB=Unknown/unused) 01h..0Bh ID String ("LIFEFITNESS" or "LIFEFITNESs") ;[0Bh].bit5=flag? [1EEEh] 0Ch..0Dh Unknown/unused 0Eh Checksum (00h-[00h..0Dh]) From SNES Packet 09h Login Part 2 (random values) ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=09h, MSB=Zero) 01h..0Ah Random values (RND1,RND2,RND3,RND4,RND5,RND6,RND7,RND8,RND9,RND10) 0Bh Checksum (00h-[00h..0Ah]) From Bike Packet 0Ah Login Part 3 (reply to random values) ATT Attention Code (133h, with 9th bit aka parity set = packet start) 00h Command (LSB=0Ah, MSB=Unknown/unused) 01h RND1+RND5 ;\ 02h RND2+(RND5*13+9) ; RND'values same as in 03h RND3+((RND5*13+9)*13+9) ; Login Part 2 04h RND4+(((RND5*13+9)*13+9)*13+9) ; 05h RND5+((((RND5*13+9)*13+9)*13+9)*13+9) ;/ 06h..0Ah Unknown/unused <-- these ARE USED for response TO bike 0Bh..0Dh Unknown/unused <-- these seem to be totally unused 0Eh Checksum (00h-[00h..0Dh]) From SNES Packet 0Bh Login Part 4 (based on received data) ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=0Bh, MSB=Zero) 01h..0Ah Values "[01h]+[01h..0Ah]" from Login Part 3 0Bh Checksum (00h-[00h..0Ah]) From Bike Packet 0Ch Login Part 5 (fixed values 00,FF,00,0C,..) ATT Attention Code (133h, with 9th bit aka parity set = packet start) 00h Command (LSB=0Ch, MSB=Unknown/unused) 01h..0Ah Constants (00h,FFh,00h,0Ch,0Ah,63h,00h,FAh,32h,C8h) 0Bh..0Dh Unknown/unused 0Eh Checksum (00h-[00h..0Dh]) From SNES Packet 0Dh Login Part 6 (login okay) ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=0Dh, MSB=Zero) 01h..0Ah All zero (00) 0Bh Checksum (00h-[00h..0Ah]) From SNES Packet 0Fh Logout (login failed, or want new login) ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=0Fh, MSB=Zero) 01h..0Ah All zero (00) 0Bh Checksum (00h-[00h..0Ah]) This is sent upon login mismatch, and also if the game wants to re-enter the login phase (as done after leaving the main menu). From Bike Packet 09h PPU Status Request (with ignored content) ATT Attention Code (133h, with 9th bit aka parity set = packet start) 00h Command (LSB=09h, MSB=Unknown/unused) 01h..0Dh Unknown/unused 0Eh Checksum (00h-[00h..0Dh]) From SNES Packet 00h PPU Status Response (with "RAD" string) ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=00h, MSB=Zero) 01h PPU2 Status [213Fh] (PPU2 chip version & Interlace/Lightgun/NTSC) 02h PPU1 Status [213Eh] (PPU1 chip version & OBJ overflow flags) 03h CPU Status [4210h] (CPU chip version & NMI flag) 04h Curr Scanline [213Dh] (lower 8bit of current scanline number) 05h..0Ah Constants (52h,41h,44h,00h,00h,00h) (aka "RAD",0,0,0) 0Bh Checksum (00h-[00h..0Ah]) Note: This data is send only after PPU Status Request. There are also cases (during menues) where SNES is sending Packet 00h with zerofilled data body. SNES Controllers Exertainment - RS232 Data Packets Biking Phase --------------------------------------------------------------- Communication Phase SNES Packet 00h Idle (while in menu) (also used for PPU Status Response) SNES Packet 01h Biking Start (start biking; probably resets time/distance) SNES Packet 02h Biking Active (biking) SNES Packet 03h Biking Pause (pause biking) SNES Packet 04h Biking Exit (finish or abort biking) SNES Packet 05h User Parameters SNES Packet 06h Biking ? SNES Packet 07h Biking ? SNES Packet 08h Biking ? Bike Packet 01h ;\these might both contain same bike data, Bike Packet 02h ;/both required to be send (else SNES hangs) Bike Packet 03h ;<-- confirms/requests pause mode Unknown values & commands might include things like TV control. From Bike Packet xxh (Communication Phase) ATT Attention Code (133h, with 9th bit aka parity set = packet start) 00h Command (LSB=00h..07h or so, MSB=Curr Level 0..12, Pedal Resistance) 01h Speed in pedal rotations per minute (0..xxx) (above 200=glitches?) 02h Time (MSB) in 60 second units (0..255) ;\ 03h Time (LSB) in 1 second units (0..59) ;/ 04h Calories per hour (MSB) in 256 cal/hr units ;\this used in bank B0h 05h Calories per hour (LSB) in 1 cal/hr units ;/ 06h Calories burned (MSB) in 256/4 cal units ;\ 07h Calories burned (LSB) in 1/4 cal units ;/ 08h Distance (MSB) in 65536/3600 miles ;\ 09h Distance (MID) in 256/3600 miles ; 0Ah Distance (LSB) in 1/3600 miles ;/ 0Bh Pulse in heart beats per minute (1..255 bpm, or 0=No Pulse Sensor) 0Ch Fit Test Score (clipped to range 10..60) 0Dh Whatever 8bit (invalid values CRASH combo-cart games) 0Eh Checksum (00h-[00h..0Dh]) In Fit Test mode (when [0Dh]=85h), the bike seems to send Time=Zero when the test ends (after 5 minutes) - either it's counting time backwards in that mode, or it's wrapping from 5 minutes to zero? Other modes, like workout, are counting time upwards, and end when reaching the selected time goal value. From SNES Packet xxh ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=01h..0xh ?, MSB=Wanted Level 0..12 Pedal Resistance) 01h Something (MSB=often same as above MSB, LSB=Present Hill related) 02h Present Hill 03h..09h Upcoming Hills (7 bytes) 0Ah Whatever (in MENU: 01h,02h,00h, WORKOUT:80h, FIT-TEST:85h) 80h..86h 0Bh Checksum (00h-[00h..0Ah]) From SNES Packet x5h (User Parameters) ACK Acknowledge Code (33h, received packet with good checksum From Bike) 00h Command (LSB=05h, MSB=Wanted Level 0..12, Pedal Resistance) 01h Player's Sex (00h=Female, 01h=Male) 02h Player's Age in years (0..99) 03h Player's Weight in pounds (0..255, plus below Weight Extra) 04h Player's Pulse in heart beats per minute 05h Player's Weight Extra (added to weight, eg. 399 = values FFh+90h) 06h..09h Garbage, set to same value as [05h], but NOT counted in checksum? 0Ah Whatever (same as in other "From SNES" communication packets) 0Bh Checksum (00h-[00h..0Ah]) --- in this case, excluding [06h..09h] ? Single-cart is configuring this packet for Fit Test (but is never sending the packet)? Combo-cart is often sending this packet (but with all parameters set to zero)? SNES Controllers Exertainment - Drawings ---------------------------------------- Exercising Machine (Side View) Front Panel (located below of the monitor) Monitor ____________________________________ .\ / Handles | | .' \ / Saddle |:::::: /\ /\ TV Menu| .' \ \ / |:::::: Volume Program _ _ | \ \ \___ |:::::: O \/ \/ |_| |_|| \__--""| // ===== |____________________________________| | | // || | | | | | | | // || | | | | TV-Picture | Rack | / | / | Pedals | | | | in picture | | / \ / | / | | | | | | / \____/ _ | | | | TV Program Up/Down | | / / \ | | Volume Up/Down | |/ O \ | Headphone socket |______|___________________| Speaker The monitor, rack and front panel have been spotted on prototype photos, unknown if the normal retail bikes did have them, too (also possible that one got only the bike and expansion port unit - and had to use it with a regular SNES and TV-set). Handlebars with Controllers ____ ______ ______ ____ | | _ \ / | | | | /\ /\ | 1st 1st | X | | | || O || <-- DPAD XYAB --> | Y A | | | | \/_\/ | | B | | | | | <-- L-Button R-Button --> | | | | | O O | (on bottom (on bottom | | | |____|______/ side) side) \______|____| | | | \ | | | | \ Select | | | | Start | | |__| ________ ________ |__| | | |<-- 2nd DPAD 2nd XYAB -->| | | | __ |_______/ (also with Start/Select/L/R) \_______| __ | | \______________________.---._______________________/ | \_________________________|___|__________________________/ | | As depicted, there appear to be absolutely no brakes on this bike. Which must have made it a frightening kamikaze-like experience to sit on that thing. Even worse, there is no bell. One could only scream "Out of the way! Out of the way!" at the monitor. SNES Controllers Pachinko ------------------------- Pachinko Controller (Sunsoft) The Pachinko controller should be connected to controller Port 2 (plus a normal joypad in Port 1 for menu selections). After the usual joypad strobing, Pachinko data can be read serially from [4017h].Bit0: 1st..8th Unknown/unused (would be Buttons/DPAD on joypads) 9th Used... probably a button? (would be Button-A on joypads) 10th..12th Unknown/unused (would be Buttons on joypads) 13th..16th ID Bit3-0 (must be 0Eh) (MSB first) 17th..24th Extra ID Bit7-0 (must be 77h) (MSB first) 25th Unknown/unused 26th..32th Analog Dial Position (7bit, MSB first, inverted, 1=Low=Zero) 33th.. Unknown/padding Average analog 7bit range returned on real hardware is unknown. In software, the used 7bit range is around 18h=Stopped through 7Fh=Fastest. The controller looks somewhat like a blue egg, plus a yellow dial with zagged finger-grips, and probably with a button somewhere (maybe the orange window in the middle of the head or so?): _ Top-View \_\___ . __________ Side-View ..' '..|\ .' '''''' '. <-- Blue Head ...' '.| _|______________| .'.' ___ '. <__<_|__<_|_______) <-- Yello dial / .' .' '. '. | | / | | | |__ | | <-- Blue Base |/\| |SUNSOFT| | / | | '. '.___.' .'/ | | '. .' ''._ __ _.'' \ '. .' _____|__|_____ ''----- cable ''._____.'' (______________) Known supported games are: Hissatsu Pachinko Collection 1 (J) 1994 Sunsoft/Fuji Hissatsu Pachinko Collection 2 (J) 1995 Sunsoft/Fuji Hissatsu Pachinko Collection 3 (J) 1995 Sunsoft/Daiichi/Nifty-Serve Hissatsu Pachinko Collection 4 (J) 1996 Sunsoft/Kyoraku/Nifty-Serve Note: Pachinko is a japanese gambling game; its appearance is resembling pinball, but concerning stupidity it's more resembling one-armed-bandit-style slot machines. SNES Controllers Other Inputs ----------------------------- Reset Button (on the console) Resets various CPU/PPU/APU registers, but leaves WRAM intact, so for example, games could use the button to restart the current level, or to enter the main menu. Note: The three SPC7110 games are containing a selftest program (executed upon first boot; when battery-backed SRAM is still unitialized), the user is prompted to push the Reset Button after each test screen. Super Famicom Box This thing has a (external) coin input, two push buttons, and a 6-position switch (all these inputs are accessible only by its HD64180 CPU though, not by the SNES CPU). The two attached joypads aren't directly wired to the SNES, instead, they are first passed to the HD64180, and then forwarded to SNES via 16bit shift registers. This allows the HD64180 to sense the "L+R+Select+Start" Soft-Reset key combination, and to inject recorded controller data in Demo/Preview mode. On the restrictive side, the 16bit shift registers are making it incompatible with special controllers like mice (which won't work with most of the SFC-Box games anyways); unless, maybe "automatic-reading" mode bypasses the 16bit shift-register, and forwards the FULL bitstream directly from SFC-Box to SNES? Moreover, during Game Selection, some normally unused bits of the WRIO/RDIO "controller" port are misused to communicate between KROM1 (on HD64180) and ATROM (on SNES). SNES Add-On Turbo File (external backup memory for storing game positions) -------------------------------------------------------------------------- The Turbo File add-ons are an external battery-backed RAM-Disks made by ASCII. Turbo File hardware has been produced for NES, SNES, 8bit Gameboy, and Gameboy Advance. It's been sold only in japan, and it's mainly supported by ASCII's own games. The SNES related hardware versions are: SNES Turbo File Twin (160K) (128K in STF mode, 4x8K in TFII mode) SNES Turbo File Adapter (SNES adapter for NES Turbo File & Turbo File II) TFII Mode (old NES mode, 4x8Kbyte) --> SNES Add-On Turbo File - TFII Mode Transmission Protocol --> SNES Add-On Turbo File - TFII Mode Filesystem STF Mode (native SNES mode, 128Kbyte) --> SNES Add-On Turbo File - STF Mode Transmission Protocol --> SNES Add-On Turbo File - STF Mode Filesystem Compatible Games --> SNES Add-On Turbo File - Games NES Turbofile (AS-TF02) Original NES version, contains 8Kbytes battery backed RAM, and a 2-position PROTECT switch, plus a LED (unknown purpose). NES Turbo File II (TFII) Newer NES version, same as above, but contains 32Kbytes RAM, divided into four 8Kbyte slots, which can be selected with a 4-position SELECT switch. SNES Turbo File Adapter Allows to connect a Turbo File or Turbo File II to SNES consoles. Aside from the pin conversion (15pin NES to 7pin SNES), it does additionally contain some electronics (for generating a SNES controller ID, and a more complicated protocol for entering the data-transfer phase). Aside from storing SNES game positions, this can be also used to import NES files to SNES games. SNES Turbo File Twin SNES version with 160Kbyte SRAM, and with 5-position mode SELECT switch. 128K used in STF mode ("SNES Super Turbo File"), and 4x8K used in TFII modes 1/2/3/4 (equivalent to NES Turbo File II with SNES Turbo File Adapter). Small square box that connects via cable to controller port. Two position PROTECT switch (off/on) Five position SELECT switch (STF, and "TFII" 1,2,3,4) There is a red LED. And two 1.5V batteries? Hardware Versions Name Capacity Connection Turbofile (AS-TF02) 1x8Kbyte NES-to-SNES Adapter Turbo File II 4x8Kbyte NES-to-SNES Adapter Turbo File Twin 4x8Kbyte plus 128Kbyte Direct SNES Connection Gameboy version ? N/A ? Gameboy Advance ? N/A ? SNES Add-On Turbo File - TFII Mode Transmission Protocol -------------------------------------------------------- oldest_recv_8191_bytes: call oldest_invoke_transfer ;start transfer if invoke_okay then for i=0001h to 1FFFh, oldest_recv_byte(buf[i]) jmp oldest_reset_turbofile ;end transfer (always, even if invoke failed) oldest_send_8191_bytes: call oldest_invoke_transfer ;start transfer if invoke_okay then for i=0001h to 1FFFh, oldest_send_byte(buf[i]) jmp oldest_reset_turbofile ;end transfer (always, even if invoke failed) oldest_invoke_transfer: call oldest_detect_and_get_status if no_tf_connected then fail/exit if data_phase=1 then ;oops, already invoked oldest_detect_and_get_status ;abort old transfer jmp oldest_invoke_transfer ;retry invoking new transfer [004016]=01h ;strobe on ;\ for i=1 to 15,dummy=[004017],next i ;issue 15 clks ; invoke transfer [004016]=00h ;strobe off ; (16 clks total) dummy=[004017] ;issue 1 clk ;/ call oldest_detect_and_get_status ;\want flag set now if data_phase=0 then fail/exit ;/ for i=1 to 7 ;\skip remaining 7 bits dummy=[004017] ;<-- required? ;issue clk ; of unused byte 0000h [004016]=01h ;strobe on ; (the first bit was [004016]=00h ;strobe off ; skipped by STROBE in next i ;/detect_and_get_status) After above, the hardware byte-address is 0001h (ie. unlike as in NES version, the unused byte at address 0000h is already skipped). oldest_detect_and_get_status: [004016]=01h ;strobe on [004016]=00h ;strobe off for i=23 to 0 ;get ID/status (MSB first) temp=[004017] ;issue clk & get data stat.bit(i)=temp.bit0 next i if stat.bit(11..8)<>0Eh then no_tf_connected=1 ;major 4bit id if stat.bit(7..0)<>0FFh then no_tf_connected=1 ;minor 8bit id if stat.bit(12)=1 then data_phase=1 else data_phase=0 oldest_reset_turbofile: [004016]=01h ;strobe on dummy=[004017] ;issue clk [004016]=00h ;strobe off dummy=[004017] ;issue clk [004016]=00h ;strobe off (again?) jmp oldest_detect_and_get_status oldest_recv_byte(data): for i=0 to 7 ;transfer data byte (LSB first) temp=[004017] ;issue clk (required?), and get bit from joy4 data.bit(i)=temp.bit(1) ;extract received data bit [004016]=01h ;strobe on [004201]=80h*data.bit(i) ;write SAME/UNCHANGED bit to hardware [004016]=00h ;strobe off (WRITE CLOCK) next i oldest_send_byte(data): for i=0 to 7 ;transfer data byte (LSB first) dummy=[004017] ;issue clk (really required for writing?) [004016]=01h ;strobe on [004201]=80h*data.bit(i) ;write NEW bit to hardware [004016]=00h ;strobe off (WRITE CLOCK) next i SNES Add-On Turbo File - TFII Mode Filesystem --------------------------------------------- Turbo File Memory The first byte (at offset 0000h) is unused (possibly because that there is a risk that other games with other controller access functions may destroy it); after resetting the address, one should read one dummy byte to skip the unused byte. The used portion is 8191 bytes (offset 0001h..1FFFh). The "filesystem" is very simple: Each file is attached after the previous file, an invalid file ID indicates begin of free memory. Turbo File Fileformat (newer files) (1987 and up) Normal files are formatted like so: 2 ID "AB" (41h,42h) 2 Filesize (16+N+2) (including title and checksum) 16 Title in ASCII (terminated by 00h or 01h) N Data Portion 2 Checksum (all N bytes in Data Portion added together) Turbo File Fileformat (old version) (1986) The oldest Turbo File game (NES Castle Excellent from 1986) doesn't use the above format. Instead, it uses the following format, without filename, and with hardcoded memory offset 0001h..01FFh (511 bytes): 1 Don't care (should be 00h) ;fixed, at offset 0001h 2 ID AAh,55h ;fixed, at offset 0002h..0003h 508 Data Portion (Data, end code "BEDEUTUN", followed by some unused bytes) CAUTION: The early version has transferred all bytes in reversed bit-order, so above ID bytes AAh,55h will be seen as 55h,AAh in newer versions! Since the address is hardcoded, Castle Excellent will forcefully destroy any other/newer files that are located at the same address. Most newer NES/SNES games (like NES Fleet Commander from 1988, and SNES Wizardry 5 from 1992) do include support for handling the Castle Excellent file. One exception that doesn't support the file is NES Derby Stallion - Zenkoku Ban from 1992. SNES Add-On Turbo File - STF Mode Transmission Protocol ------------------------------------------------------- FileTwinSendCommand (28bits) set strobe=1 8x sendbit (LSB first) ;command (24h=read or 75h=write) 20x sendbit (LSB first) ;address (00000h..FFFFFh) set strobe=0 FileTwinRecvStatusAndID error if bad-ID or general-error-flag (for write: also write protect-error) retry "FileTwinSendCommand" if desired Read (or Write) Mode bit isn't set Thereafter, send/receive data byte(s), and finish by TerminateCommand TerminateCommand set strobe=1 if command was READ then issue clk (don't do that on WRITE command) set strobe=0 FileTwinRecvStatusAndID retry "TerminateCommand" if Data Read/Write Mode bits are still nonzero FileTwinSendDataByte set strobe=1 8x sendbit (LSB first) set strobe=0 FileTwinRecvDataByte set strobe=1 set strobe=0 8x recvbit (from joy4) (LSB first) (inverted) FileTwinRecvStatusAndID (32bits) set strobe=1 set strobe=0 12x recvbit (from joy2) (ignored) 4x recvbit (from joy2) (MSB first) (major ID, must be 0Eh) 8x recvbit (from joy2) (MSB first) (minor ID, must be FEh) 1x recvbit (from joy2) Data Write Mode (0=No/Idle, 1=Yes/Command 75h) 1x recvbit (from joy2) Data Read Mode (0=No/Idle, 1=Yes/Command 24h) 1x recvbit (from joy2) General-Hardware-Error (1=Error) 1x recvbit (from joy2) Write-Protect-Error (1=Error/Protected) 4x recvbit (from joy2) (MSB first) (capacity) (usually/always 0=128K) Low Level Functions set strobe=1 --> [004016h]=1 set strobe=0 --> [004016h]=0 recvbit (from joy2) --> bit=[004017h].bit0 recvbit (from joy4) --> bit=NOT [004017h].bit1 sendbit --> [004201h]=bit*80h, dummy=[004017h] issue clk --> dummy=[004017h] SNES Add-On Turbo File - STF Mode Filesystem -------------------------------------------- FileTwinCapacityCodes (last 4bit of FileTwinRecvStatusAndID) 00h Single Drive with 128Kbytes (normal) (plus extra 32Kbyte for TFII mode) 01h Single Drive with 256Kbytes 02h Single Drive with 384Kbytes 03h Single Drive with 640Kbytes (really, this is NOT 512Kbytes) 04h Multi-Drive with 1 normal 128K Drive (128K total) ;\allows to READ from 05h Multi-Drive with 2 normal 128K Drives (256K total) ; all drives, but 06h Multi-Drive with 3 normal 128K Drives (384K total) ; can WRITE only 07h Multi-Drive with 5 normal 128K Drives (640K total) ;/to first drive 08h..0Fh Reserved (treated same as 00h; Single Drive with 128Kbytes) FileTwinAddresses (?) XXX multiply below by 400h 000h..00Fh FAT (4Kbytes) 010h..1FFh Entries for 1st 124Kbytes 200h..7FFh Unused 800h..9FFh Entries for 2nd 128Kbytes (if any) A00h..BFFh Entries for 3rd 128Kbytes (if any) C00h..DFFh Entries for 4th 128Kbytes (if any) (seems to be bugged) E00h..FFFh Unused xxxh..xxxh Partition-Read FAT (though WRITES are to address zero ?) FileTwinFAT The FAT is 4096 bytes in size: 000h..1EFh Entries for 1st 124Kbytes 1F0h..3EFh Entries for 2nd 128Kbytes (if any) 3F0h..5EFh Entries for 3rd 128Kbytes (if any) 5F0h..7EFh Entries for 4th 128Kbytes (if any) (seems to be bugged) 7F0h..FFBh Unused FFCh..FFFh ID "FAT0" Each FAT Entry is 32bit (4 bytes) wide: 0-11 filesize in kbyte (1st blk), 000h (2nd..Nth blk), FFFh (free blk) 12-23 NNNh (next blk), FFFh (last blk), or also FFFh (free blk) 24-31 8bit sector chksum (all 1024 bytes added together), or FFh (free blk) Note: The above FFFh values should be as so (though older games are checking only the upper 4bit, thereby treating any Fxxh values as free/last block). Unused FAT entries (that exceed memory capacity) are also marked as "free". FileTwinFileHeaders The first 24 bytes (in the first sector) of a file contain File ID & Name: 000h..003h ID1 (must be "SHVC") 004h..007h ID2 (should be same as Game Code at [FFB2h] in ROM-Header) 008h..017h Filename (padded with ...spaces ?) 018h.. File Data (Filesize from FAT, multiplied by 1024, minus 24 bytes) ID2 and Name may contain ASCII characters 20h..3Fh and 41h..5Ah. SNES Add-On Turbo File - Games ------------------------------ SNES Games that support Turbo File Twin in STF-Mode Bahamut Lagoon (1996) Square (INCORRECTLY?! claimed to support Turbo File) Daisenryaku Expert WWII: War in Europe (1996) SystemSoftAlpha/ASCII Corp (JP) Dark Law - Meaning of Death (1997) ASCII (JP) Derby Stallion III (1995) (supports both TFII and STF modes) Derby Stallion 96 (1996) (supports TFII and STF and Satellaview-FLASH-cards) Derby Stallion 98 (NP) (1998) (supports both TFII and STF modes) Gunple/Ganpuru - Gunman's Proof (1997) ASCII/Lenar (JP) Mini Yonku/4WD Shining Scorpion - Let's & Go!! (1996) KID/ASCII Corp (JP) Ongaku Tukool/Tsukuru Kanaderu (supports STF and Satellaview-FLASH-cards) RPG Tukool 1 RPG Tukool 2 (supports STF and Satellaview-FLASH-cards) Sound Novel Tukool (supports STF and Satellaview-FLASH-cards) Tactics Ogre - Let Us Cling Together (supports both TFII and STF modes) Wizardry 6 - Bane of the Cosmic Forge (1995) (JP) (English) Plus (unverified): STF: Tower Dream STF: Best Shot Pro Golf (J) STF: Jewel of Live (RPG Maker Super Dante) (BS) STF: Solid Runner (J) STF: Wizardry Gaiden IV - Taima no Kodou (J) (v1.1) SNES Games that support Turbo File Adapter & Turbo File Twin in TFII-Mode Ardy Lightfoot (1993) Derby Stallion II (1994) Derby Stallion III (1995) (supports both TFII and STF modes) Derby Stallion 96 (1996) (supports TFII and STF and Satellaview-FLASH-cards) Derby Stallion 98 (NP) (1998) (supports both TFII and STF modes) Down the World: Mervil's Ambition (1994) Kakinoki Shogi (1995) ASCII Corporation Tactics Ogre - Let Us Cling Together (supports both TFII and STF modes) Wizardry 5 - Heart of the Maelstrom (1992) Game Studio/ASCII (JP) BS Wizardry 5 (JP) (Satellaview BS-X version) Plus (unverified): TFII: Haisei Mahjong - Ryouga (J) TFII: Super Fire Pro Wrestling Special, X, and X Premium (J) TFII: Super Robot Taisen Gaiden - Masou Kishin - The Lord of Elemental (J) Note: The US version of Wizardry 5 (1993) contains 99% of the turbo file functions, but lacks one opcode that makes the hardware detection nonfunctional. Wizardry 5 was announced/rumoured to be able to import game positions from NES to SNES. NES Games that do support the Turbo File / Turbo File II Best Play Pro Yakyuu (1988) ASCII (J) Best Play Pro Yakyuu '90 (1990) (J) Best Play Pro Yakyuu II (1990) (J) Best Play Pro Yakyuu Special (1992) (J) Castle Excellent (1986) ASCII (J) (early access method without filename) Derby Stallion - Zenkoku Ban (1992) Sonobe Hiroyuki/ASCII (J) Downtown - Nekketsu Monogatari (19xx) Technos Japan Corp (J) Dungeon Kid (1990) Quest/Pixel (J) Fleet Commander (1988) ASCII (J) Haja no Fuuin (19xx) ASCII/KGD (J) Itadaki Street - Watashi no Mise ni Yottette (1990) ASCII (J) Ninjara Hoi! (J) Wizardry - Legacy of Llylgamyn (19xx?) (J) Wizardry - Proving Grounds of the Mad Overlord (1987) (J) Wizardry - The Knight of Diamonds (1991) (J) NES games that do support Turbo File should have a "TF" logo on the cartridge. Note: Castlequest (US version of Castle Excellent) reportedly lacks support. SNES Add-On Barcode Battler (barcode reader) -------------------------------------------- The Barcode Battler from Epoch allows to scan barcodes (either from special paper cards, or from daily-life products like food packagings), games can then use the barcode digits as Health Points, or other game attributes. Standalone-Mode The device was originally designed as stand-alone gaming console with some push buttons, a very simple LCD screen with 7-segment digits & some predefined LCD symbols, and a built-in game BIOS (ie. without external cartridge slot, and without any bitmap graphics). Link-Mode Later versions (with black case) include an "EXT" link port, allowing to link to other Barcode Battler hardware, or to Famicom/Super Famicom consoles. The EXT port is probably bi-directional, but existing Famicom/Super Famicom games seem to be using it only for reading barcodes (without accessing the LCD screen, push buttons, speaker, or EEPROM). --> SNES Add-On Barcode Transmission I/O --> SNES Add-On Barcode Battler Drawings Barcode Battler Famicom (NES) Games Barcode World (1992) Sunsoft (JP) (includes cable with 15pin connector) Barcode Battler Super Famicom (SNES) Games Alice's Paint Adventure (1995) Amazing Spider-Man, The - Lethal Foes (19xx) Barcode Battler Senki Coveni Wars (1993) Epoch Donald Duck no Mahou no Boushi (19xx) Doraemon 2: Nobita's Great Adventure Toys Land (1993) Doraemon 3: Nobita and the Jewel of Time (1994) Doraemon 4 - Nobita to Tsuki no Oukoku (19xx) Doroman (canceled) Dragon Slayer - Legend of Heroes 2 (1993) Epoch J-League Excite Stage '94 (1994) J-League Excite Stage '95 (1995) Lupin Sansei - Densetsu no Hihou wo Oe! (19xx) Super Warrior Combat (19xx - does this game exist at all?) Barcode Battler Hardware Versions Region__Case___EXT___Barcode-Reader__Name__________________Year___ Japan White None Yes Barcode Battler 1991 Japan Black 1 Yes Barcode Battler II 1992 Japan Black 2 None Barcode Battler II^2 199x Europe Black 1 Yes Barcode Battler 1992/1993 The versions with one EXT socket can be connected to NES/SNES, or to one or more of the "II^2" units (allowing more players to join the game). Connection to SNES/NES consoles Connection to Super Famicom or SNES requires a "BBII INTERFACE": a small box with 4 LEDs and two cables attached (with 3pin/7pin connectors), the interface has been sold separetedly, it's needed to add a SNES controller ID code to the transmission protocol. Connection to Famicom consoles requires a simple cable (without interface box) (with 3pin/15pin connectors), the cable was shipped with the "Barcode World" Famicom cartridge, connection to NES would require to replace the 15pin Famicom connector by 7pin NES connector. The required 3pin EXT connector is available only on newer Barcode Battlers (with black case), not on the original Barcode Battler (with white case). Unknown if all 3 pins are actually used by NES/SNES cable/interface? Unknown if NES/SNES software can access LCD/buttons/speaker/EEPROM ? Connectivity "Connectivity mode is accessible if you plug in a standard 3.5mm mono jack plug into the expansion port on the left hand side of the unit, hold down the R-Battle and R-Power buttons and turn the unit on, the Barcode Battler II goes into scanner mode." Barcode Battler II Interface The hardware itself was manufactured by Epoch, and licensed by Nintendo (it says so on the case). The four lights, from left to right, indicate as follows: "OK" All is well, the device is operating as normal. "ER" Maybe there's something wrong? "BBII" The Barcode Battler is sending data to the device. "SFC" The SFC/SNES is waiting for a signal from the Barcode Battler. Component List (may be incomplete) 80pin NEC uPD75316GF (4bit CPU with on-chip 8Kx8 ROM, 512x4 RAM, LCD driver) 8pin Seiko S2929A (Serial EEPROM, 128x16 = 2Kbit) (same/similar as S29290) 3pin EXT socket (3.5mm "stereo" jack) (only in new versions with black case) LCD Screen (with 7-segment digits and some predefined words/symbols) Five LEDs (labelled "L/R-Battle Side") Seven Push Buttons (L/R-POWER, L/R-Battle, Power on/off, Select, Set) Speaker with sound on/off switch (both on bottom side) Barcode reader (requires card-edges to be pulled through a slot) Batteries (four 1.5V AA batteries) (6V) SNES Add-On Barcode Transmission I/O ------------------------------------ The Barcode Battler outputs barcodes as 20-byte ASCII string, at 1200 Baud, 8N1. The NES software receives that bitstream via Port 4017h.Bit2. The SNES software requires a BBII Interface, which converts the 8bit ASCII digits into 4bit nibbles, and inserts SNES controller ID and status codes, the interface should be usually connected to Controller Port 2 (although the existing SNES games seem to accept it also in Port 1). Barcode Battler (with BBII Interface) SNES Controller Bits 1st..12th Unknown/unused (probably always 0=High?) 13th..16th ID Bits3..0 (MSB first, 1=Low=One) (must be 0Eh) 17th..24th Extended ID Bits7..0 (MSB first, 1=Low=One) (must be 00h..03h) (the SNES programs accept extended IDs 00h..03h, unknown if/when/why the BBII hardware does that send FOUR values) 25th Status: Barcode present (1=Low=Yes) 26th Status: Error Flag 1 ? 27th Status: Error Flag 2 ? 28th Status: Unknown ? Following bits need/should be read ONLY if the "Barcode Present" bit is set. 29th-32th 1st Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 33th-36th 2nd Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 37th-40th 3rd Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 41th-44th 4th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 45th-48th 5th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 49th-52th 6th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 53th-56th 7th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 57th-60th 8th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 61th-64th 9th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 65th-68th 10th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 69th-72th 11th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 73th-76th 12th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 77th-80th 13th Barcode Digit, Bits3..0 (MSB first, 1=Low=One) 81th and up Unknown/unused Above would be 13-digit EAN-13 codes Unknown how 12-digit UPC-A codes are transferred ;\whatever leading Unknown if/how 8-digit EAN-8 codes are transferred ; or ending padding? Unknown if/how 8-digit UPC-E codes are transferred ;/ For some reason, delays should be inserted after each 8 bits (starting with 24th bit, ie. after 24th, 32th, 40th, 48th, 56th, 64th, 72th bit, and maybe also after 80th bit). Unknown if delays are also needed after 8th and 16th bit (automatic joypad reading does probably imply suitable delays, but errors might occur when reading the ID bits via faster manual reading). Barcode Battler RAW Data Output Data is send as 20-byte ASCII string. Bytes are transferred at 1200 Bauds: 1 Start bit (must be LOW) 8 Data bits (LSB first, LOW=Zero, HIGH=One) 1 Stop bit (must be HIGH) The first 13 bytes can contain following strings: "nnnnnnnnnnnnn" ;13-digit EAN-13 code (ASCII chars 30h..39h) ;12-digit UPC-A code (with ending/leading padding?) " nnnnnnnn" ;8-digit EAN-8 code (with leading SPC-padding, ASCII 20h) ;8-digit UPC-E code (with ending/leading padding?) "ERROR " ;indicates scanning error The last 7 bytes must contain either one of following ID strings: "EPOCH",0Dh,0Ah ;<-- this is sent/accepted by existing hardware/software "SUNSOFT" ;<-- this would be alternately accepted by the NES game There are rumours that one "must" use a mono 3.5mm plug in order to receive data - that's obviously bullshit, but it might indicate that the middle pin of stereo plugs must be GNDed in order to switch the Barcode Battler into transmit mode(?) SNES Add-On Barcode Battler Drawings ------------------------------------ Barcode Battler - Handheld Console (Front) _______________________________ .---""" _______________________ """---. | /\ | | /\ | | \ \ | | / / | | L \/ | LCD Screen | \/ R | | POWER | | POWER | | /\ | | /\ | | \ \ | | / / | | L \/ |_______________________| \/ R | | BATTLE BATTLE | | O O O O O | | L <-- Battle Side --> R | ) EXT | | On/off Select Set | | [====] [====] [====] | '---_____________________________________---' --> : _____________________________ : --> --> pull card this way :/ CARD IN --> \: |_______________________________| Barcode Battler - Handheld Console (Back) _______________________________ .---""" : : """---. | : Battery Lid : | | : (Four AA Batteries) : | | : : | | :.........................: | | | | | | | | __ | | o |__| | | o o o Sound | | o on/off ( <-- 3.5mm 3pin | Speaker | EXT socket | | '---__ __---' | | | | |_______________________________| Barcode Battler - LCD Screen Layout _______________ ___________ _______________ | .-------. _|__ESCAPE___|_ .-------. | | | FIGHT | / < SUPER HIT > \ |RECOVER| | | |BARCODE| /|_______________|\ | MISS | | | '-------' '-------' | | (*) (/) (K) POWER INPUT (i) (/) (*) | | _ _ _ _ _ _______ _ _ _ _ _ | | |_||_||_|| || | |ENERGY | |_||_||_|| || | | | |_||_||_||_||_| |DAMAGE | |_||_||_||_||_| | | _ _ _ _ _ |_______| _ _ _ _ _ | | |_||_||_|| || | |ATTACK | |_||_||_|| || | | | |_||_||_||_||_| | MAGIC | |_||_||_||_||_| | | _ _ _ _ _ |_______| _ _ _ _ _ | | |_||_||_|| || | |DEFENCE| |_||_||_|| || | | | |_||_||_||_||_| |SURVIVA| |_||_||_||_||_| | |_________________|_______|_________________| Barcode Batter II Interface (SNES/SuperFamicom) & Simple Cable (Famicom) _________________ cables -> / _______ '''---> 3pin 3.5mm "stereo" EXT connector _____|_____|____ '''---> 7pin SNES/SuperFamicom connector ___| |___ | | _.----> 3pin 3.5mm "stereo" EXT connector | BBII INTERFACE | .-' | | | | O O O O | '-_ cable |________________________| ''-------> 15pin Famicom connector Paper-Card Front (Picture Side) _________________________________________________ | | | NINJA STAR WEAPON-17 | | > INSERT | | ----------------------^------------------------ | | | | | | ___ /___\ ____ | | ___---""" /__/ \__\ """---___ | | ---___ __ O __ ___--- | | """---___\ _\ /_ /___---""" / | | \ / / | | | | /_ | | ----------------------V--------------------'( ) | | ST 400 ||| | |_________________________________________________| Paper-Card Back (Description & Barcode) _________________________________________________ | | | BARCODE BATTLER | | NINJA STAR | | 1992 Epoch | | A lethal weapon which demands skill, patience | | and, most important, perfect timing. Send it | | spinning at the enemy when the Battler spirit is| | with you and the effect can be devasting. Time | | it wrong and the star may harmlessly bounce off | | their defences. | | || || |||| || || |||| || || |||| | | || || |||| || || |||| || || |||| | | || || |||| || || |||| || || |||| | |_________________________________________________| SNES Add-On SFC Modem (for JRA PAT) ----------------------------------- --> SNES Add-On SFC Modem - Data I/O --> SNES Add-On SFC Modem - Misc Controller The SFC Modem is bundled with a special controller (to be connected to controller port 1) (required for the JRA PAT software): --> SNES Controllers NTT Data Pad (joypad with numeric keypad) FLASH Backup The JRA PAT Modem BIOS cartridges contain FLASH backup memory (unlike other SNES cartridges which do use battery-backed SRAM instead of FLASH). --> SNES Cart FLASH Backup Baudrates The BIOS seems to support max 2400 baud (old BIOS version) and 9600 baud (new BIOS version) - accordingly, there are probably also two different hardware versions of the SFC Modem. Note There's also another modem (which connects to cartridge slot): --> SNES Cart X-Band (2400 baud Modem) SNES Add-On SFC Modem - Data I/O -------------------------------- The modem is intended to be connected to controller port 2. RX Data, TX Data, and Modem Status are simultaneously transferred via three I/O lines. The overall transfer length (with ID bits) is 16-bit, however, after checking the ID bits, one can abbreviate the transfer to 9-bit length. JOY2: (4017h.Bit0) - RX Data and ID Bits 1st RX Data Bit7 (0=High=Zero, 1=Low=One) ;\ 2nd RX Data Bit6 (0=High=Zero, 1=Low=One) ; 3rd RX Data Bit5 (0=High=Zero, 1=Low=One) ; to be ignored when 4th RX Data Bit4 (0=High=Zero, 1=Low=One) ; no RX Data Present 5th RX Data Bit3 (0=High=Zero, 1=Low=One) ; 6th RX Data Bit2 (0=High=Zero, 1=Low=One) ; 7th RX Data Bit1 (0=High=Zero, 1=Low=One) ; 8th RX Data Bit0 (0=High=Zero, 1=Low=One) ;/ 9th RX Data Present (0=High=None, 1=Low=Yes) 10th Unknown/Unused 11th Unknown/Unused 12th Unknown/Unused 13th ID Bit3 (always 0=High) 14th ID Bit2 (always 0=High) 15th ID Bit1 (always 1=Low) 16th ID Bit0 (always 1=Low) 17th and up Unknown/Unused (probably always whatever) JOY4: (4017h.Bit1) - Modem Status 1st Unknown Flags Bit7 (1=Low=Busy or so, 0=Ready to get TX Data) 2nd Unknown Flags Bit6 (0=High=Error/Abort or so) 3rd Unknown Flags Bit5 (1=Low=Busy or so) 4th Unknown Flags Bit4 (1=Low=Busy or so) 5th Unknown Flags Bit3 Unused? 6th Unknown Flags Bit2 Unused? 7th Unknown Flags Bit1 Unused? 8th Unknown Flags Bit0 Unused? 9th and up Unknown/Unused (probably always whatever) IOBIT (4201h.Bit7) - TX Data 1st bit should be output immediately after strobing 4016h.Output, 2nd..9th bit should be output immediately after reading 1st..8th data/status bits from 4017h. 1st TX Data Present (0=Low=Yes, 1=HighZ=None) 2nd TX Data Bit7 (0=Low=Zero, 1=HighZ=One) ;\ 3rd TX Data Bit6 (0=Low=Zero, 1=HighZ=One) ; should be DATA 4th TX Data Bit5 (0=Low=Zero, 1=HighZ=One) ; when Data Present, 5th TX Data Bit4 (0=Low=Zero, 1=HighZ=One) ; or otherwise, 6th TX Data Bit3 (0=Low=Zero, 1=HighZ=One) ; should be FFh, 7th TX Data Bit2 (0=Low=Zero, 1=HighZ=One) ; or "R" or "C" ? 8th TX Data Bit1 (0=Low=Zero, 1=HighZ=One) ; (RTS/CTS or so?) 9th TX Data Bit0 (0=Low=Zero, 1=HighZ=One) ;/ 10th and up Should be "1" (1=HighZ) SNES Add-On SFC Modem - Misc ---------------------------- "The Modem as far as I know only had one function and that was to allow you to do online betting via the official JRA (Japanese Horse Racing) online service. The modem ran on the NTT lines which probably means that NTT (Nippon Telecommunications) also had something to make out of this service or at least they thought they did :-D" JRA = Japan Racing Association (japanese horse racing) PAT = Personal Access Terminal (for telephone/online betting) NTT = Nippon Telegraph and Telephone (japanese telecommunications) NTT JRA PAT (1997) (2400 Baud version) (J) baud rates seem to be 2400,1200 (see ROM 03:8910) (and "AT%B" strings) uses standard AT-commands (ATI0, ATS0?, ATD, ATX1, etc.) supports AMD FLASH only there are two ROM versions (SHVC-TJAJ-0 and SHVC-TJBJ-0) NTT JRA PAT - Wide Baken Taiyou (1999) (9600 Baud version) (J) baud rates seem to be 9600,2400,1200 (see ROM 03:87F0) (and "AT%B" strings) uses standard AT-commands (ATI0, ATS0?, ATD, ATX1, etc.) supports AMD/ATMEL/SHARP FLASH there are two ROM versions (SHVC-TJDJ-0 and SHVC-TJEJ-0) Zaitaku Touhyou System - SPAT4-Wide (1999 or so) unknown, reportedly also horse betting with NTT modem there is one ROM version (SHVC-TOBJ-0) There is no special "modem-hardware" entry in cartridge header, but: note that all NTT/SFC modem BIOS have special "SHVC-Txxx-x" game codes. SNES Add-On Voice-Kun (IR-transmitter/receiver for use with CD Players) ----------------------------------------------------------------------- The Voice-Kun (sometimes called Voicer-Kun) from Koei is an Infrared transmitter/receiver. The transmitter part is used for controlling Audio CD Players (ie. to select and play tracks from Audio CDs that are included with supported games). The receiver part is used to "learn" IR-signals from different Remote Control manufacturers. Controller Bits The existing games expect the IR-unit connected to Port 2 (and a Joypad or Mouse in Port 1). The controller ID can be read via 4017h.Bit0 (serially, with STB/CLK signals). The actual IR-data is transferred via 4017h.Bit1/4201h.Bit7 (directly, without STB/CLK signals). 4017h.Bit0: 1st-12th Unknown/unused (probably always 0=High?) 13th-16th ID Bits 3-0 (MSB First, 0=High=Zero) (always 0Dh) 17th and up Unknown/unused (probably always whatever?) 4017h.Bit1: any bits Infrared level (receiver) (0=High=Off, 1=Low=On) 4201h.Bit7: any bits Infrared level (transmit) (0=Low=Off, 1=High=On) Required Buttons [ ] Stop [|>} Play [||] Pause [<<] Previous Track [>>] Next Track 0..9 Numeric Digits +10 Plus 10 ;\alternately either one of these >10 Two-Digit-Input ;/can be selected during configuration The sequence for entering 2-digit Track numbers may vary greatly (+10, or >10 or -/-- buttons, to be pressed before or after the low-digits), and, unknown if the Phillips "Toggle-Bit" is supported (needed for selecting track 11,22,33,etc. So far, one may expect problems with some CD players (though, as workaround, maybe the japanese GUI of the Voice-Kun games allows to select the starting track manually?). Low Level Signals Logical ________--------------------________--------------------________ Physical ________||||||||||||||||||||________||||||||||||||||||||________ The Voice-Kun hardware is automatically modulating/demodulating the transmitted/received signals, so the SNES software does only need to deal with "Logical" signals. Voice-Kun Games Angelique Voice Fantasy (29 Mar 1996) EMIT Vol. 1 - Toki no Maigo (25 Mar 1995) EMIT Vol. 2 - Inochigake no Tabi (25 Mar 1995) EMIT Vol. 3 - Watashi ni Sayonara wo (25 Mar 1995) EMIT Value Set (EMIT Vol. 1-3) (15 Dec 1995) Note - Soundware Koei also made a number of "Soundware" games (mostly for other consoles/computers), which did also include Audio CDs or Audio Tapes. For the SNES, Koei did release "Super Sangokushi II", originally on 15/09/1991, and re-released on 30 Mar 1995, at least one of that two releases (unclear which one) has been reportedly available with "Soundware" - unknown if that soundware version is Voice-Kun compatible, or (if it isn't compatible) unknown how else it was intended to be used...?) SNES 3D Glasses --------------- SNES 3D Games (there's only one known game) Jim Power: The Lost Dimension in 3-D (1993) (Loriciel) (Pulfrich Effect) Common 3D Glasses Most common glasses would be red/cyan lens (as used on NES) or glasses with LCD shutters (as used on Famicom). Neither of that types appears to be used on SNES though. Pulfrich Effect 3D Glasses (US) (dark/clear glasses) (aka Nuoptix) Another approach is using the Pulfrich effect with dark/clear glasses, this is some sort psychophysical stuff, related to different signal timings for bright/dark colors. Right Eye -- Clear ;\as so for SNES Jim Power: The Lost Dimension in 3-D) Left Eye -- Dark ;/(that is, opposite as for NES Orb-3D) The advantage is that it's cheap, and that it can be even used for colored images (unlike the red/cyan glasses method). The disadvantage is that it does work only with permanently moving objects. SNES Cartridges --------------- General Cartridge Info --> SNES Cartridge ROM Header --> SNES Cartridge PCBs --> SNES Cartridge ROM-Image Headers and File Extensions --> SNES Cartridge ROM-Image Interleave --> SNES Cartridge CIC Lockout Chip --> SNES Cartridge Slot Pinouts Basic Mapping Schemes --> SNES Cart LoROM Mapping (ROM divided into 32K banks) (around 1500 games) --> SNES Cart HiROM Mapping (ROM divided into 64K banks) (around 500 games) Cartridges with External Programmable CPUs --> SNES Cart SA-1 (programmable 65C816 CPU) (aka Super Accelerator) (35 games) --> SNES Cart GSU-n (programmable RISC CPU) (aka Super FX/Mario Chip) (10 games) --> SNES Cart Capcom CX4 (programmable RISC CPU) (Mega Man X 2-3) (2 games) Cartridges with External Pre-Programmed CPUs --> SNES Cart DSP-n/ST010/ST011 (pre-programmed NEC uPD77C25 CPU) (23 games) --> SNES Cart Seta ST018 (pre-programmed ARM CPU) (1 game) Cartridges with other custom chips --> SNES Cart OBC1 (OBJ Controller) (1 game) --> SNES Cart S-DD1 (Data Decompressor) (2 games) --> SNES Cart SPC7110 (Data Decompressor) (3 games) --> SNES Cart Unlicensed Variants Cartridges with Real-Time Clocks --> SNES Cart S-RTC (Realtime Clock) (1 game) --> SNES Cart SPC7110 with RTC-4513 Real Time Clock (1 game) Moreover, the Satellaview has a time function (allowing to receive the time via satellite dish). And, there are S-3520 (Seiko RTC's) in the Super Famicom Box and in the Nintendo Super System. Special Non-game Cartridges/Expansions --> SNES Cart Super Gameboy --> SNES Cart Satellaview (satellite receiver & mini flashcard) --> SNES Cart Data Pack Slots (satellaview-like mini-cartridge slot) --> SNES Cart Nintendo Power (flashcard) --> SNES Cart Sufami Turbo (Mini Cartridge Adaptor) --> SNES Cart X-Band (2400 baud Modem) --> SNES Cart FLASH Backup --> SNES Cart Cheat Devices --> SNES Cart Tri-Star (aka Super 8) (allows to play NES games on the SNES) --> SNES Cart Pirate X-in-1 Multicarts (1) --> SNES Cart Pirate X-in-1 Multicarts (2) --> SNES Cart Copiers --> SNES Cart CDROM Drive SNES Cartridge ROM Header ------------------------- The Cartridge header is mapped to 00FFxxh in SNES memory (near the exception vectors). In ROM-images it is found at offset 007Fxxh (LoROM), 00FFxxh (HiROM), or 40FFxxh (ExHiROM); add +200h to that offsets if "(imagesize AND 3FFh)=200h", ie. if there's an extra header from SWC/UFO/etc. copiers. Cartridge Header (Area FFC0h..FFCFh) FFC0h Cartridge title (21 bytes, uppercase ascii, padded with spaces) FFC0h First byte of title (or 5Ch far-jump-opcode in Pirate X-in-1 Carts) FFD4h Last byte of title (or 00h indicating Early Extended Header) FFD5h Rom Makeup / ROM Speed and Map Mode (see below) FFD6h Chipset (ROM/RAM information on cart) (see below) FFD7h ROM size (1 SHL n) Kbytes (usually 8=256KByte .. 0Ch=4MByte) Values are rounded-up for carts with 10,12,20,24 Mbits FFD8h RAM size (1 SHL n) Kbytes (usually 1=2Kbyte .. 5=32Kbyte) (0=None) FFD9h Country (also implies PAL/NTSC) (see below) FFDAh Developer ID code (00h=None/Homebrew, 01h=Nintendo, etc.) (33h=New) FFDBh ROM Version number (00h=First) FFDCh Checksum complement (same as below, XORed with FFFFh) FFDEh Checksum (all bytes in ROM added together; assume [FFDC-F]=FF,FF,0,0) Extended Header (Area FFB0h..FFBFh) (newer carts only) Early Extended Header (1993) (when [FFD4h]=00h; Last byte of Title=00h): FFB0h Reserved (15 zero bytes) Later Extended Header (1994) (when [FFDAh]=33h; Old Maker Code=33h): FFB0h Maker Code (2-letter ASCII, eg. "01"=Nintendo) FFB2h Game Code (4-letter ASCII) (or old 2-letter padded with 20h,20h) FFB6h Reserved (6 zero bytes) FFBCh Expansion FLASH Size (1 SHL n) Kbytes (used in JRA PAT) FFBDh Expansion RAM Size (1 SHL n) Kbytes (in GSUn games) (without battery?) FFBEh Special Version (usually zero) (eg. promotional version) Both Early and Later Extended Headers: FFBFh Chipset Sub-type (usually zero) (used when [FFD6h]=Fxh) Note: The early-extension is used only with ST010/11 games. If the first letter of the 4-letter Game Code is "Z", then the cartridge does have Satellaview-like Data Pack/FLASH cartridge slot (this applies ONLY to "Zxxx" 4-letter codes, not to old "Zx " space padded 2-letter codes). Cartridge Header Variants The BS-X Satellaview FLASH Card Files, and Sufami Turbo Mini-Cartridges are using similar looking (but not fully identical) headers (and usually the same .SMC file extension) than normal ROM cartridges. Detecting the content of .SMC files can be done by examining ID Strings (Sufami Turbo), or differently calculated checksum values (Satellaview). For details, see: --> SNES Cart Satellaview (satellite receiver & mini flashcard) --> SNES Cart Sufami Turbo (Mini Cartridge Adaptor) Homebrew games (and copiers & cheat devices) are usually having several errors in the cartridge header (usually no checksum, zero-padded title, etc), they should (hopefully) contain valid entryoints in range 8000h..FFFEh. Many Copiers are using 8Kbyte ROM bank(s) - in that special case the exception vectors are located at offset 1Fxxh within the ROM-image. CPU Exception Vectors (Area FFE0h..FFFFh) FFE0h Zerofilled (or ID "XBOO" for WRAM-Boot compatible files) FFE4h COP vector (65C816 mode) (COP opcode) FFE6h BRK vector (65C816 mode) (BRK opcode) FFE8h ABORT vector (65C816 mode) (not used in SNES) FFEAh NMI vector (65C816 mode) (SNES V-Blank Interrupt) FFECh ... FFEEh IRQ vector (65C816 mode) (SNES H/V-Timer or External Interrupt) FFF0h ... FFF4h COP vector (6502 mode) FFF6h ... FFF8h ABORT vector (6502 mode) (not used in SNES) FFFAh NMI vector (6502 mode) FFFCh RESET vector (6502 mode) (CPU is always in 6502 mode on RESET) FFFEh IRQ/BRK vector (6502 mode) Note: Exception Vectors are variable in SA-1 and CX4, and fixed in GSU. Text Fields The ASCII fields can use chr(20h..7Eh), actually they are JIS (with Yen instead backslash). ROM Size / Checksum Notes The ROM size is specified as "(1 SHL n) Kbytes", however, some cartridges contain "odd" sizes: * Game uses 2-3 ROM chips (eg. one 8MBit plus one 2MBit chip) * Game originally designed for 2 ROMs, but later manufactured as 1 ROM (?) * Game uses a single 24MBit chip (23C2401) In all three cases the ROM Size entry in [FFD7h] is rounded-up. In memory, the "bigger half" is mapped to address 0, followed by the "smaller half", then followed by mirror(s) of the smaller half. Eg. a 10MBit game would be rounded to 16MBit, and mapped (and checksummed) as "8Mbit + 4x2Mbit". In practice: Title Hardware Size Checksum Dai Kaiju Monogatari 2 (J) ExHiROM+S-RTC 5MB 4MB + 4 x Last 1MB Tales of Phantasia (J) ExHiROM 6MB Star Ocean (J) LoROM+S-DD1 6MB 4MB + 2 x Last 2MB Far East of Eden Zero (J) HiROM+SPC7110+RTC 5MB 5MB Momotaro Dentetsu Happy (J) HiROM+SPC7110 3MB 2 x 3MB Sufami Turbo BIOS LoROM in Minicart xx without checksum Sufami Turbo Games LoROM in Minicart xx without checksum Dragon Ball Z - Hyper Dimension LoROM+SA-1 3MB Overdump 4MB SD Gundam GNext (J) LoROM+SA-1 1.5MB Overdump 2MB Megaman X2 LoROM+CX4 1.5MB Overdump 2MB BS Super Mahjong Taikai (J) BS Overdump/Mirr+Empty Demon's Crest... reportedly 12MBit ? but, that's bullshit ? SPC7110 Title ROM Size (Header value) Checksum Super Power League 4 2MB (rounded to 2MB) 1x(All 2MB) Momotaro Dentetsu Happy (J) 3MB (rounded to 4MB) 2x(All 3MB) Far East of Eden Zero (J) 5MB (rounded to 8MB) 1x(All 5MB) On-chip ROM contained in external CPUs (DSPn,ST01n,CX4) is NOT counted in the ROM size entry, and not included in the checksum. Homebrew files often contain 0000h,0000h or FFFFh,0000h as checksum value. ROM Speed and Map Mode (FFD5h) Bit7-6 Always 0 Bit5 Always 1 (maybe meant to be MSB of bit4, for "2" and "3" MHz) Bit4 Speed (0=Slow, 1=Fast) (Slow 200ns, Fast 120ns) Bit3-0 Map Mode Map Mode can be: 0=LoROM/32K Banks Mode 20 (LoROM) 1=HiROM/64K Banks Mode 21 (HiROM) 2=LoROM/32K Banks + S-DD1 Mode 22 (mappable) "Super MMC" 3=LoROM/32K Banks + SA-1 Mode 23 (mappable) "Emulates Super MMC" 5=HiROM/64K Banks Mode 25 (ExHiROM) A=HiROM/64K Banks + SPC7110 Mode 25? (mappable) Note: ExHiROM is used only by "Dai Kaiju Monogatari 2 (JP)" and "Tales of Phantasia (JP)". Chipset (ROM/RAM information on cart) (FFD6h) (and some subclassed via FFBFh) 00h ROM 01h ROM+RAM 02h ROM+RAM+Battery x3h ROM+Co-processor x4h ROM+Co-processor+RAM x5h ROM+Co-processor+RAM+Battery x6h ROM+Co-processor+Battery x9h ROM+Co-processor+RAM+Battery+RTC-4513 xAh ROM+Co-processor+RAM+Battery+overclocked GSU1 ? (Stunt Race) x2h Same as x5h, used in "F1 Grand Prix Sample (J)" (?) 0xh Co-processor is DSP (DSP1,DSP1A,DSP1B,DSP2,DSP3,DSP4) 1xh Co-processor is GSU (MarioChip1,GSU1,GSU2,GSU2-SP1) 2xh Co-processor is OBC1 3xh Co-processor is SA-1 4xh Co-processor is S-DD1 5xh Co-processor is S-RTC Exh Co-processor is Other (Super Gameboy/Satellaview) Fxh.xxh Co-processor is Custom (subclassed via [FFBFh]=xxh) Fxh.00h Co-processor is Custom (SPC7110) Fxh.01h Co-processor is Custom (ST010/ST011) Fxh.02h Co-processor is Custom (ST018) Fxh.10h Co-processor is Custom (CX4) In practice, following values are used: 00h ROM ;if gamecode="042J" --> ROM+SGB2 01h ROM+RAM (if any such produced?) 02h ROM+RAM+Battery ;if gamecode="XBND" --> ROM+RAM+Batt+XBandModem ;if gamecode="MENU" --> ROM+RAM+Batt+Nintendo Power 03h ROM+DSP 04h ROM+DSP+RAM (no such produced) 05h ROM+DSP+RAM+Battery 13h ROM+MarioChip1/ExpansionRAM (and "hacked version of OBC1") 14h ROM+GSU+RAM ;\ROM size up to 1MByte -> GSU1 15h ROM+GSU+RAM+Battery ;/ROM size above 1MByte -> GSU2 1Ah ROM+GSU1+RAM+Battery+Fast Mode? (Stunt Race) 25h ROM+OBC1+RAM+Battery 32h ROM+SA1+RAM+Battery (?) "F1 Grand Prix Sample (J)" 34h ROM+SA1+RAM (?) "Dragon Ball Z - Hyper Dimension" 35h ROM+SA1+RAM+Battery 43h ROM+S-DD1 45h ROM+S-DD1+RAM+Battery 55h ROM+S-RTC+RAM+Battery E3h ROM+Super Gameboy (SGB) E5h ROM+Satellaview BIOS (BS-X) F5h.00h ROM+Custom+RAM+Battery (SPC7110) F9h.00h ROM+Custom+RAM+Battery+RTC (SPC7110+RTC) F6h.01h ROM+Custom+Battery (ST010/ST011) F5h.02h ROM+Custom+RAM+Battery (ST018) F3h.10h ROM+Custom (CX4) Country (also implies PAL/NTSC) (FFD9h) 00h - International (eg. SGB) (any) 00h J Japan (NTSC) 01h E USA and Canada (NTSC) 02h P Europe, Oceania, Asia (PAL) 03h W Sweden/Scandinavia (PAL) 04h - Finland (PAL) 05h - Denmark (PAL) 06h F France (SECAM, PAL-like 50Hz) 07h H Holland (PAL) 08h S Spain (PAL) 09h D Germany, Austria, Switz (PAL) 0Ah I Italy (PAL) 0Bh C China, Hong Kong (PAL) 0Ch - Indonesia (PAL) 0Dh K South Korea (NTSC) (North Korea would be PAL) 0Eh A Common (?) (?) 0Fh N Canada (NTSC) 10h B Brazil (PAL-M, NTSC-like 60Hz) 11h U Australia (PAL) 12h X Other variation (?) 13h Y Other variation (?) 14h Z Other variation (?) Above shows the [FFD9h] value, and the last letter of 4-character game codes. Game Codes (FFB2h, exists only when [FFDAh]=33h) "xxxx" Normal 4-letter code (usually "Axxx") (or "Bxxx" for newer codes) "xx " Old 2-letter code (space padded) "042J" Super Gameboy 2 "MENU" Nintendo Power FLASH Cartridge Menu "Txxx" NTT JRA-PAT and SPAT4 (SFC Modem BIOSes) "XBND" X-Band Modem BIOS "Zxxx" Special Cartridge with satellaview-like Data Pack Slot The last letter indicates the region (see Country/FFD9h description) (except in 2-letter codes and "MENU"/"XBND" codes). SNES Cartridge PCBs ------------------- Cartridge PCB Naming (eg. SHVC-XXXX-NN) Prefix SHVC Normal cartridge (japan, usa, europe) SNSP Special PAL version (for SA1 and S-DD1 with built-in CIC) BSC BIOS (or game cartridge) with external Satellaview FLASH cartridge slot MAXI Majesco Sales Inc cartridge (Assembled in Mexico) MJSC Majesco Sales Inc cartridge (Assembled in Mexico) WEI Whatever? (Assembled in Mexico) EA Electronics Arts cartridge First Character 1 One ROM chip (usually 36pin, sometimes 32pin) Y Two 4Mbit ROM chips (controlled by 74LS00) 2 Two 8Mbit ROM chips (controlled by 74LS00,MAD-1,etc.) B Two 16Mbit ROM chips (controlled by 74LS00 or MAD-1) L Two 32Mbit ROM chips (controlled by SPC7110F,S-DD1 or MAD-1) 3 Three 8Mbit ROM chips (controlled by 74LS139) (decoder/demultiplexer) 4 Four ROM chips (used only for 4PVnn/4QW EPROM prototype boards) 8 Eight ROM chips (used only for 8PVnn/8Xnn EPROM prototype boards) Second Character(s) A LoRom (A15 / Pin40 not connected to ROM) (uh, 1A3B-20 ?) B LoRom plus DSP-N chip C LoRom plus Mario Chip 1 62pin (and 36pin ROM) (no X1) CA LoRom plus GSU-1 62pin (and 32pin ROM) CB LoRom plus GSU-2 or GSU-2-SP1 62pin (and 40pin ROM) DC LoRom plus CX4 62pin (and 32pin ROMs) DH HiRom plus SPC7110F 62pin (and 32pin+44pin ROMs) DE LoRom plus ST018 62pin (and 32..40pin ROM possible) DS LoRom plus ST010/ST011 62pin (and 32..36pin ROM possible) E LoRom plus OBC1 chip 62pin (and 32pin ROMs) J HiRom (A15 / Pin40 is connected to ROM) K HiRom plus DSP-N chip L LoRom plus SA1 chip 62pin (and 44pin ROM) (16bit data?) N LoRom plus S-DD1 chip 62pin (and 44pin ROM) P LoRom with 2 prototype EPROMs (=unlike ROM A16..Ahi,/CS) PV WhateverRom with 4 prototype EPROMs (=unlike ROM A16..Ahi,/CS) Q WhateverRom prototype (see book2.pdf) QW WhateverRom prototype (see book2.pdf) RA LoRom plus GSU1A with prototype EPROMs (=unlike ROM A16..Ahi,/CS) 62pin X WhateverRom prototype (see book2.pdf) Third Character 0 No SRAM 1 2Kx8 SRAM (usually narrow 24pin DIP, sometimes wide 24pin DIP) 2 prototype variable size SRAM 3 8Kx8 SRAM (usually wide 28pin DIP) 5 32Kx8 SRAM (usually wide 28pin DIP) 6 64Kx8 SRAM (32pin SMD, found on boards with GSU) 8 64Kx8 SRAM (in one SA1 cart) (seems to be a 64Kx8 chip, not 256Kx8) Forth Character N No battery B Battery (with Transistor+Diodes or MM1026/MM1134 chip) M Battery (with MAD-1 chip; or with rare MAD-R chip) X Battery (with MAD-2 chip; maybe amplifies X1 oscillator for DSP1B chips) C Battery and RTC-4513 R Battery and S-RTC F FLASH Memory (instead of SRAM) (used by JRA-PAT and SPAT4) Fifth Characters (only if cart contains RAM that is NOT battery-backed) 5S 32Kx8 SRAM (for use by GSU, not battery backed) 6S 64Kx8 SRAM (for use by GSU, not battery backed) 7S 64Kx8 or 128Kx8 SRAM (for use by GSU, not battery backed) 9P 512Kx8 PSRAM (32pin 658512LFP-85) (for satellaview) (the black-blob Star Fox PCB also contains RAM, but lacks the ending "nS") Suffix -NN revision number (unknown if this indicates any relevant changes) Other Cartridge PCBs (that don't follow the above naming system) CPU2 SGB-R-10 Super Gameboy (1994) SHVC-MMS-X1 Nintendo Power FLASH Cartridge (1997) (older version) SHVC-MMS-02 Nintendo Power FLASH Cartridge (1997) (newer version) SHVC-MMSA-1 Nintendo Power FLASH Cartridge (19xx) ??? SHVC-SGB2-01 Super Gameboy 2 (1998) SHVC-1C0N Star Fox (black blob version) (PCB name lacks ending nS-NN) SHVC TURBO Sufami Turbo BASE CASSETTE (Bandai) Sufami Turbo game cartridges 123-0002-16 X-Band Modem (1995 by Catapult / licensed by Nintendo) BSMC-AF-01 Satellaview Mini FLASH Cartridge (plugged into BIOS cartridge) BSMC-CR-01 Satellaview Mini FLASH Cartridge (???) (not rewriteable ?) GPC-RAMC-4M SRAM Cartridge (without ROM)? GPC-RAMC-S1 SRAM Cartridge (without ROM)? GS 0871-102 Super Famicom Box multi-game cartridge NSS-01-ROM-A Nintendo Super System (NSS) cartridge NSS-01-ROM-B Nintendo Super System (NSS) cartridge NSS-01-ROM-C Nintendo Super System (NSS) cartridge NSS-X1-ROM-C Rebadged NSS-01-ROM-C board (plus battery/sram installed) RB-01, K-PE1-945-01 SNES CD Super Disc BIOS Cartridge (prototype) ROM Chips used in SNES cartridges 2Mbit 256Kbyte LH532 TC532 N-2001 (2nd chip/2A0N) (+SGB) (+Sufami) 4Mbit 512Kbyte 23C401 LH534 TC534 HN623n4 HN623x5 23C4001 LH5S4 CAT534 CXK384 8Mbit 1Mbyte 23C801 LH538 TC538 HN623n8 23C8001 TC23C8003 CAT548 16Mbit 2Mbyte 23C1601 LH537 LHMN7 TC5316 M5316 24Mbit 3Mbyte 23C2401 (seen on SHVC-1J3M board) 32Mbit 4Mbyte 23C3201 LH535 LHMN5 M5332 23C3202/40pin/SA1 N-32000/44pin/DD1 DIP vs SMD vs Blobs Most SNES carts are using DIP chips. SMD chips are used only in carts with coprocessors (except S-RTC, DSP-n, ST01n). Black blobs are found in several pirate carts (and in Star Fox, which contains Nintendo's Mario Chip 1, so it's apparently not a pirate cart). SNES Cartridge ROM-Image Headers and File Extensions ---------------------------------------------------- Below file headers are dated back to back-up units, which allowed to load ROM-images from 1.44MB floppy disks into RAM, larger images have been split into "multi files". Many of these files do have 512-byte headers. The headers don't contain any useful information. So, if they are present: Just ignore them. Best way to detect them is: "IF (filesize AND 3FFh)=200h THEN HeaderPresent=True" (Headerless cartridges are always sized N*1024 bytes, Carts with header are N*1024+512 bytes). .SMC - Super MagiCom (by Front Far East) This extension is often used for ANY type of SNES ROM-images, including for SWC files. .SWC - Super Wild Card (SWC) Header (by Front Far East) 000h-001h ROM Size (in 8Kbyte units) 002h Program execution mode Bit Expl. 7 Entrypoint (0=Normal/Reset Vector, 1=JMP 8000h) 6 Multi File (0=Normal/Last file, 1=Further file(s) follow) 5 SRAM mapping (0=mode20, 1=mode21) 4 Program mapping (0=mode20, 1=mode21) 3-2 SRAM Size (0=32Kbytes, 1=8Kbytes, 2=2Kbytes, 3=None) 1 Reserved (zero) 0 Unknown (seems to be randomly set to 0 or 1) 003h Reserved (zero) (but, set to 01h in homebrew "Pacman" and "Nuke") 004h-007h Reserved (zero) 008h-009h SWC File ID (AAh, BBh) 00Ah File Type (04h=Program ROM, 05h=Battery SRAM, 08h=real-time save) 00Bh-1FFh Reserved (zero) .FIG - Pro Fighter (FIG) header format (by China Coach Ltd) 000h-001h ROM Size (in 8Kbyte units) 002h Multi File (00h=Normal/Last file, 40h=Further file(s) follow) (02h=Whatever, used in homebrew Miracle,Eagle,Cen-Dem) 003h ROM Mode (00h=LoROM, 80h=HiROM) 004h-005h DSP1/SRAM Mode (8377h=ROM, 8347h=ROM+DSP1, 82FDh=ROM+DSP1+SRAM) 006h-1FFh Reserved (zero) (or garbage at 01FCh in homebrew Darkness Demo) .BIN - Raw Binary Contains a raw ROM-image without separate file header. .078 - Game Doctor file name format (by Bung) Contains a raw ROM-image without separate file header. Information about multi files is encoded in the "SFxxyyyz.078" filenames. SF Abbreviation for Super Famicom xx Image size in Mbit (2,4,8,16,32) (1-2 chars, WITHOUT leading zero) yyy Game catalogue number (or random number if unknown) z Indicates multi file (A=first, B=second, etc.) 078 File extension (should be usually 078) .MGD - Multi Game Doctor ? (by Bung) Format Unknown? Another Game Doctor version... 000h-00Fh ID "GAME DOCTOR SF 3" 010h Unknown (80h) ;-SRAM size limit 011h Unknown (20h) ;\ 012h Unknown (21h) ; DRAM mapping related 013h-018h Unknown (6x60h) ; 019h Unknown (20h) ; 01Ah Unknown (21h) ; 01Bh-028h Unknown (14x60h) ;/ 029h-02Ah Zero ;-SRAM mapping related 011h-020h 512Kbyte DRAM chunk, mapped to upper 32Kbyte of Bank 0xh-Fxh 021h-024h 512Kbyte DRAM chunk, mapped to lower 32Kbyte of Bank 4xh-7xh 025h-028h 512Kbyte DRAM chunk, mapped to lower 32Kbyte of Bank Cxh-Fxh 029h-02Ah SRAM Flags (bit0-15 = Enable SRAM at 6000-7000 in banks 0xh-Fxh) 02Bh-1FFh Zero (Reserved) Superufo 000h Unknown (20h or 40h) ;maybe ROM size in 8K units ? 001h-007h Zero 008h-00Fh ID "SUPERUFO" 010h Unknown (01h) 011h Unknown (02h or 04h) ;maybe rom speed ? 012h Unknown (E1h or F1h) ;MSB=chipset (Exh or Fxh) ? 013h Unknown (00h) 014h Unknown (01h) 015h Unknown (03h) 016h Unknown (00h) 017h Unknown (03h) 018h-1FFh Zero .SFC - Nintendo Developer File (Nintendo) Contains a raw ROM-image without separate file header. Information about multi files is encoded in the "NnnnVv-N.SFC" filenames. Nnnn Game code (4 letters) Vv ROM Version N Disk Number (0=First) SFC Fixed extension (Super FamiCom) This is how Nintendo wanted developers to name their files. NSRT Header (can be generated by Nach's NSRT tool) This format stores some additional information in a formerly unused 32-byte area near the end of the 512-byte copier headers. 1D0h Unknown/unspecified (LSB=01h..03h, MSB=00h..0Dh) ;maybe ROM mapping 1D1h Unknown/unspecified ;maybe title and/or NSRT version 1E8h ID1 "NSRT" 1ECh ID2 16h (22 decimal) 1EDh Controllers (MSB=Port1, LSB=Port2) 1EEh Checksum (sum of bytes at [1D0h..1EDh]+FFh) 1EFh Checksum Complement (Checksum XOR FFh) Controller Values: 00h Gamepad 01h Mouse 02h Mouse or Gamepad 03h Super Scope 04h Super Scope or Gamepad 05h Justifier 06h Multitap 07h Mouse, Super Scope, or Gamepad 08h Mouse or Multitap 09h Lasabirdie 0Ah Barcode Battler 0Bh..0Fh Reserved Most copiers also include a parallel PC port interface, allowing your PC to control the unit and store images on your hard drive. Copier's contain DRAM from 1 Megabyte to 16 Megabytes, 8MegaBits to 128MegaBits respectively. This is the reason why they are so expensive. SNES Cartridge ROM-Image Interleave ----------------------------------- Some ROM images are "interleaved", meaning that their content is ordered differently as how it appears in SNES memory. The interleaved format dates back to old copiers, most modern tools use/prefer normal ROM-images without interleave, but old interleaved files may still show up here and there. Interleave used by Game Doctor & UFO Copiers These copiers use interleave so that the ROM Header is always stored at file offset 007Fxxh. For HiROM files, interleave is applied as so: store upper 32K of all 64K banks, followed by lower 32K of all 64K banks (which moves the header from 00FFxxh to 007Fxxh). For example, with a 320Kbyte ROM, the ten 32K banks would be ordered as so: 0,1,2,3,4,5,6,7,8,9 - Original 1,3,5,7,9,0,2,4,6,8 - Interleaved For LoROM files, there's no interleave applied (since the header is already at 007Fxxh). Detecting an interleaved file could be done as so: Header must be located at file offset 007Fxxh (ie. in LoROM fashion) Header must not be a Sufami Turbo header (=title "ADD-ON BASE CASSETE") Header must not be a Satellaview header (=different chksum algorithm) Header should not contain corrupted entries The "Map Mode" byte at "[007FD5h] ANDed with 0Fh" is 01h,05h,0Ah (=HiROM) If so, the file is interleaved (or, possibly, it's having a corrupted header with wrong map mode setting). Interleave used by Human Stupidity There are interleaving & deinterleaving tools, intended to convert normal ROM-images to/from the format used by above copiers. Using that tools on files that are already in the desired format will result in messed-up garbage. For example, interleaving a 320Kbyte file that was already interleaved: 1,3,5,7,9,0,2,4,6,8 - Interleaved 3,7,0,4,8,1,5,9,2,6 - Double-Interleaved Or, trying to deinterleave a 320Kbyte file that wasn't interleaved: 0,1,2,3,4,5,6,7,8,9 - Original 5,0,6,1,7,2,8,3,9,4 - Mis-de-interleaved One can eventually repair such files by doing the opposite (de-)interleaving action. Or, in worst case, the user may repeat the wrong action, ending up with a Triple-Interleaved, or Double-mis-de-interleaved file. Another case of stupidity would be applying interleave to a LoROM file (which would move the header 007Fxxh towards the middle of the file, ie. the opposite of the intended interleaving effect of moving it 007Fxxh). ExHiROM Files ExHiROM Files are also having the data ordered differently as in SNES memory. However, in this special case, the data SHOULD be ordered as so. The ordering is: Fast HiROM (4Mbytes, banks C0h..FFh), followed by Slow HiROM banks (usually 1-2MByte, banks 40h..4Fh/5Fh) (of which, the header and exception vectors are in upper 32K of the first Slow HiROM bank, ie. at file offset 40FFxxh). There are only 2 games using the ExHiROM format: Dai Kaiju Monogatari 2 (JP) (5Mbytes) PCB: SHVC-LJ3R-01 Tales of Phantasia (JP) (6Mbytes) PCB: SHVC-LJ3M-01 The ExHiROM ordering is somewhat "official" as it was defined in Nintendo's developer manuals. Concerning software, the ordering does match-up with the checksum calculation algorithm (8MB chksum across 4MB plus mirror(s) of remaining 1-2MB). Concerning hardware, the ordering may have been 'required' in case Nintendo did (or planned to) use "odd" sized 5Mbyte/6Mbyte-chips (they DID produce cartridges with 3MByte/24Mbit chips). SNES Cartridge CIC Lockout Chip ------------------------------- SNES cartridges are required to contain a CIC chip (security chip aka lockout chip). The CIC is a small 4bit CPU with built-in ROM. An identical CIC is located in the SNES console. The same 4bit CPU (but with slightly different code in ROM) is also used in NES consoles/cartridges. The CIC in the console is acting as "lock", and that in the cartridge is acting as "key". The two chips are sending random-like bitstreams to each other, if the data (or transmission timing) doesn't match the expected values, then the "lock" issues a RESET signal to the console. Thereby rejecting cartridges without CIC chip (or such with CICs for wrong regions). CIC Details --> SNES Cartridge CIC Pseudo Code --> SNES Cartridge CIC Instruction Set --> SNES Cartridge CIC Notes --> SNES Cartridge CIC Versions --> SNES Pinouts CIC Chips CIC Disable --> SNES Common Mods SNES Cartridge CIC Pseudo Code ------------------------------ CicMain CicInitFirst, CicInitTiming, CicRandomSeed, CicInitStreams time=data_start, a=1, noswap=1, if snes then noswap=0 mainloop: for x=a to 0Fh if nes then Wait(time-5), else if snes then (time-7) ;\verify idle if (nes_6113=0) and (P0.0=1 or P0.1=1) then Shutdown ;/ Wait(time+0) ;\ if (console xor snes) then a=[00h+x].0, else a=[10h+x].0 ; output data if noswap then P0.0=a, else P0.1=a ;/ Wait(time+2-data_rx_error) ;\ if (console xor snes) then a=[10h+x].0, else a=[00h+x].0 ; verify input if noswap then a=(a xor P0.1), else a=(a xor P0.0) ; if a=1 then Shutdown ;/ Wait(time+3) ;\output idle if noswap then P0.0=0, else P0.1=0 ;/ if snes then time=time+92, else if nes then time=time+79 next x CicMangle(00h), CicMangle(10h) ;\mangle if snes then CicMangle(00h), CicMangle(10h) ; (thrice on SNES) if snes then CicMangle(00h), CicMangle(10h) ;/ if snes then noswap=[17h].0 ;eventually swap input/output pins (SNES only) a=[17h] if a=0 then a=1, time=time+2 if snes then time=time+44, else if nes then time=time+29 goto mainloop CicMangle(buf) for i=[buf+0Fh]+1 downto 1 a=[buf+2]+[buf+3h]+1 if a<10h then x=[buf+3], [buf+3]=a, a=x, x=1, else x=0 [buf+3+x]=[buf+3+x]+a for a=x+6 to 0Fh, [buf+a]=[buf+a]+[buf+a-1]+1, next a a=[buf+4+x]+8, if a<10h then [buf+5+x]=[buf+5+x]+a, else [buf+5+x]=a [buf+4+x]=[buf+4+x]+[buf+3+x] [buf+1]=[buf+1]+i [buf+2]=NOT([buf+2]+[buf+1]+1) time=time+84-(x*6) next i Note: All values in [buf] are 4bit wide (aka ANDed with 0Fh). CicInitFirst timer=0 ;reset timer (since reset released) P0=00h console=P0.3 ;get console/cartridge flag if console while P0.2=1, r=r+1 ;get 4bit random seed (capacitor charge time) P1.1=1, P1.1=0 ;issue reset to CIC in cartridge timer=0 ;reset timer (since reset released) if nes_6113 and (console=1) Wait(3), nes_6113_in_console=1, P0.0=1 ;request special 6113 mode if nes_6113 and (console=0) Wait(6), nes_6113_in_console=P0.1 ;check if 6113 mode requested CicRandomSeed time=seed_start for i=0 to 3 ;send/receive 4bit random seed (r) bit=((i+3) and 3) ;bit order is 3,0,1,2 (!) if console=1 Wait(time+0+i*15), P0.0=r.bit, Wait(time+3+i*15), P0.0=0 ;send if console=0 Wait(time+2+i*15), r.bit=P0.1 ;recv next i CicInitStreams if snes if ntsc then x=9, else if pal then x=6 [01h..0Fh]=B,1,4,F,4,B,5,7,F,D,6,1,E,9,8 ;init stream from cartridge (!) [11h..1Fh]=r,x,A,1,8,5,F,1,1,E,1,0,D,E,C ;init stream from console (!) if nes_usa ;3193A [01h..0Fh]=1,9,5,2,F,8,2,7,1,9,8,1,1,1,5 ;init stream from console [11h..1Fh]=r,9,5,2,1,2,1,7,1,9,8,5,7,1,5 ;init stream from cartridge if nes_6113_in_console then overwrite [01h]=5 or so ??? ;special-case if nes_europe ;3195A [01h..0Fh]=F,7,B,E,F,8,2,7,D,7,8,E,E,1,5 ;init stream from console [11h..1Fh]=r,7,B,D,1,2,1,7,E,6,7,A,7,1,5 ;init stream from cartridge if nes_hongkong_asia ;3196A [01h..0Fh]=E,6,A,D,F,8,2,7,E,6,7,E,E,E,A ;init stream from console [11h..1Fh]=r,6,A,D,E,D,E,8,E,6,7,A,7,1,5 ;init stream from cartridge if nes_uk_italy_australia ;3197A [01h..0Fh]=3,5,8,9,3,7,2,8,8,6,8,5,E,E,B ;init stream from console [11h..1Fh]=r,7,9,A,A,1,6,8,5,8,9,1,5,1,7 ;init stream from cartridge if_nes_famicombox ;3198A (unknown) Note: In most cases, the PAL region changes are simply inverted or negated NTSC values (not/neg), except, one NES-EUR value, and most of the NES-UK values are somehow different. The rev-engineered NES-UK values may not match the exact original NES-UK values (but they should be working anyways). CicInitTiming if snes_d411 -> seed_start=630, data_start=817 ;snes/ntsc if snes_d413 -> (unknown?) (same as d411?) ;snes/pal if nes_3193 -> (seems to be same as nes_3195?) ;nes/usa (v1) if nes_3195 -> seed_start=32, data_start=200 ;nes/europe if nes_3196 -> (unknown?) ;nes/asia if nes_3197 -> (unknown?) ("burns five") ;nes/uk if nes_6113 -> seed_start=32, data_start=201 ;nes/usa (v2) if nes_6113_in_console -> seed_start=33, data_start=216 ;nes/special if nes_tengen -> seed_start=32, data_start=201 ;nes/cic-clone ;now timing errors... data_rx_error=0 ;default if console=0 and nes_3193a -> randomly add 0 or 0.25 to seed_start/data_start if console=0 and snes_d413 -> always add 1.33 to seed_start/data_start (bug) if console=0 and nes_6113 -> data_rx_error=1 (and maybe +1.25 on seed/data?) if other_chips & chip_revisions -> (unknown?) Note: 3197 reportedly "burns five extra cycles before initialization", but unknown if that is relative to 3193 3195 timings, and unknown if it applies to seed_start and data_start, and unknown if it means 1MHz 4MHz cycles. Note: The "data_rx_error" looks totally wrong, but it is somewhat done intentionally, so there might be a purpose (maybe some rounding, in case 6113 and 3193 are off-sync by a half clock cycle, or maybe an improper bugfix in case they are off-sync by 1 or more cycles). Wait(time) Wait until "timer=time", whereas "timer" runs at 1MHz (NES) or 1.024MHz (SNES). The "time" values are showing the of the I/O opcodes (ie. the I/O opcodes at "time-1"). Shutdown (should never happen, unless cartridge is missing or wrong region) a=0, if nes then time=830142, else if snes then time=1037682 endless_loop: ;timings here aren't 100.000% accurate if nes_3195 then time=xlat[P1/4]*174785 ;whereas, xlat[0..3]=(3,2,4,5) if (console=0) and (snes or nes_6113) then P0=03h, P1=01h if (console=1) then P1=a, Wait(timer+time), a=a xor 4 ;toggle reset on/off goto endless_loop SNES Cartridge CIC Instruction Set ---------------------------------- CIC Registers A 4bit Accumulator X 4bit General Purpose Register L 4bit Pointer Register (lower 4bit of 6bit HL) H 2bit Pointer Register (upper 2bit of 6bit HL) C 1bit Carry Flag (changed ONLY by "set/clr c", not by "add/adc" or so) PC 10bit Program Counter (3bit bank, plus 7bit polynomial counter) CIC Memory ROM 512x8bit (program ROM) (NES/EUR=768x8) (max 1024x8 addressable) RAM 32x4bit (data RAM) (max 64x4 addressable) STACK 4x10bit (stack for call/ret opcodes) PORTS 4x4bit (external I/O ports & internal RAM-like ports) (max 16x4) Newer CIC Opcodes (6113, D411) (and probably F411,D413,F413) 00 nop no operation (aka "addsk A,0" opcode) 00+n addsk A,n add, A=A+n, skip if result>0Fh 10+n cmpsk A,n compare, skip if A=n 20+n mov L,n set L=n 30+n mov A,n set A=n 40 mov A,[HL] set A=RAM[HL] 41 xchg A,[HL] exchange A <--> RAM[HL] 42 xchgsk A,[HL+] exchange A <--> RAM[HL], L=L+1, skip if result>0Fh 43 xchgsk A,[HL-] exchange A <--> RAM[HL], L=L-1, skip if result<00h 44 neg A negate, A=0-A ;(used by 6113 mode) 45 ? 46 out [L],A output, PORT[L]=A 47 out [L],0 output, PORT[L]=0 48 set C set carry, C=1 49 clr C reset carry, C=0 4A mov [HL],A set RAM[HL]=A 4B ? 4C ret return, pop PC from stack 4D retsk return, pop PC from stack, skip 4E+n ? 52 movsk A,[HL+] set A=RAM[HL], L=L+1, skip if result>0Fh 53 ? (guess: movsk A,[HL-]) 54 not A complement, A=A XOR 0Fh 55 in A,[L] input, A=PORT[L] 56 ? 57 xchg A,L exchange A <--> L 58+n ? 5C mov X,A set X=A 5D xchg X,A exchange X <--> A 5E ??? "SPECIAL MYSTERY INSTRUCTION" ;(used by 6113 mode) 5F ? 60+n testsk [HL].n skip if RAM[HL].Bit(n)=1 64+n testsk A.n skip if A.Bit(n)=1 68+n clr [HL].n set RAM[HL].Bit(n)=0 6C+n set [HL].n set RAM[HL].Bit(n)=1 70 add A,[HL] add, A=A+RAM[HL] 71 ? (guess: addsk A,[HL]) 72 adc A,[HL] add with carry, A=A+RAM[HL]+C 73 adcsk A,[HL] add with carry, A=A+RAM[HL]+C, skip if result>0Fh 74+n mov H,n set H=n ;2bit range, n=0..3 only (used: 0..1 only) 78+n mm jmp nmm long jump, PC=nmm 7C+n mm call nmm long call, push PC+2, PC=nmm 80+nn jmp nn short jump, PC=(PC AND 380h)+nn - reset PC=000h Note: "skip" means "do not execute next instruction" Older CIC Opcodes (3195) (and probably 3193,3196,3197,etc.) Exchanged opcodes 48 <--> 49 (set/clr C) Exchanged opcodes 44 <--> 54 (neg/not A) ROM Size is 768x8 (although only 512x8 are actually used) Note The CIC is a 4bit Sharp CPU (maybe a Sharp SM4, but no datasheet exists) (the instruction seems to be an older version of that in the Sharp SM5K1..SM5K7 datasheets). SNES Cartridge CIC Notes ------------------------ Program Counter (PC) The 10bit PC register consists of a 3bit bank (which gets changed only by call/jmp/ret opcodes), and a 7bit polynomial counter (ie. not a linear counter). After fetching opcode bytes, PC is "incremented" as so: PC = (PC AND 380h) + (PC.Bit0 XOR PC.Bit1)*40h + (PC AND 7Eh)/2 Ie. the lower 7bit will "increment" through 127 different values (and wrap to 00h thereafter). Address 7Fh is unused (unless one issues a JMP 7Fh opcode, which would cause the CPU to hang on that address). Format <------------- Valid Address Area ----------> <--Stuck--> Linear 00 01 02 03 04 05 06 07 08 09 0A ... 7C 7D 7E or 7F 7F 7F 7F Polynomial 00 40 60 70 78 7C 7E 3F 5F 6F 77 ... 05 02 01 or 7F 7F 7F 7F To simplify things, programming tools like assemblers/disassemblers may use "normal" linear addresses (and translate linear/polynomial addressses when needed - the polynomial addresses are relevant only for encoding bits in jmp/call opcodes, and for how the data is physically arranged in the chip ROMs and in ROM-images). ROM-Images The existing ROM-images are .txt files, containing "0" and "1" BITS in ASCII format, arranged as a 64x64 (or 96x64) matrix (as seen in decapped chips). Line 1..32 ---> Address X+9Fh..80h ;\Lines (Y) Line 33..64 ---> Address X+1Fh..00h ;/ Column 1+(n*W) --> Data Bit(n) of Address 000h+Y ;\ ;\ Column 2+(n*W) --> Data Bit(n) of Address 020h+Y ; ; Columns (X) Column 3+(n*W) --> Data Bit(n) of Address 040h+Y ; ; Column 4+(n*W) --> Data Bit(n) of Address 060h+Y ; ; chips with 200h-byte Column 5+(n*W) --> Data Bit(n) of Address 100h+Y ; ; (W=8) (64x64 bits) Column 6+(n*W) --> Data Bit(n) of Address 120h+Y ; ; Column 7+(n*W) --> Data Bit(n) of Address 140h+Y ; ; Column 8+(n*W) --> Data Bit(n) of Address 160h+Y ; ;/ Column 9+(n*W) --> Data Bit(n) of Address 200h+Y ; Column 10+(n*W) --> Data Bit(n) of Address 220h+Y ; chips with 300h-byte Column 11+(n*W) --> Data Bit(n) of Address 240h+Y ; (W=12) (96x64 bits) Column 12+(n*W) --> Data Bit(n) of Address 260h+Y ;/ Cautions: The bits are inverted (0=1, 1=0) in some (not all) dumps. Mind that the bytes are arranged in non-linear polynomial fashion (see PC register). Recommended format for binary ROM-images would be to undo the inversion (if present), and to maintain the polynomial byte-order. Note: Known decapped/dumped CICs are D411 and 3195A, and... somebody decapped/dumped a CIC without writing down its part number (probably=6113). CIC Timings The NES CICs are driven by a 4.000MHz CIC oscillator (located in the console, and divided by 4 in the NES CIC). The SNES CICs are driven by the 24.576MHz APU oscillator (located and divided by 8 in the console's audio circuit, and further divided by 3 in the SNES CIC) (exception are older SNES mainboards, which are having a separate 4.00MHz resonator, like the NES). Ie. internally, the CICs are clocked at 1.000MHz (NES) or 1.024MHz (SNES). All opcodes are executed within 1 clock cycles, except for the 2-byte long jumps (opcodes 78h-7Fh) which take 2 clock cycles. The "skip" opcodes are forcing the following opcode to be executed as a "nop" (ie. the skipped opcode still takes 1 clock cycle; or possibly 2 cycles when skipping long jump opcodes, in case the CPU supports skipping 2-byte opcodes at all). After Reset gets released, the CICs execute the first opcode after a short delay (3195A: randomly 1.0 or 1.25 cycles, D413A: constantly 1.33 cycles) (whereas, portions of that delay may rely on a poorly falling edge of the incoming Reset signal). CIC Ports Name Pin Dir Expl P0.0 1 Out Data Out ;\SNES version occassionally swaps these P0.1 2 In Data In ;/pins by software (ie. Pin1=In, Pin2=Out) P0.2 3 In Random Seed (0=Charged/Ready, 1=Charging/Busy) P0.3 4 In Lock/Key (0=Cartridge/Key, 1=Console/Lock) P1.0 9 Out Reset SNES (0=Reset Console, 1=No) P1.1 10 Out Reset Key (0=No, 1=Reset Key) P1.2 11 In Unused, or Reset Speed A (in 3195A) ;\blink speed of reset P1.3 12 In Unused, or Reset Speed B (in 3195A) ;/signal (and Power LED) P2.0 13 - Unused P2.1 14 - Unused P2.2 15 - Unused P2.3 - - Unused P3.0 - RAM Unused, or used as "noswap" flag (in SNES CIC) P3.1 - - Unused P3.2 - - Unused P3.3 - - Unused P0.0-P2.2 are 11 external I/O lines (probably all bidirectional, above directions just indicates how they are normally used). P2.3-P3.3 are 5 internal bits (which seem to be useable as "RAM"). Pin numbers are for 16pin NES/SNES DIP chips (Pin numbers on 18pin SNES SMD chips are slightly rearranged). P4,P5,P6,P7,P8,P9,PA,PB,PC,PD,PF are unknown/unused (maybe 12x4 further bits, or mirrors of P0..P3). CIC Stream Seeds There are different seeds used for different regions. And, confusingly, there is a NES-CIC clone made Tengen, which uses different seeds than the real CIC (some of the differences automatically compensated when summing up values, eg. 8+8 gives same 4bit result as 0+0, other differences are manually adjusted by Tengen's program code). Many of the reverse-engineered NES seeds found in the internet are based on the Tengen design (the USA-seeds extracted from the decapped Tengen chip, the EUR/ASIA/UK-seeds based on sampled Nintendo-CIC data-streams, and then converted to a Tengen-compatible seed format). To convert them to real CIC seeds: Nintendo[1..F] = Tengen[1..F] - (2,0,0,0,0,0,8,8,8,8,8,8,8,8,2) There are other (working) variations possible, for example: Nintendo[1..F] = Tengen[1..F] - (2,0,0,0,0,A,E,8,8,8,8,8,8,8,2) (That, for Tengen-USA seeds. The Tengen-style-EUR/ASIA/UK seeds may differ) Whereas, the random seed in TengenKEY[1] is meant to be "r+2" (so subtracting 2 restores "r"). CIC Stream Logs There are some stream logs with filename "XXXX-N.b" where XXXX is the chip name, and N is the random seed, and bytes in the file are as so: Byte 000h, bit0-7 = 1st-8th bit on Pin 1 (DTA.OUT on NES)(DTA.OUT/IN on SNES) Byte 001h, bit0-7 = 1st-8th bit on Pin 2 (DTA.IN on NES) (DTA.IN/OUT on SNES) Byte 002h, bit0-7 = 9th-16th bit on Pin 1 Byte 003h, bit0-7 = 9th-16th bit on Pin 2 etc. Caution: The "N" in the filename is taken as if the seed were transferred in order Bit 3,2,1,0 (actually it is Bit 3,0,1,2). Ie. file "3195-1.b" would refer to a NES-EUR-CIC with seed r=4. The signals in the files are sampled at 1MHz (ie. only each fourth 4MHz cycle). The 6113 Chip The 6113 chip was invented in 1987, and it replaced the 3193 chip in US/Canadian cartridges (while US/Canadian consoles kept using 3193 chips). When used in cartridges, the 6113 does usually "emulate" a 3193 chip. But, for whatever reason, it can do more: Console Cartridge Notes 3193 3193 Works (the "old" way) ;\used combinations 3193 6113 Works (the "new" way) ;/ 6113 6113 Works (special seed/timing) ;\ 6113 3193 Doesn't work ; not used as far as known 6113 ?? Might work (??=unknown chip) ;/ When used in consoles, the 6113 uses slightly different timings and seed values (and does request cartridges with 6113 chips to use the 6113-mode, too, rather than emulating the 3193). One guess: Maybe Nintendo originally used different CICs for NTSC regions (like 3193/3194 for USA/Canada/SouthKorea), and later combined them to one region (if so, all NES consoles in Canada or SouthKorea should contain 3194/6113 chips, unlike US consoles which have 3193 chips). 3195A Signals (NES, Europe) The I/O ports are HIGH (for Output "1"), or LOW-Z (for Output "0" or Input). Raising edges take circa 0.5us, falling edges take circa 3us. 4MHz Clock Units ............................... 1MHz Clock Units . . . . . . . . ___________ ;\Console+Cartridge Data Should-be __| |________________ ;/should be 3us High __________ ;\actually 2.5us High Data From Console __.' ''----.......____ ;/and 3us falling __________ ;\ Data From Cartridge __.' ''----.......____ ; either same as console or, delayed: __________ ; or 0.25us later Data From Cartridge ___.' ''----.......___ ;/ After Power-up, the Cartridge CIC does randomly start with good timing, or with all signals delayed by 0.25us. In other words, the Cartridge CIC executes the first opcode 1.0us or 1.25us (four or five 4MHz cycles) after Reset gets released. However, for some reason, pushing the Reset Button doesn't alter the timing, the random-decision occurs only on Power-up. D413A Signals (SNES, Europe) The D413A signals are looking strange. First, the software switches signals High for 3us, but the actual signals are 3.33us High. Second, the signals on one pin are constantly jumping back'n'forth by 1.33us (in relation to the other pin). 3.072MHz Clock Units ............................... 1.024MHz Clock Units . . . . . . . . . . ________ ;\Console+Cartridge Data Should-be ________| |_____________ ;/should be 3us High _________ ;\actually 3.33us high Data From/To Console ________| '--..._______ ;/and 2us falling _________ ;\ Data From/To Cart ____| '--...___________ ; 1.33us earlier or, delayed _________ ; or 1.33us later Data From/To Cart ____________| '--...___ ;/ The earlier/later effect occurs because the SNES CICs are occassionally reversing the data-direction of the pins. Ie. in practice, Data from Cartridge is constantly 1.33us LATER than from Console. Software-wise, the D411 (and probably D413A) is programmed as if the Cartridge CIC would start "immediately", but in practice, it starts 1.33us (four 3.072MHz cycles) after releasing Reset (that offset seems to be constant, unlike as on the 3195A where it randomly changes between 1.0us and 1.25us). SNES Cartridge CIC Versions --------------------------- NES CIC Versions 3193,3193A NES NTSC Cartridges and Consoles ;\USA,Canada 6113,6113A,6113B1 NES NTSC Cartridges (not consoles) ;/(and Korea?) 3194 Unknown/doesn't exist? 3195,3193A NES PAL Cartridges and Consoles "PAL-B";-Europe 3196(A?) NES PAL Cartridges and Consoles ;-Hong Kong,Asia 3197(A?) NES PAL Cartridges and Consoles "PAL-A";-UK,Italy,Australia 3198(A?) FamicomBox CIC Cartridges and Consoles ;\ 3199(A?) FamicomBox Coin Timer (not a CIC) ; Japan N/A Famicom Cartridges and Consoles ;/ RFC-CPU10 (?) NES R.O.B. robot (no CIC, but maybe a 4bit Sharp CPU, too?) SNES CIC Versions F411,F411A,F411B SNES NTSC Cartridges-with-SMD-Chipset and Consoles D411,D411A,D411B SNES NTSC Cartridges-with-DIP-Chipset F413,F413A,F413B SNES PAL Cartridges-with-SMD-Chipset and Consoles D413,D413A,D413B SNES PAL Cartridges-with-DIP-Chipset SA-1,S-DD1,MCC-BSC SNES Cartridges (coprocessors/mappers with on-chip CIC) NES CIC Clones 23C1033 337002 ;Tengen's 16pin "Rabbit" CIC clone 337006 ;Tengen's 40pin "RAMBO-1" mapper with built-in CIC clone 4051 7660 KC5373B MX8018 NINA Ciclone ;homebrew multi-region CIC clone (based on Tengen design) Aside from using cloned CICs, many unlicensed NES cartridges used a different approach: injecting "wrong" voltages to the console, and "stunning" its CIC. SNES CIC Clones 10198 - CIC clone noname - CIC clone (black chip without any part number) ST10198S - NTSC CIC clone ST10198P - PAL CIC clone 265111 - maybe also a CIC clone (used in Bung Game Doctor SF6) D1 - maybe also a CIC clone (used in Super UFO Pro8) 74LS112 - reportedly also a CIC clone (with fake part number) (UFO Pro6) CIVIC 74LS13 16pin - CIC/D411 clone (used in a 8-in-1 pirate cart) CIVIC CT6911 16pin - CIC clone (used in a 7-in-1 pirate cart) 93C26 16pin - CIC clone (used in a 8-in-1 pirate cart) D1 16pin - CIC? (used in Super VG pirate) STS9311A 52583 16pin - CIC clone (used in Donkey King Country 3 pirate) black blob 16pin - CIC/D411 clone (used in Sonic the Hedgehog pirate) CIC Chip Year/Week Date Codes Name YYWW-YYWW 3193 8539-8642 3193A 8547-8733 (in cartridges) (but should be in consoles for more years) 3195 8627-8638 3195A 8647-9512 3197A 8647-9227 6113 8734-8823 6113A 8823-8933 6113B1 8847-9344 SNES Cart LoROM Mapping (ROM divided into 32K banks) (around 1500 games) ------------------------------------------------------------------------ Plain LoROM Board Type ROM Area ROM Mirrors SHVC-1A0N-01,02,10,20,30 00-7D,80-FF:8000-FFFF 40-7D,C0-FF:0000-7FFF SHVC-2A0N-01,10,11,20 00-7D,80-FF:8000-FFFF 40-7D,C0-FF:0000-7FFF SHVC-BA0N-01,10 00-7D,80-FF:8000-FFFF 40-7D,C0-FF:0000-7FFF SHVC-YA0N-01 00-7D,80-FF:8000-FFFF 40-7D,C0-FF:0000-7FFF LoROM with SRAM Board Type ROM Area SRAM Area SHVC-1A1B-04,05,06 00-1F,80-9F:8000-FFFF 70-7D,F0-FF:0000-FFFF SHVC-1A3B-11,12,13 00-1F,80-9F:8000-FFFF 70-7D,F0-FF:0000-FFFF SHVC-1A5B-02,04 00-1F,80-9F:8000-FFFF 70-7D,F0-FF:0000-FFFF SHVC-2A3B-01 00-3F,80-BF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-2A3M-01 with MAD-R 00-3F,80-BF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-2A3M-01,11,20 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-1A3B-20 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-1A1M-01,11,20 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-2A1M-01 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-BA1M-01 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-1A3M-10,20,21,30 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-BA3M-01 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-1A5M-01,11,20 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-2A5M-01 00-7D,80-FF:8000-FFFF 70-7D,F0-FF:0000-7FFF SHVC-1A7M-01 ? ? Note that 2A3M-01 exists with/without MAD-R (and have different mappings). Note that 1A3B-20 differs from earlier 1A3B-xx versions. The older boards map SRAM to the whole 64K areas at banks 70h-7Dh/F0-FFh. The newer boards map SRAM to the lower 32K areas at banks 70h-7Dh/F0-FFh (this allows "BigLoROM" games to use the upper 32K of that banks as additional LoROM banks, which is required for games with more than 3MB LoROM). Most of the existing boards contain 0K, 2K, 8K, or 32K SRAM. A few games contail 64K or 128K SRAM, which is divided into 32K chunks, mapped to bank 70h, 71h, etc.) Some LoROM games are bigger than 2Mbytes (eg. Super Metroid, Gunple, Wizardry 6, Derby Stallion 3), these have bank 0-3Fh mapped in the 32K LoROM banks as usually, and bank 40h and up each mapped twice in the 64K hirom banks. Note: There's also a different "SpecialLoROM" mapping scheme for 3MByte ROMs (used by Derby Stallion 96 and Sound Novel Tsukuru; aside from the special ROM mapping, these cartridges have an additional Data Pack Slot). SNES Cart HiROM Mapping (ROM divided into 64K banks) (around 500 games) ----------------------------------------------------------------------- Plain HiROM Board ROM Area ROM Mirrors SRAM Area Type at 0000-FFFF at 8000-FFFF (none such) SHVC-BJ0N-01,20 40-7d,c0-ff 00-3f,80-bf N/A SHVC-YJ0N-01 40-7d,c0-ff 00-3f,80-bf N/A SHVC-1J0N-01,10,20 40-7d,c0-ff 00-3f,80-bf N/A SHVC-2J0N-01,10,11 40-7d,c0-ff 00-3f,80-bf N/A SHVC-3J0N-01 40-6f,c0-ef 00-2f,80-af N/A The SHVC-3J0N-01 board contains 3 ROM chips (memory is divided into chunks of 16 banks, with one ROM per chunk, and with each 4th chunk being left empty, ie. bank 30-3F,70-7D,B0-BF,F0-FF are open-bus). HiROM with SRAM Board ROM Area ROM Mirrors SRAM Area Type at 0000-FFFF at 8000-FFFF at 6000-7FFF SHVC-1J3B-01 40-7d,c0-ff 00-3f,80-bf 20-3f,a0-bf SHVC-1J1M-11,20 40-7d,c0-ff 00-3f,80-bf 20-3f,a0-bf SHVC-1J3M-01,11,20 40-7d,c0-ff 00-3f,80-bf 20-3f,a0-bf SHVC-BJ3M-10 40-7d,c0-ff 00-3f,80-bf 20-3f,a0-bf SHVC-1J5M-11,20 40-7d,c0-ff 00-3f,80-bf 20-3f,a0-bf SHVC-2J3M-01,11,20 40-7d,c0-ff 00-3f,80-bf 10-1f,30-3f,90-9f,b0-bf SHVC-2J5M-01 40-7d,c0-ff 00-3f,80-bf 10-1f,90-9f,30-3f,b0-bf SHVC-LJ3M-01 40-7d,c0-ff 00-3f,80-bf 80-bf The SHVC-LJ3M-01 board uses ExHiROM mapping (meaning that bank 00h-7Dh contain different ROM banks than 80h-FFh). SNES Cart SA-1 (programmable 65C816 CPU) (aka Super Accelerator) (35 games) --------------------------------------------------------------------------- --> SNES Cart SA-1 Games --> SNES Cart SA-1 I/O Map --> SNES Cart SA-1 Interrupt/Control on SNES Side --> SNES Cart SA-1 Interrupt/Control on SA-1 Side --> SNES Cart SA-1 Timer --> SNES Cart SA-1 Memory Control --> SNES Cart SA-1 DMA Transfers --> SNES Cart SA-1 Character Conversion --> SNES Cart SA-1 Arithmetic Maths --> SNES Cart SA-1 Variable-Length Bit Processing --> SNES Pinouts SA1 Chip Memory Map (SNES Side) 00h-3Fh/80h-BFh:2200h-23FFh I/O Ports 00h-3Fh/80h-BFh:3000h-37FFh I-RAM (2Kbytes, on-chip, 10MHz fast RAM) 00h-3Fh/80h-BFh:6000h-7FFFh One mappable 8Kbyte BW-RAM block 00h-3Fh/80h-BFh:8000h-FFFFh Four mappable 1MByte LoROM blocks (max 8Mbyte) 40h-4Fh:0000h-FFFFh Entire 256Kbyte BW-RAM (mirrors in 44h-4Fh) C0h-FFh:0000h-FFFFh Four mappable 1MByte HiROM blocks (max 8Mbyte) The SA-1 supports both LoROM and HiROM mappings (eg. LoROM banks 00h-01h mirror to HiROM bank 40h). Default exception vectors (and cartridge header) are always in LoROM bank 00h (ie. at ROM offset 7Fxxh). Memory Map (SA-1 Side) Same as on SNES Side (of course without access to SNES internal WRAM and I/O ports), plus following additional areas: 00h-3Fh/80h-BFh:0000h-07FFh I-RAM (at both 0000h-07FFh and 3000h-37FFh) 60h-6Fh:0000h-FFFFh BW-RAM mapped as 2bit or 4bit pixel buffer Some other differences to SNES Side are: I/O Ports are different, on SA-1 side, the mappable BW-RAM area (at 6000h-7FFFh) can be also assigned as 2bit/4bit pixel buffer (on SNES Side it's always normal 8bit memory). Misc 65C816 CPU at 10.74MHz 2Kbytes internal I-RAM (work ram/stack) (optionally battery backed) Optional external backup/work BW-RAM up to 2MByte (or rather only 2Mbit?) Addressable ROM up to 8MByte (64MBits) The SA-1 CPU can access memory at 10.74MHz rate (or less, if the SNES does simultaneouly access cartridge memory). The SNES CPU can access memory at 2.68MHz rate (or 3.5MHz, but that mode may not be used in combination with the SA-1). When interrupts are disabled (in CIE/SIE), then it sounds as if the interrupt flags still do get set? "BW-RAM cannot be used during character conversion DMA." IRQ/NMI/Reset vectors can be mapped. Other vectors (BRK/COP etc) are always taken from ROM (for BOTH CPUs). XXX pg 62..66 timings ok XXX pg 67..78 char/bitmap ok XXX pg 79..81 arit XXX pg 82..86 var-len ok XXX pg 87..90 dma SA-1 Pinouts 1-126 Unknown 127 PAL/NTSC (for CIC mode and/or HV-timer?) 128 Unknown SA-1 PCBs BSC-1L3B-01 NTSC SRAM Battery FLASH-Slot (Itoi Shig. no Bass Tsuri No.1) SHVC-1L0N3S-20 NTSC SRAM NoBattery (Dragon Ball Z Hyper Dimension) SHVC-1L3B-11 NTSC SRAM Battery SHVC-1L5B-10 NTSC SRAM Battery SHVC-1L5B-11 NTSC SRAM Battery SHVC-1L8B-10 NTSC SRAM Battery SNSP-1L0N3S-01 PAL SRAM NoBattery (Dragon Ball Z Hyper Dimension) SNSP-1L3B-20 PAL SRAM Battery The battery can be wired to I-RAM (on-chip SA-1 memory) or BW-RAM (aka SRAM) or both; unknown how it is wired in practice (probably to BW-RAM?). Chipset/Components U1 44pin ROM (probably with full 16bit databus connected) U2 28pin SRAM (LH52A64N-YL or LH52256ANZ or 32pin LH52A512NF) U3 128pin SA1 (SA1 RF5A123) U4 8pin Battery controller MM1026AF ;\only if PCB does include a battery BATT 2pin CR2032 ;/ CN1 62pin SNES cartridge edge-connector CN2 62pin Satellaview FLASH cartridge slot ;-only on BSC-boards SNES Cart SA-1 Games -------------------- SA1 - 128pin - Super Accelerator (book2) (10.74MHz 65C816 CPU) Used by 35 games: #Asahi Shinbun Rensai Kato Ichi-Ni-San Kudan Shogi Shingiru (1995) Varie (JP) Daisenryaku Expert WWII: War in Europe (1996) SystemSoftAlpha/ASCII Corp (JP) Derby Jockey 2 (1995) Muse Soft/Asmik (JP) Dragon Ball Z: Hyper Dimension (1996) TOSE/Bandai (JP) (EU) #Habu Meijin no Omoshiro Syouhi -Unverified (19xx) Hiroshi/etc. (JP) Itoi Shigesato no Bass Tsuri No. 1 (1997) HAL Laboratory/Nintendo (JP) J. League '96 Dream Stadium (1996) Hudson Soft (JP) Jikkyou Oshaberi Parodius (1995) Konami (JP) Jumpin' Derby (1996) Naxat Soft (JP) #Kakinoki Shogi (1995) ASCII Corporation (JP) Kirby Super Star (1996) HAL Laboratory/Nintendo (NA) (JP) (EU) Kirby's Dream Land 3 (1997) HAL Laboratory/Nintendo (NA) (JP) Marvelous: Mouhitotsu no Takarajima (1996) Nintendo/R&D2 (JP) Masoukishin: Super Robot Wars Gaiden: Lord of Elemental (19xx) Banpresto (JP) Masters New: Haruka Naru Augusta 3 (1995) T&E Soft (JP) Mini Yonku/4WD Shining Scorpion - Let's & Go!! (1996) KID/ASCII Corp (JP) Pachi Slot Monogatari PAL Kogyo Special -Unverified (1995) PAL/KSS (JP) Pebble Beach no Hotou: New Tournament Edition (1996) T&E Soft (JP) PGA European Tour (1996) Halestorm/THQ/Black Pearl Software (NA) PGA Tour '96 (1995) Black Pearl Software/Electronic Arts (NA) Power Rangers Zeo: Battle Racers (1996) Natsume/Bandai (NA) #Pro Kishi Simulation Kishi No Hanamichi (1996) Atlus (JP) xRin Kaihou 9 Dan No Igo Taidou -Unverified (1996) .. (JP) SD F-1 Grand Prix (and "Sample" version) (1995) Video System (JP) SD Gundam G NEXT (1995) BEC/Bandai (JP) #Shin Shogi/Syogi Club (1995) Hect/Natsu (JP) #Shogi Saikyou (1995) Magical Company (JP) (unverified?) #Shogi Saikyou 2 (1996) Magical Company (JP) #Shougi Mahjong (1995) Varie Corp (JP) Super Bomberman Panic Bomber World (1995) Hudson Soft (JP) Super Mario RPG: Legend of the Seven Stars (1996) Square/Nintendo (NA) (JP) Super Robot T.G.: The Lord Of Elemental (?) (1996) Winkysoft/Banpresto (JP) #Super Shogi 3 Kitaihei -Unverified (1995) I'Max (JP) xTaikyoku-Igo Idaten -Unverified (1995) BPS (JP) xTakemiya Masaki Kudan No Igo Taisyou -Unverified (1995) KSS (JP) The nine Shogi/Shougi/Syouhi/Kishi/Syogi titles are japanese Chess games, the three Igo titles are Go games; that 12 titles are mainly using the SA-1 CPU for calculating moves, without doing any impressive things with the SA-1 I/O ports. SNES Cart SA-1 I/O Map ---------------------- SA-1 I/O Map (Write Only Registers) Port Side Name Reset Expl. 2200h SNES CCNT 20h SA-1 CPU Control (W) 2201h SNES SIE 00h SNES CPU Int Enable (W) 2202h SNES SIC 00h SNES CPU Int Clear (W) 2203h SNES CRV - SA-1 CPU Reset Vector Lsb (W) 2204h SNES CRV - SA-1 CPU Reset Vector Msb (W) 2205h SNES CNV - SA-1 CPU NMI Vector Lsb (W) 2206h SNES CNV - SA-1 CPU NMI Vector Msb (W) 2207h SNES CIV - SA-1 CPU IRQ Vector Lsb (W) 2208h SNES CIV - SA-1 CPU IRQ Vector Msb (W) 2209h SA-1 SCNT 00h SNES CPU Control (W) 220Ah SA-1 CIE 00h SA-1 CPU Int Enable (W) 220Bh SA-1 CIC 00h SA-1 CPU Int Clear (W) 220Ch SA-1 SNV - SNES CPU NMI Vector Lsb (W) 220Dh SA-1 SNV - SNES CPU NMI Vector Msb (W) 220Eh SA-1 SIV - SNES CPU IRQ Vector Lsb (W) 220Fh SA-1 SIV - SNES CPU IRQ Vector Msb (W) 2210h SA-1 TMC 00h H/V Timer Control (W) 2211h SA-1 CTR - SA-1 CPU Timer Restart (W) 2212h SA-1 HCNT - Set H-Count Lsb (W) 2213h SA-1 HCNT - Set H-Count Msb (W) 2214h SA-1 VCNT - Set V-Count Lsb (W) 2215h SA-1 VCNT - Set V-Count Msb (W) 2216h - - - - 2220h SNES CXB 00h MMC Bank C - Hirom C0h-CFh / LoRom 00h-1Fh (W) 2221h SNES DXB 01h MMC Bank D - Hirom D0h-DFh / LoRom 20h-3Fh (W) 2222h SNES EXB 02h MMC Bank E - Hirom E0h-EFh / LoRom 80h-9Fh (W) 2223h SNES FXB 03h MMC Bank F - Hirom F0h-FFh / LoRom A0h-BFh (W) 2224h SNES BMAPS 00h SNES CPU BW-RAM Mapping to 6000h-7FFFh (W) 2225h SA-1 BMAP 00h SA-1 CPU BW-RAM Mapping to 6000h-7FFFh (W) 2226h SNES SBWE 00h SNES CPU BW-RAM Write Enable (W) 2227h SA-1 CBWE 00h SA-1 CPU BW-RAM Write Enable (W) 2228h SNES BWPA FFh BW-RAM Write-Protected Area (W) 2229h SNES SIWP 00h SNES I-RAM Write-Protection (W) 222Ah SA-1 CIWP 00h SA-1 I-RAM Write-Protection (W) 222Bh - - - - 2230h SA-1 DCNT 00h DMA Control (W) 2231h Both CDMA 00h Character Conversion DMA Parameters (W) 2232h Both SDA - DMA Source Device Start Address Lsb (W) 2233h Both SDA - DMA Source Device Start Address Mid (W) 2234h Both SDA - DMA Source Device Start Address Msb (W) 2235h Both DDA - DMA Dest Device Start Address Lsb (W) 2236h Both DDA - DMA Dest Device Start Address Mid (Start/I-RAM) (W) 2237h Both DDA - DMA Dest Device Start Address Msb (Start/BW-RAM)(W) 2238h SA-1 DTC - DMA Terminal Counter Lsb (W) 2239h SA-1 DTC - DMA Terminal Counter Msb (W) 223Ah - - - - 223Fh SA-1 BBF 00h BW-RAM Bit Map Format for 600000h-6FFFFFh (W) 224xh SA-1 BRF - Bit Map Register File (2240h..224Fh) (W) 2250h SA-1 MCNT 00h Arithmetic Control (W) 2251h SA-1 MA - Arithmetic Param A Lsb (Multiplicand/Dividend) (W) 2252h SA-1 MA - Arithmetic Param A Msb (Multiplicand/Dividend) (W) 2253h SA-1 MB - Arithmetic Param B Lsb (Multiplier/Divisor) (W) 2254h SA-1 MB - Arithmetic Param B Msb (Multiplier/Divisor)/Start (W) 2255h - - - - 2258h SA-1 VBD - Variable-Length Bit Processing (W) 2259h SA-1 VDA - Var-Length Bit Game Pak ROM Start Address Lsb (W) 225Ah SA-1 VDA - Var-Length Bit Game Pak ROM Start Address Mid (W) 225Bh SA-1 VDA - Var-Length Bit Game Pak ROM Start Address Msb & Kick 225Ch - - - - 2261h - - - Unknown/Undocumented (Jumpin Derby writes 00h) 2262h - - - Unknown/Undocumented (Super Bomberman writes 00h) SA-1 I/O Map (Read Only Registers) Port Side Name Reset Expl. 2300h SNES SFR SNES CPU Flag Read (R) 2301h SA-1 CFR SA-1 CPU Flag Read (R) 2302h SA-1 HCR H-Count Read Lsb / Do Latching (R) 2303h SA-1 HCR H-Count Read Msb (R) 2304h SA-1 VCR V-Count Read Lsb (R) 2305h SA-1 VCR V-Count Read Msb (R) 2306h SA-1 MR Arithmetic Result, bit0-7 (Sum/Product/Quotient) (R) 2307h SA-1 MR Arithmetic Result, bit8-15 (Sum/Product/Quotient) (R) 2308h SA-1 MR Arithmetic Result, bit16-23 (Sum/Product/Remainder) (R) 2309h SA-1 MR Arithmetic Result, bit24-31 (Sum/Product/Remainder) (R) 230Ah SA-1 MR Arithmetic Result, bit32-39 (Sum) (R) 230Bh SA-1 OF Arithmetic Overflow Flag (R) 230Ch SA-1 VDP Variable-Length Data Read Port Lsb (R) 230Dh SA-1 VDP Variable-Length Data Read Port Msb (R) 230Eh SNES VC Version Code Register (R) Reset Port 2200h = 20h. Port 2228h = FFh. Ports 2220h-2223h = 00h,01h,02h,03h. Ports 2201h-2202h, 2209h-220Bh, 2210h, 2224h-2227h, 2229h-222Ah, 2230h-2231h, 223Fh, 2250h = 00h. Ports 2203h-2208h, 220Ch-220Fh, 2211h-2215h, 2232h-2239h, 2240h-224Fh, 2251h-2254h, 2258h-225Bh = N/A. SNES Cart SA-1 Interrupt/Control on SNES Side --------------------------------------------- 2200h SNES CCNT - SA-1 CPU Control (W) 0-3 Message from SNES to SA-1 (4bit value) 4 NMI from SNES to SA-1 (0=No Change?, 1=Interrupt) 5 Reset from SNES to SA-1 (0=No Reset, 1=Reset) 6 Wait from SNES to SA-1 (0=No Wait, 1=Wait) 7 IRQ from SNES to SA-1 (0=No Change?, 1=Interrupt) Unknown if Wait freezes the whole SA1 (CPU, plus Timer and DMA?). Unknown if Reset resets any I/O Ports (such like DMA or interrupts) or if it does only reset the CPU? 2201h SNES SIE - SNES CPU Int Enable (W) 0-4 Not used (should be 0) 5 IRQ Enable (Character conversion DMA) (0=Disable, 1=Enable) 6 Not used (should be 0) 7 IRQ Enable (from SA-1) (0=Disable, 1=Enable) 2202h SNES SIC - SNES CPU Int Clear (W) 0-4 Not used (should be 0) 5 IRQ Acknowledge (Character conversion DMA) (0=No change, 1=Clear) 6 Not used (should be 0) 7 IRQ Acknowledge (from SA-1) (0=No change, 1=Clear) 2203h SNES CRV - SA-1 CPU Reset Vector Lsb (W) 2204h SNES CRV - SA-1 CPU Reset Vector Msb (W) 2205h SNES CNV - SA-1 CPU NMI Vector Lsb (W) 2206h SNES CNV - SA-1 CPU NMI Vector Msb (W) 2207h SNES CIV - SA-1 CPU IRQ Vector Lsb (W) 2208h SNES CIV - SA-1 CPU IRQ Vector Msb (W) Exception Vectors on SA-1 side (these are ALWAYS replacing the normal vectors in ROM). 2300h SNES SFR - SNES CPU Flag Read (R) 0-3 Message from SA-1 to SNES (4bit value) (same as 2209h.Bit0-3) 4 NMI Vector for SNES (0=ROM FFExh, 1=Port 220Ch) (same as 2209h.Bit4) 5 IRQ from Character Conversion DMA (0=None, 1=Interrupt) (ready-to-do-DMA) 6 IRQ Vector for SNES (0=ROM FFExh, 1=Port 220Eh) (same as 2209h.Bit6) 7 IRQ from SA-1 to SNES (0=None, 1=Interrupt) (triggered by 2209h.Bit7) Bit0-3,4,6 are same as in Port 2209h. Bit5 is set via ..DMA..? Bit7 is set via Port 2209h. Bit5,7 can be cleared via Port 2202h. 230Eh SNES VC - Version Code Register (R) 0-7 SA-1 Chip Version Existing value(s) are unknown. There seems to be only one chip version (labeled SA-1 RF5A123, used for both PAL and NTSC). The "VC" register isn't read by any games (except, accidently, by a bugged memcopy function at 059E92h in Derby Jockey 2). SNES Cart SA-1 Interrupt/Control on SA-1 Side --------------------------------------------- 2209h SA-1 SCNT - SNES CPU Control (W) 0-3 Message from SA-1 to SNES (4bit value) 4 NMI Vector for SNES (0=ROM FFEAh, 1=Port 220Ch) 5 Not used (should be 0) 6 IRQ Vector for SNES (0=ROM FFEEh, 1=Port 220Eh) 7 IRQ from SA-1 to SNES (0=No Change?, 1=Interrupt) 220Ah SA-1 CIE - SA-1 CPU Int Enable (W) 0-3 Not used (should be 0) 4 NMI Enable (from SNES) (0=Disable, 1=Enable) 5 IRQ Enable (from DMA) (0=Disable, 1=Enable) 6 IRQ Enable (from Timer) (0=Disable, 1=Enable) 7 IRQ Enable (from SNES) (0=Disable, 1=Enable) 220Bh SA-1 CIC - SA-1 CPU Int Clear (W) 0-3 Not used (should be 0) 4 NMI Acknowledge (from SNES) (0=No change, 1=Clear) 5 IRQ Acknowledge (from DMA) (0=No change, 1=Clear) 6 IRQ Acknowledge (from Timer) (0=No change, 1=Clear) 7 IRQ Acknowledge (from SNES) (0=No change, 1=Clear) 220Ch SA-1 SNV - SNES CPU NMI Vector Lsb (W) 220Dh SA-1 SNV - SNES CPU NMI Vector Msb (W) 220Eh SA-1 SIV - SNES CPU IRQ Vector Lsb (W) 220Fh SA-1 SIV - SNES CPU IRQ Vector Msb (W) Exception Vectors on SNES side (these are optionally replacing the normal vectors in ROM; depending on bits in Port 2209h; the "I/O" vectors are used only by Jumpin Derby, all other games are using the normal ROM vectors). 2301h SA-1 CFR - SA-1 CPU Flag Read (R) 0-3 Message from SNES to SA-1 (4bit value) (same as 2200h.Bit0-3) 4 NMI from SNES to SA-1 (0=No, 1=Interrupt) (triggered by 2200h.Bit4) 5 IRQ from DMA to SA-1 (0=No, 1=Interrupt) (triggered by DMA-finished) 6 IRQ from Timer to SA-1 (0=No, 1=Interrupt) (triggered by Timer) 7 IRQ from SNES to SA-1 (0=No, 1=Interrupt) (triggered by 2200h.Bit7) SNES Cart SA-1 Timer -------------------- 2210h SA-1 TMC - H/V Timer Control (W) 0 HEN ;\Enables Interrupt or so ? 1 VEN ;/ 2-6 Not used (should be 0) 7 Timer Mode (0=HV Timer, 1=Linear Timer) 2211h SA-1 CTR - SA-1 CPU Timer Restart (W) 0-7 Don't care (writing any value restarts the timer at 0) 2212h SA-1 HCNT - Set H-Count Lsb (W) 2213h SA-1 HCNT - Set H-Count Msb (W) 0-8 H-Counter (9bit) 9-15 Not used (should be 0) Ranges from 0-340 (in HV mode), or 0-511 (in Linear mode). 2214h SA-1 VCNT - Set V-Count Lsb (W) 2215h SA-1 VCNT - Set V-Count Msb (W) 0-8 V-Counter (9bit) 9-15 Not used (should be 0) Ranges from 0-261 (in HV/NTSC mode), 0-311 (in HV/PAL mode), or 0-511 (in Linear mode). The PAL/NTSC selection is probably done by a soldering point on the PCB (which is probably also used for switching the built-in CIC to PAL/NTSC mode). 2302h SA-1 HCR - H-Count Read Lsb / Do Latching (R) 2303h SA-1 HCR - H-Count Read Msb (R) 2304h SA-1 VCR - V-Count Read Lsb (R) 2305h SA-1 VCR - V-Count Read Msb (R) Reading from 2302h automatically latches the other HV-Counter bits to 2303h-2305h. Notes In HV-mode, the timer clock is obviously equivalent to the dotclock (four 21MHz master cycles per dot). The time clock in linear mode is unknown (probably same as in HV-mode). H-counter has 341 dots (one more as in SNES, but without long dots). Unknown if the short-scanline (in each 2nd NTSC non-interlaced frame) is reproduced (if it isn't, then one must periodically reset the timer in order to keep it in sync with the PPU). There is no provision for interlaced video timings. The meaning of Port 2212h-2215h is totally unknown (according to existing specs it as if they do set the counter value - though alltogether it'd be more likely that they do contain values). Unknown what happens when setting both HEN and VEN (probably IRQ triggers only if H+V do match, ie. similar as for the normal SNES timers). SNES Cart SA-1 Memory Control ----------------------------- 2220h SNES CXB - Set Super MMC Bank C - Hirom C0h-CFh / LoRom 00h-1Fh (W) 2221h SNES DXB - Set Super MMC Bank D - Hirom D0h-DFh / LoRom 20h-3Fh (W) 2222h SNES EXB - Set Super MMC Bank E - Hirom E0h-EFh / LoRom 80h-9Fh (W) 2223h SNES FXB - Set Super MMC Bank F - Hirom F0h-FFh / LoRom A0h-BFh (W) 0-2 Select 1Mbyte ROM-Bank (0..7) 3-6 Not used (should be 0) 7 Map 1Mbyte ROM-Bank (0=To HiRom, 1=To LoRom and HiRom) If LoRom mapping is disabled (bit7=0), then first 2 MByte of ROM are mapped to 00h-3Fh, and next 2 MByte to 80h-BFh. The registers do affect both SNES and SA-1 mapping. 2224h SNES BMAPS - SNES CPU BW-RAM Mapping to 6000h-7FFFh (W) 0-4 Select 8Kbyte BW-RAM Block for mapping to 6000h-7FFFh (0..31) 5-7 Not used (should be 0) BW-RAM is always mapped to bank 40h-43h (max 256 Kbytes). This register allows to map an 8Kbyte chunk to offset 6000h-7FFFh in bank 0-3Fh and 80h-BFh. 2225h SA-1 BMAP - SA-1 CPU BW-RAM Mapping to 6000h-7FFFh (W) 0-6 Select 8Kbyte BW-RAM Block for mapping to 6000h-7FFFh (0..31 or 0..127) 7 Select source (0=Normal/Bank 40h..43h, 1=Bitmap/Bank 60h..6Fh) 223Fh SA-1 BBF - BW-RAM Bit Map Format for 600000h-6FFFFFh (W) 0-6 Not used (should be "..") (whatever ".." means, maybe "0"?) 7 Format (0=4bit, 1=2bit) "BW-RAM bitmap logical space format setting from perspective of the SA-1 CPU" 600000h.Bit0-1 or Bit0-3 mirrors to 400000h.Bit0-1 or 400000h.Bit0-3 600001h.Bit0-1 or Bit0-3 mirrors to 400000h.Bit2-3 or 400000h.Bit4-7 600002h.Bit0-1 or Bit0-3 mirrors to 400000h.Bit4-5 or 400001h.Bit0-3 600003h.Bit0-1 or Bit0-3 mirrors to 400000h.Bit6-7 or 400001h.Bit4-7 etc. Note that the LSBs in the packed-area contain the left-most pixel (not the right-most one). The MSBs in the unpacked area are "ignored" (this is obvious in case of writing; for reading it's unknown what it means - are reads supported at all, and if so, do they return zero's or garbage in MSBs?) 2226h SNES SBWE - SNES CPU BW-RAM Write Enable (W) 2227h SA-1 SBWE - SA-1 CPU BW-RAM Write Enable (W) 0-6 Not used (should be 0) 7 Write Enable BW-RAM (0=Protect, 1=Write Enable) 2228h SNES BWPA - BW-RAM Write-Protected Area (W) 0-3 Select size of Write-Protected Area ("256 SHL N" bytes) 4-7 Not used (should be 0) Selects how many bytes (originated at 400000h) shall be write protected. It isn't possible to set the size to "none" (min is 256 bytes), though, one can probably completely disable the protection via ports 2226h/2227h? 2229h SNES SIWP - SNES I-RAM Write-Protection (W) 222Ah SA-1 CIWP - SA-1 I-RAM Write-Protection (W) 0-7 Write enable flags for eight 256-byte chunks (0=Protect, 1=Write Enable) Bit0 for I-RAM 3000h..30FFh, bit1 for 3100h..31FFh, etc. bit7 for 3700h..37FFh. SNES Cart SA-1 DMA Transfers ---------------------------- 2230h SA-1 DCNT - DMA Control (W) 0-1 DMA Source Device (0=ROM, 1=BW-RAM, 2=I-RAM, 3=Reserved);\for 2 DMA Destination Device (0=I-RAM, 1=BW-RAM) ;/Normal DMA 3 Not used (should be 0) 4 DMA Char Conversion Type (0=Type 2/Semi-Automatic, 1=Type 1/Automatic) 5 DMA Char Conversion Enable (0=Normal DMA, 1=Character Conversion DMA) 6 DMA Priority (0=SA-1 CPU Priority, 1=DMA Priority) ;<-- for Normal DMA 7 DMA Enable (0=Disable, 1=Enable... and Clear Parameters?) Bit6 is only valid for Normal DMA between BW-RAM and I-RAM. Source and Destination may not be the same devices (ie. no I-RAM to I-RAM, or BW-RAM to BW-RAM). 2231h Both CDMA - Character Conversion DMA Parameters (W) 0-1 Color Depth (0=8bit, 1=4bit, 2=2bit, 3=Reserved) 2-4 Virtual VRAM Width (0..5 = 1,2,4,8,16,32 characters) (6..7=Reserved) 5-6 Not used (should be 0) 7 Terminate Character Conversion 1 (0=No change, 1=Terminate DMA) 2232h Both SDA - DMA Source Device Start Address Lsb (W) 2233h Both SDA - DMA Source Device Start Address Mid (W) 2234h Both SDA - DMA Source Device Start Address Msb (W) 0-23 24bit Memory Address (translated to 23bit ROM Offset via 2220h..2223h) 0-17 18bit BW-RAM Offset 0-10 11bit I-RAM Offset Used bits are 24bit/18bit/11bit for ROM/BW-RAM/I-RAM. 2235h Both DDA - DMA Destination Device Start Address Lsb (W) 2236h Both DDA - DMA Destination Device Start Address Mid (Start/I-RAM) (W) 2237h Both DDA - DMA Destination Device Start Address Msb (Start/BW-RAM)(W) 0-17 BW-RAM Offset (transfer starts after writing 2237h) 0-10 I-RAM Offset (transfer starts after writing 2236h) (2237h is unused) 2238h SA-1 DTC - DMA Terminal Counter Lsb (W) 2239h SA-1 DTC - DMA Terminal Counter Msb (W) 0-15 DMA Transfer Length in bytes (1..65535) (0=Reserved/unknown) DTC is used only for Normal DMA (whilst Character Conversion DMA lasts endless; for Type 1: as long as SNES reads "BW-RAM" / until it sets 2231h.Bit7, for Type 2: as long as SA-1 writes BRF / until it clears 2230h.Bit0). 224xh SA-1 BRF - Bit Map Register File (2240h..224Fh) (W) These 16 registers can hold two 8 pixel rows (with 2bit/4bit/8bit per pixel). 0-1 2bit pixel (bit 2-7=unused) 0-3 4bit pixel (bit 4-7=unused) 0-7 8bit pixel Used only for (semi-automatic) Character Conversion Type 2, where the "DMA" source data is to be written pixel-by-pixel to these registers; writing to one 8 pixel row can be done while transferring the other row to the SNES. Normal DMA (memory transfer within cartridge memory) ROM --> I-RAM 10.74MHz ROM --> BW-RAM 5.37MHz BW-RAM --> I-RAM 5.37MHz I-RAM --> BW-RAM 5.37MHz For normal DMA: Set DCNT (select source/dest/prio/enable) Set SDA (set source offset) Set DTC (set transfer length) Set DDA (set destination offset, and start transfer) If desired, wait for CFR.Bit5 (DMA completion interrupt) Normal DMA is used by J. League '96, Jumpin Derby, Marvelous. For ROM, SDA should be usually C00000h and up (HiROM mapping); Jumpin Derby is unconventionally using SDA at 2x8xxxh and up (LoROM mapping). Character Conversion DMA Used to convert bitmaps or pixels to bit-planed tiles. For details, see --> SNES Cart SA-1 Character Conversion SNES DMA (via Port 43xxh) Can be used to transfer "normal" data from ROM/BW-RAM/I-RAM to SNES memory, also used for forwarding temporary Character Conversion data from I-RAM to SNES. Unknown details Unknown if SDA/DDA are increased and if DTC is decreased (or if that operations appear only on internal registers) (MSBs of DDA are apparently NOT increased on char conversion DMAs). SNES Cart SA-1 Character Conversion ----------------------------------- Character Conversion Types Conversion DMA-Transfer Source / Pixel-Format Type 1 Automatic BW-RAM, Packed Pixels, Bitmap Pixel Array Type 2 Semi-Automatic CPU, Unpacked Pixels, 8x8 Pixel Tiles Both Conversion types are writing data to a temporary buffer in I-RAM: I-RAM buffer 32/64/128 bytes (two 8x8 tiles at 2bit/4bit/8bit color depth) From that buffer, data is forwarded to SNES (via a simultanously executed SNES DMA, ie. via ports 43xxh). Character Conversion 1 - Automatically Convert Packed BW-RAM Pixels Can be used only if the cartridge DOES contain BW-RAM (most or all do so). First, do this on SA-1 side: Set DCNT (Port 2230h) set to Char Conversion Type 1 (...and no DMA-enable?) Then do following on SNES side: Set SDA (Port 2232h-2234h)=BW-RAM offset, align by (bytes/char)*(chars/line) Set CDMA (Port 2231h) = store bits/pixel and chars/line Set DDA (Port 2235h-2236h)=I-RAM offset, align (bytes/char)*2 (2237h=unused) Wait for SFR.Bit5 (Port 2300h) Char_DMA_IRQ (=first character available) Launch SNES-DMA via Port 43xxh from "Virtual BW-RAM?" to PPU-VRAM (this can transfer the WHOLE bitmap in one pass) Finally, after the SNES-DMA has finished, do this on SA-1 side: Set CDMA.Bit7=1 (Port 2231h) - terminate SA-1 DMA (that stops writing to I-RAM on SA-1 side) (and stops tile-data to be mapped to 400000h-43FFFFh on SNES-side) During conversion, the SA-1 can execute other program code (but waits may occur on BW-RAM and I-RAM accesses). The SNES CPU is paused (by the DMA) for most of the time, except for the time slots shortly before/after the DMA; in that time slots, the SNES may access I-RAM, but may not access BW-RAM. Conversion 1 is used by Haruka Naru Augusta 3 and Pebble Beach no Hotou. Character Conversion 2 - Semi-Automatic Convert Unpacked CPU Pixels First, do this on SA-1 side: Set DCNT (Port 2230h) set to Char Conversion Type 2 and set DMA-enable Set CDMA (Port 2231h) = store bits/pixel (chars/line is not used) Set DDA (Port 2235h-2236h)=I-RAM offset, align (bytes/char)*2 (2237h=unused) Then repeat for each character: for y=0 to 7, for x=0 to 7, [2240h+x+(y and 1)]=pixel(x,y), next x,y On SNES side: Transfer DMA from 1st/2nd I-RAM buffer half to VRAM or WRAM Finally, Set DCNT.Bit7=0 (Port 2230h) - disable DMA Conversion 2 is used by Haruka Naru Augusta 3 and SD Gundam G NEXT. SNES Cart SA-1 Arithmetic Maths ------------------------------- 2250h SA-1 MCNT - Arithmetic Control (W) 0-1 Arithmetic Mode (0=Multiply, 1=Divide, 2=MultiplySum, 3=Reserved) 2-7 Not used (should be "..") (whatever ".." means, maybe "0"?) Note: Writing Bit1=1 does reset the Sum (aka "Cumulative Sum" aka "Accumulative Sum") to zero. 2251h SA-1 MA - Arithmetic Parameter A Lsb (Multiplicand/Dividend) (W) 2252h SA-1 MA - Arithmetic Parameter A Msb (Multiplicand/Dividend) (W) 0-15 SIGNED multiplicand or dividend (that is, both are signed) The value in this register is kept intact after multiplaction, but gets destroyed after division. 2253h SA-1 MB - Arithmetic Parameter B Lsb (Multiplier/Divisor) (W) 2254h SA-1 MB - Arithmetic Parameter B Msb (Multiplier/Divisor)/Start (W) 0-15 SIGNED multiply parameter, or UNSIGNED divisor The value in this register gets destroyed after both multiplaction and division. Writing to 2254h starts the operation. Execution time is 5 cycles (in 10.74MHz units) for both Multiply and Divide, and 6 cycles for Multiply/Sum. 2306h SA-1 MR - Arithmetic Result, bit0-7 (Sum/Product/Quotient) (R) 2307h SA-1 MR - Arithmetic Result, bit8-15 (Sum/Product/Quotient) (R) 2308h SA-1 MR - Arithmetic Result, bit16-23 (Sum/Product/Remainder) (R) 2309h SA-1 MR - Arithmetic Result, bit24-31 (Sum/Product/Remainder) (R) 230Ah SA-1 MR - Arithmetic Result, bit32-39 (Sum) (R) 32bit Multiply Result (SIGNED) 40bit Multiply/Sum (SIGNED) 16bit Division Result (SIGNED) 16bit Division Remainder (UNSIGNED !!!) 230Bh SA-1 OF - Arithmetic Overflow Flag (R) This bit is reportedly set on 40bit multiply/addition overflows (rather than on more useful 32bit overflows), thereby overflow can't occur unless one is doing at least 512 continous multiply/additions. 0-6 Not used (reportedly "..") (whatever ".." means, maybe 0 or open bus?) 7 Arithmetic Sum Overflow Flag (0=No overflow, 1=Overflow) Unknown when this bit gets cleared (all operations, or mode changes)? Division by zero returns result=0000h and remainder=0000h (other info claims other values?) (but, as far as known, doesn't set set overflow flag). SNES Cart SA-1 Variable-Length Bit Processing --------------------------------------------- 2258h SA-1 VBD - Variable-Length Bit Processing (W) 0-3 Data Length (1..15=1..15 bits, or 0=16 bits) 4-6 Not used (should be "..") (whatever ".." means, maybe "0"?) 7 Data Read Mode (0=Fixed Mode, 1=Auto-increment) Manual/Fixed Mode is used by Jumpin Derby. Auto-increment isn't used by any known games. 2259h SA-1 VDA - Variable-Length Bit Game Pak ROM Start Address Lsb (W) 225Ah SA-1 VDA - Variable-Length Bit Game Pak ROM Start Address Mid (W) 225Bh SA-1 VDA - Variable-Length Bit Game Pak ROM Start Address Msb & Kick 0-23 Game Pak ROM Address Reading starts on writing to 225Bh. The ROM address is probably originated at 000000h (rather than using LoROM/HiROM like CPU addresses)? 230Ch SA-1 VDP - Variable-Length Data Read Port Lsb (R) 230Dh SA-1 VDP - Variable-Length Data Read Port Msb (R) 0-15 Data Unknown what happens on data length less than 16bits: Are the selected bits located in MSBs or LSBs? Are the other bits set to zero? To next/prev values? Sign-expanded?? There is an "auto-increment" feature, which may trigger on reading 230Ch? or on reading or 230Dh? ;*******PRELOAD: ;Preload occurs after writing VDA ; bitpos = [2259h]*8 ; [230Ch] = WORD[bitpos/8] ;*******INCREMENT: ;Increment occurs AFTER reading VDP (when auto-increment enabled), ;and after writing VDB (reportedly always, but SHOULD be ONLY when inc=off)? ; bitpos=bitpos+(([2258h]-1) AND 0Fh)+1 ; [230Ch] = dword[bitpos/16*2] shr (bitpos and 15) AND FFFFh SNES Cart GSU-n (programmable RISC CPU) (aka Super FX/Mario Chip) (10 games) ---------------------------------------------------------------------------- Graphic Support Unit (GSU) (10.74MHz RISC-like CPU) --> SNES Cart GSU-n List of Games, Chips, and PCB versions --> SNES Cart GSU-n Memory Map --> SNES Cart GSU-n I/O Map --> SNES Cart GSU-n General I/O Ports --> SNES Cart GSU-n Bitmap I/O Ports GSU Opcodes --> SNES Cart GSU-n CPU MOV Opcodes --> SNES Cart GSU-n CPU ALU Opcodes --> SNES Cart GSU-n CPU JMP and Prefix Opcodes --> SNES Cart GSU-n CPU Pseudo Opcodes Misc --> SNES Cart GSU-n CPU Misc GSU Caches --> SNES Cart GSU-n Code-Cache --> SNES Cart GSU-n Pixel-Cache --> SNES Cart GSU-n Other Caches Pinouts --> SNES Pinouts GSU Chips SNES Cart GSU-n List of Games, Chips, and PCB versions ------------------------------------------------------ GSU1/Mario Chip1 is used by six games: Dirt Racer (1994) MotiveTime/Elite Systems (EU) Dirt Trax FX (1995) Sculptured Software/Acclaim Entertainment (NA) Powerslide (cancelled, but unfinished prototype leaked) Elite Systems (EU) Star Fox / Starwing (1993) Argonaut/Nintendo EAD (NA) (JP) (EU) Star Fox / Starwing: Competition Edition (demo version) (1993) (NA) (EU) Stunt Race FX / Wild Trax (1994) Argonaut/Nintendo EAD (NA) (JP) (EU) Vortex (1994) Argonaut Games/Electro Brain (NA), Pack-In-Video (JP) GSU2/GSU2-SP1 is used by four games: Doom (1996) Sculptured Software/Williams (NA), Imagineer (JP), Ocean (EU) Super Mario World 2: Yoshi's Island (1995) Nintendo EAD (NA) (JP) (EU) Winter Gold / FX Skiing (1997) Funcom/Nintendo (NA) (EU) Star Fox 2 (cancelled, but near-finished Beta version leaked into internet) Reportedly, there have been another three GSU2 games planned: FX Fighter (Beta) (cancelled) Argonaut Games/GTE Entertainment (NA) (EU) Comanche (cancelled) Nova Logic (NA) Super Mario FX (cancelled) Nintendo EAD GSU Chip Versions MC1 - 100pin - A/N Inc. Nintendo Mario Chip 1 (reportedly "FX-chip 1") GSU1 - 100pin - A/N Inc. Nintendo Super FX 1 (10.74MHz RISC-like CPU) GSU1A - 100pin - A/N Inc. Nintendo Super FX 1 GSU2 - 112pin - A/N Inc. Nintendo Super FX 2 (as above, but 21MHz) GSU2-SP1 - 112pin - A/N Inc. Nintendo Super FX 2 (as above, but 21MHz) XXX according to MotZilla, GSU1 supports 21MHz, too? (but with less memory) GSU PCB Versions SHVC-1C0N Mario Chip 1 Star Fox (Blob) SHVC-1C0N5S-01 Mario Chip 1 Star Fox (SMD) SHVC-1CA0N5S-01 GSU-1 Dirt Racer & Vortex SHVC-1CA0N6S-01 GSU-1 Dirt Trax FX SHVC-1CA6B-01 GSU-1 Battery Stunt Race FX SHVC-1CB0N7S-01 GSU-2 Doom SHVC-1CB5B-01 GSU-2 Battery Super Mario World 2: Yoshi's Island SHVC-1CB5B-20 GSU-2-SP1 Battery Super Mario World 2: Yoshi's Island SHVC-1RA2B6S-01 GSU1A Batt+Eprom Powerslide (prototype board) GS 0871-102 Mario Chip 1 Super Famicom Box PSS61 multi-game-cart Note: Doom's "1CB0N7S" board has only 64K RAM installed (not 128K). SNES Cart GSU-n Memory Map -------------------------- MC1 Memory Map (at SNES Side) 00-3F/80-BF:3000-347F GSU I/O Ports 00-1F/80-9F:8000-FFFF Game Pak ROM in LoRom mapping (1Mbyte max) 60-7D/E0-FF:0000-FFFF Game Pak RAM with mirrors (64Kbyte max?, usually 32K) Other Addresses Open Bus GSU1 Memory Map (at SNES Side) 00-3F/80-BF:3000-34FF? GSU I/O Ports 00-3F/80-BF:6000-7FFF Mirror of 70:0000-1FFF (ie. FIRST 8K of Game Pak RAM) 00-3F/80-BF:8000-FFFF Game Pak ROM in LoRom mapping (1Mbyte max?) 40-5F/C0-DF:0000-FFFF Game Pak ROM in HiRom mapping (mirror of above) 70-71/F0-F1:0000-FFFF Game Pak RAM with mirrors (64Kbyte max?, usually 32K) 78-7x/F8-Fx:0000-FFFF Unknown (maybe Additional "Backup" RAM like GSU2) Other Addresses Open Bus GSU2 Memory Map (at SNES Side) 00-3F/80-BF:3000-34FF GSU I/O Ports 00-3F/80-BF:6000-7FFF Mirror of 70:0000-1FFF (ie. FIRST 8K of Game Pak RAM) 00-3F:8000-FFFF Game Pak ROM in LoRom mapping (2Mbyte max) 40-5F:0000-FFFF Game Pak ROM in HiRom mapping (mirror of above) 70-71:0000-FFFF Game Pak RAM (128Kbyte max, usually 32K or 64K) 78-79:0000-FFFF Additional "Backup" RAM (128Kbyte max, usually none) 80-BF:8000-FFFF Additional "CPU" ROM LoROM (2Mbyte max, usually none) C0-FF:0000-FFFF Additional "CPU" ROM HiROM (4Mbyte max, usually none) Other Addresses Open Bus For HiROM mapping the address bits are shifted, so both LoROM and HiROM are linear (eg. Bank 40h contains mirrors of Bank 00h and 01h). Although both LoROM and HiROM are supported, the header & exception vectors are located at ROM Offset 7Fxxh (in LoROM fashion), accordingly the cartridge header declares the cartridge as LoROM. The additional ROM/RAM regions would be mapped to SNES CPU only (not to GSU), they aren't installed in existing cartridges, that implies that the "Fast" ROM banks (80h-FFh) are unused, so GSU games are restricted to "Slow" ROM. GSU2 Memory Map (at GSU Side) 00-3F:0000-7FFF Mirror of LoROM at 00-3F:8000-FFFF (for "GETB R15" vectors) 00-3F:8000-FFFF Game Pak ROM in LoRom mapping (2Mbyte max) 40-5F:0000-FFFF Game Pak ROM in HiRom mapping (mirror of above 2Mbyte) 70-71:0000-FFFF Game Pak RAM (128Kbyte max, usually 32K or 64K) PBR:0000-01FF Code-Cache (when having manually stored opcodes in it) PBR can be set to both ROM/RAM regions (or cache region), ROMBR only to ROM region (00h-5Fh), RAMBR only to RAM region (70h-71h). GSU Interrupt Vectors The SNES Exception Vectors (at FFE4h-FFFFh) are normally located in Game Pak ROM. When the GSU is running (with GO=1 and RON=1), ROM isn't mapped to SNES memory, instead, fixed values are appearing as ROM (depending of the lower 4bit of the address): Any Address Exception Vectors [xxx0h]=0100h - [xxx2h]=0100h - [xxx4h]=0104h [FFE4h]=0104h COP Vector in 65C816 mode (COP opcode) [xxx6h]=0100h [FFE6h]=0100h BRK Vector in 65C816 mode (BRK opcode) [xxx8h]=0100h [FFE8h]=0100h ABT Vector in 65C816 mode (Not used in SNES) [xxxAh]=0108h [FFEAh]=0108h NMI Vector in 65C816 mode (Vblank) [xxxCh]=0100h - [xxxEh]=010Ch [FFEEh]=010Ch IRQ Vector in 65C816 mode (H/V-IRQ & GSU-STOP) It'd be best to set the Game Pak ROM vectors to the same addresses, otherwise the vectors would change when the GSU is running (or possibly, the fixed-LSBs may be mixed-up with ROM-MSBs). GSU Cartridge Header (always at ROM Offset 7Fxxh, in LoROM fashion) [FFD5h]=20h Set to "Slow/LoROM" (although both LoROM/HiROM works) [FFD6h]=13h..1Ah Chipset = GSUn (plus battery present/absent info) [FFD8h]=00h Normal SRAM Size (None) (always use the Expansion entry) [FFBDh]=05h..06h Expansion RAM Size (32Kbyte and 64Kbyte exist) Caution: Starfox/Star Wing, Powerslide, and Starfox 2 do not have extended headers (and thereby no [FFBDh] entry). RAM Size for Starfox/Starwing is 32Kbytes, RAM Size for Powerslide and Starfox 2 is unknown. There is no info in the header (nor extended header) whether the game uses a GSU1 or GSU2. Games with 2MByte ROM are typically using GSU2 (though that rule doesn't always match: Star Fox 2 is only 1MByte). GSU Busses The GSU seems to have 4 address/data busses (three external ones, and one internal cache bus): SNES bus (for forwarding ROM/RAM access to SNES) ROM bus (for GSU opcode fetches, GETxx reads, and SNES reads) RAM bus (for GSU opcode fetches, LOAD/STORE/PLOT/RPIX, and SNES access) Code cache bus (for GSU opcode fetches only) (and SNES I/O via 3100h..32FFh) To some level, this allows to do multiple things simultaneously: Reading a GSU opcode from cache at the same time while prefetching ROM data and forwarding the RAM or Pixel cache to RAM. SNES Cart GSU-n I/O Map ----------------------- GSU I/O Map (in banks 00h-3Fh and 80h-BFh) During GSU operation, only SFR, SCMR, and VCR may be accessed. 3000h-3001h R0 Default source/destination register (Sreg/Dreg) (R/W) 3002h-3003h R1 PLOT opcode: X coordinate (0000h on reset) (R/W) 3004h-3005h R2 PLOT opcode: Y coordinate (0000h on reset) (R/W) 3006h-3007h R3 General purpose (R/W) 3008h-3009h R4 LMULT opcode: lower 16bits of result (R/W) 300Ah-300Bh R5 General purpose (R/W) 300Ch-300Dh R6 LMULT and FMULT opcodes: multiplier (R/W) 300Eh-300Fh R7 MERGE opcode (R/W) 3010h-3011h R8 MERGE opcode (R/W) 3012h-3013h R9 General purpose (R/W) 3014h-3015h R10 General purpose (conventionally stack pointer) (R/W) 3016h-3017h R11 LINK opcode: destination (R/W) 3018h-3019h R12 LOOP opcode: counter (R/W) 301Ah-301Bh R13 LOOP opcode: address (R/W) 301Ch-301Dh R14 GETxx opcodes: Game Pak ROM Address Pointer (R/W) 301Eh-301Fh R15 Program Counter, writing MSB starts GSU operation (R/W) 3020h-302Fh - 3030h-3031h SFR Status/Flag Register (R) (Bit1-5: R/W) 3032h - 3033h BRAMR Back-up RAM Register (W) 3034h PBR Program Bank Register (8bit, bank 00h..FFh) (R/W) 3035h - 3036h ROMBR Game Pak ROM Bank Register (8bit, bank 00h..FFh) (R) 3037h CFGR Config Register (W) 3038h SCBR Screen Base Register (8bit, in 1Kbyte units) (W) 3039h CLSR Clock Select Register (W) 303Ah SCMR Screen Mode Register (W) 303Bh VCR Version Code Register (R) 303Ch RAMBR Game Pak RAM Bank Register (1bit, bank 70h/71h) (R) 303Dh - 303Eh-303Fh CBR Cache Base Register (in upper 12bit; lower 4bit=unused) (R) N/A COLR Color Register (COLOR,GETC,PLOT opcodes) N/A POR Plot Option Register (CMODE opcode) N/A Sreg/Dreg Memorized TO/FROM Prefix Selections N/A ROM Read Buffer (1 byte) (prefetched from [ROMBR:R14]) N/A RAM Write Buffer (1 byte/word) N/A RAM Address (1 word, or word+rambr?) (for SBK opcode) N/A Pixel Write Buffer (two buffers for one 8-pixel row each) 3100h-32FFh Cache RAM Full I/O Map with Mirrors for Black Blob (VCR=01h) 3000h..301Fh 20h R0-R15 3020h..302Fh 10h open bus 3030h..3031h 2 status reg 3032h..303Fh 0Eh mirrors of status reg (except 303Bh=01h=VCR) 3040h..305Fh 20h mirror of R0-R15 3060h..307Fh 20h mirrors of status reg (except 307Bh=01h=VCR) 3080h..30FFh 80h open bus 3100h..32FFh 200h cache 3300h..332Fh 30h open bus 3330h..333Fh 10h mirrors of status reg (except 333Bh=01h=VCR) 3340h..335Fh 20h mirror of R0-R15 3360h..337Fh 20h mirrors of status reg (except 337Bh=01h=VCR) 3380h..33FFh 80h open bus 3400h..342Fh 30h open bus 3430h..343Fh 10h mirrors of status reg (except 343Bh=01h=VCR) 3440h..345Fh 20h mirror of R0-R15 3460h..347Fh 20h mirrors of status reg (except 347Bh=01h=VCR) 3480h..3FFFh B80h open bus Full I/O Map with Mirrors for GSU2 (VCR=04h) 3000h..301Fh 20h R0-R15 3020h..302Fh 10h mirror of 3030h..303Fh 3030h..303Fh 10h status regs (unused or write-only ones return 00h) 3040h..30FFh C0h mirrors of 3000h..303Fh 3100h..32FFh 200h cache 3300h..34FFh 200h mirrors of 3000h..303Fh 3500h..3FFFh B00h open-bus SNES Cart GSU-n General I/O Ports --------------------------------- 3000h-301Fh - R0-R15 - CPU Registers (R/W) 16bit CPU registers (see GSU I/O map for additional details on each register). Writes to 3000h-301Eh (even addresses) do set LATCH=data. Writes to 3001h-301Fh (odd addresses) do apply LSB=LATCH and MSB=data. Writes to 301Fh (R15.MSB) do also set GO=1 (and start GSU code execution). 3030h/3031h - SFR - Status/Flag Register (R) (Bit1-5: R/W) 0 - Always 0 (R) 1 Z Zero Flag (0=NotZero/NotEqual, 1=Zero/Equal) (R/W) 2 CY Carry Flag (0=Borrow/NoCarry, 1=Carry/NoBorrow) (R/W) 3 S Sign Flag (0=Positive, 1=Negative) (R/W) 4 OV Overflow Flag (0=NoOverflow, 1=Overflow) (R/W) 5 GO GSU is running (cleared on STOP) (can be forcefully=0 via 3030h)(R/W) 6 R ROM[R14] Read (0=No, 1=Reading ROM via R14 address) (R) 7 - Always 0 (R) 8 ALT1 Prefix Flag ;\for ALT1,ALT2,ALT3 prefixes (R) 9 ALT2 Prefix Flag ;/ (R) 10 IL Immediate lower 8bit flag ;\Unknown, probably set/reset internally 11 IH Immediate upper 8bit flag ;/when processing opcodes with imm operands 12 B Prefix Flag ;-for WITH prefix (used by MOVE/MOVES opcodes) 13 - Always 0 (R) 14 - Always 0 (R) 15 IRQ Interrupt Flag (reset on read, set on STOP) (also set if IRQ masked?) This register is read/write-able even when the GSU is running; reading mainly makes sense for checking GO and IRQ bits, writing allows to clear the GO flag (thereby aborting the GSU program; the write does most likely also destroy the other SFR bits, so one cannot pause/resume). 3034h - PBR - Program Bank Register (8bit, bank 00h..5Fh,70h..71h) (R/W) 3036h - ROMBR - Game Pak ROM Bank Register (8bit, bank 00h..5Fh) (R) 303Ch - RAMBR - Game Pak RAM Bank Register (1bit, bank 70h..71h) (R) Memory banks for GSU opcode/data accesses. PBR can be set to both ROM and RAM regions, ROMBR/RAMBR only to ROM or RAM regions respectively. Existing cartridges have only 32Kbyte or 64Kbyte RAM, so RAMBR should be always zero. According to book2 (page 258), the screen base is also affected by RAMBR (unknown if that is true, theoretically, SCBR is large enough to address more than 64Kbytes without RAMBR). 303Eh/303Fh - CBR - Cache Base Register (upper 12bit; lower 4bit=unused) (R) Code-Cache Base for Game Pak ROM/RAM. The register is read-only, so the SNES cannot directly write to it, however, the SNES can set CBR=0000h by writing GO=0 (in SFR register). 3033h - BRAMR - Back-up RAM Register (W) 0 BRAM Flag (0=Disable/Protect, 1=Enable) 1-7 Not used (should be zero) This register would be used only if the PCB does have a separate "Backup" RAM chip mapped to 780000h-79FFFFh (additionally to the Game Pak RAM chip). None of the existing PCBs is having that extra RAM chip, so the register is having no function. (Note: However, some PCBs do include a battery wired to Game Pak RAM chip, anyways, that type of "backup" isn't affected by this register). 303Bh - VCR - Version Code Register (R) 0-7 GSU Chip Version (01h..0xh ?) Known versions: 1=MC1/Blob, ?=MC1/SMD, ?=GSU1, ?=GSU1A, 4=GSU2, ?=GSU2-SP1. 3037h - CFGR - Config Register (W) 0-4 - Not used (should be zero) 5 MS0 Multiplier Speed Select (0=Standard, 1=High Speed Mode) 6 - Not used (should be zero) 7 IRQ Interrupt Mask (0=Trigger IRQ on STOP opcode, 1=Disable IRQ) MS0 be zero in 21MHz mode (ie. only CFGR.Bit5 or CLSR.Bit0 may be set). MS0 is implemented in GSU2 (maybe also other chips), it is not implemented on Black Blob MC1 (which is always using slow multiply mode). 3039h - CLSR - Clock Select Register (W) 0 CLS Clock Select (0=10.7MHz, 1=21.4MHz) 1-7 - Not used (should be zero) CLS exists on all GSU variants (including Black Blob MC1) (however, there are rumours that the fast mode was "bugged" on older MC1, unknown if that's true). N/A - ROM Buffer - Prefetched Byte(s?) at [ROMBR:R14] N/A - Sreg/Dreg - Memorized TO/FROM Prefix Selections 3100h..32FFh - Cache RAM SNES Cart GSU-n Bitmap I/O Ports -------------------------------- 3038h - SCBR - Screen Base Register (8bit, in 1Kbyte units) (W) 0-7 Screen Base in 1K-byte Units (Base = 700000h+N*400h) 303Ah - SCMR - Screen Mode Register (W) 0-1 MD0-1 Color Gradient (0=4-Color, 1=16-Color, 2=Reserved, 3=256-Color) 2 HT0 Screen Height (0=128-Pixel, 1=160-Pixel, 2=192-Pixel, 3=OBJ-Mode) 3 RAN Game Pak RAM bus access (0=SNES, 1=GSU) 4 RON Game Pak ROM bus access (0=SNES, 1=GSU) 5 HT1 Screen Height (MSB of HT0 bit) 6-7 - Not used (should be zero) RON/RAN can be temporarily cleared during GSU operation, this causes the GSU to enter WAIT status (if it accesses ROM or RAM), and continues when RON/RAN are changed back to 1. Note that "OBJ Mode" can be also selected by POR.Bit4 (if so, HT0/HT1 bits are ignored). 256x128 pixels 256x160 pixels 256x192 pixels OBJ Mode 256x256 pixel 000 010 .. 1F0 | 000 014 .. 26C | 000 018 .. 1E8 | 000 .. 00F 100 .. 10F 001 011 .. 1F1 | 001 015 .. 26D | 001 019 .. 1E9 | .. .. .. .. .. .. .. .. .. .. | .. .. .. .. | .. .. .. .. | 0F0 .. 0FF 1F0 .. 1FF .. .. .. .. | .. .. .. .. | .. .. .. .. | 200 .. 20F 300 .. 30F 00E 01E .. 1FE | 012 026 .. 27E | 016 02E .. 2FE | .. .. .. .. .. .. 00F 01F .. 1FF | 013 027 .. 27F | 017 02F .. 2FF | 2F0 .. 2FF 3F0 .. 3FF In the first three cases, BG Map is simply filled with columns containing increasing tile numbers. The fourth case is matched to the SNES two-dimensional OBJ mapping; it can be used for BG Map (with entries 0..3FF as shown above), or for OBJ tiles (whereas, mind that the SNES supports only 0..1FF OBJs, not 200..3FF). The Tile Number is calculated as: Height 128 --> (X/8)*10h + (Y/8) Height 160 --> (X/8)*14h + (Y/8) Height 192 --> (X/8)*18h + (Y/8) OBJ Mode --> (Y/80h)*200h + (X/80h)*100h + (Y/8 AND 0Fh)*10h + (X/8 AND 0Fh) The Tile-Row Address is: 4 Color Mode TileNo*10h + SCBR*400h + (Y AND 7)*2 16 Color Mode TileNo*20h + SCBR*400h + (Y AND 7)*2 256 Color Mode TileNo*40h + SCBR*400h + (Y AND 7)*2 With Plane0,1 stored at Addr+0, Plane 2,3 at Addr+10h, Plane 4,5 at Addr+20h, Plane 6,7 at Addr+30h. N/A - COLR - Color Register 0-7 CD0-7 Color Data N/A - POR - Plot Option Register (CMODE) 0 PLOT Transparent (0=Do Not Plot Color 0, 1=Plot Color 0) 1 PLOT Dither (0=Normal, 1=Dither; 4/16-color mode only) 2 COLOR/GETC High-Nibble (0=Normal, 1=Replace incoming LSB by incoming MSB) 3 COLOR/GETC Freeze-High (0=Normal, 1=Write-protect COLOR.MSB) 4 OBJ Mode (0=Normal, 1=Force OBJ mode; ignore SCMR.HT0/HT1) 5-7 Not used (should be zero) Can be changed by CMODE opcode, used for COLOR/GETC/PLOT opcodes. Dither can mix transparent & non-transparent pixels. Bit0=0 (Transparent) causes PLOT to skip color 0 (so PLOT does only increment R1 (X-coordinate), but doesn't draw a pixel). Depending on color depth, the color 0 check tests the lower 2/4/8 bits of the drawing color (if POR.Bit3 (Freeze-High) is set, then it checks only the lower 2/4 bits, and ignores upper 4bit even when in 256-color mode). Bit1=1 (Dither) causes PLOT to use dithering, that is, if "(r1.bit0 XOR r2.bit0)=1" then COLOR/10h is used as drawing color; using Color 0 as one of the two colors can produce a semi-transparency effect. Dither is ignored in 256-color mode. Bit2=1 (High-Nibble) causes COLOR/GETC to replace the LSB of the incoming data by the MSB of the incoming data; this allows two 4bit bitmaps being stored at the same memory area (one in the LSBs, the other in MSBs). Bit3=1 (Freeze-High) causes COLOR/GETC to change only the LSB of the color register; this allows the MSB to be used as fixed palette-like value in 256-color mode, it might be also useful for fixed dither-colors in 4/16 color mode. Bit3=1 forces OBJ Mode (same as when setting SCMR.HT0/HT1 to OBJ Mode). <------- COLOR/GETC TO COLOR -------> <------- PLOT COLOR TO RAM --------> ______ __________ ______ Bit7-4 --+--|Freeze|- - - - - ->| |---+------------->| | | |POR.3 | | COLOR | | |Transp| | |______| ______ | _ _ _ _ | | ______ |POR.0 |--> RAM '---------->|Nibble| | | '-->|Dither| | | |POR.2 |-->| Register | |POR.1 |-->| | Bit3-0 ------------->|______| |__________|------>|______| |______| SNES Cart GSU-n CPU MOV Opcodes ------------------------------- GSU MOV Opcodes (Register/Immediate) Opcode Clks Flags Native Nocash 2s 1d 2 000---- MOVE Rd,Rs mov Rd,Rs ;Rd=Rs 2d Bs 2 000vs-z MOVES Rd,Rs movs Rd,Rs ;Rd=Rs (with flags, OV=bit7) An pp 2 000---- IBT Rn,#pp mov Rn,pp ;Rn=SignExpanded(pp) Fn xx yy 3 000---- IWT Rn,#yyxx mov Rn,yyxx ;Rn=yyxx GSU MOV Opcodes (Load BYTE from ROM) EF 1-6 000---- GETB movb Rd,[romb:r14] ;hi=zero-expanded 3D EF 2-6 000---- GETBH movb Rd.hi,[romb:r14] ;lo=unchanged 3E EF 2-6 000---- GETBL movb Rd.lo,[romb:r14] ;hi=unchanged 3F EF 2-6 000---- GETBS movbs Rd,[romb:r14] ;hi=sign-expanded GSU MOV Opcodes (Load/Store Byte/Word to/from RAM) 3D 4n 6 000---- LDB (Rn) movb Rd,[ramb:Rn] ;Rd=Byte[..] ;n=0..11 4n 7 000---- LDW (Rn) mov Rd,[ramb:Rn] ;Rd=Word[..] ;n=0..11 3D Fn lo hi 11 000---- LM Rn,(hilo) mov Rn,[ramb:hilo] ;Rn=Word[..] 3D An kk 10 000---- LMS Rn,(yy) mov Rn,[ramb:kk*2] ;Rn=Word[..] 3D 3n 2-5 000---- STB (Rn) movb [ramb:Rn],Rs ;Byte[..]=Rs ;n=0..11 3n 1-6 000---- STW (Rn) mov [ramb:Rn],Rs ;Word[..]=Rs ;n=0..11 3E Fn lo hi 4-9 000---- SM (hilo),Rn mov [ramb:hilo],Rn ;Word[..]=Rn 3E An kk 3-8 000---- SMS (yy),Rn mov [ramb:kk*2],Rn ;Word[..]=Rn 90 1-6 000---- SBK mov [ram:bk],Rs ;Word[LastRamAddr]=Rs Words at odd addresses are accessing [addr AND NOT 1], with data LSB/MSB swapped. LDB does zero-expand result (Rd.hi=00h). STB does store Rs.lo (ignores Rs.hi). SBK does "writeback" to most recently used RAM address (eg. can be used after LM) (unknown if whole 17bit, including ramb, are saved). GSU ROM/RAM Banks 3E DF 2 000---- RAMB movb ramb,Rs ;RAMBR=Rs & 01h ;RAM Bank 3F DF 2 000---- ROMB movb romb,Rs ;ROMBR=Rs & FFh ;ROM Bank GSU Bitmap Opcodes 3D 4E 2 000---- CMODE movb por,Rs ;=Rs&1Fh 4E 1 000---- COLOR movb color,Rs ;=Rs&FFh DF 1-6 000---- GETC movb color,[romb:r14] ;=[membyte] 4C 1-48 000---- PLOT plot [r1,r2],color ;Pixel=COLR, R1=R1+1 3D 4C 20-74 000-s-z RPIX rpix Rd,[r1,r2] ;Rd=Pixel? FlushPixCache Unknown if RPIX always sets SF=0, theoretically 2bit/4bit/8bit pixel-colors cannot be negative, unless it uses bit7 as sign, or so? SNES Cart GSU-n CPU ALU Opcodes ------------------------------- GSU ALU Opcodes Opcode Clks Flags Native Nocash 5n 1 000vscz ADD Rn add Rd,Rs,Rn ;Rd=Rs+Rn 3E 5n 2 000vscz ADD #n add Rd,Rs,n ;Rd=Rs+n 3D 5n 2 000vscz ADC Rn adc Rd,Rs,Rn ;Rd=Rs+Rn+Cy 3F 5n 2 000vscz ADC #n adc Rd,Rs,n ;Rd=Rs+n+Cy 6n 1 000vscz SUB Rn sub Rd,Rs,Rn ;Rd=Rs-Rn 3E 6n 2 000vscz SUB #n sub Rd,Rs,n ;Rd=Rs-n 3D 6n 2 000vscz SBC Rn sbc Rd,Rs,Rn ;Rd=Rs-Rn-(Cy XOR 1) 3F 6n 2 000vscz CMP Rn cmp Rs,Rn ;Rs-Rn 7n 1 000-s-z AND Rn and Rd,Rs,Rn ;Rd=Rs AND Rn ;n=1..15! 3E 7n 2 000-s-z AND #n and Rd,Rs,n ;Rd=Rs AND n ;n=1..15! 3D 7n 2 000-s-z BIC Rn bic Rd,Rs,Rn ;Rd=Rs AND NOT Rn ;n=1..15! 3F 7n 2 000-s-z BIC #n bic Rd,Rs,n ;Rd=Rs AND NOT n ;n=1..15! Cn 1 000-s-z OR Rn or Rd,Rs,Rn ;Rd=Rs OR Rn ;n=1..15! 3E Cn 2 000-s-z OR #n or Rd,Rs,n ;Rd=Rs OR n ;n=1..15! 3D Cn (?) 2 000-s-z XOR Rn xor Rd,Rs,Rn ;Rd=Rs XOR Rn ;n=1..15? 3F Cn (?) 2 000-s-z XOR #n xor Rd,Rs,n ;Rd=Rs XOR n ;n=1..15? 4F 1 000-s-z NOT not Rd,Rs ;Rd=Rs XOR FFFFh GSU Rotate/Shift/Inc/Dec Opcodes 03 1 000-0cz LSR shr Rd,Rs,1 ;Rd=Rs SHR 1 96 1 000-scz ASR sar Rd,Rs,1 ;Rd=Rs SAR 1 04 1 000-scz ROL rcl Rd,Rs,1 ;Rd=Rs RCL 1 ;\through 97 1 000-scz ROR rcr Rd,Rs,1 ;Rd=Rs RCR 1 ;/carry 3D 96 2 000-scz DIV2 div2 Rd,Rs ;Rd=Rs SAR 1, Rd=0 if Rs=-1 Dn 1 000-s-z INC Rn inc Rn ;Rn=Rn+1 ;n=0..14! En 1 000-s-z DEC Rn dec Rn ;Rn=Rn-1 ;n=0..14! GSU Byte Operations 4D 1 000-s-z SWAP ror Rd,Rs,8 ;Rd=Rs ROR 8 95 1 000-s-z SEX movbs Rd,Rs ;Rd=SignExpanded(Rs&FFh) 9E 1 000-s-z LOB and Rd,Rs,0FFh ;Rd=Rs AND FFh ;SF=Bit7 C0 1 000-s-z HIB shr Rd,Rs,8 ;Rd=Rs SHR 8 ;SF=Bit7 70 1 000xxxx MERGE merge Rd,r7,r8 ;Rd=R7&FF00 + R8/100h Flags for MERGE are: S = set if (result AND 8080h) is nonzero V = set if (result AND C0C0h) is nonzero C = set if (result AND E0E0h) is nonzero Z = set if (result AND F0F0h) is nonzero (not set when zero!) GSU Multiply Opcodes 9F 4,8 000-scz FMULT smulw Rd:nul,Rs,r6 ;Rd=signed(Rs*R6/10000h) 3D 9F 5,9 000-scz LMULT smulw Rd:R4,Rs,R6 ;Rd:R4=signed(Rs*R6) 8n 1,2 000-s-z MULT Rn smulb Rd,Rs,Rn ;Rd=signed(RsLsb*RnLsb) 3E 8n 2,3 000-s-z MULT #n smulb Rd,Rs,n ;Rd=signed(RsLsb*0..15) 3D 8n 2,3 000-s-z UMULT Rn umulb Rd,Rs,Rn ;Rd=unsigned(RsLsb*RnLsb) 3F 8n (?) 2,3 000-s-z UMULT #n umulb Rd,Rs,n ;Rd=unsigned(RsLsb*0..15) The multiply speed can be selected via CFGR register. Do not use FMULT with Dreg=R4 (this will reportedly leave R4 unchanged). When using LMULT with Dreg=R4 then the result will be R4=MSB (and LSB is lost). Ie. if that is true then, strangely, LMULT R4 work as how FMULT R4 work. SNES Cart GSU-n CPU JMP and Prefix Opcodes ------------------------------------------ GSU Special Opcodes Opcode Clks Flags Native Nocash 00 1 000---- STOP stop ;SFR.GO=0, SFR.IRQ=1, R15=$+2 01 1 000---- NOP nop ;NOP (often used as dummy after jump) 02 1* 000---- CACHE cache ;IF CBR<>PC&FFF0 then CBR=PC&FFF0 STOP at $+0 does prefetch another opcode byte at $+1 (but without executing it), and does then stop with R15=$+2, SFR.GO=0, SFR.IRQ=1 (that, even if IRQ is disabled in CFGR.IRQ). BUG: On MC1 (maybe also GSU1), STOP hangs when executed after a RAM write (there must be at least 2 cycles after write, eg. insert two NOPs before STOP; the required delay might vary depending on CPU speed or code cache? the bug doesn't occur on GSU2). GSU Jump Opcodes Opcode Clks Flags Native Nocash 05 nn 2 ------- BRA addr jr addr ;Always, R15=R15+signed(nn) 06 nn 2 ------- BGE addr jge addr ;If (S XOR V)=0 then .. 07 nn 2 ------- BLT addr jl addr ;If (S XOR V)=1 then .. 08 nn 2 ------- BNE addr jne addr ;If ZF=0 then R15=R15+signed(nn) 09 nn 2 ------- BEQ addr je addr ;If ZF=1 then R15=R15+signed(nn) 0A nn 2 ------- BPL addr jns addr ;If SF=0 then R15=R15+signed(nn) 0B nn 2 ------- BMI addr js addr ;If SF=1 then R15=R15+signed(nn) 0C nn 2 ------- BCC addr jnc addr ;If CY=0 then R15=R15+signed(nn) 0D nn 2 ------- BCS addr jc addr ;If CY=1 then R15=R15+signed(nn) 0E nn 2 ------- BVC addr jno addr ;If OV=0 then R15=R15+signed(nn) 0F nn 2 ------- BVS addr jo addr ;If OV=1 then R15=R15+signed(nn) 9n 1 000---- JMP Rn jmp Rn ;R15=Rn ;n=8..13! 3D 9n 2 000---- LJMP Rn jmp Rn:Rs ;R15=Rs, PBR=Rn, CBR=? ;n=8..13! 3C 1 000-s-z LOOP loop r12,r13 ;r12=r12-1, if Zf=0 then R15=R13 9n 1 000---- LINK #n link r11,addr;R11=R15+n ;n=1..4 Jumps can be also implemented by using R15 (PC) as destination register (eg. in MOV/ALU commands). Observe that the NEXT BYTE after any jump/branch opcodes is fetched before continuing at the jump destination address. The fetched byte is executed after the jump, but before executing following opcodes at the destination (in case of multi-byte opcodes, this results in a 1-byte-fragment being located after the jump-origin, and the remaining byte(s) at the destination). GSU Prefix Opcodes ALT1/ALT2/ALT3 prefixes do change the operation of an opcode, these are usually implied in the opcode description (for example, "3F 6n" is "CMP R0,Rn"). TO/WITH/FROM prefixes allow to select source/destination registers (otherwise R0 is used as default register) (for example, "Bs 3F 6n" is "CMP Rs,Rn"). The prefixes are normally reset after execution of any opcode, the only exception are the Bxx (branch) opcodes, these leave prefixes unchanged (allowing to "split" opcodes, for example placing ALT1/TO/etc. before Bxx, and the next opcode byte after Bxx). Aside from setting Sreg+Dreg, WITH does additionally set the B-flag, this causes any following 1nh/Bnh bytes to act as MOVE/MOVES opcodes (rather than as TO/FROM prefixes). Opcode Clks Flags Name Bflg ALT1 ALT2 Rs Rd 3D 1 -1----- ALT1 - 1 - - - ;prefix for 3D xx opcodes 3E 1 --1---- ALT2 - - 1 - - ;prefix for 3E xx opcodes 3F 1 -11---- ALT3 - 1 1 - - ;prefix for 3F xx opcodes 1n 1 ------- TO Rn - - - - Rn ;select Rn as Rd 2n 1 1------ WITH Rn 1 - - Rn Rn ;select Rn as Rd & Rs Bn 1 ------- FROM Rn - - - Rn - ;select Rn as Rs 05..0F nn 2 ------- Bxx addr - - - - - ;branch opcodes (no change) other .. 000---- other 0 0 0 R0 R0 ;other opcodes (reset all) Other opcodes do reset B=0, ALT1=0, ALT2=0, Sreg=R0, Dreg=R0; that does really apply to ALL other opcodes, namely including JMP/LOOP (unlike Bxx branches), NOP (ie. NOP isn't exactly operation), MOVE/MOVES (where 1n/Bn are treated as 'real' opcodes rather than as TO/FROM prefixes). Ignored Prefixes ALT1/ALT2 prefixes are ignored if the opcode doesn't exist (eg. if "3D xx" doesn't exist, then the CPU does instead execute "xx") (normally, doing that wouldn't make any sense, however, "Doom" is using ALT1/ALT2 alongside with conditional jumps, resulting in situations where the prefix is used/ignored depending on the jump condition). ALT3 does reportedly mirror to ALT1 (eg. if "3F xx" doesn't exist, then it acts as "3D xx", and, if that doesn't either, as "xx"). TO/WITH/FROM are ignored if the following opcode doesn't use Dreg/Sreg. Program Counter (R15) Notes R15 can be used as source operand in MOV/ALU opcodes (and is also implied as such in Bxx,LINK,CACHE opcodes); in all cases R15 contains the address of the next opcode. SNES Cart GSU-n CPU Pseudo Opcodes ---------------------------------- Official GSU Pseudo/Macro Opcodes -- 3 000---- LEA Rn,yyxx ;Alias for IWT, without "#" -- - 000---- MOVE Rn,#hilo ;Alias for IBT/IWT (depending on size) -- - 000---- MOVE Rn,(xx) ;Alias for LM/LMS (depending on size) -- - 000---- MOVE (xx),Rn ;Alias for SM/SMS (depending on size) -- - 000---- MOVEB Rn,(Rm) ;Alias for LDB/TO+LDB (depending Rn) -- - 000---- MOVEB (Rm),Rn ;Alias for STB/FROM+STB -- - 000---- MOVEW Rn,(Rm) ;Alias for LDW/TO+LDW (depending Rn) -- - 000---- MOVEW (Rm),Rn ;Alias for STW/FROM+STW Above are official pseudo opcodes for native syntax (the nocash syntax "MOV" opcode is doing that things by default). Nocash GSU Pseudo Opcodes jmp nnnn alias for "mov r15,nnnn" jz/jnz/jae/jb alias for "je/jne/jc/jnc" Further possible pseudo opcodes (not yet supported in a22i): push rs mov [r10],rs, 2xinc_r10 ;\INCREASING on PUSH? or MEMFILL? pop rd 2xdec_r10, mov rd,[r10] ;/ (see Star Fox 1:ACA4) cmp rn,0 alias for "sub rn,rn,0" call alias for link+jmp ret alias for jmp r11 alu rd,op short for "alu rd,rs,op" and rd,rs,n alias for "bic rd,rs,not n" SNES Cart GSU-n CPU Misc ------------------------ Uncached ROM/RAM-Read-Timings ROM Read: 5 cycles per byte at 21MHz, or 3 cycles per byte at 10MHz RAM Write: 10 cycles per word at 21MHz, or unknown at 10MHz? RAM Write: unknown number of cycles per byte? ROM/RAM Opcode-byte-read: 3 cycles at both 21MHz and 10MHz? The uncached timings aren't well documented. Possibly ROM/RAM-byte read/write are all having the same timing (3/5 clks at 10/21MHz) (and RAM-word 6/10)? Jump Notes Jumps can be implemented by JMP/Bxx opcodes, or by using R15 as destination register. In all cases, the next BYTE after the jump opcode is fetched as opcode byte, and is executed before continuing at the jump-target address. Possible situations are: 1) jump + NOP ;very simple 2) jump + ONE-BYTE-OPCODE ;still quite simple 3) jump + MULTI-BYTE-OPCODE ;rather strange 4) Prefix + jump + ONE-BYTE-SUFFIX 5) Prefix + jump + MULTI-BYTE-SUFFIX In case 3, the first opcode-byte is picked from the address after jump, the following byte(s) from the jump-destination. In case 4/5, the prefix is located before the jump, the next byte after the jump (this works only with Bxx jumps) (whilst JMP/LJMP or MOV/ALU R15,dest do reset the prefix), and any further bytes at the jump-destination. Mistakes in book2.pdf BGE/BLT are exchanged with each other. MOVES src/dst operands are exchanged. LJMP bank/offs operands are exchanged. GSU Undoc opcodes UMULT #n, WITH, XOR Rn, XOR #n are sorts of undocumented; they should be described (on page 280), but the alphabetical list ends abruptly after UMULT Rn. However, they are listed in the summary (page 101) and in the index (page 409). The WITH opcode is also mentioned in various other places. page 121: R15 after STOP (strange, is that true?) (yes, it is) page 122: cache/cbr after ABORT MOV R13,R15 sets R13 to addr of next opcode after MOV (eg. for LOOP start) LINK n sets R11 to addr+n of next opcode (eg. for "CALLs" via jmp) GSU Power Consumption The GSU does (when it is running) increase the power consumption, this can overload the SNES power supply if additional peripherals are connected. GSU software should detect which controllers are connected, and refuse to start the GSU if a controller with high power consumption (or with unknown power consumption) is connected. The standard joypads are okay. A Multiplayer 5 adaptor isn't okay (at least, when multiple controllers are connected to it). After STOP Restarting (somewhere(?) after STOP) is possible by setting GO-flag (done by Dirt Trax FX). SNES Cart GSU-n Code-Cache -------------------------- ROM/RAM-Code-Cache (512-byte cache) This cache is used only for Opcode fetches from ROM or RAM (not for reading/writing Data to/from ROM nor RAM) (however, it does slightly increase data access speed in so far that data can be read/written via Gamepak bus, simultaneously while fetching opcodes from the cache). 32 lines of 16-bytes. CACHE LJMP STOP ABORT after STOP, one "must" clear GO by software to clear the cache Cache Area "SNES_Addr = (CBR AND 1FFh)+3100h". For example, a CACHE opcode at C3A5h will set CBR to C3A0h, and the (initially empty) cached region will be C3A0h..C59Fh, when code gets loaded into the cache, GSU:C3A0h..C3FFh shows up at SNES:32A0h..32FFh, and GSU:C400h..C59Fh at SNES:3100h..329Fh. Writing to Code-Cache (by SNES CPU) First of, set GO=0 (ie. write SFR=0000h), this forces CBR=0000h, and marks all cache lines as empty. Then write opcodes 16-byte lines at 3100h..32FFh, writing the last byte of a line at [3xxFh] will mark the line as not-empty. Thereafter, the cached code can be excuted (by setting R15 to 0000h..01Fxh), in this case, the GSU can be operated without RON/RAN flags being set - unless R15 leaves the cached area (this occurs also when a STOP is located in last byte of last cache line; the hardware tries to prefetch one byte after STOP), or unless ROM-DATA is accessed (via GETxx opcodes) or unless RAM-DATA is accessed (via LOAD/STORE or PLOT/RPIX opcodes). Ie. usually one would have RAN set (unless all incoming/outgoing parameters can be passed though R0..R14 registers). Code-Cache Loading Notes The 16-byte cache-lines are loaded alongside while executing opcodes (rather than first loading the whole 16-byte-line, and then executing the opcodes within it; which would be slightly slower). There are two special cases related to jumps: If current cache-line isn't fully loaded then hardware keeps loading the remaining bytes (from jump-origin to end-of-line). If the jump-target isn't aligned by 16 (and isn't yet cached), then the hardware loads the leading bytes (from start-of-line to jump-target). After that two steps, normal execution continues at the jump-target address. The leading-stuff also occurs on CACHE instruction. CACHE sets CBR to "R15 AND FFF0h" (whereas R15=address after CACHE opcode) LJMP sets CBR to "R15 AND FFF0h" (whereas R15=jump target address) SNES write to SFR register with GO=0 sets CBR=0000h (all of the above three cases do also mark all cache lines as empty) All Code-Cache lines are marked as empty when executing CACHE or LJMP opcodes, or when the SNES clears the GO flag (by writing to SFR). The STOP opcode however (which also clears GO), doesn't empty the cache, so one may eventually re-use the cached values when restarting the GSU (however, if PBR or code in GamePak RAM has changed, then one must clear the cache by writing GO=0). According to cache description (page 132), Cache-Code is 6 times faster than ROM/RAM. However, according to opcode descriptions (page 160 and up), cache is only 3 times faster than ROM/RAM. Whereas, maybe 6 times refers to 21MHz mode, and 3 times to 10MHz mode? The CACHE opcode is typically executed prior to loops and/or at the begin of often-used sub-functions (or ideally, the loop and any used subfunctions should both fit into the 512-byte cache region). SNES Cart GSU-n Pixel-Cache --------------------------- RAM-Pixel-Write-Cache (two 8-pixel rows) pixel cache is flushed when: 1) cache full 2) doing rpix <--- this does also WAIT until it is flushed 3) changing r1 or r2 (really?) Pixel Cache Primary Pixel Cache (written to by PLOT) Secondary Pixel Cache (data copied from Primary Cache, this WAITs if Secondary cache wasn't yet forwarded to RAM) (if less than 8 flags are set, data is merged with old RAM data). Each cache contains 8 pixels (with 2bit/4bit/8bit depth), plus 8 flags (indicating if (nontransparent) pixels were plotted). Pixel X/Y coordinates are 8bit wide (using LSBs of R1/R2 registers). (X and F8h) and (Y and FFh) are memorized, when plotting to different values, Primary cache is forwarded to Secondary Cache, this happens also when all 8 cache flags are set. Do not change SCREEN MODE (how to do that at all while GSU is running? SCMR is writeable for changing RAN/RON, but changing the other SCMR bits during GSU execution would be rather unpredictable) when data is in pixel caches (use RPIX to force the caches to be flushed). Before STOP opcode, do also use RPIX to force the caches to be flushed. RPIX isn't cached, it does always read data from RAM, not from cache. Moreover, before reading RAM, RPIX does force both pixel caches (unless they are empty) to be forwarded to RAM. This is making RPIX very slow (trying to read/modify pixels via RPIX+PLOT would work very slow). So far, RPIX is mainly useful for forcing the pixel caches to be forwarded to RAM (and to WAIT until that forwarding has completed). SNES Cart GSU-n Other Caches ---------------------------- ROM-Read-Data Cache (1-byte read-ahead) The cache is used for GETB/GETBS/GETBL/GETBH/GETC opcodes (which do read from [ROMBR:R14]). Loading the cache is invoked by any opcodes that do change R14 (such like ADD,MOVE,etc.), allowing following GETxx opcodes to be executed without Waitstates. In some situations WAITs can occur: When the cache-load hasn't yet completed (ie. GETxx executed shortly after changing R14), when an opcode is fetched from ROM (rather than from RAM or Code-Cache), when ROMBR is changed (caution: in this special case following GETxx will receive [OldROMBR:R14] rather than [NewROMBR:R14]). Caution: Do not execute the CACHE opcode shortly (7 cycles in 21MHz mode, or 4 cycles in 10MHz mode) after changing R14 (when doing that, the read from R14 will fail somehow, and following GETxx will return garbage). Unknown if SNES writes to R14 (via Port 301Ch) do also prefetch [R14] data? RAM-Write-Data Cache (1-byte/1-word write queue) This cache is used for STB/STW/SM/SMS/SBK opcodes. After any such store opcodes, the written byte/word is memorized in the cache, and further opcodes can be fetched (from ROM or from Code-Cache) immediately without Waitstates, simultaneously with the cached value being forwarded to RAM. In some situations WAITs can occur: When cache already contained data (ie. when executing two store opcodes shortly after each other), when an opcode is fetched from RAM (rather than from ROM or Code-Cache), when the RAMBR register is changed (this works as expected, it finishes the write to [OldRAMBR:nnnn]). Results on doing Data-RAM-Reads while the Data-RAM-write is still busy are unknown (possibly, this will WAIT, too) (or it may return garbage)? WAITs should also occur when the pixel-cache gets emptied? RAM-Address-Cache (1 word) (Bulk Processing for read-modify-write) This very simple cache memorizes the most recently used RAM address (from LM/LMS opcodes, and probably also from LDB/LDW/STB/STW/SM/SMS opcodes; though some games insert STW to push data on stack, as if they were intended not to change the memorized address?), the SBK opcode can be used to write a word to the memorized address (ie. one can avoid repeating immediate operands in SM/SMS opcodes). SNES Cart Capcom CX4 (programmable RISC CPU) (Mega Man X 2-3) (2 games) ----------------------------------------------------------------------- --> SNES Cart Capcom CX4 - I/O Ports --> SNES Cart Capcom CX4 - Opcodes --> SNES Cart Capcom CX4 - Functions --> SNES Pinouts CX4 Chip Capcom CX4 - 80pin chip Used only by two games: Mega Man X2 (1994) Capcom (NA) (JP) (EU) ;aka Rockman X2 Mega Man X3 (1995) Capcom (NA) (JP) The CX4 chip is actually a Hitachi HG51B169 as confirmed by decapping. Note: The CX4 is occassionally referred to as C4 (the real chip name is CX4, the C4 variant is some kind of scene slang). CX4 Memory Map I/O 00-3F,80-BF:6000-7FFF ROM 00-3F,80-BF:8000-FFFF SRAM 70-77:0000-7FFF (not installed; reads return 00h) MISC MISC MISC Commands are executed on the CX4 by writing the command to 0x7F4F while bit 6 of 0x7F5E is clear. Bit 6 of 0x7F5E will stay set until the command has completed, at which time output data will be available. [Registers] $7f49-b = ROM Offset $7f4d-e = Page Select $7f4f = Instruction Pointer Start Address = ((Page_Select * 256) + Instruction Pointer) * 2) + ROM_Offset [Memory layout] Program ROM is obviously 256x16-bit pages at a time. (taken from the SNES ROM) Program RAM is 2x256x16-bit. (two banks) ;<-- uh, that means cache? Data ROM is 1024x24-bit. (only ROM internal to the Cx4) Data RAM is 4x384x16-bit. ;<-- uh, but it HAS 8bit data bus? Call stack is 8-levels deep, at least 16-bits wide. CX4ROM (3Kbytes) (1024 values of 24bit each) Index Name ;Entry = Table Contents = Formula ------------------------------------------------------------------------- 000..0FFh Div ;N[0..FFh] = FFFFFFh..008080h = 800000h/(00h..FFh) 100..1FFh Sqrt ;N[0..FFh] = 000000h..FF7FDFh = 100000h*Sqrt(00h..FFh) 200..27Fh Sin ;N[0..7Fh] = 000000h..FFFB10h = 1000000h*Sin(0..89') 280..2FFh Asin ;N[0..7Fh] = 000000h..75CEB4h = 800000h/90'*Asin(0..0.99) 300..37Fh Tan ;N[0..7Fh] = 000000h..517BB5h = 10000h*Tan(0..89') 380..3FFh Cos ;N[0..7Fh] = FFFFFFh..03243Ah = 1000000h*Cos(0..89') Sin/Asin/Tan/Cos are spanning only 90' out of 360' degress (aka 80h out of 200h degrees). Overflows on Div(0) and Cos(0) are truncated to FFFFFFh. All values are unsigned, and all (except Asin/Tan) are using full 24bits (use SHR opcode to convert these to signed values with 1bit sign + 23bit integer; for Div one can omit the SHR if divider>01h). CX4 Component List (Megaman X2) PCB "SHVC-2DC0N-01, (C)1994 Nintendo" U1 32pin P0 8M MASK ROM (LH538LN4 = 8Mbit) U2 32pin P1 4/8 MASK ROM (LH534BN2 or LH5348N2 or so = 4Mbit) U3 80pin CX4 (CAPCOM CX4 DL-2427, BS169FB) U4 18pin CIC (F411A) X1 2pin 20MHz J 62pin Cart Edge connector (unknown if any special pins are actually used) CX4 Component List (Megaman X3) PCB "SHVC-1DC0N-01, (C)1994 Nintendo" U1 40pin MASK ROM (TC5316003CF = 16Mbit) U2 80pin CX4 (CAPCOM CX4 DL-2427, BS169FB) U3 18pin CIC (F411A) X1 2pin 20MHz J 62pin Cart Edge connector (unknown if any special pins are actually used) CX4 Cartridge Header (as found in Mega Man X2/X3 games) [FFBD]=00h ;expansion RAM size (none) (there is 3KB cx4ram though) [FFBF]=10h ;CustomChip=CX4 [FFD5]=20h ;Slow LoROM (but CX4 opcodes are probably using a faster cache) [FFD6]=F3h ;ROM+CustomChip (no battery, no sram) [FFD7]=0Bh ;rom size (X2: 1.5MB, rounded-up to 2MB) (X3: real 2MB) [FFD8]=00h ;sram size (none) (there is 3KB cx4ram though) [FFDA]=33h ;Extended Header (with FFB0h-FFBFh) ROM Enable On SHVC-2DC0N-01 PCBs (ie. PCBs with two ROM chips), the 2nd ROM chip is reportedly initially disabled, and can be reportedly enabled by setting [7F48h]=01h (that info doesn't match up with how 7F48h is used by the existing games; unknown if that info is correct/complete). CX4 CPU Misc All values are little-endian (opcodes, I/O Ports, cx4rom-ROM-Image, etc). Call Stack is reportedly 16 levels deep, at least 16bits per level. Carry Flag is CLEARED on borrow (ie. opposite as on 80x86 CPUs). CX4 Timings (Unknown) All opcode & DMA timings are 100% unknown. The CX4 is said to be clocked at 20.000MHz, but this might be internally divided, possibly with different waitstates for different memory regions or different opcodes. The ROM speed is 2.68Mhz (according to the cartridge header), and 16bit opcodes are passed through 8bit databus (though one may assume that the CX4 contains an opcode cache) (cache might be divided into 200h-byte pages, so, far-jumps to other pages might be slow, maybe/guessed). The "skip" opcodes are "jumping" to the location after the next opcode (this probably faster than the actual "jmp" opcodes). After Multiply opcodes one should insert one "nop" (or another instruction that doesn't access the MH or ML result registers). Reading data bytes from SNES ROM requires some complex timing/handling: 612Eh movb ext_dta,[ext_ptr] ;\these 3 opcodes are used to 4000h inc ext_ptr ; read one byte from [ext_ptr], 1C00h finish ext_dta ;/and to increment ext_ptr by 1 The exact meaning of the above opcodes is unknown (which one does what part?). It is also allowed to use the middle opcode WITHOUT the "prepare/wait" part: 4000h inc ext_ptr ;-increment ext_ptr by 1 In that case, "ext_ptr" is incremented, but "ext_dta" should not be used (might be unchanged, or contain garbage, or receive data after some cycles?). SNES Cart Capcom CX4 - I/O Ports -------------------------------- CX4 I/O Map 6000h..6BFFh R/W CX4RAM (3Kbytes) 6C00h..7F3Fh ? Unknown/unused 7F40h..7F42h ?/W DMA source, 24bit SNES LoROM address 7F43h..7F44h ?/W DMA length, 16bit, in bytes (eg. 0800h = 2Kbytes) 7F45h..7F46h ?/W DMA destination, 16bit in CX4RAM (6000h = 1st byte) 7F47h ?/W DMA start (write 00h to transfer direction SNES-to-CX4) 7F48h ?/W Unknown "toggle" (set to 00h/01h, maybe cache load/on/off?) 7F49h..7F4Bh R/W Program ROM Base, 24bit LoROM addr (028000h in Mega Man) 7F4Ch ?/W Unknown (set to 00h or 01h) soft_reset? maybe flush_cache? 7F4Dh..7F4Eh ?/W Program ROM Instruction Page (PC/200h) 7F4Fh ?/W Program ROM Instruction Pointer (PC/2), starts execution 7F50h..7F51h R/W Unknown, set to 0144h (maybe config flags or waitstates?) 7F52h R/W Unknown (set to 00h) hard_reset? maybe force stop? 7F53h..7F5Dh ? Unknown/unused 7F5Eh R/? Status (bit6=busy, set upon [7F47],[7F48],[7F4F] writes) 7F5Fh ? Unknown/unused 7F60h..7F69h ? Unknown/unused (maybe [FFE0..FFE9]) 7F6Ah..7F6Bh R/W SNES NMI Vector [FFEA..FFEB] 7F6Ch..7F6Dh ? Unknown/unused (maybe [FFEC..FFED]) 7F6Eh..7F6Fh R/W SNES IRQ Vector [FFEE..FFEF] 7F70h..7F7Fh ? Unknown/unused (maybe [FFF0..FFFF]) 7F80h..7FAFh R/W Sixteen 24bit CX4 registers (R0..R15, at 7F80h+N*3) 7FB0h..7FFFh ? Unknown/unused 8000h..FFFFh R ROM (32Kbyte LoROM Banks) (disabled when CX4 is busy) FFExh..FFxxh R/? Exception Vectors (from above I/O Ports, when CX4 is busy) Exception Vectors Unknown if these can be manually enabled, or if they are automatically enabled when the CX4 is "busy". In the latter case, they would be REQUIRED to be same as the ROM vectors (else LSB/MSB might be accidently fetched from different locations when busy-flag changes at same time). SNES Cart Capcom CX4 - Opcodes ------------------------------ CX4 Opcodes (all are 16bit wide) Opcode Clks NZC Syntax 0000h ?? ??? nop ;nop is used as delay after "mul" opcodes 0400h ?? ??? - 0800h+p0aaaaaaaa ?? ??? jmp addr/prg_page:addr 0C00h+p0aaaaaaaa ?? ??? jz addr/prg_page:addr ;Z=1 (equal) 1000h+p0aaaaaaaa ?? ??? jc addr/prg_page:addr ;C=1 (above/equal) 1400h+p0aaaaaaaa ?? ??? js addr/prg_page:addr ;N=1 (negative) 1800h ?? ??? - 1C00h ?? ??? finish ext_dta 2000h ?? ??? - 2400h+nn0000000n ?? ??? skip ;skip next opcode 2800h+p0aaaaaaaa ?? ??? call addr/prg_page:addr 2C00h+p0aaaaaaaa ?? ??? callz addr/prg_page:addr ;Z=1 (equal) 3000h+p0aaaaaaaa ?? ??? callc addr/prg_page:addr ;C=1 (above/equal) 3400h+p0aaaaaaaa ?? ??? calls addr/prg_page:addr ;N=1 (negative) 3800h ?? ??? - 3C00h ?? ??? ret 4000h ?? ??? inc ext_ptr 4400h ?? ??? - 4800h+ssoooooooo ?? ??? cmp ,A/A*2/A*100h/A*10000h ;\ 4C00h+ssoooooooo ?? ??? cmp ,A/A*2/A*100h/A*10000h ; compare 5000h+ssoooooooo ?? NZC cmp A/A*2/A*100h/A*10000h, ; 5400h+ssoooooooo ?? NZC cmp A/A*2/A*100h/A*10000h, ;/ 5800h+ss00000000 ?? ??? mov A,A.?/lsb/lsw/? ;-sign-expand 5C00h ?? ??? - 6000h+nnoooooooo ?? ??? mov A/ext_dta/?/prg_page, 6400h+nnoooooooo ?? ??? mov A/?/?/prg_page, 6800h+nnoooooooo ?? ??? movb ram_dta.lsb/mid/msb/?,cx4ram[] 6C00h+nnoooooooo ?? ??? movb ram_dta.lsb/mid/msb/?,cx4ram[ram_ptr+] 7000h+00oooooooo ?? ??? mov rom_dta,cx4rom[*3] 7400h ?? ??? - 7800h+0noooooooo ?? ??? mov prg_page.lsb/msb, 7C00h+0noooooooo ?? ??? mov prg_page.lsb/msb, 8000h+ssoooooooo ?? ??C add A,A/A*2/A*100h/A*10000h, ;\ 8400h+ssoooooooo ?? ?Z? add A,A/A*2/A*100h/A*10000h, ; 8800h+ssoooooooo ?? ??? sub A,,A/A*2/A*100h/A*10000h ; add/subtract 8C00h+ssoooooooo ?? ??C sub A,,A/A*2/A*100h/A*10000h ; 9000h+ssoooooooo ?? NZC sub A,A/A*2/A*100h/A*10000h, ; 9400h+ssoooooooo ?? NZC sub A,A/A*2/A*100h/A*10000h, ;/ 9800h+00oooooooo ?? ??? smul MH:ML,A, ;\use NOP or other opcode, 9C00h+00oooooooo ?? ??? smul MH:ML,A, ;/result is signed 48bit A000h ?? ??? - A400h ?? ??? - A800h+ssoooooooo ?? ??? xor A,A/A*2/A*100h/A*10000h, ;\ AC00h+ssoooooooo ?? ??? xor A,A/A*2/A*100h/A*10000h, ; B000h+ssoooooooo ?? ?Z? and A,A/A*2/A*100h/A*10000h, ; logic B400h+ssoooooooo ?? ?Z? and A,A/A*2/A*100h/A*10000h, ; B800h+ssoooooooo ?? ??? or A,A/A*2/A*100h/A*10000h, ; BC00h+ssoooooooo ?? ??? or A,A/A*2/A*100h/A*10000h, ;/ C000h+00oooooooo ?? ??? shr A, ;\ C400h+00oooooooo ?? NZ? shr A, ; C800h+00oooooooo ?? ??? sar A, ; CC00h+00oooooooo ?? N?? sar A, ; shift/rotate D000h+00oooooooo ?? ??? ror A, ; D400h+00oooooooo ?? ??? ror A, ; D800h+00oooooooo ?? ??? shl A, ; DC00h+00oooooooo ?? N?? shl A, ;/ E000h+00oooooooo ?? ??? mov ,A E400h ?? ??? - E800h+nnoooooooo ?? ??? movb cx4ram[],ram_dta.lsb/mid/msb/? EC00h+nnoooooooo ?? ??? movb cx4ram[ram_ptr+],ram_dta.lsb/mid/msb/? F000h+00oooooooo ?? ??? xchg ,A F400h ?? ??? - F800h ?? ??? - FC00h ?? ??? stop ;stop, and clear Port [FF5E].bit6 Opcode "Middle" 2bits (Bit9-8) Selects different parameters for some opcodes (eg. lsb/mid/msb, as shown in above descriptions). Opcode Lower 8bits (Bit7-0) Lower Bits : 00h Register A 01h Register MH ;multiply.result.upper.24bit (MSBs are sign-expanded) 02h Register ML ;multiply.result.lower.24bit (same for signed/unsigned) 03h Register ext_dta 08h Register rom_dta 0Ch Register ram_dta 13h Register ext_ptr ;24bit SNES memory address 1Ch Register ram_ptr 2Eh Special snesrom[ext_ptr] (?) ;for use by opcode 612Eh only (?) 50h Constant 000000h 51h Constant FFFFFFh 52h Constant 00FF00h 53h Constant FF0000h 54h Constant 00FFFFh 55h Constant FFFF00h 56h Constant 800000h 57h Constant 7FFFFFh 58h Constant 008000h 59h Constant 007FFFh 5Ah Constant FF7FFFh 5Bh Constant FFFF7Fh 5Ch Constant 010000h 5Dh Constant FEFFFFh 5Eh Constant 000100h 5Fh Constant 00FEFFh 6xh Register R0..R15, aka Port [7F80h+x*3] ;(x=0h..Fh) Lower Bits : nnh Immediate 000000h..0000FFh (unsigned) Lower Bits jump/call: nnh Program Counter LSBs (within 256-word page) (absolute, non-relative) Lower Bits skip: 00h Skip next opcode if selected flag is zero (conditions ?/nc/nz/ns) 01h Skip next opcode if selected flag is set (conditions ?/c/z/s) Lower Bits for opcodes that don't use them (uuuuuuuu): 00h Unused, should be zero SNES Cart Capcom CX4 - Functions -------------------------------- CX4 Functions (as contained in Mega Man X2/X3 ROMs) The CX4 functions are located at SNES address 02:8000-02:9FFF (aka CX4 addresses at PAGE:PC=0000:00..000F:FF with BASE=028000): PAGE:PC__Function_____________________________ 0000:00 build_oam 0001:00 scale_tiles ;<-- (seems to be unused by Mega Man games) 0002:00 hires_sqrt ;<-- (seems to be unused by Mega Man games) 0002:03 sqrt ;<-- (seems to be unused by Mega Man games) 0002:05 propulsion 0002:07 get_sin ;<-- (seems to be unused by Mega Man games) 0002:0A get_cos ;<-- (seems to be unused by Mega Man games) 0002:0D set_vector_length 0002:10 triangle1 0002:13 triangle2 0002:15 pythagorean 0002:1F arc_tan 0002:22 trapeziod 0002:25 multiply 0002:2D transform_coordinates 0003:00 scale_rotate1 0005:00 transform_lines 0007:00 scale_rotate2 0008:00 draw_wireframe_without_clearing_buffer 0008:01 draw_wireframe_with_clearing_buffer 000B:00 disintergrate 000C:00 wave 000E:00 test_set_r0_to_00h ;\sixteen 4-word functions, ... ... ; located at 000E:00+4*(0..15) 000E:3C test_set_r0_to_0Fh ;/setting R0 to 00h..0Fh 000E:40 test_2K_ram_chksum 000E:54 test_square ;R1:R2 = R0*R0 000E:5C test_immediate_register ;copy 16 cpu constants to 30h-bytes RAM 000E:89 test_3K_rom_chksum ;"immediate_rom" Both Mega Man X2 and X3 are containing 1:1 the same CX4 code (the only two differences are different ROM bank numbers for "Wireframe" vertices): Mega Man X2: [0008:3B]="or a,a,28h" [000A:C4]="mov a,28h" ;ROM bank 28h Mega Man X3: [0008:3B]="or a,a,08h" [000A:C4]="mov a,08h" ;ROM bank 08h That differences apply to the US/Canada versions. There be further differences in Japanese and/or European versions(?) SNES Cart DSP-n/ST010/ST011 (pre-programmed NEC uPD77C25 CPU) (23 games) ------------------------------------------------------------------------ Nintendo DSP-n Chips The DSP-n chips are 28pin NEC uPD77C25 CPUs with internal ROM/RAM. There are six versions: DSP-1, DSP-1A, DSP-1B, DSP-2, DSP-3, DSP-4 DSP-1 and DSP-1A contain exactly the same Program/Data ROM. DSP-1B contains a bug-fixed DSP1/1A version. DSP2/3/4 contain custom ROMs. Seta ST010/ST011 Chips These are 64pin chips, containing a slightly extended NEC uPD77C25 with more ROM and RAM, faster CPU clock. 64pin SETA ST010 D96050CW-012 (PCB SHVC-1DS0B-01) 64pin SETA ST011 D96050CW-013 (PCB SHVC-1DS0B-10; with extra transistor) The onchip RAM is battery-backed and is accessible directly via SNES address bus. NEC uPD77C25 Specs --> SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - Registers & Flags & Overview --> SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - ALU and LD Instructions --> SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - JP Instructions Game specific info --> SNES Cart DSP-n/ST010/ST011 - List of Games using that chips --> SNES Cart DSP-n/ST010/ST011 - BIOS Functions DSPn/ST010/ST011 Cartridge Header For DSPn Cartridges: [FFD6h]=03h..05h Chipset = DSPn (plus battery present/absent info) For ST010/ST011 Cartridges: [FFD6h]=F6h Chipset = Custom (plus battery; for the on-chip RAM) [FFD4h]=00h Last byte of Title=00h (indicate early extended header) [FFBFh]=01h Chipset Sub Type = ST010/ST011 Note: The uPD77C25's ROM/RAM aren't counted in the ROM Size, ROM Checksum, SRAM Size (nor Expansion RAM Size) entries. The header (nor extended header) includes no info whether a DSPn game uses a DSP1, DSP2, DSP3, or DSP4, and no info if a ST010/ST011 game uses ST010 or ST011. Ideally, the uPD77C25 ROM-Image should be appended at the end of the SNES ROM-Image. In practice, it's often not there, so there's no way to detect if the game uses this or that uPD77C25 ROM (except for using a list of known Titles or Checksums). SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - Registers & Flags & Overview ------------------------------------------------------------------------- DSP Mapping LoROM Mapping: DSP PCB Mode ROM RAM Bank Data (DR) Status (SR) DSP1/DSP4 SHVC-1B0N-01 LoROM 1M - 30h-3Fh 8000h-BFFFh C000h-FFFFh DSP2 SHVC-1B5B-01 LoROM 1M 32K 20h-3Fh 8000h-BFFFh C000h-FFFFh DSP3 SHVC-1B3B-01 LoROM 1M 8K 20h-3Fh 8000h-BFFFh C000h-FFFFh DSP1 SHVC-2B3B-01 LoROM 2M 8K 60h-6Fh 0000h-3FFFh 4000h-7FFFh ST010 SHVC-1DS0B-01 LoROM 1M - 60h-6xh 0000h 0001h ST011 SHVC-1DS0B-10 LoROM 512K- 60h-6xh 0000h 0001h HiROM Mapping: DSP PCB Mode ROM RAM Bank Data (DR) Status (SR) DSP1 SHVC-1K0N-01 HiROM 4M - 00h-1Fh 6000h-6FFFh 7000h-7FFFh DSP1 SHVC-1K1B-01 HiROM 4M 2K 00h-1Fh 6000h-6FFFh 7000h-7FFFh DSP1B SHVC-1K1X-01 HiROM 4M 2K 00h-0Fh,20h-2Fh 6000h-6FFFh 7000h-7FFFh DSP1B SHVC-2K1X-01 HiROM 2M 2K 00h-0Fh,20h-2Fh 6000h-6FFFh 7000h-7FFFh DSP1B SHVC-2K3X-01 HiROM 2M 8K 00h-0Fh,20h-2Fh 6000h-6FFFh 7000h-7FFFh SFC-Box: DSP PCB Mode ROM RAM Bank Data (DR) Status (SR) DSP1? GS 0871-102 Some of the above PCB names seem to be nonsense (eg. DSP with 2MbyteLoROM hasn't ever been produced, except as prototype board). SNES I/O Ports Type DR SR SRAM DSPn+LoROM (1MB) 30-3F:8000-BFFF 30-3F:C000-FFFF None DSPn+LoROM (1MB+RAM) 20-3F:8000-BFFF 20-3F:C000-FFFF 70-7D:0000-7FFF DSPn+LoROM (2MB+RAM) 60-6F:0000-3FFF 60-6F:4000-7FFF 70-7D:0000-7FFF DSPn+HiROM 00-1F:6000-6FFF 00-1F:7000-7FFF 20-3F:6000-7FFF ? DSPn+HiROM (MAD-2) 00-0F:6000-6FFF 00-0F:7000-7FFF 30-3F:6000-7FFF ? ST010/ST011+LoROM 60-6x:0000 60-6x:0001 68-6F:0000-0FFF All banks in range 00-7F are also mirrored to 80-FF. The "LoROM (2MB)" type wasn't actually produced (but is defined in Nintendo's specs, see book1.pdf page 52). For ST010/ST011, the RAM is contained in the ST01n chip, and is sized 2Kx16bit, whereas the SNES accesses it as 4Kx8bit (even addresses accessing the LSB, odd ones the MSB of the 16bit words). Registers DP 8-bit Data RAM Pointer (ST010/11: 11-bit) RP 10-bit Data ROM Pointer (ST010/11: 11-bit) PC 11-bit Program ROM Counter (ST010/11: 14-bit) STACK 11-bit x 4-levels (for call/ret/irq) (ST010/11: 14-bit x 8-level) K,L two 16bit registers (multiplier input) AccA,AccB two 16bit registers (ALU accumulators) (aka A and B) FlagA,FlagB two 6bit registers with S1,S0,C,Z,OV1,OV0 flags for AccA/AccB TR,TRB two 16bit registers (temporary storage) SR 16bit status I/O register DR parallel I/O data (selectable 8bit/16bit via SR's DRC bit) SI,SO serial I/O data (selectable 8bit/16bit via SR's SOC,SIC bits) FlagA/FlagB S0 Sign Flag (set if result.bit15) Z Zero Flag (set if result=0000h) C Carry Flag (set if carry or borrow) OV0 Overflow Flag (set if result>+7FFFh or result<-8000h) S1 Direction of Last Overflow (if OV0 then S1=S0, else S1=unchanged) OV1 Number of Overflows (0=even, 1=odd) (inverted when OV0 gets set) S0,Z,C,OV0 are "normal" flags as used by various CPUs. S1,OV1 are specials for use with JSA1/JSB1/JNSA1/JNSB1 and JOVA1/JOVB1/JNOVA1/JNOVB1 conditional jump opcodes, or with SGN operand (which equals 8000h-SA1). Examples: or a,a ;SA1=A.Bit15 (undocumented) ;\officially ;\No Addition mov l,sgn ;L=8000h-SA1 (but used by DSP1) ;/SA1=Undefined ;/ mov a,val1 ;\ add a,val2 ;affect OVA0 (and, if OVA0 set, also SA1) ; Adding jnova0 skip0 ;test OVA0 ; Two Values mov a,sgn ;A=8000h-SA1 (saturate max=+7FFFh, min=-8000h) ; skip0: ;/ ;below works with up to three 16bit values, ;\ ;would also work with hundreds of small 8bit values, ; ;ie. works if multiple overflows occur in opposite directions ; ;but doesn't work if two overflows occur in same direction) ; Adding xor a,a ;clear OVA1 ; More Values add a,val1 ;no overflow OVA1 yet ; add a,val2 ;this may set OVA1 ; add a,val3 ;this may set/reset OVA1 ; jnova1 skip1 ;test OVA1 (skip if 0 or 2 overflows occurred) ; mov a,sgn ;A=8000h-SA1 (done if 1 overflow occurred) ; skip1: ;/ Note: The JSA1/JSB1/JNSA1/JNSB1 and JOVA1/JOVB1/JNOVA1/JNOVB1 opcodes aren't used by any of the DSP1-DSP4 or ST010-ST011 games. The SGN operand is used only by DSP1/DSP1A/DSP1B (once in conjuntion with JNOVA0, which seems to be ALWAYS skipping the SGN-part, and once in conjunction with an OR opcode, which loads an undocumented value to SA1). Status Register (SR) 15 RQM (R) Request for Master (0=Busy internally, 1=Request external I/O) 14-13 USF1-0 User's Flags (general purpose) (0=Low, 1=High) 12 DRS (R) DR Status (for 16bit DR mode; 2x8bit) (0=Ready, 1=Busy) 11 DMA Direct Memory Access Mode (0=Non-DMA, 1=DMA) 10 DRC DR Control, parallel data length (0=16bit, 1=8bit) 9 SOC SO Control, serial data output length (0=16bit, 1=8bit) 8 SIC SI Control, serial data input length (0=16bit, 1=8bit) 7 EI Interrupt Enable (0=Disable, 1=Enable) 6-2 N/A (R?) Unused/Reserved (should be zero) (read=always zero?) 1-0 P1-0 Output to P0,P1 pins (0=Low, 1=High) SR.Bit15-8 are output to D7-0 pins (when /CS=LOW, /RD=LOW, /WR=HIGH, A0=HIGH). SR.Bit1-0 are always output to P1-0 pins. RQM RQM gets set when the uPD77C25 does read/write its DR register, and gets cleared when the remote CPU does complete reading/writing DR (complete: when DRC=8bit, or when DRC=16bit and DRS=Ready). DRS gets toggled in 16bit mode after each 8bit fragment being read/written by remote CPU (the fragments are transferred LSB first, then MSB). DMA The DRQ-pin isn't connected in SNES cartridges (since the DMA protocol isn't compatible with the SNES), so there's no real DMA support. However, the uPD77C25 (or at least the ST011) is fast enough to handle SNES-DMA transfers by software. Software for DSP2 uses the 65C816's block-transfer command (which is a bit slower than DMA, but, like DMA, doesn't use handshaking). Memory 2048 x 24bit Instruction ROM/PROM Opcodes 2048 x 1bit Instruction PROM Protection Flags (0=Lock, 1=Allow Dumping) 1024 x 16bit Data ROM/PROM 256 x 16bit Data RAM ROM-Images DSPn/ST010/ST011 ROM-images consist of the Program ROM followed by the Data ROM. Caution: There are several differently formatted dumps of these ROMs: Oldest Files 10K (DSPn) --> Big-Endian, 24bit-to-32bit padding Old Files 8K (DSPn) or 52K (ST01n) --> Big-Endian, raw 24bit opcodes Newer Files 8K (DSPn) or 52K (ST01n) --> Little-Endian, raw 24bit opcodes Preferred would be the "Newer" format. To detect the endianness: All existing ROMs contain "JRQM $" within first four opcodes (97C00xh, with x=0/4/8/C depending on whether it is 1st/2nd/3rd/4th opcode). Ie. possible cases are: Oldest Files 97h,C0h,0xh,FFh ;big-endian 24bit, plus FFh-padding byte Old Files 97h,C0h,0xh ;big-endian 24bit, without padding Newer Files 0xh,C0h,97h ;little-endian 24bit, without padding If the "JRQM $" opcode doesn't exist, best default to "Newer" format (that might happen only with uncommon homebrewn DSP ROMs, not with the original ROMs). Ideally, the ROM-Image should be attached at the end of the SNES Cartridge ROM-Image (when doing that, best remove any 200h-byte header, since the existing headers don't define if/how to adjust their size-entries for DSPn/ST01n ROMs). Chips uPD77C25 Mask ROM uPD77P25 Programmable PROM/UVEPROM uPD77C25 Opocde Encoding All opcodes are 24bit wide. All opcodes are executed in one clock cycle (at max=8.192MHz clock). 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +--+--+-----+-----------+--+-----+-----------+--+-----------+-----------+ |0 |RT| P | ALU opcode|A | DPL | DPH |RP| SRC | DST | ALU +--+--+-----+-----------+--+-----+-----------+--+-----------+-----+-----+ |1 |0 | BRCH (jump opcode) | NA (11bit Next Address) | - | JP +--+--+--------------------------+--------------------+-----+-----+-----+ |1 |1 | ID (16bit Immediate Data) | - | DST | LD +--+--+-----------------------------------------------+-----+-----------+ uPD77C20 Opocde Encoding (older pre-77C25 version) (not used in SNES) All opcodes are 23bit wide. All opcodes are executed in one clock cycle (at max=4.xxxMHz clock). 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +--+--+-----+-----------+--+-----+--------+--+-----------+-----------+ |0 |RT| P | ALU opcode|A | DPL | DPH |RP| SRC | DST | ALU +--+--+-----+-----------+--+-+---+--------+--+-----------+-----+-----+ |1 |0 | BRCH (jump opcode) | NA (9bit Next Address) | - | JP +--+--+----------------------+--------------------+---+--+-----+-----+ |1 |1 | ID (16bit Immediate Data) |- | DST | LD +--+--+-----------------------------------------------+--+-----------+ DPH is only 3bit (M0..M7), BRCH is only 8bit (without JDPLN0, JDPLNF opcodes). Data ROM entries are only 13bit wide (sign-expanded to 16bit... or left-shifted to 16bit?). NA is only 9bit. Internal clock is only 4MHz. TRB register is not supported. SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - ALU and LD Instructions -------------------------------------------------------------------- ALU Instructions (Artithmetic/Logical Unit) 23 0 Must be 0 for ALU opcodes 22 RT Return after ALU (0=No/Normal, 1=Yes/Return from Call/Interrupt) 21-20 P ALU input P (0=RAM[DP], 1=IDB(SRC), 2=K*L*2/10000h, 3=K*L*2) 19-16 ALU ALU opcode 15 A ALU input/output Q (0=AccA, 1=AccB) 14-13 DPL Data RAM Pointer DP.3-0 adjust (0=DPNOP, 1=DPINC, 2=DPDEC, 3=DPCLR) 12-9 DPH Data RAM Pointer DP.7-4 adjust (0..0Fh=M0..MF) (XOR by that value) 8 RP Data ROM Pointer RP.9-0 adjust (0=RPNOP, 1=RPDEC) 7-4 SRC Source (copied to DST, and, for ALU, to "IDB" internal data bus) 3-0 DST Destination (copied from SRC) Allows to combine an ALU operation with memory load & store, DP/RP pointer adjustment, optional RET from CALL, along with the K*L*2 multiplication. LD Instructions (Load) 23 1 Must be 1 for LD opcodes 22 1 Must be 1 for LD opcodes 21-6 ID 16bit Immediate 5-4 - Reserved (should be zero) 3-0 DST Destination (copied from ID) Load is mainly for initialization purposes & other special cases (normally it's faster load immediates from Data ROM, via SRC=RO in ALU opcodes). ALU Opcode (Bit19-16) Hex Name ;Expl. S1 S0 Cy Zf OV1 OV0 00h NOP ;No operation - - - - - - 01h OR ;Acc = Acc OR P sf sf 0 zf 0 0 02h AND ;Acc = Acc AND P sf sf 0 zf 0 0 03h XOR ;Acc = Acc XOR P sf sf 0 zf 0 0 04h SUB ;Acc = Acc - P * sf cy zf * ov 05h ADD ;Acc = Acc + P * sf cy zf * ov 06h SBB ;Acc = Acc - P - OtherCy * sf cy zf * ov 07h ADC ;Acc = Acc + P + OtherCy * sf cy zf * ov 08h DEC ;Acc = Acc - 1 * sf cy zf * ov 09h INC ;Acc = Acc + 1 * sf cy zf * ov 0Ah NOT ;Acc = Acc XOR FFFFh sf sf 0 zf 0 0 0Bh SAR1 ;Acc = Acc/2 ;signed sf sf cy zf 0 0 0Ch RCL1 ;Acc = Acc*2 + OtherCy sf sf cy zf 0 0 0Dh SLL2 ;Acc = Acc*4 + 3 sf sf 0 zf 0 0 0Eh SLL4 ;Acc = Acc*16 + 15 sf sf 0 zf 0 0 0Fh XCHG ;Acc = Acc ROL 8 sf sf 0 zf 0 0 ADD/ADC/SUB/SBB/INC/DEC set "S1=sf" and "OV1=OV1 XOR 1" upon overflow (and leave S1 and OV1 both unchanged if no overflow). OtherCy is the incoming carry flag from other accumulator (ie. Cy from FlagA when using AccB). Note: "NOT" is called "CMP"=Complement in official syntax; it isn't Compare. "SAR/RCL/SLL" are called "SHR/SHL/SHL" in official syntax; though they aren't "normal" logical shifts. OR/AND/XOR/NOT/SAR/RCL/SLL/XCHG do offially set S1=Undefined (but actually it seems to be S1=sf; required for loopings in "Super Air Diver 2"; which uses OR opcode followed by SGN operand). Multiplier After each instruction (namely after any ALU and LD instructions that have changed K or L registers), the hardware computes K*L*2 (signed 16bit*16bit->32bit). Result on overflows (-8000h*-8000h*2) is unknown. SRC Field (Bit7-4) and DST Field (Bit3-0) Hex SRC (Source, Bit7-4) DST (Destination, Bit3-0) 00h TRB (Temporary B) @NON (none) 01h A (AccA) @A (AccA) 02h B (AccB) @B (AccB) 03h TR (Temporary A) @TR (Temporary A) 04h DP (Data RAM Pointer) @DP (Data RAM Pointer) 05h RP (Data ROM Pointer) @RP (Data ROM Pointer) 06h RO (ROM[RP]) @DR (parallel I/O port) 07h SGN (saturation = 8000h-SA1) @SR (status register) 08h DR (parallel I/O port) @SOL (SO serial LSB first) 09h DRNF (DR without RQM/DRQ) @SOM (SO serial MSB first) 0Ah SR (status register) @K (Multiply Factor A) 0Bh SIM (SI serial MSB first) @KLR (K=SRC and L=ROM[RP]) 0Ch SIL (SI serial LSB first) @KLM (L=SRC and K=RAM[DP OR 40h]) 0Dh K (Multiply Factor A) @L (Multiply Factor B) 0Eh L (Multiply Factor B) @TRB (Temporary B) 0Fh MEM (RAM[DP]) @MEM (RAM[DP]) When not using SRC: specify "NON" in source code, and 00h (a dummy TRB fetch) in binary code. Following combinations are prohibited in ALU instructions: DST field = @KLR or @KLM combined with SRC field = K or L register DST field and SRC field specify the same register P-SELECT field = RAM, DST field = @MEM (for ALU operation) Everything else should be allowed (included ALU with SRC=Acc, eg ADD AccA,AccA) Variants The older uPD77C20 doesn't support TRB: SRC=00h is NON (=zero/undefined?), DST=0Eh (and also DST=00h) is @NON. Opcodes are only 23bit wide (strip ALU.Bit11/MSB of DPH, and LD.Bit5/Reserved). SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - JP Instructions ------------------------------------------------------------ JP Instructions (Jump/Call) 23 1 Must be 1 for JP opcodes 22 0 Must be 0 for JP opcodes 21-13 BRC Jump/Call opcode 12-2 NA 11bit Next Address Bit0-10 (000h..7FFh, in 24-bit word steps) 1-0 - Reserved (should be zero) (ST010/ST011: Bit12-11 of NA) BRCH Opcode (Bit21-13) Binary Hex Op Expl. 000000000 000h JMPSO * Unconditional jump to SO register 100000000 100h JMP Unconditional jump 0000h..1FFFh 100000001 101h JMP * Unconditional jump 2000h..3FFFh 101000000 140h CALL Unconditional call 0000h..1FFFh ;\return via RT-bit 101000001 141h CALL * Unconditional call 2000h..3FFFh ;/in ALU opcodes 010000000 080h JNCA CA = 0 ;\ 010000010 082h JCA CA = 1 ; carry flag of AccA/AccB 010000100 084h JNCB CB = 0 ; 010000110 086h JCB CB = 1 ;/ 010001000 088h JNZA ZA = 0 ;\ 010001010 08Ah JZA ZA = 1 ; zero flag of AccA/AccB 010001100 08Ch JNZB ZB = 0 ; 010001110 08Eh JZB ZB = 1 ;/ 010010000 090h JNOVA0 OVA0 = 0 ;\ 010010010 092h JOVA0 OVA0 = 1 ; overflow flag for last operation 010010100 094h JNOVB0 OVB0 = 0 ; 010010110 096h JOVB0 OVB0 = 1 ;/ 010011000 098h JNOVA1 OVA1 = 0 ;\ 010011010 09Ah JOVA1 OVA1 = 1 ; overflow flag for last 3 operations 010011100 09Ch JNOVB1 OVB1 = 0 ; (set if 1 or 3 overflows occurred) 010011110 09Eh JOVB1 OVB1 = 1 ;/ 010100000 0A0h JNSA0 SA0 = 0 ;\ 010100010 0A2h JSA0 SA0 = 1 ; sign bit (ie. Bit15) of AccA/AccB 010100100 0A4h JNSB0 SB0 = 0 ; 010100110 0A6h JSB0 SB0 = 1 ;/ 010101000 0A8h JNSA1 SA1 = 0 ;\ 010101010 0AAh JSA1 SA1 = 1 ; extra sign bit ("Bit16") 010101100 0ACh JNSB1 SB1 = 0 ; indicating direction of overflows 010101110 0AEh JSB1 SB1 = 1 ;/ 010110000 0B0h JDPL0 DPL = 00h ;\ 010110001 0B1h JDPLN0 DPL <> 00h ; lower 4bit of DP (Data RAM Pointer) 010110010 0B2h JDPLF DPL = 0Fh ; 010110011 0B3h JDPLNF DPL <> 0Fh ;/ 010110100 0B4h JNSIAK SI ACK = 0 ;\ 010110110 0B6h JSIAK SI ACK = 1 ; serial I/O port (SI/SO serial in/out) 010111000 0B8h JNSOAK SO ACK = 0 ; 010111010 0BAh JSOAK SO ACK = 1 ;/ 010111100 0BCh JNRQM RQM = 0 ;\parallel I/O port (DR data register) 010111110 0BEh JRQM RQM = 1 ;/ Jump addresses should be specified 24bit word units (not in byte units). (*) Opcodes 000h,101h,141h supported on ST010/ST011 only. On that CPU, PC.bit13 can be manipulated by unconditional jump/call/ret (whilst conditional jumps affect only PC.bit12-0). Reset (Vector 000h) Reset is triggered when RST pin is high, and does set PC=000h, FlagA=00h, FlagB=00h, SR=0000h, DRQ=0, SORQ=0, SI.ACK=0, SO.ACK=0, and RP=3FFh. Other registers and Data RAM are left unchanged. Interrupts (Vector 100h) Interrupts are triggered on raising edge of INT pin. If interrupts are enabled (in SR register), the CPU jumps to address 100h, and pushes PC on stack, the interrupts are NOT automatically disabled. Variants The older uPD77C20 doesn't support JDPLN0 and JDPLNF. Opcodes are only 23bit wide (strip JP.Bit13/LSB of BRCH). And PC/NA is only 9bit wide (replace JP.Bit3-2 by Reserved). SNES Cart DSP-n/ST010/ST011 - List of Games using that chips ------------------------------------------------------------ Games using DSPn/ST01n chips The DSP-1/1A/1B is used by around 16..19 games: Ace Wo Nerae! 3D Tennis (DSP-1A) (1993) Telenet Japan (JP) Armored Trooper Votoms: The Battling Road (1993) Takara (JP) Ballz 3D, and 3 Jigen Kakutou Ballz (DSP-1B) (1994) PF Magic/Accolade (NA) Battle Racers (1995) Banpresto (JP) Bike Daisuki! Hashiriya Kon - Rider's Spirits (1994) Genki/NCS (JP) Final Stretch (1993) Genki/LOZC (JP) Korean League (aka Hanguk Pro Yagu) (1993) Jaleco (KO) Lock-On / Super Air Diver (1993) Vic Tokai Michael Andretti's Indy Car Challenge (1994) Genki/Bullet-Proof (NA) (JP) Pilotwings (1991) Nintendo EAD (NA) (JP) (EU) (DSP-1) (visible DSP1 glitch) Shutokou Battle'94: K.T. Drift King (1994) Genki/Bullet-Proof (JP) Shutokou Battle 2: Drift King K.T. & M.B. (1995) Genki/Bullet-Proof (JP) Super 3D Baseball (?) (is that same as Super Bases Loaded 2 ?) Super Air Diver 2 (1995) Asmik (JP) Super Bases Loaded 2 (1994) Jaleco (NA) (JP) Super F1 Circus Gaiden (1995) Nichibutsu (JP) Super Mario Kart (DSP-1/DSP-1B) (1992) Nintendo EAD (NA) (JP) (EU) Suzuka 8 Hours (1993) Namco (NA) (JP) Touge Densetsu: Saisoku Battle (1996) Genki/Bullet-Proof Software (JP) ? The other five versions are used by only one game each: DSP-2: Dungeon Master (DSP-2) (1992) FTL Games/JVC Victor (JP) DSP-3: SD Gundam GX (DSP-3) (1994) BEC/Bandai (JP) DSP-4: Top Gear 3000 (DSP-4) (1995) Gremlin Interactive/Kemco (NA) (JP) (EU) ST010: F1 Race of Champions / Exhaust Heat II (1993) SETA Corp. (NA) (JP) ST011: Hayazashi Nidan Morita Shogi (1993) Random House/SETA Corp. (JP) SNES Cart DSP-n/ST010/ST011 - BIOS Functions -------------------------------------------- DSP1 Commands When requesting data from an external device the DSP is oblivious to the type of operation that occurs to the Data Register. Writing to the Data register will update the contents of the register and allow the DSP to continue execution. Reading from the Data Register will also allow the DSP to continue execution. On completion of a valid command the Data Register should contain the value 0x80. This is to prevent a valid command from executing should a device read past the end of output. 00h 16-bit Multiplication 10h Inverse Calculation 20h 16-bit Multiplication 01h Set Attitude A 11h Set Attitude B 21h Set Attitude C 02h Projection Parameter Setting 03h Convert from Object to Global Coordinate A 13h Convert from Object to Global Coordinate B 23h Convert from Object to Global Coordinate C 04h Trigonometric Calculation 14h 3D Angle Rotation 06h Object Projection Calculation 08h Vector Size Calculation 18h Vector Size Comparison 28h Vector Absolute Value Calculation (bugged) (fixed in DSP1B) 38h Vector Size Comparison 0Ah Raster Data Calculation 0Bh Calculation of Inner Product with the Forward Attitude A and a Vector 1Bh Calculation of Inner Product with the Forward Attitude B and a Vector 2Bh Calculation of Inner Product with the Forward Attitude C and a Vector 0Ch 2D Coordinate Rotation 1Ch 3D Coordinate Rotation 0Dh Convert from Global to Object Coordinate A 1Dh Convert from Global to Object Coordinate B 2Dh Convert from Global to Object Coordinate C 0Eh Coordinate Calculation of a selected point on the Screen 0Fh Test Memory Test 1Fh Test Transfer DATA ROM 2Fh Test ROM Version (0100h=DSP1/DSP1A, 0101h=DSP1B) Command 28h is bugged in DSP1/DSP1A (fixed in DSP1B) bug is evident in Pilotwings (Plane Demo). DSP2 Commands (Dungeon Master) This chip does - amazingly - assist 3D labyrinth drawing operations that are normally implemented on ZX81 computers. 01h Convert Bitmap to Bitplane Tile 03h Set Transparent Color 05h Replace Bitmap using Transparent Color 06h Reverse Bitmap 07h Add 08h Subtract 09h Multiply (bugged) (used in Dungeon Master japanese/v1.0) 0Dh Scale Bitmap 0Fh Process Command (dummy NOP command for re-synchronisation) 10h..FFh Mirrors of 00h..0Fh DSP3 Commands (SD Gundam GX) The DSP functions inherently similiar to the DSP1 with respect to command parsing and execution. On completion of a valid command the Data Register should contain the value 0x80. 02h Unknown 03h Calculate Cell Offset 06h Set Board Dimensions 07h Calculate Adjacent Cell 18h Convert Bitmap to Bitplane 38h Decode Shannon-Fano Bitstream (USF1 bit in SR register = direction) 1Eh Calculate Path of Least Travel 3Eh Set Start Cell 0Fh Test Memory Test 1Fh Test Transfer DATA ROM 2Fh Test ROM Version (0300h=DSP3) DSP4 Commands (Top Gear 3000) On completion of a valid command the Data Register should contain the value 0xffff. This is to prevent a valid command from executing should an external device read past the end of output. Unlike previous DSP programs, all data transfers are 16-bit. xxh Unknown 13h Test Transfer DATA ROM 14h Test ROM Version (0400h=DSP4) 15h..1Fh Unused (no function) 20h..FFh Mirrors of 10h..1Fh ST010 Commands Commands are executed on the ST-0010 by writing the command to 0x0020 and setting bit7 of 0x0021. Bit7 of 0x0021 will stay set until the Command has completed, at which time output data will be available. See individual commands for input and output parameter addresses. 00h Set RAM[0010h]=0000h 01h Unknown Command 02h Sort Driver Placements 03h 2D Coordinate Scale 04h Unknown Command 05h Simulated Driver Coordinate Calculation 06h Multiply 07h Raster Data Calculation 08h 2D Coordinate Rotation 09h..0Fh Mirrors of 01h..07h 10h..FFh Mirrors of 00h..0Fh The ST010 BIOS functions are more or less useless and don't increase the performance or quality of the game (the only feature that is used is the battery-backed on-chip RAM, aside from that, the powerful chip is a waste of resources). Note: The ST010 is also used in "Twin Eagle II" (arcade game, not a SNES game). ST011 Commands (japanese chess engine) 00h Unused (no function) 01h ? 02h ? 03h ? 04h ? 05h ? 06h ? 07h ? 08h Unused (no function) 09h ? 0Ah Unused (no function) 0Bh ? 0Ch ? 0Dh Unused (no function) 0Eh ? 0Fh ? 10h..F0h Unused (no function) F1h Selftest1 ? F2h Selftest2 ? F3h Dump Data ROM (bugged, doesn't work due to wrong loop address) F4h..FFh Unused (no function) SNES Cart Seta ST018 (pre-programmed ARM CPU) (1 game) ------------------------------------------------------ Seta ST018 - 160pin SETA D6984 ST018 chip (PCB SHVC-1DE3B-01) The chip is used by a single game only: Hayazashi Nidan Morita Shogi 2 (ST018) (1995) Random House/SETA Corp. (JP) ARM CPU Reference --> ARM CPU Reference ST018 Memory Map (ARM Side) 00000000h ROM 128K -- with 32bit databus 20000000h 40000000h I/O ports 60000000h probably (absent) external ROM/EPROM ;can redirect exceptions here? 80000000h A0000000h ROM 32K ? -- with 8bit databus C0000000h E0000000h RAM 16K ST018 I/O Map (ARM Side) 40000010h.R Data from SNES (reset STAT.3 and get latched data-to-arm) 40000020h.R Status (get STAT) 40000000h.W Data to SNES (set STAT.0 and latch data-to-snes) 40000010h.W Flag to SNES (set STAT.2 on writing any value) (IRQ?) 40000020h.W Config 1 40000024h.W Config 2 40000028h.W Config 3 4000002Ch.W Config 4 ST018 I/O Map (SNES Side) 3800h.R Data to SNES (reset STAT.0 and get latched data-from-arm) 3802h.R Ack Flag (reset STAT.2 and get dummy data?) 3804h.R Status (get STAT) 3802h.W Data from SNES (set STAT.3 and latch data-from-snes) 3804h.W Reset ARM (00h=Normal, 01h=HardReset, FFh=SoftReset?) ST018 Status Register There are two status registers, ARM:40000020h.R and SNES:3804h.R. Bit0 of that two registers appears to be same for ARM and SNES, the other are used only by either CPU (as shown below), although they might be actually existing on both CPUs, too. 0 SNES ARM ARM-to-SNES Data Present (0=No, 1=Yes) 1 - - Unknown/Unused (unknown) 2 SNES - ARM-to-SNES IRQ Flag? (0=No, 1=Yes) 3 - ARM SNES-to-ARM Data Present (0=No, 1=Yes) 4 SNES - Fatal Problem (0=Okay, 1=SNES skips all transfers) 5 - ARM Redirect ARM to 600000xxh (0=No, 1=Yes) 6 SNES - Unused (unless [FF41h]<>00h) (0=Busy, 1=Ready) 7 SNES - ARM Reset Ready (0=Busy, 1=Ready) STAT.2 might be IRQ signal (ST018.pin12 connects to SNES./IRQ pin), but the Shogi game contains only bugged IRQ handler (without ACK); instead it's just polling STAT.2 by software. ST018 Component List PCB "SHVC-1DE3B-01, (C) 1995 Nintendo" U1 32pin LH534BN6 LoROM 512Kx8 (alternately 40pin) (PCB: "4/8/16/32M") U2 28pin LH52A64N SRAM 8Kx8 (PCB: "64K") U3 160pin Seta ST018, (C)1994-5 SETA (PCB: "ST0018/ST0019") U4 16pin 74LS139A (demultiplexer) (PCB: "LS139") U5 8pin /\\ 532 26A (battery controller) (PCB: "MM1026") U6 18pin FA11B CIC (PCB: "CIC") BATT 2pin Maxell CR2032T (3V battery for U2) X1 3pin [M]21440C 21.44MHz (plastic oscillator) (PCB: "21.44MHz") P1 62pin SNES Cart Edge connector (plus shield) Note: U5 is located on PCB back side for some weird reason. The chip name is "ST018", although the PCB text layer calls it "ST0018" (with double zero). ST018 ARM Timings (mostly unknown) The ARM CPU is clocked by a 21.44MHz oscillator, but unknown if there is some internal clock multiplier/divider for the actual CPU clock (if so, then it might even be controlled via I/O ports for low power mode purposes). Unknown if there is any code/data cache, and unknown if there are any memory waitstates (if so, timings might differ for 8bit/32bit access, for sequential/nonsequential access, and for different memory regions). ST018 ARM Memory (mostly unknown) Unknown if there any memory mirrors, or unused regions (possibly filled with 00h, or FFh, or with garbage), or regions that do trap memory exceptions. Unknown if there any unused extra I/O ports or memory regions. The 128K ROM, I/O area, and 16K RAM seem to support both 8bit and 32bit access. The 32K ROM is used only with 8bit access; unknown what happens on 32bit access to that region. Effects on misaligned 32bit RAM writes are probably ignoring the lower address bits, and writing to "ADDR AND (NOT 3)" (at least it like so on ARMv4/ARMv5) (the case is important because there's a ST018 BUG that does "str r14,[r2,2]", which should be 8bit STRB, not mis-aligned 32bit STR). ST018 ARM Other Stuff (mostly unknown) Unknown if there's any coprocessor or SMULL/UMULL extension (the BIOS doesn't use such stuff, but CP14/CP15 are more or less common to be present). The CPU seems to use ARMv3 instruction set (since the BIOS is using ARMv3 features: 32bit program counter and CPSR register; but isn't using any ARMv4 features such like BX, LDRH, Sys mode, or THUMB code) (also possible that ARMv4 processors haven't even been available at time when the ST018 was developed in 1994/1995). ST018 Commands 00h..9Fh Unused A0 Debug: Reboot A1 Debug: Get Version 4 ;\maybe major/minor version (or vice-versa) A2 Debug: Get Version 5 ;/ A3 Debug: Dump 80h bytes from address NNNNNNNNh A4 Debug: Dump NNh bytes from address NNNNNNNNh A5 Debug: Write NNh bytes to address NNNNNNNNh A8 do_high_level_func_0_1_with_reply_flag A9 do_high_level_func_1_1_with_reply_flag AA UploadBoardAndSomethingElse (send 9x9 plus 16 bytes to 0E0000400h) AB Write_1_byte_to_0E0000468h (usually value=02h) AC Read ARM "R12" register value AD Read 1 byte from 0E0000464h (LEN) AE do_high_level_func_2_with_reply_flag AF Read 1 byte from 0E0000464h (LEN+1)*2 B0 Read (LEN+1)*2 bytes from 0E000046Ch ;LEN as from cmd ADh/AFh B1 do_high_level_func_0_X_Y_with_reply_flag (send 2 bytes: X,Y) B2 do_high_level_func_1_X_Y_with_reply_flag (send 2 bytes: X,Y) B3 do_high_level_func_4_with_1_reply_byte (recv 1 byte) B4 do_high_level_func_5_with_1_reply_byte (recv 1 byte) B5 do_high_level_func_6_with_1_reply_byte (recv 1 byte) B6 do_high_level_func_7_with_1_reply_byte (recv 1 byte) B7 do_high_level_func_3_with_reply_flag B8h..F0h Unused F1 Selftest 1 ;if response.bit2=1, receive 2 error bytes F2 Selftest 2 ;if response<>00h, receive 2 error bytes F3 Debug: Dump 128Kbyte ROM from 00000000h ;\for HEX-DUMP display F4 Debug: Dump 32Kbyte ROM from A0000000h ;/ F5 Debug: Get Chksum for 128K ROM at 00000000h F6 Debug: Get Chksum for 32K ROM at A0000000h F7h..FFh Unused Note: Command A5h allows to write code to RAM, and also to manipulate return addresses on stack, thus allowing to execute custom ARM code. ARM CPU Reference ----------------- The ARM CPU is a 32bit RISC (Reduced Instruction Set Computer) processor, designed by ARM (Advanced RISC Machines). General ARM Information --> ARM Register Set --> ARM Flags & Condition Field (cond) --> ARM 26bit Memory Interface --> ARM Exceptions The ARM Instruction Set --> ARM Instruction Summary --> ARM Opcodes: Branch and Branch with Link (B, BL, SWI) --> ARM Opcodes: Data Processing (ALU) --> ARM Opcodes: PSR Transfer (MRS, MSR) --> ARM Opcodes: Multiply and Multiply-Accumulate (MUL, MLA) --> ARM Opcodes: Memory: Block Data Transfer (LDM, STM) --> ARM Opcodes: Memory: Single Data Transfer (LDR, STR) --> ARM Opcodes: Memory: Single Data Swap (SWP) --> ARM Opcodes: Coprocessor Instructions (MRC/MCR, LDC/STC, CDP) Further Information --> ARM Pseudo Instructions and Directives --> ARM Instruction Cycle Times --> ARM Versions ARM Register Set ---------------- Overview The following table shows the ARM7TDMI register set which is available in each mode. There's a total of 37 registers (32bit each), 31 general registers (Rxx) and 6 status registers (xPSR). Note that only some registers are 'banked', for example, each mode has it's own R14 register: called R14, R14_fiq, R14_svc, etc. for each mode respectively. However, other registers are not banked, for example, each mode is using the same R0 register, so writing to R0 will always affect the content of R0 in other modes also. System/User FIQ Supervisor Abort IRQ Undefined -------------------------------------------------------------- R0 R0 R0 R0 R0 R0 R1 R1 R1 R1 R1 R1 R2 R2 R2 R2 R2 R2 R3 R3 R3 R3 R3 R3 R4 R4 R4 R4 R4 R4 R5 R5 R5 R5 R5 R5 R6 R6 R6 R6 R6 R6 R7 R7 R7 R7 R7 R7 -------------------------------------------------------------- R8 R8_fiq R8 R8 R8 R8 R9 R9_fiq R9 R9 R9 R9 R10 R10_fiq R10 R10 R10 R10 R11 R11_fiq R11 R11 R11 R11 R12 R12_fiq R12 R12 R12 R12 R13 (SP) R13_fiq R13_svc R13_abt R13_irq R13_und R14 (LR) R14_fiq R14_svc R14_abt R14_irq R14_und R15 (PC) R15 R15 R15 R15 R15 -------------------------------------------------------------- CPSR CPSR CPSR CPSR CPSR CPSR -- SPSR_fiq SPSR_svc SPSR_abt SPSR_irq SPSR_und -------------------------------------------------------------- R0-R12 Registers (General Purpose Registers) These thirteen registers may be used for whatever general purposes. Basically, each is having same functionality and performance, ie. there is no 'fast accumulator' for arithmetic operations, and no 'special pointer register' for memory addressing. R13 Register (SP) This register is used as Stack Pointer (SP) in THUMB state. While in ARM state the user may decided to use R13 and/or other register(s) as stack pointer(s), or as general purpose register. As shown in the table above, there's a separate R13 register in each mode, and (when used as SP) each exception handler may (and MUST!) use its own stack. R14 Register (LR) This register is used as Link Register (LR). That is, when calling to a sub-routine by a Branch with Link (BL) instruction, then the return address (ie. old value of PC) is saved in this register. Storing the return address in the LR register is obviously faster than pushing it into memory, however, as there's only one LR register for each mode, the user must manually push its content before issuing 'nested' subroutines. Same happens when an exception is called, PC is saved in LR of new mode. Note: In ARM mode, R14 may be used as general purpose register also, provided that above usage as LR register isn't required. R15 Register (PC) R15 is always used as program counter (PC). Note that when reading R15, this will usually return a value of PC+nn because of read-ahead (pipelining), whereas 'nn' depends on the instruction. CPSR and SPSR (Program Status Registers) (ARMv3 and up) The current condition codes (flags) and CPU control bits are stored in the CPSR register. When an exception arises, the old CPSR is saved in the SPSR of the respective exception-mode (much like PC is saved in LR). For details refer to chapter about CPU Flags. ARM Flags & Condition Field (cond) ---------------------------------- ARM Condition Field {cond} All ARM instructions can be conditionally executed depending on the state of the CPSR flags (C,N,Z,V). The respective suffixes {cond} must be appended to the mnemonics. For example: BEQ = Branch if Equal, MOVMI = Move if Signed. Code Suffix Flags Meaning 0: EQ Z=1 equal (zero) (same) 1: NE Z=0 not equal (nonzero) (not same) 2: CS/HS C=1 unsigned higher or same (carry set) 3: CC/LO C=0 unsigned lower (carry cleared) 4: MI N=1 negative (minus) 5: PL N=0 positive or zero (plus) 6: VS V=1 overflow (V set) 7: VC V=0 no overflow (V cleared) 8: HI C=1 and Z=0 unsigned higher 9: LS C=0 or Z=1 unsigned lower or same A: GE N=V greater or equal B: LT N<>V less than C: GT Z=0 and N=V greater than D: LE Z=1 or N<>V less or equal E: AL - always (the "AL" suffix can be omitted) F: NV - never (ARMv1,v2 only) (Reserved on ARMv3 and up) Execution Time: If condition=false: 1S cycle. Otherwise: as specified for the respective opcode. Current Program Status Register (CPSR) Bit Expl. 31 N - Sign Flag (0=Not Signed, 1=Signed) ;\ 30 Z - Zero Flag (0=Not Zero, 1=Zero) ; Condition 29 C - Carry Flag (0=Borrow/No Carry, 1=Carry/No Borrow) ; Code Flags 28 V - Overflow Flag (0=No Overflow, 1=Overflow) ;/ 27 Q - Reserved (used as Sticky Overflow in ARMv5TE and up) 26-8 - - Reserved (For future use) - Do not change manually! 7 I - IRQ disable (0=Enable, 1=Disable) ;\ 6 F - FIQ disable (0=Enable, 1=Disable) ; Control 5 T - Reserved (used as THUMB flag in ARMv4T and up) ; Bits 4-0 M4-M0 - Mode Bits (See below) ;/ CPSR Bit 27-8,5: Reserved Bits These bits are reserved for possible future implementations. For best forwards compatibility, the user should never change the state of these bits, and should not expect these bits to be set to a specific value. CPSR Bit 7-0: Control Bits (I,F,T,M4-M0) These bits may change when an exception occurs. In privileged modes (non-user modes) they may be also changed manually. The interrupt bits I and F are used to disable IRQ and FIQ interrupts respectively (a setting of "1" means disabled). The Mode Bits M4-M0 contain the current operating mode. Binary Hex Dec Expl. 0xx00b 00h 0 - Old User ;\26bit Backward Compatibility modes 0xx01b 01h 1 - Old FIQ ; (supported only on ARMv3, except ARMv3G, 0xx10b 02h 2 - Old IRQ ; and on some non-T variants of ARMv4) 0xx11b 03h 3 - Old Supervisor ;/ 10000b 10h 16 - User (non-privileged) 10001b 11h 17 - FIQ 10010b 12h 18 - IRQ 10011b 13h 19 - Supervisor (SWI) 10111b 17h 23 - Abort 11011b 1Bh 27 - Undefined 11111b 1Fh 31 - Reserved (used as System mode in ARMv4 and up) Writing any other values into the Mode bits is not allowed. Saved Program Status Registers (SPSR_) Additionally to above CPSR, five Saved Program Status Registers exist: SPSR_fiq, SPSR_svc, SPSR_abt, SPSR_irq, SPSR_und Whenever the CPU enters an exception, the current status register (CPSR) is copied to the respective SPSR_ register. Note that there is only one SPSR for each mode, so nested exceptions inside of the same mode are allowed only if the exception handler saves the content of SPSR in memory. For example, for an IRQ exception: IRQ-mode is entered, and CPSR is copied to SPSR_irq. If the interrupt handler wants to enable nested IRQs, then it must first push SPSR_irq before doing so. ARM 26bit Memory Interface -------------------------- The 26bit Memory Interface was used by ARMv1 and ARMv2. The 32bit interface is used by ARMv3 and newer, however, 26bit backward compatibility was included in all ARMv3 (except ARMv3G), and optionally in some non-T variants of ARMv4. Format of R15 in 26bit Mode (Program Counter Register) Bit Name Expl. 31-28 N,Z,C,V Flags (Sign, Zero, Carry, Overflow) 27-26 I,F Interrupt Disable bits (IRQ, FIQ) (1=Disable) 25-2 PC Program Counter, 24bit, Step 4 (64M range) 1-0 M1,M0 Mode (0=User, 1=FIQ, 2=IRQ, 3=Supervisor) Branches with +/-32M range wrap the PC register, and can reach all 64M memory. Reading from R15 If R15 is specified in bit16-19 of an opcode, then NZCVIF and M0,1 are masked (zero), otherwise the full 32bits are used. Writing to R15 ALU opcodes with S=1, and LDM opcodes with PSR=1 can write to all 32bits in R15 (in 26bit mode, that is allowed even in user mode, though it does then affect only NZCF, not the write protected IFMM bits ???), other opcodes which write to R15 will modify only the program counter bits. Also, special CMP/CMN/TST/TEQ{P} opcodes can be used to write to the PSR bits in R15 without modifying the PC bits. Exceptions SWIs, Reset, Data/Prefetch Aborts and Undefined instructions enter Supervisor mode. Interrupts enter IRQ and FIQ mode. Additionally, a special 26bit Address Exception exists, which enters Supervisor mode on accesses to memory addresses>=64M as follows: R14_svc = PC ($+8, including old PSR bits) M1,M0 = 11b = supervisor mode, F=same, I=1, PC=14h, to continue at the fault location, return by SUBS PC,LR,8. 32bit CPUs with 26bit compatibility mode can be configured to switch into 32bit mode when encountering exceptions. ARM Exceptions -------------- Exception Vectors The following are the exception vectors in memory. That is, when an exception arises, CPU is switched into ARM state, and the program counter (PC) is loaded by the respective address. Address Prio Exception Mode on Entry Interrupt Flags BASE+00h 1 Reset Supervisor (_svc) I=1, F=1 BASE+04h 7 Undefined Instruction Undefined (_und) I=1, F=unchanged BASE+08h 6 Software Interrupt (SWI) Supervisor (_svc) I=1, F=unchanged BASE+0Ch 5 Prefetch Abort Abort (_abt) I=1, F=unchanged BASE+10h 2 Data Abort Abort (_abt) I=1, F=unchanged BASE+14h ?? Address Exceeds 26bit Supervisor (_svc) I=1, F=unchanged BASE+18h 4 Normal Interrupt (IRQ) IRQ (_irq) I=1, F=unchanged BASE+1Ch 3 Fast Interrupt (FIQ) FIQ (_fiq) I=1, F=1 BASE is normally 00000000h, but may be optionally FFFF0000h in some ARM CPUs. Priority for simultaneously occuring exceptions ranges from Prio=1=Highest to Prio=7=Lowest. As there's only space for one ARM opcode at each of the above addresses, it'd be usually recommended to deposit a Branch opcode into each vector, which'd then redirect to the actual exception handler address. Actions performed by CPU when entering an exception - R14_=PC+nn ;save old PC, ie. return address - SPSR_=CPSR ;save old flags - CPSR new T,M bits ;set to T=0 (ARM state), and M4-0=new mode - CPSR new I bit ;IRQs disabled (I=1), done by ALL exceptions - CPSR new F bit ;FIQs disabled (F=1), done by Reset and FIQ only - PC=exception_vector ;see table above Above "PC+nn" depends on the type of exception (due to pipelining). Required user-handler actions when returning from an exception Restore any general registers (R0-R14) which might have been modified by the exception handler. Use return-instruction as listed in the respective descriptions below, this will both restore PC and CPSR - that automatically involves that the old CPU state (THUMB or ARM) as well as old state of FIQ and IRQ disable flags are restored. As mentioned above (see action on entering...), the return address is always saved in ARM-style format, so that exception handler may use the same return-instruction, regardless of whether the exception has been generated from inside of ARM or THUMB state. FIQ (Fast Interrupt Request) This interrupt is generated by a LOW level on the nFIQ input. It is supposed to process timing critical interrupts at a high priority, as fast as possible. Additionally to the common banked registers (R13_fiq,R14_fiq), five extra banked registers (R8_fiq-R12_fiq) are available in FIQ mode. The exception handler may freely access these registers without modifying the main programs R8-R12 registers (and without having to save that registers on stack). In privileged (non-user) modes, FIQs may be also manually disabled by setting the F Bit in CPSR. IRQ (Normal Interrupt Request) This interrupt is generated by a LOW level on the nIRQ input. Unlike FIQ, the IRQ mode is not having its own banked R8-R12 registers. IRQ is having lower priority than FIQ, and IRQs are automatically disabled when a FIQ exception becomes executed. In privileged (non-user) modes, IRQs may be also manually disabled by setting the I Bit in CPSR. To return from IRQ Mode (continuing at following opcode): SUBS PC,R14,4 ;both PC=R14_irq-4, and CPSR=SPSR_irq Software Interrupt Generated by a software interrupt instruction (SWI). Recommended to request a supervisor (operating system) function. The SWI instruction may also contain a parameter in the 'comment field' of the lower 24bit of the 32bit opcode opcode at [R14_svc-4]. To return from Supervisor Mode (continuing at following opcode): MOVS PC,R14 ;both PC=R14_svc, and CPSR=SPSR_svc Undefined Instruction Exception (supported by ARMv3 and up) This exception is generated when the CPU comes across an instruction which it cannot handle. Most likely signalizing that the program has locked up, and that an errormessage should be displayed. However, it might be also used to emulate custom functions, ie. as an additional 'SWI' instruction (which'd use R14_und and SPSR_und though, and it'd thus allow to execute the Undefined Instruction handler from inside of Supervisor mode without having to save R14_svc and SPSR_svc). To return from Undefined Mode (continuing at following opcode): MOVS PC,R14 ;both PC=R14_und, and CPSR=SPSR_und Note that not all unused opcodes are necessarily producing an exception, for example, an ARM state Multiply instruction with Bit6=1 would be blindly accepted as 'legal' opcode. Abort (supported by ARMv3 and up) Aborts (page faults) are mostly supposed for virtual memory systems (ie. not used in GBA, as far as I know), otherwise they might be used just to display an error message. Two types of aborts exists: - Prefetch Abort (occurs during an instruction prefetch) - Data Abort (occurs during a data access) A virtual memory systems abort handler would then most likely determine the fault address: For prefetch abort that's just "R14_abt-4". For Data abort, the THUMB or ARM instruction at "R14_abt-8" needs to be 'disassembled' in order to determine the addressed data in memory. The handler would then fix the error by loading the respective memory page into physical memory, and then retry to execute the SAME instruction again, by returning as follows: prefetch abort: SUBS PC,R14,#4 ;PC=R14_abt-4, and CPSR=SPSR_abt data abort: SUBS PC,R14,#8 ;PC=R14_abt-8, and CPSR=SPSR_abt Separate exception vectors for prefetch/data abort exists, each should use the respective return instruction as shown above. Address Exceeds 26bit This exception can occur only on old ARM CPUs with 26bit address scheme (or in 26bit backwards compatibility mode). Reset Forces PC=VVVV0000h, and forces control bits of CPSR to T=0 (ARM state), F=1 and I=1 (disable FIQ and IRQ), and M4-0=10011b (Supervisor mode). ARM Instruction Summary ----------------------- Modification of CPSR flags is optional for all {S} instructions. Logical ALU Operations Instruction Cycles Flags Expl. MOV{cond}{S} Rd,Op2 1S+x+y NZc- Rd = Op2 MVN{cond}{S} Rd,Op2 1S+x+y NZc- Rd = NOT Op2 ORR{cond}{S} Rd,Rn,Op2 1S+x+y NZc- Rd = Rn OR Op2 EOR{cond}{S} Rd,Rn,Op2 1S+x+y NZc- Rd = Rn XOR Op2 AND{cond}{S} Rd,Rn,Op2 1S+x+y NZc- Rd = Rn AND Op2 BIC{cond}{S} Rd,Rn,Op2 1S+x+y NZc- Rd = Rn AND NOT Op2 TST{cond}{P} Rn,Op2 1S+x NZc- Void = Rn AND Op2 TEQ{cond}{P} Rn,Op2 1S+x NZc- Void = Rn XOR Op2 Add x=1I cycles if Op2 shifted-by-register. Add y=1S+1N cycles if Rd=R15. Carry flag affected only if Op2 contains a non-zero shift amount. Arithmetic ALU Operations Instruction Cycles Flags Expl. ADD{cond}{S} Rd,Rn,Op2 1S+x+y NZCV Rd = Rn+Op2 ADC{cond}{S} Rd,Rn,Op2 1S+x+y NZCV Rd = Rn+Op2+Cy SUB{cond}{S} Rd,Rn,Op2 1S+x+y NZCV Rd = Rn-Op2 SBC{cond}{S} Rd,Rn,Op2 1S+x+y NZCV Rd = Rn-Op2+Cy-1 RSB{cond}{S} Rd,Rn,Op2 1S+x+y NZCV Rd = Op2-Rn RSC{cond}{S} Rd,Rn,Op2 1S+x+y NZCV Rd = Op2-Rn+Cy-1 CMP{cond}{P} Rn,Op2 1S+x NZCV Void = Rn-Op2 CMN{cond}{P} Rn,Op2 1S+x NZCV Void = Rn+Op2 Add x=1I cycles if Op2 shifted-by-register. Add y=1S+1N cycles if Rd=R15. Multiply Instruction Cycles Flags Expl. MUL{cond}{S} Rd,Rm,Rs 1S+mI NZx- Rd = Rm*Rs MLA{cond}{S} Rd,Rm,Rs,Rn 1S+mI+1I NZx- Rd = Rm*Rs+Rn UMULL{cond}{S} RdLo,RdHi,Rm,Rs 1S+mI+1I NZx- RdHiLo = Rm*Rs UMLAL{cond}{S} RdLo,RdHi,Rm,Rs 1S+mI+2I NZx- RdHiLo = Rm*Rs+RdHiLo SMULL{cond}{S} RdLo,RdHi,Rm,Rs 1S+mI+1I NZx- RdHiLo = Rm*Rs SMLAL{cond}{S} RdLo,RdHi,Rm,Rs 1S+mI+2I NZx- RdHiLo = Rm*Rs+RdHiLo Memory Load/Store Instruction Cycles Flags Expl. LDR{cond}{B}{T} Rd,
1S+1N+1I+y ---- Rd=[Rn+/-] LDM{cond}{amod} Rn{!},{^} nS+1N+1I+y ---- Load Multiple STR{cond}{B}{T} Rd,
2N ---- [Rn+/-]=Rd STM{cond}{amod} Rn{!},{^} (n-1)S+2N ---- Store Multiple SWP{cond}{B} Rd,Rm,[Rn] 1S+2N+1I ---- Rd=[Rn], [Rn]=Rm For LDR/LDM, add y=1S+1N if Rd=R15, or if R15 in Rlist. Jumps, Calls, CPSR Mode, and others Instruction Cycles Flags Expl. B{cond} label 2S+1N ---- PC=$+8+/-32M BL{cond} label 2S+1N ---- PC=$+8+/-32M, LR=$+4 MRS{cond} Rd,Psr 1S ---- Rd=Psr MSR{cond} Psr{_field},Op 1S (psr) Psr[field]=Op SWI{cond} Imm24bit 2S+1N ---- PC=8, ARM Svc mode, LR=$+4 The Undefined Instruction 2S+1I+1N ---- PC=4, ARM Und mode, LR=$+4 condition=false 1S ---- Opcodes with {cond}=false NOP 1S ---- R0=R0 Coprocessor Functions (if any) Instruction Cycles Flags Expl. CDP{cond} Pn,,Cd,Cn,Cm{,} 1S+bI ---- Coprocessor specific STC{cond}{L} Pn,Cd,
(n-1)S+2N+bI [address] = CRd LDC{cond}{L} Pn,Cd,
(n-1)S+2N+bI CRd = [address] MCR{cond} Pn,,Rd,Cn,Cm{,} 1S+bI+1C CRn = Rn { CRm} MRC{cond} Pn,,Rd,Cn,Cm{,} 1S+(b+1)I+1C Rn = CRn { CRm} ARM Binary Opcode Format |..3 ..................2 ..................1 ..................0| |1_0_9_8_7_6_5_4_3_2_1_0_9_8_7_6_5_4_3_2_1_0_9_8_7_6_5_4_3_2_1_0| |_Cond__|0_0_0|___Op__|S|__Rn___|__Rd___|__Shift__|Typ|0|__Rm___| DataProc |_Cond__|0_0_0|___Op__|S|__Rn___|__Rd___|__Rs___|0|Typ|1|__Rm___| DataProc |_Cond__|0_0_1|___Op__|S|__Rn___|__Rd___|_Shift_|___Immediate___| DataProc |_Cond__|0_0_1_1_0|P|1|0|_Field_|__Rd___|_Shift_|___Immediate___| PSR Imm |_Cond__|0_0_0_1_0|P|L|0|_Field_|__Rd___|0_0_0_0|0_0_0_0|__Rm___| PSR Reg |_Cond__|0_0_0_0_0_0|A|S|__Rd___|__Rn___|__Rs___|1_0_0_1|__Rm___| Multiply |_Cond__|0_0_0_0_1|U|A|S|_RdHi__|_RdLo__|__Rs___|1_0_0_1|__Rm___| MulLong |_Cond__|0_0_0_1_0|B|0_0|__Rn___|__Rd___|0_0_0_0|1_0_0_1|__Rm___| TransSwap |_Cond__|0_1_0|P|U|B|W|L|__Rn___|__Rd___|_________Offset________| TransImm |_Cond__|0_1_1|P|U|B|W|L|__Rn___|__Rd___|__Shift__|Typ|0|__Rm___| TransReg |_Cond__|0_1_1|________________xxx____________________|1|__xxx__| Undefined |_Cond__|1_0_0|P|U|S|W|L|__Rn___|__________Register_List________| TransBlock |_Cond__|1_0_1|L|___________________Offset______________________| B,BL |_Cond__|1_1_0|P|U|N|W|L|__Rn___|__CRd__|__CP#__|____Offset_____| CoDataTrans |_Cond__|1_1_1_0|_CPopc_|__CRn__|__CRd__|__CP#__|_CP__|0|__CRm__| CoDataOp |_Cond__|1_1_1_0|CPopc|L|__CRn__|__Rd___|__CP#__|_CP__|1|__CRm__| CoRegTrans |_Cond__|1_1_1_1|_____________Ignored_by_Processor______________| SWI ARM Opcodes: Branch and Branch with Link (B, BL, SWI) ----------------------------------------------------- Branch and Branch with Link (B, BL) Branch (B) is supposed to jump to a subroutine. Branch with Link is meant to be used to call to a subroutine, return address is then saved in R14/LR (and can be restored via MOV PC,LR aka MOV R15,R14) (for nested subroutines, use PUSH LR and POP PC). Bit Expl. 31-28 Condition 27-25 Must be "101" for this instruction 24 Opcode (0-1) 0: B{cond} label ;branch (jump) PC=PC+8+nn*4 1: BL{cond} label ;branch/link (call) PC=PC+8+nn*4, LR=PC+4 23-0 nn - Signed Offset, step 4 (-32M..+32M in steps of 4) Execution Time: 2S + 1N Return: No flags affected. Branch via ALU, LDR, LDM Most ALU, LDR, LDM opcodes can also change PC/R15. Mis-aligned PC/R15 (MOV/ALU/LDR with Rd=R15) For ARM code, the low bits of the target address should be usually zero, otherwise, R15 is forcibly aligned by clearing the lower two bits. In short, R15 will be always forcibly aligned, so mis-aligned branches won't have effect on subsequent opcodes that use R15, or [R15+disp] as operand. Software Interrupt (SWI) (svc exception) SWI supposed for calls to the operating system - Enter Supervisor mode (SVC). Bit Expl. 31-28 Condition 27-24 Opcode 1111b: SWI{cond} nn ;software interrupt 23-0 nn - Comment Field, ignored by processor (24bit value) Execution Time: 2S+1N The exception handler may interprete the Comment Field by examining the lower 24bit of the 32bit opcode opcode at [R14_svc-4]. For Returning from SWI use "MOVS PC,R14", that instruction does restore both PC and CPSR, ie. PC=R14_svc, and CPSR=SPSR_svc. Nesting SWIs: SPSR_svc and R14_svc should be saved on stack before either invoking nested SWIs, or (if the IRQ handler uses SWIs) before enabling IRQs. Undefined Instruction (und exception) Bit Expl. 31-28 Condition 27-25 Must be 011b for this instruction 24-5 Reserved for future use 4 Must be 1b for this instruction 3-0 Reserved for future use No assembler mnemonic exists, following bitstreams are (not) reserved. cond011xxxxxxxxxxxxxxxxxxxx1xxxx - reserved for future use (except below). cond01111111xxxxxxxxxxxx1111xxxx - free for user. Execution time: 2S+1I+1N. ARM Opcodes: Data Processing (ALU) ---------------------------------- Data Processing (ALU) Bit Expl. 31-28 Condition 27-26 Must be 00b for this instruction 25 I - Immediate 2nd Operand Flag (0=Register, 1=Immediate) 24-21 Opcode (0-Fh) ;*=Arithmetic, otherwise Logical 0: AND{cond}{S} Rd,Rn,Op2 ;AND logical Rd = Rn AND Op2 1: EOR{cond}{S} Rd,Rn,Op2 ;XOR logical Rd = Rn XOR Op2 2: SUB{cond}{S} Rd,Rn,Op2 ;* ;subtract Rd = Rn-Op2 3: RSB{cond}{S} Rd,Rn,Op2 ;* ;subtract reversed Rd = Op2-Rn 4: ADD{cond}{S} Rd,Rn,Op2 ;* ;add Rd = Rn+Op2 5: ADC{cond}{S} Rd,Rn,Op2 ;* ;add with carry Rd = Rn+Op2+Cy 6: SBC{cond}{S} Rd,Rn,Op2 ;* ;sub with carry Rd = Rn-Op2+Cy-1 7: RSC{cond}{S} Rd,Rn,Op2 ;* ;sub cy. reversed Rd = Op2-Rn+Cy-1 8: TST{cond}{P} Rn,Op2 ;test Void = Rn AND Op2 9: TEQ{cond}{P} Rn,Op2 ;test exclusive Void = Rn XOR Op2 A: CMP{cond}{P} Rn,Op2 ;* ;compare Void = Rn-Op2 B: CMN{cond}{P} Rn,Op2 ;* ;compare neg. Void = Rn+Op2 C: ORR{cond}{S} Rd,Rn,Op2 ;OR logical Rd = Rn OR Op2 D: MOV{cond}{S} Rd,Op2 ;move Rd = Op2 E: BIC{cond}{S} Rd,Rn,Op2 ;bit clear Rd = Rn AND NOT Op2 F: MVN{cond}{S} Rd,Op2 ;not Rd = NOT Op2 20 S - Set Condition Codes (0=No, 1=Yes) (Must be 1 for opcode 8-B) 19-16 Rn - 1st Operand Register (R0..R15) (including PC=R15) Must be 0000b for MOV/MVN. 15-12 Rd - Destination Register (R0..R15) (including PC=R15) Must be 0000b (or 1111b) for CMP/CMN/TST/TEQ{P}. When above Bit 25 I=0 (Register as 2nd Operand) When below Bit 4 R=0 - Shift by Immediate 11-7 Is - Shift amount (1-31, 0=Special/See below) When below Bit 4 R=1 - Shift by Register 11-8 Rs - Shift register (R0-R14) - only lower 8bit 0-255 used 7 Reserved, must be zero (otherwise multiply or undefined opcode) 6-5 Shift Type (0=LSL, 1=LSR, 2=ASR, 3=ROR) 4 R - Shift by Register Flag (0=Immediate, 1=Register) 3-0 Rm - 2nd Operand Register (R0..R15) (including PC=R15) When above Bit 25 I=1 (Immediate as 2nd Operand) 11-8 Is - ROR-Shift applied to nn (0-30, in steps of 2) 7-0 nn - 2nd Operand Unsigned 8bit Immediate Second Operand (Op2) This may be a shifted register, or a shifted immediate. See Bit 25 and 11-0. Unshifted Register: Specify Op2 as "Rm", assembler converts to "Rm,LSL#0". Shifted Register: Specify as "Rm,SSS#Is" or "Rm,SSS Rs" (SSS=LSL/LSR/ASR/ROR). Immediate: Specify as 32bit value, for example: "#000NN000h", assembler should automatically convert into "#0NNh,ROR#0ssh" as far as possible (ie. as far as a section of not more than 8bits of the immediate is non-zero). Zero Shift Amount (Shift Register by Immediate, with Immediate=0) LSL#0: No shift performed, ie. directly Op2=Rm, the C flag is NOT affected. LSR#0: Interpreted as LSR#32, ie. Op2 becomes zero, C becomes Bit 31 of Rm. ASR#0: Interpreted as ASR#32, ie. Op2 and C are filled by Bit 31 of Rm. ROR#0: Interpreted as RRX#1 (RCR), like ROR#1, but Op2 Bit 31 set to old C. In source code, LSR#32, ASR#32, and RRX#1 should be specified as such - attempts to specify LSR#0, ASR#0, or ROR#0 will be internally converted to LSL#0 by the assembler. Using R15 (PC) When using R15 as Destination (Rd), note below CPSR description and Execution time description. When using R15 as operand (Rm or Rn), the returned value depends on the instruction: PC+12 if I=0,R=1 (shift by register), otherwise PC+8 (shift by immediate). Returned CPSR Flags If S=1, Rd<>R15, logical operations (AND,EOR,TST,TEQ,ORR,MOV,BIC,MVN): V=not affected C=carryflag of shift operation (not affected if LSL#0 or Rs=00h) Z=zeroflag of result N=signflag of result (result bit 31) If S=1, Rd<>R15, arithmetic operations (SUB,RSB,ADD,ADC,SBC,RSC,CMP,CMN): V=overflowflag of result C=carryflag of result Z=zeroflag of result N=signflag of result (result bit 31) IF S=1, with unused Rd bits=1111b, {P} opcodes (CMPP/CMNP/TSTP/TEQP): R15=result ;modify PSR bits in R15, ARMv2 and below only. In user mode only N,Z,C,V bits of R15 can be changed. In other modes additionally I,F,M1,M0 can be changed. The PC bits in R15 are left unchanged in all modes. If S=1, Rd=R15; should not be used in user mode: CPSR = SPSR_ PC = result For example: MOVS PC,R14 ;return from SWI (PC=R14_svc, CPSR=SPSR_svc). If S=0: Flags are not affected (not allowed for CMP,CMN,TEQ,TST). The instruction "MOV R0,R0" is used as "NOP" opcode in 32bit ARM state. Execution Time: (1+p)S+rI+pN. Whereas r=1 if I=0 and R=1 (ie. shift by register); otherwise r=0. And p=1 if Rd=R15; otherwise p=0. ARM Opcodes: PSR Transfer (MRS, MSR) ------------------------------------ Opcode Format These instructions occupy an unused area (TEQ,TST,CMP,CMN with S=0) of ALU opcodes. Bit Expl. 31-28 Condition 27-26 Must be 00b for this instruction 25 I - Immediate Operand Flag (0=Register, 1=Immediate) (Zero for MRS) 24-23 Must be 10b for this instruction 22 Psr - Source/Destination PSR (0=CPSR, 1=SPSR_) 21 Opcode 0: MRS{cond} Rd,Psr ;Rd = Psr 1: MSR{cond} Psr{_field},Op ;Psr[field] = Op 20 Must be 0b for this instruction (otherwise TST,TEQ,CMP,CMN) For MRS: 19-16 Must be 1111b for this instruction (otherwise SWP) 15-12 Rd - Destination Register (R0-R14) 11-0 Not used, must be zero. For MSR: 19 f write to flags field Bit 31-24 (aka _flg) 18 s write to status field Bit 23-16 (reserved, don't change) 17 x write to extension field Bit 15-8 (reserved, don't change) 16 c write to control field Bit 7-0 (aka _ctl) 15-12 Not used, must be 1111b. For MSR Psr,Rm (I=0) 11-4 Not used, must be zero. 3-0 Rm - Source Register (R0-R14) For MSR Psr,Imm (I=1) 11-8 Shift applied to Imm (ROR in steps of two 0-30) 7-0 Imm - Unsigned 8bit Immediate In source code, a 32bit immediate should be specified as operand. The assembler should then convert that into a shifted 8bit value. MSR/MRS and CPSR/SPSR supported by ARMv3 and up. ARMv2 and below contained PSR flags in R15, accessed by CMP/CMN/TST/TEQ{P}. The field mask bits specify which bits of the destination Psr are write-able (or write-protected), one or more of these bits should be set, for example, CPSR_fsxc (aka CPSR aka CPSR_all) unlocks all bits (see below user mode restriction though). Restrictions: In non-privileged mode (user mode): only condition code bits of CPSR can be changed, control bits can't. Only the SPSR of the current mode can be accessed; In User and System modes no SPSR exists. Unused Bits in CPSR are reserved for future use and should never be changed (except for unused bits in the flags field). Execution Time: 1S. Note: The A22i assembler recognizes MOV as alias for both MSR and MRS because it is practically not possible to remember whether MSR or MRS was the load or store opcode, and/or whether it does load to or from the Psr register. ARM Opcodes: Multiply and Multiply-Accumulate (MUL, MLA) -------------------------------------------------------- Opcode Format Bit Expl. 31-28 Condition 27-25 Must be 000b for this instruction 24-21 Opcode 0000b: MUL{cond}{S} Rd,Rm,Rs ;multiply Rd = Rm*Rs 0001b: MLA{cond}{S} Rd,Rm,Rs,Rn ;mul.& accumulate Rd = Rm*Rs+Rn 0100b: UMULL{cond}{S} RdLo,RdHi,Rm,Rs ;multiply RdHiLo=Rm*Rs 0101b: UMLAL{cond}{S} RdLo,RdHi,Rm,Rs ;mul.& acc. RdHiLo=Rm*Rs+RdHiLo 0110b: SMULL{cond}{S} RdLo,RdHi,Rm,Rs ;sign.mul. RdHiLo=Rm*Rs 0111b: SMLAL{cond}{S} RdLo,RdHi,Rm,Rs ;sign.m&a. RdHiLo=Rm*Rs+RdHiLo 20 S - Set Condition Codes (0=No, 1=Yes) (Must be 0 for Halfword mul) 19-16 Rd (or RdHi) - Destination Register (R0-R14) 15-12 Rn (or RdLo) - Accumulate Register (R0-R14) (Set to 0000b if unused) 11-8 Rs - Operand Register (R0-R14) 7-4 Must be 1001b for these instructions 3-0 Rm - Operand Register (R0-R14) Multiply and Multiply-Accumulate (MUL, MLA) Restrictions: Rd may not be same as Rm. Rd,Rn,Rs,Rm may not be R15. Note: Only the lower 32bit of the internal 64bit result are stored in Rd, thus no sign/zero extension is required and MUL and MLA can be used for both signed and unsigned calculations! Execution Time: 1S+mI for MUL, and 1S+(m+1)I for MLA. Whereas 'm' depends on whether/how many most significant bits of Rs are all zero or all one. That is m=1 for Bit 31-8, m=2 for Bit 31-16, m=3 for Bit 31-24, and m=4 otherwise. Flags (if S=1): Z=zeroflag, N=signflag, C=destroyed (ARMv4 and below) or C=not affected (ARMv5 and up), V=not affected. MUL/MLA supported by ARMv2 and up. Multiply Long and Multiply-Accumulate Long (MULL, MLAL) Optionally supported, INCLUDED in ARMv3M, EXCLUDED in ARMv4xM/ARMv5xM. Restrictions: RdHi,RdLo,Rm must be different registers. R15 may not be used. Execution Time: 1S+(m+1)I for MULL, and 1S+(m+2)I for MLAL. Whereas 'm' depends on whether/how many most significant bits of Rs are "all zero" (UMULL/UMLAL) or "all zero or all one" (SMULL,SMLAL). That is m=1 for Bit 31-8, m=2 for Bit 31-16, m=3 for Bit 31-24, and m=4 otherwise. Flags (if S=1): Z=zeroflag, N=signflag, C=destroyed (ARMv4 and below) or C=not affected (ARMv5 and up), V=destroyed??? (ARMv4 and below???) or V=not affected (ARMv5 and up). ARM Opcodes: Memory: Block Data Transfer (LDM, STM) --------------------------------------------------- Opcode Format Bit Expl. 31-28 Condition 27-25 Must be 100b for this instruction 24 P - Pre/Post (0=post; add offset after transfer, 1=pre; before trans.) 23 U - Up/Down Bit (0=down; subtract offset from base, 1=up; add to base) 22 S - PSR & force user bit (0=No, 1=load PSR or force user mode) 21 W - Write-back bit (0=no write-back, 1=write address into base) 20 L - Load/Store bit (0=Store to memory, 1=Load from memory) 0: STM{cond}{amod} Rn{!},{^} ;Store (Push) 1: LDM{cond}{amod} Rn{!},{^} ;Load (Pop) Whereas, {!}=Write-Back (W), and {^}=PSR/User Mode (S) 19-16 Rn - Base register (R0-R14) (not including R15) 15-0 Rlist - Register List (Above 'offset' is meant to be the number of words specified in Rlist.) Return: No Flags affected. Execution Time: For normal LDM, nS+1N+1I. For LDM PC, (n+1)S+2N+1I. For STM (n-1)S+2N. Where n is the number of words transferred. Addressing Modes {amod} The IB,IA,DB,DA suffixes directly specify the desired U and P bits: IB increment before ;P=1, U=1 IA increment after ;P=0, U=1 DB decrement before ;P=1, U=0 DA decrement after ;P=0, U=0 Alternately, FD,ED,FA,EA could be used, mostly to simplify mnemonics for stack transfers. ED empty stack, descending ;LDM: P=1, U=1 ;STM: P=0, U=0 FD full stack, descending ; P=0, U=1 ; P=1, U=0 EA empty stack, ascending ; P=1, U=0 ; P=0, U=1 FA full stack, ascending ; P=0, U=0 ; P=1, U=1 Stack operations are conventionally using Rn=R13/SP as stack pointer in Full Descending mode (meaning that free memory starts at SP-1 and below, and used memory at SP+0 and up; that model is also used by other CPUs like 80x86 and Z80). The following expressions are aliases for each other: STMFD=STMDB=PUSH STMED=STMDA STMFA=STMIB STMEA=STMIA LDMFD=LDMIA=POP LDMED=LDMIB LDMFA=LDMDA LDMEA=LDMDB When S Bit is set (S=1) If instruction is LDM and R15 is in the list: (Mode Changes) While R15 loaded, additionally: CPSR=SPSR_ Otherwise: (User bank transfer) Rlist is referring to User Bank Registers R0-R15 (rather than to registers of the current mode; such like R14_svc etc.) Base write-back should not be used for User bank transfer. Caution - When instruction is LDM: If the following instruction reads from a banked register (eg. R14_svc), then CPU might still read R14 instead; if necessary insert a dummy NOP. Transfer Order The lowest Register in Rlist (R0 if its in the list) will be loaded/stored to/from the lowest memory address. Internally, the rlist registers are always processed with sequentially INCREASING addresses (ie. for DECREASING addressing modes, the CPU does first calculate the lowest address, and does then process rlist with increasing addresses; this detail can be important when accessing memory mapped I/O ports). Mis-aligned STM,LDM,PUSH,POP (forced align) The base address should be usually word-aligned. Otherwise, mis-aligned low bit(s) are ignored, the memory access goes to a forcibly aligned (rounded-down) memory address "addr AND (NOT 3)". Strange Effects on Invalid Rlist's Empty Rlist: R15 loaded/stored (ARMv4 only), and Rb=Rb+/-40h (ARMv4-v5). Writeback with Rb included in Rlist: Store OLD base if Rb is FIRST entry in Rlist, otherwise store NEW base (STM/ARMv4), always store OLD base (STM/ARMv5), no writeback (LDM/ARMv4), writeback if Rb is "the ONLY register, or NOT the LAST register" in Rlist (LDM/ARMv5). ARM Opcodes: Memory: Single Data Transfer (LDR, STR) ---------------------------------------------------- Opcode Format Bit Expl. 31-28 Condition 27-26 Must be 01b for this instruction 25 I - Immediate Offset Flag (0=Immediate, 1=Shifted Register) 24 P - Pre/Post (0=post; add offset after transfer, 1=pre; before trans.) 23 U - Up/Down Bit (0=down; subtract offset from base, 1=up; add to base) 22 B - Byte/Word bit (0=transfer 32bit/word, 1=transfer 8bit/byte) When above Bit 24 P=0 (Post-indexing, write-back is ALWAYS enabled): 21 T - Memory Management (0=Normal, 1=Force non-privileged access) When above Bit 24 P=1 (Pre-indexing, write-back is optional): 21 W - Write-back bit (0=no write-back, 1=write address into base) 20 L - Load/Store bit (0=Store to memory, 1=Load from memory) 0: STR{cond}{B}{T} Rd,
;[Rn+/-]=Rd 1: LDR{cond}{B}{T} Rd,
;Rd=[Rn+/-] Whereas, B=Byte, T=Force User Mode (only for POST-Indexing) 19-16 Rn - Base register (R0..R15) (including R15=PC+8) 15-12 Rd - Source/Destination Register (R0..R15) (including R15=PC+12) When above I=0 (Immediate as Offset) 11-0 Unsigned 12bit Immediate Offset (0-4095, steps of 1) When above I=1 (Register shifted by Immediate as Offset) 11-7 Is - Shift amount (1-31, 0=Special/See below) 6-5 Shift Type (0=LSL, 1=LSR, 2=ASR, 3=ROR) 4 Must be 0 (Reserved, see The Undefined Instruction) 3-0 Rm - Offset Register (R0..R14) (not including PC=R15) Instruction Formats for
An expression which generates an address: ;an immediate used as address ;*** restriction: must be located in range PC+/-4095+8, if so, ;*** assembler will calculate offset and use PC (R15) as base. Pre-indexed addressing specification: [Rn] ;offset = zero [Rn, <#{+/-}expression>]{!} ;offset = immediate [Rn, {+/-}Rm{,} ]{!} ;offset = register shifted by immediate Post-indexed addressing specification: [Rn], <#{+/-}expression> ;offset = immediate [Rn], {+/-}Rm{,} ;offset = register shifted by immediate Whereas... immediate shift such like LSL#4, ROR#2, etc. (see ALU opcodes). {!} exclamation mark ("!") indicates write-back (Rn will be updated). Notes Shift amount 0 has special meaning, as described for ALU opcodes. When writing a word (32bit) to memory, the address should be word-aligned. When reading a byte from memory, upper 24 bits of Rd are zero-extended. When reading a word from a halfword-aligned address (which is located in the middle between two word-aligned addresses), the lower 16bit of Rd will contain [address] ie. the addressed halfword, and the upper 16bit of Rd will contain [Rd-2] ie. more or less unwanted garbage. However, by isolating lower bits this may be used to read a halfword from memory. (Above applies to little endian mode, as used in GBA.) In a virtual memory based environment (ie. not in the GBA), aborts (ie. page faults) may take place during execution, if so, Rm and Rn should not specify the same register when post-indexing is used, as the abort-handler might have problems to reconstruct the original value of the register. Return: CPSR flags are not affected. Execution Time: For normal LDR: 1S+1N+1I. For LDR PC: 2S+2N+1I. For STR: 2N. Mis-aligned 32bit STR (forced align) The mis-aligned low bit(s) are ignored, the memory access goes to a forcibly aligned (rounded-down) memory address "addr AND (NOT 3)". Mis-aligned 32bit LDR (rotated read) Reads from forcibly aligned address "addr AND (NOT 3)", and does then rotate the data as "ROR (addr AND 3)*8". ARM Opcodes: Memory: Single Data Swap (SWP) ------------------------------------------- Opcode Format Bit Expl. 31-28 Condition 27-23 Must be 00010b for this instruction Opcode (fixed) SWP{cond}{B} Rd,Rm,[Rn] ;Rd=[Rn], [Rn]=Rm 22 B - Byte/Word bit (0=swap 32bit/word, 1=swap 8bit/byte) 21-20 Must be 00b for this instruction 19-16 Rn - Base register (R0-R14) 15-12 Rd - Destination Register (R0-R14) 11-4 Must be 00001001b for this instruction 3-0 Rm - Source Register (R0-R14) SWP/SWPB supported by ARMv2a and up. Swap works properly including if Rm and Rn specify the same register. R15 may not be used for either Rn,Rd,Rm. (Rn=R15 would be MRS opcode). Upper bits of Rd are zero-expanded when using Byte quantity. For info about byte and word data memory addressing, read LDR and STR opcode description. Execution Time: 1S+2N+1I. That is, 2N data cycles, 1S code cycle, plus 1I. Mis-aligned 32bit SWP (rotated read) The SWP opcode works like a combination of LDR and STR, that means, it does read-rotated, but does write-unrotated. ARM Opcodes: Coprocessor Instructions (MRC/MCR, LDC/STC, CDP) ------------------------------------------------------------- Coprocessor Register Transfers (MRC, MCR) (with ARM Register read/write) Bit Expl. 31-28 Condition 27-24 Must be 1110b for this instruction 23-21 CP Opc - Coprocessor operation code (0-7) 20 ARM-Opcode (0-1) 0: MCR{cond} Pn,,Rd,Cn,Cm{,} ;move from ARM to CoPro 1: MRC{cond} Pn,,Rd,Cn,Cm{,} ;move from CoPro to ARM 19-16 Cn - Coprocessor source/dest. Register (C0-C15) 15-12 Rd - ARM source/destination Register (R0-R15) 11-8 Pn - Coprocessor number (P0-P15) 7-5 CP - Coprocessor information (0-7) 4 Reserved, must be one (1) (otherwise CDP opcode) 3-0 Cm - Coprocessor operand Register (C0-C15) MCR/MRC supported by ARMv2 and up. A22i syntax allows to use MOV with Rd specified as first (dest), or last (source) operand. Native MCR/MRC syntax uses Rd as middle operand, can be ommited if is zero. When using MCR with R15: Coprocessor will receive a data value of PC+12. When using MRC with R15: Bit 31-28 of data are copied to Bit 31-28 of CPSR (ie. N,Z,C,V flags), other data bits are ignored, CPSR Bit 27-0 are not affected, R15 (PC) is not affected. Execution time: 1S+bI+1C for MCR, 1S+(b+1)I+1C for MRC. Return: For MRC only: Either R0-R14 modified, or flags affected (see above). For details refer to original ARM docs. The opcodes irrelevant for GBA/NDS7 because no coprocessor exists (except for a dummy CP14 unit). However, NDS9 includes a working CP15 unit. Coprocessor Data Transfers (LDC, STC) (with Memory read/write) Bit Expl. 31-28 Condition 27-25 Must be 110b for this instruction 24 P - Pre/Post (0=post; add offset after transfer, 1=pre; before trans.) 23 U - Up/Down Bit (0=down; subtract offset from base, 1=up; add to base) 22 N - Transfer length (0-1, interpretation depends on co-processor) 21 W - Write-back bit (0=no write-back, 1=write address into base) 20 Opcode (0-1) 0: STC{cond}{L} Pn,Cd,
;Store to memory (from coprocessor) 1: LDC{cond}{L} Pn,Cd,
;Read from memory (to coprocessor) whereas {L} indicates long transfer (Bit 22: N=1) 19-16 Rn - ARM Base Register (R0-R15) (R15=PC+8) 15-12 Cd - Coprocessor src/dest Register (C0-C15) 11-8 Pn - Coprocessor number (P0-P15) 7-0 Offset - Unsigned Immediate, step 4 (0-1020, in steps of 4) LDC/STC supported by ARMv2 and up. Execution time: (n-1)S+2N+bI, n=number of words transferred. For details refer to original ARM docs, irrelevant in GBA because no coprocessor exists. Coprocessor Data Operations (CDP) (without Memory or ARM Register operand) Bit Expl. 31-28 Condition 27-24 Must be 1110b for this instruction ARM-Opcode (fixed) CDP{cond} Pn,,Cd,Cn,Cm{,} 23-20 CP Opc - Coprocessor operation code (0-15) 19-16 Cn - Coprocessor operand Register (C0-C15) 15-12 Cd - Coprocessor destination Register (C0-C15) 11-8 Pn - Coprocessor number (P0-P15) 7-5 CP - Coprocessor information (0-7) 4 Reserved, must be zero (otherwise MCR/MRC opcode) 3-0 Cm - Coprocessor operand Register (C0-C15) CDP supported by ARMv2 and up. Execution time: 1S+bI, b=number of cycles in coprocessor busy-wait loop. Return: No flags affected, no ARM-registers used/modified. For details refer to original ARM docs, irrelevant in GBA because no coprocessor exists. ARM Pseudo Instructions and Directives -------------------------------------- ARM Pseudo Instructions nop mov r0,r0 ldr Rd,=Imm ldr Rd,[r15,disp] ;use .pool as parameter field add Rd,=addr add/sub Rd,r15,disp adr Rd,addr add/sub Rd,r15,disp adrl Rd,addr two add/sub opcodes with disp=xx00h+00yyh mov Rd,Imm mvn Rd,NOT Imm ;or vice-versa and Rd,Rn,Imm bic Rd,Rn,NOT Imm ;or vice-versa cmp Rd,Rn,Imm cmn Rd,Rn,-Imm ;or vice-versa add Rd,Rn,Imm sub Rd,Rn,-Imm ;or vice-versa All above opcodes may be made conditional by specifying a {cond} field. A22i Directives org adr assume following code from this address on .gba indicate GBA program .nds indicate NDS program .fix fix GBA/NDS header checksum .norewrite do not delete existing output file (keep following data in file) .data? following defines RAM data structure (assembled to nowhere) .code following is normal ROM code/data (assembled to ROM image) .include includes specified source code file (no nesting/error handling) .import imports specified binary file (optional parameters: ,begin,len) .radix nn changes default numeric format (nn=2,8,10,16 = bin/oct/dec/hex) .errif expr generates an error message if expression is nonzero .if expr assembles following code only if expression is nonzero .else invert previous .if condition .endif terminate .if/.ifdef/.ifndef .ifdef sym assemble following only if symbol is defined .ifndef sym assemble following only if symbol is not defined .align nn aligns to an address divisible-by-nn, inserts 00's l equ n l=n l: [cmd] l=$ (global label) @@l: [cmd] @@l=$ (local label, all locals are reset at next global label) end end of source code db ... define 8bit data (bytes) dw ... define 16bit data (halfwords) dd ... define 32bit data (words) defs nn define nn bytes space (zero-filled) ;... defines a comment (ignored by the assembler) // alias for CRLF, eg. allows in one line A22i Alias Directives (for compatibility with other assemblers) align .align 4 code16 .thumb align nn .align nn .code 16 .thumb % nn defs nn code32 .arm .space nn defs nn .code 32 .arm ..ds nn defs nn ltorg .pool x=n x equ n .ltorg .pool .equ x,n x equ n ..ltorg .pool .define x n x equ n dcb db (8bit data) incbin .import defb db (8bit data) @@@... ;comment .byte db (8bit data) @ ... ;comment .ascii db (8bit string) @*... ;comment dcw dw (16bit data) @... ;comment defw dw (16bit data) .text .code .hword dw (16bit data) .bss .data? dcd dd (32bit data) .global (ignored) defd dd (32bit data) .extern (ignored) .long dd (32bit data) .thumb_func (ignored) .word dw/dd, don't use #directive .directive .end end .fill nn,1,0 defs nn Alias Conditions, Opcodes, Operands hs cs ;condition higher or same = carry set lo cc ;condition lower = carry cleared asl lsl ;arithmetic shift left = logical shift left A22i Numeric Formats & Dialects Type Normal Alias Decimal 85 #85 &d85 Hexadecimal 55h #55h 0x55 #0x55 $55 &h55 Octal 125o 0o125 &o125 Ascii 'U' "U" Binary 01010101b %01010101 0b01010101 &b01010101 Roman &rLXXXV (very useful for arrays of kings and chapters) Note: The default numeric format can be changed by the .radix directive (usually 10=decimal). For example, with radix 16, values like "85" and "0101b" are treated as hexadecimal numbers (in that case, decimal and binary numbers can be still defined with prefixes &d and &b). A22i Numeric Operators Priority Prio Operator Aliases 8 (,) brackets 7 +,- sign 6 *,/,MOD,SHL,SHR MUL,DIV,<<,>> 5 +,- operation 4 EQ,GE,GT,LE,LT,NE =,>=,>,<=,<,<>,==,!= 3 NOT 2 AND 1 OR,XOR EOR Operators of same priority are processed from left to right. Boolean operators (priority 4) return 1=TRUE, 0=FALSE. A22i Nocash Syntax Even though A22i does recognize the official ARM syntax, it's also allowing to use friendly code: mov r0,0ffh ;no C64-style "#", and no C-style "0x" required stmia [r7]!,r0,r4-r5 ;square [base] brackets, no fancy {rlist} brackets mov r0,cpsr ;no confusing MSR and MRS (whatever which is which) mov r0,p0,0,c0,c0,0 ;no confusing MCR and MRC (whatever which is which) ldr r0,[score] ;allows to use clean brackets for relative addresses push rlist ;alias for stmfd [r13]!,rlist (and same for pop/ldmfd) label: ;label definitions recommended to use ":" colons [A22i is the no$gba debug version's built-in source code assembler.] ARM Instruction Cycle Times --------------------------- Instruction Cycle Summary Instruction Cycles Additional --------------------------------------------------------------------- ALU 1S +1S+1N if R15 loaded, +1I if SHIFT(Rs) MSR,MRS 1S LDR 1S+1N+1I +1S+1N if R15 loaded STR 2N LDM nS+1N+1I +1S+1N if R15 loaded STM (n-1)S+2N SWP 1S+2N+1I B,BL 2S+1N SWI,trap 2S+1N MUL 1S+ml MLA 1S+(m+1)I MULL 1S+(m+1)I MLAL 1S+(m+2)I CDP 1S+bI LDC,STC (n-1)S+2N+bI MCR 1N+bI+1C MRC 1S+(b+1)I+1C {cond} false 1S Whereas, n = number of words transferred b = number of cycles spent in coprocessor busy-wait loop m = depends on most significant byte(s) of multiplier operand Above 'trap' is meant to be the execution time for exceptions. And '{cond} false' is meant to be the execution time for conditional instructions which haven't been actually executed because the condition has been false. The separate meaning of the N,S,I,C cycles is: N - Non-sequential cycle Requests a transfer to/from an address which is NOT related to the address used in the previous cycle. (Called 1st Access in GBA language). The execution time for 1N is 1 clock cycle (plus non-sequential access waitstates). S - Sequential cycle Requests a transfer to/from an address which is located directly after the address used in the previous cycle. Ie. for 16bit or 32bit accesses at incrementing addresses, the first access is Non-sequential, the following accesses are sequential. (Called 2nd Access in GBA language). The execution time for 1S is 1 clock cycle (plus sequential access waitstates). I - Internal Cycle CPU is just too busy, not even requesting a memory transfer for now. The execution time for 1I is 1 clock cycle (without any waitstates). C - Coprocessor Cycle The CPU uses the data bus to communicate with the coprocessor (if any), but no memory transfers are requested. Memory Waitstates Ideally, memory may be accessed free of waitstates (1N and 1S are then equal to 1 clock cycle each). However, a memory system may generate waitstates for several reasons: The memory may be just too slow. Memory is currently accessed by DMA, eg. sound, video, memory transfers, etc. Or when data is squeezed through a 16bit data bus (in that special case, 32bit access may have more waitstates than 8bit and 16bit accesses). Also, the memory system may separate between S and N cycles (if so, S cycles would be typically faster than N cycles). Memory Waitstates for Different Memory Areas Different memory areas (eg. ROM and RAM) may have different waitstates. When executing code in one area which accesses data in another area, then the S+N cycles must be split into code and data accesses: 1N is used for data access, plus (n-1)S for LDM/STM, the remaining S+N are code access. If an instruction jumps to a different memory area, then all code cycles for that opcode are having waitstate characteristics of the NEW memory area. ARM Versions ------------ Version Numbers ARM CPUs are distributed by name ARM#, and are described as ARMv# in specifications, whereas "#" is NOT the same than "v#", for example, ARM7TDMI is ARMv4TM. That is so confusing, that ARM didn't even attempt to clarify the relationship between the various "#" and "v#" values. Version Variants Suffixes like "M" (long multiply), "T" (THUMB support), "E" (Enhanced DSP) indicate presence of special features, additionally to the standard instruction set of a given version, or, when preceded by an "x", indicate the absence of that features. ARMv1 aka ARM1 Some sort of a beta version, according to ARM never been used in any commercial products. ARMv2 and up MUL,MLA CDP,LDC,MCR,MRC,STC SWP/SWPB (ARMv2a and up only) Two new FIQ registers ARMv3 and up MRS,MSR opcodes (instead CMP/CMN/TST/TEQ{P} opcodes) CPSR,SPSR registers (instead PSR bits in R15) Removed never condition, cond=NV no longer valid 32bit addressing (instead 26bit addressing in older versions) 26bit addressing backwards comptibility mode (except v3G) Abt and Und modes (instead handling aborts/undefined in Svc mode) SMLAL,SMULL,UMLAL,UMULL (optionally, INCLUDED in v3M, EXCLUDED in v4xM/v5xM) ARMv4 aka ARM7 and up LDRH,LDRSB,LDRSH,STRH Sys mode (privileged user mode) BX (only ARMv4T, and any ARMv5 or ARMv5T and up) THUMB code (only T variants, ie. ARMv4T, ARMv5T) ARMv5 aka ARM9 and up BKPT,BLX,CLZ (BKPT,BLX also in THUMB mode) LDM/LDR/POP PC with mode switch (POP PC also in THUMB mode) CDP2,LDC2,MCR2,MRC2,STC2 (new coprocessor opcodes) C-flag unchanged by MUL (instead undefined flag value) changed instruction cycle timings / interlock ??? or not ??? QADD,QDADD,QDSUB,QSUB opcodes, CPSR.Q flag (v5TE and V5TExP only) SMLAxy,SMLALxy,SMLAWy,SMULxy,SMULWy (v5TE and V5TExP only) LDRD,STRD,PLD,MCRR,MRRC (v5TE only, not v5, not v5TExP) ARMv6 No public specifications available. A Milestone in Computer History Original ARMv2 has been used in the relative rare and expensive Archimedes deluxe home computers in the late eighties, the Archimedes has caught a lot of attention, particularly for being the first home computer that used a BIOS being programmed in BASIC language - which has been a absolutely revolutionary decadency at that time. Inspired, programmers all over the world have successfully developed even slower and much more inefficient programming languages, which are nowadays consequently used by nearly all ARM programmers, and by most non-ARM programmers as well. SNES Cart OBC1 (OBJ Controller) (1 game) ---------------------------------------- The OBC1 is a 80pin OBJ Controller chip from Nintendo, used by only one game: Metal Combat: Falcon's Revenge (1993) Intelligent Systems/Nintendo (Note: the game also requires a Super Scope lightgun) OBC1 I/O Ports 7FF0h OAM Xloc = [Base+Index*4+0] (R/W) 7FF1h OAM Yloc = [Base+Index*4+1] (R/W) 7FF2h OAM Tile = [Base+Index*4+2] (R/W) 7FF3h OAM Attr = [Base+Index*4+3] (R/W) 7FF4h OAM Bits = [Base+Index/4+200h].Bit((Index AND 3)*2+0..1) (R?/W) 7FF5h Base for 220h-byte region (bit0: 0=7C00h, 1=7800h) 7FF6h Index (OBJ Number) (0..127) 7FF7h Unknown (set to 00h or 0Ah) (maybe SRAM vs I/O mode select) Other bytes at 6000h..7FFFh contain 8Kbyte battery-backed SRAM (of which, 7800h..7A1Fh and 7C00h..7E1Fh can be used as OBJ workspace). Notes Port 7FF0h-7FF3h/7FF5h are totally useless. Port 7FF4h/7FF6h are eventually making it slightly easier to combine the 2bit OAM fragments, though putting a huge 80pin chip into the cartridge for merging 2bit fragments is definetly overcomplicated. As far as known, the Index isn't automatically incremented. Port 7FF4h does read-modify-write operations which may involve timing restrictions (?), or, modify-write (when prefetching data on 7FF6h writes) which may come up with out-dated-prefetch effects. Reading from 7FF4h does reportedly return the desired BYTE, but WITHOUT isolating & shifting the desired BITS into place? Setting Index bits7+5 does reportedly enable SRAM mapping at 6000h..77FFh? ROM is reportedly mapped to bank 00h..3Fh, and also to bank 70h..71h? Maybe that info just refers to SRAM not being mapped to that region (as it'd be in some other LoROM cartridges). PCB "SHVC-2E3M-01" Contains six chips and a battery. The chips are: Two 1MB ROMs, MAD-1, OBC1, CIC, 8K SRAM. All chips (except MAD-1) are SMD chips. SNES Cart S-DD1 (Data Decompressor) (2 games) --------------------------------------------- The S-DD1 is a 100pin Data Decompression chip, used by only two games: Star Ocean (6MB ROM, 8KB RAM) (1996) tri-Ace/Enix (JP) Street Fighter Alpha 2 (4MB ROM, no RAM) (1996) Capcom (NA) (JP) (EU) S-DD1 Decompression Algorithm --> SNES Cart S-DD1 Decompression Algorithm S-DD1 I/O Ports 4800h DMA Enable 1 (bit0..7 = DMA 0..7) (unchanged after DMA) 4801h DMA Enable 2 (bit0..7 = DMA 0..7) (automatically cleared after DMA) 4802h Unknown ;\set to 0000h by Star Ocean (maybe SRAM related) 4803h Unknown ;/unused by Street Fighter Alpha 2 4804h ROM Bank for C00000h-CFFFFFh (in 1MByte units) 4805h ROM Bank for D00000h-DFFFFFh (in 1MByte units) 4806h ROM Bank for E00000h-EFFFFFh (in 1MByte units) 4807h ROM Bank for F00000h-FFFFFFh (in 1MByte units) DMA from ROM returns Decompressed Data (originated at DMA start addr) S-DD1 Memory Map ???-??? SRAM (if any) 008000h-00FFFFh Exception Handlers, mapped in LoROM-fashion (ROM 0..7FFFh) C00000h-CFFFFFh ROM (mapped via Port 4804h) (in HiROM fashion) D00000h-DFFFFFh ROM (mapped via Port 4805h) (in HiROM fashion) E00000h-EFFFFFh ROM (mapped via Port 4806h) (in HiROM fashion) F00000h-FFFFFFh ROM (mapped via Port 4807h) (in HiROM fashion) S-DD1 PCBs SHVC-1NON-01 CartSlotPin59 not connected (no C12 capacitor on PA1 pin) SHVC-1NON-10 Strange revision (capacitor C12 between PA1 and GND) SNSP-1NON-10 PAL version (S-DD1.Pin82 wired to ... VCC?) (also with C12) SHVC-LN3B-01 Version with additional SRAM for Star Ocean The 1NON board contains only two chips (100pin D-DD1 and 44pin ROM), the CIC function is included in the S-DD1, whereas Pin82 does probably select "PAL/NTSC" CIC mode. The LN3B-board contains five chips (two 44pin ROMs, S-DD1, 8Kx8bit SRAM, and a MM1026AF battery controller). S-DD1 Pinouts 1-81 Unknown 82 PAL/NTSC (for CIC mode) 83-100 Unknown SNES Cart S-DD1 Decompression Algorithm --------------------------------------- decompress_init(src) input=[src], src=src+1 if (input AND C0h)=00h then num_planes = 2 if (input AND C0h)=40h then num_planes = 8 if (input AND C0h)=80h then num_planes = 4 if (input AND C0h)=C0h then num_planes = 0 if (input AND 30h)=00h then high_context_bits=01c0h, low_context_bits=0001h if (input AND 30h)=10h then high_context_bits=0180h, low_context_bits=0001h if (input AND 30h)=20h then high_context_bits=00c0h, low_context_bits=0001h if (input AND 30h)=30h then high_context_bits=0180h, low_context_bits=0003h input=(input SHL 11) OR ([src+1] SHL 3), src=src+1, valid_bits=5 for i=0 to 7 do bit_ctr[i]=00h, prev_bits[i]=0000h for i=0 to 31 do context_states[i]=00h, context_MPS[i]=00h plane=0, yloc=0, raw=0 decompress_byte(src,dst) if num_planes=0 for plane=0 to 7 do GetBit(plane) [dst]=raw, dst=dst+1 else if (plane AND 1)=0 for i=0 to 7 do GetBit(plane+0), GetBit(plane+1) [dst]=prev_bits[plane] AND FFh, dst=dst+1, plane=plane+1 else [dst]=prev_bits[plane] AND FFh, dst=dst+1, plane=plane-1 yloc=yloc+1, if yloc=8 then yloc=0, plane = (plane+2) AND (num_planes-1) GetBit(plane) context = (plane AND 1) SHL 4 context = context OR ((prev_bits[plane] AND high_context_bits) SHR 5) context = context OR (prev_bits[plane] AND low_context_bits) pbit=ProbGetBit(context) prev_bits[plane] = (prev_bits[plane] SHL 1) + pbit if num_planes=0 then raw = (raw SHR 1)+(pbit SHL 7) ProbGetBit(context) state=context_states[context] code_size=EvolutionCodeSize[state] if (bit_ctr[code_size] AND 7Fh)=0 then bit_ctr[code_size]=GetCodeword(code_size) pbit=context_MPS[context] bit_ctr[code_size] = bit_ctr[code_size]-1 if bit_ctr[code_size]=00h ;"GolombGetBit" context_states[context]=EvolutionLpsNext[state] pbit=pbit XOR 1 if state<2 then context_MPS[context]=pbit else if bit_ctr[code_size]=80h context_states[context]=EvolutionMpsNext[state] return pbit GetCodeword(code_size) if valid_bits=0 then input=input OR [src], src=src+1, valid_bits=8 input=input SHL 1, valid_bits=valid_bits-1 if (input AND 8000h)=0 return 80h+(1 SHL code_size) tmp=((input SHR 8) AND 7Fh) OR (7Fh SHR code_size) input=input SHL code_size, valid_bits=valid_bits-code_size if valid_bits<0 then input=input OR (([src] SHL (-valid_bits)) src=src+1, valid_bits=valid_bits+8 return RunTable[tmp] EvolutionCodeSize[0..32] 0 , 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 4 , 4, 5, 5, 6, 6, 7, 7, 0, 1, 2, 3, 4, 5, 6, 7 EvolutionMpsNext[0..32] 25, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17 18,19,20,21,22,23,24,24,26,27,28,29,30,31,32,24 EvolutionLpsNext[0..32] 25, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 16,17,18,19,20,21,22,23, 1, 2, 4, 8,12,16,18,22 RunTable[0..127] 128, 64, 96, 32, 112, 48, 80, 16, 120, 56, 88, 24, 104, 40, 72, 8 124, 60, 92, 28, 108, 44, 76, 12, 116, 52, 84, 20, 100, 36, 68, 4 126, 62, 94, 30, 110, 46, 78, 14, 118, 54, 86, 22, 102, 38, 70, 6 122, 58, 90, 26, 106, 42, 74, 10, 114, 50, 82, 18, 98, 34, 66, 2 127, 63, 95, 31, 111, 47, 79, 15, 119, 55, 87, 23, 103, 39, 71, 7 123, 59, 91, 27, 107, 43, 75, 11, 115, 51, 83, 19, 99, 35, 67, 3 125, 61, 93, 29, 109, 45, 77, 13, 117, 53, 85, 21, 101, 37, 69, 5 121, 57, 89, 25, 105, 41, 73, 9, 113, 49, 81, 17, 97, 33, 65, 1 SNES Cart SPC7110 (Data Decompressor) (3 games) ----------------------------------------------- The SPC7110 (full name "SPC7110F0A" or "SPC7110Foa") is a 100pin Data Decompression chip from Epson/Seiko, used only by three games from Hudson soft: Far East of Eden Zero (with RTC-4513) (1995) Red Company/Hudson Soft (JP) Momotaro Dentetsu Happy (1996) Hudson Soft (JP) Super Power League 4 (1996) Hudson Soft (JP) XXX add info from byuu's "spc7110-mcu.txt" file. --> SNES Cart SPC7110 Memory and I/O Map --> SNES Cart SPC7110 Decompression I/O Ports --> SNES Cart SPC7110 Direct Data ROM Access --> SNES Cart SPC7110 Multiply/Divide Unit --> SNES Cart SPC7110 with RTC-4513 Real Time Clock (1 game) --> SNES Cart SPC7110 Decompression Algorithm --> SNES Cart SPC7110 Notes Pinouts --> SNES Pinouts Decompression Chips SNES Cart SPC7110 Memory and I/O Map ------------------------------------ Memory Map 4800h..4842h SPC7110 I/O Ports 6000h..7FFFh Battery-backed SRAM (8K bytes, in all 3 games) 8000h..FFFFh Exception Handlers (Program ROM offset 8000h..FFFFh) C00000h..CFFFFFh Program ROM (1MByte) (HiROM) D00000h..DFFFFFh Data ROM (1MByte-fragment mapped via Port 4831h) E00000h..EFFFFFh Data ROM (1MByte-fragment mapped via Port 4832h) F00000h..FFFFFFh Data ROM (1MByte-fragment mapped via Port 4833h) I/O Ports and SRAM are probably mirrored to banks 00h-3Fh and 80h-BFh. Program/Data ROM is probably mirrored to 400000h-7FFFFFh, the upper 32K fragments of each 64K bank probably also to banks 00h-3Fh and 80h-BFh. Reportedly (probably nonsense?) "data decompressed from data rom by spc7110 mapped to $50:0000-$50:FFFF". That info would imply that "decompressed data" Port 4800h is mirrored to 500000h-5FFFFFh (though more likely, the "un-decompressed data" is mirrored from D00000h-DFFFFFh). ROM-Image Format The existing SPC7110 games are 2MB, 3MB, 5MB in size. Stored like so: 000000h..0FFFFFh Program ROM (1MByte) (HiROM) 100000h..xFFFFFh Data ROM (1MByte, 2MByte, or 4MByte max) Observe that the SPC7110 ROM checksums at [FFDCh..FFDFh] are calculated unconventionally: 3MB/5MB aren't "rounded-up" to 4MB/8MB. Instead, 3MB is checksummed twice (rounded to 6MB). 2MB/5MB are checksummed as 2MB/5MB (without rounding). Data ROM Decompression Ports 4800h -- Decompressed Data Read 4801h 00 Compressed Data ROM Directory Base, bit0-7 4802h 00 Compressed Data ROM Directory Base, bit8-15 4803h 00 Compressed Data ROM Directory Base, bit16-23 4804h 00 Compressed Data ROM Directory Index 4805h 00 Decompressed Data RAM Target Offset, bit0-7 OFFSET IN BANK $50 4806h 00 Decompressed Data RAM Target Offset, bit8-15 OFFSET IN BANK $50 4807h 00 Unknown ("DMA Channel for Decompression") 4808h 00 Unknown ("C r/w option, unknown") 4809h 00 Decompressed Data Length Counter, bit0-7 480Ah 00 Decompressed Data Length Counter, bit8-15 480Bh 00 Unknown ("Decompression Mode") 480Ch 00 Decompression Status (bit7: 0=Busy/Inactive, 1=Ready/DataAvailable) Direct Data ROM Access 4810h 00 Data ROM Read from [Base] or [Base+Offs], and increase Base or Offs 4811h 00 Data ROM Base, bit0-7 (R/W) 4812h 00 Data ROM Base, bit8-15 (R/W) 4813h 00 Data ROM Base, bit16-23 (R/W) 4814h 00 Data ROM Offset, bit0-7 ;\optionally Base=Base+Offs 4815h 00 Data ROM Offset, bit8-15 ;/on writes to both of these registers 4816h 00 Data ROM Step, bit0-7 4817h 00 Data ROM Step, bit8-15 4818h 00 Data ROM Mode 481Ah 00 Data ROM Read from [Base+Offset], and optionally set Base=Base+Offs Unsigned Multiply/Divide Unit 4820h 00 Dividend, Bit0-7 / Multiplicand, Bit0-7 4821h 00 Dividend, Bit8-15 / Multiplicand, Bit8-15 4822h 00 Dividend, Bit16-23 4823h 00 Dividend, Bit24-31 4824h 00 Multiplier, Bit0-7 4825h 00 Multiplier, Bit8-15, Start Multiply on write to this register 4826h 00 Divisor, Bit0-7 4827h 00 Divisor, Bit8-15, Start Division on write to this register 4828h 00 Multiply/Divide Result, Bit0-7 4829h 00 Multiply/Divide Result, Bit8-15 482Ah 00 Multiply/Divide Result, Bit16-23 482Bh 00 Multiply/Divide Result, Bit24-31 482Ch 00 Divide Remainder, Bit0-7 482Dh 00 Divide Remainder, Bit8-15 482Eh 00 Multiply/Divide Reset (write = reset 4820h..482Dh) (write 00h) 482Fh 00 Multiply/Divide Status (bit7: 0=Ready, 1=Busy) Memory Mapping 4830h 00 SRAM Chip Enable/Disable (bit7: 0=Disable, 1=Enable) 4831h 00 Data ROM Bank for D00000h-DFFFFFh (1MByte, using HiROM mapping) 4832h 01 Data ROM Bank for E00000h-EFFFFFh (1MByte, using HiROM mapping) 4833h 02 Data ROM Bank for F00000h-FFFFFFh (1MByte, using HiROM mapping) 4834h 00 SRAM Bank Mapping?, workings unknown Real-Time Clock Ports (for external RTC-4513) 4840h 00 RTC Chip Enable/Disable (bit0: 0=Disable, 1=Enable) 4841h -- RTC Command/Index/Data Port 4842h -- RTC Ready Status SNES Cart SPC7110 Decompression I/O Ports ----------------------------------------- 4800h - Decompressed Data Read Reading from this register returns one decompressed byte, and does also decrease the 16bit length counter [4809h] by one. 4801h - Compressed Data ROM Directory Base, bit0-7 4802h - Compressed Data ROM Directory Base, bit8-15 4803h - Compressed Data ROM Directory Base, bit16-23 4804h - Compressed Data ROM Directory Index Selects a directory entry in Data ROM at [Base+Index*4]. Each entry is 4-bytes in size: Byte0 Decompression Mode (00h,01h,02h) Byte1 Compressed Data ROM Source Pointer, bit16-23 ;\ordered as so Byte2 Compressed Data ROM Source Pointer, bit8-15 ; (ie. big-endian) Byte3 Compressed Data ROM Source Pointer, bit0-7 ;/ 4805h - Decompressed Data RAM Target Offset, bit0-7 OFFSET IN BANK $50 4806h - Decompressed Data RAM Target Offset, bit8-15 OFFSET IN BANK $50 Reportedly: Destination address in bank 50h, this would imply that the SPC7110 chip contains around 64Kbytes on-chip RAM, which is probably utmost nonsense. Or, reportedly, too: Causes the first "N" decompressed bytes to be skipped, before data shows up at 4800h. That sounds more or less reasonable. If so, unknown if the hardware does decrement the offset value? 4807h - DMA Channel for Decompression Unknown. Reportedly "DMA CHANNEL FOR DECOMPRESSION, set to match snes dma channel used for compressed data". That info seems to be nonsense; the registers seems to be always set to 00h, no matter if/which DMA channel is used. 4808h - C r/w option, unknown Unknown. Reportedly "C r/w option, unknown". 4809h - Decompressed Data Length Counter, bit0-7 480Ah - Decompressed Data Length Counter, bit8-15 This counter is decremented on reads from [4800h]. One can initialize the counter before decompression & check its value during decompression. However, this doesn't seem to be required hardware-wise; the decompression seems to be working endless (as long as software reads [4800h]), and doesn't seem to "stop" when the length counter becomes zero. 480Bh - Decompression Mode Reportedly: 00 - manual decompression, $4800 is used to read directly from the data rom 02 - hardware decompression, decompressed data is mapped to $50:0000, $4800 can be used to read sequentially from bank $50 480Ch - Decompression Status (bit7: 0=Busy/Inactive, 1=Ready/DataAvailable) Reportedly: DECOMPRESSION FINISHED STATUS: high bit set = done, high bit clear = processing, cleared after successful read, high bit is cleared after writing to $4806, $4809/A is set to compressed data length --- decompression mode is activated after writing to $4806 and finishes after reading the high bit of $480C SNES Cart SPC7110 Direct Data ROM Access ---------------------------------------- 4810h Data ROM Read from [Base] or [Base+Offs], and increase Base or Offs 481Ah Data ROM Read from [Base+Offset], and optionally set Base=Base+Offs Reportedly, Testing leads to believe that the direct ROM read section starts out as inactive. One of the ways to activate direct reads is to write a non-zero value to $4813. No other action need be taken. You can write a non-zero value and immediately write a zero to it and that's OK. The order of writes to $4811/2/3 don't seem to matter so long as $4813 has been written to once with a non-zero value. There may be a way to deactivate the direct reads again (maybe a decompression cycle?). There appears to be another way to activate direct reads that is more complex. 4811h Data ROM Base, bit0-7 (R/W) 4812h Data ROM Base, bit8-15 (R/W) 4813h Data ROM Base, bit16-23 (R/W) 4814h Data ROM Offset, bit0-7 ;\optionally Base=Base+Offs 4815h Data ROM Offset, bit8-15 ;/on writes to both of these registers 4816h Data ROM Step, bit0-7 4817h Data ROM Step, bit8-15 4818h Data ROM Mode 0 Select Step (for 4810h) (0=Increase by 1, 1=Increase by "Step" Value) 1 Enable Offset (for 4810h) (0=Disable/Read Ptr, 1=Enable/Read Ptr+Offset) 2 Expand Step from 16bit to 24bit (0=Zero-expand, 1=Sign-expand) 3 Expand Offset from 8bit?/16bit to 24bit (0=Zero-expand, 1=Sign-expand) 4 Apply Step (after 4810h read) (0=On 24bit Pointer, 1=On 16bit Offset) 5-6 Special Actions (see below) 7 Unused (should be zero) Special Actions: 0=No special actions 1=After Writing $4814/5 --> 8 bit offset addition using $4814 2=After Writing $4814/5 --> 16 bit offset addition using $4814/5 3=After Reading $481A --> 16 bit offset addition using $4814/5 Reportedly, 4818 write: set command mode, 4818 read: performs action instead of returning value, unknown purpose command mode is loaded to $4818 but only set after writing to both $4814 and $4815 in any order $4811/2/3 may increment on a $4810 read depending on mode byte) $4814/$4815 is sometimes incremented on $4810 reads (depending on mode byte) Note: the data rom command mode is activated only after registers $4814 and $4815 have been written to, regardless of the order they were written to 4831h Data ROM Bank for D00000h-DFFFFFh (1MByte, using HiROM mapping) 4832h Data ROM Bank for E00000h-EFFFFFh (1MByte, using HiROM mapping) 4833h Data ROM Bank for F00000h-FFFFFFh (1MByte, using HiROM mapping) 4830h SRAM Chip Enable/Disable (bit7: 0=Disable, 1=Enable) 4834h SRAM Bank Mapping?, workings unknown SNES Cart SPC7110 Multiply/Divide Unit -------------------------------------- Unsigned Multiply/Divide Unit 4820h Dividend, Bit0-7 / Multiplicand, Bit0-7 4821h Dividend, Bit8-15 / Multiplicand, Bit8-15 4822h Dividend, Bit16-23 4823h Dividend, Bit24-31 4824h Multiplier, Bit0-7 4825h Multiplier, Bit8-15, Start Multiply on write to this register 4826h Divisor, Bit0-7 4827h Divisor, Bit8-15, Start Division on write to this register 4828h Multiply/Divide Result, Bit0-7 4829h Multiply/Divide Result, Bit8-15 482Ah Multiply/Divide Result, Bit16-23 482Bh Multiply/Divide Result, Bit24-31 482Ch Divide Remainder, Bit0-7 482Dh Divide Remainder, Bit8-15 482Eh Multiply/Divide Reset (write = reset 4820h..482Dh) (write 00h) 482Fh Multiply/Divide Status (bit7: 0=Ready, 1=Busy) Unknown Stuff Multiply/Divide execution time is unknown. Is it constant/faster for small values? Behaviour on Divide by 0 is unknown? Purpose of 482Eh is unknown, does it really "reset" 4820h..482Dh? Meaning that those registers are set to zero? Is that required/optional? Are there other modes, like support for signed-numbers, or a fast 8bit*8bit multiply mode or such? Reportedly 482Eh.bit0 (0=unsigned, 1=signed) (un)signed div0 returns --> result=00000000h, remainder=dividend AND FFFFh -80000000h/-1 returns ? SNES Cart SPC7110 with RTC-4513 Real Time Clock (1 game) -------------------------------------------------------- RTC from Epson/Seiko. Used by one game from Hudson Soft: Far East of Eden Zero (with RTC-4513) (1995) Red Company/Hudson Soft (JP) SPC7110 I/O Ports for RTC-4513 Access 4840h RTC Chip Select (bit0: 0=Deselect: CE=LOW, 1=Select: CE=HIGH) 4841h RTC Data Port (bit0-3: Command/Index/Data) 4842h RTC Status (bit7: 1=Ready, 0=Busy) (for 4bit transfers) Usage Switch CE from LOW to HIGH, send Command (03h=Write, 0Ch=Read), send starting Index (00h..0Fh), then read or write one or more 4bit Data units (index will automatically increment after each access, and wraps from 0Fh to 00h at end of data stream). Finally, switch CE back LOW. Epson RTC-4513 Commands 03h Write-Mode 0Ch Read-Mode Epson RTC-4513 Register Table Index Bit3 Bit2 Bit1 Bit0 Expl. 0 Sec3 Sec2 Sec1 Sec0 Seconds, Low 1 LOST Sec6 Sec5 Sec4 Seconds, High 2 Min3 Min2 Min1 Min0 Minutes, Low 3 WRAP Min6 Min5 Min4 Minutes, High 4 Hour3 Hour2 Hour1 Hour0 Hours, Low 5 WRAP PM/AM Hour5 Hour4 Hours, High 6 Day3 Day2 Day0 Day0 Day, Low ;\ 7 WRAP RAM Day5 Day4 Day, High ; 8 Mon3 Mon2 Mon1 Mon0 Month, Low ; or optionally, 9 WRAP RAM RAM Mon4 Month, High ; 6x4bit User RAM A Year3 Year2 Year1 Year0 Year, Low ; B Year7 Year6 Year5 Year4 Year, High ;/ C WRAP Week2 Week1 Week0 Day of Week D 30ADJ IRQ-F CAL/HW HOLD Control Register D E RATE1 RATE0 DUTY MASK Control Register E F TEST 24/12 STOP RESET Control Register F Whereas, the meaning of the various bits is: Sec Seconds (BCD, 00h..59h) Min Minutes (BCD, 00h..59h) Hour Hours (BCD, 00h..23h or 01h..12h) Day Day (BCD, 01h..31h) Month Month (BCD, 01h..12h) Year Year (BCD, 00h..99h) Week Day of Week (0..6) (Epson suggests 0=Monday as an example) PM/AM Set for PM, cleared for AM (is that also in 24-hour mode?) WRAP Time changed during access (reset on CE=LOW, set on seconds increase) HOLD Pause clock when set (upon clearing increase seconds by 1 if needed) LOST Time lost (eg. battery failure) (can be reset by writing 0) IRQ-F Interrupt Flag (Read-only, set when: See Rate, cleared when: See Duty) RATE Interrupt Rate (0=Per 1/64s, 1=Per Second, 2=Per Minute, 3=Per Hour) DUTY Interrupt Duty (0=7.8ms, 1=Until acknowledge, ie. until IRQ-F read) MASK Interrupt Disable (when set: IRQ-F always 0, STD.P always High-Z) TEST Reserved for Epson's use (should be 0) (auto-cleared on CE=LOW) RAM General purpose RAM (usually 3bits) (24bits when Calendar=off) CAL/HW Calendar Enable (1=Yes/Normal, 0=Use Day/Mon/Year as 24bit user RAM) 24/12 24-Hour Mode (0=12, 1=24) (Time/Date may get corrupted when changed!) 30ADJ Set seconds to zero, and, if seconds was>=30, increase minutes STOP Stop clock while set (0=Stop, 1=Normal) RESET Stop clock and reset seconds to 00h (auto-cleared when CE=LOW) If WRAP=1 then one must deselect the chip, and read time/date again. Serial data is transferred LSB first. On-chip 32.768kHz quartz crystal. Pin-Outs --> SNES Pinouts RTC Chips SNES Cart SPC7110 Decompression Algorithm ----------------------------------------- decompress_mode0(src,dst,len) initialize while len>0 decoded=0 con=0, decompression_core con=1+decoded, decompression_core con=3+decoded, decompression_core con=7+decoded, decompression_core out = (out SHL 4) XOR (((out SHR 12) XOR decoded) AND Fh) decoded=0 con=15, decompression_core con=15+1+decoded, decompression_core con=15+3+decoded, decompression_core con=15+7+decoded, decompression_core out = (out SHL 4) XOR (((out SHR 12) XOR decoded) AND Fh) [dst]=(out AND FFh), dst=dst+1, len=len-1 decompress_mode1(src,dst,len) initialize while len>0 if (buf_index AND 01h)=0 for pixel=0 to 7 a = (out SHR 2) AND 03h b = (out SHR 14) AND 03h decoded=0 con = get_con(a,b,c) decompression_core con = con*2+5+decoded decompression_core do_pixel_order(a,b,c,2,decoded) plane0.bits(7..0) = out.bits(15,13,11,9,7,5,3,1) plane1.bits(7..0) = out.bits(14,12,10,8,6,4,2,0) [dst]=plane0 else [dst]=plane1 buf_index=buf_index+1, dst=dst+1, len=len-1 decompress_mode2(src,dst,len) initialize while len>0 if (buf_index AND 11h)=0 for pixel=0 to 7 a = (out SHR 0) AND 0Fh b = (out SHR 28) AND 0Fh decoded=0 con=0 decompression_core con=decoded+1 decompression_core if con=2 then con=decoded+11 else con = get_con(a,b,c)+3+decoded*5 decompression_core con=Mode2ContextTable[con]+(decoded AND 1) decompression_core do_pixel_order(a,b,c,4,decoded) plane0.bits(7..0) = out.bits(31,27,23,19,15,11,7,3) plane1.bits(7..0) = out.bits(30,26,22,18,14,10,6,2) plane2.bits(7..0) = out.bits(29,25,21,17,13, 9,5,1) plane3.bits(7..0) = out.bits(28,24,20,16,12, 8,4,0) bitplanebuffer[buf_index+0] = plane2 bitplanebuffer[buf_index+1] = plane3 [dst]=plane0 else if (buf_index AND 10h)=0 [dst]=plane1 else [dst]=bitplanebuffer[buf_index AND 0Fh] buf_index=buf_index+1, dst=dst+1, len=len-1 initialize src=directory_base+(directory_index*4) mode=[src+0] src=[src+3]+[src+2]*100h+[src+1]*10000h ;big-endian (!) buf_index=0 out=00000000h c=0 top=255 val.msb=[src], val.lsb=00h, src=src+1, in_count=0 for i=0 to 15 do pixelorder[i]=i for i=0 to 31 do ContextIndex[i]=0, ContextInvert[i]=0 decompression_core decoded=(decoded SHL 1) xor ContextInvert[con] evl=ContextIndex[con] top = top - EvolutionProb[evl] if val.msb > top val.msb = val.msb-(top-1) top = EvolutionProb[evl]-1 if top>79 then ContextInvert[con] = ContextInvert[con] XOR 1 decoded = decoded xor 1 ContextIndex[con] = EvolutionNextLps[evl] else if top<=126 then ContextIndex[con] = EvolutionNextMps[evl] while(top<=126) if in_count=0 then val.lsb=[src], src=src+1, in_count=8 top = (top SHL 1)+1 val = (val SHL 1), in_count=in_count-1 ;16bit val.msb/lsb do_pixel_order(a,b,c,shift,decoded) m=0, x=a, repeat, exchange(x,pixelorder[m]), m=m+1, until x=a for m=0 to (1 shl shift)-1 do realorder[m]=pixelorder[m] m=0, x=c, repeat, exchange(x,realorder[m]), m=m+1, until x=c m=0, x=b, repeat, exchange(x,realorder[m]), m=m+1, until x=b m=0, x=a, repeat, exchange(x,realorder[m]), m=m+1, until x=a out = (out SHL shift) + realorder[decoded] c = b get_con(a,b,c) if (a=b AND b=c) then return=0 else if (a=b) then return=1 else if (b=c) then return=2 else if (a=c) then return=3 else return=4 EvolutionProb[0..52] 90,37,17, 8, 3, 1,90,63,44,32,23,17,12, 9, 7, 5, 4, 3, 2 90,72,58,46,38,31,25,21,17,14,11, 9, 8, 7, 5, 4, 4, 3, 2 2 ,88,77,67,59,52,46,41,37,86,79,71,65,60,55 EvolutionNextLps[0..52] 1 , 6, 8,10,12,15, 7,19,21,22,23,25,26,28,29,31,32,34,35 20,39,40,42,44,45,46,25,26,26,27,28,29,30,31,33,33,34,35 36,39,47,48,49,50,51,44,45,47,47,48,49,50,51 EvolutionNextMps[0..52] 1 , 2, 3, 4, 5, 5, 7, 8, 9,10,11,12,13,14,15,16,17,18, 5 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38 5 ,40,41,42,43,44,45,46,24,48,49,50,51,52,43 Mode2ContextTable[0..14] ;only entries 3..14 used (entries 0..2 = dummies) 0 ,0 ,0 ,15,17,19,21,23,25,25,25,25,25,27,29 SNES Cart SPC7110 Notes ----------------------- Compression/Decompression Example Uncompressed Data (64-byte ASCII string): Test123.ABCDABCDAAAAAAAAaaaabbbbccccdddd7654321076543210.Test123 Compressed in Mode0: 68 91 36 15 F8 BF 42 35 2F 67 3D B7 AA 05 B4 F7 70 7A 26 20 EA 58 2C 09 61 00 C5 00 8C 6F FF D1 42 9D EE 7F 72 87 DF D6 5F 92 65 00 00 Compressed in Mode1: 4B F6 80 1E 3A 4C 42 6C DA 16 0F C6 44 ED 64 10 77 AF 50 00 05 C0 01 27 22 B0 83 51 05 32 4A 1E 74 93 08 76 07 E5 32 12 B4 99 9E 55 A3 F8 00 Compressed in Mode2: 13 B3 27 A6 F4 5C D8 ED 6C 6D F8 76 80 A7 87 20 39 4B 37 1A CC 3F E4 3D BE 65 2D 89 7E 0B 0A D3 46 D5 0C 1F D3 81 F3 AD DD E8 5C C0 BD 62 AA CB F8 B5 38 00 Selftest Program All three SPC7110 games include a selftest function (which executes on initial power-up, ie. when the battery-backed SRAM is still uninitialized). Press Button A/B to start 1st/2nd test, and push Reset Button after each test. PCBs SHVC-BDH3B-01 (without RTC) SHVC-LDH3C-01 (with RTC) SNES Cart Unlicensed Variants ----------------------------- Gamars Puzzle (Kaiser) A LoROM game with SRAM at 316000h (unlike normal LoROM games that have SRAM at 70xxxxh). Cartridge Header Maker entry is [FFDAh]=00h, and SRAM size entry is [FFD8h]=20h (4096 gigabytes), the actual size of the SRAM is unknown. Bootlegs The "bootleg" games are semi-illegal pirate productions, typically consisting of a custom (and not-so-professional) game engine, bundled with graphics and sounds ripped from commercial games. Some of these cartridges are containing some small copy-protection hardware (see below). Copy-Protected Bootlegs (Standard "bitswap" variant) This type is used by several games: A Bug's Life 2MB, CRC32=014F0FCFh Aladdin 2000 2MB, CRC32=752A25D3h Bananas de Pijamas 1MB, CRC32=52B0D84Bh Digimon Adventure 2MB, CRC32=4F660972h King of Fighters 2000 (aka KOF2000) 3MB, CRC32=A7813943h Pocket Monster (aka Picachu) 2MB, CRC32=892C6765h Pokemon Gold Silver 2MB, CRC32=7C0B798Dh Pokemon Stadium 2MB, CRC32=F863C642h Soul Edge Vs Samurai 2MB, CRC32=5E4ADA04h Street Fighter EX Plus Alpha 2MB, CRC32=DAD59B9Fh X-Men vs. Street Fighter 2MB, CRC32=40242231h The protection hardware is mapped to: 80-xx:8000-FFFF Read 8bit Latch (bits re-ordered as: 0,6,7,1,2,3,4,5) 88-xx:8000-FFFF Write 8bit Latch (bits ordered as: 7,6,5,4,3,2,1,0) Copy-Protected Bootlegs (Soulblade "constant" variant) This type is used by only one game: Soul Blade 3MB, CRC32=C97D1D7Bh The protection hardware consists of a read-only pattern, mapped to: 80-BF:8000-FFFF Filled with a constant 4-byte pattern (55h,0Fh,AAh,F0h) C0-FF:0000-FFFF Open bus (not used) Copy-Protected Bootlegs (Tekken2 "alu/flipflop" variant) This type is used by only one game: Tekken 2 2MB, CRC32=066687CAh The protection hardware is mapped to: [80-BF:80xx]=0Fh,00h Clear all 6 bits [80-BF:81xx]=xxh Probably "No Change" (unused, except for Reading) [80-BF:82xx]=FFh,00h Set Data bit0 [80-BF:83xx]=FFh,00h Set Data bit1 [80-BF:84xx]=FFh,00h Set Data bit2 [80-BF:85xx]=FFh,00h Set Data bit3 [80-BF:86xx]=FFh,00h Set ALU Direction bit (0=Up/Left, 1=Down/Right) [80-BF:87xx]=FFh,00h Set ALU Function bit (0=Count, 1=Shift) X=[80-BF:81xx] Return "4bitData plus/minus/shl/shr 1" ;the above specs are based on 12 known/guessed results (as guessed by d4s), ;the remaining 52 combinations are probably following same rules (not tested ;on real hardware). theoretically some ports might do things like "set bitX ;and clear bitY", in that case, there would be more than 64 combinations. The hardware is often missing I/O accesses, unless one is repeating them some dozens of times; the existing game is issuing 240 words (480 bytes) to write-ports, and reads 256 words (512 bytes) from the read-port. The reads contain the result in lower 4bit (probably in both low-byte and high-byte of the words) (and unknown/unused stuff in the other bits). The set/clear ports are said to react on both reads and writes (which would imply that the written data is don't care). SNES Cart S-RTC (Realtime Clock) (1 game) ----------------------------------------- PCB "SHVC-LJ3R-01" with 24pin "Sharp S-RTC" chip. Used only by one japanese game: Dai Kaiju Monogatari 2 (1996) Birthday/Hudson Soft (JP) S-RTC I/O Ports 002800h S-RTC Read (R) 002801h S-RTC Write (W) Both registers are 4bits wide. When writing: Upper 4bit should be zero. When reading: Upper 4bit should be masked-off (they do possibly contain garbage, eg. open-bus). S-RTC Communication The sequence for setting, and then reading the time is: Send <0Eh,04h,0Dh,0Eh,00h,Timestamp(12 digits),0Dh> to [002801h] If ([002800h] AND 0F)=0Fh then read If ([002800h] AND 0F)=0Fh then read If ([002800h] AND 0F)=0Fh then read If ([002800h] AND 0F)=0Fh then read etc. The exact meaning of the bytes is unknown. 0Eh/0Dh seems to invoke/terminate commands, 04h might be some configuration stuff (like setting 24-hour mode). 00h is apparently the set-time command. There might be further commands (such like setting interrupts, alarm, 12-hour mode, reading battery low & error flags, etc.). When reading, 0Fh seems to indicate sth like "time available". The 12/13-digit "SSMMHHDDMYYY(D)" Timestamps are having the following format: Seconds.lo (BCD, 0..9) Seconds.hi (BCD, 0..5) Minutes.lo (BCD, 0..9) Minutes.hi (BCD, 0..5) Hours.lo (BCD, 0..9) Hours.hi (BCD, 0..2) Day.lo (BCD, 0..9) Day.hi (BCD, 0..3) Month (HEX, 01h..0Ch) Year.lo (BCD, 0..9) Year.hi (BCD, 0..9) Century (HEX, 09h..0Ah for 19xx..20xx) When READING the time, there is one final extra digit (the existing software doesn't transmit that extra digit on WRITING, though maybe it's possible to do writing, too): Day of Week? (0..6) (unknown if RTC assigns sth like 0=Sunday or 0=Monday) Pinouts --> SNES Pinouts RTC Chips Note There's another game that uses a different RTC chip: A 4bit serial bus RTC-4513 (as made by Epson) connected to a SPC7110 chip. SNES Cart Super Gameboy ----------------------- The Super Gameboy (SGB) is some kind of an adaptor for monochrome handheld Gameboy games. The SGB cartridge contains a fully featured gameboy (with CPU, Video & Audio controllers), but without LCD screen and without joypad buttons. The 4-grayshade 160x144 pixel video signal is forwarded to SNES VRAM and shown on TV Set, and in the other direction, the SNES joypad data is forwarded to SGB CPU. Some gameboy games include additional SGB features, allowing to display a 256x224 pixel border that surrounds the 160x144 pixel screen, there are also some (rather limited) functions for colorizing the monochrome screen, plus some special Sound, OBJ, Joypad functions. Finally, the gameboy game can upload program code to the SNES and execute it. Chipset SGB CPU - 80pin - Super Gameboy CPU/Video/Audio Chip ICD2-R (or ICD2-N) - 44pin - Super Gameboy SGB-to-SNES Interface Chip Plus VRAM/WRAM for SGB CPU, plus SNES SGB BIOS, plus CIC chip. SGB I/O Map (ICD2-R) 6000 R LCD Character Row and Buffer Write-Row 6001 W Character Buffer Read Row Select 6002 R 16-Byte Packet Available Flag 6003 W Reset/Multiplayer/Speed Control 6004-6007 W Controller Data for Player 1-4 6008-600E - Unused (Open Bus, or mirror of 600Fh on some chips) 600F R Chip Version (21h or 61h) 6800-680F - Unused (Open Bus) 7000-700F R 16-byte command packet (addr 7000..700F) 7800 R Character Buffer Data (320 bytes of currently selected row) 7801-780F R Unused (Mirrors of 7800h, not Open Bus) The ICD2 chips decodes only A0-A3,A11-A15,A22 (so above is mirrored to various addresses at xx6xxN/xx7xxN). Reading the Unused registers (and write-only ones) returns garbage. On chips with [600Fh]=61h, that garbage is: CPU Open Bus values (though, for some reason, usually with bit3=1). On chips with [600Fh]=21h, that garbage is: 6001h.R, 6004h-6005h.R --> mirror of 6000h.R 6003h.R, 6006h-6007h.R --> mirror of 6002h.R 6008h-600Eh.R --> mirror of 600Fh.R On ICD2-N chips and/or such with [600Fh]=other, that garbage is: Unknown. SGB Port 6000h - LCD Character Row and Buffer Write-Row (R) 7-3 Current Character Row on Gameboy LCD (0..11h) (11h=Last Row, or Vblank) 2 Seems to be always zero 1-0 Current Character Row WRITE Buffer Number (0..3) SGB Port 6001h - Character Buffer Read Row Select (W) 7-2 Unknown/unused (should be zero) 1-0 Select Character Row READ Buffer Number (0..3) Selects one of the four buffer rows (for reading via Port 7800h). Only the three "old" buffers should be selected, ie. not the currently written row (which is indicated in 6000h.Bit1-0). SGB Port 6002h - 16-Byte Packet Available Flag (R) 7-1 Seems to be always zero 0 New 16-byte Packet Available (0=None, 1=Yes) When set, a 16-byte SGB command packet can be read from 7000h-700Fh; of which, reading 7000h does reset the flag in 6002h. SGB Port 6003h - Reset/Multiplayer/Speed Control (W) 7 Reset Gameboy CPU (0=Reset, 1=Normal) 6 Unknown/unused (should be zero) 5-4 num_controllers (0,1,3=One,Two,Four) (default 0=One Player) 3-2 Unknown/unused (should be zero) 1-0 SGB CPU Speed (0..3 = 5MHz,4MHz,3MHz,2.3MHz) (default 1=4MHz) The LSBs select the SGB CPU Speed (the SNES 21MHz master clock divided by 4,5,7,9). Unknown if/how/when the SGB BIOS does use this. For the SGB, the exact master clock depends on the console (PAL or NTSC). For the SGB2 it's derived from a separate 20.9MHz oscillator. SGB Port 6004h-6007h - Controller Data for Player 1-4 (W) 7 Start (0=Pressed, 1=Released) 6 Select (0=Pressed, 1=Released) 5 Button B (0=Pressed, 1=Released) 4 Button A (0=Pressed, 1=Released) 3 Down (0=Pressed, 1=Released) 2 Up (0=Pressed, 1=Released) 1 Left (0=Pressed, 1=Released) 0 Right (0=Pressed, 1=Released) Used to forward SNES controller data to the gameboy Joypad inputs. Ports 6005h-6007h are used only in 2-4 player mode (which can be activated via 6003h; in practice: this can be requested by SGB games via MLT_REQ (command 11h), see SGB section in Pan Docs for details). SGB Port 600Fh - Chip Version (R) 7-0 ICD2 Chip Version Seems to indicate the ICD2 Chip Version. Known values/versions are: 21h = ICD2-R (without company logo on chip package) 61h = ICD2-R (with company logo on chip package) ?? = ICD2-N (this one is used in SGB2) The versions differ on reading unused/write-only ports (see notes in SGB I/O map). SGB Port 7000h-700Fh - 16-byte Command Packet (R) 7-0 Data Reading from 7000h (but not from 7001h-700Fh) does reset the flag in 6002h Aside from regular SGB commands, the SGB BIOS (that in the SGB CPU chip) does transfer six special packets upon Reset; these do contain gameboy cartridge header bytes 104h..14Fh (ie. Nintendo Logo, Title, ROM/RAM Size, SGB-Enable bytes, etc). SGB Port 7800h - Character Buffer Data (R) 7-0 Data (320 bytes; from Buffer Row number selected in Port 6001h) This port should be used as fixed DMA source address for transferring 320 bytes (one 160x8 pixel character row) to WRAM (and, once when the SNES is in Vblank, the whole 160x144 pixels can be DMAed from WRAM to VRAM). The ICD2 chip does automatically re-arrange the pixel color signals (LD0/LD1) back to 8x8 pixel tiles with two bit-planes (ie. to the same format as used in Gameboy and SNES VRAM). The buffer index (0..511) is reset to 0 upon writing to Port 6001h, and is automatically incremented on reading 7800h. When reading more than 320 bytes, indices 320..511 return FFh bytes (black pixels), and, after 512 bytes, it wraps to index 0 within the same buffer row. Gameboy Audio The stereo Gameboy Audio Output is fed to the External Audio Input on SNES cartridge port, so sound is automatically forwarded to the TV Set, ie. software doesn't need to process sound data (however, mind that the /MUTE signal of the SNES APU must be released). SGB Commands Above describes only the SNES side of the Super Gameboy. For the Gameboy side (ie. for info on sending SGB packets, etc), see SGB section in Pan Docs: http://problemkaputt.de/pandocs.htm http://problemkaputt.de/pandocs.txt Some details that aren't described in (current) Pan Docs: * JUMP does always destroy the NMI vector (even if it's 000000h) * (The SGB BIOS doesn't seem to use NMIs, so destroying it doesn't harm) * JUMP can return via 16bit retadr (but needs to force program bank 00h) * After JUMP, all RAM can be used, except [0000BBh..0000BDh] (=NMI vector) * The IRQ/COP/BRK vectors/handlers are in ROM, ie. only NMIs can be hooked * APU Boot-ROM can be executed via MOV [2140h],FEh (but Echo-Write is kept on) * The TEST_EN command points to a RET opcode (ie. it isn't implemented) * Upon RESET, six packets with gameboy cart header are sent by gameboy bios * command 19h does allow to change an undoc flag (maybe palette related?) * command 1Ah..1Fh point to RET (no function) (except 1Eh = boot info) * sgb cpu speed can be changed (unknown if/how supported by sgb bios) Note There is a special controller, the SGB Commander (from Hori), which does reportedly have special buttons for changing the CPU speed - unknown how it is doing that (ie. unknown what data and/or ID bits it is transferring to the SNES controller port). Probably done by sending button sequences (works also with normal joypad): Codes for Super GameBoy Hardware Enter these codes very quickly for the desired effect. After choosing a border from 4 - 10, press L + R to exit. Press L, L, L, L, R, L, L, L, L, R. - Screen Savers At the Super Game Boy, press L, L, L, R, R, R, L, L, L, R, R, R, R, R, R, R - Super Gameboy Credits Hold UP as you turn on the SNES and then press L, R, R, L, L, R - Toggle Speed During a game, press L, R, R, L, L, R - Toggle Speed During a game, press R, L, L, R, R, L - Toggle Sound -- Screen Savers --> Choose a border from 4 to 10 and press L + R to exit. Press L(4), R, L(4), R. Super Gameboy Credits --> When you see the Super Game Boy screen appear, press L, L, L, R, R, R, L, L, L, R, R, R, R, R, R, R Toggle Speed (Fast, Normal, Slow, Very Slow) Hold Up when powering up the SNES, then press L, R, R, L, L, R very fast. Toggle Speed (Normal, Slow, Very Slow) During Gameplay, press L, R, R, L, L, R very fast. Un/Mute Sound --> During Gameplay, press R, L, L, R, R, L quite fast. SNES Cart Satellaview (satellite receiver & mini flashcard) ----------------------------------------------------------- Satellaview I/O Ports --> SNES Cart Satellaview I/O Map --> SNES Cart Satellaview I/O Ports of MCC Memory Controller --> SNES Cart Satellaview I/O Receiver Data Streams --> SNES Cart Satellaview I/O Receiver Data Streams (Notes) --> SNES Cart Satellaview I/O Receiver Control --> SNES Cart Satellaview I/O FLASH Detection (Type 1,2,3,4) --> SNES Cart Satellaview I/O FLASH Access (Type 1,3,4) --> SNES Cart Satellaview I/O FLASH Access (Type 2) Satellaview Transmission Format --> SNES Cart Satellaview Packet Headers and Frames --> SNES Cart Satellaview Channels and Channel Map --> SNES Cart Satellaview Town Status Packet --> SNES Cart Satellaview Directory Packet --> SNES Cart Satellaview Expansion Data (at end of Directory Packets) --> SNES Cart Satellaview Other Packets --> SNES Cart Satellaview Buildings --> SNES Cart Satellaview People --> SNES Cart Satellaview Items Satellaview Memory --> SNES Cart Satellaview SRAM (Battery-backed) --> SNES Cart Satellaview FLASH File Header --> SNES Cart Satellaview BIOS Function Summary --> SNES Cart Satellaview Interpreter Token Summary Other Satellaview Info --> SNES Cart Satellaview Chipsets --> SNES Pinouts BSX Connectors SNES Cart Satellaview I/O Map ----------------------------- Receiver I/O Map (DCD-BSA chip) 2188h Stream 1 Hardware Channel Number, Lsb (R/W) 2189h Stream 1 Hardware Channel Number, Msb (R/W) 218Ah Stream 1 Queue Size (number of received 1+22 byte Units) (R) 218Bh Stream 1 Queue 1-byte Status Units (Read=Data, Write=Reset) 218Ch Stream 1 Queue 22-byte Data Units (Read=Data, Write=Reset/Ack) 218Dh Stream 1 Status Summary (R) 218Eh Stream 2 Hardware Channel Number, Lsb (R/W) 218Fh Stream 2 Hardware Channel Number, Msb (R/W) 2190h Stream 2 Queue Size (number of received 1+22 byte Units) (R) 2191h Stream 2 Queue 1-byte Status Unit(s?) (Read=Data, Write=Reset) 2192h Stream 2 Queue 22-byte? Data Unit(s?) (Read=Data, Write=Reset/Ack) 2193h Stream 2 Status Summary (R) 2194h POWER (bit0) and ACCESS (bit2-3) LED Control? (R/W) 2195h Unknown/Unused, maybe for EXT Expansion Port (?) 2196h Status (only bit1 is tested) (R) 2197h Control (only bit7 is modified) (R/W) 2198h Serial I/O Port 1 (R/W) 2199h Serial I/O Port 2 (R/W) Flash Card I/O Map (when mapped to bank C0h and up) C00000h Type 1-4 Detection Command (W) C00002h Type 1-4 Detection Status (R) C0FFxxh Type 1-4 Detection Response (R) C00000h Type 1,3,4 Command for Type 1,3,4 (W) C00000h Type 1,3,4 Status (normal commands) (R) C00004h Type 1,3 Status (erase-entire command) (R) C02AAAh Type 2 Command/Key for Type2 (W) C05555h Type 2 Command/Status for Type2 (R/W) xx0000h Type 1-4 Erase 64K Sector Address (W) xxxxxxh Type 1-4 Write Data Address (W) BIOS Cartridge MCC-BSC Chip Ports 005000h Unknown/Unused 015000h Bank 00h-3Fh and 80h-FFh (0=FLASH, 1=PSRAM) (?) 025000h Mapping for PSRAM/FLASH (0=32K/LoROM, 1=64K/HiROM) 035000h Bank 60h-6Fh (0=FLASH, 1=PSRAM) (?) 045000h Unknown (set when mapping PSRAM as Executable or Streaming Buffer) 055000h Bank 40h-4Fh (0=PSRAM, 1=FLASH) ;\probably also affects Banks 00h-3Fh 065000h Bank 50h-5Fh (0=PSRAM, 1=FLASH) ;/and maybe 80h-BFh when BIOS is off? 075000h Bank 00h-1Fh (0=PSRAM/FLASH, 1=BIOS) 085000h Bank 80h-9Fh (0=PSRAM/FLASH, 1=BIOS) 095000h Unknown/Unused (except: used by BS Dragon Quest, set to 00h) 0A5000h Unknown/Unused (except: used by BS Dragon Quest, set to 80h) 0B5000h Unknown/Unused (except: used by BS Dragon Quest, set to 80h) 0C5000h Bank C0h-FFh FLASH Reads? (0=Disable, 1=Enable) 0D5000h Bank C0h-FFh FLASH Writes (0=Disable, 1=Enable) 0E5000h Apply Changes to Other MCC Registers (0=Unused/Reserved, 1=Apply) 0F5000h Unknown/Unused Bits C and D are R/W (the other ones maybe, too). SNES Cart Satellaview I/O Ports of MCC Memory Controller -------------------------------------------------------- MCC I/O Ports The MCC chip is a simple 16bit register, with the bits scattered across various memory banks (probably because the MCC chip doesn't have enough pins to decode lower address bits). To change a bit: [bit_number*10000h+5000h]=bit_value*80h 005000h Unknown/Unused 015000h Bank 00h-3Fh and 80h-FFh (0=FLASH, 1=PSRAM) (?) 025000h Mapping for PSRAM/FLASH (0=32K/LoROM, 1=64K/HiROM) 035000h Bank 60h-6Fh (0=FLASH, 1=PSRAM) (?) 045000h Unknown (set when mapping PSRAM as Executable or Streaming Buffer) 055000h Bank 40h-4Fh (0=PSRAM, 1=FLASH) ;\probably also affects Banks 00h-3Fh 065000h Bank 50h-5Fh (0=PSRAM, 1=FLASH) ;/and maybe 80h-BFh when BIOS is off? 075000h Bank 00h-1Fh (0=PSRAM/FLASH, 1=BIOS) 085000h Bank 80h-9Fh (0=PSRAM/FLASH, 1=BIOS) 095000h Unknown/Unused 0A5000h Unknown/Unused 0B5000h Unknown/Unused 0C5000h Bank C0h-FFh FLASH Reads? (0=Disable, 1=Enable) 0D5000h Bank C0h-FFh FLASH Writes (0=Disable, 1=Enable) 0E5000h Apply Changes to Other MCC Registers (0=Unused/Reserved, 1=Apply) 0F5000h Unknown/Unused Bits C and D are R/W (the other ones maybe, too, probably except bit E) Bit 5,6 might also enable FLASH reads,writes in bank 40h-7Dh ? Satellaview BIOS Cartridge Memory Map 00-0F:5000 MCC I/O Ports (Memory Control, BIOS/PSRAM/FLASH Enable) 10-1F:5000-5FFF SRAM (32Kbyte SRAM in 4K-banks) xx-3F:6000-7FFF PSRAM (Mirror of 8K at PSRAM offset 06000h..07FFFh) 00-3F:8000-FFFF PSRAM/FLASH/BIOS in 32K-banks (Slow LoROM mapping) 40-4F:0000-FFFF PSRAM/FLASH (for Executables with Slow HiROM mapping) 50-5F:0000-FFFF PSRAM/FLASH (for Executables with Slow HiROM mapping) 60-6F:0000-FFFF FLASH/PSRAM (for use as Work RAM or Data Files) 70-77:0000-FFFF PSRAM 80-BF:8000-FFFF PSRAM/FLASH/BIOS in 32K-banks (Fast LoROM mapping) C0-FF:0000-FFFF PSRAM/FLASH (FLASH with R/W Access) Memory BIOS ROM 1MByte (LoROM mapping, 20h banks of 32Kbytes each) FLASH 1Mbyte (can be mapped as LoROM, HiROM, or Work Storage) PSRAM 512Kbyte (can be mapped as LoROM, HiROM, or Work RAM) SRAM 32Kbyte (mapped in eight 4K banks) Note: FLASH is on an external cartridge, size is usually 1MByte (as shown above). SNES Cart Satellaview I/O Receiver Data Streams ----------------------------------------------- The receiver can be programmed to watch (and receive) two different Hardware Channels simultaneously. In practice, Stream 1 is used only by the BIOS, and Stream 2 is used only by a few BS FLASH games (Dragon Quest 1, Satella2 1, BS Fire Emblem Akaneia Senki 1, and maybe some others) (which do use it for receiving Time Channel Packets). 2188h/2189h Stream 1 Hardware Channel Number, Lsb/Msb (R/W) 218Eh/218Fh Stream 2 Hardware Channel Number, Lsb/Msb (R/W) 0-15 Hardware Channel Number (16bit) XXX reportedly only 14bit !? Values written to these registers should be taken from the Channel Map packet (or for receiving the Channel Map itself, use fixed value 0124h). Be sure to reset the Queues after changing the channel number (so you won't receive old data from old channel). 218Ah Stream 1 Queue Size (number of received 1+22 byte Units) (R) 2190h Stream 2 Queue Size (number of received 1+22 byte Units) (R) 0-6 Number of received Units contained in the Queue (0..127) 7 Overrun Error Flag (set when received more than 127 units) Indicates how many frames are in the queues. One doesn't need to process all frames at once; when reading only a few frames, the Queue Size is decremented accordingly, and the remaining frames stay in the Queue so they can be processed at a later time. The decrement occurs either after reading 1 byte from the Status Queue, or after reading 22 bytes from the Data Queue (anyways, to keep the queues in sync, one should always read the same amount of 1/22-byte Units from both Queues, so it doesn't matter when the decrement occurs). 218Bh Stream 1 Queue 1-byte Status Units (Read=Data, Write=Reset) 2191h Stream 2 Queue 1-byte Status Unit(s?) (Read=Data, Write=Reset) Contains Header/Data Start/End flags for the received Data Frames, the format seems to be same as for Port 218Dh/2193h (see there for details) (if it's really same, then the two Error bits should be also contained in the Status Queue, though the BIOS doesn't use them in that place). 218Ch Stream 1 Queue 22-byte Data Units (Read=Data, Write=Reset/Ack) 2192h Stream 2 Queue 22-byte? Data Unit(s?) (Read=Data, Write=Reset/Ack) Contains the received Data Frames, or in case of Header Frames: The 5/10-byte Frame Header, followed by the Packet/Fragment Header, followed by the actual Data. 218Dh Stream 1 Status Summary (R) 2193h Stream 2 Status Summary (R) These registers seem to contain a summary of the Status bytes being most recently removed from the Queue. Ie. status bits are probably getting set by ORing all values being read from Port 218Ah/2190h. The bits are probably cleared after reading 218Dh/2193h. 0-1 Unknown/unused 2-3 Error Flags (probably set on checksum errors or lost data/timeouts) 4 Packet Start Flag (0=Normal, 1=First Frame of Packet) (with Header) 5-6 Unknown/unused 7 Packet End Flag (0=Normal, 1=Last Frame of Packet) Bit 2-3 are more or less self-explaining: Don't use the queued data, and discard any already (but still incompletely) received packet fragments. Bit 4,7 are a bit more complicated. See Notes in next chapter for details. --> SNES Cart Satellaview I/O Receiver Data Streams (Notes) SNES Cart Satellaview I/O Receiver Data Streams (Notes) ------------------------------------------------------- Resetting the Queues Clearing the Status & Data Queues is needed on power-up, after Overrun, or after changing the Hardware Channel number. The procedure is: MOV A,01h ;\ MOV [218Bh],A ; must be executed in FAST memory (at 3.58MHz) (otherwise the NOP ; the Status Queue may be not in sync with the Data Queue) NOP ; (for Stream 2 do the same with Port 2192h/2193h accordingly, NOP ; though the existing games that do use Stream 2 are including NOP ; several near-excessive timing bugs in that section) MOV [218Ch],A ;/ Thereafter, Status & Data queue are empty, and the Queue Size register is 00h (both 7bit counter, and Overrun flag cleared). Reading the Queues N=[218Ah] ;-get queue size if N=0 then exit ;-exit if no data in queues if N.Bit7=1 then reset_queue/abort_packet/exit ;-handle overrun error N=max(20,N) ;-limit to max 20 (if desired) for i=0 to (N-1), stat[i]=[219Bh], next ;-read status units stat_summary=[219Dh] ;-get status summary for i=0 to (N*22-1), data[i]=[219Ch], next ;-read data units Channel Disable After receiving a full packet, the BIOS issues a "MOV [218Ch],00h", this might acknowledge something, or (more probably) disable the Channel so that no new data is added to the Queue. The mechanism for re-enabling the channel is unknown (prossibly resetting the Queue, or writing the Channel register). For Stream 2, "MOV [2192h],00h" should do the same thing. Overrun Notes Overrun means that one hasn't processed the queues fast enough. If so, one should Reset the queues and discard any already-received incomplete packet fragments. There seems to be no problem if an overrun occurs WHILE reading from the queue (ie. overrun seems to stop adding data to the queue, rather than overwriting the old queued data) (of course AFTER reading the queue, one will need to handle the overrun, ie. discard all newer data). Note: Stream 1 can queue 127 frames (presumably plus 1 incomplete frame, being currently received). As far as known, Stream 2 is used only for Time Channels (with single-frame packets), so it's unknown if Stream 2 is having the same queue size. Packet Start/End Flags The status queue values (with start/end bits isolated) would be: 90h ;packet is 1 frame (10-byte header + 12-byte data) 10h,80h ;packet is 2 frames (10-byte header + 34-byte data) 10h,00h,80h ;packet is 3 frames (10-byte header + 56-byte data) 10h,00h,00h,80h ;packet is 4 frames (10-byte header + 78-byte data) and so on. For Channel Map, header is only 5-byte, and data is 5 bigger. Caution: After having received the header (ie. at time when receiving the data), the BIOS treats the Header-Start Flag in the Status Summary register (!) as Error-Flag, to some point that makes sense in the Data-phase, but it will cause an error if a new header frame is received shortly AFTER the Data-phase. As a workaround, the transmitter should not send new Packet Fragments (on the same Hardware Channel) for at least 1/60 seconds (preferably longer, say 1/20 seconds) after the end of the last Data Frame. Transfer Rate The transfer rate is unknown. Aside from the actual transmission speed, the effective download rate will also depend on how often data is transmitted on a specific channel (there are probably pauses between packet fragments, and maybe also between 22-byte frames), this may vary depening on how many other packets are transmitted, and how much priority is given to individual packets. The download rate is slow enough for allowing the BIOS to write incoming data directly to FLASH memory. Moreover, the BIOS Vblank NMI Handler processes only max twenty 22-byte frames per 60Hz PPU frame. Knowing that, the download rate must be definetly below 26400 bytes/second (20*22*60). As far as known, the Satellaview broadcasts replaced former St.GIGA radio broadcasts, assuming that the radio used uncompressed CD quality (2x16bit at 44.1kHz), and assuming that Satellaview used the same amount of data, the transfer rate may have been 176400 bytes/second (which could have been divided to transfer 8 different packets at 22050 bytes/second, for example). SNES Cart Satellaview I/O Receiver Control ------------------------------------------ 2194h POWER (bit0) and ACCESS (bit2-3) LED Control? (R/W) 0 Usually set <-- is ZERO by Itoi (maybe POWER LED) (see? 2196h.Bit0) 1 Usually zero <-- is SET by Itoi (see? 2196h.Bit0) 2-3 Usually both set or both cleared (maybe ACCESS LED) (Bit2 is Access LED) 4-7 Usually zero Bit2/3 are toggled by software when writing to FLASH memory. Bit0 is usually set. Might control the POWER and ACCESS LEDs on the Satellaview's Front Panel (assuming that the LEDs are software controlled). Using other values than listed above might change the LED color (assuming they are two-color LEDs). 2195h Unknown/Unused, maybe for EXT Expansion Port (?) This register isn't used by the BIOS, nor by any games. Maybe it does allow to input/output data to the Satellaview's EXT Port. 2196h Status (only bit1 is tested) (R) 0 Unknown (reportedly toggles at fast speed when 2194h.Bit0-or-1? is set) 1 Status (0=Okay, 1=Malfunction) 2-7 Unknown/unused The BIOS is using only Bit1, that bit is tested shortly after the overall hardware detection, and also during NMI handling. Probably indicates some kind of fundamental problem (like low supply voltage, missing EXPAND-Pin connection in cartridge, or no Satellite Tuner connected). 2197h Control (only bit7 is modified) (R/W) 0-6 Unknown/unused (should be left unchanged) 7 Power Down Mode? (0=Power Down, 1=Operate/Normal) (Soundlink enable?) Bit7 is set by various BIOS functions, and, notably: When [7FD9h/FFD9h].Bit4 (in Satellaview FLASH File Header) is set. Also notably: Bit7 is set/cleared depending on Town Status Entry[07h].Bit6-7. 2198h Serial I/O Port 1 (R/W) 2199h Serial I/O Port 2 (R/W) These ports are basically 3-bit parallel ports, which can be used as three-wire serial ports (with clock, data.in, data.out lines) (by doing the "serial" transfer by software). Outgoing data must be written before toggling clock, incoming data can be read thereafter. 0 Clock (must be manually toggled per data bit) 1-5 Unknown/unused (should be 0) 6 Chip Select - For Port 1: 1=Select / For Port 2: 0=Select 7 Data (Write=Data.Out, Read=Data.in) (data-in is directly poll-able) Bits are transferred MSB first. Unknown which chips these ports are connected to. One port does most probably connect to the 64pin MN88821 chip (which should do have a serial port; assuming that it is a MN88831 variant). The other port connect to the small 8pin SPR-BSA chip? Possible purposes might be configuration/calibration, Audio volume control, and Audio channel selection (assuming that the hardware can decode audio data and inject it to SNES Expansion Port sound inputs). Serial Port 1 (2198h) The BIOS contains several functions for sending multi-byte data to, and receiving 16bit-units from this port. Though the functions seem to be left unused? (at least, they aren't used in the low-level portion in first 32K of the BIOS). Port 1 specific notes: When reading (without sending), the outgoing dummy-bits should be set to all zero. Chip is selected when Bit6=1. Aside from receiving data from bit7, that bit is also polled in some cases for sensing if the chip is ready (0=Busy, 1=Ready). Serial Port 2 (2199h) Data written to this port consists of simple 2-byte pairs (index-byte, data-byte), apparently to configure some 8bit registers. Used values are: Reg[0] = 88h (or 00h when Power-Down?) (soundlink on/off?) Reg[1] = 80h Reg[2] = 04h Reg[3] = 00h Reg[4] = 08h Reg[5] = 00h Reg[6] = 70h Reg[7] = Not used Reg[8] = 00h Reg[9..FF] = Not used There are also BIOS functions for reading 1-byte or 3-bytes from this Port, but they seem to be left unused (but, BS Dragon Quest, and Itoi are doing 24bit reads via direct I/O, whereas Itoi wants the 1st bit to be 0=ready/okay). Port 2 specific notes: When reading (without sending), the outgoing dummy-bits should be set to all ones. Chip(-writing) is selected when Bit6=0. SNES Cart Satellaview I/O FLASH Detection (Type 1,2,3,4) -------------------------------------------------------- The Satellaview FLASH cartridges contain slightly customized "standard" FLASH chips; with a custom Nintendo-specific Chip Detection sequence: Detection Sequence [C00000h]=38h, [C00000h]=D0h ;request chip info part 1 delay (push/pop A, three times each) ;delay [C00000h]=71h ;enter status mode repeat, X=[C00002h], until (X.bit7=1) ;wait until ready [C00000h]=72h, [C00000h]=75h ;request chip info part 2 FOR i=0 to 9, info[i]=BYTE[C0FF00h+i*2], NEXT ;read chip info (10 bytes) [C00000h]=FFh ;somewhat bugged, see below ;terminate status mode Note: Nintendo Power flashcarts are also using very similar nonstandard FLASH commands as above (there, for reading hidden mapping info, instead of for chip detection). BUG: For Type 2 chips, one use "[C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h" instead of "[C00000h]=FFh" (the BIOS is actually to do that, but it's doing it before having deciphered the Type bits). Detection Values info[0] - ID1 (Must be "M" aka 4Dh) info[1] - ID2 (Must be "P" aka 50h) info[2] - Flags (Must be bit7=0 and bit0=0) (other bits unknown) info[3] - Device Info (upper 4bit=Type, lower 4bit=Size) info[4..9] - Unknown/Unused (BIOS copies them to RAM, but doesn't use them) Type must be 01h..04h for Type 1-4 accordingly. Size must be 07h..0Ch for 128Kbyte, 256Kbyte, 512Kbyte, 1Mbyte, 2Mbyte, 4Mbyte accordingly (ie. 1 SHL N Kbytes). Rejected Values Wrong ID1/ID2 or wrong Flag Bit7/Bit0 are rejected. Type 00h or 05h..0Fh are rejected. Size 00h..05h is rejected. Size 06h would be a half 128Kbyte block, which is rounded-down to 0 blocks by the BIOS. Size 0Dh would exceed the 32bit block allocation flags in header entry 7FD0h/FFD0h. Size 0Fh would additionally exceed the 8bit size number. Special Cases If no FLASH cartridge is inserted, then the detection does probably rely on open bus values, ie. "MOV A,[C00002h]" probably needs to return C0h (the last opcode byte) which has bit7=1, otherwise the detection wait-loop would hang forever. There are reportedly some "write-protected" cartridges. Unknown what that means, ROM-cartridges, or FLASH-cartridges with some (or ALL) sectors being write-protected. And unknown what detection values they do return. FLASH Base Address The Satellaview BIOS always uses C00000h as Base Address when writing commands to FLASH, the MCC chip could be programmed to mirror FLASH to other locations (although unknown if they are write-able, if so, commands could be also written to that mirrors). Game Cartridges with built-in FLASH cartridge slot may map FLASH to other locations than C00000h, details on that games are unknown. The game carts don't include MCC chips, but other mapping hardware: In at least some of them the mapping seems to be controlled by a SA-1 chip (an external 10.74MHz 65C816 CPU with on-chip I/O ports, including memory-mapping facilities), the SA-1 doesn't seem to have FLASH-specific mapping registers, so the FLASH might be mapped as secondary ROM-chip. There may be also other games without SA-1, using different FLASH mapping mechanism(s)? For some details, see: --> SNES Cart Data Pack Slots (satellaview-like mini-cartridge slot) General Notes FLASH erase sets all bytes to FFh. FLASH writes can only change bits from 1 to 0. Thus, one must normally erase before writing (exceptions are, for example, clearing the "Limited-Start" bits in Satellaview file header). Type 2 can write 128 bytes at once (when writing less bytes, the other bytes in that area are left unchanged). The status/detection values may be mirrored to various addresses; the normal FLASH memory may be unavailable during write/erase/detection (ie. don't try to access FLASH memory, or even to execute program code in it, during that operations). SNES Cart Satellaview I/O FLASH Access (Type 1,3,4) --------------------------------------------------- The Type 1,3,4 protocol is somewhat compatible to Sharp LH28F032SU/LH28F320SK chips (which has also a same/similar 52pin package). Concerning the commands used by the BIOS, Type 1,3,4 seems to be exactly the same - except that Type 3 doesn't support the Erase-Entire chip command. Erase Entire Chip (Type 1 and 4 only) (not supported by Type 3) [C00000h]=50h ;clear status register [C00000h]=71h ;enter status mode repeat, X=[C00004h], until (X.bit3=0) ;wait until VPP voltage okay [C00000h]=A7h ;"erase all unlocked pages"? ;select erase entire-chip mode [C00000h]=D0h ;start erase [C00000h]=71h ;enter status mode repeat, X=[C00004h], until (X.bit7=1) ;wait until ready if (X.bit5=1) then set erase error flag ;check if erase error [C00000h]=FFh ;terminate status mode Unknown Command Same as Erase Entire (see above), but using 97h instead of A7h, and implemented ONLY for Type 1 and 4, that is: NOT supported (nor simulated by other commands) for neither Type 2 nor Type 3. Maybe A7h erases only unlocked pages, and 97h tries to erase all pages (and fails if some are locked?). Erase 64KByte Sector [C00000h]=50h ;clear status register [C00000h]=20h ;select erase sector mode [nn0000h]=D0h ;start erase 64K bank nn [C00000h]=70h ;enter status mode repeat, X=[C00000h], until (X.bit7=1) ;wait until ready ;; if (X.bit5=1) then set erase error flag ;check if erase error [C00000h]=FFh ;terminate status mode Write Data FOR i=first to last [C00000h]=10h ;write byte command [nnnnnnh+i]=data[i] ;write one data byte [C00000h]=70h ;enter status mode repeat, X=[C00000h], until (X.bit7=1) ;wait until ready NEXT i [C00000h]=70h ;enter status mode repeat, X=[C00000h], until (X.bit7=1) ;hmmm, wait again if (X.bit4=1) then set write error flag ;check if write error [C00000h]=FFh ;terminate status mode Enter Erase-Status Mode [C00000h]=71h ;enter status mode X=[C00004h] ;read status byte IF (X.bit7=0) THEN busy IF (X.bit3=1) THEN not-yet-ready-to-erase (VPP voltage low) IF (X.bit7=1) AND (X.bit5=0) THEN ready/okay IF (X.bit7=1) AND (X.bit5=1) THEN erase error ? Enter Other-Status Mode [C00000h]=70h ;enter status mode Terminate Command [C00000h]=FFh ;terminate Used to leave status or chip-detection mode. BUGs: On Type 3 chips, the BIOS tries to simulate the "Erase-Entire" command by issuing multiple "Erase-Sector" commands, the bug there is that it tests bit4 of the flash_size in 128Kbyte block units (rather than bit4 of the flash_status) as erase-error flag (see 80BED2h); in practice, that means that the erase-entire will always fail on 2MByte chips (and always pass okay on all other chips); whereas, erase-entire is used when downloading files (except for small files that can be downloaded or relocated to PSRAM). SNES Cart Satellaview I/O FLASH Access (Type 2) ----------------------------------------------- Type 2 protocol is completely different as for Type 1,3,4 (aside from the Chip Detection sequence, which is same for all types). Erase Entire Chip [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=80h ;unlock erase [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=10h ;do erase entire chip [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=70h ;enter status mode repeat, X=[C05555h], until (X.bit7=1) ;wait until ready if (X.bit5=1) then set erase error flag ;check if erase error [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h ;terminate status mode Erase 64KByte Sector [C00000h]=50h ;huh? (maybe a BIOS bug) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=80h ;unlock erase [C05555h]=AAh, [C02AAAh]=55h, [nn0000h]=30h ;do erase bank nn repeat, X=[C05555h], until (X.bit7=1) ;wait until ready if (X.bit5=1) then set erase error flag ;check if erase error [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h ;terminate status mode Write 1..128 Bytes (within a 128-byte boundary) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=A0h ;enter write mode FOR i=first to last, [nnnnnn+i]=data[i] ;write 1..128 byte(s) [nnnnnn+last]=DATA[last] ;write LAST AGAIN ;start write operation [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=70h ;enter status mode repeat, X=[C05555h], until (X.bit7=1) ;wait until ready [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h ;terminate status mode Enter Status Mode [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=70h ;enter status mode X=[C05555h] ;read status byte IF (X.bit7=0) THEN busy IF (X.bit7=1) AND (X.bit5=0) THEN ready/okay IF (X.bit7=1) AND (X.bit5=1) THEN ready/erase error ? Terminate Command [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h ;terminate Used to leave status or chip-detection mode. Bugged Commands The are some cases (BIOS addresses 80BF88h, 80DBA4h, 80E0D5h) where Type 2 programming is mixed up with some non-Type-2 commands (setting [C00000h]=50h and [C00000h]=FFh), these commands are probably ignored by chip (or switching it back default mode). SNES Cart Satellaview Packet Headers and Frames ----------------------------------------------- Packet Fragment Format (10-byte header) 00h 1 Transmission ID (in upper 4bit) (must stay same for all fragments) 01h 1 Current Fragment Number (in lower 7bit) 02h 3 Fragment Size (N) (big-endian) (excluding first 5 bytes at [00..04]) 05h 1 Fixed, Must be 01h 06h 1 Total Number of Fragments (00h=Infinite Streaming?) 07h 3 Target Offset (big-endian) (location of fragment within whole file) 0Ah N-5 Data Body (first 12 bytes located directly in header frame) ... ... Unused/Padding (until begin of next 22-byte Frame) This is the normal format used by all packets (except Channel Map packet). Channel Map Packet Format (5-byte header) 00h 1 Unknown/unused (would be 4bit Transmission ID for normal packets) 01h 1 Unknown/unused (would be 7bit Fragment Number for normal packets) 02h 3 Packet Size (N) (big-endian) (excluding first 5 bytes at [00..04]) 05h N Data Body (first 17 bytes located directly in header frame) ... ... Unused/Padding (until begin of next 22-byte Frame) Frames (22-bytes) Packets are divided into one or more 22-byte frames. For each frame, a 1-byte status info can be read from Port 218Bh/2191h, the status contains error flags (indicating bad checksums or lost-frames or so), and header flags (indicating begin/end of header/data or so). The 22-byte frame data can be read from Port 218Ch/2192h. If it is header frame, then its first 10 (or 5) bytes contain the header (as described above), and the remaining 12 (or 17) bytes are data. If it is a data frame, then all 22 bytes are plain data. Fragmented Packets A packet can consist of 1..128 fragments. The packet transmission is repeated several times (say, for one hour). If it is consisting of several fragments, one can start downloading anywhere, eg. with the middle fragment, and one can keep downloading even if some fragments had transmission errors (in both cases, one must download the missing fragments in the next pass(es) when the transmission is repeated). Software should maintain a list of fragments that are already received (if a fragment is already received: just remove it from the queue without writing to target area; both for saving CPU load, and for avoiding to destroy previously received packets in case of transmission errors). At some time (say, after an hour), transmission of the packet will end, and a different packet may be transferred on the same hardware channel. Verify the 4bit Transmission ID to avoid mixing up fragments from the old (desired) file with the new file. Ideally, that ID be stored in the Channel Map or Directory (this may actually be so), however, the Satellaview BIOS simply takes the ID from the first received Fragment, and then compares it against following Fragments (if the ID changed shortly after checking the Directory, and before receiving the first fragment, then the BIOS will download a "wrong" file). Fragment Size Bug The Satellaview BIOS supports only 16bit fragment sizes, it does try to handle 24bit sizes, but if the fragment size exceeds 65535 then it does receive only the first few bytes, and then treats the whole fragment as "fully" received. Text Strings Text strings (file/folder names and descriptions) can contain ASCII (and presumably JIS and SHIFT-JIS), and following specials: 00h End of Line (or return from a "\s" Sub-String) 0Dh Carriage Return Line Feed (in descriptions) 20h..7Eh ASCII 6pix characters (unlike SHIFT-JIS 12pix ones) 80h..9Fh Prefixes for double-byte characters (SHIFT-JIS) A0h..DFh Japanese single-byte characters (JIS or so) E0h..EAh Prefixes for double-byte characters (SHIFT-JIS) F0h Prefix for Symbols (40h..51h:Music-Note,Heart,Dots,Faces,MaKenji) "\\" Yen symbol (unlike ASCII, not a backslash) "\b0".."\b3" Insert Username/Money/Gender/NumItems (12pix SHIFT-JIS) "\c0".."\c5" Changes color or palette or so "\d#",p24bit Insert 16bit Decimal at [p24bit] using 6pix-font "\D#",p24bit Insert 16bit Decimal at [p24bit] using 12pix-font "\du#",v24bit Insert 16bit Decimal Interpreter-Variable using 6pix-font "\Du#",v24bit Insert 16bit Decimal Interpreter-Variable using 12pix-font # = 00 Variable width (no leading spaces/zeroes) # = 1..6 Width 1..6 chars (with leading spaces) # = 01..06 Width 1..6 chars (with leading zeroes) "\s",ptr24bit Insert Sub-string (don't nest with further "\s,\d,\D") "\g",ptr24bit Insert Custom Graphics/Symbol (ptr to xsiz,ysiz,bitmap) "\i" Carriage Return (set x=0, keep y=unchanged) (not so useful) "\m0".."\m3" Flags (bit0=ForceHorizontal16pixGrid, bit1=DonNotUpdateBg3Yet) "\n" Carriage Return Line Feed (same as 0Dh) "\p00".."\p07" Palette "\w00".."\w99" Character Delay in Frames (00=None) "\x00".."\xNN" Set Xloc "\y00".."\yNN" Set Yloc Note: "\m","\p","\w","\x","\y" are slightly bugged (causing stack overflows when using them too often within a single string; the text output thread quits at the string-end, which somewhat 'fixes' the stack-problem). CRLF can be used in Item Activation Messages, Folder or Download-File Descriptions. Multi-line messages are wrapped to the next line when reaching the end of a line (the wrapping can occur anywhere within words, to avoid that effect one must manually insert CRLF's (0Dh) at suitable locations). Some message boxes are clipped to the visible number of lines, other messages boxes prompt the user to push Button-A to read further lines. Caution: CRLF will hang in Item-Descriptions (they do work in item shops, but will hang in the Inventory menu; the only way to implement longer descriptions here is to space-pad them so that the wrapping occurs at a suitable location). SNES Cart Satellaview Channels and Channel Map ---------------------------------------------- Channels Transmission is organized in "channels". Each can Channel transmits a single Packet (which contains a File, or other special information like in Directory and Time packets). There can be (theoretically) up to 4 billion logical "Software Channels", but only 65536 physical "Hardware Channels". The latter ones are those being currently transmitted, and which can be received by programming the channel number into Port 2188h/218Eh. Channel Map Packet (Hardware Channel 0124h) Unlike normal packets (with 10-byte headers), this packet is preceeded by a 5-byte header. Loaded to 7E9BECh. Unspecified size (size should be max 1485 bytes or less, otherwise it'd overlap the Welcome Message at 7EA1B9h) (with that size limit, the map can contain max 113 channels) (but, caution: Itoi works only with max 1007 bytes (1024-byte buffer, cropped to N*22-bytes, minus 5-byte packet header)). 00h 2 ID 53h,46h ("SF") 02h 4 Unknown/unused 06h 1 Number of entries (must be at least 1) 07h 1 Checksum (above 7 bytes at [00..06] added together) 08h .. Entries (each one is 3+N*13 bytes) Each entry is: (Packet Groups) 00h 2 Software Channel Number (first 2 bytes, of total 4 bytes) 02h 1 Number of sub-entries (N) (must be at least 1) 03h N*13 Sub-entries (each one is 13 bytes) Each sub-entry is: (Separate Packets) 00h 1 Unknown/unused 01h 2 Software Channel Number (last 2 bytes, of total 4 bytes) 03h 5 Unknown/unused 08h 2 Fragment Interval (in seconds) (big-endian) (for use as timeout) 0Ah 1 Type/Target (lower 4bit indicate transfer method or so) Bit0-1: Autostart after Download (0=No, 1=Optional, 2=Yes, 3=Crash) Bit2-3: Target (0=WRAM, 1=PSRAM, 2=EntireFLASH, 3=FreeFLASH) Bit4-7: Unknown/Unused 0Bh 2 Hardware Channel Number (2 bytes) (for Port 2188h/218Eh) The transmission timeout for the Channel Map itself is 7 seconds. Hardware Channels (2-byte / 16bit) (XXX or only 14bit?!) 0121h Used for hardware-connection test (received data is ignored) 0124h Channel Map AAEEh Dummy number (often used to indicate an absent Time Channel) NNNNh Other Hardware Channels (as listed in Channel Map) [7FFFF7h] Incoming Time Channel value for some games (from separate loader?) Software Channels (4-byte pairs / 32bit) 1.1.0.4 Welcome Message (100 bytes) 1.1.0.5 Town Status (256 bytes) 1.1.0.6 Directory (16Kbytes) 1.1.0.7 SNES Patch (16Kbytes) 1.1.0.8 Time Channel (used by BS Satella2 1, BS Fire Emblem, and Itoi) 1.2.0.48 Time Channel (used by Dragon Quest 1, BS Zelda no Densetsu Remix) ?.?.?.? Time Channel (for BS Zelda - Kodai no Sekiban Dai 3 Hanashi) 1.2.129.0 Special Channel used by Derby Stallion 96 <-- on roof of building 1.2.129.16 Special Channel used by Derby Stallion 96 <-- 6th main menu option 1.2.130.N Special Channel(s) used by Itoi Shigesato no Bass Tsuri No. 1 N.N.N.N Other Software Channels (as listed in Directory) N.N.0.0 None (for directory entries that have no File or Include File) Endianess of Numbers in Satellite Packets In the satellite packets, all 16bit/24bit values (such like length or address offsets) are in big-endian format (opposite of the SNES CPUs byte-order). For the Hardware/Software Channel Numbers it's hard to say if they are meant to be big-endian, little-endian, or if they are meant to be simple byte-strings without endianess (see below for their ordering in practice). Endianess of Hardware Channels The endiness of the Hardware Channel numbers in Channel Map is same as in Port 2188h/218Eh. The endianess of the fixed values (0121h and 0124h) is also same as Port 2188h/218Eh. Ie. one can use that values without needing to swap LSBs and MSBs. Endianess of Software Channels The fixed 4-byte pairs are using same byte-order as how they are ordered in Channel Map (for example, 1.2.0.48 means that 48 (30h) is at highest address). So far it's simple. The (slightly) confusing part is that SNES software usually encodes them as 2-word pairs (since the SNES uses a little-endian CPU, the above example values would be 0201h.3000h). SNES Cart Satellaview Town Status Packet ---------------------------------------- Town Status (Software Channel 1.1.0.5) Loaded to 7EA31Dh, then copied to 7EA21Dh. Size (max) 256 bytes. Uses a normal 10-byte fragment header, but with "4bit Transmission ID" and "7bit Fragment Number" ignored, but still does use "Target Offset" for fragment(s)? 00h 1 Flags (bit0=1=Invalid) (bit1-7=unknown/unused) 01h 1 Town Status ID (packet must be processed only if this ID changes) 02h 1 Directory ID (compared to Directory ID in Directory packet) 03h 4 Unknown/unused 07h 1 APU Sound Effects/Music & BSX Receiver Power-Down Bit0-3 Unknown/unused Bit4-5 APU (0=Mute, 1=Effects, 2=Effects/MusicA, 3=Effects/MusicB) Bit6 BSX (0=Normal, 1=Power-down with Port 2199h Reg[0]=88h) Bit7 BSX (0=Normal, 1=Power-down with Port 2199h Reg[0]=00h) (Or, maybe, the "Power-down" stuff enables satellite radio, being injected to audio-inputs on expansion port...?) 08h 1 Unknown/unused 09h 8 People Present Flags (Bit0-63) (max 5) (LITTLE-ENDIAN) 11h 2 Fountain Replacement & Season Flags (Bit0-15) (LITTLE-ENDIAN) 13h 4 Unknown/unused 17h 1 Number of File IDs (X) (may be 00h=none) (max=E8h) 18h X File IDs (one byte each) (compared against File ID in Directory) This packet should be (re-)downloaded frequently. The File IDs indicate which Directory entries are valid (whereas, it seems to be possible to share the same ID for ALL files), the Directory ID indicates if the Directory itself is still valid. Fountain/Replacement and Season The animated Fountain (near beach stairs) has only decorative purposes (unlike buildings/people that can contain folders). Optionally, the fountain can be replaced by other (non-animated) decorative elements via Fountain Replacement Flags in the Town Status packet: Bit0-11 are selecting element 1-12 (if more than one bit is set, then the lowest bit is used) (if no bits are set, then the fountain is used). None 00h Default Fountain (default when no bits set) (animated) Bit0 01h Jan Altar with Apple or so Bit1 02h Feb Red Roses arranged as a Heart Bit2 03h Mar Mohican-Samurai & Batman-Joker Bit3 04h Apr Pink Tree Bit4 05h May Origami with Fish-flag Bit5 06h Jun Decorative Mushrooms Bit6 07h Jul Palmtree Christmas with Plastic-Blowjob-Ghost? Bit7 08h Aug Melons & Sunshade Bit8 09h Sep White Rabbit with Joss Sticks & Billiard Balls Bit9 0Ah Oct National Boule-Basketball Bit10 0Bh Nov Red Hemp Leaf (cannabis/autum) Bit11 0Ch Dec Christmas Tree (with special Gimmick upon accessing it) As shown above, the 12 replacements are eventually associated with months (Christmas in December makes sense... and Fish in May dunno why). Bit12-15 of the above flags are selecting Season: None 00h Default (when no bits set) Bit12 01h Spring (pale green grass) (seems to be same as default) Bit13 02h Summery (poppy colors with high contrast) Bit14 03h Autumn (yellow/brown grass) Bit15 04h Winter (snow covered) As for the Fountain, default is used when no bits set, and lowest bit is used if more than one bit is set. SNES Cart Satellaview Directory Packet -------------------------------------- Directory (Software Channel 1.1.0.6) Loaded to 7FC000h and then copied to 7EC000h. Size (max) 16Kbytes. 00h 1 Directory ID (compared to Directory ID in Town Status packet) 01h 1 Number of Folders (Buildings, People, or hidden folders) 02h 3 Unknown/unused 05h .. Folders (and File) entries (see below) ;\together .. 1 Number of Expansion Data Entries (00h=none) ; max 3FFBh bytes .. .. Expansion Data Entries (see next chapter) ;/ Folder Entry Format 00h 1 Flags (bit0=1=Invalid) (bit1-7=unknown/unused) 01h 1 Number of File Entries (if zero: buildings are usually closed) 02h 15h Folder Name (max 20 chars, terminated by 00h) (shown in building) 17h 1 Length of Folder Message (X) (in bytes, including ending 00h) 18h X Folder Message/Description (terminated by 00h) 18h+X 1 More Flags (Folder Type) Bit0 : Folder Content (0=Download/Files, 1=Shop/Items) Bit1-3 : Folder Purpose (0=Building, 1=Person, 2=Include-Files) 000b = Indoors (Building ID at [19h+X]) (Bit3-1=000b) (0) x01b = Outdoors (Person ID at [19h+X]) (Bit2-1=01b) (1,5) x1xb = Folder contains hidden Include Files (Bit2=1b) (2,3,6,7) 100b = Unknown/unused (may be useable for "Files at Home"?) (4) Bit4-7 : Unknown/unused 19h+X 1 Folder 6bit ID (eg. for Building:01h=News, for People:01h=Hiroshi) 1Ah+X 1 Unknown/Unused 1Bh+X 1 Unknown/Unused 1Ch+X 1 Clerk/Avatar (00h..10h) (eg. 0Eh=Robot, 10h=BS-X) (11h..FFh=Crash) 1Dh+X 1 Unknown/Unused 1Eh+X 1 Unknown/Unused 1Fh+X 1 Unknown/Unused 20h+X .. File/Item Entries (each one is 32h+X bytes; for items: fixed X=79h) File/Item Entry Format For Both Files and Items: 00h 1 File ID (compared to File IDs in Town Status Packet) 01h 1 Flag (bit0=used by "Town Status" check (1=Not Available)) 02h 15h File Name (max 20 chars, terminated by 00h) (shown in building) For Files: (in File Folders) 17h 1 Length of File Message (X) (in bytes, including ending 00h) 18h X File Message/Description (terminated by 00h) For Items: (in Item Folders) 17h 1 Length of Item Description+Activation+Price+Flag (X) (fixed=79h) 18h 25h Item Description (max 36 chars, plus ending 00h) 3Dh 47h Item Activation Message (min 1, max 70 chars, plus ending 00h) 84h 12 Item Price (12-Digit ASCII String, eg. "000000001200" for 1200G) 90h 1 Item Drop/Keep Flag (00h=Drop after Activation, 01h=Keep Item) For Both Files and Items: 18h+X 4 Software Channel Number of Current File (for Items: N.N.0.0=None) 1Ch+X 3 Big-Endian Filesize 1Fh+X 3 Unknown/unused (except, first 2 bytes used by Derby Stallion 96) 22h+X 1 Flags Bit0: used by "Town Status" check (1=Not Available) Bit1: Unknown/unused Bit2: Building Only (0=Also available at Home, 1=Building only) Bit3: Low Download Accuracy / Streaming or so 0=High-Download-Accuracy (for programs or other important data) 1=Low-Download-Accuracy (for audio/video data streaming) Bit4: Unused (except, must be 0 for Derby Stallion 96 files) Bit5-7: Unknown/unused 23h+X 1 Unknown/unused 24h+X 1 Flags/Target (seems to be same/similar as in Channel Map) Bit2-3: 0=Download to WRAM (not really implemented, will crash badly) 1=Download to PSRAM (without saving in FLASH) 2=Download to Continous FLASH banks (erases entire chip!) 3=Download to FREE-FLASH banks (relocate to PSRAM upon execution) 25h+X 2 Unknown/unused 27h+X 1 Date (Bit7-4=Month, Bit3-0=0) ;\copied to Satellaview 28h+X 1 Date (Bit7-3=Day, Bit2=0, Bit1-0=Unknown) ;/FLASH File Header FFD6h 29h+X 1 Timeslot (Bit7-3=StartHours.Bit4-0, Bit2-0=Start Minutes.Bit5-3) 2Ah+X 1 Timeslot (Bit4-0=EndHours.Bit4-0, Bit7-5=Start Minutes.Bit2-0) 2Bh+X 1 Timeslot (Bit7-2=EndMinutes.Bit5-0, Bit1-0=Unused) 2Ch+X 4 Software Channel Number for additional Include File (N.N.0.0=None) 30h+X 2 Unknown/unused The directory may contain files that aren't currently transmitted; check the Town Status for list of currently available File IDs. Also check the Directory ID in the Town Status, if it doesn't match up with the ID of the Directory packet, then one must download the Directory again (otherwise one needs to download it only once after power-up). Include Files Each File in the directory has an Include File entry. Before downloading a file, the BIOS checks if the Include File's Software Channel Number is listed in the Directory (in any folder(s) that are marked as containing Include Files). If it isn't listed (or if it's N.N.0.0), then there is no include file. If it is listed, then the BIOS does first download the include file, and thereafter download the original file. Whereas, the include file itself may also have an include file, and so on (the download order starts with the LAST include file, and ends with the original file). There are some incomplete dumps of some games, which have 1Mbyte FLASH dumped, but do require additional data in WRAM/PSRAM: BS Dragon Quest (copy of channel_map in PSRAM, episode_number in WRAM) BS Zelda no Densetsu Kodai no Sekiban Dai 3 Hanashi (hw_channel in WRAM) The missing data was probably transferred in form of Include files. Streaming Files There seems to be some streaming support: Files flagged as FILE[22h+X].Bit3=1 are repeatedly downloaded-and-executed again and again (possibly intended to produce movies/slideshows) (details: max 256K are loaded to upper half of PSRAM, and, if successfully received: copied to lower 256K of PSRAM and executed in that place; whereas, the execution starts once when receiving the next streaming block, that is: with a different 4bit transmission ID in the 10-byte packet header). Moreover, Packets marked as having 00h fragments, are treated as having infinite fragments (this would allow to overwrite received data by newer data; though none of the higher-level BIOS functions seems to be using that feature). Files Available at Home Some files can be downloaded at the "Home" building (via the 3rd of the 4 options in that building), these "Home" files may be located in any folders, namely, including following folders: FOLDER[00h].Bit0=Don't care (folder may be marked as hidden) FOLDER[18h+X]=Don't care (folder may be also used as building/person/etc.) For downloading them at "Home", the files must be defined as so: FILE[1Ah+X]<>0000h (software channel isn't N.N.0.0) FILE[22h+X].Bit2=0 (flagged as available at home) FILE[18h]=Don't care (file description isn't shown at home) BUG: If there are more than 32 of such "Home" files, then the BIOS tries to skip the additional files, but destroys the stack alongside that attempt. Note: Unlike other downloads, Home ones are always having a wooden-plank background, and are done without transmission Interval timeouts. And, Include Files are ignored. And, Autostart is disabled (ie. downloads to PSRAM are totally useless, downloads to FLASH can/must be manually started). SNES Cart Satellaview Expansion Data (at end of Directory Packets) ------------------------------------------------------------------ Directory (Software Channel 1.1.0.6) Loaded to 7FC000h and then copied to 7EC000h. Size (max) 16Kbytes. 00h 1 Directory ID (compared to Directory ID in Town Status packet) 01h 1 Number of Folders (Buildings, People, or hidden folders) 02h 3 Unknown/unused 05h .. Folders (and File) entries (see previous chapter) ;\together .. 1 Number of Expansion Data Entries (00h=none) ; max 3FFBh .. .. Expansion Data Entries ;/bytes Expansion Data Entry Format (after folder/file area) 00h 1 Flags (bit0=1=Invalid) (bit1-7=unknown/unused) 01h 1 Unknown/unused 02h 2 Length (N) (16bit) (this one is BIG-ENDIAN) 04h N Expansion Chunk(s) (all values in chunks are LITTLE-ENDIAN) For for some reason, there may be more than one of these entries, but the BIOS does use only the first entry with [00h].Bit0=0=Valid (any further entries are simply ignored). Chunk 00h (End) 00h 1 Chunk ID (00h) Ends (any further following chunks are ignored). Chunk 00h should be probably always attached at the end of the chunk list (although it can be omitted in some cases, eg. after Chunk 02h). Chunk 01h (Custom Building) All values in this chunk are LITTLE-ENDIAN. 00h 1 Chunk ID (01h) 01h 2 Chunk Length (73h+L1..L5) (LITTLE-ENDIAN) 03h 11h Message Box Headline (max 16 chars, terminated by 00h) ;\ 14h 20h BG Palette 5 (copied to WRAM:7E20A0h/CGRAM:50h) (16 words) ; 34h 38h BG Data (copied to WRAM:7E4C8Ch/BG1 Map[06h,0Dh])(4x7 words);/ 6Ch 2 Length of BG Animation Data (L1) ;\ 6Eh L1 BG Animation Data (for Custom Building) (see below) ;/ 6Eh+L1 2 Tile Length (L2) (MUST be nonzero) (zero would be 64Kbytes) ;\ BUG: Below Data may not start at WRAM addr 7Exx00h/7Exx01h ; (if so, data is accidently read from address-100h) ; 70h+L1 L2 Tile Data (DMAed to VRAM Word Addr 4900h) (byte addr 9200h) ;/ 70h+L1+L2 2 Length (L3) (should be even, data is copied in 16bit units) ;\ 72h+L1+L2 L3 Cell to Tile Xlat (copied to 7E4080h, BUG:copies L3+2 bytes);/ 72h+L1..L3 2 Length (L4) (MUST be even, MUST be nonzero, max 30h) ;\ 74h+L1..L3 L4 Cell Solid/Priority List (copied to 7E45D0h,copies L4 bytes);/ 74h+L1..L4 2 Unknown/unused, probably Length (L5) ;\ 76h+L1..L4 L5 Door Location(s) (byte-pairs: xloc,yloc, terminated FFh,FFh);/ Door Locations work only if BG1 cells also have bit15 set! Bit15 must be set IN FRONT of the door, this is effectively reducing the building size from 4x7 to 4x6 cells. Note: Animated BG cells are FORCEFULLY having bit15 cleared! This chunk may be followed by Chunk 02h. If so, it processes Chunk 02h (and ends thereafter). Otherwise it ends immediately (ie. when the following Chunk has ID=00h) (or also on any "garbage" ID other than 02h). Chunk 02h (Custom Persons) 00h 1 Chunk ID (02h) 01h 2 Chunk Length (N) (LITTLE-ENDIAN) (N may be even,odd,zero) 03h N Data (copied to 7F0000h) (N bytes) (max 0A00h bytes or so) 00h 4 7F0000h Person 2Ch - Token Interpreter Entrypoint 04h 4 7F0004h Person 2Dh - Token Interpreter Entrypoint 08h .. 7F0008h General Purpose (Further Tokens and Data) Copies the Data, and ends (any further following chunks are ignored). If Person 2Ch/2Dh are enabled in the Town Status packet, then the person thread(s) are created with above entrypoint(s). The threads may then install whatever OBJs (for examples, see the table at 99DAECh, which contains initial X/Y-coordinates and Entrypoints for Person 00h..3Fh). Chunk 03h..FFh (Ignored/Reserved for future) 00h 1 Chunk ID (03h..FFh) 01h 2 Chunk Length (N) (LITTLE-ENDIAN) 03h N Data (ignored/skipped) Skips the data, and then goes on processing the following chunk. BG Animation Data (within Chunk 01h) (for Custom Building) 00h 2 Base.xloc (0..47) (FFFFh=No Animation Data) 02h 2 Base.yloc (0..47) 04h X*4 Group(s) of 2 words (offset_to_frame_data,duration_in_60hz_units) 04h+X*4 2 End (FFFEh=Loop/Repeat animation, FFFFh=Bugged/One-shot animat.) 06h+X*4 .. BG Animation Frame Data Block(s) (see below) .. 0-2 Padding (to avoid 100h-byte boundary BUG in L2) Xloc/Yloc should be usually X=0006h,Y=000Dh (the location of the Custom Building, at 7E4C8Ch) (although one can mis-use other xloc/yloc values to animate completely different map locations; this works only if the Custom Building's folder contains files/items). BUG: The one-shot animation is applied ONLY to map cells that are INITIALLY visible (ie. according to BG scroll offsets at time when entering the town). BG Animation Frame Data Block(s) 00h Y*8 Group(s) of 4 words (xloc, yloc, bg1_cell, bg2_cell) 00h+Y*8 2 End of Frame List (8000h) (ie. xloc=8000h=end) NOTE: offset_to_frame_data is based at [94] (whereas, [94] points to the location after Chunk 01h ID/Length, ie. to the base address of Chunk 01h plus 3). If the animation goes forwards/backwards, one may use the same offsets for both passes. The Custom Bulding has 4x7 cells in non-animated form (so, usually one should use xloc=0..3, yloc=0..6). Cells can be FFFFh=Don't change (usually one would change only BG1 foreground cells, and set BG2 background cells to FFFFh). For animated BG1 cells, Bit10-15 are stripped for some stupid reason (in result, animated BG1 cells cannot be flagged as Doors via Bit15). BG Cell to Tile Translation Each 16x16 pixel Cell consists of four 8x8 Tiles. The Translation table contains tiles arranged as Upper-Left, Lower-Left, Upper-Right, Lower-Right. The 16bit table entries are 10bit BG tile numbers, plus BG attributes (eg. xflip). Building/Map Notes The PPU runs in BG Mode 1 (BG1/BG2=16-color, BG3=4-color). VRAM used as so: BG1 64x32 map at VRAM:0000h-07FFh, 8x8 tiles at VRAM:1000h-4FFFh (foreground) BG2 64x32 map at VRAM:0800h-0FFFh, 8x8 tiles at VRAM:1000h-4FFFh (background) BG3 32x32 map at VRAM:5000h-53FFh, 8x8 tiles at VRAM:5000h-6FFFh (menu text) OBJ 8x8 and 16x16 tiles at VRAM:6000h-7FFFh (without gap) (people) Custom BG1/BG2 Tiles are at VRAM:4900h-xxxxh (BG.Tile No 390h-xxxh) Custom OBJ Tiles at VRAM:7C00h-xxxxh (OBJ.Tile No 1C0h..xxxh) The PPU BG Palettes are: BG.PAL0 Four 4-Color Palettes (for Y-Button BG3 Menu) BG.PAL1 Four 4-Color Palettes (for Y-Button BG3 Menu) BG.PAL2 Buildings BG.PAL3 Buildings BG.PAL4 Buildings BG.PAL5 Custom Palette BG.PAL6 Landscape (Trees, Phone Booth) (colors changing per season) BG.PAL7 Landscape (Lawn, Streets, Water, Sky) (colors changing per season) The town map is 48x48 cells of 16x16 pix each (whole map=768x768pix). Custom BG1/BG2 Cells are at WRAM:7E4080h-7E41FFh (Cell No 3D0h-3FFh) Custom Cell Solid/Priority... SNES Cart Satellaview Other Packets ----------------------------------- SNES Patch Packet (by 105BBC) (Software Channel 1.1.0.7) Loaded to 7FC000h, data portions then copied to specified addresses. Size (max) 16Kbytes. 00h 1 Number of entries (01h..FFh) (MUST be min 01h) 01h .. Entries (max 3FFFh bytes) Each entry is: 00h 1 Flags (bit0=1=Invalid) (bit1-7=unknown/unused) 01h 1 Unknown/unused 02h 2 Length (N) (16bit, big-endian) (MUST be min 0001h) 04h 3 SNES-specific Memory Address (24bit, big-endian) 07h N Data (N bytes) The data portions are copied directly to the specified SNES addresses (the BIOS doesn't add any base-offset to the addresses; ie. if the data is to be copied to WRAM, then the satellite would transmit 7E0000h..7FFFFFh as address; there is no address checking, ie. the packet can overwrite stack or I/O ports). Welcome Message Packet (Software Channel 1.1.0.4) Loaded to 7EA1B9. Size max 64h bytes (100 decimal). Displayed in text window with 37x4 ASCII cells. 00h 100 Custom Message (max 99 characters, plus ending 00h) If this packet is included in the Channel Map (and if it's successfully received), then the Custom Message is displayed right before entering the town. The japanese Default Message is still displayed, too (so one gets two messages - which is causing some annoying additional slowdown). Time Channel Packet (Software channel 1.1.0.8) (BS Fire Emblem) Time Channel Packet (Software channel 1.1.0.8) (BS Satella2 1) Time Channel Packet (Software channel 1.1.0.8) (BS Parlor Parlor 2) Time Channel Packet (Software channel 1.1.0.8) (BS Shin Onigashima 1) Time Channel Packet (Software channel 1.1.0.8) (BS Tantei Club) Time Channel Packet (Software channel 1.1.0.8) (BS Kodomo Tyosadan..) Time Channel Packet (Software channel 1.1.0.8) (BS Super Mario USA 3) Time Channel Packet (Software channel 1.1.0.8) (BS Super Mario Collection 3) Time Channel Packet (Software channel 1.1.0.8) (BS Excitebike - Mario .. 4) Time Channel Packet (Software channel 1.1.0.8) (Itoi Shigesato no Bass Tsuri) Time Channel Packet (Software channel 1.2.0.48) (BS Dragon Quest 1) Time Channel Packet (Software channel 1.2.0.48) (BS Zelda .. Remix) Time Channel Packet (HW channel [7FFFF7h]) (BS Zelda - Kodai .. Dai 3 ..) Time Channel Packet (HW channel [7FFFF7h]) (BS Marvelous Camp Arnold 1) Time Channel Packet (HW channel [7FFFF7h]) (BS Marvelous Time Athletic 4) Preceeded by a 10-byte packet header. Of which, first 5 bytes are ignored (Body is 8-bytes, so packet size should be probably 5+8). Fixed 01h must be 01h. Number of Fragments must be 01h. Target Offset must be 000000h. The 8-byte Data Body is then: 00h 1 Unknown/unused (probably NOT seconds) ;(un-)used by Itoi only 01h 1 Minutes (0..3Bh for 0..59) 02h 1 Hours (0..17h for 0..23) (or maybe 24..26 after midnight) 03h 1 Day of Week (01h..07h) (rather not 00h..06h) (?=Monday) 04h 1 Day (01h..1Fh for 1..31) 05h 1 Month (01h..0Ch for 1..12) 06h 1 Unknown/unused (maybe year) ;\could be 2x8bit (00:00 to 99:99) 07h 1 Unknown/unused (maybe century) ;/or maybe 16bit (0..65535) or so Caution: The BS satellite program specified hours from 11..26 (ie. it didn't wrap from 23 to 0), the Time Channel(s) might have been following that notation; if so, then Date values might have also been stuck on the previous day. Unknown if the Time Channels have been online 24 hours a day, or if their broadcast ended at some time late-night. Time Channel are often used by Soundlink games, in so far, it's also quite possible that the "hours:minutes" are referring to the time within the broadcast (eg. from 0:00 to 0:59 for a 1-hour broadcast duration), rather than to a real-time-clock-style time-of-the-day. Differences between 1.1.0.8 and 1.2.0.48 are unknown. Some games require incoming Hardware channel number at [7FFFF7h] (from a separate loader or so). One would expect TIME[0] to contain seconds - however, there aren't any games using that entry as seconds (instead, they wait for minutes to change, and reset seconds to zero; due to that wait-for-next-minute mechanism, many BSX games seem to "hang" for up to 60 seconds after booting them). TIME[4..7] aren't really used as "date" by any games (a few games seem to be using TIME[4] or TIME[5] to determine how often the user has joined the game). Itoi uses (and displays) TIME[4..5] as date. Some games are treating TIME[6..7] as a 16bit little-endian value, others are using only either TIME[6] or TIME[7] (ie. half of the games that use the "year" values are apparently bugged). File Packet (Software Channel N.N.N.N as taken from Directory) 00h N Data, N bytes (N=Filesize as specified in Directory) The file must contain a Satellaview Transmit Header (at file offset 7Fxxh or FFxxh), that header is similar to the FLASH File Header. For details & differences, see: --> SNES Cart Satellaview FLASH File Header The filesize should be usually a multiple of 128Kbytes (because the checksum in File Header is computed accross that size). Transmitting smaller files is possible with some trickery: For FLASH download, assume FLASH to be erased (ie. expand checksum to FFh-filled 128Kbyte boundary). For PSRAM download, the checksum isn't verified (so no problem there). Moreover, filesize should be usually at least 32Kbytes (for LoROM header at 7Fxxh), however, one could manipulate the fragment-offset in packet header (eg. allowing a 4Kbyte file to be loaded to offset 7000h..7FFFh). Special Channel(s) used by Itoi Shigesato no Bass Tsuri No. 1 (1.2.130.N) Itoi supports four special channel numbers to unlock special contests. The game doesn't try to receive any data on that channels (it only checks if one of them is listed in the Channel Map). 1.2.130.0 ;\Special Contests 1..4 (or so) 1.2.130.16 ; The 4 contests are looking more or less the same, possibly 1.2.130.32 ; with different parameters, different japanese descriptions, 1.2.130.48 ;/contest 2-3 have "No fishing" regions in some lake-areas. 1.2.130.other ;-Invalid (don't use; shows error with TV-style "test screen") For Itoi, the Channel Map may be max 1019 bytes (or even LESS?!) (unlike usually, where it could be 1485 bytes). There should be only one channel with value 1.2.130.N in the Channel Map. The game additionally requires the 1.1.0.8 Time Channel. And, uses the "APU" byte in the Town Status packet. 1.2.129.0 Special Channel used by Derby Stallion 96 (Dish on Building/Roof) 1.2.129.16 Special Channel used by Derby Stallion 96 (6th Main Menu Option) Differences between the two channels are unknown; both are processed by the same callback function (and thus seem to have the same data-format). The packet(s) are both loaded to 7F0000h, size could be max 8000h (although, actual size might be 7E00h, as indicated by the checksum calculation). The overall format is: 0000h 3 Unknown/unused (3 bytes) 0003h 8 ID "SHVCZDBJ" (compared against [B289D6]) 000Bh 2 Number of Chunks at 0010h and up (16bit) (little-endian) (min 1) 000Dh 1 Unknown/unused? (8bit) 000Eh 1 Checksum (bytes at [0000h..7DFFh] added together) (8bit) 000Fh 1 Checksum complement (8bit) 0010h DF0h Chunks 7E00h 200h Begin of non-checksummed area (IF ANY) (if it DOES exist, then it MIGHT contain a file-style header at 7FB0h..7FFFh ?) Note: The Chunks are processed via function at B28A10h. Despite of the hardcoded channel numbers, the packets must be also listed (with the same channel numbers) in the Directory Packet (as hidden Include File entries or so). Hardware Channel 0121h - Test Channel Used for hardware-connection test (received data is ignored). Used by BIOS function 105B6Ch; which is used only when pressing X+L+R buttons while the Welcome Message is displayed. Transmission Timeout for the Test Channel is 10 seconds. SNES Cart Satellaview Buildings ------------------------------- Home Building (Starting Point) This building can be entered at any time, the four japanese options are: 1) Load File from FLASH Card 2) Delete File from FLASH Card 3) Download File (only files that are "Available at Home") (max 32 files) 4) Delete Settings in SRAM Buildings The buildings are numbered roughly anti-clockwise from 00h..1Fh, starting at lower-left of the town map: 00h Robot Skyscraper (lower-left) 01h News Center 02h Parabol Antenna 03h Junkfood 04h Police 05h Maths +-x/ 06h Beach Shop (Shop for Predefined ROM Items) 07h Turtle-Arena 08h C-Skyscaper (Shop for Predefined ROM Items) 09h Red-Heart Church 0Ah Red \\\ Factory (upper-right corner) 0Bh Dracula Gift-Shop 0Ch Cow-Skull Church 0Dh Spintop/Abacus (near Maths +-X/) 0Eh Blank Skyscraper (near Parabol Antenna) 0Fh Sign (near Red Factory) (works only ONCE) (or custom building) 10h Greek Buddah Temple (upper-end) 11h Bigger Neighbor's Building 12h Smaller Neighbor's Building (unknown how to get in there) 13h Phone Booth (can be entered only with Telephone Card item) 14h Sewerage (near Spintop) (Shop for Predefined ROM Items) 15h Unused 16h Unused ;\these Building-Folders MUST not exist (else BIOS randomly 17h Unused ;/crashes, accidently trying to animate Building number "44h/3") 18h Special Location without folder: Player's Home 19h Special Location without folder: Hydrant (near police) 1Ah Special Location without folder: Talking Tree (near C-Skyscraper) 1Bh Special Location without folder: Fountain (or Fountain Replacement) 1Ch Special Location without folder: Beach Toilets (Railway Station) 1Dh Special Location without folder: Ocean's Shore 1Eh Special Location without folder: Unused 1Fh Special Location without folder: Unused 20h-3Fh Building-Folders with these IDs do destroy memory (don't use!) Buildings can be entered only if there is a corresponding folder (in the directory), and only if the folder contains at least one file or item (for the three pre-defined Shops it works also if the folder is empty). SNES Cart Satellaview People ---------------------------- People People are showing up only if they are flagged in the 64bit People Present Flags in the Town Status packet. If more than 5 people are flagged, then only the first 5 are shown (regardless of that limit, the 4 frogs and the ship can additionally be there). 00h Red Ball (on beach) (disappears after access) 01h Spring-boot (aka Dr.Hiroshi's Shop) (near news center) (sells items) 02h General Pee (showing up here and there pissing against buildings) 03h Brown Barbarian on Cocaine (near temple) 04h Blue Depressive Barbarian (near temple) 05h Ghost Waver (near phone booth) 06h Boy in Neighborhood 07h Older Elvis (near churches) 08h Purple Helmet (on beach) 09h Surfer (near beach shop) 0Ah Grayhaired (northwest lawn) 0Bh Alien Man (near phone booth) 0Ch Uncle Bicycle (near parabol antenna) 0Dh Circus Man (near temple/lake) 0Eh Speedy Blind Man (near parabol antenna/spintop) 0Fh Blonde Boy (near factory) 10h Girl with Pink Dress (near Bigger Neighbor's Home) 11h Brunetty Guy (near Bigger Neighbor's Home) 12h Brunette (near junkfood) 13h Darkhaired (near junkfood) 14h Blue Longhair (near junkfood) 15h Brunette Longhair (near junkfood) 16h Brunette Longhair (near red-heart church) 17h Green Longhair (near red-heart church) 18h Bicycle Girl (near C-Skyscraper) 19h Brunette Office Woman (near C-Skyscraper) 1Ah Blue Longhair (near parabol antenna) 1Bh Turquoise Longhair (near home) 1Ch Blue Longhair (near maths/spintop) 1Dh Brunette Longhair (near news center/beach stairs) 1Eh Black Longhair (near police) 1Fh Red Longhair (southeast beach) 20h Blackhaired Girl (near police) 21h Greenhaired Girl (on bench between temple and lake) 22h Graybluehaired older Woman (east of C-skyscraper) 23h Darkhaired Housewife (near home) 24h Traditional Woman (west of Robot-Skyscraper) 25h Greenhaired Girl (near Turtle-Arena) 26h Pinkhaired Girl (near Cow-Skull Church) 27h Brown Dog (northeast lawn) 28h White Dog (near home) 29h Gray Duck (near temple/lake) 2Ah Portable TV-Headed Guy (near Robot-Skyscraper) 2Bh Satellite Wide-screen TV-Headed Guy (near Robot-Skyscraper) 2Ch Custom Person 2Ch ;\may be enabled only if defined in Expansion Area 2Dh Custom Person 2Dh ;/of Directory Packet (otherwise crashes) Below 2Eh-37h are specials which cannot have a Folder assigned to them: 2Eh Dead Dentist (on bench near lake) (gives Money when owning Fishing Pole) 2Fh Gimmick: Allows to use Bus/Taxi/Ferrari Tickets at Fountain 30h Gimmick: Allows to use Express/Museum-Train-Tickets at Railways Station 31h Gimmick: Special Event when accessing the Hydrant 32h Frog 32h (west of Robot-Skyscraper) ;Change Identity Item 33h Frog 33h (west of Robot-Skyscraper, too) ;Change GUI Border Scheme (or on street near turtle arena?) 34h Frog 34h (northwest lawn) ;Change GUI Color Scheme 35h Frog 35h (near Cow-Skull Church) ;Change GUI Cursor Shape 36h Gimmick: Allows to use Whale/Dolphin/Fish Food at Oceans Shore 37h Ship (cannot be accessed?) (near factory) 38h Mr.Money (near police) (donates a 500G coin) ;\only one can be present 39h Mr.Money (near police) (donates a 1000G coin) ; at once, after the coin, 3Ah Mr.Money (near police) (donates a 5000G coin) ;/all do act as Folder 38h 3Bh-3Fh Unused? Like Buildings, People can have a Folder associated to them (using above values as Folder ID, at least, that works for People 00h..2Bh). If there is no corresponding folder transmitted, then People aren't doing anything useful (aside from producing whatever japanese sentences). One exception: If there's no People-File-Folder with ID=01h, then the Spring-boot guy acts as "Dr Hiroshi's Shop" where one can buy question-marked items for 3000G. The Frogs can be picked up (adding an Item to the inventory). Frog positions seem to be random (west of Robot-Skyscraper, street near Turtle Arena, northwest lawn, or near Cow-Skull Church). Avatars These are assigned for folders (either for people in buildings, or people on the streets). 00h Geisha (faecher) 01h Snorty (nose bubble) 02h Gold hat 03h Naked guy 04h Soldier (lanze) 05h Whore (lipstick/eye blinking) 06h Wise man1 (huge white eyebrows) 07h Wise man2 (huge stirn, huge ears) 08h DJ Proppy (headphones, sunglasses, muscles) 09h Casino manager (fat guy with red slip-knot) 0Ah Student girl (manga, karierte bluse) 0Bh School girl (satchel ranzen/smiley) 0Ch Kinky gay (green hair, sunglasses, gold-ohrring) 0Dh Yankee (glistening teeth/dauerwelle) 0Eh Robot (blech-mann) 0Fh Blonde chick (blonde, lipstick) 10h BS-X logo (not a person, just the "BS-X" letters) 11h-FFh Unknown/Unused/Crashes 30h None (seems to be an un-intended effect, probably unstable, don't use) SNES Cart Satellaview Items --------------------------- Predefined Items (and their 24bit memory pointers) Items sold in C-Skyscraper: 00 88C229h Transfer Device (allows to teleport to any building) (unlimited) 01 88C2B8h Telephone Card (5) (allows to enter phone booth) ;\ 02 88C347h Telephone Card (4) (allows to enter phone booth) ; decreases 03 88C3D6h Telephone Card (3) (allows to enter phone booth) ; after usage 04 88C465h Telephone Card (2) (allows to enter phone booth) ; 05 88C4F4h Telephone Card (1) (allows to enter phone booth) ;/ 06 88C583h Fishing Pole (allows to get Money from Dead Dentist, Person 2Eh) 07 88C612h Express Train Ticket ;\these are treated special 08 88C6A1h Museum Train Ticket ;/by code at 88936Ch 09 88C630h Bus Ticket (at Fountain) ;\these all have same description 0A 88C7BFh Taxi Ticket ; 0B 88C84Eh Ferrari Blowjob Ticket ;/ Items sold by Dr.Hiroshi (spring-boot guy near News Center) 0C 88C8DDh Doping Item (walk/run faster when pushing B Button) 0D 88C96Ch Unknown (disappears after usage) Items sold in Beach Shop: 0E 88C9FBh Whale Food (can be used at Oceans Shore) 0F 88CA8Ah Dolphin Food (can be used at Oceans Shore) 10 88CB19h Fish Food (can be used at Oceans Shore) Items sold in Sewerage: 11 88CBA8h Boy/Girl Gender Changer (can be used only once) 12 88CC37h Transform Boy/Girl into Purple Helmet guy (Person 08h)(temporarily) 13 88CCC6h Transform Boy/Girl into Brunette chick (Person 1Dh)(temporarily) 14 88CD55h Smaller Neighbor's Home Door Key (allows to enter that building) Items obtained when picking-up Frogs: 15 88CDE4h Change Identity (edit user name) (from Frog 32h) (works only once) 16 88CE73h Change GUI Border Scheme (from Frog 33h) (works only once) 17 88CF02h Change GUI Color Scheme (from Frog 34h) (works only once) 18 88CF91h Change GUI Cursor Shape (from Frog 35h) (works only once) Item Format As shown above, 25 items are defined in ROM at 99C229h-88D020h with 8Fh bytes per item. Custom Items (defined in Directory packet's "File" entries) can be stored at 10506Ah. The item format is: 00h 15h Item Name (max 20 chars, plus ending 00h) (First 2 bytes 00h = Free) 15h 1 Length of following (Description, Pointer, Whatever) (always 79h?) 16h 25h Item Description (max 36 chars, plus ending 00h) 3Bh 47h Item Activation Message (max 70 chars, plus ending 00h) If Activation Message = empty (single 00h byte), then Item Function follows: 3Ch 3 Pointer to Interpreter Tokens (eg. 99974Dh for Transfer Device) 3Fh 43h Unknown/Unused/Padding (should be zero) (there is no SRAM allocated for custom item functions, so this part may be used only for predefined ROM items) 82h 12 Item Price (12-Digit ASCII String, eg. "000000001200" for 1200G) 8Eh 1 Item Drop/Keep Flag (00h=Drop after Activation, 01h=Keep Item) In case of Custom Items, above ITEM[00h..8Eh] is copied from FILE[02h..90h] (ie. a fragment of "File" Entries in the Directory Packet). Entry [15h] seems to be always 79h, giving a total length of 8Fh per item. The Item Message is used for items that cannot be activated (eg. "You can't use telephone card outside of the phone booth.",00h). If the message is empty (00h), then the next 24bit are a pointer to the item handler (eg. the Teleport function for the Transfer Device). Note: Items can be listed, activated, and dropped via Y-Button. The teleport device can be also activated via X-button. Shops There are four pre-defined shops: Dr.Hiroshi's appears when Person 01h exists, WITHOUT folder assigned, or WITH an item-folder. The Beach Shop, C-Skyscraper and Sewerage Shops appear if they HAVE an folder assigned, the folder must be flagged as Item/Shop. In all cases, the folder may contain additional items which are added to the Shop's predefined item list. Custom Shops can be created by assigning Item-Folders to other People/Buildings (in that case, the Folder MUST contain at least one item, otherwise the BIOS shows garbage). Shops may contain max 0Ah items (due to 7E865Eh array size). SNES Cart Satellaview SRAM (Battery-backed) ------------------------------------------- The Satellaview BIOS cartridge contains 32Kbyte battery-backed SRAM, mapped to eight 4Kbyte chunks at 5000h..5FFFh in Bank 10h..17h. SRAM Map 0000h 2 ID "SG" (aka 53h,47h) 0002h 2 Checksum Complement (same as below checksum XORed with FFFFh) 0004h 2 Checksum (bytes 0..2FFFh added together) (assume [2..5]=0,0,FF,FF) 0006h 20 User's Name (Shift-JIS) 001Ch 2 User's Gender (0000h=Boy, 0001h=Girl) 001Eh 6 Money (max 00E8D4A50FFFh; aka 999,999,999,999 decimal) 0024h 2 Number of Items (0..10h) (or temporarily up to 11h) 0026h 44h Item Entries (4-bytes each: Type=00/01=ROM/RAM, and 24bit pointer) 006Ah 8F0h Custom RAM Items (8Fh bytes each) (First 2 bytes 00h = free entry) 095Ah 2 Remaining Time on Doping Item (decreases when entering buildings) 095Ch 2 Number of Doping Items (walk/run faster when pushing B Button) 095Eh 2 Remaining Calls on first Telephone Card Item minus 1 0960h 2 Number of Telephone Card Items (unlocks Phone Booth) 0962h 2 Number of Transfer Devices (enables Teleport via menu or X-Button) 0964h 2 Number of Fishing Poles (allows to get Money from Dead Dentist) 0966h 2 Number of Smaller Neighbor's Home Keys (0000h=Lock, other=Unlock) 0968h 2 GUI Cursor Shape 16bit selector (0000h..0005h) (other=crash) 096Ah 3 GUI Border Scheme 24bit pointer (def=9498D9h) (MUST be 94xxxxh) 096Dh 3 GUI Color Scheme 24bit pointer (initially 94A431h) 0970h 1 Player got 500 coin from Person 38h ;\(00h=No, 01h=Yes, 0971h 1 Player got 1000 coin from Person 39h ; flags stay set until 0972h 1 Player got 5000 coin from Person 3Ah ; that Person leaves 0973h 1 Player picked-up Red Ball aka Person 00h ;/the town) 0974h 18h BIOS Boot/NMI/IRQ Hook Vectors (retf's) (mapped to 105974h and up) 098Ch 2B0h BIOS Function Hook Vectors (jmp far's) (mapped to 10598Ch and up) 0C3Ch 64h BIOS Reset Function (and some zero-filled bytes) 0CA0h 100h BIOS Interpreter Token Handlers (16bit addresses in bank 81h) 0DA0h 100h Garbage Filled (reserved for unused Tokens number 80h..FFh) 0EA0h 2 Garbage Filled (for impossible 8bit token number 100h) 0EA2h 215Eh Reserved (but, mis-used for game positions by some games) 3000h 3000h Backup Copy of 0..2FFFh 6000h 2000h General Purpose (used for game positions by various games) Game Positions in SRAM 0000h-0EA1h BX-X BIOS (see above) 1400h-14FFh BS Super Mario USA 3 (256 bytes) 1500h-15FFh BS Super Mario Collection 3 (256 bytes) 1500h-15FFh BS Kodomo Tyosadan Mighty Pockets 3 (256 bytes) 1600h-1626h BS Satella Walker 2 (27h bytes) 1600h-1626h BS Satella2 1 (27h bytes) 1700h-17FFh BS Excitebike Bun Bun Mario Battle Stadium 4 (256 bytes) 2000h-27FFh BS Marvelous Camp Arnold Course 1 (2Kbytes) 2800h-2F89h BS Dragon Quest 1 (1.9Kbytes) (probably 1K, plus 1K backup copy) 2006h-2FF5h BS Zelda no Densetsu Remix (3.9Kbytes) 2000h-2EFFh BS Zelda no Densetsu Kodai no Sekiban Dai 3 Hanashi (3.75K) 2000h-2FFFh BS Super Famicom Wars (V1.2) (first 4K of 8Kbytes) 3000h-5FFFh Backup Copy of 0..2FFFh (not useable for other purposes) 6000h-63FFh BS Treasure Conflix (1Kbyte) 6020h-62F9h BS Sutte Hakkun 98 Winter Event Version (0.7Kbytes) 6000h-7FFFh BS Chrono Trigger - Jet Bike Special (8Kbytes) 6800h-6FFFh BS Super Famicom Wars (V1.2) (middle 2K of 8Kbytes) 7500h-7529h BS Cu-On-Pa (2Ah bytes) 7800h-7FFFh BS Super Famicom Wars (V1.2) (last 2K of 8Kbytes) 7826h-7827h BS Dr. Mario (only 2 bytes used?) (7C00h-7FFFh) BS Radical Dreamers (default, if free, at 7C00h) (1Kbyte) There is no filesystem with filenames nor SRAM allocation. Most games are using hardcoded SRAM addresses, and do overwrite any other data that uses the same addresses. One exception is BS Radical Dreamers: The game searches for a free (zerofilled) 1K block (defaults to using 7C00h-7FFFh), if there isn't any free block, then it prompts the user to select a 1K memory block (at 6000h-7FFFh) to be overwritten. Some games are saving data in PSRAM (eg. Zelda no Densetsu: Kamigami no Triforce, in bank 70h) rather than SRAM - that kind of saving survives Reset, but gets lost on power-off. There aren't any known BS games that save data in FLASH memory. Some BS games are using passwords instead of saving. BIOS Hooks These are 4-byte fields, usually containing a "JMP 80xxxxh" opcode (or a "RETF" opcode in a few cases), changing them to "JMP 1x5xxxh" allows to replace the normal BIOS functions by updated functions that are installed in SRAM. Unknown if any such BIOS updates do exist, and at which SRAM locations they are intended/allowed to be stored. SRAM Speed The Satellaview SRAM is mapped to a FAST memory area with 3.58MHz access time (unlike ALL other SNES RAM chips like internal WRAM or external SRAM in other cartridges). The bad news is that this wonderful FAST memory isn't usable: It's located in Bank 10h-17h, so it isn't usable as CPU Stack or CPU Direct Page (both S and D registers can access Bank 00h only). And, the first 24Kbytes are used as reserved (and checksummed) area. SNES Cart Satellaview FLASH File Header --------------------------------------- Satellaview FLASH File Header Located at offset 7Fxxh or FFxxh in file, mapped to FFxxh in bank 00h. FFB0h 2 Maker Code (2-letter ASCII) ;\garbage when FFB2h 4 Program Type (00000100h=Tokens, Other=65C816) ; [FFDBh]=01h FFB6h 10 Reserved (zero) ;/ FFC0h 16 Title (7bit ASCII, 8bit JIS (?), and 2x8bit SHIFT-JIS supported) FFD0h 4 Block Allocation Flags (for 32 blocks of 128Kbytes each) (1=used) Retail (demo) games usually have ffff here -- Uh ??? (exception BS Camp Arnold Marvelous) -- Uh ??? FFD4h 2 Limited Starts (bit15=0=Infinite, otherwise bit14-0=Remaining Flags) FFD6h 1 Date (Bit7-4=Month, Bit3-0=0) ;\copied to from FFD7h 1 Date (Bit7-3=Day, Bit2=0, Bit1-0=Unknown) ;/Directory Packet FFD8h 1 Map Mode (20h=LoROM, 21h=HiROM) (or sometimes 30h/31h) FFD9h 1 File/Execution Type Bit0-3 Unknown/unused (usually/always 0) Bit4 Receiver Power Down (0=No/Sound Link, 1=Power-Down 2197h) Bit5-6 Execution Area (0=FLASH, 1=Reloc FLASH-to-PSRAM, 2/3=Fail) Bit7 Skip the "J033-BS-TDM1 St.GIGA" Intro (0=Normal, 1=Skip) FFDAh 1 Fixed (33h) FFDBh 1 Unknown (usually 02h, sometimes 01h, or rarely 00h) (see FFBxh) FFDCh 2 Checksum complement (same as below, XORed with FFFFh) FFDEh 2 Checksum (all bytes added together; assume [FFB0-DF]=00h-filled) FFE0h 32 Exception Vectors (IRQ,NMI,Entrypoint,etc.) (for 65C816 code) Entrypoint is at 800000h+[FFFCh] for 65C816 Machine Code, or at 400000h for Interpreter Tokens (ie. when [FFB2h]=00000100h, as used by few magazines like BS Goods Press 6 Gatsu Gou). Caution: Machine Code programs are started WITHOUT even the most basic initialization (one of the more bizarre pieces: the download "screensaver" may leave HDMAs enabled when auto-starting a downloaded file). Satellaview PSRAM File Header (download to PSRAM without saving in FLASH) Basically same as FLASH headers. FFD9h.Bit7 (skip intro) seems to be ignored (accidently using FFD9h from FLASH cartridge instead from PSRAM?). The checksum isn't verified (FFDEh must match with FFDCh, but doesn't need to match the actual file content). Satellaview Transmit Header (located at 7Fxxh or FFxxh in File) Basically same as normal Satellaview FLASH File Header. However, after downloading a file (and AFTER storing it in FLASH memory), the BIOS does overwrite some Header entries: FFD0h 4-byte Block Allocation field (set to whichever used FLASH Blocks) FFD6h 2-byte Date field (set to Date from Satellite Directory Entry) FFDAh 1-byte Fixed Value (set to 33h) Since FLASH cannot change bits from 0 to 1 (without erasing), the above values must be FFh-filled in the transmitted file (of course, for the fixed value, 33h or FFh would work) (and of course, the FFh-requirement applies only to FLASH downloads, not PSRAM downloads). Notes The title can be 16 bytes (padded with 20h when shorter), either in 7bit ASCII, 8bit JIS (or so?), or 2x8bit SHIFT-JIS, or a mixup thereof. A few files are somewhat corrupted: Title longer than 16 bytes (and thereby overlapping the Block Allocation flags). Limited Starts consists of 15 flags (bit14-0), if the limit is enabled (bit15), then one flag is changed from 1-to-0 each time when starting the file (the 1-to-0 change can be done without erasing the FLASH sector). Note that the checksum excludes bytes at FFB0h-FFDFh, this is different as in normal cartridges (and makes it relative easy to detect if a file contains a SNES ROM-image or a Satellaview FLASH-file/image. Files are treated as "deleted" if their Fixed Value isn't 33h, if Limited Starts is 8000h (limit enabled, and all other bits cleared), or if Checksum Complement entry isn't equal to Checksum entry XOR FFFFh. Some FLASH dumps in the internet do have experired Limited Starts entries (so they can be used only when changing [FFD4h] to a value other than 8000h). The FLASH card PCBs can be fitted with 1/2/4 MByte chips (8/16/32 Mbit). As far as known, all existing FLASH cards contain 1MByte chips (so Block Allocation bit8-31 should be usually always 0). Most files are occupying the whole 1MByte (so bit0-7 should be usually all set). There are also some 256Kbyte and 512Kbyte files (where only 2 or 4 bits would be set). Minimum file size would be 128Kbyte. Odd sizes like 768Kbytes would be also possible. Unlike the Satellite Packet Headers, the FLASH/Transmit-File header contains "normal" little-endian numbers. SNES Cart Satellaview BIOS Function Summary ------------------------------------------- BIOS functions must be called with BIOS ROM enabled in Bank 80h-9Fh (in some cases it may be required also in Bank 00h-1Fh), and with DB=80h. Incoming/outgoing Parameters are passed in whatever CPU registers and/or whatever WRAM locations. WRAM is somewhat reserved for the BIOS (if a FLASH file changes WRAM, then it should preserve a backup-copy in PSRAM, and restore WRAM before calling BIOS functions) (WRAM locations that MAY be destroyed are 7E00C0h..7E00FFh and 7E1500h..7E15FFh, and, to some level: 7F0000h..7FFFFFh, which is used only as temporary storage). Hooks (usually containing RETF opcodes) 105974 boot_hook (changed by nocash fast-boot patch) 105978 nmi_hook 10597C irq_vector 105980 download_start_hook --> see 9B8000 105984 file_start_hook --> see 958000 105988 whatever_hook --> see 99xxxx SRAM Vectors 10598C detect_receiver 105990 port_2194_clr_bit0 105994 port_2196_test_bit1 Copy Data Queue to RAM Buffer 105998 set_port_218B_and_218C_to_01h 10599C set_port_218C_to_00h 1059A0 read_data_queue Port 2199h (serial port 2) (maybe satellite audio related) 1059A4 init_port_2199_registers 1059A8 send_array_to_port_2199 ;BUGGED? 1059AC recv_3x8bit_from_port_2199 1059B0 send_16bit_to_port_2199 1059B4 recv_8bit_from_port_2199 Port 2198h (serial port 1) (unused/expansion or so) 1059B8 port_2198_send_cmd_recv_multiple_words 1059BC port_2198_send_cmd_recv_single_word 1059C0 port_2198_send_cmd_send_verify_multiple_words 1059C4 port_2198_send_cmd_send_verify_single_word 1059C8 port_2198_send_cmd_send_single_word 1059CC port_2198_send_10h_send_verify_single_word 1059D0 port_2198_send_cmd_verify_FFFFh 1059D4 port_2198_send_20h_verify_FFFFh 1059D8 recv_2198_skip_x BUGGED! 1059DC recv_2198_want_x 1059E0 send_30h_to_port_2198 1059E4 send_00h_to_port_2198 1059E8 send_8bit_to_port_2198 1059EC wait_port_2198_bit7 Forward Data Queue from RAM to Target 1059F0 forward_data_queue_to_target 1059F4 forward_queue_to_wram 1059F8 forward_queue_to_psram 1059FC forward_queue_to_entire_flash 105A00 forward_queue_to_entire_flash_type1 105A04 forward_queue_to_entire_flash_type2 105A08 forward_queue_to_entire_flash_type3 105A0C forward_queue_to_entire_flash_type4 105A10 forward_queue_to_flash_sectors 105A14 forward_queue_to_flash_sectors_type1 105A18 forward_queue_to_flash_sectors_type2 105A1C forward_queue_to_flash_sectors_type3 105A20 forward_queue_to_flash_sectors_type4 105A24 forward_queue_to_channel_map ;with 5-byte frame-header 105A28 forward_queue_to_town_status FLASH Files 105A2C scan_flash_directory 105A30 allocate_flash_blocks 105A34 .. prepare exec / map file or so 105A38 verify_file_checksum 105A3C get_flash_file_header_a 105A40 delete_flash_file_a 105A44 get_flash_file_header_5A 105A48 copy_file_header 105A4C search_test_file_header, out:[57] 105A50 test_gamecode_field 105A54 copy_file_to_psram 105A58 get_file_size 105A5C decrease_limited_starts Memory Mapping 105A60 map_flash_as_data_file (for non-executable data-files?) 105A64 map_psram_as_data_file (for non-executable data-files?) 105A68 .. mapping and copy 512Kbytes ? 105A6C map_flash_for_rw_access 105A70 map_flash_for_no_rw_access 105A74 map_flash_for_reloc_to_psram 105A78 .. mapping (unused?) 105A7C map_flash_as_lorom_or_hirom 105A80 execute_game_code 105A84 .. map_psram_for_streaming ??? 105A88 map_psram_as_lorom_or_hirom 105A8C .. copy 256Kbytes... FLASH Memory 105A90 flash_abort 105A94 flash_abort_type1 105A98 flash_abort_type2 105A9C flash_abort_type3 105AA0 flash_abort_type4 105AA4 flash_erase_entire 105AA8 flash_erase_entire_type1 105AAC flash_erase_entire_type2 105AB0 flash_erase_entire_type4 ;4! 105AB4 flash_erase_entire_type3 105AB8 flash_test_status ERASE-PROGRESS 105ABC flash_test_status_type1 105AC0 flash_test_status_type2 105AC4 flash_test_status_type4 ;4! 105AC8 flash_test_status_type3 105ACC flash_erase_first_sector 105AD0 flash_erase_first_sector_type1 105AD4 flash_erase_first_sector_type2 105AD8 flash_erase_first_sector_type3 105ADC flash_erase_first_sector_type4 105AE0 flash_erase_next_sector 105AE4 flash_erase_next_sector_type1 105AE8 flash_erase_next_sector_type2 105AEC flash_erase_next_sector_type3 105AF0 flash_erase_next_sector_type4 105AF4 flash_write_byte 105AF8 flash_write_byte_type1 105AFC flash_write_byte_type2 105B00 flash_write_byte_type3 105B04 flash_write_byte_type4 105B08 flash_get_free_memory_size 105B0C flash_get_and_interprete_id 105B10 flash_get_id 105B14 flash_init_chip 105B18 flash_init_chip_type1 105B1C flash_init_chip_type2 105B20 flash_init_chip_type3 105B24 flash_init_chip_type4 Satellite Directory 105B28 apply_satellite_directory 105B2C directory_find_8bit_folder_id 105B30 directory_find_32bit_file_channel 105B34 test_if_file_available 105B38 download_file_and_include_files 105B3C directory_find_32bit_bugged Misc... 105B40 .. initialize stuff on reset 105B44 download_nmi_handling (with download_callback etc.) 105B48 download_nmi_do_timeout_counting 105B4C nmi_do_led_blinking 105B50 mark_flash_busy 105B54 mark_flash_ready 105B58 set_port_2197_bit7 105B5C clr_port_2197_bit7 105B60 detect_receiver_and_port_2196_test_bit1 105B64 init_flash_chip_with_err_29h 105B68 init_flash_chip_with_err_2Ah 105B6C detect_receiver_and_do_downloads 105B70 do_download_function 105B74 retry_previous_download 105B78 set_target_id_and_search_channel_map 105B7C apply_target_for_download 105B80 clear_queue_and_set_13D1_13D2 105B84 flush_old_download ;[218C]=0, clear some bytes Invoke Download Main Functions 105B88 download_to_whatever (BUGGED) 105B8C download_channel_map 105B90 download_welcome_message 105B94 download_snes_patch 105B98 download_town_status 105B9C download_town_directory 105BA0 download_to_memory Download sub functions 105BA4 add_download_array 105BA8 wait_if_too_many_downloads 105BAC do_download_callback 105BB0 dload_channel_map_callback_1 105BB4 dload_channel_map_callback_2 105BB8 dload_welcome_message_callback 105BBC dload_snes_patch_callback 105BC0 dload_town_status_callback_1 105BC4 dload_town_status_callback_2 105BC8 dload_town_directory_callback_1 105BCC dload_town_directory_callback_2 105BD0 .. flash status 105BD4 dload_to_mem_wram_callback1 ;\ 105BD8 dload_to_mem_wram_callback2 ; 105BDC dload_to_mem_psram_callback1 ; 105BE0 dload_to_mem_psram_callback2 ; dload_to_memory_callbacks 105BE4 dload_to_mem_entire_flash_callback1 ; 105BE8 dload_to_mem_entire_flash_callback2 ; 105BEC dload_to_mem_free_flash_callback1 ; 105BF0 dload_to_mem_free_flash_callback2 ;/ 105BF4 dload_to_mem_entire_flash_callback_final 105BF8 dload_to_mem_free_flash_callback_final 105BFC reset_interpreter_and_run_thread_958000h 105C00 verify_channel_map_header 105C04 raise_error_count_check_retry_limit 105C08 search_channel_map 105C0C post_download_error_handling 105C10 .. erase satellite info ? APU Functions 105C14 apu_flush_and_clear_queues 105C18 apu_flush_raw 105C1C apu_message 105C20 apu_nmi_handling 105C24 apu_upload_extra_thread 105C28 apu_upload_curr_thread 105C2C apu_enable_effects_music_b 105C30 apu_enable_effects_music_a 105C34 apu_mute_effects_and_music 105C38 apu_enable_effects_only Reset 105C3C reboot_bios (this one works even when BIOS=disabled or WRAM=destroyed) Further Stuff 105C96 Unused 7 bytes (used for nocash fast-boot patch) 105C9D Unused 3 bytes (zero) 105CA0 Token Vectors (16bit offsets in bank 81h) BIOS Tables 105xxx Tables in SRAM (see above) 808000 Unsorted ptrs to BIOS Functions, Token-Extensions, and OBJ-Tile-Data 9FFFF0 Pointers to source data for APU uploads Additional BIOS Functions (without SRAM-Table vectors) These are some hardcoded BIOS addresses (used by some FLASH programs). 808C2A Invoke_dma_via_ax_ptr 8091B6 Create_machine_code_thread 809238 Pause_machine_code_thread 80938F Do nothing (retf) (used as dummy callback address) 80ABC8 ...whatever 80AC01 ...whatever 80B381 Upload_gui_border_shape_to_vram 80B51B Clear_text_window_content 80B91E Fill_400h_words_at_7E76000_by_0080h ;clear whole BG3 map in WRAM 80EB99 Injump_to_APU_Town_Status_handling (requires incoming pushed stuff) 81C210 Reset_interpreter 81C29A Set_interpreter_enable_flag 81C2B0 Create_interpreter_thread 81C80E Deallocate_all_obj_tiles_and_obj_palettes Note: Some of the above functions are also listed in the table at 808000h. Returning to BIOS If an executable file wants to return control to BIOS, it must first reset the APU (if it has uploaded code to it), and then it can do one the following: Perform a warmboot (the BIOS intro is skipped, but the Welcome message is re-displayed, and the player is moved back to the Home building): jmp 105C3Ch ;srv_reboot_bios (simple, but quite annoying) Or return to the BIOS NMI handler (from within which the executable was started) this is done by many games (player returns to the most recently entered building, this is more elegant from the user's view, though requires a messy hack from the programmer's view): call restore_wram ;-restore WRAM (as how it was owned by BIOS) jmp far (($+4) AND 00FFFFh) ;-PB=00h (so below can map BIOS to bank 80h) mov a,80h ;\ ;\ push a ;=80h ; ; set DB=80h, and pop db ;/ ; enable BIOS in bank 80h-9Fh mov [085000h],a ;map BIOS to bank 80h-9Fh ; (though not yet in 00h-1Fh) mov [0E5000h],a ;apply ;/ call far 99D732h ;super-slow ;out: M=0 ;-upload [9FFFF0h] to APU .assume p=10h ;(above set M=0, and keeps X=unchanged) call far 81C210h ;-Reset Token Interpreter call far 81C29Ah ;-Enable/Unpause Interpreter call far 80937Fh ;set NMI callback to RETF prevent FILE to be executed AGAIN) mov x,[13B2h] ;BIOS online flag (8bit) ;\skip below if offline jz @@skip ;/ push pb ;\retadr for below ;\ push @@back-1 ;/ ; push db ;-incoming pushed DB for below ; push 7E00h ;\ ; init apu effects/music pop db ; incoming current DB for below ; (according to APU bits pop db ;=7Eh ;/ ; in town status packet) jmp far 80EB99h ;--> injump to 105BC0h ; @@back: ; .assume p=20h ;(above set's it so) ; ;(if executed, ie. not when @@skip'ed) ;/ @@skip: clr p,30h // .assume p=00h ;below call 81C2B0h requires M=0, X=0 mov [0CDEh],0000h ;-mark fade-in/out non-busy mov a,0099h ;\ ;\ mov [0BEh],a ; 99D69A ;BIOS - enter town ; create_interpreter_thread mov a,0D69Ah ;/ ; (99D69Ah = enter town) call far 81C2B0h ;/ set p,20h // .assume p=20h mov a,81h ;\enable NMI and joypad (unstable: BIOS isn't yet mapped!) mov [4200h],a ;/caution: ensure that no NMI occurs in next few clk cycles mov a,80h ;\enable BIOS also in bank 0, mov [075000h],a ;map BIOS to bank 00h-1Fh ; and return to BIOS NMI handler jmp far 80BC27h ;apply [0E5000h]=a, and retf ;/ SNES Cart Satellaview Interpreter Token Summary ----------------------------------------------- Interpreter Tokens 00h ControlSubThread(pEntrypoint) ;special actions upon xx0000h..xx0005h 01h SetXYsignViewDirectionToSignsOfIncomingValues(vX,vY) ;not if both zero 02h SleepWithFixedObjShape(wSleep,pObjShape) 03h SleepWithXYstepAs9wayObjShape(wSleep,pObjShape1,..,pObjShape9) 04h SleepWithXYsignAs9wayObjShape(wSleep,pObjShape1,..,pObjShape9) 05h ClearForcedBlankAndFadeIn(wSleep,wSpeedRange?) 06h MasterBrightnessFadeOut(wSleep,wSpeedRange?) ;OptionalForcedBlank? 07h SetMosaicAndSleep(wSleep,wBgFlags,wMosaicSize) 08h N/A (hangs) 09h SleepAndBlendFromCurrentToNewPalette(wSleep,vPalIndex,pNewPalette) 0Ah HdmaEffectsOnBg3(wSleep,wEffectType,vScrollOffset,vExtraOffset) 0Bh SleepWithAngleAs9wayObjShape(wSleep,pObjShape1,..,pObjShape9) ;[18A8+X] 0Ch DisableObjsOfAllThreads() 0Dh ReEnableObjsOfAllThreads() 0Eh SleepWithXYsignAs9wayPlayerGenderObjShape(wSleep,pObjShape1,..,Shape9) 0Fh N/A (hangs) 10h SleepAndSetXYpos(wSleep,vX,vY) 11h SleepAndMoveTowardsTargetXYpos(wSleep,vX,vY) 12h SleepAndMoveByIncomingXYstep(wSleep,vX,vY) 13h SleepAndMoveAndAdjustXYstep(wSleep,vRotationAngleToOldXYstepOrSo?) 14h SleepAndMoveWithinBoundary(wSleep,vX1,vX2,vY1,vY2,wFactor?) 15h SleepAndMoveChangeBothXYstepsIfCollideOtherThread(wSleep,wBounceSpeed?) 16h SleepAndMoveAndIncrementXYstep(wSleep,vXincr,vYincr,qXlimit,qYlimit) 17h SleepAndMoveByIncomingYstepAndWavingXstep(wSleep,wY) 18h SleepAndMoveAndAccelerateTowardsTarget(wSleep,vX,vY,vSpeed) 19h SleepAndMoveAndSomethingComplicated?(wSleep,vX,vY) ;out: X,Y=modified 1Ah AdjustXYstep(wNewSpeedOrSo?) ;in: [18A8+X]=angle 1Bh MoveByOldXYstepWithoutSleep() 1Ch SleepAndMoveChangeXYstepIfCollideOtherThread(wSleep,vMask,vX?,vY?) 1Dh N/A (hangs) 1Dh N/A (hangs) 1Fh N/A (hangs) 20h Goto(pTarget) 21h Gosub(pTarget) ;max nesting=8 (or less when also using Loops) 22h Return() ;return from Gosub 23h QuitThread() ;terminate thread completely 24h LoopStart(wRepeatCount) ;see token 62h (LoopNext) 25h Sleep(wSleep) 26h MathsLet(vA,vB) ;A=B 27h MathsAdd(vA,vB) ;A=A+B ;1998 if unsigned carry 28h MathsSub(vA,vB) ;A=A-B ;1998 if signed overflow 29h MathsAnd(vA,vB) ;A=A AND B ;1998 if nonzero 2Ah MathsOr(vA,vB) ;A=A OR B ;1998 if nonzero 2Bh MathsXor(vA,vB) ;A=A XOR B ;1998 if nonzero 2Ch MathsNot(vA) ;A=NOT A ;1998 if nonzero 2Dh MathsMulSigned(vA,vB) ;A=A*B/100h ;1998 never (tries to be overflow) 2Eh MathsDivSigned(vA,vB) ;A=A/B*100h ;1998 if division by 0 2Fh SignedCompareWithConditionalGoto(vA,wOperator,vB,pTarget) 30h GotoIf_1998_IsNonzero(pTarget) 31h GotoIf_1998_IsZero(pTarget) 32h GotoArray(vArrayIndex,pPointerToArrayWithTargets) 33h ReadJoypad(bJoypadNumber,wX,wY) 34h CreateAnotherInterpreterThreadWithLimit(vThreadCount,bLimit,pEntry) 35h CheckIfXYposCollidesWithFlaggedThreads(vFlagMask) ;out: 1998=ID 36h GetUnsignedRandomValue(vA,wB) ;A=Random MOD B, special on B>7FFFh 37h SetObjWidthDepthFlagmask(vWidth,vDepth,vMask) ;for collide checks 38h CreateAnotherInterpreterThreadWithIncomingXYpos(vX,vY,pEntrypoint) 39h N/A (hangs) 3Ah SoundApuMessage00h_nnh(vParameter8bit) 3Bh SoundApuMessage01h_nnnh(vLower6bit,bMiddle2bit,bUpper2bit) 3Ch SoundApuMessage02h_nnnnh(vLower6bit,bMiddle2bit,bUpper2bit) 3Dh SoundApuUpload(bMode,pPtrToPtrToData) 3Eh SetPpuBgModeKillAllOtherThreadsAndResetVariousStuff(bBgMode) 3Fh SetTemporaryTableForBanksF1hAndUp(vTableNumber,pTableBase) 40h KillAllFlaggedThreads(vMask) ;ignores flags, and kills ALL when Mask=0 41h SetBUGGEDTimerHotspot(wHotspot) ;BUG: accidently ORed with AE09h 42h Ppu_Bg1_Bg2_SetScrollPosition(vX,vY) 43h Ppu_Bg1_Bg2_ApplyScrollOffsetAndSleep(wSleep,vX,vY) 44h NopWithDummyParameters(wUnused,wUnused) 45h NopWithoutParameters() 46h AllocateAndInitObjTilesOrUseExistingTiles(wLen,pSrc) 47h AllocateAndInitObjPaletteOrUseExistingPalette(pSrc) 48h DmaObjTilesToVram(wObjVramAddr,wOBjVramEnd,pSrc) 49h SetObjPalette(wObjPalIndex,wObjPalEnd,pSrc) 4Ah SramAddSubOrSetMoney(bAction,vLower16bit,vMiddle16bit,vUpper16bit) 4Bh SramUpdateChksumAndBackupCopy() 4Ch N/A (hangs) 4Dh N/A (hangs) 4Eh N/A (hangs) 4Fh N/A (hangs) 50h TestAndGotoIfNonzero(vA,vB,pTarget) ;Goto if (A AND B)<>0 51h TestAndGotoIfZero(vA,vB,pTarget) ;Goto if (A AND B)==0 52h InitNineGeneralPurposePrivateVariables(wA,wB,wC,wD,wE,wF,wG,wH,wI) 53h MultipleCreateThreadBySelectedTableEntries(vFlags,vLimit,pPtrToTable) 54h PrepareMultipleGosub() ;required prior to token 6Ah 55h StrangeXYposMultiplyThenDivide(wA,wB) ;Pos=Pos*((B-A)/2)/((B-A)/2) 56h BuggedForceXYposIntoScreenArea() ;messes up xpos and/or hangs endless 57h Maths32bitAdd16bitMul100h(vA(Msw),vB) ;A(Msw:Lsw)=A(Msw:Lsw)+B*100h 58h Maths32bitSub16bitMul100h(vA(Msw),vB) ;A(Msw:Lsw)=A(Msw:Lsw)-B*100h 59h SoundApuUploadWithTimeout(wTimeout,pPtrToPtrToData) 5Ah N/A (hangs) 5Bh N/A (hangs) 5Ch N/A (hangs) 5Dh N/A (hangs) 5Eh N/A (hangs) 5Fh N/A (hangs) 60h CallMachineCodeFunction(pTarget) 61h SetTemporaryOffsetFor0AxxxxhVariables(vOffset) 62h LoopNext() ;see token 24h (LoopStart) 63h SetForcedBlankAndSleepOnce() 64h ClearForcedBlankAndSleepOnce() 65h AllocateAndInitObjPaletteAndObjTilesOrUseExistingOnes(pSrc) ;fragile 66h WriteBgTiles(wBgNumber,pPtrTo16bitLenAnd24bitSrcPtr) 67h WritePalette(pPtrTo16bitLenAnd24bitSrcPtr) ;to backdrop/color0 and up 68h WriteBgMap(wBgNumber,pPtrTo16bitLenAnd24bitSrcPtr) 69h KillAllOtherThreads() 6Ah MultipleGosubToSelectedTableEntries(vFlags,pPtrToTable) ;see token 54h 6Bh AllocateAndInitBgPaletteTilesAndMap2(vX1,vY1,pPtrToThreePtrs,vBgMapSize) 6Ch DeallocateAllObjTilesAndObjPalettes() 6Dh BuggedSetBgParameters(bBgNumber,pPtr,wXsiz,wYsiz,wUnused,wUnused) 6Eh BuggedSetUnusedParameters(bSomeNumber,pPtr,wX,wY) 6Fh BuggedChangeBgScrolling(wX,wY) 70h PauseAllOtherThreads() 71h UnPauseAllOtherThreads() 72h GosubIfAccessedByPlayer(pGosubTargetOrPeopleFolderID) 73h Dma16kbyteObjTilesToTempBufferAt7F4000h() ;Backup OBJ Tiles 74h Dma16kbyteObjTilesFromTempBufferAt7F4000h() ;Restore OBJ Tiles 75h SetFixedPlayerGenderObjShape(pSrc,wLen1,wLen2) 76h InstallPeopleIfSatelliteIsOnline() ;create all people-threads 77h KillAllOtherThreadsAndGotoCrash() ;Goto to FFh-filled ROM at 829B5Eh 78h ZerofillBgBufferInWram(vBgNumber) 79h ChangePtrToObjPriority(vVariableToBePointedTo) ;default is 7Ah ChangeObjVsBgPriority(vPriorityBits) ;should be (0..3 * 1000h) 7Bh SetXYposRelativeToParentThread(vX,vY) 7Ch TransferObjTilesAndObjPaletteToVram(pPtrToPtrsToPaletteAndTileInfo) 7Dh AllocateAndInitBgPaletteTilesAndMap1(vX1,vY1,pPtrToThreePtrs,vBgMapSize) 7Eh DrawMessageBoxAllAtOnce(vWindowNumber,vDelay,vX,vY,pPtrToString) 7Fh DrawMessageBoxCharByCharBUGGED(..) ;works only via CALL, not token 7Fh 80h..FFh Reserved/Crashes (jumps to garbage function addresses) Legend for Token Parameters v 16bit Global or Private Variable or Immediate (encoded as 3 token bytes) p 24bit Pointer (3 token bytes) (banks F0h..FFh translated, in most cases) b 8bit Immediate (encoded directly as 1 token byte) w 16bit Immediate (encoded directly as 2 token bytes) q 16bit Immediate (accidently encoded as 3 token bytes, last byte unused) 3-byte Variable Encoding (v) +/-00nnnnh --> +/-nnnnh R ;immediate +/-01nnnnh --> +/-[nnnnh+X] R/W ;private variable (X=thread_id*2) +/-02nnnnh --> +/-[nnnnh] R/W ;global variable + 03nnnnh --> +[nnnnh+[19A4h]] W ;special (write-only permission) + 09nnnnh --> +[nnnnh+[19A4h]] R/W ;special (read/write permission) + 0Annnnh --> +[nnnnh+[19A4h]] R ;special (read-only permission) Examples: 000001h or FF0001h (aka -00FFFFh) are both meaning "+0001h". 021111h means "+[1111h]", FDEEEF (aka -021111h) means "-[1111h]". 3-byte Pointer Encoding (p) 00nnnnh..EFnnnnh --> 00nnnnh..EFnnnnh (unchanged) F0nnnnh --> TokenProgramPtr+nnnn (relative) F1nnnnh (or F2nnnnh) --> [[AFh+0]+nnnn*3] (indexed by immediate) F3nnnnh --> [[AFh+0]+[nnnn+X]*3] (indexed by thread-variable) F4nnnnh --> [[AFh+0]+[nnnn]*3] (indexed by global-variable) F5nnnnh (or F6nnnnh) --> [[AFh+3]+nnnn*3] (indexed by immediate) F7nnnnh --> [[AFh+3]+[nnnn+X]*3] (indexed by thread-variable) F8nnnnh --> [[AFh+3]+[nnnn]*3] (indexed by global-variable) F9nnnnh (or FAnnnnh) --> [[AFh+6]+nnnn*3] (indexed by immediate) FBnnnnh --> [[AFh+6]+[nnnn+X]*3] (indexed by thread-variable) FCnnnnh --> [[AFh+6]+[nnnn]*3] (indexed by global-variable) FDnnnnh..FFnnnnh --> crashes (undefined/reserved) 2-byte Operators for Signed Compare (Token 2Fh) 0000h Goto_if_less ;AB 0004h Goto_if_greater ;A>B 0005h Goto_if_greater_or_equal ;A>=B ControlSubThread(pEntrypoint) values xx0000h Pause xx0001h UnpauseSubThreadAndReenableObj xx0002h PauseAfterNextFrame xx0003h PauseAndDisableObj xx0004h ResetAndRestartSubThread xx0005h KillSubThread NNNNNNh Entrypoint (with automatic reset; only if other than old entrypoint) Maximum Stack Nesting is 4 Levels (Stack is used by Gosub and Loop tokens). Token Extensions (some predefined functions with Token-style parameters) These are invoked via CALL Token (60h), call address, followed by params. 809225h CallKillAllMachineCodeThreads() 80B47Dh CallGetTextLayerVramBase() 80B91Eh CallClearBg3TextLayer() 818EF9h CallSetApuRelatedPtr() 818F06h CallDrawMessageBoxCharByChar(vWindowNumber,vDelay,vX,vY,pPtrToString) 818FF0h CallDrawBlackCircleInLowerRightOfWindow() 81903Dh CallDisplayButton_A_ObjInLowerRightOfWindow() 81A508h CallSetGuiBorderScheme(pAddr1,pAddr2) 81A551h CallSetTextWindowBoundaries(wWindowNumber,bXpos,bYpos,bXsiz,bYsiz) 81A56Eh CallHideTextWindow(wWindowNumber) 81A57Bh CallSelectWindowBorder(wWindowNumber,wBorder) ;0..3, or FFh=NoBorder 81A59Ah CallSelectTextColor(wWindowNumber,bColor,bTileBank,bPalette) 81A5C3h CallClearTextWindowDrawBorder(wWindowNumber) 81A5D2h CallZoomInTextWindow(wWindowNumber,wZoomType) ;\1,2,3=Zoom HV,V,H 81A603h CallZoomOutTextWindow(wWindowNumber,wZoomType) ;/0=None/BuggyWinDiv2 81A634h CallSetGuiColorScheme(pAddr) 81A65Dh CallChangePaletteOfTextRow(vX,vY,vWidth,vPalette) 81A693h CallPeekMemory16bit(vDest,pSource) 81A6B4h CallPokeMemory16bit(vSource,pDest) 81C7D0h CallInitializeAndDeallocateAllObjTilesAndObjPalettes() 81C871h CallDeallocateAllObjs() 81CDF9h CallBackupObjPalette() 81CE09h CallRestoreObjPalette() 829699h CallUploadPaletteVram(pSource,wVramAddr,bPaletteIndex) 88932Fh CallTestIfFolderExists() ;in: 0780, out: 1998,077C,077E 88D076h CallTestIfDoor() 99D9A4h CallSelectPlayerAsSecondaryThread ;[19A4]=PlayerThreadId*2 Note: Some of these Call addresses are also listed in a 24bit-pointer table at address 808000h (though the (BIOS-)code uses direct 8xxxxxh values instead of indirect [808xxxh] values). Token Functions (some predefined token-functions) These can be invoked with GOSUB token (or GOTO or used as thread entrypoint): 99D69A EnterTown (use via goto, or use as entrypoint) 828230 DeallocMostBgPalettesAndBgTiles ;except tile 000h and color 00h-1Fh 88C1C6 SetCursorShape0 88C1D0 SetCursorShape1 88C1E0 SetCursorShape2 88C1EA SetCursorShape3 88C1F4 SetCursorShape4 88C1FE SetCursorShape5 99D8AB PauseSubThreadIfXYstepIsZero 99D8CD MoveWithinX1andX2boundaries 99D903 MoveWithinY1andY2boundaries Note: Some of the above functions are also listed in the table at 808000h. Compressed Data Some of the Functions can (optionally) use compressed Tile/Map/Palette data. --> SNES Decompression Formats Note: The actual compressed data is usually preceeded-by or bundled-with compression flags, length entry, and/or (in-)direct src/dest pointers (that "header" varies from function to function). SNES Cart Satellaview Chipsets ------------------------------ BSC-1A5B9P-01 (1995) (BIOS cartridge PCB) U1 44pin MCC-BSC LR39197 Nintendo U2 36pin ROM (36pin/40pin possible) U3 32pin 658512LFP-85 (4Mbit PSRAM) U4 28pin LH52B256NB-10PLL (256Kbit SRAM) U5 8pin MM1134 (battery controller for SRAM) BT1 2pin Battery CN1 62pin SNES Cartridge Edge (pin 2,33 used) CN2 62pin Flash Cartridge Connector (male?) There's no CIC chip (either it's contained in the MCC-chip... or in the flash card, but in that case the thing won't work without flash card?) MAIN-BSA-01 (1995) (receiver unit/expansion port PCB) U1 20pin 74LS541 8-bit 3-state buffer/line driver U2 20pin 74LS541 8-bit 3-state buffer/line driver U3 20pin 74LS245 8-bit 3-state bus transceiver U4 8pin SPR-BSA (unknown, might be controlled via port 2198h or 2199h?) U5 100pin DCD-BSA (custom Nintendo chip) U6 64pin MN88821 (maybe a MN88831 variant: Satellite Audio Decoder) U7 18pin AN3915S Clock Regenerator (for amplifying/stabilizing Y1 crystal) U8 4pin PQ05RH1L (5V regulator with ON/OFF control) U9 14pin LM324 Quad Amplifier Y1 2pin 18.432MHz crystal T1 4pin ZJYS5102-2PT Transformator T2 4pin ZJYS5102-2PT Transformator CN1 28pin SNES Expansion Port CN2 38pin Expansion Port (EXT) (believed to be for modem) CN3 3pin To POWER and ACCESS LEDs on Front Panel CN4 7pin Rear connector (satellite and power supply?) BSMC-AF-01 (Memory Card PCB) (to be plugged into BIOS cartridge) U1 56pin Sharp LH28F800SUT-ZI (or -Z1?) (1Mbyte FLASH) CN1 62pin Flash Cartridge Connector (female?) There are no other chips on this PCB (only capacitors and resistors). BSMC-CR-01 (Memory Card PCB) (to be plugged into GAME cartridges) U1 ?pin unknown (reportedly read-only... mask ROM?) CN1 62pin Flash Cartridge Connector (female?) BSC-1A5M-01 (1995) (GAME cartridge with onboard FLASH cartridge slot) U1 36pin ROM U2 28pin SRAM (32Kbytes) U3 16pin MAD-1A U4 16pin CIC D411B BT1 2pin Battery CR2032 CN1 62pin SNES Cartridge Edge (pin 2,33 used) CN2 62pin Flash Cartridge Connector (male 2x31 pins) Used by "Derby Stallion 96" (and maybe other games, too). BSC-1L3B-01 (1996) (GAME cartridge with SA1 and onboard FLASH cartridge slot) U1 44pin ROM U2 28pin SRAM (8Kbytes) U3 128pin SA1 U4 8pin MM1026AF (battery controller for SRAM) BT1 2pin Battery CN1 62pin SNES Cartridge Edge (pin 2,33 used) CN2 62pin Flash Cartridge Connector (male?) Used by "Itoi Shigesato no Bass Tsuri No. 1" (and maybe other games, too). Nintendo Power flashcarts Theoretically, Nintendo Power flashcarts are also compatible with the BSX expansion hardware (in terms of connecting EXPAND to SYSCK via 100 ohms), unknown if any Nintendo Power titles did actually use that feature. SNES Cart Data Pack Slots (satellaview-like mini-cartridge slot) ---------------------------------------------------------------- Data Packs Data Packs are Satellaview 8M Memory Packs which have data meant to be used as expansion for a Data Pack-compatible game. Data Pack-compatible game cartridges have a resemblence to the BS-X Cartridge itself. Usage For most of these games, Data was distributed via St.GIGA's Satellaview services. Same Game and SD Gundam G-Next had some Data Packs sold as retail in stores. RPG Tsukuru 2, Sound Novel Tsukuru and Ongaku Tsukuru Kanaderu could save user-created data to 8M Memory Packs. Cartridges with Data Pack Slot Derby Stallion 96 (SpecialLoROM, 3MB ROM, 32K RAM) Itoi Shigesato no Bass Tsuri No. 1 (SA-1, map-able 4MB ROM, 8K RAM) Joushou Mahjong Tenpai (HiROM, 1MB) Ongaku Tukool/Tsukuru Kanaderu (HiROM, 1MB) RPG Tukool/Tsukuru 2 (LoROM, 2MB) Same Game Tsume Game (HiROM, 1MB) Satellaview BS-X BIOS (MCC, 1MB ROM) (FLASH at C00000h) SD Gundam G-NEXT (SA-1, map-able 1.5MB ROM, 32K RAM) Sound Novel Tukool/Tsukuru (SpecialLoROM, 3MB ROM, 64K RAM) Aside from the BS-X BIOS, two of the above games are also accessing BS-X hardware via I/O Ports 2188h/2194h/etc (Derby Stallion 96, Itoi Shigesato no Bass Tsuri No. 1). For doing that, the cartridges do probably require the EXPAND pin to be wired via 100 ohm to SYSCK. Cartridge Header of cartridges with Data Pack Slot The presence of Data Pack Slots is indicated by a "Z" as first letter of Game Code: [FFB2h]="Z" ;first letter of game code [FFB5h]<>20h ;game code must be 4-letters (not space padded 2-letters) [FFDAh]=33h ;game code must exist (ie. extended header must be present) Data Pack Mapping MCC (BSX-BIOS) FLASH at C00000h (continous) (mappable via MCC chip) SA-1 FLASH at (probably mappable via SA1) HiROM FLASH at E00000h (probably continous) LoROM/SpecialLoROM FLASH at C00000h (looks like 32K chunks) LoROM/SpecialLoROM Mapping Notes The FLASH memory seems to be divided into 32K chunks (mirrored to Cn0000h and Cn8000h) (of which, Derby Stallion 96 uses Cn8000h, RPG Tukool uses Cn0000h, and Ongaku Tukool uses both Cn0000h and Cn8000h). The two 3MB SpecialLoROM games also have the ROM mapped in an unconventional fashion: 1st 1MB of ROM mapped to banks 00-1F 2nd 1MB of ROM mapped to banks 20-3F and A0-BF 3rd 1MB of ROM mapped to banks 80-9F 1MB of Data Pack FLASH mapped to banks C0-DF 32K..64K SRAM mapped to banks 70-71 Despite of memory-mirroring of 2nd MB, the checksum-mirroring goes on 3rd MB? Note: Above mapping differs from "normal" 3MB LoROM games like Wizardry 6 (which have 3rd 1MB in banks 40h-5Fh). SNES Cart Nintendo Power (flashcard) ------------------------------------ Nintendo Power cartridges are official FLASH cartridges from Nintendo (released only in Japan). Unlike the older Satellaview FLASH cartridges, they do connect directly to the SNES cartridge slot. The capacity is 4MByte FLASH and 32KByte battery-backed SRAM. FLASH (512Kbyte blocks) The FLASH is divided into eight 512Kbyte blocks. The first block does usually contain a Game Selection Menu, the other blocks can contain up to seven 512KByte games, or other combinations like one 3MByte game and one 512KByte game. Alternately, the cartridge can contain a single 4MByte game (in that case, without the Menu). SRAM (2Kbyte blocks) (battery-backed) The SRAM is divided into sixteen 2Kbyte blocks for storing game positions. Games can use one or more (or all) of these blocks (the menu doesn't use any of that memory). --> SNES Cart Nintendo Power - New Stuff --> SNES Cart Nintendo Power - I/O Ports --> SNES Cart Nintendo Power - FLASH Commands --> SNES Cart Nintendo Power - Directory --> SNES Pinouts Nintendo Power Flashcarts Nintendo Power Games Games have been available at kiosks with FLASH Programming Stations. There are around 150 Nintendo Power games: around 21 games exclusively released only for Nintendo Power users, and around 130 games which have been previously released as normal ROM cartridges. Nintendo Power PCB "SHVC-MMS-X1" or "SHVC-MMS-02" (1997) Chipset (SNES) U1 18pin CIC ("F411B Nintendo") U2 100pin MX15001 ("Mega Chips MX15001TFC") U3 44pin 16M FLASH ("MX 29F1601MC-11C3") (2Mbyte FLASH, plus hidden sector) U4 44pin 16M FLASH ("MX 29F1601MC-11C3") (2Mbyte FLASH, plus hidden sector) U5 44pin 16M FLASH (N/A, not installed) U6 28pin SRAM ("SEC KM62256CLG-7L") (32Kbyte SRAM) U7 8pin MM1134 ("M 707 134B") (battery controller) BAT1 2pin Battery ("Panasonic CR2032 +3V") Nintendo Power PCB "DMG-A20-01" (199x) Chipset (Gameboy version) U1 80pin G-MMC1 ("MegaChips MX15002UCA" U2 40pin 8M FLASH ("MX29F008ATC-14") (plus hidden sector) U3 32pin 1M SRAM ("UT621024SC-70LL") X1 3pin N/A (oscillator? not installed) BAT1 2pin Battery ("Panasonic CR2025") Nintendo Power Menu SNES Cartridge Header Gamecode: "MENU" (this somewhat indicates the "MX15001" chip) ROM Size: 512K (the menu size, not including the other FLASH blocks) SRAM Size: 0K (though there is 32Kbyte SRAM for use by the games) Battery Present: Yes Checksum: Across 512Kbyte menu, with Directory assumed to be FFh-filled (except for the "MULTICASSETTE 32" part) The PCB doesn't contain a ROM (the Menu is stored in FLASH, too). Nintendo Power Menu Content ROM Offset SNES Address Size Content 000000h 808000h 4xxxh Menu Code (around 16K, depending on version) 004xxxh 80xxxxh 3xxxh Unused (FFh-filled) 007FB0h 80FFB0h 50h Cartridge Header 008000h 818000h 40000h Unused (FFh-filled) 048000h 898000h 372Bh Something (APU code/data or so) 04B72Bh 8xxxxxh 47D5h Unused (FFh-filled) 050000h 8A8000h 8665h Something (VRAM data or so) 058665h 8Bxxxxh 798Bh Unused (FFh-filled) 060000h 8C8000h 10000h Directory (File 0..7) (2000h bytes/entry) 070000h 8E8000h 10000h Unused (FFh-filled) Note Nintendo has used the name "Nintendo Power" for various different things: Super Famicom Flashcards (in Japan) Gameboy Color Flashcards (in Japan) Super Famicom Magazine (online via Satellaview BS-X) (in Japan) Official SNES Magazine (printout) (in USA) SNES Cart Nintendo Power - New Stuff ------------------------------------ Operation during /RESET=LOW [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=F0h ;FLASH read/reset command [00000h]=38h, [00000h]=D0h, [00000h]=71h ;FLASH request chip info part 1 dummy=[00004h] ;Read Ready-status (bit7=1=ready) [00000h]=72h, [00000h]=75h ;FLASH request chip info part 2 Port[2404h..2407h]=[0FF00h+(n*8)+0,2,4,6] ;Read mapping info for File(n) [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=F0h ;FLASH read/reset command Detailed [00000h]=38h ;copy hidden sector to page buffer? [00000h]=D0h ; ...confirm above [00000h]=71h ;read extended status register dummy=[00004h] ; ...do read it (bit7=1=ready) [00000h]=72h ;swap page buffer (map above buffer to cpu side?) [00000h]=75h ;read page buffer to cpu xx=[0FFxxh] ; ...do read it other interesting commands: [00000h]=74h ;write page buffer single byte from cpu [0xxxxh]=xx ; ...do write it or sequential: [00000h]=E0h ;sequential load from cpu to page buffer [00000h]=num.L ; ...byte count lsb (minus 1 ?) (0=one byte, what=100h bytes) [00000h]=num.H ; ...byte cound msb (zero) [?]=data ; ...data? [00000h]=0Ch ;forward page buffer to flash [00000h]=num.L ; ...byte count lsb (minus 1 ?) (0=one byte, what=100h bytes) [addr]=num.H ; ...byte cound msb (zero) [...]? ; ...do something to wait until ready Hidden Mapping Info Example (chip 1 at C0FFxxh, chip 2 at E0FFxxh) C0FF00 03 11 AA 74 AA 97 00 12 ;Menu (512K Lorom, no SRAM) C0FF08 00 08 29 15 4A 12 10 01 ;Super Mario World (512K Lorom, 2K SRAM) C0FF10 0B FF AA FF AA FF 21 FF ;Doraemon 4 (1.5M Lorom, no SRAM) C0FF18 49 FF 61 FF A5 FF 51 FF ;Dragon Slayer II (1.5M Hirom, 8K SRAM) C0FF20..FF FF-filled (byte at C0FF7Fh is 00h in some carts) ;-unused E0FF00..8F FF-filled (other values at E0FF8xh in some carts) ;\garbage, from E0FF90 FF FF 55 00 FF FF FF FF FF FF FF FF FF FF FF FF ; chip-testing E0FFA0 FF FF FF FF FF FF 55 00 FF FF FF FF FF FF FF FF ; or so E0FFB0 FF FF FF FF FF FF 55 00 FF FF FF FF FF FF FF FF ;/ E0FFC0..FF FF-filled ;-unused There are always 8 bytes at odd addresses at C0FF01..0F, interleaved with the mapping entries 0 and 1 (though no matter if the cart uses 1, 2, or 3 mapping entries). The 'odd' bytes are some serial number, apart from the first two bytes, it seems to be just a BCD date/time stamp, ie. formatted as 11-xx-YY-MM-DD-HH-MM-SS. New findings are that the "xx" in the "11-xx-YY-MM-DD-HH-MM-SS" can be non-BCD (spotted in the Super Puyo Puyo cart). Some carts have extra 'garbage' at C0FF7F and E0FF80..BF. Nintendo Power Commands if [002400h]<>7Dh then skip unlocking ;else locking would be re-enabled [002400h]=09h ;\ dummy=[002400h] ; [002401h]=28h ; wakeup sequence (needed before sending other commands, [002401h]=84h ; and also enables reading from port 2400h..2407h) [002400h]=06h ; [002400h]=39h ;/ After wakeup, single-byte commands can be written to [002400h]: [002400h]=00h RESET and map GAME14 ? (issues /RESET pulse) [002400h]=01h causes always 8x7D [002400h]=02h Set STATUS.bit2=1 (/WP=HIGH, release Write protect) [002400h]=03h Set STATUS.bit2=0 (/WP=LOW, force Write protect) [002400h]=04h HIROM:ALL (map whole FLASH in HiROM mode) [002400h]=05h HIROM:MENU (map MENU in HiROM mode instead normal LoROM mode) [002400h]=06h causes always 8x7D (aka, undoes toggle?) [002400h]=07h causes always 8x7D [002400h]=08h causes always 8x7D [002400h]=09h no effect ;\ [002400h]=0ah no effect ;/ [002400h]=0bh causes always 8x7D [002400h]=0ch causes always 8x7D [002400h]=0dh causes always 8x7D [002400h]=0eh causes always 8x7D [002400h]=0fh causes always 8x7D [002400h]=10h causes always 8x7D [002400h]=14h causes always 8x7D [002400h]=20h Set STATUS.bit3=0 (discovered by skaman) (default) [002400h]=21h Set STATUS.bit3=1 (discovered by skaman) (disable ROM read?) [002400h]=24h causes always 8x7D [002400h]=44h no effect (once caused crash with green rectangle) [002400h]=80h..8Fh ;-Issue /RESET to SNES and map GAME 0..15 [002400h]=C5h causes always 8x7D [002400h]=FFh sometimes maps GAME14 or GAME15? (unreliable) SNES Cart Nintendo Power - I/O Ports ------------------------------------ Nintendo Power I/O Map Write registers: 2400h - Command 2401h - Extra parameter key (used only for wakeup command) 2402h..2407h - Unknown/unused Read registers (before wakeup): 2400h..2407h - Fixed 7Dh Read registers (after wakeup): 2400h - Fixed 2Ah 2401h - Status 2402h..2403h - Fixed 2Ah 2404h - Mapping Info: ROM/RAM Size ;\these four bytes are 2405h..2406h - Mapping Info: SRAM Mapping related ; initialized from the 2407h - Mapping Info: ROM/RAM Base ;/hidden flash sector Port 2401h = Status (R) 0-1 zero 2 release /WP state (set by CMD_02h, cleared by CMD_03h) 3 disable ROM reading? (set by CMD_21h, cleared by CMD_20h) 4-7 Selected Slot (0=Menu/File0, 1..15=File1..15) (via CMD_8xh) Port 2404h = Size (R) 0-1 SRAM Size (0=2K, 1=8K, 2=32K, 3=None) ;ie. 2K SHL (N*2) 2-4 ROM Size (0=512K, 2=1.5M, 5=3M, 7=4M) ;ie. 512K*(N+1) 5 Maybe ROM Size MSB for carts with three FLASH chips (set for HIROM:ALL) 6-7 Mode (0=Lorom, 1=Hirom, 2=Forced HIROM:MENU, 3=Forced HIROM:ALL) Port 2407h = Base (R) 0-3 SRAM Base in 2K units 4-7 ROM Base in 512K units (bit7 set for HIROM:MENU on skaman's blank cart) Port 2405h,2406h = SRAM Mapping Related (R) The values for port 2405h/2406h are always one of these three sets, apparently related to SRAM mapping: 29,4A for Lorom with SRAM 61,A5 for Hirom with SRAM AA,AA for Lorom/Hirom without SRAM 61,A5 (when forcing HIROM:ALL) D5,7F (when forcing HIROM:MENU) 8A,8A (when forcing HIROM:MENU on skaman's blank cart) Probably selecting which bank(s) SRAM is mapped/mirrored in the SNES memory space. Nintendo Power I/O Ports The I/O ports at 002400h-002401h are used for mapping a selected game. Done as follows: mov [002400h],09h cmp [002400h],7Dh jne $ ;lockup if invalid mov [002401h],28h mov [002401h],84h mov [002400h],06h mov [002400h],39h mov [002400h],80h+(Directory[n*2000h+0] AND 0Fh) jmp $ ;lockup (until reset applies) After the last write, the MX15001 chip maps the desired file, and does then inject a /RESET pulse to the SNES console, which resets the CPU, APU (both SPC and DSP), WRAM (address register), and any Expansion Port hardware (like Satellaview), or piggyback cartridges (like Xband modem). The two PPU chips and the CIC chip aren't affected by the /RESET signal. The overall effect is that it boots the selected file via its Reset vector at [FFFCh]. SNES Cart Nintendo Power - FLASH Commands ----------------------------------------- Before sending write/erase commands, one must initialize the MX15001 chip via port 240xh (particulary: release the /WP pin), selecting the HIROM_ALL mapping mode may be also recommended (for getting the whole 4Mbyte FLASH memory mapped as continous memory block at address C00000h-FFFFFFh). Observe that the cart contains two FLASH chips. In HIROM_ALL mode, one chip is at C00000h-DFFFFFh, the other one at E00000h-FFFFFFh (ie. commands must be either written to C0AAAAh/C05554h or E0AAAAh/E05554h, depending on which chip is meant to be accessed; when programming large files that occupy both chips, it would be fastest to program both chips simultaneously). FLASH Command Summary The FLASH chips are using more or less using standard FLASH commands, invoked by writing to low-bytes at word-addresses 05555h and 02AAAh (aka writing bytes to byte-addresses 0AAAAh and 05554h). [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=F0h, data=[addr..] ;Read/Reset [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=90h, ID=[00000h] ;Get Maker ID [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=90h, ID=[00002h] ;Get Device ID [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=90h, WP=[x0004h] ;Get Sector Protect [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=70h, SRD=[00000h] ;Read Status Reg [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=50h ;Clear Status Reg [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=A0h, [addr..]=data ;Page/Byte Program [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=80h ;Prepare Erase... [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=10h ;...do Chip Erase [0AAAAh]=AAh, [05554h]=55h, [x0000h]=30h ;...do Sector Erase [0xxxxh]=B0h ;...Erase suspend [0xxxxh]=D0h ;...Erase resume [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=60h ;Prepare Protect... [0AAAAh]=AAh, [05554h]=55h, [addr]=20h ;...do Sector Protect [0AAAAh]=AAh, [05554h]=55h, [addr]=40h ;...do Sector Unprot. [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=C0h ;Sleep [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=E0h ;Abort Undocumented commands for hidden sector: [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=77h ;Prepare Hidden... [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=99h, [addr..]=data ;...do Hidden Write [0AAAAh]=AAh, [05554h]=55h, [0AAAAh]=E0h ;...do Hidden Erase [00000h]=38h, [00000h]=D0h, [00000h]=71h, dummy=[00004] ;Prepare Hidden Rd... [00000h]=72h, [00000h]=75h, data=[addr...] ;...do Hidden Read FLASH Read/Reset Command (F0h) Resets the chip to normal Read Data mode; this is required after most commands (in order to resume normal operation; for leaving the Get Status, Get ID, or Sleep states). FLASH Get Status (70h) and Clear Status (50h) Clear Status resets the error flags in bit4,5 (required because those bits would otherwise stay set forever). Get Status switches to read-status mode (this is usually not required because the erase/program/protect/sleep commands are automatically entering read-status mode). The separate status bits are: 7 Write/Erase State (0=Busy, 1=Ready) 6 Erase Suspend (0=Normal, 1=Sector Erase Suspended) 5 Erase Failure (0=Okay, 1=Fail in erase) 4 Program Failure (0=Okay, 1=Fail in program) 3 Reserved (zero) (MX29F1610A/B) 3 Sector-Protect Status (0=?, 1=?) (MX29F1611 only) 2 Sleep Mode (0=Normal, 1=Sleep) (MX29F1611 only) 1-0 Reserved (zero) FLASH Get Maker/Device ID and Sector Protect Bytes (90h) Allows to read Maker/Device ID and/or Sector Protect Byte(s) from following address(es): [00000h]=Manufacturer ID: C2h = Macronix [00002h]=Device ID: FAh = MX29F1610A ;\with sector_protect, suspend/resume, without sleep/abort FBh = MX29F1610B ;/ F7h = MX29F1611 ;-with sector_protect, suspend/resume, sleep/abort 6Bh = MX29F1615 ;-without sector_protect, suspend/resume, sleep/abort F3h = MX29F1601MC ;<-- undocumented, used in SNES nintendo power carts [x0004h]=Sector Protect State: 00h = normal unprotected 128Kbyte sector (can occur on all sectors) C2h = write-protected 128Kbyte sector (can occur on first & last sector only) FLASH Erase: Prepare (80h), and Chip Erase (10h) or Sector Erase (30h) Allows to erase the whole 2Mbyte chip (ie. half of the Nintendo Power cart), or a specific 128Kbyte sector. Some MX29F16xx chips are also allowing to suspend (B0h) or resume (D0h) sector erase (allowing to access other sectors during erase, if that should be desired). FLASH Page/Byte Program (A0h) Allows to write one or more bytes (max 80h bytes) to a 128-byte page. The Page/Byte Program command doesn't auto-erase the written page, so the sector(s) should be manually erased prior to programming (otherwise the new bytes will be ANDed with old data). Caution: The chips in Nintendo Power carts require the LAST BYTE written TWICE in order to start programming (unlike as in offical MX29F16xx specs, which claim programmig to start automatically after not sending further bytes for about 30..100us). FLASH Protect: Prepare (60h), and Protect (20h) or Unprotect (40h) Allows to write-protect or unprotect separate 128Kbyte sectors (this works only for the first and last sector of each chip) (/WP=HIGH overrides the protection). FLASH Sleep (C0h) Switches the chip to sleep state; can be resumed only via Read/Reset command (F0h). Sleep mode is supported on MX29F1611 only. FLASH Abort (E0h) Aborts something. Supported on MX29F1611 only. Basic MX29F16xx specs JEDEC-standard EEPROM commands Endurance: 100,000 cycles Fast access time: 70/90/120ns Sector erase architecture - 16 equal sectors of 128k bytes each - Sector erase time: 1.3s typical Page program operation - Internal address and data latches for 128 bytes/64 words per page - Page programming time: 0.9ms typical - Byte programming time: 7us in average SNES Cart Nintendo Power - Directory ------------------------------------ Directory Area ROM Offset SNES Address Size Content 060000h 8C8000h 2000h File 0 (Menu) 062000h 8CA000h 2000h File 1 064000h 8CC000h 2000h File 2 066000h 8CE000h 2000h File 3 068000h 8D8000h 2000h File 4 06A000h 8DA000h 2000h File 5 06C000h 8DC000h 2000h File 6 06E000h 8DE000h 2000h File 7 070000h 8E8000h 10000h Unused (FFh-filled) The last 64Kbyte are probably usable as further file entries in cartridges bigger than 4Mbyte (the Menu software in the existing cartridges is hardcoded to process only files 1..7) (whilst Port 2400h seems to accept 4bit file numbers). Directory Entry Format 0000h 1 Directory index (00h..07h for Entry 0..7) (or FFh=Unused Entry) 0001h 1 First 512K-FLASH block (00h..07h for block 0..7) 0002h 1 First 2K-SRAM block (00h..0Fh for block 0..15) 0003h 2 Number of 512K-FLASH blocks (mul 4) (=0004h..001Ch for 1..7 blks) 0005h 2 Number of 2K-SRAM blocks (mul 16) (=0000h..0100h for 0..16 blks) 0007h 12 Gamecode (eg. "SHVC-MENU- ", "SHVC-AGPJ- ", or "SHVC-CS - ") 0013h 44 Title in Shift-JIS format (padded with 00h's) (not used by Menu) 003Fh 384 Title Bitmap (192x12 pixels, in 30h*8 bytes, ie. 180h bytes) 01BFh 10 Date "MM/DD/YYYY" (or "YYYY/MM/DD" on "NINnnnnn" carts) 01C9h 8 Time "HH:MM:SS" 01D1h 8 Law "LAWnnnnn" or "NINnnnnn" (eg. "LAW01712", or "NIN11001") 01D9h 7703 Unused (1E17h bytes, FFh-filled) 1FF0h 16 For File0: "MULTICASSETTE 32" / For Files 1-7: Unused (FFh-filled) Directory Index Directory Index indicates if the Entry is used (FFh=unused). If it is used, then it must be equal to the current directory entry number (ie. a rather redundant thing, where the index is indexing itself). The lower 4bit of the index value is used for game selection via Port 2400h. First FLASH/SRAM Block The First FLASH block number is stored in lower some bits of [0001h]. The First SRAM block number is stored in lower some bits of [0002h]. The directory doesn't contain any flag that indicates HiROM or LoROM mapping. There is no support for fragmented FLASH/SRAM files (ie. the programming station must erase & rewrite the entire cartridge, with the old used/unused blocks re-ordered so that they do form continous memory blocks). Number of FLASH/SRAM Blocks (displayed in Menu) These entries are used to display the amount of used/unused blocks. Free FLASH blocks are shown as blue "F" symbols, free SRAM blocks as red "B" symbols, used blocks as gray "F" and "B" symbols. Pressing the X-button in the menu indicates which blocks are being used by the currently selected game. Title Bitmap (displayed in Menu) The 192x12 pixel title bitmap is divided into eight 24x12 pixel sections, using a most bizarre encoding: Each section is 30h bytes in size (enough for 32 pixel width, but of these 32 pixels, the "middle" 4 pixels are overlapping each other, and the "right-most" 4 pixels are unused. The byte/pixel order for 12 rows (y=0..11) is: Left 8 pixels = (Byte[00h+y*2]) Middle 8 pixels = (Byte[01h+y*2]) OR (Byte[18h+y*2] SHR 4) Right 8 pixels = (Byte[18h+y*2] SHL 4) OR (Byte[19h+y*2] SHR 4) The result is displayed as a normal 192-pixel bitmap (without any spacing between the 24-pixel sections). The bits in the separate bytes are bit7=left, bit0=right. Color depth is 1bit (0=dark/background, 1=bright/text). The bitmap does usually contain japanese text without "special" features, though it could also be used for small icons, symbols, bold text, greek text, etc. Text Fields (not used by Menu) The Shift-JIS Title, and ASCII Game Code, Date, Time, Law & Multicassette strings aren't used by the Menu. The 5-digit Law number is usually (but not always) same for all files on the cartridge, supposedly indicating the station that has programmed the file. LAW = games installed on kiosks in Lawson Convenience Store chain NIN = games pre-installed by nintendo (eg. derby 98) The Multicassette number does probably indicate the FLASH size in MBits (it's always 32 for the existing 32Mbit/4MByte cartridges). SNES Cart Sufami Turbo (Mini Cartridge Adaptor) ----------------------------------------------- The Sufami Turbo from Bandai is an adaptor for low-cost mini-cartridges. Aside from cost-reduction, one special feature is that one can connect two cartridges at once (so two games could share ROM or SRAM data). The BIOS in the adaptor provides a huge character set, which may allow to reduce ROM size of the games. --> SNES Cart Sufami Turbo General Notes --> SNES Cart Sufami Turbo ROM/RAM Headers --> SNES Cart Sufami Turbo BIOS Functions & Charset SNES Cart Sufami Turbo General Notes ------------------------------------ Sufami Turbo Hardware The "adaptor" connects to the SNES cartridge socket, it contains the BIOS ROM, and two slots for "mini-carts". Slot A for the game being played, Slot B can contain another game (some games include features that allow to access game position data from other games, some may also access ROM data from other games). Sufami Turbo Memory Map 00-1F:8000h-FFFFh BIOS ROM (always 256Kbytes) (max 1MByte) 20-3F:8000h-FFFFh Cartridge A ROM (usually 512Kbytes) (max 1MByte) 40-5F:8000h-FFFFh Cartridge B ROM (usually 512Kbytes) (max 1MByte) 60-63:8000h-FFFFh Cartridge A SRAM (usually 0/2/8 Kbytes) (max 128Kbyte) 70-73:8000h-FFFFh Cartridge B SRAM (usually 0/2/8 Kbytes) (max 128Kbyte) 80-FF:8000h-FFFFh Mirror of above banks Memory Notes The BIOS detects max 128Kbyte (64 pages) SRAM per slot, some games are (maybe accidently) exceeding that limit (eg. Poi Poi Ninja zerofills 256 pages). Some games (eg. SD Gundam Part 1) access SRAM slot B at 700000h rather than 708000h. Some games (eg. SD Ultra Battle) may fail if the SRAM in slot B is uninitialized (ie. before linking games in Slot A and B, first launch them separately in Slot A). When not using BIOS functions, one can safely destroy all WRAM locations, except for WRAM[00000h] (which MUST be nonzero to enable the Game NMI handler & disable the BIOS NMI handler). Sufami Turbo ROM Images The games are typically 512Kbyte or 1MByte in size. Existing ROM-Images are often 1.5Mbytes or 2MBytes - those files do include the 256KByte BIOS-ROM (banks 00h-07h), plus three mirrors of the BIOS (banks 08h-1Fh), followed by the actual 512Kbyte or 1MByte Game ROM (bank 20h-2Fh or 20h-3Fh). There are also a few 3MByte ROM-images, with additional mirrors of the game (bank 30h-3Fh), followed by a second game (bank 40h-4Fh), followed by mirrors of the second game (bank 50h-5Fh). That formats are simple (but very bloated) solutions to load the BIOS & Game(s) as a "normal" LoROM file. Sufami Turbo Games There have been only 13 games released: Crayon Shin Chan Gegege No Kitarou Gekisou Sentai Car Ranger Poi Poi Ninja ;-link-able with itself (2-player sram) Sailor Moon Stars Panic 2 SD Gundam Generations: part 1 ;\ SD Gundam Generations: part 2 ; SD Gundam Generations: part 3 ; link-able with each other SD Gundam Generations: part 4 ; SD Gundam Generations: part 5 ; SD Gundam Generations: part 6 ;/ SD Ultra Battle: Seven Legend ;\link-able with each other SD Ultra Battle: Ultraman Legend ;/ All of them available only in Japan, released between June & September 1996. Thereafter, the games may have been kept available for a while, but altogether, it doesn't seem to have been a too successful product. Component List for Sufami Turbo Adaptor PCB "SHVC TURBO, BASE CASSETTE, BANDAI, PT-923" IC1 18pin unknown (CIC) IC2 16pin "74AC139" or so IC3 40pin SUFAMI TURBO "LH5326NJ" or so (BIOS ROM) (256Kbyte) IC4 8pin unknown CP1 unknown (flashlight? oscillator? strange capacitor?) CN1 62pin SNES cartridge edge (male) CN2 40pin Sufami Cartridge Slot A (Game to be played) CN3 40pin Sufami Cartridge Slot B (Other game to be "linked") C1..4 2pin capacitors for IC1..4 R1..4 2pin resistors for unknown purpose Note: Of the 62pin cartridge edge, only 43 pins are actually connected (the middle 46 pins, excluding Pin 40,48,57, aka A15/A23/SYSCK). Component Lists for Sufami Turbo Game Carts All unknown. Probably contains only ROM, and (optionally) SRAM and Battery. Physical SRAM size(s) are unknown (ie. unknown if there is enough memory for more than one file). Cartridge slot pin-outs are unknown. SNES Cart Sufami Turbo ROM/RAM Headers -------------------------------------- Sufami Turbo BIOS ROM Header The BIOS has a rather incomplete Nintendo-like header at ROM Offset 07FB0h (mapped to 00FFB0h): FFB0h Maker Code "B2" ;\extended header, present FFB2h Game Code "A9PJ" ; even though [FFDAh]<>33h FFB6h Reserved (10x00h) ;/ FFC0h Title "ADD-ON BASE CASSETE " (really mis-spelled, with only one "T") FFD4h Mapmode (always 30h = Fast LoROM) FFD5h Reserved (6x00h) (no ROM/RAM size entries, no ext.header-flag, etc.) FFDCh Dummy "checksum" value (always FFh,FFh,00h,00h) FFE0h Exception Vectors (IRQ,NMI,Entrypoint,etc.) And, there is a header-like data field at ROM-Offset 00000h (mapped to 808000h) (this part isn't really a header, but rather contains ID strings that are used by the BIOS, for comparing them with Game ROM/SRAM): 8000h 16 "BANDAI SFC-ADX",0,0 ;Game ROM ID 8010h 16 "SFC-ADX BACKUP",0,0 ;Game SRAM ID Sufami Turbo Game ROM Header (40h bytes) Located at ROM Offset 00000h (mapped to 208000h/408000h for Slot A/B): 00h 14 ID "BANDAI SFC-ADX" (required, compared against 14-byte ID in BIOS) 0Eh 2 Zero-filled 10h 14 Title, padded with spaces (can be 7bit ASCII and 8bit Japanese) 1Eh 2 Zero-filled 20h 2 Entrypoint (in bank 20h) ;game starts here (if it is in Slot A) 22h 2 NMI Vector (in bank 20h) ;if RAM[000000h]=00h: use BIOS NMI handler 24h 2 IRQ Vector (in bank 20h) 26h 2 COP Vector (in bank 20h) 28h 2 BRK Vector (in bank 20h) 2Ah 2 ABT Vector (in bank 20h) 2Ch 4 Zero-filled 30h 3 Unique 24bit ID of a Game (or series of games) (usually 0xh,00h,0yh) 33h 1 Index within a series (01h and up) (eg. 01h..06h for Gundam 1-6) 34h 1 ROM Speed (00h=Slow/2.68Mhz, 01h=Fast=3.58MHz) 35h 1 Chipset/Features (00h=Simple, 01h=SRAM or Linkable?, 03h=Special?) 36h 1 ROM Size in 128Kbyte Units (04h=512K, 08h=1024K) 37h 1 SRAM Size in 2Kbyte Units (00h=None, 01h=2K, 04h=8K) 38h 8 Zero-filled Some games have additional 64 header-like bytes at ROM Offset 40h..7Fh 40h 1 Program code/data in some carts, 00h or 01h in other carts 41h 63 Program code/data in some carts, 00h-filled in other carts The game cartridges don't use/need a Nintendo-like header at 7Fxxh/FFxxh, but some games like SDBATTLE SEVEN do have one. Sufami Turbo SRAM File Header (30h bytes) 0000h 15 ID "SFC-ADX BACKUP",0 ;Other = begin of free memory 000Fh 1 Zero 0010h 14 Title (same as 0010h..001Dh in ROM Header) 001Eh 1 Zero 001Fh 1 Zero (except, 01h in Poi Poi Ninja) 0020h 4 Unique ID and Index in Series (same as 0030h..0033h in ROM Header) 0024h 1 Filesize (in 2Kbyte units) (same as 0037h in ROM Header) 0025h 11 Zero-filled The BIOS file-functions are only reading entry 0000h (ID) and 0024h (Filesize), the BIOS doesn't write anything, all IDs and values must be filled-in by the game. SRAM is organized so that used 2Kbyte pages are at lower addresses, free pages at higher addresses (deleting a file in the middle will relocate any pages at higher addresses). Accordingly, files are always consisting of unfragmented continous page numbers (leaving apart that there are 32Kbyte gaps in the memory map). SNES Cart Sufami Turbo BIOS Functions & Charset ----------------------------------------------- Sufami Turbo BIOS Function Summary BIOS Function vectors (jmp 80xxxxh opcodes) are located at 80FF00h..80FF3Bh, (the first 12 (of the 15) functions are also duplicated at 80FF80h..80FFAFh). 80FF00 FillSramPages ;in: AL=num, AH=slot, XL=first, [09h]=fillword 80FF04 CopySramToSram ;in: AL=num, AH=direction, X/Y=first (slot A/B) 80FF08 CopySramToWram ;in: AL=num, AH=direction, X=first, Y=slot, [09h]=addr 80FF0C GetChar2bpp ;in: A=char(0000h..0FFFh), [06h]=dest_addr (64 bytes) 80FF10 GetChar4bpp ;in: A=char(0000h..0FFFh), [06h]=dest_addr (128 bytes) 80FF14 GetCartType ;out: AL/AH=Types for Slot A/B, b0=ROM, b1=SRAM, b2=? 80FF18 GetSramSize ;out: AL/AH=Sizes for Slot A/B, 0-4=0,2,8,32,128Kbyte 80FF1C FindFreeSram ;in: AL=slot, out: AL=first_free_page, FFh=none 80FF20 GetSramAddrTo6 ;in: AL=slot, XL=page, out: [06h]=addr 80FF24 GetSramAddrTo9 ;in: AL=slot, XL=page, out: [09h]=addr 80FF28 ShowHelpSwap ;display instructions how to exchange cartridges 80FF2C ShowHelpNoSwap ;display instructions how to remove cartridges 80FF30 DeleteFile ;in: AL=first, AH=slot 80FF34 TestSramId ;in: AL=page, AH=slot, out: CY: 0=Used, 1=Free 80FF38 SramToSramCopy ;in: AL=num, X=src, Y=dst; XH/YH=slot, XL/YL=first Whereas, num = number of 2Kbyte pages slot = slot (0 or 1 for slot A or B) first = first 2Kbyte page number (of a file/area) (within selected slot) page = single 2Kbyte page number (within selected slot) addr = 24bit SNES memory address AL/AH, XL/XH, YL/YH = LSB/MSB of A,X,Y registers The BIOS functions use first 16 bytes in WRAM [0000h..000Fh] for parameters, return values, and internal workspace; when using BIOS functions, don't use that memory for other purposes. [0000h] is NMI mode, don't change that even when NOT using BIOS functions. File/SRAM Functions These functions may be (not very) helpful for managing SRAM, they are extremly incomplete, there are no functions for creating files, or for searching specific files. See the "Header" chapter for details on SRAM headers (again, the BIOS doesn't create any headers or IDs, the game must fill-in all IDs, Titles, and other values on its own). Character Set The BIOS ROM contains 4096 characters (each 16x16 pixel, aka 2x2 tiles). The characters are stored at 1bit color depth in banks 04h..07h, offset 8000h-FFFFh (20h bytes/character). The GetChar2bpp and GetChat4bpp functions can be used to copy a selected character to WRAM, with bits in plane0, and the other plane(s) zerofilled. Help Functions The two help functions are showing some endless repeated japanese instructions about how to use, insert, remove, and exchange cartridges (similar to the instructions shown when booting the BIOS without Game cartridges inserted). If you have uploaded code to the APU, be sure to return control to the APU boot-rom, otherwise the help functions will hang. SNES Cart X-Band (2400 baud Modem) ---------------------------------- The X-Band is a 2400 baud modem from Catapult Entertainment Inc., licensed by Nintendo, originally released 1994 in USA, and 199x? in Japan. Aside from the SNES version, there have been also Genesis and Saturn versions. --> SNES Cart X-Band Misc --> SNES Cart X-Band I/O Map --> SNES Cart X-Band I/O - Memory Patch/Mapping --> SNES Cart X-Band I/O - Smart Card Reader --> SNES Cart X-Band I/O - LED and Debug --> SNES Cart X-Band I/O - Whatever Stuff (External FIFO for Modem?) --> SNES Cart X-Band I/O - Rockwell Modem Ports --> SNES Cart X-Band Rockwell Notes --> SNES Cart X-Band BIOS Functions --> SNES Controllers X-Band Keyboard Note There's also another modem (which connects to controller port): --> SNES Add-On SFC Modem (for JRA PAT) SNES Cart X-Band Misc --------------------- Info... It was used for networked gaming via phone lines. The Xband worked by sending controller instructions, by intercepting code from the game, and patching it with its own instructions, much like the Game Genie works. (that are, probably, two separate features messed into one sentence?) The system worked by dialing up the main server, which was located in Cupertino, California (USA), and somewhere else (Japan). The server then sent the Xband newsletters (called Bandwidth and Xband News). It also sent any patches that were needed. You could then search for opponents. Unknown Features There seems to be no CIC chip, so the BIOS does likewise work only with another SNES cart connected. There is switch, for whatever on/off/mode selection. There are three LEDs for whatever purpose. And, there is some kind of a credit-card (or so) reader. Memory Map D00000h-DFFFFFh 1MB ROM (executed here, not at C00000h-CFFFFFh) E00000h-E0FFFFh 64K SRAM (in two 32Kx8 chips) (unknown if BOTH have battery) FBC000h-FBC17Fh I/O Ports (unknown functions?) FBC180h-FBC1BFh I/O Ports (Rockwell Modem Chip) FBFC02h I/O Port (unknown functions?) FBFE00h I/O Port (unknown functions?) FFC000h I/O Port (unknown functions?) 004F02h I/O Port (unknown functions?) 00F000h Dummy/strobe read? 00FFE0h Dummy/strobe read? I/O Ports seem to be 8bit-wide / word-aligned (ie. one can use 8bit or 16bit writes, with the MSB ignored in the latter case). Normally ONLY the even addresses are used (some exceptions are: 8bit write 00h to FBC153h, 16bit write 0000h to FBC160h). Some of the I/O ports outside of the FBCxxxh region might belong to other hardware? (eg. the X-Band might automatically disable any Game Genie BIOS in order to access the Game ROM). Unknown 100pin Chip Unknown. Probably controls the cart reader, the cheat/patching feature, and maybe also memory & I/O mapping of the other chips. Games supported by the X-Band modem Doom + Ken Griffey Jr. Baseball ? (not listed in stats) Killer Instinct + Madden NFL '95 + Madden NFL '96 + Mortal Kombat II + Mortal Kombat 3 + NBA Jam TE + NHL '95 ? (not listed in stats) NHL '96 ? (not listed in stats) Super Mario Kart + Weaponlord + (listed in sf2dxb stats only) and, Kirby's Avalanche + Super Street Fighter II + The Legend of Zelda: A Link to the Past (secret maze game) + Super Mario World (chat function) "First of all, the Legend of Zelda wasn't the only cartridge that would activate the hidden maze game -- basically, any unsupported SNES cart would do it. I usually used Super Mario World." CZroe: "Zelda triggered the XBAND's built-in maze game (someone reported that their copy didn't work... Zelda 1.1?!). Mario World triggered the Chat function." CZroe: "This is how I identified that there was a second version of Killer Instinct long before it debuted on this site (all US Killer Instinct bundle SNES consoles would not work with the XBAND)." gainesvillefrank: "I remember XBAND tried this experimental use of Mario World after a while. If you dialed in to XBAND with Mario World in your SNES then it would treat the cartridge as a chat room." "The black switch on the side needs to be in the down position. Otherwise it passes through." Most of the above games, don't include any built-in Xband support, instead, Catapult reverse-engineered how they work, and patched them to work with the modem. Exceptions are Weaponlord (and Doom?), which were released with "modem support" (unknown what that means exactly... do they control modem I/O ports... interact with the modem BIOS... or are they patched the same way as other games, and the only difference is that the developers created the patches before releasing the game?) Note: The japanese BIOS does read the Game cartridge header several times (unlike the US version which reads it only once), basically there is no good reason for those multiple reads, but it might indicate the japanese version includes multiple patches built-in in ROM?) CODES/SECRETS (still working, even when offline) Maze mini-game Press Down(2), Left(2), Right, B at the main menu. Blockade mini-game (tron clone) Press Up(2), Left, Right, Left(2), Right, L at the main menu. Fish Pong mini-game Genesis only? Change Font To change the text font, enter these codes at the Player Select screen. Green and yellow font - Up, Up, Right, Right, Down, Down, Left Rainbow font - Left, Left, Up, Up, Right, Right, Down Searchlight font - Down, Down, Left, Left, Up, Up, Right Alternate screen Press Up, Up, Left, Right on the title screen. Screen Saver Press Left, Right, Down, Down, R at the "X-Mail" and "Newsletters" screens. SNES X-Band SRAM Dumps benner 3.26.97 (main character with most stats is lower-right) sf2dxb 4.30.97 luke2 3.1.97 contains stats (for played game titles; separately for each of the 4 player accounts), and the most recent bandwidth/newletter magazines, and x-mails. PCB "123-0002-16, Cyclone Rev 9, Catapult (C) 1995" Component List U1 28pin Winbond W24257S-70L (32Kx8 SRAM) U2 36pin X X, X BAND, X X, SNES US ROM 1.0.1 (BIOS ROM) U3 100pin FredIIH, H3A4D1049, 9511 Korea (with Hyundai logo) U4 68pin RC2324DPL, R6642-14, Rockwell 91, 9439 A49172-2, Mexico U5 6pin LITEON 4N25 (optocoupler) (near TN0) (back side) U6 28pin Winbond W24257S-70L (32Kx8 SRAM) U7 6pin AT&T LF1504 (solid state relay) (near TN0) (back side) BT0 2pin Battery (not installed) (component side) BT200 2pin Battery (3V Lithium Penata CR2430) (back side) SW1 3pin Two-position switch (purpose unknown... battery off ??) J0 10pin Card-reader (for credit cards or so?) 8 contacts, plus 2pin switch J1 62pin SNES Cartridge Edge (to be plugged into the SNES console) J2 62pin SNES Cartridge Slot (for game-cart plugged on top of the modem) J3 4/6pin RJ socket (to phone line) Y1 2pin Oscillator (R24AKBB4, =24MHz or so?) (back side) TN0 4pin Transformator (671-8001 MIDCOM C439) LEDs Three red LEDs (purpose/usage unknown?) PCB "123-0002-17, Catapult (C) 1995" Component List MODEM is "RC2424DPL, R6642-25, Rockwell 91, 9507 A61877.2, Hong Kong" PCB "123-0003-04, Tornado, Catapult (C) 1995" (Japan) SRAMs are "SEC KOREA, 550A, KM62256CLG-7L" BIOS is "X X 9549, X BAND, X X, SUPER FAMICOM, ROM1.0" FRED is "Catapult, FRED5S, 549D" (100pin) MODEM is "RC2424DPL, R6642-25, Rockwell 91, 9609 A62975-2, Mexico" Y1 is "A24.000" BT201 is "C?2032" (installed instead of bigger BT200) SNES Cart X-Band I/O Map ------------------------ Below I/O Map is based on source code of the Sega Genesis X-Band version (files i\harddef.a and i\feq.a). The I/O Map of the SNES version might differ in some places. default base addresses kDefaultInternal: equ ($1de000*2) ;;=3BC000h ;aka SNES: FBC000h kDefaultControl: equ ($1dff00*2) ;;=3BFE00h ;aka SNES: FBFE00h X-Band I/O Map Addr $nn*2 i\harddef.a i\feq.a ;Comment ---------------------------------------------------------------------------- C000h $00*2 kPatch_0_Byte0 - (lo?) ;Translation (Patch Addr) regs ... C002h $01*2 kPatch_0_Byte1 - (mid?) ;(aka "Vectors 0..10"?) C004h $02*2 kPatch_0_Byte2 - (hi?) C006h N/A - C008h $04*2 kPatch_1_Byte0 - C00Ah $05*2 kPatch_1_Byte1 - C00Ch $06*2 kPatch_1_Byte2 - C00Eh N/A - C010h $08*2 kPatch_2_Byte0 - C012h $09*2 kPatch_2_Byte1 - C014h $0A*2 kPatch_2_Byte2 - C016h N/A - C018h $0C*2 kPatch_3_Byte0 - C01Ah $0D*2 kPatch_3_Byte1 - C01Ch $0E*2 kPatch_3_Byte2 - C01Eh N/A - C020h $10*2 kPatch_4_Byte0 - C022h $11*2 kPatch_4_Byte1 - C024h $12*2 kPatch_4_Byte2 - C026h N/A - C028h $14*2 kPatch_5_Byte0 - C02Ah $15*2 kPatch_5_Byte1 - C02Ch $16*2 kPatch_5_Byte2 - C02Eh N/A - C030h $18*2 kPatch_6_Byte0 - C032h $19*2 kPatch_6_Byte1 - C034h $1A*2 kPatch_6_Byte2 - C036h N/A - C038h $1C*2 kPatch_7_Byte0 - C03Ah $1D*2 kPatch_7_Byte1 - C03Ch $1E*2 kPatch_7_Byte2 - C03Eh N/A - C040h $20*2 kPatch_8_Byte0 - C042h $21*2 kPatch_8_Byte1 - C044h $22*2 kPatch_8_Byte2 - C046h N/A - C048h $24*2 kPatch_9_Byte0 - C04Ah $25*2 kPatch_9_Byte1 - C04Ch $26*2 kPatch_9_Byte2 - C04Eh N/A - C050h $28*2 kPatch_10_Byte0 - C052h $29*2 kPatch_10_Byte1 - C054h $2A*2 kPatch_10_Byte2 - C056h N/A - C058h $2C*2 kRange0Start - C05Ah ""-mid? - C05Ch ""-hi? - C05Eh N/A - C060h $30*2 kRange1Start - C062h ""-mid? - C064h ""-hi? - C066h N/A - C068h N/A - C06Ah N/A - C06Ch N/A - C06Eh N/A - C070h $38*2 kMagicAddrByte0 kmagicl C072h $39*2 kMagicAddrByte1 kmagicm C074h $3A*2 kMagicAddrByte2 kmagich C076h N/A - C078h N/A - C07Ah N/A - C07Ch N/A - C07Eh N/A - C080h $40*2 kRange0End krangel C082h ""-mid? krangem C084h ""-hi? krangeh C086h N/A - C088h $44*2 kRange1End - C08Ah ""-mid? - C08Ch ""-hi? - C08Eh N/A - C090h N/A - C092h N/A - C094h N/A - C096h N/A - C098h N/A - C09Ah N/A - C09Ch N/A - C09Eh N/A - C0A0h $50*2 kRange0Dest ktrbl C0A2h ""-hi? ktrbh C0A4h $52*2 kRange0Mask ktrm C0A6h N/A - C0A8h $54*2 kRange1Dest - C0AAh ""-hi? - C0ACh $56*2 kRange1Mask - C0AEh N/A - C0B0h N/A - C0B2h N/A - C0B4h N/A - C0B6h N/A - C0B8h N/A - C0BAh N/A - C0BCh N/A - C0BEh N/A - C0C0h $60*2 kRAMBaseByte0 ksaferambasel C0C2h $61*2 kRAMBaseByte1 ksaferambaseh C0C4h N/A - C0C6h N/A - C0C8h $64*2 kRAMBoundByte0 ksaferambndl C0CAh $65*2 kRAMBoundByte1 ksaferambndh C0CCh N/A - C0CEh N/A - C0D0h $68*2 kVTableBaseByte0 kvtablel ;\vector table base address? C0D2h $69*2 kVTableBaseByte1 kvtableh ;/ (in 32-byte, or 32-word steps maybe?) C0D4h N/A - C0D6h N/A - C0D8h $6c*2 kEnableByte0 kenbll C0DAh $6d*2 kEnableByte1 kenblh C0DCh N/A - C0DEh N/A - C0E0h $70*2 kROMBound ksaferombnd C0E2h N/A - C0E4h N/A - C0E6h N/A - C0E8h $74*2 kROMBase ksaferombase C0EAh N/A - C0ECh N/A - C0EEh N/A - C0F0h N/A - ;<-- but this is used on SNES !?! C0F2h N/A - ;<-- but this is used on SNES !?! C0F4h N/A - C0F6h N/A - C0F8h $7c*2 kAddrStatus kaddrstatusl C0FAh ""-hi? kaddrstatush C0FCh N/A - C0FEh N/A - C100h $80*2 kSControl ksctl ;smart card control C102h N/A - C104h N/A - C106h N/A - C108h $84*2 kSStatus ksstatus ;smart card status C10Ah N/A - C10Ch N/A - C10Eh N/A - C110h $88*2 kReadMVSyncLow kreadmvsync ;<--Low? ;\Range of 0 to $61. C112h $89*2 kReadMVSyncHigh kreadmvsynclow ;<--low? ;/Equal to C114h N/A - ; ReadSerialVCnt/2. C116h N/A - ; Value is $5c at start C118h $8c*2 kMStatus1 kmstatus1 ; of VBlank. C11Ah N/A - C11Ch N/A - C11Eh N/A - C120h $90*2 kTxBuff ktxbuff ; modem (and serial) bits ... C122h N/A - C124h N/A - C126h N/A - C128h $94*2 kRxBuff krxbuff C12Ah N/A - C12Ch N/A - C12Eh N/A - C130h $98*2 kReadMStatus2 kreadmstatus2 C132h N/A - C134h N/A - C136h N/A - C138h $9c*2 kReadSerialVCnt kreadserialvcnt C13Ah N/A - C13Ch N/A - C13Eh N/A - C140h $a0*2 kReadMStatus1 kreadmstatus1 C142h N/A - C144h N/A - C146h N/A - C148h $a4*2 kGuard kguard C14Ah N/A - C14Ch N/A - C14Eh N/A - C150h $a8*2 kBCnt kbcnt C152h N/A - C154h N/A - C156h N/A - C158h $ac*2 kMStatus2 kmstatus2 C15Ah N/A - C15Ch N/A - C15Eh N/A - C160h $b0*2 kVSyncWrite kvsyncwrite C162h N/A - C164h N/A - C166h N/A - C168h $b4*2 kLEDData kleddata C16Ah $b5*2 kLEDEnable kledenable C16Ch N/A - C16Eh N/A - C170h N/A - C172h N/A - C174h N/A - C176h N/A - C178h N/A - C17Ah N/A - C17Ch N/A - C17Eh N/A - C180h $c0*2 kModem - ;<-- base for rockwell registers (C180h-C1BEh) FC02h N/A - ;<-- unknown, but this is used by SNES FE00h $00*2 kKillReg kkillhere ;same as killheresoft...trans register FE02h $01*2 kControlReg kreghere FF80h $c0*2 kKillHereSoft kkillheresoft ;\maybe some sort of mirrors of FF82h $c1*2 kCtlRegSoft kctlregsoft ;/FE00h and FE02h ? 617000h ? weirdness kSNESKillHereSoft ;\maybe some sort of mirrors of 617001h ? weirdness kSNESCtlRegSoft ;/FE00h and FE02h ? FFC000h I/O Port (unknown functions?) ;-bank FFh ;\ 004F02h I/O Port (unknown functions?) ;\ ; whatever, used 00F000h Dummy/strobe read? ; bank 00h ; by SNES version 00FFE0h Dummy/strobe read? ;/ ;/ SNES Cart X-Band I/O - Memory Patch/Mapping ------------------------------------------- FE00h - KillReg (aka killhere) ;same as killheresoft...trans register ;kill register bits ;aka "kKillReg" and/or "kKillHereSoft"? 0 HereAssert: equ $01 ; "Here" = cannot see cart 1 Unknown/unused 2 DecExcept: equ $04 ; 3 Force: equ $08 ; 4-7 Unknown/unused FE02h - ControlReg (aka reghere) ;control bits for control register ;aka "kControlReg"? and/or "kCtlRegSoft"? 0 EnTwoRam: equ $01 ;<-- maybe disable one of the two SRAMs? 1 EnSafeRom: equ $02 ;<-- maybe SRAM read-only? or FlashROM? 2 RomHi: equ $04 ; 3 EnInternal: equ $08 ;<-- maybe disable ports C000h..C1FFh? 4 EnFixedInternal: equ $10 ;<-- maybe whatever related to above? 5 EnSNESExcept: equ $20 ; 6-7 Unknown/unused FF80h - KillHereSoft (aka kkillheresoft) FF82h - CtlRegSoft (aka kctlregsoft) Unknown, maybe some sort of mirrors of FE00h and FE02h ? 617000h ? weirdness kSNESKillHereSoft 617001h ? weirdness kSNESCtlRegSoft Unknown, maybe some sort of mirrors of FE00h and FE02h ? Maybe non-Sega, SNES only stuff? Or maybe weird/ancient prototype stuff? C000h/C002h/C004h - Patch 0, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C008h/C00Ah/C00Ch - Patch 1, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C010h/C012h/C014h - Patch 2, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C018h/C01Ah/C01Ch - Patch 3, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C020h/C022h/C024h - Patch 4, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C028h/C02Ah/C02Ch - Patch 5, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C030h/C032h/C034h - Patch 6, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C038h/C03Ah/C03Ch - Patch 7, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C040h/C042h/C044h - Patch 8, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C048h/C04Ah/C04Ch - Patch 9, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) C050h/C052h/C054h - Patch 10, Byte0/Byte1/Byte2 (Lo/Mid/Hi?) aka "Vectors 0..10"? C070h/C072h/C074h - MagicAddr Byte0/1/2 (Lo/mid/hi) (aka magicl/m/h) 0-23 Unknown (also referred to as "transition address"?) C058h/C05Ah/C05Ch - Range0Start (Lo/mid/hi?) C060h/C062h/C064h - Range1Start (Lo/mid/hi?) C080h/C082h/C084h - Range0End (Lo/mid/hi) (aka rangel/m/h) C088h/C08Ah/C08Ch - Range1End (Lo/mid/hi?) 0-23 Unknown (maybe ROM start/end addresses for BIGGER patch regions?) C0A0h/C0A2h - Range0Dest (Lo/hi) (aka trbl/h) C0A8h/C0AAh - Range1Dest (Lo/hi?) 0-15 Unknown (maybe SRAM mapping target for above ROM ranges?) C0A4h - Range0Mask (aka trm) C0ACh - Range1Mask 0-7 Unknown C0D0h/C0D2h - VTableBase Byte0/1 (Lo/hi) (aka kvtablel/h) 0-15 Unknown (maybe SRAM mapping target for ROM patch vectors?) vector table base address? (in 32-byte, or 32-word steps maybe?) C0D8h/C0DAh - Enable Byte0/1 (Lo/hi) (aka enbll/h) 0-10 Vector 0-10 Enable (aka enable "kPatch_0..10"?) (?=off, ?=on) 11 range0ena 12 range1ena 13 unknown/unused 14 transAddrEnable aka magicena ;enable transition address 15 zeroPageEnable ;enable zero page <-- game cart access? C0C0h/C0C2h - RAMBase, Byte0/1 (Lo/hi) (aka saferambasel/h) 0-15 Unknown C0C8h/C0CAh - RAMBound Byte0/1 (Lo/hi) (aka saferambndl/h) 0-15 Unknown C0E0h - ROMBound (aka saferombnd) 0-7 Unknown C0E8h - ROMBase (aka saferombase) 0-7 Unknown C0F8h/C0FAh - AddrStatus (Lo/hi?) (aka addrstatusl/h) 0-15 Unknown SNES Cart X-Band I/O - Smart Card Reader ---------------------------------------- The X-Band contains a built-in Smart Card reader (credit card shaped chip cards with 8 gold contacts). The X-Band BIOS contains messages that refer to "XBand Cards" and "XBand Rental Cards". There aren't any photos (or other info) of these cards in the internet, maybe X-Band requested customers to return the cards, or the cards got lost for another reason. Purpose Not much known. Reportedly the card reader was used for Prepaid Cards (for users whom didn't want Xband to charge their credit cards automatically), if that is correct, then only those users would have received cards, and other users didn't need to use the card reader? Note: The Options/Account Info screen show entries "Account" and "Card". Smart Card I/O Ports The BIOS seems to be accessing the cards via these I/O ports: FBC100h Card Data/Control/Whatever (out) FBC108h.Bit0 (In) Card Switch (1=card inserted, 0=card missing) FBC108h.Bit1 (In) Card Data (input) Related BIOS functions are function 0380h..0386h (on SNES/US). C100h - SControl (aka sctl) ;smart card control 0 outputClk: equ $01 1 enOutputData:equ $02 ;aka data direction? 2 outputData: equ $04 3 outputReset: equ $08 4 outputVcc: equ $10 5-7 unknown/unused C108h - SStatus (aka sstatus) ;smart card status 0 detect: equ $01 Card Switch (1=card inserted, 0=card missing) 1 dataIn: equ $02 Card Data (input) 2 outputClk: equ $04 ;\ 3 enOutputData:equ $08 ; Current state of Port C100h.Bit0-4 ? 4 outputData: equ $10 ; 5 outputReset: equ $20 ; 6 outputVcc: equ $40 ;/ 7 outputVpp: equ $80 ;-Current state of Port ????.Bit0 ? ???? - Smart Card control ii parameters for control ii ;<-- from i\feq.a (uh, "control ii" is what?) 0 ksoutputvpp: equ $01 1-7 unknown/unused _______ _______ VCC C1 | | | C5 GND common smart card pinout |____ | ____| (unknown if xband is actually RST C2 | \__| / | C6 VPP using that same pinout) |____/ \____| CLK C3 | \_____/ | C7 I/O |____/ | \____| NC? C4 | | | C8 NC? |_______|_______| SNES Cart X-Band I/O - LED and Debug ------------------------------------ C168h - LEDData (aka leddata) 0-7 probably controls the LEDs (can be also used for other stuff) Note: Sega version has 7 LEDs, SNES version has only 3 LEDs. Unknown which of the 8 bits are controlling which LEDs. C16Ah - LEDEnable (aka ledenable) 0-7 seems to select data-direction for LED pins (0=input, 1=output) Debug Connection via LED ports People at Catapult have reportedly used modified X-Band PCBs during debugging: The seven genesis LEDs replaced by a DB25 connector with 8 wires (7 debug signals, plus GND, probably connected to a PC parallel/printer port). That hardware mod also used special software (some custom X-Band BIOS on FLASH/ROM, plus whatever software on PC side). Unknown 64bit Number via LED ports The SNES X-Band BIOS is reading a 64bit number via serial bus (which might connect to exteral debug hardware, or to 'unused' smart card pins, or to whatever), done via two I/O Ports: FBC168h Data ;bit2 (data, in/out) ;\there is maybe also a reset FBC16Ah Direction ;bit2 (0=input, 1=output) ;/flag, eventually in bit5 ? The sequence for reading the 64bits is somewhat like so: Data=Output(0), Delay (LOOPx01F4h) Data=Output(1), Delay (LOOPx01F4h) Data=Input wait until Data=1 or fail if timeout wait until Data=0 or fail if timeout wait until Data=1 or fail if timeout Delay (LOOPx02BCh) for i=1 to 4 Data=Output(0), Delay (NOPx8) Data=Output(1), Delay (NOPx8) Data=Input, Delay (LOOPx0050h) for i=1 to 4 Data=Output(0), Delay (NOPx8) Data=Output(1), Delay (LOOPx003Ch) Data=Input, Delay (LOOPx001Eh) Data=Input, Delay (LOOPx0064h) for i=0 to 63 Data=Output(1), Delay (NOPx8) Data=Input, Delay (LOOPx000Ah) key.bit(i)=Data, Delay (LOOPx004Bh) For the exact timings (Delays and other software overload), see the BIOS function (at D7BE78h). Before doing the above stuff, the BIOS initializes [FBC168h]=40h, [FBC16Ah]=FFh (this may be also required). The 64bit number is received LSB first, and stored in SRAM at 3FD8h-3FDFh. Whereas the last byte is a checksum across the first 7 bytes, calculated as so: sum=00h for i=0 to 55 if (sum.bit(0) xor key.bit(i))=1 then sum=sum/2 xor 8Ch else sum=sum/2 For example, if the 7 bytes are "testkey", then the 8th byte must be 2Fh. Or, another simplier example would be setting all 8 bytes to 00h. SNES Cart X-Band I/O - Whatever Stuff (External FIFO for Modem?) ---------------------------------------------------------------- Below is some additional modem stuff (additionally to the normal Rockwell Modem registers at C180h-C1BEh). The original source code refers to that extra stuff as "modem (and serial) bits". Purpose is unknown... Maybe the Rockwell Modem chip lacks internal FIFOs, so the VBlank handler could transfer max 60 bytes/second. As a workaround, the Fred chip might contain some sort of external FIFOs, allowing to send around 4 bytes per Vblank (which would gain 240 bytes/second, ie. gaining the full bandwidth of the 2400 baud modem). If so, then the Fred chip should be wired either to the Rockwell databus, or to the Rockwell serial bus. Despite of the possible FIFO feature, directly accessing the Rockwell RX/TX registers seems to be also supported. C118h - MStatus1 (aka mstatus1) 0 enModem 1 resetModem 2 bit_8 3 enstop 4 onestop 5 enparity 6 oddparity 7 break C120h - TxBuff (aka txbuff) C128h - RxBuff (aka rxbuff) Some TX/RX FIFOs? C130h - ReadMStatus2 (aka readmstatus2) 0 kRMrxready: rxready: equ $01 ;1 = have rx data, 0 = no data 1 kRMframeerr: ltchedframeerr: equ $02 2 kRMparityerr: ltchedparityerr: equ $04 3-4 kRMframecount: sfcnt: equ $18 6-7 unknown/unused Bit3-4 is a 2bit framecounter to tell whether a byte arrived this frame or a prev frame. It's a little wacky to use because unlike VCnt, there is no separate place to read it on Fred other than right here, sharing it with the FIFO. So, you must do the following: If there is data in the FIFO, framecount reflects the frame number of the oldest byte in the FIFO. If the FIFO is empty, however, it reflects the current frame number. Used carefullly (i.e. make sure rxready is 0 if you are using it for the current framecount), it should allow you to determine if a byte arrived in the current frame or up to 3 previous frames ago. C140h - ReadMStatus1 (aka readmstatus1) 0 txfull: equ $01 ; 1 = full, 0 = not full 1 txempty: equ $02 2 rxbreak: equ $04 3 overrun: equ $08 4-5 smartrxretry: equ $30 smartrxnumretry: equ $30 6-7 smarttxretry: equ $c0 smarttxnumretry: equ $c0 C148h - Guard (aka guard) 0-7 unknown C150h - BCnt (aka bcnt) 0-7 unknown (whatever... B control... or B counter?) C158h - MStatus2 (aka mstatus2) 0 ensmartrxretry: equ $1 ; 1 ensmarttxretry: equ $2 ; 2 smart: equ $4 ; 3 sync: equ $8 ; 4-7 unknown/unused C160h - VSyncWrite (aka vsyncwrite) 0-7 unknown Maybe the vsync/vblank handler must write here by software in order to reset to "V" counters? C110h - ReadMVSyncLow (aka readmvsync) ;<--Low? C112h - ReadMVSyncHigh (aka readmvsynclow) ;<--low? Range of 0 to $61. Equal to ReadSerialVCnt/2. Value is $5c at start of VBlank. C138h - ReadSerialVCnt (aka readserialvcnt) 0-7 some incrementing counter... ;i\feq.a: kreadserialvcnt ; top 8 bits of 20 bit counter tied to ; input clock, or it increments 1 each 4096 clks ; resets to zero at vblank ; at 24 mhz, each 170.667 usec ; in 1/60 sec, counts up to 97 ($61), so ; range is 0 to $61 (verified by observation) ;i\harddef.a: kReadSerialVCnt ; Top 8 bits of 19 bit counter tied to kFirstVCnt equ $5c ; input clock, i.e. it increments 1 each 2048 clks. kLastVCnt equ $5b ; At 24 MHz, each 85.333 usec kMaxVCnt equ $61 ; in 1/60 sec, counts up to 195 ($C3), so kMinVCnt equ $00 ; range is 0 to $C3 (not yet verified by testing) ; Value is about $B8 at start of vblank, counts up to $C3, ; wraps to 0. Note that ReadMVSyncHigh VCnt is equal ; ReadSerialVCnt/2. Note also that if there is no data ; in the read fifo, it appears that ReadSerialVCnt has ; the value of ReadMVSyncHigh (i.e. 1/2 the resolution) kVCntsPerModemBit: equ $5 ; 1 modem bit time is 1/2400 sec, or 417 usec ; 417/85.333 (1 VCnt) = 4.89, rounded up gives ; 5 VCnts per modem bit. Not that this refers ; to ReadSerialVCnt. kLinesPerModemBit: equ $7 ; 417/64 (1 horiz line time) = 6.51, rounded up ; gives 7 Lines per modem bit ; for rx: ; 1. read status until rxready ; 2. read serialVcnt <-- uhm, what/why? ; 3. read Rxbuff (reading rxbuff clears the full fifo entry) SNES Cart X-Band I/O - Rockwell Modem Ports ------------------------------------------- Below are the I/O Ports of the Rockwell chip. In the SNES, Rockwell registers 00h-1Fh are mapped to EVEN memory addresses at FBC180h-FBC1BEh. The chip used in the SNES supports data/voice modem functions (but not fax modem functions). FBC180h/FBC182h - 00h/01h - Receive Data Buffer 0-7 RBUFFER Received Data Buffer. Contains received byte of data 8 RXP Received Parity bit (or ninth data bit) 9-15 N/A Unused FBC184h/FBC186h - 02h/03h - Control 0-8 N/A Unused 9 GTE TX 1800Hz Guard Tone Enable (CCITT configuration only) 10 SDIS TX Scrambler Disable 11 ARC Automatic on-line Rate Change sequence Enable 12 N/A Unused 13 SPLIT Extended Overspeed TX/RX Split. Limit TX to basic overspeed rate 14 HDLC High Level HDLC Protocol Enable (in parallel data mode) 15 NRZIE Unknown (listed in datasheet without further description) FBC188h/FBC18Ah - 04h/05h - Control 0 CRFZ Carrier Recovery Freeze. Disable update of receiver's carrier recovery phase lock loop 1 AGCFZ AGC Freeze. Inhibit updating of receiver AGC 2 IFIX Eye Fix. Force EYEX and EYEY serial data to be rotated equalizer output 3 EQFZ Equalizer Freeze. Inhibit update of receiver's adaptive equalizer taps 4-5 N/A Unused 6 SWRES Software Reset. Reinitialize modem to its power turn-on state 7 EQRES Equalizer Reset. Reset receiver adaptive equalizer taps to zero 8 N/A Unused 9 TXVOC Transmit Voice. Enable sending of voice samples 10 RCEQ Receiver Compromise Equalizer Enable. Control insertion of receive passband digital compromise equalizer into receive path 11 CEQ(E) Compromise Equalizer Enable. Enable transmit passband digital compromise equalizer 12 TXSQ Transmitter Squelch. Disable transmission of energy 13-15 N/A Unused FBC18Ch/FBC18Eh - 06h/07h - Control 0,1 WDSZ Data Word Size, in asynchronous mode (5, 6, 7, or 8 bits) 2 STB Stop Bit Number (number of stop bits in async mode) 3 PEN Parity Enable (generate/check parity in async parallel data mode) 4,5 PARSL Parity Select (stuff/space/even/odd in async parallel data mode) 6 EXOS Extended Overspeed. Selects extended overspeed mode in async mode 7 BRKS Break Sequence. Send of continuous space in parallel async mode 8 ABORT HDLC Abort. Controls sending of continuous mark in HDLC mode 9 RA Relay A Activate. Activate RADRV output 10 RB Relay B Activate. Activate RBDVR output 11 L3ACT Loop 3 (Local Analog Loopback) Activate. Select connection of transmitter's analog output Internally to receiver's analog input 12 N/A Unused 13 L2ACT Loop 2 (Local Digital Loopback) Activate. Select connection of receiver's digital output Internally to transmitter's digital input (locally activated digital loopback) 14 RDL Remote Digital Loopback Request. Initiate a request for remote modem to go into digital loop-back 15 RDLE Remote Digital Loopback Response Enable. Enable modem to respond to remote modem's digital loopback request FBC190h/FBC192h - 08h/09h - Control 0 RTS Request to Send. Request transmitter to send data 1 RTRN Retrain. Send retrain-request or auto-rate-change to remote modem 2 N/A Unused 3 TRFZ Timing Recovery Freeze. Inhibit update of receiver's timing recovery algorithm 4 DDIS Descrambler Disable. Disable receiver's descrambler circuit 5 N/A Unused 6 TPDM Transmitter Parallel Data Mode. Select parallel/serial TX mode 7 ASYNC Asynchronous/Synchronous. Select sync/async data mode 8 SLEEP Sleep Mode. Enter SLEEP mode (wakeup upon pulse on RESET pin) 9 N/A Unused 10 DATA Data Mode. Select idle or data mode 11 LL Leased Line. Select leased line data mode or handshake mode 12 ORG Originate. Select originate or answer mode (see TONEC) 13 DTMF DTMF Dial Select. Select DTMF or Pulse dialing in dial mode 14 CC Controlled Carrier. Select controlled or constant carrier mode 15 NV25 Disable V.25 Answer Sequence (Data Modes), Disable Echo Suppressor Tone (Fax Modes). Disable transmitting of 2100Hz CCITT answer tone when a handshake sequence is initiated in a data mode or disables sending of echo suppressor tone in a fax mode FBC194h/FBC196h - 0Ah/0Bh - Status 0 CRCS CRC Sending. Sending status of 2-byte CRC in HDLC mode 1-7 N/A Unused 8 BEL1O3 Bell 103 Mark Frequency Detected. Status of 1270Hz Bell 103 mark 9 DTDET DTMF Digit Detected. Valid DTFM digit has been detected 10 PNSUC PN Success. Receiver has detected PN portion of training sequence 11 ATBELL Bell Answer Tone Detected. Detection status of 2225Hz answer tone 12 ATV25 V25 Answer Tone Detected. Detection status of 2100Hz answer tone 13 TONEC Tone Filter C Energy Detected. Status of 1650Hz or 980Hz (selected by ORG bit) FSK tone energy detection by Tone C bandpass filter in Tone Detector configuration 14 TONEB Tone Filter B Energy Detected. Status of 390Hz FSK tone energy detection by Tone B bandpass filter in Tone Detector configuration 15 TONEA Tone Filter A Energy Detected. Status of energy above threshold detection by Call Progress Monitor filter in Dial Configuration or 1300 Hz FSK tone energy detection by Tone A bandpass filter in Tone Detector configuration FBC198h/FBC19Ah - 0Ch/0Dh - Status 0-3 DTDIG Detected DTMF Digit. Hexadecimal code of detected DTMF digit 4-6 N/A Unused 7 EDET Early DTMF Detect. High group frequency of DTMF tone pair detected 8-9 N/A Unused 10 SADET Scrambled Alternating Ones Sequence Detected 11 U1DET Unscrambled Ones Sequence Detected 12 SCR1 Scrambled Ones Sequence Detected 13 S1DET S1 Sequence Detected 14 PNDET Unknown (listed in datasheet without further description) 15 N/A Unused FBC19Ch/FBC19Eh - 0Eh/0Fh - Status 0-2 SPEED Speed Indication. Data rate at completion of a connection 3 OE Overrun Error. Overrun status of Receiver Data Buffer (RBUFFER) 4 FE Framing Error. Framing error or detection of an ABORT sequence 5 PE Parity Error. Parity error status or bad CRC 6 BRKD Break Detected. Receipt status of continuous space 7 RTDET Retrain Detected. Detection status of a retrain request sequence 8 FLAGS Flag Sequence. Transmission status of Flag sequence in HDLC mode, or transmission of a constant mark in parallel asynchronous mode 9 SYNCD Unknown (listed in datasheet without further description) 10 TM Test Mode. Active status of selected test mode 11 RI Ring Indicator. Detection status of a valid ringing signal 12 DSR Data Set Ready. Data transfer state 13 CTS Clear to Send. Training sequence has been completed (see TPDM) 14 FED Fast Energy Detected. Energy above turn-on threshold is detected 15 RLSD Received Line Signal Detector (carrier and receipt of valid data) FBC1A0h/FBC1A2h - 10h/11h - Transmit Data Buffer 0-7 TBUFFER Transmitter Data Buffer. Byte to be sent in parallel mode 8 TXP Transmit Parity Bit (or 9th Data Bit) 9-15 N/A Unused FBC1A4h/FBC1A6h - 12h/13h - Control 0-7 CONF Modem Configuration Select. Modem operating mode (see below) 8-9 TXCLK Transmit Clock Select (internal, disable, slave, or external) 10-11 VOL Volume Control. Speaker volume (off, low, medium, high) 12-15 TLVL Transmit Level Attenuation Select. Select transmitter analog output level attenuation in 1 dB steps. The host can fine tune transmit level to a value lying within a 1 dB step in DSP RAM FBC1A8h/FBC1AAh - 14h/15h - Unused 0-15 N/A Unused FBC1ACh/FBC1AEh - 16h/17h - Y-RAM Data (16bit) FBC1B0h/FBC1B2h - 18h/19h - X-RAM Data (16bit) 0-15 DATA RAM data word (R/W) FBC1B4h/FBC1B6h - 1Ah/1Bh - Y-RAM Addresss/Control FBC1B8h/FBC1BAh - 1Ch/1Dh - X-RAM Addresss/Control 0-8 ADDR RAM Address 9 WT RAM Write (controls read/write direction for RAM Data registers) 10 CRD RAM Continuous Read. Enables read of RAM every sample from location addressed by ADDR Independent of ACC and WT bits 11 IOX X-RAM only: I/O Register Select. Specifies that X RAM ADDRESS bit0-7 (Port 1Ch) is an internal I/O register address 11 N/A Y-RAM only: Unused 12-14 N/A Unused 15 ACC RAM Access Enable. Controls DSP access of RAM associated with address ADDR bits. WT determines if a read or write is performed FBC1BCh/FBC1BEh - 1Eh/1Fh - Interrupt Handling 0 RDBF Receiver Data Buffer Full (RBUFFER Full) 1 N/A Unused 2 RDBIE Receiver Data Buffer Full Interrupt Enable 3 TDBE Transmitter Data Buffer Empty (TBUFFER Empty) 4 N/A Unused 5 TDBIE Transmitter Data Buffer Empty Interrupt 6 RDBIA Receiver Data Buffer Full Interrupt Active (IRQ Flag) 7 TDBIA Transmitter Data Buffer Empty Interrupt Active (IRQ Flag) 8 NEWC New Configuration. Initiates new configuration (cleared by modem 9 N/A Unused upon completion of configuration change) 10 NCIE New Configuration Interrupt Enable 11 NEWS New Status. Detection of a change in selected status bits 12 NSIE New Status Interrupt Enable 13 N/A Unused 14 NCIA New Configuration Interrupt Active (IRQ Flag) 15 NSIA New Status Interrupt Active (IRQ Flag) CONF Values Below are CONF values taken from RC96DT/RC144DT datasheet (the RC96V24DP/RC2324DPL datasheet doesn't describe CONF values). Anyways, the values hopefully same for both chip versions (except that, the higher baudrates obviously won't work on older chips). CONF Bits/sec Mode Name 01h 2400 V.27 ter 02h 4800 V.27 ter 11h 4800 V.29 12h 7200 V.29 14h 9600 V.29 52h 1200 V.22 51h 600 V.22 60h 0-300 Bell 103 62h 1200 Bell 212A 70h - V.32 bis/V.23 clear down ;\ 71h 4800 V.32 ; 72h 12000 V.32 bis TCM ; RC96DT/RC144DT only 74h 9600 V.32 TCM ; (not RC96V24DP/RC2324DPL) 75h 9600 V.32 ; 76h 14400 V.32 bis TCM ; 78h 7200 V.32 bis TCM ;/ 80h - Transmit Single Tone 81h - Dialing ;used by SNES X-Band (dial mode) 82h 1200 V.22 bis 83h - Transmit Dual Tone 84h 2400 V.22 bis ;used by SNES X-Band (normal mode) 86h - DTMF Receiver A0h 0-300 V.21 A1h 75/1200 V.23 (TX/RX) A4h 1200/75 V.23 (TX/RX) A8h 300 V.21 channel 2 B1h 14400 V.17 TCM ;\ B2h 12000 V.17 TCM ; RC96DT/RC144DT only B4h 9600 V.17 TCM ; (not RC96V24DP/RC2324DPL) B8h 7200 V.17 TCM ;/ XBand X/Y RAM Rockwell Below are X/Y RAM addresses that can be accessed via Ports 16h-1Dh. Addresses 000h-0FFh are "Data RAM", 100h-1FFh are "Coefficient RAM". X-RAM is "Real RAM", Y-RAM is "Imaginary RAM" (whatever that means). XRAM YRAM Parameter 032 - Turn-on Threshold 03C - Lower Part of Phase Error (this, in X RAM ?) - 03C Upper Part of Phase Error (this, in Y RAM ?) - 03D Rotation Angle for Carrier Recovery 03F - Max AGC Gain Word 049 049 Rotated Error, Real/Imaginary 059 059 Rotated Equalizer Output, Real/Imaginary 05E 05E Real/Imaginary Part of Error 06C - Tone 1 Angle Increment Per Sample (TXDPHI1) 06D - Tone 2 Angle Increment Per Sample (TXDPHI2) 06E - Tone 1 Amplitude (TXAMP1) 06F - Tone 2 Amplitude (TXAMP2) 070 - Transmit Level Output Attenuation 071 - Pulse Dial Interdigit Time 072 - Pulse Dial Relay Make Time 073 - Max Samples Per Ring Frequency Period (RDMAXP) 074 - Min Samples Per Ring Frequency Period (RDMINP) 07C - Tone Dial Interdigit Time 07D - Pulse Dial Relay Break Time 07E - DTMF Duration 110-11E 100-11E Adaptive Equalizer Coefficients, Real/Imag. 110 100 First coefficient, Real/Imag. (1) (Data/Fax) 110 110 Last Coefficient, Real/Imag. (17) (Data) 11E 11E Last Coefficient, Real/Imag. (31) (Fax) - 121 RLSD Turn-off Time 12D - Phase Error 12E - Average Power 12F - Tone Power (TONEA) 130 - Tone Power (TONEB,ATBELL,BEL103) 131 - Tone Power (TONEC,ATV25) 136 - Tone Detect Threshold for TONEA (THDA) 137 - Tone Detect Threshold for TONEB,ATBELL,BEL103 (THDB) 138 - Tone Detect Threshold for TONEC,ATV25 (THDC) 13E - Lower Part of AGC Gain Word 13F - Upper Part of AGC Gain Word 152 - Eye Quality Monitor (EQM) - 162-166 Biquad 5 Coefficients a0,a1,a2,b1,b2 - 167-16B Biquad 6 Coefficients a0,a1,a2,b1,b2 - 16C-170 Biquad 1 Coefficients a0,a1,a2,b1,b2 - 171-175 Biquad 2 Coefficients a0,a1,a2,b1,b2 - 176-17A Biquad 3 Coefficients a0,a1,a2,b1,b2 179 - Turn-off Threshold - 17B-17F Biquad 4 Coefficients a0,a1,a2,b1,b2 SNES Cart X-Band Rockwell Notes ------------------------------- Rockwell Configuration Changes Various changes (to ASYNC, WDSZ, etc.) seem to be not immediately applied. Instead, one must apply them by setting NEWC=1 by software (and then wait until hardware sets NEWC=0). Rockwell Dialing Dialing is done by setting CONF=81h, and then writing the telephone number digits (range 00h..09h) to TBUFFER; before each digit wait for TDBE=1 (TX buffer empty), the BIOS also checks for TONEA=1 before dialing. The telephone number for the X-Band server is stored as ASCII string in the BIOS ROM: "18002071194" at D819A0h in US-BIOS (leading "800" = Toll-free?) "03-55703001" at CE0AB2h in Japanese BIOS (leading "3" = Tokyo?) Notes: Before dialing the above 'ASCII' numbers, the US-BIOS first dials 0Ah,07h,00h, and the japanese one first dials 01h. The "-" dash in the japanese string isn't dialed. Rockwell Offline There seems to be no explicit offline mode (in CONF register). Instead, one must probably change the Relay A/B bits (RA/RB) to go online/offline. X-Band Fred Chip Pin-Outs 1-100 unknown X-Band Rockwell Pin-Outs Pin Number Signal Name I/O Type 1 RS2 IA 2 RS1 IA 3 RS0 IA 4 /TEST1 5 /SLEEP OA 6 RING 7 EYEY OB 8 EYEX OB 9 EYESYNC OB 10 RESET ID 11 XTLI IE 12 XTLO OB 13 +5VD 14 GP18 OA 15 GP16 OA 16 XTCLK IA 17 DGND1 18 TXD IA 19 TDCLK OA 20 TRSTO MI 21 TSTBO MI 22 TDACO MI 23 RADCI MI 24 RAGCO MI 25 MODEO MI 26 RSTBO MI 27 RRSTO MI 28 /RDCLK OA 29 RXD OA 30 TXA2 O(DD) 31 TXA1 O(DD) 32 RXA I(DA) 33 RFILO MI 34 AGCIN MI 35 VC 36 NC 37 NC 38 NC 39 /RBDVR OD 40 AGND 41 /RADRV OD 42 /SLEEP1 IA 43 RAGCI MI 44 NC 45 RSTBI MI 46 RRSTI MI 47 RADCO MI 48 TDACI MI 49 TRSTI MI 50 TSTBI MI 51 MODE1 MI 52 +5VA 53 SPKR O(OF) 54 DGND2 55 D7 IA/OB 56 D6 IA/OB 57 D5 IA/OB 58 D4 IA/OB 59 D3 IA/OB 60 D2 IA/OB 61 D1 IA/OB 62 D0 IA/OB 63 /IRQ OC 64 /WRITE IA 65 /CS IA 66 /READ IA 67 RS4 IA 68 RS3 IA Notes: (1) MI = Modem Interconnection (2) NC = No connection (may have internal connection; leave pin disconnected (open). (3) I/O types are described in Table 2-3 (digital signals) and Table 2-4 (analog signals). SNES Cart X-Band BIOS Functions ------------------------------- X-Band BIOS Functions (CALL E00040h) Invoked via CALL E00040h, with X=function_number (0001h..054xh on SNES/US), with parameters pushed on stack, and with return value in A register (16bit) or X:A register pair (32bit), and with zeroflag matched to the A return value. The function table isn't initialized by the compiler/linker, instead, the BIOS boot code is starting the separate components (such like "controls.c"), which are then installing their function set via calls to "SetDispatchedFunction". The Sega function numbers are based on the string list in file "SegaServer\Server\Server_OSNumbers.h" (which is part of the SERVER sources, but it does hopefully contain up to date info on the retail BIOS functions). Sega SNES SNES Function Gen. US JP Sourceless - Misc 000h RestoreSegaOS 001h AskForReplay 002h ThankYouScreen ;thankyou shown at next coldboot? 003h InstallDispatchedManager 004h CallManagerControl 005h SoftInitOS 006h GetDispatchedFunction 007h 007h 007h SetDispatchedFunction ;change/install BIOS function vector 008h SetDispatchedGroup 009h GetManagerGlobals 00Ah SetManagerGlobals 00Bh AllocateGlobalSpace 00Ch FreeGlobalSpace 00Dh DisposePatch 00Eh CompactOSCodeHeap 00Fh GetPatchVersion 010h SetPatchVersion Sourceless - Memory 011h InitHeap 012h NewMemory 013h NewMemoryHigh 014h NewMemoryClear 015h DisposeMemory 016h 01Ah 01Ah GetMemorySize ;get size of an item 017h MaxFreeMemory 018h TotalFreeMemory 019h SwitchPermHeap 01Ah SwtichTempHeap ;uh, Swtich? 01Bh CreateTempHeap 01Ch CreateHeapFromPtr 01Dh CreateTempSubHeap 01Eh AllocPermHeapZone 01Fh DisposePermHeapZone 020h CompactHeap 021h MoveHeap 022h PrepareHeapForMove 023h ComputeHeapPtrDelta 024h ResizeHeap 025h BlockMove 026h WhichMemory 027h GetHeapSize 028h VerifySegaHeap 029h PurgePermHeaps 02Ah ByteCopy 02Bh UnpackBytes 02Ch FillMemory 02Dh GetCurrentHeap 02Eh FindLastAllocatedBlock 02Fh SetOSUnstable 030h SetDBUnstable 031h SetAddressUnstable 032h InstallReliableAddress 033h CheckOSReliable GameLib\controls.c - Keyboard/Joypad Controls 034h ? InitControllers 035h 033h ReadHardwareController ;get joypad data 036h 034h ControllerVBL ;do joypad and keyboard scanning 037h ? ReadAllControllers 038h 036h FlushHardwareKeyboardBuffer ;flush char_queue 039h 037h GetNextHardwareKeyboardChar ;read char_queue 03Ah 038h GetHardwareKeyboardFlags 03Bh 039h SetHardwareKeyboardFlags 03Ch 03Ah GetNextESKeyboardRawcode ;read scancode_queue ;ES=Eric Smith 03Dh ? GetNextESKeyboardStatus 03Eh 03Ch GetNextESKeyboardChar ;read scancode_queue, xlat to char 03Fh ? SendCmdToESKeyboard - 03Eh 03Fh keyb_io_read_scancodes - 03Fh keyb_blah_do_nothing - 040h keyb_io_read_verify_id_code - 041h 043h keyb_forward_scancode_queue_to_char_queue Sourceless - Misc 040h GetGlobal 041h SetGlobal Database\PatchDB.c - Game/Patch (SNES: installed at D6:4F93 ?) 042h 042h 044h AddGamePatch 043h LoadGamePatch 044h DisposeGamePatch 045h GetGamePatchVersion 046h GetGamePatchFlags 047h 04Ah 04Eh FindGamePatch 048h 054h 058h CreateGameDispatcher 049h InitGamePatch 04Ah StartGame 04Bh GameOver 04Ch ResumeGame 04Dh GameDoDialog 04Eh UpdateGameResultsAfterError 04Fh HandleGameError 050h PlayCurrentGame 051h 053h 057h InstallGameFunction 052h 055h 059h DisposeOldestGamePatch 053h MarkGamePatchUsed Sourceless - Messages 054h InitMessages 055h ProcessServerData 056h ProcessPeerData 057h SendMessage 058h GetSendMessageHandler 059h GetPeerMessageHandler 05Ah GetSerialOpCode 05Bh GetServerMessageHandler 05Ch InstallPeerHandler 05Dh InstallReceiveServerHandler 05Eh InstallSendMessageHandler 05Fh ReceivePeerMessageDispatch 060h ReceiveServerMessageDispatch 061h GobbleMessage 062h SetClearLoginMisc 063h GetLoginMisc Graphics\Sprites.c 064h CreateSprite 065h CreateSpriteInFront 066h CreateSpriteHigh 067h DisposeSprite 068h MoveSprite 069h DrawSprite 06Ah IncrementSpriteFrame 06Bh SetSpriteFrame 06Ch GetSpriteFrame 06Dh FlipSprite 06Eh CreateSpriteData 06Fh CreateTextSprite 070h CreateTextSpriteFromBitmap 071h ExplodeSprite 072h SetSpriteGrayFlag 073h SetSpriteTilePosition 074h SetSpriteImage 075h SetSpritePalette 076h WriteSpriteToVDP 077h FigureTileSize 078h AllocateSprite 079h FreeSprite 07Ah GetSpriteLastTile 07Bh GetSpriteFirstTile 07Ch NewSpark 07Dh DisposeSpark 07Eh GetSparkSprite 07Fh StartSpark 080h StopSpark 081h DrawXBandLogo 082h DisposeXBandLogoRef 083h DisposeXBandLogoSparks 084h SyncOTron Graphics\Decompress.c 085h InitDecompression 086h CreateDecompressor 087h DisposeDecompressor 088h SetDstPattern 089h SetImageTiling 08Ah SetImageOrigin 08Bh GetImageClut 08Ch DisposeImagePatterns 08Dh DecompressFrame 08Eh SetDecompressorOptionsSelector 08Fh SetDecompressorPixelMappingSelector 090h SetDecompressorPaletteSelector 091h GetDictionaryCache 092h ReleaseDictionaryCache 093h SetDecompressorImage 094h ExpandPatternDictionary 095h GetDecompressorCache 096h ReleaseDecompressorCache 097h JoshDecompress Sourceless - Time... 098h AddTimeRequest 099h RemoveTimeRequest 09Ah TimeIdle 09Bh IncCurrentTime 09Ch DelayMS 09Dh DelayTicks 09Eh SetOSIdle 09Fh SegaOSIdle 0A0h GetJesusTime 0A1h SetJesusTime 0A2h GetJesusDate 0A3h SetJesusDate Graphics\animation.c - Animations 0A4h InitAnimateProcs 0A5h SpawnAnimation 0A6h SpawnDBAnimation 0A7h CreateAnimation 0A8h DisposeAnimation 0A9h DrawAnimationFrame 0AAh StartAnimation 0ABh StopAnimation 0ACh SuspendAnimations 0ADh SetAnimationPriority 0AEh SetAnimationGrayFlag 0AFh GetAnimationSuspendLevel Graphics\paths.c - Paths (and maybe also LinePath.c?) 0B0h InitPathManager 0B1h CreatePath 0B2h DisposePath 0B3h SetPathPoints 0B4h SetPathFrames 0B5h SetPathVelocity 0B6h GetPathPoint 0B7h DistBetweenPoints Graphics\Pattern.c 0B8h InitPatternManager 0B9h NewPatternBlock 0BAh NewPatternBlockHigh 0BBh FreePatternBlock 0BCh DeallocateTopPatternBlock 0BDh NewFirstPatternBlock 0BEh SetRange 0BFh ClearRange 0C0h RangeIsFree 0C1h FindFreeRange 0C2h GetLeftOnesTable 0C3h GetRightOnesTable Graphics\Cursor.c 0C4h CreateSegaCursor 0C5h DisposeSegaCursor 0C6h MoveSegaCursor 0C7h HideSegaCursor 0C8h ShowSegaCursor 0C9h GetSegaCursorPos 0CAh SetSegaCursorImage 0CBh LoadCursorFromVRAM 0CCh DrawSegaCursor 0CDh LoadCursorPattern Graphics\SegaText.c (1) 0CEh InitSegaFonts 0CFh SetCurFont 0D0h GetCurFont 0D1h GetCurFontHeight 0D2h GetCurFontLineHeight 0D3h SetFontColors 0D4h GetFontColors 0D5h SetupTextGDevice 0D6h GetTextPatternAddress 0D7h GetTextGDeviceOrigin 0D8h DrawSegaString 0D9h RenderSegaString 0DAh MeasureSegaText 0DBh CenterSegaText 0DCh DrawClippedSegaText 0DDh DrawCenteredClippedSegaText 0DEh DrawPaddedClippedSegaText 0DFh GetCharWidth 0E0h SegaNumToString 0E1h SegaNumToDate 0E2h SegaAppendText 0E3h CompareDates 0E4h CompareStrings 0E5h SetupTextSpriteGDevice 0E6h EraseTextGDevice 0E7h GetStringLength Graphics\SegaText.c (2) and Database\StringDB.c 0E8h DrawDBXYString ;Database\StringDB.c 0E9h GetDBXYString ;Database\StringDB.c 0EAh GetSegaString ;Database\StringDB.c 0EBh GetWriteableString ;Database\StringDB.c 0ECh SetWriteableString ;Database\StringDB.c 0EDh DeleteWriteableString ;Database\StringDB.c 0EEh GetUniqueWriteableStringID ;Database\StringDB.c - AddDBXYString ;Database\StringDB.c (simulator) Graphics\SegaText.c (3) 0EFh CopyCString 0F0h SetTextPatternStart 0F1h EqualCStrings 0F2h GetTextStateReference 0F3h SaveTextState 0F4h RestoreTextState 0F5h DisposeTextStateReference 0F6h VDPCopyBlitDirect 0F7h VDPCopyBlitDirectBGColor 0F8h VDPCopyBlitTiled 0F9h VDPCopyBlitTiledBGColor 0FAh OrBlit2to4 0FBh OrBlit1to4 Sourceless - Modem? (parts related to GameLib\CommManager.c?) 0FCh PInit 0FDh POpen 0FEh PListen 0FFh POpenAsync 100h PListenAsync 101h PClose 102h PNetIdle 103h PCheckError 104h PWritePacketSync 105h PWritePacketASync 106h PGetError 107h PUOpenPort 108h PUClosePort 109h PUProcessIdle 10Ah PUProcessSTIdle 10Bh PUReadSerialByte 10Ch PUWriteSerialByte 10Dh PUTransmitBufferFree 10Eh PUReceiveBufferAvail 10Fh PUTestForConnection 110h PUReadTimeCallback 111h PUWriteTimeCallback 112h PUSetupServerTalk 113h PUTearDownServerTalk 114h PUSetError 115h PUIsNumberBusy 116h PUOriginateAsync 117h PUAnstondet 118h PUWaitForRLSD 119h PUInitCallProgress 11Ah PUCallProgress 11Bh PUDialNumber 11Ch PUWaitDialTone 11Dh PUAnswerAsync 11Eh PUCheckAnswer 11Fh PUCheckRing 120h PUResetModem 121h PUSetTimerTicks 122h PUSetTimerSecs 123h PUTimerExpired 124h PUHangUp 125h PUPickUp 126h PUWriteXRAM 127h PUWriteYRAM 128h 13Dh PUReadXRAM 129h 13Eh PUReadYRAM 12Ah PUIdleMode 12Bh PUDataMode 12Ch PUDialMode 12Dh PUToneMode 12Eh PUCheckLine 12Fh PUCheckCarrier 130h PUDetectLineNoise 131h PUListenToLine 132h PUDisableCallWaiting 133h PUAsyncReadDispatch 134h PUDoSelectorLogin 135h PUMatchString 136h PGetDebugChatScript Sourceless - Transport? 137h TInit 138h TOpen 139h TListen 13Ah TOpenAsync 13Bh TListenAsync 13Ch TClose 13Dh TCloseAsync 13Eh TUnthread 13Fh TNetIdle 140h TUCheckTimers 141h TReadDataSync 142h TReadDataASync 143h TWriteDataSync 144h TWriteDataASync 145h TAsyncWriteFifoData 146h TReadData 147h TWriteData 148h TReadAByte 149h TWriteAByte 14Ah TQueueAByte 14Bh TReadBytesReady 14Ch TDataReady 14Dh TDataReadySess 14Eh TIndication 14Fh TForwardReset 150h TNetError 151h TCheckError 152h TUInitSessRec 153h TUSendCtl 154h TUDoSendCtl 155h TUDoSendOpenCtl 156h TUUpdateSessionInfo 157h TUSendOpen 158h TUSendOpenAck 159h TUSendCloseAdv 15Ah TUSendFwdReset 15Bh TUSendFwdResetAck 15Ch TUSendFwdResetPacket 15Dh TUSendRetransAdv 15Eh TUOpenDialogPacket 15Fh TUFwdResetPacket 160h TUCloseConnPacket 161h TURetransAdvPacket 162h TUAllowConnection 163h TUDenyConnection 164h TUSetError 165h TUGetError 166h TGetUserRef 167h TSetUserRef 168h TGetTransportHold 169h TGetTransportHoldSession 16Ah TSetTransportHold 16Bh TSetTransportHoldSession Database\DB.c - Database 16Ch InitPermDatabase 16Dh CompactPermDatabase 16Eh 185h DBGetItem 16Fh DBAddItem 170h 188h 19Bh DBDeleteItem 171h 189h 19Ch DBGetUniqueID 172h DBGetUniqueIDInRange 173h DBGetItemSize 174h DBCountItems 175h 18Dh DBGetFirstItemID 176h 18Eh DBGetNextItemID 177h DBNewItemType 178h DBGetTypeFlags 179h DBSetTypeFlags 17Ah DBDeleteItemType 17Bh DBPurge 17Ch DBTypeChanged 17Dh ComputeTypeCheckSum 17Eh DBVerifyDatabase 17Fh DBROMSwitch 180h DBAddItemPtrSize 181h 199h 1ACh DBAddItemHighPtrSize 182h 19Ah 1ADh DBPreflight ;check if enough free mem for new item 183h GetItemSize 184h DBGetTypeNode 185h DBGetPrevTypeNode 186h DBTNGetItem 187h DBTNGetPrevItem 188h DBTNDisposeList 189h DeleteItem 18Ah AddItemToDB 18Bh AllowDBItemPurge Graphics\SegaScrn.c - Video/Screen 18Ch LinearizeScreenArea 18Dh GetSegaScreenBaseAddr 18Eh InitSegaGDevices 18Fh SetCurrentDevice 190h GetCurrentDevice 191h RequestClut 192h ReleaseClut 193h IncrementClutReferences 194h SetupClutDB 195h GetSegaScreenOrigin 196h GetSegaGDevice 197h EraseGDevice 198h SetupVDP 199h BlankClut 19Ah FadeInClut 19Bh FadeInScreen 19Ch GenerateGrayMap 19Dh WaitVBlank 19Eh SetBackgroundColor 19Fh GetBackgroundColor 1A0h RequestUniqueClut 1A1h RequestSpecificClut 1A2h SetupClut 1A3h GetClut 1A4h GetColorLuminance 1A5h FillNameTable Sourceless - VRAM... 1A6h DMAToVRAM 1A7h CopyToVRAM 1A8h CopyToCRAM 1A9h CopyToVSRAM 1AAh CopyToVMap 1ABh FillVRAM 1ACh FillCRAM 1ADh FillVSRAM Database\Opponent.c - Opponent 1AEh GetOpponentPhoneNumber 1AFh SetOpponentPhoneNumber 1B0h GetCurOpponentIdentification 1B1h SetCurOpponentIdentification 1B2h GetCurOpponentTaunt 1B3h GetCurOpponentInfo 1B4h ClearOldOpponent 1B5h GetOpponentVerificationTag 1B6h SetOpponentVerificationTag Database\UsrConfg.c - User/Password 1B7h GetCurrentLocalUser 1B8h FillInUserIdentification 1B9h GetLocalUserTaunt 1BAh SetLocalUserTaunt 1BBh GetLocalUserInfo 1BCh SetLocalUserInfo 1BDh IsUserValidated 1BEh SetCurUserID 1BFh GetCurUserID 1C0h VerifyPlayerPassword 1C1h IsEmptyPassword 1C2h ComparePassword 1C3h GetPlayerPassword UserInterface\DitlMgr.c - DITL (also related to Database\DITLItemSetup.c?) 1C4h NewDITL 1C5h GiveDITLTime 1C6h DisposeDITL 1C7h GetDITLItem 1C8h InitDITLMgr 1C9h ClearDITLDone 1CAh ProcessDITLScreen 1CBh SetupDITLItemList 1CCh SetupDITLObjectData 1CDh DisposeDITLItemList 1CEh SetupControlTable 1CFh DisposeControlTable 1D0h GetDITLObjectData UserInterface\Events.c 1D1h InitUserEvents 1D2h FlushUserEvents 1D3h WaitForUserButtonPress 1D4h CheckUserButtonPress 1D5h GetNextControllerEvent 1D6h GetNextCommand 1D7h QueueGet 1D8h QueueInsert Sourceless - Sound 1D9h SetBGMDisable 1DAh GetBGMDisable 1DBh InitSoundMgr 1DCh ShutDownSoundMgr 1DDh StartDBBGM 1DEh StopBGM 1DFh PlayDBFX 1E0h FX1NoteOff 1E1h FX2NoteOff 1E2h ShutUpFXVoice1 1E3h ShutUpFXVoice2 Sourceless - Misc 1E4h GetDataSync 1E5h GetDataBytesReady 1E6h GetDataError Database\Challnge.c - Challenge 1E7h GetChallengePhoneNumber 1E8h SetChallengePhoneNumber 1E9h GetChallengeIdentification 1EAh SetChallengeIdentification Database\GameID.c - Game ID 1EBh 210h 224h GetGameID ;out:A=SnesCartStandardChksum, X=SnesHeaderCCITT - 211h 225h ... related to GameID ? Sourceless - Misc 1ECh IsRemoteModemTryingToConnect 1EDh SetRemoteModemTryingToConnectState 1EEh InitScreen 1EFh PreflightScreen 1F0h SetupScreen 1F1h SendCommandToScreen 1F2h KillScreen 1F3h GetNewScreenIdentifier 1F4h GetCurScreenIdentifier 1F5h GetScreenStateTable 1F6h ResetCurrentScreen 1F7h GetScreenLayoutRectangleCount 1F8h GetScreenLayoutRect 1F9h GetScreenLayoutCharRect 1FAh GetScreenLayoutPointCount 1FBh GetScreenLayoutPoint 1FCh GetScreenLayoutStringCount 1FDh GetScreenLayoutString 1FEh DrawScreenLayoutString 1FFh BoxScreenLayoutString 200h GetScreensEnteredCount Graphics\Backdrops.c 201h SetBackdropID 202h SetBackdropBitmap 203h ClearBackdrop 204h HideBackdrop 205h SetAuxBackgroundGraphic 206h ShowBackdrop 207h GetBlinkySprite Database\BoxSer.c (1) 208h GetBoxSerialNumber 209h SetBoxSerialNumber 20Ah GetHiddenBoxSerialNumbers 20Bh GetBoxHometown 20Ch SetBoxHometown 20Dh SetBoxState 20Eh ResetBoxState 20Fh GetBoxState 210h SetLastBoxState 211h ResetLastBoxState 212h GetLastBoxState 213h GetGameWinsLosses 214h SetCompetitionResults 215h GetCompetitionResults 216h SetGameErrorResults 217h GetGameErrorResults 218h UpdateGameResults 219h ClearGameResults 21Ah ClearNetErrors 21Bh GetLocalGameValue 21Ch SetLocalGameValue 21Dh GetOppGameValue 21Eh SetOppGameValue 21Fh IsBoxMaster 220h SetBoxMaster 221h 24Bh 25Fh SetCurGameID ;SNES/US: [3631,3633] 222h 24Ch GetCurGameID 223h CheckBoxIDGlobals 224h InitBoxIDGlobals 225h ChangedBoxIDGlobals 226h DBAddConstant 227h DBGetConstant 228h DBSetConstants 229h SetDialNetworkAgainFlag 22Ah CheckDialNetworkAgainFlag 22Bh SetBoxXBandCard 22Ch GetBoxXBandCard 22Dh GetBoxLastCard 22Eh SetBoxMagicToken 22Fh SetBoxProblemToken 230h GetBoxProblemToken 231h UseBoxProblemToken 232h SetBoxValidationToken 233h GetBoxValidationToken 234h SetIMovedOption 235h SetQwertyKeyboardOption 236h SetCallWaitingOption 237h SetAcceptChallengesOption 238h GetAcceptChallengesOption 239h GetIMovedOption 23Ah GetQwertyKeyboardOption 23Bh GetCallWaitingOption 23Ch GetNetErrors Database\BoxSer.c (2), and also Database\PhoneNumbers.c ? 23Dh GetBoxPhoneNumber 23Eh SetBoxPhoneNumber 23Fh GetLocalAccessPhoneNumber 240h SetLocalAccessPhoneNumber 241h Get800PhoneNumber Database\BoxSer.c (3) 242h GetLocalUserName 243h SetLocalUserName 244h GetLocalUserROMIconID 245h SetLocalUserROMIconID 246h GetLocalUserCustomROMClutID 247h SetLocalUserCustomROMClutID 248h GetLocalUserPassword 249h SetLocalUserPassword 24Ah ValidateUserPersonification 24Bh InvalidateUserPersonification Database\PlayerDB.c 24Ch GetAddressBookTypeForCurrentUser 24Dh GetAddressBookIDFromIndex 24Eh CountAddressBookEntries 24Fh RemoveAddressBookEntry 250h GetIndexAddressBookEntry 251h AddAddressBookEntry 252h GetUserAddressBookIndex 253h DeleteAddressBookEntry 254h SendNewAddressesToServer 255h MarkAddressBookUnchanged 256h AddressBookHasChanged 257h CorrelateAddressBookEntry - PreflightNewAddressEntry UserInterface\NewAddressMgr.c 258h AddPlayerToAddressBook 259h UpdateAddressBookStuff 25Ah AddOnDeckAddressBookEntry 25Bh MinimizeUserHandle Database\GraphicsDB.c 25Ch GetDBGraphics 25Dh DrawDBGraphic 25Eh DrawDBGraphicAt 25Fh DrawGraphic 260h DisposeGraphicReference 261h GetGraphicReferenceClut 262h DrawPlayerIcon 263h NukePlayerRAMIcon 264h GetPlayerRAMIconBitMap 265h GetPlayerIconBitMap 266h GetIconBitMap 267h PlayerRAMIconExists 268h DisposeIconReference 269h GetDBButtonFrame 26Ah DrawGraphicGray 26Bh HueShift Graphics\TextUtls.c - Text Edit 26Ch FindLineBreak 26Dh SegaBoxText 26Eh DrawSegaStringLength 26Fh MeasureSegaTextLength 270h InitTextEdit 271h SetTextEditLineHeight 272h TextEditAppend 273h TextEditDelete 274h DisposeTextEdit 275h TextEditActivate 276h TextEditDeactivate 277h TextEditPreflightAppend 278h TextEditGetLineLength 279h DrawTextBox 27Ah SetJizzleBehavior 27Bh GetJizzleBehavior 27Ch StartTextBoxAnimation 27Dh StopTextBoxAnimation 27Eh DisposeTextBoxReference 27Fh DrawSegaTextPlusSpaces 280h UpdateTECaret 281h EraseTextEditLine 282h GetCompressedJizzlers Database\News.c (and NewsUtils.c) - News 283h FindNextNewsString 284h AddPageToNewsBox 285h GetPageFromNewsBox 286h GetNewsForm 287h GetNumNewsPages 288h EmptyNewsBox 289h DrawNewsPage 28Ah ValidateNews 28Bh InvalidateNews 28Ch SetupNewsForServerConnect 28Dh ServerConnectNewsDone 28Eh DoNewsControlIdle 28Fh KillCurNewsPage 290h GetNewsGraphicsID 291h ShowLeftRightPageControls 292h DrawNewsReturnIcon 293h SetNewsCountdownTimeConst 294h DrawXBandNews 295h DisposeXBandNews Database\GameDB.c - Network Game Database (NGP) 296h GetNGPListGamePatchInfo 297h GetNGPListGamePatchVersion 298h GetNGPVersion 299h UpdateNGPList 29Ah UpdateNameList 29Bh GetGameName Database\Personification.c 29Ch ChangeUserPersonificationPart 29Dh InstallOpponentPersonification 29Eh GetPersonificationPart 29Fh PutPersonificationOnWire 2A0h GetPersonificationFromWire 2A1h DisposePersonificationSetup 2A2h ReceivePersonficationBundle 2A3h ParsePersonificationBundle 2A4h CreatePersonificationBundle Database\Mail.c - MailCntl 2A5h CountInBoxEntries 2A6h CountOutBoxEntries 2A7h AddMailToOutBox 2A8h AddMailToInBox 2A9h RemoveMailFromInBox 2AAh GetIndexInBoxMail 2ABh GetIndexOutBoxMail 2ACh GetInBoxGraphicID 2ADh MarkMailItemRead 2AEh DeleteAllOutBoxMail 2AFh GetInBoxTypeForCurrentUser 2B0h GetOutBoxTypeForCurrentUser 2B1h GetOutBoxIDFromIndex 2B2h GetInBoxIDFromIndex 2B3h GetBoxIDFromIndex Database\SendQ.c - Send Queue or so? 2B4h AddItemToSendQ 2B5h AddItemSizeToSendQ 2B6h DeleteSendQ 2B7h KillSendQItem 2B8h GetFirstSendQElementID 2B9h GetNextSendQElementID 2BAh CountSendQElements 2BBh GetSendQElement 2BCh RemoveItemFromSendQ UserInterface\DialogMgr.c 2BDh SetDialogColors 2BEh DoDialog 2BFh DialogParameterText 2C0h DoDialogItem 2C1h DoDialogParam 2C2h DoPlayAgainDialog 2C3h CopyString 2C4h DoAnyResponse 2C5h DoDataDrivenDismissal 2C6h DoPassword 2C7h DrawDialogFrame 2C8h FillTextRectangle 2C9h HorizontalLine 2CAh KillProgressTimer 2CBh ReplaceParameters 2CCh SetupProgressTimer 2CDh VerticalLine 2CEh CreateShiners 2CFh DisposeShiners Sourceless - Fred Chip Hardware 2D0h SetVector 2D1h SetVectorTblAddr 2D2h SetSafeRamSrc 2D3h SetSafeRomSrc 2D4h 323h 33Dh SetLEDs 2D5h SetLEDScreenAnimation Sourceless - Joggler 2D6h InitJoggler 2D7h DisplayJoggler 2D8h StopJoggler Database\DeferredDialogMgr.c 2D9h QDefDialog 2DAh ShowDefDialogs 2DBh CountDefDialogs 2DCh DisableDefDialogs 2DDh EnableDefDialogs Sourceless - Misc 2DEh CheckNetRegister 2DFh NetRegister 2E0h NetRegisterDone 2E1h SetNetTimeoutValue 2E2h GetNetTimeoutValue 2E3h GetNetWaitSoFar 2E4h NetRegisterTimeOutTimeProc 2E5h IsBoxNetRegistered 2E6h GetNetRegisterCase Database\Capture.c - Session Capture (not actually implemented?) - BeginSession - DeleteSession - EndSession - BeginStreamCapture - AddDataToStream Database\Playback.c - Session Playback (not actually implemented?) - BeginSessionPlayback - SessionExists - PlaybackNextStream - PlaybackCurrentStream - PlaybackPreviousStream - DoesNextSessionStreamExist - DoesPreviousSessionStreamExist GameLib\Synch.c - Synch (not actually implemented?) - SynchModems - SynchVbls Sourceless - Game Talk Session? 2E7h GTSInit 2E8h GTSShutdown 2E9h GTSFlushInput 2EAh GTSessionPrefillFifo 2EBh GTSessionEstablishSynch 2ECh GTSessionExchangeCommands 2EDh GTSessionValidateControl 2EEh GTSErrorRecover 2EFh GTSCloseSessionSynch 2F0h GTSDoCommand 2F1h GTSDoResend 2F2h GTSResendFromFrame 2F3h GTSSetPacketFormat 2F4h GTSSetRamRomOffset 2F5h GTSessionSetLatency 2F6h GTSessionSendController8 2F7h GTSessionReadController8 2F8h GTSessionSendController12 2F9h GTSessionReadController12 2FAh GTSessionSendController16 2FBh GTSessionReadController16 2FCh GTSessionSendController18 2FDh GTSessionReadController18 2FEh GTSessionSendController24 2FFh GTSessionReadController24 300h GTSessionSendController27 301h GTSessionReadController27 Sourceless - Game Talk Modem? 302h GTModemInit 303h GTModemGetModemError 304h GTModemClearFifo 305h GTModemClockInByte 306h GTModemClockOutByte 307h GTModemAbleToSend 308h GTModemSendBytes 309h GTModemCheckLine 30Ah GTModemReadModem 30Bh GTSendReceiveBytes 30Ch GTCloseSessionSafe 30Dh GTCreateLooseSession 30Eh GTLooseSessionIdle 30Fh GTCloseLooseSession 310h GTSyncotron 311h GTMasterCalculateLatency 312h GTSlaveCalculateLatency 313h GTSyncoReadModemVBL 314h GTSyncronizeVBLs 315h GTSyncronizeMasterLeave 316h GTSyncronizeSlaveLeave 317h GTSyncoTronVBLHandler 318h GTUnused1 319h GTUnused2 31Ah GTUnused3 31Bh GTUnused4 31Ch GTUnused5 31Dh GTUnused6 UserInterface\Keyboard.c - Keyboard 31Eh SetupKeyboardEntryLayout 31Fh DisposeKeyboardEntryLayout 320h DoKeyboardEntry 321h InitKeyboardEntry 322h SendCommandToKeyboard 323h FinishKeyboardEntry 324h RefreshKeyboard 325h StuffCurrentKeyboardField 326h SelectKeyboardField 327h SendCommandToChatKeyboard 328h GetKeyLayoutFieldCount 329h GetKeyLayoutFieldSize 32Ah SetKeyboardEntryMeasureProc 32Bh SetFocusField 32Ch DrawKeyboard 32Dh ComputeCursorLineNumber 32Eh CacheKeyboardGraphics 32Fh ReleaseKeyboardGraphicsCache Sourceless - Smart Card 330h GetCardType 331h CardInstalled 332h 381h ReadCardBytes ;read smart card byte(s) 333h WriteCardBit 334h GotoCardAddress 335h IncrementCardAddress 336h 385h ReadCardBit ;read smart card bit 337h ResetCard 338h PresentSecretCode 339h GetRemainingCredits 33Ah FindFirstOne 33Bh CountCardBits 33Ch DebitCardForConnect 33Dh DebitSmartCard 33Eh CheckValidDebitCard 33Fh IsGPM896 340h IsGPM103 341h IsGPM256 342h Debit896Card 343h Debit103Card 344h Get896Credits 345h Get103Credits 346h CheckWipeCard 347h UserWantsToDebitCard Sourceless - Sort 348h QSort UserInterface\Secrets.c 349h TrySecretCommand 34Ah TestThisSequence 34Bh ExecCommands 34Ch GetSecretList 34Dh GetSecretSequence 34Eh ResetSecretCommand 34Fh TestSequence 350h PlayMaze 351h EndPlayMaze Sourceless - Maths 352h LongDivide 353h LongMultiply 354h Sqrt 355h RandomShort 356h Sine 357h Cosine Database\RankingMgr.c - Ranking 358h GetFirstRanking 359h GetNextRanking 35Ah GetPrevRanking 35Bh GetHiddenStat 35Ch NextRankingExists 35Dh PrevRankingExists 35Eh CountRankings 35Fh GetFirstRankingID 360h GetNextRankingID 361h GetUniqueRankingID 362h GetRankingSize 363h DeleteRanking 364h AddRanking 365h GetRanking Graphics\Progress.c - Progress Bar Manager 366h InitProgressProcs 367h SpawnProgressProc 368h DisposeProgressProc 369h SetProgressPosition 36Ah ProgressIdle UserInterface\RadioButtons.c 36Bh SetupRadioButton 36Ch DrawRadioButton 36Dh ActivateRadioButton 36Eh DeactivateRadioButton 36Fh RadioButtonSelectNext 370h RadioButtonSelectPrevious 371h RadioButtonGetSelection 372h RadioButtonSetSelection 373h RadioButtonIdle 374h DisposeRadioButtonRef 375h DrawRadioSelection Sourceless - Misc 376h NetIdleFunc 377h CheckError 378h 3D9h 3F8h ccitt_updcrc UserInterface\PeerConnect.c 379h DoPeerConnection 37Ah ConnectToPeer 37Bh DisplayPeerInfo 37Ch DoSlavePeerConnect 37Dh DoMasterPeerConnect 37Eh PeerConnectionDropped 37Fh DoPeerRestoreOS 380h DoExchangePeerData 381h DoPeerDialog 382h Chat 383h PeerStartVBL 384h PeerStopVBL 385h PeerVBLHandler Sourceless - Fifo 386h FifoInit 387h FifoActive 388h FifoWrite 389h FifoRead 38Ah FifoPeek 38Bh FifoPeekEnd 38Ch FifoAvailable 38Dh FifoRemaining 38Eh FifoSkip 38Fh FifoCopy 390h FifoChkSum 391h GetFifoIn 392h FifoLastCharIn 393h FifoUnwrite 394h FifoSize 395h FifoFlush 396h FifoUnread 397h FifoResetConsumption 398h FifoAdjustConsumption Database\Results.c - Result FIFO (not implemented?) - AddToResultFIFO - ReplaceTopEntryOfResultFIFO - GetTopEntryOfResultFIFO - GetIndexEntryInResultFIFO - CountEntriesInResultFIFO Database\FourWayMailView.c - FourWayMail stuff Sourceless - Misc 399h AddVBLRequest 39Ah RemoveVBLRequest 39Bh VBLIdle 39Ch PatchRangeStart <--- ?? 39Dh PatchRangeEnd = kPatchRangeStart + 50 <--- ??? - 54xh SNES table end X-Band GAME Functions (CALL E000CCh) The GAME functions are just aliases for the normal BIOS functions. The idea seems to have been that the BIOS function numbering might change in later BIOS revisions, which would cause compatibility issues for older game patches. As a workaround, there's a separate GAME function table which contains copies of some important BIOS function vectors (and which is probably intendend to maintain fixed function numbers even in later BIOS revisions). The GAME functions are invoked via CALL E000CCh, with X=function_number (0000h..004Dh on SNES/US). The Game Function numbers for Sega are enumerated (among others) in "Database\GamePatch.h". The Game Function table is initialized by "CreateGameDispatcher" (which is using a lot of "InstallGameFunction" calls to transfer the separate function vectors from BIOS table to GAME table). Sega SNES SNES Function Gen. US JP general game stuff 00h 00h? kOSHandleGameError 01h 01h? kOSGameOver basic os stuff 02h kOSNewMemory 03h kOSDisposeMemory 04h kOSDelayTicks hardware stuff 05h kOSSetSafeRomSrc 06h kOSSetSafeRamSrc 07h kOSSetVectorTableAddr 08h kOSSetVector 09h 12h kOSSetLEDs PModem 0Ah kOSReadSerialByte 0Bh kOSWriteSerialByte 0Ch kOSReceiveBufferAvail 0Dh kOSTransmitBufferFree 0Eh kOSCheckLine 0Fh kOSDetectLineNoise 10h kOSCheckCarrier 11h kOSListenToLine 12h kOSSetTimerTicks 13h kOSTimerExpired 14h kOSToneMode 15h 20h kOSReadXRAM 16h 21h kOSReadYRAM 17h kOSWriteXRAM 18h kOSWriteYRAM gametalk 19h kOSGTSSetPacketFormat 1Ah kOSGTSSetRamRomOffset 1Bh kOSGTSessionSetLatency 1Ch kOSGTSessionPrefillFifo 1Dh kOSGTSessionEstablishSynch 1Eh kOSGTSErrorRecover 1Fh kOSGTSCloseSessionSynch 10h kOSGTSFlushInput 11h kOSGTSessionValidateControl 12h kOSGTSessionExchangeCommands 13h kOSGTSDoCommand 14h kOSGTSDoResend 15h kOSGTSResendFromFrame 16h kOSGTModemInit 17h kOSGTModemGetModemError 18h kOSGTModemClearFifo 19h kOSGTModemClockInByte 1Ah kOSGTModemClockOutByte 1Bh kOSGTModemAbleToSend 1Ch kOSGTModemSendBytes 1Dh kOSGTModemCheckLine controller should probably be in "hardware stuff" 1Eh kOSInitControllers 1Fh kOSReadControllers stinkotron 20h kOSGTSyncotron 21h kOSGTMasterCalculateLatency 22h kOSGTSlaveCalculateLatency 23h kOSGTSyncoReadModemVBL 24h kOSGTSyncronizeVBLs 25h kOSGTSyncronizeMasterLeave 26h kOSGTSyncronizeSlaveLeave 27h kOSGTSyncoTronVBLHandler keep this one 28h 4Eh kOSLastFunction SNES Cart FLASH Backup ---------------------- Most SNES games are using battery-backed SRAM for storing data, the only exception - which do use FLASH memory - are the JRA PAT BIOS cartridges for the SFC Modem: --> SNES Add-On SFC Modem (for JRA PAT) There are two JRA PAT versions, the older one (1997) supports only AMD FLASH, the newer one (1999) supports AMD/Atmel/Sharp FLASH chips. ID=2001h - AM29F010 AMD (128Kbyte) ;supported by BOTH bios versions ID=D51Fh - AT29C010A Atmel (128Kbyte) ;supported only by newer bios version ID=32B0h - LH28F020SUT Sharp (256Kbyte?);supported only by newer bios version The FLASH Size size defined in entry [FFBCh] of the Cartridge Header (this is set to 07h in JRA PAT, ie. "(1K SHL 7)=128Kbytes"). There don't seem to be any data sheets for the Sharp LH28F020SUT-N80 chip (ID B0h,32h) (so not 100% sure if it's really 256Kbytes), anyways, it does somehow resemble LH28F020SU-N (5V, ID B0h,30h) and LH28F020SU-L (5V/3.3V, ID B0h,31h). JRA PAT Memory Map 80h-9Fh:8000h-FFFFh ;1Mbyte LoROM (broken into 32 chunks of 32Kbytes) C0h-C3h:0000h-7FFFh ;128Kbyte FLASH (broken into 4 chunks of 32Kbytes) AMD FLASH Get Device ID (Type 1 - AMD) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=90h ;enter ID mode manufacturer=01h=[C00000h], device_type=20h=[C00001h] ;read ID (AM29F010) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h ;terminate command Erase Entire Chip (Type 1 - AMD) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=80h ;prepare erase [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=10h ;erase entire chip repeat, stat=[C00000h], until stat.bit7=1=okay, or stat.bit5=1=timeout Erase 16Kbyte Sector (Type 1 - AMD) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=80h ;prepare erase [C05555h]=AAh, [C02AAAh]=55h, [Cxx000h]=30h ;erase 16kbyte sector repeat, stat=[Cxx000h], until stat.bit7=1=okay, or stat.bit5=1=timeout Write Single Data Byte (Type 1 - AMD) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=A0h ;write 1 byte command [Cxxxxxh]=dta ;write the data byte repeat, stat=[Cxxxxxh], until stat.bit7=dta.bit7=okay, or stat.bit5=1=timeout Notes After AMD timeout errors, one should issue one dummy/status read from [C00000h] to switch the device back into normal data mode (at least, JRA PAT is doing it like so, not too sure if that is really required/correct). ATMEL FLASH Get Device ID (Type 2 - Atmel) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=90h ;enter ID mode manufacturer=1Fh=[C00000h], device_type=D5h=[C00001h] ;read ID (AT29C010A) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=F0h ;terminate command Erase Entire Chip (Type 2 - Atmel) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=80h ;prepare erase [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=10h ;erase entire chip wait two frames (or check if bit6 toggles on each read from [C00000h]) Erase 16Kbyte Sector (Type 2 - Atmel) No such command (one can write data without erasing) (to simulate a 16K-erase: write 128 all FFh-filled 128-byte blocks) Write 1..128 Data Bytes (within 128-byte boundary) (Type 2 - Atmel) [C05555h]=AAh, [C02AAAh]=55h, [C05555h]=A0h ;write 1..128 byte(s) [Cxxxxxh+0..n]=dta[0..n] ;write the data byte(s) repeat, stat=[Cxxxxxh+n], until stat=dta[n] ;wait last written byte Notes The JRA PAD functions do include a number of wait-vblank delays between various ATMEL commands, that delays aren't shown in above flowcharts. SHARP FLASH Get Device ID (Type 3 - Sharp) [C00000h]=90h ;enter ID mode manufacturer=B0h=[C00000h], device_type=32h=[C00001h] ;read ID (LH28F020SUT) [C00000h]=FFh ;terminate command Set/Reset Protection (Type 3 - Sharp) [C00000h]=57h/47h, [C000FFh]=D0h ;<-- C000FFh (!) ;set/reset protection repeat, stat=[C00000h], until stat.bit7=1 ;wait busy if stat.bit4=1 or stat.bit5=1 then [C00000h]=50h ;error --> clear status [C00000h]=FFh ;terminate command Erase Entire Chip (Type 3 - Sharp) [C00000h]=A7h, [C00000h]=D0h ;erase entire chip repeat, stat=[C00000h], until stat.bit7=1 ;wait busy if stat.bit4=1 or stat.bit5=1 then [C00000h]=50h ;error --> clear status [C00000h]=FFh ;terminate command Erase 16Kbyte Sector (Type 3 - Sharp) [C00000h]=20h, [Cxx000h]=D0h ;erase 16kbyte sector repeat, stat=[C00000h], until stat.bit7=1 ;wait busy if stat.bit4=1 or stat.bit5=1 then [C00000h]=50h ;error --> clear status [C00000h]=FFh ;terminate command if failed, issue "Reset Protection", and retry Write Single Data Byte (Type 3 - Sharp) [C00000h]=40h ;write 1 byte command [Cxxxxxh]=dta ;write the data byte repeat, stat=[C00000h], until stat.bit7=1 ;wait busy ;below error-check & terminate are needed only after writing LAST byte if stat.bit4=1 or stat.bit5=1 then [C00000h]=50h ;error --> clear status [C00000h]=FFh ;terminate command PCB VERSIONS Older PCB "SHVC-1A9F-01" (1996) (DIP) (for JRA-PAT and SPAT4) U1 32pin ROM U2 32pin AMD AM29F010-90PC (FLASH) U3 16pin SN74LS139AN U4 16pin D411B (CIC) Newer PCB "SHVC-1A8F-01" (1999) (SMD) (for JRA-PAT-Wide) U1 32pin ROM U2 32pin Sharp LH28F020SUT-N80 (FLASH) U3 16pin 74AC139 U4 18pin F411B (CIC) U5 14pin 74AC08 See Also Another approach for using FLASH backup is used in carts with Data Pack slots: --> SNES Cart Data Pack Slots (satellaview-like mini-cartridge slot) SNES Cart Cheat Devices ----------------------- Code Format Summary Pro Action Replay AAAAAADD raw 8-digits WRAM Pro Action Replay Mk2/Mk3 AAAAAADD raw 8-digits WRAM/ROM/SRAM X-Terminator/Game Wizard AAAAAADD raw 8-digits WRAM Game Genie/Game Mage DDAA-AAAA encrypted 4-4 digits ROM/SRAM Gold Finger AAAAADDDDDDCCW raw 14-digits DRAM/SRAM Front Far East NNAAAAAADD.. raw 10..80 digits DRAM offset Code Format Details --> SNES Cart Cheat Devices - Code Formats Hardware Details --> SNES Cart Cheat Devices - Game Genie --> SNES Cart Cheat Devices - Pro Action Replay I/O Ports --> SNES Cart Cheat Devices - Pro Action Replay Memory --> SNES Cart Cheat Devices - X-Terminator & Game Wizard --> SNES Cart Cheat Devices - Game Saver --> SNES Cart Cheat Devices - Theory Cheat Devices & Number of Hardware/Software patches & Built-in codes Name Hardware/ROM Software/WRAM Built-in Pro Action Replay None (of 4) 4 None Pro Action Replay Mk2a/b 0/2/4 (of 4) 100 None Pro Action Replay Mk3 1/5 (of 7) 100 ? games Game Genie (Codemasters/Galoob) 5 (of 6) None None Game Mage (Top Game & Company) 8? None? 250 codes? X-Terminator (Fire) None (of 0) 4 None X-Terminator 2 (noname) None (of 0) 64 307 games Game Wizard (Innovation) None? ? ? Game Saver (Nakitek) allows to save WRAM/VRAM snapshots in non-battery DRAM Game Saver+ (Nakitek) allows to save WRAM/VRAM snapshots in battery DRAM Super UFO (copier, supports Gold Finger and X-Terminator codes) Super Wild Card/Magicom (copiers, support Gold Finger and Front Far East) Parame ROM Cassette Vol 1-5 (by Game Tech) (expansions for X-Terminator 2) Note: The Game Mage's stylished "GAME|~AGE)" logo is often misread as "Gametaged". Links http://www.gamegenie.com/cheats/gamegenie/snes/index.html http://www.world-of-nintendo.com/pro_action_replay/super_nes.shtml http://www.gamefaqs.com/snes/562623-harvest-moon/faqs/10690 http://www.gamefaqs.com/snes/588741-super-metroid/faqs/5667 SNES Cart Cheat Devices - Code Formats -------------------------------------- PAR AAAAAADD - Normal Pro Action Replay Codes (Datel) The Pro Action Replay is a cheat device for the SNES produced by Datel. The original PAR only support 3 codes, but the PAR2 supports 255 and has a built-in trainer for code searcher. There is also a PAR3, but the added features are unknown. AAAAAADD ;-address (AAAAAA) and data (DD) Address can be a ROM, SRAM, or WRAM location. Patching cartridge memory (both ROM and SRAM) is implemented by hardware (supported by PAR2-PAR3 only, not by PAR1 or X-Terminator 1-2). Patching WRAM is done by software (rewriting the values on each Vblank NMI). WRAM addresses must be specified as 7E0000h-7FFFFFh (mirrors at nn0000h-nn1FFFh aren't recognized by the BIOSes). PAR 7E000000 - Do nothing This is the most important PAR code (required as padding value, since the GUI doesn't allow to remove items from the code list): PAR FE0000xx..FFFFFFxx - Pre-boot WRAM patch (PAR1 only) Writes xx to the corresponding WRAM address at 7E0000h..7FFFFFh, this is done only once, and it's done BEFORE starting the game (purpose unknown - if any). PAR 00600000 - Disable Game's NMI handler (PAR3 only) Disables the game's NMI handler (executes only the NMI handler of the PAR BIOS). PAR DEADC0DE - Special Multi-Byte Code Prefix (PAR2a/b and PAR3 only) Allows to hook program code, this feature is rarely used. DEADC0DE ;-prefix (often misspelled as "DEADCODE", with "O" instead "0") AAAAAANN ;-address (AAAAAA) and number of following 4-byte groups (NN) DDEEFFGG ;-first 4-byte group (DD=1st byte, .. GG=4th byte) HHIIJJKK ;-second 4-byte group (HH=5th byte, .. KK=8th byte) (if any) ... ;-further 4-byte groups (etc.) (if any) The data portion (DD,EE,FF..) (max 62h*4 = 188h bytes) is relocated to SRAM (in the PAR cartridge), and the ROM address AAAAAA is patched by a 4-byte "JMP nnnnnn" opcode (doing a far jump to the address of the relocated SRAM code; this would be at 006A80h in PAR3, at 006700h in PAR2a/b, and isn't supported in PAR1). There seems to be no special action required when returning control to the game (such like disabling the SRAM - if the hardware does support that at all?) (or such actions are required only for HiROM games that have their own SRAM at 6000h?) (or games are typically accessing SRAM at 306xxxh, so there is no conflict with PAR memory at 006xxxh?). One can use only one DEADC0DE at a time, and, when using it, there are some more restrictions: On PAR2a/b one cannot use ANY other hardware/software patches. On PAR3 one can keep using ONE hardware patch (and any number of software patches). PAR C0DEnn00 - Whatever (X-Terminator 2 only - not an official PAR code) Somehow changes the NMI (and IRQ) handling of the X-Terminator 2, "nn" can be 00..06. Game Genie Codes (Codemasters/Galoob) DDAA-AAAA ;-encrypted data (DD) and encrypted/shuffled address (AA-AAAA) Address can be a ROM, or SRAM location (internal WRAM isn't supported). To decrypt the code, first replace the Genie Hex digits by normal Hex Digits: Genie Hex: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E Normal Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F Thereafter, DD is okay, but AAAAAA still needs to be deshuffled: ijklqrst opabcduv wxefghmn ;Genie Address (i=Bit23 ... n=Bit0) abcdefgh ijklmnop qrstuvwx ;SNES Address (a=Bit23 ... x=Bit0) Aside from being generally annoying, the encryption makes it impossible to make codes like "Start in Level NN" (instead, one would need to make separate codes for each level). Game Genie codes can be reportedly also used with the Game Mage. And, the PAR3 includes a "CONV" button for converting Game Genie codes. When manually decrypting them, Game Genie codes would also work on PAR2 (although the PAR2 won't allow to use five ROM patches at once). Gold Finger / Goldfinger Codes (unknown who created this format) These codes are rarely used, and there isn't much known about them. Reportedly, they have been supported by "certain copiers" (unknown which ones... Super UFO, and also copiers from Front Far East?). AAAAADDEEFFCCW ;-Address (AAAAA), Data (DD,EE,FF), Checksum (CC), Area (W) The Address is a ROM address, not a CPU address. Data can be 1-3 bytes, when using less than 3 bytes, pad the EE,FF fields with "XX" (and treat them as zero in the checksum calculation). Checksum is calculated as so: CC = A0h + AAAAA/10000h + AAAAA/100h + AAAAA + DD (+ EE (+ FF)) W tells the copier whether to replace the byte in the DRAM (ROM image) or the SRAM (Saved game static RAM) of the copier: W=0 DRAM (ROM image) (reportedly also for W=2,8,A,C,F) W=1 SRAM (Saved game image) The 5-digit address allows to access max 1Mbyte. The address is an offset within the ROM-image (excluding any 200h-byte header). The first LoROM byte would be at address 00000h. Some copiers are using interleaved HiROM images - unknown if any such interleave is used on code addresses - if so, first HiROM byte would be at "ROMsize/2" (in middle of ROM-image), otherwise it'd be at 00000h (at begin of ROM-image). Note: It doesn't seem to be possible to enter "X" digits in all copiers. Double Pro Fighter Q allows to enter "X". Front Far East Codes (Front Far East) Supported by Front Far East copiers (Super Magicom and/or Super Wild Card?). This format is even less popular than the Gold Finger format. NNAAAAAADD.. Number of bytes (NN), Address (AAAAAA), Data (DD..) Allows to change 1..36 bytes; resulting in a code length of 10..80 digits (to avoid confusion with 14-digit Gold Finger codes, Front Far East wants Gold Finger codes to be prefixed by a "G"). AAAAAA is a 24bit offset within the ROM-image (excluding any 200h-byte header). As far as known, Front Far East didn't use interleaved ROM-images, so the offset should be straight. SNES Cart Cheat Devices - Game Genie ------------------------------------ Game Genie BIOS Versions There are at least three BIOS versions, named "GENSRC", "K7", and "ed": "GENSRC" 32Kbytes LoROM, straight I/O addresses CRC32=AC94F94Ah "K7" 32Kbytes LoROM, messy I/O addresses CRC32=F8D4C303h "ed" 64Kbytes LoROM, messy I/O addresses CRC32=58CBF2FEh The names are stored at ROM-offset 7FE0h (aka SNES address 00FFE0h). Most of the cartridge header contains garbage (no checksum, wrong ROM size, etc.), only the 21-byte title field is (more or less) correct: "Game Genie ",0,0,0,0,0 ;32K versions (GENSRC & K7) "Game Genie Jo" ;64K version (ed) Note: All three versions support only 5 codes to be entered. Game Genie I/O Ports The "GENSRC" version uses quite straight I/O addresses, the "K7" and "ed" versions have the addresses messed up (unused gaps between the codes, several mirrors, of which, mirrors with address bit8 and bits16-23 all zero are having address bit0 inverted). Version "GENSRC" "K7" & "ed" Control W:008000h W:xx8100h, W:008001h ;ed: xx=00, K7: xx=FF CodeFlags R/W:008001h R:FF8001h, W:008000h ;bit 0-4 = enable code 1-5 CodeMsb R/W:008003h+N*4 R:FF8005h+N*6, W:008004h+N*6 ;\ CodeMid R/W:008004h+N*4 R:FF8006h+N*6, W:008007h+N*6 ; N=0-4 for CodeLsb R/W:008005h+N*4 R:FF8007h+N*6, W:008006h+N*6 ; code 1-5 CodeData R/W:008006h+N*4 R:FF8008h+N*6, W:008009h+N*6 ;/ Other (accidently) used I/O addresses are: W:004017h (bugged joypad access), and W:00FFEAh/00FFEBh (used in an attempt to install a bugged NMI handler with RET instead of RETI opcode; the hardware is hopefully ignoring that attempt). Control Register Allows to select what is mapped to memory. Used values are: 00h Select Game Genie BIOS 02h Select Game Genie I/O Ports 06h Select Game Cartridge 07h Select Game Cartridge and keep it selected This register is set to 00h on /RESET (warmboot & coldboot). Code Flags Register Used to enable the 5 codes: Bit0-4 Enable Code 1..5 (0=Disable, 1=Enable) Bit5-7 Should be zero This register is set to 00h on initial power-up (coldboot), but kept intact on /RESET (warmboot), allowing to restore the previously enabled codes. CodeAddress/CodeData Registers (5*4 bytes) Contains the 24bit address and 8bit data values (in decrypted form). The registers are kept intact on /RESET (warmboot), allowing to restore the previously entered codes - however, when restoring the codes, the "K7" and "ed" BIOS versions are ORing the LSB of of the 24bit address value with 01h, thereby destroying all codes with even addresses (unknown why that's been done). Chipset The exact chipset is unknown, there should be the ROM and some logic (and no SRAM). There is also a LED and a 2-position (?) switch (unknown function). XXX For more in-depth info see "genie.txt" from Charles MacDonald. http://cgfm2.emuviews.com/txt/genie.txt Game Genie 2 (prototype) There is also an unreleased Game Genie 2 prototype, the thing includes a small LCD screen, five push buttons, four LEDs, battery backed SRAM, a 8255 PIO, a huge ACTEL chip, and some expansion connectors. SNES Cart Cheat Devices - Pro Action Replay I/O Ports ----------------------------------------------------- PAR1 I/O Ports (W) 008000h ;Code 0-3 (MID) (shared for code 0..3) 010000h,010001h,010002h ;Code 0 (DTA,LSB,MSB) (not used by BIOS) 010003h ;Control (set to FFh) 010004h,010005h,010006h ;Code 1 (DTA,LSB,MSB) (not used by BIOS) 010007h,010008h,010009h ;Code 2 (DTA,LSB,MSB) (used as NMI vector.LSB) 01000Ah,01000Bh,01000Ch ;Code 3 (DTA,LSB,MSB) (used as NMI vector.MSB) Most I/O ports are overlapping WRAM in bank 01h (unlike PAR2-PAR3 which use bank 10h). The four code registers would allow to apply 4 hardware patches, the PAR1 BIOS actually has provisions for doing that, but, before applying those patches it erases code 0-3 (and does then use code 2-3 for patching the NMI vector at 00FFEAh for applying the codes as WRAM software patches). The PAR1 supports only LoROM addresses (address bit15 removed, and bit23-16 shifted down). The PAR1 does not (maybe cannot) disable unused codes; instead, it directs them to an usually unused ROM location at 00FFF6h (aka 007FF6h after removing bit15). Applying the codes is done in order DTA,MID,LSB,MSB, whereof, the "shared" MID value is probably applied on the following LSB port write. The control register is set to FFh before starting the game, purpose is unknown (maybe enable the codes, or write-protect them, or disable the BIOS ROM; in case that can be done by software). PAR2 I/O Ports (W) 100000h,100001h,100002h,100003h ;Code 0 (DTA,LSB,MID,MSB) (code 0) 100004h,100005h,100006h,100007h ;Code 1 (DTA,LSB,MID,MSB) (code 1) 100008h,100009h,10000Ah,10000Bh ;Code 2 (DTA,LSB,MID,MSB) (code 2/NMI.LSB) 10000Ch,10000Dh,10000Eh,10000Fh ;Code 3 (DTA,LSB,MID,MSB) (code 3/NMI.MSB) 100010h ;Control A (set to 00h or FFh) C0A00nh ;Control B (address LSBs n=0..7) (written data=don't care) The registers overlapping the WRAM area are similar as for PAR1. The PAR2 BIOS allows to use the code registers for ROM patches (and/or hooking the NMI handler for WRAM patches). Similar as in PAR1, address bit23-16 are shifted down, but with bit15 being moved to bit23 (still a bit messy, but HiROM is now supported). Unused codes are redirected to 00FFF6h (aka 807FF6h after moving bit15). The control register is set to FFh before starting the game, purpose is unknown (maybe enable the codes, or write-protect them, or disable the BIOS ROM; in case that can be done by software). The lower address bits of the newly added C0A00nh Register are: Address bit0 - set if one or more codes use bank 7Fh..FEh Address bit1 - set/cleared for PAL/NTSC selection (or vice-versa NTSC/PAL?) Address bit2 - set to... maybe, forcing the selection in bit1 (?) The exact purpose of that three bits is unknown (and their implemention in PAR2a/b BIOSes looks bugged). Doing anything special on bank 7Fh-FEh doesn't make any sense, maybe the programmer wanted to use banks 80h-FFh, but that wouldn't make much more sense either; it might be something for enabling/disabling memory mirrors or so. The default PAL/NTSC flag is auto-detected by reading 213Fh.Bit4 (the BIOS is doing that detection twice, with opposite results on each detection, which seems to be a bug), the flag can be also manually changed in the BIOS menu; purpose of the PAL/NTSC thing is unknown... maybe directing a transistor to shortcut D4 to GND/VCC when games are reading 213Fh. PAR3 I/O Ports 100000h,100001h,100002h,100003h ;Code 0 (DTA,LSB,MID,MSB) (code 0) 100004h,100005h,100006h,100007h ;Code 1 (DTA,LSB,MID,MSB) (code 1) 100008h,100009h,10000Ah,10000Bh ;Code 2 (DTA,LSB,MID,MSB) (code 2) 10000Ch,10000Dh,10000Eh,10000Fh ;Code 3 (DTA,LSB,MID,MSB) (code 3) 100010h,100011h,100012h,100013h ;Code 4 (DTA,LSB,MID,MSB) (code 4) 100014h,100015h,100016h,100017h ;Code 5 (DTA,LSB,MID,MSB) (always NMI.LSB) 100018h,100019h,10001Ah,10001Bh ;Code 6 (DTA,LSB,MID,MSB) (always NMI.MSB) 10001Ch ;Control A (bit4,6,7) 10001Dh-10001Fh ;Set to zero (maybe accidently, trying to init "code 7") 10003Ch ;Control B (set to 01h upon game start) 086000h ;Control LEDs (bit0,1) 206000h ;Control C (bit0) 008000h ;Control D (set to 00h upon PAR-NMI entry) Control A (10001Ch): Bit0-3 Should be 0 Bit4 ROM Mapping (0=Normal, 1=Temporarily disable BIOS & enable GAME ROM) Bit5 Should be 0 Bit6-7 Select/force Video Type (0=Normal, 1=NTSC, 2=PAL, 3=Reserved) Control LEDs (086000h) (LEDs are in sticker area on front of cartridge): Bit0 Control left or right LED? (0=on or off?, 1=off or on?) Bit1 Control other LED ("") Bit2-7 Should be 0 Control C (206000h): Bit0 Whatever (0=BIOS or PAR-NMI Execution, 1=GAME Execution) Bit1-7 Should be 0 Code0-6: Unused codes are set to 00000000h (unlike PAR1/PAR2), and, codes use linear 24bit addresses (without moving/removing bit15). Of the seven codes, code 5-6 are always used for hooking the NMI handler (even when not using any WRAM software patches), so one can use max 5 hardware ROM patches. SNES Cart Cheat Devices - Pro Action Replay Memory -------------------------------------------------- PAR1-PAR3 SRAM All PAR versions contain 32Kbytes SRAM, divided into 8K chunks, which are unconventionally mapped to EVEN bank numbers. 00/02/04/06:6000h..7FFFh ;-32Kbyte SRAM (four 8K banks) The SRAM is used as internal workspace (stack & variables, code list, NMI handler, deadcode handler, and list of possible-matches for the code finder). Unknown if the SRAM is battery backed (the way how it is used by the BIOS suggests that it is NOT battery backed). Note: Many HiROM games have their own SRAM mapped to 6000h-7FFFh, unknown if/how/when the PAR can disable its SRAM for compatibility with such games (PAR1 seems to be designed for LoROM games only, but newer PAR2-PAR3 have HiROM support - if so, then the hardware must somehow switch the SRAM on/off depending on whether it executes game code, or PAR code like NMI & deadcode handlers). PAR1-PAR3 Switch All PAR versions do have a 3-position switch (on the right edge of the cartridge). The way how Datel wants it to be used seems to be: 1) Boot game with switch in MIDDLE position (maybe needed only for testing) 2) Set LOWER position & push RESET button (to enter the BIOS menu) 3) After selecting codes/cheat finder, start game with MIDDLE position 4) Finally, UPPER position enables codes (best in-game, AFTER intro/menu) Technically, the switch seems to work like so: UPPER Position "Codes on" Enable GAME and enable codes MIDDLE Position "Codes off" Enable GAME and disable codes LOWER Position "Trainer On" Enable BIOS and (maybe) enable codes The "Codes off" setting may be required for booting some games (which may use WRAM for different purposes during intro & game phases). The purpose of the "Trainer" setting is unclear, GAME/BIOS mapping could be as well done via I/O ports (and at least PAR3 does actually have such a feature for reading the GAME header during BIOS execution). There seems to be no I/O ports for sensing the switch setting, however, the "Codes off" setting can be sensed by testing if the patches (namely the patched NMI vector) are applied to memory or not. PAR BIOS Versions Pro Action Replay Mk1 v2.1 1992 32K CRC32=81A67556h Pro Action Replay Mk2 v1.0 1992,93 32K CRC32=83B1D39Eh Pro Action Replay Mk2 v1.1 1992,93,94 32K CRC32=70D6B036h Pro Action Replay Mk3 v1.0U 1995 128K CRC32=0D7F770Ah The two Mk2 versions are 99.9% same (v1.1 is only 10 bytes bigger than v1.0, major change seems to be the copyright message). Aside from v1.0/v1.1, there are reportedly further PAR2 BIOS versions (named v2.P, v2.T, v2.H). Moreover, there's reportedly at least one localized BIOS (a german PAR3 with unknown version number). PAR Component List The exact component list is all unknown. Some known components are: PAR1-3 3-position switch (on right edge of the cartridge) PAR1-3 32Kbytes SRAM (probably not battery-backed) PAR1-2 32Kbytes BIOS PAR3 128Kbytes BIOS (with modernized GUI and built-in "PRESET" codes) PAR1 46pin cartridge slot (incompatible with coprocessors that use 62pins) PAR2-3 62pin cartridge slot PAR2-3? second Npin cartridge slot at rear side (for CIC from other region) PAR3 two LEDs (within sticker-area on front of cartridge) PAR1-3 whatever logic chip(s) SNES Cart Cheat Devices - X-Terminator & Game Wizard ---------------------------------------------------- Pro Action Replay (PAR1) clone Wide parts of the X-Terminator BIOS are copied 1:1 from a disassembled PAR1 BIOS. The similarities begin at the entrypoint (with some entirely useless writes to 2140h-2143h), and go as far as using the ASCII characters "W H B ." as default dummy data values for the 4 codes (the initials of the PAR1 programmer W.H.BECKETT). There are some differences to the original PAR1: The hardware and I/O ports are a custom design, the GUI does resemble the PAR2 rather than the PAR1, and english words like "relation" are translated to odd expressions like "differentship". Nonetheless, the thing was called back (in some countries at least), presumably due to all too obvious copyright violations. I/O Ports & Memory Map X-Terminator 1 X-Terminator 2 00FFE8h.W 00FFEAh.W ;map BIOS (by writing any value) 00FFE9h.W 00FFEBh.W ;map GAME (by writing any value) 00FFEAh.R (NMI read) 00FFEAh.R (NMI read) ;map BIOS/GAME (switch-selection) 008000h-00FFFFh 008000h-00FFFFh ;BIOS (32Kbytes) N/A 028000h-02FFFFh ;Expansion ROM 32Kbytes 00,02,04,06:6000-7FFF 00-1F:02C00-2FFF ;SRAM (32Kbytes) Note: Both BIOS versions are confusingly using 16bit writes to the I/O ports in some cases; the LSB-write to [addr+0] has no effect (or lasts only for 1 cpu cycle), the MSB-write to [addr+1] is the relevant part. The uncommon SRAM mapping in EVEN banks at 6000h-7FFFh was cloned from PAR. The later mapping to 2C00h-2FFFh was probably invented for compatibility with HiROM games that use 6000h-7FFFh for their own SRAM (or possibly just to look less like a PAR clone). Aside from NMI, the X-Terminator 2 is also using IRQ vectors (though unknown if they are used only during BIOS execution or also during GAME execution, in latter case reads from FFEEh would probably also trigger memory mapping). Game Wizard (by Innovation) The Game Wizard seems to be a rebadged X-Terminator. Unknown if the I/O addresses are same as for X-Terminator 1 or 2. BIOS Versions There are at least two versions: X-Terminator 1993 (english) (CRC32=243C4A53h) (no built-in codes) X-Terminator 2 19xx (japanese) (CRC32=5F75CE9Eh) (codes for 307 games) There should be probably also a separate version for Game Wizard. And, considering that the BIOS is stored on ERPOM, there might be many further versions & revisions. Cartridge header is FFh-filled (except for exception vectors), BIOS is 32Kbytes LoROM. X-Terminator Expansion ROMs There have been at least 5 expansion cartridges released: Parame ROM Cassette Vol 1-5 (by Game Tech) The cartridges contain 256Kbytes LoROM, and they can be used in two ways: As normal executable (via normal ROM header at ROM-offset 7FC0h aka SNES address 00FFC0h), or as cheat-code database extension for the X-Terminator 2 (via a special ROM header at ROM-offset 10000h aka SNES address 028000h). 028000h - ID "FU O9149" (aka "UFO 1994" with each 2 bytes swapped) 028008h - Boot callback (usually containing a RETF opcode) 028010h - List of 16bit pointers (80xxh-FFFFh), terminated by 0000h The 16bit pointers do address following structures (in ROM bank 02h): 2 checksum (MSB,LSB) taken from GAME cartridge ROM header [FFDCh] 1 number of following 5-byte codes (N) 5*N codes (MID,MSB,DTA,LSB,TYPE) ;TYPE=predefined description (00h..23h) Unknown how the cartridges are intended to be connected (between X-Terminator and Game cartridge... or maybe to a separate expansion slot). Super UFO Copier The Super UFO copiers are somehow closely related to X-Terminator (probably both made by the same company). X-Terminator codes are supported by various Super UFO versions. Later Super UFO versions also include/support Parame expansion ROMs: Super UFO Pro-8 V8.8c BIOS This versions seems to detect "FU O9149" IDs (ie. Parame carts), moreover, it seems to include it's own "FU O9149" ID (but, strangely, at 048000h instead of 028000h, so the X-Terminator won't find it?). X-Terminator Chipset (whatever X-Terminator version) Goldstar GM76C256ALL-70 (32Kbytes SRAM, not battery-backed) D27256 (32Kbytes UV-Eraseable EPROM) two logic chips & two PALs or so (part numbers not legible on existing photo) 3-position switch (on PCB solder-side) (SCAN/NORMAL/ACTION) two cartridge slots (for PAL and NTSC cartridges or so) SNES Cart Cheat Devices - Game Saver ------------------------------------ The Game Saver from Nakitek allows to load/save snapshots of (most of) the SNES memory and I/O ports. Game Saver Controls (works with joypad in port 1 only) L+R upon boot --> test screen / version number L+R+START upon boot --> toggle slow DRAM checksumming on/off SELECT in title --> enter revival codes R+SELECT in game --> save state L+SELECT in game --> load state R+START in game --> toggle slow motion on/off ;\one of these keeps L+START in game --> toggle slow motion on/off ;/HDMA enabled (or so) Missing Save Data The SNES cannot directly access the APU, so APU RAM, DSP I/O Ports, and SPC700 registers aren't saved. The WRAM address (2181h-2183h) isn't saved. The VRAM/OAM/CGRAM addresses are saved (but may have wrong values since the autoincrement isn't handled). Any coprocessor I/O ports or cartridge SRAM aren't saved. Hardware Versions (Game Saver and Game Saver+) The original Game Saver didn't have any power supply, which made (and still makes) it the most controverse SNES add-on: Some people just like it, other people are crying tears because they don't understand why the DRAM isn't battery-backed. This has led to the creation of the Game Saver Plus - a surreal product that use battery-backed DRAM (according to the booklet, where it is called "portability" feature, six new AA batteries last 8-10 hours). Aside from batteries, the Game Saver Plus is powered via the 9V DC supply of NTSC-SNES consoles (even when the console itself is switched off). That's allowing to switch off the SNES during supper in order to "save" energy (though after some weeks, the permanently powered DRAM may negate that energy "saving" effect). BIOS Versions There seem to be several BIOS versions (DDMMYY formatted date and version number are shown in the test screen). Known versions are: Game Saver v1.3 (19xx) Game Saver v1.7 (31 Jul 1995) Unknown if Game Saver & Game Saver Plus use different BIOSes. Unknown if any new/changed I/O ports were invented alongside with the BIOS versions. Game Saver Memory and I/O Map 002100h-0021xxh PPU ports (logged at 2081xxh) (or at 2080xxh on 2nd write) 004200h-0042xxh CPU ports (logged at 2082xxh) 008000h-00FFFFh BIOS ROM 32Kbytes 0080xFh Switch to GAME mapping (upon opcodes that end at 80xFh) 00FFEAh Switch to BIOS mapping (upon NMI execution; when enabled) 108000h-108001h I/O - First/second write flags for write-twice PPU ports 108002h-108003h I/O - Exception Mode/Status (bit0-1=BRK, bit2=NMI) 208000h-2087FFh SRAM 2Kbytes (includes auto-logged writes to PPU/CPU ports) 400000h-73FFFFh DRAM 256Kbytes (for saving WRAM/VRAM/OAM/CGRAM, CPU/DMA regs) 808000h-80FFFFh GAME ROM (even while BIOS mapping is enabled) The Game Saver can trap BRK or NMI exceptions. Of which, BIOS v1.7 seems to use only BRKs (which are probably generated by outputting a 00h opcode in response to joypad access, ie. [4218h] reads and [4017h]=01h writes). Game Saver Revival Codes The 5-digit "Revival Codes" are used to improve compatibility with different games. Most commonly used are 2xxxx codes, which cause a byte in WRAM to be left unchanged when loading data (probably in order to keep the Main CPU aware of the state of the APU). The Code Format is: 00000-0FFFF Blank (no action) (shown as "XXXXX" in GUI) 10000-1FFFF Exception Mode (value for [108002]) (not used for any games) 20000-3FFFF Preserve WRAM byte at 7E0000-7FFFFF (used for most games) 40000-4FFFF PPU write-twice related (used only for Starfox/Star Wing) 50000-5FFFF PPU write-twice related (not used for any games) 60000-6FFFF Reserved (no action) (not used for any games) 70000-7FFFF Select special BRK handler (used only for Aero the Acro Bat) 80000-9FFFF Preserve WRAM byte at 7E0000-7FFFFF and pass it to 2140h ;\not A0000-BFFFF Preserve WRAM byte at 7E0000-7FFFFF and pass it to 2141h ; used C0000-DFFFF Preserve WRAM byte at 7E0000-7FFFFF and pass it to 2142h ; by any E0000-FFFFF Preserve WRAM byte at 7E0000-7FFFFF and pass it to 2143h ;/games Codes (and updates) have been available as print-outs from Nakitek (the list from 1995 contains codes for around 200 games; to be entered when pressing SELECT in title screen). Moreover some (or all) BIOSes contain automatically applied built-in codes (via checksumming portions of the game ROM header). The v1.7 BIOS contains 284 codes (however, the code list does (maybe accidently) contain an entry with NULL checksum, which causes the last 108 codes to be ignored). Component List (Game Saver Plus) 24pin SRAM (2Kbytes) (probably used only because DRAM is too slow for I/O) 28pin ROM/EPROM (32Kbytes) 62pin cartridge slot (on rear side of device) 14pin eight DRAM chips (256Kbytes in total) Xpin huge chip (whatever logic) 3pin 7805 or so (for turning much of the 9 volts into heat) 2pin oscillator (20.000MHz) (for DRAM refresh generator when power-off) socket/cable/plug for NTSC-SNES 9V DC supply (not PAL-SNES 9V AC supply) battery box for six 1.5V AA batteries, battery LED, and battery switch resistors, capacitors, and maybe diodes, transistors Note Some Copiers include a similar feature, allowing to load/save "real time saves" on floppy disks and/or temporarily in unused portions of their built-in DRAM. SNES Cart Cheat Devices - Theory -------------------------------- ROM Patches There are two possible ways for patching ROMs or ROM-images: 1) rewrite ROM-image in RAM once before game starts (GF/FFE/emulators) 2) patch on ROM reading (by watching address bus) (GG and PAR2-3) Both are basically having same results, there may be some variations concerning memory mirrors (depending on how the ROM-image in RAM is mirrored, or on how the GG/PAR2-3 do decode the ROM address). WRAM Patches Implemented by rewriting WRAM upon NMI, variations would involve mirrors: 1) allow WRAM addresses 7E0000-7FFFFF (PAR1-3, XT1-2) 2) allow WRAM addresses 7E0000-7FFFFF and nn0000-nn1FFF (N/A) SRAM Patches There are three possible ways for patching battery-backed SRAM: 1) rewrite once before game starts (GF) 2) patch on SRAM reading (like hardware based ROM patches) (GG and PAR2-3) 3) rewrite repeatedly on NMI execution (like WRAM patches) (N/A) SRAM is usually checksummed, so SRAM patches need to be usually combined with ROM patches which do disable the checksum verification. Some devices (like Game Genie) rely on the /ROMSEL signal, and thus probably can only patch SRAM in the ROM area at 70xxxxh (but not in the Expansion area at 306xxxh). Slow Motion Feature Implemented by inserting delays in Vblank NMI handler. The feature can be usually configured in the BIOS menu, and/or controlled via joypad button combinations from within NMI handler. Cheat Finders (for WRAM Patches) (eventually also for SRAM patches) Implemented by searching selected values from within Vblank NMI handler, or more simple: from within BIOS RESET handler. The search can be enabled/disabled mechanically via switch, or in some cases, via joypad button combinations. The searched value can be configured on RESET, or in some cases, via joypad button combinations. Game Saver (Nakitek) Allows to save a copy of WRAM/VRAM and I/O ports (but not APU memory) in DRAM, done upon joypad button-combinations sensed within BRK/NMI exception handlers. SNES Cart Tri-Star (aka Super 8) (allows to play NES games on the SNES) ----------------------------------------------------------------------- The Tri-Star is an adaptor for playing NES games on the SNES (similar to the Super Gameboy which allows to play Gameboy games on SNES). The thing have three cartridge slots (two for western/japanese NES/Famicom cartridges, and one for SNES cartridges). NES or SNES mode can be selected in BIOS boot menu. SNES mode does simply disable the BIOS and jump to game entrypoint at [FFFCh]. NES mode executes the games via a NOAC (NES-on-a-Chip, a black blob, which is also used in various other NES clones), in this mode, the SNES video signal is disabled, and, aside from the BIOS passing joypad data to the NES, the SNES does merely serve as power-supply for the NES. Memory and I/O Map 00E000h-00FFFFh.R - BIOS ROM (8Kbytes) 00FFF0h.W - NES Joypad 1 (8bit data, transferred MSB first, 1=released) 00FFF1h.W - NES Joypad 2 (bit4-5: might be NES reset and/or whatever?) 00FFF2h.W - Enter NES Mode (switch to NES video signal or so) 00FFF3h.W - Disable BIOS and map SNES cartridge Joypad I/O In NES mode, the BIOS is reading SNES joypads once per frame (via automatic reading), and forwards the first 8bit of the SNES joypad data to the NES (accordingly, it will work only with normal joypads, not with special hardware like multitaps or lightguns). Like on japanese Famicoms, there are no Start/Select buttons transferred to joypad 2. Instead, FFF1h.Bit5/4 are set to Bit5=0/Bit4=1 in SNES mode, and to Bit5=1/Bit4=0 in NES mode (purpose is unknown, one of the bits might control NES reset signal, the other might select NES/SNES video signal, unless that part is controlled via FFF3h). Mode Selection I/O When starting a NES/SNES game, ports FFF2h or FFF3h are triggered by writing twice to them (probably writing any value will work, and possibly writing only once might work, too). BIOS Versions (and chksum, shown when pressing A+X on power-up) Tri-Star (C) 1993 ;ROM CHKSUM: 187C Tri-Star Super 8 by Innovation (C) 1995 ;ROM CHKSUM: F61E Both BIOSes are 8Kbytes in size (although ROM-images are often overdumped). The versions seem to differ only by the changed copyright message. The GUI does resemble that of the X-Terminator and Super UFO (which were probably made by the same anonymous company). A third version would have been the (unreleased) Superdeck (a similar device that has been announced by Innovation and some other companies). Component List (Board: SFFTP_C/SFFTP_S; component/solder side) 82pin NOAC chip (black blob on 82pin daughterboard) (on PCB bottom side) 28pin EPROM 27C64 (8Kx8) (socketed) 16pin SNES-CIC clone (NTSC: ST10198S) (PAL: probably ST10198P) (socketed) 20pin sanded-chip (probably 8bit latch for joypad 1) 20pin sanded-chip (probably 8bit latch for joypad 2) 16pin sanded-chip (probably 8bit parallel-in shift-register for joypad 1) 16pin sanded-chip (probably 8bit parallel-in shift-register for joypad 2) 16pin sanded-chip (probably analog switch for SNES/NES audio or video) 20pin sanded-chip (probably PAL for address decoding or so) (socketed) 2pin oscillator (? MHz) (for NES cpu-clock and/or NES color-clock or so) 62pin cartridge edge (SNES) (on PCB bottom side) 12pin cartridge edge (A/V MultiOut) (to TV set) (on PCB rear side) 62pin cartridge slot (SNES) 60pin cartridge slot (Famicom) (japanense NES) 72pin cartridge slot (NES) (non-japanense NES) 6pin socket for three shielded wires (Composite & Stereo Audio in from SNES) TV Modulator (not installed on all boards) four transistors, plus some resistors & capacitors SNES Cart Pirate X-in-1 Multicarts (1) -------------------------------------- There are several X-in-1 Multicarts, all containing the same type of text based GUI, and thus probably all made by the same company. Cartridge Header The first 4 bytes of the title string at FFC0h do usually (or always) contain values 5C,xx,xx,80 (a "JMP FAR 80xxxxh" opcode, which jumps to the GAME entrypoint). The next 4 title bytes are sometimes containing another JMP FAR opcode, the rest of the header is unmodified header of the first game; except that [FFFCh] contains the MENU entrypoint. ROM-images ROM-images found in the internet are usually incomplete dumps, containing only the first 4MBytes (clipped to the maximum size for normal unmapped LoROM games), or only the first game (clipped to the ROM size entry of the 1st game header). Whilst, the actual multicarts are usually 8MBytes in size (there's one 4Mbyte cartridge, which is actually fully dumped). ROM Size Most cartridges seem to contain 8Mbyte ROMs. There is one 4MByte cartridge. And there's one cartridge that contains an 8Kbyte EPROM (plus unknown amount of ROM). LoROM/HiROM Most games seem to be LoROM. Eventually "Donkey Kong Land 3" is HiROM? Unknown if HiROM banks can be also accessed (dumped) in LoROM mode, and if so, unknown how they are ordered; with/without 32Kbyte interleave...? SRAM According to photos, most or all X-in-1 carts do not contain any SRAM. Though some might do so? DSPn According to photos, most or all X-in-1 carts do not contain any DSP chips. Though the "Super 11 in 1" cartridge with "Top Gear 3000" seems to require a DSP4 clone? Port FFFFxxh A0-A3 Bank Number bit0-3 (base offset in 256Kbyte units) A4 Bank Number bit4 (or always one in "1997 New 7 in 1") A5 Always 0 (or Bank bit4 in "1997 New 7 in 1") A6 Varies (always 0, or always 1, or HiROM-flag in "Super 7 in 1") A7 Always 1 (maybe locks further access to the I/O port) The bank number is somehow merged with the SNES address. As for somehow: This may be ORed, XORed, or even ADDed - in most cases OR/XOR/ADD should give the same result; in case of "1997 New 7 in 1" it looks as if it's XORed(?) The special meaning of A4-A5 can be detected by sensing MOV [FFFFnn],A opcodes (rather than normal MOV [FFFF00+x],A opcodes). The special meaning of A6 can be detected by checking if the selected bank contains a HiROM-header. Port 6FFFxxh Unknown. Some games write to both FFFFxxh and 6FFFxxh (using same data & address LSBs for both ports). Maybe the ROM bank address changed to 6FFFxxh on newer boards, and FFFFxxh was kept in there for backwards compatibility. Or maybe 6FFFxxh controls SRAM mapping instead ROM mapping? X-in-1 Cartridges Title FFFFxx 6FFFxx Size/Notes 8 in 1 and 10 in 1 C0-DF N/A 8MB (8 big games + 10 mini games?) 1997 New 7 in 1 D0-DF,F0-FF N/A ? MB Super 5 in 1 80-9F 80-9F 8MB Super 6 in 1 80-8F N/A 4MB Super 7 in 1 80-8F,D0 80-8F,D0 8MB? (mario all stars + 3 games) Super 11 in 1 80-9F N/A 8MB+DSP4 ? Chipset 7-in-1 (Board: SSF-07, REV.1) U1 16pin CIVIC CT6911 (CIC clone) U2 16pin 74LS13x or so (not legible on photo) U3 16pin whatever (not legible on photo) U4 14pin 74LS02 or so (not legible on photo) U5 black blob U6 black blob Chipset 8-in-1 (Board: MM32-2) U 20pin iCT PEEL18CV8P-25 U 16pin 93C26 A60841.1 9312 (CIC clone) U 42pin 56C001 12533A-A 89315 U 42pin 56C005-4X 12534A-A 89317 Chipset 8-in-1 (Board: NES40M, 20045) U 16pin CIVIC 74LS13 (CIC clone) U 16pin not installed U 28pin 27C64Q EPROM (8Kx8) U 20pin iCT PEEL18CV8P-25 U 42pin JM62301 U 42pin JM62305 SNES Cart Pirate X-in-1 Multicarts (2) -------------------------------------- There's at least one korean multicart (called "C20H" or "super20hab" or so), with 20 small games stored on a relative small 1Mbyte ROM. The games are NES games ported to work on SNES, some with typical pirate mods (like removing copyright strings, or renaming the game to bizarre names). I/O Ports 20xxh NES PPU left-overs (written to, but ignored by the SNES) 40xxh NES APU left-overs (written to, but ignored by the SNES) 8000h ROM Bank Size/Base Port 8000h works around as so: 0-4 ROM Base Offset (in 32Kbyte units) 5 Unknown/unused (always zero) 6-7 ROM Bank Size (0=Used/unknown, 1=Unused/Unknown, 2=1x32K, 3=2x32K) The ROM is mapped in LoROM fashion (with 1 or 2 banks of 32Kbyte). SRAM might also exist (the photo shows some unidentified 24pin chip). Component List PCB Name: Unknown (it has one, but isn't legible on lousy photo) 32pin C20H (1Mbyte ROM) 24pin Unknown (maybe SRAM) (there is no battery visible on PCB front side) 20pin Unknown (looks like a sanded chip; presumably memory mapper) 16pin CIVIC CTxxxx? (CIC clone) 46pin Cartridge Edge Connector SNES Cart Copiers ----------------- Copiers --> SNES Cart Copiers - Front Fareast (Super Magicom & Super Wild Card) --> SNES Cart Copiers - CCL (Supercom & Pro Fighter) --> SNES Cart Copiers - Bung (Game Doctor) --> SNES Cart Copiers - Super UFO --> SNES Cart Copiers - Sane Ting (Super Disk Interceptor) --> SNES Cart Copiers - Gamars Copier --> SNES Cart Copiers - Venus (Multi Game Hunter) --> SNES Cart Copiers - Others Misc --> SNES Cart Copiers - Misc Floppy Disc Controllers --> SNES Cart Copiers - Floppy Disc Controllers --> SNES Cart Copiers - Floppy Disc NEC uPD765 Commands --> SNES Cart Copiers - Floppy Disc FAT12 Format BIOSes --> SNES Cart Copiers - BIOSes See also --> SNES Cartridge ROM-Image Headers and File Extensions SNES Cart Copiers - Front Fareast (Super Magicom & Super Wild Card) ------------------------------------------------------------------- Front/CCL/Clones The Front Fareast I/O addresses are used by Front's own models, by early CCL models, and by some third-party clones: Super Magicom (Front/CCL) Super Wild Card (Front) Supercom Pro (CCL) (later CCL models use other I/O ports) Super Drive Pro-3 UFO (noname) (later UFO models use other I/O ports) I/O Ports (in banks 00h..7Dh and 80h..FFh) C000.R FDC Flags (Bit7: MCS3201 IRQ Signal, Bit6: Drive 'Index' Signal) Note: Index signal is (mis-)used for Disk Insert Check C002.W FDC MCS3201 Drive Control Register (motor on, etc.) C004.R FDC MCS3201 Main Status Register C005.RW FDC MCS3201 Command/Data Register C007.R FDC MCS3201 Diagnostics Register (bit7=disk change; MCS-chip only) C007.W FDC MCS3201 Density Select Register (bit0-1=Transfer rate) C008.R Parallel Data Input (Reading this register reverses busy flag) C008.W Parallel Data Output (bit0-3) and DRAM/SRAM mapping (bit0-1) Bit 0: 0=LoROM/Mode 20, 1=HiROM/Mode 21 (DRAM Mapping) Bit 1: 0=LoROM/Mode 1, 1=HiROM/Mode 2 (SRAM Mapping) C009.R Parallel Port Busy Flag, Bit 7 (older EP1810 Version) (Altera chip) C000.R Parallel Port Busy Flag, Bit 5 (newer FC9203 Version) (FRONT chip) C00A-C00F Unused (mirrors of C008h-C009h) C010-DFFF Unused (mirrors of C000h-C00Fh) Below E000h-E00Dh are triggered by writing any value E000.W Memory Page 0 ;\Select an 8Kbyte page, CART/DRAM/SRAM address is: E001.W Memory Page 1 ; SNES address AND 1FFFh ;lower bits E002.W Memory Page 2 ; +Selected Page * 2000h ;upper bits E003.W Memory Page 3 ;/ +SNES address AND FF0000h ;bank number E004.W Set System Mode 0 (BIOS Mode) (with all I/O enabled) E005.W Set System Mode 1 (Play Cartridge) (with all I/O disabled) E006.W Set System Mode 2 (Cartridge Emulation 1) (with E004-E007 kept on) E007.W Set System Mode 3 (Cartridge Emulation 2) (with all I/O disabled) E008.W Select 44256 DRAM Type (for 2,4,6,8 Mega DRAM Card) E009.W Select 441000 DRAM Type (for 8,16,24,32 Mega DRAM Card) E00C.W BIOS Mode:CART at A000-BFFF, DRAM Mode:DRAM in bank 20-5F/A0-DF E00D.W BIOS Mode:SRAM at A000-BFFF, DRAM Mode:CART in bank 20-5F/A0-DF Later Wild Card DX models have various extra ports, eg. E0FDh, F083h, C108h. Ports C00xh seem to be used by models up to DX and DX96. In DX2, Ports C00xh seem to be moved to CF8xh/DF8xh. System Mode 0 (BIOS Mode) (selected via E004h) bb2000-bb3FFF RW: SRAM or CART (E00C/E00D) bb-40-7D,C0-FF ;\8K page via bb8000-bb9FFF RW: DRAM bb-00-7D,80-FF ; E000-E003 bbA000-bbBFFF RW: SRAM or CART (E00C/E00D) bb=00-7D,80-FF ;/ bbC000-bbC00x RW: I/O Ports bb=00-7D,80-FF bbE000-bbE00x W : I/O Ports bb=00-7D,80-FF bbE000-bbFFFF R : BIOS ROM (8/16/256Kbytes) bb=00-1F System Mode 1 (CART Mode) (selected via E005h) bb0000-bbFFFF RW: CART System Mode 2/3 (DRAM Modes) (selected via E006h/E007h) bb0000-bb7FFF R : DRAM Mapping, bb=40-6F, C0-DF. (HiROM/Mode 21) bb8000-bbFFFF R : DRAM Mapping, bb=00-6F, 80-DF. (AnyROM/Mode 20,21) 708000-70FFFF RW: SRAM Mode 1 Mapping. ;<-- typically for LoROM 306000-307FFF RW: SRAM Mode 2 Mapping, Page 0. ;<-- typically for HiROM 316000-317FFF RW: SRAM Mode 2 Mapping, Page 1. ;\extra banks for HiROM 326000-327FFF RW: SRAM Mode 2 Mapping, Page 2. ; (do any 'real' cartridges 336000-337FFF RW: SRAM Mode 2 Mapping, Page 3. ;/do actually have that?) DRAM mapping (LoROM/HiROM), and corresponding SRAM mapping are selected via (sharing) Bit0-1 of the Parallel Data Output (Port C008h.W) HiROM/Mode 21: Even DRAM Bank is mapped to bb0000-bb7FFF. Odd DRAM Bank is mapped to bb8000-bbFFFF. Optionally, banks 20-5F and A0-DF can be mapped to CART instead of DRAM (via E00Dh), probably intended to allow ROM-images in DRAM to access DSP chips in CART. BIOS Notes Observe that the BIOS is divided into 8Kbyte banks (so, the exception vectors are at offset 1Fxxh in the ROM-image) (however, there are some overdumped ROM-images that contain 24K padding prior to each 8K ROM-bank, ie. with LoROM mapping style exception vectors at offset 7Fxxh). Aside from the exception vectors, there isn't any title, nor other valid cartridge header entries. Note: Unlike most SNES programs, Magicom & Wild Card (until v1.8) BIOSes are running in 6502 emulation mode (with E=1), rather than 65C816 mode (with E=0). Parallel Port Protocol (on SNES side) Data is received via 8bit data register, and sent via 4bit "status" register (which is seen as status on PC side). Strobe/busy aren't clearly documented in official Front specs; probably, Busy gets set automatically when sensing Strobe (from PC side), and gets cleared automatically when reading Data from Port C008h (on SNES side). Parallel Port Protocol (on PC side) Byte Output Procedure: Wait Busy Bit = 1 ;Status PC Port 379h/279h/3BDh.Bit7 Write One Byte ;Data PC Port 378h/278h/3BCh.Bit0-7 Reverse Strobe Bit ;Control PC Port 37Ah/27Ah/3BEh.Bit0 Byte Input Procedure: Wait Busy Bit = 0 ;Status PC Port 379h/279h/3BDh.Bit7 Read Low 4 Bits of Byte ;Status PC Port 379h/279h/3BDh.Bit3-6 Reverse Strobe Bit ;Control PC Port 37Ah/27Ah/3BEh.Bit0 Wait Busy Bit = 0 ;Status PC Port 379h/279h/3BDh.Bit7 Read High 4 Bits of Byte ;Status PC Port 379h/279h/3BDh.Bit3-6 Reverse Strobe Bit ;Control PC Port 37Ah/27Ah/3BEh.Bit0 Receiving 4bit units via status line is done for compatibility with old one-directional PC parallel (printer) ports. Unknown if "Wait Busy Bit = X" means to wait while-or-until Bit=X? Parallel Port Command Format Commands are 9-bytes in length, sent from PC side. 00h 3 ID (D5h,AAh,96h) 03h 1 Command Code (00h-01h, or 04h-06h) 04h 2 Address (LSB,MSB) 06h 2 Length (LSB,MSB) 08h 1 Checksum (81h XORed by Bytes 03h..07h) Followed by bytes of data (upload/download commands only) Commands can be: Command 00h : Download Data (using page:address,length) ;to-or-from PC? Command 01h : Upload Data (using page:address,length) ;from-or-to PC? Command 04h : Force SFC Program to JMP (to address... plus page/bank?) Command 05h : Select 8Kbyte Memory Page Number (using address) Command 06h : Sub Function (address: 0=InitialDevice: 1=ExecDRAM, 2=ExecCART) InitialDevice does probably reset the BIOS? ExecDRAM allows to run the uploaded ROM-image, but unknow how to select LoROM/HiROM mode, or is it automatically done by examining the uploaded cartridge header. The usage of the 16bit address isn't quite clear: The lower 13bit are somehow combined with the 8Kbyte page number, the upper 3bit might be used to select DRAM/SRAM? Super Magicom V3H - BIOS upgrade This ROM-image is a Magicom BIOS upgrade, and it's a pain in the ass: The upgrade works ONLY as ROM-image (ie. must be loaded to DRAM), and does NOT work as real ROM (ie. cannot be burned to EPROM), the reason is that it doesn't include a character set (and uses that from the original Magicom BIOS at E000h). The upgrade isn't compatible with the parallel port (the original BIOS relocates parallel port code from ROM to WRAM, and the upgrade relocates itself from DRAM to WRAM - but still expects the parallel port code in the same WRAM location and crashes when Busy-bit gets set). The upgrade exists as 32Kbyte or 32.5Kbyte ROM-image (an 8K upgrade, 24K garbage with entrypoint at end of garbage, plus 0.5K extra garbage), emulators and other tools will be typically interprete the 32.5K file as 32Kbyte ROM with 512-byte header (which is NOT correct in that special case). The upgrade exists in two variants: One using the standard Front Fareast I/O addresses, one using the I/O addresses at C000h-C00Fh re-ordered as so: 8000h-FFFFh RW DRAM-mode: DRAM (containing the Magicom V3H upgrade) E000h-FFFFh R BIOS-mode: BIOS (containing the Character set) C000h W DRAM bank mapped to 8000h? (set to 00,20,40 upon DRAM detect) C001h W Memory Control? C002h - Unused C003h R Parallel Port Busy (bit7) (when set: crashes the V3H upgrade) C004h-C008h - Unused C009h R Status (bit7=ready?,bit5=busy/timeout?) C00Ah - FDC Unused C00Bh W FDC Motor Control (set to 00h,29h,2Dh) C00Ch RW FDC Command/Data C00Dh R FDC Main Status C00Eh W FDC Transfer Rate? (set to 00h,01h,02h or so) C00Fh - FDC Unused E004h W Map BIOS ROM (instead V3H upgrade) ;\ E006h-E007h W Something on/off ; seems to be same/similar E008h-E009h W Something on/off ; as Front-like I/O ports E00Ch-E00Dh W Something on/off ;/ Unknown which hardware uses that re-ordered addresses. Note: The V3H version with re-ordered I/O addresses does also contain different 24K garbage (sorts of as if it were created from original source code, rather than just patched?). Component List - Super Magicom Plus U1 24pin DRAM (onboard) U2 20pin SN74LS245N (8-bit 3-state transceiver) U3 24pin DRAM (onboard) U4 24pin DRAM (onboard) U5 24pin DRAM (onboard) U6 28pin 27C128-25 EPROM (16Kx8) U7 68pin MCCS3201FN (=MCS3201FN without double-C) (disc controller) U8 100pin ? U9 28pin HM62256 (SRAM 32Kx8) U10 20pin ? U11 14pin ? (does not exist in later versions?) U12 20pin AMI 16CVB8PC-25 U13 20pin AMI 16CVB8PC-25 U14 16pin ST10198S (newer version only) (mounted on top of U10 in old ver) BT1 2pin ? J1 25pin DB-25 parallel port J2? 25pin DB-25 external floppy (not installed) J3 40pin DRAM expansion board J4 34pin internal floppy (flat cable) J5 26pin (not installed) J6 4pin floppy power supply J7 62pin cartridge edge J8 62pin cartridge slot J9 12pin jumpers (I:I:I: or :I:I:I) (enable internal or external CIC) Y1 2pin 24.000 MHz Component List - Super Wild Card DX (AH-558001-02 Made in Japan 94.8.23) U1 100pin CPU FRONT FC9203 HG62E22926F9 (or so) (SMD) U2 28pin S-RAM NEC D43256AC-10L (uPD43256AC) (SRAM, 32Kx8) U3 20pin SN74LS245 (to parallel port) (8-bit 3-state transceiver) U4 ?pin PAL-2 L GAL20V84 25LP U5 20pin SN74LS...? (or so) U6 32pin BIOS-ROM BIOS U7 16pin U7 SN74LS139AN (decoder/demultiplexer) U8 14pin U8 SN74LS125AN (quad 3-state buffer) U9 44pin GoldStar GM82C765B (SMD) (floppy disc controller) U10 16pin DECODER SNC4011 (or so) U11 20pin PAL-3 iCT PEEL17CV8P CTN24053 U12? 3pin 7805H voltage regulator U13 20pin PAL-1 AMI X1 2pin 16MHZ 16.000 MHz CN? 2pin AC/DC-IN power supply input CN? 4pin ..POW power supply to internal disc drive (only 2pin connected) CN2 62pin female cartridge slot CN3? 46pin RAM-SLOT to DRAM daughterboard (only 40pin used on remote side) CN5 25pin PC-I/F DB-25 parallel port CN6 34pin FDD-I/F cable to internal disc drive CN01 34pin goes to one 1st of male 62pin cartridge edge CN02 34pin goes to one 2nd of male 62pin cartridge edge SW1 3pin RESET-SW reset switch/button or so, for whatever purpose DB1 4pin AC-DC converter BT1 2pin 3V battery J1 12pin jumpers (near cartridge slot) J2 20pin jumpers (near cartridge slot) J3 2pin jumper (near power-input) J4 2pin jumper (near power-input) J5 2pin jumper (near power-input) DRAM Daughterboard: U1,U2,U7,U8 16pin ST T74LS139B (decoder/demultiplexer) (four pieces) U3-U6,U9-U10 28pin NEC D424900G5 (or so) (six pieces) (SMD) U11-U12 28pin M5M44800ATP (two pieces) (SMD) Component List - Supercom Pro (SP3200) (dated around 1992) (probably uses Front-like I/O) U1 20pin SN74LS245N (to parallel port) (8-bit 3-state transceiver) U2 16pin HD74LS174 (to parallel port?) U4 68pin MCCS3201FN (=MCS3201FN without double-C) (floppy disc controller) U? 68pin Altera EP1810LC-45 D9219 U? 28pin EPROM U? 28pin SRAM Winbond W24256-10L 9149 U7 20pin SN74LS245N (8-bit 3-state transceiver) U8 16pin not installed U? 20pin modded (?) chip (soldered on cart-edge connector at bottom side) J1 25pin DB-25 parallel port J2 25pin DB-25 external floppy disc connector J3 40pin to DRAM daughterboard J4 34pin not installed (internal floppy disc connector) J5 62pin cartridge edge J6 62pin cartridge slot Y1 2pin 24.000 MHz BT1 2pin VARTA Ni/Cd, 3.6V 60mA, 14h 6mA (recharge-able & acid-leaking) Component List - SMD800 Super Magic Drive (requires SNES-to-Genesis adaptor) U1 20pin SN74LS245N (to parallel port?) (8-bit 3-state transceiver) U2 16pin SN74LS174 (to parallel port?) U3 20pin SN74HC245P (8-bit 3-state transceiver) U4 20pin SN74HC245P (8-bit 3-state transceiver) U5? 68pin MCS3201FN (floppy disk controller) U6 20pin SN74HC245P (8-bit 3-state transceiver) U 28pin 27C64A-15 (EPROM, 8Kx8) (with Genesis Z80 code, non-SNES code) U 28pin HY62256ALP-10 (SRAM, 32Kx8) U pin Altera EP1810LC-45 U10 16pin MC74HC157 (decoder/demultiplexer) U11 16pin MC74HC157 (decoder/demultiplexer) U12 14pin xxxx J 25pin DB-25 parallel port J2 25pin DB-25 external floppy J3 40pin internal floppy (not installed) (likely only 34pins of 40pin used) J 64pin cartridge edge (genesis) J 64pin cartridge slot (genesis) J 40pin to DRAM daughterboard Y 2pin oscillator BT 2pin VARTA Ni/Cd, 3.6V 60mA, 14h 6mA (recharge-able & acid-leaking) DRAM Daughterboard: U1 20pin HY514400J-70 (DRAM) U2 20pin HY514400J-70 (DRAM) U3 20pin HY514400J-70 (DRAM) U4 20pin HY514400J-70 (DRAM) U5 14pin 74LS08 (quad 2-input AND gates) U6 16pin HD74LS157P (decoder/demultiplexer) U7 14pin 74LS08 (quad 2-input AND gates) CN1 40pin connector to mainboard Super Magicom-Drive (SNES-to-Genesis adaptor for above): xxx components unknown SNES Cart Copiers - CCL (Supercom & Pro Fighter) ------------------------------------------------ Below is for Supercom Partner & Pro Fighter models from CCL (China Coach Limited). See the Front Fareast chapter for their earlier Super Magicom models (which were produced by Front & CCL), and also for Supercom Pro 2 (which was made by CCL alone, but still used the Front-like I/O ports). Pro Fighter 1993 by H.K. / Supercom Partner A Ports are somewhat based on the Front design (BIOS is expanded from 8K at E000h-FFFFh to 16K at C000h-FFFFh, accordingly FDC Ports C000h-C007h are moved to 2800h-2807h, and Parallel Port Ports C008h-C009h are simply removed. Ports at E00xh are somehow changed, but might be still similar to the Front design (?) 2800.R FDC MCS General Purpose Input (bit7,bit6 used) 2802.W FDC MCS Motor Control (set to 00h,29h,2Dh) 2804.R FDC MCS Main Status 2805.RW FDC MCS Command/Data Status 2807.W FDC MCS Transfer Rate/Density (set to 0..3) Below 2808-2810 only in newer "Pro Fighter Q" 2808.R Parallel Port Data (bit0-7) 2809.W Parallel Port Data (4bit or 8bit?) 2810.R Parallel Port Busy (bit5) (there seem to be 4bit & 8bit parallel port modes supported, one of them also WRITING to 2808h, and in some cases reading "FDC" register 2800 looks also parallel port DATA and/or BUSY related) Again changed for Double Pro Fighter 2803.R Parallel Port Busy (bit7) 2808.R Parallel Port Data (bit0-7) 2809.W Parallel Port Data (4bit or 8bit?) 2804 =FDC DATA ;\swapped ! (unlike older "non-double" models) 2805 =FDC STAT ;/ 280x =other ports in this region may be changed, too ? 004800 ROM (from offset 8800-9FFF) (contains program code) 014800 ROM (from offset A800-BFFF) (contains character set) E00x E800+x Note: Having BIOS portions mapped to the fast 3.58MHz region at 4800h-5FFFh was probably done unintentionally; this would require 120ns EPROMs, whilst some Double Pro Fighter boards are fitted with 200ns EPROMs (which are stable at 2.68MHz only, and may cause crashes, or charset glitches in this case) Double Pro Fighter BIOS is 64Kbytes: 0000-3FFF Genesis/Z80 BIOS 4000-7FFF Same content as 0000-3FFF 8000-87FF Unused (zerofilled) 8800-9FFF SNES BIOS (6K mapped to 004800-005FFF) A000-A7FF Unused (zerofilled) A800-BFFF SNES BIOS (6K mapped to 014800-015FFF) C000-FFFF SNES BIOS (16K mapped to 00C000-00FFFF) 7000.R A000.RW ;7000-related C000-FFFF.R BIOS ROM (16Kbytes) E002.W set to 00h ;7000-related E003.W set to BFh ;then compares BFFD with BFFC,BFFA,BFFB,BFEA,BFEB E00C.W set to 00h ;7000-related E00E.W set to E0h 008000.RW DRAM detection? 208000.RW DRAM detection? 408000.RW DRAM detection? 608000.RW DRAM detection? SNES Cart Copiers - Bung (Game Doctor) -------------------------------------- Game Doctor SF7 Memory Map (in BIOS mode) 00:8000-807F I/O Ports 00:8080-FFFF BIOS ROM (1st 32kBytes) 01:8000-FFFF BIOS ROM (2nd 32kBytes) (if any) 02:8000-FFFF unused 03:8000-FFFF unused 04:8000-FFFF SRAM for game positions (32Kbyte) 05:8000-FFFF SRAM for real time save data (4kByte) 06:8000-FFFF SRAM for copier settings (4kByte) 07:8000-FFFF DRAM for ROM-image (32Kbyte page, selected via Port 8030h) 08-7D:8000-FFFF Mirror of above banks 00-07 80-FF:8000-FFFF Mirror of above banks 00-07 or Cartridge banks 00-7F/80-FF FFBFh compared to FFh ? I/O Ports (in BIOS mode) in bank 00h 8000h-800Fh RW 512Kbyte DRAM chunk, mapped to upper 32Kbyte of Bank 0xh-Fxh 8010h-8013h RW 512Kbyte DRAM chunk, mapped to lower 32Kbyte of Bank 4xh-7xh 8014h-8017h RW 512Kbyte DRAM chunk, mapped to lower 32Kbyte of Bank Cxh-Fxh 8018h-8019h W SRAM Flags (bit0-15=Enable SRAM at 6000-7000 in banks 0xh-Fxh) 8018h R bit1 = realtime.$4016.bit0, read bit7 = ? , bit = ? 8018h.R Flags (bit7/6 FDC IRQ?, and more) 8019h R bit1 = ? 801Ah R realtime.word, latch settings for double write word registers 801Ah W write ? 801Bh W write ? 801Dh W BIOS mode mapping: changes what is mapped into banks $80-$FF only bit0-bit1 seem to matter 0 = use cartridge banks $00-$7F 1 = use cartridge banks $80-$FF 2 = mirror banks $00-$7F (BIOS regs and all?) 3 = mirror banks $00-$7F (BIOS regs and all?) 801Eh write ? __Floppy Disc__ 8020h R FDC Main Status 8021h RW FDC Command/Data 8022h W FDC Transfer Rate/Density (?) (set to 00h,01h) 8023h - FDC Unused 8024h W FDC Motor Control (set to 00h,08h,0Ch,1Ch,2Dh) 8025h-8027h - FDC Unused 8028h W set to same value (ANY VALUE?) as 8022/8029) 8029h W set to same value (ANY VALUE?) as 8029) 802Ah W set to 01-then-00 (once) (thereafter do sth to 8022) 802Bh W set to 01h during FDC COMMAND-BYTEs (else to 00h) (maybe LED?) __Parallel Port__ 802Ch RW Parallel Port Data Lines 802Dh RW Parallel Port Status Lines 802Eh RW Parallel Port Control Lines 802Fh W Parallel Port? Unknown (set to 00h,01h) (data direction?) 802Fh R Parallel Port? Unused (reads same as $00802D) __Memory__ 8030h-8031h W Select 32Kbyte-DRAM-Page (0000h..01FFh) mapped to 078000h 8030h-803Dh R this is a 7 word table?? (gotten from code at 80/AE80) 8040h-805Fh R read same as 802Dh (uh, but, some are used for sth else?) 8040h R used, parallel port related (or other mainboard version?) 8043h W used, parallel port related (or other mainboard version?) 8060h-807Fh R read = FFh 80xFh any access to 0080xFh (x=8..F) switches to cartridge mode 802Dh - Parallel Port status (not direct pin reading?) read bit0 = /C1 (direct pin14, /AutoLF) (/Ctrl.Bit1 on PC side) bit1 = C2 (direct pin16, /INIT) (Ctrl.Bit2 on PC side) bit2 = /C3 (direct pin17, /Select) (/Ctrl.Bit3 on PC side) bit3 = "write bit3" bit4 = "write bit4" bit5 = "write bit4" (uh, not bit5 here?) bit6 = "write bit4" (uh, not bit6 here?) bit7 = /S7 (direct pin11) = "write bit7" AND not "write bit0" write bit0 Enable/Disable Busy bit (0=Enable, 1=Disable) (?) bit3 => S3 (direct pin15, /ERR) (Stat.bit3 on PC side) bit4 => S4 (direct pin13, SLCT) (Stat.bit4 on PC side) bit5 => S5 (direct pin12, PE) (Stat.bit5 on PC side) bit6 => S6 (direct pin10, /ACK) (Stat.bit6 on PC side) bit7 ... (direct pin11, BUSY (/Stat.bit7 on PC side) (ANDed with /bit0?) 802Eh - Parallel Port control (not direct control reg values) often write 12h-then-10h read/write? bit0 = /C1 (direct pin14, /AutoLF) (/Ctrl.Bit1 on PC side) W bit1 = C2 (direct pin16, /INIT) (Ctrl.Bit2 on PC side) W bit2 = /C3 (direct pin17, /Select) (/Ctrl.Bit3 on PC side) W bit3-bit6, read = bit3-bit6 of $00802D W bit7 = /C0 (direct pin1, /STB) (/Ctrl.bit0 on PC side) R Component List - Bung Game Doctor SF6 (Board CT401) U 3pin 7805 or so U 40pin GoldStar xxx (=probably GM82C765B) (floppy disc controller) U ???pin huge chip (200 pins or so) U 18pin 265111 U 20pin 74LS744 or so (not installed) U 28pin SRAM or so U 28pin SRAM or so U 28pin EPROM (GDSF_6.0) U 14pin whatever/modded chip (wired top-down near EPROM) P 40pin to DRAM daughterboard 1 (2x10 male pins, 2x10 female pins) P 40pin to DRAM daughterboard 2 (2x10 male pins, 2x10 female pins) P 62pin cartridge port P 62pin cartridge port (on PCB back side) P 25pin DB-25 parallel port (on PCB back side) P 2pin power supply (on PCB back side) P 2pin floppy supply (on PCB back side) P 34pin floppy data X 2pin oscillator SNES Cart Copiers - Super UFO ----------------------------- UFO Super Drive Pro / Super UFO UFO3 The UFO-3 is a Front Fareast clone. BIOS is 8Kbytes mapped to E000h-FFFFh, FDC Registers are at C000h-C007h, Parallel Port at C008h-C009h, Memory Control at E000h-E00Dh. For details see Front Fareast chapter. UFO6 I/O ports for this version are unknown. UFO7/UFO8 2184.W ... set to 00h/0Ch/0Fh 2185.W ... set to 00h/0Fh 2186.W ... set to 00h/0Fh 2187.W ... set to 08h/00h/0Bh 2188.W ... set to 00h..0Fh or so 2189.W ... set to 0Fh/0Eh 218A.W ... set to 00h 218B.W ... set to 0Ah/0Fh 218C.R FDC Main Status Register 218D.RW FDC Command/Data Register (emit 03h,DFh,03h = spd/dma)(then 07h,01h) 218E.W FDC Motor Control (set to 00h, 29h-then-2Dh on disc access) 218F.W FDC Transfer Rate 218F.R FDC Flags (bit7=irq?,bit6=index?) (UFO8: bit5=?) 003F68.R warmboot flag? if A581 --> JMP 3D00 003FD0..3FFF cartridge header? (or copy of it?) 003C00..003FFF SRAM 1Kbyte (BIOS settings, I/O logging?, last 32-byte OAM) 013C00..013FFF SRAM 1Kbyte (512-byte Palette and 1st 512-byte OAM) 008000h and up BIOS 64Kbytes (UFO7) or more 128K..256K (UFO8) 708000h and up SRAM 32Kbytes (for game positions) 808000h and up DRAM (variable size detected) (via calls to 9025) ufo7 rom chksum calculated at 9505 (32K ROM at 8000-FFFF must sum up to 00h) ufo8 (and maybe ufo7 too) should have 8K SRAM (ie. MORE than above 2x1K...?) UFO6 Component List - UFO Super Drive Pro (with Pro-6 BIOS) U 3pin 7805 or so U ?pin xxxx (near 7805) U 40pin GoldStar GM82C765B U 14pin xxxx U 20pin L GALxxxx U 20pin L GALxxxx U 20pin L GALxxxx U 20pin AMI xxxxx U 20pin L GALxxxx U 20pin L GALxxxx U 20pin L GALxxxx U 20pin L GALxxxx U 20pin LS245 (not installed, near DB-25) (8-bit 3-state transceiver) U 14pin HC74 (not installed, near DB-25) (dual flip-flop) U 16pin xxxx (installed, near DB-25) U 28pin EPROM U 28pin Winbond W24256-10L (SRAM 32Kx8) U 20pin Philips PC74xxxx U 16pin 74LS112 (reportedly a cloned/mislabelled CIC chip) X 2pin oscillator (near 7805) BT 2pin 3V or so P 25pin DB-25 parallel port or so P 2pin power supply P 2pin floppy supply P 34pin floppy data P 40pin to DRAM daughterboard P 46pin cartridge slot (only 46 soldering points) P 62pin cartridge edge (has 62 soldering points, but only 46 connected?) UFO8 Component List Super UFO Super Drive PRO8 (REV 7.8 2) 1x 84pin Altera EPMxxxxxxx84-15 1x 40pin GoldStar GM82C765B (DIL) (floppy disc controller) 1x 32pin BIOS ROM/EPROM (located on PCB solder side) 1x 28pin UM62256D-70L (SRAM 32Kx8) 1x 28pin UT6264PC-70LL (SRAM 8Kx8) 1x 28pin DSP chip (not installed) 2x 24pin NN5117405BJ-60 (DRAM, two pieces, located on daughterboard) 1x 16pin D1 1x 14pin FT4066 1x 14pin DSP_74HC74 (not installed) (dual flip-flop) 1x 14pin 74LS00 or so 1x 14pin whatever (near oscillator) 1x 14pin 74LSxxx whatever (near PAL/NTSC jumpers) 2x 16pin SN74HC157N (decoder/demultiplexer) 1x 3pin 7805 or so 1x 34pin connector/cable to internal disc drive 2x 62pin cartridge connectors (one male, one female) 1x 2pin wire (supply to internal disc drive) 1x 2pin connector (external power supply input) no battery, no parallel port SNES Cart Copiers - Sane Ting (Super Disk Interceptor) ------------------------------------------------------ The Super Disk Interceptor is a SNES copier from KL818 B.C./Sane Ting Co. Ltd., the company also made a copier for Mega Drive, called Mega Disk Interceptor. I/O & Memory 8000-9FFF memory (SRAM/DRAM or so) A000.W set to 00,03-then-01, or 40,80 A001.W set to 00,04 (as MSB of A000) or to 04,24,08 A001.R tests bit4,bit5 A002.W FDC Transfer Rate/Density (set to ([0B] XOR 1)*2) A003.W FDC Motor Control (set to 08,0C,1C) A004 FDC Unused A005.RW FDC Command/Data A006.R FDC Main Status A007 FDC Unused A008.W set to [1802] (bit3,bit4 used) B000-B01F ... I/O or RAM or RegisterFile workspace? B000.W set to 00 B000.R checked if 00h B001.W set to 00 B002.W set to xx OR 80h B002.R read and ORed with 06h B003.W set to xx OR 80h OR 03h B003.R bit5 isolated, ORed with 04h, then written to A001h B004.W set to 00 or 00..03h B004.R whatever, if (N+1)=00..03 --> written to B004 and B005 B005.W set to 00 B006.RW set to [4219h] = MSB of joypad1 (?) B00F.W set to [FFDC]=00h or ([FFDC] XOR 1)=01h B00F.R checked if 00h (if nonzero --> WRITE PROTECT) B01x ... C000.R dummy read within waitvblank C001.R dummy read within waitvblank E000.W E001.W E002.W E000-FFFF BIOS (32Kbytes, in 8Kbyte units, in banks 00h-03h) 704000 708000 Component List - Super Disk Interceptor (version dated around 1992) U1 40pin GoldStar GM82C765B PL (DIP) (floppy disk controller) U2 84pin MD1812 9211 (with socket) U3 28pin 2xxx4A-25 (PROM, presumably 8Kx8, non-eraseable) U4 20pin not installed (DIP) (BANK2.3) U4A 20pin not installed (DIP) (BANK2.3) U5 20pin GoldStar GMxxxxx (SMD) (BANK0.1) (DRAM) U5A 20pin GoldStar GMxxxxx (SMD) (BANK0.1) (DRAM) U6 28pin Hyundai HY62256ALP-10 (SRAM, 32Kx8) U7 20pin not installed (DIP) (BANK2.3) U7A 20pin not installed (DIP) (BANK2.3) U8 20pin GoldStar GMxxxxx (SMD) (BANK0.1) (DRAM) U8A 20pin GoldStar GMxxxxx (SMD) (BANK0.1) (DRAM) U9 16pin 74HC157N (decoder/demultiplexer) U10 16pin 74HC157N (decoder/demultiplexer) U11 20pin HY-xxxxxx-30 U12 20pin HY-xxxxxx-30 XTAL 2pin 16.000MHz J 46pin Cartridge edge (snes) J 46pin Cartridge slot (snes) J 34pin Floppy data J 2pin Floppy supply BT 2pin 3.6V Battery Component List - Super Disk Interceptor (version dated around 1993) U 44pin GoldStar GM82C765B PL (SMD) (floppy disk controller) U 28pin 27C64SDM (PROM, 8Kx8, non-eraseable) U 28pin GoldStar GM76C256ALLFW70 (SRAM, 32Kx8) U 20pin HD74HC373P (8-bit 3-state transparent latch) U 14pin xxxx U 80pin SD1812 349 (SMD, without socket) U 14pin not installed U 28pin KM48C2100J-7 (DRAM, 2Mx8) ;\ U 20pin KM44C1000CJ-6 (DRAM, 1Mx4) ; all installed, U 20pin KM44C1000CJ-6 (DRAM, 1Mx4) ; together = 4Mx8 U 20pin KM44C1000CJ-6 (DRAM, 1Mx4) ; U 20pin KM44C1000CJ-6 (DRAM, 1Mx4) ;/ X 2pin 16.000MHz X 2pin 16.257MHz J 46pin Cartridge edge (snes) J 46pin Cartridge slot (snes) J 34pin not installed (alternate floppy connector?) J 34pin Floppy data J 2pin Floppy supply BT 2pin 3.6V Battery SNES Cart Copiers - Gamars Copier --------------------------------- Known as: ALMA Super Disk F-16 Gamars Super Disk FC-301 FR-402 Super Disk (bundled with "FR-402 Super 16bit" SNES clone) 2K SRAM at 005000 with REQUIRED mirror at 005800 3F5Fxx.W set to FFh,FFh,FFh... 3F5FC0.R FDC stat (bit7,bit5) 3F5FD2.W FDC motor? (set to 0Ch,1Ch,08h,0Ch) 3F5FE4.R FDC Main Status 3F5FED.RW FDC Command/Data (emit 03,DF,03) Gamars Puzzle Aside from the Gamars BIOSes, there's a mis-named ROM-image in the internet: "Gamars (Copier BIOS)", this file is made by the same company, but it's a Puzzle game, not a copier BIOS. SNES Cart Copiers - Venus (Multi Game Hunter) --------------------------------------------- MGH (Multi Game Hunter) from Venus. The 32Kbyte BIOS contains both SNES/65C816 code (entrypoint at [FFFCh]) and Genesis/Z80 code (entrypoint at 0000h). 006000..007FFF -- RAM or so 035800..035807 -- I/O Ports --- 006400.R id "SFCJ" 007D00..007EFF.R checksummed 035800.W set to C0h 035801.W set to A0h 035802.W set to 0000h or 06h 035803.W set to 04h 035804.R disk status? (bit7,bit6) 035805.W disk command? (set to 0Bh) (not a uPD765 command?) 035806.W set to 00h or ([AAh] ROR 1) 035807.W set to 00h or [ABh] FDC Accress via 80C51 CPU Like many other copiers, the MGH does use a "normal" MCS3201FN controller, but, it does indirectly access it through a 80C51 CPU. For example, 05 cmd (write sec) ;\ [0B6B] track ;\less parameters as than ; write sector [0BA4] head ; directly accessing a uPD765 ; command [0BA2] sector ;/ ; (at PC=CBAFh) [[18]+y] data... (200h bytes) ;/ SNES Cart Copiers - Others -------------------------- Component List - Board "GP-003 REV. B" (used in Special Partner) U 14pin GD74HC04 (hex inverters) U 16pin LR74HC158 (decoder/demultiplexer) U 16pin LR74HC158 (decoder/demultiplexer) U 16pin GD74HC138 (decoder/demultiplexer) U 16pin GD74HC138 (decoder/demultiplexer) U 20pin PALCE16V8H-25 U 28pin K-105 ;DSP clone? U 28pin EPROM (28pin 27C512 64Kx8 installed, optionally 32pin possible) U 28pin NEC D43256BGU-70L (uPD43256BGU) (SRAM 32Kx8) U 28pin NEC 4364C-20L (SRAM 8Kx8) U 44pin GoldStar GM82C765B PL (SMD) U 44pin Lattice ispLSI 1016-60LJ B501B06 (SMD) U 3pin 7805 or so J2 62pin to cartridge edge (snes) J 62pin cartridge slot (snes game cartridge) J 62pin cartridge slot (an expansion slot, not for any game carts) J 40pin to DRAM daughterboard J 34pin to internal floppy drive J2 2pin floppy power supply J 2pin external power supply J6 2pin jumper (near 34pin floppy cable) J8 3pin jumper (near EPROM; maybe ROM size select?) X 2pin oscillator (160) X 2pin oscillator (?) ;DSP clock? BT 2pin NiCd 3.6V The board doesn't contain a CIC-clone (unless it's 'hidden' in one of the chips). Components - Supercom, 24m DSP, CD-ROM, FX-32, High Density, Real Time Save U1 40pin GoldStar GM82C765B (floppy disc controller) U2 20pin 16V8 (not installed) U3? 20pin PALCE16V8H-25PC/4 U4 24pin PALCE20V8H-25PC/4 U5 28pin not installed (probably for DSP clone) U6? 14pin xxx (below U5) U7? 20pin LS245 (not installed) (8-bit 3-state transceiver) U8? 24pin PALCE20V8H-25PC/4 U9 20pin 74HC273 (8bit latch with reset) U10 28pin 27C256G-20 (EPROM 32Kx8) (boots as "FX-32 CD-ROM & DSP, 1994 H.K.") U11 28pin ST MK4864 (SRAM 8Kx8) U12 28pin xxx (SRAM ?Kx8) U13 20pin xxx U14 20pin xxx U15 20pin xxx U16 20pin xxx U17 20pin xxx U18 20pin xxx U19 ?pin Toshiba xxx (16pin chip, mounted in a 20pin socket) U20 16pin ST101xxx Q1 3pin 7805 Y1 2pin oscillator Y2 2pin oscillator (not installed, probably for DSP chip) J? 34pin floppy data J? 2pin floppy power J? 2pin power supply J3? 25pin DB-25 (parallel port and/or external CD-ROM drive?) J4 62pin cartridge edge J5 62pin cartridge slot J6 40pin to DRAM daughterboard Component List - Double Pro Fighter (CCL) (1994) U1 28pin Hyundai HY62256ALP-10 (SRAM 32Kx8) U2 28pin AM27C512-205DC (EPROM 64Kx8) U3 N/A N/A U4 N/A N/A U5 20pin HD74LS245P (8-bit 3-state transceiver) U6 20pin HD74LS245P (8-bit 3-state transceiver) U7 20pin HD74LS245P (8-bit 3-state transceiver) U8 24pin GoldStar GM76C28A-10 (SRAM 2Kx8) U9 16pin noname-chip-without-part-number (or, marked 10198 on other boards) U10 3pin AN7805 (voltage regulator) U11 14pin HD74HC00P (quad 2-input NAND gates) U12 40pin Goldstar GM82C765B (floppy disc controller) U13 68pin Altera EP1810LC-45 D9407 U14 16pin 74HC139 (decoder/demultiplexer) U15 24pin PALCE20V8H U16 20pin GAL16V8xxx U17 20pin PALCxxx U18 16pin 74HC139 (decoder/demultiplexer) Y1 2pin 16.00 TDX (16 MHz oscillator) J1 2pin power supply input J2 2pin power supply connector (alternately to J1 or so, not installed) P4 50pin ro dram daughterboard ? SL1 64pin connector for remove-able snes-or-sega? cartridge edge SL2 64pin connector for remove-able sega-or-snes? cartridge edge SL3 62pin cartridge slot (snes) SL4 64pin cartridge slot (sega genesis) ? 2pin connector for disc drive (supply) ? 34pin connector for disc drive (data) DRAM Daughterboard - 40pin connector (to 40pins of the 50pin socket on Double Pro Fighter) - 20pin NEC 424400-80 (EIGHT pieces) Optional Parallel Port (plugged into SL3-socket, ie. into SNES slot): U1 20pin PALCE16V8H-25PC/4 U2 20pin HD74HC245P (8-bit 3-state transceiver) (no latch here ???) P1 25pin DB-25 parallel port connector - 62pin cartridge edge (to be plugged into SL3 of Double Pro Fighter) Component List - Super Smart Disc (same as Pro Fighter X?) U 16pin 10198 U 28pin GRAPHIC DSP1-1 (or is it "DCP1-1" or so?) U 28pin STxxxx (SRAM, ?x8) U 28pin xxxxxx (SRAM, ?x8) U 28pin EPROM (28pin chip mounted in 32pin socket) U 14pin xxxx U 40pin ICT PA7140T CTM42027JC U 40pin ICT PA7140T CTM42027JC U 40pin GoldStar GM82C765B U 24pin xxxxx (PAL or so) U 3pin 7805 or so X 2pin oscillator P1 64pin cartridge edge (via remove-able adaptor) (snes) P 62pin cartridge slot (snes) P 32pin cartridge slot (gameboy) P 34pin floppy data P 2pin power supply P 2pin floppy supply P 50pin to DRAM daughterboard SNES Cart Copiers - Misc ------------------------ Parallel Ports (DB-25) Parallel Ports are used to upload/download data from PCs. Later copiers seem to be additionally using the Parallel Port for connecting CD-ROM drives. Some copiers have fully working parallel ports installed (eg. Front Fareast), some have them incompletely installed (eg. some Supercom seem to require additional 74LS245 (8-bit 3-state transceiver), and a specially programmed PAL16V8 chip?). Other copiers don't have any provisions for parallel ports onboard - but can be eventually upgraded externally by plugging a parallel port cartridge into the SNES cartridge slot: There are at least two such upgrade cartridges (one contains pure logic, the other one additionally contains a BIOS upgrade). DSP Chips Some copiers include DSP-clones onboard (or do at least have sockets or soldering points for mounting DSP chips), other copiers can be upgraded externally: By plugging a DSP cartridge into the SNES cartridge slot (either a regular game cartridge with DSP chip, or a plain DSP-clone-cartridge without any game in it). Of course, this will work only with the correct DSP chip (DSP1 for most games; unless there are any DSP clones that support more than one DSP chip at one?). Another problem may be I/O addresses (different games expect DSP chips at different addresses). Batteries Some boards contain batteries for the internal SRAM. Either 3V Lithium cells (coin-shaped), or rechargeable 3.6V NiCd batteries (usually with blue coating, which tend to leak acid, and to destroy wires on the PCB). Other boards don't have any batteries at all (they are said to use capacitors instead of batteries, which might be nonsense, or might last only a few minutes?) (there seems to be no way to switch-off the external power-supply, so batteries aren't needed to power SRAM) (eventually some boards might even power the DRAM in standby mode (?), which would require a DRAM refresh generator). And, aside from battery-backup, most or all copiers are allowing to save SRAM to floppy. SNES Cart Copiers - Floppy Disc Controllers ------------------------------------------- FDC Chips Most (or all) SNES copiers are using one of the following FDCs: 40pin GM82C765B (DIP) (Supercom, Ufo, Pro Fighter, Smart Disc, Bung?) 44pin GM82C765B (SMD) (Wild Card, GP-003) 68pin MCS3201FN (SMD) (used by OLD copiers: Super Magic Drive) 68pin MCCS3201FN (SMD) (used by OLD copiers: Supercom & Super Magicom) FDC Address Decoding The 68pin MCS3201FN chips include a 10bit address bus (for decoding address 3F0h-3F7h on IBM PCs; whereas, SNES copiers are using only the lower some address bits), and an 8bit General Purpose Input. The 40pin/44pin GM82C765B chips include a 1bit address bus bundled with 3 select lines, and have no General Purpose Input register. GM82C765B MCS3201FN Dir Register N/A A0-A2=0 R General Purpose Input (pins I0..I7) /LDOR A0-A2=2 W Motor Control (bit0-7) /CS+A0=0 A0-A2=4 R Main Status (NEC uPD765 compatible) /CS+A0=1 A0-A2=5 RW Command/Data (NEC uPD765 compatible) /LDCR A0-A2=7 W Transfer Rate (Density) (bit0-1) N/A A0-A2=7 R Bit7=DiskChange, Bit6-0=Zero Accordingly, MCS3201FN ports are always ordered as shown above, whilst GM82C765B ports can be arranged differently (in case of the Super Wild Card, Front Fareast kept them arranged the same way as on their older Super Magicom). FDC Command/Data and Main Status --> SNES Cart Copiers - Floppy Disc NEC uPD765 Commands FDC Motor Control GM Bit0-7: DSEL ,X ,/RES,DMAEN,MOTOR1,MOTOR2,X ,MSEL MCS Bit0-7: DSEL0,DSEL1,/RES,DMAEN,MOTOR1,MOTOR2,MOTOR3,MOTOR4 Note that, for whatever reason, most SNES Copiers are using the SECOND drive (ie. DSEL=1 instead of DSEL=0, and MOTOR2=1 instead of MOTOR1=1). Transfer Rate (Density) Val Usage MCS3201FN GM82C765B 00h HD (high density) 500K if /RWC=1 MFM:500K or FM:250K 01h DD 5.25" (double den) 300K if /RWC=0 MFM:300K if DRV=1, 250K if DRV=0 02h DD 3.5"(double den) 250K if /RWC=0 MFM:250K or FM:125K 03h N/A Reserved 125K Disk Change (MCS3201FN only) (not GM82C765B) 7 Disk Change Flag 6-0 Unused (zero) Possibly useful, but purpose/usage is unclear. According to the datasheet it is for "diagnostics" purposes. Unknown when the flag gets reset, and unknown for which drive(s) it does apply. SNES Cart Copiers - Floppy Disc NEC uPD765 Commands --------------------------------------------------- Accessing the FDC 765 The Data Register is used to write Commands and Parameters, to read/write data bytes, and to receive result bytes. These three operations are called Command-, Execution-, and Result-Phase. The Main Status Register signalizes when the FDC is ready to send/receive the next byte through the Data Register. Command Phase A command consists of a command byte (eventually including the MF, MK, SK bits), and up to eight parameter bytes. Execution Phase During this phase, the actual data is transferred (if any). Usually that are the data bytes for the read/written sector(s), except for the Format Track Command, in that case four bytes for each sector are transferred. Result Phase Returns up to seven result bytes (depending on the command) that are containing status information. The Recalibrate and Seek Track commands do not return result bytes directly, instead the program must wait until the Main Status Register signalizes that the command has been completed, and then it must (!) send a Sense Interrupt State command to 'terminate' the Seek/Recalibrate command. FDC Command Table Command Parameters Exm Result Description 02+MF+SK HU TR HD ?? SZ NM GP SL S0 S1 S2 TR HD NM SZ read track 03 XX YY - specify spd/dma 04 HU - S3 sense drive state 05+MT+MF HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ write sector(s) 06+MT+MF+SK HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ read sector(s) 07 HU - recalib.seek TP=0 08 - - S0 TP sense int.state 09+MT+MF HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ wr deleted sec(s) 0A+MF HU - S0 S1 S2 TR HD LS SZ read ID 0C+MT+MF+SK HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ rd deleted sec(s) 0D+MF HU SZ NM GP FB S0 S1 S2 TR HD LS SZ format track 0F HU TP - seek track n 11+MT+MF+SK HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ scan equal 19+MT+MF+SK HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ scan low or equal 1D+MT+MF+SK HU TR HD SC SZ LS GP SL S0 S1 S2 TR HD LS SZ scan high or eq. Parameter bits that can be specified in some Command Bytes are: MT Bit7 Multi Track (continue multi-sector-function on other head) MF Bit6 MFM-Mode-Bit (Default 1=Double Density) SK Bit5 Skip-Bit (set if secs with deleted DAM shall be skipped) Parameter/Result bytes are: HU b0,1=Unit/Drive Number, b2=Physical Head Number, other bits zero TP Physical Track Number TR Track-ID (usually same value as TP) HD Head-ID SC First Sector-ID (sector you want to read) SZ Sector Size (80h shl n) (default=02h for 200h bytes) LS Last Sector-ID (should be same as SC when reading a single sector) GP Gap (default=2Ah except command 0D: default=52h) SL Sectorlen if SZ=0 (default=FFh) Sn Status Register 0..3 FB Fillbyte (for the sector data areas) (default=E5h) NM Number of Sectors (default=09h) XX b0..3=headunload n*32ms (8" only), b4..7=steprate (16-n)*2ms YY b0=DMA_disable, b1-7=headload n*4ms (8" only) Format Track: output TR,HD,SC,SZ for each sector during execution phase Read Track: reads NM sectors (starting with first sec past index hole) Read ID: read ID bytes for current sec, repeated/undelayed read lists all IDs Recalib: walks up to 77 tracks, 80tr-drives may need second recalib if failed Seek/Recalib: All read/write commands will be disabled until succesful senseint Senseint: Set's IC if unsuccesful (no int has occured) (until IC=0) FDC Status Registers The Main Status register can be always read through an I/O Port. The other four Status Registers cannot be read directly, instead they are returned through the data register as result bytes in response to specific commands. Main Status Register (I/O Port) b0..3 DB FDD0..3 Busy (seek/recalib active, until succesful sense intstat) b4 CB FDC Busy (still in command-, execution- or result-phase) b5 EXM Execution Mode (still in execution-phase, non_DMA_only) b6 DIO Data Input/Output (0=CPU->FDC, 1=FDC->CPU) (see b7) b7 RQM Request For Master (1=ready for next byte) (see b6 for direction) Status Register 0 b0,1 US Unit Select (driveno during interrupt) b2 HD Head Address (head during interrupt) b3 NR Not Ready (drive not ready or non-existing 2nd head selected) b4 EC Equipment Check (drive failure or recalibrate failed (retry)) b5 SE Seek End (Set if seek-command completed) b6,7 IC Interrupt Code (0=OK, 1=aborted:readfail/OK if EN, 2=unknown cmd or senseint with no int occured, 3=aborted:disc removed etc.) Status Register 1 b0 MA Missing Address Mark (Sector_ID or DAM not found) b1 NW Not Writeable (tried to write/format disc with wprot_tab=on) b2 ND No Data (Sector_ID not found, CRC fail in ID_field) b3,6 0 Not used b4 OR Over Run (CPU too slow in execution-phase (ca. 26us/Byte)) b5 DE Data Error (CRC-fail in ID- or Data-Field) b7 EN End of Track (set past most read/write commands) (see IC) Status Register 2 b0 MD Missing Address Mark in Data Field (DAM not found) b1 BC Bad Cylinder (read/programmed track-ID different and read-ID = FF) b2 SN Scan Not Satisfied (no fitting sector found) b3 SH Scan Equal Hit (equal) b4 WC Wrong Cylinder (read/programmed track-ID different) (see b1) b5 DD Data Error in Data Field (CRC-fail in data-field) b6 CM Control Mark (read/scan command found sector with deleted DAM) b7 0 Not Used Status Register 3 b0,1 US Unit Select (pin 28,29 of FDC) b2 HD Head Address (pin 27 of FDC) b3 TS Two Side (0=yes, 1=no (!)) GM82C765: Also WP (same as bit6)? b4 T0 Track 0 (on track 0 we are) b5 RY Ready (drive ready signal) GM82C765: Always 1=Ready b6 WP Write Protected (write protected) b7 FT Fault (if supported: 1=Drive failure) GM82C765: Always 0=Okay Notes: Before accessing a disk you should first Recalibrate the drive, that'll move the head backwards until it reaches Track 0 (that's required to initialize the FDCs track counter). On a 80 track drive you may need to repeat that in case that the first recalibration attempt wasn't successful (that's because the FDC stops searching after 77 steps) (at least older uPD765 chips did so, maybe the MCS3201FN/GM82C765B chips don't). Now if you want to format, read or write a sector on a specific track you must first Seek that track (command 0Fh). That'll move the read/write head to the physical track number. If you don't do that, then the FDC will attempt to read/write data to/from the current physical track, independendly of the specified logical Track-ID. The Track-, Sector-, and Head-IDs are logical IDs only. These logical IDs are defined when formatting the disk, and aren't required to be identical to the physical Track, Sector, or Head numbers. However, when reading or writing a sector you must specify the same IDs that have been used during formatting. Despite of the confusing name, a sector with a "Deleted Data Address Mark" (DAM) is not deleted. The DAM-flag is just another ID-bit, and (if that ID-bit is specified correctly in the command) it can be read/written like normal data sectors. DMA/IRQ Most (or all) SNES copiers don't support DMA or IRQs (some are allowing to poll the IRQ flag by software I/O). Terminal Count (TC) *** Below info applies to Amstrad CPC with uPD765 chip. *** Unknown if anything similar applies to SNES with MCS3201FN/GM82C765B chips. At the end of a successful read/write command, the program should send a Terminal Count (TC) signal to the FDC. However, in the CPC the TC pin isn't connected to the I/O bus, making it impossible for the program to confirm a correct operation. For that reason, the FDC will assume that the command has failed, and it'll return both Bit 6 in Status Register 0 and Bit 7 in Status Register 1 set. The program should ignore this errormessage. SNES Cart Copiers - Floppy Disc FAT12 Format -------------------------------------------- The SNES Copier floppy format is compatible to that used under DOS on PCs. Typical formats are 3.5", Double Density, 80 Tracks/9 Sectors, Double Sided (720KB). The Sectors are logically numbered 01h..09h, and each sized 200h bytes. XXX HD-disks have more sectors XXX snes copiers are usually HD (or maybe some are DD?) XXX snes copiers support 1.44MB and 1.6MB (FDFORMAT-like) Boot-Record The first sector is always used as bootsector, giving information about the usage of the following sectors, and including the boot procedure (for loading MSDOS etc). 00-02 80x86 boot procedure (jmp opcode) (not used for SNES) 03-0A ascii disk name 0B-0C bytes / sector 0D sectors / cluster 0E-0F sectors / boot-record 10 number of FAT-copys 11-12 entrys / root-directory 13-14 sectors / disk 15 ID: F8=hdd, F9=3.5", FC=SS/9sec, FD=DS9, FE=SS8,FF=DS8 16-17 sectors / FAT 18-19 sectors / track 1A-1B heads / disk 1C-1D number of reserved sectors 1E-1FF MSX boot procedure (Z80 code) (not used for SNES) FAT and FAT copy(s) The following sectors are occupied by the File Allocation Table (FAT), which contains 12- or 16-bit entries for each cluster: (0)000 unused, free (0)001 ??? (0)002... pointer to next cluster in chain (0)002..(F)FEF (F)FF0-6 reserved (no part of chain, not free) (F)FF7 defect cluster, don't use (F)FF8-F last cluster of chain Number and size of FATs can be calculated by the information in the boot sector. Root directory The following sectors are the Root directory, again, size depends on the info in bootsector. Each entry consists of 32 bytes: 00-07 Filename (first byte: 00=free entry,2E=dir, E5=deleted entry) 08-0A Filename extension 0B Fileattribute 0C-15 reserved 16-17 Timestamp: HHHHHMMM, MMMSSSSS 18-19 Datestamp: YYYYYYYM, MMMDDDDD 1A-1B Pointer to first cluster of file 1C-1F Filesize in bytes The 'cluster' entry points to the first used cluster of the file. The FAT entry for that cluster points to the next used cluster (if any), the FAT entry for that cluster points to the next cluster, and so on. Reserved Sectors (if any) Usually the number of reserved sectors is zero. If it is non-zero, then the following sector(s) are reserved (and could be used by the boot procedure for whatever purposes). Data Clusters 0002..nnnn Finally all following sectors are data clusters. The first cluster is called cluster number (0)002, followed by number (0)003, (0)004, and so on. Special Features Unknown if any copiers support sub-directories. Unknown if any copiers support long file names. Unknown if any copiers support compressed files (ZIP or such). SNES Cart Copiers - BIOSes -------------------------- Copier BIOSes Name I/O BIOS Size Double Pro Fighter (1994) 2800 64K(6+6+16) Gamars Puzzle (not a Copier BIOS) - 1M (32x32K) GAMARS~5 1,048,576 Gamars Super Disk FC-301 V6.0 Kaiser94 5Fxx 64K (1x64K) GAMARS~4 65,536 Gamars Super Disk FC-301 V7.13 Kaiser94 5Fxx 256K (4x64K) GAMARS~3 262,144 Gamars Super Disk FC-301 V7.16 Kaiser94 5Fxx 256K (4x64K) GAMARS~2 262,144 Game Doctor SF 3 V3.3C 8000 32K (1x32K) GAMEDO~3 32,768 Game Doctor SF 6 V6.2 (Professor SF) 8000 64K (2x32K) GAMEDO~4 65,536 Game Doctor SF 6 V6.21 (Professor SF) 8000 64K (2x32K) GAMEDO~6 65,536 Game Doctor SF 7 V7.11 (Professor SF 2) 8000 64K (2x32K) GAMEDO~2 65,536 Multi Game Hunter V1.2 (Venus) 5800 32K (1x32K) MULTIG~2 32,768 Multi Game Hunter V1.3 (Venus) 5800 32K (1x32K) MULTIG~3 32,768 Multi Game Hunter V1.4 (Venus) 5800 32K (1x32K) MULTIG~3 32,768 Pro Fighter Q (H.K.) xx-xx-93 2800 16K (1x16K) SUPERP~1 16,xxx Supercom Partner A [o1] 2800 16K (1x16K) SUPERC~1 3,145,728 Supercom Pro 2 (CCL) ports=FFE 06-21-92 FFE 8K (1x8K) SUPERC~2 32,768 Super Disk Interceptor v5.2 (Sane Ting) A000 32K (4x8K) SUPERD~1 32,768 Super Magicom V1H (Front/CCL) 12-23-91 FFE 8K (1x8K) SUPERM~2 32,768 Super Magicom V31 (Front/CCL) xx-xx-92 FFE 8K (1x8K) SUPERM~4 32,768 Super Magicom V3H SoftUpgrade xx-xx-9x FFE 32K (DRAM) SUPERM~8 32,768 Super Pro Fighter (H.K.) xx-xx-93 2800 16K (1x16K) SUPERP~1 16,xxx Super Pro Fighter (H.K.) [a1] xx-xx-93 2800 16K (1x16K) SUPERP~1 16,xxx Super Wild Card V1.6 (Front) 93-01-26 FFE 16K (2x8K) SUPERW~6 16,384 Super Wild Card V1.8 (Front) 93-02-19 FFE 16K (2x8K) SUPERW~7 16,384 Super Wild Card V2.0XL (Front) 93-04-12 FFE 16K (2x8K) SUPERW~9 16,384 Super Wild Card V2.1B (Front) 93-04-28 FFE 16K (2x8K) SUPER~10 16,384 Super Wild Card V2.1C (Front) 93-04-28 FFE 16K (2x8K) SUPER~11 16,384 Super Wild Card V2.2CC (Front) 93-05-03 FFE 16K (2x8K) SUPER~12 16,384 Super Wild Card V2.6CC (Front) 93-07-17 FFE 16K (2x8K) SUPER~15 16,384 Super Wild Card V2.6F (Front) 93-07-17 FFE 16K (2x8K) SUPER~16 16,384 Super Wild Card V2.6FX (Front) 93-07-17 FFE 16K (2x8K) SUPER~17 16,384 Super Wild Card V2.7CC (Front) 93-12-07 FFE 16K (2x8K) SUPER~18 16,384 Super Wild Card V2.8CC (Front) 06-08-94 FFE 16K (2x8K) SUPER~19 16,384 Super Wild Card V2.8CC [o1] 06-28-94 FFE 16K (2x8K) SUPER~22 65,536 Super Wild Card DX 10-14-94 FFE 256K (32x8K) SUPERW~2 262,144 Super Wild Card DX 11-03-94 FFE 256K (32x8K) SUPERW~3 262,144 Super Wild Card DX96 01-04-96 FFE 256K (32x8K) SUPERW~1 262,144 Super Wild Card DX2 06-08-96 FFE 256K (32x8K) SUPERW~4 262,144 UFO - Super Drive PRO 3 [o1 as 4x8K] FFE 8K (1x8K) UFOSUP~1 32,768 UFO - Pro 6 ? ? (?) UFO - Super UFO Pro-7 V7.3 1994 2184 64K (2x32K) SUPERU~1 65,536 UFO - Super UFO Pro-8 V8.1 1995 2184 128K (4x32K) SUPERU~2 131,072 UFO - Super UFO Pro-8 V8.8c 1995 2184 256K (8x32K) SUPERU~3 262,144 SNES Cart CDROM Drive --------------------- SNES Sony CDROM (unreleased) Nintendo and Sony originally planned a partnership where Sony would produce a CDROM drive add-on for the SNES, additionally Sony would have produced a SNES compatible console with the CDROM drive built-in. The project progressed far enough to produce some prototype, and publish some press releases. However, the deal failed, and Sony finally produced their own console (the Sony Playstation). Anyways, the unreleased SNES CD Prototype worked as so: --> SNES Cart CDROM - Memory and I/O Map --> SNES Cart CDROM - CDROM Bootsector and Volume Descriptor --> SNES Cart CDROM - BIOS Cartridge --> SNES Cart CDROM - BIOS Functions --> SNES Cart CDROM - Mechacon --> SNES Cart CDROM - Decoder/FIFO --> SNES Cart CDROM - Component List For general info about CDROM discs, see the documentation for my PSX debugger: http://problemkaputt.de/psx.htm - no$psx homepage http://problemkaputt.de/psx-spx.htm - psx specifications That docs are covering about everything about sector headers, sector encoding, subchannels, tocs, tracks, sectors, frames, sessions, volume descriptors, filesystem, xa-adpcm, cd-da audio, plus specs for different cdrom-image file formats. SNES Philips CDROM (unreleased) After the deal with Sony had failed, Nintendo tried a new deal with Philips - which failed, too. SNES Copier CDROM (released) Whilst Nintendo failed on producing an official CDROM drive, some SNES Copiers are allowing to load ROM-images from CDROMs. SNES Cart CDROM - Memory and I/O Map ------------------------------------ I/O Ports 21D0h.W - BIOS Cartridge Battery RAM Lock (write 00h) 21E0h.W - BIOS Cartridge Battery RAM Unlock Step 2 (write 0Fh downto 01h) 21E1h.R/W - CDROM Unit Mechacon CPU (probably the NEC chip on daughterboard) 21E2h.R/W - CDROM Unit Decoder/FIFO Index (CXD1800Q chip) 21E3h.R/W - CDROM Unit Decoder/FIFO Data (CXD1800Q chip) 21E4h.W - CDROM Unit (?) Whatever Control/Enable or so 21E5h.W - BIOS Cartridge Battery RAM Unlock Step 1 (write FFh) ???.R/W - NEXT connector? (maybe some kind of UART, like PSX serial port?) ???.R/W - BIOS Cartridge S-WRAM chip(s) (seem be wired to /PARD and /PAWR) IRQ - used for Decoder and Mechacon APU I/O Ports The SNES CD prototype has APU chips with uncommon part numbers, which might work slightly different than standard SNES APUs. However, adding that chips wouldn't be possible with SNES CD expansions (for existing SNES consoles). Either old SNES consoles would need to stick with old APUs, or, theoretically, the SNES CD expansions could contain an extra APU unit (but, mapped elsewhere than 2140h-2143h). Memory 00h-03h:8000h-FFFFh BIOS Cart ROM (128Kbyte LoROM) 80h-87h:8000h-FFFFh BIOS Cart Work RAM (256Kbyte DRAM) (two S-WRAM chips) 90h :8000h-9FFFh BIOS Cart Battery RAM (8Kbyte SRAM) Special Memory regions/addresses: 00h:1Fxxh Work RAM reserved for BIOS functions 00h:1FF8h Work RAM containing NMI vector (should be 4-byte "JMP far" opcode) 00h:1FFCh Work RAM containing IRQ vector (should be 4-byte "JMP far" opcode) 00h:0000h Work RAM containing IRQ/BRK/COP vectors (if used) 00h:1000h Load address for 800h-byte boot sector 00h:1080h Entrypoint for 800h-byte boot sector 00h:E000h CD BIOS Functions in BIOS ROM 83h:C000h Work RAM reserved for loading cdrom data in "VRAM mode" (16Kbyte) Caution: Initial/empty SRAM may NOT be zerofilled (else the BIOS treats the checksum to be okay, with 0 files installed - but with 0000h bytes free space, which is making it impossible to create/delete any files). Caution: RAM at 1Fxxh is reserved for BIOS functions (and NMI/IRQ vectors, even when not using any other BIOS functions), so stacktop should be 1EFFh (not 1FFFh, where it'd be usually located). Unknown if the memory is mirrored anywhere; particulary mirroring the S-WRAMs to C0h-C3h:0000h-FFFFh would be useful for HiROM-style games. Unknown if the two S-WRAM chips are also mapped to B-bus (the B-bus would be useful only for DMA from ROM carts, ie. not useful for CDROM games). 21E4h.W - Whatever Control/Enable or so 7-4 Unknown/Unused (always set to 0) 3 Enable Mechacon? (0=Off, 1=On) 2 Enable Decoder? (0=Off, 1=On) 1 Maybe Reset? (0=Normal, 1=What?) 0 Unknown/Unused (always set to 0) Set to 0Eh,00h,04h,08h,0Ch. Decoder/FIFO Registers (CXD1800Q) (accessed via 21E2h/21E3h) Decoder Write Registers 00h - Reserved 01h DRVIF DRIVE Interface (W) 02h CHPCTL Chip Control (W) 03h DECCTL Decoder Control (W) 04h INTMSK Interrupt Mask (0=Disable, 1=Enable) (W) ;\interrupt 05h INTCLR Interrupt Clear/Ack (0=No change, 1=Clear/ack);/ 06h CI ADPCM Coding Information (to be used when AUTOCI=0) 07h DMAADRC_L SRAM-to-CPU Xfer Address, Low (W) ;\ 08h DMAADRC_H SRAM-to-CPU Xfer Address, High (W) ; 09h DMAXFRC_L SRAM-to-CPU Xfer Length, Low (W) ; 0Ah DMAXFRC_H SRAM-to-CPU Xfer Length, High & DMA Control (W) ;/ 0Bh DRVADRC_L Disc-to-SRAM Xfer Address, Low (W) ;\ 0Ch DRVADRC_H Disc-to-SRAM Xfer Address, High (W) ;/ 0Dh-0Fh - Unspecified 0Dh "PLBA" <-- shown as so in SNES CD's "CXD1800" test screen 10h-1Ch - Mirrors of 00h-0Ch 1Dh - Reserved (TEST2) 1Eh - Reserved (TEST1) 1Fh - Reserved (TEST0) Decoder Read Registers 00h DMADATA SRAM-to-CPU Xfer Data (R) ;-Sector Data 01h INTSTS Interrupt Status (0=No IRQ, 1=IRQ) (R);-Interrupt 02h STS Status (R) ;\ 03h HDRFLG Header Flags (R) ; 04h HDR_MIN Header "MM" Minute (R) ; important info on 05h HDR_SEC Header "SS" Second (R) ; current sector 06h HDR_BLOCK Header "FF" Frame (R) ; (to be handled 07h HDR_MODE Header Mode (R) ; upon "DECINT" 08h SHDR_FILE Sub-Header File (R) ; interrupt) 09h SHDR_CH Sub-Header Channel (R) ; 0Ah SHDR_S-MODE Sub-Header SubMode (R) ; 0Bh SHDR_CI Sub-Header Coding Info (R) ; 0Ch CMADR_L Current Minute Address, Low (R) ; 0Dh CMADR_H Current Minute Address, High (R) ;/ 0Eh MDFM MODE/FORM (R) ;\extra details on 0Fh ADPCI ADPCM Coding Information (R) ;/current sector 10h-to-2 Reserved (TEST 0 to 2) (R) 13h - Unspecified 14h-17h - Mirrors of 04h-07h (HDR_xxx) 18h.R DMAXFRC_L - SRAM-to-CPU Xfer Length, Low (R) ;\allows to read 19h.R DMAXFRC_H - SRAM-to-CPU Xfer Length, High (R) ; address/remain 1Ah.R DMAADRC_L - SRAM-to-CPU Xfer Address, Low (R) ; values 1Bh.R DMAADRC_H - SRAM-to-CPU Xfer Address, High (R) ; (needed only for 1Ch.R DRVADRC_L - Disc-to-SRAM Xfer Address, Low (R) ; diagnostics) 1Dh.R DRVADRC_H - Disc-to-SRAM Xfer Address, High (R) ;/ 1Eh-1Fh - Mirrors of 0Eh-0Fh (MDFM and ADPCI) SNES Cart CDROM - CDROM Bootsector and Volume Descriptor -------------------------------------------------------- SNES CD can be in MODE1 or MODE2/FORM1 format. The disc requires an 28h-byte ID in sector 16, and a 800h-byte bootsector in sector 0, which may then loaded further data via BIOS functions, or via direct access to the cdrom I/O ports. The BIOS doesn't contain any filesystem support, however, the games may implement a standard ISO filesystem (or some custom format), if desired. Aside from data sectors, the drive controller does also support CD-DA audio tracks and playing compressed ADPCM audio sectors. SNES CD Bootsector (sector 0) Located on Sector 0 (address 00:02:00), loaded to 00:1000h..17FFh, and then started by jumping to 00:1080h. Primary Volume Descriptor (sector 16) Located on Sector 16 (address 00:02:16), the first 28h bytes must have following values for boot-able SNES CDs. 000h 1 Volume Descriptor Type (01h=Primary Volume Descriptor) 001h 5 Standard Identifier ("CD001") 006h 1 Volume Descriptor Version (01h=Standard) 007h 1 Reserved (00h) 008h 32 System Identifier (a-characters) ("SUPERDISC") 028h ... (further ISO primary volume descriptor entries may follow here) Note Aside from booting executable software, the CD BIOS does also contain code for some "ELECTRONIC BOOK" format, but the volume descriptor detection lacks support for detecting that disc type. SNES Cart CDROM - BIOS Cartridge -------------------------------- Contains extra DRAM, some small battery-backed SRAM, and the BIOS ROM. The DRAM and SRAM are rather small, and there's no coprocessor. However, this is only prototype, and Nintendo could have easly expanded the BIOS cartridge (without needing to modify the actual CDROM hardware). For example, there have been rumours about a 32bit CPU being planned, and SRAM might have been intended to be replaced by a bigger memory chip (or possibly by an external FLASH cart as used in Satellaview BIOS carts). BIOS User Interface START --> Load CDROM (if any) SELECT --> SRAM Manager (in there: Up/Down=Select, B=Delete, Y=Exit) A+X --> Test Screen (in there: Up/Down/B --> Menu Selection) Self Check tests: Page1: VRAM, CGRAM, OAM, WRAM, DMA, TIMER, SOUND (sound test works only once) Page2: BIOS_DRAM, BIOS_SRAM, CDROM DECODER, CD-PLAYER I/F The DECODER test seems to try to count sectors/second on STOPPED drive, that might fail on real HW, or it might work with the NOSYNC bit triggered? ADPCM Test: Use Up/Down and L/R Buttons to select File/Channel and MM:SS:FF Press B to play ADPCM audio (eg. from PSX disc with ADPCM at selected values) Press Y to toggle Normal/Double speed, press Select to go back to menu Observe that APU is muting sound output (unless previously running Selfcheck) Communication (Mechacon) Test: Use L/R Buttons to select a command, use B to issue the command, Select=Exit Use Up/Down and L/R Buttons to change variable parameters CXD-1800 (Decoder) Test: Use Up/Down and L/R Buttons to change Write values Use Y to toggle Read/Write, X to toggle IRQ, Select=Exit 00h-03h:8000h-FFFFh - BIOS Cart ROM (128Kbyte LoROM) (Sticker 0.95 SX) The BIOS has CRC32=3B64A370h and the ROM/EPROM is badged "0.95 SX", there are some ASCII strings in the file: "Super Disc boot ROM ver.0.95 Jul. 14, 1992 by Tomomi Abe at SONY " "Super Disc BIOS program ver.0.93 by Tomomi Abe. May. 26 1992 at SONY. " 01h,"CD001",01h,00h,"SUPERDISC",23x00h ;28h-byte ISO volume descriptor The cart header at 7FC0h-7FDFh is just FFh-filled and IRQ/NMI vectors point to RAM: 7FC0 FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF 7FD0 FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF 7FE0 00,00,00,00,00,00,00,00,00,00,F8,1F,00,00,FC,1F 7FF0 00,00,00,00,00,00,00,00,00,00,00,00,00,80,00,00 That uncommon combination of FFh's and IRQ/NMI vectors can be used to detect if a ROM image is having Super Disc support. 80h-87h:8000h-FFFFh - BIOS Cart Work RAM (256Kbyte DRAM) (two S-WRAM chips) This expands the SNES's internal 128KBytes to a total of 384Kbytes Work RAM. Allowing to load code and data from CDROM to CPU memory space. 90h:8000h-9FFFh - BIOS Cart Battery RAM (8Kbyte SRAM) 21D0h.W - BIOS Cartridge Battery RAM Lock (write 00h) 21E0h.W - BIOS Cartridge Battery RAM Unlock Step 2 (write 0Fh downto 01h) 21E5h.W - BIOS Cartridge Battery RAM Unlock Step 1 (write FFh) These ports seem to be used to write-protect the battery backed SRAM (the BIOS functions are automatically locking/unlocking the SRAM when saving/deleting game position files). SNES Cart CDROM - BIOS Functions -------------------------------- SNES CD BIOS Function Summary (jump opcodes at 00:E0xxh) 00h:E000h cdrom_InitDetect ;00h ;\ 00h:E003h cdrom_LoadFromDisc ;01h ; 00h:E006h cdrom_SendMechaconCommand ;02h ; Main Functions 00h:E009h cdrom_WramToVramDMA ;03h ; 00h:E00Ch cdrom_PollMechacon ;04h ;/ 00h:E00Fh no_function ;05h..0Fh 00h:E030h cdrom_SramTest ;10h ;\ 00h:E033h cdrom_SramGetDirectory ;11h ; 00h:E036h cdrom_SramSaveFile ;12h ; SRAM Functions 00h:E039h cdrom_SramLoadFile ;13h ; 00h:E03Ch cdrom_SramDeleteFile ;14h ;/ 00h:E03Fh no_function ;15h..1Fh 00h:E060h cdrom_DecoderDataMode ;20h ;\ 00h:E063h cdrom_DecoderAudioMode ;21h ; Misc Functions 00h:E066h cdrom_DecoderTestDecint ;22h ;/ 00h:E069h no_function ;23h 00h:Exxxh crash ;24h and up ______________________________ Main Functions ______________________________ 00h:E000h - cdrom_InitDetect Initializes variables and NMI/IRQ handlers at [1Fxxh], and tries to flush any old mechacon IRQs, and to issue a mechacon get status command. out: cy=error (0=okay, 1=no cdrom hardware) 00h:E003h - cdrom_LoadFromDisc in: [1F00h]=source address (24bit LBA, or 3-byte MM,SS,FF address) in: [1F03h]=read mode (flag byte) (usually 40h for LBA with normal data) in: [1F04h]=destination address (24bit wram address) (or 16bit vram address) in: [1F07h]=transfer length (max 7FFFh bytes, or maybe max 87FFh works, too) in: [1F09h]=max number of sub-q mismatches or so (usually 0Fh) in: [1F33h]=file and channel bytes (for ADPCM mode only) out: cy=error (0=okay, 1=bad) Flag byte format: 7 VRAM Mode (0=Load to WRAM, 1=Forward sectors from WRAM to VRAM) 6 Source Address format (0=MM:SS:FF in non-BCD, 1=24bit LBA) 5 ADPCM Mode (0=No, 1=Play ADPCM file/channel until EOR/EOF) 4 Prevent loading (0=No, 1=Skip everything except ADPCM, if enabled) 3-0 Unused (should be 0) The cdrom_LoadFromDisc function uses DMA7 to transfer data from Disc to WRAM, the "VRAM Mode" additionally uses DMA6 for forwarding incoming data from a WRAM buffer (at 83h:C000h-FFFFh) to VRAM. 00h:E006h - cdrom_SendMechaconCommand Allows to send mechacon commands (normally not required, the LoadFromDisc functions does automatically issue seek+play+pause commands). in: a=command (8bit) in: [1Fxxh]=optional parameters (for command 00h and 01h) out: cy=error (0=okay, 1=bad) out: [1F2E]=last response digit (unknown purpose, checked after seek_mmssff) Command numbers are: 00h seek_tr_indx CxxxxF --> FFFFFx ;in: [1F0Fh..1F12h]=four nibbles 01h seek_mmssff BxxxxxxF --> FFFFFFFx ;in: [1F13h..1F18h]=six nibbles 02h stop D01F --> FFFx 03h play D02F --> FFFx 04h pause D03F --> FFFx 05h open_close D04F --> FFFx 06h fast_forward D10F --> FFFx 07h fast_reverse D11F --> FFFx 08h forward D12F --> FFFx 09h reverse D13F --> FFFx 0Ah key_direct D40F --> FFFx 0Bh key_ignore D41F --> FFFx 0Ch continous D42F --> FFFx 0Dh track_pause D43F --> FFFx 0Eh index_pause D44F --> FFFx 0Fh req_sub_q D50F_0000000000000000F ;out:[1F1Eh..1F2Dh]=16 nibbles 10h req_status D51F_01234F ;out:[1F19h..1F1Dh]=5 nibbles 11h normal_speed D45F --> FFFx 12h double_speed D46F --> FFFx 13h flush F --> a N/A ? D14F --> FFFx N/A ? D15F --> FFFx 00h:E009h - cdrom_WramToVramDMA (custom NMI handler callback) Usually done automatically by the default BIOS NMI handler: If CDROM loading is done in "VRAM mode", then this functions forwards the incoming CDROM data from WRAM to VRAM. 00h:E00Ch - cdrom_PollMechacon (custom IRQ handler callback) Usually done automatically by the default BIOS IRQ handler: If a mechacon command is being transmitted, then this function handles incoming mechacon response nibbles, and sends further mechacon parameter nibbles (until completion of the command sequence). ______________________________ SRAM Functions ______________________________ 00h:E030h - cdrom_SramTest Tests the SRAM checksum, does range checks on free memory size and number of files, automatically reformats/erases the SRAM in case of errors. out: cy=error (0=okay, 1=bad, reformatted sram) 00h:E033h - cdrom_SramGetDirectory Returns the whole SRAM directory with max 32 files, each 16-byte entry consists of 14-byte filename, folled by 16bit filesize value. in: DB:Y = destination address (200h byte buffer) out: cy=error (0=okay, 1=bad) out: a=number of files actually used ;\returned only out: [DB:Y+0..1FF]=directory (unused entries 00h-filled) ;/when cy=0=okay 00h:E036h - cdrom_SramSaveFile in: DB:Y = source address (14-byte name, 16bit length, filebody[length]) out: cy=error (0=okay, 1=bad, directory or memory full) 00h:E039h - cdrom_SramLoadFile in: DB:Y = source address (14-byte name, 16bit length, filebody[length]) out: filebody[length] is overwritten by loaded file (zeropadded if the specified length exceeded the specified filesize) out: cy=error (0=okay, 1=bad, file not found) 00h:E03Ch - cdrom_SramDeleteFile in: DB:Y = source address (14-byte name) out: cy=error (0=okay, 1=bad, file not found) Character Set for SRAM Filenames (shown when pressing SELECT in BIOS) 00h..09h "0..9" 0Ah..23h "A..Z" 24h..27h Space, Slash, Dash, Dot 28h..7Fh Japanese symbols 80h..FFh Cause directory sort-order corruption when creating/deleting files ______________________________ Misc Functions ______________________________ 00h:E060h - cdrom_DecoderDataMode 00h:E063h - cdrom_DecoderAudioMode (CD-DA) These functions are just setting the decoder to data/audio mode, there are no parameters or return values. 00h:E066h - cdrom_DecoderTestDecint Runs a test on measuring the number of DECINT's per second (aka sectors per second), passes okay when measuring 75+/-5 or 150+/-10 DECINTs (ie. both single & double speed mode should pass). Execution time of the test is 1 second. out: cy=error (0=okay, 1=bad) ______________________________ Bugs & Glitches _____________________________ Instead of using unsigned maths, the BIOS used a lot of signed comparisions without overflow checking. This is restricting the CDROM filesize to max 7FFFh (or possibly 87FFh might work when subtracting the first sector unit). SRAM filename characters are also using that signed maths for the filename sort order (using characters 80h..FFh can have unpredictable results when adding/removing SRAM files; which may cause new comparision overflows to occur/disappear). SRAM is intended to hold max 32 files, however, that limit is checked when overwriting old files (not when creating new files): Results are that one cannot overwrite any files if the cart contains 32 files or more, whilst, on the other hand, one could create even more then 32 files. Booting the BIOS seems to be instantly STOPPING the drive motor (after the BIOS intro/delay), apparently preventing the drive to spin-up, and to read the TOC, or even to load data from the disc - until going through the "PRESS START" nag screen. SNES Cart CDROM - Mechacon -------------------------- The Mechacon handles all the drive mechanics (motor start/stop, seeking, tracking, gain, balance). Essentinally it's covering only the "Audio" part (streaming bits and watching the SubQ-channel's position info) without being aware of "Digital" data in CDROM Headers & Data Blocks. However, the same mechanics are also used for "Playing" CDROM data discs (ie. seek the desired sector in MM:SS:FF notation, then issue Play command to start reading). Observe that seeking may inaccuratly settle "nearby" of the desired target address (ie. one must check the Data header's MM:SS:FF bytes from the Decoder chip, and ignore any sectors with smaller sector numbers, or eventually retry seeking if the sector number is higher as planned). 21E1h.R/W - CDROM Unit Mechacon CPU (probably the NEC chip on daughterboard) 7 Transfer Ready IRQ (R) 6-4 - 3-0 Data (R/W) Mechacon Commands Access MM/SS/FF BmmssffF --> FFFFFFFx Access Track/Index CttiiF --> FFFFFx Stop D01F --> FFFx Play D02F --> FFFx Pause D03F --> FFFx Open/Close D04F --> FFFx Fast Forward D10F --> FFFx Fast Reverse D11F --> FFFx Forward D12F --> FFFx Reverse D13F --> FFFx Key Direct D40F --> FFFx Key Ignore D41F --> FFFx Continous Play D42F --> FFFx Auto Track Pause D43F --> FFFx Auto Index Pause D44F --> FFFx Normal Speed D45F --> FFFx Double Speed D46F --> FFFx Q-Data Request D50F 0000000000000000F --> FFFx ................x Status Request D51F 01234F --> FFFx .....x Nop/Flush ? F --> x Q-Data Request Digits These 16 digits are probably 8 bytes straight from 12-byte SubQ Position data in BCD format (probably Track, Index, MM:SS:FF, AMM:ASS:AFF) (ie. probably excluding the ADR/Control byte, Reserved byte, and the two CRC bytes). Status Request Digits Digit(0) - Disc Type Bit0: Disc Type (or maybe Track Type) (0=Audio, 1=Data) Bit1-3: Unknown/unused Digit(1) Unknown/unused Digit(2) - Drive state 00h No Disc 01h Stop 02h Play 03h Pause 04h Fast Reverse 05h Fast Forward 06h Slow Reverse 07h Slow Forward 08h ? 09h ? 0Ah Access, Seek 0Bh Access, Read TOC 0Ch Tray Open 0Dh ? 0Eh ? 0Fh ? Digit(3) Unknown/unused Digit(4) Unknown/unused Unknown bits & digits might include double-speed flag, LCD pad buttons, or such stuff. SNES Cart CDROM - Decoder/FIFO ------------------------------ CXD1800Q chip (equivalent to CXD1196AR datasheet). IRQs can be sensed via CXD1800 Register(01h.R). 21E2h.R/W - CDROM Unit CXD1800 Index (REGADR) (R/W) 7-5 - Reserved (should be 0) 4-0 RA4-0 Register Index This register is used for selection of the internal registers. --> When the low order 4 bits of REGADR are not 0 (hex), and a register write or read is made by setting A0=1 and /CS=0, the low order 4 bits of REGADR are incremented --> REGADR is cleared to 00h by rising edge of DMAEN (in DMA Control register) 21E3h.R/W - CDROM Unit CXD1800 Data (R/W) 7-0 Data for register selected via REGADR _________________________ Configuration _________________________ X1h.W - DRVIF - DRIVE Interface (W) 7 XSLOW DMA/SRAM Speed (0=Slow/12 clks/320ns, 1=Fast/4 clks/120ns) 6 C2PL1ST DATA input C2PO-byte-order (0=Upper first, 1=Lower first) 5 LCHLOW Audio LRCK Polarity for Left channel (0=High, 1=Low) 4 BCKRED Audio BCLK Edge for strobing DATA (0=Falling, 1=Rising) 3-2 BCKMD1-0 Audio BCLKs per WCLK cycle (0=16, 1=24, 2/3=32) 1 LSB1ST Audio DATA (bit?-)ordering (0=MSB First, 1=LSB first) 0 CLKLOW CLK Pin Output (0=8.4672MHz, 1=Fixed Low) Configures how the drive is wired up. The SNES CD doesn't touch this register and leaves it at it's power-up default. The Decoder should be disabled before changing the register. X2h.W - CHPCTL - Chip Control (W) 7-5 - Reserved (should be 0) 4 CHPRST Chip Reset (takes 500ns) (0=No change, 1=Reset the chip) 3 CD-DA CD-Digital Audio Mode (0=Data/CDROM, 1=Audio/CD-DA) 2 SWOPN Sync Detection Window (0=Only if Sync expected, 1=Anytime) 1 RPSTART Repeat Correction Start (0=No change, 1=Repeat if repeat mode) 0 ADPEN ADPCM Decode (to be set max 11.5ms after DECINT) (0=No, 1=Yes) X3h.W - DECCTL - Decoder Control (W) 7 AUTOCI ADPCM Coding Information (0=Use CI Register, 1=Disc Subheader) 6 - Reserved (should be 0) 5 MODESEL Mode Select (when AUTODIST=0) (0=MODE1, 1=MODE2) 4 FORMSEL Form Select (when AUTODIST=0 and MODESEL=1) (0=FORM1, 1=FORM2) 3 AUTODIST Auto Distinction (0=Use MODESEL/FORMSEL, 1=Disc Header) 2-0 DECMD2-0 Decoder Mode (00h-07h, see below) Decoder Mode values: 00h/01h = Decoder disable (to be used for CD-DA Audio mode & during config) 02h/03h = Monitor only (read Header/Subheader, but don't write SRAM?) 04h = Write only mode (write sectors to SRAM without error correction?) 05h = Real time correction (abort correction if it takes too long?) 06h = Repeat correction (allow resume via RPSTART for important sectors?) 07h = Inhibit (reserved) X6h.W - CI - ADPCM Coding Information (to be used when AUTOCI=0) (W) 7 - Reserved (should be 0) 6 EMPHASIS ADPCM Emphasis (0=Normal/Off, 1=Emphasis) 5 - Reserved (should be 0) 4 BITL4H8 ADPCM Bit Length (0=Normal/4bit, 1=8bit) 3 - Reserved (should be 0) 2 FSL3H1 ADPCM Sampling Frequency (0=37800Hz, 1=18900Hz) 1 - Reserved (should be 0) 0 MONOSTE ADPCM Mono/Stereo (0=Mono, 1=Stereo) This register is used only when AUTOCI=0, allowing to use the correct ADPCM format even in case of read errors on the CI byte in sector sub header (if AUTOCI=1, such errors would trigger CIERR interrupt and omit playback of the ADPCM sector with bad CI byte). 0Dh.W - "PLBA" - Unknown <-- shown as so in SNES CD's "CXD1800" test screen 7-0 PLBA? ;Maybe PLBA means "PLayBAck" or even "PLayBAckwards" or so? _________________________ Interrupt / Status _________________________ 01h.R - INTSTS - Interrupt Status (0=No IRQ, 1=IRQ) (R) X4h.W - INTMSK - Interrupt Mask (0=Disable, 1=Enable) (W) X5h.W - INTCLR - Interrupt Clear/Ack (0=No change, 1=Clear/ack) (W) 7 ADPEND ADPCM sector decode completed, and ADPCM disabled for next sector 6 DECTOUT Decoder Time Out (no Sync within 3 sectors) Can occurs (only?) after the DECODER has been set to monitor only mode, or real time correction mode. 5 DMACMP DMA Complete (by DMAXFRC=0) (0=No, 1=Yes) 4 DECINT Decoder Interrupt (new "current sector" arrived) (0=No, 1=Yes) If a SYNC mark is detected or internally inserted during execution of the write only, monitor only and real time correction modes by the DECODER, the DECINT status is created. When the SYNC mark detected window is open, however, if the SYNC mark spacing is less than 2352 bytes, the DECINT status is not created. During execution of the repeat correction mode by the DECODER, the DECINT status is created each time a correction ends. 3 CIERR Coding Info Error (0=Okay, 1=Bad CI in ADPCM sector & AUTOCI=1) 2-0 - Reserved (should be 0) DECINT Handling (new "current sector" successfully/unsuccessfully received) First check the error flags in STS and HDRFLG registers (if desired, also check MDFM and ADPCI to see how the decoder interpreted the sector). Then check the MM:SS:FF values in HDR_xxx registers and ignore the sector if the values aren't matching up with the desired values (that may happen if the mechacon settled on sector number slightly lower than the requested seek address, it might also happen during seek-busy phase, and it might happen if a sector was skipped for some reason, which would require to issue a new seek command and to retry reading the skipped sector). When using ADPCM playback, also check SHDR_xxx registers to see if the sector contains ADPCM data, and if it's having the desired file/channel numbers, if so, set the ADPEN bit in CHPCTL. Otherwise, if the sector is desired to be loaded to SNES memory: Handle the CMADR either immediately, or if that isn't possible, memorize it in a queue, and handle it as soon as possible, ie. after processing older queue entries, but before the Sector Buffer location gets overwritten by newer sectors; the 32K SRAM can probably hold at least 8 sectors (8 x 924h bytes, plus some unused padding areas, possibly plus some ADPCM area; as so on PSX). As for handling CMADR: Usually one would only read the 800h-byte data portion (without Header and Subheader), done by writing CMDADR+4 (for MODE1) or CMDADR+0Ch (for MODE2) to DMAADRC, then writing 8800h to DMAXFRC, and then reading 800h bytes from port 21E2h (usually via a SNES DMA channel). 02h.R - STS - Status (R) 7 DRQ Data Request (DRQ Pin) (0=?, 1=?) 6 ADPBSY ADPCM Playback Busy (0=No, 1=Busy) 5 ERINBLK Erasure in Block; C2 flg anywhere except Syncmark (0=Okay, 1=Bad) 4 CORINH Correction Inhibit; MODE/FORM error & AUTODIST=1 (0=Okay, 1=Bad) 3 EDCOK EDC Error Detect Checksum (optional for FORM2) (0=Bad, 1=Okay) 2 ECCOK ECC Error Correction Codes (not for FORM2) (0=Bad, 1=Okay) 1 SHRTSCT Sync Mark too early, no ECC/EDC done (0=Okay, 1=Bad) 0 NOSYNC Sync Mark too late/missing, unreal SYNC inserted (0=Okay, 1=Bad) 03h.R - HDRFLG - Header C2-Error Flags (R) 7 MIN Header MM (0=Okay, 1=Error) ;\ 6 SEC Header SS (0=Okay, 1=Error) ; Header from MODE1/MODE2 data 5 BLOCK Header FF (0=Okay, 1=Error) ; sector (ie. not for audio) 4 MODE Header MODE (0=Okay, 1=Error) ;/ 3 FILE Sub-Header (0=Okay, 1=Error) ;\Subheader exists for MODE2 only 2 CHANNEL Sub-Header (0=Okay, 1=Error) ; (the SNES CD BIOS wants these 1 SUBMODE Sub-Header (0=Okay, 1=Error) ; bits to be zero for MODE1, too) 0 CI Sub-Header (0=Okay, 1=Error) ;/ X4h.R - HDR_MIN - Header "MM" Minute (R) X5h.R - HDR_SEC - Header "SS" Second (R) X6h.R - HDR_BLOCK - Header "FF" Frame (R) X7h.R - HDR_MODE - Header Mode (R) 08h.R - SHDR_FILE - Sub-Header File (R) 09h.R - SHDR_CH - Sub-Header Channel (R) 0Ah.R - SHDR_S-MODE - Sub-Header SubMode (R) 0Bh.R - SHDR_CI - Sub-Header Coding Info (R) Contains current sector's 4-byte Header (and 4-byte Subheader for MODE2 discs). 0Ch/0Dh.R - CMADR_L/H - Current Minute Address, Low/High (R) 15 Unused 14-0 Pointer to 1st byte of current sector (ie. to MM:SS:FF:MODE header) Note: "Minute" is meaning the "1st byte of the sector". Named so because the 1st byte the "MM" value from the "MM:SS:FF:MODE" header. The sector stored in SRAM is 924h bytes in size (ie. the whole 930h-byte sector, excluding the 12 Sync bytes). XEh.R - MDFM - MODE/FORM (R) 7-5 X Unused 4 RMODE2 Raw MODE byte, Bit2-7 ("logic sum") (aka all six bits ORed?) Indicates the logic sum of the value of the high-order 6 bits of the raw MODE byte AND THE POINTER (whut pointer?). 3 RMODE1 Raw MODE byte, Bit1 2 RMODE0 Raw MODE byte, Bit0 1 CMODE Correction Mode (0=MODE1, 1=MODE2) 0 CFORM Correction Form (0=FORM1, 1=FORM2) (for MODE2 only) These bits indicate which of the MODEs and FORMs this IC determined that the current sector was associated with when it corrected errors. XFh.R - ADPCI - ADPCM Coding Information (R) 7 MUTE DA data is muted on (0=No, 1=Muted) <--- from where? 6 EMPHASIS ADPCM Emphasis (0=Normal/Off, 1=Emphasis) 5 EOR End of Record <--- (from SubMode.Bit0) 4 BITLNGTH ADPCM Bit Length (0=Normal/4bit, 1=8bit) 3 X Unused 2 FS ADPCM Sampling Frequency (0=37800Hz, 1=18900Hz) 1 X Unused 0 M/S ADPCM Mono/Stereo (0=Mono, 1=Stereo) Bit5 gets 1 when the SubMode.bit0=1 and there is no error in the SubMode byte. _________________________ DMA / Sector Buffer _________________________ 00h.R - DMADATA - SRAM-to-CPU Xfer Data (R) 7-0 Data from Sector buffer at [DMAADRC] Reading increments DMAADRC and decrements DMAXFRC. However, for this special case, REGADR is NOT incremented (allowing to read DMADATA continously without needing to reset REGADR). X7h/X8h.W - DMAADRC_L/H - SRAM-to-CPU Xfer Address, Low/High (W) 1Ah/1Bh.R - DMAADRC_L/H - SRAM-to-CPU Xfer Address, Low/High (R) 15 Unused 14-0 Current Read address for SRAM-to-CPU transfer (incrementing) X9h/XAh.W - DMAXFRC_L/H - SRAM-to-CPU Xfer Length & DMA Control, Low/High (W) 18h/19h.R - DMAXFRC_L/H - SRAM-to-CPU Xfer Length, Low/High (R) For writing X9h/XAh (with DMAEN bit inserted between other bits): 15-12 DMAXFRC11-8 Transfer Length Remain Counter DMAXFRC, bit11-8 11 DMAEN CPU DMA Enable (0=Inhibit, 1=Enable) 10-8 - Reserved (should be 0) 7-0 DMAXFRC7-0 Transfer Length Remain Counter DMAXFRC, bit7-0 For reading 18h/19h (without DMAEN bit, but instead with 15bit counter range): 15 Unused Unused 14-0 DMAXFRC14-0 Transfer Length Remain Counter DMAXFRC, bit14-0 Setting DMAEN=1 does automatically set REGADR=00h (ie. select the DMADATA register). DMAEN=1 should be used whenever starting a transfer (not matter if the data is transferred via DMA, or if it's manually polled from DMADATA register). The DMACMP IRQ will occur when DMAXFRX reaches zero (to avoid that effect, one may write DMAXFRC=0800h (DMAEN=1 and counter=000h); that will reportedly prevent the IRQ; either because the counter doesn't decrease beyond zero, or maybe it wraps to 7FFFh and thus won't expire anytime soon). XBh/XCh.W - DRVADRC_L/H - Disc-to-SRAM Xfer Address, Low/High (W) 1Ch/1Dh.R - DRVADRC_L/H - Disc-to-SRAM Xfer Address, Low/High (R) 15 Unused 14-0 Disc-to-SRAM Xfer Address (incrementing) This register is automatically advanced when storing incoming disc data in Sector Buffer. The SNES CD BIOS doesn't touch this register at all. Note: The datasheet has some obscure notes about needing to write the register before "write only mode and real time correction mode" (unknown how/why/when to do that). SNES Cart CDROM - Component List -------------------------------- "based on the on photos that have been posted, the main board has the same parts as a Super Famicom, but with 7 additional chips: 1) CXD2500 CD-DSP 2) CXD1800 CD-ROM decoder/interface 3) 32K SRAM (presuambly the CD-ROM sector buffer) 4) some 20 pin SOP device that looks like a bus buffer 5) a QFP with no markings (mechacon MCU?) 6) A Sanyo 16 bit stereo DAC 7) an 8 pin SOP - probably a dual opamp (it's next to the DAC outputs, so probably a buffer) The top board has a 4-bit MCU and a liquid crystal display. There are also 5 visible ICs on the back of the CD-ROM control board - one of them is a Rohm BTL driver another looks like a Sony CXA1272 (old CD drive focus / tracking servo) - the other chips are small SOP devices with numbers I can't read. No sign of an RF amp chip, but on a lot of those older drives it was built into the optical pickup. Basically, it has all the chips you would expect for a basic data/audio CD drive of that vintage and nothing else." Sony Playstation SFX-100 Console Component List Mainboard (MA-115, 0-396-987-04) IC101 100pin Nintendo S-CPU, 5A22-01 (65816 CPU with joypad I/O ports) IC102 100pin Nintendo S-PPU1, 5C77-01 (Video Chip 1) IC103 100pin Nintendo S-PPU2, 5C78-01 (Video Chip 2) IC104 28pin NEC uPD43256A6U-10L? (32Kx8 SRAM, Video RAM 1) IC105 28pin NEC uPD43256A6U-10L? (32Kx8 SRAM, Video RAM 2) IC106 ... whatever, maybe S-ENC or similar (Video RGB to composite) IC107 64pin Nintendo S-WRAM (128Kx8 DRAM with B-bus) IC108 28pin 65256BLFP-12T (32Kx8 SRAM, Sound RAM 1) IC109 18pin Nintendo F411 (NTSC CIC) IC110 28pin 65256BLFP-12T (32Kx8 SRAM, Sound RAM 2) IC111 64pin SONY CXP1100Q-1 (APU, some newer S-SMP revision, SPC700 CPU) IC112 80pin SONY CXD1222Q-1 (APU, some newer S-DSP revision, Sound Chip) IC113 20pin LC78815M (Two-channel 16bit D/A converter 1) IC201 80pin SONY CXD2500AQ (CDROM Signal Processor) IC202 20pin LC78815M (Two-channel 16bit D/A converter 2) IC203 48pin Noname ... maybe Servo Amplifier (like CXA1782BR on PSX?) IC204 80pin SONY CXD1800Q (CDROM Decoder/FIFO, equivalent to CXD1196AR) IC205 18pin 74xxxx? (PCB has 20pin solderpoints, but chip is only 18pin) IC206 28pin SONY CXK58257AM-70L (32Kx8 SRAM, CDROM Sector Buffer) IC301 8pin Texas Instruments RC4558, "R4558 TI 25" (Dual Op-Amp 1) IC302 ... ... whatever, maybe one of the 8pin IC???'s IC303 8pin Texas Instruments RC4558, "R4558 TI 25" (Dual Op-Amp 2) ICxxx ... if any... ? IC??? 8pin whatever (front board edge, near headphone socket) IC??? 8pin whatever (front board edge, near headphone socket) IC??? 24pin whatever (front/mid board edge) (probably S-ENC or so) IC??? 3pin voltage regulator (7805 or similar) IC??? ?? address decoder for I/O ports, 21E4h latch, NEXT port...? (maybe IC203 is doing that? but then where's Servo Amplifier?) CN201 29pin To LCD Board CN.. .. To CDROM Drive CN.. .. To Controller Ports CN.. 62pin SNES Cartridge Slot CN.. .. Rear panel Daughterboard with LCD IC701 80pin NEC uPD75P308GF (CDROM Mechacon?) IC7xx ... if any... ? X701 oscillator CN701 28pin LCD and six Buttons (28pin, or maybe 2x28 pins?) CN702 4pin to somewhere (2 LEDs ?, left of drive tray) CN703 29pin to Mainboard (29pin, or maybe 2x29 pins?) CN704 3pin to front panel (disc eject button?, right of drive tray) ICxxx ... if any... ? N/A? 28pin Something like BA6297AFP,BA6398FP,BA6397FP,AN8732SB,etc ? Daughterboard with controller ports ??? ... whatever Daughterboard with Eject button ??? ... whatever, a button, and maybe more stuff for the 3pin wire Daughterboard with LEDs ??? ... whatever, two LEDs, and maybe more stuff for the 4pin wire Components in actual CD Drive unit ??? ... whatever External Connectors 1x snes cartridge slot (top) 2x controller ports (front) 1x 3.5mm headphone socket with "voltage level" regulator (front) 1x "NEXT" port (serial link like PSX maybe?) 1x Audio R (red) (apparently with mono-switch when not connected) 1x Audio L (MONO) (white) 1x Video (yellow) 1x S VIDEO 1x RF DC OUT 1x MULTI OUT 1x DC IN 7.6V Note: Some other/similar model has three RCA jacks instead headphone on front BIOS Cartridge - Case Sticker "'92.10.6." (plus some japanese symbols) PCB "RB-01, K-PE1-945-01" IC1 64pin Nintendo S-WRAM (128Kx8 DRAM) IC2 64pin Nintendo S-WRAM (128Kx8 DRAM) IC3 32pin HN2xxxxxx? (Sticker 0.95 SX) (ROM/EPROM) IC4 28pin SONY CXK5864BM-12LL (8Kx8 SRAM) IC5 16pin Noname? IC6 14pin 74F32 (Quad 2-input OR gates) IC7 16pin 74F138? (1-of-8 inverting decoder/demultiplexer?) IC8 14pin Noname? IC9 14pin Noname? IC10 16pin Noname? IC11 16pin Nintendo D411 (NTSC CIC) ? ? white space (in upper left) ? 2pin something with 2 pins is apparently on PCB back side (battery?) LCD/Button Panel PlayStation SFX-100 .---------------------------. | TRACK STEP/MIN SEC | | .---------------------. | | | (LCD) | | | '---------------------' | | PLAY MODE REMAIN | | =========== =========== | | |<< >>| | | =========== =========== | | |> || [] | | =========== =========== | '---------------------------' Note: The date codes on the three S-WRAM's, D411, and uPD75P308GF seem to be from 1991. Sticker on case of BIOS cart seems to be from 1992. SNES Hotel Boxes and Arcade Machines ------------------------------------ Nintendo Super System (NSS) (USA) (1991) Arcade Cabinet. Contains up to three special cartridges (with one game each). --> NSS Memory and I/O Maps --> NSS I/O Ports - Control Registers --> NSS I/O Ports - Button Inputs and Coin Control --> NSS I/O Ports - RTC and OSD --> NSS I/O Ports - EEPROM and PROM --> NSS BIOS and INST ROM Maps --> NSS Interpreter Tokens --> NSS Controls --> NSS Games, BIOSes and ROM-Images --> NSS Component Lists --> NSS On-Screen Controller (OSD) --> SNES Pinouts NSS Connectors --> Z80 CPU Specifications Super Famicom Box (Japan/Nintendo/HAL) (1993) For use in hotel rooms. Typically contains two special multi-carts (which, together, contain a menu-program and 5 games). --> SFC-Box Overview --> SFC-Box Coprocessor (HD64180) (extended Z80) --> SFC-Box Memory & I/O Maps --> SFC-Box I/O Ports (Custom Ports) --> SFC-Box I/O Ports (HD64180 Ports) --> SFC-Box GROM Format --> SFC-Box OSD Chip (On-Screen Display Controller) --> SFC-Box Component List (Cartridges) --> SFC-Box Component List (Console) --> RTC S-3520 (Real-Time Clock) --> Z80 CPU Specifications --> HD64180 --> HD64180 Internal I/O Map --> HD64180 New Opcodes (Z80 Extension) --> HD64180 Serial I/O Ports (ASCI and CSI/O) --> HD64180 Timers (PRT and FRC) --> HD64180 Direct Memory Access (DMA) --> HD64180 Interrupts --> HD64180 Memory Mapping and Control --> HD64180 Extensions DS-109S (Third-Party/Japan?) (Osaka Tu...?) For hotels or so. Contains 10 regular SNES/SFC cartridges. Game selection is done via a push button and single-digit 7-segment LED display. Not much more known about the hardware. Nintendo Gateway System / Lodgenet (USA/Third-Party) For hotels and airports or so. Reportedly offers 18 SNES games or so (later versions allow games for other/newer consoles). There seem to be no photos of the hardware. With the "net" in in "Lodgenet" mind... it might be "server based" (with only Controller & TV-Set located in the hotel room, and the actual Console & Games located elsewhere?). NSS Memory and I/O Maps ----------------------- Z80 Memory Map 0000h-7FFFh : 32K BIOS 8000h-9FFFh : 8K RAM (upper 4K with write-protect) A000h : EEPROM Input (R) C000h-DFFFh : Upper 8K of 32K Instruction EPROM (in Cartridge) (INST-ROM) E000h : EEPROM Output (W) Exxxh : PROM Input AND Output AND Program Code (RST opcodes) (R/W/EXEC) Note: For some reason, Nintendo has stored the 8K INST-ROM in 32K EPROMs - the first 24K of that EPROMs are unused (usually 00h-filled or FFh-filled, and EPROM pins A13 and A14 are wired to VCC, so there is no way to access the unused 24K area). Z80 IN-Ports Port 00h.R - IC46/74LS540 - Joypad Buttons and Vsync Flag Port 01h.R - IC38/74LS540 - Front-Panel Buttons & Game Over Flag Port 02h.R - IC32/74LS540 - Coin and Service Buttons Inputs Port 03h.R - IC31/74HC367 - Real-Time Clock (RTC) Input Port 04h.R - Returns FFh (unused) Port 05h.R - Returns FFh (unused) Port 06h.R - Returns FFh (unused) Port 07h.R - Returns FFh (same effect as write-any-value to Port 07h.W) Port 0008h..FFFFh are mirrors of above ports (whereof, mirrors at xx00h..xx03h are often used). Z80 OUT-Ports Port 00h/80h.W - IC40/74HC161 - NMI Control and RAM-Protect Port 01h/81h.W - IC39/74HC377 - Unknown and Slot Select Port 02h/82h/72h/EAh.W - IC45/74HC377 - RTC and OSD Port 03h/83h.W - IC47/74HC377 - Unknown and LED control Port 84h.W - IC25/74HC161 - Coin Counter Outputs Port 05h.W - Unused (bug: written by mistake) Port 06h.W - Unused Port 07h.W - IC23/74HC109 - SNES Watchdog: Acknowledge SNES Joypad Read Flag These ports seem to be decoded by A0..A2 only (upper address bits are sometimes set to this or that value, but seem to have no meaning). SNES Memory Map Normal SNES memory map, plus some special registers: 4100h/Read.Bit0-7 - DIP-Switches (contained in some NSS cartridges) 4016h/Write.Bit0 - Joypad Strobe (probably clears the SNES Watchdog flag?) (OR, maybe that occurs not on 4016h-writes, but rather on 4016h/4017h-reads, OR elsewhere?) 4016h/Write.Bit2 - Joypad OUT2 indicates Game Over (in Skill Mode games) 4016h/4017h/4218h..421Bh - Joypad Inputs (can be disabled) NSS I/O Ports - Control Registers --------------------------------- Port WHERE.W Somewhere, following OUTPUT signals should be found: SNES Reset Signal (maybe separate CPU/PPU resets, and stop, as on PC10) SNES Joypad Disable SNES Power Supply Enable (SNES VCC switched via Q1 transistor) Maybe support for sending data from Z80 to SNES (eg. to 4016h/4017h/4213h)? Port 00h/80h.W - NMI Control and RAM-Protect (IC40/74HC161) 7-4 Unknown/unused (should be always 0) 3 Maybe SNES CPU/PPU reset (usually same as Port 01h.W.Bit1) 2 RAM at 9000h-9FFFh (0=Disable/Protect, 1=Enable/Unlock) 1 Looks like maybe somehow NMI Related ? ;\or one of these is PC10-style 0 Looks like NMI Enable ;/hardware-watchdog reload? Usually accessed as "Port 80h", sometimes as "Port 00h". Port 01h/81h.W - Unknown and Slot Select (IC39/74HC377) 7 Maybe SNES Joypad Enable? (0=Disable/Demo, 1=Enable/Game) 6 Unknown/unused (should be always 0) 5 SNES Sound Mute (0=Normal, 1=Mute) (for optional mute in demo mode) 4 Player 2 Controls (0=CN4 Connector, 1=Normal/Joypad 2) (INST ROM Flags.0) 3-2 Slot Select (0..2=1st..3rd Slot, 3=None) (mapping to both SNES and Z80) 1 Maybe SNES CPU pause? (cleared on deposit coin to continue) (1=Run) 0 Maybe SNES CPU/PPU reset? (0=Reset, 1=Run) Sometimes accessed as "Port 81h", sometimes as "Port 01h". Port 03h/83h.W - Unknown and LED control (IC47/74HC377) 7 Layer SNES Enable? (used by token proc, see 7A46h) SNES? 6 Layer OSD Enable? 5-4 Unknown/unused (should be always 0) 3 LED Instructions (0=Off, 1=On) ;-glows in demo (prompt for INST button) 2 LED Game 3 (0=Off, 1=On) ;\ 1 LED Game 2 (0=Off, 1=On) ; blinked when enough credits inserted 0 LED Game 1 (0=Off, 1=On) ;/ Usually accessed as "Port 83h", sometimes as "Port 03h". Port 05h.W - Unused/Bug 7-0 Unknown Accessed only as "Port 05h" (via "outd" opcode executed 5 times; but that seems to be just a bugged attempt to access Port 04h downto 00h). Port 07h.W - SNES Watchdog: Acknowledge SNES Joypad Read Flag (IC23/74HC109) 7-0 Unknown/unused (write any dummy value) Accessed only as "Port 07h". Writing any value seems to switch Port 00h.R.Bit7 back to "1". That bit is used for the SNES Watchdog feature; the SNES must read joypads at least once every some frames (the exact limit can be set in INST ROM). If the watchdog expires more than once, then the game is removed from the cartridge list, and used credits are returned to the user (then allowing to play other games; as long as there are any other games installed). Note: Judging from hardware tests, there seem to be other ways to acknowledge the flag (probably via Port 07h.R, or maybe even via Port 00h.R itself). NMI The NMI source is unknown. Maybe Vblank/Vsync, maybe from SNES or OSD, or some other timer signal. Game/Demo-Mode Detection The original NSS games seem to be unable to detect if a coin is inserted (ie. if they should enter game or demo mode). However, it's possible to do that kind of detection: Joypad Disable does work much like disconnecting the joypad, so one can check the 17th joypad bit to check if the joypad is connected/enabled (aka if money is inserted). The Magic Floor game is using that trick to switch between game and demo mode (this has been tested by DogP and works on real hardware, ie. the NSS does really disable the whole joypad bitstream, unlike the PC10 which seems to disable only certain buttons). NSS I/O Ports - Button Inputs and Coin Control ---------------------------------------------- Port 00h.R - Joypad Buttons (IC46/74LS540) 7 SNES Watchdog (0=SNES did read Joypads, 1=Didn't do so) (ack via 07h.W) 6 Vsync (from OSD or SNES ?) (0=Vsync, 1=No) (zero for ca. 3 scanlines) 5 Button "Joypad Button B?" (0=Released, 1=Pressed) 4 Button "Joypad Button A" (0=Released, 1=Pressed) 3 Button "Joypad Down" (0=Released, 1=Pressed) 2 Button "Joypad Up" (0=Released, 1=Pressed) 1 Button "Joypad Left" (0=Released, 1=Pressed) 0 Button "Joypad Right" (0=Released, 1=Pressed) Port 01h.R - Front-Panel Buttons & Game Over Flag (IC38/74LS540) 7 From SNES Port 4016h.W.Bit2 (0=Game Over Flag, 1=Normal) (Inverted!) 6 Button "Restart" (0=Released, 1=Pressed) ;-also resets SNES? 5 Button "Page Up" (0=Released, 1=Pressed) 4 Button "Page Down" (0=Released, 1=Pressed) 3 Button "Instructions" (0=Released, 1=Pressed) 2 Button "Game 3" (0=Released, 1=Pressed) ;\if present (single 1 Button "Game 2" (0=Released, 1=Pressed) ; cartridge mode does 0 Button "Game 1" (0=Released, 1=Pressed) ;/work without them) Port 02h.R - Coin and Service Buttons Inputs (IC32/74LS540) 7-3 External 5bit input (usually CN5 isn't connected: always 0=High) 2 Service Button (1=Pressed: Add Credit; with INST button: Config) 1 Coin Input 2 (1=Coin inserted in coin-slot 2) 0 Coin Input 1 (1=Coin inserted in coin-slot 1) Port 84h.W - Coin Counter Outputs (IC25/74HC161) 7-4 Unknown/unused (should be always 0) (probably not connected anywhere) 3-2 Unknown/unused (should be always 0) (probably wired to 74HC161) 1 Coin Counter 2 (0=No change, 1=Increment external counter) 0 Coin Counter 1 (0=No change, 1=Increment external counter) Accessed only as "Port 84h". To increase a counter, the bit should be set for around 4 frames, and cleared for at least 3 frames (before sending a second pulse). NSS I/O Ports - RTC and OSD --------------------------- Real-Time Clock (RTC) and On-Screen Display (OSD) Registers Port 03h.R - Real-Time Clock (RTC) Input (IC31/74HC367) 7-1 Unknown/unused (seems to be always 7Eh, ie. all seven bits set) 0 RTC Data In (0=Low=Zero, 1=High=One) Port 02h/82h/72h/EAh.W - RTC and OSD (IC45/74HC377) 7 OSD Clock ? (usually same as Bit6) ;\Chip Select when Bit6=Bit7 ? 6 OSD Clock ? (usually same as Bit7) ;/ 5 OSD Data Out (0=Low=Zero, 1=High=One) 4 OSD Special (?) ... or just /CS ? (or software index DC3F/DD3F?) 3 RTC /CLK (0=Low=Clock, 1=High=Idle) ;S-3520 2 RTC Data Out (0=Low=Zero, 1=High=One) 1 RTC Direction (0=Low=Write, 1=High=Read) 0 RTC /CS (0=Low/Select, 1=High/No) RTC is accessed via "Port 82h", OSD via "Port 02h/72h/EAh". For OSD access, the BIOS toggles a LOT of data (and address) lines; not quite clear which of those lines are OSD CLK and OSD Chip Select. RTC Real-Time Clock (S-3520) The NSS-BIOS supports year 1900..2099 (century 00h=19xx, FFh=20xx is stored in RAM at 8F8Dh/978Dh/9F8Dh; in the two version "03" BIOSes). The current time is shown when pressing Restart in the Bookkeeping screen. --> RTC S-3520 (Real-Time Clock) OSD On-Screen Display (M50458-001SP) --> NSS On-Screen Controller (OSD) NSS I/O Ports - EEPROM and PROM ------------------------------- Memory A000h.R - EEPROM Input 7 EEPROM Data In (0=Low=Zero, 1=High=One) 6 EEPROM Ready (0=Low=Busy, 1=High=Ready) 5-0 Unknown/unused Memory E000h.W - EEPROM Output 7 Unknown/set (should be always 1) 6-5 Unknown/unused (should be always 0) 4 EEPROM Clock (0=Low=Clock, 1=High=Idle) ;(Data In/Out must be stable 3 EEPROM Data Out (0=Low=Zero, 1=High=One) ;on raising CLK edge) 2-1 Unknown/unused (should be always 0) ;(and updated on falling edge) 0 EEPROM Select (0=High=No, 1=Low=Select) Note E000h (W) and Exxxh (W) are probably mirrors of each other. If so, some care should be taken not to conflict PROM and EEPROM accesses. Memory Exxxh.R.W.EXEC - Ricoh RP5H01 serial 72bit PROM (Decryption Key) Data Write: 7-5 Unknown/unused 4 PROM Test Mode (0=Low=6bit Address, 1=High=7bit Address) 3 PROM Clock (0=Low, 1=High) ;increment address on 1-to-0 transition 2-1 Unknown/unused 0 PROM Address Reset (0=High=Reset Address to zero, 1=Low=No Change) Data Read and Opcode Fetch: 7-5 Always set (MSBs of RST Opcode) 4 PROM Counter Out (0=High=One, 1=Low=Zero) ;PROM Address Bit5 3 PROM Data Out (0=High=One, 1=Low=Zero) 2-0 Always set (LSBs of RST Opcode) The BIOS accesses the PROM in two places: 1st PROM check: Accessed via E37Fh, this part decrypts the 32h-byte area. the first data bit is read at a time when PROM reset is still high, and reset is then released after reading that data bit. At this point, there's a critical glitch: If the data bit was 1=Low, then the decryption code chooses to issue a 1-to-0 CLK transition at SAME time as when releasing reset - the PROM must ignore this CLK edge (otherwise half of the games won't work). 2nd PROM check: Accessed via EB27h, this part decrypts the double-encrypted title (from within the 32h-byte area) and displays on the OSD layer, alongsides it does verify a checksum at DC3Fh. Note: The program code hides in the OSD write string function, and gets executed when passing invalid VRAM addresses to it; this is usually done via Token 06h. This is initially done shortly after the 1st PROM check (at that point just for testing DC3Fh, with "invisible" black-on-black color attributes). And, there are two more (unused/bugged) places: 3rd PROM check: Accessed via FB37h, this part is similar to 2nd PROM check, but sends garbage to OSD screen, and is just meant to verify checksum at DD3Fh. However, this part seems to be bugged (passing FB37h to the RST handler will hang the BIOS). The stuff would be invoked via Token 4Eh, but (fortunately) the BIOS is never doing that. 4th PROM check: Accessed via ExExh, this part is comparing the 1st eight bytes of the PROM with a slightly encrypted copy in INST ROM. However, in F-Zero, the required pointer at [2Eh-2Fh] in the 32h-byte area is misaligned, thus causing the check to fail. The stuff would be invoked from inside of NMI handler (when [80ECh] nonzero), but (fortunately) the BIOS is never doing that. Note: All (used) PROM reading functions use RST vectors which are executing Z80 code in INST ROM. Accordingly, the code in INST ROM can be programmed so that it works with PROM-less cartridges. PROM Dumps Theoretically, dumping serial PROMs is ways easier than dumping parallel ROMs/EPROMs - but, as by now, nobody does ever seem to have done this. Anyways, with a brute-force program, it's possible to find matching PROM values for decrypting known title strings. Title PROM content ActRaiser B9,4B,F5,72,E4,9E,25,FF,F2,F2,00,00,F2,F2,00,00 AMAZING TENNIS 2D,EB,21,3B,9A,81,86,93,57,57,00,00,57,57,00,00 F-ZERO 49,63,FA,03,B5,DF,F6,17,B7,B7,00,00,B7,B7,00,00 LETHAL WEAPON 7F,9B,42,99,D4,C2,A9,0A,CB,CB,00,00,CB,CB,00,00 NCAA Basketball DB,35,54,07,A0,EF,A2,72,F8,F8,00,00,F8,F8,00,00 New Game 1 [Contra 3] 3A,BC,E6,47,10,DD,45,AF,FC,FC,00,00,FC,FC,00,00 ROBOCOP 3 6A,06,DC,99,5F,3A,5C,D1,5D,5D,00,00,5D,5D,00,00 Super Mario World AE,D4,A8,1C,EC,DA,8D,EA,7D,7D,00,00,7D,7D,00,00 SUPER SOCCER 6C,57,7E,3C,8F,1F,AB,F2,3D,3D,00,00,3D,3D,00,00 Super Tennis 86,B7,8E,BD,74,A3,6E,56,9F,9F,00,00,9F,9F,00,00 The Addams Family C1,70,F2,7F,3A,EC,D3,02,67,67,00,00,67,67,00,00 The Irem Skins Game D7,3F,FE,6A,B7,3A,18,AA,D6,D6,00,00,D6,D6,00,00 Mitsubishi M6M80011 64x16 Serial EEPROM Protocol All values transferred LSB first. Write Enable: Send C5h,xxh Write Disable: Send 05h,xxh Write Word: Send 25h,addr, Send lsb,msb Read Word: Send 15h,addr, Read lsb,msb Read Status: Send 95h,mode, Read stat... (mode: 0=Busy, 1=WriteEnable, 2=ECC Flag) (stat: endless repeated bits, 0=Busy/WriteEnable/ECC_Correct) ( 1=Ready/WriteDisable/ECC_Incorrect) M6M80011 Pin-Out (2x4pin version) 1=/CS, 2=/CLK, 3=DTA.IN, 4=DTA.OUT, 5=GND, 6=RESET, 7=RDY/BUSY, 8=VCC NSS EEPROM Format (Coinage Settings) 00h-3Bh Fifteen 4-byte chunks (unused entry when 1st byte = 00h) Byte0: Upper Nibble: Checksum (all other 7 nibbles added together) Byte0: Lower Nibble: Price (Number of credits for this game, 1..9) Byte1: GameID Byte2: Time Minutes (BCD) (time limit per game) Byte3: Time Seconds (BCD) (time limit per game) 3Ch Right Coinage and Unused (bit7-4=Unused, but must be 1..9) 3Dh Left Coinage and Flags (bit7=Music, bit6=Freeplay, bit5-4=Unused) 3Eh-3Fh Checksum (all bytes at [00h..3Dh] added together) 40h-7Fh Backup Copy of 00h..3Fh NSS BIOS and INST ROM Maps -------------------------- NSS BIOS ROM (32K mapped to 0000h-7FFFh) 0000h Reset Vector 0008h RST Handlers (internally used by PROM checks) 0066h NMI Handler (unknown source, probably Vblank or Vsync or so) 3FFDh Hardcoded Token Address (used by F-Zero INST ROM) 5F30h Hardcoded Return-Address from 2nd PROM check in INST ROM NSS INST ROM (8K mapped to C000h-DFFFh) [C034h]+00h..31h Encrypted Data (to be decrypted via PROM data) [C034h]+32h..33h Chksum on above 32h bytes (all BYTEs added together) [C67Fh]+C600h RST 38h for 1st PROM check ;\ [C67Fh]*100h+7Fh RST 28h for 1st PROM check ; for decrypting the [C77Fh]+C700h RST 20h for 1st PROM check ; 32h-byte area [C77Fh]*100h+7Fh RST 30h for 1st PROM check ;/ [D627h]+D600h RST 38h for 2nd PROM check ;\for decrypting the [D627h]*100h+27h RST 28h for 2nd PROM check ; 21-byte title (and [D727h]+D700h RST 20h for 2nd PROM check ; verifying [DC3Fh]) [D727h]*100h+27h RST 30h for 2nd PROM check ;/ [(where are?)] RST's for 3rd PROM check ;-this part looks bugged [DC15h+00h..29h] Spaces,FFh,"-credit play" (with underline attr) (for Menu) [DC3Fh] 8bit chksum for 2nd PROM security check [DD3Fh] 8bit chksum for 3rd PROM security check [DEF1h..DEFFh] Title (for Bookkeeping) (in 8bit OSD characters) [DF00h..DF02h] Token Entrypoint 1 (Goto token) [DF05h..DF07h] Token Entrypoint 2 (Goto token) (overlaps below DF06h!) [[DF06h]+6] Title Xloc+Odd MSBs (for title-centering via token 66h) [NNNNh] Further locations accessed via pointers in 32h-byte area [C032h] 16bit Ptr to inst.chksum.lsb ;\all WORDs at C000..DFFF [DFFEh] 16bit Ptr to inst.chksum.msb ;/added together 32h-Byte Area at [C034h]+00h..31h (encrypted via PROM data) 00h Flags Bit0 Player 2 Controls (0=CN4 Connector, 1=Normal/Joypad 2) Bit1 Unused (should be 0) Bit2 Unused (should be 0) Bit3 Continue Type (0=Normal/Resume Game, 1=Reset Game) Bit4 Continue (1=Prompt "Insert Coin to Continue" in Skill Mode) Bit5 Used entry (must be 1) (otherwise treated as empty slot) Bit6 Checksum Type ([2Ah,2Bh] and num "0" bits in chk[2Eh-2Fh]) Bit7 Skill Mode (0=Time-Limit Mode, 1=Skill Mode) 01h GameID (must be a unique value; BIOS rejects carts with same IDs) 02h-16h Title (21 OSD chars) (needs second PROM decryption pass) 17h-18h Attraction/Demo Time (in "NMI" units) ("You Are Now Viewing...") 19h-1Ah VRAM Addr for Inserted Credits string (during game play) 1Bh-1Ch Ptr to List of Encrypted Instruction Text Lines (len byte, followed by len+1 pointers to 24-word text strings) 1Dh Default Price (number of credits per game) (LSB must be 01h..09h) 1Eh Time Minutes (BCD) ;\(TIME mode: MUST be 01:00 .. 30:00 and LSB 1Fh Time Seconds (BCD) ;/MUST be 0 or 5) (In SKILL mode: [1Eh]=0Dh, some Continue delay used when Flags.4=1) 20h-21h VRAM Addr for Remaining Time value (unused in Skill Mode) 22h SNES Watchdog (SNES must read joypads every N frames; 00h=Disable) 23h ??? Byte... (jump enable for token 60h) (allow money-back?) 24h ???Byte, alternate for [25h]? 25h ???Byte, time-limit related; combined with [1Eh..1Fh,26h..27h]? 26h-27h ???Word (unused for GameID 00-02; these use 00C0h/0140h) 28h-29h Unused (0000h) 2Ah-2Bh Checksum adjust (optional XOR value for [30h-31h], when Flags.6=1) 2Ch-2Dh Encrypted.ptr to 4th check xfer.order.XOR.byte (eg.byte 07h=reverse) 2Eh-2Fh Encrypted.ptr to 4th check 8-byte key (sometimes depends [01h]) 30h-31h Checksum accross [00h..2Fh], eventually XORed with [2Ah]:[2Bh] Note: After decryption, the above 32h-bytes are stored at 8s00h..8s31h (with s=0..2 for slot 1-3). Note: Instructions can be viewed by pressing Instructions Button, either during game, or in demo mode. Skill Mode Notes There are some variants (unknown how exactly to select which variant): Game RESTARTS after Game Over (if one still has credits) Game CONTINUES after Game Over (if one still has credits) And, if one does NOT have credits remaining: Game PROMPTS insert coin to CONTINUE (eg. ActRaiser) Game ABORTS and goes to Game Menu And, for supporting Skill Mode, the DF00h function must contain a Poke(8060h,00h) token. GameID Notes Known values used by original games are 00h..09h, FDh, and FFh. The homebrew Magic Floor game is using ID 3Fh. The no$sns/a22i tool assigns IDs 40h..BFh based on the game Title checksum (that assignment does more or less reduce risk that different homebrew games could conflict with each other). Tools The a22i assembler (in no$sns debugger, v1.3 and up) allows to create INST ROM files with title, instructions, checksums, time/skill settings, and special PROM-less RST handlers. For details see the "magicnss.a22" sample source code in the "magicsns.zip" package. NSS Interpreter Tokens ---------------------- Tokens 00h Reboot_Bios() 02h Osd_Wrstr_Direct(Len8,VramAddr16,Data16[Len], ... ,FFh,Sleep0) 04h Osd_Wrstr_Encrypted_Txt_Line(Yloc*12,Sleep0) 06h Osd_Wrstr_Prom_Title_Slot_80C0h(Len8-1,VramAddr+2000h*N,Sleep0) ? 08h Osd_Wrstr_Prom_Title(Slot+80h,Len8-1,VramAddr+2000h*N,Sleep0) ? 0Ah Port_00h_W_Set_Bits(OrValue) 0Ch Port_01h_W_Set_Bits(OrValue) 0Eh Port_03h_W_Set_Bits(OrValue) 10h Port_00h_W_Mask_Bits(AndValue) 12h Port_01h_W_Mask_Bits(AndValue) 14h Port_03h_W_Mask_Bits(AndValue) 16h Set_80C2h_To_Immediate(Imm8) 18h Set_80C3h_To_Immediate(Imm8) 1Ah Set_80C4h_To_Immediate(Imm8) 1Ch Set_80C5h_To_Immediate(Imm8) 1Eh Compare_And_Goto_If_Equal(Addr16,Imm8,Target) ;\ 20h Compare_And_Goto_If_Not_Equal(Addr16,Imm8,Target) ; unsigned 22h Compare_And_Goto_If_Below_or_Equal(Addr16,Imm8,Target) ; cmp [addr],imm 24h Compare_And_Goto_If_Above(Addr16,Imm8,Target) ;/ 26h Decrement_And_Goto_If_Nonzero(Addr16,Target) 28h Poke_Immediate(Addr16,Imm8) 2Ah Sleep_Long(Sleep16) 2Ch Disable_Interpreter_and_Reset_Gosub_Stack() 2Eh Osd_Display_Num_Credit_Play(Slot*4,VramAddr16,Sleep0) 30h Test_And_Goto_If_Nonzero(Addr16,Imm8,Target) 32h Test_And_Goto_If_Zero(Addr16,Imm8,Target) 34h Osd_Wrstr_Indirect(Addr16,Sleep0) 36h Gosub_To_Subroutine(Target) ;\max 3 nesting levels 38h Return_From_Subroutine() ;/ 3Ah Goto(Target) 3Ch _xxx() ... init some values 3Eh _xxx() ... init more, based on inst rom 40h Wait_Vblank() ;or so (waits for Port[00h].bit6) 42h Osd_Wrstr_Indexed(index8,Sleep0) 44h Reload_Attraction_Timer() 46h _xxx() ... advance to next instruction page ... or so 48h Handle_PageUpDown_For_Multipage_Instructions() 4Ah Reload_SNES_Watchdog() 4Ch Decrease_SNES_Watchdog_and_Goto_if_Expired(Target) 4Eh _xxx_osd_SPECIAL...(Slot+80h,Len8-1,VramAddr+2000h*N,Sleep0) ? bugged? 50h _copy_cart_flag_bit0_to_port_01_w_bit4() ... joypad2 vs CN4 52h Map_Slot_80C0h() 54h Osd_Wrstr_Indirect_Encrypted(Addr16,Sleep0) Below exist in BIOS version "03" only: 56h Osd_Wrstr_Num_Credit_Play(VramAddr16,Sleep0) 58h Map_Slot_804Ch() 5Ah _xxx() ;two lines: SubtractVramAddrBy1Ah_and_Strip_Underline ? 5Ch Osd_Wrstr_Prom_Title_Slot_804Ch_unless_Slot1_Empty(Len8,VramAddr,Sleep0) 5Eh Copy_8s19h_To_81E9h() ;=VRAM Addr for Credits String 60h Goto_If_8s23h_Nonzero(Target) 62h _xxx(Target) ;load timer from 8s24h or 8s25h goto if zero 64h Goto_If_GameID_is_00h_or_01h_or_02h(Target) 66h Create_Centered_Osd_Wrstr_Title_Function_at_84C0h(yloc*24) 68h _xxx() ;... 8s25h, 8s26h, and MM:SS time-limit related ? And, some general token values: 56h..7Eh Unused_Lockup() ;unused version "02" tokens ;\jump to an 6Ah..7Eh Unused_Lockup() ;unused version "03" tokens ;/endless loop 01h..7Fh Crash() ;odd token numbers jump to garbage addresses 80h..FFh Sleep_Short(Sleep7) ;00h..7Fh (in LSBs of Token) Sleep0 is an optional 00h-byte that can be appended after the Wrstr(Params) commands. If the 00h-byte is NOT there, then a Sleep occurs for 1 frame. If the 00h-byte is there, then token execution continues (after skipping the 00h) without Sleeping. Note INST ROM contains two interpreter functions (invoked via Gosub DF00h and Gosub DF05h). DF00h - Custom code (quite simple in F-Zero, very bizarre in ActRaiser) DF05h - Display centered & underlined Title in first line Available stack depth is unknown (at least one stack level is used, so there are max two free levels, or maybe less) (the DF00h function CAN use at least one stack level). The DF05h function is used for displaying the instructions headline (when viewing instructions in Demo mode). The purpose/usage of the DF00h function is unknown; essentially, everything works fine even if it just contains a Return token; for Skill Mode games it also seems to require a Poke(8060h,00h) token. NSS Controls ------------ Front Panel .---------------------------------------------------------------------------. | _________________ _________________ _________________ | | | | | | | | | | | game 1 logo | | game 2 logo | | game 3 logo | | | | | | | | | | | | | | | | | | | |_________________| |_________________| |_________________| | | ( ) ( ) ( ) | | GAME 1 GAME 2 GAME 3 | |---------------------------------------------------------------------------| | PAGE PAGE RESTART | | INSTRUCTIONS UP DOWN GAME | | __ __ ( ) ( ) ( ) __ ( ) __ | | / '''---...__ __...---''' \ / '''---...__ __...---''' \ | || _ ''' | | _ ''' || || _| |_ ( ) | | _| |_ ( ) || |' |_ _| ( ) ( ) ' ' |_ _| ( ) ( ) '| | | |_| ( ) ( ) ( ) | | |_| ( ) ( ) ( ) | | | '...........................' '...........................' | \ / '-----------------------------------------------------------------------' Unlike normal cabinets, the NSS doesn't have arcade joysticks. Instead, there are two huge SNES joypads firmly mounted on the front-plate (about twice as big as normal SNES joypads). L/R symbols are depicted on the joypad "surface" (although the actual L/R buttons seem to be on "rear" shoulders as usually). GAME 1..3 and INSTRUCTION buttons are fitted with LEDs For single-cartridge use, there may be a different front-panel without GAME 1-3 buttons (there is no Game Menu, and the Config screen is joypad controlled in single-cart mode). Plus, TEST Button, SERVICE Button Plus, TWO Coin input/switches Plus, DIP-Switches in Cartridge NSS Games, BIOSes and ROM-Images -------------------------------- Nintendo Super System BIOS (Nintendo) The BIOS is stored in a 32Kx8 EPROM on the mainboard. There are at least three BIOS versions (the version number, "02" for oldest version, and "03" for the two newer versions, is shown at the top of the Selftest result screen). The "02" version is incompatible with newer games (works only with the 3 oldest titles). NSS-v02.bin aka NSS-C.DAT ;CRC32: A8E202B3 (version "02" oldest) NSS-v03a.bin aka NSS-IC14.02 ;CRC32: E06CB58F (version "03" older) NSS-v03b.bin aka NSS-V3.ROM ;CRC32: AC385B53 (version "03" newer/patch) NSS Cartridge ROM-Images ROM-Images should consist of following components in following order: 1. PRG-ROM (the SNES game) (usually 512Kbytes or 1024Kbytes) 2. INST-ROM (the Z80 title & instructions) (32Kbytes) 3. PROM (decryption key) (16 bytes) Note: For the Type B/C PCBs, the PROM is 16 bytes in size. The Type A PCBs seem to be somehow different - details are still unknown; the ROM-image format may need to be changed in case that those details are discovered. The existing cartridges don't contain any coprocessors - if somebody should make such cartridges, please insert the coprocessor ROM (eg. DSP1) between PRG-ROM and INST-ROM. NSS Games PCB Title C Act Raiser (NSS) 1992 Enix (Two EPROMs+DIPSW) C Addams Family, The (NSS) 1992 Ocean (Two EPROMs+DIPSW) C Contra 3: The Alien Wars (NSS) 1992 Konami (Two EPROMs+SRAM+DIPSW) C David Crane's Amazing Tennis (NSS) 1992 Abs.Ent.Inc. (Two EPROMs+DIPSW) B F-Zero (NSS) 1991 Nintendo (ROM+SRAM) C Irem Skins Game, The (NSS) 1992 Irem (Two EPROMs+DIPSW) C Lethal Weapon (NSS) 1992 Ocean (Two EPROMs+DIPSW) - Magic Floor (NSS) 2012 nocash (EPROM+DIPSW, works without PROM) C NCAA Basketball (NSS) 1992 Sculptured Software Inc. (Two EPROMs+DIPSW) C Robocop 3 (NSS) 1992 Ocean (Two EPROMs+DIPSW) A Super Mario World (NSS) 1991 Nintendo (ROM) A Super Soccer (NSS) 1992 Human Inc. (EPROM) A Super Tennis (NSS) 1991 Nintendo (ROM) Additionally, Ocean has announced Push-Over (unknown if that was ever released). And, there seems to have been a Super Copa cartridge in Mexico. And, there is somebody owning a NHL Stanley Cup prototype cartridge. Contra 3 also appears to exist as prototype only (its INST-ROM title/instructions are just saying "New Game 1" and "To be announced"). NSS Component Lists ------------------- Cartridge PCB "NSS-01-ROM-A" (1991 Nintendo) IC1 32pin PRG ROM (LH534J ROM or TC574000 EPROM) (512Kx8 LoROM) IC2 16pin 74HC367 (2bit + 4bit drivers) (unknown purpose... for PROM?) IC3 28pin INST-ROM (27C256) (32Kx8 EPROM) IC4 8pin Key-Chip (RP5H01 serial 72bit PROM) CL/SL 2pin Jumpers (see notes) CN? 100pin Cartridge connector (2x50pin) Used by Super Mario World (ROM), Super Tennis (ROM), and Super Soccer (EPROM). For ROM: Short CL1-CL5, Open SL1-SL5. For EPROM: Short SL1-SL5, Open CL1-CL5. Cartridge PCB "NSS-01-ROM-B" (1991 Nintendo) IC1 28pin SRAM (LH5168FB-10L) IC2 32pin PRG ROM (LH534J ROM) (512Kx8 LoROM) IC3 16pin 74LS139 (demultiplexer) (for ROM vs SRAM mapping) IC4 16pin 74HC367 (2bit + 4bit drivers) (unknown purpose... for PROM?) IC5 14pin 74HC27 (3x3 NOR) (for SW1) (not installed on the F-Zero board) IC6 14pin 74HC10 (3x3 NAND)(for SW1) (not installed on the F-Zero board) IC7 20pin 74HC540 (inv.drv)(for SW1) (not installed on the F-Zero board) IC8 28pin INST-ROM (27C256) (32Kx8 EPROM) IC9 8pin Key-Chip (RP5H01 serial 72bit PROM) SW1 16pin DIP-Switch (8 switches) (not installed on the F-Zero board) AR1 9pin Resistor network (for SW1) (not installed on the F-Zero board) BAT1 2pin Battery (CR2032 3V coin) (with socket) CL/SL 2pin Jumpers (see notes) CN? 100pin Cartridge connector (2x50pin) Used only by F-Zero. For that game: Short CL1-CL7, Open SL1-SL7. Other settings might allow to use EPROM instead ROM, or to change ROM/SRAM capacity. Cartridge PCB "NSS-01-ROM-C" (1992 Nintendo) Judging from low-res photos, the PCB is basically same as NSS-01-ROM-B, but with two PRG ROM chips (for double capactity). Exact components are unknown, except for a few ones: IC1 28pin SRAM (6116, 2Kx8) (DIP24 in 28pin socket?) (Contra III only) IC2 32pin PRG-ROM-1 (TC574000 EPROM) (512Kx8 LoROM, upper half) IC3 32pin PRG-ROM-0 (TC574000 EPROM) (512Kx8 LoROM, lower half) IC4 16pin 74LS139 (demultiplexer) (for ROM vs SRAM mapping) IC5 16pin 74HC367 (2bit + 4bit drivers) (unknown purpose... for PROM?) IC6 14pin 74HC27 (3x3 NOR) (for SW1) IC7 14pin 74HC10 (3x3 NAND)(for SW1) IC8 28pin INST ROM (27C256) (32Kx8 EPROM) IC9 20pin 74HC540 (inv.drv)(for SW1) IC10 8pin Key-Chip (RP5H01 serial 72bit PROM) SW1? 16pin DIP-Switch (8 switches) (installed) AR1 9pin Resistor network for SW1 (installed) BAT1? 2pin Battery (CR2032 3V coin) (with socket) (Contra III only) CL/SL 2pin Jumpers (see notes) CN? 100pin Cartridge connector (2x50pin) Used by ActRaiser, Addams Family, Amazing Tennis, Irem Skins Game, Lethal Weapon, NCAA Basketball, Robocop 3 (all without SRAM), and, by Contra III (with SRAM). Default (for all those games) is reportedly: Short CL2-CL6,CL12-CL13,CL15,CL17-CL19, Open SL1,SL7-SL12,SL14,SL16,SL20-SL22. DIP Switches are usually/always installed. Battery/SRAM is usually NOT installed, except on the Contra III cartridge (which has "NSS-01-ROM-C" PCB rebadged as "NSS-X1-ROM-C" with a sticker). Mainboard NSS-01-CPU MADE IN JAPAN (C) 1991 Nintendo Below lists only the main chipset (not the logic chips; which are mostly located on the bottom side of the PCB). Standard SNES Chipset S-CPU 5A22-02 (QFP100) S-PPU1 5C77-01 (QFP100) S-PPU2 5C78-01 (QFP100) S-WRAM LH68120 (SOP64) 128Kx8 DRAM with sequential access feature (SNES WRAM) Fujitsu MB84256-10L 32Kx8 SRAM (SOP28) (SNES VRAM LSBs) Fujitsu MB84256-10L 32Kx8 SRAM (SOP28) (SNES VRAM MSBs) NSS/Z80 Specific Components Zilog Z84C0006FEC Z80 CPU, clock input 4.000MHz (QFP44) 27C256 32Kx8 EPROM "NSS-C_IC14_02" (DIP28) (Z80 BIOS) Sharp LH5168N-10L 8Kx8 SRAM (SOP28) (Z80 WRAM) Mitsubishi M50458-001SP On-Screen Display (OSD) Chip (NDIP32) Mitsubishi M6M80011 64x16 Serial EEPROM (DIP8) (Pinout: 1=CS, 2=CLK, 3=DATA IN, 4=DATA OUT, 5=VSS, 6=RESET, 7=RDY, 8=VCC) Seiko Epson S-3520 Real Time Clock (SOIC14) Amplifiers/Converters/Battery and so Sharp IR3P32A (chroma/luma to RGB converter... what is that for???) (NDIP30) Hitachi HA13001 Dual 5.5W Power Amplifier IC Matsushita AN5836 DC Volume and Tone Control IC (SIL12) Mitsumi Monolithic MM1026BF Battery Controller (SOIC8) (on PCB bottom side) 5.5V - 5.5 volt supercap Oscillators 21.47724MHz SNES NTSC Master Clock <-- not 21.47727MHz, unlike NTSC (?) 14.31818MHz (unknown purpose, maybe for OSD chip or RGB converter or so) 4.000MHz for Z80 CPU 32.678kHz for RTC for OSD Dotclock Connectors CN1 - 2x28 pin connector - "JAMMA" - Audio/Video/Supply/Coin/Joypad CN2 - 10 pin connector - 10P Connector (Extra Joypad Buttons) CN3 - 13 pin connector - 13P Connector (Front Panel LEDs/Buttons) CN4 - 8 pin connector - alternate player 2 controller (eg. lightgun) (unused) CN5 - 7 pin connector - external 5bit input (Port 02h.R.bit3-7) (unused) CN6 - 24 pin connector (to APU daughterboard) CN11/12/13 - 2x50 pin connectors for game cartridges Jumpers SL1/SL2/SL3/CL1/CL2 - Mono/stero mode (for details see PCB text layer) SL4 - Use Audio+ (pin 11 on edge connector) SL5 - Unknown purpose TB1 - Z80 Watchdog Disable APU Daughterboard (shielded unit, plugged into CN6 on mainboard) Nintendo S-SMP (M) SONY (C) Nintendo '89' (QFP80) (SNES SPC700 CPU) Nintendo S-DSP (M) (C) SONY '89' (QFP80) (SNES sound chip) Toshiba TC51832FL-12 32Kx8 SRAM (SOP28) (1st half of APU RAM) Toshiba TC51832FL-12 32Kx8 SRAM (SOP28) (2nd half of APU RAM) Japan Radio Co. JRC2904 Dual Low Power Op Amp (SOIC8) NEC D6376 Audio 2-Channel 16-Bit D/A Converter (SOIC16) CN1 - 24 pin connector (to CN6 on mainboard) for APU (probably SNES/APU standard 24.576MHz) NSS On-Screen Controller (OSD) ------------------------------ On-Screen Display Controller M50458-001SP (Mitsubishi Microcomputers) OSD Addresses The OSD Address is transferred as first word (after chip select): 0000h..011Fh Character RAM (24x12 tiles, aka 288 tiles, aka 120h tiles) 0120h..0127h Configuration Registers (8 registers) Further words are then written to the specified address (which is auto-incremented after each word). Character Codes (for OSD Address 000h..011Fh) 0-6 Character Number (non-ASCII) 7 Unused (zero) 8-10 Text Color (on NSS: 3bit RGB) (Bit0=Red, Bit1=Green, Bit2=Blue) 11 Blinking flag (0=Normal, 1=Blink) 12 Underline flag (0=Normal, 1=Underline) 13-15 Unused (zero) (on NSS: used as hidden PROM check flags by NSS BIOS) The M50458-001SP charset has been dumped by DogP, letters & punctuation marks are: Character <---00h..0Fh---><---10h..1Fh---><---20h..2Fh---><---30h..3Fh---> 00h..3Fh "0123456789-:/.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ[]();?| " 40h..7Fh "_abcdefghijklmnopqrstuvwxyz+*=# " All characters are 12x18 pixels in size. OSD M50458 Register 0 - Port Output Control 0 P0 Usage (0=Manual Control, 1=YM; Luminance) 1 P1 Usage (0=Manual Control, 1=BLNK; Blanking) 2 P2 Usage (0=Manual Control, 1=B; Blue) 3 P3 Usage (0=Manual Control, 1=G; Green) 4 P4 Usage (0=Manual Control, 1=R; Red) 5 P5 Usage (0=Manual Control, 1=CSYN; Composite Sync) 6-11 Manual P0-P5 Output Level (0=Low, 1=High) 12 Synchronize Port Output with Vsync (0=No, 1=Yes) 13-15 Unused (zero) NSS uses values 003Fh (whatever/maybe SNES as backdrop), and 00BDh (maybe solid backdrop). OSD M50458 Register 1 - Horizontal Display Start/Zoom 0-5 Horizontal Display Start in 4-pixel (?) units 6-7 Horizontal Character Size in Line 1 (0..3 = 1,2,3,4 pixels/dot) 8-9 Horizontal Character Size in Line 2..11 (0..3 = 1,2,3,4 pixels/dot) 10-11 Horizontal Character Size in Line 12 (0..3 = 1,2,3,4 pixels/dot) 12 PAL: Interlace Lines (0=625 Lines, 1=627 Lines) NTSC: Unused (zero) 13-15 Unused (zero) NSS uses 0018h (normal centered display) and 011Bh (fine-adjusted position in intro screen). OSD M50458 Register 2 - Vertical Display Start/Zoom 0-5 Vertical Display Start in 4-scanline (?) units 6-7 Vertical Character Size in Line 1 (0..3 = 1,2,3,4 pixels/dot) 8-9 Vertical Character Size in Line 2..11 (0..3 = 1,2,3,4 pixels/dot) 10-11 Vertical Character Size in Line 12 (0..3 = 1,2,3,4 pixels/dot) 12 Halftone in Superimpose Display (0=Halftone Off, Halftone On) 13-15 Unused (zero) NSS uses 0009h (normal centered display) and 0107h (fine-adjusted position in intro screen). OSD M50458 Register 3 - Character Size 0-4 Vertical Scroll Dot Offset (within char) (0..17) (18..31=Reserved) 5-6 Vertical Space between Line 1 and 2 (0..3 = 0,18,36,54 scanlines) 7 Control RS,CB Terminals (0=Both Off, 1=Both On) 8-11 Vertical Scroll Char Offset (0=No Scroll, 1..11=Line 2-12, 12..15=Res.) 12 PAL: Revise 25Hz Vsync (0=No, 1=Yes/Revice) NTSC: Unused 13-15 Unused (zero) NSS uses 0000h (normal 1x1 pix size) and 082Ah (large 2x2 pix "NINTENDO" in intro), 0y20h (in-demo: instructions with double-height headline? and y-scroll on 2nd..10th line), 0y00h (in-game: instructions without headline and fullscreen scroll). Verical Scroll OFF: Show 12 lines Verical Scroll ON: Show 11 lines (1st line fixed, 10 lines scrolled) (in scroll mode only 11 lines are shown) (allowing to update the hidden 12th line without disturbing the display) OSD M50458 Register 4 - Display Mode 0-11 Display Mode Flags for Line 1..12 (0=Via BLK0,BLK1, 1=Via Different) 12 LINEU - Underline Display (0=Off, 1=On) "depends on above bit0-bit11" 13-15 Unused (zero) NSS uses 0000h. OSD M50458 Register 5 - Blinking and so on 0-1 Blink Duty (0=Off, 1=25%, 2=50%, 3=75%) (WHAT color during WHAT time?) 2 Blink Cycle (0=64 Frames, 1=32 Frames) 3 Horizontal Border Size (0..1 = 1,2 dots) 4-5 Blink/Inverse Mode (0=Cursor, 1=ReverseChr, 2=ReverseBlink, 3=AltBlink) aka EXP0,EXP1 (see details below) 6 Horizontal Display Range when all chars are in matrix-outline (0..1=?) 7 OSCIN frequency (0=4*fsec, 1=2*fsec) (for NTSC only) 8 Color Burst Width (0=Standard, 1=Altered) 9 Vsync Signal separated from Composite Sync (0=No, 1=Separated Circut) 10-12 Test Register "Exception video RAM display mode" (should be zero) 13-15 Unused (zero) NSS uses 0240h, 0241h, 0247h. OSD M50458 Register 6 - Raster Color 0-2 Raster Color (on NSS: 3bit RGB) (Bit0=Red, Bit1=Green, Bit2=Blue) (aka Backdrop color?) 3 Composite Signal BIAS (0=Internal BIAS Off, 1=Internal BIAS On) 4-6 Character Background Color (Bit0=Red, Bit1=Green, Bit2=Blue) 7 Blanking Level (0=White, 1=Black) 8-10 Cursor and Underline Display Color (Bit0=Red, Bit1=Green, Bit2=Blue) 11 Cursor/Underline Color for Dot 1 (0=From VRAM, 1=From above bit8-10) 12 Cursor/Underline Color for Dot 18 (0=From VRAM, 1=From above bit8-10) 13-15 Unused (zero) NSS uses 1804h, 1880h, 1882h, 1884h. OSD M50458 Register 7 - Control Display 0 Raster (backdrop?) blanking (0=By Mode;bit2-3?, 1=Whole TV full raster) 1 Background Color Brightness for RGB (0=Normal, 1=Variable) huh? 2-3 Mode (0=Blanking OFF, 1=Chr Size, 2=Border Size, 3=Matrix-outline Size) aka special meanings in conjunction with register 4 (?) 4 Mode (0=External Sync, 1=Internal Sync) 5 Erase RAM (0=No, 1=Erase RAM) (=clear screen?) 6 Display Output Enable for Composite Signal (0=Off, 1=On) 7 Display Output Enable for RGB Signal (0=Off, 1=On) 8 Stop OSCIN/OSCOUT (0=Oscillate, 1=Stop) (for sync signals) 9 Stop OSC1/OSC2 (0=Oscillate, 1=Stop) (for display) 10 Exchange External C by Internal C in Y-C Mode (0=Normal, 1=Exchange) 11 Video Signal (0=Composite, 1=Y-C output) 12 Interlace Enable (0=Enable, 1=Disable) (only in Internal Sync mode) 13-15 Unused (zero) NSS uses 1289h, 12A9h and 12B9h. NSS OSD Dotclock The OSD chip is having an unknown dotclock (somewhat higher than the SNES dotclock: 12 pixels on OSD are having roughly the same width as 8 pixels on SNES). Blink/Underline Shape EXP1 EXP0 EXP BLINK x x 0 0 " A " Normal x x 0 1 " A " <--> " " Character is blinking 0 0 1 0 "_A_" Underlined 0 0 1 1 "_A_" <--> " A " Underline is blinking 0 1 1 0 "[A]" Inverted Character 0 1 1 1 "[A]" <--> " A " Inversion is blinking 1 0 1 0 "[A]" Inverted Character 1 0 1 1 "[A]" <--> " A " Inversion is blinking 1 1 1 0 " " <--> " A " Character is blinking, duty swapped 1 1 1 1 " A " <--> "_ _" Character and Underline alternating SFC-Box Overview ---------------- Main Menu Allows to select from 5 games Note: If the two cartridges do contain more than 5 games in total, then the GUI is divided into two pages with 4 games, plus prev/next page option (unknown if more than 8 games are also supported). Per Game Menu (after selecting a Game in Main Menu) 1. Game Start 2. Game Instructions 3. Game Preview 4. Return to Main Menu Soft-Reset Feature Press L+R+Select+Start (on Joypad) --> Reset Current Game Press Reset Button (on SFC-Box Front Panel) --> Restart Boot Menu GAME/TV Button Allows to switch between Game & TV mode. The purpose is totally unclear... maybe it just allows to disable forwarding the Antenna-input to the RF-Out connector... but, should one want to disable that? SFC-Box Cartridges The SFC-Box contains two special multi-game cartridges. There have been only 4 cartridges produced. The first cartridge MUST be always PSS61 (contains 3 games, plus the required GUI and 128Kbyte SRAM). The second cartridge can be PSS62, PSS63, or PSS64 (which contain 2 games each; these carts have no own SRAM, but they can share portions of the SRAM from the PSS61 cart). SFC-Box Special ROM/EPROMs KROM 1 EPROM 64Kbytes (HD64180 BIOS in SFC-Box console) GROM1-1 EPROM 32Kbytes (Directory) (IC1 in PSS61 cart) GROM2-1 EPROM 32Kbytes (Directory) (IC1 in PSS62 cart) GROM3-1 EPROM 32Kbytes (Directory) (IC1 in PSS63 cart) GROM4-1 EPROM 32Kbytes (Directory) (IC1 in PSS64 cart) ATROM-4S-0 LoROM 512Kbytes (GUI "Attraction" Menu) (ROM5 in PSS61 cart) DSP1 DSP ROM 8Kbytes (or with padding: 10Kbytes) MB90082 OSD ROM 9Kbytes (OSD-Character Set in MB90082-001 chip) ATROM-4S-0 contains a regular SNES header at 7FC0h, interesting entries are: 7FC0h Title "4S ATTRACTION " 7FD6h Coprocessors (00h) (none, but, ATROM can communicate with the HD64180) 7FD8h RAM Size (00h) (none, but, GROM indicates 32Kbytes allocated to ATROM) 7FDAh Maker (B6h) (HAL) Note: "GROM3-1" is dumped (but its ROM-image is "conventionally" misnamed as "GROM1-3"). There is reportedly also a "different" GUI version (not confirmed/details unknown, maybe there's just a configuration setting, in SRAM or EPROMs or so, that changes the GUI appearance). SFC-Box Game ROMs SHVC-4M-1 LoROM 2048Kbytes (Mario Collection) (ROM3 in PSS61 cart) SHVC-MK-0 HiROM 512Kbytes (Mario Kart) (ROM12 in PSS61 cart) SHVC-FO-1 LoROM 1024Kbytes (Starfox) (IC20 in PSS61 cart) SHVC-GC-0 LoROM 1024Kbytes (WaiaraeGolf) (ROM1 in PSS62 cart) SHVC-2A-1 HiROM 512Kbytes (Mahjong) (ROM9 in PSS62 cart) SHVC-8X-1 HiROM 4096Kbytes (Donkey Kong) (ROM7 in PSS63 cart) SHVC-T2-1 LoROM 1024Kbytes (Tetris2/Bombliss) (ROM3 in PSS63 cart) SHVC-8X-1 HiROM 4096Kbytes (Donkey Kong) (ROM7 in PSS64 cart) SHVC-M4-0 HiROM 1024Kbytes (Bomberman2) (ROM9 in PSS64 cart) All Game ROMs seem to be identical as in normal (japanese) cartridges, (ie. without any SFC-Box specific revisions). SFC-Box ROM-Images ROM-Images should contain all EPROMs/ROMs from the cartridge, ordered as so: GROM + ROM0(+ROM1(+ROM2(+etc))) (+DSP1) The GROM at the begin of the file does also serve as file header: The size of the GROM (1 SHL N kbytes) is found in GROM [0001h]. The number of ROMs is found in GROM [0000h]. Title & Size of ROM can be found at [[0008h]+n*2]*1000h. Physical IC Socket ID for ROM can be found in GROM at [0008h]+[0000h]*2+n. The presence of a DSP ROM Image is indicated in GROM [0004h].Bit1. With that information, one can calculate the file-offsets for each ROM. If desired, one may merge two cartridges images in one file, eg. GROM1+ROM0+ROM1+ROM2+ROM3+DSP + GROM2+ROM0+ROM1 Before merging GROM+ROMs, make sure that the ROMs are raw-images (without 512-byte copier headers), and that the DSP ROM is unpadded (8Kbytes), in little-endian format. The additional "non-cartridge" ROMs of the SFC-Box (KROM1 and MB90082) should be located in a separate BIOS folder; not in the cartridge ROM-Image. SFC-Box Crashes Some bugged ATROM functions (7E2125h and 7E2173h) are messing up the SNES stack, causing the SNES to run into endless execution of BRK opcodes (thereby destroying lower 8K of WRAM, any enabled SRAM, and all I/O ports). Normally, SNES emulators could stop emulation in such "beyond-repair" situations - however, for the SFC-Box, emulation must be kept running (or better: crashing), since the KROM can restore normal operation by issuing a /RESET to the SNES (for example, this is happens near completion of the "**********" progress bar in the SFC-Box boot screen). Moreover, the KROM does change SNES mapping (via Port C0h/C1h), apparently without pausing/resetting the SNES CPU during that time, thus causing SNES to execute garbage code (though there are also working situations: eg. when checking the GAME headers, the SNES executes ATROM code relocated to WRAM). And, there seems to be a situation (maybe caused by above stuff) where the SNES NMI handler jumps to Open Bus regions. Note: In most or all cases, the crashing program is running into BRK opcodes (emulating BRK opcodes as "leave PC and SP unchanged" helps avoiding the more hazardous crash-effects). SFC-Box Coprocessor (HD64180) (extended Z80) -------------------------------------------- This is the "heart" of the SFC-Box. The two central parts are a HD64180 CPU (with extended Z80 instruction set), and a 64Kbyte EPROM labelled "KROM 1" (HD64180 BIOS). Plus, a frightening amount of about 50 small logic chips on the mainboard & daughterboard. Overall Features are (probably)... - Injecting Controller Data (for Demo/Preview mode) - Sniffing Controller Data (for L+R+Select+Start Soft-Reset feature) - Send/Receive Data to the SNES Menu Program (via WRIO/RDIO ports) - Mapping the selected Game ROM (or Menu Program) into SNES memory - Maybe also mapping GAME-SRAM bank(s) and/or the DSP-1 chip - Resetting the SNES, for starting the Game ROM (or Menu Program) - Reading "GROM" data from EPROMs in the cartridges - Reportedly drawing an extra "OSD" video layer on top of the SNES picture - Accessing the RTC Real-Time-Clock (unknown purpose) - Somehow logging/counting or restricting the "pay-per-play" time - Maybe handling the GAME/TV button in whatever fashion - Maybe handling the RESET button by software - Maybe controlling the two GAME/TV LEDs Pay-per-play Not much known there. Some people say the SFC-Box was coin-operated... but, it doesn't contain any coin-slot, and there seem to be no external connectors for external coin-slot hardware. And, there seem to be no external connectors for a "network-cable" for automatically charging the room-bill. Usage of [4201]=RDIO / [4213]=WRIO on SNES Side (used by Menu Program) Default WRIO output value is 00E6h. bit0 Out (usually Output=LOW, from SNES) (maybe indicate ready) bit1 In (data in, to SNES) bit2 In (status/ready/malfunction or so, to SNES) bit3 Out (clock/ack out, from SNES) bit4 Out (data out, from SNES) bit5 In (clock in, to SNES) bit6 - (probably normal joy1 io-line) bit7 - (probably normal joy2 io-line & lightgun latch) After booting, the SNES menu program checks the initial "1bit" status, and does then repeatedly receive 32bit packets (one command byte, and three parameter bytes) (and, in response to certain commands, it does additionally send or receive further bytes; in some cases these extra transfers are done via joy1/joy2 shift-registers instead of via WRIO, that probably because the HLL-coded KROM is so incredibly inefficient that it needs "hardware-accelerated" serial shifts). SFC-Box Memory & I/O Maps ------------------------- most of KROM is high-level-language based crap, this is ACTUALLY WORSE than 6502-code compiled to run on a Z80 CPU. Physical 19bit Memory Map 00000h..00FFFFh KROM 20000h..207FFFh WRAM (mainly 204000h..207FFFh used) (area at 200000h..203FFFh used as battery-ram? with read/write-protect via [A0].7?) 40000h..407FFFh GROM-Slot 0 60000h..607FFFh GROM-Slot 1 Virtual 16bit Memory Map 0000h..7FFFh KROM (first 32K) 8000h..BFFFh Bank Area (16K banks, KROM,GROM,WRAM) C000h..FFFFh WRAM (last 16K) RAM (as used by KROM1) [8000...] <-- extra 16K RAM bank (unchanged on reset/entrypoint... probably battery backed?) ... (that 16K are read/write-protected via [A0].7 ?) [C000..FFFF] work ram I/O Map [00h..3Fh] HD64180 (CPU on-chip I/O ports) [40h..7Fh] Unused (reading returns FFh) [80h].R Keyswitch and Button Inputs [80h].W SNES Transfer and Misc Output [81h].R SNES Transfer and Misc Input [81h].W Misc Output [82h].R/W Unknown/unused [83h].R Joypad Input/Status [83h].W Joypad Output/Control [84h].R/W Joypad 1, MSB (1st 8 bits) (eg. Bit7=ButtonB, 0=Low=Pressed) [85h].R/W Joypad 1, LSB (2nd 8 bits) (eg. Bit0=LSB of ID, 0=Low=One) [86h].R/W Joypad 2, MSB (1st 8 bits) (eg. Bit7=ButtonB, 0=Low=Pressed) [87h].R/W Joypad 2, LSB (2nd 8 bits) (eg. Bit0=LSB of ID, 0=Low=One) [88h..9Fh] Unused (mirrors of Port 80h..87h) [A0h].R Real Time Clock Input [A0h].W Real Time Clock Output [A1h..BFh] Unused (mirror of Port A0h) [C0h].R Unknown/unused (reading returns FFh) [C0h].W SNES Mapping Register 0 [C1h].R Unknown/unused (reading returns FFh) [C1h].W SNES Mapping Register 1 [C2h..FFh] Unused (maybe mirrors of Port C0h..C1h) (reading returns FFh) 16bit I/O Space (when address MSB=xx=nonzero): [xx00h..xx7Fh] Unused (reading returns FFh) (no mirror of 0000h..003Fh) [xx80h..xxBFh] Mirror of 0080h..00BFh [xxC0h..xxFFh] Unknown (probably mirror of 00C0h..00FFh) SFC-Box I/O Ports (Custom Ports) -------------------------------- [80h].R - Keyswitch and Button Inputs 0 Switch Pin0 Position ("OFF") Play Mode? (2nd from left) (0=Yes, 1=No) 1 Switch Pin1 Position ("ON") Play Mode? (3rd from left) (0=Yes, 1=No) 2 Switch Pin2 Position ("2") Play Mode? (4th from left) (0=Yes, 1=No) 3 Switch Pin3 Position ("3") Self-Test (5th from left) (0=Yes, 1=No) 4 Switch Pin9 Position ("1") Options (1st from left) (0=Yes, 1=No) 5 Switch Pin4 Position (N/A) Relay Off? (6th from left) (0=Yes, 1=No) 6 TV/GAME Button (0=On, 1=Off) 7 RESET Button (0=On, 1=Off) [80h].W - SNES Transfer and Misc Output 0 SNES Transfer STAT to SNES (Bit2 of WRIO/RDIO on SNES side) 1 SNES Transfer CLOCK to SNES (Bit5 of WRIO/RDIO on SNES side) 2 SNES Transfer DATA to SNES (Bit1 of WRIO/RDIO on SNES side) 3 Unknown/unused 4 ?? pulsed while [C094] is nonzero (0370h timer0 steps) 5 ?? PLENTY used (often same as bit7) 6 Unknown/unused 7 ?? (often same as bit5) [81h].R - SNES Transfer and Misc Input 0 Int0 Request (Coin-Input, Low for 44ms..80ms) (0=IRQ, 1=No) 1 SNES Transfer ACK from SNES (Bit3 of WRIO/RDIO on SNES side) 2 SNES Transfer DATA from SNES (Bit4 of WRIO/RDIO on SNES side) 3 Boot mode or so (maybe a jumper, or watchdog-flag, or Bit0 of WRIO/RDIO?) 4 Unknown/unused (0) ;\joy1/slot0 or so, used by an UNUSED function (08A0h) 5 Unknown/unused (0) ;/(for "joy2/slot1" or so, use [A0].4-5) 6 Int1 Request (Joypad is/was accessed by SNES or so?) (0=IRQ, 1=No) 7 Vblank, Vsync, or Whatever flag (seems to toggle at 100..200Hz or so?) [81h].W - Misc Output 0 SNES Reset CPU/PPU/APU/GSU/DSP1 or so (0=Reset, 1=Normal) 1 ?? PLENTY used 2 ?? something basic, ATROM related (or maybe HALT snes CPU?) 3 Int1 Acknowledge (Joypad related) (0=Ack, 1=Normal) 4 ?? PLENTY used 5 ?? set to 1-then-0 upon init (maybe ACK/RESET something?) 6 Watchdog Reload (must be pulsed during mem tests/waits/transfers/etc) 7 OSD Chip Select (for CSI/O) (0=No, 1=Select) [83h].R - Joypad Input/Status 0 Joy2 Port [86h..87h] ready for reading (0=No, 1=Yes) ;\Automatic 1 Joy1 Port [84h..85h] ready for reading (0=No, 1=Yes) ;/Reading 2 Unknown/unused (usually/always 0) 3 Unknown/unused (usually/always 1) (maybe joy4 Data?) 4 Unknown/unused (usually/always 1) (maybe joy3 Data?) 5 Joy2 Data (0=Low, 1=High) ;\that is inverse as on SNES ;\Manual 6 Joy1 Data (0=Low, 1=High) ;/(where it'd be 1=Low) ;/Reading 7 Unknown/unused (usually/always 0) [83h].W - Joypad Output/Control 0 Joypad Strobe (0=No, 1=Yes) ;\Manual 1 Joypad2? Clock (0=Yes, 1=No) ; Reading 2 Joypad1? Clock (0=Yes, 1=No) ;/ 3 Joypad Reading (0=Automatic, 1=Manual) 4 Joypad Swap (0=Normal, 1=Swap Joy1/Joy2) 5-7 Unknown/unused (should be 0) Not quite clear if the "Swap" feature affects... software/hardware? upon reading/writing? upon manual/automatic access? [84h].R/W - Joypad 1, MSB (1st 8 bits) (eg. Bit7=ButtonB, 0=Low=Pressed) [85h].R/W - Joypad 1, LSB (2nd 8 bits) (eg. Bit0=LSB of ID, 0=Low=One) [86h].R/W - Joypad 2, MSB (1st 8 bits) (eg. Bit7=ButtonB, 0=Low=Pressed) [87h].R/W - Joypad 2, LSB (2nd 8 bits) (eg. Bit0=LSB of ID, 0=Low=One) 2x16bit Joypad data from Controller / to SNES. In Automatic Reading mode, data is automatically forwarded to SNES, and if desired, it can be read from [84h..87h] (when [83h].0-1 are zero). The clock source for reading is unknown (maybe it comes from the SNES, so it'd work only IF the SNES is reading). In Manual Reading mode, joypad can be read via [83h], and data can be then forwarded to SNES by writing to [84h..87h]. Notes: Observe that the bits are inverse as on SNES (where it'd be 1=Low). Aside from [83h..87h], joypad seems to also somehow wired to INT1 interrupt (and [81h].R.Bit6 and [81h.W.Bit3). Also observe that [84h/86h] are containing the MSBs (not LSBs). The KROM1/ATROM are also mis-using [84h..87h] for general-purpose "high-speed" data transfers (that is, faster than the crude HLL coded software transfers in KROM1). [A0h].R - Real Time Clock Input (S-3520) 0 RTC Data In (0=Low=Zero, 1=High=One) 1 Unknown/unused (usually/always 0) 2 Unknown/unused (usually/always 0) 3 Unknown/unused (usually/always 1) 4 Unknown/unused (0) ;\joy2/slot1 or so, used by an UNUSED function (08A0h) 5 Unknown/unused (0) ;/(for "joy1/slot0" or so, use [81].4-5) 6 Unknown/used?! (usually/always 1) used/flag ? extra BUTTON ? 7 Unknown/used?! (usually/always 1) used/flag ? extra BUTTON ? [A0h].W - Real Time Clock Output (S-3520) 0 RTC Chip Select (0=High=No, 1=Low=Select) 1 RTC Direction (0=Low=Write, 1=High=Read) 2 RTC Data Out (0=Low=Zero, 1=High=One) 3 RTC Serial Clock (0=Low=Clk, 1=High=Idle) 4 ?? cleared after "C632" offhold (5 timer1 steps) 5 Unknown/Set to 0 (can be changed via 0A2Dh) 6 Unknown/Unused (can be changed via 0A26h) 7 Unlock access to lower 16K of WRAM (0=Lock, 1=Unlock) (save area) [C0h].W - SNES Mapping Register 0 0-1 ROM Socket (0=ROM5, 1=ROM1/7/12, 2=ROM3/9, 3=IC20) 2 ROM Slot (0=Slot0, 1=Slot1) 3 SRAM Enable (0=Disable, 1=Enable) 4 SRAM Slot (0=Slot0, 1=Slot1) 5 DSP Enable (0=Disable, 1=Enable) 6 DSP Slot (0=Slot0, 1=Slot1) 7 ROM, DSP, and/or SRAM Mapping (0=LoROM, 1=HiROM) [C1h].W - SNES Mapping Register 1 0-1 ROM, DSP, and/or SRAM Mapping (0=Reserved, 1=GSU, 2=LoROM, 3=HiROM) 2-3 SRAM Base (in 32Kbyte units) (range 0..3) 4 GSU Slot (0=Slot0, 1=Slot1) 5 Zero/Unused? 6-7 SRAM Size (0=2K, 1=8K, 2=Reserved, 3=32K) [82h].R/W - Unknown/unused [C0h].R - Unknown/unused [C1h].R - Unknown/unused Not used by KROM1 (nor GROMs). Reading from these ports usually/always returns FFh. SFC-Box I/O Ports (HD64180 Ports) --------------------------------- System Clock The CPU and Timer/Baudrate-Prescalers are clocked at PHI=4.608MHz (derived from a 9.216MHz oscillator, and internally divided by 2 in the HD64180). asci_ch0 - implemented, tx is "used" for UNUSED joypad recording asci_ch1 - implemented, but rx+tx both unused initialized to 8N1 with baudrate 28.8 kbit/s (PHI/10/16 SHR 0) csio - implemented, tx is used - OSD video chip initialized to 230.4 kbit/s (PHI/20 SHR 0) chipselect is controlled via port [81h].W.Bit7 (1=select, 0=deselect) the OSD chip is having an unknown dotclock (higher than the SNES) (12 pixels on OSD are having roughly the same width as 8 pixels on SNES) timer0 timer0 should run at 4.608MHz/20/130 --> 1772.3 Hz timer1 timer1 should run at 4.608MHz/20/3840 --> 60.0 Hz external interrupts reset power-up, and maybe watchdog? (but, probably not "RESET" button?) nmi unknown/unused int0 coin ? (must be low for 78..140 timer0 ticks) (44ms..80ms) int1 joypad is/was accessed by snes ? int2 unknown/unused CPU Registers Port Name Expl. (On Reset) [00] CNTLA0 ASCI Channel 0 Control Reg A (10h, bit3=var) [01] CNTLA1 ASCI Channel 1 Control Reg A (10h, bit3=var) [02] CNTLB0 ASCI Channel 0 Control Reg B (07h, bit7/bit5=var) [03] CNTLB1 ASCI Channel 1 Control Reg B (07h, bit7=var) [04] STAT0 ASCI Channel 0 Status Register (00h, bit1/2=var) [05] STAT1 ASCI Channel 1 Status Register (02h) [06] TDR0 ASCI Channel 0 Transmit Data Register [07] TDR1 ASCI Channel 1 Transmit Data Register [08] RDR0 ASCI Channel 0 Receive Data Register [09] RDR1 ASCI Channel 1 Receive Data Register [0A] CNTR CSI/O Control Register (0Fh) [0B] TRDR CSI/O Transmit/Receive Data Register [0C] TMDR0L Timer 0 Counter "Data" Register, Bit0-7 (FFh) [0D] TMDR0H Timer 0 Counter "Data" Register, Bit8-15 (FFh) [0E] RLDR0L Timer 0 Reload Register, Bit0-7 (FFh) [0F] RLDR0H Timer 0 Reload Register, Bit8-15 (FFh) [10] TCR Timer Control Register (00h) [14] TMDR1L Timer 1 Counter "Data" Register, Bit0-7 (FFh) [15] TMDR1H Timer 1 Counter "Data" Register, Bit8-15 (FFh) [16] RLDR1L Timer 1 Reload Register, Bit0-7 (FFh) [17] RLDR1H Timer 1 Reload Register, Bit8-15 (FFh) [18] FRC Free Running Counter (not used by SFC-Box) (FFh) [20-31] (DMA) DMA Registers (not used by SFC-Box) [36] RCR Refresh Control Reg (not used by SFC-Box) (FCh) [3F] ICR I/O Control Register (not used by SFC-Box) (1Fh) [11-13] Reserved (not used by SFC-Box) [19-1F] Reserved (not used by SFC-Box) [35] Reserved (not used by SFC-Box) [37] Reserved (not used by SFC-Box) [3B-3E] Reserved (not used by SFC-Box) [32] DCNTL DMA/WAIT Control Register (F0h) [33] IL Interrupt Vector Low Register (00h) [34] ITC INT/TRAP Control Register (39h) [38] CBR MMU Common Base Register (Common Area 1) (00h) [39] BBR MMU Bank Base Register (Bank Area) (00h) [3A] CBAR MMU Common/Bank Area Register (F0h) OSD_INIT OUT[81h]=00h ;osd chip deselect OUT[0Ah]=00h ;init CSIO for i=1 to 4,OUT[81H]=80h,OUT[81H]=00h,next ;osd wake-up from reset-state OSD_SEND_CMD ;in: HL=param10bit, A=(80h OR cmd*8) SHL L ;move bit7 to cy RCL H ;shift-in cy SHR L ;undo SHL (now bit7=0 for second byte) OR A,H ;merge command and 3bit data CALL osd_send_byte_a LD A,L ;7bit data JMP osd_send_byte_a OSD_SEND_BYTE set OUT[81h]=80h ;osd chip select set OUT[0Bh]=data ;prepare TX data set OUT[0Ah]=10h ;start TX wait until (IN[0Ah] AND 10h)=0 ;wait until TX ready set OUT[81h]=00h ;osd chip deselect SFC-Box OSD Chip (On-Screen Display Controller) ----------------------------------------------- OSD Command Summary CMD, First Byte (Command+Data) Second Byte (More Data) Function BASE b7 b6 b5 b4 b3 b2 b1 b0 b7 b6 b5 b4 b3 b2 b1 b0 --- +--+-----------+--------+ +--+--------------------+ ----------------- 0 80 |1 |0 0 0 0 |FL A8 A7| |0 |A6 A5 A4 A3 A2 A1 A0| Preset VRAM Addr 1 88 |1 |0 0 0 1 |D2 D1 D0| |0 |C2 C1 C0 BS B2 B1 B0| Select Color 2 90 |1 |0 0 1 0 |AT - M7| |0 |M6 M5 M4 M3 M2 M1 M0| Write Character 3 98 |1 |0 0 1 1 |S2 S1 S0| |0 |SC SC SC - SB SB SB| Sprite Ctrl 1 4 A0 |1 |0 1 0 0 |IE IN EB| |0 |MM CM MP NP - - DC| Screen Ctrl 1 5 A8 |1 |0 1 0 1 |LP DM SG| |0 |FM SV SD - W2 W1 W0| Screen Ctrl 2 6 B0 |1 |0 1 1 0 |BK G1 G0| |0 |BC VD DG N3 N2 N1 N0| Line Control 7 B8 |1 |0 1 1 1 |EC XE FO| |0 |- - Y4 Y3 Y2 Y1 Y0| Vertical Offset 8 C0 |1 |1 0 0 0 |SC XS FC| |0 |- X5 X4 X3 X2 X1 X0| Horizontal Offset 9 C8 |1 |1 0 0 1 |- - - | |0 |- - - - - - - | Reserved A D0 |1 |1 0 1 0 |XC XB RA| |0 |R2 R1 R0 RS U2 U1 U0| Set under-color B D8 |1 |1 0 1 1 |- - - | |0 |- - - - - - - | Reserved (Used?) C E0 |1 |1 1 0 0 |- XC XC| |0 |XC XC XC XD XD XD XD| Sprite Ctrl 2 D E8 |1 |1 1 0 1 |- YC YC| |0 |YC YC YD YD YD YD YD| Sprite Ctrl 3 E F0 |1 |1 1 1 0 |- - - | |0 |- - - - - - - | Reserved F F8 |1 |1 1 1 1 |- - - | |0 |- - - - - - - | Reserved Note: Below descriptions are showing only the 10bit parameter values (without command bits in 1st byte, and without zero-bit in 2nd byte). OSD Command 0 (80h) - Preset VRAM Address 9 FL Fill Mode (0=Normal, 1=Fill) 8-5 An Address A8-A5 (aka Bit3-0 of Y) (range 0..11) 4-0 An Address A4-A0 (aka Bit4-0 of X) (range 0..23) OSD Command 1 (88h) - Select Color 9-7 Dn Unknown Color? ;SFCBOX/MB90089 only, not MB90075 (per CHARACTER) 6-4 Cn Character Color (can be GRAYSCALE or COLOR) (per CHARACTER) 3 BS Unknown (Shade?) ;MB90089 only, not MB90075/SFCBOX 2-0 Bn Background Color (always GRAYSCALE) (per SCREEN or per LINE?) OSD Command 2 (90h) - Write Character 9 AT Character Background (0=Normal/Transp, 1=Solid) ;SFCBOX/MB90089 8 0 Character Blink (0=Off, 1=Blink) ;SFCBOX only, not MB90075/MB90089 7-0 Mn Character Tile Number (ASCII) (20h=Normal Space, FFh=Transp Space) Before Command 2: Change the VRAM address and Character Color via Commands 0 and 1 (if needed). Upon Command 2: The specified character is stored in VRAM (together with previously specified color attributes), VRAM address is automatically incremented (and wraps from X=23 to X=0 in next line). If Fill Mode is enabled, then Command 2 repeats until reaching the end of VRAM (Fill may take up to 1ms, do not send further commands during that time). Writes aren't performed during /HSYNC period (approx 3us), as a simple workaround, configure serial access rate so that an 8-bit transfer takes more than 3us. OSD Command 4 (A0h) - Screen Control 1 9 IE Internal/External Sync (0=Internal/Color, 1=External/Mono) 8 IN Interlace Mode (0=On, 1=Off) 7 EB Unknown (EB) ;MB90089 only, not MB90075/SFCBOX 6 MM Unknown (MM) ;MB90089 only, not MB90075/SFCBOX 5 CM Color/Monochrome (0=Mono, 1=Color) (affects Character + Undercolor) 4 MP Unknown (MP) ;MB90089 only, not MB90075/SFCBOX 3 NP NTSC/PAL Mode (0=NTSC, 1=PAL) 2-1 0 Reserved (should be 0) 0 DC Display Enable (0=Backdrop, 1=Backdrop+Background+Characters) xxx pg17 - details in IE OSD Command 5 (A8h) - Screen Control 2 9 LP Unknown ;MB90089 only, not MB90075/SFCBOX 8 DM Unknown ;MB90089 only, not MB90075/SFCBOX 7 SG Unknown ;MB90089 only, not MB90075/SFCBOX 6 FM Unknown ;MB90089 only, not MB90075/SFCBOX 5 SV Unknown ;MB90089 only, not MB90075/SFCBOX 4 SD Unknown ;MB90089 only, not MB90075/SFCBOX 3 - Reserved (should be 0) 2-0 Wn Line Spacing ;SFCBOX/MB90089 only, not MB90075 Used by SFC-Box. OSD Command 6 (B0h) - Line Control 9 BK Background Type (0=Bordered, 1=Solid 12x18) ;-per LINE 8 G1 Character Y-Size (0=Normal/18pix, 1=Zoomed/36pix) ;-per LINE 7 G0 Character X-Size (0=Normal/12pix, 1=Zoomed/24pix) ;-per LINE (old MB90075: G0=Unused, G1=Affects both X+Y Size) 6 BC Background Control (0=Transparent, 1=Displayed) ;-per LINE 5 VD Analog VOUT,YOUT,COUT Video Enable (0=Off, On) ;\per SCREEN 4 DG Digital VOC2-VOC0,VOB Video Enable (0=Off, On) ;/ 3-0 Nn Vertical Line Number (N3-N0) (range 0..11) <-- for per LINE bits Note: On the screen, a double-height line at Line Y extends through Line Y and Y+1, drawing does then continue reading the next VRAM source data from line Y+2 (ie. line Y+1 is NOT drawn). OSD Command 7 (B8h) - Vertical Offset 9 EC Output on /HSYNC Pin (0=Composite Video, 1=Hsync) 8 XE Unknown (XE) ;SFCBOX/MB90089 only, not MB90075 7 FO Output on FSCO Pin (0=Low, 1=Color Burst) ;SFCBOX/MB90089 only 6 0 Reserved (should be 0) 5 Y5 MSB of Yn? ;SFCBOX only, not MB90075/MB90089 4-0 Yn Vertical Display Start Position (Y4-Y0) (in 2-pixel steps) Vertical Display Start is at "Y*2+1" lines after raising /VBLK. Whereas, raising /VBLK is 15h (NTSC) or 20h (PAL) lines after raising /VSYNC). SFC-Box seems to use a 6bit offset (so maybe MB90082 has 1-pixel steps). SFC-Box writes totally bugged values to bit7-9 (writes them to bit8-10, and replaces them by HORIZONTAL bits when changing the VERTICAL setting). OSD Command 8 (C0h) - Horizontal Offset 9 SC Input on /EXHSYN Pin (0=Composite Video, 1=Hsync) 8 XS Unknown (XS) ;SFCBOX/MB90089 only, not MB90075 7 FC Input on /EXHSYN Pin (0=Use3usFilter, 1=NoFilter) ;MB90089 only 6-5 0 Reserved (should be 0) 5 X5 MSB of Xn ;SFCBOX/MB90089 only, not MB90075 4-0 Xn Horizontal Display Start Position (X4-X0) MB90075: Horizontal Display Start is at "(X+15)*12" dots after raising /HSYNC. MB90082: Horizontal Display Start is at "(X+?)*?" dots after raising /HSYNC. MB90089: Horizontal Display Start is at "(X+?)*3" dots after raising /HSYNC. OSD Command A (D0h) - Set Under-color 9 XC Unknown (XC) ;MB90089 only, not MB90075 ;sth on SFCBOX? 8 XB Unknown (XB) ;MB90089 only, not MB90075 ;sth on SFCBOX? 7 RA Unknown (RA) ;MB90089 only, not MB90075/SFCBOX 6-4 Rn Unknown (R2-R0) ;MB90089 only, not MB90075/SFCBOX 3 RS Unknown (RS) ;MB90089 only, not MB90075/SFCBOX 2-0 Un Under Color (U2-U0) (aka Backdrop (and Border?) color) Under Color can be COLOR or GRAYSCALE (select via CM bit). Under Color is shown only in INTERNAL sync mode. OSD Command B (D8h) - Reserved (Used?) This, in SFCBOX and MB90092, is similar to "Sprite Control 1" in MB90089 ??? 9 - Unknown (unused by SFC-Box) ;not MB90075, not MB90089 8 ? Unknown (used by SFC-Box) ;not MB90075, not MB90089 7 - Unknown (unused by SFC-Box) ;not MB90075, not MB90089 6-4 ? Unknown (used by SFC-Box) ;not MB90075, not MB90089 3 - Unknown (unused by SFC-Box) ;not MB90075, not MB90089 2-0 ? Unknown (used by SFC-Box) ;not MB90075, not MB90089 Used by SFC-Box. Is that a MB90082-only feature? The SFC-Box software contains a function for setting a 1bit flag, and two 3bit parameters (however, it's clipping the "3bit" values to range 0..3); the function is used only once (with flag=00h, and with the other two parameters each set to 01h, and "unused" bits set to zero). OSD Command 3 (98h) - Sprite Control 1 (TileNo, Char/BG Colors?) OSD Command C (E0h) - Sprite Control 2 (Horizontal Position?) OSD Command D (E8h) - Sprite Control 3 (Vertical Position?) Unknown ;MB90089 only, not MB90075 Not used by SFC-Box. According to the poor MB90089 data sheet, TileNo seems to select char "8Fh+(0..7)*10h". And X/Y coordinates seem to consist of character coordinates & pixel-offsets within that character cell. OSD Wake-Up from Reset After Power-on, the OSD chip is held in Reset-state (with IE=0 and DC=0). To wake-up from that state, issue four /CS=LOW pulses. OSD Video RAM (VRAM) Main VRAM is 288 cells (24x12), each cell contains: 8bit Character Tile Number 3bit Character Color probably also 1bit "AT" flag (on chips that do support it) plus maybe some more per-character stuff Additionally, there's an array with 12 per-line settings: .. zoom bit(s) plus maybe some more per-line stuff Other settings (like background & backdrop colors) are per-screen only. SFC-Box Character/Outline/Background Styles AT=0 --> draw Background transparent (=Undercolor, or TV layer) AT=1 --> draw Background solid by using "Dn" Unknown Color AT=0, BK=1, BC=1 --> draw Background solid by "Bn" color (unless Char=FFh) AT=x, BK=0, BC=1 --> draw Outline by "Bn" color OSD Character Generator ROM (CGROM) There are 256 characters in CGROM. The Character Set is undocumented, it seems that one can order chips with different/custom character sets, chips with suffix -001 in the part number are probably containing some kind of a "standard" charset. That "standard" charset contains normal ASCII characters (uppercase & lowercase, with normal ASCII codes eg. 41h="A", but some missing chars like "@|\"), plus japanese symbols, and some graphics symbols (volume bar, AM, PM, No, Tape and arrow symbols). Character FFh is said to be a "blank/end" code, the meaning there is unknown. "Blank" might refer to a normal SPACE, but maybe with BG forced to be transparent (even when using solid BG). "End" might be nonsense, or maybe it forces the remaining chars (in the current line, and/or following lines) to be hidden? And/or maybe it acts as CRLF (moving Address to X=0, Y=Y+1)? OSD Color Table Color Table (according to MB90075 datasheet): Value 0 1 2 3 4 5 6 7 Color Black Blue Red Magenta Green Cyan Yellow White Mono Black ... Increasing Gray Levels ... White (ie. Colors are RGB with Bit0=Blue, Bit1=Red, Bit2=Green) Characters --> Grayscale or Color (depending on CM bit) Background --> Always Grayscale Backdrop --> Grayscale or Color (depending on CM bit) Colors should be enabled (via CM bit) only in INTERNAL sync mode. OSD Datasheets / Application Manuals MB80075 commands described on 9 pages ;\these are all 24x12 cells MB80082 no datasheet exists? ; (with extra features in MB80089 commands summarized on 1 page ;/MB80082 and MB80089) MB80092 commands described on .. pages ;-similar/newer chip or so MB80050 commands summarized on 1 page ;-different/newer chip or so MB90092 pg80 and up MB90089 vram 24x12 cells (288x216 pixels) cgrom (character generator rom) (256 chars, 12x18 pixels) base.x 3pix (1/4 character) ;\relative to END of vblank/hblank base.y 2 pix ;/ 8 color/grayscales shaded (3d) or bordered chars or solid bg 8 custom chars, one can be displayed colors only in INTERNAL sync mode mono in EXTERNAL sync mode zoom.x / zoom.y 12x18 pix ---> 24x36 pix pg10 --> background pg11 --> shade pg11 --> sprite pg11 --> base xy (6bit x, 5bit y) line space 0..7 pg12 --> serial access pg13 --> COMMANDS pg15 --> wake-up dot clock (pins EXD,XD) can be 6MHz .. 8MHz (=affects horizontal resolution) FFh is "blank" or "end" code? display details pg10,11 MB90075 base.x is only 5bit (not 6bit) zoom affects BOTH x+y (cannot be done separately) no SHADED drawing vram fill function ? CMD 01 --> without D2..D0 CMD 02 --> without AT CMD 03,0C,0D --> reserved (no sprite functions) CMD 04 --> CMD 05 --> reserved (no screen ctrl 2) CMD 06 --> lacks G0 (but DOES have G1 ?) CMD 07 --> lacks XE,FO CMD 08 --> lacks XS,FC,X5 CMD 0A --> only U2..U0 (lacks XC,XB,RA,R2,R1,R0,RS) details on pg14..21 SFC-Box GROM Format ------------------- All SFC-Box Cartridges are containing a 32Kbyte "GROM" EPROM, the chip contains info about the ROMs in the cartridge (title, instructions, etc). GROM Overall Memory Map 0000h - Root Header and HD64180 Code 1000h - ROM File Info Block(s) ;usually at 1000h,2000h,3000h,etc. 7FFCh - Checksum (above bytes at 0000h..7FFBh added together) 7FFEh - Complement (same as above Checksum, XORed by FFFFh) The various unused locations are usually FFh-filled. Checksum/Complement are located at the end of the EPROM (7FFCh in case of the usual 32Kbyte EPROMs). GROM - Root Header (located at 0000h) 0000h 1 Number of ROMs (01h..08h) (usually 02h or 04h) (NumROMs) 0001h 1 GROM size (1 SHL N) kbytes (usually 05h=32Kbytes) (FFh=None) 0002h 1 Unknown (00h or 01h or 09h) 0003h 1 Unknown (00h) 0004h 1 Chipset (07h or 00h) (Bit0:SRAM, Bit1:DSP, Bit2:GSU?) 0005h 1 Unknown (01h or 00h) Menu Flag? 0006h 2 Offset to HD64180 code (usually 0020h or 0030h) 0008h 2 Offset to ROM Directory (usually 0010h) 000Ah 2 Unknown (0000h) 000Ch 1 Unknown (78h) (aka 120 decimal) 000Dh 1 Unknown (B0h or 00h) (theoretically unused... but isn't FFh) 000Eh 2 Unknown (FFFFh) (probably unused) ROM Directory (usually located at 0010h): NumROM words Offset to ROM info, div 1000h (usually 0001h..NumROMs) NumROM bytes Physical Socket on PCB (usually 00h..03h or 01h..02h) The above byte-values (usually located at 0010h+NumROMs*2) can have following known values: 00h ROM5 (upper-right) (AttractionMenu) 01h ROM1/ROM7/ROM12 (lower-right or upper-left) (MarioKar,Mahjong,Donkey) 02h ROM3/ROM9 (middle-right) (MarioCol,Waiarae,Tetris) 03h IC20 (special GSU ROM location) (StarFox) HD64180 code (usually at 0020h or 0030h): Around 256-bytes of HD64180 code, called with following parameters: A=function (00h=Change Mapping, FFh=Boot Callback, other=Reserved) BC=ptr to 10-bytes E=same as [BC+5] [BC+0] ROM Slot (0 or 1) ;Cartridge Slot 0-1 [BC+1] ROM Socket (0..3) ;from GROM[8] [BC+2] Mapmode (0=LoROM, 1=HiROM, 2=GSU) ;from GROM[P0+16h] [BC+3] Used Chipset (bit0=SRAM, bit1=DSP) ;from GROM[P0+2Ah] [BC+4] SRAM Size (0=None, 1=2K, 3=8K, 5=32K) ;from GROM[P0+17h] [BC+5] SRAM Base (0..3) (0..7 when 2 chips) ;from GROM[P0+1Ch] [BC+6] Slot 1 Chipset (bit0=SRAM, bit1=DSP, bit2=GSU?) ;from Slot1.GROM[4] [BC+7] Slot 0 Chipset (bit0=SRAM, bit1=DSP, bit2=GSU?) ;from Slot0.GROM[4] [BC+8] Copy of Port[C0h] ;\the function must update these values alongside [BC+9] Copy of Port[C1h] ;/with the new values written to Port C0h/C1h Note: During execution, the 1st 16K of GROM are mapped to 8000h..BFFFh. GROM - ROM File n Info (located at 1000h,2000h,3000h,etc.) x000h 2 P0 Offset to ASCII Title and Configuration (usually 000Eh) x002h 2 P1 Offset to Bitmap-Title-Tiles ;\bitmap 128x24 pix (16x3 tiles) x004h 2 P2 Offset to Bitmap-Padding-Tile ; padded to 160x24 pix (20x3 tiles) x006h 2 P3 Offset to Bitmap-Palette ;/with 16-color (4bpp) palette x008h 2 P4 Offset to Shift-JIS Instruction Pages x00Ah 2 P5 Offset to Demo-Joypad-Data (for demo/preview feature) x00Ch 2 P6 Offset to Unused-Joypad-Data ;<-- not included in Attraction ROM ASCII Title and Configuration Field (at P0): 00h 22 ASCII Title (uppercase ASCII, 22 bytes, padded with spaces) 16h 1 ROM/SRAM mapping/speed? (00h=SlowLoROM, 01h=FastHiROM, 02h=GSU/NoSRAM) 17h 1 SRAM Size (1 SHL N Kbytes) (but for Menu: ATROM Header claims NoSRAM?) 18h 1 Coprocessor is DSP1 (00h=No, 01h=Yes) 19h 1 ROM Size (in 1MBit units, aka in 128Kbyte Units) 1Ah 1 Unknown (01h or 02h or 03h) 1Bh 1 Demo/Preview enable (00h=Off, 01h=On) 1Ch 1 SRAM Base (0..3) (or 0..7 when SRAMs in BOTH slots) (CHANGED by KROM1) 1Dh 1 Preferred Title (00h=SNES[FFC0h]/Destroys SNES stack, 01h=GROM[P0]) 1Eh 1 Unknown ("strange values") (can be edited in menu point "2-4-1:3") 1Fh 1 Always Zero (00h) (seems to be MSB of above entry) (always zero) 20h 4 Whatever (01h,00h,00h,01h=Menu or 00h,30h,30h,05h=Game) 24h 1 Unknown (00h or 01h or 02h) (maybe... num players/joypads?) 25h 1 Unknown (00h or 05h or 1Eh) (aka decimal 0,5,30) 26h 1 Game Flag (00h=Menu, 01h=Game) 27h 1 Unknown (00h or 05h or 1Eh) (aka decimal 0,5,30) 28h 1 Unknown (00h or 80h or 90h or A0h or D0h) 29h 1 Unknown (00h or 21h or 22h or 23h) 2Ah 1 Chipset (bit0=Uses SRAM, bit1=Uses DSP) ;<-- missing in Star Fox 2Bh 22 Unknown (all 2Eh-filled) ;<-- located at index 2Ah in Star Fox Bitmap-Title-Tiles (at P1): 1 byte - Unknown (Should be 80h) (probably bit7=compression flag?) 2 bytes - Number of following bytes (N) (varies 02D5h..0573h) (max=600h) N bytes - Compressed Title Bitmap (128x24 pix, 4bpp) (16x3 Tiles) (the uncompressed bitmap consists of 3 rows of 16 bit-planed 4bpp SNES tiles) (see below for the compression format) Bitmap-Padding-Tile (at P2): 32 bytes - Uncompressed Padding Tile (8x8 pix, 4bpp) (used to pad the 128x24 pix title bitmap, centered within a 160x24 pix area) (should be usually uni-colored tile, with same color as bitmap's background) (or, alternately, one could probably also use a "hatched" background pattern) Bitmap-Palette (at P3): 32 bytes - 16-color Palette for Title Bitmap (words in range 0000h..7FFFh) (color 0 is unused/transparent, usually contains 0038h as dummy value) Shift-JIS Instruction Pages (at P4): 1 byte - Number of Pages N bytes - Page(s) ;max 1372 bytes per page ;21 lines = max 6+(32*2+1)*21+1 Each page starts with a 6-byte header (usually 8,2,4,1,4,4), followed by Text (mixed 7bit ASCII, 8bit JIS, and 2x8bit Shift-JIS), lines are terminated by chr(09h), each page terminated by chr(00h). Demo-Joypad-Data (at P5): ;<-- if none: eight 00h-bytes 1 byte - Unknown (usually 05h) 2 byte - Number of following 4-Byte Pairs (N) N*4 bytes - data (most 4-byte pairs are "xx,FF,FF,FF") (controller-data for demo/preview, in format: Time,Lsb,Msb,FFh) (or rather: 8bit time, 12bit joy1, 12bit joy2 ...?) Unused-Joypad-Data (at P6): ;<-- if none: four 00h-bytes Unknown purpose. The GROMs have more controller data here (similar as at P5), but the existing KROM/ATROM do not seem to use that extra data. Title Bitmap Compression --> SNES Decompression Formats SFC-Box Component List (Cartridges) ----------------------------------- SFC-Box Cartridge PCB (GS 0871-102) IC1 28pin DIP 27C256 EPROM "GROMn-1" (usually 28pin; 28pin/32pin possible) IC2 20pin SMD Philips 74HC273D IC3 20pin SMD Philips 74HC541D IC4 20pin SMD Philips 74HC273D IC5 14pin SMD IC6 14pin SMD IC7 14pin SMD IC8 16pin SMD 74HC138 (semi-optional) IC9 16pin SMD 74HC138 (semi-optional) IC10 16pin SMD HC138 or HC130 or so? (semi-optional) IC11 16pin SMD 74HC138 or 74HC130 or so ? (semi-optional) IC12 16pin SMD (near IC16) (semi-optional) IC13 16pin SMD Philips 74HC153D (semi-optional) IC14 20pin DIP GAL16V8B IC15 14pin SMD 74AC125 (near IC17) IC16 32pin DIP Sony CXK581000P-12L (SRAM 128Kx8) (optional) IC17 28pin DIP Nintendo DSP1 A/B (for Mario Kart) (optional) IC18 14pin SMD 74HC04 (below X1) (semi-optional) IC19 100pin SMD Mario Chip 1 (Star Fox GSU) (optional) IC20 32pin SMD SHVC-FO-1 (Star Fox ROM) (optional) IC21 28pin SMD HY62256A (Star Fox RAM, 32Kx8) (optional) IC22 14pin SMD (below IC4) IC23 14pin SMD HC08 (semi-optional) ROM1 36pin DIP -or- ROM7 36pin DIP ;\solder pads for up to six ROMs ROM2 36pin DIP -or- ROM8 36pin DIP ; (each with two alternate pin-outs, ROM3 36pin DIP -or- ROM9 36pin DIP ; eg. ROM1=LoROM or ROM7=HiROM) ROM4 36pin DIP -or- ROM10 36pin DIP ; (can be fitted with 32pin/36pin chips ROM5 36pin DIP -or- ROM11 36pin DIP ; except, ROM6 can be 32pin only) ROM6 32pin DIP -or- ROM12 36pin DIP ;/(see IC1 & IC20 for further (EP)ROMs) X1 ?pin DIP , oscillator for DSP1, probably 2-3 pins?(optional) CN1 100pin DIP OMRON XC5F-0122 Cartridge Connector (female 2x50pin) IC16 is 128K SRAM, this chip is installed in the PSS61 cartridge only, but, it's shared for multiple games (including games in PSS62-PSS64 carts). The SRAM isn't battery-backed, however, the SFC-Box cannot be switched off (unless when unplugging supply cables), so SRAM should be always receiving a standby-voltage from the console. The hardware might allow to share the DSP1 chip in similar fashion (?), in the existing carts, it's used only for Mario Kart. The "optional" components are installed in PSS61 only. The "semi-optional" ones are installed in PSS61 and (for unknown reason) also in PSS62 (whilst, PSS63/PSS64 don't have them, although they should be functionally same as PSS62). Unknown how many different programs are possible (there are pads for max 6 DIP ROMs, plus 1 SMD ROM, but maybe the SMD is alternate to one DIP, and maybe some pads are reserved for games with 2 ROMs; and unknown if the GUI menu supports more than 8 games). SFC-Box Component List (Console) -------------------------------- SFC-Box Mainboard "MAIN 0871-100A" Section 1 (CPU/PPU) (Front-Left) U1 100pin S-CPU B U2 100pin S-PPU1 U3 100pin S-PPU2 C U4 28pin LH2A256N-10PLL (Mosel-Vitelic, VRAM, 32Kx8) U5 28pin LH2A256N-10PLL (Mosel-Vitelic, VRAM, 32Kx8) U6 64pin S-WRAM A U7 24pin S-ENC A (near APU section) U8 N/A ? U9 14pin 74HCU04 U10 8pin unknown (maybe audio amplifier) (near relay) U11 8pin unknown (maybe audio amplifier) (near relay) X1 D21M4 Oscillator (21.47727MHz for S-CPU) TC1 Red Trimmer (for above oscillator) Section 2 (APU) (Rear-Left) IC1 64pin S-SMP IC2 80pin S-DSP A IC3 28pin HM9453100FP (APU-RAM, 32Kx8) IC4 28pin HM9453100FP (APU-RAM, 32Kx8) IC5 16pin NEC uPD6376 (serial audio D/A converter) IC6 8pin unknown (maybe audio amplifier) IC72 28pin MB90082-001 (OSD video controller) (near S-ENC A) X2 Blue oscillator (maybe 24.576MHz for APU?) X4 D143A4 oscillator (maybe separate NTSC color clock 3.579545MHz mul 4) TC2 Trimmer (for X4/D143A4) TC3 Trimmer (for IC72/OSD-Chip pin16) Section 3 (Rear-Right) IC30 80pin HD64180RF6X (extended Z80 CPU) X3 D921B4 oscillator (9.216MHz) (ie. HD64180 clocked at PHI=4.608MHz) 24 small logic chips (details unknown) (plenty 74HCxxx & 74LSxxx) Section 4 (Front-Right) 18 small logic chips (details unknown) Connectors CN1 100pin cartridge slot (2x50pin male) (via adaptor to TWO 2x50 slots) CN2 44pin daugtherboard socket (2x22pin male) CN3 3pin unknown/unused (without cable?) (front-right) (coin mechanics?) CN4 5pin Yellow Cable to Front Panel (FR 0871-105) (front-middle) CN5 7pin Yellow Cable to 6-position Keyswitch (front-middle) CN6 11pin Multi-colored Cable (to joypad connectors) (front-left) CN? 7pin Yellow Cable to Modulator (rear-left) CN8 6pin unknown/unused (without cable?) (front-right) (maybe RS232 ???) 2pin Black cable to "Nintendo AC Adapter" (Input: DC 5V 10W) (rear) 2pin RCA Audio Out Left (rear) 2pin RCA Audio Out Right (rear) Options & Specials SP1 3pin unknown / jumper (near HD64180) (usually two pins bridged) SP2 2pin unknown / jumper or so (near OSD chip) (usually not bridged) SP3 3x5pin unknown / not installed (located in center of mainboard) JP1,JP2,JP3,JP4,JP5 - seem to allow to disconnect Shield from GND TR1 3pin unknown (big transistor or so) ? 8pin OMRON G5V-2-5VDC (dual two-position relay) (rear-left) SFC-Box Daughterboard "(unknown PCB name)" (Modulator) Shielded box with whatever contents, plus external connectors: 2pin RCA Audio Out Mono ;\raw A/V (stereo is also available, via 2pin RCA Video Out Composite ;/the external connectors on mainboard) 2pin RF Out ;\ 2pin ANT In ; RF modulated ?pin Channel Select 1CH/2CH ;/ 7pin Yellow Cable to Mainboard SFC-Box Daughterboard "Nintendo AC Adapter" (Power Supply) Remove-able metal box with whatever contents, plus external connectors: 4pin AC OUT 200W MAX (dual 2pin or so) 2pin DC OUT 5V 5A (via short EXTERNAL cable to Mainboard) 2pin AC IN (cable to wall socket) AC125 5A (Fuse?) SFC-Box Daughterboard "PU 0871-101" IC1 28pin DIP 27C512 EPROM "KROM 1" (usually 28pin; 28pin/32pin possible) IC2 28pin SMD SRM20257 (SRAM 32Kx8) (Work-RAM for HD64180, battery-backed) IC3 16pin SMD 74HC139 IC4 20pin SMD 74HC273D (Philips) IC5 20pin SMD 74LS541 IC6 16pin SMD MB3790 (Fujitsu battery controller) IC7 14pin SMD S-3520CF (Seiko RTC, Real Time Clock, battery-backed) IC8 14pin SMD IC9 14pin SMD X1 2pin Oscillator (for RTC) ("S441") (probably 32kHz or so) TC1 Osc-Adjust (for RTC) BAT 2pin Battery (for IC7/RTC and IC2/SRAM) TM1 8pin Massive connector (not installed) (maybe FamicomBox-style CATV?) CN1 44pin DIP Female Connector 2x22pin (to Mainboard) SFC-Box Daughterboard "GD 0871-103" (Game Cartridge Connectors) CN? 100pin DIP Female Connector 2x22pin (to Mainboard) CN? 100pin DIP Male Connector 2x22pin (to Cartridge 1) CN? 100pin DIP Male Connector 2x22pin (to Cartridge 2) SFC-Box Daughterboard "CC 0871-104" (Controller Connectors) 11pin Multicolored Cable to Mainboard 7pin Controller 1 ;\Standard SNES Joypad connectors (for two standard 7pin Controller 2 ;/joypads with extra-long cables) SFC-Box Daughterboard "FR 0871-105" (Front Panel) TV-LED and GAME-LED GAME/TV-Button RESET-Button 5pin Yellow Cable (to Mainboard) SFC-Box Daughterboard "(unknown PCB name)" (Keyswitch) 10-Position Keyswitch (requires a key) (6-positions connected) 7pin Yellow Cable to (to Mainboard) (one common pin, plus 6 switch positions) The 10-position keyswitch is mechanically limited to 6 positions (9,0,1,2,3,4). There are different keys for different purposes. For example, a "visitor" key can select only the "ON" and "OFF" positions. The right-most position does switch a relay, which does... what? Probably switch-off the SFC-Box? RTC S-3520 (Real-Time Clock) ---------------------------- Seiko/Epson S-3520CF Serial 4bit Real-Time Clock (RTC) Contains the usual Time/Date registers, plus 120bit battery-backed RAM (aka 15 bytes) (organized in 2 pages of 15 x 4bits). This chip is used in both Nintendo Super System (NSS), and in Super Famicom Box. Seiko/Epson S-3520CF Register Table Index Bit3 Bit2 Bit1 Bit0 ;Expl. ___Registers in Mode 0_____________ ______________ 0 Sec3 Sec2 Sec1 Sec0 ;Seconds, Low ;\ 1 0 Sec6 Sec5 Sec4 ;Seconds, High ; 2 Min3 Min2 Min1 Min0 ;Minutes, Low ; Read/Increment-able 3 0 Min6 Min5 Min4 ;Minutes, High ; 4 Hour3 Hour2 Hour1 Hour0 ;Hours, Low ; (reading returns the 5 PM/AM 0 Hour5 Hour4 ;Hours, High ; counter value) 6 0 Week2 Week1 Week0 ;Day of Week ; 7 Day3 Day2 Day0 Day0 ;Day, Low ; (writing any dummy 8 0 0 Day5 Day4 ;Day, High ; value does increment 9 Mon3 Mon2 Mon1 Mon0 ;Month, Low ; counter value by 1) A 0 0 0 Mon4 ;Month, High ; B Year3 Year2 Year1 Year0 ;Year, Low ; C Year7 Year6 Year5 Year4 ;Year, High ;/ D TPS 30ADJ CNTR 24/12 ;Control Register ;-Read/Write-able E STA LOST 0 0 ;Status Register ;-Read only ___Registers in Mode 1_____________ ________________ 0-E x x x x ;Reserved ;-Don't use ___Registers in Mode 2_____________ ________________ 0-E SRAM SRAM SRAM SRAM ;SRAM Page 0 ;-Read/Write-able ___Registers in Mode 3_____________ ________________ 0-E SRAM SRAM SRAM SRAM ;SRAM Page 1 ;-Read/Write-able ___Mode Register (in Mode 0..3)____ ________________ F SYSR TEST Mode1 Mode0 ;Mode Register ;-Read/Write-able Whereas, the meaning of the various bits is: Sec Seconds (BCD, 00h..59h) Min Minutes (BCD, 00h..59h) Hour Hours (BCD, 00h..23h or 01h..12h) Day Day (BCD, 01h..31h) Month Month (BCD, 01h..12h) Year Year (BCD, 00h..99h) Week Day of Week (0..6) (SFC-Box: Unknown assignment) (NSS: 0=Sunday) PM/AM Set for PM, cleared for AM (this is done even when in 24-hour mode) 24/12 24-Hour Mode (0=12, 1=24) (Time/Date may get corrupted when changed?) TPS Select Reference Waveform for output on Pin8 (0=1024Hz, 1=1Hz) 30ADJ Set seconds to zero, and, if seconds was>=30, increase minutes CNTR Reset Counters (0=Normal, 1=Reset) SYSR Reset Counters and Control/Status/Mode Registers (0=Normal, 1=Reset) LOST Time Lost (0=Okay, 1=Lost/Battery failure) (can be reset... how?) STA Time Stable (0=Stable/Sec won't change in next 3.9ms, 1=Unstable) Mode Mode for Register 0-E (0=RTC, 1=Reserved, 2=SramPage0, 3=SramPage1) If STA=0 then it's safe to read the time (counters won't change within next 3.9ms aka 1/256 seconds). If STA=1 then one should wait until STA=0 before reading the time (else one may miss counter-carry-outs). Serial Access Set /CLK and /CS to HIGH as default level. Set /WR to desired direction (before dragging /CS low). Then set /CS to LOW to invoke transfer. Then transfer index/data/garbage (usually 8 clks for WRITES, and 16 clks for READS). Then set /CS back HIGH. Index/Data/Garbage Nibbles are 4bit each (transferred LSB first). Bits should be output (to DataIn) on falling CLK edge (note: the NSS is doing that properly, the SFC-Box actually outputs data shortly after falling CLK), and can be read (from DataOut) at-or-after raising CLK edge. The separate nibbles are: Nibble To RTC From RTC 1st Index I Garbage (old index or so) 2nd Data I (or dummy) Garbage (data from old index or so) 3rd Index II (or dummy) Garbage (index I or so) 4th Data II (or dummy) Data I 5th Index III (or dummy) Garbage (index II or so) 6th Data III (or dummy) Data II For Writes, one needs to send only 2 nibbles (of which, 2nd nibble is used only for Control & SRAM writes, for Counter-Increment writes it's only a dummy value). For Reads, one needs to send/receive at least 4 nibbles (though most of them are dummies/garbage; actually used are 1st-To-RTC, and 4th-From-RTC). If desired, one can read two or more registers by reading/writing 6 or more nibbles (the NSS BIOS does so). Pin-Outs --> SNES Pinouts RTC Chips Z80 CPU Specifications ---------------------- --> Z80 Register Set --> Z80 Flags --> Z80 Instruction Format --> Z80 Load Commands --> Z80 Arithmetic/Logical Commands --> Z80 Rotate/Shift and Singlebit Operations --> Z80 Jumpcommands & Interrupts --> Z80 I/O Commands --> Z80 Interrupts --> Z80 Meaningless and Duplicated Opcodes --> Z80 Garbage in Flag Register --> Z80 Compatibility --> Z80 Pin-Outs --> Z80 Local Usage Z80 Register Set ---------------- Register Summary 16bit Hi Lo Name/Function --------------------------------------- AF A - Accumulator & Flags BC B C BC DE D E DE HL H L HL AF' - - Second AF BC' - - Second BC DE' - - Second DE HL' - - Second HL IX IXH IXL Index register 1 IY IYH IYL Index register 2 SP - - Stack Pointer PC - - Program Counter/Pointer - I R Interrupt & Refresh Normal 8bit and 16bit Registers The Accumulator (A) is the allround register for 8bit operations. Registers B, C, D, E, H, L are normal 8bit registers, which can be also accessed as 16bit register pairs BC, DE, HL. The HL register pair is used as allround register for 16bit operations. B and BC are sometimes used as counters. DE is used as DEstination pointer in block transfer commands. Second Register Set The Z80 includes a second register set (AF',BC',DE',HL') these registers cannot be accessed directly, but can be exchanged with the normal registers by using the EX AF,AF and EXX instructions. Refresh Register The lower 7 bits of the Refresh Register (R) are incremented with every instruction. Instructions with at least one prefix-byte (CB,DD,ED,FD, or DDCB,FDCB) will increment the register twice. Bit 7 can be used by programmer to store data. Permanent writing to this register will suppress memory refresh signals, causing Dynamic RAM to lose data. Interrupt Register The Interrupt Register (I) is used in interrupt mode 2 only (see command "im 2"). In other modes it can be used as simple 8bit data register. IX and IY Registers IX and IY are able to manage almost all the things that HL is able to do. When used as memory pointers they are additionally including a signed index byte (IX+d). The disadvantage is that the opcodes occupy more memory bytes, and that they are less fast than HL-instructions. Undocumented 8bit Registers IXH, IXL, IYH, IYL are undocumented 8bit registers which can be used to access high and low bytes of the IX and IY registers (much like H and L for HL). Even though these registers do not officially exist, they seem to be available in all Z80 CPUs, and are quite commonly used by various software. Z80 Flags --------- Flag Summary The Flags are located in the lower eight bits of the AF register pair. Bit Name Set Clr Expl. 0 C C NC Carry Flag 1 N - - Add/Sub-Flag (BCD) 2 P/V PE PO Parity/Overflow-Flag 3 - - - Undocumented 4 H - - Half-Carry Flag (BCD) 5 - - - Undocumented 6 Z Z NZ Zero-Flag 7 S M P Sign-Flag Carry Flag (C) This flag signalizes if the result of an arithmetic operation exceeded the maximum range of 8 or 16 bits, ie. the flag is set if the result was less than Zero, or greater than 255 (8bit) or 65535 (16bit). After rotate/shift operations the bit that has been 'shifted out' is stored in the carry flag. Zero Flag (Z) Signalizes if the result of an operation has been zero (Z) or not zero (NZ). Note that the flag is set (1) if the result was zero (0). Sign Flag (S) Signalizes if the result of an operation is negative (M) or positive (P), the sign flag is just a copy of the most significant bit of the result. Parity/Overflow Flag (P/V) This flag is used as Parity Flag, or as Overflow Flag, or for other purposes, depending on the instruction. Parity: Bit7 XOR Bit6 XOR Bit5 ... XOR Bit0 XOR 1. 8bit Overflow: Indicates if the result was greater/less than +127/-128. HL Overflow: Indicates if the result was greater/less than +32767/-32768. After LD A,I or LD A,R: Contains current state of IFF2. After LDI,LDD,CPI,CPD,CPIR,CPDR: Set if BC<>0 at end of operation. BCD Flags (H,N) These bits are solely supposed to be used by the DAA instruction. The N flag signalizes if the previous operation has be an addition or substraction. The H flag indicates if the lower 4 bits exceeded the range from 0-0Fh. (For 16bit instructions: H indicates if the lower 12 bits exceeded the range from 0-0FFFh.) After adding/subtracting two 8bit BCD values (0-99h) the DAA instruction can be used to convert the hexadecimal result in the A register (0-FFh) back to BCD format (0-99h). Note that DAA also requires the carry flag to be set correctly, and thus should not be used after INC A or DEC A. Undocumented Flags (Bit 3,5) The content of these undocumented bits is filled by garbage by all instructions that affect one or more of the normal flags (for more info read the chapter Garbage in Flag Register), the only way to read out these flags would be to copy the flags register onto the stack by using the PUSH AF instruction. However, the existence of these bits makes the AF register a full 16bit register, so that for example the code sequence PUSH DE, POP AF, PUSH AF, POP HL would set HL=DE with all 16bits intact. Z80 Instruction Format ---------------------- Commands and Parameters Each instruction consists of a command, and optionally one or two parameters. Usually the leftmost parameter is modified by the operation when two parameters are specified. Parameter Placeholders The following placeholders are used in the following chapters: r 8bit register A,B,C,D,E,H,L rr 16bit register BC, DE, HL/IX/IY, AF/SP (as described) i 8bit register A,B,C,D,E,IXH/IYH,IXL/IYL ii 16bit register IX,IY n 8bit immediate 00-FFh (unless described else) nn 16bit immediate 0000-FFFFh d 8bit signed offset -128..+127 f flag condition nz,z,nc,c AND/OR po,pe,p,m (as described) (..) 16bit pointer to byte/word in memory Opcode Bytes Each command (including parameters) consists of 1-4 bytes. The respective bytes are described in the following chapters. In some cases the register number or other parameters are encoded into some bits of the opcode, in that case the opcode is specified as "xx". Opcode prefix bytes "DD" (IX) and "FD" (IY) are abbreviated as "pD". Clock Cycles The clock cycle values in the following chapters specify the execution time of the instruction. For example, an 8-cycle instruction would take 2 microseconds on a CPU which is operated at 4MHz (8/4 ms). For conditional instructions two values are specified, for example, 17;10 means 17 cycles if condition true, and 10 cycles if false. Note that in case that WAIT signals are sent to the CPU by the hardware then the execution may take longer. Affected Flags The instruction tables below are including a six character wide field for the six flags: Sign, Zero, Halfcarry, Parity/Overflow, N-Flag, and Carry (in that order). The meaning of the separate characters is: s Indicates Signed result z Indicates Zero h Indicates Halfcarry o Indicates Overflow p Indicates Parity c Indicates Carry - Flag is not affected 0 Flag is cleared 1 Flag is set x Flag is destroyed (unspecified) i State of IFF2 e Indicates BC<>0 for LDX(R) and CPX(R), or B=0 for INX(R) and OUTX(R) Z80 Load Commands ----------------- 8bit Load Commands Instruction Opcode Cycles Flags Notes ld r,r xx 4 ------ r=r ld i,i pD xx 8 ------ i=i ld r,n xx nn 7 ------ r=n ld i,n pD xx nn 11 ------ i=n ld r,(HL) xx 7 ------ r=(HL) ld r,(ii+d) pD xx dd 19 ------ r=(ii+d) ld (HL),r 7x 7 ------ (HL)=r ld (ii+d),r pD 7x dd 19 ------ ld (HL),n 36 nn 10 ------ ld (ii+d),n pD 36 dd nn 19 ------ ld A,(BC) 0A 7 ------ ld A,(DE) 1A 7 ------ ld A,(nn) 3A nn nn 13 ------ ld (BC),A 02 7 ------ ld (DE),A 12 7 ------ ld (nn),A 32 nn nn 13 ------ ld A,I ED 57 9 sz0i0- A=I ;Interrupt Register ld A,R ED 5F 9 sz0i0- A=R ;Refresh Register ld I,A ED 47 9 ------ ld R,A ED 4F 9 ------ 16bit Load Commands Instruction Opcode Cycles Flags Notes ld rr,nn x1 nn nn 10 ------ rr=nn ;rr may be BC,DE,HL or SP ld ii,nn pD 21 nn nn 13 ------ ii=nn ld HL,(nn) 2A nn nn 16 ------ HL=(nn) ld ii,(nn) pD 2A nn nn 20 ------ ii=(nn) ld rr,(nn) ED xB nn nn 20 ------ rr=(nn) ;rr may be BC,DE,HL or SP ld (nn),HL 22 nn nn 16 ------ (nn)=HL ld (nn),ii pD 22 nn nn 20 ------ (nn)=ii ld (nn),rr ED x3 nn nn 20 ------ (nn)=rr ;rr may be BC,DE,HL or SP ld SP,HL F9 6 ------ SP=HL ld SP,ii pD F9 10 ------ SP=ii push rr x5 11 ------ SP=SP-2, (SP)=rr ;rr may be BC,DE,HL,AF push ii pD E5 15 ------ SP=SP-2, (SP)=ii pop rr x1 10 (-AF-) rr=(SP), SP=SP+2 ;rr may be BC,DE,HL,AF pop ii pD E1 14 ------ ii=(SP), SP=SP+2 ex DE,HL EB 4 ------ exchange DE <--> HL ex AF,AF 08 4 xxxxxx exchange AF <--> AF' exx D9 4 ------ exchange BC,DE,HL <--> BC',DE',HL' ex (SP),HL E3 19 ------ exchange (SP) <--> HL ex (SP),ii pD E3 23 ------ exchange (SP) <--> ii Blocktransfer Instruction Opcode Cycles Flags Notes ldi ED A0 16 --0e0- (DE)=(HL), HL=HL+1, DE=DE+1, BC=BC-1 ldd ED A8 16 --0e0- (DE)=(HL), HL=HL-1, DE=DE-1, BC=BC-1 ldir ED B0 bc*21-5 --0?0- ldi-repeat until BC=0 lddr ED B8 bc*21-5 --0?0- ldd-repeat until BC=0 Z80 Arithmetic/Logical Commands ------------------------------- 8bit Arithmetic/Logical Commands Instruction Opcode Cycles Flags Notes daa 27 4 szxp-x decimal adjust akku cpl 2F 4 --1-1- A = A xor FF neg ED 44 8 szho1c A = 00-A r xx 4 szhonc see below i pD xx 8 szhonc see below, UNDOCUMENTED n xx nn 7 szhonc see below (HL) xx 7 szhonc see below (ii+d) pD xx dd 19 szhonc see below r xx 4 szhon- see below i pD xx 8 szhon- see below, UNDOCUMENTED (HL) xx 11 szhon- see below (ii+d) pD xx dd 23 szhon- see below r xx 4 szhp00 see below i pD xx 8 szhp00 see below, UNDOCUMENTED n xx nn 7 szhp00 see below (HL) xx 7 szhp00 see below (ii+d) pD xx dd 19 szhp00 see below Arithmetic commands: add A,op see above 4-19 szho0c A=A+op adc A,op see above 4-19 szho0c A=A+op+cy sub op see above 4-19 szho1c A=A-op sbc A,op see above 4-19 szho1c A=A-op-cy cp op see above 4-19 szho1c compare, ie. VOID=A-op Increment/Decrement commands: inc op see above 4-23 szho0- op=op+1 dec op see above 4-23 szho1- op=op-1 Logical commands: and op see above 4-19 sz1p00 A=A & op xor op see above 4-19 sz0p00 A=A XOR op or op see above 4-19 sz0p00 A=A | op 16bit Arithmetic Commands Instruction Opcode Cycles Flags Notes add HL,rr x9 11 --h-0c HL = HL+rr ;rr may be BC,DE,HL,SP add ii,rr pD x9 15 --h-0c ii = ii+rr ;rr may be BC,DE,ii,SP (!) adc HL,rr ED xA 15 szho0c HL = HL+rr+cy ;rr may be BC,DE,HL,SP sbc HL,rr ED x2 15 szho1c HL = HL-rr-cy ;rr may be BC,DE,HL,SP inc rr x3 6 ------ rr = rr+1 ;rr may be BC,DE,HL,SP inc ii pD 23 10 ------ ii = ii+1 dec rr xB 6 ------ rr = rr-1 ;rr may be BC,DE,HL,SP dec ii pD 2B 10 ------ ii = ii-1 Searchcommands Instruction Opcode Cycles Flags Notes cpi ED A1 16 szhe1- compare A-(HL), HL=HL+1, DE=DE+1, BC=BC-1 cpd ED A9 16 szhe1- compare A-(HL), HL=HL-1, DE=DE-1, BC=BC-1 cpir ED B1 x*21-5 szhe1- cpi-repeat until BC=0 or compare fits cpdr ED B9 x*21-5 szhe1- cpd-repeat until BC=0 or compare fits Z80 Rotate/Shift and Singlebit Operations ----------------------------------------- Rotate and Shift Commands Instruction Opcode Cycles Flags Notes rlca 07 4 --0-0c rotate akku left rla 17 4 --0-0c rotate akku left through carry rrca 0F 4 --0-0c rotate akku right rra 1F 4 --0-0c rotate akku right through carry rld ED 6F 18 sz0p0- rotate left low digit of A through (HL) rrd ED 67 18 sz0p0- rotate right low digit of A through (HL) r CB xx 8 sz0p0c see below (HL) CB xx 15 sz0p0c see below (ii+d) pD CB dd xx 23 sz0p0c see below r,(ii+d) pD CB dd xx 23 sz0p0c see below, UNDOCUMENTED modify and load Whereas may be: rlc rotate left rl rotate left through carry rrc rotate right rr rotate right through carry sla shift left arithmetic (b0=0) sll UNDOCUMENTED shift left (b0=1) sra shift right arithmetic (b7=b7) srl shift right logical (b7=0) Singlebit Operations Instruction Opcode Cycles Flags Notes bit n,r CB xx 8 xz1x0- test bit n ;n=0..7 bit n,(HL) CB xx 12 xz1x0- bit n,(ii+d) pD CB dd xx 20 xz1x0- set n,r CB xx 8 ------ set bit n ;n=0..7 set n,(HL) CB xx 15 ------ set n,(ii+d) pD CB dd xx 23 ------ set r,n,(ii+d) pD CB dd xx 23 ------ UNDOCUMENTED set n,(ii+d) and ld r,(ii+d) res n,r CB xx 8 ------ reset bit n ;n=0..7 res n,(HL) CB xx 15 ------ res n,(ii+d) pD CB dd xx 23 ------ res r,n,(ii+d) pD CB dd xx 23 ------ UNDOCUMENTED res n,(ii+d) and ld r,(ii+d) ccf 3F 4 --h-0c h=cy, cy=cy xor 1 scf 37 4 --0-01 cy=1 Z80 Jumpcommands & Interrupts ----------------------------- General Jump Commands Instruction Opcode Cycles Flags Notes jp nn C3 nn nn 10 ------ jump to nn, ie. PC=nn jp HL E9 4 ------ jump to HL, ie. PC=HL jp ii pD E9 8 ------ jump to ii, ie. PC=ii jp f,nn xx nn nn 10;10 ------ jump to nn if nz,z,nc,c,po,pe,p,m jr nn 18 dd 12 ------ relative jump to nn, ie. PC=PC+d jr f,nn xx dd 12;7 ------ relative jump to nn if nz,z,nc,c djnz nn 10 dd 13;8 ------ B=B-1 and relative jump to nn if B<>0 call nn CD nn nn 17 ------ call nn ie. SP=SP-2, (SP)=PC, PC=nn call f,nn xx nn nn 17;10 ------ call nn if nz,z,nc,c,po,pe,p,m ret C9 10 ------ pop PC ie. PC=(SP), SP=SP+2 ret f xx 11;5 ------ pop PC if nz,z,nc,c,po,pe,p,m rst n xx 11 ------ call n ;n=00,08,10,18,20,28,30,38 nop 00 4 ------ no operation Interrupt Related Commands Instruction Opcode Cycles Flags Notes di F3 4 ------ IFF1=0, IFF2=0 ;disable interrupts ei FB 4 ------ IFF1=1, IFF2=1 ;enable interrupts im 0 ED 46 8 ------ read opcode from databus on interrupt im 1 ED 56 8 ------ execute call 0038h on interrupt im 2 ED 5E 8 ------ execute call (i*100h+databus) on int. halt 76 N*4 ------ repeat until interrupt occurs reti ED 4D 14 ------ pop PC, IFF1=IFF2, ACK (ret from INT) retn ED 45 14 ------ pop PC, IFF1=IFF2 (ret from NMI) 1+var ------ IFF1=0,IFF2=0, exec opcode from databus 12 ------ IFF1=0,IFF2=0, CALL 0038h 18 ------ IFF1=0,IFF2=0, CALL [I*100h+databus] ? ------ IFF1=0, CALL 0066h Z80 I/O Commands ---------------- Instruction Opcode Cycles Flags Notes in A,(n) DB nn 11 ------ A=PORT(A*100h+n) in r,(C) ED xx 12 sz0p0- r=PORT(BC) in (C) ED 70 12 sz0p0- **undoc/illegal** VOID=PORT(BC) out (n),A D3 nn 11 ------ PORT(A*100h+n)=A out (C),r ED xx 12 ------ PORT(BC)=r out (C),0 ED 71 12 ------ **undoc/illegal** PORT(BC)=00 ini ED A2 16 xexxxx MEM(HL)=PORT(BC), HL=HL+1, B=B-1 ind ED AA 16 xexxxx MEM(HL)=PORT(BC), HL=HL-1, B=B-1 outi ED A3 16 xexxxx B=B-1, PORT(BC)=MEM(HL), HL=HL+1 outd ED AB 16 xexxxx B=B-1, PORT(BC)=MEM(HL), HL=HL-1 inir ED B2 b*21-5 x1xxxx same than ini, repeat until b=0 indr ED BA b*21-5 x1xxxx same than ind, repeat until b=0 otir ED B3 b*21-5 x1xxxx same than outi, repeat until b=0 otdr ED BB b*21-5 x1xxxx same than outd, repeat until b=0 Z80 Interrupts -------------- Interrupt Flip-Flop (IFF1,IFF2) The IFF1 flag is used to enable/disable INTs (maskable interrupts). In a raw INT-based system, IFF2 is always having the same state than IFF1. However, in a NMI-based system the IFF2 flag is used to backup the recent IFF1 state prior to NMI execution, and may be used to restore IFF1 upon NMI completion by RETN opcode. Beside for the above 'backup' function, IFF2 itself is having no effect. Neither IFF1 nor IFF2 affect NMIs which are always enabled. The following opcodes/events are modifying IFF1 and/or IFF2: EI IFF1=1, IFF2=1 DI IFF1=0, IFF2=0 IFF1=0, IFF2=0 IFF1=0 RETI IFF1=IFF2 RETN IFF1=IFF2 When using the EI instruction, the new IFF state isn't applied until the next instruction has completed (this ensures that an interrupt handler which is using the sequence "EI, RET" may return to the main program before the next interrupt is executed). Interrupts can be disabled by the DI instruction (IFF=0), and are additionally automatically each time when an interrupt is executed. Interrupt Execution An interrupt is executed when an interrupt is requested by the hardware, and IFF is set. Whenever both conditions are true, the interrupt is executed after the completion of the current opcode. Note that repeated block commands (such like LDIR) can be interrupted also, the interrupt return address on the stack then points to the interrupted opcode, so that the instruction may continue as normal once the interrupt handler returns. Interrupt Modes (IM 0,1,2) The Z80 supports three interrupt modes which can be selected by IM 0, IM 1, and IM 2 instructions. The table below describes the respective operation and execution time in each mode. Mode Cycles Refresh Operation 0 1+var 0+var IFF1=0,IFF2=0, read and execute opcode from databus 1 12 1 IFF1=0,IFF2=0, CALL 0038h 2 18 1 IFF1=0,IFF2=0, CALL [I*100h+databus] Mode 0 requires an opcode to be output to the databus by external hardware, in case that no byte is output, and provided that the 'empty' databus is free of garbage, then the CPU might tend to read a value of FFh (opcode RST 38h, 11 cycles, 1 refresh) - the clock cycles (11+1), refresh cycles (1), and executed operation are then fully identical as in Mode 1. Mode 1 interrupts always perform a CALL 0038h operation. The downside is that many systems may have ROM located at this address, making it impossible to hook the interrupt handler directly. Mode 2 calls to a 16bit address which is read from a table in memory, the table pointer is calculated from the "I" register (initialized by LD I,A instruction) multiplied by 100h, plus an index byte which is read from the databus. The following trick may be used to gain stable results in Mode 2 even if no index byte is supplied on the databus: For example, set I=40h the origin of the table will be then at 4000h in memory. Now fill the entire area from 4000h to 4100h (101h bytes, including 4100h) by the value 41h. The CPU will then perform a CALL 4141h upon interrupt execution - regardless of whether the randomized index byte is an even or odd number. Non-Maskable Interrupts (NMIs) Unlike INTs, NMIs cannot be disabled by the CPU, ie. DI and EI instructions and the state of IFF1 and IFF2 do not have effect on NMIs. The NMI handler address is fixed at 0066h, regardless of the interrupt mode (IM). Upon NMI execution, IFF1 is cleared (disabeling maskable INTs - NMIs remain enabled, which may result in nested execution if the handler does not return before next NMI is requested). IFF2 remains unchanged, thus containing the most recent state of IFF1, which may be used to restore IFF1 if the NMI handler returns by RETN instruction. Execution time for NMIs is unknown (?). RETN (return from NMI and restore IFF1) Intended to return from NMI and to restore the old IFF1 state (assuming the old state was IFF1/IFF2 both set or both cleared). RETI (return from INT with external acknowledge) Intended to return from INT and to notify peripherals about completion of the INT handler, the Z80 itself doesn't send any such acknowledge signal (instead, peripherals like Z80-PIO or Z80-SIO must decode the databus during /M1 cycles, and identify the opcode sequence EDh,4Fh as RETI). Aside from such external handling, internally, RETI is exactly same as RETN, and, like RETN it does set IFF1=IFF2 (though in case of RETI this is a dirt effect without practical use; within INT handlers IFF1 and IFF2 are always both zero, or when EI was used both set). Recommended methods to return from INT are: EI+RETI (when needing the external acknowledge), or EI+RET (faster). Z80 Meaningless and Duplicated Opcodes -------------------------------------- Mirrored Instructions NEG (ED44) is mirrored to ED4C,54,5C,64,6C,74,7C. RETN (ED45) is mirrored to ED55,65,75. RETI (ED4D) is mirrored to ED5D,6D,7D. Mirrored IM Instructions IM 0,X,1,2 (ED46,4E,56,5E) are mirrored to ED66,6E,76,7E. Whereas IM X is an undocumented mirrored instruction itself which appears to be identical to either IM 0 or IM 1 instruction (?). Duplicated LD HL Instructions LD (nn),HL (opcode 22NNNN) is mirrored to ED63NNNN. LD HL,(nn) (opcode 2ANNNN) is mirrored to ED6BNNNN. Unlike the other instructions in this chapter, these two opcodes are officially documented. The clock/refresh cycles for the mirrored instructions are then 20/2 instead of 16/1 as for the native 8080 instructions. Mirrored BIT N,(ii+d) Instructions Unlike as for RES and SET, the BIT instruction does not support a third operand, ie. DD or FD prefixes cannot be used on a BIT N,r instruction in order to produce a BIT r,N,(ii+d) instruction. When attempting this, the 'r' operand is ignored, and the resulting instruction is identical to BIT N,(ii+d). Except that, not tested yet, maybe undocumented flags are then read from 'r' instead of from ii+d(?). Non-Functional Opcodes The following opcodes behave much like the NOP instruction. ED00-3F, ED77, ED7F, ED80-9F, EDA4-A7, EDAC-AF, EDB4-B7, EDBC-BF, EDC0-FF. The execution time for these opcodes is 8 clock cycles, 2 refresh cycles. Note that some of these opcodes appear to be used for additional instructions by the R800 CPU in newer turbo R (MSX) models. Ignored DD and FD Prefixes In some cases, DD-prefixes (IX) and FD-prefixes (IY) may be ignored by the CPU. This happens when using one (or more) of the above prefixes prior to instructions that already contain an ED, DD, or FD prefix, or prior to any instructions that do not support IX, IY, IXL, IXH, IYL, IYH operands. In such cases, 4 clock cycles and 1 refresh cycle are counted for each ignored prefix byte. Z80 Garbage in Flag Register ---------------------------- Nocash Z80-flags description This chapter describes the undocumented Z80 flags (bit 3 and 5 of the Flags Register), these flags are affected by ALL instructions that modify one or more of the normal flags - all OTHER instructions do NOT affect the undocumented flags. For some instructions, the content of some flags has been officially documented as 'destroyed', indicating that the flags contain garbage, the exact garbage calculation for these instructions will be described here also. All information below just for curiosity. Keep in mind that Z80 compatible CPUs (or emulators) may not supply identical results, so that it wouldn't be a good idea to use these flags in any programs (not that they could be very useful anyways). Normal Behaviour for Undocumented Flags In most cases, undocumented flags are copied from the Bit 3 and Bit 5 of the result byte. That is "A AND 28h" for: RLD; CPL; RLCA; RLA; LD A,I; ADD OP; ADC OP; XOR OP; AND OP; RRD; NEG; RRCA; RRA; LD A,R; SUB OP; SBC OP; OR OP ; DAA. When other operands than A may be modified, "OP AND 28h" for: RLC OP; RL OP; SLA OP; SLL OP; INC OP; IN OP,(C); RRC OP; RR OP; SRA OP; SRL OP; DEC OP For 16bit instructions flags are calculated as "RR AND 2800h": ADD RR,XX; ADC RR,XX; SBC RR,XX. Slightly Special Undocumented Flags For 'CP OP' flags are calculated as "OP AND 28h", that is the unmodified operand, and NOT the internally calculated result of the comparision. For 'SCF' and 'CCF' flags are calculated as "(A OR F) AND 28h", ie. the flags remain set if they have been previously set. For 'BIT N,R' flags are calculated as "OP AND 28h", additionally the P-Flag is set to the same value than the Z-Flag (ie. the Parity of "OP AND MASK"), and the S-flag is set to "OP AND MASK AND 80h". Fatal MEMPTR Undocumented Flags For 'BIT N,(HL)' the P- and S-flags are set as for BIT N,R, but the undocumented flags are calculated as "MEMPTR AND 2800h", for more info about MEMPTR read on below. The same applies to 'BIT N,(ii+d)', but the result is less unpredictable because the instruction sets MEMPTR=ii+d, so that undocumented flags are " AND 2800h". Memory Block Command Undocumented Flags For LDI, LDD, LDIR, LDDR, undocumented flags are "((A+DATA) AND 08h) + ((A+DATA) AND 02h)*10h". For CPI, CPD, CPIR, CPDR, undocumented flags are "((A-DATA-FLG_H) AND 08h) + ((A-DATA-FLG_H) AND 02h)*10h", whereas the CPU first calculates A-DATA, and then internally subtracts the resulting H-flag from the result. Chaotic I/O Block Command Flags The INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR instructions are doing a lot of obscure things, to simplify the description a placeholder called DUMMY is used in the formulas. DUMMY = "REG_C+DATA+1" ;for INI/INIR DUMMY = "REG_C+DATA-1" ;for IND/INDR DUMMY = "REG_L+DATA" ;for OUTI,OUTD,OTIR,OTDR FLG_C = Carry of above "DUMMY" calculation FLG_H = Carry of above "DUMMY" calculation (same as FLG_C) FLG_N = Sign of "DATA" FLG_P = Parity of "REG_B XOR (DUMMY AND 07h)" FLG_S = Sign of "REG_B" UNDOC = Bit3,5 of "REG_B AND 28h" The above registers L and B are meant to contain the new values which are already incremented/decremented by the instruction. Note that the official docs mis-described the N-Flag as set, and the C-Flag as not affected. DAA Flags Addition (if N was 0): FLG_H = (OLD_A AND 0Fh) > 09h FLG_C = Carry of result Subtraction (if N was 1): FLG_H = (NEW_A AND 0Fh) > 09h FLG_C = OLD_CARRY OR (OLD_A>99h) For both addition and subtraction, N remains unmodified, and S, Z, P contain "Sign", Zero, and Parity of result (A). Undocumented flags are set to (A AND 28h) as normal. Mis-documented Flags For all XOR/OR: H=N=C=0, and for all AND: H=1, N=C=0, unlike described else in Z80 docs. Also note C,N flag description bug for I/O block commands (see above). Internal MEMPTR Register This is an internal Z80 register, modified by some instructions, and usually completely hidden to the user, except that Bit 11 and Bit 13 can be read out at a later time by BIT N,(HL) instructions. The following list specifies the resulting content of the MEMPTR register caused by the respective instructions. Content Instruction A*100h LD (xx),A ;xx=BC,DE,nn xx+1 LD A,(xx) ;xx=BC,DE,nn nn+1 LD (nn),rr; LD rr,(nn) ;rr=BC,DE,HL,IX,IY rr EX (SP),rr ;rr=HL,IX,IY (MEMPTR=new value of rr) rr+1 ADD/ADC/SBC rr,xx ;rr=HL,IX,IY (MEMPTR=old value of rr+1) HL+1 RLD and RRD dest JP nn; CALL nn; JR nn ;dest=nn dest JP f,nn; CALL f,nn ;regardless of condition true/false dest RET; RETI; RETN ;dest=value read from (sp) dest RET f; JR f,nn; DJNZ nn ;only if condition=true 00XX RST n adr+1 IN A,(n) ;adr=A*100h+n, memptr=A*100h+n+1 bc+1 IN r,(BC); OUT (BC),r ;adr=bc ii+d All instructions with operand (ii+d) Also the following might or might not affect MEMPTR, not tested yet: OUT (N),A and block commands LDXX, CPXX, INXX, OUTXX and probably interrupts in IM 0, 1, 2 All other commands do not affect the MEMPTR register - this includes all instructions with operand (HL), all PUSH and POP instructions, not executed conditionals JR f,d, DJNZ d, RET f (ie. with condition=false), and the JP HL/IX/IY jump instructions. Z80 Compatibility ----------------- The Z80 CPU is (almost) fully backwards compatible to older 8080 and 8085 CPUs. Instruction Format The Z80 syntax simplifies the chaotic 8080/8085 syntax. For example, Z80 uses the command "LD" for all load instructions, 8080/8085 used various different commands depending on whether the operands are 8bit registers, 16bit registers, memory pointers, and/or an immediates. However, these changes apply to the source code only - the generated binary code is identical for both CPUs. Parity/Overflow Flag The Z80 CPU uses Bit 2 of the flag register as Overflow flag for arithmetic instructions, and as Parity flag for other instructions. 8080/8085 CPUs are always using this bit as Parity flag for both arithmetic and non-arithmetic instructions. Z80 Specific Instructions The following instructions are available for Z80 CPUs only, but not for older 8080/8085 CPUs: All CB-prefixed opcodes (most Shift/Rotate, all BIT/SET/RES commands). All ED-prefixed opcodes (various instructions, and all block commands). All DD/FD-prefixed opcodes (registers IX and IY). As well as DJNZ nn; JR nn; JR f,nn; EX AF,AF; and EXX. 8085 Specific Instructions The 8085 instruction set includes two specific opcodes in addition to the 8080 instruction set, used to control 8085-specifc interrupts and SID and SOD input/output signals. These opcodes, RIM (20h) and SIM (30h), are not supported by Z80/8080 CPUs. Z80 vs Z80A Both Z80 and Z80A are including the same instruction set, the only difference is the supported clock frequency (Z80 = max 2.5MHz, Z80A = max 4MHz). NEC-780 vs Zilog-Z80 These CPUs are apparently fully compatible to each other, including for undocumented flags and undocumented opcodes. Z80 Pin-Outs ------------ _____ _____ | |_| | A11 |1 40| A10 A12 |2 39| A9 A13 |3 38| A8 A14 |4 37| A7 A15 |5 36| A6 CLK |6 35| A5 D4 |7 34| A4 D3 |8 33| A3 D5 |9 32| A2 D6 |10 Z80 31| A1 VCC |11 CPU 30| A0 D2 |12 29| GND D7 |13 28| /RFSH D0 |14 27| /M1 D1 |15 26| /RST /INT |16 25| /BUSRQ /NMI |17 24| /WAIT /HALT |18 23| /BUSAK /MREQ |19 22| /WR /IORQ |20 21| /RD |_____________| Z80 Local Usage --------------- Nintendo Super System (Z80) Clocked at 4.000MHz. NMIs are used for something (probably Vblank or Vsync or so). Normal interrupts seem to be unused. There is MAYBE no watchdog hardware (but the BIOS is using a software-based watchdog; namely, it's misusing the "I" register as watchdog timer; decreased by NMI handler). ALTHOUGH, like the PC10, it might ADDITIONALLY have a hardware watchdog...? Super Famicom Box (HD64180) Clocked at by a 9.216MHz oscillator, ie. the HD64180 is internally clocked at PHI=4.608MHz. HD64180 ------- The HD64180/Z180 are extended Z80 CPUs, the HD64180 was originally made by Hitachi, and later adopted as Z180 by Zilog. --> HD64180 Internal I/O Map --> HD64180 New Opcodes (Z80 Extension) --> HD64180 Serial I/O Ports (ASCI and CSI/O) --> HD64180 Timers (PRT and FRC) --> HD64180 Direct Memory Access (DMA) --> HD64180 Interrupts --> HD64180 Memory Mapping and Control --> HD64180 Extensions The system clock (PHI) is half the frequency of the crystal. Supported PHI values are 6.144MHz, 4.608MHz, 3.072MHz (these values allow to program ASCI channels to valid RS232 baudrates). HD64180 Internal I/O Map ------------------------ HD64180 Internal Registers Internal I/O Ports are initially mapped to Port 0000h..003Fh (but can be reassigned to 0040h..007Fh, 0080h..00BFh, or 00C0h..00FFh via ICR register). Port Name Expl. (On Reset) 00h CNTLA0 ASCI Channel 0 Control Reg A (10h, bit3=var) 01h CNTLA1 ASCI Channel 1 Control Reg A (10h, bit3/bit4=var) 02h CNTLB0 ASCI Channel 0 Control Reg B (07h, bit7/bit5=var) 03h CNTLB1 ASCI Channel 1 Control Reg B (07h, bit7=var) 04h STAT0 ASCI Channel 0 Status Register (00h, bit2/bit1=var) 05h STAT1 ASCI Channel 1 Status Register (02h) 06h TDR0 ASCI Channel 0 Transmit Data Register 07h TDR1 ASCI Channel 1 Transmit Data Register 08h RDR0 ASCI Channel 0 Receive Data Register 09h RDR1 ASCI Channel 1 Receive Data Register 0Ah CNTR CSI/O Control Register (0Fh) 0Bh TRDR CSI/O Transmit/Receive Data Register 0Ch TMDR0L Timer 0 Counter "Data" Register, Bit0-7 (FFh) 0Dh TMDR0H Timer 0 Counter "Data" Register, Bit8-15 (FFh) 0Eh RLDR0L Timer 0 Reload Register, Bit0-7 (FFh) 0Fh RLDR0H Timer 0 Reload Register, Bit8-15 (FFh) 10h TCR Timer Control Register (00h) 11h-13h Reserved 12h ASEXT0 ASCI Channel 0 Extension Control Reg ;\Z8S180/Z8L180 only 13h ASEXT1 ASCI Channel 0 Extension Control Reg ;/(not Z80180/HD64180) 14h TMDR1L Timer 1 Counter "Data" Register, Bit0-7 (FFh) 15h TMDR1H Timer 1 Counter "Data" Register, Bit8-15 (FFh) 16h RLDR1L Timer 1 Reload Register, Bit0-7 (FFh) 17h RLDR1H Timer 1 Reload Register, Bit8-15 (FFh) 18h FRC Free Running Counter (FFh) 19h-1Fh Reserved 1Ah ASTC0L ASCI Channel 0 Time Constant, Bit0-7 ;\ 1Bh ASTC0H ASCI Channel 0 Time Constant, Bit8-15 ; Z8S180/Z8L180 only 1Ch ASTC1L ASCI Channel 1 Time Constant, Bit0-7 ; (not Z80180/HD64180) 1Dh ASTC1H ASCI Channel 1 Time Constant, Bit8-15 ; 1Eh CMR Clock Multiplier Register ; 1Fh CCR CPU Control Register ;/ 20h SAR0L DMA Channel 0 Source Address, Bit0-7 (Memory or I/O) 21h SAR0H DMA Channel 0 Source Address, Bit8-15 (Memory or I/O) 22h SAR0B DMA Channel 0 Source Address, Bit16-19 (Memory or DRQ) 23h DAR0L DMA Channel 0 Destination Address, Bit0-7 (Memory or I/O) 24h DAR0H DMA Channel 0 Destination Address, Bit8-15 (Memory or I/O) 25h DAR0B DMA Channel 0 Destination Address, Bit16-19 (Memory or DRQ) 26h BCR0L DMA Channel 0 Byte Count Register, Bit0-7 27h BCR0H DMA Channel 0 Byte Count Register, Bit8-15 28h MAR1L DMA Channel 1 Memory Address, Bit0-7 (Source or Dest) 29h MAR1H DMA Channel 1 Memory Address, Bit8-15 (Source or Dest) 2Ah MAR1B DMA Channel 1 Memory Address, Bit16-19 (Source or Dest) 2Bh IAR1L DMA Channel 1 I/O Address, Bit0-7 (Dest or Source) 2Ch IAR1H DMA Channel 1 I/O Address, Bit8-15 (Dest or Source) 2Dh Reserved ;IAR1B on Z8S180/Z8L180 (not Z80180/HD64180) 2Eh BCR1L DMA Channel 1 Byte Count Register, Bit0-7 2Fh BCR1H DMA Channel 1 Byte Count Register, Bit8-15 30h DSTAT DMA "Status" Register (32h on Reset) 31h DMODE DMA Mode Register (C1h on Reset) 32h DCNTL DMA/WAIT Control Register (F0h on Reset) 33h IL Interrupt Vector Low Register (00h on Reset) 34h ITC INT/TRAP Control Register (39h on Reset) 35h Reserved 36h RCR Refresh Control Register (FCh on Reset) 37h Reserved 38h CBR MMU Common Base Register (Common Area 1)(00h on Reset) 39h BBR MMU Bank Base Register (Bank Area) (00h on Reset) 3Ah CBAR MMU Common/Bank Area Register (F0h on Reset) 3Bh-3Dh Reserved 3Eh OMCR Operation Mode, Z180 only (not HD64180) (FFh on Reset) 3Fh ICR I/O Control Register (1Fh on Reset) HD64180 New Opcodes (Z80 Extension) ----------------------------------- New HD64180 Opcodes ED 00 nn IN0 B,(nn) ED 01 nn OUT0 (nn),B ED 04 TST B ED 08 nn IN0 C,(nn) ED 09 nn OUT0 (nn),C ED 0C TST C ED 10 nn IN0 D,(nn) ED 11 nn OUT0 (nn),D ED 14 TST D ED 18 nn IN0 E,(nn) ED 19 nn OUT0 (nn),E ED 1C TST E ED 20 nn IN0 H,(nn) ED 21 nn OUT0 (nn),H ED 24 TST H ED 28 nn IN0 L,(nn) ED 29 nn OUT0 (nn),L ED 2C TST L ED 30 nn IN0 (nn) ED 34 TST (HL) ED 38 nn IN0 A,(nn) ED 39 nn OUT0 (nn),A ED 3C TST A ED 4C MULT BC ED 83 OTIM ED 64 nn TST nn ED 5C MULT DE ED 8B OTDM ED 70 IN (C) ED 6C MULT HL ED 93 OTIMR ED 74 nn TSTIO nn ED 7C MULT SP ED 9B OTDMR ED 76 SLP On a real Z80, ED-4C/5C/6C/7C and ED-64/74 have been mirrors of NEG. On a real Z80, ED-70 did the same (but was undocumented). On a real Z80, ED-76 has been mirror of IM 2. On a real Z80, ED-00..3F and ED-80..9F have acted as NOP. Notes IN0/OUT0/OTxMx same as IN/OUT/OTxx but with I/O-address bit8-15 forced 00h. TST op: Test A,op. ;non-destructive AND (only flags changed) TSTIO nn: Test Port[C],nn ;\hitachi lists BOTH definitions (page 75) TSTIO nn: Test Port[nn],A ;/zilog also lists BOTH definitions (page 173,174) TSTIO nn: Test Port[C],nn ;<-- this is reportedly the correct definition MLT xy: xy=x*y ;unsigned multiply (flags=unchanged) SLP (SLEEP) stops internal clock (including stopping DRAM refresh and DMAC). IOSTOP: stops ASCI, CSI/O, PRT. Z80 incompatible opcodes (according to Zilog's Z180 Application Note) Opcode Z80 Z180 DAA Checks Cy and A>99h Checks Cy only? (when N=1) RLD/RRD Sets flags for A Sets flags for [HL] Opcode Execution Time Some opcodes are slightly faster as on real Z80. For example, some (not all) 4-cycle Z80 opcodes take only 3-cyles on HD64180. Undefined Opcodes On the HD64180, undefined opcodes are causing a TRAP exception (this feature cannot be disabled). So, while the real Z80 does have some useful (and some useless) undocumented opcodes, none (?) of these is working on HD64180 (except for the now-official ED-70 opcode). The HD64180 datasheet doesn't list "SLL" as valid opcode. The HD64180 datasheet doesn't list the "SET-and-LD" or "RES-and-LD" opcodes. The HD64180 datasheet doesn't list opcodes with "IXL,IXH,IYL,IYH" operands, however, it does mention existence of "IXL" here and there (however, that seems to refer only to 16bit operations like "PUSH IX" (which do internally split 16bit IX into two 8bit units). The HD64180 datasheet lists EX DE,HL with IX/IY-prefix as invalid. NEWER INFO: The HD64180 is actually trapping all undocumented opcodes, even those that are more or less commonly used on Z80 CPUs, ie. the HD64180 doesn't support accessing IX/IY 16bit registers as 8bit fragments (IXH,IXL,IYH,IYL), doesn't support "SLL" opcode, nor useless opcode mirrors (like alternate NEG/IM/RETN/RETI/NOP mirrors). HD64180 Serial I/O Ports (ASCI and CSI/O) ----------------------------------------- Asynchronous Serial Communication Interfaces (ASCI) and Clocked Serial I/O (CSI/I) XXX pg 51... 56 00h - CNTLA0 - ASCI Channel 0 Control Reg A (10h on Reset, bit3=var) 01h - CNTLA1 - ASCI Channel 1 Control Reg A (10h on Reset, bit3/bit4=var) 7 MPE RX Multi Processor Filter (0=RX all bytes, 1=RX flagged bytes) 6 RE RX Receiver Enable (0=Disable, 1=Enable) 5 TE TX Transmitter Enable (0=Disable, 1=Enable) 4 /RTS0 for Ch0: Request to Send output (0=Low, 1=High) (/RTS pin) CKL1D for Ch1: CKA1 Clock Disable (CKA1/TEND pin) 3 MPBR Read: RX Multi Processor Bit (Received Flag-Bit) EFR Write: RX Error Flag Reset (0=Reset OVRN,PE,FE-Flags, 1=No Change) 2 MOD2 Number of Data bits (0=7bit, 1=8bit) 1 MOD1 Number of Parity bits (0=None, 1=1bit) (only if MP=0) 0 MOD0 Number of Stop bits (0=1bit, 1=2bit) 02h - CNTLB0 - ASCI Channel 0 Control Reg B (07h on Reset, bit7/bit5=var) 03h - CNTLB1 - ASCI Channel 1 Control Reg B (07h on Reset, bit7=var) 7 MPBT TX Multi Processor Bit (Flag-Bit to be Transmitted) 6 MP Multiprocessor Mode (0=Off/Normal, 1=Add Flag-bit to all bytes) 5 CTS Read: /CTS-pin (0=Low, 1=High), PS Write: Prescaler (0=Div10, 1=Div30) 4 PEO Parity Even/Odd (0=Even, 1=Odd) (ignored when MOD1=0 or MP=1) 3 DR Divide Ratio (0=Div16, 1=Div64) 2-0 SS Speed Select (0..6: "(PHI SHR N)", 7=External clock) The baudrate is "SS div PS div DR" (or "External_Clock div DR"). 04h - STAT0 - ASCI Channel 0 Status Register (00h on Reset, bit2/bit1=var) 05h - STAT1 - ASCI Channel 1 Status Register (02h on Reset) 7 RDRF RX Receive Data Register Full (0=No, 1=Yes) (R) 6 OVRN RX Overrun Error (0=Okay, 1=Byte received while RDRF=1) (R) 5 PE RX Parity Error (0=Okay, 1=Wrong Parity Bit) (R) 4 FE RX Framing Error (0=Okay, 1=Wrop Stop Bit) (R) 3 RIE RX Receive Interrupt Enable (R/W) 2 /DCD0 For Ch0: Data Carrier Detect (/DCD pin) (R) CTS1E For Ch1: CTS input enable (/CTS pin) (R/W) 1 TDRE TX Transmit Data Register Empty (R) 0 TIE TX Transmit Interrupt Enable (R/W) Note: RDRD/TDRE can be used as DRQ signal for DMA channel 0. 06h - TDR0 - ASCI Channel 0 Transmit Data Register 07h - TDR1 - ASCI Channel 1 Transmit Data Register 08h - RDR0 - ASCI Channel 0 Receive Data Register 09h - RDR1 - ASCI Channel 1 Receive Data Register 7-0 Data The hardware can hold one byte in the data register (plus one byte currently processed in a separate shift register). 0Ah - CNTR - CSI/O Control Register (0Fh on Reset) 7 EF End Flag, completion of Receive/Transmit (0=No/Busy, 1=Yes/Ready) 6 EIE End Interrupt Enable (0=Disable, 1=Enable) 5 RE Receive Enable (0=Off/Ready, 1=Start/Busy) 4 TE Transmit Enable (0=Off/Ready, 1=Start/Busy) 3 - Unused (should be all-ones) 2-0 SS Speed Select (0..6: "(20 shl N) clks per bit", 7=External clock) The select "speed" is output on CKS pin (or input from CKS pin when selecting External clock). Bit7 is read-only (cleared when reading/writing TRDR). 0Bh - TRDR - CSI/O Transmit/Receive Data Register 7-0 Data (8bit) (called TRDR by Hitachi, called TRD by Zilog) Data is output on TXS pin, and input on RXS pin (both LSB first). Despite of the separate pins, one may NOT set RE and TE simultanoulsy (for whatever reason... or maybe it's meant to WORK ONLY if RX and TX are STARTED simultaneously). The RXS pin is also used as /CTS1 (for ASCI channel 1). ASCI Multi Processor "Network" Feature This feature allows to share the serial bus by multiple computers. Each byte is transferred with a "MPB" Multi Processor Flag Bit (located between Data and Stop bits) (Parity is forcefully disabled in Multi Processor Mode). Assume broadcasting "Header+Data" Packets (with "Header" bytes flagged as MPB=1, and "Data" as MPB=0): The RX-Filter can select to receive only "Header" bytes, and, if the receiver treats itself to be addressed by the header, it can change the filter setting depending on whether it wants to receive/skip the following "Data" bytes. HD64180 Timers (PRT and FRC) ---------------------------- Programmable Reload Timers (PRT) and Free Running Counter (FRC) 10h - TCR - Timer Control Register (00h on Reset) 7 TIF1 Timer 1 Interrupt Flag (0=No, 1=Yes/Decrement reached 0000h) (R) 6 TIF0 Timer 0 Interrupt Flag (0=No, 1=Yes/Decrement reached 0000h) (R) 5 TIE1 Timer 1 Interrupt Enable (0=Disable, 1=Enable) 4 TIE0 Timer 0 Interrupt Enable (0=Disable, 1=Enable) 3-2 TOC Timer 1 Output Control to A18-Pin (0=A18, 1=Toggled, 2=Low, 3=High) 1 TDIE1 Timer 1 Decrement Enable (0=Stop, 1=Decrement; once every 20 clks) 0 TDIE0 Timer 0 Decrement Enable (0=Stop, 1=Decrement; once every 20 clks) TIF1 is reset when reading TCR or TMDR1L or TMDR1H. TIF0 is reset when reading TCR or TMDR0L or TMDR0H. The TOC bits control the A18/TOUT pin (it can be either A18 address line, or forced to Low or High, or "toggled": that is, inverted when TMDR1 decremts to 0. 0Ch - TMDR0L - Timer 0 Counter "Data" Register, Bit0-7 (FFh on Reset) 0Dh - TMDR0H - Timer 0 Counter "Data" Register, Bit8-15 (FFh on Reset) 0Eh - RLDR0L - Timer 0 Reload Register, Bit0-7 (FFh on Reset) 0Fh - RLDR0H - Timer 0 Reload Register, Bit8-15 (FFh on Reset) Timer 0 counter/reload values. The counter is decremented once every 20 clks, and triggers IRQ and gets reloaded when reaching 0000h. Reading TMDR0L returns current timer LSB, and latches current timer MSB. Reading TMDR0H returns that LATCHED timer MSB. Accordingly reads should be always done in order LSB, MSB. If the timer is stopped TMDR0L/TMDR0H can be written (and read) in any order. 14h - TMDR1L - Timer 1 Counter "Data" Register, Bit0-7 (FFh on Reset) 15h - TMDR1H - Timer 1 Counter "Data" Register, Bit8-15 (FFh on Reset) 16h - RLDR1L - Timer 1 Reload Register, Bit0-7 (FFh on Reset) 17h - RLDR1H - Timer 1 Reload Register, Bit8-15 (FFh on Reset) Timer 1 counter/reload values. Same as for Timer 0 (see above). 18h - FRC - Free Running Counter (FFh on Reset) 7-0 FRC Free Running Counter (decremented every 10 clks) This register should be read-only, writing to FRC may mess up DRAM refresh, ASCI and CSI/O baud rates. HD64180 Direct Memory Access (DMA) ---------------------------------- 20h - SAR0L - DMA Channel 0 Source Address, Bit0-7 (Memory or I/O) 21h - SAR0H - DMA Channel 0 Source Address, Bit8-15 (Memory or I/O) 22h - SAR0B - DMA Channel 0 Source Address, Bit16-19 (Memory or DRQ) 23h - DAR0L - DMA Channel 0 Destination Address, Bit0-7 (Memory or I/O) 24h - DAR0H - DMA Channel 0 Destination Address, Bit8-15 (Memory or I/O) 25h - DAR0B - DMA Channel 0 Destination Address, Bit16-19 (Memory or DRQ) 26h - BCR0L - DMA Channel 0 Byte Count Register, Bit0-7 27h - BCR0H - DMA Channel 0 Byte Count Register, Bit8-15 DMA Channel 1 Source/Dest/Len. Direction can be Memory-to-Memory, Memory-to-I/O, I/O-to-Memory, or I/O-to-I/O, Memory-Address can be Fixed, Incrementing, or Decrementing, I/O-Address is Fixed (see DMODE Register). For I/O transfers, Bit16-17 of SAR/DAR are selecting the DRQ type: 00h DRQ by /DREQ0-Pin (normal case) 01h DRQ by ASCI Channel 0 (RDRF-Bit for Source, or TDRE-Bit for Dest) 02h DRQ by ASCI Channel 1 (RDRF-Bit for Source, or TDRE-Bit for Dest) 03h Reserved Memory-to-Memory DMA clock can be selected in MMOD bit ("Burst" pauses CPU until transfer is completed, "Cycle Steal" keeps the CPU running at roughly half-speed during DMA). 28h - MAR1L - DMA Channel 1 Memory Address, Bit0-7 (Source or Dest) 29h - MAR1H - DMA Channel 1 Memory Address, Bit8-15 (Source or Dest) 2Ah - MAR1B - DMA Channel 1 Memory Address, Bit16-19 (Source or Dest) 2Bh - IAR1L - DMA Channel 1 I/O Address, Bit0-7 (Dest or Source) 2Ch - IAR1H - DMA Channel 1 I/O Address, Bit8-15 (Dest or Source) 2Eh - BCR1L - DMA Channel 1 Byte Count Register, Bit0-7 2Fh - BCR1H - DMA Channel 1 Byte Count Register, Bit8-15 DMA Channel 1 Source/Dest/Len. Direction can be Memory-to-I/O or I/O-to-Memory, Memory-Address can be Incrementing or Decrementing, I/O-Address is Fixed (see DCNTL Register). DRQ is taken from /DREQ1-Pin. 30h - DSTAT - DMA "Status" Register (32h on Reset) 7 DE1 DMA Channel 1 Enable (0=Ready, 1=Start/Busy) 6 DE0 DMA Channel 0 Enable (0=Ready, 1=Start/Busy) 5 /DWE1 Writing to DE1 (0=Allowed, 1=Ignored, keep Bit7 unchanged) 4 /DWE0 Writing to DE0 (0=Allowed, 1=Ignored, keep Bit6 unchanged) 3 DIE1 DMA Channel 1 Interrupt Enable (0=Disable, 1=Enable) 2 DIE0 DMA Channel 0 Interrupt Enable (0=Disable, 1=Enable) 1 - Unused (should be all-ones) 0 DME DMA Main Enable 31h - DMODE - DMA Mode Register (E1h on Reset) 7-6 - Unused (should be all-ones) 5-4 DM DMA Channel 0 Dest (0=Mem/Inc, 1=Mem/Dec, 2=Mem/Fix, 3=IO/Fix) 3-2 SM DMA Channel 0 Src (0=Mem/Inc, 1=Mem/Dec, 2=Mem/Fix, 3=IO/Fix) 1 MMOD DMA Channel 0 Mem-to-Mem Mode (0=Cycle Steal, 1=Burst) 0 - Unused (should be all-ones) 32h - DCNTL - DMA/WAIT Control Register (F0h on Reset) 7-6 MW Memory Waitstates (0..3 = 0..3) 5-4 IW External I/O Waitstates (0..3 = 1..4) and /INT/LIR and more XXX 3 DMS1 DMA Channel 1 Sense /DREQ1-Pin (0=Sense Level, 1=Sense Edge) 2 DMS0 DMA Channel 0 Sense /DREQ0-Pin (0=Sense Level, 1=Sense Edge) 1 DIM1 DMA Channel 1 Src-to-Dest Direction (0=Mem-to-I/O, 1=I/O-to-Mem) 0 DIM0 DMA Channel 1 Memory-Step Direction (0=Increment, 1=Decrement) Note On some chip versions address bus is only 19bits, namely that does apply on 64pin chips (68pin/80pin chips should have 20bits). Regardless of the pin-outs, the extra bit might (maybe) exist internally on newer 64pin chips(?) HD64180 Interrupts ------------------ Interrupts Prio Vector 0 /RES Reset (non-maskable) (PC=0000h, with TRAP=0 in ITC) 1 TRAP Undefined Opcode (non-maskable) (PC=0000h, with TRAP=1 in ITC) 2 /NMI Non-maskable Interrupt (PC=0066h) 3 /INT0 Maskable Interrupt Level 0 (PC=[I*100h+databus], or PC=0038h) 4 /INT1 Maskable Interrupt Level 1 (PC=[I*100h+IL*20h+00h]) 5 /INT2 Maskable Interrupt Level 2 (PC=[I*100h+IL*20h+02h]) 6 Timer 0 (PC=[I*100h+IL*20h+04h]) 7 Timer 1 (PC=[I*100h+IL*20h+06h]) 8 DMA Channel 0 Ready (PC=[I*100h+IL*20h+08h]) 9 DMA Channel 1 Ready (PC=[I*100h+IL*20h+0Ah]) 10 Clocked Serial I/O Port (CSI/O) (PC=[I*100h+IL*20h+0Ch]) 11 Asynchronous SCI channel 0 (PC=[I*100h+IL*20h+0Eh]) 12 Asynchronous SCI channel 1 (PC=[I*100h+IL*20h+10h]) Below whatever only (not HD64180 and not Z180) ? Input Capture (PC=[I*100h+IL*20h+10h]) ? Output Compare (PC=[I*100h+IL*20h+12h]) ? Timer Overflow (PC=[I*100h+IL*20h+16h]) Note: "I" is a CPU-register (set via MOV I,A opcode). "IL" is new I/O port (set via OUT opcode). /INT0 works same as on real Z80 (and depends on mode set via IM 0/1/2 opcodes). 33h - IL - Interrupt Vector Low Register (00h on Reset) 7-5 IL Bit7-5 of IM 2 Interrupt Vector Table Address 4-0 - Unused (should be zero) 34h - ITC - INT/TRAP Control Register (39h on Reset) 7 TRAP Undefined Opcode occurred (0=No, 1=Yes) 6 UFO Addr of Undef Opcode (aka Undefined Fetch Object) (0=PC-1, 1=PC-2) 5-3 - Unused (should be all-ones) 2 ITE2 Interrupt /INT2 Enable (0=Disable, 1=Enable) 1 ITE1 Interrupt /INT1 Enable (0=Disable, 1=Enable) 0 ITE0 Interrupt /INT0 Enable (0=Disable, 1=Enable) TRAP gets set upon Undefined Opcodes (TRAP and RESET are both using vector 0000h, the TRAP bit allows to sense if the vector was called by Reset or Undef Opcode). The TRAP bit can be cleared by software by writing "0" to it (however, software cannot write "1" to it). HD64180 Memory Mapping and Control ---------------------------------- Memory Managment Unit (MMU) The Memory Managment Unit translates "virtual" 16bit CPU memory addresses to "physical" 19bit address bus. 0000h -------> +--------------------+ | Common Area 0 | Phys19bit = Virt16bit + 00000h BA*1000h ----> +--------------------+ | Bank Area | Phys19bit = Virt16bit + BBR*1000h CA*1000h ----> +--------------------+ | Common Area 1 | Phys19bit = Virt16bit + CBR*1000h FFFFh -------> +--------------------+ The 16bit CPU address space is divided into three areas (of which, the first two areas can be 0 bytes in size: BA=0 disables Common Area 0, CA=BA disables Bank Area). 38h - CBR - MMU Common Base Register (Common Area 1) (00h on Reset) 39h - BBR - MMU Bank Base Register (Bank Area) (00h on Reset) 7 Unused (should be zero) (but, used on chips with 20bit address bus) 0-6 Base in 4K-units within "physical" 19bit 512K address space 3Ah - CBAR - MMU Common/Bank Area Register (F0h on Reset) 4-7 CA Start of Common Area 1 (End of Bank Area) (0Fh upon Reset) 0-3 BA Start of Bank Area (End of Common Area 0) (00h upon Reset) This is in 4K-units within the "virtual" 16bit 64K address space. Results on CA code (ccc=0..6) len 5bit (Nnnnn+1) 111cccNn.nnnnnnnn --> code (ccc=0..7) len 10bit (Nnnnnnnnnn+1) 11111111 --> end code (FFh) The "code/length" pairs are then follwed by "src" data, or "disp" offsets (depending on the "ccc" codes). The meaning of the "ccc" codes varies from program to program (see below for how they are used by BSX and SFC-Box). Note: As seen above, ccc=7 works only with 10bit len (not 5bit len) and only with max len=2FFh+1 (not 3FFh+1). Nintendo-specific Compression Codes (BSX) (Satellaview) Used to decompress various data (including custom person OBJs in the Directory packet). The decompression functions are at 80939Fh (to RAM) and 80951Eh (to VRAM) in the BSX-BIOS. The meaning of the "ccc" codes is: 0 Copy_bytes_from_src 1 Fill_byte_from_src 2 Fill_word_from_src 3 Fill_incrementing_byte_from_src 4 Copy_bytes_from_dest_base_plus_16bit_disp 5 Copy_bytes_from_dest_base_plus_16bit_disp_with_invert 6 Copy_bytes_from_current_dest_addr_minus_8bit_disp 7 Copy_bytes_from_current_dest_addr_minus_8bit_disp_with_invert For all codes (including ccc=2), len is the number of BYTEs to be copied/filled. For ccc=4..6, the code is followed by a 16bit offset in LITTLE-ENDIAN format. For ccc=5/7, copied data is inverted (XORed with FFh). Nintendo-specific Compression Codes (SFC-Box) (Super Famicom Box) Used (among others) to decompress the Title-Bitmaps in "GROM" EPROMs, the decompression function is at 0088A2h in the "ATROM" menu program. The meaning of the "ccc" codes is: 0 Copy_bytes_from_src 1 Fill_byte_from_src 2 Fill_word_from_src 3 Fill_incrementing_byte_from_src 4 Copy_bytes_from_dest_base_plus_16bit_disp 5 Copy_bytes_from_dest_base_plus_16bit_disp_with_xflip 6 Copy_bytes_from_dest_base_plus_16bit_disp_with_yflip 7 Unused (same as ccc=4) For ccc=2, len is the number of WORDs to be filled, for all other codes, it's the number of BYTEs to be copied/filled. For ccc=4..7, the code is followed by a 16bit offset in BIG-ENDIAN format. For ccc=5 (xflip), bit-order of all bytes is reversed (bit0/1/2/3 <--> bit7/6/5/4). For ccc=6 (yflip), reading starts at dest_base+disp (as usually), but the read-address is then decremented after each byte-transfer (instead of incremented). SNES Decompression Hardware The APU automatically decompresses BRR-encoded audio samples (4bit to 15bit ADPCM, roughly similar to CD-XA format). Cartridges with SPC7110 or S-DD1 chips can decompress (roughly JPEG-style) video data, and convert it to SNES bit-plane format. Cartridges with SA-1 chips include a "Variable-Length Bit Processing" feature for reading "N" bits from a compressed bit-stream. SNES Unpredictable Things ------------------------- Open Bus Garbage appears on reads from unused addresses (see below), on reads from registers that contain less than 8 bits (see more below), and on reads from (most) write-only registers (see even more below). The received data is the value being previously output on the data bus. In most cases, that is the last byte of the opcode (direct reads), or the upper byte of indirect address (indirect reads), ie. LDA IIJJ,Y aka MOV A,[IIJJ+Y] --> garbage = II LDA (NN),Y aka MOV A,[[NN]+Y] --> garbage = [NN+1] When using General Purpose DMA, it'd be probably rely on the store opcode that has started the DMA (in similar fashion as above loads). In case of HDMA things would be most unpredictable, garbage would be whatever current-opcode related value. And, if two DMA transfers follow directly after each other, garbage would probably come from the previous DMA. Also, in 6502-mode (and maybe also in 65816-mode), the CPU may insert dummy-fetches from unintended addresses on page-wraps? Unused Addresses in the System Region Address Size 2000h..20FFh 100h ;unused addresses 2181h..2183h 3 ;write-only WRAM Address registers 2184h..21FFh 7Ch ;unused addresses in the B-BUS region 2200h..3FFFh 1E00h ;unused addresses 4000h..4015h 16h ;unused slow-CPU Ports 4018h..41FFh 1E8h ;unused slow-CPU Ports 4200h..420Dh 0Eh ;write-only CPU Ports 420Eh..420Fh 2 ;unused CPU Ports 4220h..42FFh E0h ;unused CPU Ports 43xCh..43xEh 3*8 ;unused DMA Ports 4380h..7FFFh 3C80h ;unused/expansion area So, of the total of 8000h bytes, a large number of 5EF4h is left unused. Ports 2144h..217Fh are APU mirrors, NOT open bus. Unused bits (in Ports with less than 8 used bits) Addr Mask Name Unused Bits 4016h FCh JOYA Bit7-2 are open bus 4017h E0h JOYB Bit7-5 are open bus 4210h 70h RDNMI Bit6-4 are open bus 4211h 7Fh TIMEUP Bit6-0 are open bus 4212h 3Eh HVBJOY Bit5-1 are open bus PPU1 Open Bus PPU1 Open Bus is relies on the value most recently read from Ports 2134h-2136h, 2138h-213Ah, 213Eh. This memorized value shows up on later reads from read-only Ports 21x4h..21x6h and 21x8h..21xAh (with x=0,1,2) (in all 8bits), as well as in Port 213Eh.Bit4. PPU2 Open Bus PPU2 Open Bus is relies on the value most recently read from Ports 213Bh-213Dh, 213Fh. This memorized value shows up on later reads from Port 213Bh.2nd_read.Bit7, 213Ch/213Dh.2nd_read.Bits7-1, and Port 213Fh.Bit5. PPU Normal Open Bus Other write-only PPU registers & the HV-latch "strobe" register are acting like "normal" CPU Open Bus (ie. usually returning the most recent opcode byte). These are 21x0h..21x3h, 21x7h (with x=0,1,2,3), and 21xBh..21xFh (with x=0,1,2). Open Bus for DMA DMA cannot read from most I/O ports, giving it some additional open bus areas: 2100h-21FFh Open Bus (when used as A-Bus) (of course they work as B-Bus) 4000h-41FFh Open Bus (name 4016h/4017h cannot be read) actually, 4017h return bit4-2 set (1=GNDed joypad input) 4210h-421Fh These do work (the only I/O ports that are not open bus) 4300h-437Fh Special Open Bus (DMA registers, may return [PC] instead of FFh) For DMA reads, one may expect the same garbage as for CPU reads (ie. when starting a DMA via "MOV [420Bh],A", one would expect 42h as open bus value). However, it takes a few cycles before the DMA transfer does actually start, during that time the hardware "forgets" the 42h value, and instread, DMA does always read FFh (High-Z) as open bus value. With two exceptions: If DMA wraps from an used to unused address (eg. from 1FFFh/WRAM to 2000h/unused) then the first "unused" byte will be same as the last "used" byte, thereafter, it forgets that value (and returns FFh on further unused addresses). The other exception is if DMA at 4300h..437Fh: In this case it will read [PC] for that region (and will also "memorize" it when reaching the first unused address at 4380h, and then returns FFh for 4381h and up). For example: "MOV [420Bh],A" followed by "ADC A,33h" would return 69h (the first byte of the ADC opcode). This effect occurs only if the transfer in that region, ie. if starts below that area, and does then wrap from 42FFh to 4300h, then it returns FFh instead of 69h. (The reason of this special effect is probably that the DMA somehow "ignores the databus", so external HIGH-Z levels (like from XBOO cable or Cartridge) cannot drag the "memorized" value to HIGH.) EDIT: The above "memorize for next ONE unused address" applies only when XBOO cable is connected (which pulls the databus to HIGH rather quickly). Without XBOO cable (and without cartridge connected) the "memorized" value may last for the next 2000h (!) unused addresses, then it may slowly get corrupted (some bits going to HIGH state, until, after some more time, all bits are HIGH). Actually, it seems to last even longer than 2000h -- possibly forever (until DMA ends, or until it reaches a used address). SPC700 Division Overflow/Result (DIV YA,X opcode) The overall division mechanism (with and without overflows) is: H = (X AND 0Fh)<=(Y AND 0Fh) ;half carry flag (odd dirt effect) Temp = YA FOR i=1 TO 9 Temp=Temp*2 ;\rotate within 17bits IF Temp AND 20000h THEN Temp=(Temp XOR 20001h) ;/ IF Temp>=(X*200h) THEN Temp=(Temp XOR 1) IF Temp AND 1 THEN Temp=(Temp-(X*200h)) AND 1FFFFh NEXT i A = (Temp AND FFh) ;result.bit7-0 V = (Temp.Bit8=1) ;result.bit8 Y = (Temp/200h) ;remainder (aka temp.bit9-16) N = (A.Bit7=1) ;sign-flag (on result.bit7) (though division is unsigned) Z = (A=00h) ;zero-flag (on result.bit7-0) That is, normally (when result = 0000h..00FFh): A=YA/X, Y=YA MOD X, N=ResultingA.Bit7, Z=(ResultingA=00h), V=0, H=(see above) An intact 9bit result can be read from V:A (when result = 0000h..01FFh). Otherwise return values are useless garbage (when result = 0200h..Infinite). SNES Timings ------------ --> SNES Timing Oscillators --> SNES Timing H/V Counters --> SNES Timing H/V Events --> SNES Timing PPU Memory Accesses SNES Timing Oscillators ----------------------- NTSC Timings NTSC crystal 21.4772700MHz (X1, type number D214K1) NTSC color clock 3.57954500MHz (21.47727MHz/6) (generated by PPU2 chip) NTSC master clock 21.4772700MHz (21.47727MHz/1) (without multiplier/divider) NTSC dot clock 5.36931750MHz (21.47727MHz/4) (generated by PPU chip) NTSC cpu clock 3.57954500MHz (21.47727MHz/6) (without waitstates) NTSC cpu clock 2.68465875MHz (21.47727MHz/8) (short waitstates) NTSC cpu clock 1.78977250MHz (21.47727MHz/12) (joypad waitstates) NTSC frame rate 60.09880627Hz (21.477270MHz/(262*1364-4/2)) NTSC interlace 30.xxxxxxxxHz (21.477270MHz/(525*1364)) PAL Timings PAL crystal 17.7344750MHz (X1, type number D177F2) PAL color clock 4.43361875MHz (17.7344750MHz/4) (generated by S-CLK chip) PAL master clock 21.2813700MHz (17.7344750MHz*6/5) (generated by S-CLK chip) PAL dot clock 5.32034250MHz (21.2813700MHz/4) (generated by PPU chip) PAL cpu clock 3.54689500MHz (21.2813700MHz/6) (without waitstates) PAL cpu clock 2.66017125MHz (21.2813700MHz/8) (short waitstates) PAL cpu clock 1.77344750MHz (21.2813700MHz/12) (joypad waitstates) PAL frame rate 50.00697891Hz (21.281370MHz/(312*1364)) PAL interlace 25.xxxxxxxxHz (21.281370MHz/(625*1364+4/2)) APU Timings APU oscillator 24.576MHz (X2, type number 24.57MX) DSP sample rate 32000Hz (24.576MHz/24/32) SPC700 cpu clock 1.024MHz (24.576MHz/24) SPC700 timer 0+1 8000Hz (24.576MHz/24/128) SPC700 timer 2 64000Hz (24.576MHz/24/16) CIC clock 3.072MHz (24.576MHz/8) Expansion Port 8.192MHz (24.576MHz/3) CPU Clock Notes CPU Clock cycles (opcode fetches, data transfers, and internal cycles) are usually clocked at 3.5MHz or 2.6MHz (or a mixup thereof). 3.5MHz Used for Fast ROM, most I/O ports, and internal CPU cycles 2.6MHz Used for Slow ROM, for WRAM, and for DMA/HDMA transfers 1.7MHz Used only for (some) Joypad I/O Ports The CPU is paused for 40 master cycles (per 1364 cycle scanline) for memory REFRESH purposes, effectively making the CPU around 3% slower. The CPU is also paused when using DMA/HDMA transfers. Nintendo specifies the following ROM timings to be required: 3.5MHz use 120ns or faster ROM/EPROMs 2.6MHz use 200ns or faster ROM/EPROMs Dot Clock Notes The above values apply for the drawing period, in the hblank period some cycles are a bit longer. This "stuttering" effect appears also on the dotclk output on expansion port. External Oscillators (in Cartridges) DSPn 7.600MHz Plastic Type "[M]7600A" (used without divider) ST010 22.000MHz Plastic Type "[M]22000C" (internally 11.000MHz) ST011 15.000MHz Ceramic Type "15.00X" (used without divider) ST018 21.440MHz Plastic Type "[M]21440C" CX4 20.000MHz Plastic Type "[M]20000C" or "20.0MC/TDKY" MC1 SNES Master Clock GSU1 21.4MHz Plastic Type "21.4MC/TDKT" GSU2 21.44MHz Plastic Type "[M]21440C" SA-1 SNES Master Clock S-DD1 SNES Master Clock SPC7110 SNES Master Clock MX15001 SNES Master Clock (Nintendo Power Flashcarts) SGB SNES Master Clock SGB2 20.9MHz External oscillator (located on PCBs solder-side) BS-X 18.432MHz Satellaview Receiver Unit (on expansion port) RTC-4513 32.768kHz On-chip 32.768kHz quartz crystal in RTC chip S-3520 32.768kHz External 32.768kHz quartz crystal (SFC-Box) S-RTC ? kHz External unknown-frequency crystal ACE SNES Dot Clock (Exertainment RS232 on expansion port) SNES Master Clock, = 21.4772700MHz (NTSC), or 21.2813700MHz (PAL). SNES Timing H/V Counters ------------------------ Horizontal Timings Scanline Length 1364 master cycles (341 dot cycles) Except, Line F0h in Field.Bit=1 of Interlace: 1360 master cycles Refresh (per scanline) 40 master cycles (10 dot cycles) 50*312*1364 = 21.278400 MHz // 21.281370MHz/(312*1364) = 50.00697891 Hz 60*262*1364 = 21.442080 MHz // 21.477270MHz/(262*1364-2) = 60.09880627 Hz Long and Short Scanlines A normal scanline is 1364 master cycles long. But, there are two special cases, in which lines are 4 cycles longer or shorter: Short Line --> at 60Hz frame rate + interlace=off + field=1 + line=240 Long Line --> at 50Hz frame rate + interlace=on + field=1 + line=311 (in both cases, the selected picture size, 224 or 239 lines, doesn't matter) Technically, the effects work as so: Normal Line : 1364 cycles, 340 dots (0-339), four dots are 5-cycles long Long Line : 1368 cycles, 341 dots (0-340), four dots are 5-cycles long Short Line : 1360 cycles, 340 dots (0-339), all dots are 4-cycles long Glitch: The long scanline is placed in the last line (directly after the Hsync for line 0, thus shifting the Hsync position of Line 1, ie. of the first line of the drawing period), accordingly, the upper some scanlines in interlaced 50Hz mode are visibly shifted to the right (by around one pixel), until after a handful of scanlines the picture stablizes on the new hsync position (ie. trying to display a vertical line will appear a little curved). Long and Short Scanlines (Purpose) The Scanline Rate doesn't match up with the PAL/NTSC Color Clocks, so, for example, a red rectangle on black background will look like so: RGB-Output Composite-Output Composite-Output Flawless Static-Error Flimmering-Error RRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR rRRRRRRRRRRRRRRRr RRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR rrRRRRRRRRRRRRRRrr RRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR rRRRRRRRRRRRRRRRr RRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR rRRRRRRRRRRRRRRRr RRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR rrRRRRRRRRRRRRRRrr RRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR rRRRRRRRRRRRRRRRr Inserting the long/short scanlines does synchronize the Frame Rate with the PAL/NTSC color clocks: PAL Mode Master Clocks (21MHz) Color Clocks (PAL:4.4MHz) 50Hz Normal 425568 (312*1364) 88660 (425568/6*5/4) 50Hz Interlace 426936 (313*1364+4) 88945 (426936/6*5/4) NTSC Mode Master Clocks (21MHz) Color Clocks (NTSC:3.5MHz) 30Hz Normal 714732 ((262+262)*1364-4) 119122 (714732/6) 30Hz Interlace 716100 ((262+263)*1364) 119350 (716100/6) The result is that the composite video output is producing the "Static Error" effect (in the above example, the rectangle has sawtooth-edges). And the "Flimmering" effect is avoided (which would have blurry edges, and which would also appear as if the edges were wandering up) (Note: The flimmering effect can be seen when switching a modded 50Hz PAL console to 60Hz mode). SNES Timing H/V Events ---------------------- Summary of Vertical Timings V=0 End of Vblank, toggle Field, prefetch OBJs of 1st scanline V=0..224/239 Perform HDMA transfers (before each line & after last line) V=1 Begin of Drawing Period V=225/240 Begin of Vblank Period (NMI, joypad read, reload OAMADD) V=240 Short scanline in Non-interlaced 60Hz field=1 V=311 Long scanline in Interlaced 50Hz field=1 V=261/311 Last Line (in normal frames) V=262/312 Extra scanline (occurs only in Interlace Field=0) V=VTIME Trigger V-IRQ or HV-IRQ Detailed List (H=Horizontal, V=Vertical, F=Field) H=0, V=0, F=0 SNES starts at this time after /RESET H=0, V=0 clear Vblank flag, and reset NMI flag (auto ack) H=0, V=225 set Vblank flag H=0.5, V=225 set NMI flag H=1 clear hblank flag H=1, V=0 toggle interlace FIELD flag H=HTIME+3.5 H-IRQ H=2.5, V=VTIME V-IRQ (or HV-IRQ with HTIME=0) H=HTIME+3.5, V=VTIME HV-IRQ (when HTIME=1..339) H=6, V=0 reload HDMA registers H=10, V=225 reload OAMADD H=22-277(?), V=1-224 draw picture H=32.5..95.5, V=225 around here, joypad read begins (duration 4224 clks) H=133.5 around here, REFRESH begins (duration 40 clks/10 dots) H=274 set hblank flag H=278, V=0..224 perform HDMA transfers H=323,327 seen as long-PPU-dots (but not as long-CPU-dots) H=323,327, V=240, F=1 seen as normal-PPU-dots (in short scanline 240) (60Hz) H=339 this is last PPU-dot (in normal and short scanlines) H=340, V=311, F=1 this is last PPU-dot in long scanlines (50Hz+Interlace) CPU.H=339 this is last CPU-dot (in normal scanlines) CPU.H=338, V=240, F=1 this is last CPU-dot (in short scanlines) CPU.H=340, V=311, F=1 this is last CPU-dot (in long scanlines) H=0?, V=0 reset OBJ overflow flags in 213Eh (only if not f-blank) H=0?+INDEX*2, V=YLOC set OBJ overflow bit6 (too many OBJs in next line) H=0?, V=YLOC+1 set OBJ overflow bit7 (too many OBJ pix in this line) ...? xxx joypad read xxx reload mosaic h/v counter (at some point during vblank) xxx count mosaic v counter (at some point in each scanline) Note that a PAL TV-set can display around 264 lines (about 25 more than supported by the 239-line mode). Note that a superscope pointing at pixel (X, Y) on the screen will latch approximately dot X+40 on scanline Y+1. PPU H-Counter-Latch Quantities When latching PPU H/V-latches via reading [2137h] by software, 341*4 times at evenly spread locations, one will statistically get following H values: 0..132 4 times (normal) 133 3 times (occurs sometimes at H=133.5, and always at H=133.0) 134 1 time (occurs sometimes at H=134.x) 135..142 never (refresh is busy, cpu is stopped) 143 1 time (occurs sometimes at H=143.x) 144 3 times (occurs sometimes at H=144.0, and always at H=144.5) 145..322 4 times (normal) 323 6 times (seen as long dot) (or 5.99 times if NTSC+InterlaceOff) 324..326 4 times (normal) 327 6 times (seen as long dot) (or 5.99 times if NTSC+InterlaceOff) 328..339 4 times (normal) 340 never (doesn't exist) (or 0.01 times if PAL+InterlaceOn) 341-511 never (doesn't exist) For the 1 and 3 times effect, one would expect the 40 clk refresh as so: --- H=133.5--><--H=134.0 ------------------ H=143.5--><--H=144.0 --- ccccccccccccccRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRcccccccccccccc but, sometimes (randomly at 50:50 chance) it occurs somewhat like so: ccccccccccccRRccRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRccRRccccccccccc whereas "c"=CPU, "R"=Refresh (ie. sometimes, the CPU wakes up within the Refresh period). Unknown why & when exactly that stuttering refresh occurs. Opcodes may begin before Refresh, and end after Refresh (rather than forcefully finishing the Opcode before starting Refresh), so above statistics are same for latching via "MOV A,[2137h]" (4 cycles) and "MOV A,[002137h]" (5 cycles) opcodes. Writing [4201h] (instead of reading [3137h]) shifts the visible refresh-related H values (H=136..143=never, H=135/144 once, H=134/H=145 thrice), but obviously doesn't alter the amounts of visible PPU-related H values. SNES Timing PPU Memory Accesses ------------------------------- Below is some info/guesses on what is happening during the 1364 master cycles of a scanline. Plus some info/guesses on if/when/why it is (or isn't) possible the change VRAM/CGRAM/OAM outside of V-Blank or Forced-Blank. PPU VRAM Load VRAM access time is 4 master cycles per word (aka 1 dot-cycle per word). In each line, the PPU fetches 34*2 words (for 34 OBJ tiles of 8pix/4bpp), plus 33*8 words (for BgMap+BgTiles) (eg. 33*4 BgMap entries plus 33*4 BgTiles at 2bpp in BG Mode 0) (or less BG layers, but more bpp per tile in other BG Modes). As a whole, 4 master cycles per 34*2 + 33*8 words sums up to 1328 master cycles (or possibly a bit more if accesses during "long dots" should happen to take 5 master cycles per word). 1328 would leave 36 unused master cycles per scanline (or maybe MORE unused cycles if some BG layers are disabled? and/or if less than 34 OBJ tiles are located in the scanline? unknown if VRAM can be accessed during any such unused cycles? as far as known, existing games aren't trying to do so). PPU Palette Load Not much known about CGRAM access timings. There would be some theories: 1) Maybe 512 accesses/line (for frontmost main/sub-screen pixels) 2) Maybe 1296 accesses/line (for 256*4 BG pixels + 34*8 OBJ pixels) 3) Maybe 1360 accesses/line (for 33*4*8 BG pixels + 34*8 OBJ pixels) For the 1296/1360 accesses therories, CGRAM would be inaccessible for most of the 1364 cycles. In practice, it is possible to change CGRAM during certain timespots in the Hblank-period (not during the Hblank period, but it works , though doing so may require some research - and may end up with more or less fragile timings). As for when/why it is working: Maybe there some totally unused cycles, or it depends on how many OBJs are displayed in the current scanline, possibly also on the number of used and/or enabled BG layers (and thereby, maybe also allowing to change CGRAM outside of Hblank during BG-drawing period?). PPU OAM load OAM handling is done in three steps: 1) scan 128 entries (collect max 32 entries per line) 2) scan 32 entries (collect max 34 tiles per line) 3) scan 34 entries (collect max 34x8 pixels per line) OAM-Access time for Step 1 is 128*2 dots aka 128*8 master cycles (as seen in STAT77.Bit6). OAM-Access times for Steps 2 and 3 is unknown (might be some cycles per entry... or might be NULL cycles; in case OAM entries were copied to separate buffer during previous Step... and/or NULL cycles if no OBJs are in current scanline). So, aside from the 256 known/used dot-cycles, there may (or may not) be up to 84 unused dot-cycles... possibly allowing to change OAM during Hblank(?). Note: Mario Kart is using Forced Blank to change OAM in middle of screen. Observe that the OAM address in Port 2102h is scattered during drawing period. SNES Pinouts ------------ External Connector Pinouts --> SNES Controllers Pinouts --> SNES Audio/Video Connector Pinouts --> SNES Power Supply --> SNES Expansion Port (EXT) Pinouts --> SNES Cartridge Slot Pinouts Chipset Pinouts --> SNES Chipset --> SNES Pinouts CPU Chip --> SNES Pinouts PPU Chips --> SNES Pinouts APU Chips --> SNES Pinouts ROM Chips --> SNES Pinouts RAM Chips --> SNES Pinouts CIC Chips --> SNES Pinouts MAD Chips --> SNES Pinouts RTC Chips --> SNES Pinouts Misc Chips --> SNES Pinouts GSU Chips --> SNES Pinouts CX4 Chip --> SNES Pinouts SA1 Chip --> SNES Pinouts Decompression Chips --> SNES Pinouts BSX Connectors --> SNES Pinouts NSS Connectors --> SNES Pinouts Nintendo Power Flashcarts Mods --> SNES Common Mods --> SNES Controller Mods --> SNES Xboo Upload (WRAM Boot) SNES Controllers Pinouts ------------------------ Joypads (2) Pin Dir Port 1 Port2 ____________ _________________ 1 - VCC +5VDC VCC +5VDC / 7 6 5 | 4 3 2 1 | 2 Out JOY-1/3 Clock JOY-2/4 Clock | GND IO6 IN3 | IN1 STB CK1 VCC | 1 3 Out JOY-STROBE JOY-STROBE \____________|_________________| 4 In JOY-1 Data JOY-2 Data ____________ _________________ 5 In JOY-3 Data JOY-4 Data / 7 PEN 5 | 4 3 2 1 | 6 I/O I/O bit6 I/O bit7, Pen | GND IO7 IN4 | IN2 STB CK2 VCC | 2 7 - GND GND \____________|_________________| Pin 6 on Port 2 is shared for I/O and Lightpen input. Internal Connector The two joypad connectors (and power LED) are located on a small daughterboard, which connects to the mainboard via an 11pin connector: 1 VCC 2 IO6 ;-pad1 3 IO7 / pen ;\ 4 IN2 ; pad2 5 IN4 ;/ 6 IN1 ;\pad1 7 IN3 ;/ 8 CK1 (one short LOW pulse per JOY1/JOY3 data bit) 9 CK2 (one short LOW pulse per JOY2/JOY4 data bit) 10 STB (one short HIGH pulse at begin of transfer) 11 GND For PAL consoles: The daughterboard contains diodes in the CK1, CK2, STB lines, effectively making them open-collector outputs (so the joypad may require pull-up resistors for that signals). SNES PAL vs NTSC Controllers SNES PAL consoles are passing CK1, CK2, STB lines through diodes (the diodes are located on the controller connector daughterboard inside of the console, and the diodes are effectively making that lines open-collector outputs, so PAL controllers do require pull-up resistors for that signals). SNES NTSC consoles don't have that diodes, and don't require pull-ups. Using PAL controllers on NTSC consoles should work without problems. For using NTSC controllers on PAL consoles: Remove or shortcut the diodes inside of the SNES, or install pull-ups inside of the controller. SNES Audio/Video Connector Pinouts ---------------------------------- RF Out (TV Modulator) Cinch with channel switch. Modulated video signal with mono-audio. Multi Out 1 RGB - Red analog video out ________________---________________ 2 RGB - Green analog video out / 11 9 7 5 3 1 \ 3 RGB - H/V sync out | | 4 RGB - Blue analog video out \__12____10____8_____6_____4_____2__/ 5 Ground (used for Video) 6 Ground (used for Audio) 7 S-Video Y (luminance) out 8 S-Video C (chroma) out 9 Video Composite out (Yellow Cinch) 10 +5V DC 11 Audio Left out (White Cinch) 12 Audio Right out (Red Cinch) Pin 1,2,4: Red/Green/Blue (1V DC offset, 1V pp video into 75 ohms) Pin 3,7,8,9: (1V pp into 75 ohms) Pin 11,12: Left/Right (5V pp) In cost-down SNES models, pin 1-4 and 7-8 are reportedly not connected (though one can upgrade them with some small modifications on the mainboard). SNES Power Supply ----------------- AC 9V (PAL version) Power Supply input. The 9V AC input is internally converted to 9V DC, and is then converted to 5V DC by a 7805 IC which turns the additional volts into heat. The CPU/PPU/APU are solely operated at 5V DC (ie. you can feed 5V to the 7805 output). However, 9V DC are used by the Audio Amplifier, the console works without the 9V supply, but you won't hear any sounds. The Amplifier does work more less okay with 5V supply (ie. you can shortcut the 7805 input and output pins, and feed 5V to both of them) (when doing that disconnect the original 9V input to make sure that 9V aren't accidently passed to the CPU/PPU). However, at 5V, the middle amplitude levels are generated linearily intact, but the MIN/MAX levels are chopped off, for example a sawtooth wave looks like so: Amplifier Output at 9V: Amplifier Output at 5V: /| /| /| /| /| -8000h +2.5V _ _ _ _ _ / | / | / | / | / | / | / | / | / | / | -3XXXh +1V / | / | / | / | / | _/ |_/ |_/ |_/ |_/ | +3XXXh -1V / |/ |/ |/ |/ | +7FFFh -2.5V The effect applies only if a game does use MIN/MAX levels (ie. there'd be no problem at Master Volume of 40h or less; unless additional output comes from Echo Unit). 10V DC 850mA (NTSC version) Same as above, but using a DC supply (not AC), passed through a diode (so internally the voltage may drop from 10V to around 9V). Power Switch / Anti-Eject In older SNES consoles the Power switch comes with an anti-eject lever, which goes into a notch in the cartridge. Some carts have notches with square edges; cart cannot be removed while power is on. Other carts have notches with diagonal edge; the lever gets pushed (while sliding along the diagonal edge), and power is switched off automatically when removing the cartridge. The anti-eject type is probably (?) used by carts with battery-backed SRAM, in order to prevent garbage writes (which might occur when simultaneously ejecting and powering-down). SNES Expansion Port (EXT) Pinouts --------------------------------- EXT (at bottom of console) (used by Satellaview and Exertainment) Most pins are exactly the same as on the cartridge slot, the only special pins, which aren't found on Cart slot, are EXT pins 21, 22, and 25: SMPCK is 8.192MHz (24.576MHz/3) from APU, DOTCK is the PPU dot clock (around 5.3MHz, with some stuttering during hblank period), MONO is a mono audio output. .--------.--- SHIELD=GND PA0 |1 2| PA1 Bottom View of console: PA2 |3 4| PA3 .-------------------------------------. PA4 |5 6| PA5 | (rear side) | PA6 |7 8| PA7 | +----+---------------+ | /PAWR |9 10| /PARD | |snap| 28 ...... 2 | | D0 |11 12| D1 | | in | 27 ...... 1 | | D2 |13 14| D3 | +----+---------------+ | D4 |15 16| D5 | EXT | D6 |17 18| D7 | | /RESET |19 20| +5VDC | | SMPCLK |21 22| DOTCK | | GND |23 24| EXPAND | | MONO-AUDIO |25 26| /IRQ | | L-AUDIO |27 28| R-AUDIO | (front side) | '--------' '-------------------------------------' The L/R-AUDIO inputs are essentially same as on cart slot, although they are passed through separate capacitors, so there is no 0 Ohm connection between EXT and Cart audio pins. EXT Pin 24 connects to Cart pin 2 (aside from a 10K pull-up it isn't connected anywhere inside of the console) so this pin is reserved for communication between cartridge hardware and ext hardware (used by Satellaview). SNES Cartridge Slot Pinouts --------------------------- Cartridge Slot 62 pins (31x2 pins) Most cartridges are using only the middle 46 pins. Front/Round Rear/Flat Solder side Component side MCK 21M - 01 32 - /WRAMSEL 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 3.072MHz (or 4.00MHz on older SNES) /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 GND - SHIELD - GND Caution: The connector uses a nonstandard 2.5mm pitch (not 2.54mm). And, the PCB is only 1.2mm thick (not 1.5mm). The width of the key gaps equals to 2 pins each (ie. the overall connector size is 35x2 pins, with 31x2 used pins, and two unused 2x2 pin clusters). Pin assignments A23-0, D7-0, /WR, /RD - CPU address/data bus, read/write signals /IRQ - Interrupt Request (used by SA-1 and GSU) /RESET - When the system is reset (power-up or hard reset) this goes low /WRAMSEL - Work RAM select (00-3F,80-BF:0000-1FFF, 7E-7F:0000-FFFF) /ROMSEL - Cart ROM select (00-3F,80-BF:8000-FFFF, 40-7D,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 (used by SGB1 and MarioChip1) SYSCK - Unknown, is an output from the CPU. SOUND-L/R - Left/Right Analog Audio Input, mixed with APU output (SGB, MSU1) EXPAND - Connected to pin 24 of the EXT expansion port (for Satellaview) REFRESH - DRAM refresh (connects to WRAM, also used by SGB and SA-1) four HIGH pulses every 60us (every scanline) Used by SGB (maybe to sense SNES hblanks?) CIC0 - Lockout Data to CIC chip in console ;\from/to=initial direction CIC1 - Lockout Data from CIC chip in console ;/(on random-seed transfer) CIC2 - Lockout Start (short HIGH pulse when releasing reset button) CIC3 - Lockout Clock (3.072MHz) (24.576MHz/8 from APU) (or 4.00MHz) SHIELD - GND (connected in SA-1 carts, SGB-also has provisions) Physical Cartridge Shape Front Side _________________ _________________ .--'' ''--. .-----' '-----. / Japan NTSC and PAL \ | US NTSC | |___________________________| |_:":_____________________:":_| Rear Side SNES Chipset ------------ Chipset (PAL) Board: (C) 1992 Nintendo, SNSP-CPU-01 ;BOARD U1 100pin Nintendo, S-CPU A, 5A22-02, 2FF 7S ;CPU (ID=2 in 4210h) U2 100pin Nintendo, S-PPU1, 5C77-01, 2EU 64 ;PPU1 (ID=1 in 213Eh) U3 100pin Nintendo, S-PPU2 B, 5C78-03, 2EV 7G ;PPU2 (ID=3 in 213Fh) U4 28pin SONY JAPAN, CXK58257AM-12L, 227M87EY ;VRAM1 32Kx8 SRAM U5 28pin SONY JAPAN, CXK58257AM-12L, 227M87EY ;VRAM2 32Kx8 SRAM U6 64pin Nintendo, W-WRAM, 9227 T23 F ;WRAM U7 24pin S-ENC, Nintendo, S (for Sony) 9226 B ;video RGB to composite U8 18pin F413, (C) 1992, Nintendo, 9209 A ;CIC U9 - N/A (NTSC version only, type 74HCU04) ;hex inverter (for X1 & CIC) U10 14pin (M)224, AN1324S (equivalent to LM324) ;SND Quad Amplifier U11 3pin T529D, 267 ;GND,VCC,/RESET U12 3pin 17805, 2F2, SV, JAPAN ;5V U13 64pin Nintendo, S-SMP, SONY, Nintendo'89... ;SND1 (SPC700 CPU) U14 80pin Nintendo, S-DSP, SONY'89, WWW149D4X ;SND2 (sound chip) U15 28pin MCM51L832F12, (M) JAPAN RZZZZ9224 ;SND-RAM1 32Kx8 SRAM U16 28pin MCM51L832F12, (M) JAPAN RZZZZ9224 ;SND-RAM2 32Kx8 SRAM U17 16pin NEC, D6376, 9225CJ (ie. NEC uPD6376) ;SND-Dual 16bit D/A U18 14pin S-CLK, 2FS 4A (for PAL only) ;X1 to 21.2MHz and 4.43MHz TC1 2pin Red Trimmer ;X1-ADJUST X1 2pin D177F2 ;CPU/PPU 17.7344750MHz (PAL) X2 2pin CSA, 24.57MX, Gm J ;SND 24.576MHz F1 2pin SOC, 1.5A ;FUSE (supply-input) T1 4pin TDK, ZJYS-2, t ;DUAL-LOOP (supply-input) DB1 4pin TOSHIBA, 4B1, 1B 2-E JAPAN ;AC-DC (PAL/AC-version only) L1 2pin 220 (22uH) ;LOOP (color clock to GND) VR1 2pin (M)ZNR, FK220, 26 ;? (supply) J1? 2pin AC Input 9V ;AC-IN J2 4pin SNSP CCIR-EEC, A E210265, 250142A ;RF-Unit (modulator) SW 4pin Reset Button (on board) P1 64pin Cartridge Slot P2 11pin To Front Panel (Controllers/Power LED) P3 2pin To Power Switch P4 12pin Multi Out P5 28pin EXT Expansion Port (bottom side) Costdown SNES chipset U1 160pin Nintendo S-CPUN A, RF5A122 (CPU, PPU1, PPU2, S-CLK) U2 100pin Nintendo S-APU (S-SMP, S-DSP, 64Kx8 Sound RAM) U3 64pin Nintendo S-WRAM B U4 28pin 32Kx8 SRAM (video ram) U5 28pin 32Kx8 SRAM (video ram) U6? 8pin? ? U7 24pin Nintendo S-RGB A U8 18pin Nintendo F411B (CIC) U9 3pin 17805 (5V supply) U10 14pin S-MIX A (maybe sound amplifier?) U11 3pin Reset? X1 2pin D21G8N (21.4MHz NTSC, or 17.7MHz PAL) X2 2pin APU clock (probably the usual 24.576MHz?) 51832 Toshiba TC51832FL-12 32k x8 SRAM (SOP28) CXK58257AM-12L 32768-word x 8-bit high speed CMOS static RAM, 120ns, standby 2.5uW in 28-pin SOP package. Operational temperature range from 0'C to 70'C. SNES Pinouts CPU Chip --------------------- CPU 5A22 1 In VCC (supply) 2-17 Out A8..A23 18 In GND (supply) 19-26 I/O JOY-IO-0..7 (Port 4201h/4213h.Bit0..7) 27-31 In JOY-2 (4017h.Read.Bit0..4) (Pin 29-31 wired to GND) 32-33 In JOY-1 (4016h.Read.Bit0..1) 34 In "VCC" (unknown, this is NOT 4016h.Bit2) (wired to VCC) 35 Out JOY-1-CLK (strobed on 4016h.Read) 36 Out JOY-2-CLK (strobed on 4017h.Read) 37-39 Out JOY-OUT0..2 (4016h.Write.Bit0-2, OUT0=JOY-STROBE,OUT1-OUT2=UNUSED?) 40 Out REFRESH (DRAM refresh for WRAM, four HIGH pulses per scanline) 41-42 In TCKSEL0,TCKSEL1 (wired to GND) (purpose unknown) 43-44 In HBLANK,VBLANK (from PPU, for H/V-timers and V-Blank NMI) 45 In /NMI (wired to VCC) 46 In /IRQ (wired to Cartridge and Expansion Port) 47 In GND (supply) 48 In MCK ;21.47727 MHz master clock ;measured ca.21.666666MHz? low volts 49 In /DRAMMODE (wired to GND) (allows to disable DRAM refresh) 50 In /RESET 51-58 Out PA0..PA7 59 In VCC (supply) 60-67 I/O D0-D7 68 Out /PARD 69 Out /PAWR 70 Out /DMA (NC) HI 71 Out CPUCK (NC) LOOKS SAME AS PIN72 (MAYBE PHASE-SHIFTED?) 72 Out SYSCK (to WRAM and Cartridge) FAST CLK... TYPICALLY 2xHI, 1xLO 73 In TM (wired to GND) (purpose unknown) 74 In HVCMODE (wired to GND) (purpose unknown) 75 In HALT (wired to GND) (purpose unknown) (related to RDY?) 76 In /ABORT (wired to VCC) 77 Out /ROMSEL (access to 00-3F/80-BF:8000-FFFF or 40-7D/C0-FF:0000-FFFF) 78 Out /WRAMSEL (access to 00-3F/80-BF:0000-1FFF or 7E-7F:0000-FFFF) 79 In GND (supply) 80 Out R/W (NC) (ie. almost same as /WR, but with longer LOW-duty) 81 In RDY (wired to VCC) (schematic says "PE" or RE" or so?) 82 Out /ML (NC) (memory lock,low on read-modify,ie.inc/dec/shift/etc) 83 Out MF (NC) (CPU's M-Flag, 8bit/16bit mode) 84 Out XF (NC) (CPU's X-Flag, 8bit/16bit mode) 85 In VCC (supply) 86 Out VFB or VPB or so (NC) RAPID PULSED 87 Out VFA or VPA or so (NC) RAPID PULSED 88 Out ALCK LOOKS LIKE INVERSE OF PIN71 or PIN72 89 Out /VP (NC) (vector pull, low when executing exception vector) 90 In GND 91 Out /WR (low on any memory write, including io-writes to 21xxh/4xxxh) 92 Out /RD 93-100 Out A0..A7 The three VCC pins are interconnected inside of the chip (verified). The various GND pins are not verified (some may be supply, or inputs). SNES Pinouts PPU Chips ---------------------- S-PPU1, 5C77 1 ? TST1 (GND) 2 ? TST0 (GND) 3 CPU /PARD 4 CPU /PAWR 5-12 CPU PA7-PA0 (main cpu b-bus) 13 Supply VCC 14-21 CPU D7-D0 (main cpu) 22 Supply GND 23 ? HVCMODE (GND) 24 Mode PALMODE (VCC=PAL or GND=NTSC) 25 ? /MASTER (GND) 26 ? /EXTSYNC (VCC) 27 ? NC (GND) 28-35 SRAM DH0-DH7 (sram data bus high-bytes) 36 Supply VCC 37-44 SRAM DL0-DL7 (sram data bus low-bytes) 45 Supply GND 46 SRAM VA15 (NC) (would be for 64K-word RAM, SNES has only 32K-words) 47 SRAM VA14 (sram address bus for upper/lower 8bit data) 48-61 SRAM VAB13-VAB0 (sram address bus for upper 8bit data) 62 Supply VCC 63-76 VRAM VAA13-VAA0 (sram address bus for lower 8bit data) 77 Supply GND 78 VRAM /VAWR (sram write lower 8bit data) 79 VRAM /VBWR (sram write upper 8bit data) 80 VRAM /VRD (sram read 16bit data) 81 Supply VCC 82-85 PPU CHR3-CHR0 ;\ 86-87 PPU PRIO1-PRIO0 ; 88-90 PPU COLOR2-COLOR0 ;/ 91 /VCLD (20ms high, 60us low) (LOW during V=0) 92 /HCLD (60us high, 0.2us low) (low during 11th dot-cycle of the 15-cycle color burst) 93 /5MOUT (shortcut with pin 97, /5MIN) (and to PPU2, /5MIN) 8 clks = 7.5*0.2us = 5.333MHz 94 /OVEP (always high?) (to PPU2 /OVER1 and /OVER2) 95 FIELD (NTSC: 30Hz, PAL: 25Hz) (signalizes even/odd frame) 96 Supply GND 97 /5MIN (shortcut with pin 93, /5MOUT) (as above 5mout) 98 PPU /RESET (from PPU2 /RESOUT0) 99 ? TST2 (GND) 100 System XIN (21MHz) S-PPU2, 5C78 1 Video /BURST (LOW for 15 dot-clocks, thereof 1st dot is LONG) 2 ? /PED (NC) (ca. 15kHz, hblank related, 50us high, 10us low) 3 Video 3.58M (to NTSC encoder) 5 clks = 1.4us 4 ? /TOUMEI (NC) (LOW during V-Blank and H-Blank) (or vram access?) 5 Supply VCC 6 CPU /PAWR 7 CPU /PARD 8-15 CPU D7-D0 16 Supply GND 17-24 CPU PA7-PA0 25 CPU HBLANK (for CPU h/v-timers) high during last some pixels, right border HSYNC,lead,burst low during last some burst clks, left border, and most pixels 26 CPU VBLANK (for CPU h/v-timers) high during VBLANK (line 225-261) low during prepare (line 0) and picture (line 1-224) 27 /5MOUT (via 100 ohm to DOTCK on Expansion Port Pin22) 28 System /RESOUT1 (via 1K to CPU, APU, Cartridge, Expansion, etc.) 29 Joy EXTLATCH (Lightpen signal) 30 Mode PALMODE (VCC=PAL or GND=NTSC) 31 System XIN (21MHz) 32 Supply VCC 33 PPU /RESOUT0 (to PPU1 /RESET) 34 CIC /RESET (from CIC Lockout chip & Reset Button) 35 Supply GND 36 FIELD (NTSC: 30Hz, PAL: 25Hz) (signalizes even/odd frame) 37 /OVER1 ?? 38 /5MIN (from PPU1) 39 /HCLD (low during 11th dot-cycle of the 15-cycle color burst) 40 /VCLD (LOW during V=0) 41-43 PPU OBJ0-OBJ2 (COLOR0-COLOR2) 44-45 PPU OBJ3-OBJ4 (PRIO0-PRIO1) 46-49 PPU OBJ5-OBJ8 (CHR0-CHR3) 50 /OVER2 51-58 SRAM VDB0-VDB7 (sram data upper 8bit) 59 Supply VCC 60-67 SRAM VDA0-VDA7 (sram data lower 8bit) 68 Supply GND 69-76 SRAM EXT0-EXT7 (sram data upper 8bit) (shortcut with VDB0-VDB7) 77-82 ? TST0-TST5 (NC) (always low?) 83 Supply VCC 84-89 ? TST6-TST11 (NC) (always low?) 90-93 ? TST12-TST15 (GND) 94 Supply AVCC (VCC) 95-97 Video R,G,B (Analog RGB Output) 98 ? HVCMODE (GND) 99 Supply GND 100 Video /CSYNC (normally LOW during Hsync, but inverted during Vsync) CPUN-A (160pin chip with CPU and PPU1 and PPU2 in one chip) Used in newer cost-down SNES consoles. Pinouts unknown. SNES Pinouts APU Chips ---------------------- S-DSP Pinouts (Sound Chip) 1 CK DKD (NC) (5 clks = 1.2us) 4.096MHz (24.576MHz/6) 2 CK MXK or MYX or so (NC) (5 clks = 1.6us) 3.072MHz (24.576MHz/8) 3-5 CK MX1-MX3 (NC) 1.024MHz (24.576MHz/24) (3pins: phase/duty shifted) 6-8 SRAM MD2-MD0 (SRAM Data) 9-11 SRAM MA0-MA2 (SRAM Address) 12 Supply GND 13-19 SRAM MA3-MA7,MA12,MA14 (SRAM Address) 20 SRAM MA15 (NC) (instead, upper/lower 32K selected via /CE1 and /CE0) 21 ? DIP (NC) (always high?) 22-32 SRAM MD3,MD4,MD5,MD6,MD7,/CE1,/CE0,MA10,/OE,MA11,MA9 33 Supply VCC 34-36 SRAM MA8,MA13,/WE 37 ? TF (GND) ;\wiring TF and/or TK to VCC crashes the SPC700 38 ? TK (GND) ;/(ie. they seem to mess up CPUK clock or SRAM bus) 39 Audio /MUTE (to/after amplifier) 40 CK MCK (NC) 64000Hz (24.576MHz/24/16) 41 CIC SCLK 3.072MHz (24.576MHz/8) (via inverters to "CIC" chips) 42 Audio BCK 1.536MHz (24.576/16) BitClk ;\to uPD6376 43 Audio LRCK 32000Hz (24.576MHz/16/48) StereoClk ; D/A converter 44 Audio DATA Data Bits (8xZeroPadding+16xData) ;/ 45-46 Osc XTAO,XTAI (24.576MHz) 47 System /RESET 48 SPC700 CPUK 2.048MHz (24.576MHz/12) (to S-SMP) 49 SPC700 PD2 (on boot: always high?) 50 SPC700 PD3 (on boot: always low?) 51 SPC700 D0 52 Supply GND 53-59 SPC700 D1-D7 60-72 SPC700 A0-A12 73 Supply VCC 74-76 SPC700 A13-A15 77 CK XCK 24.576MHz (24.576MHz/1) (NC) 78 Exp. DCK 8.192MHz (24.576MHz/3) (to Expansion Port Pin 21, SMPCLK) 79 CK CK1 12.288MHz (24.576MHz/2) (NC) 80 CK CK2 6.144MHz (24.576MHz/4) (NC) S-SMP Pinouts (SPC700 CPU) 1-5 DSP A4..A0 Address Bus 6-13 DSP D7..D0 Data Bus 14 DSP PD3 (maybe R/W signal or RAM/DSP select?) 15 DSP PD2 (maybe R/W signal or RAM/DSP select?) 16 DSP CPUK (2.048MHz from DSP chip) 17 AUX /P5RD (NC) 18-25 AUX P57..P50 (NC) 26 Supply GND 27-34 AUX P47..P40 (NC) 35 ? T1 (NC or wired to VCC) (maybe test or timer?) 36 ? T0 (NC or wired to VCC) (maybe test or timer?) 37 System /RESET 38-45 CPU D7..D0 Data Bus 46-51 CPU /PARD,/PAWR,PA1,PA0,PA6 (aka CS), PA7 (aka /CS) B-Address Bus 52-56 DSP A15-A11 Address Bus 57 Supply VCC (5V) 58 Supply GND 59-64 DSP A10-A5 Address Bus Pin 1-16 and 52-64 to S-DSP chip, Pin 17-34 Aux (not connected), Pin35-36 are NC on real hardware (but are wired to VCC in schematic), pin 37-51 to main CPU. CPUK caution: scope measure with "x10" ref (gives the correct signal): -_-_-_-_-_-_-_-_ 2.048MHz (0.5us per cycle) during (and AFTER) "x1" ref (this seems to "crash" the clock generator): ---_---_---_---_ 1.024MHz (1.0us per cycle) (with triple-high duty) S-APU Pinouts (S-SMP, S-DSP, 64Kx8 Sound RAM) This 100pin chip is used in newer cost-down SNES consoles. 1-100 Unknown It combines the S-SMP, S-DSP, and the two 32Kx8 SRAMs in one chip. And, possibly also the NEC uPD6376 D/A converter? SNES Pinouts ROM Chips ---------------------- Standard SNES ROMs EPROM-style ROMs __________ __________ GND | 01 \_/ 40 | VCC GND | 02 ...... .......39 | VCC ________ ________ --> A20 | 03 01 \./ 36 38 | VCC ? | 01 \_/ 36 | VCC GND,A21 | 04 02 ... ... 35 37 | A22,GND <-- ? | 02 .... .... 35 | ? --> A17 | 05 03 01 \./ 32 34 36 | NC,VCC <-- NC | 03 01 \./ 32 34 | VCC --> A18 | 06 04 02 31 33 35 | /CS <-- A16 | 04 02 31 33 | NC A15 | 07 05 03 30 32 34 | A19 <-- A15 | 05 03 30 32 | A17 A12 | 08 06 04 29 31 33 | A14 A12 | 06 04 29 31 | A14 A7 | 09 07 05 ROM 28 30 32 | A13 A7 | 07 05 EPROM 28 30 | A13 A6 | 10 08 06 27 29 31 | A8 A6 | 08 06 style 27 29 | A8 A5 | 11 09 07 26 28 30 | A9 A5 | 09 07 (eg. 26 28 | A9 A4 | 12 10 08 25 27 29 | A11 A4 | 10 08 in 25 27 | A11 A3 | 13 11 09 24 26 28 | A16 <-- A3 | 11 09 SGB) 24 26 | /OE A2 | 14 12 10 23 25 27 | A10 A2 | 12 10 23 25 | A10 A1 | 15 13 11 22 24 26 | /RD A1 | 13 11 22 24 | /CS A0 | 16 14 12 21 23 25 | D7 A0 | 14 12 21 23 | D7 D0 | 17 15 13 20 22 24 | D6 D0 | 15 13 20 22 | D6 D1 | 18 16 14 19 21 23 | D5 D1 | 16 14 19 21 | D5 D2 | 19 17 15 18 20 22 | D4 D2 | 17 15 18 20 | D4 GND | 20 18 16 17 19 21 | D3 GND | 18 16 17 19 | D3 |_______________________| |___________________| Note that Standard SNES ROMs have /CS and A16..A22 located elsewhere as on normal EPROMs. Most common SNES ROMs are 32pin or 36pin (the 40pin ROMs are used by some SPC7110 games; these chips are using a bigger package, though without actually having more address lines). Most SNES carts are using DIP chips (smaller SMD ROMs are used only in carts that contain SMD coprocessors). Mind that SNES "LoROM" cartridges are leaving SNES.A15 unused (and do instead connect "ROM.A15 and up" to "SNES.A16 and up"). 44pin ROMs _____ _____ /WE A22 | 1 \_/ 44 | A21 /WP A19 | 2 43 | A20 A18 | 3 42 | A9 A8 | 4 41 | A10 A7 | 5 40 | A11 A6 | 6 39 | A12 A5 | 7 38 | A13 A4 | 8 37 | A14 A3 | 9 36 | A15 A2 | 10 35 | A16 A1 | 11 34 | A17 /CE | 12 33 | BHE (HI) GND | 13 32 | GND /OE | 14 31 | D15,A0 D0 | 15 30 | D7 D8 | 16 29 | D14 D1 | 17 28 | D6 D9 | 18 27 | D13 D2 | 19 26 | D5 D10 | 20 25 | D12 D3 | 21 24 | D4 D11 | 22 23 | VCC |_____________| 44pin ROMs are used by (some) SPC7110 boards (with 8bit databus), and by (all) S-DD1 and SA-1 boards (existing photos look as if: with 16bit databus). 44pin FLASH is used in Nintendo Power carts (with 8bit databus) (with /WE and /WP instead of A22 and A21). SNES Pinouts RAM Chips ---------------------- 128K WRAM Pinouts 1 VCC 9 - 17 GND 25 A1 33 GND 41 A8 49 VCC 57 /RD 2 D4 10 CS,VCC 18 - 26 A10 34 A13 42 ENA,A22 50 PS,PA7 58 /PAWR 3 D5 11 CS,VCC 19 - 27 A2 35 A5 43 /PS,PA2 51 PS,VCC 59 /WR 4 D6 12 CS,VCC 20 - 28 A11 36 A14 44 /PS,PA3 52 PS,VCC 60 D0 5 D7 13 /CS,GND 21 - 29 A3 37 A6 45 /PS,PA4 53 PA0 61 D1 6 SYSCK 14 /CS,GND 22 - 30 A12 38 A15 46 /PS,PA5 54 PA1 62 D2 7 REFRESH 15 /CS,/WRAMSEL 23 A0 31 A4 39 A7 47 /PS,PA6 55 G (NC) 63 D3 8 /RESET 16 VCC 24 A9 32 VCC 40 A16 48 GND 56 /PARD 64 GND Note: The WRAM is Dynamic RAM (DRAM) and does require REFRESH pulses. If REFRESH is disabled (via DRAMMODE pin) then WRAM forgets its content after some minutes. Whereas, refresh occurs also on /RD (with the refresh row output on A0..A8), so, for example, games that are DMA'ing 512 bytes from WRAM to OAM in every frame should work perfectly without REFRESH. Interestingly, WRAM is kept intact even if the RESET button is held down for about 30 minutes (although the CPU doesn't generate any /RD, REFRESH, nor A0..A8 cycles during that time). SRAM Pinouts .-------------__-------------. NC |1 36| VCC A20 |2 ..........__.......... 35| A19 NC,A18 |3 1 32 34| NC,VCC (NC, ie. not CE2) A16 |4 2 .......__....... 31 33| A15 NC,A14 |5 3 1 28 30 32| A17,CE2,VCC A12 |6 4 2 ....__.... 27 29 31| /WE A7 |7 5 3 1 24 26 28 30| A13,CE2,VCC A6 |8 6 4 2 23 25 27 29| A8 A5 |9 7 5 3 22 24 26 28| A9 A4 |10 8 6 4 SRAM 21 23 25 27| A11,/WE A3 |11 9 7 5 20 22 24 26| /OE A2 |12 10 8 6 19 21 23 25| A10 A1 |13 11 9 7 18 20 22 24| /CE,/CE1 A0 |14 12 10 8 17 19 21 23| D7 D0 |15 13 11 9 16 18 20 22| D6 D1 |16 14 12 10 15 17 19 21| D5 D2 |17 15 13 11 14 16 18 20| D4 GND |18 16 14 12 13 15 17 19| D3 '----------------------------' 28pin 32Kbyte SRAM is used for Video RAM and Sound RAM (on mainboard) Various SRAM sizes are used in game cartridges. SNES Pinouts CIC Chips ---------------------- CIC Pinouts F411/F413: 18pin SMD-chip (used in console and in some carts) D411/D413: 16pin DIP-chip (used in most carts) SMD DIP Pin Dir Usage In Console In Cartridge 1 1 P00 Out DTA0 Cart.55 CIC1 Cart.24 CIC0 2 2 P01 In DTA1 Cart.24 CIC0 Cart.55 CIC1 3 3 P02 In RANDOM Via capacitor to VCC NC 4 4 P03 In MODE VCC=Console (Lock) GND=Cartridge (Key) 5 NC - (NC) NC NC 6 5 CL2 - (NC) NC SMD:NC or DIP:GND 7 6 CL1 In CLK 3.072MHz (from APU) Cart.56 CIC3 (3.072MHz) 8 7 RES In RESET From Reset button Cart.25 CIC2 (START) 9 8 GND - GND Supply Supply 10 9 P10 Out /RESET To PPU (and CPU/APU/etc) NC (or to ROM, eg. in SGB) 11 10 P11 Out START Cart.25 CIC2 NC 12 11 P12 - (NC) NC NC (or SlotID in FamicomBox) 13 12 P13 - (NC) NC NC (or SlotID in FamicomBox) 14 NC - (NC) NC NC 15 13 P20 - (NC) NC NC 16 14 P21 - (NC) NC NC (or SlotID in FamicomBox) 17 15 P22 - (NC) NC NC (or SlotID in FamicomBox) 18 16 VCC - VCC Supply Supply P00=Out,P01=In are the initial directions (for the Random Seed transfer), later on the directions are randomly swapped (ie. P00=In,P01=Out or P00=Out,P01=In). START: short HIGH pulse on power-up or when releasing reset button. /RESET: in console: to PPU, and from there to CPU,APU,Cart,Expansion. SNES Pinouts MAD Chips ---------------------- MAD-1 (and MAD-1 A) Pinouts (Memory Address Decoder 1) 1 OUT1 /ROM.CS1 ;Chipselect to Upper ROM (NC if single ROM) 2 OUT2 /SRAM.CS ;Chipselect to SRAM 3 OUT3 /AUX.CS ;Chipselect to Expansion I/O or so (usually NC) 4 OUT4 /ROM.CS ;Chipselect to Single ROM (NC if two ROMs) 5 Vout ;Supply to SRAM (+3V when VCC=off, +5V when VCC=on) 6 VCC ;Supply from SNES (+5V) 7 Vbat ;Supply from Battery via resistor (+3V) 8 GND ;Supply Ground 9 IN6 /RESET ;From cart.26 10 IN5 MODE ;HiROM: VCC | LoROM: GND 11 IN4 /ROMSEL ;From cart.49 12 IN3 Addr3 ;HiROM: A22 (400000h) or A15 | LoROM: A22 (400000h) or VCC 13 IN2 Addr2 ;HiROM: A21 (200000h) | LoROM: A21 (200000h) 14 IN1 Addr1 ;HiROM: A14 (4000h) | LoROM: A20 (100000h) 15 IN0 Addr0 ;HiROM: A13 (2000h) | LoROM: A15 (8000h) 16 OUT0 /ROM.CS0 ;Chipselect to Lower ROM (NC if single ROM) Note that Addr3 is sometimes wired this or that way. And, when using two ROMs, Addr2 is used as upper ROM address line (eg. Addr2=A20 for a cart with two 1Mbyte ROM chips) (so the ROM-size may also affect the SRAM/AUX mapping; according to the Addr2 wiring). MAD-1 (and MAD-1 A) Logic Table IN0 IN1 IN2 IN3 IN4 IN5 IN6 --> Output being Addr0 Addr1 Addr2 Addr3 /ROM MODE /RES dragged LOW ----------------------------------------------------------- HIGH x x x LOW LOW HIGH --> /ROM.CS=LOW ;\ HIGH x LOW x LOW LOW HIGH --> /ROM.CS0=LOW ; HIGH x HIGH x LOW LOW HIGH --> /ROM.CS1=LOW ; LoROM LOW LOW HIGH HIGH LOW LOW HIGH --> /AUX.CS=LOW ; LOW HIGH HIGH HIGH LOW LOW HIGH --> /SRAM.CS=LOW ;/ x x x x LOW HIGH HIGH --> /ROM.CS=LOW ;\ x x LOW x LOW HIGH HIGH --> /ROM.CS0=LOW ; x x HIGH x LOW HIGH HIGH --> /ROM.CS1=LOW ; HiROM HIGH HIGH LOW LOW HIGH HIGH HIGH --> /AUX.CS=LOW ; HIGH HIGH HIGH LOW HIGH HIGH HIGH --> /SRAM.CS=LOW ;/ MAD-2 Pinouts (Memory Address Decoder 2) Unknown. Used in some newer DSPn cartridges (mainly/only DSP1B ones?) (probably similar to MAD-1, but maybe with some pins replaced by a clock amplifier for the DSPn oscillator... and/or maybe it supplies an inverted RESET signal to the DSPn chip). MAD-R Pinouts (Memory Address Decoder with Reset-Inverter) Pinouts are same as MAD-1, except for one pin: Pin4 outputs RESET (inverse of /RESET input) (there aren't any known cartridges using this feature). The SHVC-2A3M-01, SHVC-2A3M-10, SHVC-2J3M-01 boards can be fitted with either MAD-1 or MAD-R (later SHVC-2A3M-11, SHVC-2J3M-11, SHVC-2J3M-20 boards are used with MAD-1 only, so MAD-R appears to have been discontinued after soon). XXX The following boards do (also) accept either MAD-1 or MAD-R: 2A1M-01 2A5M-01 2J5M-01 MAD-R Logic Table IN0 IN1 IN2 IN3 IN4 IN5 IN6 --> Output being Addr0 Addr1 Addr2 Addr3 /ROM MODE /RES dragged LOW ----------------------------------------------------------- x x x x x x HIGH --> RESET=LOW * ;-Reset x x LOW LOW LOW LOW HIGH --> /ROM.CS0=LOW * ;\ x x HIGH LOW LOW LOW HIGH --> /ROM.CS1=LOW * ; LoROM x x LOW HIGH LOW LOW HIGH --> /AUX.CS=LOW * ; LOW HIGH HIGH HIGH LOW LOW HIGH --> /SRAM.CS=LOW ;/ x x LOW x LOW HIGH HIGH --> /ROM.CS0=LOW ;\ x x HIGH x LOW HIGH HIGH --> /ROM.CS1=LOW ; HiROM HIGH HIGH LOW LOW HIGH HIGH HIGH --> /AUX.CS=LOW ; HIGH HIGH HIGH LOW HIGH HIGH HIGH --> /SRAM.CS=LOW ;/ The four "*" marked lines are different as MAD-1. Other Battery Controllers Battery Controllers are used to write-protect the SRAM during power-up/power-down, and to switch from Vbat to VCC supply when available. Early carts used a transistor/diode circuit, later carts are using MAD-1/MAD-2/MAD-R or MM1026/MM1134 chips. MM1026/MM1134 Pinouts 1 GND 2 /RESET (output) 3 CS (to SRAM) (usually NC when using /CS) 4 Vbat (from battery) 5 /CS (to SRAM) 6 Vout (to SRAM) 7 NC (MM1026) or /Y (MM1134) (aka /CS input) 8 VCC (from snes) On MM1026, /CS is simply inverse of CS (both true when VCC=good). On MM1134, the additional /Y input allows to force /CS false (but doesn't affect CS). On SA-1 "SNSP-1L3B-20" boards, the PCB text layer says MM1026AF, but the actual chip is labelled "6129A, 6C33"; which refers to a "BA6129A" chip. Batteries CR2032 (3 volt lithium cells, 20mm diameter, 3.2mm width) <-- most SNES carts CR2430 (3 volt lithium cells, 24.5mm diameter, 3mm width) <-- X-Band Modem NiCd (3.6V, rechargeable, but acid-leaking) <-- many Copiers MAD Versions/Revisions & Power Down Notes BU2230 MAD-1 XLU2230 MAD-1 BU2230A MAD-1A BU2231A MAD-2A BU2220 MAD-R TexasInstruments MAD-1 At VCC>Vbat, the chips do operate normally (as shown in above Logic Tables). At VCC=Vbat, the BU2230,BU2230A,XLU2230 (MAD1/MAD1A) force /SRAM.CS=high, whilst TexasInstrument (MAD1) and BU2220 (MAD-R) keep /SRAM.CS operating as normally. At VCC=0, the BU2230,BU2230A,XLU2230 (MAD1/MAD1A) chips and BU2220 (MAD-R) switch the other 4 outputs to LOW, whilst TexasInstrument (MAD1) switch them HIGH (or maybe they are left floating and get pulled high by the test circuit). SNES Pinouts RTC Chips ---------------------- Sharp S-RTC Pin-Outs (used by Dai Kaiju Monogatari 2) 1-24 Unknown (should have an address decoder and 4bit data bus or so) 24pin chip. Still unknown which & how many address/data lines are connected, and if there are "specials" like /IRQs (?) Epson/Seiko RTC-4513 Pin-Outs (for Far East of Eden Zero) (via SPC7110 chip) 1 NC 2 DATA 3 STD.P 4 NC 5 NC 6 VCC 7 NC 8 NC 9 GND 10 NC 11 NC 12 CE 13 CLK 14 NC Seiko/Epson S-3520CF Pin-Outs (used in SFC-Box and NSS) 1 Xin 2 NC 3 Xout 4 /CLK 5 DataIn 6 /WR 7 GND 8 /TPOUT 9 DataOut 10 PDW 11 /CS 12 Capacitor 13 NC 14 VCC Crystal = 32.768kHz (see datasheet page 13) SNES Pinouts Misc Chips ----------------------- S-ENC Pin-Outs 1 (R-Y)O 5 VCC 9 YI 13 VC (clk) 17 PHA (NC) 21 AG (Green) 2 GND 6 CO 10 (B-Y)I 14 VB (clk) 18 PDO (NC) 22 AB (Blue) 3 PCP,/BURST 7 VO 11 (R-Y)I 15 VA (NC) 19 NTSC/PAL 23 YO 4 SW (VCC) 8 SYNC 12 BLA 16 BFP,/BURST 20 AR (Red) 24 (B-Y)O Analog RGB to composite converter. Pin19 allows to select PAL or NTSC mode (also requires the correct PAL or NTSC clock input on Pin13,14). The "S-RGB A" has reportedly other pinouts: 1 ? 5 ? 9 ? 13 ? 17 Y (luma) 21 ? 2 ? 6 ? 10 ? 14 ? 18 ? 22 Green 3 ? 7 CSYNC 11 ? 15 ? 19 ? 23 ? 4 ? 8 ? 12 C (chroma) 16 ? 20 Red 24 Blue S-CLK Pin-Outs (PAL only) 1 17.7MHz(X1.A) 4 21.28MHz(MCK) 7 3.072MHz(Cart) 10 GND 13 Low 2 17.7MHz(X1.B) 5 4.433MHz(PAL) 8 3.072MHz(APU) 11 Low 14 VCC 3 VCC 6 3.072MHz(CIC) 9 3.072MHz(APU) 12 Low Clock multiplier/divider for PAL consolses (none such in NTSC consoles). Pin6-9 are two inverters (for APU-generated CIC clock) (NTSC consoles have equivalent inverters in a 74HCU04 chip). NEC uPD6376 (two-channel serial 16bit D/A Converter) 1 DSSEL (GND) 5 AGND (NC) 9 RREF 13 LRCK (32000Hz) 2 DGND (GND) 6 ROUT 10 LREF 14 LRSEL (GND) 3 NC (VCC) 7 AVDD (VCC) 11 LOUT 15 SI (DATA) 4 DVDD (VCC) 8 AVDD (VCC) 12 AGND (GND) 16 CLK (1.536MHz) DATA changes on falling CLK and is valid on raising CLK, falling LRCK indicates that the most recent 16 bits were LEFT data, raising LRCK indicates RIGHT data. Each 16bit sample is preceeded by 8 dummy bits (which are always zero). The 16bit values are signed without BIAS offset (0000h=silence). _ _ _ _ _ _ _ _ _ _ _ _ _ CLK | |_| |_| |_| |_| |_| |_ _| |_| |_| |_| |_| |_| |_| |_ Pin 16 __________:_____________ .. __________________: LRCK :MSB <--- LEFT SAMPLE --> LSB|_________ Pin 13 :___ ___ ___ _ __ ___ ___ ___ ___: DATA __________/___X___X___X_ .. __X___X___X___X___\_________ Pin 15 :b15 b14 b13 b3 b2 b1 b0 : If the MUTE bit is set in FLG.6, then DATA is always 0, and additionally /MUTE=LOW is output to the Amplifier (so the DSP is "double-muted", and, the /MUTE signal also mutes external sound inputs like from SGB). S-MIX Pin-Outs Unknown. This chip is found on some cost-down SNES mainboards. Maybe a sound amplifier. LM324 Quad Amplifier 1 LeftPostOut 8 LeftPreOut 2 LeftPostIn- 9 LeftPreIn- 3 LeftPostIn+ 10 LeftPreIn+ 4 VS (not VCC) 11 GND 5 RightPostIn+ 12 RightPreIn+ 6 RightPostIn- 13 RightPreIn- 7 RightPostOut 14 RightPreOut The Pre-amplifiers do amplify the signal from the D/A converter. The pre-amplified signal is then mixed (via resisters and capacitors) with the other two audio sources (from cartridge and expansion port), the result is then passed through the Post-amplifier stage, eventually muted via transistors (if DSP outputs /MUTE=Low), and amplified through further transistors. The final stereo signal is output to A/V connector, and mono signals are mixed (via resistors) for Expansion Port and TV Modulator). The LM324 chip and the transistors are using the VS supply, rather than normal 5V VCC. SNES Pinouts GSU Chips ---------------------- GSU Chip Packages 100 81 112 85 111 86 .----------. .------------. .------------. 1 /O |80 1| O |84 112| O |85 | MC1 | | | 1| | | GSU1 | | GSU2 | | GSU2-SP1 | | GSU1A | | | | | 30| |51 28| |57 29| |56 '------------' '------------' '------------' 31 50 29 56 30 55 GSU2-SP1 is having odd pin numbering (with pin1 being the SECOND pin; which was apparently done to maintain same pin numbers as for GSU2). MC1, GSU1, and GSU1A 1 GND 2 ROM.A18 3 ROM.A17 4 ROM.A16 5 ROM.A15 6 ROM.A14 7 ROM.A13 8 ROM.A12 9 ROM.A11 10 ROM.A10 11 ROM.A9 12 ROM.A8 13 ROM.A7 14 ROM.A6 15 ROM.A5 16 ROM.A4 17 ROM.A3 18 ROM.A2 19 ROM.A1 20 ROM.A0 21 ROM.D7 22 ROM.D6 23 ROM.D5 24 ROM.D4 25 ROM.D3 26 ROM.D2 27 GND 28 ROM.D1 29 ROM.D0 30 VCC -- 31 ? 32 /WR 33 /RD 34 /RESET 35 D7 36 D6 37 D5 38 D4 39 D3 40 GND ;\swapped on GSU2 41 VCC ;/ 42 D2 43 D1 44 D0 45 A22 46 A21 47 A20 48 A19 49 A18 50 A17 -- 51 A16 52 A15 53 A14 54 A13 55 A12 56 /IRQ 57 A0 58 A1 59 A2 60 A3 61 A4 62 A5 63 A6 64 A7 65 A8 66 A9 67 A10 68 A11 69 GND 70 X1 (21.44MHz ?) 71 SRAM.D0 72 SRAM.D1 73 SRAM.D2 74 SRAM.D3 75 SRAM.D4 76 SRAM.D5 77 SRAM.D6 78 SRAM.D7 79 SRAM.A0 80 SRAM.A1 -- 81 SRAM.A2 82 SRAM.A3 83 SRAM.A4 84 SRAM.A5 85 SRAM.A6 86 SRAM.A7 87 SRAM.A8 88 SRAM.A9 89 VCC 90 GND 91 SRAM.A10 92 SRAM.A11 93 SRAM.A12 94 SRAM.A13 95 SRAM.A14 96 GND 97 SRAM.A15 98 SRAM./OE 99 SRAM./WE 100 ROM.A19 GSU2, and GSU2-SP1 1 ROM.A17 2 ROM.A16 3 ROM.A15 4 ROM.A14 5 ROM.A13 6 ROM.A12 7 ROM.A11 8 ROM.A10 9 ROM.A9 10 ROM.A8 11 ROM.A7 12 ROM.A6 13 ROM.A5 14 VCC 15 ROM.A4 16 ROM.A3 17 ROM.A2 18 ROM.A1 19 ROM.A0 20 ROM./CE 21 ? (NC, probably /CE for 2nd ROM chip) 22 ROM.D7 23 ROM.D6 24 ROM.D5 25 ROM.D4 26 ROM.D3 27 ROM.D2 28 GND? -- 29 ROM.D1 30 ROM.D0 31 ? 32 ? 33 /WR 34 /RD 35 /RESET 36 GND? 37 D7 38 D6 39 D5 40 D4 41 D3 42 VCC 43 GND 44 D2 45 D1 46 D0 47 A23 48 A22 49 A21 50 A20 51 A19 52 A18 53 A17 54 A16 55 A15 56 A14 -- 57 A13 58 A12 59 /IRQ 60 A0 61 A1 62 A2 63 A3 64 A4 65 GND? 66 A5 67 A6 68 A7 69 A8 70 VCC 71 A9 72 A10 73 A11 74 GND 75 X1 (21.44MHz) 76 VCC 77 SRAM.D0 78 SRAM.D1 79 SRAM.D2 80 SRAM.D3 81 SRAM.D4 82 SRAM.D5 83 SRAM.D6 84 SRAM.D7 -- 85 SRAM.A0 86 SRAM.A1 87 SRAM.A2 88 SRAM.A3 89 SRAM.A4 90 SRAM.A5 91 SRAM.A6 92 SRAM.A7 93 SRAM.A8 94 SRAM.A9 95 NC? 96 NC? 97 VCC 98 VCC 99 GND 100 SRAM.A10 101 SRAM.A11 102 SRAM.A12 103 SRAM.A13 104 SRAM.A14 105 NC/SRAM.A15 106 NC/SRAM.A16 107 SRAM./OE 108 SRAM./WE 109 ROM.A20 110 ROM.A19 111 GND 112 ROM.A18 SNES Pinouts CX4 Chip --------------------- Capcom CX4 (used in Mega Man X2/X3) 1 A3 21 A15 41 RA8 61 /IRQ 2 A4 22 A14 42 RA7 62 D7 3 A5 23 A13 43 RA6 63 D6 4 A6 24 A12 44 RA5 64 D5 5 A7 25 /SRAM 45 RA4 65 D4 6 A8 26 /ROM2 46 RA3 66 Vcc 7 A9 27 /ROM1 47 RA2 67 D3 8 A10 28 RA19 48 RA1 68 D2 9 A11 29 RA18 49 RA0 69 D1 10 GND 30 RA17 50 GND 70 D0 11 XIN 31 Vcc 51 /RWE 71 Vcc 12 XOUT 32 RA16 52 /ROE 72 /RST 13 A23 33 RA15 53 RD7 73 GND 14 A22 34 RA20 54 RD6 74 GNDed 15 A21 35 RA14 55 RD5 75 GNDed 16 A20 36 RA13 56 RD4 76 /RD 17 A19 37 RA12 57 RD3 77 /WR 18 A18 38 RA11 58 RD2 78 A0 19 A17 39 RA10 59 RD1 79 A1 20 A16 40 RA9 60 RD0 80 A2 SNES bus (cartridge slot) connects to Pin 1-24 and 61-80, CX4 bus (ROM/SRAM) to pin 25-60. Pin 74 and 75 are GNDed (but not interconnected to GND inside of the chip); of these, Pin 75 can be reconfigured on some PCBs (via CL and R4 options); maybe one of the pins is for HiROM mapping. SNES Pinouts SA1 Chip --------------------- SA-1 1 SNES./IRQ 2 SNES.D7 3 SNES.D3 4 SNES.D6 5 SNES.D2 6 SNES.D5 7 SNES.D1 8 SNES.D4 9 SNES.D0 10 VCC 11 GND 12 SNES.A23 13 SNES.A0 14 SNES.A22 15 SNES.A1 16 SNES.A21 17 SNES.A2 18 SNES.A20 19 SNES.A3 20 SNES.A19 21 SNES.A4 22 SNES.A18 23 SNES.A5 24 SNES.A17 25 SNES.A6 26 SNES.A16 27 SNES.A7 28 SNES.A15 29 SNES.A8 30 SNES.A14 31 SNES.A9 32 SNES.A13 33 SNES.A10 34 SNES.A12 35 SNES.A11 36 VCC 37 GND 38 REFRESH --- 39 GND 40 X.? MasterClock (21.477MHz) 41 X.? MasterClock (21.477MHz) 42 GND 43 ROM.D15 pin31 (D15/A0) 44 ROM.D7 pin30 45 ROM.D14 pin29 46 ROM.D6 pin28 47 ROM.D11 pin22 48 ROM.D3 pin21 49 ROM.D10 pin20 50 ROM.D2 pin19 51 ROM.D13 pin27 52 ROM.D5 pin26 53 ROM.D12 pin25 54 ROM.D4 pin24 55 ROM.D9 pin18 56 ROM.D1 pin17 57 ROM.D8 pin16 58 ROM.D0 pin15 59 ROM.A1 pin11 60 ROM.A2 pin10 61 ROM.A3 pin9 62 ROM.A4 pin8 63 ROM.A5 pin7 64 ROM.A6 pin6 --- 65 ROM.A7 pin5 66 ROM.A8 pin4 67 ROM.A9 pin42 68 ROM.A10 pin41 69 ROM.A11 pin40 70 ROM.A12 pin39 71 ROM.A13 pin38 72 ROM.A14 pin37 73 ROM.A15 pin36 74 ROM.A16 pin35 75 ROM.A17 pin34 76 ROM.A19 pin2 77 ROM.A18 pin3 78 ROM.A20 pin43 79 ROM.A21 pin44 80 ROM.A22 pin1 81 maybe A23 ? 82 GND? 83 VCC 84 GND 85 GND? 86 SRAM. A16? pin1-1 (extra pin) 87 SRAM. A14 pin1 88 SRAM. A12 pin2 89 SRAM.A7 pin3 90 SRAM.A6 pin4 91 SRAM.A5 pin5 92 SRAM.A4 pin6 93 SRAM.A3 pin7 94 SRAM.A2 pin8 95 SRAM.A1 pin9 96 SRAM.A0 pin10 97 SRAM. A10 pin21 98 SRAM. A11 pin23 99 SRAM. A9 pin24 100 GND 101 VCC 102 SRAM. A8 pin25 --- 103 to left-solder pads (U4.3.CS) (aka SRAM.A13) 104 SRAM. A18?? pin1-2 (extra pin) 105 SRAM. A15 pin28+1 (extra pin) 106 107 108 SRAM. /OE pin22 109 SRAM. /WE pin27 110 SRAM.D0 pin11 111 SRAM.D1 pin12 112 SRAM.D2 pin13 113 SRAM.D3 pin15 114 SRAM.D4 pin16 115 SRAM.D5 pin17 116 SRAM.D6 pin18 117 SRAM.D7 pin19 118 GND 119 VCC 120 SNES./RESET 121 SNES.SYSCK 122 SNES.CIC3 (3.072MHz) 123 SNES.CIC2 124 SNES.CIC1 125 SNES.CIC0 126 SNES./WR 127 PAL/NTSC (GND=NTSC, VCC=PAL) (for CIC mode and/or HV-timer?) 128 SNES./RD ROM-Chip Note: ROM./CE and ROM./OE are wired to GND (always enabled). ROM-Chip Note: ROM.BHE is wired to VCC (always 16bit databus mode). U4.Pin5./CS ---> SRAM./CS pin20 (U4:6129A aka PCB:MM1026AF) U4.Pin3.CS ---> SRAM.A13? pin26 (left 4 solder-pads near U4 --> SRAM.pin26 = CS or A14) (right 4 solder-pads near U4 --> SRAM.pin28 = CS or Vbat) Cart Slot Unused: /ROMSEL Cart Slot Used: SHIELD (!) SNES Pinouts Decompression Chips -------------------------------- SPC7110F0A Pin-Outs 1 SnsA8 16 SnsA15 31 DatD7 46 GND 61 DatA9 76 SramCE2 91 GND 2 GND 17 SnsA16 32 DatD6 47 Prg/CE 62 DatA8 77 RtcData 92 SnsD3 3 SnsA7 18 SnsA17 33 DatD5 48 Dat/CE 63 VCC 78 RtcClk 93 SnsD2 4 SnsA6 19 SnsA18 34 DatD4 49 DatA18 64 GND 79 Rtc/CE 94 SnsD1 5 SnsA5 20 SnsS19 35 GND 50 DatA17 65 DatA7 80 VCC 95 SnsD0 6 SnsA4 21 SnsA20 36 DatD3 51 VCC 66 DatA6 81 VCC 96 GND 7 SnsA3 22 SnsA21 37 DatD2 52 GND 67 DatA5 82 GND 97 VCC 8 SnsA2 23 SnsA22 38 DatD1 53 DatA16 68 DatA4 83 GND 98 SnsA11 9 SnsA1 24 SnsA23 39 DatD0 54 DatA15 69 GND 84 GND 99 SnsA10 10 SnsA0 25 Sns/RD 40 VCC 55 DatA14 70 DatA3 85 VCC 100 SnsA9 11 GND 26 Sns/WR 41 GND 56 DatA13 71 DatA2 86 GND 12 VCC 27 SnsRESET 42 DatA22 57 DatA12 72 DatA1 87 SnsD7 13 SnsA12 28 Sns21MHz 43 DatA21 58 GND 73 DatA0 88 SnsD6 14 SnsA13 29 Sns21MHz 44 DatA20 59 DatA11 74 VCC 89 SnsD5 15 SnsA14 30 GND 45 DatA19 60 DatA10 75 GND 90 SnsD4 Sns=SNES Cart-Edge, Prg=Program ROM (/CE), Dat=Data ROM, Rtc=RTC, Sram=SRAM. S-DD1 Pin-Outs Pin 1..100 = unknown Pin 82 is possibly CIC mode (PAL/NTSC mode) SNES Pinouts BSX Connectors --------------------------- FLASH Card Slot (as found on a "BSC-1A5M-01" board) There are two conflicting numbering schemes for the 62pin connector. Pin-numbering on the black plastic connector: Rear/Left --> 62 ............................... 32 <-- Rear/Right Front/Left --> 31 ............................... 1 <-- Front/Right Pin-numbering on SNES cartridge PCB text layer: Rear/Left --> 62 ............................... 2 <-- Rear/Right Front/Left --> 61 ............................... 1 <-- Front/Right Below is using the PCB text layer's numbering scheme: 1 GND 2 GND 3 D0 4 D4 (with cap to gnd) 5 D1 (with cap to gnd) 6 D5 7 D2 8 D6 9 D3 10 D7 11 A12 12 - 13 A7 14 via R2 to /RD (33 ohm) 15 A6 16 via R3 to /WR (33 ohm) 17 A5 18 VCC 19 A4 20 - 21 A3 22 via R4 to VCC (47kOhm) 23 A2 24 via R5 to GND (47kOhm) 25 A1 26 via R6 to GND (47kOhm) 27 A0 28 - 29 A14 30 VCC 31 VCC 32 VCC 33 via R7 to VCC (47kOhm) 34 3/5 (GNDed=5V) 35 A13 36 REFRESH to SNES.pin.33 37 A8 38 A15 rom SNES.A16 SNES.pin.41 39 A9 40 A16 rom SNES.A17 SNES.pin.42 41 A11 42 A17 rom SNES.A18 SNES.pin.43 43 A10 44 A18 rom SNES.A19 SNES.pin.44 45 SYSCK SNES.pin57 (and via R1 to SNES.pin.2 EXPAND) (100 ohm) 46 A19 rom SNES.A20 SNES.pin.45 47 /RESET 48 A20 rom SNES.A21 SNES.pin.46 49 - 50 A21 rom SNES.A23 SNES.pin.48 (NOT SNES.A22 !!!) 51 /CS (from MAD-1A.pin1) 52 GND 53 Dx 54 Dx 55 Dx 56 Dx ... pins here are D8-D15 (on PCBs with 16bit databus) 57 Dx 58 Dx 59 Dx 60 Dx 61 GND 62 GND pitch: 38.1mm per 30 pins === 1.27mm per pin There are some connection variants: The Itoi cartridge with SA-1 is using 16bit databus (with extra data lines somewhere on pin53-60), pin12 seems to be connected to something, some of the the pull-up/pull-downs and VCC/GND pins on pin 14-34 and 52 may be wired differently. SNES Cartridge Slot Usage for Satellaview BIOS and Datapack carts REFRESH (SNES.pin33) is forwarded to FLASH cart slot (for unknown reason, maybe it is ACTUALLY used for deselecting FLASH during REFRESH, or maybe it was INTENDED for unreleased DRAM cartridges). SYSCK (SNES.pin57) is forwarded to FLASH cart slot (for unknown reason), and is also forwarded (via 100 ohms) to EXPAND (SNES.pin2) (and from there forwarded to the BSX Receiver Unit on SNES Expansion port). BSX-EXT-Port Pinouts (half-way rev-engineered by byuu) 1 = +5V 2 = +5V 3 = +5V 4 = +5V 5 = GND 6 = GND 7 = GND 8 = GND 9 = GND 10 = GND 11 = U3.pin17 (B2) ;\ 12 = U3.pin18 (B1) ; 13 = U3.pin15 (B4) ; 14 = U3.pin16 (B3) ; 15 = U3.pin13 (B6) ; 16 = U3.pin14 (B5) ; 17 = U3.pin11 (B8) ; 18 = U3.pin12 (B7) ;/ 19 = U2.pin11 (Y8) 20 = GND 21 = U2.pin12 (Y7) 22 = GND 23 = ??? 24 = GND 25 = U1.pin12 (Y7) 26 = GND 27 = U1.pin11 (Y8) 28 = U1.pin13 (Y6) 29 = ??? 30 = ??? 31 = ??? 32 = U2.pin14 (Y5) 33 = ??? 34 = ??? 35 = GND 36 = GND 37 = GND 38 = GND The U3 transceiver is probably passing databus to/from SNES, the U1/U2 drivers are maybe passing some address/control signals from SNES. The indirect connection via U1/U2/U3 may be intended to amplify the bus, or to disconnect the bus (in case when the receiver power supply isn't connected). SNES Pinouts NSS Connectors --------------------------- NSS - CN11/12/13 - Cartridge Slots (3 slots, 2x50pin each) Solder side Component side A B WRAM.64 GND - 1 - VCC2 INST.28 ;\ WRAM.64 GND - 2 - VCC2 INST.28 ; PROM PROM.7-R3 PROM.RES - 3 - PROM.CLK PROM.6 ; (and SNES PROM.5-R2 PROM.TST - 4 - PROM.CNT PROM.8 ; select) /SNES_# - 5 - PROM.DTA PROM.1 ;/ INST.15 D3 - 6 - D4 INST.16 ;\ INST.13 D2 - 7 - D5 INST.17 ; INST.12 D1 - 8 - D6 INST.18 ; INST.11 D0 - 9 - D7 INST.19 ; INST.10 A0 - 10 - /CE_# INST.20 ; INST.9 A1 - 11 - A10 INST.21 ; INST ROM INST.8 A2 - 12 - /OE INST.22 ; INST.7 A3 - 13 - A11 INST.23 ; INST.6 A4 - 14 - A9 INST.24 ; INST.5 A5 - 15 - A8 INST.25 ; INST.4 A6 - 16 - A7 INST.3 ; INST.2 A12 - 17 - GND WRAM.64 ; WRAM.64 GND - 18 - VCC2 INST.28 ; WRAM.64 _______ GND - 19 - VCC2 ______ INST.28 ;/ WRAM.64 GND - 20 - VCC WRAM.1 ;\ WRAM.64 GND - 21 - VCC WRAM.1 ; WRAM.56 /PARD - 22 - /PAWR WRAM.58 ; WRAM.47 PA6 - 23 - PA7 WRAM.50 ; WRAM.45 PA4 - 24 - PA5 WRAM.46 ; WRAM.43 PA2 - 25 - PA3 WRAM.44 ; SNES Bus WRAM.53 PA0 - 26 - PA1 WRAM.54 ; (and PROM WRAM.57 /RD - 27 - /WR WRAM.59 ; select) WRAM.63 D3 - 28 - D4 WRAM.2 ;\D4..D7 in ; WRAM.62 D2 - 29 - D5 WRAM.3 ; opposite ; WRAM.61 D1 - 30 - D6 WRAM.4 ; order as ; WRAM.60 D0 - 31 - D7 WRAM.5 ;/on SNES ; CPU.46 /IRQ - 32 - /ROMSEL CPU.77 ; CPU.93 A0 - 33 - A23 CPU.17 ; CPU.94 A1 - 34 - A22 CPU.16 ; CPU.95 A2 - 35 - A21 CPU.15 ; CPU.96 A3 - 36 - A20 CPU.14 ; CPU.97 A4 - 37 - A19 CPU.13 ; CPU.98 A5 - 38 - A18 CPU.12 ; CPU.99 A6 - 39 - A17 CPU.11 ; CPU.100 A7 - 40 - A16 CPU.10 ; CPU.2 A8 - 41 - A15 CPU.9 ; CPU.3 A9 - 42 - A14 CPU.8 ; CPU.4 A10 - 43 - A13 CPU.7 ; CPU.5 A11 - 44 - A12 CPU.6 ; WRAM.7 REFRESH - 45 - /WRAMSEL WRAM.15 ; AUDIO_L - 46 - AUDIO_R ; PROM.2 PROM./CE_# - 47 - SYSCLK WRAM.6 ; CPU.48 MCK 21M - 48 - /RESET WRAM.8 ; WRAM.64 GND - 49 - VCC WRAM.1 ; WRAM.64 GND - 50 - VCC WRAM.1 ;/ The NSS motherboard uses female Matsushita AXD100271 connectors, and the NSS cartridges have male Matsushita AXD200251 connectors. Both are obsolete as of a few years ago, but they're just shrouded 0.1" headers. RICOH RP5H01 PROM Pinout (Decryption Key PROM on NSS Cartridges) 1 DATA.OUT 2 /CE (VPP) 3 VCC 4 GND 5 TEST 6 DATA.CLK 7 RESET 8 COUNTER.OUT NSS - CN1 - Big Edge Connector "JAMMA" - 2x28 pin 1 GND (from Power Supply) A GND (from Power Supply) 2 GND (NC) B GND (from Power Supply) 3 +5V (from Power Supply) C +5V (to joypads; and NC there) 4 +5V (from Power Supply) D +5V (from Power Supply) 5 NC (NC) E -5V (from Power Supply) 6 +12V (to Coin Lamps and Coin Counter) F +12V (from Power Supply) 7 KEY H KEY 8 Coin Counter 1 J Coin Counter 2 9 NC K NC 10 SPEAKER (Right) L SPEAKER (Left) 11 AUDIO (+) (NC) M AUDIO GND 12 VIDEO RED N VIDEO GREEN 13 VIDEO BLUE P VIDEO SYNC 14 VIDEO GND R SERVICE SW 15 TEST SW S NC 16 COIN SW 1 T COIN SW 2 17 1P START U 2P START 18 1P UP V 2P UP 19 1P DOWN W 2P DOWN 20 1P LEFT 2P LEFT 21 1P RIGHT 2P RIGHT 22 1P A 2P A 23 1P B 2P B 24 1P SELECT 2P SELECT 25 VOLUME ? (POT Center Pin) VOLUME ? (POT Outer Pin) 26 VOLUME GND (POT Outer Pin) NC 27 GND GND 28 GND GND NSS - CN2 - 10P Connector (Extra Joypad Buttons) 1 GND 2 2P TR 3 2P TL 4 2P Y 5 2P X 6 1P TR 7 1P TL 8 1P Y 9 1P X 10 GND NSS - CN3 - 13P Connector (Front Panel LEDs/Buttons) 1 GND (for Buttons) 2 Button Restart 3 Button Page Down 4 Button Page Up 5 Button Instructions 6 Button Game #3 7 Button Game #2 8 Button Game #1 9 LED Instructions 10 LED Game #3 11 LED Game #2 12 LED Game #1 13 +5V or so (for LEDs) NSS - CN4 1 GND (to SNES Controller pin 7) 2 /EXT_CTRL2 (Low=External CN4 controller, High=Internal Joypad2 selected) 3 JPIO7 (to SNES Controller pin 6) ;\ 4 JPSTR (to SNES Controller pin 3) ; always connected 5 JPCLK2 (to SNES Controller pin 2) ;/ 6 4017.D1 (to SNES Controller pin 5) ;\only when CN4 selected 7 4017.D0 (to SNES Controller pin 4) ;/ 8 SNES +5V (to SNES Controller pin 1) The external input is enabled when setting INST ROM Flags Bit0=0 (that bit is copied to Port 01h.W bit4). NSS - CN5 1 GND 2 IC32/74LS540 pin 9 (Port 02h.R bit 7) 3 IC32/74LS540 pin 8 (Port 02h.R bit 6) 4 IC32/74LS540 pin 7 (Port 02h.R bit 5) 5 IC32/74LS540 pin 6 (Port 02h.R bit 4) 6 IC32/74LS540 pin 5 (Port 02h.R bit 3) 7 +5V NSS Repair (Blank Screen / Washed out colors) There seems to be a fairly common hardware problem that causes the NSS to show a picture with washed out colors or a completely blank screen; in some cases the problem appears or disappears when the unit has warmed up. The problem is related to the power supply of the IR3P32A chip: The supply should be around 9V, and video glitches appear when it drops below 8V. For deriving the "9V", Nintendo has strapped the IR3P32A to the 12V line via a 100 ohm resistor; which is rather crude and unreliable. As workaround one could add a second resistor in parallel with the 100 ohms (which is equally crude, though it should help temporarily), a more reliable solution should be to replace the 100 ohms by a 7809 voltage regulator (and eventually some capacitors as far as needed). The actual reason for the problem is unknown - apparently some odd aging effect on the IR3P32A chip and/or other components connected to it. No info if the problem occurs both with original monitor and power supply as well as with third-party hardware. NSS-to-SNES-cartridge adaptor (signal quality) Using SNES cartridges with coprocessors (eg. DSP1 carts) on NSS requires some fine tuning: DogP's older solution: The /RD and /WR pins seem to have high slew rates and overshoot badly (by around 3V, for just a few ns)... a regular Mario Kart cartridge works perfectly with LPFs added to those pins. The PowerPak seems to still have some issues though. DogP's newer solution: I actually ended up just adding small resistors in series with the data bus, which helped reduce the overshoot/ringing. This also fixed the PowerPak issues. NSS-to-SNES-cartridge adaptor (CIC) A fully functional NSS-to-SNES-cartridge adaptor would also require a CIC chip (as a few SNES cartridges with special protections won't work if the 'console' doesn't output the correct CIC signals). Accordingly, the adaptor would also need something that generates the 3.072MHz CIC clock signal (on a real SNES that would be 24.576MHz/8 coming from APU) (on the NSS adaptor it would require a separate oscillator, or if accuracy doesn't matter, then one might get away with 21.xxxMHz PAL/NTSC master clock divided by 7 (or dirtier: divided by 8)). Unless there should be another way to get those protected cartridges to work (maybe by simply wiring CIC clock to VCC or GND, or by feeding it only a few dozen of CIC clks after reset, so it could initialize itself, but would never reach the point where the protection could do something harmful). SNES Pinouts Nintendo Power Flashcarts -------------------------------------- MX15001TFC 1 GND 21 SNES_A6 41 VCC 61 FLASH_A13 81 SNES_D7 2 VCC 22 SNES_A5 42 SRAM_A11 62 FLASH_A14 82 SNES_D6 3 SNES_A23 23 SNES_A4 43 SRAM_A12 63 FLASH_A15 83 SNES_D5 4 SNES_A22 24 SNES_A3 44 SRAM_A13 64 FLASH_A16 84 SNES_D4 5 SNES_A21 25 SNES_A2 45 SRAM_A14 65 FLASH_A17 85 SNES_D3 6 SNES_A20 26 SNES_A1 46 MEM_A0 66 GND 86 SNES_D2 7 SNES_A19 27 SNES_A0 47 MEM_A1 67 FLASH_A18 87 SNES_D1 8 SNES_A18 28 GND 48 MEM_A2 68 FLASH_A19 88 SNES_D0 9 SNES_A17 29 VCC 49 MEM_A3 69 FLASH_A20 89 FLASH_OE 10 SNES_A16 30 SNES_21MHZ 50 MEM_A4 70 GND 90 GND 11 SNES_A15 31 SNES_21MHZ 51 MEM_A5 71 FLASH_CS3 91 VCC 12 SNES_A14 32 FLASH_WP 52 VCC 72 NC 92 GND 13 SNES_A13 33 GND 53 GND 73 NC 93 CIC_ERROR 14 SNES_A12 34 GND 54 MEM_A6 74 FLASH_CS2 94 GND 15 GND 35 VCC_GOOD 55 MEM_A7 75 FLASH_CS1 95 GND 16 SNES_A11 36 SRAM_CS 56 MEM_A8 76 FLASH_WE1 96 SNES_RESET1 17 SNES_A10 37 VCC 57 MEM_A9 77 FLASH_WE2 97 MODESEL2? 18 SNES_A9 38 MODESEL1? 58 MEM_A10 78 MEM_WE3 98 SNES_WR 19 SNES_A8 39 SRAM_OE 59 FLASH_A11 79 VCC 99 SNES_RD 20 SNES_A7 40 GND 60 FLASH_A12 80 GND 100 SNES_RESET2 The "MEM_xxx" signals are wired to both FLASH and SRAM. The CIC_ERROR pin should be held LOW. For PAL (with CIC disabled in the console), the cart does somewhat work when rebooting several times, but it works more reliable when cutting CIC_ERROR (and preferably GNDing pin93, though pin93 seems to be floating/low anyways). SNES Common Mods ---------------- CIC Disable The console contains a F411 (NTSC) or F413 (PAL) chip that verifies if the cartridge contains an identical chip, if it doesn't, then it resets the SNES, preventing to use unlicensed carts, or to use NTSC carts on PAL consoles. F411/F413 Pin 4 (GND=Disable/Unlock, VCC=Enable/Lock) Even when disabled, some newer games (eg. Donkey Kong Country) may verify the PAL/NTSC framerate by software and refuse to run if it doesn't match the expected setting, this can be solved by adding a framerate switch (see below), the verification is often done only after power-up, so one can restore the desired setting after power-up. Some newer games are reportedly also refusing to run if the CIC chip in the console is disabled, as a workaround, one would usually add a switch that allows to re-enables the CIC when needed. Eventually one could also modify the cartridges (they are probably connecting the CIC /RESET output to ROM CE2 pin or so?). Games with SA-1 or S-DD1 chips won't work. 50Hz/60Hz Switch PPU1 Pin 24 (GND=60Hz, VCC=50Hz) PPU2 Pin 30 (GND=60Hz, VCC=50Hz) 50Hz/60Hz Switch on newer cost-down SNES (those with 160pin S-CPUN A) Basically, the frame rate is selected by a single pin: S-CPUN A, Pin 111 - PAL/NTSC (high=PAL, low=NTSC) An unwanted side effect is that this pin also changes the expected clock input: X1 oscillator (21.47727MHz=NTSC, 17.7344750MHz=PAL) as a workaround, buy the missing oscillator, and use a "stereo" switch that simultaneously toggles the oscillator and the PAL/NTSC pin. Another unwanted side effect is that it does (probably) change the color clock output for the S-RGB A chip, making the composite video signal unusable. As a workaround, one could use a TV set with RGB input (this would also require to connect the R,G,B,SYNC pins, which are left unconnected on the Multi-Out port of the cost-down SNES). Eventually it might be also possible to use composite video by connecting a matching oscillator directly to the S-RGB A chip (NTSC:3.579545MHz, PAL:4.43361875MHz) (not tested). SNES Controller Mods -------------------- Shift Registers SNES Joypads are basically consisting of buttons wired to a 16bit shift register. This could be reproduced using two 4021 chips (two 8bit parallel-in serial-out shift registers). SNES PAL vs NTSC Controllers For using SNES NTSC controllers on SNES PAL consoles: --> SNES Controllers Pinouts SNESPAD (SNES Controller to PC Parallel Port) This is a circuit for connecting up to five SNES joypads to a PC Parallel Port, using 25pin DSUB or 36pin Centronics connector. The circuit can be used with drivers like "Direct Pad Pro" or "PPJoy", or by emulators with built-in SNESPAD support. Pin DB25 CNTR d3 5 5 ---|>|--. .---. d4 6 6 ---|>|--+------------| O | 1 vcc d5 7 7 ---|>|--| .---------| O | 2 clk d6 8 8 ---|>|--| | .-------| O | 3 stb d7 9 9 ---|>|--' | | .-----|_O_| 4 dta1 d0 2 2 -----------' | | | O | 5 dta3 d1 3 3 -------------' | | O | 6 io x x x ---------------' .---| O | 7 gnd gnd 18-25 19-30 -------------' \_/ For Pad 1..5, wire Pin "x" to ack,pe,slct,err,busy (aka DB25 pin 10, 12, 13, 15, 11) (aka CNTR pin 10, 12, 13, 32, 11) (aka bit6, bit5, bit4, bit3, NOT(bit7) in the PC's I/O Port). The circuit is pretty well standarized (there is only one variant, a so-called "Linux" circuit with messed-up pin ordering: ack,busy,pe,slct,err for pad 1..5). 7pin Connectors (1mm pin diameter) With some efforts, these can be made pulling contacts from regular DSUB connectors (which have same pin diameter, but different pin spacing). Solder the contacts onto a piece of board, and eventually build some plastic block with holes/notches as in real SNES connectors. Alternately, SNES extension cables (with one male & one female connector) are reportedly available. SNES Xboo Upload (WRAM Boot) ---------------------------- WRAM-Boot Circuit (for WRAM-boot-compatible ROMs, max 128K bytes) ____ CTR.01./STB-----|AND \_____WRAM.58./PAWR VCC-------/cut/--CPU.81.RDY EXT.09./PAWR----|____/ PA7-------/cut/--WRAM.50.PA7 CTR.36./SELECT--|XOR \_____HIGHSEL /PAWR-----/cut/--WRAM.58./PAWR EXT.20.VCC -----|____/ /WRAMSEL--/cut/--WRAM.15./WRAMSEL HIGHSEL---------|OR \_____WRAM.50.PA7 /ROMSEL---/cut/--SLT.49./ROMSEL EXT.08.PA7 -----|____/ CTR.01./STB-----[10K]--EXT.20.VCC HIGHSEL---------|OR \___ ____ CTR.14./AUTOLF--[10K]--EXT.20.VCC SLT.32./WRAMSEL-|____/ |AND \___WRAM.15. CTR.36./SELECT--[10K]--EXT.20.VCC CPU.77./ROMSEL--|OR \___|____/ /WRAMSEL CTR.01./STB-----|10n|--EXT.23.GND CTR.14./AUTOLF--|____/ ________* CTR.14./AUTOLF--|10n|--EXT.23.GND CTR.14./AUTOLF--|XOR \_|_ ____ CTR.36./SELECT--|10n|--EXT.23.GND EXT.20.VCC------|____/ |OR \___SLT.49. CTR.31.INIT----------RESET_BUTTON CPU.77./ROMSEL___________|____/ /ROMSEL CTR.36./SELECT---------CPU.81.RDY CTR.19-30.GND__________________EXT.23.GND CTR.02-09.D0-D7---EXT.11-18.D0-D7 Extended Circuit (for larger ROMs, and for non-WRAM-boot-compatible ROMs) ____ CTR.14./AUTOLF--|AND \____(XOR) /STB------/cut/-----------(AND) CTR.01./STB-----|____/ /AUTOLF---/cut/-----------(XOR) CTR.01./STB-----|OR \____(AND) /PARD-----/cut/---WRAM.56./PARD CTR.36./SELECT--|____/ ________________ CPU.77./ROMSEL--|OR \__________________|/CS SRAM CS2|__VCC (if any) CTR.01./STB-----|____/ A0..A14___|A0..A14 D0..D7|__D0..D7 SLT.nn.A15------|XOR \__________________|A15 /OE|__CPU.92./RD SLT.nn.A(hi+1)--|____/ A16..A(hi)___|A16..A(hi) /WE|__CPU.91./WR CTR.14./AUTOLF--|OR \___ ____ |________________| CTR.36./SELECT--|____/ |AND \___WRAM.56./PARD EXT.10./PARD_____________|____/ CTR.10./ACK_______________________CPU.39.OUT2 Revision Nov 2012 (/RD disable, for /ROMSEL-less carts like GSU) ____ * ------------|OR \_____ SLT.23. CPU.92./RD----/cut/---SLT.23./RD CPU.92./RD ---|____/ /RD Functional Description (WRAM Boot) RESET/INIT and RDY/SELECT are used to reset and stop the CPU, in that state, PA0-PA7 and /WRAMSEL are all LOW (of which, PA7 and /WRAMSEL need to be changed for DMA), and WRAM address is reset to zero. Data is then DMA transferred to WRAM via databus and /STB/PAWR. Finally, WRAM is mirrored (in HiROM fashion) to the ROM-region via /AUTOLF, and entrypoint and program code are fetched from WRAM. WRAM-Boot compatible files are identified by ID "XBOO" at FFE0h in ROM Header. WRAM-boot files should be also bootable from normal ROM (unless written by less-than-lame people). The WRAM upload function is found in no$sns "Utility" menu. WRAM boot works only if a regular cartride is inserted, or if the lockout chip is disabled. Normal ROM-cartridges can be used if the cable is disconnected, or if the parallel port is set to /STB=HIGH, /AUTOLF=HIGH, /SELECT=HIGH, /INIT=LOW, and DATA=HIGH-Z. Functional Description (Extended Circuit) Data is uploaded (in 127.5K blocks) to WRAM, and is then automatically relocated (by a 0.5K stub) from WRAM to SRAM by software, /ACK is used to indicate completion of relocation, after uploading all block(s) the console gets reset with SRAM mapped to the ROM-region. The XOR gate maps the bottom halves of the HiROM banks as additional LoROM banks. About A(hi) and A(hi+1): For example, for 128Kx8 chip (A0..A16): connect A(hi) to A16, A(hi+1) to A17. For more than 2Mx8 SRAM: connect the A(hi+1) input to GND; or leave out the XOR gate completely. /STB and /AUTOLF are used (while /SELECT=HIGH) to select ROM, WRAM, or SRAM mapping, and as /PARD and /PAWR (while /SELECT=LOW). The /PARD pin allows to download status information and other data from WRAM. Parts List 1 74LS08 Quad 2-Input AND gates 1 74LS32 Quad 2-Input OR gates 1 74LS86 Quad 2-Input XOR gates 3 10K Ohm Resistors (required when cable is disconnected) 3 10nF capacitor (to eliminate dirt on some ports) 1 36pin centronics socket (plus standard printer cable) Additional components for Extended Circuit 1 74LS32 Quad 2-Input OR gates 1 nn-pin DIP Nx8 Static RAM (SRAM) 1 40-pin DIP Socket for SRAM Requires a bi-directional parallel port (very old printer ports aren't bi-directional, also some hyper-modern ports aren't bi-directional when configured to "ECP" mode, for that ports: use "EPP" mode). Currently SRAMs of up to 512Kx8 (32pin) should be available for less than $5, also 2Mx8 chips (36pin) are manufactured, but I've no idea where to buy them, best use a 40pin DIP socket for future expansion. TEST Mode Optionally, one can replace the "XBOO" ID-string in cartridge header by "TEST", this will cause normal Cartridge ROM to be mapped (instead of mirroring WRAM to the ROM area). The advantage is that the uploaded program can examine cartridge memory (eg. for reverse-engineering purposes), the disadvantage is that it cannot set up it's own IRQ/NMI vectors. The program should redirect the reset vector from Bank 00h to Bank 7Eh by executing a JMP 7Exxxxh immediately after reset, and then wait until WRAM is no longer mapped at 008xxxxh; thereafter, ROM is freely accessible (the switch from WRAM to ROM mapping occurs circa 100us after RESET). CPU 65XX Microprocessor ----------------------- Overview --> CPU Registers and Flags --> CPU Memory Addressing --> CPU Clock Cycles Instruction Set --> CPU Memory and Register Transfers --> CPU Arithmetic/Logical Operations --> CPU Rotate and Shift Instructions --> CPU Jump and Control Instructions Other Info --> CPU Assembler Directives/Syntax --> CPU Glitches --> CPU The 65XX Family CPU Registers and Flags ----------------------- The 65XX CPUs are equipped with not more than three general purpose registers (A, X, Y). However, the limited number of registers is parts of covered by comfortable memory operations, especially page 0 of memory (address 0000h-00FFh) may be used for relative fast and complicated operations, in so far one might say that the CPU has about 256 8bit 'registers' (or 128 16bit 'registers') in memory. For details see Memory Addressing chapter. Registers Bits Name Expl. 8/16 A Accumulator 8/16 X Index Register X 8/16 Y Index Register Y 16 PC Program Counter 8/16 S Stack Pointer (see below) 8 P Processor Status Register (see below) 16 D Zeropage Offset ;expands 8bit [nn] to 16bit [00:nn+D] 8 DB Data Bank ;expands 16bit [nnnn] to 24bit [DB:nnnn] 8 PB Program Counter Bank ;expands 16bit PC to 24bit PB:PC Stack Pointer The stack pointer is addressing 256 bytes in page 1 of memory, ie. values 00h-FFh will address memory at 0100h-01FFh. As for most other CPUs, the stack pointer is decrementing when storing data. However, in the 65XX world, it points to the first FREE byte on stack, so, when initializing stack to top set S=(1)FFh (rather than S=(2)00h). Processor Status Register (Flags) Bit Name Expl. 0 C Carry (0=No Carry, 1=Carry) 1 Z Zero (0=Nonzero, 1=Zero) 2 I IRQ Disable (0=IRQ Enable, 1=IRQ Disable) 3 D Decimal Mode (0=Normal, 1=BCD Mode for ADC/SBC opcodes) 4 X/B Break Flag (0=IRQ/NMI, 1=BRK/PHP opcode) (0=16bit, 1=8bit) 5 M/U Unused (Always 1) (0=16bit, 1=8bit) 6 V Overflow (0=No Overflow, 1=Overflow) 7 N Negative/Sign (0=Positive, 1=Negative) - E (0=16bit, 1=8bit) Emulation Flag (E) (can accessed only via XCE opcode) Activates 6502 emulation mode. In that mode, A/X/Y are 8bit (as when X/M are set). S is 8bit (range 0100h..01FFh). The X/M flags are replaced by B/U flags (B=Break/see below, U=Unused/always 1). Exception Vectors are changed to 6502 addresses, and exceptions push only 16bit return addresses (rather than 24bit). Conditional Branches take one extra cycle when crossing pages. The new 65C02 and 65C816 opcodes can be kept used; respectively, none of the undocumented opcodes of the original 6502 CPU are supported. Accumulator/Memory Flag (M) Switches A to 8bit mode (the upper 8bit of A can be still accessed via XBA). Additionally switches all opcodes that do not use A,X,Y operands (eg. STZ, and read-modify-write opcodes like inc/dec, Rotate/Shift) to 8bit mode. Index Register Flag (X) Switches X and Y to 8bit mode (the upper 8bit are forcefully set to 00h). Carry Flag (C) Caution: When used for subtractions (SBC and CMP), the carry flag is having opposite meaning as for normal 80x86 and Z80 CPUs, ie. it is SET when above-or-equal. For all other instructions (ADC, ASL, LSR, ROL, ROR) it works as normal, whereas ROL/ROR are rotating carry (ie. much like 80x86 RCL/RCR and not like ROL/ROR). Zero Flag (Z), Negative/Sign Flag (N), Overflow Flag (V) Works just as everywhere, Z it is set when result (or destination register, in case of some 'move' instructions) is zero, N is set when signed (ie. same as Bit 7 of result/destination). V is set when an addition/subtraction exceeded the maximum range for signed numbers (-128..+127). IRQ Disable Flag (I) Disables IRQs when set. NMIs (non maskable interrupts) and BRK instructions cannot be disabled. Decimal Mode Flag (D) Packed BCD mode (range 00h..99h) for ADC and SBC opcodes. Break Flag (B) The Break flag is intended to separate between IRQ and BRK which are both using the same vector, [FFFEh]. The flag cannot be accessed directly, but there are 4 situations which are writing the P register to stack, which are then allowing the examine the B-bit in the pushed value: The BRK and PHP opcodes always write "1" into the bit, IRQ/NMI execution always write "0". --- Common Confusing Aliases for Register Names DPR D (used in homebrew specs) K PB (used by PHK) PBR PB (used in specs) DBR DB (used in specs) B DB (used by PLB,PHB) B Upper 8bit of A (used by XBA) C Full 16bit of A (used by TDC,TCD,TSC,TCS) CPU Memory Addressing --------------------- Opcode Addressing Modes Name Native Nocash Implied - A,X,Y,S,P Immediate #nn nn Zero Page nn [nn] Zero Page,X nn,X [nn+X] Zero Page,Y nn,Y [nn+Y] Absolute nnnn [nnnn] Absolute,X nnnn,X [nnnn+X] Absolute,Y nnnn,Y [nnnn+Y] (Indirect,X) (nn,X) [[nn+X]] (Indirect),Y (nn),Y [[nn]+Y] Zero Page - [nn] [nn+X] [nn+Y] Uses an 8bit parameter (one byte) to address the first 256 of memory at 0000h..00FFh. This limited range is used even for "nn+X" and "nn+Y", ie. "C0h+60h" will access 0020h (not 0120h). Absolute - [nnnn] [nnnn+X] [nnnn+Y] Uses a 16bit parameter (two bytes) to address the whole 64K of memory at 0000h..FFFFh. Because of the additional parameter bytes, this is a bit slower than Zero Page accesses. Indirect - [[nn+X]] [[nn]+Y] Uses an 8bit parameter that points to a 16bit parameter in page zero. Even though the CPU doesn't support 16bit registers (except for the program counter), this (double-)indirect addressing mode allows to use variable 16bit pointers. On-Chip Bi-directional I/O port Addresses (00)00h and (00)01h are occupied by an I/O port which is built-in into 6510, 8500, 7501, 8501 CPUs (eg. used in C64 and C16), be sure not to use the addresses as normal memory. For description read chapter about I/O ports. Caution Because of the identical format, assemblers will be more or less unable to separate between [XXh+r] and [00XXh+r], the assembler will most likely produce [XXh+r] when address is already known to be located in page 0, and [00XXh+r] in case of forward references. Beside for different opcode size/time, [XXh+r] will always access page 0 memory (even when XXh+r>FFh), while [00XXh+r] may direct to memory in page 0 or 1, to avoid unpredictable results be sure not to use (00)XXh+r>FFh if possible. CPU Clock Cycles ---------------- SNES Memory Speed Memory Area Speed Clks Comment 00-3F:0000-1FFF Medium 2.68MHz 8 WRAM (8K mirror of 7E:0000-1FFF) 00-3F:2000-3FFF Fast 3.58MHz 6 I/O and Expansion 00-3F:4000-41FF Slow 1.78MHz 12 Manual Joypad Reading 00-3F:4200-5FFF Fast 3.58MHz 6 I/O and Expansion 00-3F:6000-7FFF Medium 2.68MHz 8 SRAM and Expansion 00-3F:8000-FFFF Medium 2.68MHz 8 ROM (32K banks) 40-7F:0000-FFFF Medium 2.68MHz 8 ROM/SRAM/WRAM 80-BF:0000-1FFF Medium 2.68MHz 8 WRAM (8K mirror of 7E:0000-1FFF) 80-BF:2000-3FFF Fast 3.58MHz 6 I/O and Expansion 80-BF:4000-41FF Slow 1.78MHz 12 Manual Joypad Reading 80-BF:4200-5FFF Fast 3.58MHz 6 I/O and Expansion 80-BF:6000-7FFF Medium 2.68MHz 8 SRAM and Expansion 80-BF:8000-FFFF Variable 6/8 ROM (32K banks) ;\speed selectable C0-FF:0000-FFFF Variable 6/8 ROM (64K banks) ;/via port 420Dh Internal Cycles Fast 3.58MHz 6 Internal cycles (eg. 2nd cycle in NOPs) Implied or Immediate Operands CN 2 Opcodes without memory/immediate parameters CNN 3 XBA/WAI/STP (swap A, wait irq, stop) CPp 2,3 nn or nnnn ;+p if 16bit CPN 3 nn (REP/SEP) Memory Operands CPnDd 3,4,5 [nn+d] ;+n if (D AND 00FFh)>0, +d if 16bit CPnDdNDd 5..8 [nn+d] (RMW) ;+n if (D AND 00FFh)>0, +dd if 16bit CPnNDd 4,5,6 [nn+x+d] or [nn+y+d] ;+n if (D AND 00FFh)>0, +d if 16bit CPnNDdNDd 6..9 [nn+x+d] (RMW) ;+n if (D AND 00FFh)>0, +dd if 16bit CPNDd 4,5 [nn+s] ;+d if 16bit CPPDd 4,5 [nnnn] ;+d if 16bit CPPDdNDd 6,8 [nnnn] (RMW) ;+dd if 16bit CPPyDd 4,5,6 [nnnn+x] or [nnnn+y] (RD) +y xxx ;+d if 16bit CPPNDd 5,6 [nnnn+x] or [nnnn+y] (WR) ;+d if 16bit CPPNDdNDd 7,9 [nnnn+x] (RMW) ;+dd if 16bit CPPPDd 5,6 [nnnnnn] or [nnnnnn+x] ;+d if 16bit CPnAADd 5,6,7 [[nn+d]] ;+n if (D AND 00FFh)>0, +d if 16bit CPnAAyDd 5..8 [[nn+d]+y] (RD) +n+y xxx ;+d if 16bit CPnAANDd 6..8 [[nn+d]+y] (WR) ;+n if (D AND 00FFh)>0, +d if 16bit CPnNAADd 6,7,8 [[nn+d+x]] ;+n if (D AND 00FFh)>0, +d if 16bit CPNAANDd 7,8 [[nn+s]+y] ;+d if 16bit CPnAAADd 6,7,8 [far[nn+d]] or [far[nn+d]+y] ;+n if (D ..)>0, +d if 16bit CPPDDNN 7 ldir/lddr Push/Pop CNsS 3,4 PUSH register ;+s if 16bit CNNSs 4,5 POP register ;+s if 16bit CPnDDSS 6,7 PUSH word[nn+d] ("PEI") ;+n if (D AND 00FFh)>0 CPPSS 5 PUSH nnnn ("PEA") CPPNSS 6 PUSH $+/-nnnn ("PER") Jumps CP 2 relative 8bit jump (condition false) CPNx 3,4 relative 8bit jump ;+x if "E=1 and crossing 100h-boundary" CPPN 4 relative 16bit jump CPP 3 Jump nnnn CPPP 4 Jump nnnnnn CPPNSS 6 Call nnnn CPPSNPSS 8(7?) Call nnnnnn CPPDD 5 jump [nnnn] CPPNDD 6 jump [nnnn+X] CPPDDD 6 jump far[nnnn] CPSSPNDD 8 call [nnnn+X] CNNSSN 6 RTS (ret) CNNSSS 6 RTL (retf) CNNSSSs 6,7 RTI (reti) ;+s if E=0 NNsSSSDD 7,8 Exception (/ABORT, /IRQ, /NMI, /RES) ;+s if E=0 CPsSSSDD 7,8 Exception (BRK, COP) ;+s if E=0 Legend C Opcode command P Opcode parameter (immediate or address) A Address cycles (on double-indirect addresses) D Data cycles N Internal cycles S Stack cycles Additional cycles d Data (MSB in 16bit modes, ie. when M/X=0) s Stack (MSB in 16bit modes, or BANK in 65C816-mode exceptions) n Internal cycle, when (D AND 00FFh)>0 x Internal cycle, when E=1 and rel-jump crossing 100h-boundary y Internal cycle, when X=0 or indexing across page boundaries CPU Memory and Register Transfers --------------------------------- Register to Register Transfer Opcode Flags Clks Native Nocash Bits Effect A8 nz---- 2 TAY MOV Y,A x Y=A AA nz---- 2 TAX MOV X,A x X=A BA nz---- 2 TSX MOV X,S x X=S 98 nz---- 2 TYA MOV A,Y m A=Y 8A nz---- 2 TXA MOV A,X m A=X 9A ------ 2 TXS MOV S,X e S=X 9B nz---- 2 TXY MOV Y,X x Y=X BB nz---- 2 TYX MOV X,Y x X=Y 7B nz---- 2 TDC MOV A,D 16 A=D 5B nz---- 2 TCD MOV D,A 16 D=A 3B nz---- 2 TSC MOV A,SP 16 A=SP 1B ------ 2 TCS MOV SP,A e? SP=A Load Register from Memory Opcode Flags Clks Native Nocash Bits Effect A9 nn nz---- 2 LDA #nn MOV A,nn A=nn A5 nn nz---- 3 LDA nn MOV A,[nn] A=[D+nn] B5 nn nz---- 4 LDA nn,X MOV A,[nn+X] A=[D+nn+X] A3 nn nz---- LDA nn,S MOV A,[nn+S] A=[nn+S] AD nn nn nz---- 4 LDA nnnn MOV A,[nnnn] A=[DB:nnnn] BD nn nn nz---- 4* LDA nnnn,X MOV A,[nnnn+X] A=[DB:nnnn+X] B9 nn nn nz---- 4* LDA nnnn,Y MOV A,[nnnn+Y] A=[DB:nnnn+Y] AF nn nn nn nz---- LDA nnnnnn MOV A,[nnnnnn] A=[nnnnnn] BF nn nn nn nz---- LDA nnnnnn,X MOV A,[nnnnnn+X] A=[nnnnnn+X] B2 nn nz---- LDA (nn) MOV A,[[nn]] A=[WORD[D+nn]] A1 nn nz---- 6 LDA (nn,X) MOV A,[[nn+X]] A=[WORD[D+nn+X]] B1 nn nz---- 5* LDA (nn),Y MOV A,[[nn]+Y] A=[WORD[D+nn]+Y] B3 nn nz---- LDA (nn,S),Y MOV A,[[nn+S]+Y] A=[WORD[nn+S]+Y] A7 nn nz---- LDA [nn] MOV A,[FAR[nn]] A=[FAR[D+nn]] B7 nn nz---- LDA [nn],y MOV A,[FAR[nn]+Y] A=[FAR[D+nn]+Y] A2 nn nz---- 2 LDX #nn MOV X,nn X=nn A6 nn nz---- 3 LDX nn MOV X,[nn] X=[D+nn] B6 nn nz---- 4 LDX nn,Y MOV X,[nn+Y] X=[D+nn+Y] AE nn nn nz---- 4 LDX nnnn MOV X,[nnnn] X=[DB:nnnn] BE nn nn nz---- 4* LDX nnnn,Y MOV X,[nnnn+Y] X=[DB:nnnn+Y] A0 nn nz---- 2 LDY #nn MOV Y,nn Y=nn A4 nn nz---- 3 LDY nn MOV Y,[nn] Y=[D+nn] B4 nn nz---- 4 LDY nn,X MOV Y,[nn+X] Y=[D+nn+X] AC nn nn nz---- 4 LDY nnnn MOV Y,[nnnn] Y=[DB:nnnn] BC nn nn nz---- 4* LDY nnnn,X MOV Y,[nnnn+X] Y=[DB:nnnn+X] * Add one cycle if indexing crosses a page boundary. Store Register in Memory Opcode Flags Clks Native Nocash Bits Effect 64 nn ------ 3 STZ nn MOV [nn],0 m [D+nn]=0 74 nn ------ 4 STZ nn_x MOV [nn+X],0 m [D+nn+X]=0 9C nn nn ------ 4 STZ nnnn MOV [nnnn],0 m [DB:nnnn]=0 9E nn nn ------ 5 STZ nnnn_x MOV [nnnn+X],0 m [DB:nnnn+X]=0 85 nn ------ 3 STA nn MOV [nn],A m [D+nn]=A 95 nn ------ 4 STA nn,X MOV [nn+X],A m [D+nn+X]=A 83 nn ------ STA nn,S MOV [nn+S],A m [nn+S]=A 8D nn nn ------ 4 STA nnnn MOV [nnnn],A m [DB:nnnn]=A 9D nn nn ------ 5 STA nnnn,X MOV [nnnn+X],A m [DB:nnnn+X]=A 99 nn nn ------ 5 STA nnnn,Y MOV [nnnn+Y],A m [DB:nnnn+Y]=A 8F nn nn nn ------ STA nnnnnn MOV [nnnnnn],A m [nnnnnn]=A 9F nn nn nn ------ STA nnnnnn,X MOV [nnnnnn+X],A m [nnnnnn+X]=A 81 nn ------ 6 STA (nn,X) MOV [[nn+X]],A m [WORD[D+nn+X]]=A 91 nn ------ 6 STA (nn),Y MOV [[nn]+Y],A m [WORD[D+nn]+Y]=A 92 nn ------ STA (nn) MOV [[nn]],A m [WORD[D+nn]]=A 93 nn ------ STA (nn,S),Y MOV [[nn+S]+Y],A m [WORD[nn+S]+Y]=A 87 nn ------ STA [nn] MOV [FAR[nn]],A m [FAR[D+nn]]=A 97 nn ------ STA [nn],y MOV [FAR[nn]+Y],A m [FAR[D+nn]+Y]=A 86 nn ------ 3 STX nn MOV [nn],X x [D+nn]=X 96 nn ------ 4 STX nn,Y MOV [nn+Y],X x [D+nn+Y]=X 8E nn nn ------ 4 STX nnnn MOV [nnnn],X x [DB:nnnn]=X 84 nn ------ 3 STY nn MOV [nn],Y x [D+nn]=Y 94 nn ------ 4 STY nn,X MOV [nn+X],Y x [D+nn+X]=Y 8C nn nn ------ 4 STY nnnn MOV [nnnn],Y x [DB:nnnn]=Y Push/Pull (Stack) Opcode Flags Clks Native Nocash Bits Effect 48 ------ 3 PHA PUSH A m [S]=A DA ------ 3 PHX PUSH X x [S]=X 5A ------ 3 PHY PUSH Y x [S]=Y 08 ------ 3 PHP PUSH P 8 [S]=P 8B ------ 3 PHB PUSH DB 8 [S]=DB 4B ------ 3 PHK PUSH PB 8 [S]=PB 0B ------ 4 PHD PUSH D 16 [S]=D D4 nn ------ 6 PEI nn PUSH WORD[nn] 16 [S]=WORD[D+nn] F4 nn nn ------ 5 PEA nnnn PUSH nnnn 16 [S]=NNNN 62 nn nn ------ 6 PER rel16 PUSH disp16 16 [S]=$+3+disp 68 nz---- 4 PLA POP A m A=[S] FA nz---- 4 PLX POP X x X=[S] 7A nz---- 4 PLY POP Y x Y=[S] 2B nz---- 5 PLD POP D 16 D=[S] AB nz---- 4 PLB POP DB 8 DB=[S] 28 nzcidv 4 PLP POP P 8 P=[S] Notes: PLA sets Z and N according to content of A. The B-flag and unused flags cannot be changed by PLP, these flags are always written as "1" by PHP. Memory Block Transfer Commands Opcode Flags Clks Native Nocash ;Notes 44 dd ss ------ 7x MVP ss,dd LDDR [dd:Y],[ss:X],A+1 ;DEC X/Y 54 dd ss ------ 7x MVN ss,dd LDIR [dd:Y],[ss:X],A+1 ;INC X/Y Sets DB=dstbank (!), copies one byte from [srcbank:X] to [dstbank:Y], increments or decrements X and Y (8bit or 16bit, depending on X and E flags), decrements A (all 16bits, no matter of M and E flags), continues at next opcode when resulting A=FFFFh, otherwise sets PC=PC-3 (thus repeats the transfer opcode). Note: The native opcode names (MVP/MVN, Move Positive/Negative) are chosen so that "positive" refers to transfers from "to higher" memory addresses (which would matter on overlapping source/dest blocks), accordingly, the practical meaning is that "positive" means to DECREASE the X,Y registers. CPU Arithmetic/Logical Operations --------------------------------- ALU Opcodes Base Flags Native Nocash Operands Name Function 00 nz---- ORA op OR A,op OR A=A OR op 20 nz---- AND op AND A,op AND A=A AND op 40 nz---- EOR op XOR A,op XOR A=A XOR op 60 nzc--v ADC op ADC A,op Add A=A+C+op E0 nzc--v SBC op SBC A,op Subtract A=A+C-1-op C0 nzc--- CMP op CMP A,op Compare A-op E0 nzc--- CPX op CMP X,op Compare X-op C0 nzc--- CPY op CMP Y,op Compare Y-op alu_types (Operands for OR,AND,XOR,ADC,SBC,CMP Opcodes) Opcode Clks Native Nocash Name Effect Base+09 nn 2 #nn nn Immediate nn Base+05 nn 3 nn [nn] Zero Page [D+nn] Base+15 nn 4 nn,X [nn+X] Zero Page,X [D+nn+X] Base+0D nn nn 4 nnnn [nnnn] Absolute [DB:nnnn] Base+1D nn nn 4* nnnn,X [nnnn+X] Absolute,X [DB:nnnn+X] Base+19 nn nn 4* nnnn,Y [nnnn+Y] Absolute,Y [DB:nnnn+Y] Base+01 nn 6 (nn,X) [[nn+X]] (Indirect,X) [WORD[D+nn+X]] Base+11 nn 5* (nn),Y [[nn]+Y] (Indirect),Y [WORD[D+nn]+Y] Base+12 nn (nn) [[nn]] (Indirect) [WORD[D+nn]] Base+03 nn nn,S [nn+S] [nn+S] Base+13 nn (nn,S),Y [[nn+S]+Y] [WORD[nn+S]+Y] Base+07 nn [nn] [FAR[nn]] [FAR[D+nn]] Base+17 nn [nn],y [FAR[nn]+Y] [FAR[D+nn]+Y] Base+0F nn nn nn nnnnnn [nnnnnn] [nnnnnn] Base+1F nn nn nn nnnnnn,X [nnnnnn+X] [nnnnnn+X] * Add one cycle if indexing crosses a page boundary. cpx_types (Operands for CMP Opcodes with X,Y Operand) Opcode Clks Native Nocash Name Effect Base+00 nn 2 #nn nn Immediate nn Base+04 nn 3 nn [nn] Zero Page [D+nn] Base+0C nn nn 4 nnnn [nnnn] Absolute [DB:nnnn] Bit Test Opcode Flags Clks Native Nocash Operand 24 nn xz---x 3 BIT nn TEST A,[nn] [D+nn] 2C nn nn xz---x 4 BIT nnnn TEST A,[nnnn] [DB:nnnn] 34 nn xz---x BIT nn,X TEST A,[nn+X] [D+nn+X] 3C nn nn xz---x BIT nnnn,X TEST A,[nnnn+X] [DB:nnnn+X] 89 nn -z---- BIT #nn TEST A,nn nn Flags are set as "Z=((A AND op)=0)", and "N=op.Bit(MSB)", and "V=op.Bit(MSB-1)". Where MSB=bit15/bit7, and MSB-1=bit14/bit6 (depending on M-flag). Note that N and V do rely only on "op" (ie. not on "A AND op"). Increment by one Opcode Clks Native Nocash Effect E6 nn nz---- 5 INC nn INC [nn] [D+nn]=[D+nn]+1 F6 nn nz---- 6 INC nn,X INC [nn+X] [D+nn+X]=[D+nn+X]+1 EE nn nn nz---- 6 INC nnnn INC [nnnn] [DB:nnnn]=[DB:nnnn]+1 FE nn nn nz---- 7 INC nnnn,X INC [nnnn+X] [DB:nnnn+X]=[DB:nnnn+X]+1 E8 nz---- 2 INX INC X X=X+1 C8 nz---- 2 INY INC Y Y=Y+1 1A nz---- 2 INA INC A A=A+1 Decrement by one Opcode Clks Native Nocash Effect C6 nn nz---- 5 DEC nn DEC [nn] [D+nn]=[D+nn]-1 D6 nn nz---- 6 DEC nn,X DEC [nn+X] [D+nn+X]=[D+nn+X]-1 CE nn nn nz---- 6 DEC nnnn DEC [nnnn] [DB:nnnn]=[DB:nnnn]-1 DE nn nn nz---- 7 DEC nnnn,X DEC [nnnn+X] [DB:nnnn+X]=[DB:nnnn+X]-1 CA nz---- 2 DEX DEC X X=X-1 88 nz---- 2 DEY DEC Y Y=Y-1 3A nz---- 2 DEA DEC A A=A-1 TSB/TRB (Test and Set/Reset) Opcode Clks Native Nocash 04 nn -z---- 5 TSB nn SET [nn],A ;\"TEST op,A" --> z 0C nn nn -z---- 6 TSB nnnn SET [nnnn],A ;/then "OR op,A" 14 nn -z---- 5 TRB nn CLR [nn],A ;\"TEST op,A" --> z 1C nn nn -z---- 6 TRB nnnn CLR [nnnn],A ;/then "AND op,NOT A" CPU Rotate and Shift Instructions --------------------------------- Shift Left Logical/Arithmetic Opcode Clks Native Nocash Effect 0A nzc--- 2 ASL A SHL A SHL A 06 nn nzc--- 5 ASL nn SHL [nn] SHL [D+nn] 16 nn nzc--- 6 ASL nn,X SHL [nn+X] SHL [D+nn+X] 0E nn nn nzc--- 6 ASL nnnn SHL [nnnn] SHL [DB:nnnn] 1E nn nn nzc--- 7 ASL nnnn,X SHL [nnnn+X] SHL [DB:nnnn+X] Shift Right Logical 4A 0zc--- 2 LSR A SHR A SHR A 46 nn 0zc--- 5 LSR nn SHR [nn] SHR [D+nn] 56 nn 0zc--- 6 LSR nn,X SHR [nn+X] SHR [D+nn+X] 4E nn nn 0zc--- 6 LSR nnnn SHR [nnnn] SHR [DB:nnnn] 5E nn nn 0zc--- 7 LSR nnnn,X SHR [nnnn+X] SHR [DB:nnnn+X] Rotate Left through Carry 2A nzc--- 2 ROL A RCL A RCL A 26 nn nzc--- 5 ROL nn RCL [nn] RCL [D+nn] 36 nn nzc--- 6 ROL nn,X RCL [nn+X] RCL [D+nn+X] 2E nn nn nzc--- 6 ROL nnnn RCL [nnnn] RCL [DB:nnnn] 3E nn nn nzc--- 7 ROL nnnn,X RCL [nnnn+X] RCL [DB:nnnn+X] Rotate Right through Carry 6A nzc--- 2 ROR A RCR A RCR A 66 nn nzc--- 5 ROR nn RCR [nn] RCR [D+nn] 76 nn nzc--- 6 ROR nn,X RCR [nn+X] RCR [D+nn+X] 6E nn nn nzc--- 6 ROR nnnn RCR [nnnn] RCR [DB:nnnn] 7E nn nn nzc--- 7 ROR nnnn,X RCR [nnnn+X] RCR [DB:nnnn+X] Notes: ROR instruction is available on MCS650X microprocessors after June, 1976. ROL and ROR rotate an 8bit value through carry (rotates 9bits in total). CPU Jump and Control Instructions --------------------------------- Normal Jumps Opcode Flags Clks Native Nocash Effect 80 dd ------ 3xx BRA disp8 JMP disp PC=PC+/-disp8 82 dd dd ------ 4 BRL disp16 JMP disp PC=PC+/-disp16 4C nn nn ------ 3 JMP nnnn JMP nnnn PC=nnnn 5C nn nn nn ------ 4 JMP nnnnnn JMP nnnnnn PB:PC=nnnnnn 6C nn nn ------ 5 JMP (nnnn) JMP [nnnn] PC=WORD[00:nnnn] 7C nn nn ------ 6 JMP (nnnn,X) JMP [nnnn+X] PC=WORD[PB:nnnn+X] DC nn nn ------ 6 JML ... JMP FAR[nnnn] PB:PC=[00:nnnn] 20 nn nn ------ 6 JSR nnnn CALL nnnn [S]=PC+2,PC=nnnn 22 nn nn nn ------ 4 JSL nnnnnn CALL nnnnnn PB:PC=nnnnnn [S]=PB:PC+3 FC nn nn ------ 6 JSR (nnnn,X) CALL [nnnn+X] PC=WORD[PB:nnnn+X] [S]=PC 40 nzcidv 6 RTI RETI P=[S+1],PB:PC=[S+2],S=S+4 6B ------ ? RTL RETF PB:PC=[S+1]+1, S=S+3 60 ------ 6 RTS RET PC=[S+1]+1, S=S+2 Note: RTI cannot modify the B-Flag or the unused flag. Glitch: For JMP [nnnn] the operand word cannot cross page boundaries, ie. JMP [03FFh] would fetch the MSB from [0300h] instead of [0400h]. Very simple workaround would be to place a ALIGN 2 before the data word. Conditional Branches (Branch on condition, to PC=PC+/-nn) Opcode Flags Clks Native Nocash Condition (jump if) 10 dd ------ 2** BPL JNS disp ;N=0 (plus/positive) 30 dd ------ 2** BMI JS disp ;N=1 (minus/negative/signed) 50 dd ------ 2** BVC JNO disp ;V=0 (no overflow) 70 dd ------ 2** BVS JO disp ;V=1 (overflow) 90 dd ------ 2** BCC/BLT JNC/JB disp ;C=0 (less/below/no carry) B0 dd ------ 2** BCS/BGE JC/JAE disp ;C=1 (above/greater/equal/carry) D0 dd ------ 2** BNE/BZC JNZ/JNE disp ;Z=0 (not zero/not equal) F0 dd ------ 2** BEQ/BZS JZ/JE disp ;Z=1 (zero/equal) ** The execution time is 2 cycles if the condition is false (no branch executed). Otherwise, 3 cycles if the destination is in the same memory page, or 4 cycles if it crosses a page boundary (see below for exact info). Note: After subtractions (SBC or CMP) carry=set indicates above-or-equal, unlike as for 80x86 and Z80 CPUs. Interrupts, Exceptions, Breakpoints Opcode 6502 65C816 00 BRK Break B=1 [S]=$+2,[S]=P,D=0 I=1, PB=00, PC=[00FFFE] [00FFE6] 02 COP ;65C816 B=1 [S]=$+2,[S]=P,D=0 I=1, PB=00, PC=[00FFF4] [00FFE4] -- /ABORT ;65C816 PB=00, PC=[00FFF8] [00FFE8] -- /IRQ Interrupt B=0 [S]=PC, [S]=P,D=0 I=1, PB=00, PC=[00FFFE] [00FFEE] -- /NMI NMI B=0 [S]=PC, [S]=P,D=0 I=1, PB=00, PC=[00FFFA] [00FFEA] -- /RESET Reset D=0 E=1 I=1 D=0000, DB=00 PB=00, PC=[00FFFC] N/A Notes: IRQs can be disabled by setting the I-flag, a BRK command, a NMI, and a /RESET signal cannot be masked by setting I. Exceptions do first change the B-flag (in 6502 mode), then write P to stack, and then set the I-flag, the D-flag IS cleared (unlike as on original 6502). In 6502 mode, the same vector is shared for BRK and IRQ, software can separate between BRK and IRQ by examining the pushed B-flag only. The RTI opcode can be used to return from BRK/IRQ/NMI, note that using the return address from BRK skips one dummy/parameter byte following after the BRK opcode. Software or hardware must take care to acknowledge or reset /IRQ or /NMI signals after processing it. IRQs are executed whenever "/IRQ=LOW AND I=0". NMIs are executed whenever "/NMI changes from HIGH to LOW". If /IRQ is kept LOW then same (old) interrupt is executed again as soon as setting I=0. If /NMI is kept LOW then no further NMIs can be executed. CPU Control Opcode Flags Clks Native Nocash Effect 18 --0--- 2 CLC CLC C=0 ;Clear carry flag 58 ---0-- 2 CLI EI I=0 ;Clear interrupt disable bit D8 ----0- 2 CLD CLD D=0 ;Clear decimal mode B8 -----0 2 CLV CL? V=0 ;Clear overflow flag 38 --1--- 2 SEC STC C=1 ;Set carry flag 78 ---1-- 2 SEI DI I=1 ;Set interrupt disable bit F8 ----1- 2 SED STD D=1 ;Set decimal mode C2 nn xxxxxx 3 REP #nn CLR P,nn P=P AND NOT nn E2 nn xxxxxx 3 SEP #nn SET P,nn P=P OR nn FB --c--- 2 XCE XCE C=E, E=C Special Opcodes Opcode Flags Clks Native Nocash DB ------ - STP KILL ;STOP/KILL EB nz---- 3 XBA SWAP A ;A=B, B=A, NZ=LSB CB ------ 3x WAI HALT ;HALT 42 nn 2 WDM #nn NUL nn ;No operation EA ------ 2 NOP NOP ;No operation WAI/HALT stops the CPU until an exception (usually an IRQ or NMI) request occurs; in case of IRQs this works even if IRQs are disabled (via I=1). Conditional Branch Page Crossing The branch opcode with parameter takes up two bytes, causing the PC to get incremented twice (PC=PC+2), without any extra boundary cycle. The signed parameter is then added to the PC (PC+disp), the extra clock cycle occurs if the addition crosses a page boundary (next or previous 100h-page). CPU Assembler Directives/Syntax ------------------------------- Below are some common 65XX assembler directives, and the corresponding expressions in 80XX-style language. 65XX-style 80XX-style Expl. .native .nocash select native or nocash syntax *=$c100 org 0c100h sets the assumed origin in memory *=*+8 org $+8 increments origin, does NOT produce data label label: sets a label equal to the current address label=$dc00 label equ 0dc00h assigns a value or address to label .by $00 db 00h defines a (list of) byte(s) in memory .byt $00 defb 00h same as .by and db .wd $0000 dw 0000h defines a (list of) word(s) in memory .end end indicates end of source code file |nn [|nn] force 16bit "00NN" instead 8bit "NN" #nnnn nnnn DIV 100h isolate upper 8bits of 16bit value Special Directives .65xx Select 6502 Instruction Set .nes Create NES ROM-Image with .NES extension .c64_prg Create C64 file with .PRG extension/stub/fixed entry .c64_p00 Create C64 file with .P00 extension/stub/fixed entry/header .vic20_prg Create VIC20/C64 file with .PRG extension/stub/relocated entry end entry End of Source, the parameter specifies the entrypoint The C64 files contain Basic Stub "10 SYS" with default ORG 80Eh. VIC20 Stub The VIC20 Stub is "10 SYSPEEK(44)*256+" with default ORG 1218h, this relocates the entryoint relative to the LOAD address (for C64: 818h, for VIC20: 1018h (Unexpanded), 0418h (3K Expanded), 1218h (8K and more Expansion). It does NOT relocate absolute addresses in the program, if the program wishes to run at a specific memory location, then it must de-relocate itself from the LOAD address to the desired address. CPU Glitches ------------ Dummy Write Cycles in Read-Modify-Opcodes The original 6502 CPU includes a dummy-write cycle in all Read-Modify opcodes (ie. INC, DEC, Shift/Rotate). The 65C816 does NOT reproduce this effect (neither when E=0, nor when E=1). Dummy Read Cycles at Page-Wraps [Below applies to original 6502 CPUs] [Unknown if 65C816 has similar effects on page- and/or bank-wraps?] Dummy reads occur when reads from [nnnn+X] or [nnnn+Y] or [WORD[nn]+Y] are crossing page boundaries, this applies only to raw read-opcodes, not for write or read-and-modify opcodes (ie. only for opcodes that include an extra clock cycle on page boundaries, such as LDA, CMP, etc.) For above reads, the CPU adds the index register to the lower 8bits of the 16bit memory address, and does then read from the resulting memory address, if the addition caused a carry-out, then an extra clock cycle is used to increment the upper 8bits of the address, and to read from the correct memory location. For example, a read from [1280h+X] with X=C0h produces a dummy read from [1240h], followed by the actual read from [1340h]. Dummy reads cause no problems with normal ROM or RAM, but may cause problems with read-sensitive I/O ports (eg. IRQ flags that are automatically cleared after reading, or data-registers that are automatically incrementing associated memory pointers, etc.) CPU The 65XX Family ------------------- Different versions of the 6502: All of these processors are the same concerning the software-side: 6501 Some sort of 6502 prototype 6502 Used in the CBM floppies and some other 8 bit computers. 6507 Used in Atari 2600, 28pins (only 13 address lines, no /IRQ, no /NMI). 6510 Used in C64, with built-in 6bit I/O port. 7501 Used in C16,C116,Plus/4, with built-in 7bit I/O Port, without /NMI pin. 8500 Used in C64-II, with different pin-outs. 8501 Same as 7501 8502 Used in C128s. Some processors of the family which are not 100% compatible: 65C02 Extension of the 6502 65SC02 Small version of the 65C02 which lost a few opcodes again. 65CE02 Extension of the 65C02, used in the C65. 65C816 Extended 65C02 with new opcodes and 16 bit operation modes. 2A03 Nintendo NES/Famicom, modified 6502 with built-in sound controller. About/Credits ------------- About This document is part of the no$sns emulator/debugger help text. Copyright 2012 by Martin Korth (nocash). PPU and APU specs are widely based on Anomie's great specs (on that part I've mainly rearranged and reformatted the Anomie's txt files, verified most of it on real hardware, and discovered only a few additional details). For information on Add-Ons like Controllers or Cartridges with Coprocessors: There haven't been any all-in-one specs (not even a complete list of existing add-ons), so I needed to collect scattered fragments of information from hundreds of webpages (and do a lot of puzzling and reverse-engineering on my own). The result should be a fairly complete document that covers almost everything about the SNES hardware. There are still thousands of missing details (marked by words like unknown, whatever, might, maybe, probably, or by question marks). Info on such details (or donated hardware for research purposes) would be very welcome! Credits - Anomie (first ever reasonable/detailed SNES specs) - Boris (donated a SNES and SGB back in 1999) - SNES Central (cartridge PCB photos/scans) - SNES Development (http://wiki.superfamicom.org/) - snes9x - open source emulator (info on undocumented coprocessors) - http://www.datasheetarchive.com/ - byuu (coprocessor decapping, info on snes hw glitches, cart memory maps) - Segher's weird and wonderful CIC (rev-engineered CIC opcodes) - DogP (lots of hard to get info on NSS) Plus many-many other people who released valueable bits of information on their own webpages, wikis, and in various forum threads. Homepage http://problemkaputt.de/sns.htm - no$sns emulator/debugger updates http://problemkaputt.de/fullsnes.htm - snes specs updates (html version) http://problemkaputt.de/fullsnes.txt - snes specs updates (text version) http://problemkaputt.de/email.htm - contact Index ----- --> Contents --> SNES I/O Map --> SNES Memory --> SNES Memory Map --> SNES Memory Control --> SNES Memory Work RAM Access --> SNES Memory OAM Access (Sprite Attributes) --> SNES Memory VRAM Access (Tile and BG Map) --> SNES Memory CGRAM Access (Palette Memory) --> SNES DMA Transfers --> SNES DMA and HDMA Start/Enable Registers --> SNES DMA and HDMA Channel 0..7 Registers --> SNES DMA and HDMA Notes --> SNES Picture Processing Unit (PPU) --> SNES PPU Control --> SNES PPU BG Control --> SNES PPU Rotation/Scaling --> SNES PPU Sprites (OBJs) --> SNES PPU Video Memory (VRAM) --> SNES PPU Color Palette Memory (CGRAM) and Direct Colors --> SNES PPU Window --> SNES PPU Color-Math --> SNES PPU Timers and Status --> SNES PPU Interrupts --> SNES PPU Resolution --> SNES PPU Offset-Per-Tile Mode --> SNES Audio Processing Unit (APU) --> SNES APU Memory and I/O Map --> SNES APU Block Diagram --> SNES APU SPC700 CPU Overview --> SNES APU SPC700 CPU Load/Store Commands --> SNES APU SPC700 CPU ALU Commands --> SNES APU SPC700 CPU Jump/Control Commands --> SNES APU SPC700 I/O Ports --> SNES APU Main CPU Communication Port --> SNES APU DSP BRR Samples --> SNES APU DSP BRR Pitch --> SNES APU DSP ADSR/Gain Envelope --> SNES APU DSP Volume Registers --> SNES APU DSP Control Registers --> SNES APU DSP Echo Registers --> SNES APU Low Level Timings --> SNES Maths Multiply/Divide --> SNES Controllers --> SNES Controllers I/O Ports - Automatic Reading --> SNES Controllers I/O Ports - Manual Reading --> SNES Controllers Hardware ID Codes --> SNES Controllers Detecting Controller Support of ROM-Images --> SNES Controllers Joypad --> SNES Controllers Mouse (Two-button Mouse) --> SNES Controllers Mouse Games --> SNES Controllers Multiplayer 5 (MP5) (Five Player Adaptor) --> SNES Controllers Multiplayer 5 - Unsupported Hardware --> SNES Controllers Multiplayer 5 - Supported Games --> SNES Controllers SuperScope (Lightgun) --> SNES Controllers Konami Justifier (Lightgun) --> SNES Controllers M.A.C.S. (Lightgun) --> SNES Controllers Twin Tap --> SNES Controllers Miracle Piano --> SNES Controllers Miracle Piano Controller Port --> SNES Controllers Miracle Piano MIDI Commands --> SNES Controllers Miracle Piano Instruments --> SNES Controllers Miracle Pinouts and Component List --> SNES Controllers NTT Data Pad (joypad with numeric keypad) --> SNES Controllers X-Band Keyboard --> SNES Controllers Tilt/Motion Sensors --> SNES Controllers Lasabirdie (golf club) --> SNES Controllers Exertainment (bicycle exercising machine) --> SNES Controllers Exertainment - I/O Ports --> SNES Controllers Exertainment - RS232 Controller --> SNES Controllers Exertainment - RS232 Data Packets & Configuration --> SNES Controllers Exertainment - RS232 Data Packets Login Phase --> SNES Controllers Exertainment - RS232 Data Packets Biking Phase --> SNES Controllers Exertainment - Drawings --> SNES Controllers Pachinko --> SNES Controllers Other Inputs --> SNES Add-On Turbo File (external backup memory for storing game positions) --> SNES Add-On Turbo File - TFII Mode Transmission Protocol --> SNES Add-On Turbo File - TFII Mode Filesystem --> SNES Add-On Turbo File - STF Mode Transmission Protocol --> SNES Add-On Turbo File - STF Mode Filesystem --> SNES Add-On Turbo File - Games --> SNES Add-On Barcode Battler (barcode reader) --> SNES Add-On Barcode Transmission I/O --> SNES Add-On Barcode Battler Drawings --> SNES Add-On SFC Modem (for JRA PAT) --> SNES Add-On SFC Modem - Data I/O --> SNES Add-On SFC Modem - Misc --> SNES Add-On Voice-Kun (IR-transmitter/receiver for use with CD Players) --> SNES 3D Glasses --> SNES Cartridges --> SNES Cartridge ROM Header --> SNES Cartridge PCBs --> SNES Cartridge ROM-Image Headers and File Extensions --> SNES Cartridge ROM-Image Interleave --> SNES Cartridge CIC Lockout Chip --> SNES Cartridge CIC Pseudo Code --> SNES Cartridge CIC Instruction Set --> SNES Cartridge CIC Notes --> SNES Cartridge CIC Versions --> SNES Cart LoROM Mapping (ROM divided into 32K banks) (around 1500 games) --> SNES Cart HiROM Mapping (ROM divided into 64K banks) (around 500 games) --> SNES Cart SA-1 (programmable 65C816 CPU) (aka Super Accelerator) (35 games) --> SNES Cart SA-1 Games --> SNES Cart SA-1 I/O Map --> SNES Cart SA-1 Interrupt/Control on SNES Side --> SNES Cart SA-1 Interrupt/Control on SA-1 Side --> SNES Cart SA-1 Timer --> SNES Cart SA-1 Memory Control --> SNES Cart SA-1 DMA Transfers --> SNES Cart SA-1 Character Conversion --> SNES Cart SA-1 Arithmetic Maths --> SNES Cart SA-1 Variable-Length Bit Processing --> SNES Cart GSU-n (programmable RISC CPU) (aka Super FX/Mario Chip)(10 games) --> SNES Cart GSU-n List of Games, Chips, and PCB versions --> SNES Cart GSU-n Memory Map --> SNES Cart GSU-n I/O Map --> SNES Cart GSU-n General I/O Ports --> SNES Cart GSU-n Bitmap I/O Ports --> SNES Cart GSU-n CPU MOV Opcodes --> SNES Cart GSU-n CPU ALU Opcodes --> SNES Cart GSU-n CPU JMP and Prefix Opcodes --> SNES Cart GSU-n CPU Pseudo Opcodes --> SNES Cart GSU-n CPU Misc --> SNES Cart GSU-n Code-Cache --> SNES Cart GSU-n Pixel-Cache --> SNES Cart GSU-n Other Caches --> SNES Cart Capcom CX4 (programmable RISC CPU) (Mega Man X 2-3) (2 games) --> SNES Cart Capcom CX4 - I/O Ports --> SNES Cart Capcom CX4 - Opcodes --> SNES Cart Capcom CX4 - Functions --> SNES Cart DSP-n/ST010/ST011 (pre-programmed NEC uPD77C25 CPU) (23 games) --> SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - Registers & Flags & Overview --> SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - ALU and LD Instructions --> SNES Cart DSP-n/ST010/ST011 - NEC uPD77C25 - JP Instructions --> SNES Cart DSP-n/ST010/ST011 - List of Games using that chips --> SNES Cart DSP-n/ST010/ST011 - BIOS Functions --> SNES Cart Seta ST018 (pre-programmed ARM CPU) (1 game) --> ARM CPU Reference --> ARM Register Set --> ARM Flags & Condition Field (cond) --> ARM 26bit Memory Interface --> ARM Exceptions --> ARM Instruction Summary --> ARM Opcodes: Branch and Branch with Link (B, BL, SWI) --> ARM Opcodes: Data Processing (ALU) --> ARM Opcodes: PSR Transfer (MRS, MSR) --> ARM Opcodes: Multiply and Multiply-Accumulate (MUL, MLA) --> ARM Opcodes: Memory: Block Data Transfer (LDM, STM) --> ARM Opcodes: Memory: Single Data Transfer (LDR, STR) --> ARM Opcodes: Memory: Single Data Swap (SWP) --> ARM Opcodes: Coprocessor Instructions (MRC/MCR, LDC/STC, CDP) --> ARM Pseudo Instructions and Directives --> ARM Instruction Cycle Times --> ARM Versions --> SNES Cart OBC1 (OBJ Controller) (1 game) --> SNES Cart S-DD1 (Data Decompressor) (2 games) --> SNES Cart S-DD1 Decompression Algorithm --> SNES Cart SPC7110 (Data Decompressor) (3 games) --> SNES Cart SPC7110 Memory and I/O Map --> SNES Cart SPC7110 Decompression I/O Ports --> SNES Cart SPC7110 Direct Data ROM Access --> SNES Cart SPC7110 Multiply/Divide Unit --> SNES Cart SPC7110 with RTC-4513 Real Time Clock (1 game) --> SNES Cart SPC7110 Decompression Algorithm --> SNES Cart SPC7110 Notes --> SNES Cart Unlicensed Variants --> SNES Cart S-RTC (Realtime Clock) (1 game) --> SNES Cart Super Gameboy --> SNES Cart Satellaview (satellite receiver & mini flashcard) --> SNES Cart Satellaview I/O Map --> SNES Cart Satellaview I/O Ports of MCC Memory Controller --> SNES Cart Satellaview I/O Receiver Data Streams --> SNES Cart Satellaview I/O Receiver Data Streams (Notes) --> SNES Cart Satellaview I/O Receiver Control --> SNES Cart Satellaview I/O FLASH Detection (Type 1,2,3,4) --> SNES Cart Satellaview I/O FLASH Access (Type 1,3,4) --> SNES Cart Satellaview I/O FLASH Access (Type 2) --> SNES Cart Satellaview Packet Headers and Frames --> SNES Cart Satellaview Channels and Channel Map --> SNES Cart Satellaview Town Status Packet --> SNES Cart Satellaview Directory Packet --> SNES Cart Satellaview Expansion Data (at end of Directory Packets) --> SNES Cart Satellaview Other Packets --> SNES Cart Satellaview Buildings --> SNES Cart Satellaview People --> SNES Cart Satellaview Items --> SNES Cart Satellaview SRAM (Battery-backed) --> SNES Cart Satellaview FLASH File Header --> SNES Cart Satellaview BIOS Function Summary --> SNES Cart Satellaview Interpreter Token Summary --> SNES Cart Satellaview Chipsets --> SNES Cart Data Pack Slots (satellaview-like mini-cartridge slot) --> SNES Cart Nintendo Power (flashcard) --> SNES Cart Nintendo Power - New Stuff --> SNES Cart Nintendo Power - I/O Ports --> SNES Cart Nintendo Power - FLASH Commands --> SNES Cart Nintendo Power - Directory --> SNES Cart Sufami Turbo (Mini Cartridge Adaptor) --> SNES Cart Sufami Turbo General Notes --> SNES Cart Sufami Turbo ROM/RAM Headers --> SNES Cart Sufami Turbo BIOS Functions & Charset --> SNES Cart X-Band (2400 baud Modem) --> SNES Cart X-Band Misc --> SNES Cart X-Band I/O Map --> SNES Cart X-Band I/O - Memory Patch/Mapping --> SNES Cart X-Band I/O - Smart Card Reader --> SNES Cart X-Band I/O - LED and Debug --> SNES Cart X-Band I/O - Whatever Stuff (External FIFO for Modem?) --> SNES Cart X-Band I/O - Rockwell Modem Ports --> SNES Cart X-Band Rockwell Notes --> SNES Cart X-Band BIOS Functions --> SNES Cart FLASH Backup --> SNES Cart Cheat Devices --> SNES Cart Cheat Devices - Code Formats --> SNES Cart Cheat Devices - Game Genie --> SNES Cart Cheat Devices - Pro Action Replay I/O Ports --> SNES Cart Cheat Devices - Pro Action Replay Memory --> SNES Cart Cheat Devices - X-Terminator & Game Wizard --> SNES Cart Cheat Devices - Game Saver --> SNES Cart Cheat Devices - Theory --> SNES Cart Tri-Star (aka Super 8) (allows to play NES games on the SNES) --> SNES Cart Pirate X-in-1 Multicarts (1) --> SNES Cart Pirate X-in-1 Multicarts (2) --> SNES Cart Copiers --> SNES Cart Copiers - Front Fareast (Super Magicom & Super Wild Card) --> SNES Cart Copiers - CCL (Supercom & Pro Fighter) --> SNES Cart Copiers - Bung (Game Doctor) --> SNES Cart Copiers - Super UFO --> SNES Cart Copiers - Sane Ting (Super Disk Interceptor) --> SNES Cart Copiers - Gamars Copier --> SNES Cart Copiers - Venus (Multi Game Hunter) --> SNES Cart Copiers - Others --> SNES Cart Copiers - Misc --> SNES Cart Copiers - Floppy Disc Controllers --> SNES Cart Copiers - Floppy Disc NEC uPD765 Commands --> SNES Cart Copiers - Floppy Disc FAT12 Format --> SNES Cart Copiers - BIOSes --> SNES Cart CDROM Drive --> SNES Cart CDROM - Memory and I/O Map --> SNES Cart CDROM - CDROM Bootsector and Volume Descriptor --> SNES Cart CDROM - BIOS Cartridge --> SNES Cart CDROM - BIOS Functions --> SNES Cart CDROM - Mechacon --> SNES Cart CDROM - Decoder/FIFO --> SNES Cart CDROM - Component List --> SNES Hotel Boxes and Arcade Machines --> NSS Memory and I/O Maps --> NSS I/O Ports - Control Registers --> NSS I/O Ports - Button Inputs and Coin Control --> NSS I/O Ports - RTC and OSD --> NSS I/O Ports - EEPROM and PROM --> NSS BIOS and INST ROM Maps --> NSS Interpreter Tokens --> NSS Controls --> NSS Games, BIOSes and ROM-Images --> NSS Component Lists --> NSS On-Screen Controller (OSD) --> SFC-Box Overview --> SFC-Box Coprocessor (HD64180) (extended Z80) --> SFC-Box Memory & I/O Maps --> SFC-Box I/O Ports (Custom Ports) --> SFC-Box I/O Ports (HD64180 Ports) --> SFC-Box OSD Chip (On-Screen Display Controller) --> SFC-Box GROM Format --> SFC-Box Component List (Cartridges) --> SFC-Box Component List (Console) --> RTC S-3520 (Real-Time Clock) --> Z80 CPU Specifications --> Z80 Register Set --> Z80 Flags --> Z80 Instruction Format --> Z80 Load Commands --> Z80 Arithmetic/Logical Commands --> Z80 Rotate/Shift and Singlebit Operations --> Z80 Jumpcommands & Interrupts --> Z80 I/O Commands --> Z80 Interrupts --> Z80 Meaningless and Duplicated Opcodes --> Z80 Garbage in Flag Register --> Z80 Compatibility --> Z80 Pin-Outs --> Z80 Local Usage --> HD64180 --> HD64180 Internal I/O Map --> HD64180 New Opcodes (Z80 Extension) --> HD64180 Serial I/O Ports (ASCI and CSI/O) --> HD64180 Timers (PRT and FRC) --> HD64180 Direct Memory Access (DMA) --> HD64180 Interrupts --> HD64180 Memory Mapping and Control --> HD64180 Extensions --> SNES Decompression Formats --> SNES Unpredictable Things --> SNES Timings --> SNES Timing Oscillators --> SNES Timing H/V Counters --> SNES Timing H/V Events --> SNES Timing PPU Memory Accesses --> SNES Pinouts --> SNES Controllers Pinouts --> SNES Audio/Video Connector Pinouts --> SNES Power Supply --> SNES Expansion Port (EXT) Pinouts --> SNES Cartridge Slot Pinouts --> SNES Chipset --> SNES Pinouts CPU Chip --> SNES Pinouts PPU Chips --> SNES Pinouts APU Chips --> SNES Pinouts ROM Chips --> SNES Pinouts RAM Chips --> SNES Pinouts CIC Chips --> SNES Pinouts MAD Chips --> SNES Pinouts RTC Chips --> SNES Pinouts Misc Chips --> SNES Pinouts GSU Chips --> SNES Pinouts CX4 Chip --> SNES Pinouts SA1 Chip --> SNES Pinouts Decompression Chips --> SNES Pinouts BSX Connectors --> SNES Pinouts NSS Connectors --> SNES Pinouts Nintendo Power Flashcarts --> SNES Common Mods --> SNES Controller Mods --> SNES Xboo Upload (WRAM Boot) --> CPU 65XX Microprocessor --> CPU Registers and Flags --> CPU Memory Addressing --> CPU Clock Cycles --> CPU Memory and Register Transfers --> CPU Arithmetic/Logical Operations --> CPU Rotate and Shift Instructions --> CPU Jump and Control Instructions --> CPU Assembler Directives/Syntax --> CPU Glitches --> CPU The 65XX Family --> About/Credits