mirror of
https://github.com/romychs/z80go.git
synced 2026-04-16 08:44:20 +03:00
227 lines
4.0 KiB
Go
227 lines
4.0 KiB
Go
package z80go
|
|
|
|
import log "github.com/sirupsen/logrus"
|
|
|
|
func (z *CPU) flags() FlagsType {
|
|
return FlagsType{
|
|
S: z.Flags.S,
|
|
Z: z.Flags.Z,
|
|
Y: z.Flags.Y,
|
|
H: z.Flags.H,
|
|
X: z.Flags.X,
|
|
P: z.Flags.P,
|
|
N: z.Flags.N,
|
|
C: z.Flags.C,
|
|
}
|
|
}
|
|
|
|
func (z *CPU) altFlags() FlagsType {
|
|
return FlagsType{
|
|
S: z.FlagsAlt.S,
|
|
Z: z.FlagsAlt.Z,
|
|
Y: z.FlagsAlt.Y,
|
|
H: z.FlagsAlt.H,
|
|
X: z.FlagsAlt.X,
|
|
P: z.FlagsAlt.P,
|
|
N: z.FlagsAlt.N,
|
|
C: z.FlagsAlt.C,
|
|
}
|
|
}
|
|
|
|
func (z *CPU) rb(addr uint16) byte {
|
|
z.memAccess[addr] = MemAccessRead
|
|
return z.core.MemRead(addr)
|
|
}
|
|
|
|
func (z *CPU) wb(addr uint16, val byte) {
|
|
z.memAccess[addr] = MemAccessWrite
|
|
z.core.MemWrite(addr, val)
|
|
}
|
|
|
|
func (z *CPU) rw(addr uint16) uint16 {
|
|
z.memAccess[addr] = MemAccessRead
|
|
z.memAccess[addr+1] = MemAccessRead
|
|
return (uint16(z.core.MemRead(addr+1)) << 8) | uint16(z.core.MemRead(addr))
|
|
}
|
|
|
|
func (z *CPU) ww(addr uint16, val uint16) {
|
|
z.memAccess[addr] = MemAccessWrite
|
|
z.memAccess[addr+1] = MemAccessWrite
|
|
z.core.MemWrite(addr, byte(val))
|
|
z.core.MemWrite(addr+1, byte(val>>8))
|
|
}
|
|
|
|
func (z *CPU) pushW(val uint16) {
|
|
z.SP -= 2
|
|
z.ww(z.SP, val)
|
|
z.extendedStack[z.SP] = PushValueTypePush
|
|
}
|
|
|
|
func (z *CPU) popW() uint16 {
|
|
z.SP += 2
|
|
return z.rw(z.SP - 2)
|
|
}
|
|
|
|
func (z *CPU) nextB() byte {
|
|
b := z.core.MemRead(z.PC)
|
|
z.PC++
|
|
return b
|
|
}
|
|
|
|
func (z *CPU) nextW() uint16 {
|
|
w := (uint16(z.core.MemRead(z.PC+1)) << 8) | uint16(z.core.MemRead(z.PC))
|
|
z.PC += 2
|
|
return w
|
|
}
|
|
|
|
func (z *CPU) bc() uint16 {
|
|
return (uint16(z.B) << 8) | uint16(z.C)
|
|
}
|
|
|
|
func (z *CPU) de() uint16 {
|
|
return (uint16(z.D) << 8) | uint16(z.E)
|
|
}
|
|
|
|
func (z *CPU) hl() uint16 {
|
|
return (uint16(z.H) << 8) | uint16(z.L)
|
|
}
|
|
|
|
func (z *CPU) setBC(val uint16) {
|
|
z.B = byte(val >> 8)
|
|
z.C = byte(val)
|
|
}
|
|
|
|
func (z *CPU) setDE(val uint16) {
|
|
z.D = byte(val >> 8)
|
|
z.E = byte(val)
|
|
}
|
|
|
|
func (z *CPU) setHL(val uint16) {
|
|
z.H = byte(val >> 8)
|
|
z.L = byte(val)
|
|
}
|
|
|
|
func (z *CPU) f() byte {
|
|
val := byte(0)
|
|
if z.Flags.C {
|
|
val |= 0x01
|
|
}
|
|
if z.Flags.N {
|
|
val |= 0x02
|
|
}
|
|
if z.Flags.P {
|
|
val |= 0x04
|
|
}
|
|
if z.Flags.X {
|
|
val |= 0x08
|
|
}
|
|
if z.Flags.H {
|
|
val |= 0x10
|
|
}
|
|
if z.Flags.Y {
|
|
val |= 0x20
|
|
}
|
|
if z.Flags.Z {
|
|
val |= 0x40
|
|
}
|
|
if z.Flags.S {
|
|
val |= 0x80
|
|
}
|
|
return val
|
|
}
|
|
|
|
func (z *CPU) setF(val byte) {
|
|
z.Flags.C = val&1 != 0
|
|
z.Flags.N = (val>>1)&1 != 0
|
|
z.Flags.P = (val>>2)&1 != 0
|
|
z.Flags.X = (val>>3)&1 != 0
|
|
z.Flags.H = (val>>4)&1 != 0
|
|
z.Flags.Y = (val>>5)&1 != 0
|
|
z.Flags.Z = (val>>6)&1 != 0
|
|
z.Flags.S = (val>>7)&1 != 0
|
|
}
|
|
|
|
// increments R, keeping the highest byte intact
|
|
func (z *CPU) incR() {
|
|
z.R = (z.R & 0x80) | ((z.R + 1) & 0x7f)
|
|
}
|
|
|
|
func boolToInt32(b bool) int32 {
|
|
if b {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// returns if there was a carry between bit "bit_no" and "bit_no - 1" when
|
|
// executing "a + b + cy"
|
|
func carry(bitNo int, a uint16, b uint16, cy bool) bool {
|
|
result := int32(a) + int32(b) + boolToInt32(cy)
|
|
carry := result ^ int32(a) ^ int32(b)
|
|
return (carry & (1 << bitNo)) != 0
|
|
}
|
|
|
|
// parity returns the parity of byte: 0 if odd, else 1
|
|
func parity(val byte) bool {
|
|
ones := byte(0)
|
|
for i := 0; i < 8; i++ {
|
|
ones += (val >> i) & 1
|
|
}
|
|
return (ones & 1) == 0
|
|
}
|
|
|
|
// updateXY set undocumented 3rd (X) and 5th (Y) flags
|
|
func (z *CPU) updateXY(result byte) {
|
|
z.Flags.Y = result&0x20 != 0
|
|
z.Flags.X = result&0x08 != 0
|
|
}
|
|
|
|
func (z *CPU) DebugOutput() {
|
|
log.Debugf("PC: %04X, AF: %04X, BC: %04X, DE: %04X, HL: %04X, SP: %04X, IX: %04X, IY: %04X, I: %02X, R: %02X",
|
|
z.PC, (uint16(z.A)<<8)|uint16(z.f()), z.bc(), z.de(), z.hl(), z.SP,
|
|
z.IX, z.IY, z.I, z.R)
|
|
|
|
log.Debugf("\t(%02X %02X %02X %02X), cycleCount: %d\n", z.rb(z.PC), z.rb(z.PC+1),
|
|
z.rb(z.PC+2), z.rb(z.PC+3), z.cycleCount)
|
|
}
|
|
|
|
func (z *CPU) Reset() {
|
|
z.cycleCount = 0
|
|
z.PC = 0
|
|
z.SP = 0xFFFF
|
|
z.IX = 0
|
|
z.IY = 0
|
|
z.MemPtr = 0
|
|
|
|
z.A = 0xFF
|
|
z.B = 0
|
|
z.C = 0
|
|
z.D = 0
|
|
z.E = 0
|
|
z.H = 0
|
|
z.L = 0
|
|
|
|
z.AAlt = 0
|
|
z.BAlt = 0
|
|
z.CAlt = 0
|
|
z.DAlt = 0
|
|
z.EAlt = 0
|
|
z.HAlt = 0
|
|
z.LAlt = 0
|
|
|
|
z.I = 0
|
|
z.R = 0
|
|
|
|
z.Flags.SetFlags(0xff)
|
|
z.FlagsAlt.SetFlags(0x00)
|
|
|
|
z.iffDelay = 0
|
|
z.IMode = 0
|
|
z.Iff1 = false
|
|
z.Iff2 = false
|
|
z.Halted = false
|
|
z.IntOccurred = false
|
|
z.NmiOccurred = false
|
|
z.intData = 0
|
|
}
|