mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-06-07 06:29:32 +00:00
Machine model is a bit fuller now.
This commit is contained in:
parent
8c9dfe7004
commit
5af7c458ea
|
@ -92,11 +92,39 @@ that has a natural symmetrical opcode (e.g. `pha`, `sei`). These instructions
|
|||
take a block. The natural symmetrical opcode is inserted at the end of the
|
||||
block.
|
||||
|
||||
### Loops ###
|
||||
|
||||
Still need to figure this out.
|
||||
|
||||
Typical `repeat` loop looks like:
|
||||
|
||||
ldy #0
|
||||
_loop:
|
||||
lda #65
|
||||
sta screen, y
|
||||
iny
|
||||
cpy #250
|
||||
bne _loop
|
||||
|
||||
This might be
|
||||
|
||||
routine blah {
|
||||
ldy# 0
|
||||
repeat bne {
|
||||
lda# 65
|
||||
sta,y screen
|
||||
iny
|
||||
cpy# 250
|
||||
}
|
||||
}
|
||||
|
||||
Note, `screen` must be a `byte table` here.
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
* Parse HEX values like $40A3
|
||||
* Full machine model
|
||||
* Fuller machine model
|
||||
* Addressing modes; rename instructions to match
|
||||
|
||||
Tests
|
||||
|
|
|
@ -9,11 +9,11 @@ import SixtyPical.Model
|
|||
-- -- -- -- data-flow-analysis context -- -- -- --
|
||||
|
||||
data Usage = Unknown
|
||||
| Value LocationName -- obviously a bit daft for now
|
||||
| Retained Register
|
||||
| Value StorageLocation -- obviously a bit daft for now
|
||||
| Retained StorageLocation
|
||||
deriving (Show, Ord, Eq)
|
||||
|
||||
type RoutineContext = Map.Map Register Usage
|
||||
type RoutineContext = Map.Map StorageLocation Usage
|
||||
|
||||
type ProgramContext = Map.Map RoutineName RoutineContext
|
||||
|
||||
|
|
|
@ -21,14 +21,16 @@ locationDeclared locName (Program decls _) =
|
|||
elem locName (map (getDeclLocationName) decls)
|
||||
where
|
||||
|
||||
-- in the following, we mean Named locations
|
||||
|
||||
routineUsedLocations (Routine _ instrs) = blockUsedLocations instrs
|
||||
|
||||
blockUsedLocations [] = []
|
||||
blockUsedLocations (instr:instrs) =
|
||||
(instrUsedLocations instr) ++ blockUsedLocations instrs
|
||||
|
||||
instrUsedLocations (LOAD reg loc) = [loc]
|
||||
instrUsedLocations (CMP reg loc) = [loc]
|
||||
instrUsedLocations (LOAD reg (NamedLocation loc)) = [loc]
|
||||
instrUsedLocations (CMP reg (NamedLocation loc)) = [loc]
|
||||
-- TODO: JSR...
|
||||
instrUsedLocations (IFEQ b1 b2) =
|
||||
blockUsedLocations b1 ++ blockUsedLocations b2
|
||||
|
|
|
@ -35,10 +35,10 @@ emitInstrs _ _ [] = ""
|
|||
emitInstrs p r (instr:instrs) =
|
||||
" " ++ emitInstr p r instr ++ "\n" ++ emitInstrs p r instrs
|
||||
|
||||
emitInstr p r (LOAD A label) = "lda " ++ label
|
||||
emitInstr p r (LOAD X label) = "ldx " ++ label
|
||||
emitInstr p r (LOAD Y label) = "ldy " ++ label
|
||||
emitInstr p r (CMP A label) = "cmp " ++ label
|
||||
emitInstr p r (LOAD A (NamedLocation label)) = "lda " ++ label
|
||||
emitInstr p r (LOAD X (NamedLocation label)) = "ldx " ++ label
|
||||
emitInstr p r (LOAD Y (NamedLocation label)) = "ldy " ++ label
|
||||
emitInstr p r (CMP A (NamedLocation label)) = "cmp " ++ label
|
||||
|
||||
emitInstr p r (COPY A X) = "tax"
|
||||
emitInstr p r (COPY A Y) = "tay"
|
||||
|
|
|
@ -8,10 +8,30 @@ type Address = Int -- LET'S ASSUME THIS IS AT LEAST 16 BITS
|
|||
|
||||
type LocationName = String
|
||||
|
||||
data Register = A | X | Y -- | MemLoc LocationName
|
||||
-- We do not include the PC as it of course changes constantly.
|
||||
-- We do not include the stack pointer, as it should not change over
|
||||
-- the lifetime of a single routine. (Always pop what you pushed.)
|
||||
-- Ditto the I flag. (always enable interrupts after disabling them.)
|
||||
-- We do not include the B flag, because for us, BRK is game over, man.
|
||||
|
||||
-- One of these should never refer to the program code. We can only police
|
||||
-- this up to a point.
|
||||
|
||||
data StorageLocation = A
|
||||
| Y
|
||||
| X
|
||||
| FlagN
|
||||
| FlagV
|
||||
| FlagD
|
||||
| FlagZ
|
||||
| FlagC
|
||||
| NamedLocation LocationName
|
||||
deriving (Show, Ord, Eq)
|
||||
|
||||
allRegisters = [A, X, Y]
|
||||
-- this is bunk, man. if a location does not appear in an analysis
|
||||
-- map the meaning should be taken to be "preserved".
|
||||
|
||||
allRegisters = [A, X, Y, FlagN, FlagV, FlagD, FlagZ, FlagC]
|
||||
|
||||
-- -- -- -- program model -- -- -- --
|
||||
|
||||
|
@ -25,9 +45,9 @@ data Decl = Assign LocationName Size Address -- .alias
|
|||
|
||||
type RoutineName = String
|
||||
|
||||
data Instruction = LOAD Register LocationName
|
||||
| COPY Register Register
|
||||
| CMP Register LocationName
|
||||
data Instruction = LOAD StorageLocation StorageLocation
|
||||
| COPY StorageLocation StorageLocation
|
||||
| CMP StorageLocation StorageLocation
|
||||
| JSR RoutineName
|
||||
| IFEQ [Instruction] [Instruction]
|
||||
| NOP
|
||||
|
|
|
@ -88,28 +88,28 @@ cmp = do
|
|||
string "cmp"
|
||||
spaces
|
||||
l <- locationName
|
||||
return (CMP A l)
|
||||
return (CMP A (NamedLocation l))
|
||||
|
||||
lda :: Parser Instruction
|
||||
lda = do
|
||||
string "lda"
|
||||
spaces
|
||||
l <- locationName
|
||||
return (LOAD A l)
|
||||
return (LOAD A (NamedLocation l))
|
||||
|
||||
ldx :: Parser Instruction
|
||||
ldx = do
|
||||
string "ldx"
|
||||
spaces
|
||||
l <- locationName
|
||||
return (LOAD X l)
|
||||
return (LOAD X (NamedLocation l))
|
||||
|
||||
ldy :: Parser Instruction
|
||||
ldy = do
|
||||
string "ldy"
|
||||
spaces
|
||||
l <- locationName
|
||||
return (LOAD Y l)
|
||||
return (LOAD Y (NamedLocation l))
|
||||
|
||||
txa :: Parser Instruction
|
||||
txa = do
|
||||
|
|
Loading…
Reference in New Issue
Block a user