From 9ae3a621b6f3e6ed35b445be8dc68c060bfd4bf1 Mon Sep 17 00:00:00 2001 From: Cat's Eye Technologies Date: Tue, 1 Apr 2014 20:34:16 +0100 Subject: [PATCH] Beginnings of `vector` type addresses. --- README.markdown | 45 ++++++++++++++++++++++++----- src/SixtyPical/Model.hs | 12 +++++--- src/SixtyPical/Parser.hs | 62 +++++++++++++++++++++++++++++++--------- 3 files changed, 95 insertions(+), 24 deletions(-) diff --git a/README.markdown b/README.markdown index ef7ce62..214883d 100644 --- a/README.markdown +++ b/README.markdown @@ -59,14 +59,27 @@ assembler, with the understanding that the value will be treated "like an address." This is generally an address into the operating system or hardware (e.g. kernal routine, I/O port, etc.) -Inside a routine, an address may be declared with `temporary`. This is like -`static` in C, except the value at that address is not guaranteed to be -retained between invokations of the routine. Such addresses may only be used -within the routine where they are declared. If analysis indicates that two -temporary addresses are never used simultaneously, they may be merged -to the same address. +Not there yet: -An address knows if it is an address of a byte, of a word, or of a table. +> Inside a routine, an address may be declared with `temporary`. This is like +> `static` in C, except the value at that address is not guaranteed to be +> retained between invokations of the routine. Such addresses may only be used +> within the routine where they are declared. If analysis indicates that two +> temporary addresses are never used simultaneously, they may be merged +> to the same address. + +An address knows what kind of data is stored at the address: + +* `byte`: an 8-bit byte. not part of a word. not to be used as an address. + (could be an index though.) +* `word`: a 16-bit word. not to be used as an address. +* `vector`: a 16-bit address of a routine. two operations are supported + on vectors: copying the contents of one vector to another, and jumping + to the code at the address contained in the vector (and this can only + happen at the end of a routine.) +* `byte table`: (not yet implemented) a series of `byte`s + contiguous in memory starting from the address. + this is the only kind of address that can be used in indexed addressing. ### Blocks ### @@ -501,3 +514,21 @@ Nested ifs. = _past_2: = _past_3: = rts + + + | assign byte screen 1024 + | assign vector cinv 788 + | reserve vector save_cinv + | + | routine patch_cinv { + | sei { + | copy vector cinv to save_cinv + | copy routine our_cinv to cinv + | } + | } + | + | routine our_cinv { + | inc screen + | jmp save_cinv + | } + = story checks out diff --git a/src/SixtyPical/Model.hs b/src/SixtyPical/Model.hs index 78ef1c5..39ced15 100644 --- a/src/SixtyPical/Model.hs +++ b/src/SixtyPical/Model.hs @@ -38,12 +38,13 @@ allRegisters = [A, X, Y, FlagN, FlagV, FlagD, FlagZ, FlagC] -- -- -- -- program model -- -- -- -- -data Size = Byte - | Word +data StorageType = Byte + | Word + | Vector deriving (Show, Ord, Eq) -data Decl = Assign LocationName Size Address -- .alias - | Reserve LocationName Size -- .word, .byte +data Decl = Assign LocationName StorageType Address -- .alias + | Reserve LocationName StorageType -- .word, .byte deriving (Show, Ord, Eq) type RoutineName = String @@ -59,6 +60,9 @@ data Instruction = LOADIMM StorageLocation DataValue | IF InternalID Branch [Instruction] [Instruction] | REPEAT InternalID Branch [Instruction] | DELTA StorageLocation DataValue + | SEI [Instruction] + | COPYVECTOR StorageLocation StorageLocation + | COPYROUTINE RoutineName StorageLocation | NOP deriving (Show, Ord, Eq) diff --git a/src/SixtyPical/Parser.hs b/src/SixtyPical/Parser.hs index 2a5bb19..1759a82 100644 --- a/src/SixtyPical/Parser.hs +++ b/src/SixtyPical/Parser.hs @@ -8,9 +8,9 @@ import Text.ParserCombinators.Parsec {- Toplevel := {Decl} {Routine}. -Decl := "reserve" Size LocationName - | "assign" Size LocationName Address. -Size := "byte" | "word". +Decl := "reserve" StorageType LocationName + | "assign" StorageType LocationName Address. +StorageType := "byte" | "word" | "vector". Routine := "routine" RoutineName Block. Block := "{" {Command} "}". Command := "if" Branch Block "else" Block @@ -23,6 +23,7 @@ Command := "if" Branch Block "else" Block | "cpy" (LocationName | Immediate) | "inx" | "iny" | "dex" | "dey" | "inc" Location | "dec" Location | "clc" | "cld" | "clv" | "sec" | "sed" + | "sei" Block | "nop". Branch := "bcc" | "bcs" | "beq" | "bmi" | "bne" | "bpl" | "bvc" | "bvs". @@ -38,8 +39,7 @@ reserve :: Parser Decl reserve = do string "reserve" spaces - sz <- size - spaces -- size does not do its own spacesising + sz <- storage_type name <- locationName return $ Reserve name sz @@ -47,18 +47,20 @@ assign :: Parser Decl assign = do string "assign" spaces - sz <- size - spaces -- size does not do its own spacesising + sz <- storage_type name <- locationName addr <- address return $ Assign name sz addr -size :: Parser Size -size = do - s <- (string "byte") <|> (string "word") - return $ case s of - "byte" -> Byte - "word" -> Word +get_storage "byte" = Byte +get_storage "word" = Word +get_storage "vector" = Vector + +storage_type :: Parser StorageType +storage_type = do + s <- (string "byte") <|> (string "word") <|> (string "vector") + spaces + return $ get_storage s routine :: Parser Routine routine = do @@ -88,6 +90,9 @@ command = (try lda) <|> (try inx) <|> (try iny) <|> (try dex) <|> (try dey) <|> (try inc) <|> (try dec) <|> (try clc) <|> (try cld) <|> (try clv) <|> (try sec) <|> (try sed) <|> + (try sei) <|> + (try copy_vector_statement) <|> + (try copy_routine_statement) <|> if_statement <|> repeat_statement <|> nop nop :: Parser Instruction @@ -262,6 +267,13 @@ tay = do spaces return (COPY A Y) +sei :: Parser Instruction +sei = do + string "sei" + spaces + blk <- block + return (SEI blk) + if_statement :: Parser Instruction if_statement = do string "if" @@ -281,6 +293,30 @@ repeat_statement = do blk <- block return (REPEAT 0 brch blk) +copy_vector_statement :: Parser Instruction +copy_vector_statement = do + string "copy" + spaces + string "vector" + spaces + src <- locationName + string "to" + spaces + dst <- locationName + return (COPYVECTOR (NamedLocation src) (NamedLocation dst)) + +copy_routine_statement :: Parser Instruction +copy_routine_statement = do + string "copy" + spaces + string "routine" + spaces + src <- routineName + string "to" + spaces + dst <- locationName + return (COPYROUTINE src (NamedLocation dst)) + branch :: Parser Branch branch = try (b "bcc" BCC) <|> try (b "bcs" BCS) <|> try (b "beq" BEQ) <|> try (b "bmi" BMI) <|> try (b "bne" BNE) <|> try (b "bpl" BPL) <|>