Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- 6502 By Lewisk3 (Redxone) - Special thanks to SquidDev for compiler help!
- Methods of emulation:
- 1. Memory segments
- : Use a table of bytes 64KB
- 2. Onboard registers
- : Use a seperate table for registers
- 3. Flags
- : Use a String of true or falses
- 4. Data Stack
- : 256B - Stored on another memory area
- --]]
- -- TODO: 0200 to 0D5B = Screen memory
- -- Setup _6502 Enviorment
- local _NIBBLE = 4
- local _BYTE = 8
- local _KBYTE = 1024
- local _BUSWIDTH = 16
- local _CCENV = true
- -- Non CC lua compatibility
- if(write == nil)then write = io.write end
- if(read == nil)then read = io.read end
- if(sleep == nil)then sleep = function() end end
- if(term == nil)then
- term = {}
- term.current = function() return { setVisible = function(tf) return false end } end
- term.isColor = function() return false end
- term.setCursorPos = function(x,y) end
- term.clear = function() end
- term.setBackgroundColor = function(col) end
- term.setTextColor = function(col) end
- colors = {}
- colors.white = 0
- os = {}
- os.pullEvent = function(ev) return nil end
- shell = {}
- shell.resolve = function(txt) return txt end
- shell.getRunningProgram = function() return "6502" end
- _CCENV = false
- elseif(term.current == nil)then
- term.current().setVisible = function(tf) return false end
- end
- -- Monochrome support
- if(not term.isColor())then
- colors.orange = colors.white
- colors.magenta = colors.white
- colors.lightBlue = colors.white
- colors.yellow = colors.white
- colors.lime = colors.white
- colors.pink = colors.white
- colors.gray = colors.white
- colors.lightGray = colors.white
- colors.cyan = colors.white
- colors.purple = colors.white
- colors.blue = colors.white
- colors.brown = colors.white
- colors.green = colors.white
- colors.red = colors.white
- colors.black = colors.white
- end
- --]] "BIOS" Functionality (All functions defined for Input and Output)
- -- Useful bit logic functions
- typeCheck = function(val)
- if(not tonumber(val,16))then
- return "dec"
- else
- return "hex"
- end
- end
- function valueCheck(val)
- if(type(val) == "string")then val = tonumber(val,16) end
- return val
- end
- toHex = function(dec)
- local hex = ""
- local hexkey = "0123456789ABCDEF"
- local rim
- if(dec == 0)then hex = "0" end
- while dec > 0 do
- rim = math.floor(dec%16)
- hex = hexkey:sub(rim+1,rim+1) .. hex
- dec = math.floor(dec/16)
- end
- if(#hex == 1)then
- hex = "0" .. hex
- end
- if(dec < 0)then
- local num = 256 + dec
- return toHex(num)
- end
- return hex
- end
- toBin = function(dec)
- -- Convert to base 10 soooo easy
- local bin = ""
- local binkey = "01"
- local rim
- if(type(dec) == "string")then error("toBin -> Invalid type: " .. dec) end
- while dec > 0 do
- rim = math.floor(dec%2)
- bin = binkey:sub(rim+1,rim+1) .. bin
- dec = math.floor(dec/2)
- end
- if(#bin < 8)then
- bin = string.rep("0",8-#bin) .. bin
- end
- return bin
- end
- signedHextoDec = function(hex)
- local dechex = tonumber(hex,16)
- -- Check sign
- local checksign = toBin(dechex):sub(1,1)
- --print(toBin(dechex))
- if(checksign == "1")then
- return (dechex - 255)-1
- else
- return dechex
- end
- end
- -- 1Byte Registers
- function writeReg(reg,byte)
- if(not _G.ASM.reg[reg])then
- error("Invalid register -> " .. reg)
- end
- _G.ASM.reg[reg] = string.char(tonumber(byte,16))
- end
- function writeRegDec(reg,byte)
- if(not _G.ASM.reg[reg])then
- error("Invalid register -> " .. reg)
- end
- _G.ASM.reg[reg] = string.char(byte)
- end
- function writeRegChar(reg,ch)
- if(not _G.ASM.reg[reg])then
- error("Invalid register -> " .. reg)
- end
- _G.ASM.reg[reg] = ch
- end
- function moveRegs(from,to,flags)
- if(flags == nil)then flags = false end
- local from = readRegHex(from)
- writeReg(to,from)
- if(flags)then updateResultFlags(readRegDec(to)) end
- end
- function loadRegIndirect(reg,ind,itype)
- local plusx = 0
- local plusy = 0
- -- Optional indexing types
- if(itype == nil)then itype = "" end
- if(itype == "X")then
- plusx = decodeByte(readReg("X"))
- elseif(itype == "Y")then
- plusy = decodeByte(readReg("Y"))
- end
- -- Get ind data from 1, and 2 (ind + 1) and concatenate location, lsb..msb
- local ind = toHex(tonumber(ind,16) + plusx)
- local ind2 = toHex(tonumber(ind,16) + 1)
- local byte1 = readByteHex(ind)
- local byte2 = readByteHex(ind2)
- local addr = toHex(tonumber(byte2 .. byte1,16) + plusy)
- if(#addr < 4)then
- addr = string.rep("0",4-#addr) .. addr
- end
- writeReg(reg,readByteHex(addr))
- end
- --storeRegIndirect("A","15","X")
- function storeRegIndirect(reg,ind,itype)
- local plusx = 0
- local plusy = 0
- -- Optional indexing types
- if(itype == nil)then itype = "" end
- if(itype == "X")then
- plusx = decodeByte(readReg("X"))
- end
- if(itype == "Y")then
- plusy = decodeByte(readReg("Y"))
- end
- local ind = toHex(tonumber(ind,16) + plusx)
- local ind2 = toHex(tonumber(ind,16) + 1)
- local byte1 = readByteHex(ind)
- local byte2 = readByteHex(ind2)
- local addr = toHex(tonumber(byte2 .. byte1,16) + plusy)
- if(#addr < 4)then
- addr = string.rep("0",4-#addr) .. addr
- end
- writeByte(addr,readRegHex(reg))
- end
- function readReg(reg)
- if(not _G.ASM.reg[reg])then
- error("Invalid register -> " .. reg)
- end
- return tostring(_G.ASM.reg[reg])
- end
- function readRegHex(reg)
- return toHex(decodeByte(readReg(reg)))
- end
- function readRegDec(reg)
- if(not _G.ASM.reg[reg])then
- error("Invalid register -> " .. reg)
- end
- return string.byte(_G.ASM.reg[reg])
- end
- function decodeByte(byte)
- return string.byte(byte)
- end
- -- Program Counter
- function readPC()
- local MSB = toHex(string.byte(_G.ASM.reg['PC']:sub(1,1)))
- local LSB = toHex(string.byte(_G.ASM.reg['PC']:sub(2,2)))
- return MSB .. LSB
- end
- setPC = function(bytes)
- if(#bytes > 4)then print("Program counter must be 4Bytes!") end
- if(#bytes < 4)then
- bytes = string.rep("0",4-#bytes) .. bytes
- end
- local MSB = string.char(tonumber(bytes:sub(1,2),16))
- local LSB = string.char(tonumber(bytes:sub(3,4),16))
- --print(MSB .. LSB)
- _G.ASM.reg['PC'] = MSB .. LSB
- end
- getProgramByte = function(byte)
- -- Program byte will be a hex value
- local hexPC = toHex(string.byte(readReg('PC')))
- -- PROGM is in ASCII format
- -- Convert to HEX then return
- return readByteHex(hexPC)
- end
- movePC = function(bytes)
- local absval = toHex(tonumber(readPC(),16) + bytes)
- if(#absval < 4)then absval = "0" .. absval end
- setPC(absval)
- end
- -- Stacks
- function pushStack(val)
- local sp = toHex(string.byte(readReg('SP')))
- local pointer = toHex(string.byte(readReg("SP")))
- local val = tonumber(val,16)
- local offs = math.floor(tonumber(pointer,16)%_BUSWIDTH)
- local pointer = math.floor(tonumber(pointer,16)/_BUSWIDTH)+1
- local byte = _G.ASM.stack[pointer]
- byte = byte:sub(1,offs-1) .. string.char(val) .. byte:sub(offs+1,#byte)
- _G.ASM.stack[pointer] = byte
- -- Move pointer to next item in stack
- pointer = tonumber(sp,16) - 1
- -- If the pointer reached the end of the stack, reset it
- if(pointer < 1)then
- pointer = "FF"
- -- Write pointer back into Stack Pointer
- writeReg("SP",pointer)
- else
- -- Write pointer back into Stack Pointer
- writeRegDec("SP",pointer)
- end
- end
- function pullStack()
- -- Pull value off stack, and increment the stack pointer
- local sp = toHex(string.byte(readReg("SP")))
- local pointer = toHex(string.byte(readReg("SP"))+1)
- local offs = math.floor(tonumber(pointer,16)%_BUSWIDTH)
- local pointer = math.floor(tonumber(pointer,16)/_BUSWIDTH)+1
- local byte = _G.ASM.stack[pointer]
- -- Move pointer to next item in stack
- pointer = tonumber(sp,16) + 1
- -- If the pointer reached the end of the stack, reset it
- if(pointer > 255)then
- pointer = "00"
- -- Write pointer back into Stack Pointer
- writeReg("SP",pointer)
- else
- -- Write pointer back into Stack Pointer
- writeRegDec("SP",pointer)
- end
- if(byte == nil)then
- return string.char("0")
- end
- return byte:sub(offs,offs)
- end
- -- Flags
- function setFlag(flagbit,onoff)
- if(_G.ASM.flagtypes[flagbit])then flagbit = _G.ASM.flagtypes[flagbit] end
- flagbit = tostring(flagbit)
- local flags = toBin(decodeByte(_G.ASM.flags))
- if(onoff ~= 1 and onoff ~= 0)then error("Invaild flag state!") end
- if(#flags < 0 or #flags > 8)then error("Invalid flag index!") end
- flags = flags:sub(1,flagbit-1) .. tostring(onoff) .. flags:sub(flagbit+1,#flags)
- _G.ASM.flags = string.char(tonumber(flags,2))
- end
- function getFlag(flagbit)
- if(_G.ASM.flagtypes[flagbit])then flagbit = _G.ASM.flagtypes[flagbit] end
- return toBin(decodeByte(_G.ASM.flags)):sub(flagbit,flagbit)
- end
- function getFlagsByte()
- return _G.ASM.flags
- end
- function setAllFlags(flaghex)
- _G.ASM.flags = string.char(decodeByte(flaghex))
- end
- function updateResultFlags(val)
- -- Val is in Hex
- if(type(val) == "string")then
- val = tonumber(val,16)
- end
- local binval = toBin(val)
- local flags = toBin(decodeByte(_G.ASM.flags))
- if(val == 0)then
- setFlag("ZRO",1)
- else
- setFlag("ZRO",0)
- end
- if(binval:sub(1,1) == "1")then
- setFlag("NEG",1)
- else
- setFlag("NEG",0)
- end
- return
- end
- function checkCarry(mode,val)
- if(type(val) == "string")then error("Value must be decimal for CARRY check!") end
- if(string.lower(mode) == "add")then
- if(val > 255)then
- setFlag("CRY",1)
- return true
- elseif(val < 0)then
- setFlag("CRY",1)
- return true
- else
- setFlag("CRY",0)
- return false
- end
- elseif(string.lower(mode) == "sub")then
- if(val < 0)then
- setFlag("CRY",0)
- return true
- else
- setFlag("CRY",1)
- return false
- end
- else
- error("Invalid CARRY check mode: " .. mode)
- end
- end
- function addHex(n1,n2)
- local num = tonumber(n1,16) + tonumber(n2,16)
- if(num > 255)then
- num = num - 256
- end
- return toHex(num)
- end
- function subHex(n1,n2)
- local num = (tonumber(n1,16) - tonumber(n2,16))
- if(num < 0)then
- num = 256 + num
- end
- return toHex(num)
- end
- function addSignedDec(n1,n2)
- local num = tonumber(n1,16) + tonumber(n2,16)
- if(num > 255)then
- num = num - 256
- end
- return num
- end
- function subSignedDec(n1,n2)
- local num = (tonumber(n1,16) - tonumber(n2,16))
- if(num < 0)then
- num = 256 + num
- end
- return num
- end
- function checkOverflow(mode,val,val2)
- if(val2 == nil)then val2 = "00" end
- if(string.lower(mode) == "bit")then
- val = toBin(tonumber(val,16))
- -- Check bit 6 (0 indexed) of value for a 1 if so, set V flag
- if(val:sub(2,2) == "1")then
- setFlag("OVR",1)
- return true
- else
- setFlag("OVR",0)
- return false
- end
- elseif(string.lower(mode) == "math")then
- val = signedHextoDec(val) + signedHextoDec(tonumber(val2,16))
- -- Check if value is negative (2s signed)
- -- Convert value into Decimal
- -- Convert decimal into 8bit signed decimal
- -- Check if val is outside the bounds of an 8bit
- -- 2's complement signed number, if so, set overflow.
- if(val < -127)then
- setFlag("OVR",1)
- return true
- elseif(val > 127)then
- setFlag("OVR",1)
- return true
- else
- setFlag("OVR",0)
- return false
- end
- end
- end
- function getSign(val)
- -- Returns true if negative
- return toBin(tonumber(val,16)):sub(1,1) == "1"
- end
- function signedAdd(val,val2)
- if(getFlag("DEC") == "1")then
- return signedAddDec(val, val2)
- end
- local snum = toHex(signedHextoDec(val) + signedHextoDec(val2))
- local num = tonumber(val,16) + tonumber(val2,16)
- checkOverflow("math",snum)
- checkCarry("add",num)
- if(getFlag("CRY") == "1")then
- -- Push off MSB from NUM, to fit in 1Byte space
- num = toHex(num)
- num = num:sub(#num-1,#num)
- num = tonumber(num,16)
- end
- return toHex(num)
- end
- function signedAddDec(val, val2)
- -- Determine string HEX or Dec, based on DEC flag "reasonableness" (Basically, the DEC flag math can still do hex, but only to an extent. )
- if(tonumber(val) == nil)then val = tonumber(val,16) else val = tonumber(val) end
- if(tonumber(val2) == nil)then val2 = tonumber(val2,16) else val2 = tonumber(val2) end
- local num = val + val2
- if(num > 99)then
- setFlag("CRY",1)
- num = ( (num-1) - 99 )
- elseif(num < 0)then
- setFlag("CRY",1)
- else
- setFlag("CRY",0)
- end
- num = tostring(num)
- if(#num == 1)then num = "0" .. num end
- return num
- end
- --signedSub("FF","01")
- function signedSub(val,val2)
- if(getFlag("DEC") == "1")then
- return signedSubDec(val, val2)
- end
- local snum = toHex(signedHextoDec(val) - (signedHextoDec(val2)) )
- local num = tonumber(val,16) - (tonumber(val2,16))
- checkOverflow("math",snum)
- checkCarry("sub",num)
- return toHex(num)
- end
- function signedSubDec(val, val2)
- -- Determine string HEX or Dec, based on DEC flag "reasonableness" (Basically, the DEC flag math can still do hex, but only to an extent. )
- if(tonumber(val) == nil)then val = tonumber(val,16) else val = tonumber(val) end
- if(tonumber(val2) == nil)then val2 = tonumber(val2,16) else val2 = tonumber(val2) end
- local num = val - val2
- if(num < 0)then
- setFlag("CRY",1)
- num = ( 99 + num )
- else
- setFlag("CRY",0)
- end
- num = tostring(num)
- if(#num == 1)then num = "0" .. num end
- return num
- end
- -- RAM
- function readIndirectByte(ind,itype)
- local plusx = 0
- local plusy = 0
- if(itype == "X")then
- plusx = decodeByte(readReg("X"))
- end
- if(itype == "Y")then
- plusy = decodeByte(readReg("Y"))
- end
- local ind = toHex(tonumber(ind,16) + plusx)
- local ind2 = toHex(tonumber(ind,16) + 1)
- local byte1 = readByteHex(ind)
- local byte2 = readByteHex(ind2)
- local addr = toHex(tonumber(byte2 .. byte1,16) + plusy)
- return addr
- end
- function writeByte(loc,byte,debug)
- if(debug == nil)then debug = false end
- local locraw = loc
- local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
- local absoluteloc = tonumber(loc,16) - math.floor(tonumber(loc,16)%_BUSWIDTH)
- local loc = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
- local byte = string.char(tonumber(byte,16))
- local byteloc = _G.ASM.ram[loc]
- if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
- byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
- _G.ASM.ram[loc] = byteloc
- refreshScreen(locraw)
- if(debug)then print(absoluteloc .. " = " .. byteloc) end
- end
- function writeByteDec(loc,byte,debug)
- if(debug == nil)then debug = false end
- local locraw = loc
- local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
- local absoluteloc = tonumber(loc,16) - math.floor(tonumber(loc,16)%_BUSWIDTH)
- local loc = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
- local byte = string.char(byte)
- local byteloc = _G.ASM.ram[loc]
- if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
- byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
- _G.ASM.ram[loc] = byteloc
- refreshScreen(locraw)
- if(debug)then print(absoluteloc .. " = " .. byteloc) end
- end
- function writeDecByte(loc,byte,debug)
- if(debug == nil)then debug = false end
- local locraw = loc
- local offs = math.floor(loc%_BUSWIDTH)+1
- local absoluteloc = loc - math.floor(loc%_BUSWIDTH)
- local loc = math.floor(loc/_BUSWIDTH)+1
- local byte = string.char(byte)
- local byteloc = _G.ASM.ram[loc]
- if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
- byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
- _G.ASM.ram[loc] = byteloc
- refreshScreen(locraw)
- if(debug)then print(absoluteloc .. " = " .. byteloc) end
- end
- function readByte(loc,debug)
- if(debug == nil)then debug = false end
- local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
- local loc = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
- local byte = tostring(_G.ASM.ram[loc]:sub(offs,offs))
- if(debug)then print(loc .. ":" .. offs .. " = " .. byte) end
- return byte
- end
- function readAddressByte(byte,itype)
- local reg = false
- if(byte == "A" or byte == "X" or byte == "Y")then
- reg = true
- end
- if(itype == nil)then itype = "" end
- local plus = 0
- if(itype == "X")then
- plus = decodeByte(readReg("X"))
- end
- if(itype == "Y")then
- plus = decodeByte(readReg("Y"))
- end
- local addr = 0
- local val = 0
- if(not reg)then addr = toHex(tonumber(byte,16) + plus) end
- if(reg)then
- val = toHex(decodeByte(readReg(reg)))
- else
- val = toHex(decodeByte(readByte(addr)))
- end
- return val
- end
- function readByteHex(loc,debug)
- return toHex(string.byte(readByte(loc,debug)))
- end
- function readByteDec(loc,debug)
- return toHex(string.byte(readByte(loc,debug)))
- end
- function readDecByte(decloc)
- return string.byte(readByte(loc,debug))
- end
- function writeChar(loc,byte,debug)
- if(debug == nil)then debug = false end
- local locraw = loc
- local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
- local absoluteloc = tonumber(loc,16) - math.floor(tonumber(loc,16)%_BUSWIDTH)
- local loc = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
- local byteloc = _G.ASM.ram[loc]
- if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
- byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
- _G.ASM.ram[loc] = byteloc
- refreshScreen(locraw)
- if(debug)then print(absoluteloc .. " = " .. byteloc) end
- end
- -- Screen memory/rendering
- function refreshScreen(mem)
- local scr_start = 512
- local scr_end = 2448
- if( _G.ASM.pmode == 2 )then
- mem = (valueCheck(mem))
- if(mem >= scr_start and mem <= scr_end)then
- drawScreenAt(toHex(mem))
- end
- end
- end
- function drawScreenAt(addr,debug)
- if( _G.ASM.pmode ~= 2)then return nil end
- if(debug == nil)then debug = false end
- local scr_start = tonumber("0200",16)
- local scr_width = 51
- local scr_end = tonumber("0990",16)
- local addr = tonumber(addr,16)
- local iscolor = false
- local ischar = false
- if(addr < scr_start or addr > scr_end)then
- return nil
- end
- -- Determine screen type at memory
- if(addr%2 == 0)then
- iscolor = true
- else
- ischar = true
- end
- -- Decode cursor position
- -- As Address is always larger then or equal to screen start
- local ypos = math.floor(((addr - scr_start)/2)/scr_width)+1
- local xpos = 0
- if(ischar)then
- xpos = math.ceil(((addr - scr_start)/2)-((ypos-1)*51))
- elseif(iscolor)then
- xpos = math.ceil((((addr+1) - scr_start)/2)-((ypos-1)*51))
- end
- if(debug)then
- print("Color: " .. tostring(iscolor))
- print("Text : " .. tostring(ischar))
- print("X: " .. xpos)
- print("Y: " .. ypos)
- end
- -- Decode colors
- local colors = "FF"
- local tcol = colors.black
- local bcol = colors.black
- if(iscolor)then
- colors = readByteHex(toHex(addr))
- elseif(ischar)then
- colors = readByteHex(toHex(addr-1))
- end
- -- Seperatew colors get MSB, LSB
- tcol = 2^tonumber(colors:sub(1,1),16)
- bcol = 2^tonumber(colors:sub(2,2),16)
- if(debug)then
- print("Text color: " .. tcol)
- print("Back color: " .. bcol)
- end
- -- Print char
- local char = " "
- if(ischar)then
- char = readByte(toHex(addr))
- elseif(iscolor)then
- char = readByte(toHex(addr+1))
- end
- local ox, oy = term.getCursorPos()
- term.setCursorPos(xpos, ypos)
- term.setTextColor(tcol)
- term.setBackgroundColor(bcol)
- write(char)
- term.setTextColor(1)
- term.setBackgroundColor(2^15)
- term.setCursorPos(ox, oy)
- end
- function drawScreen()
- if( _G.ASM.pmode ~= 2)then return nil end
- local size = 969
- local scr_start = tonumber("0200",16)
- local scr_end = tonumber("0990",16)
- for i = 0, size*2 do
- drawScreenAt(toHex(scr_start+(i+1)))
- end
- end
- -- Instruction decoding
- function runOpperation(op,type,val,debug,noexe)
- -- Get Hex code first
- local diss = ""
- if(op == nil)then return false end
- if(debug == nil)then debug = false end -- OCD precaution :P
- if(noexe == nil)then noexe = false end -- OCD precaution :P
- if(_G.ASM._HEXENCODE[op] == nil)then error("Invalid instruction: " .. op) end
- if(_G.ASM._HEXENCODE[op][type] == nil)then error("Invalid type for: " .. op .. ", " .. type) end
- -- Seperate arguments into Bytes
- local opEncode = _G.ASM._HEXENCODE[op][type]
- -- Split into bytes of 2
- local bytes = {}
- val = tostring(val)
- if(#val > 2)then
- for i=1, #val, 2 do
- bytes[#bytes+1] = val:sub(i,i+1)
- end
- else
- bytes[1] = val
- end
- -- If bytes passed is more than isntruction requires, error
- local optimalBytes = _G.ASM._OPCODES[opEncode].bytes
- if(optimalBytes > 0)then
- --if(#bytes > optimalBytes)then error("Malformed instruction: " .. op .. ", " .. val) end
- local i, j = 1, #bytes
- while i < j do
- bytes[i], bytes[j] = bytes[j], bytes[i]
- i = i + 1
- j = j - 1
- end
- for k, v in pairs(bytes) do
- -- For Accumulative instructions
- if(#v == 1)then v = "FF FF" end
- diss = diss .. v .. " "
- end
- end
- if(debug)then print("Dissassembly: " .. opEncode .. " " .. diss) end
- if(not noexe)then
- return opEncode .. " " .. diss, _G.ASM._OPCODES[opEncode]:exe(unpack(bytes))
- else
- return opEncode .. " " .. diss
- end
- end
- function procInstructionType(op,debug,err)
- -- Get instruction
- -- Syntax Tabing check
- if(err == nil)then err = true end
- if(#op:gsub("%s+","") == 0)then
- return nil
- elseif(op:sub(1,1) == " " or op:sub(1,1) == "\t")then
- op = op:gsub("%s+","")
- op = op:sub(1,3) .. " " .. op:sub(4,#op)
- end
- if(debug == nil)then debug = false end -- OCD precaution :P
- local instruction = string.upper(op:sub(1,3))
- local args = (op:sub(5,#op)):gsub("%s+","")
- local optype = "undefined"
- -- Check for implicit instructions
- if((#args:gsub('%s+','') == 0 or args == nil or args == "") and #op:gsub("%s+","") == 3)then
- optype = "IMP"
- if(debug)then print(instruction .. ":" .. optype) end
- return instruction, optype, ""
- end
- -- Check for Accumulator instructions
- if(#args == 1)then
- args = string.upper(args)
- if(args == "A" or args == "X" or args == "Y")then
- if(args == "A")then num = "01" end
- if(args == "X")then num = "02" end
- if(args == "Y")then num = "03" end
- optype = "ACC"
- if(debug)then print(instruction .. ":" .. optype .. " ->" .. args) end
- return instruction, optype, num
- else
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- end
- -- Check if Relative
- if(args:sub(1,1) == "*")then
- args = args:gsub("%s+","")
- local sign = args:sub(2,#args):sub(1,1)
- local num = signedHextoDec(args:sub(3,#args))
- if(num > 127)then error("Out of bounds Error: " .. op) end
- if(num < -127)then error("Out of bounds Error: " .. op) end
- if(num == nil)then error("Syntax Error: " .. op) end
- if(sign == "-")then
- num = toHex(tonumber("FF",16) - (tonumber(toHex(math.abs(num)-1),16)))
- else
- num = toHex(num)
- end
- optype = "REL"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
- return instruction, optype, num
- end
- -- Check if Alpha numeric
- if(args:sub(1,1) == "#" and args:sub(2,2) == "'" )then
- if(args:sub(4,4) ~= "'")then if(err)then error("Syntax Error: " .. op) else return "err" end end
- local char = args:sub(3,3)
- local num = toHex(string.byte(char))
- args = args:sub(1,1) .. "$" .. num
- end
- -- Determine type of instruction
- -- Check if not HEX, then convert
- if(args:sub(1,1) == "#" and args:sub(2,2) ~= "$")then
- local num = args:sub(2,#args)
- -- If trying to zero page x or y a decimal, error
- if(args:find(","))then
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- -- Convert num to hex
- num = toHex(tonumber(num))
- args = args:sub(1,1) .. "$" .. num
- end
- -- Check if value is an Immeditate address
- if(args:sub(1,1) == "#")then
- local num = args:sub(3,#args)
- if(#num == 2)then -- Instruction is Immeditate
- optype = "IMM"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
- return instruction, optype, num
- else
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- end
- -- Zero Page X, Absolute XY checking
- if(args:sub(1,1) == "$")then
- local num = args:sub(2,#args)
- -- Check for , because a Zero Page X can pass as an Absolute numerically wise.
- if(not num:find(","))then
- if(tonumber(num,16) == nil)then error("Syntax Error: " .. op) end
- if(#num == 2)then -- Instruction is Zero Page
- optype = "ZP"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
- return instruction, optype, num
- end
- if(#num == 4)then -- Instruction is absolute
- optype = "AB"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
- return instruction, optype, num
- end
- end
- -- Check for Zero Paged X
- if(num:find(","))then
- local nargs = {}
- -- Take spaces out of string, then split it into 2 variables
- local num = num:gsub("%s+", "")
- -- Split string by comma
- for word in string.gmatch(num, '([^,]+)') do
- table.insert(nargs, word)
- end
- num = nargs[1]
- local reg = string.upper(nargs[2])
- -- If we have more than 2 variables in the string, then the user has seriously screwed up,
- -- Be sure to annoy them with a noice syntax error.
- if(#nargs > 2)then if(err)then error("Syntax Error: " .. op) else return "err" end end
- -- Check if num is zero paged or absolute
- if(#num == 2)then
- -- Looks like we got a Zero Page, check for registered versions
- if(string.upper(reg) == "X")then
- optype = "ZPX"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
- return instruction, optype, num
- elseif(string.upper(reg) == "Y")then
- optype = "ZPY"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
- return instruction, optype, num
- end
- end
- if(#num == 4)then
- -- Looks like we got a Absolute, check for registered versions
- if(string.upper(reg) == "X")then
- optype = "ABX"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num .. ", X") end
- return instruction, optype, num
- elseif(string.upper(reg) == "Y")then
- optype = "ABY"
- if(debug)then print(instruction .. ":" .. optype .. " -> " .. num .. ", Y") end
- return instruction, optype, num
- else
- -- Invalid register
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- end
- else
- -- Wut, we got a more than 4 digit value with no registers attached to it?!?!?, wut u smoking boi!
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- end
- -- Indirect checking
- if(args:sub(1,1) == "(")then
- -- Any multi-argument statement needs to be space checked!
- local args = string.upper(args:gsub("%s+", ""))
- local num = 0
- -- Insert true hex number into indirect instruction
- if(args:sub(2,2) ~= "$")then
- num = tonumber(args:sub(3,4))
- if(num == nil)then if(err)then error("Syntax Error: " .. op) else return "err" end end
- num = toHex(num)
- args = args:sub(1,1) .. "$" .. num .. args:sub(4,#args)
- elseif(args:sub(2,2) == "#")then
- -- If user is trying to pass a value as an address, NOPE 'em!
- if(err)then error("Syntax Error: " .. op) else return "err" end
- else
- -- If hex number is passed by default set that minus its $ symbol
- num = args:sub(3,4)
- end
- if(args:sub(5,7) == "),Y")then
- -- If this is found at 5 we know, this must be a INY
- optype = "INY"
- if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. "), Y") end
- return instruction, optype, num
- end
- if(args:sub(5,7) == ",X)")then
- -- If this is found at 7 we know, this must be a INX
- optype = "INX"
- if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. ", X)") end
- return instruction, optype, num
- end
- if(args:sub(7,7) == ")")then
- if(args:sub(2,2) ~= "$")then if(err)then error("Syntax Error: " .. op) else return "err" end end
- -- If this is found at 7 we know, this must be a IN
- -- Get new number as 2Byte HEX
- num = args:sub(3,6)
- if(#num == 4)then
- optype = "IN"
- else
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. ")") end
- return instruction, optype, num
- end
- -- Zero paged indirect
- if(args:sub(5,5) == ")")then
- if(args:sub(2,2) ~= "$")then if(err)then error("Syntax Error: " .. op) else return "err" end end
- -- If this is found at 5 we know, this must be a IZP
- -- Get new number as 2Byte HEX
- num = args:sub(3,4)
- if(#num == 2)then
- optype = "IZP"
- else
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. ")") end
- return instruction, optype, num
- end
- end
- if(optype == "undefined")then
- if(err)then error("Syntax Error: " .. op) else return "err" end
- end
- end
- --- Setting everything up
- function initalize()
- -- Define sizes in Bytes
- _G.ASM = {}
- _G.ASM.MSIZE = _KBYTE*64
- _G.ASM.SSIZE = _BYTE*32
- local GRAM = {}
- local GREG = {}
- local GSTACK = {}
- -- Initialize Virtual RAM
- for _RINDEX = 1, _G.ASM.MSIZE/_BUSWIDTH do
- GRAM[_RINDEX] = string.rep(string.char("0"),_BUSWIDTH)
- end
- -- Initialize Virtual STACK
- for _SINDEX = 1, _G.ASM.SSIZE/_BUSWIDTH do
- GSTACK[_SINDEX] = string.rep(string.char("0"),_BUSWIDTH)
- end
- -- Initialize Virtual Registers
- GREG['A'] = string.char("0")
- GREG['X'] = string.char("0")
- GREG['Y'] = string.char("0")
- GREG['SP'] = string.char(tonumber("FF",16))
- GREG['PC'] = string.char(tonumber("06",16)) .. string.char(tonumber("00",16))
- _G.ASM.pmode = 1 -- Program execution mode, 1 = text, 2 = graphics
- _G.ASM.ram = GRAM
- _G.ASM.stack = GSTACK
- _G.ASM.reg = GREG
- _G.ASM.flags = string.char(tonumber("00100000",2))
- _G.ASM.flagtypes = {
- ["CRY"] = 8, -- Carry
- ["ZRO"] = 7, -- Zero Flag
- ["INT"] = 6, -- Interupt Disable
- ["DEC"] = 5, -- Decimal
- ["BRK"] = 4, -- Software interupt
- ["UNK"] = 3, -- Unknown, logical 1
- ["OVR"] = 2, -- Overflow
- ["NEG"] = 1, -- Sign
- }
- -- Instruction encoding
- _G.ASM._HEXENCODE = {
- ['LDA'] = {
- ['IZP'] = "B2",
- ['IMM'] = "A9",
- ['ZP'] = "A5",
- ['ZPX'] = "B5",
- ['AB'] = "AD",
- ['ABX'] = "BD",
- ['ABY'] = "B9",
- ['INX'] = "A1",
- ['INY'] = "B1",
- },
- ['STA'] = {
- ['IZP'] = "92",
- ['ZP'] = "85",
- ['ZPX'] = "95",
- ['AB'] = "8D",
- ['ABX'] = "9D",
- ['ABY'] = "99",
- ['INX'] = "81",
- ['INY'] = "91",
- },
- ['ADC'] = {
- ['IZP'] = "72",
- ['IMM'] = "69",
- ['ZP'] = "65",
- ['ZPX'] = "75",
- ['AB'] = "6D",
- ['ABX'] = "7D",
- ['ABY'] = "79",
- ['INX'] = "61",
- ['INY'] = "71",
- },
- ['AND'] = {
- ['IZP'] = "32",
- ['IMM'] = "29",
- ['ZP'] = "25",
- ['ZPX'] = "35",
- ['AB'] = "2D",
- ['ABX'] = "3D",
- ['ABY'] = "39",
- ['INX'] = "21",
- ['INY'] = "31",
- },
- ['ASL'] = {
- ['ACC'] = "0A",
- ['ZP'] = "06",
- ['ZPX'] = "16",
- ['AB'] = "0E",
- ['ABX'] = "1E",
- },
- ['BCC'] = {
- ['REL'] = "90",
- },
- ['BCS'] = {
- ['REL'] = "B0",
- },
- ['BEQ'] = {
- ['REL'] = "F0",
- },
- ['BIT'] = {
- ['ZP'] = "24",
- ['AB'] = "2C",
- },
- ['BMI'] = {
- ['REL'] = "30",
- },
- ['BNE'] = {
- ['REL'] = "D0",
- },
- ['BPL'] = {
- ['REL'] = "10",
- },
- ['BRK'] = {
- ['IMP'] = "00",
- },
- ['BVC'] = {
- ['REL'] = "50",
- },
- ['BVS'] = {
- ['REL'] = "70",
- },
- ['CLC'] = {
- ['IMP'] = "18",
- },
- ['CLD'] = {
- ['IMP'] = "D8",
- },
- ['CLI'] = {
- ['IMP'] = "58",
- },
- ['CLV'] = {
- ['IMP'] = "B8",
- },
- ['CMP'] = {
- ['IZP'] = "D2",
- ['IMM'] = "C9",
- ['ZP'] = "C5",
- ['ZPX'] = "D5",
- ['AB'] = "CD",
- ['ABX'] = "DD",
- ['ABY'] = "D9",
- ['INX'] = "C1",
- ['INY'] = "D1",
- },
- ['CPX'] = {
- ['IMM'] = "E0",
- ['ZP'] = "E4",
- ['AB'] = "EC",
- },
- ['CPY'] = {
- ['IMM'] = "C0",
- ['ZP'] = "C4",
- ['AB'] = "CC",
- },
- ['DEC'] = {
- ['ACC'] = "3A",
- ['ZP'] = "C6",
- ['ZPX'] = "D6",
- ['AB'] = "CE",
- ['ABX'] = "DE",
- },
- ['DEX'] = {
- ['IMP'] = "CA",
- },
- ['DEY'] = {
- ['IMP'] = "88",
- },
- ['EOR'] = {
- ['IZP'] = "52",
- ['IMM'] = "49",
- ['ZP'] = "45",
- ['ZPX'] = "55",
- ['AB'] = "4D",
- ['ABX'] = "5D",
- ['ABY'] = "59",
- ['INX'] = "41",
- ['INY'] = "51",
- },
- ['INC'] = {
- ['ACC'] = "1A",
- ['ZP'] = "E6",
- ['ZPX'] = "F6",
- ['AB'] = "EE",
- ['ABX'] = "FE",
- },
- ['INX'] = {
- ['IMP'] = "E8",
- },
- ['INY'] = {
- ['IMP'] = "C8",
- },
- ['JMP'] = {
- ['AB'] = "4C",
- ['IN'] = "6C",
- },
- ['JSR'] = {
- ['AB'] = "20",
- },
- ['LDX'] = {
- ['IMM'] = "A2",
- ['ZP'] = "A6",
- ['ZPY'] = "B6",
- ['AB'] = "AE",
- ['ABY'] = "BE",
- },
- ['LDY'] = {
- ['IMM'] = "A0",
- ['ZP'] = "A4",
- ['ZPX'] = "B4",
- ['AB'] = "AC",
- ['ABX'] = "BC",
- },
- ['LSR'] = {
- ['ACC'] = "4A",
- ['ZP'] = "46",
- ['ZPX'] = "56",
- ['AB'] = "4E",
- ['ABX'] = "5E",
- },
- ['NOP'] = {
- ['IMP'] = "EA",
- },
- ['ORA'] = {
- ['IZP'] = "12",
- ['IMM'] = "09",
- ['ZP'] = "05",
- ['ZPX'] = "15",
- ['AB'] = "0D",
- ['ABX'] = "1D",
- ['ABY'] = "19",
- ['INX'] = "01",
- ['INY'] = "11",
- },
- ['PHA'] = {
- ['IMP'] = "48",
- },
- ['PHP'] = {
- ['IMP'] = "08",
- },
- ['PLA'] = {
- ['IMP'] = "68",
- },
- ['PLP'] = {
- ['IMP'] = "28",
- },
- ['ROL'] = {
- ['ACC'] = "2A",
- ['ZP'] = "26",
- ['ZPX'] = "36",
- ['AB'] = "2E",
- ['ABX'] = "3E",
- },
- ['ROR'] = {
- ['ACC'] = "6A",
- ['ZP'] = "66",
- ['ZPX'] = "76",
- ['AB'] = "6E",
- ['ABX'] = "7E",
- },
- ['RTI'] = {
- ['IMP'] = "40",
- },
- ['RTS'] = {
- ['IMP'] = "60",
- },
- ['SBC'] = {
- ['IZP'] = "F2",
- ['IMM'] = "E9",
- ['ZP'] = "E5",
- ['ZPX'] = "F5",
- ['AB'] = "ED",
- ['ABX'] = "FD",
- ['ABY'] = "F9",
- ['INX'] = "E1",
- ['INY'] = "F1",
- },
- ['SEC'] = {
- ['IMP'] = "38",
- },
- ['SED'] = {
- ['IMP'] = "F8",
- },
- ['SEI'] = {
- ['IMP'] = "78",
- },
- ['STX'] = {
- ['ZP'] = "86",
- ['ZPY'] = "96",
- ['AB'] = "8E",
- },
- ['STY'] = {
- ['ZP'] = "84",
- ['ZPX'] = "94",
- ['AB'] = "8C",
- },
- ['TAX'] = {
- ['IMP'] = "AA",
- },
- ['TAY'] = {
- ['IMP'] = "A8",
- },
- ['TSX'] = {
- ['IMP'] = "BA",
- },
- ['TXA'] = {
- ['IMP'] = "8A",
- },
- ['TXS'] = {
- ['IMP'] = "9A",
- },
- ['TYA'] = {
- ['IMP'] = "98",
- },
- }
- _G.ASM._OPCODES = {
- -- Bytes = How many more bytes to read
- -- Assembler will convert values to hex
- -- TODO: REMINDER!!!
- -- ACCUMULATIVE INSTRUCTIONS: Use 01 = A, 02 = X, 03 = Y
- --]] LDA instructions
- ["B2"] = {bytes=1,exe=function(self,val)
- -- Zero paged Indirect
- loadRegIndirect("A",val)
- updateResultFlags(readRegDec("A"))
- end},-- LDA ($00)
- ['A9'] = {bytes=1,exe=function(self,val)
- -- Load a value into A
- writeReg("A",val)
- updateResultFlags(val)
- end}, -- LDA #00
- ['A5'] = {bytes=1,exe=function(self,mem)
- -- Load a value from memory into A
- writeReg("A",readByteHex(mem))
- updateResultFlags(readByteDec(mem))
- end}, -- LDA $00
- ['B5'] = {bytes=1,exe=function(self,val)
- local val = ( tonumber(val,16) + decodeByte(readReg("X")) )
- writeReg("A",readDecByte(val))
- updateResultFlags(val)
- end}, -- LDA $00, X
- ['AD'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readByteHex(msb .. lsb)
- writeReg('A',val)
- updateResultFlags(val)
- end}, -- LDA $0000
- ['BD'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readAddressByte(msb..lsb,"X")
- writeReg('A', val)
- updateResultFlags(val)
- end}, -- LDA $0000, X
- ['B9'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readAddressByte(msb..lsb,"Y")
- writeReg('A',val)
- updateResultFlags(val)
- end}, -- LDA $0000, Y
- ['A1'] = {bytes=1,exe=function(self,val)
- loadRegIndirect("A",val,"X")
- updateResultFlags(decodeByte(readReg("A")))
- end}, -- LDA ($00, X)
- ['B1'] = {bytes=1,exe=function(self,val)
- loadRegIndirect("A",val,"Y")
- updateResultFlags(decodeByte(readReg("A")))
- end}, -- LDA ($00), Y
- --]] STA instructions
- ['92'] = {bytes=1,exe=function(self,val)
- storeRegIndirect("A",val)
- end}, -- STA ($00)
- ['85'] = {bytes=1,exe=function(self,val) writeByteDec(val,readRegDec("A")) end}, -- STA $00
- ['95'] = {bytes=1,exe=function(self,val)
- local val = (tonumber(val,16) + decodeByte(readReg("X")))
- writeDecByte(val,readRegDec("A"))
- end}, -- STA $00, X
- ['8D'] = {bytes=2,exe=function(self,lsb,msb) writeByteDec(msb .. lsb,readRegDec("A")) end}, -- STA $0000
- ['9D'] = {bytes=2,exe=function(self,lsb,msb)
- local val = msb .. lsb
- local val = (tonumber(val,16) + decodeByte(readReg("X")))
- writeDecByte(val,readRegDec("A"))
- end}, -- STA $0000, X
- ['99'] = {bytes=2,exe=function(self,lsb,msb)
- local val = msb .. lsb
- local val = (tonumber(val,16) + decodeByte(readReg("Y")))
- writeDecByte(val,readRegDec("A"))
- end}, -- STA $0000, Y
- ['81'] = {bytes=1,exe=function(self,val)
- storeRegIndirect("A",val,"X")
- end}, -- STA ($00, X)
- ['91'] = {bytes=1,exe=function(self,val)
- storeRegIndirect("A",val,"Y")
- end}, -- STA ($00), Y
- -- ADC (Add with carry) Adds to A
- ['72'] = {bytes=1,exe=function(self,val)
- local num = signedAdd(readRegHex("A"),readByteHex(readIndirectByte(val)))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end}, -- ADC ($00)
- ['69'] = {bytes=1,exe=function(self,val)
- local num = signedAdd(readRegHex("A"), val)
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC #00
- ['65'] = {bytes=1,exe=function(self,val)
- local num = signedAdd(readRegHex("A"), readByteHex(val) )
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC $00
- ['75'] = {bytes=1,exe=function(self,val)
- local num = signedAdd(readRegHex("A"),readAddressByte(val,"X"))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC $00, X
- ['6D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = signedAdd(readRegHex("A"), readByteHex(msb..lsb))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC $0000
- ['7D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = signedAdd(readRegHex("A"),readAddressByte(msb..lsb,"X"))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC $0000, X
- ['79'] = {bytes=2,exe=function(self,lsb,msb)
- local num = signedAdd(readRegHex("A"),readAddressByte(msb..lsb,"Y"))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC $0000, Y
- ['61'] = {bytes=1,exe=function(self,val)
- local num = signedAdd(readRegHex("A"),readByteHex(readIndirectByte(val,"X")))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC ($00, X)
- ['71'] = {bytes=1,exe=function(self,val)
- local num = signedAdd(readRegHex("A"),readByteHex(readIndirectByte(val,"Y")))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- ADC ($00), Y
- -- AND (Logical And)
- ['32'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), tonumber( readByteHex(readIndirectByte(val)), 16) )
- updateResultFlags(num)
- writeRegDec("A",num)
- end}, -- AND ($00)
- ['29'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), tonumber(val,16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND #00
- ['25'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), decodeByte(readByte(val)))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND $00
- ['35'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), tonumber(readAddressByte(val,"X"),16) )
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND $00, X
- ['2D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.band(decodeByte(readReg("A")), decodeByte(readByte(msb..lsb)))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND $0000
- ['3D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.band(decodeByte(readReg("A")), tonumber(readAddressByte(msb..lsb,"X"),16) )
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND $0000, X
- ['39'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.band(decodeByte(readReg("A")), tonumber(readAddressByte(msb..lsb,"Y"),16) )
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND $0000, Y
- ['21'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), tonumber( readByteHex(readIndirectByte(val,"X")), 16) )
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND ($00, X)
- ['31'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), tonumber( readByteHex(readIndirectByte(val,"Y"))),16)
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- AND ($00), Y
- -- ASL (Arithmetic Shift Left)
- ['0A'] = {bytes=1,exe=function(self,val)
- if(val == "01")then val = "A" end
- if(val == "02")then val = "X" end
- if(val == "03")then val = "Y" end
- local num = bit.blshift(decodeByte(readReg(val)), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags(num)
- if(num > 255)then num = 255 setFlag("NEG",0) end
- writeRegDec(val,num)
- end},-- ASL A/X/Y
- ['06'] = {bytes=1,exe=function(self,val)
- local num = bit.blshift(decodeByte(readByte(val)), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = 255 setFlag("NEG",0) end
- writeByteDec(val,num)
- end},-- ASL $00
- ['16'] = {bytes=1,exe=function(self,val)
- local num = bit.blshift(tonumber(readAddressByte(val,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = 255 setFlag("NEG",0) end
- writeByteDec(addHex(val,readRegHex("X")),num)
- end},-- ADC $00, X
- ['0E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.blshift(decodeByte(readByte(msb..lsb)), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = 255 setFlag("NEG",0) end
- writeByteDec(msb..lsb,num)
- end},-- ADC $0000
- ['1E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.blshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = 255 setFlag("NEG",0) end
- writeByteDec(addHex(msb..lsb,readRegHex("Y")),num)
- end},-- ADC $0000, X
- -- BCC (Branch if Carry Clear)
- ['90'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("CRY") == "0")then movePC(num) end
- end},-- BCC *+val
- -- BCS (Branch if Carry Set)
- ['B0'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("CRY") == "1")then movePC(num) end
- end},-- BCS *+val
- -- BEQ (Branch if Equal)
- ['F0'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("ZRO") == "1")then movePC(num) end
- end},-- BCS *+val
- -- BIT (Bit Test)
- ['24'] = {bytes=1,exe=function(self,val)
- local num = bit.band(decodeByte(readReg("A")), decodeByte(readByte(val)))
- if(toBin(num):sub(2,2))then setFlag("OVR",1) end
- updateResultFlags(num)
- end},-- BIT $00
- ['2C'] = {bytes=2,exe=function(self,val)
- end},-- BIT $0000
- -- BMI (Branch if Minus)
- ['30'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("NEG") == "1")then movePC(num) end
- end},-- BMI *+val
- -- BNE (Branch if Not Equal)
- ['D0'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("ZRO") == "0")then movePC(num) end
- end},-- BNE *+val
- -- BPL (Branch if Positive)
- ['10'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("NEG") == "0")then movePC(num) end
- end},-- BPL *+val
- -- BRK (Force Interrupt)
- ['00'] = {bytes=0,exe=function(self)
- pushStack(toHex(decodeByte(getFlagsByte())))
- local pc = "0" .. tostring(tonumber(readPC(),16)+1)
- pushStack(tostring(readPC()):sub(1,2))
- pushStack(tostring(readPC()):sub(3,4))
- -- Push status to stack, stop program wait for re-run program executor will check for interupt flag and pull from stacks and resume program
- setFlag("BRK",1)
- end},-- BRK
- -- BVC (Branch if Overflow Clear)
- ['50'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("OVR") == "0")then movePC(num) end
- end},-- BVC *+val
- -- BVS (Branch if Overflow Set)
- ['70'] = {bytes=1,exe=function(self,val)
- local num = signedHextoDec(val)
- if(getFlag("OVR") == "1")then movePC(num) end
- end},-- BVC *+val
- -- CLC (Clear Carry Flag)
- ['18'] = {bytes=0,exe=function(self,val)
- setFlag("CRY",0)
- end},-- CLC
- -- CLD (Clear Decimal Mode)
- ['D8'] = {bytes=0,exe=function(self,val)
- setFlag("DEC",0)
- end},-- CLD
- -- CLI (Clear Interrupt Disable)
- ['58'] = {bytes=0,exe=function(self,val)
- setFlag("INT",0)
- end},-- CLI
- -- CLV (Clear Overflow Flag)
- ['B8'] = {bytes=0,exe=function(self,val)
- setFlag("OVR",0)
- end},-- CLV
- -- CMP (Compare)
- ['D2'] = {bytes=1,exe=function(self,val)
- local num = tonumber(readByteHex(readIndirectByte(val)),16) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end}, -- CMP ($00)
- ['C9'] = {bytes=1,exe=function(self,val)
- local num = decodeByte(readReg("A")) - tonumber(val,16)
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP #00
- ['C5'] = {bytes=1,exe=function(self,val)
- local num = decodeByte(readByte(val)) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP $00
- ['D5'] = {bytes=1,exe=function(self,val)
- local num = tonumber(readAddressByte(val,"X"),16) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP $00, X
- ['CD'] = {bytes=2,exe=function(self,lsb,msb)
- local num = decodeByte(readByte(msb..lsb)) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP $0000
- ['DD'] = {bytes=2,exe=function(self,lsb,msb)
- local num = tonumber(readAddressByte(msb..lsb,"X"),16) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP $0000, X
- ['D9'] = {bytes=2,exe=function(self,lsb,msb)
- local num = tonumber(readAddressByte(msb..lsb,"Y"),16) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP $0000, Y
- ['C1'] = {bytes=1,exe=function(self,val)
- local num = tonumber(readByteHex(readIndirectByte(val,"X")),16) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP ($00, X)
- ['D1'] = {bytes=1,exe=function(self,val)
- local num = tonumber(readByteHex(readIndirectByte(val,"Y")),16) - decodeByte(readReg("A"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CMP ($00), Y
- -- CPX (Compare X Register)
- ['E0'] = {bytes=1,exe=function(self,val)
- local num = tonumber(val,16) - decodeByte(readReg("X"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CPX #00
- ['E4'] = {bytes=1,exe=function(self,val)
- local num = decodeByte(readByte(val)) - decodeByte(readReg("X"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CPX $00
- ['EC'] = {bytes=2,exe=function(self,lsb,msb)
- local num = decodeByte(readByte(msb..lsb)) - decodeByte(readReg("X"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CPX $0000
- -- CPY (Compare Y Register)
- ['C0'] = {bytes=1,exe=function(self,val)
- local num = tonumber(val,16) - decodeByte(readReg("Y"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CPY #00
- ['C4'] = {bytes=1,exe=function(self,val)
- local num = decodeByte(readByte(val)) - decodeByte(readReg("Y"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CPY $00
- ['CC'] = {bytes=2,exe=function(self,lsb,msb)
- local num = decodeByte(readByte(msb..lsb)) - decodeByte(readReg("Y"))
- if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
- updateResultFlags(num)
- end},-- CPY $0000
- -- DEC (Decrement Memory)
- ['3A'] = {bytes=1,exe=function(self,val)
- if(val == "01")then val = "A" end
- if(val == "02")then val = "X" end
- if(val == "03")then val = "Y" end
- local num = subHex(readRegHex(val),"01")
- writeReg(val,num)
- end}, -- INC A/X/Y
- ['C6'] = {bytes=1,exe=function(self,val)
- local num = subSignedDec(readByteHex(val),"01")
- writeByteDec(val,num)
- end},-- DEC $00
- ['D6'] = {bytes=1,exe=function(self,val)
- local num = subSignedDec(readAddressByte(val,"X"),"01")
- writeByteDec(addHex(val,readRegHex("X")),num)
- end},-- DEC $00, X
- ['CE'] = {bytes=2,exe=function(self,lsb,msb)
- local num = subSignedDec(readByteHex(msb..lsb),"01")
- writeByteDec(msb..lsb,num)
- end},-- DEC $0000
- ['DE'] = {bytes=2,exe=function(self,lsb,msb)
- local num = subSignedDec(readAddressByte(msb..lsb,"X"),"01")
- writeByteDec(addHex(msb..lsb,readRegHex("X")),num)
- end},-- DEC $0000, X
- -- DEX (Decrement X Register)
- ['CA'] = {bytes=0,exe=function(self,val)
- local num = subSignedDec(readRegHex('X'),"01")
- updateResultFlags(num)
- writeRegDec("X",num)
- end},-- DEX
- -- DEY (Decrement Y Register)
- ['88'] = {bytes=0,exe=function(self,val)
- local num = subSignedDec(readRegHex('Y'),"01")
- updateResultFlags(num)
- writeRegDec("Y",num)
- end},-- DEY
- -- EOR (Exclusive OR)
- ['52'] = {bytes=1,exe=function(self,val)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val)),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end}, -- EOR ($00)
- ['49'] = {bytes=1,exe=function(self,val)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(val,16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR #00
- ['45'] = {bytes=1,exe=function(self,val)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(val),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR $00
- ['55'] = {bytes=1,exe=function(self,val)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(val,"X"),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR $00, X
- ['4D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(msb..lsb),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR $0000
- ['5D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"X"),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR $0000, X
- ['59'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"Y"),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR $0000, Y
- ['41'] = {bytes=1,exe=function(self,val)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"X")),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR ($00, X)
- ['51'] = {bytes=1,exe=function(self,val)
- local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"Y")),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end},-- EOR ($00), Y
- -- INC (Increment Memory)
- ['1A'] = {bytes=1,exe=function(self,val)
- if(val == "01")then val = "A" end
- if(val == "02")then val = "X" end
- if(val == "03")then val = "Y" end
- local num = addHex(readRegHex(val),"01")
- writeReg(val,num)
- end}, -- INC A/X/Y
- ['E6'] = {bytes=1,exe=function(self,val)
- local num = addSignedDec(readByteHex(val),"01")
- writeByteDec(val,num)
- end},-- INC $00
- ['F6'] = {bytes=1,exe=function(self,val)
- local num = addSignedDec(readAddressByte(val,"X"),"01")
- writeByteDec(addHex(val,readRegHex("X")),num)
- end},-- INC $00, X
- ['EE'] = {bytes=2,exe=function(self,lsb,msb)
- local num = addSignedDec(readByteHex(msb..lsb),"01")
- writeByteDec(msb..lsb,num)
- end},-- INC $0000
- ['FE'] = {bytes=2,exe=function(self,val)
- local num = addSignedDec(readAddressByte(msb..lsb,"X"),"01")
- writeByteDec(addHex(msb..lsb,readRegHex("X")),num)
- end},-- INC $0000, X
- -- INX (Increment X Register)
- ['E8'] = {bytes=0,exe=function(self,val)
- local num = addSignedDec(readRegHex('X'),"01")
- updateResultFlags(num)
- writeRegDec("X",num)
- end},-- INX
- -- INY (Increment Y Register)
- ['C8'] = {bytes=0,exe=function(self,val)
- local num = addSignedDec(readRegHex('Y'),"01")
- updateResultFlags(num)
- writeRegDec("Y",num)
- end},-- INY
- -- JMP (Jump)
- ['4C'] = {bytes=2,exe=function(self,lsb,msb)
- setPC(msb..lsb)
- end},-- JMP $0000
- ['6C'] = {bytes=2,exe=function(self,lsb,msb)
- setPC(readIndirectByte(msb..lsb))
- end},-- JMP ($0000)
- -- JSR
- ['20'] = {bytes=2,exe=function(self,lsb,msb)
- pushStack(readPC():sub(1,2))
- pushStack(readPC():sub(3,4))
- setPC(msb..lsb)
- end},-- JSR $0000
- -- LDX (Load X Register)
- ['A2'] = {bytes=1,exe=function(self,val)
- writeReg("X",val)
- updateResultFlags(val)
- end},-- LDX #00
- ['A6'] = {bytes=1,exe=function(self,val)
- writeReg("X",readByteHex(val))
- updateResultFlags(readByteDec(val))
- end},-- LDX $00
- ['B6'] = {bytes=1,exe=function(self,val)
- local val = ( tonumber(val,16) + decodeByte(readReg("Y")) )
- writeRegDec("X",val)
- updateResultFlags(val)
- end},-- LDX $00, Y
- ['AE'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readByteHex(msb .. lsb)
- writeRegDec('X',val)
- updateResultFlags(val)
- end},-- LDX $0000
- ['BE'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readAddressByte(msb..lsb,"Y")
- writeReg('X', val)
- updateResultFlags(val)
- end},-- LDX $0000, Y
- -- LDY (Load Y Register)
- ['A0'] = {bytes=1,exe=function(self,val)
- writeReg("Y",val)
- updateResultFlags(val)
- end},-- LDY #00
- ['A4'] = {bytes=1,exe=function(self,val)
- writeReg("Y",readByteHex(val))
- updateResultFlags(readByteDec(val))
- end},-- LDY $00
- ['B4'] = {bytes=1,exe=function(self,val)
- local val = ( tonumber(val,16) + decodeByte(readReg("X")) )
- writeRegDec("Y",val)
- updateResultFlags(val)
- end},-- LDY $00, X
- ['AC'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readByteHex(msb .. lsb)
- writeReg('Y',val)
- updateResultFlags(val)
- end},-- LDY $0000
- ['BC'] = {bytes=2,exe=function(self,lsb,msb)
- local val = readAddressByte(msb..lsb,"X")
- writeReg('Y', val)
- updateResultFlags(val)
- end},-- LDY $0000, X
- -- LSR (Logical Shift Right)
- ['4A'] = {bytes=1,exe=function(self,val)
- if(val == "01")then val = "A" end
- if(val == "02")then val = "X" end
- if(val == "03")then val = "Y" end
- local num = bit.brshift(decodeByte(readReg(val)), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags(num)
- writeRegDec(val,num)
- end},-- LSR A/X/Y
- ['46'] = {bytes=1,exe=function(self,val)
- local num = bit.brshift(decodeByte(readByte(val)), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags(num)
- writeByteDec(val,num)
- end},-- LSR $00
- ['56'] = {bytes=1,exe=function(self,val)
- local num = bit.brshift(tonumber(readAddressByte(val,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags(num)
- writeByteDec(val,num)
- end},-- LSR $00, X
- ['4E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.brshift(decodeByte(readByte(msb..lsb)), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags(num)
- writeByteDec(msb..lsb,num)
- end},-- LSR $0000
- ['5E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.brshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(num):sub(8,8)))
- updateResultFlags(num)
- writeByteDec(msb..lsb,num)
- end},-- LSR $0000, X
- -- NOP (No Operation)
- ['EA'] = {bytes=0,exe=function(self,val)
- sleep(0) -- CC is alot faster than ur average 6502
- end},-- NOP
- -- ORA (Logical Inclusive OR)
- ['12'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val)),16))
- updateResultFlags(num)
- writeRegDec("A",num)
- end}, -- ORA ($00)
- ['09'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(val,16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA #00
- ['05'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(val),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA $00
- ['15'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(val,"X"),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA $00, X
- ['0D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(msb..lsb),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA $0000
- ['1D'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"X"),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA $0000, X
- ['19'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"Y"),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA $0000, Y
- ['01'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"X")),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA ($00, X)
- ['11'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"Y")),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end},-- ORA ($00), Y
- -- PHA (Push Accumulator)
- ['48'] = {bytes=0,exe=function(self,val)
- pushStack(readRegHex("A"))
- end},-- PHA
- -- PHP (Push Processor Status)
- ['08'] = {bytes=0,exe=function(self,val)
- pushStack(toHex(decodeByte(getFlagsByte())))
- end},-- PHP
- -- PLA (Pull Accumulator)
- ['68'] = {bytes=0,exe=function(self,val)
- writeRegDec("A", decodeByte(pullStack()))
- updateResultFlags(readRegDec("A"))
- end},-- PLA
- -- PLP (Pull Processor Status)
- ['28'] = {bytes=0,exe=function(self,val)
- setAllFlags(pullStack())
- end},-- PLP
- -- ROL (Rotate Left)
- ['2A'] = {bytes=1,exe=function(self,val)
- if(val == "01")then val = "A" end
- if(val == "02")then val = "X" end
- if(val == "03")then val = "Y" end
- setFlag("CRY",tonumber(toBin(decodeByte(readReg(val))):sub(8,8)))
- local num = bit.blshift(decodeByte(readReg(val)), 1)
- updateResultFlags(num)
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeRegDec(val,num)
- end},-- ROL A/X/Y
- ['26'] = {bytes=1,exe=function(self,val)
- local num = bit.blshift(decodeByte(readByte(val)), 1)
- setFlag("CRY",tonumber(toBin(decodeByte(readByte(val))):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(val,(num))
- end},-- ROL $00
- ['36'] = {bytes=1,exe=function(self,val)
- local num = bit.blshift(tonumber(readAddressByte(val,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(val,"X"),16)):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(readAddressByte(val,"X"),(num))
- end},-- ROL $00, X
- ['2E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.blshift(decodeByte(readByte(msb..lsb)), 1)
- setFlag("CRY",tonumber(toBin(decodeByte(readByte(msb..lsb))):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(msb..lsb,(num))
- end},-- ROL $0000
- ['3E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.blshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(msb..lsb,"X"),16)):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(readAddressByte(msb..lsb,"X"),(num))
- end},-- ROL $0000, X
- -- ROR (Rotate Right)
- ['6A'] = {bytes=1,exe=function(self,val)
- if(val == "01")then val = "A" end
- if(val == "02")then val = "X" end
- if(val == "03")then val = "Y" end
- setFlag("CRY",tonumber(toBin(decodeByte(readReg(val))):sub(8,8)))
- local num = bit.brshift(decodeByte(readReg(val)), 1)
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeRegDec(val,(num))
- end},-- ROR A/X/Y
- ['66'] = {bytes=1,exe=function(self,val)
- local num = bit.brshift(decodeByte(readByte(val)), 1)
- setFlag("CRY",tonumber(toBin(decodeByte(readByte(val))):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(val,(num))
- end},-- ROR $00
- ['76'] = {bytes=1,exe=function(self,val)
- local num = bit.brshift(tonumber(readAddressByte(val,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(val,"X"),16)):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(readAddressByte(val,"X"),(num))
- end},-- ROR $00, X
- ['6E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.brshift(decodeByte(readByte(msb..lsb)), 1)
- setFlag("CRY",tonumber(toBin(decodeByte(readByte(msb..lsb))):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(msb..lsb,(num))
- end},-- ROR $0000
- ['7E'] = {bytes=2,exe=function(self,lsb,msb)
- local num = bit.brshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
- setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(msb..lsb,"X"),16)):sub(8,8)))
- updateResultFlags((num))
- if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
- writeByteDec(readAddressByte(msb..lsb,"X"),(num))
- end},-- ROR $0000, X
- -- RTI (Return from Interrupt)
- ['40'] = {bytes=0,exe=function(self,val)
- local lsb = toHex(decodeByte(pullStack()))
- local msb = toHex(decodeByte(pullStack()))
- local status = pullStack()
- setAllFlags(status)
- setPC(msb..lsb)
- end},-- RTI
- -- RTS (Return from Subroutine)
- ['60'] = {bytes=0,exe=function(self,val)
- local lsb = toHex(decodeByte(pullStack()))
- local msb = toHex(decodeByte(pullStack()))
- setPC(msb..lsb)
- end},-- RTS
- -- SBC (Subtract with Carry)
- ['F2'] = {bytes=1,exe=function(self,val)
- local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val)),16))
- updateResultFlags((num))
- writeRegDec("A",(num))
- end}, -- SBC ($00)
- ['E9'] = {bytes=1,exe=function(self,val)
- local num = signedSub(readRegHex("A"), val)
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC #00
- ['E5'] = {bytes=1,exe=function(self,val)
- local num = signedSub(readRegHex("A"), readByteHex(val) )
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC $00
- ['F5'] = {bytes=1,exe=function(self,val)
- local num = signedSub(readRegHex("A"),readAddressByte(val,"X"))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC $00, X
- ['ED'] = {bytes=2,exe=function(self,lsb,msb)
- local num = signedSub(readRegHex("A"), readByteHex(msb..lsb))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC $0000
- ['FD'] = {bytes=2,exe=function(self,lsb,msb)
- local num = signedSub(readRegHex("A"),readAddressByte(msb..lsb,"X"))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC $0000, X
- ['F9'] = {bytes=2,exe=function(self,lsb,msb)
- local num = signedSub(readRegHex("A"),readAddressByte(msb..lsb,"Y"))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC $0000, Y
- ['E1'] = {bytes=2,exe=function(self,val)
- local num = signedSub(readRegHex("A"),readByteHex(readIndirectByte(val,"X")))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC ($00, X)
- ['F1'] = {bytes=2,exe=function(self,val)
- local num = signedSub(readRegHex("A"),readByteHex(readIndirectByte(val,"Y")))
- writeReg("A",num)
- updateResultFlags(decodeByte(readReg("A")))
- end},-- SBC ($00), Y
- -- SEC (Set Carry Flag)
- ['38'] = {bytes=0,exe=function(self,val)
- setFlag("CRY",1)
- end},-- SEC
- -- SED (Set Decimal Flag)
- ['F8'] = {bytes=0,exe=function(self,val)
- setFlag("DEC",1)
- end},-- SED
- -- SEI (Set Interrupt Disable)
- ['78'] = {bytes=0,exe=function(self,val)
- setFlag("INT",1)
- end},-- SEI
- -- STX (Store X Register)
- ['86'] = {bytes=1,exe=function(self,val)
- writeByte(val,readRegHex("X"))
- end},-- STX $00
- ['96'] = {bytes=1,exe=function(self,val)
- local val = toHex(tonumber(val,16) + decodeByte(readReg("Y")))
- writeByteDec(addHex(val,readRegHex("Y")),decodeByte(readReg("X")))
- end},-- STX $00, Y
- ['8E'] = {bytes=2,exe=function(self,lsb,msb)
- writeByte(msb .. lsb,readRegHex("X"))
- end},-- STX $0000
- -- STY (Store Y Register)
- ['84'] = {bytes=1,exe=function(self,val)
- writeByte(val,readRegHex("Y"))
- end},-- STY $00
- ['94'] = {bytes=1,exe=function(self,val)
- local val = toHex(tonumber(val,16) + decodeByte(readReg("X")))
- writeByteDec(addHex(val,readRegHex("X"),decodeByte(readReg("Y"))))
- end},-- STY $00, X
- ['8C'] = {bytes=2,exe=function(self,lsb,msb)
- writeByte(msb .. lsb,readRegHex("Y"))
- end},-- STY $0000
- -- TAX (Transfer Accumulator to X)
- ['AA'] = {bytes=0,exe=function(self,val)
- moveRegs("A","X",true)
- end},-- TAX
- -- TAY (Transfer Accumulator to Y)
- ['A8'] = {bytes=0,exe=function(self,val)
- moveRegs("A","Y",true)
- end},-- TAX
- -- TSX (Transfer Stack Pointer to X)
- ['BA'] = {bytes=1,exe=function(self,val)
- moveRegs("SP`","X",true)
- end},-- TSX
- -- TXA (Transfer X to Accumulator)
- ['8A'] = {bytes=0,exe=function(self,val)
- moveRegs("X","A",true)
- end},-- TXA
- -- TXS (Transfer X to Stack Pointer)
- ['9A'] = {bytes=0,exe=function(self,val)
- moveRegs("X","SP",true)
- end},-- TXS
- -- TYA (Transfer Y to Accumulator)
- ['98'] = {bytes=0,exe=function(self,val)
- moveRegs("Y","A",true)
- end},-- TYA
- }
- end
- function getInstuctionBytes(op,type)
- if(_G.ASM._HEXENCODE[op])then
- if(_G.ASM._OPCODES[_G.ASM._HEXENCODE[op][type]] == nil)then
- print(type)
- end
- return _G.ASM._OPCODES[_G.ASM._HEXENCODE[op][type]].bytes+1
- else
- return "err"
- end
- end
- function str_shearWord(str,word)
- local str = str:gsub("%s+","")
- return str:sub(#word+1,#str)
- end
- function AssembleHEX(code,ln)
- local op, otype, num = procInstructionType(code,false,false)
- if(op == "err")then error("Syntax error line " .. ln .. ": " .. code:gsub("%s+","")) end
- local hex = runOpperation(op,otype,num,false,true)
- return hex
- end
- function DecodeOpCodeHex(hex,args)
- for k, v in pairs(_G.ASM._HEXENCODE) do
- for kk, vv in pairs(v) do
- if(vv == hex)then
- local format = k .. " "
- if(kk == "IMP")then
- elseif(kk == "IMM")then
- format = format .. "#$" .. args[1]
- elseif(kk == "AB")then
- format = format .. "$" .. args[2] .. args[1]
- elseif(kk == "ABX")then
- format = format .. "$" .. args[2] .. args[1] .. ", X"
- elseif(kk == "ABY")then
- format = format .. "$" .. args[2] .. args[1] .. ", Y"
- elseif(kk == "IN")then
- format = format .. "($" .. args[1] .. ")"
- elseif(kk == "INX")then
- format = format .. "($" .. args[1] .. ", X)"
- elseif(kk == "INY")then
- format = format .. "($" .. args[1] .. "), Y"
- elseif(kk == "ACC")then
- format = format .. "$" .. args[1]
- elseif(kk == "REL")then
- format = format .. "$" .. args[1]
- elseif(kk == "ZP")then
- format = format .. "$" .. args[1]
- end
- return format
- end
- end
- end
- end
- function disassembleASM(input)
- local code = ""
- local hex = {}
- local f = fs.open(input,"rb")
- local progstart = ""
- local counter = 1
- local index = 1
- for byte in f.read do -- Iterate over every byte in the file.
- if(index > 2)then
- hex[#hex+1] = toHex(byte)
- else
- progstart = progstart .. toHex(byte)
- end
- index = index + 1
- end
- f.close()
- print("Read " .. index .. " Bytes.")
- local codeindex = 1
- while codeindex < #hex do
- local args = {}
- local dump = hex[codeindex]
- local opBytes = 0
- local opperation = "???"
- if(_G.ASM._OPCODES[hex[codeindex]] ~= nil)then
- opBytes = _G.ASM._OPCODES[hex[codeindex]].bytes
- if(opBytes >= 1)then
- for byteIndex = 1, opBytes do
- args[#args+1] = hex[codeindex+byteIndex]
- dump = dump .. " " .. hex[codeindex+byteIndex]
- end
- end
- opperation = DecodeOpCodeHex(hex[codeindex],args)
- end
- -- Example:
- -- Address Hexdump Disassembly
- -- -------------------------------
- -- $600 A9 02 03 LDA $0302
- -- $601 A9 02 LDA $02
- -- ..............................
- local addr = toHex(tonumber(progstart,16) + codeindex-1)
- code = code .. "\n" .. "$" .. string.rep("0",4-#addr) .. addr .. " " .. dump .. string.rep(" ",(8-#dump)+4) .. opperation
- codeindex = codeindex + 1
- codeindex = codeindex + opBytes
- end
- return code
- end
- function runCompiledASM(input,mode,debug)
- local step = true
- if(mode == "-s")then step = true else step = false end
- if(debug == nil)then debug = true end
- if(not fs.exists(input))then error("File doesnt exist: " .. input) end
- -- Convert Bytes to hex
- local dump = ""
- local hex = {}
- local f = fs.open(input,"rb")
- local progstart = ""
- local index = 1
- for byte in f.read do -- Iterate over every byte in the file.
- if(index > 2)then
- hex[#hex+1] = toHex(byte)
- dump = dump .. " " .. toHex(byte)
- else
- progstart = progstart .. toHex(byte)
- end
- index = index + 1
- end
- f.close()
- print("Read " .. index .. " Bytes.")
- -- Load Hex into program memory
- -- Make sure interupt hasnt been called, if it has dont reset the program counter.
- if(tonumber(getFlag("BRK")) == 0)then
- setPC(progstart)
- else
- print("Break detected, resuming program.")
- print("press any key. ")
- setFlag("BRK",0)
- os.pullEvent("key")
- end
- -- Insert HEX into Program memory
- for i = 1, #hex do
- writeByte(toHex( tonumber(progstart,16)+(i-1) ),hex[i])
- end
- -- With program loaded, start running through it base on the program counter index
- local line = 1
- local IPSTimer = os.startTimer(1)
- local inCounter = 0
- local hexstart = tonumber(progstart,16)
- -- Run program till its hex limit is reached.
- term.clear()
- term.setCursorPos(1, 1)
- while tonumber(readPC(),16) <= hexstart+(#hex-1) do
- if(tonumber(getFlag("BRK")) == 1)then
- term.setTextColor(colors.white)
- print("\nProgram brk at PC=$" .. readPC())
- break
- end
- -- Get key inputs / generate random numbers
- os.queueEvent("ASMWait")
- local ev = {os.pullEvent()}
- if(ev[1] == "key")then writeByte("FF",toHex(tonumber(ev[2]))) end
- writeByte("FE",toHex(math.random(0,255)))
- if(ev[1] == "timer" and _G.ASM.pmode ~= 2)then
- term.setCursorPos(1, 1)
- print("IPS: " .. inCounter)
- inCounter = 0
- IPSTimer = os.startTimer(1)
- elseif(_G.ASM.pmode ~= 2 and line == 1)then
- term.clear()
- term.setCursorPos(1, 1)
- print("IPS: " .. inCounter)
- inCounter = 0
- end
- local args = {}
- local opperation = readByteHex(readPC())
- if(_G.ASM._OPCODES[opperation] == nil)then print(opperation .. " nil?") end
- local opBytes = _G.ASM._OPCODES[opperation].bytes
- for byteIndex = 1, opBytes do
- args[#args+1] = readByteHex(toHex((tonumber(readPC(),16)+byteIndex)))
- end
- -- Run command
- if(debug and _G.ASM.pmode ~= 2)then
- term.current().setVisible(false)
- term.setCursorPos(1, 2)
- print("A: " .. readRegHex("A") .. " X: ".. readRegHex("X") .. " Y: " .. readRegHex("Y") .. " SP: " .. readRegHex("SP") .. " PC: " .. readPC())
- print("NZ-BDIZC")
- print(toBin(decodeByte(getFlagsByte())))
- for i = 1, #hex do
- local found = false
- local ind = tonumber(readPC(),16) - tonumber(progstart,16)
- if( (i-1) == ind)then
- term.setTextColor(colors.orange)
- write(hex[i] .. " ")
- else
- if(opBytes > 0)then
- for x = 1, opBytes do
- if((i-1)-x == ind)then
- term.setTextColor(colors.green)
- write(hex[i] .. " ")
- found = true
- end
- end
- end
- if not found then
- term.setTextColor(colors.white)
- write(hex[i] .. " ")
- end
- end
- end
- end
- term.current().setVisible(true)
- movePC(1)
- movePC(opBytes)
- _G.ASM._OPCODES[opperation]:exe(unpack(args))
- inCounter = inCounter + 1
- line = line + 1
- if(step)then
- if(_G.ASM.pmode ~= 2)then term.setCursorPos(1, 1) end
- term.setTextColor(colors.white)
- print("\nPress any key. ")
- os.pullEvent("key")
- end
- end
- if(tonumber(getFlag("BRK")) == 0)then
- term.setTextColor(colors.white)
- print("\nProgram end at PC=$" .. readPC())
- end
- end
- function runPreCompiledASM(input,mode,debug)
- --error("Broken feature, use -rnr instead.")
- local step = true
- if(mode == "-s")then step = true else step = false end
- if(debug == nil)then debug = true end
- if(not fs.exists(input))then error("File doesnt exist: " .. input) end
- -- Convert Bytes to hex
- local dump = ""
- local hex = {}
- local f = fs.open(input,"rb")
- local progstart = ""
- local index = 1
- for byte in f.read do -- Iterate over every byte in the file.
- if(index > 2)then
- hex[#hex+1] = toHex(byte)
- dump = dump .. " " .. toHex(byte)
- else
- progstart = progstart .. toHex(byte)
- end
- index = index + 1
- end
- f.close()
- print("Read " .. index .. " Bytes.")
- -- Load Hex into program memory
- -- Make sure interupt hasnt been called, if it has dont reset the program counter.
- if(tonumber(getFlag("BRK")) == 0)then
- setPC(progstart)
- else
- print("Break detected, resuming program.")
- print("press any key. ")
- setFlag("BRK",0)
- os.pullEvent("key")
- end
- -- Insert HEX into Program memory
- for i = 1, #hex do
- writeByte(toHex( tonumber(progstart,16)+(i-1) ),hex[i])
- end
- -- With program loaded, start running through it base on the program counter index
- local line = 1
- local index = 1
- local inCounter = 0
- local hexstart = tonumber(progstart,16)
- program = {ops={},args={}}
- print("Compiling code from memory...")
- -- Run program till its hex limit is reached.
- term.clear()
- term.setCursorPos(1, 1)
- while tonumber(readPC(),16) <= hexstart+(#hex-1) do
- if(tonumber(getFlag("BRK")) == 1)then
- term.setTextColor(colors.white)
- print("\nProgram brk at PC=$" .. readPC())
- break
- end
- -- Get key inputs / generate random numbers
- local args = {}
- local opperation = readByteHex(readPC())
- if(_G.ASM._OPCODES[opperation] ~= nil)then
- local opBytes = _G.ASM._OPCODES[opperation].bytes
- for byteIndex = 1, opBytes do
- args[#args+1] = readByteHex(toHex((tonumber(readPC(),16)+byteIndex)))
- end
- program.ops[readPC()] = opperation
- movePC(1)
- movePC(opBytes)
- program.args[readPC()] = args
- --print(i .. "=" .. #hex-1)
- --print(DecodeOpCodeHex(opperation,{unpack(args)}))
- --print(opperation .. ": " .. opBytes)
- --print(textutils.serialize(args))
- --print(program.args[line])
- --print(program.funcs[line])
- --print(program.instances[line])
- --print(opBytes .. " : " .. #hex-1)
- --os.pullEvent("key")
- else
- program.ops[readPC()] = "EA"
- movePC(1)
- movePC(1)
- program.args[readPC()] = {}
- end
- line = line + 1
- end
- if(_G.ASM.pmode ~= 2)then -- If text mode.
- print("Successfully compiled: " .. line .. " Bytes.")
- print("Press any key.")
- os.pullEvent("key")
- end
- -- Run program
- setPC(progstart)
- local IPSTimer = os.startTimer(1)
- line = 1
- while tonumber(readPC(),16) <= hexstart+(#hex-1) do
- if(tonumber(getFlag("BRK")) == 1)then
- term.setTextColor(colors.white)
- print("\nProgram brk at PC=$" .. readPC())
- break
- end
- -- Get key inputs / generate random numbers
- local pop = program.ops[readPC()]
- os.queueEvent("ASMWait")
- local ev = {os.pullEvent()}
- if(ev[1] == "timer" and _G.ASM.pmode ~= 2)then
- term.setCursorPos(1, 1)
- print("IPS: " .. inCounter)
- inCounter = 0
- IPSTimer = os.startTimer(1)
- elseif(_G.ASM.pmode ~= 2 and line == 1)then
- term.clear()
- term.setCursorPos(1, 1)
- print("IPS: " .. inCounter)
- inCounter = 0
- end
- if(ev[1] == "key")then writeByte("FF",toHex(tonumber(ev[2]))) end
- writeByte("FE",toHex(math.random(0,255)))
- if(_G.ASM._OPCODES[pop] == nil)then print(pop .. " nil?") end
- local opBytes = _G.ASM._OPCODES[pop].bytes
- -- Run command
- if(debug and _G.ASM.pmode ~= 2)then
- term.current().setVisible(false)
- term.setCursorPos(1, 2)
- print("A: " .. readRegHex("A") .. " X: ".. readRegHex("X") .. " Y: " .. readRegHex("Y") .. " SP: " .. readRegHex("SP") .. " PC: " .. readPC())
- print("NZ-BDIZC")
- print(toBin(decodeByte(getFlagsByte())))
- for i = 1, #hex do
- local found = false
- local ind = tonumber(readPC(),16) - tonumber(progstart,16)
- if( (i-1) == ind)then
- term.setTextColor(colors.orange)
- write(hex[i] .. " ")
- else
- if(opBytes > 0)then
- for x = 1, opBytes do
- if((i-1)-x == ind)then
- term.setTextColor(colors.green)
- write(hex[i] .. " ")
- found = true
- end
- end
- end
- if not found then
- term.setTextColor(colors.white)
- write(hex[i] .. " ")
- end
- end
- end
- end
- term.current().setVisible(true)
- movePC(1)
- movePC(opBytes)
- _G.ASM._OPCODES[pop]:exe(unpack( program.args[readPC()] ))
- inCounter = inCounter + 1
- line = line + 1
- if(step)then
- if(_G.ASM.pmode ~= 2)then term.setCursorPos(1, 1) end
- term.setTextColor(colors.white)
- print("\nPress any key. ")
- os.pullEvent("key")
- end
- end
- if(tonumber(getFlag("BRK")) == 0)then
- term.setTextColor(colors.white)
- print("\nProgram end at PC=$" .. readPC())
- end
- end
- function AssembleASM(input,output,nout)
- if(nout == nil)then nout = false
- elseif(nout ~= "-y")then nout = false end
- if(nout == "-y")then nout = true end
- if(not fs.exists(input))then error("File doesnt exist: " .. input) end
- if(fs.exists(output))then error("File exists: " .. output) end
- local labels = {}
- local vars = {}
- bytearray = {}
- local keyword_var = "define"
- local keyword_label = ":"
- local keyword_begin = ".begin"
- local keyword_bytes = "dcb"
- local online = 1
- local codeline = 0
- local programstart = "0600"
- print("Reading file...")
- -- Safer to read file first, then compile as the fs hook is closed, and they is no risk of data loss.
- local source = fs.open(input,"r")
- local code = {}
- local line = source.readLine()
- while line do
- code[#code+1] = line
- line = source.readLine()
- end
- source.close()
- -- Compile Variables and labels, check for syntax errors
- print("Initializing...")
- for i = 1, #code do
- -- Handle variables
- if(code[i]:find(";"))then
- local nargs = {}
- for word in string.gmatch(code[i], '([^;]+)') do
- table.insert(nargs, word)
- end
- if(#nargs <= 1)then
- code[i] = ""
- else
- code[i] = nargs[1]
- end
- end
- if(code[i]:find(keyword_bytes))then
- local val = str_shearWord(code[i],keyword_bytes)
- if(code[i]:find(","))then
- for word in string.gmatch(val, '([^,]+)') do
- word = word:gsub("%s","")
- if(word:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
- if(word:sub(2,2) == "'")then
- if(#word:sub(3,#word-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
- word = "$" .. toHex((string.byte(word:sub(3,#word-1))))
- end
- if(#word == 5)then
- -- Divide and reverse order
- word = "$" .. word:sub(4,5) .. word:sub(2,3)
- end
- bytearray[codeline] = word:sub(2,#word)
- codeline = codeline + 1
- end
- else
- if(val:sub(2,2) == "'")then
- if(#val:sub(3,#val-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
- val = "$" .. toHex((string.byte(val:sub(3,#val-1))))
- end
- if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
- bytearray[codeline] = val:sub(2,#val)
- codeline = codeline + 1
- end
- end
- if(code[i]:find(keyword_begin))then
- local val = str_shearWord(code[i],keyword_begin)
- if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
- if(codeline ~= 0)then error("Syntax error line " .. online .. ": " .. code[i] .. " :> Must be placed only at start of file.") end
- programstart = val:sub(2,#val)
- end
- if(code[i]:find(keyword_var))then
- local val = str_shearWord(code[i],keyword_var)
- local nargs = {}
- -- Take spaces out of string, then split it into 2 variables
- val = val:gsub("%s+", "")
- -- Split string by $
- for word in string.gmatch(val, '([^$]+)') do
- table.insert(nargs, word)
- end
- if(#nargs > 2)then error("Syntax error line " .. online .. ": " .. code[i]) end
- -- Convert ASCII to hex
- if(nargs[2]:sub(1,1) == "'")then
- if(nargs[2]:sub(3,3) ~= "'")then error("Syntax error line " .. online .. ": " .. code[i]) end
- nargs[2] = toHex(string.byte(nargs[2]:sub(2,#nargs))) -- ToHex needed upon converted chars their respective byte.
- -- Using SUB because the string is split up into sections from the $ char, sub is needed to remove the ''.
- end
- -- if(_G.ASM._HEXENCODE[string.upper(nargs[1])])then error("Syntax error line " .. online .. ": " .. code[i]) end
- vars[nargs[1]] = nargs[2]
- -- print(nargs[1] .. ": " .. vars[nargs[1]])
- end
- -- Handle labels
- if(code[i]:find(keyword_label))then
- local val = code[i]:gsub("%s+","")
- local nargs = {}
- for word in string.gmatch(val, '([^:]+)') do
- table.insert(nargs, word)
- end
- if(#nargs > 1 or nargs == nil)then
- error("Syntax error line " .. online .. ": " .. code[i])
- end
- labels[nargs[1]] = codeline
- -- print(nargs[1] .. ": " .. labels[nargs[1]])
- end
- online = online + 1
- if(#code[i]:gsub("%s+","") ~= 0 and not code[i]:find(keyword_label) and not code[i]:find(keyword_var) and not code[i]:find(keyword_begin) and not code[i]:find(keyword_bytes))then
- codeline = codeline + 1
- end
- end
- -- Get Bytes Per line
- codeline = 0
- online = 1
- linebytes = {}
- local loadedbytes = false
- code_backup = code -- LUA bug where this variable acts like a pointer and still writes to code.
- print("Getting Bytes...")
- -- Process each defined byte
- for i = 1, #code_backup do
- if(code[i]:find(";"))then
- local nargs = {}
- for word in string.gmatch(code[i], '([^;]+)') do
- table.insert(nargs, word)
- end
- if(#nargs <= 1)then
- code[i] = ""
- else
- code[i] = nargs[1]
- end
- end
- -- Calculate defined bytes
- if(code_backup[i]:find(keyword_bytes))then
- local val = str_shearWord(code[i],keyword_bytes)
- if(code_backup[i]:find(","))then
- for word in string.gmatch(val, '([^,]+)') do
- word = word:gsub("%s","")
- if(word:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- if(word:sub(2,2) == "'")then
- if(#word:sub(3,#word-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- end
- if(#word == 5)then
- -- Divide and reverse order
- linebytes[#linebytes+1] = 2
- else
- linebytes[#linebytes+1] = 1
- end
- end
- else
- if(val:sub(2,2) == "'")then
- if(#val:sub(3,#val-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
- linebytes[#linebytes+1] = 1
- else
- linebytes[#linebytes+1] = 1
- end
- if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
- codeline = codeline + 1
- end
- end
- if(#code_backup[i]:gsub("%s+","") ~= 0 and not code_backup[i]:find(keyword_label) and not code_backup[i]:find(keyword_var) and not code_backup[i]:find(keyword_begin) and not code_backup[i]:find(keyword_bytes))then
- local op = string.upper(code_backup[i]:gsub("%s+",""):sub(1,3))
- local vtype = code_backup[i]:gsub("%s+",""):sub(4,4)
- local opperand = ""
- local prefix = ""
- local val = code_backup[i]:gsub("%s+",""):sub(4,#code_backup[i])
- if(code[i]:find(","))then
- local ends = {}
- for word in string.gmatch(code[i], '([^,]+)') do
- table.insert(ends, word)
- end
- val = str_shearWord(ends[1],op)
- opperand = ", " .. ends[2]:gsub("%s","")
- if(code[i]:find("%("))then
- if(string.lower(ends[2]:gsub("%s","")) == "y")then
- opperand = ")" .. opperand
- end
- prefix = "("
- end
- end
- if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
- if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- if(vars[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- error("Syntax error line " .. online .. ": " .. code_backup[i])
- end
- if(vtype == "#")then
- code_backup[i] = op .. " #$" .. vars[val] .. opperand
- else
- if(not tonumber(vars[val],16))then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- code_backup[i] = op .. " $" .. vars[val] .. opperand
- end
- elseif(labels[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- code_backup[i] = op .. " *+" .. "00"
- else
- code_backup[i] = op .. " $" .. "0000" .. opperand
- end
- end
- -- Variable encoding
- val = val:gsub("[()]","")
- if(vars[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- -- No variable branching!
- error("Syntax error line " .. online .. ": " .. code_backup[i])
- end
- if(vtype == "#")then
- code[i] = op .. " " .. prefix .. "#$" .. vars[val] .. opperand
- --print(code[i])
- else
- -- Direct index
- if(not tonumber(vars[val],16))then error("Syntax error line " .. online .. ": " .. code[i]) end
- code[i] = op .. " " .. prefix .. "$" .. vars[val] .. opperand
- --print(code[i])
- end
- end
- codeline = codeline + 1
- local opr, otype, num = procInstructionType(code_backup[i],false,false)
- if(lineB == "op")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- if(otype == nil)then otype = "err" end
- print(opr .. ": " .. otype)
- local lineB = getInstuctionBytes(opr,otype)
- if(lineB == "err")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- linebytes[#linebytes+1] = lineB
- --print(#linebytes .. ": " .. lineB)
- --os.pullEvent("key")
- end
- online = online + 1
- end
- -- Compile Code substitute variables and labels, check syntax
- -- Branch labels and jump labels, are controlled based on additions to the base program start
- codeline = 0
- online = 1
- local source = fs.open(input,"r")
- local code = {}
- local line = source.readLine()
- while line do
- code[#code+1] = line
- line = source.readLine()
- end
- source.close()
- local hexdump = ""
- print("Compiling code...")
- for i = 1, #code do
- if(code[i]:find(";"))then
- local nargs = {}
- for word in string.gmatch(code[i], '([^;]+)') do
- table.insert(nargs, word)
- end
- if(#nargs <= 1)then
- code[i] = ""
- else
- code[i] = nargs[1]
- end
- end
- if(#code[i]:gsub("%s+","") ~= 0 and not code[i]:find(keyword_label) and not code[i]:find(keyword_var) and not code[i]:find(keyword_begin) and not code[i]:find(keyword_bytes))then
- -- Check if code references label or variable
- local op = string.upper(code[i]:gsub("%s+",""):sub(1,3))
- local vtype = code[i]:gsub("%s+",""):sub(4,4)
- local opperand = ""
- local prefix = ""
- local val = code[i]:gsub("%s+",""):sub(4,#code[i])
- if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
- if(code[i]:find(","))then
- local ends = {}
- for word in string.gmatch(code[i], '([^,]+)') do
- table.insert(ends, word)
- end
- val = str_shearWord(ends[1],op)
- opperand = ", " .. ends[2]:gsub("%s","")
- if(code[i]:find("%("))then
- if(string.lower(ends[2]:gsub("%s","")) == "y")then
- opperand = ")" .. opperand
- end
- prefix = "("
- end
- end
- val = val:gsub("[()]","")
- if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code[i]) end
- if(vars[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- -- No variable branching!
- error("Syntax error line " .. online .. ": " .. code[i])
- end
- if(vtype == "#")then
- code[i] = op .. " " .. prefix .. "#$" .. vars[val] .. opperand
- --print(code[i])
- else
- -- Direct index
- if(not tonumber(vars[val],16))then error("Syntax error line " .. online .. ": " .. code[i]) end
- code[i] = op .. " " .. prefix .. "$" .. vars[val] .. opperand
- --print(code[i])
- end
- elseif(labels[val] ~= nil)then
- -- Insert for relative branching
- --error("Labels do not work yet (And may never work)")
- local bytediff = 0
- branches = {}
- for i = 1, #linebytes do
- if(i > 1)then
- branches[i] = branches[i-1] + linebytes[i]
- else
- branches[i] = linebytes[i]
- end
- end
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- -- Jump difference
- local difference = (branches[labels[val]] - branches[codeline+1])
- if(difference < -128 or difference > 127)then
- error("Out of range branch on line " .. online .. " (branches are limited to -128 to +127): " .. code[i] .. "(" .. difference .. ") ")
- end
- if(difference < 0)then
- -- Subtract the amount of bytes taken by branch
- difference = 256 + difference
- end
- difference = toHex(difference)
- -- Insert branch difference into code
- code[i] = op .. " *+" .. difference
- --print(code[i])
- else
- -- Insert for jumping
- local newBase = toHex(tonumber(programstart,16) + branches[labels[val]])
- if(#newBase < 4)then newBase = string.rep("0",4-#newBase) .. newBase end
- code[i] = op .. " $" .. newBase .. opperand
- --print(code[i])
- end
- end
- local hex = AssembleHEX(code[i],online)
- hexdump = hexdump .. hex
- codeline = codeline + 1
- end
- online = online + 1
- -- if DCB, replace with the raw bytes
- -- Calculate defined bytes
- if(code[i]:find(keyword_bytes))then
- local val = str_shearWord(code[i],keyword_bytes)
- local hex = ""
- local wInd = 0
- if(code[i]:find(","))then
- for word in string.gmatch(val, '([^,]+)') do
- word = word:gsub("%s","")
- if(word:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
- if(word:sub(2,2) == "'")then
- if(#word:sub(3,#word-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
- word = "$" .. toHex(string.byte(word:sub(3,3)))
- end
- code[wInd] = word:sub(2,#word)
- hex = word:sub(2,#word)
- wInd = wInd +1
- if(#hex == 4)then
- hex = hex:sub(1,2) .. " " .. hex:sub(3,4)
- end
- hexdump = hexdump .. hex .. " "
- codeline = codeline+1
- end
- else
- if(val:sub(2,2) == "'")then
- if(#val:sub(3,#val-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
- val = toHex(string.byte(val:sub(3,3)))
- code[i] = val
- hex = val
- else
- code[i] = val:sub(2,#val)
- hex = val:sub(2,#val)
- end
- if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
- if(#hex == 4)then
- hex = hex:sub(1,2) .. " " .. hex:sub(3,4)
- end
- hexdump = hexdump .. hex .. " "
- codeline = codeline + 1
- end
- end
- end
- -- Compile hex to bytes
- local hexbytes = ""
- local _hexdump = hexdump
- hexdump = hexdump:gsub("%s+","")
- if(hexdump == "")then
- print("No code to run.")
- return
- end
- if(#hexdump > 2)then
- for i=1, #hexdump, 2 do
- hexbytes = hexbytes .. string.char(tonumber(hexdump:sub(i,i+1),16))
- end
- else
- hexbytes = string.char(tonumber(hexdump,16))
- end
- print("Hex Compiled: " .. _hexdump)
- if(nout == false)then
- local f = fs.open(output,"wb")
- for i=1, #hexdump, 2 do
- if(i == 1)then
- -- Program counter encoding.
- f.write(tonumber(programstart:sub(1,2),16))
- f.write(tonumber(programstart:sub(3,4),16))
- end
- f.write(tonumber(hexdump:sub(i, i + 1), 16))
- end
- f.close()
- print("Hex outputed to: " .. output)
- print("Done. ")
- --os.pullEvent("key")
- end
- end
- local function StartSyntaxInterpreter()
- print("Starting Syntax Interpreter (type \"exit\" to exit.)")
- local running = true
- local function getinp()
- local opperation = read()
- if(opperation == "exit")then
- if(_CCENV)then
- print("Returning to CraftOS.")
- else
- print("Returning to LUA.")
- end
- running = false
- end
- local op, type, val = procInstructionType(opperation,true)
- runOpperation(op,type,val,true)
- print("A: " .. readRegHex("A") .. " X: ".. readRegHex("X") .. " Y: " .. readRegHex("Y") .. " SP: " .. readRegHex("SP") .. " PC: " .. readPC())
- print(toBin(decodeByte(getFlagsByte())))
- end
- while running do
- write("Ready :> ")
- local gd, err = pcall(getinp)
- if(not ok and err and running)then print(err) end --print(err:sub(11,#err)) end
- end
- end
- if(not _G.ASM and shell)then
- print("6502: Not Initialized, press any key. ")
- os.pullEvent("key")
- initalize()
- print("Memory testing...")
- writeByte("1","0C")
- writeByte("2","0C")
- writeByte("3","0C")
- writeByte("FFFF","0C")
- print("Retrieving...")
- readByte("1",true)
- readByte("2",true)
- readByte("3",true)
- readByte("FFFF",true)
- print("Memory check successful!, re-initalizing...")
- writeByte("1","0")
- writeByte("2","0")
- writeByte("3","0")
- writeByte("FFFF","0")
- print("Memory: " .. _G.ASM.MSIZE .. "B free. \n")
- print("Ready. ")
- sleep(0.5)
- term.clear()
- term.setCursorPos(1,1)
- elseif(not shell and not _G.ASM)then
- initalize()
- end
- -- Program Arguments Use
- local progargs = { ... }
- -- Arguments -i, -c, -r, interpreter, compile, run
- -- If this program is not being loaded as an API
- if(shell ~= nil)then
- if(#progargs == 0)then
- print("Usage: " .. shell.resolve(shell.getRunningProgram()) .. " -<mode> <args> \n")
- print("Modes -> -i, -c, -r, -rn, -m, -d")
- print("-i Starts 6502 Interpreter. ")
- print("-c Compiles <file>, outputs hex to <output>.")
- print("-r Runs compiled ASM hex <file>. ")
- print("-rn Runs the <file> without exporting it (Runs Pre-Compiled, Faster).")
- print("-rnr Runs the <file> without exporting it (Runs in RealTime, Slower).")
- print("-m Sets run <mode>: [1 - Text] [2 - Graphics]" )
- print("-d Exports Disassembled ASM from <source> to <output>")
- end
- if(not _CCENV)then
- local mode = io.read()
- for word in string.gmatch(mode, '([^ ]+)') do
- table.insert(progargs, word)
- end
- end
- if(progargs[1] == "-i")then
- StartSyntaxInterpreter()
- elseif(progargs[1] == "-c")then
- if(#progargs < 3)then error("Usage: -i <source> <output>") end
- AssembleASM(progargs[2],progargs[3],progargs[4])
- elseif(progargs[1] == "-r")then
- if(#progargs < 2)then error("Usage: -r <compiled asm>") end
- runCompiledASM(progargs[2],progargs[3],progargs[4])
- elseif(progargs[1] == "-rn")then
- if(#progargs < 2)then error("Usage: -rn <source>") end
- if(fs.exists("/.tempasm"))then fs.delete("/.tempasm") end
- AssembleASM(progargs[2],"/.tempasm",progargs[3])
- if(fs.exists("/.tempasm"))then
- runPreCompiledASM("/.tempasm",progargs[3],progargs[4])
- end
- fs.delete("/.tempasm")
- elseif(progargs[1] == "-m")then
- if(#progargs < 2)then error("Usage: -m <mode>") end
- local mode = tonumber(progargs[2])
- if(progargs[2] == "2")then
- print("Programs set to run in Graphics mode.")
- elseif(progargs[2] == "1")then
- print("Programs set to run in Text mode.")
- else
- print("Unknown mode: " .. progargs[2])
- mode = 1
- end
- _G.ASM.pmode = mode
- elseif(progargs[1] == "-rnr")then
- if(#progargs < 2)then error("Usage: -rn <source>") end
- if(fs.exists("/.tempasm"))then fs.delete("/.tempasm") end
- AssembleASM(progargs[2],"/.tempasm",progargs[3])
- if(fs.exists("/.tempasm"))then
- runCompiledASM("/.tempasm",progargs[3],progargs[4])
- end
- fs.delete("/.tempasm")
- elseif(progargs[1] == "-d")then
- if(#progargs < 3)then error("Usage: -d <compiled asm> <output>") end
- if(not fs.exists(progargs[2]))then error("No such file: " .. progargs[2]) end
- local asmc = disassembleASM(progargs[2])
- local f = fs.open(progargs[3],"w")
- f.writeLine("Address Hexdump Dissassembly")
- f.writeLine("-------------------------------")
- f.write(asmc)
- f.close()
- print("Disassembly outputed to: " .. progargs[3])
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement