module Nes.APU.BusInterface.DMC (write4010, write4011, write4012, write4013) where
import Data.Bits
import Nes.APU.Monad
import Nes.APU.State
import Nes.APU.State.DMC
import Nes.Internal.MonadState
import Nes.Memory
{-# INLINE write4010 #-}
write4010 :: Byte -> APU r ()
write4010 :: forall r. Byte -> APU r ()
write4010 Byte
byte = do
let irq :: Bool
irq = Byte
byte Byte -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
7
loop :: Bool
loop = Byte
byte Byte -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
6
rateIdx :: Int
rateIdx = Byte -> Int
byteToInt (Byte -> Int) -> Byte -> Int
forall a b. (a -> b) -> a -> b
$ Byte
byte Byte -> Byte -> Byte
forall a. Bits a => a -> a -> a
.&. Byte
0b1111
rate :: Int
rate = Int -> Int
getPeriodValue Int
rateIdx
(DMC -> Identity DMC) -> APUState -> Identity APUState
Lens' APUState DMC
dmc ((DMC -> Identity DMC) -> APUState -> Identity APUState)
-> (DMC -> DMC) -> APU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> (a -> a) -> m ()
%= \DMC
dmc' ->
DMC
dmc'
{ interruptFlag = irq
, loopFlag = loop
, period = rate
}
{-# INLINE write4011 #-}
write4011 :: Byte -> APU r ()
write4011 :: forall r. Byte -> APU r ()
write4011 Byte
byte = do
let directLoad :: Int
directLoad = Byte -> Int
byteToInt (Byte -> Int) -> Byte -> Int
forall a b. (a -> b) -> a -> b
$ Byte
byte Byte -> Byte -> Byte
forall a. Bits a => a -> a -> a
.&. Byte
0b1111111
(DMC -> Identity DMC) -> APUState -> Identity APUState
Lens' APUState DMC
dmc ((DMC -> Identity DMC) -> APUState -> Identity APUState)
-> (DMC -> DMC) -> APU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> (a -> a) -> m ()
%= \DMC
dmc' -> DMC
dmc'{outputLevel = directLoad}
{-# INLINE write4012 #-}
write4012 :: Byte -> APU r ()
write4012 :: forall r. Byte -> APU r ()
write4012 Byte
byte = do
let sampleAddr :: Addr
sampleAddr = Addr
0xC000 Addr -> Addr -> Addr
forall a. Num a => a -> a -> a
+ (Byte -> Addr
byteToAddr Byte
byte Addr -> Addr -> Addr
forall a. Num a => a -> a -> a
* Addr
64)
(DMC -> Identity DMC) -> APUState -> Identity APUState
Lens' APUState DMC
dmc ((DMC -> Identity DMC) -> APUState -> Identity APUState)
-> (DMC -> DMC) -> APU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> (a -> a) -> m ()
%= \DMC
dmc' -> DMC
dmc'{sampleOgAddr = sampleAddr}
{-# INLINE write4013 #-}
write4013 :: Byte -> APU r ()
write4013 :: forall r. Byte -> APU r ()
write4013 Byte
byte = do
let sampleLength :: Int
sampleLength = (Byte -> Int
byteToInt Byte
byte Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
16) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
(DMC -> Identity DMC) -> APUState -> Identity APUState
Lens' APUState DMC
dmc ((DMC -> Identity DMC) -> APUState -> Identity APUState)
-> (DMC -> DMC) -> APU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> (a -> a) -> m ()
%= \DMC
dmc' -> DMC
dmc'{sampleOgLength = sampleLength}