--- /dev/null
+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
--- /dev/null
+<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> 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> 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> 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> 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> 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> 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> 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<>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 <cannot> 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 <cannot> 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> 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> 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> 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> 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 <write> to FF69. Auto Increment has \r
+no effect when <reading> 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> 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> 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> 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> 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> 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> 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>=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>=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=>144+16. Just setting the X coordinate to \r
+X=0 or X=>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> 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 <end> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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
+ <INT> ;Disable Ints & Call to Interrupt Vector\r
+</TD></TR></TABLE>Whereas <INT> 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 <requesting> an interrupt to be \r
+executed. The actual <execution> 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> 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 <> 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> 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> 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> 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> 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> 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 <before> 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> 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> 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 --> Color 0\r
+ Light Gray --> Color 1\r
+ Dark Gray --> Color 2\r
+ Black --> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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 <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
+</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> 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 <> $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> 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> 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> 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> 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> 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->01h \r
+procedure.<BR>\r
+This is supposed for <reading> 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 <writing> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> END</FONT></TD></TR></TABLE></BODY></HTML>\r
+\1a
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+#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;
+ }
+
+
+
+
+
+
+
+
+
+ }
+
+}
+
--- /dev/null
+#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
--- /dev/null
+#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
+
--- /dev/null
+#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
+