Skip to content

Commit

Permalink
Unconditional jump. Added fix for clamping addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
lisphacker committed Oct 29, 2023
1 parent 6be2c43 commit d9e4c30
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 12 deletions.
15 changes: 10 additions & 5 deletions src/TIS100/Tiles/T21.hs
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,22 @@ instance IsConnectedTile T21 where
SUBI v -> incPC $ writeRegOrPort (Register ACC) $ maybeAddSub (flip (-)) (t, Just v) $ readRegOrPort (Register ACC) t
SUB src -> incPC $ writeRegOrPort (Register ACC) $ maybeAddSub (flip (-)) (readRegOrPort src t) (readRegOrPort (Register ACC) t)
NEG -> incPC $ writeRegOrPort (Register ACC) $ maybeAddSub (-) (t, Just $ Value 0) $ readRegOrPort (Register ACC) t
JMP addr -> t{tileState = (tileState t){pc = addr}}
JMP addr -> t{tileState = (tileState t){pc = clampAddr addr}}
JCC cond addr -> case cond of
EZ -> if acc (tileState t) == 0 then t{tileState = (tileState t){pc = addr}} else incPC t
NZ -> if acc (tileState t) /= 0 then t{tileState = (tileState t){pc = addr}} else incPC t
GZ -> if acc (tileState t) > 0 then t{tileState = (tileState t){pc = addr}} else incPC t
LZ -> if acc (tileState t) < 0 then t{tileState = (tileState t){pc = addr}} else incPC t
EZ -> if acc (tileState t) == 0 then t{tileState = (tileState t){pc = clampAddr addr}} else incPC t
NZ -> if acc (tileState t) /= 0 then t{tileState = (tileState t){pc = clampAddr addr}} else incPC t
GZ -> if acc (tileState t) > 0 then t{tileState = (tileState t){pc = clampAddr addr}} else incPC t
LZ -> if acc (tileState t) < 0 then t{tileState = (tileState t){pc = clampAddr addr}} else incPC t
JROI v -> addValueToPC (t, Just v)
JRO src -> addValueToPC $ readRegOrPort src t

maybeAddSub :: (Value -> Value -> Value) -> (T21, Maybe Value) -> (T21, Maybe Value) -> (T21, Maybe Value)
maybeAddSub f (t', Just v1) (_, Just v2) = (t', Just $ f v1 v2)
maybeAddSub _ tv _ = tv -- Just to silence the linter
clampAddr :: Address -> Address
clampAddr (Address a) = Address $ max 0 $ min a maxAddr
where
maxAddr = V.length (tileProgram t) - 1

readRegOrPort :: RegisterOrPort -> T21 -> (T21, Maybe Value)
readRegOrPort rp t = case rp of
Expand Down
62 changes: 55 additions & 7 deletions test/Sim/T21.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import TIS100.Tiles.T21
import Test.Hspec
import Prelude hiding (init, last)

mkT21Tile :: Value -> Value -> [Instruction] -> T21
mkT21Tile initAcc initBak instns =
mkT21TileWithPC :: Address -> Value -> Value -> [Instruction] -> T21
mkT21TileWithPC initPc initAcc initBak instns =
T21
{ tileProgram =
V.fromList instns
Expand All @@ -18,11 +18,14 @@ mkT21Tile initAcc initBak instns =
{ acc = initAcc
, bak = initBak
, last = ANY
, pc = 0
, pc = initPc
, runState = Ready
}
}

mkT21Tile :: Value -> Value -> [Instruction] -> T21
mkT21Tile = mkT21TileWithPC 0

testADDSUB :: Bool -> Spec
testADDSUB add = describe ("Testing " ++ insName) $ do
testADDSUB_ACC
Expand Down Expand Up @@ -61,10 +64,6 @@ testADD :: Spec
testADD = testADDSUB True
testSUB :: Spec
testSUB = testADDSUB False
testADDI :: Spec
testADDI = testADDSUBI True
testSUBI :: Spec
testSUBI = testADDSUBI False

testADDSUBI :: Bool -> Spec
testADDSUBI add = do
Expand All @@ -78,6 +77,39 @@ testADDSUBI add = do
f = if add then (+) else (-)
insName = if add then "ADDI" else "SUBI"

testADDI :: Spec
testADDI = testADDSUBI True
testSUBI :: Spec
testSUBI = testADDSUBI False

testUnconditionalJump :: Spec
testUnconditionalJump = describe "Testing JMP" $ do
testUnconditionalJump' "without overflow/underflow" (JMP (Address 5)) (Address 5)
testUnconditionalJump' "underflow" (JMP (Address (-5))) (Address 0)
testUnconditionalJump' "overflow" (JMP (Address 10)) (Address 6)
where
testUnconditionalJump' desc ins tgtAddr = do
let next = step $ init ins

describe ("Testing " ++ desc) $ do
it "Status" $ do
pc (tileState next) `shouldBe` tgtAddr

init ins = mkT21TileWithPC 3 2 0 [NOP, NOP, NOP, ins, NOP, NOP, NOP]

testJEZ :: Spec
testJEZ = undefined
testJGZ :: Spec
testJGZ = undefined
testJLZ :: Spec
testJLZ = undefined
testJNZ :: Spec
testJNZ = undefined
testJMP :: Spec
testJMP = testUnconditionalJump
testJRO :: Spec
testJRO = undefined

testMOVI :: Spec
testMOVI = describe "Testing MOVI" $ do
let ports = [UP, DOWN, LEFT, RIGHT]
Expand Down Expand Up @@ -122,6 +154,15 @@ testMOV = describe "Testing MOV" $ do
it "Status" $ do
runState (tileState next) `shouldBe` WaitingOnRead port Nothing

testNEG :: Spec
testNEG = describe "Testing NEG" $ do
let init = mkT21Tile 10 20 [NEG]
let next = step init

describe "Testing NEG" $ do
it "Status" $ do
acc (tileState next) `shouldBe` Value (-10)

testNOP :: Spec
testNOP = describe "Testing NOPs" $ do
testNOP' NOP
Expand Down Expand Up @@ -150,8 +191,15 @@ simTestsSpec :: Spec
simTestsSpec = describe "Intra-T21 tests" $ parallel $ do
testADD
testADDI
-- testJEZ
-- testJGZ
-- testJLZ
-- testJNZ
testJMP
-- testJRO
testMOV
testMOVI
testNEG
testNOP
testSUB
testSUBI
Expand Down

0 comments on commit d9e4c30

Please sign in to comment.