summaryrefslogtreecommitdiff
path: root/fig-emulator-gb
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2024-05-07 14:21:13 -0400
committerLLLL Colonq <llll@colonq>2024-05-07 14:21:13 -0400
commita81c92dc2cdff02c55fdc197d943bc7a35c64be5 (patch)
treec5c4039f1e81d8290859656f3a0d306e6af62053 /fig-emulator-gb
parent82d4f5c55bdb1f160fe558bd9e413b726e36541b (diff)
fig-emulator-gb: Fix space leak
Diffstat (limited to 'fig-emulator-gb')
-rw-r--r--fig-emulator-gb/fig-emulator-gb.cabal3
-rw-r--r--fig-emulator-gb/main/Main.hs4
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB.hs57
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/Bus.hs10
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/CPU.hs162
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/Component/Interrupt.hs33
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs7
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/Component/Serial.hs14
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/Component/Video.hs41
-rw-r--r--fig-emulator-gb/src/Fig/Emulator/GB/Test/Instr.hs2
10 files changed, 187 insertions, 146 deletions
diff --git a/fig-emulator-gb/fig-emulator-gb.cabal b/fig-emulator-gb/fig-emulator-gb.cabal
index 35566dd..4a094c6 100644
--- a/fig-emulator-gb/fig-emulator-gb.cabal
+++ b/fig-emulator-gb/fig-emulator-gb.cabal
@@ -5,7 +5,7 @@ version: 0.1.0.0
common defaults
ghc-options: -Wall
default-language: GHC2021
- default-extensions: NoImplicitPrelude PackageImports LambdaCase MultiWayIf OverloadedStrings OverloadedLists RecordWildCards BlockArguments ViewPatterns TypeFamilies DataKinds GADTs
+ default-extensions: NoImplicitPrelude PackageImports LambdaCase MultiWayIf OverloadedStrings OverloadedLists RecordWildCards BlockArguments ViewPatterns TypeFamilies DataKinds GADTs Strict StrictData
common deps
build-depends:
@@ -51,6 +51,7 @@ library
Fig.Emulator.GB.Component.Video
Fig.Emulator.GB.Component.Joystick
Fig.Emulator.GB.Component.Serial
+ Fig.Emulator.GB.Component.Interrupt
Fig.Emulator.GB.Test.Instr
executable fig-emulator-gb
diff --git a/fig-emulator-gb/main/Main.hs b/fig-emulator-gb/main/Main.hs
index 7a15c45..6284c6a 100644
--- a/fig-emulator-gb/main/Main.hs
+++ b/fig-emulator-gb/main/Main.hs
@@ -19,13 +19,13 @@ import Fig.Emulator.GB.Test.Instr
data RunOptions = RunOptions
{ romPath :: !FilePath
- , serialOut :: !FilePath
+ , serialOut :: !(Maybe FilePath)
} deriving Show
parseRunOptions :: Parser RunOptions
parseRunOptions = do
romPath <- argument str (metavar "PATH")
- serialOut <- strOption (long "serial" <> metavar "PATH" <> help "Path to write link cable serial output")
+ serialOut <- optional $ strOption (long "serial" <> metavar "PATH" <> help "Path to write link cable serial output")
pure RunOptions{..}
newtype InstrTestOptions = InstrTestOptions
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB.hs b/fig-emulator-gb/src/Fig/Emulator/GB.hs
index 76e6c85..6f32682 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB.hs
@@ -6,7 +6,7 @@ import System.IO (withFile, IOMode (WriteMode))
import Control.Lens ((.=), use)
import Control.Monad (when)
-import Control.Monad.State (StateT(..))
+import Control.Monad.State.Strict (StateT(..))
import qualified SDL
@@ -18,9 +18,10 @@ import Fig.Emulator.GB.Component.ROM
import Fig.Emulator.GB.Component.Video
import Fig.Emulator.GB.Component.Joystick
import Fig.Emulator.GB.Component.Serial
+import Fig.Emulator.GB.Component.Interrupt (compInterrupt)
-cpuDMG :: (MonadIO m, MonadThrow m) => Handle -> ByteString -> Framebuffer -> CPU m
-cpuDMG h rom fb = CPU
+cpuDMG :: (MonadIO m, MonadThrow m) => Maybe Handle -> ByteString -> Framebuffer -> CPU m
+cpuDMG serial rom fb = CPU
{ _lastPC = 0x0
, _lastIns = Nop
, _running = True
@@ -30,26 +31,30 @@ cpuDMG h rom fb = CPU
, compWRAM 0xc000 $ 8 * 1024
, compVideo fb
, compJoystick
- , compSerial h
+ , compSerial serial
+ , compInterrupt
, compWRAM 0xff80 0x7e -- HRAM
]
}
-testRun :: forall m. (MonadIO m, MonadThrow m) => FilePath -> ByteString -> m ()
+testRun :: forall m. (MonadIO m, MonadThrow m) => Maybe FilePath -> ByteString -> m ()
testRun serialOut rom = do
SDL.initializeAll
window <- SDL.createWindow "taking" SDL.defaultWindow
fb <- initializeFramebuffer
- liftIO $ withFile serialOut WriteMode \hserial -> do
+ let withSerial f = case serialOut of
+ Nothing -> f Nothing
+ Just p -> withFile p WriteMode $ f . Just
+ liftIO $ withSerial \hserial -> do
let cpu = cpuDMG hserial rom fb
let
loop :: forall m'. Emulating m' => Int -> m' ()
loop cycle = do
- events <- SDL.pollEvents
- forM_ events \ev ->
- case SDL.eventPayload ev of
- SDL.QuitEvent -> running .= False
- _else -> pure ()
+ -- events <- SDL.pollEvents
+ -- forM_ events \ev ->
+ -- case SDL.eventPayload ev of
+ -- SDL.QuitEvent -> running .= False
+ -- _else -> pure ()
pc <- use $ regs . regPC
ins <- decode
when (pc == 0x2817) do
@@ -58,20 +63,22 @@ testRun serialOut rom = do
, ": ", tshow ins
]
step ins
- when (rem cycle 70224 == 0) do
- ws <- SDL.getWindowSurface window
- SDL.surfaceFillRect ws Nothing $ SDL.V4 0x00 0x00 0x00 0xff
- void $
- SDL.surfaceBlitScaled
- (fbSurface fb)
- Nothing
- ws
- (Just $ SDL.Rectangle
- (SDL.P $ SDL.V2 0 0)
- (SDL.V2
- (fromIntegral screenWidth * 8)
- (fromIntegral screenHeight * 8)))
- SDL.updateWindowSurface window
+ when (rem cycle 1000000 == 0) do
+ log "1 million"
+ -- when (rem cycle 70224 == 0) do
+ -- ws <- SDL.getWindowSurface window
+ -- SDL.surfaceFillRect ws Nothing $ SDL.V4 0x00 0x00 0x00 0xff
+ -- void $
+ -- SDL.surfaceBlitScaled
+ -- (fbSurface fb)
+ -- Nothing
+ -- ws
+ -- (Just $ SDL.Rectangle
+ -- (SDL.P $ SDL.V2 0 0)
+ -- (SDL.V2
+ -- (fromIntegral screenWidth * 8)
+ -- (fromIntegral screenHeight * 8)))
+ -- SDL.updateWindowSurface window
r <- use running
when r . loop $ cycle + 1
void $ flip runStateT cpu do
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Bus.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Bus.hs
index dd61dbc..6550d2d 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB/Bus.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/Bus.hs
@@ -20,11 +20,11 @@ instance Pretty Addr where
pretty (Addr w) = "$" <> pack (showHex w "")
data Component m = forall (s :: Type). Component
- { compState :: !s
- , compMatches :: !(Addr -> Bool)
- , compUpdate :: !(s -> Int -> m s)
- , compWrite :: !(s -> Addr -> Word8 -> m s)
- , compRead :: !(s -> Addr -> m Word8)
+ { compState :: s
+ , compMatches :: Addr -> Bool
+ , compUpdate :: s -> Int -> m s
+ , compWrite :: s -> Addr -> Word8 -> m s
+ , compRead :: s -> Addr -> m Word8
}
newtype Bus m = Bus { busComponents :: [Component m] }
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/CPU.hs b/fig-emulator-gb/src/Fig/Emulator/GB/CPU.hs
index cd4abba..6f56324 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB/CPU.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/CPU.hs
@@ -63,11 +63,11 @@ initialRegs = Registers
}
data CPU m = CPU
- { _lastPC :: !Word16
- , _lastIns :: !Instruction
- , _running :: !Bool
- , _regs :: !Registers
- , _bus :: !(Bus m)
+ { _lastPC :: Word16
+ , _lastIns :: Instruction
+ , _running :: Bool
+ , _regs :: Registers
+ , _bus :: Bus m
}
makeLenses 'CPU
@@ -108,7 +108,7 @@ updateComps t = do
decode :: Emulating m => m Instruction
decode = do
- updateComps 4
+ -- updateComps 4
b <- use bus
pc <- use $ regs . regPC
lastPC .= pc
@@ -125,7 +125,7 @@ cond CondC = use (regs . regFlagC)
read8 :: Emulating m => Addr -> m Word8
read8 a = do
- updateComps 4
+ -- updateComps 4
b <- use bus
pc <- use lastPC
ins <- use lastIns
@@ -149,7 +149,7 @@ read16 a = do
write8 :: Emulating m => Addr -> Word8 -> m ()
write8 a v = do
- updateComps 4
+ -- updateComps 4
b <- use bus
b' <- liftIO $ Bus.write b a v
bus .= b'
@@ -257,27 +257,27 @@ step ins = do
regs . regFlagN .= False
pure res
case ins of
- Nop -> pure ()
- LdR16Imm16 r (Imm16 i) -> setR16 r i
- LdR16MemA r -> do
+ Nop -> {-# SCC "Nop" #-} pure ()
+ LdR16Imm16 r (Imm16 i) -> {-# SCC "LdR16Imm16" #-} setR16 r i
+ LdR16MemA r -> {-# SCC "LdR16MemA" #-} do
addr <- r16Mem r
a <- r8 R8A
write8 (Addr addr) a
- LdAR16Mem r -> do
+ LdAR16Mem r -> {-# SCC "LdAR16Mem" #-} do
addr <- r16Mem r
v <- read8 $ Addr addr
setR8 R8A v
- LdImm16Sp (Imm16 addr) -> do
+ LdImm16Sp (Imm16 addr) -> {-# SCC "LdImm16Sp" #-} do
sp <- r16 R16SP
write8 (Addr addr) $ w16lo sp
write8 (Addr addr + 1) $ w16hi sp
- IncR16 r -> do
+ IncR16 r -> {-# SCC "IncR16" #-} do
v <- r16 r
setR16 r $ v + 1
- DecR16 r -> do
+ DecR16 r -> {-# SCC "DecR16" #-} do
v <- r16 r
setR16 r $ v - 1
- AddHlR16 r -> do
+ AddHlR16 r -> {-# SCC "AddHlR16" #-} do
x <- r16 R16HL
y <- r16 r
let
@@ -289,14 +289,14 @@ step ins = do
regs . regFlagC .= (shiftR resl 16 .&. 0b1 == 0b1)
regs . regFlagN .= False
setR16 R16HL res
- IncR8 r -> do
+ IncR8 r -> {-# SCC "IncR8" #-} do
v <- r8 r
let (res, _) = addC False v 1
regs . regFlagH .= addH False v 1
regs . regFlagZ .= (res == 0)
regs . regFlagN .= False
setR8 r res
- DecR8 r -> do
+ DecR8 r -> {-# SCC "DecR8" #-} do
v <- r8 r
let
res :: Word8
@@ -305,22 +305,22 @@ step ins = do
regs . regFlagZ .= (res == 0)
regs . regFlagN .= True
setR8 r res
- LdR8Imm8 r (Imm8 i) -> setR8 r i
- Rlca -> do
+ LdR8Imm8 r (Imm8 i) -> {-# SCC "LdR8Imm8" #-} setR8 r i
+ Rlca -> {-# SCC "Rlca" #-} do
v <- r8 R8A
regs . regFlagH .= False
regs . regFlagZ .= False
regs . regFlagN .= False
regs . regFlagC .= w8bit 7 v
setR8 R8A $ rotateL v 1
- Rrca -> do
+ Rrca -> {-# SCC "Rrca" #-} do
v <- r8 R8A
regs . regFlagH .= False
regs . regFlagZ .= False
regs . regFlagN .= False
regs . regFlagC .= w8bit 0 v
setR8 R8A $ rotateR v 1
- Rla -> do
+ Rla -> {-# SCC "Rla" #-} do
v <- r8 R8A
c <- use $ regs . regFlagC
regs . regFlagH .= False
@@ -328,7 +328,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 7 v
setR8 R8A $ shiftL v 1 .|. if c then 1 else 0
- Rra -> do
+ Rra -> {-# SCC "Rra" #-} do
v <- r8 R8A
c <- use $ regs . regFlagC
regs . regFlagH .= False
@@ -336,7 +336,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 0 v
setR8 R8A $ shiftR v 1 .|. if c then 0b10000000 else 0
- Daa -> do
+ Daa -> {-# SCC "Daa" #-} do
v <- r8 R8A
halfcarry <- use $ regs . regFlagH
carry <- use $ regs . regFlagC
@@ -353,34 +353,34 @@ step ins = do
regs . regFlagZ .= (res == 0)
regs . regFlagC .= c
pure ()
- Cpl -> do
+ Cpl -> {-# SCC "Cpl" #-} do
v <- r8 R8A
regs . regFlagH .= True
regs . regFlagN .= True
setR8 R8A $ complement v
- Scf -> do
+ Scf -> {-# SCC "Scf" #-} do
regs . regFlagH .= False
regs . regFlagN .= False
regs . regFlagC .= True
- Ccf -> do
+ Ccf -> {-# SCC "Ccf" #-} do
c <- use $ regs . regFlagC
regs . regFlagH .= False
regs . regFlagN .= False
regs . regFlagC .= not c
- JrImm8 (Imm8 i) -> do
+ JrImm8 (Imm8 i) -> {-# SCC "JrImm8" #-} do
pc <- use $ regs . regPC
regs . regPC .= pc + sext i
- JrCondImm8 c (Imm8 i) -> do
+ JrCondImm8 c (Imm8 i) -> {-# SCC "JrCondImm8" #-} do
b <- cond c
when b do
pc <- use $ regs . regPC
regs . regPC .= pc + sext i
- Stop -> unimplemented
- LdR8R8 dst src -> do
+ Stop -> {-# SCC "Stop" #-} unimplemented
+ LdR8R8 dst src -> {-# SCC "LdR8R8" #-} do
v <- r8 src
setR8 dst v
- Halt -> unimplemented
- AddAR8 i -> do
+ Halt -> {-# SCC "Halt" #-} unimplemented
+ AddAR8 i -> {-# SCC "AddAR8" #-} do
x <- r8 R8A
y <- r8 i
let (res, carry) = addC False x y
@@ -389,7 +389,7 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= False
regs . regA .= res
- AdcAR8 i -> do
+ AdcAR8 i -> {-# SCC "AdcAR8" #-} do
x <- r8 R8A
y <- r8 i
c <- use $ regs . regFlagC
@@ -399,7 +399,7 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= False
regs . regA .= res
- SubAR8 i -> do
+ SubAR8 i -> {-# SCC "SubAR8" #-} do
x <- r8 R8A
y <- r8 i
let (res, carry) = subC False x y
@@ -408,7 +408,7 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= True
regs . regA .= res
- SbcAR8 i -> do
+ SbcAR8 i -> {-# SCC "SbcAR8" #-} do
x <- r8 R8A
y <- r8 i
c <- use $ regs . regFlagC
@@ -418,23 +418,23 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= True
regs . regA .= res
- AndAR8 i -> do
+ AndAR8 i -> {-# SCC "AndAR8" #-} do
x <- r8 R8A
y <- r8 i
res <- bitwise8 (.&.) x y
regs . regFlagH .= True
regs . regA .= res
- XorAR8 i -> do
+ XorAR8 i -> {-# SCC "XorAR8" #-} do
x <- r8 R8A
y <- r8 i
res <- bitwise8 xor x y
regs . regA .= res
- OrAR8 i -> do
+ OrAR8 i -> {-# SCC "OrAR8" #-} do
x <- r8 R8A
y <- r8 i
res <- bitwise8 (.|.) x y
regs . regA .= res
- CpAR8 i -> do
+ CpAR8 i -> {-# SCC "CpAR8" #-} do
x <- r8 R8A
y <- r8 i
let (res, carry) = subC False x y
@@ -442,7 +442,7 @@ step ins = do
regs . regFlagC .= carry
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= True
- AddAImm8 (Imm8 y) -> do
+ AddAImm8 (Imm8 y) -> {-# SCC "AddAImm8" #-} do
x <- r8 R8A
let (res, carry) = addC False x y
regs . regFlagH .= addH False x y
@@ -450,7 +450,7 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= False
regs . regA .= res
- AdcAImm8 (Imm8 y) -> do
+ AdcAImm8 (Imm8 y) -> {-# SCC "AdcAImm8" #-} do
x <- r8 R8A
c <- use $ regs . regFlagC
let (res, carry) = addC c x y
@@ -459,7 +459,7 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= False
regs . regA .= res
- SubAImm8 (Imm8 y) -> do
+ SubAImm8 (Imm8 y) -> {-# SCC "SubAImm8" #-} do
x <- r8 R8A
let (res, carry) = subC False x y
regs . regFlagH .= subH False x y
@@ -467,7 +467,7 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= True
regs . regA .= res
- SbcAImm8 (Imm8 y) -> do
+ SbcAImm8 (Imm8 y) -> {-# SCC "SbcAImm8" #-} do
x <- r8 R8A
c <- use $ regs . regFlagC
let (res, carry) = subC c x y
@@ -476,50 +476,50 @@ step ins = do
regs . regFlagZ .= (res .&. 0xff == 0)
regs . regFlagN .= True
regs . regA .= res
- AndAImm8 (Imm8 y) -> do
+ AndAImm8 (Imm8 y) -> {-# SCC "AndAImm8" #-} do
x <- r8 R8A
res <- bitwise8 (.&.) x y
regs . regFlagH .= True
regs . regA .= res
- XorAImm8 (Imm8 y) -> do
+ XorAImm8 (Imm8 y) -> {-# SCC "XorAImm8" #-} do
x <- r8 R8A
res <- bitwise8 xor x y
regs . regA .= res
- OrAImm8 (Imm8 y) -> do
+ OrAImm8 (Imm8 y) -> {-# SCC "OrAImm8" #-} do
x <- r8 R8A
res <- bitwise8 (.|.) x y
regs . regA .= res
- CpAImm8 (Imm8 y) -> do
+ CpAImm8 (Imm8 y) -> {-# SCC "CpAImm8" #-} do
x <- r8 R8A
void $ sub8 (-) x y
- RetCond c -> do
+ RetCond c -> {-# SCC "RetCond" #-} do
b <- cond c
when b do
sp <- r16 R16SP
v <- read16 $ Addr sp
setR16 R16SP $ sp + 2
regs . regPC .= v
- Ret -> do
+ Ret -> {-# SCC "Ret" #-} do
sp <- r16 R16SP
v <- read16 $ Addr sp
setR16 R16SP $ sp + 2
regs . regPC .= v
- Reti -> do
+ Reti -> {-# SCC "Reti" #-} do
regs . regFlagIME .= True
sp <- r16 R16SP
v <- read16 $ Addr sp
setR16 R16SP $ sp + 2
regs . regPC .= v
- JpCondImm16 c (Imm16 i) -> do
+ JpCondImm16 c (Imm16 i) -> {-# SCC "JpCondImm16" #-} do
b <- cond c
when b do
regs . regPC .= i
- JpImm16 (Imm16 i) -> do
+ JpImm16 (Imm16 i) -> {-# SCC "JpImm16" #-} do
regs . regPC .= i
- JpHl -> do
+ JpHl -> {-# SCC "JpHl" #-} do
hl <- r16 R16HL
regs . regPC .= hl
- CallCondImm16 c (Imm16 i) -> do
+ CallCondImm16 c (Imm16 i) -> {-# SCC "CallCondImm16" #-} do
b <- cond c
when b do
next <- use $ regs . regPC
@@ -527,49 +527,49 @@ step ins = do
setR16 R16SP sp
write16 (Addr sp) next
regs . regPC .= i
- CallImm16 (Imm16 i) -> do
+ CallImm16 (Imm16 i) -> {-# SCC "CallImm16" #-} do
next <- use $ regs . regPC
sp <- (\x -> x - 2) <$> r16 R16SP
setR16 R16SP sp
write16 (Addr sp) next
regs . regPC .= i
- RstTgt3 (Tgt3 v) -> do
+ RstTgt3 (Tgt3 v) -> {-# SCC "RstTgt3" #-} do
next <- use $ regs . regPC
sp <- (\x -> x - 2) <$> r16 R16SP
setR16 R16SP sp
write16 (Addr sp) next
regs . regPC .= shiftL (fromIntegral v) 3
- PopR16Stk r -> do
+ PopR16Stk r -> {-# SCC "PopR16Stk" #-} do
sp <- r16 R16SP
v <- read16 $ Addr sp
setR16 R16SP $ sp + 2
setR16Stk r v
- PushR16Stk r -> do
+ PushR16Stk r -> {-# SCC "PushR16Stk" #-} do
sp <- (\x -> x - 2) <$> r16 R16SP
v <- r16Stk r
setR16 R16SP sp
write16 (Addr sp) v
- LdhCA -> do
+ LdhCA -> {-# SCC "LdhCA" #-} do
c <- r8 R8C
a <- r8 R8A
write8 (Addr $ 0xff00 + zext c) a
- LdhImm8A (Imm8 i) -> do
+ LdhImm8A (Imm8 i) -> {-# SCC "LdhImm8A" #-} do
a <- r8 R8A
write8 (Addr $ 0xff00 + zext i) a
- LdImm16A (Imm16 i) -> do
+ LdImm16A (Imm16 i) -> {-# SCC "LdImm16A" #-} do
a <- r8 R8A
write8 (Addr i) a
- LdhAC -> do
+ LdhAC -> {-# SCC "LdhAC" #-} do
c <- r8 R8C
v <- read8 (Addr $ 0xff00 + zext c)
setR8 R8A v
- LdhAImm8 (Imm8 i) -> do
+ LdhAImm8 (Imm8 i) -> {-# SCC "LdhAImm8" #-} do
v <- read8 (Addr $ 0xff00 + zext i)
setR8 R8A v
- LdAImm16 (Imm16 i) -> do
+ LdAImm16 (Imm16 i) -> {-# SCC "LdAImm16" #-} do
v <- read8 (Addr i)
setR8 R8A v
- AddSpImm8 (Imm8 y) -> do
+ AddSpImm8 (Imm8 y) -> {-# SCC "AddSpImm8" #-} do
x <- r16 R16SP
let
res :: Word16
@@ -580,7 +580,7 @@ step ins = do
regs . regFlagZ .= False
regs . regFlagN .= False
setR16 R16SP res
- LdHlSpPlusImm8 (Imm8 y) -> do
+ LdHlSpPlusImm8 (Imm8 y) -> {-# SCC "LdHlSpPlusImm8" #-} do
x <- r16 R16SP
let
res :: Word16
@@ -591,12 +591,12 @@ step ins = do
regs . regFlagZ .= False
regs . regFlagN .= False
setR16 R16HL res
- LdSpHl -> do
+ LdSpHl -> {-# SCC "LdSpHl" #-} do
v <- r16 R16HL
setR16 R16SP v
- Di -> regs . regFlagIME .= False
- Ei -> regs . regFlagIME .= True
- CbRlcR8 r -> do
+ Di -> {-# SCC "Di" #-} regs . regFlagIME .= False
+ Ei -> {-# SCC "Ei" #-} regs . regFlagIME .= True
+ CbRlcR8 r -> {-# SCC "CbRlcR8" #-} do
v <- r8 r
let res = rotateL v 1
regs . regFlagH .= False
@@ -604,7 +604,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 7 v
setR8 r res
- CbRrcR8 r -> do
+ CbRrcR8 r -> {-# SCC "CbRrcR8" #-} do
v <- r8 r
let res = rotateR v 1
regs . regFlagH .= False
@@ -612,7 +612,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 0 v
setR8 r res
- CbRlR8 r -> do
+ CbRlR8 r -> {-# SCC "CbRlR8" #-} do
v <- r8 r
c <- use $ regs . regFlagC
let res = shiftL v 1 .|. if c then 0b1 else 0
@@ -621,7 +621,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 7 v
setR8 r res
- CbRrR8 r -> do
+ CbRrR8 r -> {-# SCC "CbRrR8" #-} do
v <- r8 r
c <- use $ regs . regFlagC
let rizz = shiftR v 1 .|. if c then 0b10000000 else 0
@@ -630,7 +630,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 0 v
setR8 r rizz
- CbSlaR8 r -> do
+ CbSlaR8 r -> {-# SCC "CbSlaR8" #-} do
v <- r8 r
let res = shiftL v 1
regs . regFlagZ .= (res == 0)
@@ -638,7 +638,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 7 v
setR8 r res
- CbSraR8 r -> do
+ CbSraR8 r -> {-# SCC "CbSraR8" #-} do
v <- r8 r
let
vs :: Int8
@@ -651,7 +651,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 0 v
setR8 r res
- CbSwapR8 r -> do
+ CbSwapR8 r -> {-# SCC "CbSwapR8" #-} do
v <- r8 r
let res = rotate v 4
regs . regFlagZ .= (res == 0)
@@ -659,7 +659,7 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= False
setR8 r res
- CbSrlR8 r -> do
+ CbSrlR8 r -> {-# SCC "CbSrlR8" #-} do
v <- r8 r
let res = shiftR v 1
regs . regFlagZ .= (res == 0)
@@ -667,15 +667,15 @@ step ins = do
regs . regFlagN .= False
regs . regFlagC .= w8bit 0 v
setR8 r res
- CbBitB3R8 (B3 idx) r -> do
+ CbBitB3R8 (B3 idx) r -> {-# SCC "CbBitB3R8" #-} do
v <- r8 r
regs . regFlagH .= True
regs . regFlagN .= False
regs . regFlagZ .= not (w8bit idx v)
- CbResB3R8 (B3 idx) r -> do
+ CbResB3R8 (B3 idx) r -> {-# SCC "CbResB3R8" #-} do
v <- r8 r
setR8 r $ v .&. (0xff .^. shiftL 0b1 idx)
- CbSetB3R8 (B3 idx) r -> do
+ CbSetB3R8 (B3 idx) r -> {-# SCC "CbSetB3R8" #-} do
v <- r8 r
setR8 r $ v .|. shiftL 0b1 idx
where
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Component/Interrupt.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Component/Interrupt.hs
new file mode 100644
index 0000000..ec5540c
--- /dev/null
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/Component/Interrupt.hs
@@ -0,0 +1,33 @@
+module Fig.Emulator.GB.Component.Interrupt where
+
+import Fig.Prelude
+
+import Fig.Emulator.GB.Utils
+import Fig.Emulator.GB.Bus
+
+newtype InterruptError = InterruptError Text
+ deriving Show
+instance Exception InterruptError
+instance Pretty InterruptError where
+ pretty (InterruptError b) = mconcat
+ [ "interrupt error: "
+ , b
+ ]
+
+compInterrupt :: (MonadIO m, MonadThrow m) => Component m
+compInterrupt = Component
+ { compState = ()
+ , compMatches = \a -> a == 0xff0f || a == 0xffff
+ , compUpdate = \s _ -> pure s
+ , compWrite = \s (Addr a) v -> do
+ case a of
+ 0xff0f -> do
+ -- log $ "set IF:" <> show8 v
+ pure ()
+ 0xffff -> do
+ -- log $ "set IE:" <> show8 v
+ pure ()
+ _ -> throwM . InterruptError $ "write to invalid address: " <> pretty (Addr a)
+ pure s
+ , compRead = \_ _ -> pure 0x00
+ }
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs
index e20dd8d..b17292c 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs
@@ -3,7 +3,6 @@ module Fig.Emulator.GB.Component.RAM
) where
import Fig.Prelude
-import Prelude (fromIntegral)
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
@@ -25,11 +24,11 @@ compWRAM start size = Component
{ compState = V.replicate size 0 :: V.Vector Word8
, compMatches = \a ->
a >= start && a <= end
- , compUpdate = \s _ -> pure s
- , compWrite = \s ad v -> do
+ , compUpdate = \s _ -> {-# SCC "ComponentWRAMUpdate" #-} pure s
+ , compWrite = \s ad v -> {-# SCC "ComponentWRAMWrite" #-} do
let offset = fromIntegral . unAddr $ ad - start
pure $ V.modify (\ms -> MV.write ms offset v) s
- , compRead = \s ad -> do
+ , compRead = \s ad -> {-# SCC "ComponentWRAMRead" #-} do
let offset = fromIntegral . unAddr $ ad - start
case s V.!? offset of
Nothing -> throwM . RAMError $ mconcat
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Component/Serial.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Component/Serial.hs
index 59200f1..0ee529b 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB/Component/Serial.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/Component/Serial.hs
@@ -18,16 +18,18 @@ instance Pretty SerialError where
, b
]
-compSerial :: (MonadIO m, MonadThrow m) => Handle -> Component m
-compSerial h = Component
+compSerial :: (MonadIO m, MonadThrow m) => Maybe Handle -> Component m
+compSerial mh = Component
{ compState = ()
, compMatches = (== 0xff01)
, compUpdate = \s _ -> pure s
, compWrite = \s _ v -> do
- log $ mconcat
- [ "wrote serial byte: ", tshow $ chr $ fromIntegral v
- ]
- liftIO . hPutChar h . chr $ fromIntegral v
+ -- log $ mconcat
+ -- [ "wrote serial byte: ", tshow $ chr $ fromIntegral v
+ -- ]
+ case mh of
+ Nothing -> pure ()
+ Just h -> liftIO . hPutChar h . chr $ fromIntegral v
pure s
, compRead = \_ _ -> pure 0x00
}
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Component/Video.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Component/Video.hs
index 3f73be0..9326e41 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB/Component/Video.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/Component/Video.hs
@@ -1,7 +1,7 @@
module Fig.Emulator.GB.Component.Video where
import Fig.Prelude
-import Prelude (error, fromIntegral)
+import Prelude (error)
import qualified Foreign.Ptr as Ptr
import qualified Foreign.Storable as St
@@ -16,7 +16,6 @@ import qualified SDL
import Fig.Emulator.GB.Utils
import Fig.Emulator.GB.Bus
-import Data.Vector.Generic.Lens (vector)
newtype VideoError = VideoError Text
deriving Show
@@ -93,8 +92,8 @@ blitTile v (Addr a) (bx, by) fb = do
(x, y) fb
data VideoAddrRange
- = VideoAddrVRAM !Addr
- | VideoAddrStatus !Addr
+ = VideoAddrVRAM Addr
+ | VideoAddrStatus Addr
deriving Show
videoAddrRange :: Addr -> Maybe VideoAddrRange
@@ -111,14 +110,14 @@ data RenderState
deriving Show
data VideoState = VideoState
- { vstFb :: !Framebuffer
- , vstVRAM :: !(V.Vector Word8)
- , vstScx :: !Word8
- , vstScy :: !Word8
- , vstLy :: !Word8
- , vstLx :: !Word8
- , vstRenderState :: !RenderState
- , vstTick :: !Word16
+ { vstFb :: Framebuffer
+ , vstVRAM :: V.Vector Word8
+ , vstScx :: Word8
+ , vstScy :: Word8
+ , vstLy :: Word8
+ , vstLx :: Word8
+ , vstRenderState :: RenderState
+ , vstTick :: Word16
}
compVideo :: (MonadIO m, MonadThrow m) => Framebuffer -> Component m
@@ -134,7 +133,7 @@ compVideo framebuffer = Component
, vstTick = 0
}
, compMatches = isJust . videoAddrRange
- , compUpdate = \olds t -> do
+ , compUpdate = \olds t -> {-# SCC "ComponentVideoUpdate" #-} do
let tick = vstTick olds + fromIntegral t
let s = olds { vstTick = tick }
case vstRenderState s of
@@ -162,13 +161,13 @@ compVideo framebuffer = Component
let ly = vstLy olds + 1
if ly == 153
then do
- log "vblank"
+ -- log "vblank"
-- logTilemap $ vstVRAM s
- forM_ (zip [0..] [48,52,45,111,112,32,114,44,105,109,109] :: [(Int, Int)]) \(idx, b) -> do
- blitTile (vstVRAM s)
- (fromIntegral $ b * 16)
- (fromIntegral $ idx * 8, 0)
- $ vstFb s
+ -- forM_ (zip [0..] [48,52,45,111,112,32,114,44,105,109,109] :: [(Int, Int)]) \(idx, b) -> do
+ -- blitTile (vstVRAM s)
+ -- (fromIntegral $ b * 16)
+ -- (fromIntegral $ idx * 8, 0)
+ -- $ vstFb s
-- forM_ ([0..10] :: [Int]) \x -> do
-- forM_ ([0..10] :: [Int]) \y -> do
-- let i = y * 10 + x
@@ -180,7 +179,7 @@ compVideo framebuffer = Component
else
pure s { vstTick = 0, vstLy = ly }
| otherwise -> pure s
- , compWrite = \s a v -> case videoAddrRange a of
+ , compWrite = \s a v -> {-# SCC "ComponentVideoWrite" #-} case videoAddrRange a of
Nothing -> throwM $ VideoError $ mconcat
[ "write address out of bounds for video system: "
, pretty a
@@ -205,7 +204,7 @@ compVideo framebuffer = Component
0xa -> pure s
0xb -> pure s
_ -> pure s
- , compRead = \s a -> case videoAddrRange a of
+ , compRead = \s a -> {-# SCC "ComponentVideoRead" #-} case videoAddrRange a of
Nothing -> throwM $ VideoError $ mconcat
[ "read address out of bounds for video system: "
, pretty a
diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Test/Instr.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Test/Instr.hs
index 9c3da8c..f0e8724 100644
--- a/fig-emulator-gb/src/Fig/Emulator/GB/Test/Instr.hs
+++ b/fig-emulator-gb/src/Fig/Emulator/GB/Test/Instr.hs
@@ -4,7 +4,7 @@ module Fig.Emulator.GB.Test.Instr where
import Control.Lens.TH (makeLenses)
import Control.Lens ((^.))
-import Control.Monad.State (StateT(..))
+import Control.Monad.State.Strict (StateT(..))
import Data.Word (Word8, Word16)
import qualified Data.Aeson as Aeson