Add all opcodes to the instruction representation

This commit is contained in:
Joscha 2019-11-07 10:49:51 +00:00
parent 75b06c3a9f
commit dd7c9d44a6

View file

@ -14,68 +14,84 @@ import Data.Word
import Mima.Util
import Mima.Word
data SmallOpcode = LDC | LDV | STV | ADD | AND | OR | XOR | EQL | JMP | JMN | LDIV | STIV
data SmallOpcode = LDC | LDV | STV | ADD | AND | OR | XOR | EQL
| JMP | JMN | LDIV | STIV | CALL | LDVR | STVR
deriving (Show, Eq, Ord)
instance ToText SmallOpcode where
toText = T.pack . show
allSmallOpcodes :: [SmallOpcode]
allSmallOpcodes = [LDC, LDV, STV, ADD, AND, OR, XOR, EQL, JMP, JMN, LDIV, STIV]
allSmallOpcodes = [LDC, LDV, STV, ADD, AND, OR, XOR, EQL,
JMP, JMN, LDIV, STIV, CALL, LDVR, STVR]
getSmallOpcode :: SmallOpcode -> Word32
getSmallOpcode LDC = 0
getSmallOpcode LDV = 1
getSmallOpcode STV = 2
getSmallOpcode ADD = 3
getSmallOpcode AND = 4
getSmallOpcode OR = 5
getSmallOpcode XOR = 6
getSmallOpcode EQL = 7
getSmallOpcode JMP = 8
getSmallOpcode JMN = 9
getSmallOpcode LDIV = 10
getSmallOpcode STIV = 11
smallOpcodeToWord32 :: SmallOpcode -> Word32
smallOpcodeToWord32 LDC = 0
smallOpcodeToWord32 LDV = 1
smallOpcodeToWord32 STV = 2
smallOpcodeToWord32 ADD = 3
smallOpcodeToWord32 AND = 4
smallOpcodeToWord32 OR = 5
smallOpcodeToWord32 XOR = 6
smallOpcodeToWord32 EQL = 7
smallOpcodeToWord32 JMP = 8
smallOpcodeToWord32 JMN = 9
smallOpcodeToWord32 LDIV = 10
smallOpcodeToWord32 STIV = 11
smallOpcodeToWord32 CALL = 12
smallOpcodeToWord32 LDVR = 13
smallOpcodeToWord32 STVR = 14
smallOpcodeMap :: Map.Map Word32 SmallOpcode
smallOpcodeMap = Map.fromList [(getSmallOpcode oc, oc) | oc <- allSmallOpcodes]
smallOpcodeMap = Map.fromList [(smallOpcodeToWord32 so, so) | so <- allSmallOpcodes]
data LargeOpcode = HALT | NOT | RAR
data LargeOpcode = HALT | NOT | RAR | RET | LDRA | STRA
| LDSP | STSP | LDFP | STFP | ADC
deriving (Show, Eq, Ord)
instance ToText LargeOpcode where
toText = T.pack . show
allLargeOpcodes :: [LargeOpcode]
allLargeOpcodes = [HALT, NOT, RAR]
allLargeOpcodes = [HALT, NOT, RAR, RET, LDRA, STRA, LDSP, STSP, LDFP, STFP, ADC]
getLargeOpcode :: LargeOpcode -> Word32
getLargeOpcode HALT = 0
getLargeOpcode NOT = 1
getLargeOpcode RAR = 2
largeOpcodeToWord32 :: LargeOpcode -> Word32
largeOpcodeToWord32 HALT = 0
largeOpcodeToWord32 NOT = 1
largeOpcodeToWord32 RAR = 2
largeOpcodeToWord32 RET = 3
largeOpcodeToWord32 LDRA = 4
largeOpcodeToWord32 STRA = 5
largeOpcodeToWord32 LDSP = 6
largeOpcodeToWord32 STSP = 7
largeOpcodeToWord32 LDFP = 8
largeOpcodeToWord32 STFP = 9
largeOpcodeToWord32 ADC = 10
largeOpcodeMap :: Map.Map Word32 LargeOpcode
largeOpcodeMap = Map.fromList [(getLargeOpcode oc, oc) | oc <- allLargeOpcodes]
largeOpcodeMap = Map.fromList [(largeOpcodeToWord32 lo, lo) | lo <- allLargeOpcodes]
data Instruction
= SmallInstruction !SmallOpcode !MimaAddress
| LargeInstruction !LargeOpcode
= SmallInstruction !SmallOpcode !LargeValue
| LargeInstruction !LargeOpcode !SmallValue
deriving (Show, Eq)
instance ToText Instruction where
toText (SmallInstruction oc addr) = T.justifyLeft 4 ' ' (toText oc) <> " " <> addrToDec addr
toText (LargeInstruction oc) = toText oc
toText (SmallInstruction oc lv) = T.justifyLeft 4 ' ' (toText oc) <> " " <> largeValueToDec lv
toText (LargeInstruction oc sv)
| sv == minBound = T.justifyLeft 4 ' ' (toText oc)
| otherwise = T.justifyLeft 4 ' ' (toText oc) <> " " <> smallValueToDec sv
wordToInstruction :: MimaWord -> Either T.Text Instruction
wordToInstruction mw = if upperOpcode mw == 0xF
wordToInstruction mw = if getLargeOpcode mw == 0xF
then parseLargeInstruction mw
else parseSmallInstruction mw
parseSmallInstruction :: MimaWord -> Either T.Text Instruction
parseSmallInstruction mw = do
oc <- parseSmallOpcode (upperOpcode mw)
pure $ SmallInstruction oc (address mw)
so <- parseSmallOpcode (getSmallOpcode mw)
pure $ SmallInstruction so (getLargeValue mw)
-- Assumes that all bits not part of the opcode are zeroed. The opcode
-- uses the lowest four bits.
@ -86,7 +102,9 @@ parseSmallOpcode w = case smallOpcodeMap Map.!? w of
<> " (" <> toHex 2 w <> ")"
parseLargeInstruction :: MimaWord -> Either T.Text Instruction
parseLargeInstruction mw = LargeInstruction <$> parseLargeOpcode (lowerOpcode mw)
parseLargeInstruction mw = do
lo <- parseLargeOpcode (getLargeOpcode mw)
pure $ LargeInstruction lo (getSmallValue mw)
-- Assumes that all bits not part of the opcode are zeroed. The opcode
-- uses the lowest four bits.