From 249d29b695d11ded67438fc3e26d000f879f5546 Mon Sep 17 00:00:00 2001 From: Cat's Eye Technologies Date: Wed, 2 Apr 2014 20:02:20 +0100 Subject: [PATCH] addressing_mode gen --- README.markdown | 27 ++++++++-- src/SixtyPical/Emitter.hs | 1 + src/SixtyPical/Parser.hs | 102 ++++++++++++++++++++------------------ 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/README.markdown b/README.markdown index 9e09194..dbd4655 100644 --- a/README.markdown +++ b/README.markdown @@ -205,6 +205,7 @@ In these, `absolute` must be a `reserve`d or `locate`d address. lda absolute lda absolute, x lda absolute, y + lda (absolute), y ldx #immediate ldx absolute @@ -242,6 +243,7 @@ In these, `absolute` must be a `reserve`d or `locate`d address. sta absolute sta absolute, x sta absolute, y + sta (absolute), y stx absolute @@ -357,7 +359,7 @@ All declarations (`reserve`s and `assign`s) must come before any `routines`. All locations used in all routines must be declared first. - | reserve word score + | reserve byte score | routine main { | lda score | cmp screen @@ -366,8 +368,8 @@ All locations used in all routines must be declared first. Even in inner blocks. - | reserve word score - | assign word screen 1024 + | reserve byte score + | assign byte screen 1024 | routine main { | lda score | cmp screen @@ -461,6 +463,23 @@ We cannot absolute-indexed a word. | } ? indexed access of non-table +> We cannot absolute acess a word. +> +> | assign word screen 1024 +> | routine main { +> | lda screen +> | } +> ? absolute access of non-byte-based address +> +> Instead, we have to do this. +> +> | assign word screen 1024 +> | routine main { +> | lda | lda >screen +> | } +> = True + -> Tests for functionality "Emit ASM for SixtyPical program" -> Functionality "Emit ASM for SixtyPical program" is implemented by @@ -475,6 +494,7 @@ We cannot absolute-indexed a word. | lda screen | lda screen, x | lda screen, y + | lda (screen), y | inc screen | tax | inx @@ -520,6 +540,7 @@ We cannot absolute-indexed a word. = lda screen = lda screen, x = lda screen, y + = lda (screen), y = inc screen = tax = inx diff --git a/src/SixtyPical/Emitter.hs b/src/SixtyPical/Emitter.hs index 7da2e2e..608d3a7 100644 --- a/src/SixtyPical/Emitter.hs +++ b/src/SixtyPical/Emitter.hs @@ -61,6 +61,7 @@ emitInstr p r (COPY (Indexed (NamedLocation (Just ByteTable) label) X) A) = "lda emitInstr p r (COPY (Indexed (NamedLocation (Just ByteTable) label) Y) A) = "lda " ++ label ++ ", y" emitInstr p r (COPY A (IndirectIndexed (NamedLocation st label) Y)) = "sta (" ++ label ++ "), y" +emitInstr p r (COPY (IndirectIndexed (NamedLocation st label) Y) A) = "lda (" ++ label ++ "), y" emitInstr p r (CMP A (NamedLocation st label)) = "cmp " ++ label emitInstr p r (CMP X (NamedLocation st label)) = "cpx " ++ label diff --git a/src/SixtyPical/Parser.hs b/src/SixtyPical/Parser.hs index 55dc6cb..981c3cb 100644 --- a/src/SixtyPical/Parser.hs +++ b/src/SixtyPical/Parser.hs @@ -111,17 +111,6 @@ comment = do -- -- -- -- -- -- commands -- -- -- -- -- -immediate :: (DataValue -> Instruction) -> Parser Instruction -immediate f = do - string "#" - v <- data_value - return $ f v - -absolute :: (LocationName -> Instruction) -> Parser Instruction -absolute f = do - l <- locationName - return $ f l - index :: Parser StorageLocation index = do string "," @@ -132,11 +121,12 @@ index = do "x" -> X "y" -> Y -data Directness = Directly LocationName - | Indirectly LocationName +data AddressingModality = Directly LocationName + | Indirectly LocationName + | Immediately DataValue deriving (Ord, Show, Eq) -indirect_location :: Parser Directness +indirect_location :: Parser AddressingModality indirect_location = do string "(" spaces @@ -145,25 +135,23 @@ indirect_location = do spaces return $ Indirectly l -direct_location :: Parser Directness +direct_location :: Parser AddressingModality direct_location = do l <- locationName return $ Directly l -directness_location = (try indirect_location) <|> direct_location +immediate :: Parser AddressingModality +immediate = do + string "#" + v <- data_value + return $ Immediately v -indirect_indexed :: (Directness -> [StorageLocation] -> Instruction) -> Parser Instruction -indirect_indexed f = do - d <- directness_location +addressing_mode :: (AddressingModality -> [StorageLocation] -> Instruction) -> Parser Instruction +addressing_mode f = do + d <- ((try immediate) <|> (try indirect_location) <|> direct_location) indexes <- many index return $ f d indexes -absolute_indexed :: (LocationName -> [StorageLocation] -> Instruction) -> Parser Instruction -absolute_indexed f = do - l <- locationName - indexes <- many index - return $ f l indexes - commented_command :: Parser Instruction commented_command = do c <- command @@ -265,79 +253,99 @@ cmp :: Parser Instruction cmp = do string "cmp" spaces - (try $ immediate (\v -> CMP A (Immediate v)) <|> - absolute (\l -> CMP A (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = CMP A (Immediate v) + gen (Directly l) [] = CMP A (NamedLocation Nothing l) cpx :: Parser Instruction cpx = do string "cpx" spaces - (try $ immediate (\v -> CMP X (Immediate v)) <|> - absolute (\l -> CMP X (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = CMP X (Immediate v) + gen (Directly l) [] = CMP X (NamedLocation Nothing l) cpy :: Parser Instruction cpy = do string "cpy" spaces - (try $ immediate (\v -> CMP Y (Immediate v)) <|> - absolute (\l -> CMP Y (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = CMP Y (Immediate v) + gen (Directly l) [] = CMP Y (NamedLocation Nothing l) adc :: Parser Instruction adc = do string "adc" spaces - (try $ immediate (\v -> ADD A (Immediate v)) <|> - absolute (\l -> ADD A (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = ADD A (Immediate v) + gen (Directly l) [] = ADD A (NamedLocation Nothing l) sbc :: Parser Instruction sbc = do string "sbc" spaces - (try $ immediate (\v -> SUB A (Immediate v)) <|> - absolute (\l -> SUB A (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = SUB A (Immediate v) + gen (Directly l) [] = SUB A (NamedLocation Nothing l) and :: Parser Instruction and = do string "and" spaces - (try $ immediate (\v -> AND A (Immediate v)) <|> - absolute (\l -> AND A (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = AND A (Immediate v) + gen (Directly l) [] = AND A (NamedLocation Nothing l) ora :: Parser Instruction ora = do string "ora" spaces - (try $ immediate (\v -> OR A (Immediate v)) <|> - absolute (\l -> OR A (NamedLocation Nothing l))) + addressing_mode gen + where + gen (Immediately v) [] = OR A (Immediate v) + gen (Directly l) [] = OR A (NamedLocation Nothing l) lda :: Parser Instruction lda = do string "lda" spaces - (try $ immediate (\v -> COPY (Immediate v) A) <|> absolute_indexed gen) + addressing_mode gen where - gen l [] = COPY (NamedLocation Nothing l) A - gen l [reg] = COPY (Indexed (NamedLocation Nothing l) reg) A + gen (Immediately v) [] = COPY (Immediate v) A + gen (Directly l) [] = COPY (NamedLocation Nothing l) A + gen (Directly l) [reg] = COPY (Indexed (NamedLocation Nothing l) reg) A + gen (Indirectly l) [reg] = COPY (IndirectIndexed (NamedLocation Nothing l) reg) A ldx :: Parser Instruction ldx = do string "ldx" spaces - (try $ immediate (\v -> COPY (Immediate v) X) <|> - absolute (\l -> COPY (NamedLocation Nothing l) X)) + addressing_mode gen + where + gen (Immediately v) [] = COPY (Immediate v) X + gen (Directly l) [] = COPY (NamedLocation Nothing l) X ldy :: Parser Instruction ldy = do string "ldy" spaces - (try $ immediate (\v -> COPY (Immediate v) Y) <|> - absolute (\l -> COPY (NamedLocation Nothing l) Y)) + addressing_mode gen + where + gen (Immediately v) [] = COPY (Immediate v) Y + gen (Directly l) [] = COPY (NamedLocation Nothing l) Y sta :: Parser Instruction sta = do string "sta" spaces - indirect_indexed gen + addressing_mode gen where gen (Directly l) [] = COPY A (NamedLocation Nothing l) gen (Directly l) [reg] = COPY A (Indexed (NamedLocation Nothing l) reg)