From 7f59fd16534fc4fe417640130c415107008a638c Mon Sep 17 00:00:00 2001 From: Aleksey Veresov Date: Tue, 16 Feb 2021 13:11:37 +0300 Subject: Now Machine is in Emulator which is a monad. =) --- src/Suem.hs | 83 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 24 deletions(-) (limited to 'src/Suem.hs') diff --git a/src/Suem.hs b/src/Suem.hs index fe73a1e..0207a91 100644 --- a/src/Suem.hs +++ b/src/Suem.hs @@ -1,28 +1,23 @@ +-- This module organizes Emulator execution. module Suem (Config(..), ConfigSocket(..), suem) where import qualified Data.Vector.Unboxed as V +import qualified Data.Vector.Unboxed.Mutable as VM import qualified Data.ByteString as B +import Prelude hiding (Word) import Data.Word +import Data.IORef +import Data.Foldable +import Control.Monad.Reader (runReaderT) import Machine import Commands import Utils -data ConfigSocket = ConfigInet String | ConfigUnix String +------------------------------------------------------------------------------- +-- Main loop and command deciphering. -data Config = Config Int -- frequence - Int -- size of RAM - FilePath -- path to ROM - (Maybe ConfigSocket) - (Maybe ConfigSocket) - (Maybe ConfigSocket) - (Maybe ConfigSocket) - (Maybe ConfigSocket) - (Maybe ConfigSocket) - (Maybe ConfigSocket) - (Maybe ConfigSocket) - -doCommand :: [Int] -> Machine -> Machine +doCommand :: [Int] -> Emulator () doCommand [0,1,0,0,1,1,1,0, 0,1,1,0,0,0,0,0] = doReset doCommand [0,1,0,0,1,1,1,0, 0,1,1,0,0,0,0,1] = doNothing doCommand [0,1,0,0,1,1,1,0, 0,1,1,0,0,0,1,0] = doStop @@ -38,18 +33,58 @@ doCommand [0,1,0,0,1,0,1,0, 0,1,0,1,1,a,b,c] = doUnlink [a,b,c] doCommand [0,1,0,0,1,0,1,0, a,b,c,d,e,f,g,h] = doTST [a,b] [c,d,e] [f,g,h] doCommand _ = error "Bad command." -runMachine :: Machine -> IO () -runMachine m = do - runMachine $ doCommand (toBits $ getWord m $ fromIntegral $ pc $ regs m) m +runMachine :: Emulator () +runMachine = forM_ [0..] $ \_ -> do + pc <- with pc $ \pc -> readIORef pc + cmd <- getWord $ fromIntegral pc + doCommand (toBitsWhole cmd) + + +------------------------------------------------------------------------------- +-- Config and start of execution based on the config. + +data ConfigSocket = ConfigInet String | ConfigUnix String + +data Config = Config Int -- frequence + Int -- size of RAM + FilePath -- path to ROM + (Maybe ConfigSocket) + (Maybe ConfigSocket) + (Maybe ConfigSocket) + (Maybe ConfigSocket) + (Maybe ConfigSocket) + (Maybe ConfigSocket) + (Maybe ConfigSocket) + (Maybe ConfigSocket) + +makeMachine :: VM.IOVector Byte -> V.Vector Byte -> IO Machine +makeMachine ramData romData = do + pc <- newIORef pcval + sr <- newIORef 0x2700 + drs <- newIORef (fromIntegral 0, fromIntegral 0, fromIntegral 0, + fromIntegral 0, fromIntegral 0, fromIntegral 0, + fromIntegral 0, fromIntegral 0) + ars <- newIORef (fromIntegral 0, fromIntegral 0, fromIntegral 0, + fromIntegral 0, fromIntegral 0, fromIntegral 0, + fromIntegral 0) + usp <- newIORef 0 + ssp <- newIORef sspval + return $ Machine pc sr drs ars usp ssp ramData romData + where pcval = (fromIntegral $ romData V.! 4) * 256 * 256 * 256 + + (fromIntegral $ romData V.! 5) * 256 * 256 + + (fromIntegral $ romData V.! 6) * 256 + + (fromIntegral $ romData V.! 7) + sspval = (fromIntegral $ romData V.! 0) * 256 * 256 * 256 + + (fromIntegral $ romData V.! 1) * 256 * 256 + + (fromIntegral $ romData V.! 2) * 256 + + (fromIntegral $ romData V.! 3) -makeMachine :: V.Vector Word8 -> Int -> Machine -makeMachine romData ramSize = Machine rs rd romData - where rd = V.replicate ramSize 0 - rs = Registers (getLong m 0x7e0004) 0x2700 (replicate 8 0) - (replicate 7 0) 0 (getLong m 0x7e0000) - m = Machine (Registers 0 0 [] [] 0 0) V.empty romData +runEmulator :: Emulator a -> Machine -> IO a +runEmulator (Emulator reader) m = runReaderT reader m suem :: Config -> IO () suem (Config _ ramSize romPath _ _ _ _ _ _ _ _) = do romData <- B.readFile romPath - runMachine (makeMachine (V.fromList $ B.unpack $ romData) ramSize) + ram <- VM.replicate ramSize 0 + m <- makeMachine ram (V.fromList $ B.unpack $ romData) + runEmulator runMachine m -- cgit v1.2.3