From: slack Date: Tue, 9 Jan 2007 11:05:47 +0000 (+0000) Subject: Import inicial. X-Git-Tag: v0.1~78 X-Git-Url: http://slack.codemaniacs.com/git/?a=commitdiff_plain;h=2a9bd8781c99ee01ae185a892f480b9d7867b042;p=wenboi.git Import inicial. git-svn-id: http://slack.codemaniacs.com/wenboi@1 0666ae3d-8926-0410-aeff-ae84559ff337 --- 2a9bd8781c99ee01ae185a892f480b9d7867b042 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..274c684 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CXXFLAGS=-g -Wall -Weffc++ -Wstrict-null-sentinel -Wold-style-cast \ + -Woverloaded-virtual + +all: gbcore.o + +tests: tests/test_gbrom + +gbcore.o: gbcore.cc gbcore.h gbrom.h + g++ $(CXXFLAGS) -c -o $@ $< + +tests/test_gbrom: gbrom.cc gbrom.h + g++ -DTEST_GBROM -o $@ $< + +clean: + rm -f *.o tests/* + +.PHONY: clean tests all diff --git a/docs/GBCPUman.pdf b/docs/GBCPUman.pdf new file mode 100644 index 0000000..7cf38e1 Binary files /dev/null and b/docs/GBCPUman.pdf differ diff --git a/docs/pandocs.htm b/docs/pandocs.htm new file mode 100644 index 0000000..a5308a3 --- /dev/null +++ b/docs/pandocs.htm @@ -0,0 +1,2899 @@ + + Specifications + + +
 Pan Docs

+Overview
+
About the Pan Docs
+Game Boy Technical Data
+Memory Map
+
+I/O Ports
+
Video Display
+Sound Controller
+Joypad Input
+Serial Data Transfer (Link Cable)
+Timer and Divider Registers
+Interrupts
+CGB Registers
+SGB Functions
+
+CPU Specifications
+
CPU Registers and Flags
+CPU Instruction Set
+CPU Comparision with Z80
+
+Cartridges
+
The Cartridge Header
+Memory Bank Controllers
+Gamegenie/Shark Cheats
+
+Other
+
Power Up Sequence
+Reducing Power Consumption
+Sprite RAM Bug
+External Connectors
+
+
+
 About the Pan Docs

+
 =================================================================
+       Everything You Always Wanted To Know About GAMEBOY *
+ =================================================================
+

+
                     * but were afraid to ask
+

+
        Pan of -ATX- Document Updated by contributions from:
+     Marat Fayzullin, Pascal Felber, Paul Robson, Martin Korth
+             CPU, SGB, CGB, AUX specs by Martin Korth
+

+
                  Last updated 10/2001 by nocash
+               Previously updated 4-Mar-98 by kOOPa
+

+Forward
+
The following was typed up for informational purposes regarding the +inner workings on the hand-held game machine known as GameBoy, +manufactured and designed by Nintendo Co., LTD. This info is presented +to inform a user on how their Game Boy works and what makes it "tick". +GameBoy is copyrighted by Nintendo Co., LTD. Any reference to +copyrighted material is not presented for monetary gain, but for +educational purposes and higher learning.
+
+Available Document Formats
+
The present version of this document is available in Text and Html format:
+
  http://www.work.de/nocash/pandocs.txt
+  http://www.work.de/nocash/pandocs.htm
+
Also, a copy of this document is included in the manual of newer +versions of the no$gmb debugger, because of recent piracy attacks (many +thanks and best wishes go to hell) I have currently no intention to +publish any such or further no$gmb updates though.
+
+
+
 Game Boy Technical Data

+
  CPU          - 8-bit (Similar to the Z80 processor)
+  Clock Speed  - 4.194304MHz (4.295454MHz for SGB, max. 8.4MHz for CGB)
+  Work RAM     - 8K Byte (32K Byte for CGB)
+  Video RAM    - 8K Byte (16K Byte for CGB)
+  Screen Size  - 2.6"
+  Resolution   - 160x144 (20x18 tiles)
+  Max sprites  - Max 40 per screen, 10 per line
+  Sprite sizes - 8x8 or 8x16
+  Palettes     - 1x4 BG, 2x3 OBJ (for CGB: 8x4 BG, 8x3 OBJ)
+  Colors       - 4 grayshades (32768 colors for CGB)
+  Horiz Sync   - 9198 KHz (9420 KHz for SGB)
+  Vert Sync    - 59.73 Hz (61.17 Hz for SGB)
+  Sound        - 4 channels with stereo sound
+  Power        - DC6V 0.7W (DC3V 0.7W for GB Pocket, DC3V 0.6W for CGB)
+

+
+
 Memory Map

+The gameboy is having a 16bit address bus, that is used to address ROM, +RAM, and I/O registers.
+
+General Memory Map
+
  0000-3FFF   16KB ROM Bank 00     (in cartridge, fixed at bank 00)
+  4000-7FFF   16KB ROM Bank 01..NN (in cartridge, switchable bank number)
+  8000-9FFF   8KB Video RAM (VRAM) (switchable bank 0-1 in CGB Mode)
+  A000-BFFF   8KB External RAM     (in cartridge, switchable bank, if any)
+  C000-CFFF   4KB Work RAM Bank 0 (WRAM)
+  D000-DFFF   4KB Work RAM Bank 1 (WRAM)  (switchable bank 1-7 in CGB Mode)
+  E000-FDFF   Same as C000-DDFF (ECHO)    (typically not used)
+  FE00-FE9F   Sprite Attribute Table (OAM)
+  FEA0-FEFF   Not Usable
+  FF00-FF7F   I/O Ports
+  FF80-FFFE   High RAM (HRAM)
+  FFFF        Interrupt Enable Register
+

+Jump Vectors in First ROM Bank
+
The following addresses are supposed to be used as jump vectors:
+
  0000,0008,0010,0018,0020,0028,0030,0038   for RST commands
+  0040,0048,0050,0058,0060                  for Interrupts
+
However, the memory may be used for any other purpose in case that your +program doesn't use any (or only some) RST commands or Interrupts. RST +commands are 1-byte opcodes that work similiar to CALL opcodes, except +that the destination address is fixed.
+
+Cartridge Header in First ROM Bank
+
The memory at 0100-014F contains the cartridge header. This area +contains information about the program, its entry point, checksums, +information about the used MBC chip, the ROM and RAM sizes, etc. Most of +the bytes in this area are required to be specified correctly. For more +information read the chapter about The Cartridge Header.
+
+External Memory and Hardware
+
The areas from 0000-7FFF and A000-BFFF may be used to connect external +hardware. The first area is typically used to address ROM (read only, of +course), cartridges with Memory Bank Controllers (MBCs) are additionally +using this area to output data (write only) to the MBC chip. The second +area is often used to address external RAM, or to address other external +hardware (Real Time Clock, etc). External memory is often battery +buffered, and may hold saved game positions and high scrore tables +(etc.) even when the gameboy is turned of, or when the cartridge is +removed. For specific information read the chapter about Memory Bank +Controllers.
+
+
+
 Video Display

+Video I/O Registers
+
LCD Control Register
+LCD Status Register
+LCD Interrupts
+LCD Position and Scrolling
+LCD Monochrome Palettes
+LCD Color Palettes (CGB only)
+LCD VRAM Bank (CGB only)
+LCD OAM DMA Transfers
+LCD VRAM DMA Transfers (CGB only)
+
+Video Memory
+
VRAM Tile Data
+VRAM Background Maps
+VRAM Sprite Attribute Table (OAM)
+Accessing VRAM and OAM
+
+
+
 LCD Control Register

+FF40 - LCDC - LCD Control (R/W)
+
  Bit 7 - LCD Display Enable             (0=Off, 1=On)
+  Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
+  Bit 5 - Window Display Enable          (0=Off, 1=On)
+  Bit 4 - BG & Window Tile Data Select   (0=8800-97FF, 1=8000-8FFF)
+  Bit 3 - BG Tile Map Display Select     (0=9800-9BFF, 1=9C00-9FFF)
+  Bit 2 - OBJ (Sprite) Size              (0=8x8, 1=8x16)
+  Bit 1 - OBJ (Sprite) Display Enable    (0=Off, 1=On)
+  Bit 0 - BG Display (for CGB see below) (0=Off, 1=On)
+

+LCDC.7 - LCD Display Enable
+
CAUTION: Stopping LCD operation (Bit 7 from 1 to 0) may be performed +during V-Blank ONLY, disabeling the display outside of the V-Blank +period may damage the hardware. This appears to be a serious issue, +Nintendo is reported to reject any games that do not follow this rule.
+V-blank can be confirmed when the value of LY is greater than or equal +to 144. When the display is disabled the screen is blank (white), and +VRAM and OAM can be accessed freely.
+
+--- LCDC.0 has different Meanings depending on Gameboy Type ---
+
+LCDC.0 - 1) Monochrome Gameboy and SGB: BG Display
+
When Bit 0 is cleared, the background becomes blank (white). Window and +Sprites may still be displayed (if enabled in Bit 1 and/or Bit 5).
+
+LCDC.0 - 2) CGB in CGB Mode: BG and Window Master Priority
+
When Bit 0 is cleared, the background and window lose their priority - +the sprites will be always displayed on top of background and window, +independently of the priority flags in OAM and BG Map attributes.
+
+LCDC.0 - 3) CGB in Non CGB Mode: BG and Window Display
+
When Bit 0 is cleared, both background and window become blank (white), +ie. the Window Display Bit (Bit 5) is ignored in that case. Only Sprites +may still be displayed (if enabled in Bit 1).
+This is a possible compatibility problem - any monochrome games (if any) +that disable the background, but still want to display the window +wouldn't work properly on CGBs.
+
+
+
 LCD Status Register

+FF41 - STAT - LCDC Status (R/W)
+
  Bit 6 - LYC=LY Coincidence Interrupt (1=Enable) (Read/Write)
+  Bit 5 - Mode 2 OAM Interrupt         (1=Enable) (Read/Write)
+  Bit 4 - Mode 1 V-Blank Interrupt     (1=Enable) (Read/Write)
+  Bit 3 - Mode 0 H-Blank Interrupt     (1=Enable) (Read/Write)
+  Bit 2 - Coincidence Flag  (0:LYC<>LY, 1:LYC=LY) (Read Only)
+  Bit 1-0 - Mode Flag       (Mode 0-3, see below) (Read Only)
+            0: During H-Blank
+            1: During V-Blank
+            2: During Searching OAM-RAM
+            3: During Transfering Data to LCD Driver
+

+The two lower STAT bits show the current status of the LCD controller.
+
  Mode 0: The LCD controller is in the H-Blank period and
+          the CPU can access both the display RAM (8000h-9FFFh)
+          and OAM (FE00h-FE9Fh)
+

+
  Mode 1: The LCD contoller is in the V-Blank period (or the
+          display is disabled) and the CPU can access both the
+          display RAM (8000h-9FFFh) and OAM (FE00h-FE9Fh)
+

+
  Mode 2: The LCD controller is reading from OAM memory.
+          The CPU <cannot> access OAM memory (FE00h-FE9Fh)
+          during this period.
+

+
  Mode 3: The LCD controller is reading from both OAM and VRAM,
+          The CPU <cannot> access OAM and VRAM during this period.
+          CGB Mode: Cannot access Palette Data (FF69,FF6B) either.
+

+The following are typical when the display is enabled:
+
  Mode 2  2_____2_____2_____2_____2_____2___________________2____
+  Mode 3  _33____33____33____33____33____33__________________3___
+  Mode 0  ___000___000___000___000___000___000________________000
+  Mode 1  ____________________________________11111111111111_____
+

+The Mode Flag goes through the values 0, 2, and 3 at a cycle of about +109uS. 0 is present about 48.6uS, 2 about 19uS, and 3 about 41uS. This +is interrupted every 16.6ms by the VBlank (1). The mode flag stays set +at 1 for about 1.08 ms.
+
+Mode 0 is present between 201-207 clks, 2 about 77-83 clks, and 3 about +169-175 clks. A complete cycle through these states takes 456 clks. +VBlank lasts 4560 clks. A complete screen refresh occurs every 70224 +clks.)
+
+
+
 LCD Interrupts

+INT 40 - V-Blank Interrupt
+
The V-Blank interrupt occurs ca. 59.7 times a second on a regular GB and +ca. 61.1 times a second on a Super GB (SGB). This interrupt occurs at +the beginning of the V-Blank period (LY=144).
+During this period video hardware is not using video ram so it may be +freely accessed. This period lasts approximately 1.1 milliseconds.
+
+INT 48 - LCDC Status Interrupt
+
There are various reasons for this interrupt to occur as described by +the STAT register ($FF40). One very popular reason is to indicate to the +user when the video hardware is about to redraw a given LCD line. This +can be useful for dynamically controlling the SCX/SCY registers +($FF43/$FF42) to perform special video effects.
+
+
+
 LCD Position and Scrolling

+FF42 - SCY - Scroll Y (R/W)
+FF43 - SCX - Scroll X (R/W)
+
Specifies the position in the 256x256 pixels BG map (32x32 tiles) which +is to be displayed at the upper/left LCD display position.
+Values in range from 0-255 may be used for X/Y each, the video +controller automatically wraps back to the upper (left) position in BG +map when drawing exceeds the lower (right) border of the BG map area.
+
+FF44 - LY - LCDC Y-Coordinate (R)
+
The LY indicates the vertical line to which the present data is +transferred to the LCD Driver. The LY can take on any value between 0 +through 153. The values between 144 and 153 indicate the V-Blank period. +Writing will reset the counter.
+
+FF45 - LYC - LY Compare (R/W)
+
The gameboy permanently compares the value of the LYC and LY registers. +When both values are identical, the coincident bit in the STAT register +becomes set, and (if enabled) a STAT interrupt is requested.
+
+FF4A - WY - Window Y Position (R/W)
+FF4B - WX - Window X Position minus 7 (R/W)
+
Specifies the upper/left positions of the Window area. (The window is an +alternate background area which can be displayed above of the normal +background. OBJs (sprites) may be still displayed above or behinf the +window, just as for normal BG.)
+The window becomes visible (if enabled) when positions are set in range +WX=0..166, WY=0..143. A postion of WX=7, WY=0 locates the window at +upper left, it is then completly covering normal background.
+
+
+
 LCD Monochrome Palettes

+FF47 - BGP - BG Palette Data (R/W) - Non CGB Mode Only
+
This register assigns gray shades to the color numbers of the BG and +Window tiles.
+
  Bit 7-6 - Shade for Color Number 3
+  Bit 5-4 - Shade for Color Number 2
+  Bit 3-2 - Shade for Color Number 1
+  Bit 1-0 - Shade for Color Number 0
+
The four possible gray shades are:
+
  0  White
+  1  Light gray
+  2  Dark gray
+  3  Black
+
In CGB Mode the Color Palettes are taken from CGB Palette Memory +instead.
+
+FF48 - OBP0 - Object Palette 0 Data (R/W) - Non CGB Mode Only
+
This register assigns gray shades for sprite palette 0. It works exactly +as BGP (FF47), except that the lower two bits aren't used because sprite +data 00 is transparent.
+
+FF49 - OBP1 - Object Palette 1 Data (R/W) - Non CGB Mode Only
+
This register assigns gray shades for sprite palette 1. It works exactly +as BGP (FF47), except that the lower two bits aren't used because sprite +data 00 is transparent.
+
+
+
 LCD Color Palettes (CGB only)

+FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index
+
This register is used to address a byte in the CGBs Background Palette +Memory. Each two byte in that memory define a color value. The first 8 +bytes define Color 0-3 of Palette 0 (BGP0), and so on for BGP1-7.
+
  Bit 0-5   Index (00-3F)
+  Bit 7     Auto Increment  (0=Disabled, 1=Increment after Writing)
+
Data can be read/written to/from the specified index address through +Register FF69. When the Auto Increment Bit is set then the index is +automatically incremented after each <write> to FF69. Auto Increment has +no effect when <reading> from FF69, so the index must be manually +incremented in that case.
+
+FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data
+
This register allows to read/write data to the CGBs Background Palette +Memory, addressed through Register FF68.
+Each color is defined by two bytes (Bit 0-7 in first byte).
+
  Bit 0-4   Red Intensity   (00-1F)
+  Bit 5-9   Green Intensity (00-1F)
+  Bit 10-14 Blue Intensity  (00-1F)
+
Much like VRAM, Data in Palette Memory cannot be read/written during the +time when the LCD Controller is reading from it. (That is when the STAT +register indicates Mode 3).
+Note: Initially all background colors are initialized as white.
+
+FF6A - OCPS/OBPI - CGB Mode Only - Sprite Palette Index
+FF6B - OCPD/OBPD - CGB Mode Only - Sprite Palette Data
+
These registers are used to initialize the Sprite Palettes OBP0-7, +identically as described above for Background Palettes. Note that four +colors may be defined for each OBP Palettes - but only Color 1-3 of each +Sprite Palette can be displayed, Color 0 is always transparent, and can +be initialized to a don't care value.
+Note: Initially all sprite colors are uninitialized.
+
+RGB Translation by CGBs
+
When developing graphics on PCs, note that the RGB values will have +different appearance on CGB displays as on VGA monitors:
+The highest intensity will produce Light Gray color rather than White. +The intensities are not linear; the values 10h-1Fh will all appear very +bright, while medium and darker colors are ranged at 00h-0Fh.
+The CGB display will mix colors quite oddly, increasing intensity of +only one R,G,B color will also influence the other two R,G,B colors.
+For example, a color setting of 03EFh (Blue=0, Green=1Fh, Red=0Fh) will +appear as Neon Green on VGA displays, but on the CGB it'll produce a +decently washed out Yellow.
+
+RGB Translation by GBAs
+
Even though GBA is described to be compatible to CGB games, most CGB +games are completely unplayable on GBAs because most colors are +invisible (black). Of course, colors such like Black and White will +appear the same on both CGB and GBA, but medium intensities are arranged +completely different.
+Intensities in range 00h..0Fh are invisible/black (unless eventually +under best sunlight circumstances, and when gazing at the screen under +obscure viewing angles), unfortunately, these intensities are regulary +used by most existing CGB games for medium and darker colors.
+Newer CGB games may avoid this effect by changing palette data when +detecting GBA hardware. A relative simple method would be using the +formula GBA=CGB/2+10h for each R,G,B intensity, probably the result +won't be perfect, and (once colors became visible) it may turn out that +the color mixing is different also, anyways, it'd be still ways better +than no conversion.
+Asides, this translation method should have been VERY easy to implement +in GBA hardware directly, even though Nintendo obviously failed to do +so. How did they say, This seal is your assurance for excellence in +workmanship and so on?
+
+
+
 LCD VRAM Bank (CGB only)

+FF4F - VBK - CGB Mode Only - VRAM Bank
+
This 1bit register selects the current Video Memory (VRAM) Bank.
+
  Bit 0 - VRAM Bank (0-1)
+
Bank 0 contains 192 Tiles, and two background maps, just as for +monochrome games. Bank 1 contains another 192 Tiles, and color attribute +maps for the background maps in bank 0.
+
+
+
 LCD OAM DMA Transfers

+FF46 - DMA - DMA Transfer and Start Address (W)
+
Writing to this register launches a DMA transfer from ROM or RAM to OAM +memory (sprite attribute table). The written value specifies the +transfer source address divided by 100h, ie. source & destination are:
+
  Source:      XX00-XX9F   ;XX in range from 00-F1h
+  Destination: FE00-FE9F
+
It takes 160 microseconds until the transfer has completed (80 +microseconds in CGB Double Speed Mode), during this time the CPU can +access only HRAM (memory at FF80-FFFE). For this reason, the programmer +must copy a short procedure into HRAM, and use this procedure to start +the transfer from inside HRAM, and wait until the transfer has finished:
+
   ld  (0FF46h),a ;start DMA transfer, a=start address/100h
+   ld  a,28h      ;delay...
+  wait:           ;total 5x40 cycles, approx 200ms
+   dec a          ;1 cycle
+   jr  nz,wait    ;4 cycles
+
Most programs are executing this procedure from inside of their VBlank +procedure, but it is possible to execute it during display redraw also, +allowing to display more than 40 sprites on the screen (ie. for example +40 sprites in upper half, and other 40 sprites in lower half of the +screen).
+
+
+
 LCD VRAM DMA Transfers (CGB only)

+FF51 - HDMA1 - CGB Mode Only - New DMA Source, High
+FF52 - HDMA2 - CGB Mode Only - New DMA Source, Low
+FF53 - HDMA3 - CGB Mode Only - New DMA Destination, High
+FF54 - HDMA4 - CGB Mode Only - New DMA Destination, Low
+FF55 - HDMA5 - CGB Mode Only - New DMA Length/Mode/Start
+
These registers are used to initiate a DMA transfer from ROM or RAM to +VRAM. The Source Start Address may be located at 0000-7FF0 or A000-DFF0, +the lower four bits of the address are ignored (treated as zero). The +Destination Start Address may be located at 8000-9FF0, the lower four +bits of the address are ignored (treated as zero), the upper 3 bits are +ignored either (destination is always in VRAM).
+
+Writing to FF55 starts the transfer, the lower 7 bits of FF55 specify +the Transfer Length (divided by 10h, minus 1). Ie. lengths of 10h-800h +bytes can be defined by the values 00h-7Fh. And the upper bit of FF55 +indicates the Transfer Mode:
+
+Bit7=0 - General Purpose DMA
+
When using this transfer method, all data is transferred at once. The +execution of the program is halted until the transfer has completed. +Note that the General Purpose DMA blindly attempts to copy the data, +even if the LCD controller is currently accessing VRAM. So General +Purpose DMA should be used only if the Display is disabled, or during +V-Blank, or (for rather short blocks) during H-Blank.
+The execution of the program continues when the transfer has been +completed, and FF55 then contains a value if FFh.
+
+Bit7=1 - H-Blank DMA
+
The H-Blank DMA transfers 10h bytes of data during each H-Blank, ie. at +LY=0-143, no data is transferred during V-Blank (LY=144-153), but the +transfer will then continue at LY=00. The execution of the program is +halted during the separate transfers, but the program execution +continues during the 'spaces' between each data block.
+Note that the program may not change the Destination VRAM bank (FF4F), +or the Source ROM/RAM bank (in case data is transferred from bankable +memory) until the transfer has completed!
+Reading from Register FF55 returns the remaining length (divided by 10h, +minus 1), a value of 0FFh indicates that the transfer has completed. It +is also possible to terminate an active H-Blank transfer by writing zero +to Bit 7 of FF55. In that case reading from FF55 may return any value +for the lower 7 bits, but Bit 7 will be read as "1".
+
+Confirming if the DMA Transfer is Active
+
Reading Bit 7 of FF55 can be used to confirm if the DMA transfer is +active (1=Not Active, 0=Active). This works under any circumstances - +after completion of General Purpose, or H-Blank Transfer, and after +manually terminating a H-Blank Transfer.
+
+Transfer Timings
+
In both Normal Speed and Double Speed Mode it takes about 8us to +transfer a block of 10h bytes. That are 8 cycles in Normal Speed Mode, +and 16 'fast' cycles in Double Speed Mode.
+Older MBC controllers (like MBC1-4) and slower ROMs are not guaranteed +to support General Purpose or H-Blank DMA, that's because there are +always 2 bytes transferred per microsecond (even if the itself program +runs it Normal Speed Mode).
+
+
+
 VRAM Tile Data

+Tile Data is stored in VRAM at addresses 8000h-97FFh, this area defines +the Bitmaps for 192 Tiles. In CGB Mode 384 Tiles can be defined, because +memory at 0:8000h-97FFh and at 1:8000h-97FFh is used.
+
+Each tile is sized 8x8 pixels and has a color depth of 4 colors/gray +shades. Tiles can be displayed as part of the Background/Window map, +and/or as OAM tiles (foreground sprites). Note that foreground sprites +may have only 3 colors, because color 0 is transparent.
+
+As it was said before, there are two Tile Pattern Tables at $8000-8FFF +and at $8800-97FF. The first one can be used for sprites and the +background. Its tiles are numbered from 0 to 255. The second table can +be used for the background and the window display and its tiles are +numbered from -128 to 127.
+
+Each Tile occupies 16 bytes, where each 2 bytes represent a line:
+
  Byte 0-1  First Line (Upper 8 pixels)
+  Byte 2-3  Next Line
+  etc.
+
For each line, the first byte defines the least significant bits of the +color numbers for each pixel, and the second byte defines the upper bits +of the color numbers. In either case, Bit 7 is the leftmost pixel, and +Bit 0 the rightmost.
+
+So, each pixel is having a color number in range from 0-3. The color +numbers are translated into real colors (or gray shades) depending on +the current palettes. The palettes are defined through registers +FF47-FF49 (Non CGB Mode), and FF68-FF6B (CGB Mode).
+
+
+
 VRAM Background Maps

+The gameboy contains two 32x32 tile background maps in VRAM at addresses +9800h-9BFFh and 9C00h-9FFFh. Each can be used either to display "normal" +background, or "window" background.
+
+BG Map Tile Numbers
+
An area of VRAM known as Background Tile Map contains the numbers of +tiles to be displayed. It is organized as 32 rows of 32 bytes each. Each +byte contains a number of a tile to be displayed. Tile patterns are +taken from the Tile Data Table located either at $8000-8FFF or +$8800-97FF. In the first case, patterns are numbered with unsigned +numbers from 0 to 255 (i.e. pattern #0 lies at address $8000). In the +second case, patterns have signed numbers from -128 to 127 (i.e. pattern +#0 lies at address $9000). The Tile Data Table address for the +background can be selected via LCDC register.
+
+BG Map Attributes (CGB Mode only)
+
In CGB Mode, an additional map of 32x32 bytes is stored in VRAM Bank 1 +(each byte defines attributes for the corresponding tile-number map +entry in VRAM Bank 0):
+
  Bit 0-2  Background Palette number  (BGP0-7)
+  Bit 3    Tile VRAM Bank number      (0=Bank 0, 1=Bank 1)
+  Bit 4    Not used
+  Bit 5    Horizontal Flip            (0=Normal, 1=Mirror horizontally)
+  Bit 6    Vertical Flip              (0=Normal, 1=Mirror vertically)
+  Bit 7    BG-to-OAM Priority         (0=Use OAM priority bit, 1=BG Priority)
+
When Bit 7 is set, the corresponding BG tile will have priority above +all OBJs (regardless of the priority bits in OAM memory). There's also +an Master Priority flag in LCDC register Bit 0 which overrides all other +priority bits when cleared.
+
+As one background tile has a size of 8x8 pixels, the BG maps may hold a +picture of 256x256 pixels, an area of 160x144 pixels of this picture can +be displayed on the LCD screen.
+
+Normal Background (BG)
+
The SCY and SCX registers can be used to scroll the background, allowing +to select the origin of the visible 160x144 pixel area within the total +256x256 pixel background map. Background wraps around the screen (i.e. +when part of it goes off the screen, it appears on the opposite side.)
+
+The Window
+
Besides background, there is also a "window" overlaying the background. +The window is not scrollable i.e. it is always displayed starting from +its left upper corner. The location of a window on the screen can be +adjusted via WX and WY registers. Screen coordinates of the top left +corner of a window are WX-7,WY. The tiles for the window are stored in +the Tile Data Table. Both the Background and the window share the same +Tile Data Table.
+
+Both background and window can be disabled or enabled separately via +bits in the LCDC register.
+
+
+
 VRAM Sprite Attribute Table (OAM)

+GameBoy video controller can display up to 40 sprites either in 8x8 or +in 8x16 pixels. Because of a limitation of hardware, only ten sprites +can be displayed per scan line. Sprite patterns have the same format as +BG tiles, but they are taken from the Sprite Pattern Table located at +$8000-8FFF and have unsigned numbering.
+
+Sprite attributes reside in the Sprite Attribute Table (OAM - Object +Attribute Memory) at $FE00-FE9F. Each of the 40 entries consists of four +bytes with the following meanings:
+
+Byte0 - Y Position
+
Specifies the sprites vertical position on the screen (minus 16).
+An offscreen value (for example, Y=0 or Y>=160) hides the sprite.
+
+Byte1 - X Position
+
Specifies the sprites horizontal position on the screen (minus 8).
+An offscreen value (X=0 or X>=168) hides the sprite, but the sprite
+still affects the priority ordering - a better way to hide a sprite is +to set its Y-coordinate offscreen.
+
+Byte2 - Tile/Pattern Number
+
Specifies the sprites Tile Number (00-FF). This (unsigned) value selects +a tile from memory at 8000h-8FFFh. In CGB Mode this could be either in +VRAM Bank 0 or 1, depending on Bit 3 of the following byte.
+In 8x16 mode, the lower bit of the tile number is ignored. Ie. the upper +8x8 tile is "NN AND FEh", and the lower 8x8 tile is "NN OR 01h".
+
+Byte3 - Attributes/Flags:
+
  Bit7   OBJ-to-BG Priority (0=OBJ Above BG, 1=OBJ Behind BG color 1-3)
+         (Used for both BG and Window. BG color 0 is always behind OBJ)
+  Bit6   Y flip          (0=Normal, 1=Vertically mirrored)
+  Bit5   X flip          (0=Normal, 1=Horizontally mirrored)
+  Bit4   Palette number  **Non CGB Mode Only** (0=OBP0, 1=OBP1)
+  Bit3   Tile VRAM-Bank  **CGB Mode Only**     (0=Bank 0, 1=Bank 1)
+  Bit2-0 Palette number  **CGB Mode Only**     (OBP0-7)
+

+Sprite Priorities and Conflicts
+
When sprites with different x coordinate values overlap, the one with +the smaller x coordinate (closer to the left) will have priority and +appear above any others. This applies in Non CGB Mode only.
+When sprites with the same x coordinate values overlap, they have +priority according to table ordering. (i.e. $FE00 - highest, $FE04 - +next highest, etc.) In CGB Mode priorities are always assigned like +this.
+
+Only 10 sprites can be displayed on any one line. When this limit is +exceeded, the lower priority sprites (priorities listed above) won't be +displayed. To keep unused sprites from affecting onscreen sprites set +their Y coordinate to Y=0 or Y=>144+16. Just setting the X coordinate to +X=0 or X=>160+8 on a sprite will hide it but it will still affect other +sprites sharing the same lines.
+
+Writing Data to OAM Memory
+
The recommened method is to write the data to normal RAM first, and to +copy that RAM to OAM by using the DMA transfer function, initiated +through DMA register (FF46).
+Beside for that, it is also possible to write data directly to the OAM +area by using normal LD commands, this works only during the H-Blank and +V-Blank periods. The current state of the LCD controller can be read out +from the STAT register (FF41).
+
+
+
 Accessing VRAM and OAM

+CAUTION
+
When the LCD Controller is drawing the screen it is directly reading +from Video Memory (VRAM) and from the Sprite Attribute Table (OAM). +During these periods the Gameboy CPU may not access the VRAM and OAM. +That means, any attempts to write to VRAM/OAM are ignored (the data +remains unchanged). And any attempts to read from VRAM/OAM will return +undefined data (typically a value of FFh).
+
+For this reason the program should verify if VRAM/OAM is accessable +before actually reading or writing to it. This is usually done by +reading the Mode Bits from the STAT Register (FF41). When doing this (as +described in the examples below) you should take care that no interrupts +occur between the wait loops and the following memory access - the +memory is guaranted to be accessable only for a few cycles directly +after the wait loops have completed.
+
+VRAM (memory at 8000h-9FFFh) is accessable during Mode 0-2
+
  Mode 0 - H-Blank Period,
+  Mode 1 - V-Blank Period, and
+  Mode 2 - Searching OAM Period
+
A typical procedure that waits for accessibility of VRAM would be:
+
  ld   hl,0FF41h    ;-STAT Register
+ @@wait:            ;\
+  bit  1,(hl)       ; Wait until Mode is 0 or 1
+  jr   nz,@@wait    ;/
+
Even if the procedure gets executed at the <end> of Mode 0 or 1, it is +still proof to assume that VRAM can be accessed for a few more cycles +because in either case the following period is Mode 2 which allows +access to VRAM either.
+In CGB Mode an alternate method to write data to VRAM is to use the HDMA +Function (FF51-FF55).
+
+OAM (memory at FE00h-FE9Fh) is accessable during Mode 0-1
+
  Mode 0 - H-Blank Period, and
+  Mode 1 - V-Blank Period
+
Beside for that, OAM can be accessed at any time by using the DMA +Function (FF46). When directly reading or writing to OAM, a typical +procedure that waits for accessibilty or OAM Memory would be:
+
  ld   hl,0FF41h    ;-STAT Register
+ @@wait1:           ;\
+  bit  1,(hl)       ; Wait until Mode is -NOT- 0 or 1
+  jr   z,@@wait1    ;/
+ @@wait2:           ;\
+  bit  1,(hl)       ; Wait until Mode 0 or 1 -BEGINS-
+  jr   nz,@@wait2   ;/
+
The two wait loops ensure that Mode 0 or 1 will last for a few clock +cycles after completion of the procedure. In V-Blank period it might be +recommended to skip the whole procedure - and in most cases using the +above mentioned DMA function would be more recommended anyways.
+
+Note
+
When the display is disabled, both VRAM and OAM are accessable at any +time. The downside is that the screen is blank (white) during this +period, so that disabling the display would be recommended only during +initialization.
+
+
+
 Sound Controller

+Sound Overview
+Sound Channel 1 - Tone & Sweep
+Sound Channel 2 - Tone
+Sound Channel 3 - Wave Output
+Sound Channel 4 - Noise
+Sound Control Registers
+
+
+
 Sound Overview

+There are two sound channels connected to the output terminals SO1 and +SO2. There is also a input terminal Vin connected to the cartridge. It +can be routed to either of both output terminals. GameBoy circuitry +allows producing sound in four different ways:
+
+
   Quadrangular wave patterns with sweep and envelope functions.
+   Quadrangular wave patterns with envelope functions.
+   Voluntary wave patterns from wave RAM.
+   White noise with an envelope function.
+

+These four sounds can be controlled independantly and then mixed +separately for each of the output terminals.
+
+Sound registers may be set at all times while producing sound.
+
+(Sounds will have a 2.4% higher frequency on Super GB.)
+
+
+
 Sound Channel 1 - Tone & Sweep

+FF10 - NR10 - Channel 1 Sweep register (R/W)
+
  Bit 6-4 - Sweep Time
+  Bit 3   - Sweep Increase/Decrease
+             0: Addition    (frequency increases)
+             1: Subtraction (frequency decreases)
+  Bit 2-0 - Number of sweep shift (n: 0-7)
+
Sweep Time:
+
  000: sweep off - no freq change
+  001: 7.8 ms  (1/128Hz)
+  010: 15.6 ms (2/128Hz)
+  011: 23.4 ms (3/128Hz)
+  100: 31.3 ms (4/128Hz)
+  101: 39.1 ms (5/128Hz)
+  110: 46.9 ms (6/128Hz)
+  111: 54.7 ms (7/128Hz)
+

+The change of frequency (NR13,NR14) at each shift is calculated by the +following formula where X(0) is initial freq & X(t-1) is last freq:
+
  X(t) = X(t-1) +/- X(t-1)/2^n
+

+FF11 - NR11 - Channel 1 Sound length/Wave pattern duty (R/W)
+
  Bit 7-6 - Wave Pattern Duty (Read/Write)
+  Bit 5-0 - Sound length data (Write Only) (t1: 0-63)
+
Wave Duty:
+
  00: 12.5% ( _-------_-------_------- )
+  01: 25%   ( __------__------__------ )
+  10: 50%   ( ____----____----____---- ) (normal)
+  11: 75%   ( ______--______--______-- )
+
Sound Length = (64-t1)*(1/256) seconds
+The Length value is used only if Bit 6 in NR14 is set.
+
+FF12 - NR12 - Channel 1 Volume Envelope (R/W)
+
  Bit 7-4 - Initial Volume of envelope (0-0Fh) (0=No Sound)
+  Bit 3   - Envelope Direction (0=Decrease, 1=Increase)
+  Bit 2-0 - Number of envelope sweep (n: 0-7)
+            (If zero, stop envelope operation.)
+
Length of 1 step = n*(1/64) seconds
+
+FF13 - NR13 - Channel 1 Frequency lo (Write Only)
+

+Lower 8 bits of 11 bit frequency (x).
+Next 3 bit are in NR14 ($FF14)
+
+FF14 - NR14 - Channel 1 Frequency hi (R/W)
+
  Bit 7   - Initial (1=Restart Sound)     (Write Only)
+  Bit 6   - Counter/consecutive selection (Read/Write)
+            (1=Stop output when length in NR11 expires)
+  Bit 2-0 - Frequency's higher 3 bits (x) (Write Only)
+
Frequency = 131072/(2048-x) Hz
+
+
+
 Sound Channel 2 - Tone

+This sound channel works exactly as channel 1, except that it doesn't +have a Tone Envelope/Sweep Register.
+
+FF16 - NR21 - Channel 2 Sound Length/Wave Pattern Duty (R/W)
+
  Bit 7-6 - Wave Pattern Duty (Read/Write)
+  Bit 5-0 - Sound length data (Write Only) (t1: 0-63)
+
Wave Duty:
+
  00: 12.5% ( _-------_-------_------- )
+  01: 25%   ( __------__------__------ )
+  10: 50%   ( ____----____----____---- ) (normal)
+  11: 75%   ( ______--______--______-- )
+
Sound Length = (64-t1)*(1/256) seconds
+The Length value is used only if Bit 6 in NR24 is set.
+
+FF17 - NR22 - Channel 2 Volume Envelope (R/W)
+
  Bit 7-4 - Initial Volume of envelope (0-0Fh) (0=No Sound)
+  Bit 3   - Envelope Direction (0=Decrease, 1=Increase)
+  Bit 2-0 - Number of envelope sweep (n: 0-7)
+            (If zero, stop envelope operation.)
+
Length of 1 step = n*(1/64) seconds
+
+FF18 - NR23 - Channel 2 Frequency lo data (W)
+
Frequency's lower 8 bits of 11 bit data (x).
+Next 3 bits are in NR24 ($FF19).
+
+FF19 - NR24 - Channel 2 Frequency hi data (R/W)
+
  Bit 7   - Initial (1=Restart Sound)     (Write Only)
+  Bit 6   - Counter/consecutive selection (Read/Write)
+            (1=Stop output when length in NR21 expires)
+  Bit 2-0 - Frequency's higher 3 bits (x) (Write Only)
+
Frequency = 131072/(2048-x) Hz
+
+
+
 Sound Channel 3 - Wave Output

+This channel can be used to output digital sound, the length of the +sample buffer (Wave RAM) is limited to 32 digits. This sound channel can +be also used to output normal tones when initializing the Wave RAM by a +square wave. This channel doesn't have a volume envelope register.
+
+FF1A - NR30 - Channel 3 Sound on/off (R/W)
+
  Bit 7 - Sound Channel 3 Off  (0=Stop, 1=Playback)  (Read/Write)
+

+FF1B - NR31 - Channel 3 Sound Length
+
  Bit 7-0 - Sound length (t1: 0 - 255)
+
Sound Length = (256-t1)*(1/256) seconds
+This value is used only if Bit 6 in NR34 is set.
+
+FF1C - NR32 - Channel 3 Select output level (R/W)
+
  Bit 6-5 - Select output level (Read/Write)
+
Possible Output levels are:
+
  0: Mute (No sound)
+  1: 100% Volume (Produce Wave Pattern RAM Data as it is)
+  2:  50% Volume (Produce Wave Pattern RAM data shifted once to the right)
+  3:  25% Volume (Produce Wave Pattern RAM data shifted twice to the right)
+

+FF1D - NR33 - Channel 3 Frequency's lower data (W)
+
Lower 8 bits of an 11 bit frequency (x).
+
+FF1E - NR34 - Channel 3 Frequency's higher data (R/W)
+
  Bit 7   - Initial (1=Restart Sound)     (Write Only)
+  Bit 6   - Counter/consecutive selection (Read/Write)
+            (1=Stop output when length in NR31 expires)
+  Bit 2-0 - Frequency's higher 3 bits (x) (Write Only)
+
Frequency = 4194304/(64*(2048-x)) Hz = 65536/(2048-x) Hz
+
+FF30-FF3F - Wave Pattern RAM
+
Contents - Waveform storage for arbitrary sound data
+
+This storage area holds 32 4-bit samples that are played back upper 4 +bits first.
+
+
+
 Sound Channel 4 - Noise

+This channel is used to output white noise. This is done by randomly +switching the amplitude between high and low at a given frequency. +Depending on the frequency the noise will appear 'harder' or 'softer'.
+
+It is also possible to influence the function of the random generator, +so the that the output becomes more regular, resulting in a limited +ability to output Tone instead of Noise.
+
+FF20 - NR41 - Channel 4 Sound Length (R/W)
+
  Bit 5-0 - Sound length data (t1: 0-63)
+
Sound Length = (64-t1)*(1/256) seconds
+The Length value is used only if Bit 6 in NR44 is set.
+
+FF21 - NR42 - Channel 4 Volume Envelope (R/W)
+
  Bit 7-4 - Initial Volume of envelope (0-0Fh) (0=No Sound)
+  Bit 3   - Envelope Direction (0=Decrease, 1=Increase)
+  Bit 2-0 - Number of envelope sweep (n: 0-7)
+            (If zero, stop envelope operation.)
+
Length of 1 step = n*(1/64) seconds
+
+FF22 - NR43 - Channel 4 Polynomial Counter (R/W)
+
The amplitude is randomly switched between high and low at the given +frequency. A higher frequency will make the noise to appear 'softer'.
+When Bit 3 is set, the output will become more regular, and some +frequencies will sound more like Tone than Noise.
+
  Bit 7-4 - Shift Clock Frequency (s)
+  Bit 3   - Counter Step/Width (0=15 bits, 1=7 bits)
+  Bit 2-0 - Dividing Ratio of Frequencies (r)
+
Frequency = 524288 Hz / r / 2^(s+1) ;For r=0 assume r=0.5 instead
+
+FF23 - NR44 - Channel 4 Counter/consecutive; Inital (R/W)
+
  Bit 7   - Initial (1=Restart Sound)     (Write Only)
+  Bit 6   - Counter/consecutive selection (Read/Write)
+            (1=Stop output when length in NR41 expires)
+

+
+
 Sound Control Registers

+FF24 - NR50 - Channel control / ON-OFF / Volume (R/W)
+
The volume bits specify the "Master Volume" for Left/Right sound output.
+
  Bit 7   - Output Vin to SO2 terminal (1=Enable)
+  Bit 6-4 - SO2 output level (volume)  (0-7)
+  Bit 3   - Output Vin to SO1 terminal (1=Enable)
+  Bit 2-0 - SO1 output level (volume)  (0-7)
+
The Vin signal is received from the game cartridge bus, allowing +external hardware in the cartridge to supply a fifth sound channel, +additionally to the gameboys internal four channels. As far as I know +this feature isn't used by any existing games.
+
+FF25 - NR51 - Selection of Sound output terminal (R/W)
+
  Bit 7 - Output sound 4 to SO2 terminal
+  Bit 6 - Output sound 3 to SO2 terminal
+  Bit 5 - Output sound 2 to SO2 terminal
+  Bit 4 - Output sound 1 to SO2 terminal
+  Bit 3 - Output sound 4 to SO1 terminal
+  Bit 2 - Output sound 3 to SO1 terminal
+  Bit 1 - Output sound 2 to SO1 terminal
+  Bit 0 - Output sound 1 to SO1 terminal
+

+FF26 - NR52 - Sound on/off
+
If your GB programs don't use sound then write 00h to this register to +save 16% or more on GB power consumption. Disabeling the sound +controller by clearing Bit 7 destroys the contents of all sound +registers. Also, it is not possible to access any sound registers +(execpt FF26) while the sound controller is disabled.
+
  Bit 7 - All sound on/off  (0: stop all sound circuits) (Read/Write)
+  Bit 3 - Sound 4 ON flag (Read Only)
+  Bit 2 - Sound 3 ON flag (Read Only)
+  Bit 1 - Sound 2 ON flag (Read Only)
+  Bit 0 - Sound 1 ON flag (Read Only)
+
Bits 0-3 of this register are read only status bits, writing to these +bits does NOT enable/disable sound. The flags get set when sound output +is restarted by setting the Initial flag (Bit 7 in NR14-NR44), the flag +remains set until the sound length has expired (if enabled). A volume +envelopes which has decreased to zero volume will NOT cause the sound +flag to go off.
+
+
+
 Joypad Input

+FF00 - P1/JOYP - Joypad (R/W)
+
The eight gameboy buttons/direction keys are arranged in form of a 2x4 +matrix. Select either button or direction keys by writing to this +register, then read-out bit 0-3.
+
  Bit 7 - Not used
+  Bit 6 - Not used
+  Bit 5 - P15 Select Button Keys      (0=Select)
+  Bit 4 - P14 Select Direction Keys   (0=Select)
+  Bit 3 - P13 Input Down  or Start    (0=Pressed) (Read Only)
+  Bit 2 - P12 Input Up    or Select   (0=Pressed) (Read Only)
+  Bit 1 - P11 Input Left  or Button B (0=Pressed) (Read Only)
+  Bit 0 - P10 Input Right or Button A (0=Pressed) (Read Only)
+
Note: Most programs are repeatedly reading from this port several times +(the first reads used as short delay, allowing the inputs to stabilize, +and only the value from the last read actually used).
+
+Usage in SGB software
+
Beside for normal joypad input, SGB games mis-use the joypad register to +output SGB command packets to the SNES, also, SGB programs may read out +gamepad states from up to four different joypads which can be connected +to the SNES.
+See SGB description for details.
+
+INT 60 - Joypad Interrupt
+
Joypad interrupt is requested when any of the above Input lines changes +from High to Low. Generally this should happen when a key becomes +pressed (provided that the button/direction key is enabled by above +Bit4/5), however, because of switch bounce, one or more High to Low +transitions are usually produced both when pressing or releasing a key.
+
+Using the Joypad Interrupt
+
It's more or less useless for programmers, even when selecting both +buttons and direction keys simultaneously it still cannot recognize all +keystrokes, because in that case a bit might be already held low by a +button key, and pressing the corresponding direction key would thus +cause no difference. The only meaningful purpose of the keystroke +interrupt would be to terminate STOP (low power) standby state.
+Also, the joypad interrupt does not appear to work with CGB and GBA +hardware (the STOP function can be still terminated by joypad keystrokes +though).
+
+
+
 Serial Data Transfer (Link Cable)

+FF01 - SB - Serial transfer data (R/W)
+
8 Bits of data to be read/written
+
+FF02 - SC - Serial Transfer Control (R/W)
+
  Bit 7 - Transfer Start Flag (0=No Transfer, 1=Start)
+  Bit 1 - Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only **
+  Bit 0 - Shift Clock (0=External Clock, 1=Internal Clock)
+
The clock signal specifies the rate at which the eight data bits in SB +(FF01) are transferred. When the gameboy is communicating with another +gameboy (or other computer) then either one must supply internal clock, +and the other one must use external clock.
+
+Internal Clock
+
In Non-CGB Mode the gameboy supplies an internal clock of 8192Hz only +(allowing to transfer about 1 KByte per second). In CGB Mode four +internal clock rates are available, depending on Bit 1 of the SC +register, and on whether the CGB Double Speed Mode is used:
+
    8192Hz -  1KB/s - Bit 1 cleared, Normal
+   16384Hz -  2KB/s - Bit 1 cleared, Double Speed Mode
+  262144Hz - 32KB/s - Bit 1 set,     Normal
+  524288Hz - 64KB/s - Bit 1 set,     Double Speed Mode
+

+External Clock
+
The external clock is typically supplied by another gameboy, but might +be supplied by another computer (for example if connected to a PCs +parallel port), in that case the external clock may have any speed. Even +the old/monochrome gameboy is reported to recognizes external clocks of +up to 500KHz. And there is no limitiation into the other direction - +even when suppling an external clock speed of "1 bit per month", then +the gameboy will still eagerly wait for the next bit(s) to be +transferred. It isn't required that the clock pulses are sent at an +regular interval either.
+
+Timeouts
+
When using external clock then the transfer will not complete until the +last bit is received. In case that the second gameboy isn't supplying a +clock signal, if it gets turned off, or if there is no second gameboy +connected at all) then transfer will never complete. For this reason the +transfer procedure should use a timeout counter, and abort the +communication if no response has been received during the timeout +interval.
+
+Delays and Synchronization
+
The gameboy that is using internal clock should always execute a small +delay between each transfer, in order to ensure that the opponent +gameboy has enough time to prepare itself for the next transfer, ie. the +gameboy with external clock must have set its transfer start bit before +the gameboy with internal clock starts the transfer. Alternately, the +two gameboys could switch between internal and external clock for each +transferred byte to ensure synchronization.
+
+Transfer is initiated by setting the Transfer Start Flag. This bit is +automatically set to 0 at the end of Transfer. Reading this bit can be +used to determine if the transfer is still active.
+
+INT 58 - Serial Interrupt
+
When the transfer has completed (ie. after sending/receiving 8 bits, if +any) then an interrupt is requested by setting Bit 3 of the IF Register +(FF0F). When that interrupt is enabled, then the Serial Interrupt vector +at 0058 is called.
+
+XXXXXX...
+

+Transmitting and receiving serial data is done simultaneously. The +received data is automatically stored in SB.
+
+The serial I/O port on the Gameboy is a very simple setup and is crude +compared to standard RS-232 (IBM-PC) or RS-485 (Macintosh) serial ports. +There are no start or stop bits.
+
+During a transfer, a byte is shifted in at the same time that a byte is +shifted out. The rate of the shift is determined by whether the clock +source is internal or external.
+The most significant bit is shifted in and out first.
+
+When the internal clock is selected, it drives the clock pin on the game +link port and it stays high when not used. During a transfer it will go +low eight times to clock in/out each bit.
+
+The state of the last bit shifted out determines the state of the output +line until another transfer takes place.
+
+If a serial transfer with internal clock is performed and no external +GameBoy is present, a value of $FF will be received in the transfer.
+
+The following code causes $75 to be shifted out the serial port and a +byte to be shifted into $FF01:
+
+
    ld   a,$75
+    ld  ($FF01),a
+    ld   a,$81
+    ld  ($FF02),a
+

+
+
 Timer and Divider Registers

+FF04 - DIV - Divider Register (R/W)
+
This register is incremented at rate of 16384Hz (~16779Hz on SGB). In +CGB Double Speed Mode it is incremented twice as fast, ie. at 32768Hz. +Writing any value to this register resets it to 00h.
+
+FF05 - TIMA - Timer counter (R/W)
+
This timer is incremented by a clock frequency specified by the TAC +register ($FF07). When the value overflows (gets bigger than FFh) then +it will be reset to the value specified in TMA (FF06), and an interrupt +will be requested, as described below.
+
+FF06 - TMA - Timer Modulo (R/W)
+
When the TIMA overflows, this data will be loaded.
+
+FF07 - TAC - Timer Control (R/W)
+
  Bit 2    - Timer Stop  (0=Stop, 1=Start)
+  Bits 1-0 - Input Clock Select
+             00:   4096 Hz    (~4194 Hz SGB)
+             01: 262144 Hz  (~268400 Hz SGB)
+             10:  65536 Hz   (~67110 Hz SGB)
+             11:  16384 Hz   (~16780 Hz SGB)
+

+INT 50 - Timer Interrupt
+
Each time when the timer overflows (ie. when TIMA gets bigger than FFh), +then an interrupt is requested by setting Bit 2 in the IF Register +(FF0F). When that interrupt is enabled, then the CPU will execute it by +calling the timer interrupt vector at 0050h.
+
+Note
+
The above described Timer is the built-in timer in the gameboy. It has +nothing to do with the MBC3s battery buffered Real Time Clock - that's a +completely different thing, described in the chapter about Memory +Banking Controllers.
+
+
+
 Interrupts

+IME - Interrupt Master Enable Flag (Write Only)
+
  0 - Disable all Interrupts
+  1 - Enable all Interrupts that are enabled in IE Register (FFFF)
+
The IME flag is used to disable all interrupts, overriding any enabled +bits in the IE Register. It isn't possible to access the IME flag by +using a I/O address, instead IME is accessed directly from the CPU, by +the following opcodes/operations:
+
  EI     ;Enable Interrupts  (ie. IME=1)
+  DI     ;Disable Interrupts (ie. IME=0)
+  RETI   ;Enable Ints & Return (same as the opcode combination EI, RET)
+  <INT>  ;Disable Ints & Call to Interrupt Vector
+
Whereas <INT> means the operation which is automatically executed by the +CPU when it executes an interrupt.
+
+FFFF - IE - Interrupt Enable (R/W)
+
  Bit 0: V-Blank  Interrupt Enable  (INT 40h)  (1=Enable)
+  Bit 1: LCD STAT Interrupt Enable  (INT 48h)  (1=Enable)
+  Bit 2: Timer    Interrupt Enable  (INT 50h)  (1=Enable)
+  Bit 3: Serial   Interrupt Enable  (INT 58h)  (1=Enable)
+  Bit 4: Joypad   Interrupt Enable  (INT 60h)  (1=Enable)
+

+FF0F - IF - Interrupt Flag (R/W)
+
  Bit 0: V-Blank  Interrupt Request (INT 40h)  (1=Request)
+  Bit 1: LCD STAT Interrupt Request (INT 48h)  (1=Request)
+  Bit 2: Timer    Interrupt Request (INT 50h)  (1=Request)
+  Bit 3: Serial   Interrupt Request (INT 58h)  (1=Request)
+  Bit 4: Joypad   Interrupt Request (INT 60h)  (1=Request)
+
When an interrupt signal changes from low to high, then the +corresponding bit in the IF register becomes set. For example, Bit 0 +becomes set when the LCD controller enters into the V-Blank period.
+
+Interrupt Requests
+
Any set bits in the IF register are only <requesting> an interrupt to be +executed. The actual <execution> happens only if both the IME flag, and +the corresponding bit in the IE register are set, otherwise the +interrupt 'waits' until both IME and IE allow its execution.
+
+Interrupt Execution
+
When an interrupt gets executed, the corresponding bit in the IF +register becomes automatically reset by the CPU, and the IME flag +becomes cleared (disabeling any further interrupts until the program +re-enables the interrupts, typically by using the RETI instruction), and +the corresponding Interrupt Vector (that are the addresses in range +0040h-0060h, as shown in IE and IF register decriptions above) becomes +called.
+
+Manually Requesting/Discarding Interrupts
+
As the CPU automatically sets and cleares the bits in the IF register it +is usually not required to write to the IF register. However, the user +may still do that in order to manually request (or discard) interrupts. +As for real interrupts, a manually requested interrupt isn't executed +unless/until IME and IE allow its execution.
+
+Interrupt Priorities
+
In the following three situations it might happen that more than 1 bit +in the IF register are set, requesting more than one interrupt at once:
+
  1) More than one interrupt signal changed from Low
+     to High at the same time.
+  2) Several interrupts have been requested during a
+     time in which IME/IE didn't allow these interrupts
+     to be executed directly.
+  3) The user has written a value with several "1" bits
+     (for example 1Fh) to the IF register.
+
Provided that IME and IE allow the execution of more than one of the +requested interrupts, then the interrupt with the highest priority +becomes executed first. The priorities are ordered as the bits in the IE +and IF registers, Bit 0 (V-Blank) having the highest priority, and Bit 4 +(Joypad) having the lowest priority.
+
+Nested Interrupts
+
The CPU automatically disables all other interrupts by setting IME=0 +when it executes an interrupt. Usually IME remains zero until the +interrupt procedure returns (and sets IME=1 by the RETI instruction). +However, if you want any other interrupts of lower or higher (or same) +priority to be allowed to be executed from inside of the interrupt +procedure, then you can place an EI instruction into the interrupt +procedure.
+
+
+
 CGB Registers

+Forward
+
This chapter describes only CGB (Color Gameboy) registers that didn't +fit into normal categories - most CGB registers are described in the +chapter about Video Display (Color Palettes, VRAM Bank, VRAM DMA +Transfers, and changed meaning of Bit 0 of LCDC Control register). Also, +a changed bit is noted in the chapter about the Serial/Link port.
+
+Unlocking CGB functions
+
When using any CGB registers (including those in the Video/Link +chapters), you must first unlock CGB features by changing byte 0143h in +the cartridge header. Typically use a value of 80h for games which +support both CGB and monochrome gameboys, and C0h for games which work +on CGBs only. Otherwise, the CGB will operate in monochrome "Non CGB" +compatibility mode.
+
+Detecting CGB (and GBA) functions
+
CGB hardware can be detected by examing the CPU accumulator (A-register) +directly after startup. A value of 11h indicates CGB (or GBA) hardware, +if so, CGB functions can be used (if unlocked, see above).
+When A=11h, you may also examine Bit 0 of the CPUs B-Register to +separate between CGB (bit cleared) and GBA (bit set), by that detection +it is possible to use 'repaired' color palette data matching for GBA +displays.
+
+FF4D - KEY1 - CGB Mode Only - Prepare Speed Switch
+
  Bit 7: Current Speed     (0=Normal, 1=Double) (Read Only)
+  Bit 0: Prepare Speed Switch (0=No, 1=Prepare) (Read/Write)
+
This register is used to prepare the gameboy to switch between CGB +Double Speed Mode and Normal Speed Mode. The actual speed switch is +performed by executing a STOP command after Bit 0 has been set. After +that Bit 0 will be cleared automatically, and the gameboy will operate +at the 'other' speed. The recommended speed switching procedure in +pseudo code would be:
+
  IF KEY1_BIT7 <> DESIRED_SPEED THEN
+    IE=00H       ;(FFFF)=00h
+    JOYP=30H     ;(FF00)=30h
+    KEY1=01H     ;(FF4D)=01h
+    STOP         ;STOP
+  ENDIF
+
The CGB is operating in Normal Speed Mode when it is turned on. Note +that using the Double Speed Mode increases the power consumption, it +would be recommended to use Single Speed whenever possible. However, the +display will flicker (white) for a moment during speed switches, so this +cannot be done permanentely.
+In Double Speed Mode the following will operate twice as fast as normal:
+
  The CPU (2.10 MHz, 1 Cycle = approx. 0.5us)
+  Timer and Divider Registers
+  Serial Port (Link Cable)
+  DMA Transfer to OAM
+
And the following will keep operating as usual:
+
  LCD Video Controller
+  HDMA Transfer to VRAM
+  All Sound Timings and Frequencies
+

+FF56 - RP - CGB Mode Only - Infrared Communications Port
+
This register allows to input and output data through the CGBs built-in +Infrared Port. When reading data, bit 6 and 7 must be set (and obviously +Bit 0 must be cleared - if you don't want to receive your own gameboys +IR signal). After sending or receiving data you should reset the +register to 00h to reduce battery power consumption again.
+
  Bit 0:   Write Data   (0=LED Off, 1=LED On)             (Read/Write)
+  Bit 1:   Read Data    (0=Receiving IR Signal, 1=Normal) (Read Only)
+  Bit 6-7: Data Read Enable (0=Disable, 3=Enable)         (Read/Write)
+
Note that the receiver will adapt itself to the normal level of IR +pollution in the air, so if you would send a LED ON signal for a longer +period, then the receiver would treat that as normal (=OFF) after a +while. For example, a Philips TV Remote Control sends a series of 32 LED +ON/OFF pulses (length 10us ON, 17.5us OFF each) instead of a permanent +880us LED ON signal.
+Even though being generally CGB compatible, the GBA does not include an +infra-red port.
+
+FF70 - SVBK - CGB Mode Only - WRAM Bank
+
In CGB Mode 32 KBytes internal RAM are available. This memory is divided +into 8 banks of 4 KBytes each. Bank 0 is always available in memory at +C000-CFFF, Bank 1-7 can be selected into the address space at D000-DFFF.
+
  Bit 0-2  Select WRAM Bank (Read/Write)
+
Writing a value of 01h-07h will select Bank 1-7, writing a value of 00h +will select Bank 1 either.
+
+FF6C - Undocumented (FEh) - Bit 0 (Read/Write) - CGB Mode Only
+FF72 - Undocumented (00h) - Bit 0-7 (Read/Write)
+FF73 - Undocumented (00h) - Bit 0-7 (Read/Write)
+FF74 - Undocumented (00h) - Bit 0-7 (Read/Write) - CGB Mode Only
+FF75 - Undocumented (8Fh) - Bit 4-6 (Read/Write)
+FF76 - Undocumented (00h) - Always 00h (Read Only)
+FF77 - Undocumented (00h) - Always 00h (Read Only)
+
These are undocumented CGB Registers. The numbers in brackets () +indicate the initial values. Purpose of these registers is unknown (if +any). Registers FF6C and FF74 are always FFh if the CGB is in Non CGB +Mode.
+
+
+
 SGB Functions

+General Information
+
SGB Description
+SGB Unlocking and Detecting SGB Functions
+SGB Command Packet Transfers
+SGB VRAM Transfers
+SGB Command Summary
+SGB Color Palettes Overview
+
+SGB Commands
+
SGB Palette Commands
+SGB Color Attribute Commands
+SGB Sound Functions
+SGB System Control Commands
+SGB Multiplayer Command
+SGB Border and OBJ Commands
+
+
+
 SGB Description

+General Description
+
Basically, the SGB (Super Gameboy) is an adapter cartridge that allows +to play gameboy games on a SNES (Super Nintendo Entertainment System) +gaming console. In detail, you plug the gameboy cartridge into the SGB +cartridge, then plug the SGB cartridge into the SNES, and then connect +the SNES to your TV Set. In result, games can be played and viewed on +the TV Set, and are controlled by using the SNES joypad(s).
+
+More Technical Description
+
The SGB cartridge just contains a normal gameboy CPU and normal gameboy +video controller. Normally the video signal from this controller would +be sent to the LCD screen, however, in this special case the SNES read +out the video signal and displays it on the TV set by using a special +SNES BIOS ROM which is located in the SGB cartridge. Also, normal +gameboy sound output is forwared to the SNES and output to the TV Set, +vice versa, joypad input is forwared from the SNES controller(s) to the +gameboy joypad inputs.
+
+Normal Monochrome Games
+
Any gameboy games which have been designed for normal monochrome +handheld gameboys will work with the SGB hardware as well. The SGB will +apply a four color palette to these games by replacing the normal four +grayshades. The 160x144 pixel gamescreen is displayed in the middle of +the 256x224 pixel SNES screen (the unused area is filled by a screen +border bitmap). The user may access built-in menues, allowing to change +color palette data, to select between several pre-defined borders, etc.
+
+Games that have been designed to support SGB functions may also access +the following additional features:
+
+Colorized Game Screen
+
There's limited ability to colorize the gamescreen by assigning custom +color palettes to each 20x18 display characters, however, this works +mainly for static display data such like title screens or status bars, +the 20x18 color attribute map is non-scrollable, and it is not possible +to assign separate colors to moveable foreground sprites (OBJs), so that +animated screen regions will be typically restricted to using a single +palette of four colors only.
+
+SNES Foreground Sprites
+
Up to 24 foreground sprites (OBJs) of 8x8 or 16x16 pixels, 16 colors can +be displayed. When replacing (or just overlaying) the normal gameboy +OBJs by SNES OBJs it'd be thus possible to display OBJs with other +colors than normal background area. This method doesn't appear to be +very popular, even though it appears to be quite easy to implement, +however, the bottommost character line of the gamescreen will be masked +out because this area is used to transfer OAM data to the SNES.
+
+The SGB Border
+
The possibly most popular and most impressive feature is to replace the +default SGB screen border by a custom bitmap which is stored in the game +cartridge.
+
+Multiple Joypads
+
Up to four joypads can be conected to the SNES, and SGB software may +read-out each of these joypads separately, allowing up to four players +to play the same game simultaneously. Unlike for multiplayer handheld +games, this requires only one game cartridge and only one SGB/SNES, and +no link cables are required, the downside is that all players must share +the same display screen.
+
+Sound Functions
+
Beside for normal gameboy sound, a number of digital sound effects is +pre-defined in the SNES BIOS, these effects may be accessed quite +easily. Programmers whom are familiar with SNES sounds may also access +the SNES sound chip, or use the SNES MIDI engine directly in order to +produce other sound effects or music.
+
+Taking Control of the SNES CPU
+
Finally, it is possible to write program code or data into SNES memory, +and to execute such program code by using the SNES CPU.
+
+SGB System Clock
+
Because the SGB is synchronized to the SNES CPU, the gameboy system +clock is directly chained to the SNES system clock. In result, the +gameboy CPU, video controller, timers, and sound frequencies will be all +operated approx 2.4% faster as by normal gameboys.
+Basically, this should be no problem, and the game will just run a +little bit faster. However sensitive musicians may notice that sound +frequencies are a bit too high, programs that support SGB functions may +avoid this effect by reducing frequencies of gameboy sounds when having +detected SGB hardware.
+Also, I think that I've heard that SNES models which use a 50Hz display +refresh rate (rather than 60Hz) are resulting in respectively slower +SGB/gameboy timings ???
+
+
+
 SGB Unlocking and Detecting SGB Functions

+Cartridge Header
+
SGB games are required to have a cartridge header with Nintendo and +proper checksum just as normal gameboy games. Also, two special entries +must be set in order to unlock SGB functions:
+
  146h - SGB Flag - Must be set to 03h for SGB games
+  14Bh - Old Licensee Code - Must be set 33h for SGB games
+
When these entries aren't set, the game will still work just like all +'monochrome' gameboy games, but it cannot access any of the special SGB +functions.
+
+Detecting SGB hardware
+
The recommended detection method is to send a MLT_REQ command which +enables two (or four) joypads. A normal handheld gameboy will ignore +this command, a SGB will now return incrementing joypad IDs each time +when deselecting keyboard lines (see MLT_REQ description for details).
+Now read-out joypad state/IDs several times, and if the ID-numbers are +changing, then it is a SGB (a normal gameboy would typically always +return 0Fh as ID). Finally, when not intending to use more than one +joypad, send another MLT_REQ command in order to re-disable the +multi-controller mode.
+Detection works regardless of whether and how many joypads are +physically connected to the SNES. However, detection works only when +having unlocked SGB functions in the cartridge header, as described +above.
+
+Separating between SGB and SGB2
+
It is also possible to separate between SGB and SGB2 models by examining +the inital value of the accumulator (A-register) directly after startup.
+
  01h  SGB or Normal Gameboy (DMG)
+  FFh  SGB2 or Pocket Gameboy
+  11h  CGB or GBA
+
Because values 01h and FFh are shared for both handhelds and SGBs, it is +still required to use the above MLT_REQ detection procedure. As far as I +know the SGB2 doesn't have any extra features which'd require separate +SGB2 detection except for curiosity purposes, for example, the game +"Tetris DX" chooses to display an alternate SGB border on SGB2s.
+
+Reportedly, some SGB models include link ports (just like handheld +gameboy) (my own SGB does not have such an port), possibly this feature +is available in SGB2-type models only ???
+
+
+
 SGB Command Packet Transfers

+Command packets (aka Register Files) are transferred from the gameboy to +the SNES by using P14 and P15 output lines of the JOYPAD register +(FF00h), these lines are normally used to select the two rows in the +gameboy keyboard matrix (which still works).
+
+Transferring Bits
+
A command packet transfer must be initiated by setting both P14 and P15 +to LOW, this will reset and start the SNES packet receiving program. +Data is then transferred (LSB first), setting P14=LOW will indicate a +"0" bit, and setting P15=LOW will indicate a "1" bit. For example:
+
       RESET 0   0   1   1   0   1   0
+  P14  --_---_---_-----------_-------_--...
+  P15  --_-----------_---_-------_------...
+
Data and reset pulses must be kept LOW for at least 5us. P14 and P15 +must be kept both HIGH for at least 15us between any pulses.
+Obviously, it'd be no good idea to access the JOYPAD register during the +transfer, for example, in case that your VBlank interrupt procedure +reads-out joypad states each frame, be sure to disable that interrupt +during the transfer (or disable only the joypad procedure by using a +software flag).
+
+Transferring Packets
+
Each packet is invoked by a RESET pulse, then 128 bits of data are +transferred (16 bytes, LSB of first byte first), and finally, a "0"-bit +must be transferred as stop bit. The structure of normal packets is:
+
   1 PULSE Reset
+   1 BYTE  Command Code*8+Length
+  15 BYTES Parameter Data
+   1 BIT   Stop Bit (0)
+
The above 'Length' indicates the total number of packets (1-7, including +the first packet) which will be sent, ie. if more than 15 parameter +bytes are used, then further packet(s) will follow, as such:
+
   1 PULSE Reset
+  16 BYTES Parameter Data
+   1 BIT   Stop Bit (0)
+
By using all 7 packets, up to 111 data bytes (15+16*6) may be sent.
+Unused bytes at the end of the last packet must be set to zero.
+A 60ms (4 frames) delay should be invoked between each packet transfer.
+
+
+
 SGB VRAM Transfers

+Overview
+
Beside for the packet transfer method, larger data blocks of 4KBytes can +be transferred by using the video signal. These transfers are invoked by +first sending one of the commands with the ending _TRN (by using normal +packet transfer), the 4K data block is then read-out by the SNES from +gameboy display memory during the next frame.
+
+Transfer Data
+
Normally, transfer data should be stored at 8000h-8FFFh in gameboy VRAM,
+even though the SNES receives the data in from display scanlines, it +will automatically re-produce the same ordering of bits and bytes, as +being originally stored at 8000h-8FFFh in gameboy memory.
+
+Preparing the Display
+
The above method works only when recursing the following things: BG Map +must display unsigned characters 00h-FFh on the screen; 00h..13h in +first line, 14h..27h in next line, etc. The gameboy display must be +enabled, the display may not be scrolled, OBJ sprites should not overlap +the background tiles, the BGP palette register must be set to E4h.
+
+Transfer Time
+
Note that the transfer data should be prepared in VRAM <before> sending +the transfer command packet. The actual transfer starts at the beginning +of the next frame after the command has been sent, and the transfer ends +at the end of the 5th frame after the command has been sent (not +counting the frame in which the command has been sent).
+
+Avoiding Screen Garbage
+
The display will contain 'garbage' during the transfer, this dirt-effect +can be avoided by freezing the screen (in the state which has been +displayed before the transfer) by using the MASK_EN command.
+Of course, this works only when actually executing the game on a SGB +(and not on normal handheld gameboys), it'd be thus required to detect +the presence of SGB hardware before blindly sending VRAM data.
+
+
+
 SGB Command Summary

+SGB System Command Table
+
  Code Name      Expl.
+  00   PAL01     Set SGB Palette 0,1 Data
+  01   PAL23     Set SGB Palette 2,3 Data
+  02   PAL03     Set SGB Palette 0,3 Data
+  03   PAL12     Set SGB Palette 1,2 Data
+  04   ATTR_BLK  "Block" Area Designation Mode
+  05   ATTR_LIN  "Line" Area Designation Mode
+  06   ATTR_DIV  "Divide" Area Designation Mode
+  07   ATTR_CHR  "1CHR" Area Designation Mode
+  08   SOUND     Sound On/Off
+  09   SOU_TRN   Transfer Sound PRG/DATA
+  0A   PAL_SET   Set SGB Palette Indirect
+  0B   PAL_TRN   Set System Color Palette Data
+  0C   ATRC_EN   Enable/disable Attraction Mode
+  0D   TEST_EN   Speed Function
+  0E   ICON_EN   SGB Function
+  0F   DATA_SND  SUPER NES WRAM Transfer 1
+  10   DATA_TRN  SUPER NES WRAM Transfer 2
+  11   MLT_REG   Controller 2 Request
+  12   JUMP      Set SNES Program Counter
+  13   CHR_TRN   Transfer Character Font Data
+  14   PCT_TRN   Set Screen Data Color Data
+  15   ATTR_TRN  Set Attribute from ATF
+  16   ATTR_SET  Set Data to ATF
+  17   MASK_EN   Game Boy Window Mask
+  18   OBJ_TRN   Super NES OBJ Mode
+

+
+
 SGB Color Palettes Overview

+Available SNES Palettes
+
The SGB/SNES provides 8 palettes of 16 colors each, each color may be +defined out of a selection of 34768 colors (15 bit). Palettes 0-3 are +used to colorize the gamescreen, only the first four colors of each of +these palettes are used. Palettes 4-7 are used for the SGB Border, all +16 colors of each of these palettes may be used.
+
+Color 0 Restriction
+
Color 0 of each of the eight palettes is transparent, causing the +backdrop color to be displayed instead. The backdrop color is typically +defined by the most recently color being assigned to Color 0 (regardless +of the palette number being used for that operation).
+Effectively, gamescreen palettes can have only three custom colors each, +and SGB border palettes only 15 colors each, additionally, color 0 can +be used for for all palettes, which will then all share the same color +though.
+
+Translation of Grayshades into Colors
+
Because the SGB/SNES reads out the gameboy video controllers display +signal, it translates the different grayshades from the signal into SNES +colors as such:
+
  White       -->  Color 0
+  Light Gray  -->  Color 1
+  Dark Gray   -->  Color 2
+  Black       -->  Color 3
+
Note that gameboy colors 0-3 are assigned to user-selectable grayshades +by the gameboys BGP, OBP1, and OBP2 registers. There is thus no fixed +relationship between gameboy colors 0-3 and SNES colors 0-3.
+
+Using Gameboy BGP/OBP Registers
+
A direct translation of color 0-3 into color 0-3 may be produced by +setting BGP/OBP registers to a value of 0E4h each. However, in case that +your program uses black background for example, then you may internally +assign background as "White" at the gameboy side by BGP/OBP registers +(which is then interpreted as SNES color 0, which is shared for all SNES +palettes). The advantage is that you may define Color 0 as Black at the +SNES side, and may assign custom colors for Colors 1-3 of each SNES +palette.
+
+System Color Palette Memory
+
Beside for the actually visible palettes, up to 512 palettes of 4 colors +each may be defined in SNES RAM. Basically, this is completely +irrelevant because the palettes are just stored in RAM whithout any +relationship to the displayed picture, anyways, these pre-defined colors +may be transferred to actually visible palettes slightly faster as when +transferring palette data by separate command packets.
+
+
+
 SGB Palette Commands

+SGB Command 00h - PAL01
+
Transmit color data for SGB palette 0, color 0-3, and for SGB palette 1, +color 1-3 (without separate color 0).
+
  Byte  Content
+  0     Command*8+Length (fixed length=01h)
+  1-E   Color Data for 7 colors of 2 bytes (16bit) each:
+          Bit 0-4   - Red Intensity   (0-31)
+          Bit 5-9   - Green Intensity (0-31)
+          Bit 10-14 - Blue Intensity  (0-31)
+          Bit 15    - Not used (zero)
+  F     Not used (00h)
+
The value transferred as color 0 will be applied for all eight palettes.
+
+SGB Command 01h - PAL23
+
Same as above PAL01, but for Palettes 2 and 3 respectively.
+
+SGB Command 02h - PAL03
+
Same as above PAL01, but for Palettes 0 and 3 respectively.
+
+SGB Command 03h - PAL12
+
Same as above PAL01, but for Palettes 1 and 2 respectively.
+
+SGB Command 0Ah - PAL_SET
+
Used to copy pre-defined palette data from SGB system color palette to +actual SGB palette.
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1-2   System Palette number for SGB Color Palette 0 (0-511)
+  3-4   System Palette number for SGB Color Palette 1 (0-511)
+  5-6   System Palette number for SGB Color Palette 2 (0-511)
+  7-8   System Palette number for SGB Color Palette 3 (0-511)
+  9     Attribute File
+          Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1)
+          Bit 6   - Cancel Mask           (0=No change, 1=Yes)
+          Bit 7   - Use Attribute File    (0=No, 1=Apply above ATF Number)
+  A-F   Not used (zero)
+
Before using this function, System Palette data should be initialized by +PAL_TRN command, and (when used) Attribute File data should be +initialized by ATTR_TRN.
+
+SGB Command 0Bh - PAL_TRN
+
Used to initialize SGB system color palettes in SNES RAM.
+System color palette memory contains 512 pre-defined palettes, these +palettes do not directly affect the display, however, the PAL_SET +command may be later used to transfer four of these 'logical' palettes +to actual visible 'physical' SGB palettes. Also, the OBJ_TRN function +will use groups of 4 System Color Palettes (4*4 colors) for SNES OBJ +palettes (16 colors).
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1-F   Not used (zero)
+
The palette data is sent by VRAM-Transfer (4 KBytes).
+
  000-FFF  Data for System Color Palette 0-511
+
Each Palette consists of four 16bit-color definitions (8 bytes).
+Note: The data is stored at 3000h-3FFFh in SNES memory.
+
+
+
 SGB Color Attribute Commands

+SGB Command 04h - ATTR_BLK
+
Used to specify color attributes for the inside or outside of one or +more rectangular screen regions.
+
  Byte  Content
+  0     Command*8+Length (length=1..7)
+  1     Number of Data Sets (01h..12h)
+  2-7   Data Set #1
+          Byte 0 - Control Code (0-7)
+            Bit 0 - Change Colors inside of surrounded area     (1=Yes)
+            Bit 1 - Change Colors of surrounding character line (1=Yes)
+            Bit 2 - Change Colors outside of surrounded area    (1=Yes)
+            Bit 3-7 - Not used (zero)
+            Exception: When changing only the Inside or Outside, then the
+            Surrounding line becomes automatically changed to same color.
+          Byte 1 - Color Palette Designation
+            Bit 0-1 - Palette Number for inside of surrounded area
+            Bit 2-3 - Palette Number for surrounding character line
+            Bit 4-5 - Palette Number for outside of surrounded area
+            Bit 6-7 - Not used (zero)
+          Data Set Byte 2 - Coordinate X1 (left)
+          Data Set Byte 3 - Coordinate Y1 (upper)
+          Data Set Byte 4 - Coordinate X2 (right)
+          Data Set Byte 5 - Coordinate Y2 (lower)
+            Specifies the coordinates of the surrounding rectangle.
+  8-D   Data Set #2 (if any)
+  E-F   Data Set #3 (continued at 0-3 in next packet) (if any)
+
When sending three or more data sets, data is continued in further +packet(s). Unused bytes at the end of the last packet should be set to +zero. The format of the separate Data Sets is described below.
+
+SGB Command 05h - ATTR_LIN
+
Used to specify color attributes of one or more horizontal or vertical +character lines.
+
  Byte  Content
+  0     Command*8+Length (length=1..7)
+  1     Number of Data Sets (01h..6Eh) (one byte each)
+  2     Data Set #1
+          Bit 0-4 - Line Number    (X- or Y-coordinate, depending on bit 7)
+          Bit 5-6 - Palette Number (0-3)
+          Bit 7   - H/V Mode Bit   (0=Vertical line, 1=Horizontal Line)
+  3     Data Set #2 (if any)
+  4     Data Set #3 (if any)
+  etc.
+
When sending 15 or more data sets, data is continued in further +packet(s). Unused bytes at the end of the last packet should be set to +zero. The format of the separate Data Sets (one byte each) is described +below.
+The length of each line reaches from one end of the screen to the other +end. In case that some lines overlap each other, then lines from +lastmost data sets will overwrite lines from previous data sets.
+
+SGB Command 06h - ATTR_DIV
+
Used to split the screen into two halfes, and to assign separate color +attributes to each half, and to the division line between them.
+
  Byte  Content
+  0     Command*8+Length   (fixed length=1)
+  1     Color Palette Numbers and H/V Mode Bit
+          Bit 0-1  Palette Number below/right of division line
+          Bit 2-3  Palette Number above/left of division line
+          Bit 4-5  Palette Number for division line
+          Bit 6    H/V Mode Bit  (0=split left/right, 1=split above/below)
+  2     X- or Y-Coordinate (depending on H/V bit)
+  3-F   Not used (zero)
+

+SGB Command 07h - ATTR_CHR
+
Used to specify color attributes for separate characters.
+
  Byte  Content
+  0     Command*8+Length (length=1..6)
+  1     Beginning X-Coordinate
+  2     Beginning Y-Coordinate
+  3-4   Number of Data Sets (1-360)
+  5     Writing Style   (0=Left to Right, 1=Top to Bottom)
+  6     Data Sets 1-4   (Set 1 in MSBs, Set 4 in LSBs)
+  7     Data Sets 5-8   (if any)
+  8     Data Sets 9-12  (if any)
+  etc.
+
When sending 41 or more data sets, data is continued in further +packet(s). Unused bytes at the end of the last packet should be set to +zero. Each data set consists of two bits, indicating the palette number +for one character.
+Depending on the writing style, data sets are written from left to +right, or from top to bottom. In either case the function wraps to the +next row/column when reaching the end of the screen.
+
+SGB Command 15h - ATTR_TRN
+
Used to initialize Attribute Files (ATFs) in SNES RAM. Each ATF consists +of 20x18 color attributes for the gameboy screen. This function does not +directly affect display attributes. Instead, one of the defined ATFs may +be copied to actual display memory at a later time by using ATTR_SET or +PAL_SET functions.
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1-F   Not used (zero)
+
The ATF data is sent by VRAM-Transfer (4 KBytes).
+
  000-FD1  Data for ATF0 through ATF44 (4050 bytes)
+  FD2-FFF  Not used
+
Each ATF consists of 90 bytes, that are 5 bytes (20x2bits) for each of +the 18 character lines of the gameboy window. The two most significant +bits of the first byte define the color attribute (0-3) for the first +character of the first line, the next two bits the next character, and +so on.
+
+SGB Command 16h - ATTR_SET
+
Used to transfer attributes from Attribute File (ATF) to gameboy window.
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1     Attribute File Number (00-2Ch), Bit 6=Cancel Mask
+  2-F   Not used (zero)
+
When above Bit 6 is set, the gameboy screen becomes re-enabled after the +transfer (in case it has been disabled/frozen by MASK_EN command).
+Note: The same functions may be (optionally) also included in PAL_SET +commands, as described in the chapter about Color Palette Commands.
+
+
+
 SGB Sound Functions

+SGB Command 08h - SOUND
+
Used to start/stop internal sound effect, start/stop sound using +internal tone data.
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1     Sound Effect A (Port 1) Decrescendo 8bit Sound Code
+  2     Sound Effect B (Port 2) Sustain     8bit Sound Code
+  3     Sound Effect Attributes
+          Bit 0-1 - Sound Effect A Pitch  (0..3=Low..High)
+          Bit 2-3 - Sound Effect A Volume (0..2=High..Low, 3=Mute on)
+          Bit 4-5 - Sound Effect B Pitch  (0..3=Low..High)
+          Bit 6-7 - Sound Effect B Volume (0..2=High..Low, 3=Not used)
+  4     Music Score Code (must be zero if not used)
+  5-F   Not used (zero)
+
See Sound Effect Tables below for a list of available pre-defined effects.
+"Notes"
+1) Mute is only active when both bits D2 and D3 are 1.
+2) When the volume is set for either Sound Effect A or Sound Effect B, +mute is turned off.
+3) When Mute on/off has been executed, the sound fades out/fades in.
+4) Mute on/off operates on the (BGM) which is reproduced by Sound Effect +A, Sound Effect B, and the Super NES APU. A "mute off" flag does not +exist by itself. When mute flag is set, volume and pitch of Sound Effect +A (port 1) and Sound Effect B (port 2) must be set.
+
+SGB Command 09h - SOU_TRN
+
Used to transfer sound code or data to SNES Audio Processing Unit memory +(APU-RAM).
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1-F   Not used (zero)
+
The sound code/data is sent by VRAM-Transfer (4 KBytes).
+
  000      One (or two ???) 16bit expression(s ???) indicating the
+           transfer destination address and transfer length.
+  ...-...  Transfer Data
+  ...-FFF  Remaining bytes not used
+
Possible destinations in APU-RAM are:
+
  0400h-2AFFh  APU-RAM Program Area (9.75KBytes)
+  2B00h-4AFFh  APU-RAM Sound Score Area (8Kbytes)
+  4DB0h-EEFFh  APU-RAM Sampling Data Area (40.25 Kbytes)
+
This function may be used to take control of the SNES sound chip, and/or +to access the SNES MIDI engine. In either case it requires deeper +knowledge of SNES sound programming.
+
+SGB Sound Effect A/B Tables
+
Below lists the digital sound effects that are pre-defined in the +SGB/SNES BIOS, and which can be used with the SGB "SOUND" Command.
+Effect A and B may be simultaneously reproduced.
+The P-column indicates the recommended Pitch value, the V-column +indicates the numbers of Voices used. Sound Effect A uses voices 6,7. +Sound Effect B uses voices 0,1,4,5. Effects that use less voices will +use only the upper voices (eg. 4,5 for Effect B with only two voices).
+
+Sound Effect A Flag Table
+
  Code Description             P V     Code Description             P V
+  00  Dummy flag, re-trigger   - 2     18  Fast Jump                3 1
+  80  Effect A, stop/silent    - 2     19  Jet (rocket) takeoff     0 1
+  01  Nintendo                 3 1     1A  Jet (rocket) landing     0 1
+  02  Game Over                3 2     1B  Cup breaking             2 2
+  03  Drop                     3 1     1C  Glass breaking           1 2
+  04  OK ... A                 3 2     1D  Level UP                 2 2
+  05  OK ... B                 3 2     1E  Insert air               1 1
+  06  Select...A               3 2     1F  Sword swing              1 1
+  07  Select...B               3 1     20  Water falling            2 1
+  08  Select...C               2 2     21  Fire                     1 1
+  09  Mistake...Buzzer         2 1     22  Wall collapsing          1 2
+  0A  Catch Item               2 2     23  Cancel                   1 2
+  0B  Gate squeaks 1 time      2 2     24  Walking                  1 2
+  0C  Explosion...small        1 2     25  Blocking strike          1 2
+  0D  Explosion...medium       1 2     26  Picture floats on & off  3 2
+  0E  Explosion...large        1 2     27  Fade in                  0 2
+  0F  Attacked...A             3 1     28  Fade out                 0 2
+  10  Attacked...B             3 2     29  Window being opened      1 2
+  11  Hit (punch)...A          0 2     2A  Window being closed      0 2
+  12  Hit (punch)...B          0 2     2B  Big Laser                3 2
+  13  Breath in air            3 2     2C  Stone gate closes/opens  0 2
+  14  Rocket Projectile...A    3 2     2D  Teleportation            3 1
+  15  Rocket Projectile...B    3 2     2E  Lightning                0 2
+  16  Escaping Bubble          2 1     2F  Earthquake               0 2
+  17  Jump                     3 1     30  Small Laser              2 2
+
Sound effect A is used for formanto sounds (percussion sounds).
+
+Sound Effect B Flag Table
+
  Code Description             P V     Code Description             P V
+  00  Dummy flag, re-trigger   - 4     0D  Waterfall                2 2
+  80  Effect B, stop/silent    - 4     0E  Small character running  3 1
+  01  Applause...small group   2 1     0F  Horse running            3 1
+  02  Applause...medium group  2 2     10  Warning sound            1 1
+  03  Applause...large group   2 4     11  Approaching car          0 1
+  04  Wind                     1 2     12  Jet flying               1 1
+  05  Rain                     1 1     13  UFO flying               2 1
+  06  Storm                    1 3     14  Electromagnetic waves    0 1
+  07  Storm with wind/thunder  2 4     15  Score UP                 3 1
+  08  Lightning                0 2     16  Fire                     2 1
+  09  Earthquake               0 2     17  Camera shutter, formanto 3 4
+  0A  Avalanche                0 2     18  Write, formanto          0 1
+  0B  Wave                     0 1     19  Show up title, formanto  0 1
+  0C  River                    3 2
+
Sound effect B is mainly used for looping sounds (sustained sounds).
+
+
+
 SGB System Control Commands

+SGB Command 17h - MASK_EN
+
Used to mask the gameboy window, among others this can be used to freeze +the gameboy screen before transferring data through VRAM (the SNES then +keeps displaying the gameboy screen, even though VRAM doesn't contain +meaningful display information during the transfer).
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1     Gameboy Screen Mask (0-3)
+          0  Cancel Mask   (Display activated)
+          1  Freeze Screen (Keep displaying current picture)
+          2  Blank Screen  (Black)
+          3  Blank Screen  (Color 0)
+  2-F   Not used (zero)
+
Freezing works only if the SNES has stored a picture, ie. if necessary +wait one or two frames before freezing (rather than freezing directly +after having displayed the picture).
+The Cancel Mask function may be also invoked (optionally) by completion +of PAL_SET and ATTR_SET commands.
+
+SGB Command 0Ch - ATRC_EN
+
Used to enable/disable Attraction mode. It is totally unclear what an +attraction mode is ???, but it is enabled by default.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     Attraction Disable  (0=Enable, 1=Disable)
+  2-F   Not used (zero)
+

+SGB Command 0Dh - TEST_EN
+
Used to enable/disable test mode for "SGB-CPU variable clock speed +function". This function is disabled by default.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     Test Mode Enable    (0=Disable, 1=Enable)
+  2-F   Not used (zero)
+
Maybe intended to determine whether SNES operates at 50Hz or 60Hz +display refresh rate ??? Possibly result can be read-out from joypad +register ???
+
+SGB Command 0Eh - ICON_EN
+
Used to enable/disable ICON function. Possibly meant to enable/disable +SGB/SNES popup menues which might otherwise activated during gameboy +game play. By default all functions are enabled (0).
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     Disable Bits
+          Bit 0 - Use of SGB-Built-in Color Palettes    (1=Disable)
+          Bit 1 - Controller Set-up Screen    (0=Enable, 1=Disable)
+          Bit 2 - SGB Register File Transfer (0=Receive, 1=Disable)
+          Bit 3-6 - Not used (zero)
+  2-F   Not used (zero)
+
Above Bit 2 will suppress all further packets/commands when set, this +might be useful when starting a monochrome game from inside of the +SGB-menu of a multi-gamepak which contains a collection of different +games.
+
+SGB Command 0Fh - DATA_SND
+
Used to write one or more bytes directly into SNES Work RAM.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     SNES Destination Address, low
+  2     SNES Destination Address, high
+  3     SNES Destination Address, bank number
+  4     Number of bytes to write (01h-0Bh)
+  5     Data Byte #1
+  6     Data Byte #2 (if any)
+  7     Data Byte #3 (if any)
+  etc.
+
Unused bytes at the end of the packet should be set to zero, this +function is restricted to a single packet, so that not more than 11 +bytes can be defined at once.
+Free Addresses in SNES memory are Bank 0 1800h-1FFFh, Bank 7Fh +0000h-FFFFh.
+
+SGB Command 10h - DATA_TRN
+
Used to transfer binary code or data directly into SNES RAM.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     SNES Destination Address, low
+  2     SNES Destination Address, high
+  3     SNES Destination Address, bank number
+  4-F   Not used (zero)
+
The data is sent by VRAM-Transfer (4 KBytes).
+
  000-FFF  Data
+
Free Addresses in SNES memory are Bank 0 1800h-1FFFh, Bank 7Fh +0000h-FFFFh. The transfer length is fixed at 4KBytes ???, so that directly +writing to the free 2KBytes at 0:1800h would be a not so good idea ???
+
+SGB Command 12h - JUMP
+
Used to set the SNES program counter to a specified address. Optionally, +it may be used to set a new address for the SNES NMI handler, the NMI +handler remains unchanged if all bytes 4-6 are zero.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     SNES Program Counter, low
+  2     SNES Program Counter, high
+  3     SNES Program Counter, bank number
+  4     SNES NMI Handler, low
+  5     SNES NMI Handler, high
+  6     SNES NMI Handler, bank number
+  7-F   Not used, zero
+
Note: The game "Space Invaders 94" uses this function when selecting +"Arcade mode" to execute SNES program code which has been previously +transferred from the SGB to the SNES. The type of the CPU which is used +in the SNES is unknown ???
+
+
+
 SGB Multiplayer Command

+SGB Command 11h - MLT_REQ
+
Used to request multiplayer mode (ie. input from more than one joypad).
+Because this function provides feedback from the SGB/SNES to the gameboy +program, it is also used to detect SGB hardware.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     Multiplayer Control (0-3) (Bit0=Enable, Bit1=Two/Four Players)
+          0 = One player
+          1 = Two players
+          3 = Four players
+  2-F   Not used (zero)
+
In one player mode, the second joypad (if any) is used for the SGB +system program. In two player mode, both joypads are used for the game. +Because SNES have only two joypad sockets, four player mode requires an +external "Multiplayer 5" adapter.
+
+Reading Multiple Controllers (Joypads)
+
When having enabled multiple controllers by MLT_REQ, data for each +joypad can be read out through JOYPAD register (FF00) as follows: First +set P14 and P15 both HIGH (deselect both Buttons and Cursor keys), you +can now read the lower 4bits of FF00 which indicate the joypad ID for +the following joypad input:
+
  0Fh  Joypad 1
+  0Eh  Joypad 2
+  0Dh  Joypad 3
+  0Ch  Joypad 4
+
Next, set P14 and P15 low (one after each other) to select Buttons and +Cursor lines, and read-out joypad state as normally. When completed, set +P14 and P15 back HIGH, this automatically increments the joypad number +(or restarts counting once reached the lastmost joypad). Repeat the +procedure until you have read-out states for all two (or four) joypads.
+
+
+
 SGB Border and OBJ Commands

+SGB Command 13h - CHR_TRN
+
Used to transfer tile data (characters) to SNES Tile memory in VRAM. This +normally used to define BG tiles for the SGB Border (see PCT_TRN), but +might be also used to define moveable SNES foreground sprites (see +OBJ_TRN).
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1     Tile Transfer Destination
+          Bit 0   - Tile Numbers   (0=Tiles 00h-7Fh, 1=Tiles 80h-FFh)
+          Bit 1   - Tile Type      (0=BG Tiles, 1=OBJ Tiles)
+          Bit 2-7 - Not used (zero)
+  2-F   Not used (zero)
+
The tile data is sent by VRAM-Transfer (4 KBytes).
+
  000-FFF  Bitmap data for 128 Tiles
+
Each tile occupies 16bytes (8x8 pixels, 16 colors each).
+When intending to transfer more than 128 tiles, call this function twice +(once for tiles 00h-7Fh, and once for tiles 80h-FFh). Note: The BG/OBJ +Bit seems to have no effect and writes to the same VRAM addresses for +both BG and OBJ ???
+
+SGB Command 14h - PCT_TRN
+
Used to transfer tile map data and palette data to SNES BG Map memory in +VRAM to be used for the SGB border. The actual tiles must be separately +transferred by using the CHR_TRN function.
+
  Byte  Content
+  0     Command*8+Length    (fixed length=1)
+  1-F   Not used (zero)
+
The map data is sent by VRAM-Transfer (4 KBytes).
+
  000-7FF  BG Map 32x32 Entries of 16bit each (2048 bytes)
+  800-87F  BG Palette Data (Palettes 4-7, each 16 colors of 16bits each)
+  880-FFF  Not used, don't care
+
Each BG Map Entry consists of a 16bit value as such:
+
  Bit 0-9   - Character Number (use only 00h-FFh, upper 2 bits zero)
+  Bit 10-12 - Palette Number   (use only 4-7, officially use only 4-6)
+  Bit 13    - BG Priority      (use only 0)
+  Bit 14    - X-Flip           (0=Normal, 1=Mirror horizontally)
+  Bit 15    - Y-Flip           (0=Normal, 1=Mirror vertically)
+
Even though 32x32 map entries are transferred, only upper 32x28 are +actually used (256x224 pixels, SNES screen size). The 20x18 entries in +the center of the 32x28 area should be set to 0000h as transparent space +for the gameboy window to be displayed inside. Reportedly, +non-transparent border data will cover the gameboy window.
+
+SGB Command 18h - OBJ_TRN
+
Used to transfer OBJ attributes to SNES OAM memory. Unlike all other +functions with the ending _TRN, this function does not use the usual +one-shot 4KBytes VRAM transfer method.
+Instead, when enabled (below execute bit set), data is permanently (each +frame) read out from the lower character line of the gameboy screen. To +suppress garbage on the display, the lower line is masked, and only the +upper 20x17 characters of the gameboy window are used - the masking +method is unknwon - frozen, black, or recommended to be covered by the +SGB border, or else ??? Also, when the function is enabled, "system +attract mode is not performed" - whatever that means ???
+
  Byte  Content
+  0     Command*8+Length (fixed length=1)
+  1     Control Bits
+          Bit 0   - SNES OBJ Mode enable (0=Cancel, 1=Enable)
+          Bit 1   - Change OBJ Color     (0=No, 1=Use definitions below)
+          Bit 2-7 - Not used (zero)
+  2-3   System Color Palette Number for OBJ Palette 4 (0-511)
+  4-5   System Color Palette Number for OBJ Palette 5 (0-511)
+  6-7   System Color Palette Number for OBJ Palette 6 (0-511)
+  8-9   System Color Palette Number for OBJ Palette 7 (0-511)
+          These color entries are ignored if above Control Bit 1 is zero.
+          Because each OBJ palette consists of 16 colors, four system
+          palette entries (of 4 colors each) are transferred into each
+          OBJ palette. The system palette numbers are not required to be
+          aligned to a multiple of four, and will wrap to palette number
+          0 when exceeding 511. For example, a value of 511 would copy
+          system palettes 511, 0, 1, 2 to the SNES OBJ palette.
+  A-F   Not used (zero)
+
The recommended method is to "display" gameboy BG tiles F9h..FFh from +left to right as first 7 characters of the bottom-most character line of +the gameboy screen. As for normal 4KByte VRAM transfers, this area +should not be scrolled, should not be overlapped by gameboy OBJs, and +the gameboy BGP palette register should be set up properly. By following +that method, SNES OAM data can be defined in the 70h bytes of the +gameboy BG tile memory at following addresses:
+
  8F90-8FEF  SNES OAM, 24 Entries of 4 bytes each (96 bytes)
+  8FF0-8FF5  SNES OAM MSBs, 24 Entries of 2 bits each (6 bytes)
+  8FF6-8FFF  Not used, don't care (10 bytes)
+
The format of SNES OAM Entries is:
+
  Byte 0  OBJ X-Position (0-511, MSB is separately stored, see below)
+  Byte 1  OBJ Y-Position (0-255)
+  Byte 2-3  Attributes (16bit)
+    Bit 0-8    Tile Number     (use only 00h-FFh, upper bit zero)
+    Bit 9-11   Palette Number  (use only 4-7)
+    Bit 12-13  OBJ Priority    (use only 3)
+    Bit 14     X-Flip          (0=Normal, 1=Mirror horizontally)
+    Bit 15     Y-Flip          (0=Normal, 1=Mirror vertically)
+
The format of SNES OAM MSB Entries is:
+
  Actually, the format is unknown ??? However, 2 bits are used per entry:
+  One bit is the most significant bit of the OBJ X-Position.
+  The other bit specifies the OBJ size (8x8 or 16x16 pixels).
+

+
+
 CPU Registers and Flags

+Registers
+
  16bit Hi   Lo   Name/Function
+  AF    A    -    Accumulator & Flags
+  BC    B    C    BC
+  DE    D    E    DE
+  HL    H    L    HL
+  SP    -    -    Stack Pointer
+  PC    -    -    Program Counter/Pointer
+
As shown above, most registers can be accessed either as one 16bit +register, or as two separate 8bit registers.
+
+The Flag Register (lower 8bit of AF register)
+
  Bit  Name  Set Clr  Expl.
+  7    zf    Z   NZ   Zero Flag
+  6    n     -   -    Add/Sub-Flag (BCD)
+  5    h     -   -    Half Carry Flag (BCD)
+  4    cy    C   NC   Carry Flag
+  3-0  -     -   -    Not used (always zero)
+
Conatins the result from the recent instruction which has affected +flags.
+
+The Zero Flag (Z)
+
This bit becomes set (1) if the result of an operation has been zero +(0). Used for conditional jumps.
+
+The Carry Flag (C, or Cy)
+
Becomes set when the result of an addition became bigger than FFh (8bit) +or FFFFh (16bit). Or when the result of a subtraction or comparision +became less than zero (much as for Z80 and 80x86 CPUs, but unlike as for +65XX and ARM CPUs). Also the flag becomes set when a rotate/shift +operation has shifted-out a "1"-bit.
+Used for conditional jumps, and for instructions such like ADC, SBC, RL, +RLA, etc.
+
+The BCD Flags (N, H)
+
These flags are (rarely) used for the DAA instruction only, N Indicates +whether the previous instruction has been an addition or subtraction, +and H indicates carry for lower 4bits of the result, also for DAA, the C +flag must indicate carry for upper 8bits.
+After adding/subtracting two BCD numbers, DAA is intended to convert the +result into BCD format; BCD numbers are ranged from 00h to 99h rather +than 00h to FFh.
+Because C and H flags must contain carry-outs for each digit, DAA cannot +be used for 16bit operations (which have 4 digits), or for INC/DEC +operations (which do not affect C-flag).
+
+
+
 CPU Instruction Set

+Tables below specify the mnemonic, opcode bytes, clock cycles, affected +flags (ordered as znhc), and explanatation.
+The timings assume a CPU clock frequency of 4.194304 MHz (or 8.4
+MHz for CGB in double speed mode), as all gameboy timings are divideable
+by 4, many people specify timings and clock frequency divided by 4.
+
+GMB 8bit-Loadcommands
+
  ld   r,r         xx         4 ---- r=r
+  ld   r,n         xx nn      8 ---- r=n
+  ld   r,(HL)      xx         8 ---- r=(HL)
+  ld   (HL),r      7x         8 ---- (HL)=r
+  ld   (HL),n      36 nn     12 ----
+  ld   A,(BC)      0A         8 ----
+  ld   A,(DE)      1A         8 ----
+  ld   A,(nn)      FA        16 ----
+  ld   (BC),A      02         8 ----
+  ld   (DE),A      12         8 ----
+  ld   (nn),A      EA        16 ----
+  ld   A,(FF00+n)  F0 nn     12 ---- read from io-port n (memory FF00+n)
+  ld   (FF00+n),A  E0 nn     12 ---- write to io-port n (memory FF00+n)
+  ld   A,(FF00+C)  F2         8 ---- read from io-port C (memory FF00+C)
+  ld   (FF00+C),A  E2         8 ---- write to io-port C (memory FF00+C)
+  ldi  (HL),A      22         8 ---- (HL)=A, HL=HL+1
+  ldi  A,(HL)      2A         8 ---- A=(HL), HL=HL+1
+  ldd  (HL),A      32         8 ---- (HL)=A, HL=HL-1
+  ldd  A,(HL)      3A         8 ---- A=(HL), HL=HL-1
+

+GMB 16bit-Loadcommands
+
  ld   rr,nn       x1 nn nn  12 ---- rr=nn (rr may be BC,DE,HL or SP)
+  ld   SP,HL       F9         8 ---- SP=HL
+  push rr          x5        16 ---- SP=SP-2  (SP)=rr   (rr may be BC,DE,HL,AF)
+  pop  rr          x1        12 (AF) rr=(SP)  SP=SP+2   (rr may be BC,DE,HL,AF)
+

+GMB 8bit-Arithmetic/logical Commands
+
  add  A,r         8x         4 z0hc A=A+r
+  add  A,n         C6 nn      8 z0hc A=A+n
+  add  A,(HL)      86         8 z0hc A=A+(HL)
+  adc  A,r         8x         4 z0hc A=A+r+cy
+  adc  A,n         CE nn      8 z0hc A=A+n+cy
+  adc  A,(HL)      8E         8 z0hc A=A+(HL)+cy
+  sub  r           9x         4 z1hc A=A-r
+  sub  n           D6 nn      8 z1hc A=A-n
+  sub  (HL)        96         8 z1hc A=A-(HL)
+  sbc  A,r         9x         4 z1hc A=A-r-cy
+  sbc  A,n         DE nn      8 z1hc A=A-n-cy
+  sbc  A,(HL)      9E         8 z1hc A=A-(HL)-cy
+  and  r           Ax         4 z010 A=A & r
+  and  n           E6 nn      8 z010 A=A & n
+  and  (HL)        A6         8 z010 A=A & (HL)
+  xor  r           Ax         4 z000
+  xor  n           EE nn      8 z000
+  xor  (HL)        AE         8 z000
+  or   r           Bx         4 z000 A=A | r
+  or   n           F6 nn      8 z000 A=A | n
+  or   (HL)        B6         8 z000 A=A | (HL)
+  cp   r           Bx         4 z1hc compare A-r
+  cp   n           FE nn      8 z1hc compare A-n
+  cp   (HL)        BE         8 z1hc compare A-(HL)
+  inc  r           xx         4 z0h- r=r+1
+  inc  (HL)        34        12 z0h- (HL)=(HL)+1
+  dec  r           xx         4 z1h- r=r-1
+  dec  (HL)        35        12 z1h- (HL)=(HL)-1
+  daa              27         4 z-0x decimal adjust akku
+  cpl              2F         4 -11- A = A xor FF
+

+GMB 16bit-Arithmetic/logical Commands
+
  add  HL,rr     x9           8 -0hc HL = HL+rr     ;rr may be BC,DE,HL,SP
+  inc  rr        x3           8 ---- rr = rr+1      ;rr may be BC,DE,HL,SP
+  dec  rr        xB           8 ---- rr = rr-1      ;rr may be BC,DE,HL,SP
+  add  SP,dd     E8          16 00hc SP = SP +/- dd ;dd is 8bit signed number
+  ld   HL,SP+dd  F8          12 00hc HL = SP +/- dd ;dd is 8bit signed number
+

+GMB Rotate- und Shift-Commands
+
  rlca           07           4 000c rotate akku left
+  rla            17           4 000c rotate akku left through carry
+  rrca           0F           4 000c rotate akku right
+  rra            1F           4 000c rotate akku right through carry
+  rlc  r         CB 0x        8 z00c rotate left
+  rlc  (HL)      CB 06       16 z00c rotate left
+  rl   r         CB 1x        8 z00c rotate left through carry
+  rl   (HL)      CB 16       16 z00c rotate left through carry
+  rrc  r         CB 0x        8 z00c rotate right
+  rrc  (HL)      CB 0E       16 z00c rotate right
+  rr   r         CB 1x        8 z00c rotate right through carry
+  rr   (HL)      CB 1E       16 z00c rotate right through carry
+  sla  r         CB 2x        8 z00c shift left arithmetic (b0=0)
+  sla  (HL)      CB 26       16 z00c shift left arithmetic (b0=0)
+  swap r         CB 3x        8 z000 exchange low/hi-nibble
+  swap (HL)      CB 36       16 z000 exchange low/hi-nibble
+  sra  r         CB 2x        8 z00c shift right arithmetic (b7=b7)
+  sra  (HL)      CB 2E       16 z00c shift right arithmetic (b7=b7)
+  srl  r         CB 3x        8 z00c shift right logical (b7=0)
+  srl  (HL)      CB 3E       16 z00c shift right logical (b7=0)
+

+GMB Singlebit Operation Commands
+
  bit  n,r       CB xx        8 z01- test bit n
+  bit  n,(HL)    CB xx       12 z01- test bit n
+  set  n,r       CB xx        8 ---- set bit n
+  set  n,(HL)    CB xx       16 ---- set bit n
+  res  n,r       CB xx        8 ---- reset bit n
+  res  n,(HL)    CB xx       16 ---- reset bit n
+

+GMB CPU-Controlcommands
+
  ccf            3F           4 -00c cy=cy xor 1
+  scf            37           4 -001 cy=1
+  nop            00           4 ---- no operation
+  halt           76         N*4 ---- halt until interrupt occurs (low power)
+  stop           10 00        ? ---- low power standby mode (VERY low power)
+  di             F3           4 ---- disable interrupts, IME=0
+  ei             FB           4 ---- enable interrupts, IME=1
+

+GMB Jumpcommands
+
  jp   nn        C3 nn nn    16 ---- jump to nn, PC=nn
+  jp   HL        E9           4 ---- jump to HL, PC=HL
+  jp   f,nn      xx nn nn 16;12 ---- conditional jump if nz,z,nc,c
+  jr   PC+dd     18 dd       12 ---- relative jump to nn (PC=PC+/-7bit)
+  jr   f,PC+dd   xx dd     12;8 ---- conditional relative jump if nz,z,nc,c
+  call nn        CD nn nn    24 ---- call to nn, SP=SP-2, (SP)=PC, PC=nn
+  call f,nn      xx nn nn 24;12 ---- conditional call if nz,z,nc,c
+  ret            C9          16 ---- return, PC=(SP), SP=SP+2
+  ret  f         xx        20;8 ---- conditional return if nz,z,nc,c
+  reti           D9          16 ---- return and enable interrupts (IME=1)
+  rst  n         xx          16 ---- call to 00,08,10,18,20,28,30,38
+

+
+
 CPU Comparision with Z80

+Comparision with 8080
+
Basically, the gameboy CPU works more like an older 8080 CPU rather than +like a more powerful Z80 CPU. It is, however, supporting CB-prefixed +instructions. Also, all known gameboy assemblers using the more obvious +Z80-style syntax, rather than the chaotic 8080-style syntax.
+
+Comparision with Z80
+
Any DD-, ED-, and FD-prefixed instructions are missing, that means no +IX-, IY-registers, no block commands, and some other missing commands.
+All exchange instructions have been removed (including total absence of +second register set), 16bit memory accesses are mostly missing, and +16bit arithmetic functions are heavily cut-down.
+The gameboy has no IN/OUT instructions, instead I/O ports are accessed +directly by normal LD instructions, or by special LD (FF00+n) opcodes.
+The sign and parity/overflow flags have been removed.
+The gameboy operates approximately as fast as a 4MHz Z80 (8MHz in CGB +double speed mode), execution time of all instructions has been rounded +up to a multiple of 4 cycles though.
+
+Moved, Removed, and Added Opcodes
+
  Opcode  Z80             GMB
+  ---------------------------------------
+  08      EX   AF,AF      LD   (nn),SP
+  10      DJNZ PC+dd      STOP
+  22      LD   (nn),HL    LDI  (HL),A
+  2A      LD   HL,(nn)    LDI  A,(HL)
+  32      LD   (nn),A     LDD  (HL),A
+  3A      LD   A,(nn)     LDD  A,(HL)
+  D3      OUT  (n),A      -
+  D9      EXX             RETI
+  DB      IN   A,(n)      -
+  DD      <IX>            -
+  E0      RET  PO         LD   (FF00+n),A
+  E2      JP   PO,nn      LD   (FF00+C),A
+  E3      EX   (SP),HL    -
+  E4      CALL P0,nn      -
+  E8      RET  PE         ADD  SP,dd
+  EA      JP   PE,nn      LD   (nn),A
+  EB      EX   DE,HL      -
+  EC      CALL PE,nn      -
+  ED      <pref>          -
+  F0      RET  P          LD   A,(FF00+n)
+  F2      JP   P,nn       LD   A,(FF00+C)
+  F4      CALL P,nn       -
+  F8      RET  M          LD   HL,SP+dd
+  FA      JP   M,nn       LD   A,(nn)
+  FC      CALL M,nn       -
+  FD      <IY>            -
+  CB3X    SLL  r/(HL)     SWAP r/(HL)
+
Note: The unused (-) opcodes will lock-up the gameboy CPU when used.
+
+
+
 The Cartridge Header

+An internal information area is located at 0100-014F in
+each cartridge. It contains the following values:
+
+0100-0103 - Entry Point
+
After displaying the Nintendo Logo, the built-in boot procedure jumps to +this address (100h), which should then jump to the actual main program +in the cartridge. Usually this 4 byte area contains a NOP instruction, +followed by a JP 0150h instruction. But not always.
+
+0104-0133 - Nintendo Logo
+
These bytes define the bitmap of the Nintendo logo that is displayed +when the gameboy gets turned on. The hexdump of this bitmap is:
+
  CE ED 66 66 CC 0D 00 0B 03 73 00 83 00 0C 00 0D
+  00 08 11 1F 88 89 00 0E DC CC 6E E6 DD DD D9 99
+  BB BB 67 63 6E 0E EC CC DD DC 99 9F BB B9 33 3E
+
The gameboys boot procedure verifies the content of this bitmap (after +it has displayed it), and LOCKS ITSELF UP if these bytes are incorrect. +A CGB verifies only the first 18h bytes of the bitmap, but others (for +example a pocket gameboy) verify all 30h bytes.
+
+0134-0143 - Title
+
Title of the game in UPPER CASE ASCII. If it is less than 16 characters +then the remaining bytes are filled with 00's. When inventing the CGB, +Nintendo has reduced the length of this area to 15 characters, and some +months later they had the fantastic idea to reduce it to 11 characters +only. The new meaning of the ex-title bytes is described below.
+
+013F-0142 - Manufacturer Code
+
In older cartridges this area has been part of the Title (see above), in +newer cartridges this area contains an 4 character uppercase +manufacturer code. Purpose and Deeper Meaning unknown.
+
+0143 - CGB Flag
+
In older cartridges this byte has been part of the Title (see above). In +CGB cartridges the upper bit is used to enable CGB functions. This is +required, otherwise the CGB switches itself into Non-CGB-Mode. Typical +values are:
+
  80h - Game supports CGB functions, but works on old gameboys also.
+  C0h - Game works on CGB only (physically the same as 80h).
+
Values with Bit 7 set, and either Bit 2 or 3 set, will switch the +gameboy into a special non-CGB-mode with uninitialized palettes. Purpose +unknown, eventually this has been supposed to be used to colorize +monochrome games that include fixed palette data at a special location +in ROM.
+
+0144-0145 - New Licensee Code
+
Specifies a two character ASCII licensee code, indicating the company or +publisher of the game. These two bytes are used in newer games only +(games that have been released after the SGB has been invented). Older +games are using the header entry at 014B instead.
+
+0146 - SGB Flag
+
Specifies whether the game supports SGB functions, common values are:
+
  00h = No SGB functions (Normal Gameboy or CGB only game)
+  03h = Game supports SGB functions
+
The SGB disables its SGB functions if this byte is set to another value +than 03h.
+
+0147 - Cartridge Type
+
Specifies which Memory Bank Controller (if any) is used in the +cartridge, and if further external hardware exists in the cartridge.
+
  00h  ROM ONLY                 13h  MBC3+RAM+BATTERY
+  01h  MBC1                     15h  MBC4
+  02h  MBC1+RAM                 16h  MBC4+RAM
+  03h  MBC1+RAM+BATTERY         17h  MBC4+RAM+BATTERY
+  05h  MBC2                     19h  MBC5
+  06h  MBC2+BATTERY             1Ah  MBC5+RAM
+  08h  ROM+RAM                  1Bh  MBC5+RAM+BATTERY
+  09h  ROM+RAM+BATTERY          1Ch  MBC5+RUMBLE
+  0Bh  MMM01                    1Dh  MBC5+RUMBLE+RAM
+  0Ch  MMM01+RAM                1Eh  MBC5+RUMBLE+RAM+BATTERY
+  0Dh  MMM01+RAM+BATTERY        FCh  POCKET CAMERA
+  0Fh  MBC3+TIMER+BATTERY       FDh  BANDAI TAMA5
+  10h  MBC3+TIMER+RAM+BATTERY   FEh  HuC3
+  11h  MBC3                     FFh  HuC1+RAM+BATTERY
+  12h  MBC3+RAM
+

+0148 - ROM Size
+
Specifies the ROM Size of the cartridge. Typically calculated as "32KB +shl N".
+
  00h -  32KByte (no ROM banking)
+  01h -  64KByte (4 banks)
+  02h - 128KByte (8 banks)
+  03h - 256KByte (16 banks)
+  04h - 512KByte (32 banks)
+  05h -   1MByte (64 banks)  - only 63 banks used by MBC1
+  06h -   2MByte (128 banks) - only 125 banks used by MBC1
+  07h -   4MByte (256 banks)
+  52h - 1.1MByte (72 banks)
+  53h - 1.2MByte (80 banks)
+  54h - 1.5MByte (96 banks)
+

+0149 - RAM Size
+
Specifies the size of the external RAM in the cartridge (if any).
+
  00h - None
+  01h - 2 KBytes
+  02h - 8 Kbytes
+  03h - 32 KBytes (4 banks of 8KBytes each)
+
When using a MBC2 chip 00h must be specified in this entry, even though +the MBC2 includes a built-in RAM of 512 x 4 bits.
+
+014A - Destination Code
+
Specifies if this version of the game is supposed to be sold in japan, +or anywhere else. Only two values are defined.
+
  00h - Japanese
+  01h - Non-Japanese
+

+014B - Old Licensee Code
+
Specifies the games company/publisher code in range 00-FFh. A value of +33h signalizes that the New License Code in header bytes 0144-0145 is +used instead.
+(Super GameBoy functions won't work if <> $33.)
+
+014C - Mask ROM Version number
+
Specifies the version number of the game. That is usually 00h.
+
+014D - Header Checksum
+
Contains an 8 bit checksum across the cartridge header bytes 0134-014C. +The checksum is calculated as follows:
+
  x=0:FOR i=0134h TO 014Ch:x=x-MEM[i]-1:NEXT
+
The lower 8 bits of the result must be the same than the value in this +entry. The GAME WON'T WORK if this checksum is incorrect.
+
+014E-014F - Global Checksum
+
Contains a 16 bit checksum (upper byte first) across the whole cartridge +ROM. Produced by adding all bytes of the cartridge (except for the two +checksum bytes). The Gameboy doesn't verify this checksum.
+
+
+
 Memory Bank Controllers

+As the gameboys 16 bit address bus offers only limited space for ROM and +RAM addressing, many games are using Memory Bank Controllers (MBCs) to +expand the available address space by bank switching. These MBC chips +are located in the game cartridge (ie. not in the gameboy itself), +several different MBC types are available:
+
+None (32KByte ROM only)
+MBC1 (max 2MByte ROM and/or 32KByte RAM)
+MBC2 (max 256KByte ROM and 512x4 bits RAM)
+MBC3 (max 2MByte ROM and/or 32KByte RAM and Timer)
+HuC1 (MBC with Infrared Controller)
+
+MBC Timing Issues
+
+In each cartridge, the required (or preferred) MBC type should be +specified in byte at 0147h of the ROM. (As described in the chapter +about The Cartridge Header.)
+
+
+
 None (32KByte ROM only)

+Small games of not more than 32KBytes ROM do not require a MBC chip for +ROM banking. The ROM is directly mapped to memory at 0000-7FFFh. +Optionally up to 8KByte of RAM could be connected at A000-BFFF, even +though that could require a tiny MBC-like circuit, but no real MBC chip.
+
+
+
 MBC1 (max 2MByte ROM and/or 32KByte RAM)

+This is the first MBC chip for the gameboy. Any newer MBC chips are +working similiar, so that is relative easy to upgrade a program from one +MBC chip to another - or even to make it compatible to several different +types of MBCs.
+
+Note that the memory in range 0000-7FFF is used for both reading from +ROM, and for writing to the MBCs Control Registers.
+
+0000-3FFF - ROM Bank 00 (Read Only)
+
This area always contains the first 16KBytes of the cartridge ROM.
+
+4000-7FFF - ROM Bank 01-7F (Read Only)
+
This area may contain any of the further 16KByte banks of the ROM, +allowing to address up to 125 ROM Banks (almost 2MByte). As described +below, bank numbers 20h, 40h, and 60h cannot be used, resulting in the +odd amount of 125 banks.
+
+A000-BFFF - RAM Bank 00-03, if any (Read/Write)
+
This area is used to address external RAM in the cartridge (if any). +External RAM is often battery buffered, allowing to store game positions +or high score tables, even if the gameboy is turned off, or if the +cartridge is removed from the gameboy. Available RAM sizes are: 2KByte +(at A000-A7FF), 8KByte (at A000-BFFF), and 32KByte (in form of four 8K +banks at A000-BFFF).
+
+0000-1FFF - RAM Enable (Write Only)
+
Before external RAM can be read or written, it must be enabled by +writing to this address space. It is recommended to disable external RAM +after accessing it, in order to protect its contents from damage during +power down of the gameboy. Usually the following values are used:
+
  00h  Disable RAM (default)
+  0Ah  Enable RAM
+
Practically any value with 0Ah in the lower 4 bits enables RAM, and any +other value disables RAM.
+
+2000-3FFF - ROM Bank Number (Write Only)
+
Writing to this address space selects the lower 5 bits of the ROM Bank +Number (in range 01-1Fh). When 00h is written, the MBC translates that +to bank 01h also. That doesn't harm so far, because ROM Bank 00h can be +always directly accessed by reading from 0000-3FFF.
+But (when using the register below to specify the upper ROM Bank bits), +the same happens for Bank 20h, 40h, and 60h. Any attempt to address +these ROM Banks will select Bank 21h, 41h, and 61h instead.
+
+4000-5FFF - RAM Bank Number - or - Upper Bits of ROM Bank Number (Write Only) +This 2bit register can be used to select a RAM Bank in range from +00-03h, or to specify the upper two bits (Bit 5-6) of the ROM Bank +number, depending on the current ROM/RAM Mode. (See below.)
+
+6000-7FFF - ROM/RAM Mode Select (Write Only)
+
This 1bit Register selects whether the two bits of the above register +should be used as upper two bits of the ROM Bank, or as RAM Bank Number.
+
  00h = ROM Banking Mode (up to 8KByte RAM, 2MByte ROM) (default)
+  01h = RAM Banking Mode (up to 32KByte RAM, 512KByte ROM)
+
The program may freely switch between both modes, the only limitiation +is that only RAM Bank 00h can be used during Mode 0, and only ROM Banks +00-1Fh can be used during Mode 1.
+
+
+
 MBC2 (max 256KByte ROM and 512x4 bits RAM)

+0000-3FFF - ROM Bank 00 (Read Only)
+
Same as for MBC1.
+
+4000-7FFF - ROM Bank 01-0F (Read Only)
+
Same as for MBC1, but only a total of 16 ROM banks is supported.
+
+A000-A1FF - 512x4bits RAM, built-in into the MBC2 chip (Read/Write)
+
The MBC2 doesn't support external RAM, instead it includes 512x4 bits of +built-in RAM (in the MBC2 chip itself). It still requires an external +battery to save data during power-off though.
+As the data consists of 4bit values, only the lower 4 bits of the +"bytes" in this memory area are used.
+
+0000-1FFF - RAM Enable (Write Only)
+
The least significant bit of the upper address byte must be zero to +enable/disable cart RAM. For example the following addresses can be used +to enable/disable cart RAM: 0000-00FF, 0200-02FF, 0400-04FF, ..., +1E00-1EFF.
+The suggested address range to use for MBC2 ram enable/disable is +0000-00FF.
+
+2000-3FFF - ROM Bank Number (Write Only)
+
Writing a value (XXXXBBBB - X = Don't cares, B = bank select bits) into +2000-3FFF area will select an appropriate ROM bank at 4000-7FFF.
+
+The least significant bit of the upper address byte must be one to +select a ROM bank. For example the following addresses can be used to +select a ROM bank: 2100-21FF, 2300-23FF, 2500-25FF, ..., 3F00-3FFF.
+The suggested address range to use for MBC2 rom bank selection is +2100-21FF.
+
+
+
 MBC3 (max 2MByte ROM and/or 32KByte RAM and Timer)

+Beside for the ability to access up to 2MB ROM (128 banks), and 32KB RAM +(4 banks), the MBC3 also includes a built-in Real Time Clock (RTC). The +RTC requires an external 32.768 kHz Quartz Oscillator, and an external +battery (if it should continue to tick when the gameboy is turned off).
+
+0000-3FFF - ROM Bank 00 (Read Only)
+
Same as for MBC1.
+
+4000-7FFF - ROM Bank 01-7F (Read Only)
+
Same as for MBC1, except that accessing banks 20h, 40h, and 60h is +supported now.
+
+A000-BFFF - RAM Bank 00-03, if any (Read/Write)
+A000-BFFF - RTC Register 08-0C (Read/Write)
+
Depending on the current Bank Number/RTC Register selection (see below), +this memory space is used to access an 8KByte external RAM Bank, or a +single RTC Register.
+
+0000-1FFF - RAM and Timer Enable (Write Only)
+
Mostly the same as for MBC1, a value of 0Ah will enable reading and +writing to external RAM - and to the RTC Registers! A value of 00h will +disable either.
+
+2000-3FFF - ROM Bank Number (Write Only)
+
Same as for MBC1, except that the whole 7 bits of the RAM Bank Number +are written directly to this address. As for the MBC1, writing a value +of 00h, will select Bank 01h instead. All other values 01-7Fh select the +corresponding ROM Banks.
+
+4000-5FFF - RAM Bank Number - or - RTC Register Select (Write Only)
+
As for the MBC1s RAM Banking Mode, writing a value in range for 00h-03h +maps the corresponding external RAM Bank (if any) into memory at +A000-BFFF.
+When writing a value of 08h-0Ch, this will map the corresponding RTC +register into memory at A000-BFFF. That register could then be +read/written by accessing any address in that area, typically that is +done by using address A000.
+
+6000-7FFF - Latch Clock Data (Write Only)
+
When writing 00h, and then 01h to this register, the current time +becomes latched into the RTC registers. The latched data will not change +until it becomes latched again, by repeating the write 00h->01h +procedure.
+This is supposed for <reading> from the RTC registers. It is proof to +read the latched (frozen) time from the RTC registers, while the clock +itself continues to tick in background.
+
+The Clock Counter Registers
+
  08h  RTC S   Seconds   0-59 (0-3Bh)
+  09h  RTC M   Minutes   0-59 (0-3Bh)
+  0Ah  RTC H   Hours     0-23 (0-17h)
+  0Bh  RTC DL  Lower 8 bits of Day Counter (0-FFh)
+  0Ch  RTC DH  Upper 1 bit of Day Counter, Carry Bit, Halt Flag
+        Bit 0  Most significant bit of Day Counter (Bit 8)
+        Bit 6  Halt (0=Active, 1=Stop Timer)
+        Bit 7  Day Counter Carry Bit (1=Counter Overflow)
+
The Halt Flag is supposed to be set before <writing> to the RTC +Registers.
+
+The Day Counter
+
The total 9 bits of the Day Counter allow to count days in range from +0-511 (0-1FFh). The Day Counter Carry Bit becomes set when this value +overflows. In that case the Carry Bit remains set until the program does +reset it.
+Note that you can store an offset to the Day Counter in battery RAM. For +example, every time you read a non-zero Day Counter, add this Counter to +the offset in RAM, and reset the Counter to zero. This method allows to +count any number of days, making your program Year-10000-Proof, provided +that the cartridge gets used at least every 511 days.
+
+Delays
+
When accessing the RTC Registers it is recommended to execute a 4ms +delay (4 Cycles in Normal Speed Mode) between the separate accesses.
+
+
+
 HuC1 (MBC with Infrared Controller)

+This controller (made by Hudson Soft) appears to be very similar to an +MBC1 with the main difference being that it supports infrared LED input +/ output. (Similiar to the infrared port that has been later invented in +CGBs.)
+
+The Japanese cart "Fighting Phoenix" (internal cart name: SUPER B DAMAN) +is known to contain this chip.
+
+
+
 MBC Timing Issues

+Using MBCs with CGB Double Speed Mode
+
The MBC5 has been designed to support CGB Double Speed Mode.
+There have been rumours that older MBCs (like MBC1-3) wouldn't be fast +enough in that mode. If so, it might be nethertheless possible to use +Double Speed during periods which use only code and data which is +located in internal RAM.
+However, despite of the above, my own good old selfmade MBC1-EPROM card +appears to work stable and fine even in Double Speed Mode though.
+
+
+
 Gamegenie/Shark Cheats

+Game Shark and Gamegenie are external cartridge adapters that can be +plugged between the gameboy and the actual game cartridge. Hexadecimal +codes can be then entered for specific games, typically providing things +like Infinite Sex, 255 Cigarettes, or Starting directly in Wonderland +Level PRO, etc.
+
+Gamegenie (ROM patches)
+
Gamegenie codes consist of nine-digit hex numbers, formatted as +ABC-DEF-GHI, the meaning of the separate digits is:
+
  AB    New data
+  FCDE  Memory address, XORed by 0F000h
+  GI    Old data, XORed by 0BAh and rotated left by two
+  H     Don't know, maybe checksum and/or else
+
The address should be located in ROM area 0000h-7FFFh, the adapter +permanently compares address/old data with address/data being read by +the game, and replaces that data by new data if necessary. That method +(more or less) prohibits unwanted patching of wrong memory banks. +Eventually it is also possible to patch external RAM ?
+Newer devices reportedly allow to specify only the first six digits +(optionally). As far as I rememeber, around three or four codes can be +used simultaneously.
+
+Game Shark (RAM patches)
+
Game Shark codes consist of eight-digit hex numbers, formatted as +ABCDEFGH, the meaning of the separate digits is:
+
  AB    External RAM bank number
+  CD    New Data
+  GHEF  Memory Address (internal or external RAM, A000-DFFF)
+
As far as I understand, patching is implement by hooking the original +VBlank interrupt handler, and re-writing RAM values each frame. The +downside is that this method steals some CPU time, also, it cannot be +used to patch program code in ROM.
+As far as I rememeber, somewhat 10-25 codes can be used simultaneously.
+
+
+
 Power Up Sequence

+When the GameBoy is powered up, a 256 byte program starting at memory +location 0 is executed. This program is located in a ROM inside the +GameBoy. The first thing the program does is read the cartridge +locations from $104 to $133 and place this graphic of a Nintendo logo on +the screen at the top. This image is then scrolled until it is in the +middle of the screen. Two musical notes are then played on the internal +speaker. Again, the cartridge locations $104 to $133 are read but this +time they are compared with a table in the internal rom. If any byte +fails to compare, then the GameBoy stops comparing bytes and simply +halts all operations. If all locations compare the same, then the +GameBoy starts adding all of the bytes in the cartridge from $134 to +$14d. A value of 25 decimal is added to this total. If the least +significant byte of the result is a not a zero, then the GameBoy will +stop doing anything. If it is a zero, then the internal ROM is disabled +and cartridge program execution begins at location $100 with the +following register values:
+
+
   AF=$01B0
+   BC=$0013
+   DE=$00D8
+   HL=$014D
+   Stack Pointer=$FFFE
+   [$FF05] = $00   ; TIMA
+   [$FF06] = $00   ; TMA
+   [$FF07] = $00   ; TAC
+   [$FF10] = $80   ; NR10
+   [$FF11] = $BF   ; NR11
+   [$FF12] = $F3   ; NR12
+   [$FF14] = $BF   ; NR14
+   [$FF16] = $3F   ; NR21
+   [$FF17] = $00   ; NR22
+   [$FF19] = $BF   ; NR24
+   [$FF1A] = $7F   ; NR30
+   [$FF1B] = $FF   ; NR31
+   [$FF1C] = $9F   ; NR32
+   [$FF1E] = $BF   ; NR33
+   [$FF20] = $FF   ; NR41
+   [$FF21] = $00   ; NR42
+   [$FF22] = $00   ; NR43
+   [$FF23] = $BF   ; NR30
+   [$FF24] = $77   ; NR50
+   [$FF25] = $F3   ; NR51
+   [$FF26] = $F1-GB, $F0-SGB ; NR52
+   [$FF40] = $91   ; LCDC
+   [$FF42] = $00   ; SCY
+   [$FF43] = $00   ; SCX
+   [$FF45] = $00   ; LYC
+   [$FF47] = $FC   ; BGP
+   [$FF48] = $FF   ; OBP0
+   [$FF49] = $FF   ; OBP1
+   [$FF4A] = $00   ; WY
+   [$FF4B] = $00   ; WX
+   [$FFFF] = $00   ; IE
+

+It is not a good idea to assume the above values will always exist. A +later version GameBoy could contain different values than these at +reset. Always set these registers on reset rather than assume they are +as above.
+
+Please note that GameBoy internal RAM on power up contains random data. +All of the GameBoy emulators tend to set all RAM to value $00 on entry.
+
+Cart RAM the first time it is accessed on a real GameBoy contains random +data. It will only contain known data if the GameBoy code initializes it +to some value.
+
+
+
 Reducing Power Consumption

+The following can be used to recude the power consumption of the +gameboy, and to extend the life of the batteries.
+
+PWR Using the HALT Instruction
+PWR Using the STOP Instruction
+PWR Disabeling the Sound Controller
+PWR Not using CGB Double Speed Mode
+PWR Using the Skills
+
+
+
 PWR Using the HALT Instruction

+It is recommended that the HALT instruction be used whenever possible to +reduce power consumption & extend the life of the batteries. This +command stops the system clock reducing the power consumption of both +the CPU and ROM.
+
+The CPU will remain suspended until an interrupt occurs at which point +the interrupt is serviced and then the instruction immediately following +the HALT is executed.
+
+Depending on how much CPU time is required by a game, the HALT +instruction can extend battery life anywhere from 5 to 50% or possibly +more.
+
+When waiting for a vblank event, this would be a BAD example:
+
  @@wait:
+   ld   a,(0FF44h)      ;LY
+   cp   a,144
+   jr   nz,@@wait
+

+A better example would be a procedure as shown below. In this case the +vblank interrupt must be enabled, and your vblank interrupt procedure +must set vblank_flag to a non-zero value.
+
   ld   hl,vblank_flag  ;hl=pointer to vblank_flag
+   xor  a               ;a=0
+  @@wait:               ;wait...
+   halt                 ;suspend CPU - wait for ANY interrupt
+   cp   a,(hl)          ;vblank flag still zero?
+   jr   z,@@wait        ;wait more if zero
+   ld   (hl),a          ;set vblank_flag back to zero
+
The vblank_flag is used to determine whether the HALT period has been +terminated by a vblank interrupt, or by another interrupt. In case that +your program has all other interrupts disabled, then it would be proof +to replace the above procedure by a single HALT instruction.
+
+
+
 PWR Using the STOP Instruction

+The STOP instruction is intended to switch the gameboy into VERY low +power standby mode. For example, a program may use this feature when it +hasn't sensed keyboard input for a longer period (assuming that somebody +forgot to turn off the gameboy).
+
+Before invoking STOP, it might be required to disable Sound and Video +manually (as well as IR-link port in CGB). Much like HALT, the STOP +state is terminated by interrupt events - in this case this would be +commonly a joypad interrupt. The joypad register might be required to be +prepared for STOP either.
+
+
+
 PWR Disabeling the Sound Controller

+If your programs doesn't use sound at all (or during some periods) then +write 00h to register FF26 to save 16% or more on GB power consumption.
+Sound can be turned back on by writing 80h to the same register, all +sound registers must be then re-initialized.
+When the gameboy becomes turned on, sound is enabled by default, and +must be turned off manually when not used.
+
+
+
 PWR Not using CGB Double Speed Mode

+Because CGB Double Speed mode consumes more power, it'd be recommended +to use normal speed when possible.
+There's limited ability to switch between both speeds, for example, a +game might use normal speed in the title screen, and double speed in the +game, or vice versa.
+However, during speed switch the display collapses for a short moment, +so that it'd be no good idea to alter speeds within active game or title +screen periods.
+
+
+
 PWR Using the Skills

+Most of the above power saving methods will produce best results when +using efficient and tight assembler code which requires as less CPU +power as possible. Thus, experienced old-school programmers will +(hopefully) produce lower power consumption, as than HLL-programming +teenagers, for example.
+
+
+
 Sprite RAM Bug

+There is a flaw in the GameBoy hardware that causes trash to be written +to OAM RAM if the following commands are used while their 16-bit content +is in the range of $FE00 to $FEFF:
+
  inc rr        dec rr          ;rr = bc,de, or hl
+  ldi a,(hl)    ldd a,(hl)
+  ldi (hl),a    ldd (hl),a
+
Only sprites 1 & 2 ($FE00 & $FE04) are not affected by these +instructions.
+
+
+
 External Connectors

+Cartridge Slot
+
  Pin   Name    Expl.
+  1     VDD     Power Supply +5V DC
+  2     PHI     System Clock
+  3     /WR     Write
+  4     /RD     Read
+  5     /CS     Chip Select
+  6-21  A0-A15  Address Lines
+  22-29 D0-D7   Data Lines
+  30    /RES    Reset signal
+  31    VIN     External Sound Input
+  32    GND     Ground
+

+Link Port
+
Pin numbers are arranged as 2,4,6 in upper row, 1,3,5 un lower row; +outside view of gameboy socket; flat side of socket upside.
+Colors as used in most or all standard link cables, because SIN and SOUT +are crossed, colors Red and Orange are exchanged at one cable end.
+
  Pin Name Color  Expl.
+  1   VCC  -      +5V DC
+  2   SOUT red    Data Out
+  3   SIN  orange Data In
+  4   P14  -      Not used
+  5   SCK  green  Shift Clock
+  6   GND  blue   Ground
+
Note: The original gameboy used larger plugs (unlike pocket gameboys and +newer), linking between older/newer gameboys is possible by using cables +with one large and one small plug though.
+
+Stereo Sound Connector (3.5mm, female)
+
  Pin     Expl.
+  Tip     Sound Left
+  Middle  Sound Right
+  Base    Ground
+

+External Power Supply
+
...
+
+
+
+
 END
+ \ No newline at end of file diff --git a/docs/pandocs.txt b/docs/pandocs.txt new file mode 100644 index 0000000..b983910 --- /dev/null +++ b/docs/pandocs.txt @@ -0,0 +1,2885 @@ +Pan Docs +-------- + +Overview +--> About the Pan Docs +--> Game Boy Technical Data +--> Memory Map + +I/O Ports +--> Video Display +--> Sound Controller +--> Joypad Input +--> Serial Data Transfer (Link Cable) +--> Timer and Divider Registers +--> Interrupts +--> CGB Registers +--> SGB Functions + +CPU Specifications +--> CPU Registers and Flags +--> CPU Instruction Set +--> CPU Comparision with Z80 + +Cartridges +--> The Cartridge Header +--> Memory Bank Controllers +--> Gamegenie/Shark Cheats + +Other +--> Power Up Sequence +--> Reducing Power Consumption +--> Sprite RAM Bug +--> External Connectors + +About the Pan Docs +------------------ + + ================================================================= + Everything You Always Wanted To Know About GAMEBOY * + ================================================================= + + * but were afraid to ask + + Pan of -ATX- Document Updated by contributions from: + Marat Fayzullin, Pascal Felber, Paul Robson, Martin Korth + CPU, SGB, CGB, AUX specs by Martin Korth + + Last updated 10/2001 by nocash + Previously updated 4-Mar-98 by kOOPa + +Forward +The following was typed up for informational purposes regarding the inner +workings on the hand-held game machine known as GameBoy, manufactured and +designed by Nintendo Co., LTD. This info is presented to inform a user on how +their Game Boy works and what makes it "tick". GameBoy is copyrighted by +Nintendo Co., LTD. Any reference to copyrighted material is not presented for +monetary gain, but for educational purposes and higher learning. + +Available Document Formats +The present version of this document is available in Text and Html format: + http://www.work.de/nocash/pandocs.txt + http://www.work.de/nocash/pandocs.htm +Also, a copy of this document is included in the manual of newer versions of +the no$gmb debugger, because of recent piracy attacks (many thanks and best +wishes go to hell) I have currently no intention to publish any such or +further no$gmb updates though. + +Game Boy Technical Data +----------------------- + + CPU - 8-bit (Similar to the Z80 processor) + Clock Speed - 4.194304MHz (4.295454MHz for SGB, max. 8.4MHz for CGB) + Work RAM - 8K Byte (32K Byte for CGB) + Video RAM - 8K Byte (16K Byte for CGB) + Screen Size - 2.6" + Resolution - 160x144 (20x18 tiles) + Max sprites - Max 40 per screen, 10 per line + Sprite sizes - 8x8 or 8x16 + Palettes - 1x4 BG, 2x3 OBJ (for CGB: 8x4 BG, 8x3 OBJ) + Colors - 4 grayshades (32768 colors for CGB) + Horiz Sync - 9198 KHz (9420 KHz for SGB) + Vert Sync - 59.73 Hz (61.17 Hz for SGB) + Sound - 4 channels with stereo sound + Power - DC6V 0.7W (DC3V 0.7W for GB Pocket, DC3V 0.6W for CGB) + +Memory Map +---------- + +The gameboy is having a 16bit address bus, that is used to address ROM, RAM, +and I/O registers. + +General Memory Map + 0000-3FFF 16KB ROM Bank 00 (in cartridge, fixed at bank 00) + 4000-7FFF 16KB ROM Bank 01..NN (in cartridge, switchable bank number) + 8000-9FFF 8KB Video RAM (VRAM) (switchable bank 0-1 in CGB Mode) + A000-BFFF 8KB External RAM (in cartridge, switchable bank, if any) + C000-CFFF 4KB Work RAM Bank 0 (WRAM) + D000-DFFF 4KB Work RAM Bank 1 (WRAM) (switchable bank 1-7 in CGB Mode) + E000-FDFF Same as C000-DDFF (ECHO) (typically not used) + FE00-FE9F Sprite Attribute Table (OAM) + FEA0-FEFF Not Usable + FF00-FF7F I/O Ports + FF80-FFFE High RAM (HRAM) + FFFF Interrupt Enable Register + +Jump Vectors in First ROM Bank +The following addresses are supposed to be used as jump vectors: + 0000,0008,0010,0018,0020,0028,0030,0038 for RST commands + 0040,0048,0050,0058,0060 for Interrupts +However, the memory may be used for any other purpose in case that your +program doesn't use any (or only some) RST commands or Interrupts. RST +commands are 1-byte opcodes that work similiar to CALL opcodes, except that +the destination address is fixed. + +Cartridge Header in First ROM Bank +The memory at 0100-014F contains the cartridge header. This area contains +information about the program, its entry point, checksums, information about +the used MBC chip, the ROM and RAM sizes, etc. Most of the bytes in this area +are required to be specified correctly. For more information read the chapter +about The Cartridge Header. + +External Memory and Hardware +The areas from 0000-7FFF and A000-BFFF may be used to connect external +hardware. The first area is typically used to address ROM (read only, of +course), cartridges with Memory Bank Controllers (MBCs) are additionally using +this area to output data (write only) to the MBC chip. The second area is +often used to address external RAM, or to address other external hardware +(Real Time Clock, etc). External memory is often battery buffered, and may +hold saved game positions and high scrore tables (etc.) even when the gameboy +is turned of, or when the cartridge is removed. For specific information read +the chapter about Memory Bank Controllers. + +Video Display +------------- + +Video I/O Registers +--> LCD Control Register +--> LCD Status Register +--> LCD Interrupts +--> LCD Position and Scrolling +--> LCD Monochrome Palettes +--> LCD Color Palettes (CGB only) +--> LCD VRAM Bank (CGB only) +--> LCD OAM DMA Transfers +--> LCD VRAM DMA Transfers (CGB only) + +Video Memory +--> VRAM Tile Data +--> VRAM Background Maps +--> VRAM Sprite Attribute Table (OAM) +--> Accessing VRAM and OAM + +LCD Control Register +-------------------- + +FF40 - LCDC - LCD Control (R/W) + Bit 7 - LCD Display Enable (0=Off, 1=On) + Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) + Bit 5 - Window Display Enable (0=Off, 1=On) + Bit 4 - BG & Window Tile Data Select (0=8800-97FF, 1=8000-8FFF) + Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) + Bit 2 - OBJ (Sprite) Size (0=8x8, 1=8x16) + Bit 1 - OBJ (Sprite) Display Enable (0=Off, 1=On) + Bit 0 - BG Display (for CGB see below) (0=Off, 1=On) + +LCDC.7 - LCD Display Enable +CAUTION: Stopping LCD operation (Bit 7 from 1 to 0) may be performed during +V-Blank ONLY, disabeling the display outside of the V-Blank period may damage +the hardware. This appears to be a serious issue, Nintendo is reported to +reject any games that do not follow this rule. +V-blank can be confirmed when the value of LY is greater than or equal to 144. +When the display is disabled the screen is blank (white), and VRAM and OAM can +be accessed freely. + +--- LCDC.0 has different Meanings depending on Gameboy Type --- + +LCDC.0 - 1) Monochrome Gameboy and SGB: BG Display +When Bit 0 is cleared, the background becomes blank (white). Window and +Sprites may still be displayed (if enabled in Bit 1 and/or Bit 5). + +LCDC.0 - 2) CGB in CGB Mode: BG and Window Master Priority +When Bit 0 is cleared, the background and window lose their priority - the +sprites will be always displayed on top of background and window, +independently of the priority flags in OAM and BG Map attributes. + +LCDC.0 - 3) CGB in Non CGB Mode: BG and Window Display +When Bit 0 is cleared, both background and window become blank (white), ie. +the Window Display Bit (Bit 5) is ignored in that case. Only Sprites may still +be displayed (if enabled in Bit 1). +This is a possible compatibility problem - any monochrome games (if any) that +disable the background, but still want to display the window wouldn't work +properly on CGBs. + +LCD Status Register +------------------- + +FF41 - STAT - LCDC Status (R/W) + Bit 6 - LYC=LY Coincidence Interrupt (1=Enable) (Read/Write) + Bit 5 - Mode 2 OAM Interrupt (1=Enable) (Read/Write) + Bit 4 - Mode 1 V-Blank Interrupt (1=Enable) (Read/Write) + Bit 3 - Mode 0 H-Blank Interrupt (1=Enable) (Read/Write) + Bit 2 - Coincidence Flag (0:LYC<>LY, 1:LYC=LY) (Read Only) + Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only) + 0: During H-Blank + 1: During V-Blank + 2: During Searching OAM-RAM + 3: During Transfering Data to LCD Driver + +The two lower STAT bits show the current status of the LCD controller. + Mode 0: The LCD controller is in the H-Blank period and + the CPU can access both the display RAM (8000h-9FFFh) + and OAM (FE00h-FE9Fh) + + Mode 1: The LCD contoller is in the V-Blank period (or the + display is disabled) and the CPU can access both the + display RAM (8000h-9FFFh) and OAM (FE00h-FE9Fh) + + Mode 2: The LCD controller is reading from OAM memory. + The CPU access OAM memory (FE00h-FE9Fh) + during this period. + + Mode 3: The LCD controller is reading from both OAM and VRAM, + The CPU access OAM and VRAM during this period. + CGB Mode: Cannot access Palette Data (FF69,FF6B) either. + +The following are typical when the display is enabled: + Mode 2 2_____2_____2_____2_____2_____2___________________2____ + Mode 3 _33____33____33____33____33____33__________________3___ + Mode 0 ___000___000___000___000___000___000________________000 + Mode 1 ____________________________________11111111111111_____ + +The Mode Flag goes through the values 0, 2, and 3 at a cycle of about 109uS. 0 +is present about 48.6uS, 2 about 19uS, and 3 about 41uS. This is interrupted +every 16.6ms by the VBlank (1). The mode flag stays set at 1 for about 1.08 +ms. + +Mode 0 is present between 201-207 clks, 2 about 77-83 clks, and 3 about +169-175 clks. A complete cycle through these states takes 456 clks. VBlank +lasts 4560 clks. A complete screen refresh occurs every 70224 clks.) + +LCD Interrupts +-------------- + +INT 40 - V-Blank Interrupt +The V-Blank interrupt occurs ca. 59.7 times a second on a regular GB and ca. +61.1 times a second on a Super GB (SGB). This interrupt occurs at the +beginning of the V-Blank period (LY=144). +During this period video hardware is not using video ram so it may be freely +accessed. This period lasts approximately 1.1 milliseconds. + +INT 48 - LCDC Status Interrupt +There are various reasons for this interrupt to occur as described by the STAT +register ($FF40). One very popular reason is to indicate to the user when the +video hardware is about to redraw a given LCD line. This can be useful for +dynamically controlling the SCX/SCY registers ($FF43/$FF42) to perform special +video effects. + +LCD Position and Scrolling +-------------------------- + +FF42 - SCY - Scroll Y (R/W) +FF43 - SCX - Scroll X (R/W) +Specifies the position in the 256x256 pixels BG map (32x32 tiles) which is to +be displayed at the upper/left LCD display position. +Values in range from 0-255 may be used for X/Y each, the video controller +automatically wraps back to the upper (left) position in BG map when drawing +exceeds the lower (right) border of the BG map area. + +FF44 - LY - LCDC Y-Coordinate (R) +The LY indicates the vertical line to which the present data is transferred to +the LCD Driver. The LY can take on any value between 0 through 153. The values +between 144 and 153 indicate the V-Blank period. Writing will reset the +counter. + +FF45 - LYC - LY Compare (R/W) +The gameboy permanently compares the value of the LYC and LY registers. When +both values are identical, the coincident bit in the STAT register becomes +set, and (if enabled) a STAT interrupt is requested. + +FF4A - WY - Window Y Position (R/W) +FF4B - WX - Window X Position minus 7 (R/W) +Specifies the upper/left positions of the Window area. (The window is an +alternate background area which can be displayed above of the normal +background. OBJs (sprites) may be still displayed above or behinf the window, +just as for normal BG.) +The window becomes visible (if enabled) when positions are set in range +WX=0..166, WY=0..143. A postion of WX=7, WY=0 locates the window at upper +left, it is then completly covering normal background. + +LCD Monochrome Palettes +----------------------- + +FF47 - BGP - BG Palette Data (R/W) - Non CGB Mode Only +This register assigns gray shades to the color numbers of the BG and Window +tiles. + Bit 7-6 - Shade for Color Number 3 + Bit 5-4 - Shade for Color Number 2 + Bit 3-2 - Shade for Color Number 1 + Bit 1-0 - Shade for Color Number 0 +The four possible gray shades are: + 0 White + 1 Light gray + 2 Dark gray + 3 Black +In CGB Mode the Color Palettes are taken from CGB Palette Memory instead. + +FF48 - OBP0 - Object Palette 0 Data (R/W) - Non CGB Mode Only +This register assigns gray shades for sprite palette 0. It works exactly as +BGP (FF47), except that the lower two bits aren't used because sprite data 00 +is transparent. + +FF49 - OBP1 - Object Palette 1 Data (R/W) - Non CGB Mode Only +This register assigns gray shades for sprite palette 1. It works exactly as +BGP (FF47), except that the lower two bits aren't used because sprite data 00 +is transparent. + +LCD Color Palettes (CGB only) +----------------------------- + +FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index +This register is used to address a byte in the CGBs Background Palette Memory. +Each two byte in that memory define a color value. The first 8 bytes define +Color 0-3 of Palette 0 (BGP0), and so on for BGP1-7. + Bit 0-5 Index (00-3F) + Bit 7 Auto Increment (0=Disabled, 1=Increment after Writing) +Data can be read/written to/from the specified index address through Register +FF69. When the Auto Increment Bit is set then the index is automatically +incremented after each to FF69. Auto Increment has no effect when + from FF69, so the index must be manually incremented in that case. + +FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data +This register allows to read/write data to the CGBs Background Palette Memory, +addressed through Register FF68. +Each color is defined by two bytes (Bit 0-7 in first byte). + Bit 0-4 Red Intensity (00-1F) + Bit 5-9 Green Intensity (00-1F) + Bit 10-14 Blue Intensity (00-1F) +Much like VRAM, Data in Palette Memory cannot be read/written during the time +when the LCD Controller is reading from it. (That is when the STAT register +indicates Mode 3). +Note: Initially all background colors are initialized as white. + +FF6A - OCPS/OBPI - CGB Mode Only - Sprite Palette Index +FF6B - OCPD/OBPD - CGB Mode Only - Sprite Palette Data +These registers are used to initialize the Sprite Palettes OBP0-7, identically +as described above for Background Palettes. Note that four colors may be +defined for each OBP Palettes - but only Color 1-3 of each Sprite Palette can +be displayed, Color 0 is always transparent, and can be initialized to a don't +care value. +Note: Initially all sprite colors are uninitialized. + +RGB Translation by CGBs +When developing graphics on PCs, note that the RGB values will have different +appearance on CGB displays as on VGA monitors: +The highest intensity will produce Light Gray color rather than White. The +intensities are not linear; the values 10h-1Fh will all appear very bright, +while medium and darker colors are ranged at 00h-0Fh. +The CGB display will mix colors quite oddly, increasing intensity of only one +R,G,B color will also influence the other two R,G,B colors. +For example, a color setting of 03EFh (Blue=0, Green=1Fh, Red=0Fh) will appear +as Neon Green on VGA displays, but on the CGB it'll produce a decently washed +out Yellow. + +RGB Translation by GBAs +Even though GBA is described to be compatible to CGB games, most CGB games are +completely unplayable on GBAs because most colors are invisible (black). Of +course, colors such like Black and White will appear the same on both CGB and +GBA, but medium intensities are arranged completely different. +Intensities in range 00h..0Fh are invisible/black (unless eventually under +best sunlight circumstances, and when gazing at the screen under obscure +viewing angles), unfortunately, these intensities are regulary used by most +existing CGB games for medium and darker colors. +Newer CGB games may avoid this effect by changing palette data when detecting +GBA hardware. A relative simple method would be using the formula +GBA=CGB/2+10h for each R,G,B intensity, probably the result won't be perfect, +and (once colors became visible) it may turn out that the color mixing is +different also, anyways, it'd be still ways better than no conversion. +Asides, this translation method should have been VERY easy to implement in GBA +hardware directly, even though Nintendo obviously failed to do so. How did +they say, This seal is your assurance for excellence in workmanship and so on? + +LCD VRAM Bank (CGB only) +------------------------ + +FF4F - VBK - CGB Mode Only - VRAM Bank +This 1bit register selects the current Video Memory (VRAM) Bank. + Bit 0 - VRAM Bank (0-1) +Bank 0 contains 192 Tiles, and two background maps, just as for monochrome +games. Bank 1 contains another 192 Tiles, and color attribute maps for the +background maps in bank 0. + +LCD OAM DMA Transfers +--------------------- + +FF46 - DMA - DMA Transfer and Start Address (W) +Writing to this register launches a DMA transfer from ROM or RAM to OAM memory +(sprite attribute table). The written value specifies the transfer source +address divided by 100h, ie. source & destination are: + Source: XX00-XX9F ;XX in range from 00-F1h + Destination: FE00-FE9F +It takes 160 microseconds until the transfer has completed (80 microseconds in +CGB Double Speed Mode), during this time the CPU can access only HRAM (memory +at FF80-FFFE). For this reason, the programmer must copy a short procedure +into HRAM, and use this procedure to start the transfer from inside HRAM, and +wait until the transfer has finished: + ld (0FF46h),a ;start DMA transfer, a=start address/100h + ld a,28h ;delay... + wait: ;total 5x40 cycles, approx 200ms + dec a ;1 cycle + jr nz,wait ;4 cycles +Most programs are executing this procedure from inside of their VBlank +procedure, but it is possible to execute it during display redraw also, +allowing to display more than 40 sprites on the screen (ie. for example 40 +sprites in upper half, and other 40 sprites in lower half of the screen). + +LCD VRAM DMA Transfers (CGB only) +--------------------------------- + +FF51 - HDMA1 - CGB Mode Only - New DMA Source, High +FF52 - HDMA2 - CGB Mode Only - New DMA Source, Low +FF53 - HDMA3 - CGB Mode Only - New DMA Destination, High +FF54 - HDMA4 - CGB Mode Only - New DMA Destination, Low +FF55 - HDMA5 - CGB Mode Only - New DMA Length/Mode/Start +These registers are used to initiate a DMA transfer from ROM or RAM to VRAM. +The Source Start Address may be located at 0000-7FF0 or A000-DFF0, the lower +four bits of the address are ignored (treated as zero). The Destination Start +Address may be located at 8000-9FF0, the lower four bits of the address are +ignored (treated as zero), the upper 3 bits are ignored either (destination is +always in VRAM). + +Writing to FF55 starts the transfer, the lower 7 bits of FF55 specify the +Transfer Length (divided by 10h, minus 1). Ie. lengths of 10h-800h bytes can +be defined by the values 00h-7Fh. And the upper bit of FF55 indicates the +Transfer Mode: + +Bit7=0 - General Purpose DMA +When using this transfer method, all data is transferred at once. The +execution of the program is halted until the transfer has completed. Note that +the General Purpose DMA blindly attempts to copy the data, even if the LCD +controller is currently accessing VRAM. So General Purpose DMA should be used +only if the Display is disabled, or during V-Blank, or (for rather short +blocks) during H-Blank. +The execution of the program continues when the transfer has been completed, +and FF55 then contains a value if FFh. + +Bit7=1 - H-Blank DMA +The H-Blank DMA transfers 10h bytes of data during each H-Blank, ie. at +LY=0-143, no data is transferred during V-Blank (LY=144-153), but the transfer +will then continue at LY=00. The execution of the program is halted during the +separate transfers, but the program execution continues during the 'spaces' +between each data block. +Note that the program may not change the Destination VRAM bank (FF4F), or the +Source ROM/RAM bank (in case data is transferred from bankable memory) until +the transfer has completed! +Reading from Register FF55 returns the remaining length (divided by 10h, minus +1), a value of 0FFh indicates that the transfer has completed. It is also +possible to terminate an active H-Blank transfer by writing zero to Bit 7 of +FF55. In that case reading from FF55 may return any value for the lower 7 +bits, but Bit 7 will be read as "1". + +Confirming if the DMA Transfer is Active +Reading Bit 7 of FF55 can be used to confirm if the DMA transfer is active +(1=Not Active, 0=Active). This works under any circumstances - after +completion of General Purpose, or H-Blank Transfer, and after manually +terminating a H-Blank Transfer. + +Transfer Timings +In both Normal Speed and Double Speed Mode it takes about 8us to transfer a +block of 10h bytes. That are 8 cycles in Normal Speed Mode, and 16 'fast' +cycles in Double Speed Mode. +Older MBC controllers (like MBC1-4) and slower ROMs are not guaranteed to +support General Purpose or H-Blank DMA, that's because there are always 2 +bytes transferred per microsecond (even if the itself program runs it Normal +Speed Mode). + +VRAM Tile Data +-------------- + +Tile Data is stored in VRAM at addresses 8000h-97FFh, this area defines the +Bitmaps for 192 Tiles. In CGB Mode 384 Tiles can be defined, because memory at +0:8000h-97FFh and at 1:8000h-97FFh is used. + +Each tile is sized 8x8 pixels and has a color depth of 4 colors/gray shades. +Tiles can be displayed as part of the Background/Window map, and/or as OAM +tiles (foreground sprites). Note that foreground sprites may have only 3 +colors, because color 0 is transparent. + +As it was said before, there are two Tile Pattern Tables at $8000-8FFF and at +$8800-97FF. The first one can be used for sprites and the background. Its +tiles are numbered from 0 to 255. The second table can be used for the +background and the window display and its tiles are numbered from -128 to 127. + +Each Tile occupies 16 bytes, where each 2 bytes represent a line: + Byte 0-1 First Line (Upper 8 pixels) + Byte 2-3 Next Line + etc. +For each line, the first byte defines the least significant bits of the color +numbers for each pixel, and the second byte defines the upper bits of the +color numbers. In either case, Bit 7 is the leftmost pixel, and Bit 0 the +rightmost. + +So, each pixel is having a color number in range from 0-3. The color numbers +are translated into real colors (or gray shades) depending on the current +palettes. The palettes are defined through registers FF47-FF49 (Non CGB Mode), +and FF68-FF6B (CGB Mode). + +VRAM Background Maps +-------------------- + +The gameboy contains two 32x32 tile background maps in VRAM at addresses +9800h-9BFFh and 9C00h-9FFFh. Each can be used either to display "normal" +background, or "window" background. + +BG Map Tile Numbers +An area of VRAM known as Background Tile Map contains the numbers of tiles to +be displayed. It is organized as 32 rows of 32 bytes each. Each byte contains +a number of a tile to be displayed. Tile patterns are taken from the Tile Data +Table located either at $8000-8FFF or $8800-97FF. In the first case, patterns +are numbered with unsigned numbers from 0 to 255 (i.e. pattern #0 lies at +address $8000). In the second case, patterns have signed numbers from -128 to +127 (i.e. pattern #0 lies at address $9000). The Tile Data Table address for +the background can be selected via LCDC register. + +BG Map Attributes (CGB Mode only) +In CGB Mode, an additional map of 32x32 bytes is stored in VRAM Bank 1 (each +byte defines attributes for the corresponding tile-number map entry in VRAM +Bank 0): + Bit 0-2 Background Palette number (BGP0-7) + Bit 3 Tile VRAM Bank number (0=Bank 0, 1=Bank 1) + Bit 4 Not used + Bit 5 Horizontal Flip (0=Normal, 1=Mirror horizontally) + Bit 6 Vertical Flip (0=Normal, 1=Mirror vertically) + Bit 7 BG-to-OAM Priority (0=Use OAM priority bit, 1=BG Priority) +When Bit 7 is set, the corresponding BG tile will have priority above all OBJs +(regardless of the priority bits in OAM memory). There's also an Master +Priority flag in LCDC register Bit 0 which overrides all other priority bits +when cleared. + +As one background tile has a size of 8x8 pixels, the BG maps may hold a +picture of 256x256 pixels, an area of 160x144 pixels of this picture can be +displayed on the LCD screen. + +Normal Background (BG) +The SCY and SCX registers can be used to scroll the background, allowing to +select the origin of the visible 160x144 pixel area within the total 256x256 +pixel background map. Background wraps around the screen (i.e. when part of it +goes off the screen, it appears on the opposite side.) + +The Window +Besides background, there is also a "window" overlaying the background. The +window is not scrollable i.e. it is always displayed starting from its left +upper corner. The location of a window on the screen can be adjusted via WX +and WY registers. Screen coordinates of the top left corner of a window are +WX-7,WY. The tiles for the window are stored in the Tile Data Table. Both the +Background and the window share the same Tile Data Table. + +Both background and window can be disabled or enabled separately via bits in +the LCDC register. + +VRAM Sprite Attribute Table (OAM) +--------------------------------- + +GameBoy video controller can display up to 40 sprites either in 8x8 or in 8x16 +pixels. Because of a limitation of hardware, only ten sprites can be displayed +per scan line. Sprite patterns have the same format as BG tiles, but they are +taken from the Sprite Pattern Table located at $8000-8FFF and have unsigned +numbering. + +Sprite attributes reside in the Sprite Attribute Table (OAM - Object Attribute +Memory) at $FE00-FE9F. Each of the 40 entries consists of four bytes with the +following meanings: + +Byte0 - Y Position +Specifies the sprites vertical position on the screen (minus 16). +An offscreen value (for example, Y=0 or Y>=160) hides the sprite. + +Byte1 - X Position +Specifies the sprites horizontal position on the screen (minus 8). +An offscreen value (X=0 or X>=168) hides the sprite, but the sprite +still affects the priority ordering - a better way to hide a sprite is to set +its Y-coordinate offscreen. + +Byte2 - Tile/Pattern Number +Specifies the sprites Tile Number (00-FF). This (unsigned) value selects a +tile from memory at 8000h-8FFFh. In CGB Mode this could be either in VRAM Bank +0 or 1, depending on Bit 3 of the following byte. +In 8x16 mode, the lower bit of the tile number is ignored. Ie. the upper 8x8 +tile is "NN AND FEh", and the lower 8x8 tile is "NN OR 01h". + +Byte3 - Attributes/Flags: + Bit7 OBJ-to-BG Priority (0=OBJ Above BG, 1=OBJ Behind BG color 1-3) + (Used for both BG and Window. BG color 0 is always behind OBJ) + Bit6 Y flip (0=Normal, 1=Vertically mirrored) + Bit5 X flip (0=Normal, 1=Horizontally mirrored) + Bit4 Palette number **Non CGB Mode Only** (0=OBP0, 1=OBP1) + Bit3 Tile VRAM-Bank **CGB Mode Only** (0=Bank 0, 1=Bank 1) + Bit2-0 Palette number **CGB Mode Only** (OBP0-7) + +Sprite Priorities and Conflicts +When sprites with different x coordinate values overlap, the one with the +smaller x coordinate (closer to the left) will have priority and appear above +any others. This applies in Non CGB Mode only. +When sprites with the same x coordinate values overlap, they have priority +according to table ordering. (i.e. $FE00 - highest, $FE04 - next highest, +etc.) In CGB Mode priorities are always assigned like this. + +Only 10 sprites can be displayed on any one line. When this limit is exceeded, +the lower priority sprites (priorities listed above) won't be displayed. To +keep unused sprites from affecting onscreen sprites set their Y coordinate to +Y=0 or Y=>144+16. Just setting the X coordinate to X=0 or X=>160+8 on a sprite +will hide it but it will still affect other sprites sharing the same lines. + +Writing Data to OAM Memory +The recommened method is to write the data to normal RAM first, and to copy +that RAM to OAM by using the DMA transfer function, initiated through DMA +register (FF46). +Beside for that, it is also possible to write data directly to the OAM area by +using normal LD commands, this works only during the H-Blank and V-Blank +periods. The current state of the LCD controller can be read out from the STAT +register (FF41). + +Accessing VRAM and OAM +---------------------- + +CAUTION +When the LCD Controller is drawing the screen it is directly reading from +Video Memory (VRAM) and from the Sprite Attribute Table (OAM). During these +periods the Gameboy CPU may not access the VRAM and OAM. That means, any +attempts to write to VRAM/OAM are ignored (the data remains unchanged). And +any attempts to read from VRAM/OAM will return undefined data (typically a +value of FFh). + +For this reason the program should verify if VRAM/OAM is accessable before +actually reading or writing to it. This is usually done by reading the Mode +Bits from the STAT Register (FF41). When doing this (as described in the +examples below) you should take care that no interrupts occur between the wait +loops and the following memory access - the memory is guaranted to be +accessable only for a few cycles directly after the wait loops have completed. + +VRAM (memory at 8000h-9FFFh) is accessable during Mode 0-2 + Mode 0 - H-Blank Period, + Mode 1 - V-Blank Period, and + Mode 2 - Searching OAM Period +A typical procedure that waits for accessibility of VRAM would be: + ld hl,0FF41h ;-STAT Register + @@wait: ;\ + bit 1,(hl) ; Wait until Mode is 0 or 1 + jr nz,@@wait ;/ +Even if the procedure gets executed at the of Mode 0 or 1, it is still +proof to assume that VRAM can be accessed for a few more cycles because in +either case the following period is Mode 2 which allows access to VRAM either. +In CGB Mode an alternate method to write data to VRAM is to use the HDMA +Function (FF51-FF55). + +OAM (memory at FE00h-FE9Fh) is accessable during Mode 0-1 + Mode 0 - H-Blank Period, and + Mode 1 - V-Blank Period +Beside for that, OAM can be accessed at any time by using the DMA Function +(FF46). When directly reading or writing to OAM, a typical procedure that +waits for accessibilty or OAM Memory would be: + ld hl,0FF41h ;-STAT Register + @@wait1: ;\ + bit 1,(hl) ; Wait until Mode is -NOT- 0 or 1 + jr z,@@wait1 ;/ + @@wait2: ;\ + bit 1,(hl) ; Wait until Mode 0 or 1 -BEGINS- + jr nz,@@wait2 ;/ +The two wait loops ensure that Mode 0 or 1 will last for a few clock cycles +after completion of the procedure. In V-Blank period it might be recommended +to skip the whole procedure - and in most cases using the above mentioned DMA +function would be more recommended anyways. + +Note +When the display is disabled, both VRAM and OAM are accessable at any time. +The downside is that the screen is blank (white) during this period, so that +disabling the display would be recommended only during initialization. + +Sound Controller +---------------- + +--> Sound Overview +--> Sound Channel 1 - Tone & Sweep +--> Sound Channel 2 - Tone +--> Sound Channel 3 - Wave Output +--> Sound Channel 4 - Noise +--> Sound Control Registers + +Sound Overview +-------------- + +There are two sound channels connected to the output terminals SO1 and SO2. +There is also a input terminal Vin connected to the cartridge. It can be +routed to either of both output terminals. GameBoy circuitry allows producing +sound in four different ways: + + Quadrangular wave patterns with sweep and envelope functions. + Quadrangular wave patterns with envelope functions. + Voluntary wave patterns from wave RAM. + White noise with an envelope function. + +These four sounds can be controlled independantly and then mixed separately +for each of the output terminals. + +Sound registers may be set at all times while producing sound. + +(Sounds will have a 2.4% higher frequency on Super GB.) + +Sound Channel 1 - Tone & Sweep +------------------------------ + +FF10 - NR10 - Channel 1 Sweep register (R/W) + Bit 6-4 - Sweep Time + Bit 3 - Sweep Increase/Decrease + 0: Addition (frequency increases) + 1: Subtraction (frequency decreases) + Bit 2-0 - Number of sweep shift (n: 0-7) +Sweep Time: + 000: sweep off - no freq change + 001: 7.8 ms (1/128Hz) + 010: 15.6 ms (2/128Hz) + 011: 23.4 ms (3/128Hz) + 100: 31.3 ms (4/128Hz) + 101: 39.1 ms (5/128Hz) + 110: 46.9 ms (6/128Hz) + 111: 54.7 ms (7/128Hz) + +The change of frequency (NR13,NR14) at each shift is calculated by the +following formula where X(0) is initial freq & X(t-1) is last freq: + X(t) = X(t-1) +/- X(t-1)/2^n + +FF11 - NR11 - Channel 1 Sound length/Wave pattern duty (R/W) + Bit 7-6 - Wave Pattern Duty (Read/Write) + Bit 5-0 - Sound length data (Write Only) (t1: 0-63) +Wave Duty: + 00: 12.5% ( _-------_-------_------- ) + 01: 25% ( __------__------__------ ) + 10: 50% ( ____----____----____---- ) (normal) + 11: 75% ( ______--______--______-- ) +Sound Length = (64-t1)*(1/256) seconds +The Length value is used only if Bit 6 in NR14 is set. + +FF12 - NR12 - Channel 1 Volume Envelope (R/W) + Bit 7-4 - Initial Volume of envelope (0-0Fh) (0=No Sound) + Bit 3 - Envelope Direction (0=Decrease, 1=Increase) + Bit 2-0 - Number of envelope sweep (n: 0-7) + (If zero, stop envelope operation.) +Length of 1 step = n*(1/64) seconds + +FF13 - NR13 - Channel 1 Frequency lo (Write Only) + +Lower 8 bits of 11 bit frequency (x). +Next 3 bit are in NR14 ($FF14) + +FF14 - NR14 - Channel 1 Frequency hi (R/W) + Bit 7 - Initial (1=Restart Sound) (Write Only) + Bit 6 - Counter/consecutive selection (Read/Write) + (1=Stop output when length in NR11 expires) + Bit 2-0 - Frequency's higher 3 bits (x) (Write Only) +Frequency = 131072/(2048-x) Hz + +Sound Channel 2 - Tone +---------------------- + +This sound channel works exactly as channel 1, except that it doesn't have a +Tone Envelope/Sweep Register. + +FF16 - NR21 - Channel 2 Sound Length/Wave Pattern Duty (R/W) + Bit 7-6 - Wave Pattern Duty (Read/Write) + Bit 5-0 - Sound length data (Write Only) (t1: 0-63) +Wave Duty: + 00: 12.5% ( _-------_-------_------- ) + 01: 25% ( __------__------__------ ) + 10: 50% ( ____----____----____---- ) (normal) + 11: 75% ( ______--______--______-- ) +Sound Length = (64-t1)*(1/256) seconds +The Length value is used only if Bit 6 in NR24 is set. + +FF17 - NR22 - Channel 2 Volume Envelope (R/W) + Bit 7-4 - Initial Volume of envelope (0-0Fh) (0=No Sound) + Bit 3 - Envelope Direction (0=Decrease, 1=Increase) + Bit 2-0 - Number of envelope sweep (n: 0-7) + (If zero, stop envelope operation.) +Length of 1 step = n*(1/64) seconds + +FF18 - NR23 - Channel 2 Frequency lo data (W) +Frequency's lower 8 bits of 11 bit data (x). +Next 3 bits are in NR24 ($FF19). + +FF19 - NR24 - Channel 2 Frequency hi data (R/W) + Bit 7 - Initial (1=Restart Sound) (Write Only) + Bit 6 - Counter/consecutive selection (Read/Write) + (1=Stop output when length in NR21 expires) + Bit 2-0 - Frequency's higher 3 bits (x) (Write Only) +Frequency = 131072/(2048-x) Hz + +Sound Channel 3 - Wave Output +----------------------------- + +This channel can be used to output digital sound, the length of the sample +buffer (Wave RAM) is limited to 32 digits. This sound channel can be also used +to output normal tones when initializing the Wave RAM by a square wave. This +channel doesn't have a volume envelope register. + +FF1A - NR30 - Channel 3 Sound on/off (R/W) + Bit 7 - Sound Channel 3 Off (0=Stop, 1=Playback) (Read/Write) + +FF1B - NR31 - Channel 3 Sound Length + Bit 7-0 - Sound length (t1: 0 - 255) +Sound Length = (256-t1)*(1/256) seconds +This value is used only if Bit 6 in NR34 is set. + +FF1C - NR32 - Channel 3 Select output level (R/W) + Bit 6-5 - Select output level (Read/Write) +Possible Output levels are: + 0: Mute (No sound) + 1: 100% Volume (Produce Wave Pattern RAM Data as it is) + 2: 50% Volume (Produce Wave Pattern RAM data shifted once to the right) + 3: 25% Volume (Produce Wave Pattern RAM data shifted twice to the right) + +FF1D - NR33 - Channel 3 Frequency's lower data (W) +Lower 8 bits of an 11 bit frequency (x). + +FF1E - NR34 - Channel 3 Frequency's higher data (R/W) + Bit 7 - Initial (1=Restart Sound) (Write Only) + Bit 6 - Counter/consecutive selection (Read/Write) + (1=Stop output when length in NR31 expires) + Bit 2-0 - Frequency's higher 3 bits (x) (Write Only) +Frequency = 4194304/(64*(2048-x)) Hz = 65536/(2048-x) Hz + +FF30-FF3F - Wave Pattern RAM +Contents - Waveform storage for arbitrary sound data + +This storage area holds 32 4-bit samples that are played back upper 4 bits +first. + +Sound Channel 4 - Noise +----------------------- + +This channel is used to output white noise. This is done by randomly switching +the amplitude between high and low at a given frequency. Depending on the +frequency the noise will appear 'harder' or 'softer'. + +It is also possible to influence the function of the random generator, so the +that the output becomes more regular, resulting in a limited ability to output +Tone instead of Noise. + +FF20 - NR41 - Channel 4 Sound Length (R/W) + Bit 5-0 - Sound length data (t1: 0-63) +Sound Length = (64-t1)*(1/256) seconds +The Length value is used only if Bit 6 in NR44 is set. + +FF21 - NR42 - Channel 4 Volume Envelope (R/W) + Bit 7-4 - Initial Volume of envelope (0-0Fh) (0=No Sound) + Bit 3 - Envelope Direction (0=Decrease, 1=Increase) + Bit 2-0 - Number of envelope sweep (n: 0-7) + (If zero, stop envelope operation.) +Length of 1 step = n*(1/64) seconds + +FF22 - NR43 - Channel 4 Polynomial Counter (R/W) +The amplitude is randomly switched between high and low at the given +frequency. A higher frequency will make the noise to appear 'softer'. +When Bit 3 is set, the output will become more regular, and some frequencies +will sound more like Tone than Noise. + Bit 7-4 - Shift Clock Frequency (s) + Bit 3 - Counter Step/Width (0=15 bits, 1=7 bits) + Bit 2-0 - Dividing Ratio of Frequencies (r) +Frequency = 524288 Hz / r / 2^(s+1) ;For r=0 assume r=0.5 instead + +FF23 - NR44 - Channel 4 Counter/consecutive; Inital (R/W) + Bit 7 - Initial (1=Restart Sound) (Write Only) + Bit 6 - Counter/consecutive selection (Read/Write) + (1=Stop output when length in NR41 expires) + +Sound Control Registers +----------------------- + +FF24 - NR50 - Channel control / ON-OFF / Volume (R/W) +The volume bits specify the "Master Volume" for Left/Right sound output. + Bit 7 - Output Vin to SO2 terminal (1=Enable) + Bit 6-4 - SO2 output level (volume) (0-7) + Bit 3 - Output Vin to SO1 terminal (1=Enable) + Bit 2-0 - SO1 output level (volume) (0-7) +The Vin signal is received from the game cartridge bus, allowing external +hardware in the cartridge to supply a fifth sound channel, additionally to the +gameboys internal four channels. As far as I know this feature isn't used by +any existing games. + +FF25 - NR51 - Selection of Sound output terminal (R/W) + Bit 7 - Output sound 4 to SO2 terminal + Bit 6 - Output sound 3 to SO2 terminal + Bit 5 - Output sound 2 to SO2 terminal + Bit 4 - Output sound 1 to SO2 terminal + Bit 3 - Output sound 4 to SO1 terminal + Bit 2 - Output sound 3 to SO1 terminal + Bit 1 - Output sound 2 to SO1 terminal + Bit 0 - Output sound 1 to SO1 terminal + +FF26 - NR52 - Sound on/off +If your GB programs don't use sound then write 00h to this register to save +16% or more on GB power consumption. Disabeling the sound controller by +clearing Bit 7 destroys the contents of all sound registers. Also, it is not +possible to access any sound registers (execpt FF26) while the sound +controller is disabled. + Bit 7 - All sound on/off (0: stop all sound circuits) (Read/Write) + Bit 3 - Sound 4 ON flag (Read Only) + Bit 2 - Sound 3 ON flag (Read Only) + Bit 1 - Sound 2 ON flag (Read Only) + Bit 0 - Sound 1 ON flag (Read Only) +Bits 0-3 of this register are read only status bits, writing to these bits +does NOT enable/disable sound. The flags get set when sound output is +restarted by setting the Initial flag (Bit 7 in NR14-NR44), the flag remains +set until the sound length has expired (if enabled). A volume envelopes which +has decreased to zero volume will NOT cause the sound flag to go off. + +Joypad Input +------------ + +FF00 - P1/JOYP - Joypad (R/W) +The eight gameboy buttons/direction keys are arranged in form of a 2x4 matrix. +Select either button or direction keys by writing to this register, then +read-out bit 0-3. + Bit 7 - Not used + Bit 6 - Not used + Bit 5 - P15 Select Button Keys (0=Select) + Bit 4 - P14 Select Direction Keys (0=Select) + Bit 3 - P13 Input Down or Start (0=Pressed) (Read Only) + Bit 2 - P12 Input Up or Select (0=Pressed) (Read Only) + Bit 1 - P11 Input Left or Button B (0=Pressed) (Read Only) + Bit 0 - P10 Input Right or Button A (0=Pressed) (Read Only) +Note: Most programs are repeatedly reading from this port several times (the +first reads used as short delay, allowing the inputs to stabilize, and only +the value from the last read actually used). + +Usage in SGB software +Beside for normal joypad input, SGB games mis-use the joypad register to +output SGB command packets to the SNES, also, SGB programs may read out +gamepad states from up to four different joypads which can be connected to the +SNES. +See SGB description for details. + +INT 60 - Joypad Interrupt +Joypad interrupt is requested when any of the above Input lines changes from +High to Low. Generally this should happen when a key becomes pressed (provided +that the button/direction key is enabled by above Bit4/5), however, because of +switch bounce, one or more High to Low transitions are usually produced both +when pressing or releasing a key. + +Using the Joypad Interrupt +It's more or less useless for programmers, even when selecting both buttons +and direction keys simultaneously it still cannot recognize all keystrokes, +because in that case a bit might be already held low by a button key, and +pressing the corresponding direction key would thus cause no difference. The +only meaningful purpose of the keystroke interrupt would be to terminate STOP +(low power) standby state. +Also, the joypad interrupt does not appear to work with CGB and GBA hardware +(the STOP function can be still terminated by joypad keystrokes though). + +Serial Data Transfer (Link Cable) +--------------------------------- + +FF01 - SB - Serial transfer data (R/W) +8 Bits of data to be read/written + +FF02 - SC - Serial Transfer Control (R/W) + Bit 7 - Transfer Start Flag (0=No Transfer, 1=Start) + Bit 1 - Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only ** + Bit 0 - Shift Clock (0=External Clock, 1=Internal Clock) +The clock signal specifies the rate at which the eight data bits in SB (FF01) +are transferred. When the gameboy is communicating with another gameboy (or +other computer) then either one must supply internal clock, and the other one +must use external clock. + +Internal Clock +In Non-CGB Mode the gameboy supplies an internal clock of 8192Hz only +(allowing to transfer about 1 KByte per second). In CGB Mode four internal +clock rates are available, depending on Bit 1 of the SC register, and on +whether the CGB Double Speed Mode is used: + 8192Hz - 1KB/s - Bit 1 cleared, Normal + 16384Hz - 2KB/s - Bit 1 cleared, Double Speed Mode + 262144Hz - 32KB/s - Bit 1 set, Normal + 524288Hz - 64KB/s - Bit 1 set, Double Speed Mode + +External Clock +The external clock is typically supplied by another gameboy, but might be +supplied by another computer (for example if connected to a PCs parallel +port), in that case the external clock may have any speed. Even the +old/monochrome gameboy is reported to recognizes external clocks of up to +500KHz. And there is no limitiation into the other direction - even when +suppling an external clock speed of "1 bit per month", then the gameboy will +still eagerly wait for the next bit(s) to be transferred. It isn't required +that the clock pulses are sent at an regular interval either. + +Timeouts +When using external clock then the transfer will not complete until the last +bit is received. In case that the second gameboy isn't supplying a clock +signal, if it gets turned off, or if there is no second gameboy connected at +all) then transfer will never complete. For this reason the transfer procedure +should use a timeout counter, and abort the communication if no response has +been received during the timeout interval. + +Delays and Synchronization +The gameboy that is using internal clock should always execute a small delay +between each transfer, in order to ensure that the opponent gameboy has enough +time to prepare itself for the next transfer, ie. the gameboy with external +clock must have set its transfer start bit before the gameboy with internal +clock starts the transfer. Alternately, the two gameboys could switch between +internal and external clock for each transferred byte to ensure +synchronization. + +Transfer is initiated by setting the Transfer Start Flag. This bit is +automatically set to 0 at the end of Transfer. Reading this bit can be used to +determine if the transfer is still active. + +INT 58 - Serial Interrupt +When the transfer has completed (ie. after sending/receiving 8 bits, if any) +then an interrupt is requested by setting Bit 3 of the IF Register (FF0F). +When that interrupt is enabled, then the Serial Interrupt vector at 0058 is +called. + +XXXXXX... + +Transmitting and receiving serial data is done simultaneously. The received +data is automatically stored in SB. + +The serial I/O port on the Gameboy is a very simple setup and is crude +compared to standard RS-232 (IBM-PC) or RS-485 (Macintosh) serial ports. There +are no start or stop bits. + +During a transfer, a byte is shifted in at the same time that a byte is +shifted out. The rate of the shift is determined by whether the clock source +is internal or external. +The most significant bit is shifted in and out first. + +When the internal clock is selected, it drives the clock pin on the game link +port and it stays high when not used. During a transfer it will go low eight +times to clock in/out each bit. + +The state of the last bit shifted out determines the state of the output line +until another transfer takes place. + +If a serial transfer with internal clock is performed and no external GameBoy +is present, a value of $FF will be received in the transfer. + +The following code causes $75 to be shifted out the serial port and a byte to +be shifted into $FF01: + + ld a,$75 + ld ($FF01),a + ld a,$81 + ld ($FF02),a + +Timer and Divider Registers +--------------------------- + +FF04 - DIV - Divider Register (R/W) +This register is incremented at rate of 16384Hz (~16779Hz on SGB). In CGB +Double Speed Mode it is incremented twice as fast, ie. at 32768Hz. Writing any +value to this register resets it to 00h. + +FF05 - TIMA - Timer counter (R/W) +This timer is incremented by a clock frequency specified by the TAC register +($FF07). When the value overflows (gets bigger than FFh) then it will be reset +to the value specified in TMA (FF06), and an interrupt will be requested, as +described below. + +FF06 - TMA - Timer Modulo (R/W) +When the TIMA overflows, this data will be loaded. + +FF07 - TAC - Timer Control (R/W) + Bit 2 - Timer Stop (0=Stop, 1=Start) + Bits 1-0 - Input Clock Select + 00: 4096 Hz (~4194 Hz SGB) + 01: 262144 Hz (~268400 Hz SGB) + 10: 65536 Hz (~67110 Hz SGB) + 11: 16384 Hz (~16780 Hz SGB) + +INT 50 - Timer Interrupt +Each time when the timer overflows (ie. when TIMA gets bigger than FFh), then +an interrupt is requested by setting Bit 2 in the IF Register (FF0F). When +that interrupt is enabled, then the CPU will execute it by calling the timer +interrupt vector at 0050h. + +Note +The above described Timer is the built-in timer in the gameboy. It has nothing +to do with the MBC3s battery buffered Real Time Clock - that's a completely +different thing, described in the chapter about Memory Banking Controllers. + +Interrupts +---------- + +IME - Interrupt Master Enable Flag (Write Only) + 0 - Disable all Interrupts + 1 - Enable all Interrupts that are enabled in IE Register (FFFF) +The IME flag is used to disable all interrupts, overriding any enabled bits in +the IE Register. It isn't possible to access the IME flag by using a I/O +address, instead IME is accessed directly from the CPU, by the following +opcodes/operations: + EI ;Enable Interrupts (ie. IME=1) + DI ;Disable Interrupts (ie. IME=0) + RETI ;Enable Ints & Return (same as the opcode combination EI, RET) + ;Disable Ints & Call to Interrupt Vector +Whereas means the operation which is automatically executed by the CPU +when it executes an interrupt. + +FFFF - IE - Interrupt Enable (R/W) + Bit 0: V-Blank Interrupt Enable (INT 40h) (1=Enable) + Bit 1: LCD STAT Interrupt Enable (INT 48h) (1=Enable) + Bit 2: Timer Interrupt Enable (INT 50h) (1=Enable) + Bit 3: Serial Interrupt Enable (INT 58h) (1=Enable) + Bit 4: Joypad Interrupt Enable (INT 60h) (1=Enable) + +FF0F - IF - Interrupt Flag (R/W) + Bit 0: V-Blank Interrupt Request (INT 40h) (1=Request) + Bit 1: LCD STAT Interrupt Request (INT 48h) (1=Request) + Bit 2: Timer Interrupt Request (INT 50h) (1=Request) + Bit 3: Serial Interrupt Request (INT 58h) (1=Request) + Bit 4: Joypad Interrupt Request (INT 60h) (1=Request) +When an interrupt signal changes from low to high, then the corresponding bit +in the IF register becomes set. For example, Bit 0 becomes set when the LCD +controller enters into the V-Blank period. + +Interrupt Requests +Any set bits in the IF register are only an interrupt to be +executed. The actual happens only if both the IME flag, and the +corresponding bit in the IE register are set, otherwise the interrupt 'waits' +until both IME and IE allow its execution. + +Interrupt Execution +When an interrupt gets executed, the corresponding bit in the IF register +becomes automatically reset by the CPU, and the IME flag becomes cleared +(disabeling any further interrupts until the program re-enables the +interrupts, typically by using the RETI instruction), and the corresponding +Interrupt Vector (that are the addresses in range 0040h-0060h, as shown in IE +and IF register decriptions above) becomes called. + +Manually Requesting/Discarding Interrupts +As the CPU automatically sets and cleares the bits in the IF register it is +usually not required to write to the IF register. However, the user may still +do that in order to manually request (or discard) interrupts. As for real +interrupts, a manually requested interrupt isn't executed unless/until IME and +IE allow its execution. + +Interrupt Priorities +In the following three situations it might happen that more than 1 bit in the +IF register are set, requesting more than one interrupt at once: + 1) More than one interrupt signal changed from Low + to High at the same time. + 2) Several interrupts have been requested during a + time in which IME/IE didn't allow these interrupts + to be executed directly. + 3) The user has written a value with several "1" bits + (for example 1Fh) to the IF register. +Provided that IME and IE allow the execution of more than one of the requested +interrupts, then the interrupt with the highest priority becomes executed +first. The priorities are ordered as the bits in the IE and IF registers, Bit +0 (V-Blank) having the highest priority, and Bit 4 (Joypad) having the lowest +priority. + +Nested Interrupts +The CPU automatically disables all other interrupts by setting IME=0 when it +executes an interrupt. Usually IME remains zero until the interrupt procedure +returns (and sets IME=1 by the RETI instruction). However, if you want any +other interrupts of lower or higher (or same) priority to be allowed to be +executed from inside of the interrupt procedure, then you can place an EI +instruction into the interrupt procedure. + +CGB Registers +------------- + +Forward +This chapter describes only CGB (Color Gameboy) registers that didn't fit into +normal categories - most CGB registers are described in the chapter about +Video Display (Color Palettes, VRAM Bank, VRAM DMA Transfers, and changed +meaning of Bit 0 of LCDC Control register). Also, a changed bit is noted in +the chapter about the Serial/Link port. + +Unlocking CGB functions +When using any CGB registers (including those in the Video/Link chapters), you +must first unlock CGB features by changing byte 0143h in the cartridge header. +Typically use a value of 80h for games which support both CGB and monochrome +gameboys, and C0h for games which work on CGBs only. Otherwise, the CGB will +operate in monochrome "Non CGB" compatibility mode. + +Detecting CGB (and GBA) functions +CGB hardware can be detected by examing the CPU accumulator (A-register) +directly after startup. A value of 11h indicates CGB (or GBA) hardware, if so, +CGB functions can be used (if unlocked, see above). +When A=11h, you may also examine Bit 0 of the CPUs B-Register to separate +between CGB (bit cleared) and GBA (bit set), by that detection it is possible +to use 'repaired' color palette data matching for GBA displays. + +FF4D - KEY1 - CGB Mode Only - Prepare Speed Switch + Bit 7: Current Speed (0=Normal, 1=Double) (Read Only) + Bit 0: Prepare Speed Switch (0=No, 1=Prepare) (Read/Write) +This register is used to prepare the gameboy to switch between CGB Double +Speed Mode and Normal Speed Mode. The actual speed switch is performed by +executing a STOP command after Bit 0 has been set. After that Bit 0 will be +cleared automatically, and the gameboy will operate at the 'other' speed. The +recommended speed switching procedure in pseudo code would be: + IF KEY1_BIT7 <> DESIRED_SPEED THEN + IE=00H ;(FFFF)=00h + JOYP=30H ;(FF00)=30h + KEY1=01H ;(FF4D)=01h + STOP ;STOP + ENDIF +The CGB is operating in Normal Speed Mode when it is turned on. Note that +using the Double Speed Mode increases the power consumption, it would be +recommended to use Single Speed whenever possible. However, the display will +flicker (white) for a moment during speed switches, so this cannot be done +permanentely. +In Double Speed Mode the following will operate twice as fast as normal: + The CPU (2.10 MHz, 1 Cycle = approx. 0.5us) + Timer and Divider Registers + Serial Port (Link Cable) + DMA Transfer to OAM +And the following will keep operating as usual: + LCD Video Controller + HDMA Transfer to VRAM + All Sound Timings and Frequencies + +FF56 - RP - CGB Mode Only - Infrared Communications Port +This register allows to input and output data through the CGBs built-in +Infrared Port. When reading data, bit 6 and 7 must be set (and obviously Bit 0 +must be cleared - if you don't want to receive your own gameboys IR signal). +After sending or receiving data you should reset the register to 00h to reduce +battery power consumption again. + Bit 0: Write Data (0=LED Off, 1=LED On) (Read/Write) + Bit 1: Read Data (0=Receiving IR Signal, 1=Normal) (Read Only) + Bit 6-7: Data Read Enable (0=Disable, 3=Enable) (Read/Write) +Note that the receiver will adapt itself to the normal level of IR pollution +in the air, so if you would send a LED ON signal for a longer period, then the +receiver would treat that as normal (=OFF) after a while. For example, a +Philips TV Remote Control sends a series of 32 LED ON/OFF pulses (length 10us +ON, 17.5us OFF each) instead of a permanent 880us LED ON signal. +Even though being generally CGB compatible, the GBA does not include an +infra-red port. + +FF70 - SVBK - CGB Mode Only - WRAM Bank +In CGB Mode 32 KBytes internal RAM are available. This memory is divided into +8 banks of 4 KBytes each. Bank 0 is always available in memory at C000-CFFF, +Bank 1-7 can be selected into the address space at D000-DFFF. + Bit 0-2 Select WRAM Bank (Read/Write) +Writing a value of 01h-07h will select Bank 1-7, writing a value of 00h will +select Bank 1 either. + +FF6C - Undocumented (FEh) - Bit 0 (Read/Write) - CGB Mode Only +FF72 - Undocumented (00h) - Bit 0-7 (Read/Write) +FF73 - Undocumented (00h) - Bit 0-7 (Read/Write) +FF74 - Undocumented (00h) - Bit 0-7 (Read/Write) - CGB Mode Only +FF75 - Undocumented (8Fh) - Bit 4-6 (Read/Write) +FF76 - Undocumented (00h) - Always 00h (Read Only) +FF77 - Undocumented (00h) - Always 00h (Read Only) +These are undocumented CGB Registers. The numbers in brackets () indicate the +initial values. Purpose of these registers is unknown (if any). Registers FF6C +and FF74 are always FFh if the CGB is in Non CGB Mode. + +SGB Functions +------------- + +General Information +--> SGB Description +--> SGB Unlocking and Detecting SGB Functions +--> SGB Command Packet Transfers +--> SGB VRAM Transfers +--> SGB Command Summary +--> SGB Color Palettes Overview + +SGB Commands +--> SGB Palette Commands +--> SGB Color Attribute Commands +--> SGB Sound Functions +--> SGB System Control Commands +--> SGB Multiplayer Command +--> SGB Border and OBJ Commands + +SGB Description +--------------- + +General Description +Basically, the SGB (Super Gameboy) is an adapter cartridge that allows to play +gameboy games on a SNES (Super Nintendo Entertainment System) gaming console. +In detail, you plug the gameboy cartridge into the SGB cartridge, then plug +the SGB cartridge into the SNES, and then connect the SNES to your TV Set. In +result, games can be played and viewed on the TV Set, and are controlled by +using the SNES joypad(s). + +More Technical Description +The SGB cartridge just contains a normal gameboy CPU and normal gameboy video +controller. Normally the video signal from this controller would be sent to +the LCD screen, however, in this special case the SNES read out the video +signal and displays it on the TV set by using a special SNES BIOS ROM which is +located in the SGB cartridge. Also, normal gameboy sound output is forwared to +the SNES and output to the TV Set, vice versa, joypad input is forwared from +the SNES controller(s) to the gameboy joypad inputs. + +Normal Monochrome Games +Any gameboy games which have been designed for normal monochrome handheld +gameboys will work with the SGB hardware as well. The SGB will apply a four +color palette to these games by replacing the normal four grayshades. The +160x144 pixel gamescreen is displayed in the middle of the 256x224 pixel SNES +screen (the unused area is filled by a screen border bitmap). The user may +access built-in menues, allowing to change color palette data, to select +between several pre-defined borders, etc. + +Games that have been designed to support SGB functions may also access the +following additional features: + +Colorized Game Screen +There's limited ability to colorize the gamescreen by assigning custom color +palettes to each 20x18 display characters, however, this works mainly for +static display data such like title screens or status bars, the 20x18 color +attribute map is non-scrollable, and it is not possible to assign separate +colors to moveable foreground sprites (OBJs), so that animated screen regions +will be typically restricted to using a single palette of four colors only. + +SNES Foreground Sprites +Up to 24 foreground sprites (OBJs) of 8x8 or 16x16 pixels, 16 colors can be +displayed. When replacing (or just overlaying) the normal gameboy OBJs by SNES +OBJs it'd be thus possible to display OBJs with other colors than normal +background area. This method doesn't appear to be very popular, even though it +appears to be quite easy to implement, however, the bottommost character line +of the gamescreen will be masked out because this area is used to transfer OAM +data to the SNES. + +The SGB Border +The possibly most popular and most impressive feature is to replace the +default SGB screen border by a custom bitmap which is stored in the game +cartridge. + +Multiple Joypads +Up to four joypads can be conected to the SNES, and SGB software may read-out +each of these joypads separately, allowing up to four players to play the same +game simultaneously. Unlike for multiplayer handheld games, this requires only +one game cartridge and only one SGB/SNES, and no link cables are required, the +downside is that all players must share the same display screen. + +Sound Functions +Beside for normal gameboy sound, a number of digital sound effects is +pre-defined in the SNES BIOS, these effects may be accessed quite easily. +Programmers whom are familiar with SNES sounds may also access the SNES sound +chip, or use the SNES MIDI engine directly in order to produce other sound +effects or music. + +Taking Control of the SNES CPU +Finally, it is possible to write program code or data into SNES memory, and to +execute such program code by using the SNES CPU. + +SGB System Clock +Because the SGB is synchronized to the SNES CPU, the gameboy system clock is +directly chained to the SNES system clock. In result, the gameboy CPU, video +controller, timers, and sound frequencies will be all operated approx 2.4% +faster as by normal gameboys. +Basically, this should be no problem, and the game will just run a little bit +faster. However sensitive musicians may notice that sound frequencies are a +bit too high, programs that support SGB functions may avoid this effect by +reducing frequencies of gameboy sounds when having detected SGB hardware. +Also, I think that I've heard that SNES models which use a 50Hz display +refresh rate (rather than 60Hz) are resulting in respectively slower +SGB/gameboy timings ??? + +SGB Unlocking and Detecting SGB Functions +----------------------------------------- + +Cartridge Header +SGB games are required to have a cartridge header with Nintendo and proper +checksum just as normal gameboy games. Also, two special entries must be set +in order to unlock SGB functions: + 146h - SGB Flag - Must be set to 03h for SGB games + 14Bh - Old Licensee Code - Must be set 33h for SGB games +When these entries aren't set, the game will still work just like all +'monochrome' gameboy games, but it cannot access any of the special SGB +functions. + +Detecting SGB hardware +The recommended detection method is to send a MLT_REQ command which enables +two (or four) joypads. A normal handheld gameboy will ignore this command, a +SGB will now return incrementing joypad IDs each time when deselecting +keyboard lines (see MLT_REQ description for details). +Now read-out joypad state/IDs several times, and if the ID-numbers are +changing, then it is a SGB (a normal gameboy would typically always return 0Fh +as ID). Finally, when not intending to use more than one joypad, send another +MLT_REQ command in order to re-disable the multi-controller mode. +Detection works regardless of whether and how many joypads are physically +connected to the SNES. However, detection works only when having unlocked SGB +functions in the cartridge header, as described above. + +Separating between SGB and SGB2 +It is also possible to separate between SGB and SGB2 models by examining the +inital value of the accumulator (A-register) directly after startup. + 01h SGB or Normal Gameboy (DMG) + FFh SGB2 or Pocket Gameboy + 11h CGB or GBA +Because values 01h and FFh are shared for both handhelds and SGBs, it is still +required to use the above MLT_REQ detection procedure. As far as I know the +SGB2 doesn't have any extra features which'd require separate SGB2 detection +except for curiosity purposes, for example, the game "Tetris DX" chooses to +display an alternate SGB border on SGB2s. + +Reportedly, some SGB models include link ports (just like handheld gameboy) +(my own SGB does not have such an port), possibly this feature is available in +SGB2-type models only ??? + +SGB Command Packet Transfers +---------------------------- + +Command packets (aka Register Files) are transferred from the gameboy to the +SNES by using P14 and P15 output lines of the JOYPAD register (FF00h), these +lines are normally used to select the two rows in the gameboy keyboard matrix +(which still works). + +Transferring Bits +A command packet transfer must be initiated by setting both P14 and P15 to +LOW, this will reset and start the SNES packet receiving program. Data is then +transferred (LSB first), setting P14=LOW will indicate a "0" bit, and setting +P15=LOW will indicate a "1" bit. For example: + RESET 0 0 1 1 0 1 0 + P14 --_---_---_-----------_-------_--... + P15 --_-----------_---_-------_------... +Data and reset pulses must be kept LOW for at least 5us. P14 and P15 must be +kept both HIGH for at least 15us between any pulses. +Obviously, it'd be no good idea to access the JOYPAD register during the +transfer, for example, in case that your VBlank interrupt procedure reads-out +joypad states each frame, be sure to disable that interrupt during the +transfer (or disable only the joypad procedure by using a software flag). + +Transferring Packets +Each packet is invoked by a RESET pulse, then 128 bits of data are transferred +(16 bytes, LSB of first byte first), and finally, a "0"-bit must be +transferred as stop bit. The structure of normal packets is: + 1 PULSE Reset + 1 BYTE Command Code*8+Length + 15 BYTES Parameter Data + 1 BIT Stop Bit (0) +The above 'Length' indicates the total number of packets (1-7, including the +first packet) which will be sent, ie. if more than 15 parameter bytes are +used, then further packet(s) will follow, as such: + 1 PULSE Reset + 16 BYTES Parameter Data + 1 BIT Stop Bit (0) +By using all 7 packets, up to 111 data bytes (15+16*6) may be sent. +Unused bytes at the end of the last packet must be set to zero. +A 60ms (4 frames) delay should be invoked between each packet transfer. + +SGB VRAM Transfers +------------------ + +Overview +Beside for the packet transfer method, larger data blocks of 4KBytes can be +transferred by using the video signal. These transfers are invoked by first +sending one of the commands with the ending _TRN (by using normal packet +transfer), the 4K data block is then read-out by the SNES from gameboy display +memory during the next frame. + +Transfer Data +Normally, transfer data should be stored at 8000h-8FFFh in gameboy VRAM, +even though the SNES receives the data in from display scanlines, it will +automatically re-produce the same ordering of bits and bytes, as being +originally stored at 8000h-8FFFh in gameboy memory. + +Preparing the Display +The above method works only when recursing the following things: BG Map must +display unsigned characters 00h-FFh on the screen; 00h..13h in first line, +14h..27h in next line, etc. The gameboy display must be enabled, the display +may not be scrolled, OBJ sprites should not overlap the background tiles, the +BGP palette register must be set to E4h. + +Transfer Time +Note that the transfer data should be prepared in VRAM sending the +transfer command packet. The actual transfer starts at the beginning of the +next frame after the command has been sent, and the transfer ends at the end +of the 5th frame after the command has been sent (not counting the frame in +which the command has been sent). + +Avoiding Screen Garbage +The display will contain 'garbage' during the transfer, this dirt-effect can +be avoided by freezing the screen (in the state which has been displayed +before the transfer) by using the MASK_EN command. +Of course, this works only when actually executing the game on a SGB (and not +on normal handheld gameboys), it'd be thus required to detect the presence of +SGB hardware before blindly sending VRAM data. + +SGB Command Summary +------------------- + +SGB System Command Table + Code Name Expl. + 00 PAL01 Set SGB Palette 0,1 Data + 01 PAL23 Set SGB Palette 2,3 Data + 02 PAL03 Set SGB Palette 0,3 Data + 03 PAL12 Set SGB Palette 1,2 Data + 04 ATTR_BLK "Block" Area Designation Mode + 05 ATTR_LIN "Line" Area Designation Mode + 06 ATTR_DIV "Divide" Area Designation Mode + 07 ATTR_CHR "1CHR" Area Designation Mode + 08 SOUND Sound On/Off + 09 SOU_TRN Transfer Sound PRG/DATA + 0A PAL_SET Set SGB Palette Indirect + 0B PAL_TRN Set System Color Palette Data + 0C ATRC_EN Enable/disable Attraction Mode + 0D TEST_EN Speed Function + 0E ICON_EN SGB Function + 0F DATA_SND SUPER NES WRAM Transfer 1 + 10 DATA_TRN SUPER NES WRAM Transfer 2 + 11 MLT_REG Controller 2 Request + 12 JUMP Set SNES Program Counter + 13 CHR_TRN Transfer Character Font Data + 14 PCT_TRN Set Screen Data Color Data + 15 ATTR_TRN Set Attribute from ATF + 16 ATTR_SET Set Data to ATF + 17 MASK_EN Game Boy Window Mask + 18 OBJ_TRN Super NES OBJ Mode + +SGB Color Palettes Overview +--------------------------- + +Available SNES Palettes +The SGB/SNES provides 8 palettes of 16 colors each, each color may be defined +out of a selection of 34768 colors (15 bit). Palettes 0-3 are used to colorize +the gamescreen, only the first four colors of each of these palettes are used. +Palettes 4-7 are used for the SGB Border, all 16 colors of each of these +palettes may be used. + +Color 0 Restriction +Color 0 of each of the eight palettes is transparent, causing the backdrop +color to be displayed instead. The backdrop color is typically defined by the +most recently color being assigned to Color 0 (regardless of the palette +number being used for that operation). +Effectively, gamescreen palettes can have only three custom colors each, and +SGB border palettes only 15 colors each, additionally, color 0 can be used for +for all palettes, which will then all share the same color though. + +Translation of Grayshades into Colors +Because the SGB/SNES reads out the gameboy video controllers display signal, +it translates the different grayshades from the signal into SNES colors as +such: + White --> Color 0 + Light Gray --> Color 1 + Dark Gray --> Color 2 + Black --> Color 3 +Note that gameboy colors 0-3 are assigned to user-selectable grayshades by the +gameboys BGP, OBP1, and OBP2 registers. There is thus no fixed relationship +between gameboy colors 0-3 and SNES colors 0-3. + +Using Gameboy BGP/OBP Registers +A direct translation of color 0-3 into color 0-3 may be produced by setting +BGP/OBP registers to a value of 0E4h each. However, in case that your program +uses black background for example, then you may internally assign background +as "White" at the gameboy side by BGP/OBP registers (which is then interpreted +as SNES color 0, which is shared for all SNES palettes). The advantage is that +you may define Color 0 as Black at the SNES side, and may assign custom colors +for Colors 1-3 of each SNES palette. + +System Color Palette Memory +Beside for the actually visible palettes, up to 512 palettes of 4 colors each +may be defined in SNES RAM. Basically, this is completely irrelevant because +the palettes are just stored in RAM whithout any relationship to the displayed +picture, anyways, these pre-defined colors may be transferred to actually +visible palettes slightly faster as when transferring palette data by separate +command packets. + +SGB Palette Commands +-------------------- + +SGB Command 00h - PAL01 +Transmit color data for SGB palette 0, color 0-3, and for SGB palette 1, color +1-3 (without separate color 0). + Byte Content + 0 Command*8+Length (fixed length=01h) + 1-E Color Data for 7 colors of 2 bytes (16bit) each: + Bit 0-4 - Red Intensity (0-31) + Bit 5-9 - Green Intensity (0-31) + Bit 10-14 - Blue Intensity (0-31) + Bit 15 - Not used (zero) + F Not used (00h) +The value transferred as color 0 will be applied for all eight palettes. + +SGB Command 01h - PAL23 +Same as above PAL01, but for Palettes 2 and 3 respectively. + +SGB Command 02h - PAL03 +Same as above PAL01, but for Palettes 0 and 3 respectively. + +SGB Command 03h - PAL12 +Same as above PAL01, but for Palettes 1 and 2 respectively. + +SGB Command 0Ah - PAL_SET +Used to copy pre-defined palette data from SGB system color palette to actual +SGB palette. + Byte Content + 0 Command*8+Length (fixed length=1) + 1-2 System Palette number for SGB Color Palette 0 (0-511) + 3-4 System Palette number for SGB Color Palette 1 (0-511) + 5-6 System Palette number for SGB Color Palette 2 (0-511) + 7-8 System Palette number for SGB Color Palette 3 (0-511) + 9 Attribute File + Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1) + Bit 6 - Cancel Mask (0=No change, 1=Yes) + Bit 7 - Use Attribute File (0=No, 1=Apply above ATF Number) + A-F Not used (zero) +Before using this function, System Palette data should be initialized by +PAL_TRN command, and (when used) Attribute File data should be initialized by +ATTR_TRN. + +SGB Command 0Bh - PAL_TRN +Used to initialize SGB system color palettes in SNES RAM. +System color palette memory contains 512 pre-defined palettes, these palettes +do not directly affect the display, however, the PAL_SET command may be later +used to transfer four of these 'logical' palettes to actual visible 'physical' +SGB palettes. Also, the OBJ_TRN function will use groups of 4 System Color +Palettes (4*4 colors) for SNES OBJ palettes (16 colors). + Byte Content + 0 Command*8+Length (fixed length=1) + 1-F Not used (zero) +The palette data is sent by VRAM-Transfer (4 KBytes). + 000-FFF Data for System Color Palette 0-511 +Each Palette consists of four 16bit-color definitions (8 bytes). +Note: The data is stored at 3000h-3FFFh in SNES memory. + +SGB Color Attribute Commands +---------------------------- + +SGB Command 04h - ATTR_BLK +Used to specify color attributes for the inside or outside of one or more +rectangular screen regions. + Byte Content + 0 Command*8+Length (length=1..7) + 1 Number of Data Sets (01h..12h) + 2-7 Data Set #1 + Byte 0 - Control Code (0-7) + Bit 0 - Change Colors inside of surrounded area (1=Yes) + Bit 1 - Change Colors of surrounding character line (1=Yes) + Bit 2 - Change Colors outside of surrounded area (1=Yes) + Bit 3-7 - Not used (zero) + Exception: When changing only the Inside or Outside, then the + Surrounding line becomes automatically changed to same color. + Byte 1 - Color Palette Designation + Bit 0-1 - Palette Number for inside of surrounded area + Bit 2-3 - Palette Number for surrounding character line + Bit 4-5 - Palette Number for outside of surrounded area + Bit 6-7 - Not used (zero) + Data Set Byte 2 - Coordinate X1 (left) + Data Set Byte 3 - Coordinate Y1 (upper) + Data Set Byte 4 - Coordinate X2 (right) + Data Set Byte 5 - Coordinate Y2 (lower) + Specifies the coordinates of the surrounding rectangle. + 8-D Data Set #2 (if any) + E-F Data Set #3 (continued at 0-3 in next packet) (if any) +When sending three or more data sets, data is continued in further packet(s). +Unused bytes at the end of the last packet should be set to zero. The format +of the separate Data Sets is described below. + +SGB Command 05h - ATTR_LIN +Used to specify color attributes of one or more horizontal or vertical +character lines. + Byte Content + 0 Command*8+Length (length=1..7) + 1 Number of Data Sets (01h..6Eh) (one byte each) + 2 Data Set #1 + Bit 0-4 - Line Number (X- or Y-coordinate, depending on bit 7) + Bit 5-6 - Palette Number (0-3) + Bit 7 - H/V Mode Bit (0=Vertical line, 1=Horizontal Line) + 3 Data Set #2 (if any) + 4 Data Set #3 (if any) + etc. +When sending 15 or more data sets, data is continued in further packet(s). +Unused bytes at the end of the last packet should be set to zero. The format +of the separate Data Sets (one byte each) is described below. +The length of each line reaches from one end of the screen to the other end. +In case that some lines overlap each other, then lines from lastmost data sets +will overwrite lines from previous data sets. + +SGB Command 06h - ATTR_DIV +Used to split the screen into two halfes, and to assign separate color +attributes to each half, and to the division line between them. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Color Palette Numbers and H/V Mode Bit + Bit 0-1 Palette Number below/right of division line + Bit 2-3 Palette Number above/left of division line + Bit 4-5 Palette Number for division line + Bit 6 H/V Mode Bit (0=split left/right, 1=split above/below) + 2 X- or Y-Coordinate (depending on H/V bit) + 3-F Not used (zero) + +SGB Command 07h - ATTR_CHR +Used to specify color attributes for separate characters. + Byte Content + 0 Command*8+Length (length=1..6) + 1 Beginning X-Coordinate + 2 Beginning Y-Coordinate + 3-4 Number of Data Sets (1-360) + 5 Writing Style (0=Left to Right, 1=Top to Bottom) + 6 Data Sets 1-4 (Set 1 in MSBs, Set 4 in LSBs) + 7 Data Sets 5-8 (if any) + 8 Data Sets 9-12 (if any) + etc. +When sending 41 or more data sets, data is continued in further packet(s). +Unused bytes at the end of the last packet should be set to zero. Each data +set consists of two bits, indicating the palette number for one character. +Depending on the writing style, data sets are written from left to right, or +from top to bottom. In either case the function wraps to the next row/column +when reaching the end of the screen. + +SGB Command 15h - ATTR_TRN +Used to initialize Attribute Files (ATFs) in SNES RAM. Each ATF consists of +20x18 color attributes for the gameboy screen. This function does not directly +affect display attributes. Instead, one of the defined ATFs may be copied to +actual display memory at a later time by using ATTR_SET or PAL_SET functions. + Byte Content + 0 Command*8+Length (fixed length=1) + 1-F Not used (zero) +The ATF data is sent by VRAM-Transfer (4 KBytes). + 000-FD1 Data for ATF0 through ATF44 (4050 bytes) + FD2-FFF Not used +Each ATF consists of 90 bytes, that are 5 bytes (20x2bits) for each of the 18 +character lines of the gameboy window. The two most significant bits of the +first byte define the color attribute (0-3) for the first character of the +first line, the next two bits the next character, and so on. + +SGB Command 16h - ATTR_SET +Used to transfer attributes from Attribute File (ATF) to gameboy window. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Attribute File Number (00-2Ch), Bit 6=Cancel Mask + 2-F Not used (zero) +When above Bit 6 is set, the gameboy screen becomes re-enabled after the +transfer (in case it has been disabled/frozen by MASK_EN command). +Note: The same functions may be (optionally) also included in PAL_SET +commands, as described in the chapter about Color Palette Commands. + +SGB Sound Functions +------------------- + +SGB Command 08h - SOUND +Used to start/stop internal sound effect, start/stop sound using internal tone +data. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Sound Effect A (Port 1) Decrescendo 8bit Sound Code + 2 Sound Effect B (Port 2) Sustain 8bit Sound Code + 3 Sound Effect Attributes + Bit 0-1 - Sound Effect A Pitch (0..3=Low..High) + Bit 2-3 - Sound Effect A Volume (0..2=High..Low, 3=Mute on) + Bit 4-5 - Sound Effect B Pitch (0..3=Low..High) + Bit 6-7 - Sound Effect B Volume (0..2=High..Low, 3=Not used) + 4 Music Score Code (must be zero if not used) + 5-F Not used (zero) +See Sound Effect Tables below for a list of available pre-defined effects. +"Notes" +1) Mute is only active when both bits D2 and D3 are 1. +2) When the volume is set for either Sound Effect A or Sound Effect B, mute is +turned off. +3) When Mute on/off has been executed, the sound fades out/fades in. +4) Mute on/off operates on the (BGM) which is reproduced by Sound Effect A, +Sound Effect B, and the Super NES APU. A "mute off" flag does not exist by +itself. When mute flag is set, volume and pitch of Sound Effect A (port 1) and +Sound Effect B (port 2) must be set. + +SGB Command 09h - SOU_TRN +Used to transfer sound code or data to SNES Audio Processing Unit memory +(APU-RAM). + Byte Content + 0 Command*8+Length (fixed length=1) + 1-F Not used (zero) +The sound code/data is sent by VRAM-Transfer (4 KBytes). + 000 One (or two ???) 16bit expression(s ???) indicating the + transfer destination address and transfer length. + ...-... Transfer Data + ...-FFF Remaining bytes not used +Possible destinations in APU-RAM are: + 0400h-2AFFh APU-RAM Program Area (9.75KBytes) + 2B00h-4AFFh APU-RAM Sound Score Area (8Kbytes) + 4DB0h-EEFFh APU-RAM Sampling Data Area (40.25 Kbytes) +This function may be used to take control of the SNES sound chip, and/or to +access the SNES MIDI engine. In either case it requires deeper knowledge of +SNES sound programming. + +SGB Sound Effect A/B Tables +Below lists the digital sound effects that are pre-defined in the SGB/SNES +BIOS, and which can be used with the SGB "SOUND" Command. +Effect A and B may be simultaneously reproduced. +The P-column indicates the recommended Pitch value, the V-column indicates the +numbers of Voices used. Sound Effect A uses voices 6,7. Sound Effect B uses +voices 0,1,4,5. Effects that use less voices will use only the upper voices +(eg. 4,5 for Effect B with only two voices). + +Sound Effect A Flag Table + Code Description P V Code Description P V + 00 Dummy flag, re-trigger - 2 18 Fast Jump 3 1 + 80 Effect A, stop/silent - 2 19 Jet (rocket) takeoff 0 1 + 01 Nintendo 3 1 1A Jet (rocket) landing 0 1 + 02 Game Over 3 2 1B Cup breaking 2 2 + 03 Drop 3 1 1C Glass breaking 1 2 + 04 OK ... A 3 2 1D Level UP 2 2 + 05 OK ... B 3 2 1E Insert air 1 1 + 06 Select...A 3 2 1F Sword swing 1 1 + 07 Select...B 3 1 20 Water falling 2 1 + 08 Select...C 2 2 21 Fire 1 1 + 09 Mistake...Buzzer 2 1 22 Wall collapsing 1 2 + 0A Catch Item 2 2 23 Cancel 1 2 + 0B Gate squeaks 1 time 2 2 24 Walking 1 2 + 0C Explosion...small 1 2 25 Blocking strike 1 2 + 0D Explosion...medium 1 2 26 Picture floats on & off 3 2 + 0E Explosion...large 1 2 27 Fade in 0 2 + 0F Attacked...A 3 1 28 Fade out 0 2 + 10 Attacked...B 3 2 29 Window being opened 1 2 + 11 Hit (punch)...A 0 2 2A Window being closed 0 2 + 12 Hit (punch)...B 0 2 2B Big Laser 3 2 + 13 Breath in air 3 2 2C Stone gate closes/opens 0 2 + 14 Rocket Projectile...A 3 2 2D Teleportation 3 1 + 15 Rocket Projectile...B 3 2 2E Lightning 0 2 + 16 Escaping Bubble 2 1 2F Earthquake 0 2 + 17 Jump 3 1 30 Small Laser 2 2 +Sound effect A is used for formanto sounds (percussion sounds). + +Sound Effect B Flag Table + Code Description P V Code Description P V + 00 Dummy flag, re-trigger - 4 0D Waterfall 2 2 + 80 Effect B, stop/silent - 4 0E Small character running 3 1 + 01 Applause...small group 2 1 0F Horse running 3 1 + 02 Applause...medium group 2 2 10 Warning sound 1 1 + 03 Applause...large group 2 4 11 Approaching car 0 1 + 04 Wind 1 2 12 Jet flying 1 1 + 05 Rain 1 1 13 UFO flying 2 1 + 06 Storm 1 3 14 Electromagnetic waves 0 1 + 07 Storm with wind/thunder 2 4 15 Score UP 3 1 + 08 Lightning 0 2 16 Fire 2 1 + 09 Earthquake 0 2 17 Camera shutter, formanto 3 4 + 0A Avalanche 0 2 18 Write, formanto 0 1 + 0B Wave 0 1 19 Show up title, formanto 0 1 + 0C River 3 2 +Sound effect B is mainly used for looping sounds (sustained sounds). + +SGB System Control Commands +--------------------------- + +SGB Command 17h - MASK_EN +Used to mask the gameboy window, among others this can be used to freeze the +gameboy screen before transferring data through VRAM (the SNES then keeps +displaying the gameboy screen, even though VRAM doesn't contain meaningful +display information during the transfer). + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Gameboy Screen Mask (0-3) + 0 Cancel Mask (Display activated) + 1 Freeze Screen (Keep displaying current picture) + 2 Blank Screen (Black) + 3 Blank Screen (Color 0) + 2-F Not used (zero) +Freezing works only if the SNES has stored a picture, ie. if necessary wait +one or two frames before freezing (rather than freezing directly after having +displayed the picture). +The Cancel Mask function may be also invoked (optionally) by completion of +PAL_SET and ATTR_SET commands. + +SGB Command 0Ch - ATRC_EN +Used to enable/disable Attraction mode. It is totally unclear what an +attraction mode is ???, but it is enabled by default. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Attraction Disable (0=Enable, 1=Disable) + 2-F Not used (zero) + +SGB Command 0Dh - TEST_EN +Used to enable/disable test mode for "SGB-CPU variable clock speed function". +This function is disabled by default. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Test Mode Enable (0=Disable, 1=Enable) + 2-F Not used (zero) +Maybe intended to determine whether SNES operates at 50Hz or 60Hz display +refresh rate ??? Possibly result can be read-out from joypad register ??? + +SGB Command 0Eh - ICON_EN +Used to enable/disable ICON function. Possibly meant to enable/disable +SGB/SNES popup menues which might otherwise activated during gameboy game +play. By default all functions are enabled (0). + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Disable Bits + Bit 0 - Use of SGB-Built-in Color Palettes (1=Disable) + Bit 1 - Controller Set-up Screen (0=Enable, 1=Disable) + Bit 2 - SGB Register File Transfer (0=Receive, 1=Disable) + Bit 3-6 - Not used (zero) + 2-F Not used (zero) +Above Bit 2 will suppress all further packets/commands when set, this might be +useful when starting a monochrome game from inside of the SGB-menu of a +multi-gamepak which contains a collection of different games. + +SGB Command 0Fh - DATA_SND +Used to write one or more bytes directly into SNES Work RAM. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 SNES Destination Address, low + 2 SNES Destination Address, high + 3 SNES Destination Address, bank number + 4 Number of bytes to write (01h-0Bh) + 5 Data Byte #1 + 6 Data Byte #2 (if any) + 7 Data Byte #3 (if any) + etc. +Unused bytes at the end of the packet should be set to zero, this function is +restricted to a single packet, so that not more than 11 bytes can be defined +at once. +Free Addresses in SNES memory are Bank 0 1800h-1FFFh, Bank 7Fh 0000h-FFFFh. + +SGB Command 10h - DATA_TRN +Used to transfer binary code or data directly into SNES RAM. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 SNES Destination Address, low + 2 SNES Destination Address, high + 3 SNES Destination Address, bank number + 4-F Not used (zero) +The data is sent by VRAM-Transfer (4 KBytes). + 000-FFF Data +Free Addresses in SNES memory are Bank 0 1800h-1FFFh, Bank 7Fh 0000h-FFFFh. +The transfer length is fixed at 4KBytes ???, so that directly writing to the +free 2KBytes at 0:1800h would be a not so good idea ??? + +SGB Command 12h - JUMP +Used to set the SNES program counter to a specified address. Optionally, it +may be used to set a new address for the SNES NMI handler, the NMI handler +remains unchanged if all bytes 4-6 are zero. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 SNES Program Counter, low + 2 SNES Program Counter, high + 3 SNES Program Counter, bank number + 4 SNES NMI Handler, low + 5 SNES NMI Handler, high + 6 SNES NMI Handler, bank number + 7-F Not used, zero +Note: The game "Space Invaders 94" uses this function when selecting "Arcade +mode" to execute SNES program code which has been previously transferred from +the SGB to the SNES. The type of the CPU which is used in the SNES is unknown +??? + +SGB Multiplayer Command +----------------------- + +SGB Command 11h - MLT_REQ +Used to request multiplayer mode (ie. input from more than one joypad). +Because this function provides feedback from the SGB/SNES to the gameboy +program, it is also used to detect SGB hardware. + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Multiplayer Control (0-3) (Bit0=Enable, Bit1=Two/Four Players) + 0 = One player + 1 = Two players + 3 = Four players + 2-F Not used (zero) +In one player mode, the second joypad (if any) is used for the SGB system +program. In two player mode, both joypads are used for the game. Because SNES +have only two joypad sockets, four player mode requires an external +"Multiplayer 5" adapter. + +Reading Multiple Controllers (Joypads) +When having enabled multiple controllers by MLT_REQ, data for each joypad can +be read out through JOYPAD register (FF00) as follows: First set P14 and P15 +both HIGH (deselect both Buttons and Cursor keys), you can now read the lower +4bits of FF00 which indicate the joypad ID for the following joypad input: + 0Fh Joypad 1 + 0Eh Joypad 2 + 0Dh Joypad 3 + 0Ch Joypad 4 +Next, set P14 and P15 low (one after each other) to select Buttons and Cursor +lines, and read-out joypad state as normally. When completed, set P14 and P15 +back HIGH, this automatically increments the joypad number (or restarts +counting once reached the lastmost joypad). Repeat the procedure until you +have read-out states for all two (or four) joypads. + +SGB Border and OBJ Commands +--------------------------- + +SGB Command 13h - CHR_TRN +Used to transfer tile data (characters) to SNES Tile memory in VRAM. This +normally used to define BG tiles for the SGB Border (see PCT_TRN), but might +be also used to define moveable SNES foreground sprites (see OBJ_TRN). + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Tile Transfer Destination + Bit 0 - Tile Numbers (0=Tiles 00h-7Fh, 1=Tiles 80h-FFh) + Bit 1 - Tile Type (0=BG Tiles, 1=OBJ Tiles) + Bit 2-7 - Not used (zero) + 2-F Not used (zero) +The tile data is sent by VRAM-Transfer (4 KBytes). + 000-FFF Bitmap data for 128 Tiles +Each tile occupies 16bytes (8x8 pixels, 16 colors each). +When intending to transfer more than 128 tiles, call this function twice (once +for tiles 00h-7Fh, and once for tiles 80h-FFh). Note: The BG/OBJ Bit seems to +have no effect and writes to the same VRAM addresses for both BG and OBJ ??? + +SGB Command 14h - PCT_TRN +Used to transfer tile map data and palette data to SNES BG Map memory in VRAM +to be used for the SGB border. The actual tiles must be separately transferred +by using the CHR_TRN function. + Byte Content + 0 Command*8+Length (fixed length=1) + 1-F Not used (zero) +The map data is sent by VRAM-Transfer (4 KBytes). + 000-7FF BG Map 32x32 Entries of 16bit each (2048 bytes) + 800-87F BG Palette Data (Palettes 4-7, each 16 colors of 16bits each) + 880-FFF Not used, don't care +Each BG Map Entry consists of a 16bit value as such: + Bit 0-9 - Character Number (use only 00h-FFh, upper 2 bits zero) + Bit 10-12 - Palette Number (use only 4-7, officially use only 4-6) + Bit 13 - BG Priority (use only 0) + Bit 14 - X-Flip (0=Normal, 1=Mirror horizontally) + Bit 15 - Y-Flip (0=Normal, 1=Mirror vertically) +Even though 32x32 map entries are transferred, only upper 32x28 are actually +used (256x224 pixels, SNES screen size). The 20x18 entries in the center of +the 32x28 area should be set to 0000h as transparent space for the gameboy +window to be displayed inside. Reportedly, non-transparent border data will +cover the gameboy window. + +SGB Command 18h - OBJ_TRN +Used to transfer OBJ attributes to SNES OAM memory. Unlike all other functions +with the ending _TRN, this function does not use the usual one-shot 4KBytes +VRAM transfer method. +Instead, when enabled (below execute bit set), data is permanently (each +frame) read out from the lower character line of the gameboy screen. To +suppress garbage on the display, the lower line is masked, and only the upper +20x17 characters of the gameboy window are used - the masking method is +unknwon - frozen, black, or recommended to be covered by the SGB border, or +else ??? Also, when the function is enabled, "system attract mode is not +performed" - whatever that means ??? + Byte Content + 0 Command*8+Length (fixed length=1) + 1 Control Bits + Bit 0 - SNES OBJ Mode enable (0=Cancel, 1=Enable) + Bit 1 - Change OBJ Color (0=No, 1=Use definitions below) + Bit 2-7 - Not used (zero) + 2-3 System Color Palette Number for OBJ Palette 4 (0-511) + 4-5 System Color Palette Number for OBJ Palette 5 (0-511) + 6-7 System Color Palette Number for OBJ Palette 6 (0-511) + 8-9 System Color Palette Number for OBJ Palette 7 (0-511) + These color entries are ignored if above Control Bit 1 is zero. + Because each OBJ palette consists of 16 colors, four system + palette entries (of 4 colors each) are transferred into each + OBJ palette. The system palette numbers are not required to be + aligned to a multiple of four, and will wrap to palette number + 0 when exceeding 511. For example, a value of 511 would copy + system palettes 511, 0, 1, 2 to the SNES OBJ palette. + A-F Not used (zero) +The recommended method is to "display" gameboy BG tiles F9h..FFh from left to +right as first 7 characters of the bottom-most character line of the gameboy +screen. As for normal 4KByte VRAM transfers, this area should not be scrolled, +should not be overlapped by gameboy OBJs, and the gameboy BGP palette register +should be set up properly. By following that method, SNES OAM data can be +defined in the 70h bytes of the gameboy BG tile memory at following addresses: + 8F90-8FEF SNES OAM, 24 Entries of 4 bytes each (96 bytes) + 8FF0-8FF5 SNES OAM MSBs, 24 Entries of 2 bits each (6 bytes) + 8FF6-8FFF Not used, don't care (10 bytes) +The format of SNES OAM Entries is: + Byte 0 OBJ X-Position (0-511, MSB is separately stored, see below) + Byte 1 OBJ Y-Position (0-255) + Byte 2-3 Attributes (16bit) + Bit 0-8 Tile Number (use only 00h-FFh, upper bit zero) + Bit 9-11 Palette Number (use only 4-7) + Bit 12-13 OBJ Priority (use only 3) + Bit 14 X-Flip (0=Normal, 1=Mirror horizontally) + Bit 15 Y-Flip (0=Normal, 1=Mirror vertically) +The format of SNES OAM MSB Entries is: + Actually, the format is unknown ??? However, 2 bits are used per entry: + One bit is the most significant bit of the OBJ X-Position. + The other bit specifies the OBJ size (8x8 or 16x16 pixels). + +CPU Registers and Flags +----------------------- + +Registers + 16bit Hi Lo Name/Function + AF A - Accumulator & Flags + BC B C BC + DE D E DE + HL H L HL + SP - - Stack Pointer + PC - - Program Counter/Pointer +As shown above, most registers can be accessed either as one 16bit register, +or as two separate 8bit registers. + +The Flag Register (lower 8bit of AF register) + Bit Name Set Clr Expl. + 7 zf Z NZ Zero Flag + 6 n - - Add/Sub-Flag (BCD) + 5 h - - Half Carry Flag (BCD) + 4 cy C NC Carry Flag + 3-0 - - - Not used (always zero) +Conatins the result from the recent instruction which has affected flags. + +The Zero Flag (Z) +This bit becomes set (1) if the result of an operation has been zero (0). Used +for conditional jumps. + +The Carry Flag (C, or Cy) +Becomes set when the result of an addition became bigger than FFh (8bit) or +FFFFh (16bit). Or when the result of a subtraction or comparision became less +than zero (much as for Z80 and 80x86 CPUs, but unlike as for 65XX and ARM +CPUs). Also the flag becomes set when a rotate/shift operation has shifted-out +a "1"-bit. +Used for conditional jumps, and for instructions such like ADC, SBC, RL, RLA, +etc. + +The BCD Flags (N, H) +These flags are (rarely) used for the DAA instruction only, N Indicates +whether the previous instruction has been an addition or subtraction, and H +indicates carry for lower 4bits of the result, also for DAA, the C flag must +indicate carry for upper 8bits. +After adding/subtracting two BCD numbers, DAA is intended to convert the +result into BCD format; BCD numbers are ranged from 00h to 99h rather than 00h +to FFh. +Because C and H flags must contain carry-outs for each digit, DAA cannot be +used for 16bit operations (which have 4 digits), or for INC/DEC operations +(which do not affect C-flag). + +CPU Instruction Set +------------------- + +Tables below specify the mnemonic, opcode bytes, clock cycles, affected flags +(ordered as znhc), and explanatation. +The timings assume a CPU clock frequency of 4.194304 MHz (or 8.4 +MHz for CGB in double speed mode), as all gameboy timings are divideable +by 4, many people specify timings and clock frequency divided by 4. + +GMB 8bit-Loadcommands + ld r,r xx 4 ---- r=r + ld r,n xx nn 8 ---- r=n + ld r,(HL) xx 8 ---- r=(HL) + ld (HL),r 7x 8 ---- (HL)=r + ld (HL),n 36 nn 12 ---- + ld A,(BC) 0A 8 ---- + ld A,(DE) 1A 8 ---- + ld A,(nn) FA 16 ---- + ld (BC),A 02 8 ---- + ld (DE),A 12 8 ---- + ld (nn),A EA 16 ---- + ld A,(FF00+n) F0 nn 12 ---- read from io-port n (memory FF00+n) + ld (FF00+n),A E0 nn 12 ---- write to io-port n (memory FF00+n) + ld A,(FF00+C) F2 8 ---- read from io-port C (memory FF00+C) + ld (FF00+C),A E2 8 ---- write to io-port C (memory FF00+C) + ldi (HL),A 22 8 ---- (HL)=A, HL=HL+1 + ldi A,(HL) 2A 8 ---- A=(HL), HL=HL+1 + ldd (HL),A 32 8 ---- (HL)=A, HL=HL-1 + ldd A,(HL) 3A 8 ---- A=(HL), HL=HL-1 + +GMB 16bit-Loadcommands + ld rr,nn x1 nn nn 12 ---- rr=nn (rr may be BC,DE,HL or SP) + ld SP,HL F9 8 ---- SP=HL + push rr x5 16 ---- SP=SP-2 (SP)=rr (rr may be +BC,DE,HL,AF) + pop rr x1 12 (AF) rr=(SP) SP=SP+2 (rr may be +BC,DE,HL,AF) + +GMB 8bit-Arithmetic/logical Commands + add A,r 8x 4 z0hc A=A+r + add A,n C6 nn 8 z0hc A=A+n + add A,(HL) 86 8 z0hc A=A+(HL) + adc A,r 8x 4 z0hc A=A+r+cy + adc A,n CE nn 8 z0hc A=A+n+cy + adc A,(HL) 8E 8 z0hc A=A+(HL)+cy + sub r 9x 4 z1hc A=A-r + sub n D6 nn 8 z1hc A=A-n + sub (HL) 96 8 z1hc A=A-(HL) + sbc A,r 9x 4 z1hc A=A-r-cy + sbc A,n DE nn 8 z1hc A=A-n-cy + sbc A,(HL) 9E 8 z1hc A=A-(HL)-cy + and r Ax 4 z010 A=A & r + and n E6 nn 8 z010 A=A & n + and (HL) A6 8 z010 A=A & (HL) + xor r Ax 4 z000 + xor n EE nn 8 z000 + xor (HL) AE 8 z000 + or r Bx 4 z000 A=A | r + or n F6 nn 8 z000 A=A | n + or (HL) B6 8 z000 A=A | (HL) + cp r Bx 4 z1hc compare A-r + cp n FE nn 8 z1hc compare A-n + cp (HL) BE 8 z1hc compare A-(HL) + inc r xx 4 z0h- r=r+1 + inc (HL) 34 12 z0h- (HL)=(HL)+1 + dec r xx 4 z1h- r=r-1 + dec (HL) 35 12 z1h- (HL)=(HL)-1 + daa 27 4 z-0x decimal adjust akku + cpl 2F 4 -11- A = A xor FF + +GMB 16bit-Arithmetic/logical Commands + add HL,rr x9 8 -0hc HL = HL+rr ;rr may be BC,DE,HL,SP + inc rr x3 8 ---- rr = rr+1 ;rr may be BC,DE,HL,SP + dec rr xB 8 ---- rr = rr-1 ;rr may be BC,DE,HL,SP + add SP,dd E8 16 00hc SP = SP +/- dd ;dd is 8bit signed number + ld HL,SP+dd F8 12 00hc HL = SP +/- dd ;dd is 8bit signed number + +GMB Rotate- und Shift-Commands + rlca 07 4 000c rotate akku left + rla 17 4 000c rotate akku left through carry + rrca 0F 4 000c rotate akku right + rra 1F 4 000c rotate akku right through carry + rlc r CB 0x 8 z00c rotate left + rlc (HL) CB 06 16 z00c rotate left + rl r CB 1x 8 z00c rotate left through carry + rl (HL) CB 16 16 z00c rotate left through carry + rrc r CB 0x 8 z00c rotate right + rrc (HL) CB 0E 16 z00c rotate right + rr r CB 1x 8 z00c rotate right through carry + rr (HL) CB 1E 16 z00c rotate right through carry + sla r CB 2x 8 z00c shift left arithmetic (b0=0) + sla (HL) CB 26 16 z00c shift left arithmetic (b0=0) + swap r CB 3x 8 z000 exchange low/hi-nibble + swap (HL) CB 36 16 z000 exchange low/hi-nibble + sra r CB 2x 8 z00c shift right arithmetic (b7=b7) + sra (HL) CB 2E 16 z00c shift right arithmetic (b7=b7) + srl r CB 3x 8 z00c shift right logical (b7=0) + srl (HL) CB 3E 16 z00c shift right logical (b7=0) + +GMB Singlebit Operation Commands + bit n,r CB xx 8 z01- test bit n + bit n,(HL) CB xx 12 z01- test bit n + set n,r CB xx 8 ---- set bit n + set n,(HL) CB xx 16 ---- set bit n + res n,r CB xx 8 ---- reset bit n + res n,(HL) CB xx 16 ---- reset bit n + +GMB CPU-Controlcommands + ccf 3F 4 -00c cy=cy xor 1 + scf 37 4 -001 cy=1 + nop 00 4 ---- no operation + halt 76 N*4 ---- halt until interrupt occurs (low power) + stop 10 00 ? ---- low power standby mode (VERY low power) + di F3 4 ---- disable interrupts, IME=0 + ei FB 4 ---- enable interrupts, IME=1 + +GMB Jumpcommands + jp nn C3 nn nn 16 ---- jump to nn, PC=nn + jp HL E9 4 ---- jump to HL, PC=HL + jp f,nn xx nn nn 16;12 ---- conditional jump if nz,z,nc,c + jr PC+dd 18 dd 12 ---- relative jump to nn (PC=PC+/-7bit) + jr f,PC+dd xx dd 12;8 ---- conditional relative jump if nz,z,nc,c + call nn CD nn nn 24 ---- call to nn, SP=SP-2, (SP)=PC, PC=nn + call f,nn xx nn nn 24;12 ---- conditional call if nz,z,nc,c + ret C9 16 ---- return, PC=(SP), SP=SP+2 + ret f xx 20;8 ---- conditional return if nz,z,nc,c + reti D9 16 ---- return and enable interrupts (IME=1) + rst n xx 16 ---- call to 00,08,10,18,20,28,30,38 + +CPU Comparision with Z80 +------------------------ + +Comparision with 8080 +Basically, the gameboy CPU works more like an older 8080 CPU rather than like +a more powerful Z80 CPU. It is, however, supporting CB-prefixed instructions. +Also, all known gameboy assemblers using the more obvious Z80-style syntax, +rather than the chaotic 8080-style syntax. + +Comparision with Z80 +Any DD-, ED-, and FD-prefixed instructions are missing, that means no IX-, +IY-registers, no block commands, and some other missing commands. +All exchange instructions have been removed (including total absence of second +register set), 16bit memory accesses are mostly missing, and 16bit arithmetic +functions are heavily cut-down. +The gameboy has no IN/OUT instructions, instead I/O ports are accessed +directly by normal LD instructions, or by special LD (FF00+n) opcodes. +The sign and parity/overflow flags have been removed. +The gameboy operates approximately as fast as a 4MHz Z80 (8MHz in CGB double +speed mode), execution time of all instructions has been rounded up to a +multiple of 4 cycles though. + +Moved, Removed, and Added Opcodes + Opcode Z80 GMB + --------------------------------------- + 08 EX AF,AF LD (nn),SP + 10 DJNZ PC+dd STOP + 22 LD (nn),HL LDI (HL),A + 2A LD HL,(nn) LDI A,(HL) + 32 LD (nn),A LDD (HL),A + 3A LD A,(nn) LDD A,(HL) + D3 OUT (n),A - + D9 EXX RETI + DB IN A,(n) - + DD - + E0 RET PO LD (FF00+n),A + E2 JP PO,nn LD (FF00+C),A + E3 EX (SP),HL - + E4 CALL P0,nn - + E8 RET PE ADD SP,dd + EA JP PE,nn LD (nn),A + EB EX DE,HL - + EC CALL PE,nn - + ED - + F0 RET P LD A,(FF00+n) + F2 JP P,nn LD A,(FF00+C) + F4 CALL P,nn - + F8 RET M LD HL,SP+dd + FA JP M,nn LD A,(nn) + FC CALL M,nn - + FD - + CB3X SLL r/(HL) SWAP r/(HL) +Note: The unused (-) opcodes will lock-up the gameboy CPU when used. + +The Cartridge Header +-------------------- + +An internal information area is located at 0100-014F in +each cartridge. It contains the following values: + +0100-0103 - Entry Point +After displaying the Nintendo Logo, the built-in boot procedure jumps to this +address (100h), which should then jump to the actual main program in the +cartridge. Usually this 4 byte area contains a NOP instruction, followed by a +JP 0150h instruction. But not always. + +0104-0133 - Nintendo Logo +These bytes define the bitmap of the Nintendo logo that is displayed when the +gameboy gets turned on. The hexdump of this bitmap is: + CE ED 66 66 CC 0D 00 0B 03 73 00 83 00 0C 00 0D + 00 08 11 1F 88 89 00 0E DC CC 6E E6 DD DD D9 99 + BB BB 67 63 6E 0E EC CC DD DC 99 9F BB B9 33 3E +The gameboys boot procedure verifies the content of this bitmap (after it has +displayed it), and LOCKS ITSELF UP if these bytes are incorrect. A CGB +verifies only the first 18h bytes of the bitmap, but others (for example a +pocket gameboy) verify all 30h bytes. + +0134-0143 - Title +Title of the game in UPPER CASE ASCII. If it is less than 16 characters then +the remaining bytes are filled with 00's. When inventing the CGB, Nintendo has +reduced the length of this area to 15 characters, and some months later they +had the fantastic idea to reduce it to 11 characters only. The new meaning of +the ex-title bytes is described below. + +013F-0142 - Manufacturer Code +In older cartridges this area has been part of the Title (see above), in newer +cartridges this area contains an 4 character uppercase manufacturer code. +Purpose and Deeper Meaning unknown. + +0143 - CGB Flag +In older cartridges this byte has been part of the Title (see above). In CGB +cartridges the upper bit is used to enable CGB functions. This is required, +otherwise the CGB switches itself into Non-CGB-Mode. Typical values are: + 80h - Game supports CGB functions, but works on old gameboys also. + C0h - Game works on CGB only (physically the same as 80h). +Values with Bit 7 set, and either Bit 2 or 3 set, will switch the gameboy into +a special non-CGB-mode with uninitialized palettes. Purpose unknown, +eventually this has been supposed to be used to colorize monochrome games that +include fixed palette data at a special location in ROM. + +0144-0145 - New Licensee Code +Specifies a two character ASCII licensee code, indicating the company or +publisher of the game. These two bytes are used in newer games only (games +that have been released after the SGB has been invented). Older games are +using the header entry at 014B instead. + +0146 - SGB Flag +Specifies whether the game supports SGB functions, common values are: + 00h = No SGB functions (Normal Gameboy or CGB only game) + 03h = Game supports SGB functions +The SGB disables its SGB functions if this byte is set to another value than +03h. + +0147 - Cartridge Type +Specifies which Memory Bank Controller (if any) is used in the cartridge, and +if further external hardware exists in the cartridge. + 00h ROM ONLY 13h MBC3+RAM+BATTERY + 01h MBC1 15h MBC4 + 02h MBC1+RAM 16h MBC4+RAM + 03h MBC1+RAM+BATTERY 17h MBC4+RAM+BATTERY + 05h MBC2 19h MBC5 + 06h MBC2+BATTERY 1Ah MBC5+RAM + 08h ROM+RAM 1Bh MBC5+RAM+BATTERY + 09h ROM+RAM+BATTERY 1Ch MBC5+RUMBLE + 0Bh MMM01 1Dh MBC5+RUMBLE+RAM + 0Ch MMM01+RAM 1Eh MBC5+RUMBLE+RAM+BATTERY + 0Dh MMM01+RAM+BATTERY FCh POCKET CAMERA + 0Fh MBC3+TIMER+BATTERY FDh BANDAI TAMA5 + 10h MBC3+TIMER+RAM+BATTERY FEh HuC3 + 11h MBC3 FFh HuC1+RAM+BATTERY + 12h MBC3+RAM + +0148 - ROM Size +Specifies the ROM Size of the cartridge. Typically calculated as "32KB shl N". + 00h - 32KByte (no ROM banking) + 01h - 64KByte (4 banks) + 02h - 128KByte (8 banks) + 03h - 256KByte (16 banks) + 04h - 512KByte (32 banks) + 05h - 1MByte (64 banks) - only 63 banks used by MBC1 + 06h - 2MByte (128 banks) - only 125 banks used by MBC1 + 07h - 4MByte (256 banks) + 52h - 1.1MByte (72 banks) + 53h - 1.2MByte (80 banks) + 54h - 1.5MByte (96 banks) + +0149 - RAM Size +Specifies the size of the external RAM in the cartridge (if any). + 00h - None + 01h - 2 KBytes + 02h - 8 Kbytes + 03h - 32 KBytes (4 banks of 8KBytes each) +When using a MBC2 chip 00h must be specified in this entry, even though the +MBC2 includes a built-in RAM of 512 x 4 bits. + +014A - Destination Code +Specifies if this version of the game is supposed to be sold in japan, or +anywhere else. Only two values are defined. + 00h - Japanese + 01h - Non-Japanese + +014B - Old Licensee Code +Specifies the games company/publisher code in range 00-FFh. A value of 33h +signalizes that the New License Code in header bytes 0144-0145 is used +instead. +(Super GameBoy functions won't work if <> $33.) + +014C - Mask ROM Version number +Specifies the version number of the game. That is usually 00h. + +014D - Header Checksum +Contains an 8 bit checksum across the cartridge header bytes 0134-014C. The +checksum is calculated as follows: + x=0:FOR i=0134h TO 014Ch:x=x-MEM[i]-1:NEXT +The lower 8 bits of the result must be the same than the value in this entry. +The GAME WON'T WORK if this checksum is incorrect. + +014E-014F - Global Checksum +Contains a 16 bit checksum (upper byte first) across the whole cartridge ROM. +Produced by adding all bytes of the cartridge (except for the two checksum +bytes). The Gameboy doesn't verify this checksum. + +Memory Bank Controllers +----------------------- + +As the gameboys 16 bit address bus offers only limited space for ROM and RAM +addressing, many games are using Memory Bank Controllers (MBCs) to expand the +available address space by bank switching. These MBC chips are located in the +game cartridge (ie. not in the gameboy itself), several different MBC types +are available: + +--> None (32KByte ROM only) +--> MBC1 (max 2MByte ROM and/or 32KByte RAM) +--> MBC2 (max 256KByte ROM and 512x4 bits RAM) +--> MBC3 (max 2MByte ROM and/or 32KByte RAM and Timer) +--> HuC1 (MBC with Infrared Controller) + +--> MBC Timing Issues + +In each cartridge, the required (or preferred) MBC type should be specified in +byte at 0147h of the ROM. (As described in the chapter about The Cartridge +Header.) + +None (32KByte ROM only) +----------------------- + +Small games of not more than 32KBytes ROM do not require a MBC chip for ROM +banking. The ROM is directly mapped to memory at 0000-7FFFh. Optionally up to +8KByte of RAM could be connected at A000-BFFF, even though that could require +a tiny MBC-like circuit, but no real MBC chip. + +MBC1 (max 2MByte ROM and/or 32KByte RAM) +---------------------------------------- + +This is the first MBC chip for the gameboy. Any newer MBC chips are working +similiar, so that is relative easy to upgrade a program from one MBC chip to +another - or even to make it compatible to several different types of MBCs. + +Note that the memory in range 0000-7FFF is used for both reading from ROM, and +for writing to the MBCs Control Registers. + +0000-3FFF - ROM Bank 00 (Read Only) +This area always contains the first 16KBytes of the cartridge ROM. + +4000-7FFF - ROM Bank 01-7F (Read Only) +This area may contain any of the further 16KByte banks of the ROM, allowing to +address up to 125 ROM Banks (almost 2MByte). As described below, bank numbers +20h, 40h, and 60h cannot be used, resulting in the odd amount of 125 banks. + +A000-BFFF - RAM Bank 00-03, if any (Read/Write) +This area is used to address external RAM in the cartridge (if any). External +RAM is often battery buffered, allowing to store game positions or high score +tables, even if the gameboy is turned off, or if the cartridge is removed from +the gameboy. Available RAM sizes are: 2KByte (at A000-A7FF), 8KByte (at +A000-BFFF), and 32KByte (in form of four 8K banks at A000-BFFF). + +0000-1FFF - RAM Enable (Write Only) +Before external RAM can be read or written, it must be enabled by writing to +this address space. It is recommended to disable external RAM after accessing +it, in order to protect its contents from damage during power down of the +gameboy. Usually the following values are used: + 00h Disable RAM (default) + 0Ah Enable RAM +Practically any value with 0Ah in the lower 4 bits enables RAM, and any other +value disables RAM. + +2000-3FFF - ROM Bank Number (Write Only) +Writing to this address space selects the lower 5 bits of the ROM Bank Number +(in range 01-1Fh). When 00h is written, the MBC translates that to bank 01h +also. That doesn't harm so far, because ROM Bank 00h can be always directly +accessed by reading from 0000-3FFF. +But (when using the register below to specify the upper ROM Bank bits), the +same happens for Bank 20h, 40h, and 60h. Any attempt to address these ROM +Banks will select Bank 21h, 41h, and 61h instead. + +4000-5FFF - RAM Bank Number - or - Upper Bits of ROM Bank Number (Write Only) +This 2bit register can be used to select a RAM Bank in range from 00-03h, or +to specify the upper two bits (Bit 5-6) of the ROM Bank number, depending on +the current ROM/RAM Mode. (See below.) + +6000-7FFF - ROM/RAM Mode Select (Write Only) +This 1bit Register selects whether the two bits of the above register should +be used as upper two bits of the ROM Bank, or as RAM Bank Number. + 00h = ROM Banking Mode (up to 8KByte RAM, 2MByte ROM) (default) + 01h = RAM Banking Mode (up to 32KByte RAM, 512KByte ROM) +The program may freely switch between both modes, the only limitiation is that +only RAM Bank 00h can be used during Mode 0, and only ROM Banks 00-1Fh can be +used during Mode 1. + +MBC2 (max 256KByte ROM and 512x4 bits RAM) +------------------------------------------ + +0000-3FFF - ROM Bank 00 (Read Only) +Same as for MBC1. + +4000-7FFF - ROM Bank 01-0F (Read Only) +Same as for MBC1, but only a total of 16 ROM banks is supported. + +A000-A1FF - 512x4bits RAM, built-in into the MBC2 chip (Read/Write) +The MBC2 doesn't support external RAM, instead it includes 512x4 bits of +built-in RAM (in the MBC2 chip itself). It still requires an external battery +to save data during power-off though. +As the data consists of 4bit values, only the lower 4 bits of the "bytes" in +this memory area are used. + +0000-1FFF - RAM Enable (Write Only) +The least significant bit of the upper address byte must be zero to +enable/disable cart RAM. For example the following addresses can be used to +enable/disable cart RAM: 0000-00FF, 0200-02FF, 0400-04FF, ..., 1E00-1EFF. +The suggested address range to use for MBC2 ram enable/disable is 0000-00FF. + +2000-3FFF - ROM Bank Number (Write Only) +Writing a value (XXXXBBBB - X = Don't cares, B = bank select bits) into +2000-3FFF area will select an appropriate ROM bank at 4000-7FFF. + +The least significant bit of the upper address byte must be one to select a +ROM bank. For example the following addresses can be used to select a ROM +bank: 2100-21FF, 2300-23FF, 2500-25FF, ..., 3F00-3FFF. +The suggested address range to use for MBC2 rom bank selection is 2100-21FF. + +MBC3 (max 2MByte ROM and/or 32KByte RAM and Timer) +-------------------------------------------------- + +Beside for the ability to access up to 2MB ROM (128 banks), and 32KB RAM (4 +banks), the MBC3 also includes a built-in Real Time Clock (RTC). The RTC +requires an external 32.768 kHz Quartz Oscillator, and an external battery (if +it should continue to tick when the gameboy is turned off). + +0000-3FFF - ROM Bank 00 (Read Only) +Same as for MBC1. + +4000-7FFF - ROM Bank 01-7F (Read Only) +Same as for MBC1, except that accessing banks 20h, 40h, and 60h is supported +now. + +A000-BFFF - RAM Bank 00-03, if any (Read/Write) +A000-BFFF - RTC Register 08-0C (Read/Write) +Depending on the current Bank Number/RTC Register selection (see below), this +memory space is used to access an 8KByte external RAM Bank, or a single RTC +Register. + +0000-1FFF - RAM and Timer Enable (Write Only) +Mostly the same as for MBC1, a value of 0Ah will enable reading and writing to +external RAM - and to the RTC Registers! A value of 00h will disable either. + +2000-3FFF - ROM Bank Number (Write Only) +Same as for MBC1, except that the whole 7 bits of the RAM Bank Number are +written directly to this address. As for the MBC1, writing a value of 00h, +will select Bank 01h instead. All other values 01-7Fh select the corresponding +ROM Banks. + +4000-5FFF - RAM Bank Number - or - RTC Register Select (Write Only) +As for the MBC1s RAM Banking Mode, writing a value in range for 00h-03h maps +the corresponding external RAM Bank (if any) into memory at A000-BFFF. +When writing a value of 08h-0Ch, this will map the corresponding RTC register +into memory at A000-BFFF. That register could then be read/written by +accessing any address in that area, typically that is done by using address +A000. + +6000-7FFF - Latch Clock Data (Write Only) +When writing 00h, and then 01h to this register, the current time becomes +latched into the RTC registers. The latched data will not change until it +becomes latched again, by repeating the write 00h->01h procedure. +This is supposed for from the RTC registers. It is proof to read the +latched (frozen) time from the RTC registers, while the clock itself continues +to tick in background. + +The Clock Counter Registers + 08h RTC S Seconds 0-59 (0-3Bh) + 09h RTC M Minutes 0-59 (0-3Bh) + 0Ah RTC H Hours 0-23 (0-17h) + 0Bh RTC DL Lower 8 bits of Day Counter (0-FFh) + 0Ch RTC DH Upper 1 bit of Day Counter, Carry Bit, Halt Flag + Bit 0 Most significant bit of Day Counter (Bit 8) + Bit 6 Halt (0=Active, 1=Stop Timer) + Bit 7 Day Counter Carry Bit (1=Counter Overflow) +The Halt Flag is supposed to be set before to the RTC Registers. + +The Day Counter +The total 9 bits of the Day Counter allow to count days in range from 0-511 +(0-1FFh). The Day Counter Carry Bit becomes set when this value overflows. In +that case the Carry Bit remains set until the program does reset it. +Note that you can store an offset to the Day Counter in battery RAM. For +example, every time you read a non-zero Day Counter, add this Counter to the +offset in RAM, and reset the Counter to zero. This method allows to count any +number of days, making your program Year-10000-Proof, provided that the +cartridge gets used at least every 511 days. + +Delays +When accessing the RTC Registers it is recommended to execute a 4ms delay (4 +Cycles in Normal Speed Mode) between the separate accesses. + +HuC1 (MBC with Infrared Controller) +------------------------------------ + +This controller (made by Hudson Soft) appears to be very similar to an MBC1 +with the main difference being that it supports infrared LED input / output. +(Similiar to the infrared port that has been later invented in CGBs.) + +The Japanese cart "Fighting Phoenix" (internal cart name: SUPER B DAMAN) is +known to contain this chip. + +MBC Timing Issues +----------------- + +Using MBCs with CGB Double Speed Mode +The MBC5 has been designed to support CGB Double Speed Mode. +There have been rumours that older MBCs (like MBC1-3) wouldn't be fast enough +in that mode. If so, it might be nethertheless possible to use Double Speed +during periods which use only code and data which is located in internal RAM. +However, despite of the above, my own good old selfmade MBC1-EPROM card +appears to work stable and fine even in Double Speed Mode though. + +Gamegenie/Shark Cheats +---------------------- + +Game Shark and Gamegenie are external cartridge adapters that can be plugged +between the gameboy and the actual game cartridge. Hexadecimal codes can be +then entered for specific games, typically providing things like Infinite Sex, +255 Cigarettes, or Starting directly in Wonderland Level PRO, etc. + +Gamegenie (ROM patches) +Gamegenie codes consist of nine-digit hex numbers, formatted as ABC-DEF-GHI, +the meaning of the separate digits is: + AB New data + FCDE Memory address, XORed by 0F000h + GI Old data, XORed by 0BAh and rotated left by two + H Don't know, maybe checksum and/or else +The address should be located in ROM area 0000h-7FFFh, the adapter permanently +compares address/old data with address/data being read by the game, and +replaces that data by new data if necessary. That method (more or less) +prohibits unwanted patching of wrong memory banks. Eventually it is also +possible to patch external RAM ? +Newer devices reportedly allow to specify only the first six digits +(optionally). As far as I rememeber, around three or four codes can be used +simultaneously. + +Game Shark (RAM patches) +Game Shark codes consist of eight-digit hex numbers, formatted as ABCDEFGH, +the meaning of the separate digits is: + AB External RAM bank number + CD New Data + GHEF Memory Address (internal or external RAM, A000-DFFF) +As far as I understand, patching is implement by hooking the original VBlank +interrupt handler, and re-writing RAM values each frame. The downside is that +this method steals some CPU time, also, it cannot be used to patch program +code in ROM. +As far as I rememeber, somewhat 10-25 codes can be used simultaneously. + +Power Up Sequence +----------------- + +When the GameBoy is powered up, a 256 byte program starting at memory location +0 is executed. This program is located in a ROM inside the GameBoy. The first +thing the program does is read the cartridge locations from $104 to $133 and +place this graphic of a Nintendo logo on the screen at the top. This image is +then scrolled until it is in the middle of the screen. Two musical notes are +then played on the internal speaker. Again, the cartridge locations $104 to +$133 are read but this time they are compared with a table in the internal +rom. If any byte fails to compare, then the GameBoy stops comparing bytes and +simply halts all operations. If all locations compare the same, then the +GameBoy starts adding all of the bytes in the cartridge from $134 to $14d. A +value of 25 decimal is added to this total. If the least significant byte of +the result is a not a zero, then the GameBoy will stop doing anything. If it +is a zero, then the internal ROM is disabled and cartridge program execution +begins at location $100 with the following register values: + + AF=$01B0 + BC=$0013 + DE=$00D8 + HL=$014D + Stack Pointer=$FFFE + [$FF05] = $00 ; TIMA + [$FF06] = $00 ; TMA + [$FF07] = $00 ; TAC + [$FF10] = $80 ; NR10 + [$FF11] = $BF ; NR11 + [$FF12] = $F3 ; NR12 + [$FF14] = $BF ; NR14 + [$FF16] = $3F ; NR21 + [$FF17] = $00 ; NR22 + [$FF19] = $BF ; NR24 + [$FF1A] = $7F ; NR30 + [$FF1B] = $FF ; NR31 + [$FF1C] = $9F ; NR32 + [$FF1E] = $BF ; NR33 + [$FF20] = $FF ; NR41 + [$FF21] = $00 ; NR42 + [$FF22] = $00 ; NR43 + [$FF23] = $BF ; NR30 + [$FF24] = $77 ; NR50 + [$FF25] = $F3 ; NR51 + [$FF26] = $F1-GB, $F0-SGB ; NR52 + [$FF40] = $91 ; LCDC + [$FF42] = $00 ; SCY + [$FF43] = $00 ; SCX + [$FF45] = $00 ; LYC + [$FF47] = $FC ; BGP + [$FF48] = $FF ; OBP0 + [$FF49] = $FF ; OBP1 + [$FF4A] = $00 ; WY + [$FF4B] = $00 ; WX + [$FFFF] = $00 ; IE + +It is not a good idea to assume the above values will always exist. A later +version GameBoy could contain different values than these at reset. Always set +these registers on reset rather than assume they are as above. + +Please note that GameBoy internal RAM on power up contains random data. All of +the GameBoy emulators tend to set all RAM to value $00 on entry. + +Cart RAM the first time it is accessed on a real GameBoy contains random data. +It will only contain known data if the GameBoy code initializes it to some +value. + +Reducing Power Consumption +-------------------------- + +The following can be used to recude the power consumption of the gameboy, and +to extend the life of the batteries. + +--> PWR Using the HALT Instruction +--> PWR Using the STOP Instruction +--> PWR Disabeling the Sound Controller +--> PWR Not using CGB Double Speed Mode +--> PWR Using the Skills + +PWR Using the HALT Instruction +------------------------------ + +It is recommended that the HALT instruction be used whenever possible to +reduce power consumption & extend the life of the batteries. This command +stops the system clock reducing the power consumption of both the CPU and ROM. + +The CPU will remain suspended until an interrupt occurs at which point the +interrupt is serviced and then the instruction immediately following the HALT +is executed. + +Depending on how much CPU time is required by a game, the HALT instruction can +extend battery life anywhere from 5 to 50% or possibly more. + +When waiting for a vblank event, this would be a BAD example: + @@wait: + ld a,(0FF44h) ;LY + cp a,144 + jr nz,@@wait + +A better example would be a procedure as shown below. In this case the vblank +interrupt must be enabled, and your vblank interrupt procedure must set +vblank_flag to a non-zero value. + ld hl,vblank_flag ;hl=pointer to vblank_flag + xor a ;a=0 + @@wait: ;wait... + halt ;suspend CPU - wait for ANY interrupt + cp a,(hl) ;vblank flag still zero? + jr z,@@wait ;wait more if zero + ld (hl),a ;set vblank_flag back to zero +The vblank_flag is used to determine whether the HALT period has been +terminated by a vblank interrupt, or by another interrupt. In case that your +program has all other interrupts disabled, then it would be proof to replace +the above procedure by a single HALT instruction. + +PWR Using the STOP Instruction +------------------------------ + +The STOP instruction is intended to switch the gameboy into VERY low power +standby mode. For example, a program may use this feature when it hasn't +sensed keyboard input for a longer period (assuming that somebody forgot to +turn off the gameboy). + +Before invoking STOP, it might be required to disable Sound and Video manually +(as well as IR-link port in CGB). Much like HALT, the STOP state is terminated +by interrupt events - in this case this would be commonly a joypad interrupt. +The joypad register might be required to be prepared for STOP either. + +PWR Disabeling the Sound Controller +----------------------------------- + +If your programs doesn't use sound at all (or during some periods) then write +00h to register FF26 to save 16% or more on GB power consumption. +Sound can be turned back on by writing 80h to the same register, all sound +registers must be then re-initialized. +When the gameboy becomes turned on, sound is enabled by default, and must be +turned off manually when not used. + +PWR Not using CGB Double Speed Mode +----------------------------------- + +Because CGB Double Speed mode consumes more power, it'd be recommended to use +normal speed when possible. +There's limited ability to switch between both speeds, for example, a game +might use normal speed in the title screen, and double speed in the game, or +vice versa. +However, during speed switch the display collapses for a short moment, so that +it'd be no good idea to alter speeds within active game or title screen +periods. + +PWR Using the Skills +-------------------- + +Most of the above power saving methods will produce best results when using +efficient and tight assembler code which requires as less CPU power as +possible. Thus, experienced old-school programmers will (hopefully) produce +lower power consumption, as than HLL-programming teenagers, for example. + +Sprite RAM Bug +-------------- + +There is a flaw in the GameBoy hardware that causes trash to be written to OAM +RAM if the following commands are used while their 16-bit content is in the +range of $FE00 to $FEFF: + inc rr dec rr ;rr = bc,de, or hl + ldi a,(hl) ldd a,(hl) + ldi (hl),a ldd (hl),a +Only sprites 1 & 2 ($FE00 & $FE04) are not affected by these instructions. + +External Connectors +------------------- + +Cartridge Slot + Pin Name Expl. + 1 VDD Power Supply +5V DC + 2 PHI System Clock + 3 /WR Write + 4 /RD Read + 5 /CS Chip Select + 6-21 A0-A15 Address Lines + 22-29 D0-D7 Data Lines + 30 /RES Reset signal + 31 VIN External Sound Input + 32 GND Ground + +Link Port +Pin numbers are arranged as 2,4,6 in upper row, 1,3,5 un lower row; outside +view of gameboy socket; flat side of socket upside. +Colors as used in most or all standard link cables, because SIN and SOUT are +crossed, colors Red and Orange are exchanged at one cable end. + Pin Name Color Expl. + 1 VCC - +5V DC + 2 SOUT red Data Out + 3 SIN orange Data In + 4 P14 - Not used + 5 SCK green Shift Clock + 6 GND blue Ground +Note: The original gameboy used larger plugs (unlike pocket gameboys and +newer), linking between older/newer gameboys is possible by using cables with +one large and one small plug though. + +Stereo Sound Connector (3.5mm, female) + Pin Expl. + Tip Sound Left + Middle Sound Right + Base Ground + +External Power Supply +... + + +END + \ No newline at end of file diff --git a/gbcore.cc b/gbcore.cc new file mode 100644 index 0000000..9ef4baa --- /dev/null +++ b/gbcore.cc @@ -0,0 +1,618 @@ +#include "gbcore.h" + +#include "sized_types.h" +#include "gbrom.h" +#include +#include + +class GameBoy +{ + u8 memory[65536]; + GBRom *rom; + + enum flags_enum + { + ZERO_FLAG=0x80, + ADD_SUB_FLAG=0x40, + HALF_CARRY_FLAG=0x20, + CARRY_FLAG=0x10, + }; + + // CPU Registers + // ENDIANNESS WARNING! + struct + { + union + { + u16 AF; + struct { u8 flags; u8 A; }; + }; + union + { + u16 BC; + struct { u8 C; u8 B; }; + }; + union + { + u16 DE; + struct { u8 E; u8 D; }; + }; + union + { + u16 HL; + struct { u8 L; u8 H; }; + }; + u16 SP; + u16 PC; + + } __attribute__((packed)) regs; + + void set_flag(const u8 f) { regs.flags |= f; } + void reset_flag(const u8 f) { regs.flags &= (~f); } + + public: + GameBoy(std::string rom_name); + + void reset(); + void run_cycle(); + void run(); + +}; + +GameBoy::GameBoy(std::string rom_name): + rom(0), regs() +{ + rom = read_gbrom(rom_name); + reset(); +} + +void GameBoy::reset() +{ + std::memcpy(memory, rom->data, 16384); + regs.PC = 0x100; +} + + +void GameBoy::run_cycle() +{ + int prefix; + int opcode; + opcode = memory[regs.PC++]; + if (opcode == 0xCB) + { + prefix=opcode; + opcode=memory[regs.PC++]; + } + + switch(opcode) + { + // LD n, nn + case 0x76: // LD A,n + regs.A = memory[regs.PC++]; + break; + case 0x06: // LD B,n + regs.B = memory[regs.PC++]; + break; + case 0x0E: // LD C,n + regs.C = memory[regs.PC++]; + break; + case 0x16: // LD D,n + regs.D = memory[regs.PC++]; + break; + case 0x1E: // LD E,n + regs.E = memory[regs.PC++]; + break; + case 0x26: // LD H,n + regs.H = memory[regs.PC++]; + break; + case 0x2E: // LD L,n + regs.L = memory[regs.PC++]; + break; + + // LD r1,r2 + case 0x7F: // LD A,A + regs.A = regs.A; + break; + case 0x78: // LD A,B + regs.A = regs.B; + break; + case 0x79: // LD A,C + regs.A = regs.C; + break; + case 0x7A: // LD A,D + regs.A = regs.D; + break; + case 0x7B: // LD A,E + regs.A = regs.E; + break; + case 0x7C: // LD A,H + regs.A = regs.H; + break; + case 0x7D: // LD A,L + regs.A = regs.L; + break; + case 0x7E: // LD A,(HL) + regs.A = memory[regs.HL]; + break; + + case 0x47: // LD B,A + regs.B = regs.A; + break; + case 0x40: // LD B,B + regs.B = regs.B; + break; + case 0x41: // LD B,C + regs.B = regs.C; + break; + case 0x42: // LD B,D + regs.B = regs.D; + break; + case 0x43: // LD B,E + regs.B = regs.E; + break; + case 0x44: // LD B,H + regs.B = regs.H; + break; + case 0x45: // LD B,L + regs.B = regs.L; + break; + case 0x46: // LD B,(HL) + regs.B = memory[regs.HL]; + break; + + case 0x4F: // LD C,A + regs.C = regs.A; + break; + case 0x48: // LD C,B + regs.C = regs.B; + break; + case 0x49: // LD C,C + regs.C = regs.C; + break; + case 0x4A: // LD C,D + regs.C = regs.D; + break; + case 0x4B: // LD C,E + regs.C = regs.E; + break; + case 0x4C: // LD C,H + regs.C = regs.H; + break; + case 0x4D: // LD C,L + regs.C = regs.L; + break; + case 0x4E: // LD C,(HL) + regs.C = memory[regs.HL]; + break; + + case 0x57: // LD D,A + regs.D = regs.A; + break; + case 0x50: // LD D,B + regs.D = regs.B; + break; + case 0x51: // LD D,C + regs.D = regs.C; + break; + case 0x52: // LD D,D + regs.D = regs.D; + break; + case 0x53: // LD D,E + regs.D = regs.E; + break; + case 0x54: // LD D,H + regs.D = regs.H; + break; + case 0x55: // LD D,L + regs.D = regs.L; + break; + case 0x56: // LD D,(HL) + regs.D = memory[regs.HL]; + break; + + case 0x5F: // LD E,A + regs.E = regs.A; + break; + case 0x58: // LD E,B + regs.E = regs.D; + break; + case 0x59: // LD E,C + regs.E = regs.C; + break; + case 0x5A: // LD E,D + regs.E = regs.D; + break; + case 0x5B: // LD E,E + regs.E = regs.E; + break; + case 0x5C: // LD E,H + regs.E = regs.H; + break; + case 0x5D: // LD E,L + regs.E = regs.L; + break; + case 0x5E: // LD E,(HL) + regs.E = memory[regs.HL]; + break; + + case 0x67: // LD H,A + regs.H = regs.A; + break; + case 0x60: // LD H,B + regs.H = regs.B; + break; + case 0x61: // LD H,C + regs.H = regs.C; + break; + case 0x62: // LD H,D + regs.H = regs.D; + break; + case 0x63: // LD H,E + regs.H = regs.E; + break; + case 0x64: // LD H,H + regs.H = regs.H; + break; + case 0x65: // LD H,L + regs.H = regs.L; + break; + case 0x66: // LD H,(HL) + regs.H = memory[regs.HL]; + break; + + case 0x6F: // LD L,A + regs.L = regs.A; + break; + case 0x68: // LD L,B + regs.L = regs.D; + break; + case 0x69: // LD L,C + regs.L = regs.C; + break; + case 0x6A: // LD L,D + regs.L = regs.D; + break; + case 0x6B: // LD L,E + regs.L = regs.E; + break; + case 0x6C: // LD L,H + regs.L = regs.H; + break; + case 0x6D: // LD L,L + regs.L = regs.L; + break; + case 0x6E: // LD L,(HL) + regs.L = memory[regs.HL]; + break; + + case 0x77: // LD (HL),A + memory[regs.HL] = regs.A; + break; + case 0x70: // LD (HL),B + memory[regs.HL] = regs.B; + break; + case 0x71: // LD (HL),C + memory[regs.HL] = regs.C; + break; + case 0x72: // LD (HL),D + memory[regs.HL] = regs.D; + break; + case 0x73: // LD (HL),E + memory[regs.HL] = regs.E; + break; + case 0x74: // LD (HL),H + memory[regs.HL] = regs.H; + break; + case 0x75: // LD (HL),L + memory[regs.HL] = regs.L; + break; + case 0x36: // LD (HL), n + memory[regs.HL] = memory[regs.PC++]; + break; + + // LD A, n + case 0x0A: // LD A, (BC) + regs.A = memory[regs.BC]; + break; + case 0x1A: // LD A, (DE) + regs.A = memory[regs.DE]; + break; + case 0xFA: // LD A, (nn) + regs.A = memory[memory[regs.PC] + memory[regs.PC+1]<<8]; + regs.PC+=2; + break; + + // LD n, A + case 0x02: // LD (BC), A + memory[regs.BC] = regs.A; + break; + case 0x12: // LD (DE), A + memory[regs.DE] = regs.A; + break; + case 0xEA: // LD (nn), A + memory[memory[regs.PC] + memory[regs.PC+1]<<8] = regs.A; + break; + + // LD A, (C) + case 0xF2: + regs.A = memory[0xFF00 + regs.C]; + break; + // LD (C), A + case 0xE2: + memory[0xFF00 + regs.C] = regs.A; + break; + + // LD A, (HLD); LD A, (HL-); LDD A,(HL); + case 0x3A: + regs.A = memory[regs.HL]; + --regs.HL; + break; + // LD (HLD), A; LD (HL-), A; LDD (HL), A; + case 0x32: + memory[regs.HL] = regs.A; + --regs.HL; + break; + // LD A, (HLI); LD A, (HL+); LDI A, (HL); + case 0x2A: + regs.A = memory[regs.HL]; + ++regs.HL; + break; + // LD (HLI), A; LD (HL+), A; LDI (HL), A; + case 0x22: + memory[regs.HL] = regs.A; + ++regs.HL; + break; + + // LDH (n), A + case 0xE0: + memory[0xFF00 + regs.PC++] = regs.A; + break; + // LDH A, (n) + case 0xF0: + regs.A = memory[0xFF00 + regs.PC++]; + break; + + // LD n, nn + case 0x01: // LD BC, nn + regs.BC = memory[regs.PC]+(memory[regs.PC+1] << 8); + regs.PC +=2; + break; + case 0x11: // LD DE, nn + regs.DE = memory[regs.PC]+(memory[regs.PC+1] << 8); + regs.PC +=2; + break; + case 0x21: // LD HL, nn + regs.HL = memory[regs.PC]+(memory[regs.PC+1] << 8); + regs.PC +=2; + break; + case 0x31: // LD SP, nn + regs.SP = memory[regs.PC]+(memory[regs.PC+1] << 8); + regs.PC +=2; + break; + + // LD SP, HL + case 0xF9: + regs.SP = regs.HL; + break; + + // LD HL, SP+n + // LDHL SP, n + case 0xF8: { + s8 offset = *(reinterpret_cast(memory+regs.PC++)); + int res = regs.SP + offset; + + // TODO: Verificar si los flags van asi + if (res > 0xFFFF) set_flag(CARRY_FLAG); + else reset_flag(CARRY_FLAG); + + // TODO: hacer lo apropiado con el half-carry flag + reset_flag(ADD_SUB_FLAG); + reset_flag(ZERO_FLAG); + + regs.HL = static_cast(res & 0xFFFF); + break; + } + + // LD (nn), SP + case 0x08: { + int addr = memory[regs.PC] + memory[regs.PC+1] << 8; + regs.PC += 2; + memory[addr] = regs.SP; + break; + } + + // PUSH nn + case 0xF5: // push AF + memory[regs.SP-1] = regs.A; + memory[regs.SP-2] = regs.flags; + regs.SP -= 2; + break; + case 0xC5: // push BC + memory[regs.SP-1] = regs.B; + memory[regs.SP-2] = regs.C; + regs.SP -= 2; + break; + case 0xD5: // push DE + memory[regs.SP-1] = regs.D; + memory[regs.SP-2] = regs.E; + regs.SP -= 2; + break; + case 0xE5: // push HL + memory[regs.SP-1] = regs.H; + memory[regs.SP-2] = regs.L; + regs.SP -= 2; + break; + + // POP nn + case 0xF1: // pop AF + regs.flags = memory[regs.SP]; + regs.A = memory[regs.SP+1]; + regs.SP += 2; + break; + case 0xC1: // pop BC + regs.C = memory[regs.SP]; + regs.B = memory[regs.SP+1]; + regs.SP += 2; + break; + case 0xD1: // pop DE + regs.E = memory[regs.SP]; + regs.D = memory[regs.SP+1]; + regs.SP += 2; + break; + case 0xE1: // pop HL + regs.L = memory[regs.SP]; + regs.H = memory[regs.SP+1]; + regs.SP += 2; + break; + + // 8-bit ALU + // ADD A, n + case 0x87: {// ADD A, A + int res = regs.A + regs.A; + int half_res = (regs.A & 0x0F) + (regs.A & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x80: {// ADD A, B + int res = regs.A + regs.B; + int half_res = (regs.A & 0x0F) + (regs.B & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x81: {// ADD A, C + int res = regs.A + regs.C; + int half_res = (regs.A & 0x0F) + (regs.C & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x82: {// ADD A, D + int res = regs.A + regs.D; + int half_res = (regs.A & 0x0F) + (regs.D & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x83: {// ADD A, E + int res = regs.A + regs.E; + int half_res = (regs.A & 0x0F) + (regs.E & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x84: {// ADD A, H + int res = regs.A + regs.H; + int half_res = (regs.A & 0x0F) + (regs.H & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x85: {// ADD A, L + int res = regs.A + regs.L; + int half_res = (regs.A & 0x0F) + (regs.L & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0x86: {// ADD A, (HL) + int res = regs.A + memory[regs.HL]; + int half_res = (regs.A & 0x0F) + (memory[regs.HL] & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + case 0xC6: {//ADD A, # + int inm = memory[regs.PC++]; + int res = regs.A + inm; + int half_res = (regs.A & 0x0F) + (inm & 0x0F); + + regs.A = static_cast(res); + if (res > 0xFF) + set_flag(CARRY_FLAG); + reset_flag(ADD_SUB_FLAG); + if (regs.A == 0) + set_flag(ZERO_FLAG); + + if (half_res > 0x0F) + set_flag(HALF_CARRY_FLAG); + break; + } + + + + + + + + + + } + +} + diff --git a/gbcore.h b/gbcore.h new file mode 100644 index 0000000..e69de29 diff --git a/gbrom.cc b/gbrom.cc new file mode 100644 index 0000000..b1c3082 --- /dev/null +++ b/gbrom.cc @@ -0,0 +1,36 @@ +#include "gbrom.h" +#include +#include +#include + +using std::ifstream; +using std::ios; +using std::cout; +using std::endl; + +GBRom *read_gbrom(std::string filename) +{ + ifstream is; + is.open(filename.c_str(), ios::binary); + + is.seekg(0,ios::end); + int length = is.tellg(); + cout << "Loading " << filename << " (length=" << length << ")" << endl; + is.seekg(0,ios::beg); + + void *buffer = ::operator new(length); + is.read((char*)buffer, length); + GBRom *rom = (GBRom*) buffer; + + char buf[17]; + std::memcpy(buf, rom->header.old_title, 16); + buf[16]=0; + cout << "Loaded " << buf << endl; +} + +#ifdef TEST_GBROM +int main(int argc, char *argv[]) +{ + GBRom *rom=read_gbrom(argv[1]); +} +#endif diff --git a/gbrom.h b/gbrom.h new file mode 100644 index 0000000..c88dd81 --- /dev/null +++ b/gbrom.h @@ -0,0 +1,77 @@ +#ifndef GBROM_H +#define GBROM_H + +#include "sized_types.h" +#include + +namespace cartrigde_types { + const u8 ROM_ONLY=0x00; + const u8 MBC1=0x01; + const u8 MBC1_RAM=0x02; + const u8 MBC1_RAM_BATTERY=0x03; + const u8 MBC2=0x05; + const u8 MBC2_BATTERY=0x06; + const u8 ROM_RAM=0x08; + const u8 ROM_RAM_BATTERY=0x09; + const u8 MMM01=0x0B; + const u8 MMM01_RAM=0x0C; + const u8 MMM01_RAM_BATTERY=0x0D; + const u8 MBC3_TIMER_BATTERY=0X0F; + const u8 MBC3_TIMER_RAM_BATTERY=0X10; + const u8 MBC3=0X11; + const u8 MBC3_RAM=0X12; + const u8 MBC3_RAM_BATTERY=0X13; + const u8 MBC4=0X15; + const u8 MBC4_RAM=0X16; + const u8 MBC4_RAM_BATTERY=0X17; + const u8 MBC5=0X19; + const u8 MBC5_RAM=0X1A; + const u8 MBC5_RAM_BATTERY=0X1B; + const u8 MBC5_RUMBLE=0X1C; + const u8 MBC5_RUMBLE_RAM=0X1D; + const u8 MBC5_RUMBLE_RAM_BATTERY=0X1E; + const u8 POCKET_CAMERA=0XFC; + const u8 BANDAI_TAMA5=0XFD; + const u8 HuC3=0XFE; + const u8 HuC1_RAM_BATTERY=0xFF; +} + + + + +struct GBRomHeader { + u8 dummy[256]; // ROM beginning, before header + u32 entry_point; // 0100-0103 + u8 nintendo_logo[48]; // 0104-0133 + union { + struct { + u8 old_title[16]; + }; + struct { + u8 new_title[11]; + u8 manuf_code[4]; + u8 cgb_flag; + }; + }; + u8 new_licensee_code[2]; + u8 sgb_flag; + u8 cartridge_type; + u8 rom_size; // 32Kb shl rom_size + u8 ram_size; + u8 destination_code; + u8 old_licensee_code; + u8 mask_rom_version_number; + u8 header_checksum; + u8 global_checksum[2]; +}; + +union GBRom { + GBRomHeader header; + u8 data[1]; // struct hack +}; + +GBRom *read_gbrom(std::string filename); + + +#endif + diff --git a/sized_types.h b/sized_types.h new file mode 100644 index 0000000..7bd0287 --- /dev/null +++ b/sized_types.h @@ -0,0 +1,155 @@ +#ifndef SIZED_TYPES_H +#define SIZED_TYPES_H + +#include + + +// NOTE: sizeof(char) <= sizeof(short) <= sizeof(int) +// <= sizeof(long) <= sizeof(long long) +// char >= 8 bit +// short >= 16 bit +// long >= 32 bit + + +// Define SIZEOF_CHAR +#if UCHAR_MAX == 0xff +#define SIZEOF_CHAR 1 +#elif UCHAR_MAX == 0xffff +#define SIZEOF_CHAR 2 +#elif UCHAR_MAX == 0xfffffffful +#define SIZEOF_CHAR 4 +#elif UCHAR_MAX == 0xfffffffffffffffful +#define SIZEOF_CHAR 8 +#endif // SIZEOF_CHAR + +// Define SIZEOF_SHORT +#if USHRT_MAX == 0xffff +#define SIZEOF_SHORT 2 +#elif USHRT_MAX == 0xfffffffful +#define SIZEOF_SHORT 4 +#elif USHRT_MAX == 0xfffffffffffffffful +#define SIZEOF_SHORT 8 +#endif // SIZEOF_SHORT + +// Define SIZEOF_INT +#if UINT_MAX == 0xffff +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xfffffffful +#define SIZEOF_INT 4 +#elif UINT_MAX == 0xfffffffffffffffful +#define SIZEOF_INT 8 +#endif // SIZEOF_INT + +// Define SIZEOF_LONG +#if ULONG_MAX == 0xfffffffful +#define SIZEOF_LONG 4 +#elif ULONG_MAX == 0xfffffffffffffffful +#define SIZEOF_LONG 8 +#endif // SIZEOF_LONG + +// Define SIZEOF_LONG_LONG +#ifdef ULLONG_MAX +#if ULLONG_MAX == 0xffffffffull +#define SIZEOF_LONG_LONG 4 +#elif ULLONG_MAX == 0xffffffffffffffffull +#define SIZEOF_LONG_LONG 8 +#endif +#endif // SIZEOF_LONG_LONG + +#define COMPILE_TIME_ASSERT(name, x) \ + typedef int APRIL_SIZED_dummy_ ## name[(x) * 2 - 1] + + +// Define 8-bit types +#if SIZEOF_CHAR == 1 +typedef unsigned char uint8; +typedef signed char int8; +COMPILE_TIME_ASSERT(uint8, 1==sizeof(uint8)); +COMPILE_TIME_ASSERT(int8, 1==sizeof(int8)); +#define HAVE_INT8 +#define HAVE_UINT8 +#endif // short y siguientes tienen minimo 16 bits + +// Define 16-bit types +#if SIZEOF_SHORT == 2 +typedef unsigned short uint16; +typedef signed short int16; +COMPILE_TIME_ASSERT(uint16, 2==sizeof(uint16)); +COMPILE_TIME_ASSERT(int16, 2==sizeof(int16)); +#define HAVE_INT16 +#define HAVE_UINT16 +#endif + +// Define 32-bit types +#if SIZEOF_SHORT == 4 +typedef unsigned short uint32; +typedef signed short int32; +COMPILE_TIME_ASSERT(uint32, 4==sizeof(uint32)); +COMPILE_TIME_ASSERT(int32, 4==sizeof(int32)); +#define HAVE_INT32 +#define HAVE_UINT32 +#elif SIZEOF_INT == 4 +typedef unsigned int uint32; +typedef signed int int32; +COMPILE_TIME_ASSERT(uint32, 4==sizeof(uint32)); +COMPILE_TIME_ASSERT(int32, 4==sizeof(int32)); +#define HAVE_INT32 +#define HAVE_UINT32 +#elif SIZEOF_LONG == 4 +typedef unsigned long uint32; +typedef signed long int32; +COMPILE_TIME_ASSERT(uint32, 4==sizeof(uint32)); +COMPILE_TIME_ASSERT(int32, 4==sizeof(int32)); +#define HAVE_INT32 +#define HAVE_UINT32 +#elif SIZEOF_LONG_LONG == 4 +typedef unsigned long long uint32; +typedef signed long long int32; +COMPILE_TIME_ASSERT(uint32, 4==sizeof(uint32)); +COMPILE_TIME_ASSERT(int32, 4==sizeof(int32)); +#define HAVE_INT32 +#define HAVE_UINT32 +#endif + +// Define 64-bit types +#if SIZEOF_SHORT == 8 +typedef unsigned short uint64; +typedef signed short int64; +COMPILE_TIME_ASSERT(uint64, 8==sizeof(uint64)); +COMPILE_TIME_ASSERT(int64, 8==sizeof(int64)); +#define HAVE_INT64 +#define HAVE_UINT64 +#elif SIZEOF_INT == 8 +typedef unsigned int uint64; +typedef signed int int64; +COMPILE_TIME_ASSERT(uint64, 8==sizeof(uint64)); +COMPILE_TIME_ASSERT(int64, 8==sizeof(int64)); +#define HAVE_INT64 +#define HAVE_UINT64 +#elif SIZEOF_LONG == 8 +typedef unsigned long uint64; +typedef signed long int64; +COMPILE_TIME_ASSERT(uint64, 8==sizeof(uint64)); +COMPILE_TIME_ASSERT(int64, 8==sizeof(int64)); +#define HAVE_INT64 +#define HAVE_UINT64 +#elif SIZEOF_LONG_LONG == 8 +typedef unsigned long long uint64; +typedef signed long long int64; +COMPILE_TIME_ASSERT(uint64, 8==sizeof(uint64)); +COMPILE_TIME_ASSERT(int64, 8==sizeof(int64)); +#define HAVE_INT64 +#define HAVE_UINT64 +#endif + +typedef uint8 u8; +typedef int8 s8; +typedef uint16 u16; +typedef int16 s16; +typedef uint32 u32; +typedef int32 s32; + + + +#endif // SIZED_TYPES_H +