ZXS: Make relative jumps return absolute addresses
authorLucian Mogosanu <lucian.mogosanu@gmail.com>
Tue, 23 Dec 2014 20:55:37 +0000 (22:55 +0200)
committerLucian Mogosanu <lucian.mogosanu@gmail.com>
Tue, 23 Dec 2014 20:56:32 +0000 (22:56 +0200)
For the sake of complying to the dZ80 diassembly format, but this should
also simplify some of the execution logic.

src/Z80/ISA.hs
src/ZXS/Decode.hs

index 2fff828..c4cf4ff 100644 (file)
@@ -183,16 +183,12 @@ data Instruction =
   -- jump group
   | JP_NN Word16
   | JP_CC_NN Cond Word16
-  | JR_E Int8
---  | JR_C_E Int8
---  | JR_NC_E Int8
---  | JR_Z_E Int8
---  | JR_NZ_E Int8
-  | JR_CC_E Cond Int8
+  | JR_E Word16
+  | JR_CC_E Cond Word16
   | JP_HL
   | JP_IX
   | JP_IY
-  | DJNZ_E Int8
+  | DJNZ_E Word16
   -- call and return group
   | CALL_NN Word16
   | CALL_CC_NN Cond Word16
@@ -407,12 +403,12 @@ instance Show Instruction where
     -- jump group
     JP_NN       nn    -> "jp " ++ showWord nn
     JP_CC_NN    cc nn -> "jp " ++ show cc ++ "," ++ showWord nn
-    JR_E        _     -> "jr " ++ "FIXME" -- should decode to an address
-    JR_CC_E     cc _  -> "jr " ++ show cc ++ "," ++ "FIXME" -- needs address
+    JR_E        nn    -> "jr " ++ showWord nn
+    JR_CC_E     cc nn -> "jr " ++ show cc ++ "," ++ showWord nn
     JP_HL             -> "jp hl"
     JP_IX             -> "jp ix"
     JP_IY             -> "jp iy"
-    DJNZ_E      _     -> "djnz " ++ "FIXME" -- needs address
+    DJNZ_E      nn    -> "djnz " ++ showWord nn
     -- call and return group
     CALL_NN     nn    -> "call " ++ showWord nn
     CALL_CC_NN  cc nn -> "call " ++ show cc ++ "," ++ showWord nn
index 2b00e23..07044c3 100644 (file)
@@ -8,6 +8,7 @@ module ZXS.Decode where
 
 import Data.Bits
 import Data.Word
+import Data.Int
 
 import Z80.CPU
 import Z80.ISA
@@ -31,9 +32,21 @@ decode = do
       0 -> case y of
         0 -> return NOP
         1 -> return EX_AF_AF'
-        2 -> fetch >>= return . DJNZ_E . (+ 2) . fromIntegral
-        3 -> fetch >>= return . JR_E . (+ 2) . fromIntegral
-        _ -> fetch >>= return . JR_CC_E (decodeCond $ y - 4) . (+ 2) . fromIntegral
+        2 -> do
+          e <- fmap relativeToInt fetch
+          pc <- fmap fromIntegral $ getsCPU getPC
+          -- don't add 2, since we've done two fetches
+          return . DJNZ_E . fromIntegral $ pc + e
+        3 -> do
+          e <- fmap relativeToInt fetch
+          pc <- fmap fromIntegral $ getsCPU getPC
+          -- don't add 2, since we've done two fetches
+          return . JR_E . fromIntegral $ pc + e
+        _ -> do
+          e <- fmap relativeToInt fetch
+          pc <- fmap fromIntegral $ getsCPU getPC
+          -- don't add 2, since we've done two fetches
+          return . JR_CC_E (decodeCond $ y - 4) . fromIntegral $ pc + e
       -- z = 1
       1 -> case q of
         0 -> do
@@ -231,6 +244,10 @@ decodeDDFDCB pref = do
 bbToWord :: Word8 -> Word8 -> Word16
 bbToWord hb lb = (fromIntegral hb `shiftL` 8) .|. fromIntegral lb
 
+relativeToInt :: Word8 -> Int
+relativeToInt b = let i8 = fromIntegral b :: Int8
+  in fromIntegral i8
+
 decodeReg :: Word8 -> Reg
 decodeReg b = case b of
   0 -> B