Add all opcodes to the instruction representation
This commit is contained in:
parent
75b06c3a9f
commit
dd7c9d44a6
1 changed files with 50 additions and 32 deletions
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue