Implement new specification
This commit is contained in:
parent
75821abb2c
commit
957f65c380
5 changed files with 55 additions and 25 deletions
|
|
@ -29,12 +29,18 @@ printWord n word = do
|
||||||
T.putStr $ T.justifyRight n ' ' $ toDec word
|
T.putStr $ T.justifyRight n ' ' $ toDec word
|
||||||
putStr ")"
|
putStr ")"
|
||||||
|
|
||||||
|
-- Color scheme:
|
||||||
|
-- Red: HALT
|
||||||
|
-- Yellow: Instructions for accessing other registers
|
||||||
|
-- Green: Instructions that can modify the IAR (jumps)
|
||||||
|
-- Blue: Instructions that read from or write to memory
|
||||||
|
-- Cyan: Logical operations and calculations that modify the ACC
|
||||||
printInstruction :: Instruction -> IO ()
|
printInstruction :: Instruction -> IO ()
|
||||||
printInstruction (SmallInstruction so lv) = do
|
printInstruction (SmallInstruction so lv) = do
|
||||||
setSGR [SetConsoleIntensity BoldIntensity]
|
setSGR [SetConsoleIntensity BoldIntensity]
|
||||||
if | so `elem` [JMP, JMN, CALL] -> setSGR [SetColor Foreground Dull Green]
|
if | so `elem` [JMP, JMN, CALL] -> setSGR [SetColor Foreground Dull Green]
|
||||||
| so `elem` [LDC, LDV, STV, LDIV, STIV, LDVR, STVR] -> setSGR [SetColor Foreground Vivid Blue]
|
| so `elem` [LDC, LDV, STV, LDIV, STIV] -> setSGR [SetColor Foreground Vivid Blue]
|
||||||
| so `elem` [ADD, AND, OR, XOR, EQL] -> setSGR [SetColor Foreground Vivid Cyan]
|
| so `elem` [ADD, AND, OR, XOR, EQL, ADC] -> setSGR [SetColor Foreground Vivid Cyan]
|
||||||
| otherwise -> pure ()
|
| otherwise -> pure ()
|
||||||
T.putStr $ toText so
|
T.putStr $ toText so
|
||||||
putStr " "
|
putStr " "
|
||||||
|
|
@ -44,12 +50,13 @@ printInstruction (SmallInstruction so lv) = do
|
||||||
printInstruction (LargeInstruction lo sv) = do
|
printInstruction (LargeInstruction lo sv) = do
|
||||||
setSGR [SetConsoleIntensity BoldIntensity]
|
setSGR [SetConsoleIntensity BoldIntensity]
|
||||||
if | lo == HALT -> setSGR [SetColor Foreground Vivid Red]
|
if | lo == HALT -> setSGR [SetColor Foreground Vivid Red]
|
||||||
| lo == RET -> setSGR [SetColor Foreground Dull Green]
|
|
||||||
| lo `elem` [NOT, RAR, ADC] -> setSGR [SetColor Foreground Vivid Cyan]
|
|
||||||
| lo `elem` [LDRA, STRA, LDSP, STSP, LDFP, STFP] -> setSGR [SetColor Foreground Dull Yellow]
|
| lo `elem` [LDRA, STRA, LDSP, STSP, LDFP, STFP] -> setSGR [SetColor Foreground Dull Yellow]
|
||||||
|
| lo == RET -> setSGR [SetColor Foreground Dull Green]
|
||||||
|
| lo `elem` [LDRS, STRS, LDRF, STRF] -> setSGR [SetColor Foreground Vivid Blue]
|
||||||
|
| lo `elem` [NOT, RAR] -> setSGR [SetColor Foreground Vivid Cyan]
|
||||||
| otherwise -> pure ()
|
| otherwise -> pure ()
|
||||||
T.putStr $ toText lo
|
T.putStr $ toText lo
|
||||||
when (lo == ADC || sv /= zeroBits) $ do
|
when (lo `elem` [LDRS, STRS, LDRF, STRF] || sv /= zeroBits) $ do
|
||||||
putStr " "
|
putStr " "
|
||||||
setSGR [SetColor Foreground Vivid Black]
|
setSGR [SetColor Foreground Vivid Black]
|
||||||
T.putStr $ toDec sv
|
T.putStr $ toDec sv
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ parseByLiteral = foldl (<|>) empty . map (\(a, b) -> b <$ C.string' a)
|
||||||
smallOpcode' :: Parser SmallOpcode
|
smallOpcode' :: Parser SmallOpcode
|
||||||
smallOpcode' = parseByLiteral
|
smallOpcode' = parseByLiteral
|
||||||
[ ( "LDC", LDC)
|
[ ( "LDC", LDC)
|
||||||
, ("LDVR", LDVR) -- Needs to be before LDV
|
|
||||||
, ("STVR", STVR) -- Needs to be before STV
|
|
||||||
, ( "LDV", LDV)
|
, ( "LDV", LDV)
|
||||||
, ( "STV", STV)
|
, ( "STV", STV)
|
||||||
, ( "ADD", ADD)
|
, ( "ADD", ADD)
|
||||||
|
|
@ -41,10 +39,16 @@ smallOpcode' = parseByLiteral
|
||||||
, ("LDIV", LDIV)
|
, ("LDIV", LDIV)
|
||||||
, ("STIV", STIV)
|
, ("STIV", STIV)
|
||||||
, ("CALL", CALL)
|
, ("CALL", CALL)
|
||||||
|
, ( "ADC", ADC)
|
||||||
]
|
]
|
||||||
|
|
||||||
largeOpcode' :: Parser LargeOpcode
|
largeOpcode' :: Parser LargeOpcode
|
||||||
largeOpcode' = parseByLiteral [( "ADC", ADC)]
|
largeOpcode' = parseByLiteral
|
||||||
|
[ ("STRS", STRS)
|
||||||
|
, ("LDRS", LDRS)
|
||||||
|
, ("STRF", STRF)
|
||||||
|
, ("LDRF", LDRF)
|
||||||
|
]
|
||||||
|
|
||||||
largeOptionalOpcode' :: Parser LargeOpcode
|
largeOptionalOpcode' :: Parser LargeOpcode
|
||||||
largeOptionalOpcode' = parseByLiteral
|
largeOptionalOpcode' = parseByLiteral
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import Mima.Util
|
||||||
import Mima.Word
|
import Mima.Word
|
||||||
|
|
||||||
data SmallOpcode = LDC | LDV | STV | ADD | AND | OR | XOR | EQL
|
data SmallOpcode = LDC | LDV | STV | ADD | AND | OR | XOR | EQL
|
||||||
| JMP | JMN | LDIV | STIV | CALL | LDVR | STVR
|
| JMP | JMN | LDIV | STIV | CALL | ADC
|
||||||
deriving (Show, Eq, Ord)
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
instance ToText SmallOpcode where
|
instance ToText SmallOpcode where
|
||||||
|
|
@ -23,7 +23,7 @@ instance ToText SmallOpcode where
|
||||||
|
|
||||||
allSmallOpcodes :: [SmallOpcode]
|
allSmallOpcodes :: [SmallOpcode]
|
||||||
allSmallOpcodes = [LDC, LDV, STV, ADD, AND, OR, XOR, EQL,
|
allSmallOpcodes = [LDC, LDV, STV, ADD, AND, OR, XOR, EQL,
|
||||||
JMP, JMN, LDIV, STIV, CALL, LDVR, STVR]
|
JMP, JMN, LDIV, STIV, CALL, ADC]
|
||||||
|
|
||||||
smallOpcodeNr :: SmallOpcode -> Opcode
|
smallOpcodeNr :: SmallOpcode -> Opcode
|
||||||
smallOpcodeNr LDC = 0
|
smallOpcodeNr LDC = 0
|
||||||
|
|
@ -39,21 +39,21 @@ smallOpcodeNr JMN = 9
|
||||||
smallOpcodeNr LDIV = 10
|
smallOpcodeNr LDIV = 10
|
||||||
smallOpcodeNr STIV = 11
|
smallOpcodeNr STIV = 11
|
||||||
smallOpcodeNr CALL = 12
|
smallOpcodeNr CALL = 12
|
||||||
smallOpcodeNr LDVR = 13
|
smallOpcodeNr ADC = 13
|
||||||
smallOpcodeNr STVR = 14
|
|
||||||
|
|
||||||
smallOpcodeMap :: Map.Map Opcode SmallOpcode
|
smallOpcodeMap :: Map.Map Opcode SmallOpcode
|
||||||
smallOpcodeMap = Map.fromList [(smallOpcodeNr so, so) | so <- allSmallOpcodes]
|
smallOpcodeMap = Map.fromList [(smallOpcodeNr so, so) | so <- allSmallOpcodes]
|
||||||
|
|
||||||
data LargeOpcode = HALT | NOT | RAR | RET | LDRA | STRA
|
data LargeOpcode = HALT | NOT | RAR | RET | LDRA | STRA | LDSP | STSP
|
||||||
| LDSP | STSP | LDFP | STFP | ADC
|
| LDFP | STFP | LDRS | STRS | LDRF | STRF
|
||||||
deriving (Show, Eq, Ord)
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
instance ToText LargeOpcode where
|
instance ToText LargeOpcode where
|
||||||
toText = T.pack . show
|
toText = T.pack . show
|
||||||
|
|
||||||
allLargeOpcodes :: [LargeOpcode]
|
allLargeOpcodes :: [LargeOpcode]
|
||||||
allLargeOpcodes = [HALT, NOT, RAR, RET, LDRA, STRA, LDSP, STSP, LDFP, STFP, ADC]
|
allLargeOpcodes = [HALT, NOT, RAR, RET, LDRA, STRA, LDSP, STSP,
|
||||||
|
LDFP, STFP, LDRS, STRS, LDRF, STRF]
|
||||||
|
|
||||||
largeOpcodeNr :: LargeOpcode -> Opcode
|
largeOpcodeNr :: LargeOpcode -> Opcode
|
||||||
largeOpcodeNr HALT = 0
|
largeOpcodeNr HALT = 0
|
||||||
|
|
@ -66,7 +66,10 @@ largeOpcodeNr LDSP = 6
|
||||||
largeOpcodeNr STSP = 7
|
largeOpcodeNr STSP = 7
|
||||||
largeOpcodeNr LDFP = 8
|
largeOpcodeNr LDFP = 8
|
||||||
largeOpcodeNr STFP = 9
|
largeOpcodeNr STFP = 9
|
||||||
largeOpcodeNr ADC = 10
|
largeOpcodeNr LDRS = 10
|
||||||
|
largeOpcodeNr STRS = 11
|
||||||
|
largeOpcodeNr LDRF = 12
|
||||||
|
largeOpcodeNr STRF = 13
|
||||||
|
|
||||||
largeOpcodeMap :: Map.Map Opcode LargeOpcode
|
largeOpcodeMap :: Map.Map Opcode LargeOpcode
|
||||||
largeOpcodeMap = Map.fromList [(largeOpcodeNr lo, lo) | lo <- allLargeOpcodes]
|
largeOpcodeMap = Map.fromList [(largeOpcodeNr lo, lo) | lo <- allLargeOpcodes]
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,7 @@ doSmallOpcode STIV addr ms@MimaState{..} =
|
||||||
let indirAddr = getLargeValue $ readAt addr msMemory
|
let indirAddr = getLargeValue $ readAt addr msMemory
|
||||||
in ms{msMemory = writeAt indirAddr msACC msMemory}
|
in ms{msMemory = writeAt indirAddr msACC msMemory}
|
||||||
doSmallOpcode CALL addr ms@MimaState{..} = ms{msRA = msIAR, msIAR = addr}
|
doSmallOpcode CALL addr ms@MimaState{..} = ms{msRA = msIAR, msIAR = addr}
|
||||||
doSmallOpcode LDVR addr ms@MimaState{..} = ms{msACC = readAt (msSP + addr) msMemory}
|
doSmallOpcode ADC lv ms@MimaState{..} = ms{msACC = msACC + signedLargeValueToWord lv}
|
||||||
doSmallOpcode STVR addr ms@MimaState{..} = ms{msMemory = writeAt (msSP + addr) msACC msMemory}
|
|
||||||
|
|
||||||
doLargeOpcode :: LargeOpcode -> SmallValue -> MimaState -> Either AbortReason MimaState
|
doLargeOpcode :: LargeOpcode -> SmallValue -> MimaState -> Either AbortReason MimaState
|
||||||
doLargeOpcode HALT _ _ = Left Halted
|
doLargeOpcode HALT _ _ = Left Halted
|
||||||
|
|
@ -136,7 +135,18 @@ doLargeOpcode LDSP _ ms@MimaState{..} = pure ms{msACC = largeValueToWord msSP}
|
||||||
doLargeOpcode STSP _ ms@MimaState{..} = pure ms{msSP = getLargeValue msACC}
|
doLargeOpcode STSP _ ms@MimaState{..} = pure ms{msSP = getLargeValue msACC}
|
||||||
doLargeOpcode LDFP _ ms@MimaState{..} = pure ms{msACC = largeValueToWord msFP}
|
doLargeOpcode LDFP _ ms@MimaState{..} = pure ms{msACC = largeValueToWord msFP}
|
||||||
doLargeOpcode STFP _ ms@MimaState{..} = pure ms{msFP = getLargeValue msACC}
|
doLargeOpcode STFP _ ms@MimaState{..} = pure ms{msFP = getLargeValue msACC}
|
||||||
doLargeOpcode ADC sv ms@MimaState{..} = pure ms{msACC = msACC + signedSmallValueToWord sv}
|
doLargeOpcode LDRS sv ms@MimaState{..} =
|
||||||
|
let indirAddr = msSP + signedSmallValueToLargeValue sv
|
||||||
|
in pure ms{msACC = readAt indirAddr msMemory}
|
||||||
|
doLargeOpcode STRS sv ms@MimaState{..} =
|
||||||
|
let indirAddr = msSP + signedSmallValueToLargeValue sv
|
||||||
|
in pure ms{msMemory = writeAt indirAddr msACC msMemory}
|
||||||
|
doLargeOpcode LDRF sv ms@MimaState{..} =
|
||||||
|
let indirAddr = msFP + signedSmallValueToLargeValue sv
|
||||||
|
in pure ms{msACC = readAt indirAddr msMemory}
|
||||||
|
doLargeOpcode STRF sv ms@MimaState{..} =
|
||||||
|
let indirAddr = msFP + signedSmallValueToLargeValue sv
|
||||||
|
in pure ms{msMemory = writeAt indirAddr msACC msMemory}
|
||||||
|
|
||||||
run :: MimaState -> (MimaState, AbortReason, Integer)
|
run :: MimaState -> (MimaState, AbortReason, Integer)
|
||||||
run ms = helper 0 ms
|
run ms = helper 0 ms
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ module Mima.Word
|
||||||
, wordToBytes
|
, wordToBytes
|
||||||
, boolToWord
|
, boolToWord
|
||||||
, largeValueToWord
|
, largeValueToWord
|
||||||
, signedSmallValueToWord
|
, signedLargeValueToWord
|
||||||
|
, signedSmallValueToLargeValue
|
||||||
, wordFromSmallOpcode
|
, wordFromSmallOpcode
|
||||||
, wordFromLargeOpcode
|
, wordFromLargeOpcode
|
||||||
-- ** 'MimaWord' properties
|
-- ** 'MimaWord' properties
|
||||||
|
|
@ -56,9 +57,14 @@ boolToWord True = complement zeroBits
|
||||||
largeValueToWord :: LargeValue -> MimaWord
|
largeValueToWord :: LargeValue -> MimaWord
|
||||||
largeValueToWord = fromIntegral
|
largeValueToWord = fromIntegral
|
||||||
|
|
||||||
signedSmallValueToWord :: SmallValue -> MimaWord
|
signedLargeValueToWord :: LargeValue -> MimaWord
|
||||||
signedSmallValueToWord sv
|
signedLargeValueToWord lv
|
||||||
| topBit sv = 0xFF0000 .|. fromIntegral sv
|
| topBit lv = 0xF00000 .|. fromIntegral lv
|
||||||
|
| otherwise = fromIntegral lv
|
||||||
|
|
||||||
|
signedSmallValueToLargeValue :: SmallValue -> LargeValue
|
||||||
|
signedSmallValueToLargeValue sv
|
||||||
|
| topBit sv = 0xF0000 .|. fromIntegral sv
|
||||||
| otherwise = fromIntegral sv
|
| otherwise = fromIntegral sv
|
||||||
|
|
||||||
wordFromSmallOpcode :: Opcode -> LargeValue -> MimaWord
|
wordFromSmallOpcode :: Opcode -> LargeValue -> MimaWord
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue