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