mirror of
https://github.com/macocianradu/goboy.git
synced 2026-03-18 21:10:07 +00:00
finished first row of opcodes
This commit is contained in:
22
cpu/flags.go
22
cpu/flags.go
@@ -1,6 +1,10 @@
|
|||||||
package cpu
|
package cpu
|
||||||
|
|
||||||
func Set8BitAddFlags(context op_context, byte1 byte, byte2 byte) byte {
|
import (
|
||||||
|
"radu.macocian.me/goboy/cpu/operations"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Add8BitsAndSetFlags(context op_context, byte1 byte, byte2 byte) byte {
|
||||||
result := uint16(byte1) + uint16(byte2)
|
result := uint16(byte1) + uint16(byte2)
|
||||||
halfcarry := (byte1&0x0F)+(byte2&0x0F) > 0x0F
|
halfcarry := (byte1&0x0F)+(byte2&0x0F) > 0x0F
|
||||||
context.cpu.SetNF(false)
|
context.cpu.SetNF(false)
|
||||||
@@ -17,3 +21,19 @@ func Add16BitsAndSetFlags(context op_context, op1 uint16, op2 uint16) uint16 {
|
|||||||
context.cpu.SetCF(result > 0xFFFF)
|
context.cpu.SetCF(result > 0xFFFF)
|
||||||
return uint16(result)
|
return uint16(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IncAndSetFlags(context op_context, op1 *byte) {
|
||||||
|
halfcarry := *op1&0x0F == 0x0F
|
||||||
|
context.cpu.SetNF(false)
|
||||||
|
context.cpu.SetHF(halfcarry)
|
||||||
|
context.cpu.SetZF(*op1 == byte(0))
|
||||||
|
operations.INC(op1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecAndSetFlags(context op_context, op1 *byte) {
|
||||||
|
halfcarry := *op1&0x0F == 0x00
|
||||||
|
context.cpu.SetZF(*op1 == byte(0))
|
||||||
|
context.cpu.SetNF(true)
|
||||||
|
context.cpu.SetHF(halfcarry)
|
||||||
|
operations.DEC(op1)
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,48 +34,33 @@ func INCBC(context op_context) {
|
|||||||
|
|
||||||
// 0x04 INCB Increment the contents of register B by 1.
|
// 0x04 INCB Increment the contents of register B by 1.
|
||||||
func INCB(context op_context) {
|
func INCB(context op_context) {
|
||||||
if context.cpu.B&0x0F == 0x0F {
|
IncAndSetFlags(context, &context.cpu.B)
|
||||||
context.cpu.SetHF(true)
|
|
||||||
} else {
|
|
||||||
context.cpu.SetHF(false)
|
|
||||||
}
|
|
||||||
operations.INC(&context.cpu.B)
|
|
||||||
|
|
||||||
context.cpu.SetZF(context.cpu.B == byte(0))
|
|
||||||
context.cpu.SetNF(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x05 DECB Decrement the contents of register B by 1.
|
// 0x05 DECB Decrement the contents of register B by 1.
|
||||||
func DECB(context op_context) {
|
func DECB(context op_context) {
|
||||||
if context.cpu.B&0x0F == 0x00 {
|
DecAndSetFlags(context, &context.cpu.B)
|
||||||
context.cpu.SetHF(true)
|
|
||||||
} else {
|
|
||||||
context.cpu.SetHF(false)
|
|
||||||
}
|
|
||||||
operations.DEC(&context.cpu.B)
|
|
||||||
|
|
||||||
context.cpu.SetZF(context.cpu.B == byte(0))
|
|
||||||
context.cpu.SetNF(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x06 LD8B Load the 8-bit immediate operand d8 into register B.
|
// 0x06 LDBd8 Load the 8-bit immediate operand d8 into register B.
|
||||||
func LD8B(context op_context) {
|
func LDBd8(context op_context) {
|
||||||
operations.LD(&context.cpu.B, memory.Read8(uint(context.immediate)))
|
operations.LD(&context.cpu.B, byte(context.immediate))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x07 RLCA Rotate the contents of register A to the left. The contents of bit 7 are placed in both the CY flag and bit 0 of register A.
|
// 0x07 RLCA Rotate the contents of register A to the left. The contents of bit 7 are placed in both the CY flag and bit 0 of register A.
|
||||||
func RLCA(context op_context) {
|
func RLCA(context op_context) {
|
||||||
a7 := context.cpu.A>>7 == 1
|
a7 := context.cpu.A >> 7
|
||||||
operations.Shift(&context.cpu.A)
|
operations.ShiftLeft(&context.cpu.A)
|
||||||
|
context.cpu.A = context.cpu.A | byte(a7)
|
||||||
|
|
||||||
context.cpu.SetZF(false)
|
context.cpu.SetZF(false)
|
||||||
context.cpu.SetNF(false)
|
context.cpu.SetNF(false)
|
||||||
context.cpu.SetHF(false)
|
context.cpu.SetHF(false)
|
||||||
context.cpu.SetCF(a7)
|
context.cpu.SetCF(a7 == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x08 LDA16 Store the lower byte of stack pointer SP at the address specified by the 16-bit immediate operand a16, and store the upper byte of SP at address a16 + 1.
|
// 0x08 LDa16SP Store the lower byte of stack pointer SP at the address specified by the 16-bit immediate operand a16, and store the upper byte of SP at address a16 + 1.
|
||||||
func LDA16(context op_context) {
|
func LDa16SP(context op_context) {
|
||||||
operations.LDInMemory8(context.immediate, operations.GetLowerByte(context.cpu.SP))
|
operations.LDInMemory8(context.immediate, operations.GetLowerByte(context.cpu.SP))
|
||||||
operations.LDInMemory8(context.immediate+1, operations.GetHigherByte(context.cpu.SP))
|
operations.LDInMemory8(context.immediate+1, operations.GetHigherByte(context.cpu.SP))
|
||||||
}
|
}
|
||||||
@@ -85,3 +70,41 @@ func ADDHLBC(context op_context) {
|
|||||||
result := Add16BitsAndSetFlags(context, context.cpu.HL(), context.cpu.BC())
|
result := Add16BitsAndSetFlags(context, context.cpu.HL(), context.cpu.BC())
|
||||||
context.cpu.SetHL(result)
|
context.cpu.SetHL(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0x0A LDABC Load the 8-bit contents of memory specified by register pair BC into register A.
|
||||||
|
func LDABC(context op_context) {
|
||||||
|
operations.LDFromMem(&context.cpu.A, uint(context.cpu.BC()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x0B DECBC Decrement the contents of register pair BC by 1.
|
||||||
|
func DECBC(context op_context) {
|
||||||
|
operations.DEC16(&context.cpu.B, &context.cpu.C)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x0C INCC Increment the contents of register C by 1.
|
||||||
|
func INCC(context op_context) {
|
||||||
|
IncAndSetFlags(context, &context.cpu.C)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x0D DECC Decrement the contents of register C by 1.
|
||||||
|
func DECC(context op_context) {
|
||||||
|
DecAndSetFlags(context, &context.cpu.C)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x0E LDCd8 Load the 8-bit immediate operand d8 into register C.
|
||||||
|
func LDCd8(context op_context) {
|
||||||
|
context.cpu.C = byte(context.immediate)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x0F RRRCA Rotate the contents of register A to the right. That is, the contents of bit 7 are copied to bit 6, and the previous contents of bit 6 (before the copy) are copied to bit 5. The same operation is repeated in sequence for the rest of the register. The contents of bit 0 are placed in both the CY flag and bit 7 of register A.
|
||||||
|
func RRRCA(context op_context) {
|
||||||
|
a0 := context.cpu.A & 0x01
|
||||||
|
operations.ShiftRight(&context.cpu.A)
|
||||||
|
context.cpu.A = context.cpu.A | byte(a0)<<7
|
||||||
|
|
||||||
|
context.cpu.SetZF(false)
|
||||||
|
context.cpu.SetNF(false)
|
||||||
|
context.cpu.SetHF(false)
|
||||||
|
context.cpu.SetCF(a0 == 1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package operations
|
package operations
|
||||||
|
|
||||||
func Shift(r1 *byte) {
|
func ShiftLeft(r1 *byte) {
|
||||||
*r1 = *r1 << 1
|
*r1 = *r1 << 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ShiftRight(r1 *byte) {
|
||||||
|
*r1 = *r1 >> 1
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShift(t *testing.T) {
|
func TestShiftLeft(t *testing.T) {
|
||||||
r1 := byte(0b01010101)
|
r1 := byte(0b01010101)
|
||||||
Shift(&r1)
|
ShiftLeft(&r1)
|
||||||
|
|
||||||
expected := byte(0b10101010)
|
expected := byte(0b10101010)
|
||||||
actual := r1
|
actual := r1
|
||||||
@@ -15,3 +15,15 @@ func TestShift(t *testing.T) {
|
|||||||
t.Errorf("actual %x != expected %x", actual, expected)
|
t.Errorf("actual %x != expected %x", actual, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShiftRight(t *testing.T) {
|
||||||
|
r1 := byte(0b01010101)
|
||||||
|
ShiftLeft(&r1)
|
||||||
|
|
||||||
|
expected := byte(0b00101010)
|
||||||
|
actual := r1
|
||||||
|
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf("actual %x != expected %x", actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ var OpTable = [256]func(context op_context){
|
|||||||
INCBC, //0x03
|
INCBC, //0x03
|
||||||
INCB, //0x04
|
INCB, //0x04
|
||||||
DECB, //0x05
|
DECB, //0x05
|
||||||
LD8B, //0x06
|
LDBd8, //0x06
|
||||||
RLCA, //0x07
|
RLCA, //0x07
|
||||||
|
LDa16SP, //0x08
|
||||||
|
ADDHLBC, //0x09
|
||||||
|
LDABC, //0x0A
|
||||||
|
DECBC, //0x0B
|
||||||
|
INCC, //0x0C
|
||||||
|
DECC, //0x0D
|
||||||
|
LDCd8, //0x0E
|
||||||
|
RRRCA, //0x0F
|
||||||
}
|
}
|
||||||
|
|||||||
7
journal/Day 3 - 2025.06.30.md
Normal file
7
journal/Day 3 - 2025.06.30.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# For the day:
|
||||||
|
- Understand the cpu flags and when they are set
|
||||||
|
|
||||||
|
# Conclusion
|
||||||
|
- Wrote helper functions for setting the flags after addition/subtraction
|
||||||
|
- Understood when the half-carry flag is set in addtions and subtractions
|
||||||
|
- ?The carry flag is not set of INC and DEC operations?
|
||||||
Reference in New Issue
Block a user