Added command line disassembler

This commit is contained in:
Will Angenent 2018-05-10 13:32:42 +01:00
parent f8ca059f18
commit 7ec43f0299
5 changed files with 94 additions and 44 deletions

36
cmd/disasm.go Normal file
View File

@ -0,0 +1,36 @@
package main
import (
"flag"
"mos6502go/cpu"
"mos6502go/mmu"
"mos6502go/utils"
)
func main() {
startString := flag.String("start", "", "Start address")
endString := flag.String("end", "", "End address")
flag.Parse()
startAddress := utils.DecodeCmdLineAddress(startString)
endAddress := utils.DecodeCmdLineAddress(endString)
if startAddress == nil {
panic("Must include -start")
}
if endAddress == nil {
e := uint16(0xffff)
endAddress = &e
}
cpu.InitInstructionDecoder()
mmu.InitApple2eROM()
cpu.State.PC = *startAddress
for cpu.State.PC <= *endAddress {
cpu.PrintInstruction(false)
cpu.AdvanceInstruction()
}
}

View File

@ -1,7 +1,6 @@
package main
import (
"encoding/hex"
"flag"
"fmt"
"mos6502go/cpu"
@ -18,6 +17,8 @@ func main() {
breakAddressString := flag.String("break", "", "Break on address")
flag.Parse()
breakAddress := utils.DecodeCmdLineAddress(breakAddressString)
cpu.InitInstructionDecoder()
mmu.InitRAM()
@ -69,24 +70,6 @@ func main() {
mmu.PageTable[0xc0+i] = RomPretendingToBeRAM[i*0x100 : i*0x100+0x100]
}
var breakAddress *uint16
if *breakAddressString != "" {
breakAddressValue, err := hex.DecodeString(*breakAddressString)
if err != nil {
panic(err)
}
var foo uint16
if len(breakAddressValue) == 1 {
foo = uint16(breakAddressValue[0])
} else if len(breakAddressValue) == 2 {
foo = uint16(breakAddressValue[0])*uint16(0x100) + uint16(breakAddressValue[1])
} else {
panic("Invalid break address")
}
breakAddress = &foo
}
keyboard.Init()
cpu.Run(*showInstructions, breakAddress, false, 0)

View File

@ -561,7 +561,7 @@ func Run(showInstructions bool, breakAddress *uint16, disableBell bool, wantedCy
}
if showInstructions {
PrintInstruction()
PrintInstruction(true)
}
opcode := mmu.ReadMemory(State.PC)

View File

@ -14,30 +14,32 @@ func printFlag(p byte, flag uint8, code string) {
}
}
func printInstruction(instruction string) {
fmt.Printf("%04x %-24s A=%02x X=%02x Y=%02x S=%02x P=%02x ",
State.PC,
instruction,
State.A,
State.X,
State.Y,
State.SP,
State.P,
)
func printInstruction(instruction string, showRegisters bool) {
fmt.Printf("%04x- %-24s", State.PC, instruction)
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")
if showRegisters {
fmt.Printf(" A=%02x X=%02x Y=%02x S=%02x P=%02x ",
State.A,
State.X,
State.Y,
State.SP,
State.P,
)
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")
}
fmt.Println("")
}
func PrintInstruction() {
func PrintInstruction(showRegisters bool) {
opcodeValue := mmu.PageTable[(State.PC)>>8][(State.PC)&0xff]
opcode := OpCodes[opcodeValue]
mnemonic := opcode.Mnemonic
@ -46,7 +48,7 @@ func PrintInstruction() {
var value uint16
if size == 0 {
printInstruction(fmt.Sprintf("%02x %s", opcodeValue, mnemonic))
printInstruction(fmt.Sprintf("%02x %s", opcodeValue, mnemonic), showRegisters)
return
}
@ -63,20 +65,27 @@ func PrintInstruction() {
}
suffix = fmt.Sprintf(stringFormat, relativeAddress)
opcodes = fmt.Sprintf("%02x %02x ", opcodeValue, value)
opcodes = fmt.Sprintf("%02x %02x ", opcodeValue, value)
} else if size == 1 {
value = uint16(mmu.PageTable[(State.PC+1)>>8][(State.PC+1)&0xff])
suffix = fmt.Sprintf(stringFormat, value)
opcodes = fmt.Sprintf("%02x %02x ", opcodeValue, value)
opcodes = fmt.Sprintf("%02x %02x ", opcodeValue, value)
} else if size == 2 {
lsb := mmu.PageTable[(State.PC+1)>>8][(State.PC+1)&0xff]
msb := mmu.PageTable[(State.PC+2)>>8][(State.PC+2)&0xff]
value = uint16(lsb) + uint16(msb)*0x100
suffix = fmt.Sprintf(stringFormat, value)
opcodes = fmt.Sprintf("%02x %02x %02x ", opcodeValue, lsb, msb)
opcodes = fmt.Sprintf("%02x %02x %02x ", opcodeValue, lsb, msb)
}
printInstruction(fmt.Sprintf("%s %s %s", opcodes, mnemonic, suffix))
printInstruction(fmt.Sprintf("%s %s %s", opcodes, mnemonic, suffix), showRegisters)
}
func AdvanceInstruction() {
opcodeValue := mmu.PageTable[(State.PC)>>8][(State.PC)&0xff]
opcode := OpCodes[opcodeValue]
size := opcode.AddressingMode.OperandSize + 1
State.PC += uint16(size)
}
func DumpMemory(offset uint16) {

View File

@ -2,6 +2,7 @@ package utils
import (
"compress/gzip"
"encoding/hex"
"io/ioutil"
"os"
)
@ -22,3 +23,24 @@ func ReadMemoryFromGzipFile(filename string) (data []byte, err error) {
return
}
func DecodeCmdLineAddress(s *string) (result *uint16) {
if *s != "" {
breakAddressValue, err := hex.DecodeString(*s)
if err != nil {
panic(err)
}
var value uint16
if len(breakAddressValue) == 1 {
value = uint16(breakAddressValue[0])
} else if len(breakAddressValue) == 2 {
value = uint16(breakAddressValue[0])*uint16(0x100) + uint16(breakAddressValue[1])
} else {
panic("Invalid break address")
}
result = &value
}
return result
}