I/O Registers
-------------
FF00
Name - P1
Contents - Register for reading joy pad info
and determining system type. (R/W)
Bit 7 - Not used
Bit 6 - Not used
Bit 5 - P15 out port
Bit 4 - P14 out port
Bit 3 - P13 in port
Bit 2 - P12 in port
Bit 1 - P11 in port
Bit 0 - P10 in port
This is the matrix layout for register $FF00:
P14 P15
| |
P10-------O-Right----O-A
| |
P11-------O-Left-----O-B
| |
P12-------O-Up-------O-Select
| |
P13-------O-Down-----O-Start
| |
Example code:
Game: Ms. Pacman
Address: $3b1
LD A,$20 <- bit 5 = $20
LD ($FF00),A <- select P14 by setting it low
LD A,($FF00)
LD A,($FF00) <- wait a few cycles
CPL <- complement A
AND $0F <- get only first 4 bits
SWAP A <- swap it
LD B,A <- store A in B
LD A,$10
LD ($FF00),A <- select P15 by setting it low
LD A,($FF00)
LD A,($FF00)
LD A,($FF00)
LD A,($FF00)
LD A,($FF00)
LD A,($FF00) <- Wait a few MORE cycles
CPL <- complement (invert)
AND $0F <- get first 4 bits
OR B <- put A and B together
LD B,A <- store A in D
LD A,($FF8B) <- read old joy data from ram
XOR B <- toggle w/current button bit
AND B <- get current button bit back
LD ($FF8C),A <- save in new Joydata storage
LD A,B <- put original value in A
LD ($FF8B),A <- store it as old joy data
LD A,$30 <- deselect P14 and P15
LD ($FF00),A <- RESET Joypad
RET <- Return from Subroutine
The button values using the above method are such:
$80 - Start $8 - Down
$40 - Select $4 - Up
$20 - B $2 - Left
$10 - A $1 - Right
Let's say we held down A, Start, and Up.
The value returned in accumulator A would be $94
FF01
Name - SB
Contents - Serial transfer data (R/W)
8 Bits of data to be read/written
FF02
Name - SC
Contents - SIO control (R/W)
Bit 7 - Transfer Start Flag
0: Non transfer
1: Start transfer
Bit 0 - Shift Clock
0: External Clock (500KHz Max.)
1: Internal Clock (8192Hz)
Transfer is initiated by setting the
Transfer Start Flag. This bit may be read
and is automatically set to 0 at the end of
Transfer.
Transmitting and receiving serial data is
done simultaneously. The received data is
automatically stored in SB.
FF04
Name - DIV
Contents - Divider Register (R/W)
This register is incremented 16384 (~16779
on SGB) times a second. Writing any value
sets it to $00.
FF05
Name - TIMA
Contents - Timer counter (R/W)
This timer is incremented by a clock frequency
specified by the TAC register ($FF07). The timer
generates an interrupt when it overflows.
FF06
Name - TMA
Contents - Timer Modulo (R/W)
When the TIMA overflows, this data will be loaded.
FF07
Name - TAC
Contents - Timer Control (R/W)
Bit 2 - Timer Stop
0: Stop Timer
1: Start Timer
Bits 1+0 - Input Clock Select
00: 4.096 KHz (~4.194 KHz SGB)
01: 262.144 KHz (~268.4 KHz SGB)
10: 65.536 KHz (~67.11 KHz SGB)
11: 16.384 KHz (~16.78 KHz SGB)
FF0F
Name - IF
Contents - Interrupt Flag (R/W)
Bit 4: Transition from High to Low of Pin number P10-P13
Bit 3: Serial I/O transfer complete
Bit 2: Timer Overflow
Bit 1: LCDC (see STAT)
Bit 0: V-Blank
The priority and jump address for the above 5 interrupts are:
Interrupt Priority Start Address
V-Blank 1 $0040
LCDC Status 2 $0048 - Modes 0, 1, 2
LYC=LY coincide (selectable)
Timer Overflow 3 $0050
Serial Transfer 4 $0058 - when transfer is complete
Hi-Lo of P10-P13 5 $0060
* When more than 1 interrupts occur at the same time
only the interrupt with the highest priority can be
acknowledged. When an interrupt is used a '0' should
be stored in the IF register before the IE register
is set.
FF10
Name - NR 10
Contents - Sound Mode 1 register, Sweep register (R/W)
Bit 6-4 - Sweep Time
Bit 3 - Sweep Increase/Decrease
0: Addition (frequency increases)
1: Subtraction (frequency decreases)
Bit 2-0 - Number of sweep shift (n: 0-7)
Sweep Time: 000: sweep off - no freq change
001: 7.8 ms (1/128Hz)
010: 15.6 ms (2/128Hz)
011: 23.4 ms (3/128Hz)
100: 31.3 ms (4/128Hz)
101: 39.1 ms (5/128Hz)
110: 46.9 ms (6/128Hz)
111: 54.7 ms (7/128Hz)
The change of frequency (NR13,NR14) at each shift
is calculated by the following formula where
X(0) is initial freq & X(t-1) is last freq:
X(t) = X(t-1) +/- X(t-1)/2^n
FF11
Name - NR 11
Contents - Sound Mode 1 register, Sound length/Wave pattern duty (R/W)
Only Bits 7-6 can be read.
Bit 7-6 - Wave Pattern Duty
Bit 5-0 - Sound length data (t1: 0-63)
Wave Duty: 00: 12.5% ( _--------_--------_-------- )
01: 25% ( __-------__-------__------- )
10: 50% ( ____-----____-----____----- ) (default)
11: 75% ( ______---______---______--- )
Sound Length = (64-t1)*(1/256) seconds
FF12
Name - NR 12
Contents - Sound Mode 1 register, Envelope (R/W)
Bit 7-4 - Initial volume of envelope
Bit 3 - Envelope UP/DOWN
0: Attenuate
1: Amplify
Bit 2-0 - Number of envelope sweep (n: 0-7)
(If zero, stop envelope operation.)
Initial volume of envelope is from 0 to $F.
Zero being no sound.
Length of 1 step = n*(1/64) seconds
FF13
Name - NR 13
Contents - Sound Mode 1 register, Frequency lo (W)
Lower 8 bits of 11 bit frequency (x).
Next 3 bit are in NR 14 ($FF14)
FF14
Name - NR 14
Contents - Sound Mode 1 register, Frequency hi (R/W)
Only Bit 6 can be read.
Bit 7 - Initial (when set, sound restarts)
Bit 6 - Counter/consecutive selection
Bit 2-0 - Frequency's higher 3 bits (x)
Frequency = 4194304/(32*(2048-x)) Hz
= 131072/(2048-x) Hz
Counter/consecutive Selection
0 = Regardless of the length data in NR11
sound can be produced consecutively.
1 = Sound is generated during the time period
set by the length data in NR11. After this
period the sound 1 ON flag (bit 0 of NR52)
is reset.
FF16
Name - NR 21
Contents - Sound Mode 2 register, Sound Length; Wave Pattern Duty (R/W)
Only bits 7-6 can be read.
Bit 7-6 - Wave pattern duty
Bit 5-0 - Sound length data (t1: 0-63)
Wave Duty: 00: 12.5% ( _--------_--------_-------- )
01: 25% ( __-------__-------__------- )
10: 50% ( ____-----____-----____----- ) (default)
11: 75% ( ______---______---______--- )
Sound Length = (64-t1)*(1/256) seconds
FF17
Name - NR 22
Contents - Sound Mode 2 register, envelope (R/W)
Bit 7-4 - Initial volume of envelope
Bit 3 - Envelope UP/DOWN
0: Attenuate
1: Amplify
Bit 2-0 - Number of envelope sweep (n: 0-7)
(If zero, stop envelope operation.)
Initial volume of envelope is from 0 to $F.
Zero being no sound.
Length of 1 step = n*(1/64) seconds
FF18
Name - NR 23
Contents - Sound Mode 2 register, frequency lo data (W)
Frequency's lower 8 bits of 11 bit data (x).
Next 3 bits are in NR 14 ($FF19).
FF19
Name - NR 24
Contents - Sound Mode 2 register, frequency hi data (R/W)
Only bit 6 can be read.
Bit 7 - Initial (when set, sound restarts)
Bit 6 - Counter/consecutive selection
Bit 2-0 - Frequency's higher 3 bits (x)
Frequency = 4194304/(32*(2048-x)) Hz
= 131072/(2048-x) Hz
Counter/consecutive Selection
0 = Regardless of the length data in NR21
sound can be produced consecutively.
1 = Sound is generated during the time period
set by the length data in NR21. After this
period the sound 2 ON flag (bit 1 of NR52)
is reset.
FF1A
Name - NR 30
Contents - Sound Mode 3 register, Sound on/off (R/W)
Only bit 7 can be read
Bit 7 - Sound OFF
0: Sound 3 output stop
1: Sound 3 output OK
FF1B
Name - NR 31
Contents - Sound Mode 3 register, sound length (R/W)
Bit 7-0 - Sound length (t1: 0 - 255)
Sound Length = (256-t1)*(1/2) seconds
FF1C
Name - NR 32
Contents - Sound Mode 3 register, Select output level (R/W)
Only bits 6-5 can be read
Bit 6-5 - Select output level
00: Mute
01: Produce Wave Pattern RAM Data as it is
(4 bit length)
10: Produce Wave Pattern RAM data shifted once
to the RIGHT (1/2) (4 bit length)
11: Produce Wave Pattern RAM data shifted twice
to the RIGHT (1/4) (4 bit length)
* - Wave Pattern RAM is located from $FF30-$FF3f.
FF1D
Name - NR 33
Contents - Sound Mode 3 register, frequency's lower data (W)
Lower 8 bits of an 11 bit frequency (x).
FF1E
Name - NR 34
Contents - Sound Mode 3 register, frequency's higher data (R/W)
Only bit 6 can be read.
Bit 7 - Initial (when set, sound restarts)
Bit 6 - Counter/consecutive flag
Bit 2-0 - Frequency's higher 3 bits (x).
Frequency = 4194304/(64*(2048-x)) Hz
= 65536/(2048-x) Hz
Counter/consecutive Selection
0 = Regardless of the length data in NR31
sound can be produced consecutively.
1 = Sound is generated during the time period
set by the length data in NR31. After this
period the sound 3 ON flag (bit 2 of NR52)
is reset.
FF20
Name - NR 41
Contents - Sound Mode 4 register, sound length (R/W)
Bit 5-0 - Sound length data (t1: 0-63)
Sound Length = (64-t1)*(1/256) seconds
FF21
Name - NR 42
Contents - Sound Mode 4 register, envelope (R/W)
Bit 7-4 - Initial volume of envelope
Bit 3 - Envelope UP/DOWN
0: Attenuate
1: Amplify
Bit 2-0 - Number of envelope sweep (n: 0-7)
(If zero, stop envelope operation.)
Initial volume of envelope is from 0 to $F.
Zero being no sound.
Length of 1 step = n*(1/64) seconds
FF22
Name - NR 43
Contents - Sound Mode 4 register, polynomial counter (R/W)
Bit 7-4 - Selection of the shift clock frequency of the
polynomial counter
Bit 3 - Selection of the polynomial counter's step
Bit 2-0 - Selection of the dividing ratio of frequencies
Selection of the dividing ratio of frequencies:
000: f * 1/2^3 * 2
001: f * 1/2^3 * 1
010: f * 1/2^3 * 1/2
011: f * 1/2^3 * 1/3
100: f * 1/2^3 * 1/4
101: f * 1/2^3 * 1/5
110: f * 1/2^3 * 1/6
111: f * 1/2^3 * 1/7 f = 4.194304 Mhz
Selection of the polynomial counter step:
0: 15 steps
1: 7 steps
Selection of the shift clock frequency of the polynomial
counter:
0000: dividing ratio of frequencies * 1/2
0001: dividing ratio of frequencies * 1/2^2
0010: dividing ratio of frequencies * 1/2^3
0011: dividing ratio of frequencies * 1/2^4
: :
: :
: :
0101: dividing ratio of frequencies * 1/2^14
1110: prohibited code
1111: prohibited code
FF23
Name - NR 44
Contents - Sound Mode 4 register, counter/consecutive; inital (R/W)
Only bit 6 can be read.
Bit 7 - Initial (when set, sound restarts)
Bit 6 - Counter/consecutive selection
Counter/consecutive Selection
0 = Regardless of the length data in NR41
sound can be produced consecutively.
1 = Sound is generated during the time period
set by the length data in NR41. After this
period the sound 4 ON flag (bit 3 of NR52)
is reset.
FF24
Name - NR 50
Contents - Channel control / ON-OFF / Volume (R/W)
Bit 7 - Vin->SO2 ON/OFF
Bit 6-4 - SO2 output level (volume) (# 0-7)
Bit 3 - Vin->SO1 ON/OFF
Bit 2-0 - SO1 output level (volume) (# 0-7)
Vin->SO1 (Vin->SO2)
By synthesizing the sound from sound 1
through 4, the voice input from Vin
terminal is put out.
0: no output
1: output OK
FF25
Name - NR 51
Contents - Selection of Sound output terminal (R/W)
Bit 7 - Output sound 4 to SO2 terminal
Bit 6 - Output sound 3 to SO2 terminal
Bit 5 - Output sound 2 to SO2 terminal
Bit 4 - Output sound 1 to SO2 terminal
Bit 3 - Output sound 4 to SO1 terminal
Bit 2 - Output sound 3 to SO1 terminal
Bit 1 - Output sound 2 to SO1 terminal
Bit 0 - Output sound 1 to SO1 terminal
FF26
Name - NR 52 (Value at reset: $F1-GB, $F0-SGB)
Contents - Sound on/off (R/W)
Bit 7 - All sound on/off
0: stop all sound circuits
1: operate all sound circuits
Bit 3 - Sound 4 ON flag
Bit 2 - Sound 3 ON flag
Bit 1 - Sound 2 ON flag
Bit 0 - Sound 1 ON flag
Bits 0 - 3 of this register are meant to
be status bits to be read. Writing to these
bits does NOT enable/disable sound.
If your GB programs don't use sound then
write $00 to this register to save 16% or
more on GB power consumption.
FF30 - FF3F
Name - Wave Pattern RAM
Contents - Waveform storage for arbitrary sound data
This storage area holds 32 4-bit samples
that are played back upper 4 bits first.
FF40
Name - LCDC (value $91 at reset)
Contents - LCD Control (R/W)
Bit 7 - LCD Control Operation *
0: Stop completely (no picture on screen)
1: operation
Bit 6 - Window Tile Map Display Select
0: $9800-$9BFF
1: $9C00-$9FFF
Bit 5 - Window Display
0: off
1: on
Bit 4 - BG & Window Tile Data Select
0: $8800-$97FF
1: $8000-$8FFF <- Same area as OBJ
Bit 3 - BG Tile Map Display Select
0: $9800-$9BFF
1: $9C00-$9FFF
Bit 2 - OBJ (Sprite) Size
0: 8*8
1: 8*16 (width*height)
Bit 1 - OBJ (Sprite) Display
0: off
1: on
Bit 0 - BG Display
0: off
1: on
* - Stopping LCD operation (bit 7 from 1 to 0)
must be performed during V-blank to work
properly. V-blank can be confirmed when the
value of LY is greater than or equal to 144.
FF41
Name - STAT
Contents - LCDC Status (R/W)
Bits 6-3 - Interrupt Selection By LCDC Status
Bit 6 - LYC=LY Coincidence (Selectable)
Bit 5 - Mode 10
Bit 4 - Mode 01
Bit 3 - Mode 00
0: Non Selection
1: Selection
Bit 2 - Coincidence Flag
0: LYC not equal to LCDC LY
1: LYC = LCDC LY
Bit 1-0 - Mode Flag
00: During H-Blank
01: During V-Blank
10: During Searching OAM-RAM
11: During Transfering Data to LCD Driver
STAT shows the current status of the LCD controller.
Mode 00: When the flag is 00 it is the H-Blank period
and the CPU can access the display RAM
($8000-$9FFF).
Mode 01: When the flag is 01 it is the V-Blank period
and the CPU can access the display RAM
($8000-$9FFF).
Mode 10: When the flag is 10 then the OAM is being
used ($FE00-$FE9F). The CPU cannot access
the OAM during this period
Mode 11: When the flag is 11 both the OAM and display
RAM are being used. The CPU cannot access
either during this period.
The following are typical when the display is enabled:
Mode 0 000___000___000___000___000___000___000________________
Mode 1 _______________________________________11111111111111__
Mode 2 ___2_____2_____2_____2_____2_____2___________________2_
Mode 3 ____33____33____33____33____33____33__________________3
The Mode Flag goes through the values 0, 2,
and 3 at a cycle of about 109uS. 0 is present
about 48.6uS, 2 about 19uS, and 3 about 41uS. This
is interrupted every 16.6ms by the VBlank (1).
The mode flag stays set at 1 for about 1.08 ms.
(Mode 0 is present between 201-207 clks, 2 about
77-83 clks, and 3 about 169-175 clks. A complete
cycle through these states takes 456 clks.
VBlank lasts 4560 clks. A complete screen refresh
occurs every 70224 clks.)
FF42
Name - SCY
Contents - Scroll Y (R/W)
8 Bit value $00-$FF to scroll BG Y screen
position.
FF43
Name - SCX
Contents - Scroll X (R/W)
8 Bit value $00-$FF to scroll BG X screen
position.
FF44
Name - LY
Contents - LCDC Y-Coordinate (R)
The LY indicates the vertical line to which
the present data is transferred to the LCD
Driver. The LY can take on any value between
0 through 153. The values between 144 and 153
indicate the V-Blank period. Writing will
reset the counter.
FF45
Name - LYC
Contents - LY Compare (R/W)
The LYC compares itself with the LY. If the
values are the same it causes the STAT to set
the coincident flag.
FF46
Name - DMA
Contents - DMA Transfer and Start Address (W)
The DMA Transfer (40*28 bit) from internal ROM or RAM
($0000-$F19F) to the OAM (address $FE00-$FE9F) can be
performed. It takes 160 microseconds for the transfer.
40*28 bit = #140 or #$8C. As you can see, it only
transfers $8C bytes of data. OAM data is $A0 bytes
long, from $0-$9F.
But if you examine the OAM data you see that 4 bits are
not in use.
40*32 bit = #$A0, but since 4 bits for each OAM is not
used it's 40*28 bit.
It transfers all the OAM data to OAM RAM.
The DMA transfer start address can be designated every
$100 from address $0000-$F100. That means $0000, $0100,
$0200, $0300....
As can be seen by looking at register $FF41 Sprite RAM
($FE00 - $FE9F) is not always available. A simple routine
that many games use to write data to Sprite memory is shown
below. Since it copies data to the sprite RAM at the appro-
priate times it removes that responsibility from the main
program.
All of the memory space, except high ram ($FF80-$FFFE),
is not accessible during DMA. Because of this, the routine
below must be copied & executed in high ram. It is usually
called from a V-blank Interrupt.
Example program:
org $40
jp VBlank
org $ff80
VBlank:
push af <- Save A reg & flags
ld a,BASE_ADRS <- transfer data from BASE_ADRS
ld ($ff46),a <- put A into DMA registers
ld a,28h <- loop length
Wait: <- We need to wait 160 microseconds.
dec a <- 4 cycles - decrease A by 1
jr nz,Wait <- 12 cycles - branch if Not Zero to Wait
pop af <- Restore A reg & flags
reti <- Return from interrupt
FF47
Name - BGP
Contents - BG & Window Palette Data (R/W)
Bit 7-6 - Data for Dot Data 11 (Normally darkest color)
Bit 5-4 - Data for Dot Data 10
Bit 3-2 - Data for Dot Data 01
Bit 1-0 - Data for Dot Data 00 (Normally lightest color)
This selects the shade of grays to use for
the background (BG) & window pixels. Since
each pixel uses 2 bits, the corresponding
shade will be selected from here.
FF48
Name - OBP0
Contents - Object Palette 0 Data (R/W)
This selects the colors for sprite palette 0.
It works exactly as BGP ($FF47) except each
each value of 0 is transparent.
FF49
Name - OBP1
Contents - Object Palette 1 Data (R/W)
This Selects the colors for sprite palette 1.
It works exactly as OBP0 ($FF48).
See BGP for details.
FF4A
Name - WY
Contents - Window Y Position (R/W)
0 <= WY <= 143
WY must be greater than or equal to 0 and
must be less than or equal to 143 for
window to be visible.
FF4B
Name - WX
Contents - Window X Position (R/W)
0 <= WX <= 166
WX must be greater than or equal to 0 and
must be less than or equal to 166 for
window to be visible.
WX is offset from absolute screen coordinates
by 7. Setting the window to WX=7, WY=0 will
put the upper left corner of the window at
absolute screen coordinates 0,0.
Lets say WY = 70 and WX = 87.
The window would be positioned as so:
0 80 159
______________________________________
0 | |
| | |
| |
| Background Display |
| Here |
| |
| |
70 | - +------------------|
| | 80,70 |
| | |
| | Window Display |
| | Here |
| | |
| | |
143 |___________________|__________________|
OBJ Characters (Sprites) can still enter the
window. None of the window colors are
transparent so any background tiles under the
window are hidden.
FFFF
Name - IE
Contents - Interrupt Enable (R/W)
Bit 4: Transition from High to Low of Pin
number P10-P13.
Bit 3: Serial I/O transfer complete
Bit 2: Timer Overflow
Bit 1: LCDC (see STAT)
Bit 0: V-Blank
0: disable
1: enable