From 5e463f8e1b4b4aa072a007104db00c4ce46e40a4 Mon Sep 17 00:00:00 2001 From: Lucian Mogosanu Date: Wed, 24 Dec 2014 22:08:41 +0200 Subject: [PATCH] OpcodeTest: Handle program load addresses --- src/OpcodeTest.hs | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/OpcodeTest.hs b/src/OpcodeTest.hs index f892b4e..905dab1 100644 --- a/src/OpcodeTest.hs +++ b/src/OpcodeTest.hs @@ -4,6 +4,7 @@ import Text.Printf import System.IO import System.Environment import Data.Word +import Data.Bits (shiftL, (.|.)) import qualified Data.ByteString as BS import Z80.CPU @@ -12,6 +13,12 @@ import ZXS.Machine import ZXS.RAM import ZXS.Decode +data Program = Program + { prgSpectrum :: Spectrum + , prgAddr :: Word16 + , prgLength :: Word16 + } + whatevsRAM :: IO RAM whatevsRAM = newRAM (0x0000, 0xffff) @@ -34,14 +41,23 @@ whatevsCPU = CPU , getPrefixed = Unprefixed } -whatevsSpectrum :: BS.ByteString -> IO Spectrum +whatevsSpectrum :: BS.ByteString -> IO Program whatevsSpectrum bs = do let header = BS.take 8 bs - code = BS.drop 8 bs + code = BS.drop 10 bs + addr = makeAddr . BS.unpack . BS.take 2 . BS.drop 8 $ bs if header /= BS.pack [ 0x5a, 0x38, 0x30, 0x41, 0x53, 0x4d, 0x1a, 0x0a ] then fail "Doesn't look like a Z80 file..." - else whatevsRAM >>= initRAM 0 bs -- code - >>= \ ram -> return $ Spectrum whatevsCPU { getPC = 0 } ram + else whatevsRAM + >>= initRAM addr code + >>= \ ram -> return $ Program + { prgSpectrum = Spectrum whatevsCPU { getPC = addr } ram + , prgAddr = addr + , prgLength = fromIntegral $ BS.length code } + where + makeAddr ws = case ws of + [ wl, wh ] -> fromIntegral wl .|. (fromIntegral wh `shiftL` 8) + _ -> error "whatevsSpectrum has a bug." initRAM :: Word16 -> BS.ByteString -> RAM -> IO RAM initRAM addr code ram @@ -49,17 +65,16 @@ initRAM addr code ram | otherwise = ramSetByte ram addr (BS.head code) >> initRAM (addr + 1) (BS.tail code) ram -parseZ80 :: Word16 -> ZXS [(Word16, [Word8], Instruction)] +parseZ80 :: Word16 -> Word16 -> ZXS [(Word16, [Word8], Instruction)] parseZ80 = go [] - where go acc n - | n == 0 = return $ reverse acc + where go acc addr addr' + | addr >= addr' = return $ reverse acc | otherwise = do pc <- getsCPU getPC i <- decode pc' <- getsCPU getPC ops <- getOpcodesBetween pc pc' - let d = pc' - pc - go ((pc, ops, i) : acc) (n - d) + go ((pc, ops, i) : acc) pc' addr' getOpcodesBetween pc pc' | pc == pc' = return [] | otherwise = do @@ -80,7 +95,6 @@ main = do then print "TODO: print usage" else do bs <- withFile (head args) ReadMode BS.hGetContents - let n = fromIntegral $ BS.length bs - s <- whatevsSpectrum bs - is <- evalZXST (parseZ80 n) s + Program s addr n <- whatevsSpectrum bs + is <- evalZXST (parseZ80 addr $ addr + n) s printInstrs is -- 1.7.10.4