Created
August 15, 2014 22:23
-
-
Save nulldatamap/d63c1d9cb0b56fa683b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Data.Bits | |
| import Data.Char | |
| import Data.Word | |
| _intToHex :: Int -> Int -> Bool -> String | |
| -- i: integer, l: length of the number string, s: show sign? | |
| _intToHex i l s = sign ++ body | |
| where | |
| n = if i < 0 | |
| then if s | |
| then abs i | |
| else 0xFFFF + i + 1 | |
| else i | |
| sign = if s | |
| then if i < 0 | |
| then "-" | |
| else "+" | |
| else "" | |
| hexchars = "0123456789ABCDEF" | |
| -- Takes the x'th hex digit ( isolate it ) and get the char | |
| body = reverse [ hexchars !! ( shift n ((-4) * x) .&. 0xF ) | |
| | x <- [0..l-1] ] | |
| intToHex :: Int -> Int -> String | |
| intToHex i l = _intToHex i l False | |
| intToSHex :: Int -> Int -> String | |
| intToSHex i l = _intToHex i l True | |
| data AddressMode = Acc | |
| | Abs Int | |
| | AbsX Int | |
| | AbsY Int | |
| | Imm Int | |
| | Impl | |
| | Ind Int | |
| | IndX Int | |
| | IndY Int | |
| | Rel Int | |
| | Zpg Int | |
| | ZpgX Int | |
| | ZpgY Int | |
| instance Show AddressMode where | |
| show Acc = "A" | |
| show (Abs x) = "[" ++ intToHex x 4 ++ "]" | |
| show (AbsX x) = "[" ++ intToHex x 4 ++ ":X]" | |
| show (AbsY x) = "[" ++ intToHex x 4 ++ ":Y]" | |
| show (Imm x) = intToSHex x 4 | |
| show (Impl) = "" | |
| show (Ind x) = "[[" ++ intToHex x 2 ++ "]]" | |
| show (IndX x) = "[[" ++ intToHex x 2 ++ ":X]]" | |
| show (IndY x) = "[[" ++ intToHex x 2 ++ ":Y]]" | |
| show (Rel x) = sx : "[" ++ ax ++ "]" | |
| where | |
| sx:ax = intToSHex x 2 | |
| show (Zpg x) = "[:" ++ intToHex x 2 ++ "]" | |
| show (ZpgX x) = "[:" ++ intToHex x 2 ++ ":X]" | |
| show (ZpgY x) = "[:" ++ intToHex x 2 ++ ":Y]" | |
| data InstructionName = Adc | |
| | And | |
| | Asl | |
| | Bcc | |
| | Bcs | |
| | Beq | |
| | Bit | |
| | Bmi | |
| | Bne | |
| | Bpl | |
| | Brk | |
| | Bvc | |
| | Bvs | |
| | Clc | |
| | Cld | |
| | Cli | |
| | Clv | |
| | Cmp | |
| | Cpx | |
| | Cpy | |
| | Dec | |
| | Dex | |
| | Dey | |
| | Eor | |
| | Inc | |
| | Inx | |
| | Iny | |
| | Jmp | |
| | Jsr | |
| | Lda | |
| | Ldx | |
| | Ldy | |
| | Lsr | |
| | Nop | |
| | Ora | |
| | Pha | |
| | Php | |
| | Pla | |
| | Plp | |
| | Rol | |
| | Ror | |
| | Rti | |
| | Rts | |
| | Sbc | |
| | Sec | |
| | Sed | |
| | Sei | |
| | Sta | |
| | Stx | |
| | Sty | |
| | Tax | |
| | Tay | |
| | Tsx | |
| | Txa | |
| | Txs | |
| | Tya | |
| deriving Show | |
| type Instruction = ( InstructionName, AddressMode ) | |
| toSource :: Instruction -> String | |
| toSource (ins, adr) = inss ++ " " ++ show adr | |
| where | |
| (h:t) = show ins | |
| inss = toLower h : t | |
| intToByte :: Int -> [Word8] | |
| intToByte i = [ (fromIntegral i) .&. 0xFF ] | |
| intToWord :: Int -> [Word8] | |
| intToWord i = (shiftR (fromIntegral i) 2 .&. 0xFF) : intToByte i | |
| encode :: Instruction -> [Word8] | |
| encode (Adc, (Imm x)) = 0x69 : (intToWord x) | |
| encode (Adc, (Zpg x)) = 0x65 : (intToWord x) | |
| encode (Adc, (ZpgX x)) = 0x75 : (intToByte x) | |
| encode (Adc, (Abs x)) = 0x6D : (intToWord x) | |
| encode (Adc, (AbsX x)) = 0x7D : (intToWord x) | |
| encode (Adc, (AbsY x)) = 0x79 : (intToWord x) | |
| encode (Adc, (IndX x)) = 0x61 : (intToByte x) | |
| encode (Adc, (IndY x)) = 0x71 : (intToByte x) | |
| encode (And, (Imm x)) = 0x29 : (intToWord x) | |
| encode (And, (Zpg x)) = 0x25 : (intToByte x) | |
| encode (And, (ZpgX x)) = 0x35 : (intToByte x) | |
| encode (And, (Abs x)) = 0x2D : (intToWord x) | |
| encode (And, (AbsX x)) = 0x3D : (intToWord x) | |
| encode (And, (AbsY x)) = 0x39 : (intToWord x) | |
| encode (And, (IndX x)) = 0x21 : (intToByte x) | |
| encode (And, (IndY x)) = 0x31 : (intToByte x) | |
| encode (Asl, Acc) = [ 0x0A ] | |
| encode (Asl, (Zpg x)) = 0x06 : (intToByte x) | |
| encode (Asl, (ZpgX x)) = 0x16 : (intToByte x) | |
| encode (Asl, (Abs x)) = 0x0E : (intToWord x) | |
| encode (Asl, (AbsX x)) = 0x1E : (intToWord x) | |
| encode (Bcc, (Rel x)) = 0x90 : (intToByte x) | |
| encode (Bcs, (Rel x)) = 0xB0 : (intToByte x) | |
| encode (Beq, (Rel x)) = 0xF0 : (intToByte x) | |
| encode (Bit, (Zpg x)) = 0x24 : (intToByte x) | |
| encode (Bit, (Abs x)) = 0x2C : (intToWord x) | |
| encode (Bmi, (Rel x)) = 0x30 : (intToByte x) | |
| encode (Bne, (Rel x)) = 0xD0 : (intToByte x) | |
| encode (Bpl, (Rel x)) = 0x10 : (intToByte x) | |
| encode (Brk, Impl) = [ 0x00 ] | |
| encode (Bvc, (Rel x)) = 0x50 : (intToByte x) | |
| encode (Bvs, (Rel x)) = 0x70 : (intToByte x) | |
| encode (Clc, Impl) = [ 0x18 ] | |
| encode (Cld, Impl) = [ 0xD8 ] | |
| encode (Cli, Impl) = [ 0x58 ] | |
| encode (Clv, Impl) = [ 0xB8 ] | |
| encode (Cmp, (Imm x)) = 0xC9 : (intToWord x) | |
| encode (Cmp, (Zpg x)) = 0xC5 : (intToByte x) | |
| encode (Cmp, (ZpgX x)) = 0xD5 : (intToByte x) | |
| encode (Cmp, (Abs x)) = 0xCD : (intToWord x) | |
| encode (Cmp, (AbsX x)) = 0xDD : (intToWord x) | |
| encode (Cmp, (AbsY x)) = 0xD9 : (intToWord x) | |
| encode (Cmp, (IndX x)) = 0xC1 : (intToByte x) | |
| encode (Cmp, (IndY x)) = 0xD1 : (intToByte x) | |
| encode (Cpx, (Imm x)) = 0xE0 : (intToWord x) | |
| encode (Cpx, (Zpg x)) = 0xE4 : (intToByte x) | |
| encode (Cpx, (Abs x)) = 0xEC : (intToWord x) | |
| encode (Cpy, (Imm x)) = 0xC0 : (intToWord x) | |
| encode (Cpy, (Zpg x)) = 0xC4 : (intToByte x) | |
| encode (Cpy, (Abs x)) = 0xCC : (intToWord x) | |
| encode (Dec, (Zpg x)) = 0xC6 : (intToByte x) | |
| encode (Dec, (ZpgX x)) = 0xD6 : (intToByte x) | |
| encode (Dec, (Abs x)) = 0xCE : (intToWord x) | |
| encode (Dec, (AbsX x)) = 0xDE : (intToWord x) | |
| encode (Dex, Impl) = [ 0xCA ] | |
| encode (Dey, Impl) = [ 0x88 ] | |
| encode (Eor, (Imm x)) = 0x49 : (intToWord x) | |
| encode (Eor, (Zpg x)) = 0x45 : (intToByte x) | |
| encode (Eor, (ZpgX x)) = 0x55 : (intToByte x) | |
| encode (Eor, (Abs x)) = 0x4D : (intToWord x) | |
| encode (Eor, (AbsX x)) = 0x5D : (intToWord x) | |
| encode (Eor, (AbsY x)) = 0x59 : (intToWord x) | |
| encode (Eor, (IndX x)) = 0x41 : (intToByte x) | |
| encode (Eor, (IndY x)) = 0x51 : (intToByte x) | |
| encode (Inc, (Zpg x)) = 0xE6 : (intToByte x) | |
| encode (Inc, (ZpgX x)) = 0xF6 : (intToByte x) | |
| encode (Inc, (Abs x)) = 0xEE : (intToWord x) | |
| encode (Inc, (AbsX x)) = 0xFE : (intToWord x) | |
| encode (Inx, Impl) = [ 0xE8 ] | |
| encode (Iny, Impl) = [ 0xC8 ] | |
| encode (Jmp, (Abs x)) = 0x4C : (intToWord x) | |
| encode (Jmp, (Ind x)) = 0x6C : (intToByte x) | |
| encode (Jsr, (Abs x)) = 0x20 : (intToWord x) | |
| encode (Lda, (Imm x)) = 0xA9 : (intToWord x) | |
| encode (Lda, (Zpg x)) = 0xA5 : (intToByte x) | |
| encode (Lda, (ZpgX x)) = 0xB5 : (intToByte x) | |
| encode (Lda, (Abs x)) = 0xAD : (intToWord x) | |
| encode (Lda, (AbsX x)) = 0xBD : (intToWord x) | |
| encode (Lda, (AbsY x)) = 0xB9 : (intToWord x) | |
| encode (Lda, (IndX x)) = 0xA1 : (intToByte x) | |
| encode (Lda, (IndY x)) = 0xB1 : (intToByte x) | |
| encode (Ldx, (Imm x)) = 0xA2 : (intToWord x) | |
| encode (Ldx, (Zpg x)) = 0xA6 : (intToByte x) | |
| encode (Ldx, (ZpgY x)) = 0xB6 : (intToByte x) | |
| encode (Ldx, (Abs x)) = 0xAE : (intToWord x) | |
| encode (Ldx, (AbsY x)) = 0xBE : (intToWord x) | |
| encode (Ldy, (Imm x)) = 0xA0 : (intToWord x) | |
| encode (Ldy, (Zpg x)) = 0xA4 : (intToByte x) | |
| encode (Ldy, (ZpgX x)) = 0xB4 : (intToByte x) | |
| encode (Ldy, (Abs x)) = 0xAC : (intToWord x) | |
| encode (Ldy, (AbsX x)) = 0xBC : (intToWord x) | |
| encode (Lsr, Acc) = [ 0x4A ] | |
| encode (Lsr, (Zpg x)) = 0x46 : (intToByte x) | |
| encode (Lsr, (ZpgX x)) = 0x56 : (intToByte x) | |
| encode (Lsr, (Abs x)) = 0x4E : (intToWord x) | |
| encode (Lsr, (AbsX x)) = 0x5E : (intToWord x) | |
| encode (Nop, Impl) = [ 0xEA ] | |
| encode (Ora, (Imm x)) = 0x09 : (intToWord x) | |
| encode (Ora, (Zpg x)) = 0x05 : (intToByte x) | |
| encode (Ora, (ZpgX x)) = 0x15 : (intToByte x) | |
| encode (Ora, (Abs x)) = 0x0D : (intToWord x) | |
| encode (Ora, (AbsX x)) = 0x1D : (intToWord x) | |
| encode (Ora, (AbsY x)) = 0x19 : (intToWord x) | |
| encode (Ora, (IndX x)) = 0x01 : (intToByte x) | |
| encode (Ora, (IndY x)) = 0x11 : (intToByte x) | |
| encode (Pha, Impl) = [ 0x48 ] | |
| encode (Php, Impl) = [ 0x08 ] | |
| encode (Pla, Impl) = [ 0x68 ] | |
| encode (Plp, Impl) = [ 0x28 ] | |
| encode (Rol, Acc) = [ 0x2A ] | |
| encode (Rol, (Zpg x)) = 0x26 : (intToByte x) | |
| encode (Rol, (ZpgX x)) = 0x36 : (intToByte x) | |
| encode (Rol, (Abs x)) = 0x2E : (intToWord x) | |
| encode (Rol, (AbsX x)) = 0x3E : (intToWord x) | |
| encode (Ror, Acc) = [ 0x6A ] | |
| encode (Ror, (Zpg x)) = 0x66 : (intToByte x) | |
| encode (Ror, (ZpgX x)) = 0x76 : (intToByte x) | |
| encode (Ror, (Abs x)) = 0x6E : (intToWord x) | |
| encode (Ror, (AbsX x)) = 0x7E : (intToWord x) | |
| encode (Rti, Impl) = [ 0x40 ] | |
| encode (Rts, Impl) = [ 0x60 ] | |
| encode (Sbc, (Imm x)) = 0xE9 : (intToWord x) | |
| encode (Sbc, (Zpg x)) = 0xE5 : (intToByte x) | |
| encode (Sbc, (ZpgX x)) = 0xF5 : (intToByte x) | |
| encode (Sbc, (Abs x)) = 0xED : (intToWord x) | |
| encode (Sbc, (AbsX x)) = 0xFD : (intToWord x) | |
| encode (Sbc, (AbsY x)) = 0xF9 : (intToWord x) | |
| encode (Sbc, (IndX x)) = 0xE1 : (intToByte x) | |
| encode (Sbc, (IndY x)) = 0xF1 : (intToByte x) | |
| encode (Sec, Impl) = [ 0x38 ] | |
| encode (Sed, Impl) = [ 0xF8 ] | |
| encode (Sei, Impl) = [ 0x78 ] | |
| encode (Sta, (Zpg x)) = 0x85 : (intToByte x) | |
| encode (Sta, (ZpgX x)) = 0x95 : (intToByte x) | |
| encode (Sta, (Abs x)) = 0x8D : (intToWord x) | |
| encode (Sta, (AbsX x)) = 0x9D : (intToWord x) | |
| encode (Sta, (AbsY x)) = 0x99 : (intToWord x) | |
| encode (Sta, (IndX x)) = 0x81 : (intToByte x) | |
| encode (Sta, (IndY x)) = 0x91 : (intToByte x) | |
| encode (Stx, (Zpg x)) = 0x86 : (intToByte x) | |
| encode (Stx, (ZpgY x)) = 0x96 : (intToByte x) | |
| encode (Stx, (Abs x)) = 0x8E : (intToWord x) | |
| encode (Sty, (Zpg x)) = 0x84 : (intToByte x) | |
| encode (Sty, (ZpgX x)) = 0x94 : (intToByte x) | |
| encode (Sty, (Abs x)) = 0x8C : (intToWord x) | |
| encode (Tax, Impl) = [ 0xAA ] | |
| encode (Tay, Impl) = [ 0xA8 ] | |
| encode (Tsx, Impl) = [ 0xBA ] | |
| encode (Txa, Impl) = [ 0x8A ] | |
| encode (Txs, Impl) = [ 0x9A ] | |
| encode (Tya, Impl) = [ 0x98 ] | |
| encode _ = [] | |
| encode_all :: [Instruction] -> (Either Instruction [Word8]) | |
| encode_all (fi:rs) = case encode fi of | |
| [] -> Left fi | |
| bs -> encode_all rs >>= (\x -> return (bs ++ x)) | |
| encode_all [] = Right [] | |
| main = do | |
| print $ encode_all [ (Adc, (AbsX (-3))) | |
| , (Bne, (Abs 13)) ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment