From 389084c3a6dd2382f50824d68b58e4b7f0ea24c6 Mon Sep 17 00:00:00 2001 From: Lucian Mogosanu Date: Wed, 24 Dec 2014 01:49:53 +0200 Subject: [PATCH] ZXS: Decode remaining prefixed opcodes --- src/Z80/ISA.hs | 8 ++++++-- src/ZXS/Decode.hs | 44 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/Z80/ISA.hs b/src/Z80/ISA.hs index 015ae53..1565368 100644 --- a/src/Z80/ISA.hs +++ b/src/Z80/ISA.hs @@ -138,7 +138,9 @@ data Instruction = | HALT | DI | EI - | IM Word8 + | IM0 + | IM1 + | IM2 -- 16-bit arithmetic group | ADD_HL_SS RegPair_ss | ADC_HL_SS RegPair_ss @@ -362,7 +364,9 @@ instance Show Instruction where HALT -> "halt" DI -> "di" EI -> "ei" - IM _ -> "im FIXME" -- must be 0, 1 or 2 + IM0 -> "im 0" + IM1 -> "im 1" + IM2 -> "im 2" -- 16-bit arithmetic group ADD_HL_SS ss -> "add hl," ++ show ss ADC_HL_SS ss -> "adc hl," ++ show ss diff --git a/src/ZXS/Decode.hs b/src/ZXS/Decode.hs index f966dbd..ed55985 100644 --- a/src/ZXS/Decode.hs +++ b/src/ZXS/Decode.hs @@ -148,16 +148,34 @@ decode = do rollback >> return (LD_R_R' dry drz) else return HALT -- x = 2 - 2 -> return . decodeALU y . AOp_R $ decodeReg prefixed z + 2 -> let drz = decodeReg prefixed z + dalu = decodeALU y + aop = if prefixed == DDPrefixed then AOp_PIX else AOp_PIY + in if (prefixed == DDPrefixed || prefixed == FDPrefixed) && drz == PHL + then fetch >>= return . dalu . aop . fromIntegral + else return . dalu $ AOp_R drz -- x = 3 3 -> case z of -- z = 0, 1 0 -> return . RET_CC $ decodeCond y 1 -> case q of - 0 -> return . POP_QQ $ decodeRegPair_qq p + 0 -> return $ case (prefixed, decodeRegPair_qq p) of + (DDPrefixed, R3 HL) -> POP_IX + (FDPrefixed, R3 HL) -> POP_IY + (_, _) -> POP_QQ $ decodeRegPair_qq p 1 -> if p > 3 then return . IllegalInstruction $ "decode: opcode = " ++ show b - else return $ [ RET, EXX, JP_HL, LD_SP_HL ] !! fromIntegral p + else return $ case p of + 0 -> RET + 1 -> EXX + 2 -> case prefixed of + Unprefixed -> JP_HL + DDPrefixed -> JP_IX + FDPrefixed -> JP_IY + 3 -> case prefixed of + Unprefixed -> LD_SP_HL + DDPrefixed -> LD_SP_IX + FDPrefixed -> LD_SP_IY -- z = 2 2 -> do lb <- fetch @@ -185,7 +203,10 @@ decode = do -- z = 5 5 -> case q of -- q = 0, 1 - 0 -> return . PUSH_QQ $ decodeRegPair_qq p + 0 -> return $ case (prefixed, decodeRegPair_qq p) of + (DDPrefixed, R3 HL) -> PUSH_IX + (FDPrefixed, R3 HL) -> PUSH_IY + (_, _) -> PUSH_QQ $ decodeRegPair_qq p 1 -> case p of 0 -> do lb <- fetch @@ -247,8 +268,12 @@ decodeED prefixed = do else LD_DD_PNN (decodeRegPair_dd p) w 4 -> return NEG -- z = 5, 6 - 5 -> return $ if y /= 1 then RETN else RETI - 6 -> return $ IM y -- handle interrupt mode based on y's value + 5 -> return $ case y of + 0 -> RETN + 1 -> RETI + _ -> RET + -- if y /= 1 then RETN else RETI + 6 -> return $ decodeIM y 7 -> return $ [ LD_I_A, LD_R_A, LD_A_I, LD_A_R, RRD, RLD, NOP, NOP ] !! fromIntegral y -- x = 2 @@ -375,6 +400,13 @@ decodeALU b = case b of 6 -> OR_A_S 7 -> CP_A_S +decodeIM :: Word8 -> Instruction +decodeIM b = case b `mod` 4 of + 0 -> IM0 + 1 -> IM0 + 2 -> IM1 + 3 -> IM2 + decodeSR :: Word8 -> SRSpec -> Instruction decodeSR b = case b of 0 -> RLC -- 1.7.10.4