draft --------------------------------------------------------------------------- Sega Game 1000 Specifications by Omar Cornut / Zoop Project started on the 04/27/99 Last updated on the 04/27/99 --------------------------------------------------------------------------- CPU: Zilog Z-80 at 3,579545 mhz Video: TMS9918. Resolution is 256x192. Sound: SN76489 Programmable Sound Generator, by Texas Instruments RAM: 8 kilobytes. VRAM: 16 kilobytes. Memory Map ---------- 0x0000 ------------------------------------------------ ROM (read-only) 0x8000 ------------------------------------------------ Unused on SG-1000 0xA000 ------------------------------------------------ RAM (read/write) 0xC000 ------------------------------------------------ Mirror of RAM (read/write) 0xFFFF ------------------------------------------------ IO Ports -------- 0xDC / 0xC0 : Joypad Port 1 (read-only) bit 0 : Joypad 1 Up bit 1 : Joypad 1 Down bit 2 : Joypad 1 Left bit 3 : Joypad 1 Right bit 4 : Joypad 1 Button 1 bit 5 : Joypad 1 Button 2 bit 6 : Joypad 2 Up bit 7 : Joypad 2 Down Low logic port. 0 = pressed, 1 = released 0xDD / 0xC1 : Joypad Port 2 (read-only) bit 0 : Joypad 2 Left bit 1 : Joypad 2 Right bit 2 : Joypad 2 Button 1 bit 3 : Joypad 2 Button 2 bit 4 : Reset Button Low logic port. 0 = pressed, 1 = released 0x7E : 0x7F : Programmable Sound Generator Output (write) 0xBE : VDP Data (read/write) Use to read and write to VRAM (not VDP Registers). 0xBF : VDP Address (write) To set an address, write two bytes: bbbbbbbb then 01aaaaaa Where bbbbbbbbaaaaaa is a 14-bit VRAM address. To write to a VDP register, write two bytes: bbbbbbbb then 1000aaaa Where aaaa is the VDP register number and bbbbbbbb the value to write to it. 0xBF : VDP Status Register (read) bit 5 : Sprite Collision Flag Set when two sprites overlap. bit 6 : Line Interrupt Flag (maybe unused in SG-1000 ?) Set when a line interrupt occurs. bit 7 : VSync flag Set when any interrupt occurs. Bit 6 and 7 are reset when the port is read. Interrupts ---------- An interrupts occur every 60th/second = CPU_CLOCK * 1000000 / 60 cycles. The SG-1000 only supports Z-80 interrupt in mode 1: - push PC register to stack - jump to 0x38 When returning from the interrupt with IRET, the PC register is restored. It's up to the interrupt routine to save other registers and restore them. Non Maskable Interrupts ----------------------- A NMI occurs when the Pause button is pressed. It's behaviour is the same as standard interrupt, except that the jumping location is 0x66. VDP Registers ------------- Register 0 ---------- bit 1 : video mode bit 0 bit 2 : video mode bit 1 bit 3 : video mode bit 2 Register 1 ---------- bit 0 : zoomed sprites (show 8x8 as 16x16 and 16x16 as 32x32) bit 1 : double sprite size (8x8 -> 16x16) bit 3 : video mode bit 3 bit 4 : video mode bit 4 bit 6 : display bit. set to 0 and the screen will stay black. Register 2 ---------- bit 0 -> Tile Map Address bit 10 bit 1 -> Tile Map Address bit 11 bit 2 -> Tile Map Address bit 12 bit 3 -> Tile Map Address bit 13 Register 3 ---------- Color Map Address in VRAM. The bitmask depend on the video mode: mode 0: 0x00 (text) mode 1: 0xFF (graphic 1) mode 2: 0x80 (graphic 2, the most common) Multiply the ANDed value by 0x40 and you have the address. Register 4 ---------- Tiles Starting Address in VRAM. The bitmask depend on the video mode: mode 0: 0x3F (text) mode 1: 0x3F (graphic 1) mode 2: 0x3C (graphic 2, the most common) Multiply the ANDed value by 0x8000 and you have the address. Register 5 ---------- Sprite Table Address Bits 0 to 6 -> multiply by 128 -> Start address of the table in VRAM Register 6 ---------- Sprite Starting Tile Address Multiplay value by 0x800 and you've got the address. Register 7 ---------- Bits 0 to 3 code for the transparent color. Setting them to 0 mean a black color, else the color is taken in the palette. Palette ------- The palette is constitued of 16 fixed colors, which 8-bit RGB values are: 0: transparent 1: black - 0x00, 0x00, 0x00 2: green - 0x20, 0xC0, 0x20 3: bright green - 0x60, 0xE0, 0x60 4: blue - 0x20, 0x20, 0xE0 5: bright blue - 0x40, 0x60, 0xE0 6: dark red - 0xA0, 0x20, 0x20 7: cyan (?) - 0x40, 0xC0, 0xE0 8: red - 0xE0, 0x20, 0x20 9: bright red - 0xE0, 0x60, 0x60 10: yellow - 0xC0, 0xC0, 0x20 11: bright yellow - 0xC0, 0xC0, 0x80 12: dark green - 0x20, 0x80, 0x20 13: pink - 0xC0, 0x40, 0xA0 14: gray - 0xA0, 0xA0, 0xA0 15: white - 0xE0, 0xE0, 0xE0 Graphics Modes -------------- All graphics modes display sprites after background. Resolution is 256x192 pixels = 32x24 tiles. Tile encoding ------------- A tile is 8x8 pixels large. Each lines of the tile is stored in one byte, therefore a tile is 8 bytes. As tiles can use two colors only, each bit set a pixel. Mode 0 Background ----------------- ... Mode 1 Background ----------------- ... Mode 2 Background ----------------- The screen is splitted in three 32x8 tiles blocks. Each use a different area to store the tile graphics: Tiles_Start_Address ------------------------------------- Tiles graphics for the top part Tiles_Start_Address + 0x0800 ---------------------------- Tiles graphics for the middle part Tiles_Start_Address + 0x1000 ---------------------------- Tiles graphics for the bottom part Tiles_Start_Address + 0x1800 ---------------------------- Usually used for sprites tiles graphics --------------------------------------------------------- Tiles number are raw stored, starting at the address specified by VDP Register 2. Tiles colors are raw stored, starting at the address specified by VDP Register 3. Each byte contains the background color in the first four bits and the foreground color in the last four bits. .....to complete Sprites ------- Sprite are shown in modes 1 and 2 only. The sprite table is 128 bytes: 0 + (n * 4) : Y coordinate 1 + (n * 4) : X coordinate 2 + (n * 4) : Tile Number. Clear bits 0 and 1 is sprites are doubled. 3 + (n * 4) : Bits 0 to 3 = Color. If color is 0, don't display the sprite. When bit 7 is set, shift sprite by 8 pixels. When Y = 208, stop displaying sprites.