module Nes.CPU.Instructions.Branch (bvc, bvs, bcc, bcs, beq, bne, bmi, bpl) where
import Control.Lens (view)
import Control.Monad
import Nes.CPU.Instructions.Addressing (AddressingMode, getOperandAddr')
import Nes.CPU.Monad
import Nes.CPU.State
import Nes.FlagRegister
import Nes.Internal.MonadState
bvc :: AddressingMode -> CPU r ()
bvc :: forall r. AddressingMode -> CPU r ()
bvc = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Bool -> Bool
not (Bool -> Bool) -> (CPUState -> Bool) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Overflow (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
bvs :: AddressingMode -> CPU r ()
bvs :: forall r. AddressingMode -> CPU r ()
bvs = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Overflow (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
bcc :: AddressingMode -> CPU r ()
bcc :: forall r. AddressingMode -> CPU r ()
bcc = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Bool -> Bool
not (Bool -> Bool) -> (CPUState -> Bool) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Carry (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
bcs :: AddressingMode -> CPU r ()
bcs :: forall r. AddressingMode -> CPU r ()
bcs = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Carry (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
beq :: AddressingMode -> CPU r ()
beq :: forall r. AddressingMode -> CPU r ()
beq = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Zero (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
bne :: AddressingMode -> CPU r ()
bne :: forall r. AddressingMode -> CPU r ()
bne = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Bool -> Bool
not (Bool -> Bool) -> (CPUState -> Bool) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Zero (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
bmi :: AddressingMode -> CPU r ()
bmi :: forall r. AddressingMode -> CPU r ()
bmi = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Negative (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
bpl :: AddressingMode -> CPU r ()
bpl :: forall r. AddressingMode -> CPU r ()
bpl = (CPUState -> Bool) -> AddressingMode -> CPU r ()
forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf (Bool -> Bool
not (Bool -> Bool) -> (CPUState -> Bool) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag StatusRegister -> StatusRegister -> Bool
forall a. FlagRegister a => Flag a -> a -> Bool
getFlag Flag StatusRegister
StatusRegisterFlag
Negative (StatusRegister -> Bool)
-> (CPUState -> StatusRegister) -> CPUState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting StatusRegister CPUState StatusRegister
-> CPUState -> StatusRegister
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting StatusRegister CPUState StatusRegister
Lens' CPUState StatusRegister
status)
{-# INLINE branchOverIf #-}
branchOverIf :: (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf :: forall r. (CPUState -> Bool) -> AddressingMode -> CPU r ()
branchOverIf CPUState -> Bool
check AddressingMode
mode = do
Bool
doBranch <- (CPUState -> Bool) -> CPU r Bool
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets CPUState -> Bool
check
(Addr
addr, Bool
crosses) <- AddressingMode -> CPU r (Addr, Bool)
forall r. AddressingMode -> CPU r (Addr, Bool)
getOperandAddr' AddressingMode
mode
Bool -> CPU r () -> CPU r ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
doBranch (CPU r () -> CPU r ()) -> CPU r () -> CPU r ()
forall a b. (a -> b) -> a -> b
$ do
Bool -> CPU r () -> CPU r ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
crosses CPU r ()
forall r. CPU r ()
tickOnce
CPU r ()
forall r. CPU r ()
tickOnce
(Addr -> Identity Addr) -> CPUState -> Identity CPUState
Lens' CPUState Addr
pc ((Addr -> Identity Addr) -> CPUState -> Identity CPUState)
-> Addr -> CPU r ()
forall s (m :: * -> *) a.
MonadState s m =>
ASetter' s a -> a -> m ()
.= Addr
addr