Import inicial.
authorslack <slack@0666ae3d-8926-0410-aeff-ae84559ff337>
Tue, 9 Jan 2007 11:05:47 +0000 (11:05 +0000)
committerslack <slack@0666ae3d-8926-0410-aeff-ae84559ff337>
Tue, 9 Jan 2007 11:05:47 +0000 (11:05 +0000)
git-svn-id: http://slack.codemaniacs.com/wenboi@1 0666ae3d-8926-0410-aeff-ae84559ff337

Makefile [new file with mode: 0644]
docs/GBCPUman.pdf [new file with mode: 0644]
docs/pandocs.htm [new file with mode: 0644]
docs/pandocs.txt [new file with mode: 0644]
gbcore.cc [new file with mode: 0644]
gbcore.h [new file with mode: 0644]
gbrom.cc [new file with mode: 0644]
gbrom.h [new file with mode: 0644]
sized_types.h [new file with mode: 0644]

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