import Data.Bits
import Data.Word
+import Z80.CPU
import Z80.ISA
+import Z80.Microcode
import ZXS.Machine
import ZXS.Fetch
lb <- fetch
hb <- fetch
return . CALL_NN $ bbToWord hb lb
- 1 -> decodeDD
+ 1 -> decodeDDFD 0xdd
2 -> decodeED
- 3 -> decodeFD
+ 3 -> decodeDDFD 0xfd
-- z = 6
6 -> fetch >>= return . decodeALU y . AOp_N
7 -> return . RST_P $ y * 8
_ -> return . IllegalInstruction $ "decode: opcode = " ++ show b
-- decode prefixed opcodes
-decodeCB, decodeDD, decodeED, decodeFD :: ZXS Instruction
+decodeCB, decodeED :: ZXS Instruction
-- CB-prefixed opcodes
decodeCB = do
-- TODO: these are trickier and will require using extra logic in the decode
-- function above and the getPrefixed field in the CPU. To bear in mind.
-decodeDD = undefined
-decodeFD = undefined
+decodeDDFD :: Word8 -> ZXS Instruction
+decodeDDFD prevb = do
+ b <- fetch
+ let rollback = modifyCPU $ flip modifyPC (\ x -> x - 1)
+ prefixed = if prevb == 0xdd then DDPrefixed else FDPrefixed
+ if b == 0xdd || b == 0xed || b == 0xfd
+ then do
+ -- refetch this opcode at the next decode stage
+ rollback
+ return NOP -- NONI?
+ else case b of
+ 0xcb -> decodeDDFDCB prefixed
+ _ -> do
+ rollback
+ modifyCPU . flip setPrefixed $ prefixed
+ return NOP -- NONI?
+
+decodeDDFDCB :: Prefixed -> ZXS Instruction
+decodeDDFDCB pref = do
+ d <- fmap fromIntegral fetch
+ b <- fetch
+ let x = (b `shiftR` 6) .&. 0x03
+ y = (b `shiftR` 3) .&. 0x07
+ z = (b `shiftR` 0) .&. 0x07
+ srspec = (if pref == DDPrefixed then SROp_PIX else SROp_PIY) d
+ bwspec = (if pref == DDPrefixed then BOp_PIX else BOp_PIY) d
+ return $ case (x, z) of
+ (0, 6) -> decodeSR y srspec
+ (2, 6) -> RES y bwspec
+ (3, 6) -> SET y bwspec
+ (0, _) -> decodeSR' y (decodeReg z) srspec
+ (1, _) -> BIT y bwspec
+ (2, _) -> LD_R_RES (decodeReg z) y bwspec
+ (3, _) -> LD_R_SET (decodeReg z) y bwspec
+ _ -> IllegalInstruction $ "decodeDDFDCB: opcode " ++ show b
bbToWord :: Word8 -> Word8 -> Word16
bbToWord hb lb = (fromIntegral hb `shiftL` 8) .|. fromIntegral lb
6 -> SLL
7 -> SRL
+decodeSR' :: Word8 -> Reg -> SRSpec -> Instruction
+decodeSR' b = case b of
+ 0 -> LD_R_RLC
+ 1 -> LD_R_RRC
+ 2 -> LD_R_RL
+ 3 -> LD_R_RR
+ 4 -> LD_R_SLA
+ 5 -> LD_R_SRA
+ 6 -> LD_R_SLL
+ 7 -> LD_R_SRL
+
decodeBLI :: Word8 -> Word8 -> Instruction
decodeBLI a b = [
[ LDI, CPI, INI, OUTI ],