Skip to content

Instantly share code, notes, and snippets.

@nulldatamap
Created August 15, 2014 22:23
Show Gist options
  • Select an option

  • Save nulldatamap/d63c1d9cb0b56fa683b3 to your computer and use it in GitHub Desktop.

Select an option

Save nulldatamap/d63c1d9cb0b56fa683b3 to your computer and use it in GitHub Desktop.
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