apple2-go/utils/utils.go

81 lines
2.0 KiB
Go

package utils
import (
"compress/gzip"
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/freewilll/apple2-go/cpu"
"github.com/freewilll/apple2-go/system"
)
// ReadMemoryFromGzipFile just reads and uncompresses a gzip file
func ReadMemoryFromGzipFile(filename string) (data []byte, err error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
reader, err := gzip.NewReader(f)
if err != nil {
return nil, err
}
defer reader.Close()
data, err = ioutil.ReadAll(reader)
return
}
// DecodeCmdLineAddress decodes a 4 byte string hex address
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
}
// RunUntilBreakPoint runs the CPU until it either hits a breakpoint or a time
// has expired. An assertion is done at the end to ensure the breakpoint has
// been reached.
func RunUntilBreakPoint(t *testing.T, breakAddress uint16, seconds int, showInstructions bool, message string) {
fmt.Printf("Running until %#04x: %s \n", breakAddress, message)
system.LastAudioCycles = 0
exitAtBreak := false
disableFirmwareWait := false
cpu.Run(showInstructions, &breakAddress, exitAtBreak, disableFirmwareWait, uint64(system.CPUFrequency*seconds))
if cpu.State.PC != breakAddress {
t.Fatalf("Did not reach breakpoint at %04x. Got to %04x", breakAddress, cpu.State.PC)
}
}
// Disassemble disassembles and prints the code in memory between start and end
func Disassemble(start uint16, end uint16) {
oldPC := cpu.State.PC
cpu.State.PC = start
for cpu.State.PC <= end {
cpu.PrintInstruction(false)
cpu.AdvanceInstruction()
}
cpu.State.PC = oldPC
}