Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,11 @@ func (c *CPU) Store8(addr uint32, val uint8) {
c.inter.Store8(addr, val)
}

func (c *CPU) Load32(addr uint32) uint32 { //load 32-bit from inter
return c.inter.Load32(addr)
}


func (c *CPU) Load16(addr uint32) uint16 {
return c.inter.Load16(addr)
}
Expand Down Expand Up @@ -1098,9 +1103,11 @@ func (c *CPU) Decode_and_execute(inst Instruction) {
}
}

func (c *CPU) Run_next() {
func (c *CPU) Run_next(d Debugger) {
c.current_pc = c.pc

d.PcChange(*c)

if c.current_pc % 4 != 0 {
c.Exception(LoadAddressError)
return
Expand All @@ -1121,8 +1128,8 @@ func (c *CPU) Run_next() {
c.reg = c.out_reg
}

func (c *CPU) Load32(addr uint32) uint32 { //load 32-bit from inter
return c.inter.Load32(addr)
func (c *CPU) Pc() uint32 {
return c.pc
}

func (c *CPU) Exception(cause Exception) { //Trigger Exception
Expand Down
108 changes: 108 additions & 0 deletions debugger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package main

import (
"fmt"
)

type Debugger struct {
breakpoints []uint32
readWatchpoints []uint32
writeWatchpoints []uint32
}

func (d *Debugger) AddBreakpoint(addr uint32) {
for _, breakpoint := range d.breakpoints {
if breakpoint == addr {
return
}
}
d.breakpoints = append(d.breakpoints, addr)
}

func (d *Debugger) AddReadBreakpoint(addr uint32) {
for _, watchpoint := range d.readWatchpoints {
if watchpoint == addr {
return
}
}
d.readWatchpoints = append(d.readWatchpoints, addr)
}

func (d *Debugger) AddWriteBreakpoint(addr uint32) {
for _, watchpoint := range d.writeWatchpoints {
if watchpoint == addr {
return
}
}
d.writeWatchpoints = append(d.writeWatchpoints, addr)
}

func (d *Debugger) DelBreakpoint(addr uint32) {
// Retain only the breakpoints that are not equal to addr
newBreakpoints := d.breakpoints[:0]
for _, breakpoint := range d.breakpoints {
if breakpoint != addr {
newBreakpoints = append(newBreakpoints, breakpoint)
}
}
d.breakpoints = newBreakpoints
}

func (d *Debugger) DelReadWatchpoint(addr uint32) {
// Retain only the watchpoints that are not equal to addr
newWatchpoints := d.readWatchpoints[:0]
for _, watchpoint := range d.readWatchpoints {
if watchpoint != addr {
newWatchpoints = append(newWatchpoints, watchpoint)
}
}
d.readWatchpoints = newWatchpoints
}

func (d *Debugger) DelWriteWatchpoint(addr uint32) {
// Retain only the watchpoints that are not equal to addr
newWatchpoints := d.writeWatchpoints[:0]
for _, watchpoint := range d.writeWatchpoints {
if watchpoint != addr {
newWatchpoints = append(newWatchpoints, watchpoint)
}
}
d.writeWatchpoints = newWatchpoints
}

func (d *Debugger) MemoryRead(cpu *CPU, addr uint32) {
// Handle unaligned watchpoints if necessary
for _, watchpoint := range d.readWatchpoints {
if watchpoint == addr {
fmt.Printf("Read watchpoint triggered at 0x%08X\n", addr)
d.Debug(*cpu)
}
}
}

func (d *Debugger) MemoryWrite(cpu *CPU, addr uint32) {
// Handle unaligned watchpoints if necessary
for _, watchpoint := range d.writeWatchpoints {
if watchpoint == addr {
fmt.Printf("Write watchpoint triggered at 0x%08X\n", addr)
d.Debug(*cpu)
}
}
}

func (d *Debugger) PcChange(c CPU) {
for _, breakpoint := range d.breakpoints {
if c.pc == breakpoint {
d.Debug(c)
}
}
}

func (d *Debugger) Debug(c CPU) {
fmt.Println("CPU State:")
fmt.Printf("PC: 0x%08X\n", c.pc)
fmt.Println("Registers:")
for i, reg := range c.reg {
fmt.Printf("R%d: 0x%08X\n", i, reg)
}
}
25 changes: 25 additions & 0 deletions gpu/gpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,4 +608,29 @@ func Gp0DrawOffsetWrapper(g *GPU, val uint32) {

func Gp0MaskBitSettingWrapper(g *GPU, val uint32) {
g.Gp0MaskBitSetting(val)
}

func (g *GPU) load(offset uint32) uint32 {
var r uint32
switch offset {
case 0:
r = g.Read()
case 4:
r = g.Status()
default:
panic("unreachable!")
}

return r
}

func (g *GPU) store(offset uint32, val uint32) {
switch offset {
case 0:
g.Gp0(val)
case 4:
g.Gp1(val)
default:
panic("unreachable!")
}
}
24 changes: 17 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,28 @@ func main() {
cpu := &CPU{}
cpu.New(inter)
fmt.Println(cpu.reg[0])
debugger := Debugger{}

for{
for i := 0; i < 1000000; i++ {
cpu.Run_next()
}
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch event.(type) {
for {
for i := 0; i < 1000000; i++ {
cpu.Run_next(debugger)
}
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch e := event.(type) {
case *sdl.KeyboardEvent:
if e.Type == sdl.KEYDOWN {
switch e.Keysym.Sym {
case sdl.K_PAUSE:
debugger.Debug(*cpu)
case sdl.K_ESCAPE:
return
}
}
case *sdl.QuitEvent:
return
}
}
}
}
}

func CheckForErrors() {
Expand Down