module Nes.CPU.Instructions.Access (
lda,
ldx,
ldy,
sta,
stx,
sty,
las,
) where
import Control.Monad
import Data.Bits
import Nes.CPU.Instructions.Addressing
import Nes.CPU.Instructions.After (setZeroAndNegativeFlags)
import Nes.CPU.Monad
import Nes.CPU.State
import Nes.Internal.MonadState
import Nes.Memory
lda :: AddressingMode -> CPU r ()
lda :: forall r. AddressingMode -> CPU r ()
lda = Register -> AddressingMode -> CPU r ()
forall r. Register -> AddressingMode -> CPU r ()
loadRegisterFromMemory Register
A
ldx :: AddressingMode -> CPU r ()
ldx :: forall r. AddressingMode -> CPU r ()
ldx = Register -> AddressingMode -> CPU r ()
forall r. Register -> AddressingMode -> CPU r ()
loadRegisterFromMemory Register
X
ldy :: AddressingMode -> CPU r ()
ldy :: forall r. AddressingMode -> CPU r ()
ldy = Register -> AddressingMode -> CPU r ()
forall r. Register -> AddressingMode -> CPU r ()
loadRegisterFromMemory Register
Y
{-# INLINE loadRegisterFromMemory #-}
loadRegisterFromMemory :: Register -> AddressingMode -> CPU r ()
loadRegisterFromMemory :: forall r. Register -> AddressingMode -> CPU r ()
loadRegisterFromMemory Register
reg AddressingMode
mode = do
Addr
argAddr <- AddressingMode -> CPU r Addr
forall r. AddressingMode -> CPU r Addr
getOperandAddr AddressingMode
mode
Byte
param <- Addr -> () -> CPU r Byte
forall a (m :: * -> *). MemoryInterface a m => Addr -> a -> m Byte
readByte Addr
argAddr ()
Register -> Lens' CPUState Byte
register Register
reg ((Byte -> Identity Byte) -> CPUState -> Identity CPUState)
-> Byte -> CPU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> a -> m ()
.= Byte
param
Byte -> CPU r ()
forall r. Byte -> CPU r ()
setZeroAndNegativeFlags Byte
param
sta :: AddressingMode -> CPU r ()
sta :: forall r. AddressingMode -> CPU r ()
sta = Register -> AddressingMode -> CPU r ()
forall r. Register -> AddressingMode -> CPU r ()
storeRegisterInMemory Register
A
stx :: AddressingMode -> CPU r ()
stx :: forall r. AddressingMode -> CPU r ()
stx = Register -> AddressingMode -> CPU r ()
forall r. Register -> AddressingMode -> CPU r ()
storeRegisterInMemory Register
X
sty :: AddressingMode -> CPU r ()
sty :: forall r. AddressingMode -> CPU r ()
sty = Register -> AddressingMode -> CPU r ()
forall r. Register -> AddressingMode -> CPU r ()
storeRegisterInMemory Register
Y
{-# INLINE storeRegisterInMemory #-}
storeRegisterInMemory :: Register -> AddressingMode -> CPU r ()
storeRegisterInMemory :: forall r. Register -> AddressingMode -> CPU r ()
storeRegisterInMemory Register
reg AddressingMode
mode = do
(Addr
addr, Bool
crosses) <- AddressingMode -> CPU r (Addr, Bool)
forall r. AddressingMode -> CPU r (Addr, Bool)
getOperandAddr' AddressingMode
mode
Byte
value <- Getting Byte CPUState Byte -> CPU r Byte
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use (Getting Byte CPUState Byte -> CPU r Byte)
-> Getting Byte CPUState Byte -> CPU r Byte
forall a b. (a -> b) -> a -> b
$ Register -> Lens' CPUState Byte
register Register
reg
let shouldDummyRead :: Bool
shouldDummyRead = (Bool
crosses Bool -> Bool -> Bool
&& (AddressingMode
mode AddressingMode -> AddressingMode -> Bool
forall a. Eq a => a -> a -> Bool
/= AddressingMode
AbsoluteX)) Bool -> Bool -> Bool
|| (Bool -> Bool
not Bool
crosses Bool -> Bool -> Bool
&& (AddressingMode
mode AddressingMode -> AddressingMode -> Bool
forall a. Eq a => a -> a -> Bool
== AddressingMode
AbsoluteX Bool -> Bool -> Bool
|| AddressingMode
mode AddressingMode -> AddressingMode -> Bool
forall a. Eq a => a -> a -> Bool
== AddressingMode
AbsoluteY Bool -> Bool -> Bool
|| AddressingMode
mode AddressingMode -> AddressingMode -> Bool
forall a. Eq a => a -> a -> Bool
== AddressingMode
IndirectY))
Bool -> CPU r () -> CPU r ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
shouldDummyRead (CPU r () -> CPU r ()) -> CPU r () -> CPU r ()
forall a b. (a -> b) -> a -> b
$ CPU r Byte -> CPU r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (CPU r Byte -> CPU r ()) -> CPU r Byte -> CPU r ()
forall a b. (a -> b) -> a -> b
$ Addr -> () -> CPU r Byte
forall a (m :: * -> *). MemoryInterface a m => Addr -> a -> m Byte
readByte Addr
addr ()
Byte -> Addr -> () -> CPU r ()
forall a (m :: * -> *).
MemoryInterface a m =>
Byte -> Addr -> a -> m ()
writeByte Byte
value Addr
addr ()
las :: AddressingMode -> CPU r ()
las :: forall r. AddressingMode -> CPU r ()
las AddressingMode
mode = do
Addr
addr <- AddressingMode -> CPU r Addr
forall r. AddressingMode -> CPU r Addr
getOperandAddr AddressingMode
mode
Byte
byte <- Addr -> () -> CPU r Byte
forall a (m :: * -> *). MemoryInterface a m => Addr -> a -> m Byte
readByte Addr
addr ()
Byte
s <- Getting Byte CPUState Byte -> CPU r Byte
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Byte CPUState Byte
Lens' CPUState Byte
registerS
let res :: Byte
res = Byte
byte Byte -> Byte -> Byte
forall a. Bits a => a -> a -> a
.&. Byte
s
(Byte -> Identity Byte) -> CPUState -> Identity CPUState
Lens' CPUState Byte
registerA ((Byte -> Identity Byte) -> CPUState -> Identity CPUState)
-> Byte -> CPU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> a -> m ()
.= Byte
res
(Byte -> Identity Byte) -> CPUState -> Identity CPUState
Lens' CPUState Byte
registerX ((Byte -> Identity Byte) -> CPUState -> Identity CPUState)
-> Byte -> CPU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> a -> m ()
.= Byte
res
(Byte -> Identity Byte) -> CPUState -> Identity CPUState
Lens' CPUState Byte
registerS ((Byte -> Identity Byte) -> CPUState -> Identity CPUState)
-> Byte -> CPU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> a -> m ()
.= Byte
res
Byte -> CPU r ()
forall r. Byte -> CPU r ()
setZeroAndNegativeFlags Byte
res