Skip to content

Commit

Permalink
feat: add disassembler
Browse files Browse the repository at this point in the history
  • Loading branch information
gaoliveira21 committed Jan 20, 2024
1 parent 0948873 commit a0dba91
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 72 deletions.
2 changes: 2 additions & 0 deletions core/chip8.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func (c8 *Chip8) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHei
}

func RunChip8(rom []byte, title string) {
Disassemble(rom)

c := cpu.NewCpu()
c.LoadROM(rom)

Expand Down
96 changes: 48 additions & 48 deletions core/cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ func (cpu *CPU) clock() {

opcode := cpu.decode(data)

switch opcode.instruction {
switch opcode.Instruction {
case 0x0000:
if opcode.registerY == 0xC {
cpu.scd(opcode.n)
if opcode.RegisterY == 0xC {
cpu.scd(opcode.N)
return
}

switch opcode.nnn {
switch opcode.NNN {
case 0x0E0:
cpu.cls()

Expand All @@ -124,91 +124,91 @@ func (cpu *CPU) clock() {
cpu.ext()

default:
cpu.jp(opcode.nnn, 0)
cpu.jp(opcode.NNN, 0)
}
case 0x1000:
cpu.jp(opcode.nnn, 0)
cpu.jp(opcode.NNN, 0)
case 0x2000:
cpu.call(opcode.nnn)
cpu.call(opcode.NNN)
case 0x3000:
cpu.skp(cpu.v[opcode.registerX] == opcode.nn)
cpu.skp(cpu.v[opcode.RegisterX] == opcode.NN)
case 0x4000:
cpu.skp(cpu.v[opcode.registerX] != opcode.nn)
cpu.skp(cpu.v[opcode.RegisterX] != opcode.NN)
case 0x5000:
cpu.skp(cpu.v[opcode.registerX] == cpu.v[opcode.registerY])
cpu.skp(cpu.v[opcode.RegisterX] == cpu.v[opcode.RegisterY])
case 0x6000:
cpu.ld(opcode.registerX, opcode.nn)
cpu.ld(opcode.RegisterX, opcode.NN)
case 0x7000:
cpu.add(opcode.registerX, opcode.nn, false)
cpu.add(opcode.RegisterX, opcode.NN, false)
case 0x8000:
switch opcode.n {
switch opcode.N {
case 0x0:
cpu.ld(opcode.registerX, cpu.v[opcode.registerY])
cpu.ld(opcode.RegisterX, cpu.v[opcode.RegisterY])
case 0x1:
cpu.or(opcode.registerX, cpu.v[opcode.registerY])
cpu.or(opcode.RegisterX, cpu.v[opcode.RegisterY])
case 0x2:
cpu.and(opcode.registerX, cpu.v[opcode.registerY])
cpu.and(opcode.RegisterX, cpu.v[opcode.RegisterY])
case 0x3:
cpu.xor(opcode.registerX, cpu.v[opcode.registerY])
cpu.xor(opcode.RegisterX, cpu.v[opcode.RegisterY])
case 0x4:
cpu.add(opcode.registerX, cpu.v[opcode.registerY], true)
cpu.add(opcode.RegisterX, cpu.v[opcode.RegisterY], true)
case 0x5:
cpu.sub(opcode.registerX, cpu.v[opcode.registerX], cpu.v[opcode.registerY])
cpu.sub(opcode.RegisterX, cpu.v[opcode.RegisterX], cpu.v[opcode.RegisterY])
case 0x6:
cpu.shr(opcode.registerX)
cpu.shr(opcode.RegisterX)
case 0x7:
cpu.sub(opcode.registerX, cpu.v[opcode.registerY], cpu.v[opcode.registerX])
cpu.sub(opcode.RegisterX, cpu.v[opcode.RegisterY], cpu.v[opcode.RegisterX])
case 0xE:
cpu.shl(opcode.registerX)
cpu.shl(opcode.RegisterX)
}
case 0x9000:
cpu.skp(cpu.v[opcode.registerX] != cpu.v[opcode.registerY])
cpu.skp(cpu.v[opcode.RegisterX] != cpu.v[opcode.RegisterY])
case 0xA000:
cpu.ldi(opcode.nnn)
cpu.ldi(opcode.NNN)
case 0xB000:
cpu.jp(opcode.nnn, cpu.v[0x0])
cpu.jp(opcode.NNN, cpu.v[0x0])
case 0xC000:
cpu.rnd(opcode.registerX, opcode.nn)
cpu.rnd(opcode.RegisterX, opcode.NN)
case 0xD000:
switch opcode.n {
switch opcode.N {
case 0x0:
cpu.schip_drw(opcode)
default:
cpu.drw(opcode)
}
case 0xE000:
switch opcode.nn {
switch opcode.NN {
case 0x9E:
cpu.skp(cpu.Keys[cpu.v[opcode.registerX]] == 0x01)
cpu.skp(cpu.Keys[cpu.v[opcode.RegisterX]] == 0x01)
case 0xA1:
cpu.skp(cpu.Keys[cpu.v[opcode.registerX]] == 0x00)
cpu.skp(cpu.Keys[cpu.v[opcode.RegisterX]] == 0x00)
}
case 0xF000:
switch opcode.nn {
switch opcode.NN {
case 0x07:
cpu.ld(opcode.registerX, cpu.delayTimer)
cpu.ld(opcode.RegisterX, cpu.delayTimer)
case 0x15:
cpu.ldt(cpu.v[opcode.registerX])
cpu.ldt(cpu.v[opcode.RegisterX])
case 0x18:
cpu.lds(cpu.v[opcode.registerX])
cpu.lds(cpu.v[opcode.RegisterX])
case 0x0A:
cpu.ldk(opcode.registerX)
cpu.ldk(opcode.RegisterX)
case 0x1E:
cpu.adi(uint16(cpu.v[opcode.registerX]))
cpu.adi(uint16(cpu.v[opcode.RegisterX]))
case 0x29:
cpu.ldi(0x050 + 5*uint16(cpu.v[opcode.registerX]))
cpu.ldi(0x050 + 5*uint16(cpu.v[opcode.RegisterX]))
case 0x30:
cpu.ldi(0x0A0 + 10*uint16(cpu.v[opcode.registerX]))
cpu.ldi(0x0A0 + 10*uint16(cpu.v[opcode.RegisterX]))
case 0x33:
cpu.bcd(cpu.v[opcode.registerX])
cpu.bcd(cpu.v[opcode.RegisterX])
case 0x55:
cpu.stm(opcode.registerX)
cpu.stm(opcode.RegisterX)
case 0x65:
cpu.ldm(opcode.registerX)
cpu.ldm(opcode.RegisterX)
case 0x75:
cpu.srpl(opcode.registerX)
cpu.srpl(opcode.RegisterX)
case 0x85:
cpu.lrpl(opcode.registerX)
cpu.lrpl(opcode.RegisterX)
}
}
}
Expand Down Expand Up @@ -346,11 +346,11 @@ func (cpu *CPU) ldm(vIndex uint8) {
}

func (cpu *CPU) drw(oc *opcode) {
x := cpu.v[oc.registerX] & (byte(cpu.Graphics.Width - 1))
y := cpu.v[oc.registerY] & (byte(cpu.Graphics.Height - 1))
x := cpu.v[oc.RegisterX] & (byte(cpu.Graphics.Width - 1))
y := cpu.v[oc.RegisterY] & (byte(cpu.Graphics.Height - 1))
cpu.v[0xF] = 0x00

for i := 0; uint8(i) < oc.n; i++ {
for i := 0; uint8(i) < oc.N; i++ {
addr := uint16(i) + cpu.i
pixels := byte(cpu.mmu.Fetch(addr) >> 8)
xIndex := x
Expand Down Expand Up @@ -418,8 +418,8 @@ func (cpu *CPU) lrpl(x uint8) {
}

func (cpu *CPU) schip_drw(oc *opcode) {
x := cpu.v[oc.registerX] & (byte(cpu.Graphics.Width - 1))
y := cpu.v[oc.registerY] & (byte(cpu.Graphics.Height - 1))
x := cpu.v[oc.RegisterX] & (byte(cpu.Graphics.Width - 1))
y := cpu.v[oc.RegisterY] & (byte(cpu.Graphics.Height - 1))
cpu.v[0xF] = 0x00

n := 16
Expand Down
24 changes: 12 additions & 12 deletions core/cpu/opcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ const (
)

type opcode struct {
instruction uint16
registerX uint8
registerY uint8
n uint8
nn uint8
nnn uint16
Instruction uint16
RegisterX uint8
RegisterY uint8
N uint8
NN uint8
NNN uint16
}

func NewOpcode(data uint16) *opcode {
return &opcode{
instruction: data & INSTRUCTION_BITMASK,
registerX: uint8((data & X_BITMASK) >> 8),
registerY: uint8((data & Y_BITMASK) >> 4),
n: uint8(data & N_BITMASK),
nn: uint8(data & NN_BITMASK),
nnn: (data & NNN_BITMASK),
Instruction: data & INSTRUCTION_BITMASK,
RegisterX: uint8((data & X_BITMASK) >> 8),
RegisterY: uint8((data & Y_BITMASK) >> 4),
N: uint8(data & N_BITMASK),
NN: uint8(data & NN_BITMASK),
NNN: (data & NNN_BITMASK),
}
}
24 changes: 12 additions & 12 deletions core/cpu/opcode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,32 @@ func TestDecode(t *testing.T) {

var expected uint16 = 0xA000

if opcode.instruction != expected {
t.Errorf("opcode.instruction = 0x%X; expected 0x%X", opcode.instruction, expected)
if opcode.Instruction != expected {
t.Errorf("opcode.Instruction = 0x%X; expected 0x%X", opcode.Instruction, expected)
}

expected = 0xB
if opcode.registerX != uint8(expected) {
t.Errorf("opcode.registerX = 0x%X; expected 0x%X", opcode.registerX, expected)
if opcode.RegisterX != uint8(expected) {
t.Errorf("opcode.RegisterX = 0x%X; expected 0x%X", opcode.RegisterX, expected)
}

expected = 0xC
if opcode.registerY != uint8(expected) {
t.Errorf("opcode.registerY = 0x%X; expected 0x%X", opcode.registerY, expected)
if opcode.RegisterY != uint8(expected) {
t.Errorf("opcode.RegisterY = 0x%X; expected 0x%X", opcode.RegisterY, expected)
}

expected = 0xD
if opcode.n != uint8(expected) {
t.Errorf("opcode.n = 0x%X; expected 0x%X", opcode.n, expected)
if opcode.N != uint8(expected) {
t.Errorf("opcode.N = 0x%X; expected 0x%X", opcode.N, expected)
}

expected = 0xCD
if opcode.nn != uint8(expected) {
t.Errorf("opcode.n = 0x%X; expected 0x%X", opcode.nn, expected)
if opcode.NN != uint8(expected) {
t.Errorf("opcode.NN = 0x%X; expected 0x%X", opcode.NN, expected)
}

expected = 0xBCD
if opcode.nnn != expected {
t.Errorf("opcode.n = 0x%X; expected 0x%X", opcode.nnn, expected)
if opcode.NNN != expected {
t.Errorf("opcode.NNN = 0x%X; expected 0x%X", opcode.NNN, expected)
}
}
Loading

0 comments on commit a0dba91

Please sign in to comment.