From 3a0a7b0a89fd841edd5f25f79cdb877051d0e948 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Tue, 9 Apr 2024 22:35:42 -0400 Subject: End-of-stream emulator WIP --- .../src/Fig/Emulator/GB/Component/RAM.hs | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs (limited to 'fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs') diff --git a/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs b/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs new file mode 100644 index 0000000..c88033e --- /dev/null +++ b/fig-emulator-gb/src/Fig/Emulator/GB/Component/RAM.hs @@ -0,0 +1,41 @@ +module Fig.Emulator.GB.Component.RAM + ( compWRAM + ) where + +import Fig.Prelude +import Prelude (fromIntegral) + +import qualified Data.Vector as V +import qualified Data.Vector.Mutable as MV +import Data.Word (Word8) + +import Fig.Emulator.GB.Bus + +newtype RAMError = RAMError Text + deriving Show +instance Exception RAMError +instance Pretty RAMError where + pretty (RAMError b) = mconcat + [ "internal RAM error: " + , b + ] + +compWRAM :: (MonadIO m, MonadThrow m) => Addr -> Int -> Component m +compWRAM start size = Component + { compState = V.replicate size 0 :: V.Vector Word8 + , compMatches = \a -> + a >= start && a < end + , compUpdate = pure + , compWrite = \s ad v -> do + let offset = fromIntegral . unAddr $ ad - start + pure $ V.modify (\ms -> MV.write ms offset v) s + , compRead = \s ad -> do + let offset = fromIntegral . unAddr $ ad - start + case s V.!? offset of + Nothing -> throwM . RAMError $ mconcat + [ "address ", pretty ad, " out of bounds" + ] + Just v -> pure v + } + where + end = start + Addr (fromIntegral size) -- cgit v1.2.3