aboutsummaryrefslogtreecommitdiff
path: root/src/Suem.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Suem.hs')
-rw-r--r--src/Suem.hs83
1 files changed, 59 insertions, 24 deletions
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