Documentation
¶
Overview ¶
Package cpu emulates the Sharp LR35902 executors contains implementations of assembly instructions registers contains register information and methods instructions contains all CPU instructions
Package cpu executors contains implementations of all non-CB prefixed Sharp LR35902 instructions Non-CB prefixed means these are only run if the instruction we received is not `CB .. ..` Executor function field on the Instruction struct executes these
Package cpu instructions contains instruction opcodes & definitions Reference: http://www.pastraiser.com/cpu/gameboy/gameboyopcodes.html
Index ¶
- Variables
- type GBCPU
- func (gbcpu *GBCPU) ADCAHL()
- func (gbcpu *GBCPU) ADCAn()
- func (gbcpu *GBCPU) ADCrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) ADDAHL()
- func (gbcpu *GBCPU) ADDAn()
- func (gbcpu *GBCPU) ADDHLSP()
- func (gbcpu *GBCPU) ADDHLrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) ADDSPs()
- func (gbcpu *GBCPU) ADDrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) ANDHL()
- func (gbcpu *GBCPU) ANDn()
- func (gbcpu *GBCPU) ANDr(reg *byte)
- func (gbcpu *GBCPU) BITHL(pos uint8)
- func (gbcpu *GBCPU) BITnr(pos uint8, reg *byte)
- func (gbcpu *GBCPU) CALLCaa() int
- func (gbcpu *GBCPU) CALLNCaa() int
- func (gbcpu *GBCPU) CALLNZaa() int
- func (gbcpu *GBCPU) CALLZaa() int
- func (gbcpu *GBCPU) CALLaa()
- func (gbcpu *GBCPU) CB() int
- func (gbcpu *GBCPU) CCF()
- func (gbcpu *GBCPU) CPL()
- func (gbcpu *GBCPU) CPaa(a1, a2 *byte)
- func (gbcpu *GBCPU) CPn()
- func (gbcpu *GBCPU) CPr(reg *byte)
- func (gbcpu *GBCPU) DAA()
- func (gbcpu *GBCPU) DECHL()
- func (gbcpu *GBCPU) DECSP()
- func (gbcpu *GBCPU) DECr(reg *byte)
- func (gbcpu *GBCPU) DECrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) DI()
- func (gbcpu *GBCPU) EI()
- func (gbcpu *GBCPU) HALT()
- func (gbcpu *GBCPU) INCHL()
- func (gbcpu *GBCPU) INCSP()
- func (gbcpu *GBCPU) INCr(reg *byte)
- func (gbcpu *GBCPU) INCrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) InitCPU()
- func (gbcpu *GBCPU) JPCaa() int
- func (gbcpu *GBCPU) JPHL()
- func (gbcpu *GBCPU) JPNCaa() int
- func (gbcpu *GBCPU) JPNZaa() int
- func (gbcpu *GBCPU) JPZaa() int
- func (gbcpu *GBCPU) JPaa()
- func (gbcpu *GBCPU) JRCn() int
- func (gbcpu *GBCPU) JRNCn() int
- func (gbcpu *GBCPU) JRNZn() int
- func (gbcpu *GBCPU) JRZn() int
- func (gbcpu *GBCPU) JRn()
- func (gbcpu *GBCPU) LDAaa(reg *byte)
- func (gbcpu *GBCPU) LDAffC()
- func (gbcpu *GBCPU) LDAffn()
- func (gbcpu *GBCPU) LDDHLr(reg *byte)
- func (gbcpu *GBCPU) LDDrHL(reg *byte)
- func (gbcpu *GBCPU) LDHLSPs()
- func (gbcpu *GBCPU) LDHLn()
- func (gbcpu *GBCPU) LDIAHL()
- func (gbcpu *GBCPU) LDIHLA()
- func (gbcpu *GBCPU) LDSPHL()
- func (gbcpu *GBCPU) LDSPnn()
- func (gbcpu *GBCPU) LDaaA(reg *byte)
- func (gbcpu *GBCPU) LDaaSP()
- func (gbcpu *GBCPU) LDaar(a1, a2, reg *byte)
- func (gbcpu *GBCPU) LDffCA()
- func (gbcpu *GBCPU) LDffnA()
- func (gbcpu *GBCPU) LDraa(reg, a1, a2 *byte)
- func (gbcpu *GBCPU) LDrn(reg *byte)
- func (gbcpu *GBCPU) LDrr(to, from *byte)
- func (gbcpu *GBCPU) LDrrnn(reg1, reg2 *byte)
- func (gbcpu *GBCPU) ORHL()
- func (gbcpu *GBCPU) ORn()
- func (gbcpu *GBCPU) ORr(reg *byte)
- func (gbcpu *GBCPU) POPrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) PUSHrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) RESHL(pos uint8)
- func (gbcpu *GBCPU) RESnr(pos uint8, reg *byte)
- func (gbcpu *GBCPU) RET()
- func (gbcpu *GBCPU) RETC() int
- func (gbcpu *GBCPU) RETI()
- func (gbcpu *GBCPU) RETNC() int
- func (gbcpu *GBCPU) RETNZ() int
- func (gbcpu *GBCPU) RETZ() int
- func (gbcpu *GBCPU) RLA()
- func (gbcpu *GBCPU) RLCA()
- func (gbcpu *GBCPU) RLCHL()
- func (gbcpu *GBCPU) RLCr(reg *byte)
- func (gbcpu *GBCPU) RLHL()
- func (gbcpu *GBCPU) RLr(reg *byte)
- func (gbcpu *GBCPU) RRA()
- func (gbcpu *GBCPU) RRCA()
- func (gbcpu *GBCPU) RRCHL()
- func (gbcpu *GBCPU) RRCr(reg *byte)
- func (gbcpu *GBCPU) RRHL()
- func (gbcpu *GBCPU) RRr(reg *byte)
- func (gbcpu *GBCPU) RST(imm byte)
- func (gbcpu *GBCPU) RSTI(addr byte)
- func (gbcpu *GBCPU) SBCAHL()
- func (gbcpu *GBCPU) SBCAn()
- func (gbcpu *GBCPU) SBCrr(reg1, reg2 *byte)
- func (gbcpu *GBCPU) SCF()
- func (gbcpu *GBCPU) SETHL(pos uint8)
- func (gbcpu *GBCPU) SETnr(pos uint8, reg *byte)
- func (gbcpu *GBCPU) SLAHL()
- func (gbcpu *GBCPU) SLAr(reg *byte)
- func (gbcpu *GBCPU) SRAHL()
- func (gbcpu *GBCPU) SRAr(reg *byte)
- func (gbcpu *GBCPU) SRLHL()
- func (gbcpu *GBCPU) SRLr(reg *byte)
- func (gbcpu *GBCPU) SUBHL()
- func (gbcpu *GBCPU) SUBn()
- func (gbcpu *GBCPU) SUBr(reg *byte)
- func (gbcpu *GBCPU) SWAPHL()
- func (gbcpu *GBCPU) SWAPr(reg *byte)
- func (gbcpu *GBCPU) XORaa(a1, a2 *byte)
- func (gbcpu *GBCPU) XORn()
- func (gbcpu *GBCPU) XORr(reg *byte)
- type Instruction
- type Registers
Constants ¶
This section is empty.
Variables ¶
var GbMMU *mmu.GBMMU
GbMMU variable injection from main.go Prevents having to set MMU pointer as a field on the CPU struct
Functions ¶
This section is empty.
Types ¶
type GBCPU ¶
type GBCPU struct {
// Total time cycles
TCycles uint16
Regs *Registers
Instrs map[byte]Instruction
InstrsCB map[byte]Instruction
Jumped bool
// Interrupt master enabled flag
// Not accessed by a mem address and not technically(?) a register
// Accessed directly by the CPU
IME byte
EIReceived bool
Halted bool
// Interrupt flag prior to halting
IFPreHalt byte
}
GBCPU represents an instance of an LR35902 Reference: http://www.zilog.com/docs/z80/um0080.pdf Page 80 discusses clocks
func (*GBCPU) ADCAHL ¶
func (gbcpu *GBCPU) ADCAHL()
ADCAHL -> e.g. ADC A,(HL) Adds value at addr (HL) + carry bit to reg A Flags: Z0HC
func (*GBCPU) ADCAn ¶
func (gbcpu *GBCPU) ADCAn()
ADCAn -> e.g. ADC A,i8 Values of operand and carry flag are added to reg Result is written into reg Flags: Z0HC
func (*GBCPU) ADCrr ¶
ADCrr -> e.g. ADC A,B Values of reg1, reg2 and carry flag are added together Result is written into reg1 Flags: Z0HC
func (*GBCPU) ADDAHL ¶
func (gbcpu *GBCPU) ADDAHL()
ADDAHL -> e.g. ADD A,(HL) Adds value at addr (HL) to reg A Flags: Z0HC
func (*GBCPU) ADDAn ¶
func (gbcpu *GBCPU) ADDAn()
ADDAn -> e.g. ADD A,i8 Values of reg and i8 are added together Result is written into reg Flags: Z0HC
func (*GBCPU) ADDHLSP ¶
func (gbcpu *GBCPU) ADDHLSP()
ADDHLSP -> e.g. ADD HL,SP Adds HL and SP, then sets HL to result Flags: -0HC
func (*GBCPU) ADDHLrr ¶
ADDHLrr -> e.g. ADD HL,BC Values of HL and reg1reg2 are added together Result is written into HL Flags: -0HC
func (*GBCPU) ADDSPs ¶
func (gbcpu *GBCPU) ADDSPs()
ADDSPs -> e.g. ADD SP,s8 Adds signed 8-bit value to SP Sets SP to new value Flags: 00HC
func (*GBCPU) ADDrr ¶
ADDrr -> e.g. ADD A,B Values of reg1 and reg2 are added together Result is written into reg1 Flags: Z0HC
func (*GBCPU) ANDHL ¶
func (gbcpu *GBCPU) ANDHL()
ANDHL -> e.g. AND (HL) Bitwise AND of value at addr (HL) into A Flags: Z010
func (*GBCPU) ANDn ¶
func (gbcpu *GBCPU) ANDn()
ANDn -> e.g. AND i8 Bitwise AND of i8 into A Flags: Z010
func (*GBCPU) BITHL ¶
BITHL -> e.g. BIT 0,(HL) Test bit at position in value at addr (HL) Flags: Z01-
func (*GBCPU) CALLaa ¶
func (gbcpu *GBCPU) CALLaa()
CALLaa -> e.g. CALL $028B Pushes the addr at PC+3 to the stack Jumps to the address specified by next 2 bytes
func (*GBCPU) CPL ¶
func (gbcpu *GBCPU) CPL()
CPL performs bitwise complement of A into a Flags: -11-
func (*GBCPU) CPaa ¶
CPaa -> e.g. CP (HL) Subtraction of value at addr from accumulator that doesn't update it Only updates flags Flags: Z1HC
func (*GBCPU) CPn ¶
func (gbcpu *GBCPU) CPn()
CPn -> e.g. CP i8 Subtraction from accumulator that doesn't update it Only updates flags Flags: Z1HC
func (*GBCPU) CPr ¶
CPr -> e.g. CP B Subtraction from accumulator that doesn't update it Only updates flags Flags: Z1HC
func (*GBCPU) DAA ¶
func (gbcpu *GBCPU) DAA()
DAA Decimal adjust A TODO Maybe rewrite this to be less esoteric Notoriously a pain to implement Reference: http://forums.nesdev.com/viewtopic.php?t=9088
func (*GBCPU) DECHL ¶
func (gbcpu *GBCPU) DECHL()
DECHL -> e.g. DEC (HL) Decrement value at addr (HL) Flags: Z1H-
func (*GBCPU) DECSP ¶
func (gbcpu *GBCPU) DECSP()
DECSP -> e.g. DEC SP Decrement value of stack pointer by 1 Flags: none
func (*GBCPU) EI ¶
func (gbcpu *GBCPU) EI()
EI enables interrupts by setting IME to 1 Enables AFTER instruction immediately after
func (*GBCPU) INCHL ¶
func (gbcpu *GBCPU) INCHL()
INCHL -> e.g. INC (HL) Increment value at addr (HL) Flags: Z0H-
func (*GBCPU) INCSP ¶
func (gbcpu *GBCPU) INCSP()
INCSP -> e.g. INC SP Increment value of stack pointer by 1 Flags: none
func (*GBCPU) InitCPU ¶
func (gbcpu *GBCPU) InitCPU()
InitCPU initializes a new CPU struct Sets Regs and Instrs fields Sets program counter to location
func (*GBCPU) JPHL ¶
func (gbcpu *GBCPU) JPHL()
JPHL -> e.g. JP (HL) Jumps to addr specified by addr (HL)
func (*GBCPU) JRn ¶
func (gbcpu *GBCPU) JRn()
JRn -> e.g. JR s8 Add byte at PC + 1 to PC, and set PC to that value
func (*GBCPU) LDAaa ¶
LDAaa -> e.g. LD A,(a16) Loads value at addr specified by next 2 bytes into A Flags: none
func (*GBCPU) LDAffC ¶
func (gbcpu *GBCPU) LDAffC()
LDAffC -> e.g. LD A,($FF00+C) Sets A to value at addr (0xFF00+C)
func (*GBCPU) LDAffn ¶
func (gbcpu *GBCPU) LDAffn()
LDAffn -> e.g. LD A,($FF00+a8) Loads value at addr ($FF00+a8) into A
func (*GBCPU) LDHLSPs ¶
func (gbcpu *GBCPU) LDHLSPs()
LDHLSPs -> e.g. LD BC,SP+s8 Loads value of SP + signed 8-bit value into register pair HC and C are a little weird for this instruction https://stackoverflow.com/questions/5159603/gbz80-how-does-ld-hl-spe-affect-h-and-c-flags
func (*GBCPU) LDHLn ¶
func (gbcpu *GBCPU) LDHLn()
LDHLn -> e.g. LD (HL),i8 Loads 8 bit immediate into addr (HL)
func (*GBCPU) LDIAHL ¶
func (gbcpu *GBCPU) LDIAHL()
LDIAHL -> e.g. LDI A,(HL) Set value in reg to value at address a1a2 Increment HL
func (*GBCPU) LDIHLA ¶
func (gbcpu *GBCPU) LDIHLA()
LDIHLA -> e.g. LDI (HL),A Set value at address a1a2 to value in reg Increment reg
func (*GBCPU) LDSPHL ¶
func (gbcpu *GBCPU) LDSPHL()
LDSPHL -> e.g. LD SP,HL Loads bytes from register pair HL into SP
func (*GBCPU) LDSPnn ¶
func (gbcpu *GBCPU) LDSPnn()
LDSPnn -> e.g. LD SP,i16 Loads 16 bit value from next 2 bytes into SP Flags: none
func (*GBCPU) LDaaA ¶
LDaaA -> e.g. LD (a16),A Loads reg A into addr specified by next 2 bytes Flags: none
func (*GBCPU) LDaaSP ¶
func (gbcpu *GBCPU) LDaaSP()
LDaaSP -> e.g. LD (a16),SP Loads value of SP into addr provided by operands Since SP is 2 bytes, we write to (a16) and (a16 + 1) Flags: none
func (*GBCPU) LDffCA ¶
func (gbcpu *GBCPU) LDffCA()
LDffCA -> e.g. LD ($FF00+C),A Sets value at addr (0xFF00+C) to A
func (*GBCPU) LDffnA ¶
func (gbcpu *GBCPU) LDffnA()
LDffnA -> e.g. LD ($FF00+a8),A Loads A into value at addr ($FF00+a8)
func (*GBCPU) ORHL ¶
func (gbcpu *GBCPU) ORHL()
ORHL -> e.g. OR (HL) Bitwise OR of byte at addr Flags: Z000
func (*GBCPU) RET ¶
func (gbcpu *GBCPU) RET()
RET pops the top of the stack into the program counter
func (*GBCPU) RLA ¶
func (gbcpu *GBCPU) RLA()
RLA rotates register A left through CF Store old 0th bit into carry Old carry becomes new 7th bit Flags: 000C
func (*GBCPU) RLCA ¶
func (gbcpu *GBCPU) RLCA()
RLCA performs 8-bit rotation to the left Rotated bit is copied to carry Flags: 000C GB opcodes list show Z being set to zero, but other sources disagree Z80 does not modify Z, other emulator sources do Reference: https://hax.iimarckus.org/topic/1617/
func (*GBCPU) RLCHL ¶
func (gbcpu *GBCPU) RLCHL()
RLCHL -> e.g. RLC (HL) Performs 8-bit rotation to the left of value at address (HL) Rotated bit is copied to carry Flags: Z00C
func (*GBCPU) RLCr ¶
RLCr -> e.g. RLC B Performs 8-bit rotation to the left Rotated bit is copied to carry Flags: Z00C
func (*GBCPU) RLHL ¶
func (gbcpu *GBCPU) RLHL()
RLHL -> e.g. RL (HL) Rotates value at address (HL) left through CF Store old 0th bit into carry Old carry becomes new 7th bit Flags: Z00C
func (*GBCPU) RLr ¶
RLr -> e.g. RL B Rotates register left through CF Store old 0th bit into carry Old carry becomes new 7th bit Flags: Z00C
func (*GBCPU) RRA ¶
func (gbcpu *GBCPU) RRA()
RRA rotates register A right through CF Store old 0th bit into carry Old carry becomes new 7th bit Flags: 000C
func (*GBCPU) RRCA ¶
func (gbcpu *GBCPU) RRCA()
RRCA performs 8-bit rotation to the right Rotated bit is copied to carry Flags: 000C GB opcodes list show Z being set to zero, but other sources disagree Z80 does not modify Z, other emulator sources do
func (*GBCPU) RRCHL ¶
func (gbcpu *GBCPU) RRCHL()
RRCHL -> e.g. RRC (HL) Performs 8-bit rotation to the right of value at address (HL) Rotated bit is copied to carry Flags: Z00C
func (*GBCPU) RRCr ¶
RRCr -> e.g. RRC B Performs 8-bit rotation to the right Rotated bit is copied to carry Flags: Z00C
func (*GBCPU) RRHL ¶
func (gbcpu *GBCPU) RRHL()
RRHL -> e.g. RR (HL) Rotates value at address (HL) right through CF Store old 0th bit into carry Old carry becomes new 7th bit Flags: Z00C
func (*GBCPU) RST ¶
RST pushes current PC + 3 onto stack MSB of PC is set to 0x00, LSB is set to argument Handles 0000,0008,0010,0018,0020,0028,0030,0038 which come from ROM Flags: none
func (*GBCPU) RSTI ¶
RSTI runs interrupt handlers Does not have a corresponding opcode, but is slightly different than RST Flags: none
func (*GBCPU) SBCAHL ¶
func (gbcpu *GBCPU) SBCAHL()
SBCAHL -> e.g. SBC A,(HL) Subtract value at addr (HL) and carry flag from reg A Write result to reg A Flags: Z1HC
func (*GBCPU) SBCAn ¶
func (gbcpu *GBCPU) SBCAn()
SBCAn -> e.g. SBC A,i8 Sum of i8 and carry flag is subtracted from reg Result is written into reg Flags: Z1HC
func (*GBCPU) SBCrr ¶
SBCrr -> e.g. SBC A,B Sum of reg2 and carry flag is subtracted from reg1 Result is written into reg1 Flags: Z1HC
func (*GBCPU) SLAHL ¶
func (gbcpu *GBCPU) SLAHL()
SLAHL -> e.g. SLA (HL) Shift value at addr (HL) left into carry Least significant bit of reg set to 0 Flags: Z00C
func (*GBCPU) SLAr ¶
SLAr -> e.g. SLA B Shift reg left into carry Least significant bit of reg set to 0 Flags: Z00C
func (*GBCPU) SRAHL ¶
func (gbcpu *GBCPU) SRAHL()
SRAHL -> e.g. SRA (HL) Shift value at addr (HL) right into carry Most significant bit of reg is unaffected Flags: Z000
func (*GBCPU) SRAr ¶
SRAr -> e.g. SRA B Shift reg right into carry Most significant bit of reg is unaffected Flags: Z000
func (*GBCPU) SRLHL ¶
func (gbcpu *GBCPU) SRLHL()
SRLHL -> e.g. SRL (HL) Shift value at addr (HL) right into carry Most significant bit of reg is set to 0 Flags: Z00C
func (*GBCPU) SRLr ¶
SRLr -> e.g. SRL B Shift reg right into carry Most significant bit of reg is set to 0 Flags: Z00C
func (*GBCPU) SUBHL ¶
func (gbcpu *GBCPU) SUBHL()
SUBHL -> e.g. SUB (HL) Subtract value at addr (HL) from A Write result to A Flags: Z1HC
func (*GBCPU) SUBn ¶
func (gbcpu *GBCPU) SUBn()
SUBn -> e.g. SUB i8 Value of i8 is subtracted from A Result is written into reg Flags: Z1HC
func (*GBCPU) SUBr ¶
SUBr -> e.g. SUB B Value of reg is subtracted from A Result is written into reg Flags: Z1HC
func (*GBCPU) SWAPHL ¶
func (gbcpu *GBCPU) SWAPHL()
SWAPHL -> e.g. SWAP (HL) Swap nibbles of value at addr (HL) Flags: Z000
type Instruction ¶
type Instruction struct {
Mnemonic string
// Number of T cycles instruction takes to execute
// Divide by 4 to get number of M cycles
TCycles uint16
NumOperands uint16
Executor func() int // Executes appropriate function
}
Instruction holds all relevant information for CPU instructions Don't think we need to store opcode in the struct since it will be equal to the byte key of the instruction in the map
type Registers ¶
type Registers struct {
PC []byte // Program counter
// contains filtered or unexported fields
}
Registers represents Sharp LR35902 registers Each individual register is a byte, but AF, BC, DE, HL can be addressed as pairs (single 16-bit value) Stack pointer and program counter are 2 bytes always Could have also represented SP/PC as a single uint16. However, seems more semantically accurate to do them as byte slices w/ 2 values Notes: Carry flag - https://stackoverflow.com/questions/31409444/what-is-the-behavior-of-the-carry-flag-for-cp-on-a-game-boy Half carry flag - http://stackoverflow.com/questions/8868396/gbz80-what-constitutes-a-half-carry/8874607#8874607
func (*Registers) InitRegs ¶
func (regs *Registers) InitRegs()
InitRegs sets post-bootrom register values GB register initial values: http://bgb.bircd.org/pandocs.htm#powerupsequence