---------------------------------------------------------------------- -- FILE: Swi.hs -- DESCRIPTION: -- DATE: 03/22/2001 -- PROJECT: -- LANGUAGE PLATFORM: -- OS PLATFORM: RedHat Linux 6.2 -- AUTHOR: Jeffrey A. Meunier -- EMAIL: jeffm@cse.uconn.edu -- MAINTAINER: Alex Mason -- EMAIL: axman6@gmail.com ---------------------------------------------------------------------- module Arm.Swi where ---------------------------------------------------------------------- -- Standard libraries. ---------------------------------------------------------------------- import Data.Bits import Data.Char import Data.IORef import Data.Word ---------------------------------------------------------------------- -- Local libraries. ---------------------------------------------------------------------- import Arm.CPU import Arm.Loader import Arm.Memory import Arm.Register import Arm.RegisterName line = "----------------------------------------" ---------------------------------------------------------------------- -- Software interrupt services. ---------------------------------------------------------------------- swi :: CPU -> Word32 -> Bool -> IO () -- display character in R0 swi cpu 0 debug = do let regs = registers cpu r0 <- getReg regs R0 let c = fromIntegral r0 if debug then do putStrLn line putStrLn ("CHR: [" ++ [chr c] ++ "]") putStrLn line else putStr [chr c] -- display integer in R0 swi cpu 1 debug = do let regs = registers cpu r0 <- getReg regs R0 let r0i = fromIntegral r0 if debug then do putStrLn line putStrLn ("INT: [" ++ show r0i ++ "]") putStrLn line else putStr (show r0i) -- display string starting in location contained in R0 swi cpu 2 debug = do let regs = registers cpu r0 <- getReg regs R0 str <- fetchString (memory cpu) r0 if debug then do putStrLn line putStrLn ("STR: [" ++ str ++ "]") putStrLn line else putStr str -- read a number from the keyboard, place in R0 swi cpu 3 debug = do if debug then do putStrLn line putStr "INPUT INT: " else return () i <- readLn if debug then putStrLn line else return () let w = fromIntegral i let regs = registers cpu setReg regs R0 w -- read a string from the keyboard, place in buffer that -- r0 points to, with maximum length in r1 (this service -- will not store more than r1 - 1 characters in the -- buffer, the string will automatically be null-terminated) swi cpu 4 debug = do if debug then do putStrLn line putStr "INPUT STRING: " else return () s <- getLine if debug then putStrLn s else return () let regs = registers cpu addr <- getReg regs R0 r1 <- getReg regs R1 let len = fromIntegral r1 let s' = take (len - 1) s let mem = memory cpu loadString mem addr (s' ++ ['\NUL']) -- display newline swi cpu 10 debug = do if debug then do putStrLn line putStrLn "NEWLINE" putStrLn line else putStrLn "" -- exit swi cpu 11 debug = do if debug then do putStrLn line putStrLn "NORMAL EXIT" putStrLn line else return () let runFlag = running cpu writeIORef runFlag False swi cpu a debug = error $ "unknown SWI: " ++ show a ++ " " ++ show debug ---------------------------------------------------------------------- -- Fetch a string from memory. ---------------------------------------------------------------------- fetchString :: Memory -> Address -> IO String fetchString mem addr = do word <- readMem mem addr let c4 = fromIntegral ((word .&. 0xFF000000) `shift` (-24)) let c3 = fromIntegral ((word .&. 0xFF0000) `shift` (-16)) let c2 = fromIntegral ((word .&. 0xFF00) `shift` (-8)) let c1 = fromIntegral (word .&. 0xFF) if c1 == 0 then return "" else if c2 == 0 then return [chr c1] else if c3 == 0 then return [chr c1, chr c2] else if c4 == 0 then return [chr c1, chr c2, chr c3] else do s <- fetchString mem (addr + 4) return ([chr c1, chr c2, chr c3, chr c4] ++ s) ---------------------------------------------------------------------- -- eof ----------------------------------------------------------------------