3a_asm: .ascii directive
authorBernhard Urban <lewurm@gmail.com>
Tue, 11 Jan 2011 23:59:28 +0000 (00:59 +0100)
committerBernhard Urban <lewurm@gmail.com>
Tue, 11 Jan 2011 23:59:28 +0000 (00:59 +0100)
in der .data section kann man nun
  .ascii "balblalbabla ganz viel text"
schreiben und der ganze schas wird auch richtig ausgerichtet (weil wir haben ja
wrong^H^H^H^H^Hlittle endian im data ram :P)

3a_asm/DTFormat.hs
3a_asm/Main.hs

index 8b85ca1cca9c0656e4155bd0b6c391b4600b6db6..17b2f014c8bc737dab587f75dc2bfbcabff301ce 100644 (file)
@@ -21,6 +21,7 @@ type ValueToParse = String
 type Code = String
 type Label = String
 type Comment = String
+type Ascii = String
 
 data DTF =
        DTF_Data Address Value Code Label Comment | -- 0;...
@@ -33,6 +34,7 @@ data DTF =
        DTF_Org Address |
        DTF_Define Label Value Comment |
        DTF_Fill Repeat Value Label Code Comment |
+       DTF_Ascii String Label Code Comment |
        DTF_State DT_State
 
 instance Show (DTF) where
@@ -48,6 +50,7 @@ showsDTF (DTF_SectionToDet a v c l s) = (++) (datins "std" a v c l s)
 showsDTF (DTF_Org a) = (++) (printf "org;%08x\n" a)
 showsDTF (DTF_Define l a c) = (++) (printf "def;%s;%08x;%s\n" l a c)
 showsDTF (DTF_Fill r v code l c) = (++) (printf "fill;%08x;%08x;%s;%s;%s\n" r v code l c)
+showsDTF (DTF_Ascii str l code c) = (++) (printf "ascii;%s;%s;%s;%s" str code l c)
 showsDTF (DTF_State s) = (++) (printf "sta;%s\n" (show s))
 
 datins :: String -> Address -> Value -> Code -> Label -> Comment -> String
index 08522c658d34fabbc0d97ac1cb7d2744d543418c..3470e0d2777c2d5fa3258f579bf8ad7e9708ad8b 100644 (file)
@@ -14,7 +14,9 @@ import Text.Parsec.String
 import Text.Parsec.Combinator
 import qualified Data.Map as M
 import Data.List
+import Data.Char
 import Data.Word
+import Data.Bits
 import qualified Data.ByteString.Lazy as BL
 import Control.Monad
 
@@ -70,6 +72,25 @@ convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdt
                where
                repi :: Int
                repi = fromInteger (toInteger rep)
+       actlist (DTF_Ascii str lab code comment) =
+               (DTF_Data datacnt (strval!!0) code lab comment):
+               [(DTF_Data ic (strval!!i) code lab comment)
+               | i<-[1..len]
+               , let ic = [datacnt,(datacnt+0x4)..]!!i
+               ]
+               ++ next
+               where
+               len = ((length str)`div`4)
+               strval :: [Word32]
+               strval = pf $ map (\x -> fromIntegral $ ord x :: Word8) str
+               pf :: [Word8] -> [Word32]
+               pf [] = []
+               pf xs@(_:[]) = pf (xs ++ [0,0,0])
+               pf xs@(_:_:[]) = pf (xs ++ [0,0])
+               pf xs@(_:_:_:[]) = pf (xs ++ [0])
+               pf (a:b:c:d:xs) = (foldl' accum 0 [d,c,b,a]):(pf xs)
+                       where
+                       accum x o = (x `shiftL` 8) .|. fromIntegral o
        actlist y = y:next
 
        (newdict,next) = convertDTF xs (nstate newdtf) (ndatacnt newdtf) (ninstrcnt newdtf) (ndict newdtf)
@@ -80,6 +101,9 @@ convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdt
        ndatacnt (DTF_Fill rep _ _ _ _)
                | state == InData = datacnt + (4*rep)
                | otherwise = datacnt
+       ndatacnt (DTF_Ascii str _ _ _)
+               | state == InData = datacnt + (4*len)
+               where len = fromIntegral $ ((length str)`div`4)+1
        ndatacnt (DTF_Data _ _ _ _ _) = inc datacnt
        ndatacnt _ = datacnt
 
@@ -105,6 +129,9 @@ convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdt
        ndict (DTF_Fill _ _ _ l _)
                | state == InText = dict `add_elem` (l,instrcnt)
                | state == InData = dict `add_elem` (l,datacnt)
+       ndict (DTF_Ascii _ l c _)
+               | state == InData = dict `add_elem` (l,datacnt)
+               | otherwise = error $ "don't use .ascii in .text here: " ++ c
        ndict _ = dict
 
        newdtf = case (parse (parseDTFLine dict) "" (str++"\n")) of
@@ -125,9 +152,7 @@ convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdt
                                NoState -> error "missing .data or .text"
                                InData -> (DTF_Label l c datacnt)
                                InText -> (DTF_Label l c instrcnt)
-               Right z -> z -- DTF_Comment, DTF_State, DTF_Define, DTF_Fill
-
-
+               Right z -> z -- DTF_Comment, DTF_State, DTF_Define, DTF_Fill, DTF_Ascii
 
 testDTF :: String -> IO ()
 testDTF input =
@@ -140,7 +165,7 @@ testDTF input =
 parseDTFLine :: [DictElem] -> Parser DTF
 parseDTFLine dict = foldl1 (<|>) (fmap (\x -> try (x dict)) lineFormats) <* char '\n'
 
-lineFormats = [lf_define, lf_sdata, lf_stext, lf_org, lf_data, lf_ifill, lf_comment, lf_toparse, lf_label]
+lineFormats = [lf_define, lf_sdata, lf_stext, lf_org, lf_data, lf_ifill, lf_ascii, lf_comment, lf_toparse, lf_label]
 
 -- helper
 parseIdent :: Parser String
@@ -193,6 +218,16 @@ lf_ifill d = do
        comment <- try(parseComment) <|> parseMySpaces
        return $ DTF_Fill 1 val (fill ++ code) l comment
 
+lf_ascii _ = do
+       l <- try (parseLabel) <|> string ""
+       skipMany space
+       ascii <- string ".ascii "
+       char '"'
+       str <- many1 $ noneOf "\"";
+       char '"'
+       comment <- try(parseComment) <|> parseMySpaces
+       return $ DTF_Ascii str (ascii ++ "\"" ++ str ++ "\"") l comment
+
 lf_comment _ = do
        comment <- parseComment
        return $ DTF_Comment comment