{-# OPTIONS -Wall #-} module Language.Pck.Cpu.Register ( -- * Note -- $note -- * Basic types GRegArray , Flag(..) , FlagArray -- * access to general purpose registers , initGReg , getGReg , getGReg2 , getGRegs , modifyGReg -- * access to flag registers , initFlag , getFlag , getFlags , modifyFlag , judgeFCond ) where import Data.Array (Array, Ix, listArray, (//), (!), elems) import Language.Pck.Cpu.Instruction -- $note -- This is an implementation dependent module. -- It's better to use functions in Language.Pck.Cpu.State. ---------------------------------------- -- general purpose register implementation ---------------------------------------- type GRegArray = Array GReg Int -- | initialize the general purpose registers array initGReg :: GRegArray initGReg = listArray (minBound::GReg, maxBound::GReg) $ replicate (fromEnum (maxBound::GReg) + 1) 0 -- | get a value of the general purpose register getGReg :: GRegArray -> GReg -> Int getGReg ary reg = ary ! reg -- | get values of the general purpose register pair getGReg2 :: GRegArray -> GReg -> GReg -> (Int, Int) getGReg2 ary ra rb = (ary ! ra, ary ! rb) -- | get all values of the general purpose registers getGRegs :: GRegArray -> [Int] getGRegs = elems -- | modify general purpose registers modifyGReg :: GRegArray -> GReg -> Int -> GRegArray modifyGReg ary reg val = ary // [(reg,val)] ---------------------------------------- -- flag register implementation ---------------------------------------- data Flag = FLZ -- ^ zero flag | FLC -- ^ carry flag deriving (Show, Eq, Ord, Ix, Enum, Bounded) type FlagArray = Array Flag Bool -- | initialize the flag registers array initFlag :: FlagArray initFlag = listArray (minBound::Flag, maxBound::Flag) $ replicate (fromEnum (maxBound::Flag) + 1) False -- | get a value of the flag register value getFlag :: FlagArray -> Flag -> Bool getFlag ary flag = ary ! flag -- | get all values of the flag registers getFlags :: FlagArray -> [Bool] getFlags = elems -- | modify flag registers modifyFlag :: FlagArray -> Flag -> Bool -> FlagArray modifyFlag ary flag val = ary // [(flag,val)] -- | judge a flag condition judgeFCond :: FlagArray -> FCond -> Bool judgeFCond ary FCEQ = (getFlag ary FLZ) == True judgeFCond ary FCNE = (getFlag ary FLZ) == False judgeFCond ary FCLT = (getFlag ary FLC) == True judgeFCond ary FCLE = (getFlag ary FLC) == True || (getFlag ary FLZ) == True judgeFCond ary FCGT = (getFlag ary FLC) == False && (getFlag ary FLZ) == False judgeFCond ary FCGE = (getFlag ary FLC) == False