Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Emulator/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ executeInstruction mutRegisters mutMemory flags pc sp instruction = do
ROL rd -> rol mutRegisters mutMemory flags sp rd
ROR rd -> ror mutRegisters mutMemory flags sp rd
SBC rd rr -> sbc mutRegisters mutMemory flags sp rd rr
SBR rd k -> sbr mutRegisters mutMemory flags sp rd k
SBRC rd b -> sbrc mutRegisters flags sp rd b
SBRS rd b -> sbrs mutRegisters flags sp rd b
SEC -> sec flags sp
Expand Down
16 changes: 16 additions & 0 deletions src/Emulator/Instructions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ data Instruction
| ROL Register
| ROR Register
| SBC Register Register
| SBR Register Word8
| SBRC Register Word8
| SBRS Register Word8
| SEC
Expand Down Expand Up @@ -917,6 +918,21 @@ sbc registers memory oldFlags sp op1 op2 = do
}
return (updatedFlags, 0, sp)

sbr :: MutRegisters s -> MutMemory s -> StatusFlags -> StackPointer -> Register -> Word8 -> ST s (StatusFlags, Int, StackPointer)
sbr registers memory oldFlags sp op1 immediate = do
let rdIndex = fromIntegral op1
rd <- getRegister registers rdIndex
let k = immediate
let result = rd .|. k
setRegister registers memory rdIndex result
let updatedFlags = oldFlags {
overflowFlag = False,
negativeFlag = testBit result 7,
zeroFlag = result == 0,
signFlag = xor (negativeFlag updatedFlags) (overflowFlag updatedFlags)
}
return (updatedFlags, 0, sp)

sbrc :: MutRegisters s -> StatusFlags -> StackPointer -> Register -> Word8 -> ST s (StatusFlags, Int, StackPointer)
sbrc registers oldFlags sp op1 immediate = do
let rdIndex = fromIntegral op1
Expand Down
9 changes: 9 additions & 0 deletions src/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,14 @@ pSBRS = do
pComma
SBRS rd <$> pDecimal

pSBR :: Parser Instruction
pSBR = do
cistring "SBR" >> space1
rd <- pRegister
when (rd < 16) (fail "Can't use SBR with registers lower than R16")
pComma
SBR rd <$> pWord8

pSEC :: Parser Instruction
pSEC = do
cistring "SEC" >> (space1 <|> eof)
Expand Down Expand Up @@ -726,6 +734,7 @@ instructionParser = do
pSBC,
pSBRC,
pSBRS,
pSBR,
pSEC,
pSEH,
pSEI,
Expand Down
6 changes: 3 additions & 3 deletions src/Repl.hs
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,10 @@ helpText = unlines
, " e Run until the end of the program"
, " f Run until the next RET or RETI instruction"
, " restart | re Restart the emulator with the same parameters"
, " registers | r Print the current values of the register"
, " registers | r Print the current values of the registers"
, " flags Print the current values of the status flags"
, " pc | p Print the ccurent value of the program counter"
, " m [[<start>] <end>] Print the memory contents between those addresses"
, " pc | p Print the curent value of the program counter"
, " m [[<start>] <end>] Print the memory contents between two addresses"
, " instruction | i Print the next instruction to be executed"
, " help Print this message"
, " Control-D Exit the REPL"
Expand Down
25 changes: 25 additions & 0 deletions test/MainTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ main = hspec $ describe "AVR Emulator E2E tests" $ do
let assemblyFilePath = "test_files/test_bset.asm"
emulateProgramFromFile assemblyFilePath testBset

-- test_sbr.asm
it "Should correctly emulate test_sbr.asm and match expected state" $ do
let assemblyFilePath = "test_files/test_sbr.asm"
emulateProgramFromFile assemblyFilePath testSbr

-- Checking emulator state for array_merge.asm
testArrayMerge :: EmulatorState -> IO ()
testArrayMerge state = do
Expand Down Expand Up @@ -1302,3 +1307,23 @@ testBset state = do
negativeFlag (flags state) `shouldBe` True
zeroFlag (flags state) `shouldBe` True
carryFlag (flags state) `shouldBe` True

-- Checking EmulatorState for the "test_sbr.asm"
testSbr :: EmulatorState -> IO ()
testSbr state = do
-- Registers
let regValue = registers state ! 16
regValue `shouldBe` 0xAF

-- Program counter
programCounter state `shouldBe` 2

-- Status flags
interruptFlag (flags state) `shouldBe` False
tFlag (flags state) `shouldBe` False
halfCarryFlag (flags state) `shouldBe` False
signFlag (flags state) `shouldBe` True
overflowFlag (flags state) `shouldBe` False
negativeFlag (flags state) `shouldBe` True
zeroFlag (flags state) `shouldBe` False
carryFlag (flags state) `shouldBe` False
2 changes: 2 additions & 0 deletions test_files/test_sbr.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ldi r16, 0xAA ; r16 = 0xAA
sbr r16, 0x0F ; r16 = 0xAA OR 0x0F = 0xAF