Ocean-240.2-Emulator/z80/js/opcodeCB.go

109 lines
2.4 KiB
Go

package js
func (z *Z80) opcodeCB() {
z.incR()
z.PC++
opcode := z.core.M1MemRead(z.PC)
bitNumber := (opcode & 0x38) >> 3
regCode := opcode & 0x07
if opcode < 0x40 {
// Shift/rotate instructions
opArray := []OpShift{z.doRlc, z.doRrc, z.doRl, z.doRr, z.doSla, z.doSra, z.doSll, z.doSrl}
switch regCode {
case 0:
z.B = opArray[bitNumber](z.B)
case 1:
z.C = opArray[bitNumber](z.C)
case 2:
z.D = opArray[bitNumber](z.D)
case 3:
z.E = opArray[bitNumber](z.E)
case 4:
z.H = opArray[bitNumber](z.H)
case 5:
z.L = opArray[bitNumber](z.L)
case 6:
z.core.MemWrite(z.hl(), opArray[bitNumber](z.core.MemRead(z.hl())))
default:
z.A = opArray[bitNumber](z.A)
}
} else if opcode < 0x80 {
// BIT instructions
mask := byte(1 << bitNumber)
switch regCode {
case 0:
z.Flags.Z = z.B&mask == 0
case 1:
z.Flags.Z = z.C&mask == 0
case 2:
z.Flags.Z = z.D&mask == 0
case 3:
z.Flags.Z = z.E&mask == 0
case 4:
z.Flags.Z = z.H&mask == 0
case 5:
z.Flags.Z = z.L&mask == 0
case 6:
z.Flags.Z = z.core.MemRead(z.hl())&mask == 0
default:
z.Flags.Z = z.A&mask == 0
}
z.Flags.N = false
z.Flags.H = true
z.Flags.P = z.Flags.Z
z.Flags.S = (bitNumber == 7) && !z.Flags.Z
// TODO: ZXALL fail this
// For the BIT n, (HL) instruction, the X and Y flags are obtained
// from what is apparently an internal temporary register used for
// some of the 16-bit arithmetic instructions.
// I haven't implemented that register here,
// so for now we'll set X and Y the same way for every BIT opcode,
// which means that they will usually be wrong for BIT n, (HL).
z.Flags.Y = (bitNumber == 5) && !z.Flags.Z
z.Flags.X = (bitNumber == 3) && !z.Flags.Z
} else if opcode < 0xC0 {
// RES instructions
negMask := byte(^(1 << bitNumber))
switch regCode {
case 0:
z.B &= negMask
case 1:
z.C &= negMask
case 2:
z.D &= negMask
case 3:
z.E &= negMask
case 4:
z.H &= negMask
case 5:
z.L &= negMask
case 6:
z.core.MemWrite(z.hl(), z.core.MemRead(z.hl())&negMask)
default:
z.A &= negMask
}
} else {
// SET instructions
mask := byte(1 << bitNumber)
switch regCode {
case 0:
z.B |= mask
case 1:
z.C |= mask
case 2:
z.D |= mask
case 3:
z.E |= mask
case 4:
z.H |= mask
case 5:
z.L |= mask
case 6:
z.core.MemWrite(z.hl(), z.core.MemRead(z.hl())|mask)
default:
z.A |= mask
}
}
z.CycleCounter += CycleCountsCb[opcode]
}