apple2-go/cpu/debug.go

113 lines
3.1 KiB
Go
Raw Normal View History

2018-04-29 19:41:11 +00:00
package cpu
import (
"fmt"
"strings"
2018-05-27 10:05:00 +00:00
2019-11-02 13:33:05 +00:00
"github.com/freewilll/apple2-go/mmu"
2018-04-29 19:41:11 +00:00
)
// printFlag prints a lower or uppercase letter depending on the state of the flag
2018-04-29 19:41:11 +00:00
func printFlag(p byte, flag uint8, code string) {
if (p & flag) == 0 {
fmt.Print(code)
} else {
fmt.Printf("%s", strings.ToUpper(code))
}
}
// printInstruction prings a single instruction and optionally also registers
2018-05-10 12:32:42 +00:00
func printInstruction(instruction string, showRegisters bool) {
fmt.Printf("%04x- %-24s", State.PC, instruction)
2018-04-29 19:41:11 +00:00
2018-05-10 12:32:42 +00:00
if showRegisters {
fmt.Printf(" A=%02x X=%02x Y=%02x S=%02x P=%02x ",
State.A,
State.X,
State.Y,
State.SP,
State.P,
)
2018-05-28 16:31:52 +00:00
printFlag(State.P, cpuFlagN, "n")
printFlag(State.P, cpuFlagV, "v")
fmt.Print("-") // cpuFlagR flag that's always 1
printFlag(State.P, cpuFlagB, "b")
printFlag(State.P, cpuFlagD, "d")
printFlag(State.P, cpuFlagI, "i")
printFlag(State.P, cpuFlagZ, "z")
printFlag(State.P, cpuFlagC, "c")
2018-05-10 12:32:42 +00:00
}
2018-04-29 19:41:11 +00:00
fmt.Println("")
}
// PrintInstruction prints the instruction at the current PC
2018-05-10 12:32:42 +00:00
func PrintInstruction(showRegisters bool) {
2018-05-20 10:02:08 +00:00
opcodeValue := mmu.ReadPageTable[(State.PC)>>8][(State.PC)&0xff]
opcode := opCodes[opcodeValue]
mnemonic := opcode.mnemonic
size := opcode.addressingMode.operandSize
stringFormat := opcode.addressingMode.stringFormat
2018-04-29 19:41:11 +00:00
var value uint16
if size == 0 {
2018-05-10 12:32:42 +00:00
printInstruction(fmt.Sprintf("%02x %s", opcodeValue, mnemonic), showRegisters)
2018-04-29 19:41:11 +00:00
return
}
var opcodes string
var suffix string
if opcode.addressingMode.mode == amRelative {
2018-05-20 10:02:08 +00:00
value = uint16(mmu.ReadPageTable[(State.PC+1)>>8][(State.PC+1)&0xff])
2018-04-29 19:41:11 +00:00
var relativeAddress uint16
if (value & 0x80) == 0 {
relativeAddress = State.PC + 2 + uint16(value)
2018-04-29 19:41:11 +00:00
} else {
relativeAddress = State.PC + 2 + uint16(value) - 0x100
2018-04-29 19:41:11 +00:00
}
suffix = fmt.Sprintf(stringFormat, relativeAddress)
2018-05-10 12:32:42 +00:00
opcodes = fmt.Sprintf("%02x %02x ", opcodeValue, value)
2018-04-29 19:41:11 +00:00
} else if size == 1 {
2018-05-20 10:02:08 +00:00
value = uint16(mmu.ReadPageTable[(State.PC+1)>>8][(State.PC+1)&0xff])
2018-04-29 19:41:11 +00:00
suffix = fmt.Sprintf(stringFormat, value)
2018-05-10 12:32:42 +00:00
opcodes = fmt.Sprintf("%02x %02x ", opcodeValue, value)
2018-04-29 19:41:11 +00:00
} else if size == 2 {
2018-05-20 10:02:08 +00:00
lsb := mmu.ReadPageTable[(State.PC+1)>>8][(State.PC+1)&0xff]
msb := mmu.ReadPageTable[(State.PC+2)>>8][(State.PC+2)&0xff]
value = uint16(lsb) + uint16(msb)*0x100
2018-04-29 19:41:11 +00:00
suffix = fmt.Sprintf(stringFormat, value)
2018-05-10 12:32:42 +00:00
opcodes = fmt.Sprintf("%02x %02x %02x ", opcodeValue, lsb, msb)
2018-04-29 19:41:11 +00:00
}
2018-05-10 12:32:42 +00:00
printInstruction(fmt.Sprintf("%s %s %s", opcodes, mnemonic, suffix), showRegisters)
}
// AdvanceInstruction goes forward one instruction without executing anything
2018-05-10 12:32:42 +00:00
func AdvanceInstruction() {
2018-05-20 10:02:08 +00:00
opcodeValue := mmu.ReadPageTable[(State.PC)>>8][(State.PC)&0xff]
opcode := opCodes[opcodeValue]
size := opcode.addressingMode.operandSize + 1
2018-05-10 12:32:42 +00:00
State.PC += uint16(size)
2018-04-29 19:41:11 +00:00
}
// DumpMemory dumps $100 bytes of memory
func DumpMemory(offset uint16) {
2018-04-29 19:41:11 +00:00
var i uint16
for i = 0; i < 0x100; i++ {
if (i & 0xf) == 8 {
fmt.Print(" ")
}
if (i & 0xf) == 0 {
if i > 0 {
fmt.Print("\n")
}
fmt.Printf("%04x ", offset+i)
}
2018-05-20 10:02:08 +00:00
fmt.Printf(" %02x", mmu.ReadPageTable[(offset+i)>>8][(offset+i)&0xff])
2018-04-29 19:41:11 +00:00
}
fmt.Print("\n")
}