From 04036bb047f99ed75e4a2804616ffe84bb49c7d1 Mon Sep 17 00:00:00 2001 From: Joscha Date: Wed, 6 Nov 2019 14:17:32 +0000 Subject: [PATCH] Add LDIV, STIV instructions --- src/Mima/Instruction.hs | 6 ++++-- src/Mima/State.hs | 28 ++++++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Mima/Instruction.hs b/src/Mima/Instruction.hs index f3f4197..37d515d 100644 --- a/src/Mima/Instruction.hs +++ b/src/Mima/Instruction.hs @@ -14,14 +14,14 @@ import Data.Word import Mima.Util import Mima.Word -data SmallOpcode = LDC | LDV | STV | ADD | AND | OR | XOR | EQL | JMP | JMN +data SmallOpcode = LDC | LDV | STV | ADD | AND | OR | XOR | EQL | JMP | JMN | STIV | LDIV 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] +allSmallOpcodes = [LDC, LDV, STV, ADD, AND, OR, XOR, EQL, JMP, JMN, STIV, LDIV] getSmallOpcode :: SmallOpcode -> Word32 getSmallOpcode LDC = 0 @@ -34,6 +34,8 @@ getSmallOpcode XOR = 6 getSmallOpcode EQL = 7 getSmallOpcode JMP = 8 getSmallOpcode JMN = 9 +getSmallOpcode STIV = 10 +getSmallOpcode LDIV = 11 smallOpcodeMap :: Map.Map Word32 SmallOpcode smallOpcodeMap = Map.fromList [(getSmallOpcode oc, oc) | oc <- allSmallOpcodes] diff --git a/src/Mima/State.hs b/src/Mima/State.hs index 10283b4..c08854f 100644 --- a/src/Mima/State.hs +++ b/src/Mima/State.hs @@ -81,16 +81,24 @@ step ms = do (LargeInstruction oc) -> executeLargeOpcode oc ms executeSmallOpcode :: SmallOpcode -> MimaAddress -> MimaState -> Either ExecException MimaState -executeSmallOpcode LDC addr ms = incrementIp ms{msAcc = addressToWord addr} -executeSmallOpcode LDV addr ms = incrementIp ms{msAcc = readAt addr (msMemory ms)} -executeSmallOpcode STV addr ms = incrementIp ms{msMemory = writeAt addr (msAcc ms) (msMemory ms)} -executeSmallOpcode ADD addr ms = incrementIp ms{msAcc = addWords (msAcc ms) (readAt addr $ msMemory ms)} -executeSmallOpcode AND addr ms = incrementIp ms{msAcc = msAcc ms .&. readAt addr (msMemory ms)} -executeSmallOpcode OR addr ms = incrementIp ms{msAcc = msAcc ms .|. readAt addr (msMemory ms)} -executeSmallOpcode XOR addr ms = incrementIp ms{msAcc = msAcc ms `xor` readAt addr (msMemory ms)} -executeSmallOpcode EQL addr ms = incrementIp ms{msAcc = boolToWord $ msAcc ms == readAt addr (msMemory ms)} -executeSmallOpcode JMP addr ms = pure ms{msIp = addr} -executeSmallOpcode JMN addr ms = if topBit (msAcc ms) then pure ms{msIp = addr} else incrementIp ms +executeSmallOpcode LDC addr ms = incrementIp ms{msAcc = addressToWord addr} +executeSmallOpcode LDV addr ms = incrementIp ms{msAcc = readAt addr (msMemory ms)} +executeSmallOpcode STV addr ms = incrementIp ms{msMemory = writeAt addr (msAcc ms) (msMemory ms)} +executeSmallOpcode ADD addr ms = incrementIp ms{msAcc = addWords (msAcc ms) (readAt addr $ msMemory ms)} +executeSmallOpcode AND addr ms = incrementIp ms{msAcc = msAcc ms .&. readAt addr (msMemory ms)} +executeSmallOpcode OR addr ms = incrementIp ms{msAcc = msAcc ms .|. readAt addr (msMemory ms)} +executeSmallOpcode XOR addr ms = incrementIp ms{msAcc = msAcc ms `xor` readAt addr (msMemory ms)} +executeSmallOpcode EQL addr ms = incrementIp ms{msAcc = boolToWord $ msAcc ms == readAt addr (msMemory ms)} +executeSmallOpcode JMP addr ms = pure ms{msIp = addr} +executeSmallOpcode JMN addr ms = if topBit (msAcc ms) then pure ms{msIp = addr} else incrementIp ms +executeSmallOpcode STIV addr ms = + let mem = msMemory ms + indirAddr = address $ readAt addr mem + in incrementIp ms{msMemory = writeAt indirAddr (msAcc ms) mem} +executeSmallOpcode LDIV addr ms = + let mem = msMemory ms + indirAddr = address $ readAt addr mem + in incrementIp ms{msAcc = readAt indirAddr mem} executeLargeOpcode :: LargeOpcode -> MimaState -> Either ExecException MimaState executeLargeOpcode HALT ms =