module Nes.Memory (
newMemory,
memorySize,
Byte (..),
Addr (..),
byteToAddr,
bytesToAddr,
negateByte,
byteToInt,
addrToInt,
unsafeAddrToByte,
MemoryPointer,
MemoryInterface (..),
) where
import Data.Ix (Ix)
import Foreign
newtype Byte = Byte {Byte -> Word8
unByte :: Word8} deriving (Byte -> Byte -> Bool
(Byte -> Byte -> Bool) -> (Byte -> Byte -> Bool) -> Eq Byte
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Byte -> Byte -> Bool
== :: Byte -> Byte -> Bool
$c/= :: Byte -> Byte -> Bool
/= :: Byte -> Byte -> Bool
Eq, Int -> Byte -> ShowS
[Byte] -> ShowS
Byte -> String
(Int -> Byte -> ShowS)
-> (Byte -> String) -> ([Byte] -> ShowS) -> Show Byte
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Byte -> ShowS
showsPrec :: Int -> Byte -> ShowS
$cshow :: Byte -> String
show :: Byte -> String
$cshowList :: [Byte] -> ShowS
showList :: [Byte] -> ShowS
Show, Integer -> Byte
Byte -> Byte
Byte -> Byte -> Byte
(Byte -> Byte -> Byte)
-> (Byte -> Byte -> Byte)
-> (Byte -> Byte -> Byte)
-> (Byte -> Byte)
-> (Byte -> Byte)
-> (Byte -> Byte)
-> (Integer -> Byte)
-> Num Byte
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Byte -> Byte -> Byte
+ :: Byte -> Byte -> Byte
$c- :: Byte -> Byte -> Byte
- :: Byte -> Byte -> Byte
$c* :: Byte -> Byte -> Byte
* :: Byte -> Byte -> Byte
$cnegate :: Byte -> Byte
negate :: Byte -> Byte
$cabs :: Byte -> Byte
abs :: Byte -> Byte
$csignum :: Byte -> Byte
signum :: Byte -> Byte
$cfromInteger :: Integer -> Byte
fromInteger :: Integer -> Byte
Num, Eq Byte
Byte
Eq Byte =>
(Byte -> Byte -> Byte)
-> (Byte -> Byte -> Byte)
-> (Byte -> Byte -> Byte)
-> (Byte -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> Byte
-> (Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Bool)
-> (Byte -> Maybe Int)
-> (Byte -> Int)
-> (Byte -> Bool)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int -> Byte)
-> (Byte -> Int)
-> Bits Byte
Int -> Byte
Byte -> Bool
Byte -> Int
Byte -> Maybe Int
Byte -> Byte
Byte -> Int -> Bool
Byte -> Int -> Byte
Byte -> Byte -> Byte
forall a.
Eq a =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
$c.&. :: Byte -> Byte -> Byte
.&. :: Byte -> Byte -> Byte
$c.|. :: Byte -> Byte -> Byte
.|. :: Byte -> Byte -> Byte
$cxor :: Byte -> Byte -> Byte
xor :: Byte -> Byte -> Byte
$ccomplement :: Byte -> Byte
complement :: Byte -> Byte
$cshift :: Byte -> Int -> Byte
shift :: Byte -> Int -> Byte
$crotate :: Byte -> Int -> Byte
rotate :: Byte -> Int -> Byte
$czeroBits :: Byte
zeroBits :: Byte
$cbit :: Int -> Byte
bit :: Int -> Byte
$csetBit :: Byte -> Int -> Byte
setBit :: Byte -> Int -> Byte
$cclearBit :: Byte -> Int -> Byte
clearBit :: Byte -> Int -> Byte
$ccomplementBit :: Byte -> Int -> Byte
complementBit :: Byte -> Int -> Byte
$ctestBit :: Byte -> Int -> Bool
testBit :: Byte -> Int -> Bool
$cbitSizeMaybe :: Byte -> Maybe Int
bitSizeMaybe :: Byte -> Maybe Int
$cbitSize :: Byte -> Int
bitSize :: Byte -> Int
$cisSigned :: Byte -> Bool
isSigned :: Byte -> Bool
$cshiftL :: Byte -> Int -> Byte
shiftL :: Byte -> Int -> Byte
$cunsafeShiftL :: Byte -> Int -> Byte
unsafeShiftL :: Byte -> Int -> Byte
$cshiftR :: Byte -> Int -> Byte
shiftR :: Byte -> Int -> Byte
$cunsafeShiftR :: Byte -> Int -> Byte
unsafeShiftR :: Byte -> Int -> Byte
$crotateL :: Byte -> Int -> Byte
rotateL :: Byte -> Int -> Byte
$crotateR :: Byte -> Int -> Byte
rotateR :: Byte -> Int -> Byte
$cpopCount :: Byte -> Int
popCount :: Byte -> Int
Bits, Eq Byte
Eq Byte =>
(Byte -> Byte -> Ordering)
-> (Byte -> Byte -> Bool)
-> (Byte -> Byte -> Bool)
-> (Byte -> Byte -> Bool)
-> (Byte -> Byte -> Bool)
-> (Byte -> Byte -> Byte)
-> (Byte -> Byte -> Byte)
-> Ord Byte
Byte -> Byte -> Bool
Byte -> Byte -> Ordering
Byte -> Byte -> Byte
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Byte -> Byte -> Ordering
compare :: Byte -> Byte -> Ordering
$c< :: Byte -> Byte -> Bool
< :: Byte -> Byte -> Bool
$c<= :: Byte -> Byte -> Bool
<= :: Byte -> Byte -> Bool
$c> :: Byte -> Byte -> Bool
> :: Byte -> Byte -> Bool
$c>= :: Byte -> Byte -> Bool
>= :: Byte -> Byte -> Bool
$cmax :: Byte -> Byte -> Byte
max :: Byte -> Byte -> Byte
$cmin :: Byte -> Byte -> Byte
min :: Byte -> Byte -> Byte
Ord)
newtype Addr = Addr {Addr -> Word16
unAddr :: Word16} deriving (Addr -> Addr -> Bool
(Addr -> Addr -> Bool) -> (Addr -> Addr -> Bool) -> Eq Addr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Addr -> Addr -> Bool
== :: Addr -> Addr -> Bool
$c/= :: Addr -> Addr -> Bool
/= :: Addr -> Addr -> Bool
Eq, Int -> Addr -> ShowS
[Addr] -> ShowS
Addr -> String
(Int -> Addr -> ShowS)
-> (Addr -> String) -> ([Addr] -> ShowS) -> Show Addr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Addr -> ShowS
showsPrec :: Int -> Addr -> ShowS
$cshow :: Addr -> String
show :: Addr -> String
$cshowList :: [Addr] -> ShowS
showList :: [Addr] -> ShowS
Show, Integer -> Addr
Addr -> Addr
Addr -> Addr -> Addr
(Addr -> Addr -> Addr)
-> (Addr -> Addr -> Addr)
-> (Addr -> Addr -> Addr)
-> (Addr -> Addr)
-> (Addr -> Addr)
-> (Addr -> Addr)
-> (Integer -> Addr)
-> Num Addr
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Addr -> Addr -> Addr
+ :: Addr -> Addr -> Addr
$c- :: Addr -> Addr -> Addr
- :: Addr -> Addr -> Addr
$c* :: Addr -> Addr -> Addr
* :: Addr -> Addr -> Addr
$cnegate :: Addr -> Addr
negate :: Addr -> Addr
$cabs :: Addr -> Addr
abs :: Addr -> Addr
$csignum :: Addr -> Addr
signum :: Addr -> Addr
$cfromInteger :: Integer -> Addr
fromInteger :: Integer -> Addr
Num, Eq Addr
Addr
Eq Addr =>
(Addr -> Addr -> Addr)
-> (Addr -> Addr -> Addr)
-> (Addr -> Addr -> Addr)
-> (Addr -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> Addr
-> (Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Bool)
-> (Addr -> Maybe Int)
-> (Addr -> Int)
-> (Addr -> Bool)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int -> Addr)
-> (Addr -> Int)
-> Bits Addr
Int -> Addr
Addr -> Bool
Addr -> Int
Addr -> Maybe Int
Addr -> Addr
Addr -> Int -> Bool
Addr -> Int -> Addr
Addr -> Addr -> Addr
forall a.
Eq a =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
$c.&. :: Addr -> Addr -> Addr
.&. :: Addr -> Addr -> Addr
$c.|. :: Addr -> Addr -> Addr
.|. :: Addr -> Addr -> Addr
$cxor :: Addr -> Addr -> Addr
xor :: Addr -> Addr -> Addr
$ccomplement :: Addr -> Addr
complement :: Addr -> Addr
$cshift :: Addr -> Int -> Addr
shift :: Addr -> Int -> Addr
$crotate :: Addr -> Int -> Addr
rotate :: Addr -> Int -> Addr
$czeroBits :: Addr
zeroBits :: Addr
$cbit :: Int -> Addr
bit :: Int -> Addr
$csetBit :: Addr -> Int -> Addr
setBit :: Addr -> Int -> Addr
$cclearBit :: Addr -> Int -> Addr
clearBit :: Addr -> Int -> Addr
$ccomplementBit :: Addr -> Int -> Addr
complementBit :: Addr -> Int -> Addr
$ctestBit :: Addr -> Int -> Bool
testBit :: Addr -> Int -> Bool
$cbitSizeMaybe :: Addr -> Maybe Int
bitSizeMaybe :: Addr -> Maybe Int
$cbitSize :: Addr -> Int
bitSize :: Addr -> Int
$cisSigned :: Addr -> Bool
isSigned :: Addr -> Bool
$cshiftL :: Addr -> Int -> Addr
shiftL :: Addr -> Int -> Addr
$cunsafeShiftL :: Addr -> Int -> Addr
unsafeShiftL :: Addr -> Int -> Addr
$cshiftR :: Addr -> Int -> Addr
shiftR :: Addr -> Int -> Addr
$cunsafeShiftR :: Addr -> Int -> Addr
unsafeShiftR :: Addr -> Int -> Addr
$crotateL :: Addr -> Int -> Addr
rotateL :: Addr -> Int -> Addr
$crotateR :: Addr -> Int -> Addr
rotateR :: Addr -> Int -> Addr
$cpopCount :: Addr -> Int
popCount :: Addr -> Int
Bits, Eq Addr
Eq Addr =>
(Addr -> Addr -> Ordering)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Addr)
-> (Addr -> Addr -> Addr)
-> Ord Addr
Addr -> Addr -> Bool
Addr -> Addr -> Ordering
Addr -> Addr -> Addr
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Addr -> Addr -> Ordering
compare :: Addr -> Addr -> Ordering
$c< :: Addr -> Addr -> Bool
< :: Addr -> Addr -> Bool
$c<= :: Addr -> Addr -> Bool
<= :: Addr -> Addr -> Bool
$c> :: Addr -> Addr -> Bool
> :: Addr -> Addr -> Bool
$c>= :: Addr -> Addr -> Bool
>= :: Addr -> Addr -> Bool
$cmax :: Addr -> Addr -> Addr
max :: Addr -> Addr -> Addr
$cmin :: Addr -> Addr -> Addr
min :: Addr -> Addr -> Addr
Ord, Ord Addr
Ord Addr =>
((Addr, Addr) -> [Addr])
-> ((Addr, Addr) -> Addr -> Int)
-> ((Addr, Addr) -> Addr -> Int)
-> ((Addr, Addr) -> Addr -> Bool)
-> ((Addr, Addr) -> Int)
-> ((Addr, Addr) -> Int)
-> Ix Addr
(Addr, Addr) -> Int
(Addr, Addr) -> [Addr]
(Addr, Addr) -> Addr -> Bool
(Addr, Addr) -> Addr -> Int
forall a.
Ord a =>
((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
$crange :: (Addr, Addr) -> [Addr]
range :: (Addr, Addr) -> [Addr]
$cindex :: (Addr, Addr) -> Addr -> Int
index :: (Addr, Addr) -> Addr -> Int
$cunsafeIndex :: (Addr, Addr) -> Addr -> Int
unsafeIndex :: (Addr, Addr) -> Addr -> Int
$cinRange :: (Addr, Addr) -> Addr -> Bool
inRange :: (Addr, Addr) -> Addr -> Bool
$crangeSize :: (Addr, Addr) -> Int
rangeSize :: (Addr, Addr) -> Int
$cunsafeRangeSize :: (Addr, Addr) -> Int
unsafeRangeSize :: (Addr, Addr) -> Int
Ix)
{-# INLINE byteToAddr #-}
byteToAddr :: Byte -> Addr
byteToAddr :: Byte -> Addr
byteToAddr = Word16 -> Addr
Addr (Word16 -> Addr) -> (Byte -> Word16) -> Byte -> Addr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word16) -> (Byte -> Word8) -> Byte -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Byte -> Word8
unByte
{-# INLINE byteToInt #-}
byteToInt :: Byte -> Int
byteToInt :: Byte -> Int
byteToInt = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> (Byte -> Word8) -> Byte -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Byte -> Word8
unByte
{-# INLINE negateByte #-}
negateByte :: Byte -> Byte
negateByte :: Byte -> Byte
negateByte (Byte Word8
byte) = Word8 -> Byte
Byte (Int8 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (-(Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
byte :: Int8) Int8 -> Int8 -> Int8
forall a. Num a => a -> a -> a
- Int8
1) :: Word8)
{-# INLINE addrToInt #-}
addrToInt :: Addr -> Int
addrToInt :: Addr -> Int
addrToInt = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> (Addr -> Word16) -> Addr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> Word16
unAddr
{-# INLINE unsafeAddrToByte #-}
unsafeAddrToByte :: Addr -> Byte
unsafeAddrToByte :: Addr -> Byte
unsafeAddrToByte (Addr Word16
a) = Word8 -> Byte
Byte (Word8 -> Byte) -> Word8 -> Byte
forall a b. (a -> b) -> a -> b
$ Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
a
{-# INLINE bytesToAddr #-}
bytesToAddr :: Byte -> Byte -> Addr
bytesToAddr :: Byte -> Byte -> Addr
bytesToAddr Byte
low Byte
high = Addr -> Int -> Addr
forall a. Bits a => a -> Int -> a
shiftL (Byte -> Addr
byteToAddr Byte
high) Int
8 Addr -> Addr -> Addr
forall a. Bits a => a -> a -> a
.|. Byte -> Addr
byteToAddr Byte
low
type MemoryPointer = ForeignPtr ()
memorySize :: Addr
memorySize :: Addr
memorySize = Addr
0xffff
newMemory :: IO MemoryPointer
newMemory :: IO MemoryPointer
newMemory = Int -> IO MemoryPointer
forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes (Int -> IO MemoryPointer) -> Int -> IO MemoryPointer
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Word16 -> Int
forall a b. (a -> b) -> a -> b
$ Addr -> Word16
unAddr Addr
memorySize
class MemoryInterface a m where
readByte :: Addr -> a -> m Byte
readAddr :: Addr -> a -> m Addr
writeByte :: Byte -> Addr -> a -> m ()
writeAddr :: Addr -> Addr -> a -> m ()