z80go/cpu.go

164 lines
3.3 KiB
Go

package z80go
import (
"errors"
)
const (
MemAccessRead = 1
MemAccessWrite = 2
)
// NewCPU initializes a Z80 CPU instance and return pointer to it
func NewCPU(core MemIoRW) *CPU {
z := CPU{}
z.Reset()
z.core = core
z.cycleCount = 0
z.codeCoverageEnabled = false
// z.codeCoverage = make(map[uint16]bool)
// z.memAccess =
z.codeCoverageEnabled = false
// z.codeCoverage map[uint16]bool
z.extendedStackEnabled = false
//z.extendedStack [65536]uint8
return &z
}
// RunInstruction executes the next instruction in memory + handles interrupts
func (z *CPU) RunInstruction() (uint32, *map[uint16]byte) {
z.memAccess = map[uint16]byte{}
if z.codeCoverageEnabled {
z.codeCoverage[z.PC] = true
}
pre := z.cycleCount
if z.Halted {
z.execOpcode(0x00)
} else {
opcode := z.nextB()
z.execOpcode(opcode)
}
z.processInterrupts()
return z.cycleCount - pre, &z.memAccess
}
// SetState set current CPU state
// Used by debuggers to override CPU state, set new PC, for example
func (z *CPU) SetState(state *CPU) {
z.A = state.A
z.B = state.B
z.C = state.C
z.D = state.D
z.E = state.E
z.H = state.H
z.L = state.L
z.AAlt = state.AAlt
z.BAlt = state.BAlt
z.CAlt = state.CAlt
z.DAlt = state.DAlt
z.EAlt = state.EAlt
z.HAlt = state.HAlt
z.LAlt = state.LAlt
z.PC = state.PC
z.SP = state.SP
z.IX = state.IX
z.IY = state.IY
z.I = state.I
z.R = state.R
z.Flags.S = state.Flags.S
z.Flags.Z = state.Flags.Z
z.Flags.Y = state.Flags.Y
z.Flags.H = state.Flags.H
z.Flags.X = state.Flags.X
z.Flags.P = state.Flags.P
z.Flags.N = state.Flags.N
z.Flags.C = state.Flags.C
z.IMode = state.IMode
z.Iff1 = state.Iff1
z.Iff2 = state.Iff2
z.Halted = state.Halted
z.IntOccurred = state.IntOccurred
z.NmiOccurred = false
}
func (z *CPU) GetState() *CPU {
return &CPU{
A: z.A,
B: z.B,
C: z.C,
D: z.D,
E: z.E,
H: z.H,
L: z.L,
AAlt: z.AAlt,
BAlt: z.BAlt,
CAlt: z.CAlt,
DAlt: z.DAlt,
EAlt: z.EAlt,
HAlt: z.HAlt,
LAlt: z.LAlt,
IX: z.IX,
IY: z.IY,
I: z.I,
R: z.R,
SP: z.SP,
PC: z.PC,
Flags: z.flags(),
FlagsAlt: z.altFlags(),
IMode: z.IMode,
Iff1: z.Iff1,
Iff2: z.Iff2,
Halted: z.Halted,
CycleCount: z.cycleCount,
IntOccurred: z.IntOccurred,
NmiOccurred: z.NmiOccurred,
memPtr: z.memPtr,
}
}
//func (z *CPU) PC() uint16 {
// return z.PC
//}
// ClearCodeCoverage - clears code coverage journal
func (z *CPU) ClearCodeCoverage() {
clear(z.codeCoverage)
}
// SetCodeCoverage - enable of disable code coverage journal
func (z *CPU) SetCodeCoverage(enabled bool) {
z.codeCoverageEnabled = enabled
if !enabled {
clear(z.codeCoverage)
}
}
// CodeCoverage - return list of addresses executed by CPU
func (z *CPU) CodeCoverage() map[uint16]bool {
return z.codeCoverage
}
// SetExtendedStack - enable or disable marking stack values by PushValueType*
func (z *CPU) SetExtendedStack(enabled bool) {
z.extendedStackEnabled = enabled
if enabled {
for addr := 0; addr < 65536; addr++ {
z.extendedStack[addr] = PushValueTypeDefault
}
}
}
// ExtendedStack - return array with markers of PushValueType* for each byte of memory
func (z *CPU) ExtendedStack() ([]byte, error) {
var err error
if !z.extendedStackEnabled {
err = errors.New("error, z80: ExtendedStack disabled")
}
return z.extendedStack[:], err
}