diff --git a/cpu.go b/cpu.go index 55e2af4..fafd778 100644 --- a/cpu.go +++ b/cpu.go @@ -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) } @@ -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 @@ -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 diff --git a/debugger.go b/debugger.go new file mode 100644 index 0000000..a772330 --- /dev/null +++ b/debugger.go @@ -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) + } +} \ No newline at end of file diff --git a/gpu/gpu.go b/gpu/gpu.go index 8a75ad7..ef26e24 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -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!") + } } \ No newline at end of file diff --git a/main.go b/main.go index 3b54e22..7ccb46f 100644 --- a/main.go +++ b/main.go @@ -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() {