Redxone

[CC - Emulation] 6502 CPU Emulator (WIP)

Mar 21st, 2017
774
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 97.33 KB | None | 0 0
  1. --[[
  2.   6502 By Lewisk3 (Redxone) - Special thanks to SquidDev for compiler help!
  3. Methods of emulation:
  4.   1. Memory segments
  5.     : Use a table of bytes 64KB
  6.   2. Onboard registers
  7.     : Use a seperate table for registers
  8.   3. Flags
  9.     : Use a String of true or falses
  10.   4. Data Stack
  11.     : 256B - Stored on another memory area
  12. --]]
  13.  
  14. -- TODO: 0200 to 0D5B = Screen memory
  15.  
  16. -- Setup _6502 Enviorment
  17. local _NIBBLE = 4
  18. local _BYTE = 8
  19. local _KBYTE = 1024
  20. local _BUSWIDTH = 16
  21. local _CCENV = true
  22. -- Non CC lua compatibility
  23. if(write == nil)then write = io.write end
  24. if(read == nil)then read = io.read end
  25. if(sleep == nil)then sleep = function() end end
  26. if(term == nil)then
  27.   term = {}
  28.   term.current = function() return { setVisible = function(tf) return false end } end
  29.   term.isColor = function() return false end
  30.   term.setCursorPos = function(x,y) end
  31.   term.clear = function() end
  32.   term.setBackgroundColor = function(col) end
  33.   term.setTextColor = function(col) end
  34.   colors = {}
  35.   colors.white = 0
  36.   os = {}
  37.   os.pullEvent = function(ev) return nil end
  38.   shell = {}
  39.   shell.resolve = function(txt) return txt end
  40.   shell.getRunningProgram = function() return "6502" end
  41.   _CCENV = false
  42. elseif(term.current == nil)then
  43.   term.current().setVisible = function(tf) return false end
  44. end
  45. -- Monochrome support
  46. if(not term.isColor())then
  47.   colors.orange    = colors.white
  48.   colors.magenta   = colors.white
  49.   colors.lightBlue = colors.white
  50.   colors.yellow    = colors.white
  51.   colors.lime      = colors.white
  52.   colors.pink      = colors.white
  53.   colors.gray      = colors.white
  54.   colors.lightGray = colors.white
  55.   colors.cyan      = colors.white
  56.   colors.purple    = colors.white
  57.   colors.blue      = colors.white
  58.   colors.brown     = colors.white
  59.   colors.green     = colors.white
  60.   colors.red       = colors.white
  61.   colors.black     = colors.white
  62. end
  63. --]] "BIOS" Functionality (All functions defined for Input and Output)
  64.  
  65. -- Useful bit logic functions
  66.  
  67.   typeCheck = function(val)
  68.       if(not tonumber(val,16))then
  69.           return "dec"
  70.       else
  71.           return "hex"
  72.       end
  73.   end
  74.  
  75.   toHex = function(dec)
  76.     local hex = ""
  77.     local hexkey = "0123456789ABCDEF"
  78.     local rim
  79.     if(dec == 0)then hex = "0" end
  80.     while dec > 0 do
  81.        rim = math.floor(dec%16)
  82.        hex = hexkey:sub(rim+1,rim+1) .. hex
  83.        dec = math.floor(dec/16)
  84.     end
  85.     if(#hex == 1)then
  86.       hex = "0" .. hex
  87.     end
  88.     if(dec < 0)then
  89.       local num = 256 + dec
  90.       return toHex(num)
  91.     end
  92.     return hex
  93.   end
  94.  
  95.   toBin = function(dec)
  96.     -- Convert to base 10 soooo easy
  97.     local bin = ""
  98.     local binkey = "01"
  99.     local rim
  100.     if(type(dec) == "string")then error("toBin -> Invalid type: " .. dec) end
  101.     while dec > 0 do
  102.        rim = math.floor(dec%2)
  103.        bin = binkey:sub(rim+1,rim+1) .. bin
  104.        dec = math.floor(dec/2)
  105.     end
  106.     if(#bin < 8)then
  107.       bin = string.rep("0",8-#bin) .. bin
  108.     end
  109.     return bin
  110.   end
  111.  
  112.   signedHextoDec = function(hex)
  113.      local dechex = tonumber(hex,16)
  114.    -- Check sign
  115.    local checksign = toBin(dechex):sub(1,1)
  116.    --print(toBin(dechex))
  117.      if(checksign == "1")then
  118.       return (dechex - 255)-1
  119.      else
  120.       return dechex
  121.      end
  122.   end
  123.  
  124. -- 1Byte Registers
  125. function writeReg(reg,byte)
  126.   if(not _G.ASM.reg[reg])then
  127.     error("Invalid register -> " .. reg)
  128.   end
  129.   _G.ASM.reg[reg] = string.char(tonumber(byte,16))
  130. end
  131.  
  132. function writeRegDec(reg,byte)
  133.   if(not _G.ASM.reg[reg])then
  134.     error("Invalid register -> " .. reg)
  135.   end
  136.   _G.ASM.reg[reg] = string.char(byte)
  137. end
  138.  
  139. function writeRegChar(reg,ch)
  140.   if(not _G.ASM.reg[reg])then
  141.     error("Invalid register -> " .. reg)
  142.   end
  143.   _G.ASM.reg[reg] = ch
  144. end
  145.  
  146. function moveRegs(from,to,flags)
  147.   if(flags == nil)then flags = false end
  148.   local from = readRegHex(from)
  149.   writeReg(to,from)
  150.   if(flags)then updateResultFlags(readRegDec(to)) end
  151. end
  152.  
  153. function loadRegIndirect(reg,ind,itype)
  154.   local plusx = 0
  155.   local plusy = 0
  156.   -- Optional indexing types
  157.   if(itype == nil)then itype = "" end
  158.   if(itype == "X")then
  159.     plusx = decodeByte(readReg("X"))
  160.   elseif(itype == "Y")then
  161.     plusy = decodeByte(readReg("Y"))
  162.   end
  163.  
  164.   -- Get ind data from 1, and 2 (ind + 1) and concatenate location, lsb..msb
  165.  
  166.   local ind = toHex(tonumber(ind,16) + plusx)
  167.   local ind2 = toHex(tonumber(ind,16) + 1)
  168.   local byte1 = readByteHex(ind)
  169.   local byte2 = readByteHex(ind2)
  170.   local addr = toHex(tonumber(byte2 .. byte1,16) + plusy)
  171.   if(#addr < 4)then
  172.     addr = string.rep("0",4-#addr) .. addr
  173.   end
  174.   writeReg(reg,readByteHex(addr))
  175. end
  176. --storeRegIndirect("A","15","X")
  177. function storeRegIndirect(reg,ind,itype)
  178.   local plusx = 0
  179.   local plusy = 0
  180.   -- Optional indexing types
  181.   if(itype == nil)then itype = "" end
  182.   if(itype == "X")then
  183.     plusx = decodeByte(readReg("X"))
  184.   end
  185.   if(itype == "Y")then
  186.     plusy = decodeByte(readReg("Y"))
  187.   end
  188.   local ind = toHex(tonumber(ind,16) + plusx)
  189.   local ind2 = toHex(tonumber(ind,16) + 1)
  190.   local byte1 = readByteHex(ind)
  191.   local byte2 = readByteHex(ind2)
  192.   local addr = toHex(tonumber(byte2 .. byte1,16) + plusy)
  193.   if(#addr < 4)then
  194.     addr = string.rep("0",4-#addr) .. addr
  195.   end
  196.   writeByte(addr,readRegHex(reg))
  197. end
  198.  
  199. function readReg(reg)
  200.   if(not _G.ASM.reg[reg])then
  201.     error("Invalid register -> " .. reg)
  202.   end
  203.   return tostring(_G.ASM.reg[reg])
  204. end
  205. function readRegHex(reg)
  206.   return toHex(decodeByte(readReg(reg)))
  207. end
  208. function readRegDec(reg)
  209.   if(not _G.ASM.reg[reg])then
  210.     error("Invalid register -> " .. reg)
  211.   end
  212.   return string.byte(_G.ASM.reg[reg])
  213. end
  214.  
  215. function decodeByte(byte)
  216.   return string.byte(byte)
  217. end
  218.  
  219. -- Program Counter
  220. function readPC()
  221.   local MSB = toHex(string.byte(_G.ASM.reg['PC']:sub(1,1)))
  222.   local LSB = toHex(string.byte(_G.ASM.reg['PC']:sub(2,2)))
  223.   return MSB .. LSB
  224. end
  225.  
  226. setPC = function(bytes)
  227.   if(#bytes > 4)then print("Program counter must be 4Bytes!") end
  228.   if(#bytes < 4)then
  229.     bytes = string.rep("0",4-#bytes) .. bytes
  230.   end
  231.   local MSB = string.char(tonumber(bytes:sub(1,2),16))
  232.   local LSB = string.char(tonumber(bytes:sub(3,4),16))
  233.   --print(MSB .. LSB)
  234.   _G.ASM.reg['PC'] = MSB .. LSB
  235. end
  236.  
  237. getProgramByte = function(byte)
  238.   -- Program byte will be a hex value
  239.     local hexPC = toHex(string.byte(readReg('PC')))
  240.     -- PROGM is in ASCII format
  241.     -- Convert to HEX then return
  242.     return readByteHex(hexPC)
  243. end
  244.  
  245. movePC = function(bytes)
  246.   local absval = toHex(tonumber(readPC(),16) + bytes)
  247.   if(#absval < 4)then absval = "0" .. absval end
  248.   setPC(absval)
  249. end
  250.  
  251. -- Stacks
  252.  
  253. function pushStack(val)
  254.   local sp = toHex(string.byte(readReg('SP')))
  255.   local pointer = toHex(string.byte(readReg("SP")))
  256.   local val = tonumber(val,16)
  257.   local offs = math.floor(tonumber(pointer,16)%_BUSWIDTH)
  258.   local pointer = math.floor(tonumber(pointer,16)/_BUSWIDTH)+1
  259.   local byte = _G.ASM.stack[pointer]
  260.   byte = byte:sub(1,offs-1) .. string.char(val) .. byte:sub(offs+1,#byte)
  261.   _G.ASM.stack[pointer] = byte
  262.   -- Move pointer to next item in stack
  263.   pointer = tonumber(sp,16) - 1
  264.   -- If the pointer reached the end of the stack, reset it
  265.   if(pointer < 1)then
  266.     pointer = "FF"
  267.     -- Write pointer back into Stack Pointer
  268.     writeReg("SP",pointer)
  269.   else
  270.     -- Write pointer back into Stack Pointer
  271.     writeRegDec("SP",pointer)
  272.   end
  273. end
  274.  
  275.  
  276. function pullStack()
  277.   -- Pull value off stack, and increment the stack pointer
  278.   local sp = toHex(string.byte(readReg("SP")))
  279.   local pointer = toHex(string.byte(readReg("SP"))+1)
  280.   local offs = math.floor(tonumber(pointer,16)%_BUSWIDTH)
  281.   local pointer = math.floor(tonumber(pointer,16)/_BUSWIDTH)+1
  282.   local byte = _G.ASM.stack[pointer]
  283.   -- Move pointer to next item in stack
  284.   pointer = tonumber(sp,16) + 1
  285.   -- If the pointer reached the end of the stack, reset it
  286.   if(pointer > 255)then
  287.     pointer = "00"
  288.     -- Write pointer back into Stack Pointer
  289.     writeReg("SP",pointer)
  290.   else
  291.     -- Write pointer back into Stack Pointer
  292.     writeRegDec("SP",pointer)
  293.   end
  294.   if(byte == nil)then
  295.     return string.char("0")
  296.   end
  297.   return byte:sub(offs,offs)
  298. end
  299.  
  300. -- Flags
  301.  
  302. function setFlag(flagbit,onoff)
  303.   if(_G.ASM.flagtypes[flagbit])then flagbit = _G.ASM.flagtypes[flagbit] end
  304.   flagbit = tostring(flagbit)
  305.   local flags = toBin(decodeByte(_G.ASM.flags))
  306.   if(onoff ~= 1 and onoff ~= 0)then error("Invaild flag state!") end
  307.   if(#flags < 0 or #flags > 8)then error("Invalid flag index!") end
  308.   flags = flags:sub(1,flagbit-1) .. tostring(onoff) .. flags:sub(flagbit+1,#flags)
  309.   _G.ASM.flags = string.char(tonumber(flags,2))
  310. end
  311. function getFlag(flagbit)
  312.   if(_G.ASM.flagtypes[flagbit])then flagbit = _G.ASM.flagtypes[flagbit] end
  313.   return toBin(decodeByte(_G.ASM.flags)):sub(flagbit,flagbit)
  314. end
  315. function getFlagsByte()
  316.   return _G.ASM.flags
  317. end
  318. function setAllFlags(flaghex)
  319.   _G.ASM.flags = string.char(decodeByte(flaghex))
  320. end
  321.  
  322. function updateResultFlags(val)
  323.   -- Val is in Hex
  324.   if(type(val) == "string")then
  325.       val = tonumber(val,16)
  326.   end
  327.   local binval = toBin(val)
  328.   local flags = toBin(decodeByte(_G.ASM.flags))
  329.   if(val == 0)then
  330.     setFlag("ZRO",1)
  331.   else
  332.     setFlag("ZRO",0)
  333.   end
  334.   if(binval:sub(1,1) == "1")then
  335.     setFlag("NEG",1)
  336.   else
  337.     setFlag("NEG",0)
  338.   end
  339.   return
  340. end
  341.  
  342. function checkCarry(mode,val)
  343.   if(type(val) == "string")then error("Value must be decimal for CARRY check!") end
  344.   if(string.lower(mode) == "add")then
  345.     if(val > 255)then
  346.       setFlag("CRY",1)
  347.       return true
  348.     elseif(val < 0)then
  349.       setFlag("CRY",1)
  350.       return true
  351.     else
  352.       setFlag("CRY",0)
  353.       return false
  354.     end
  355.   elseif(string.lower(mode) == "sub")then
  356.     if(val < 0)then
  357.       setFlag("CRY",0)
  358.       return true
  359.     else
  360.       setFlag("CRY",1)
  361.       return false
  362.     end
  363.   else
  364.     error("Invalid CARRY check mode: " .. mode)
  365.   end
  366. end
  367.  
  368. function addHex(n1,n2)
  369.   local num = tonumber(n1,16) + tonumber(n2,16)
  370.   if(num > 255)then
  371.     num = num - 256
  372.   end
  373.   return toHex(num)
  374. end
  375. function subHex(n1,n2)
  376.   local num = (tonumber(n1,16) - tonumber(n2,16))
  377.   if(num < 0)then
  378.     num = 256 + num
  379.   end
  380.   return toHex(num)
  381. end
  382.  
  383. function addSignedDec(n1,n2)
  384.   local num = tonumber(n1,16) + tonumber(n2,16)
  385.   if(num > 255)then
  386.     num = num - 256
  387.   end
  388.   return num
  389. end
  390.  
  391. function subSignedDec(n1,n2)
  392.   local num = (tonumber(n1,16) - tonumber(n2,16))
  393.   if(num < 0)then
  394.     num = 256 + num
  395.   end
  396.   return num
  397. end
  398.  
  399.  
  400.  
  401.  
  402.  
  403. function checkOverflow(mode,val,val2)
  404.   if(val2 == nil)then val2 = "00" end
  405.   if(string.lower(mode) == "bit")then
  406.     val = toBin(tonumber(val,16))
  407.     -- Check bit 6 (0 indexed) of value for a 1 if so, set V flag
  408.     if(val:sub(2,2) == "1")then
  409.       setFlag("OVR",1)
  410.       return true
  411.     else
  412.       setFlag("OVR",0)
  413.       return false
  414.     end
  415.   elseif(string.lower(mode) == "math")then
  416.     val = signedHextoDec(val) + signedHextoDec(tonumber(val2,16))
  417.     -- Check if value is negative (2s signed)
  418.     -- Convert value into Decimal
  419.     -- Convert decimal into 8bit signed decimal
  420.     -- Check if val is outside the bounds of an 8bit
  421.     -- 2's complement signed number, if so, set overflow.
  422.     if(val < -127)then
  423.       setFlag("OVR",1)
  424.       return true
  425.     elseif(val > 127)then
  426.       setFlag("OVR",1)
  427.       return true
  428.     else
  429.       setFlag("OVR",0)
  430.       return false
  431.     end
  432.   end
  433. end
  434.  
  435. function getSign(val)
  436.   -- Returns true if negative
  437.   return toBin(tonumber(val,16)):sub(1,1) == "1"
  438. end
  439.  
  440. function signedAdd(val,val2)
  441.   if(getFlag("DEC") == "1")then
  442.     return signedAddDec(val, val2)
  443.   end
  444.   local snum = toHex(signedHextoDec(val) + signedHextoDec(val2))
  445.   local num = tonumber(val,16) + tonumber(val2,16)
  446.   checkOverflow("math",snum)
  447.   checkCarry("add",num)
  448.   if(getFlag("CRY") == "1")then
  449.     -- Push off MSB from NUM, to fit in 1Byte space
  450.     num = toHex(num)
  451.     num = num:sub(#num-1,#num)
  452.     num = tonumber(num,16)
  453.   end
  454.   return toHex(num)
  455. end
  456.  
  457. function signedAddDec(val, val2)
  458.     -- Determine string HEX or Dec, based on DEC flag "reasonableness" (Basically, the DEC flag math can still do hex, but only to an extent. )
  459.     if(tonumber(val) == nil)then val = tonumber(val,16) else val = tonumber(val) end
  460.     if(tonumber(val2) == nil)then val2 = tonumber(val2,16) else val2 = tonumber(val2) end
  461.   local num = val + val2
  462.     if(num > 99)then
  463.       setFlag("CRY",1)
  464.       num = ( (num-1) - 99 )
  465.     elseif(num < 0)then
  466.       setFlag("CRY",1)
  467.     else
  468.       setFlag("CRY",0)
  469.     end
  470.   num = tostring(num)
  471.   if(#num == 1)then num = "0" .. num end
  472.   return num
  473. end
  474.  
  475. --signedSub("FF","01")
  476. function signedSub(val,val2)
  477.   if(getFlag("DEC") == "1")then
  478.     return signedSubDec(val, val2)
  479.   end
  480.   local snum = toHex(signedHextoDec(val) - (signedHextoDec(val2)) )
  481.   local num = tonumber(val,16) - (tonumber(val2,16))
  482.   checkOverflow("math",snum)
  483.   checkCarry("sub",num)
  484.   return toHex(num)
  485. end
  486.  
  487. function signedSubDec(val, val2)
  488.     -- Determine string HEX or Dec, based on DEC flag "reasonableness" (Basically, the DEC flag math can still do hex, but only to an extent. )
  489.     if(tonumber(val) == nil)then val = tonumber(val,16) else val = tonumber(val) end
  490.     if(tonumber(val2) == nil)then val2 = tonumber(val2,16) else val2 = tonumber(val2) end
  491.   local num = val - val2
  492.     if(num < 0)then
  493.       setFlag("CRY",1)
  494.       num = ( 99 + num )
  495.     else
  496.       setFlag("CRY",0)
  497.     end
  498.     num = tostring(num)
  499.     if(#num == 1)then num = "0" .. num end
  500.   return num
  501. end
  502.  
  503. -- RAM
  504. function readIndirectByte(ind,itype)
  505.   local plusx = 0
  506.   local plusy = 0
  507.   if(itype == "X")then
  508.     plusx = decodeByte(readReg("X"))
  509.   end
  510.   if(itype == "Y")then
  511.     plusy = decodeByte(readReg("Y"))
  512.   end
  513.   local ind = toHex(tonumber(ind,16) + plusx)
  514.   local ind2 = toHex(tonumber(ind,16) + 1)
  515.   local byte1 = readByteHex(ind)
  516.   local byte2 = readByteHex(ind2)
  517.   local addr = toHex(tonumber(byte2 .. byte1,16) + plusy)
  518.   return addr
  519. end
  520.  
  521. function writeByte(loc,byte,debug)
  522.   if(debug == nil)then debug = false end
  523.   local locraw = loc
  524.   local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
  525.   local absoluteloc = tonumber(loc,16) - math.floor(tonumber(loc,16)%_BUSWIDTH)
  526.   local loc  = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
  527.   local byte = string.char(tonumber(byte,16))
  528.   local byteloc = _G.ASM.ram[loc]
  529.   if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
  530.   byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
  531.   _G.ASM.ram[loc] = byteloc
  532.   refreshScreen(locraw)
  533.   if(debug)then print(absoluteloc .. " = " .. byteloc) end
  534. end
  535. function writeByteDec(loc,byte,debug)
  536.   if(debug == nil)then debug = false end
  537.   local locraw = loc
  538.   local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
  539.   local absoluteloc = tonumber(loc,16) - math.floor(tonumber(loc,16)%_BUSWIDTH)
  540.   local loc  = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
  541.   local byte = string.char(byte)
  542.   local byteloc = _G.ASM.ram[loc]
  543.   if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
  544.   byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
  545.   _G.ASM.ram[loc] = byteloc
  546.   refreshScreen(locraw)
  547.   if(debug)then print(absoluteloc .. " = " .. byteloc) end
  548. end
  549. function writeDecByte(loc,byte,debug)
  550.   if(debug == nil)then debug = false end
  551.   local locraw = loc
  552.   local offs = math.floor(loc%_BUSWIDTH)+1
  553.   local absoluteloc = loc - math.floor(loc%_BUSWIDTH)
  554.   local loc  = math.floor(loc/_BUSWIDTH)+1
  555.   local byte = string.char(byte)
  556.   local byteloc = _G.ASM.ram[loc]
  557.   if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
  558.   byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
  559.   _G.ASM.ram[loc] = byteloc
  560.   refreshScreen(locraw)
  561.   if(debug)then print(absoluteloc .. " = " .. byteloc) end
  562. end
  563. function readByte(loc,debug)
  564.   if(debug == nil)then debug = false end
  565.   local offs =  math.floor(tonumber(loc,16)%_BUSWIDTH)+1
  566.   local loc  = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
  567.   local byte = tostring(_G.ASM.ram[loc]:sub(offs,offs))
  568.   if(debug)then print(loc .. ":" .. offs .. " = " .. byte) end
  569.   return byte
  570. end
  571. function readAddressByte(byte,itype)
  572.   local reg = false
  573.   if(byte == "A" or byte == "X" or byte == "Y")then
  574.     reg = true
  575.   end
  576.   if(itype == nil)then itype = "" end
  577.   local plus = 0
  578.   if(itype == "X")then
  579.     plus = decodeByte(readReg("X"))
  580.   end
  581.   if(itype == "Y")then
  582.     plus = decodeByte(readReg("Y"))
  583.   end
  584.   local addr = 0
  585.   local val = 0
  586.   if(not reg)then addr = toHex(tonumber(byte,16) + plus) end
  587.   if(reg)then
  588.     val = toHex(decodeByte(readReg(reg)))
  589.   else
  590.     val = toHex(decodeByte(readByte(addr)))
  591.   end
  592.   return val
  593. end
  594.  
  595.  
  596. function readByteHex(loc,debug)
  597.   return toHex(string.byte(readByte(loc,debug)))
  598. end
  599. function readByteDec(loc,debug)
  600.   return toHex(string.byte(readByte(loc,debug)))
  601. end
  602.  
  603. function readDecByte(decloc)
  604.   return string.byte(readByte(loc,debug))
  605. end
  606.  
  607. function writeChar(loc,byte,debug)
  608.   if(debug == nil)then debug = false end
  609.   local locraw = loc
  610.   local offs = math.floor(tonumber(loc,16)%_BUSWIDTH)+1
  611.   local absoluteloc = tonumber(loc,16) - math.floor(tonumber(loc,16)%_BUSWIDTH)
  612.   local loc  = math.floor(tonumber(loc,16)/_BUSWIDTH)+1
  613.   local byteloc = _G.ASM.ram[loc]
  614.   if(debug)then print(absoluteloc .. ":" .. offs .. " = " .. byte) end
  615.   byteloc = byteloc:sub(1,offs-1) .. byte .. byteloc:sub(offs+1,#byteloc)
  616.   _G.ASM.ram[loc] = byteloc
  617.   refreshScreen(locraw)
  618.   if(debug)then print(absoluteloc .. " = " .. byteloc) end
  619. end
  620.  
  621.  
  622. -- Screen memory/rendering
  623.   function valueCheck(val)
  624.     if(type(val) == "string")then val = tonumber(val,16) end
  625.     return val
  626.   end
  627.  
  628.  
  629. function refreshScreen(mem)
  630.   local scr_start = 512
  631.   local scr_end   = 2448
  632.   if( _G.ASM.pmode == 2 )then
  633.     mem = (valueCheck(mem))
  634.     if(mem >= scr_start and mem <= scr_end)then
  635.       drawScreenAt(toHex(mem))
  636.     end
  637.   end
  638. end
  639.  
  640.  
  641. function drawScreenAt(addr,debug)
  642.     if( _G.ASM.pmode ~= 2)then return nil end
  643.     if(debug == nil)then debug = false end
  644.     local scr_start = tonumber("0200",16)
  645.     local scr_width = 51
  646.     local scr_end   = tonumber("0990",16)
  647.     local addr = tonumber(addr,16)
  648.     local iscolor = false
  649.     local ischar  = false
  650.     if(addr < scr_start or addr > scr_end)then
  651.         return nil
  652.     end
  653.     -- Determine screen type at memory
  654.     if(addr%2 == 0)then
  655.         iscolor = true
  656.     else
  657.         ischar  = true
  658.     end
  659.     -- Decode cursor position
  660.     -- As Address is always larger then or equal to screen start
  661.     local ypos = math.floor(((addr - scr_start)/2)/scr_width)+1
  662.     local xpos = 0
  663.     if(ischar)then
  664.         xpos = math.ceil(((addr - scr_start)/2)-((ypos-1)*51))
  665.     elseif(iscolor)then
  666.         xpos = math.ceil((((addr+1) - scr_start)/2)-((ypos-1)*51))
  667.     end
  668.     if(debug)then
  669.         print("Color: " .. tostring(iscolor))
  670.         print("Text : " .. tostring(ischar))
  671.         print("X: " .. xpos)
  672.         print("Y: " .. ypos)
  673.     end
  674.     -- Decode colors
  675.     local colors = "FF"
  676.     local tcol = colors.black
  677.     local bcol = colors.black
  678.     if(iscolor)then
  679.         colors = readByteHex(toHex(addr))
  680.     elseif(ischar)then
  681.         colors = readByteHex(toHex(addr-1))
  682.     end
  683.     -- Seperatew colors get MSB, LSB
  684.     tcol = 2^tonumber(colors:sub(1,1),16)
  685.     bcol = 2^tonumber(colors:sub(2,2),16)
  686.     if(debug)then
  687.         print("Text color: " .. tcol)
  688.         print("Back color: " .. bcol)
  689.     end
  690.     -- Print char
  691.     local char = " "
  692.     if(ischar)then
  693.         char = readByte(toHex(addr))
  694.     elseif(iscolor)then
  695.         char = readByte(toHex(addr+1))
  696.     end
  697.     local ox, oy = term.getCursorPos()
  698.     term.setCursorPos(xpos, ypos)
  699.     term.setTextColor(tcol)
  700.     term.setBackgroundColor(bcol)
  701.     write(char)
  702.     term.setTextColor(1)
  703.     term.setBackgroundColor(2^15)
  704.     term.setCursorPos(ox, oy)
  705. end
  706.  
  707. function drawScreen()
  708.     if( _G.ASM.pmode ~= 2)then return nil end
  709.     local size = 969
  710.     local scr_start = tonumber("0200",16)
  711.     local scr_end   = tonumber("0990",16)
  712.     for i = 0, size*2 do
  713.         drawScreenAt(toHex(scr_start+(i+1)))
  714.     end
  715. end
  716.  
  717. -- Instruction decoding
  718. function runOpperation(op,type,val,debug,noexe)
  719.   -- Get Hex code first
  720.   local diss = ""
  721.   if(op == nil)then return false end
  722.   if(debug == nil)then debug = false end -- OCD precaution :P
  723.   if(noexe == nil)then noexe = false end -- OCD precaution :P
  724.   if(_G.ASM._HEXENCODE[op] == nil)then error("Invalid instruction: " .. op) end
  725.   if(_G.ASM._HEXENCODE[op][type] == nil)then error("Invalid type for: " .. op .. ", " .. type) end
  726.   -- Seperate arguments into Bytes
  727.   local opEncode = _G.ASM._HEXENCODE[op][type]
  728.   -- Split into bytes of 2
  729.   local bytes = {}
  730.   val = tostring(val)
  731.   if(#val > 2)then
  732.       for i=1, #val, 2 do
  733.           bytes[#bytes+1] = val:sub(i,i+1)
  734.       end
  735.   else
  736.     bytes[1] = val
  737.   end
  738.     -- If bytes passed is more than isntruction requires, error
  739.     local optimalBytes = _G.ASM._OPCODES[opEncode].bytes
  740.     if(optimalBytes > 0)then
  741.       --if(#bytes > optimalBytes)then error("Malformed instruction: " .. op .. ", " .. val) end
  742.       local i, j = 1, #bytes
  743.     while i < j do
  744.       bytes[i], bytes[j] = bytes[j], bytes[i]
  745.       i = i + 1
  746.       j = j - 1
  747.     end
  748.       for k, v in pairs(bytes) do
  749.         -- For Accumulative instructions
  750.         if(#v == 1)then v = "FF FF" end
  751.         diss = diss .. v .. " "
  752.       end
  753.     end
  754.     if(debug)then print("Dissassembly: " .. opEncode .. " " .. diss) end
  755.   if(not noexe)then
  756.     return opEncode .. " " .. diss, _G.ASM._OPCODES[opEncode]:exe(unpack(bytes))
  757.   else
  758.     return opEncode .. " " .. diss
  759.   end
  760. end
  761. function procInstructionType(op,debug,err)
  762.   -- Get instruction
  763.   -- Syntax Tabing check
  764.   if(err == nil)then err = true end
  765.   if(#op:gsub("%s+","") == 0)then
  766.     return nil
  767.   elseif(op:sub(1,1) == " " or op:sub(1,1) == "\t")then
  768.     op = op:gsub("%s+","")
  769.     op = op:sub(1,3) .. " " .. op:sub(4,#op)
  770.   end
  771.   if(debug == nil)then debug = false end -- OCD precaution :P
  772.   local instruction = string.upper(op:sub(1,3))
  773.   local args = (op:sub(5,#op)):gsub("%s+","")
  774.   local optype = "undefined"
  775.   -- Check for implicit instructions
  776.   if((#args:gsub('%s+','') == 0 or args == nil or args == "") and #op:gsub("%s+","") == 3)then
  777.     optype = "IMP"
  778.     if(debug)then print(instruction .. ":" .. optype) end
  779.     return instruction, optype, ""
  780.   end
  781.   -- Check for Accumulator instructions
  782.   if(#args == 1)then
  783.     args = string.upper(args)
  784.     if(args == "A" or args == "X" or args == "Y")then
  785.       if(args == "A")then num = "01" end
  786.       if(args == "X")then num = "02" end
  787.       if(args == "Y")then num = "03" end
  788.       optype = "ACC"
  789.       if(debug)then print(instruction .. ":" .. optype .. " ->" .. args) end
  790.       return instruction, optype, num
  791.     else
  792.       if(err)then error("Syntax Error: " .. op) else return "err" end
  793.     end
  794.   end
  795.   -- Check if Relative
  796.   if(args:sub(1,1) == "*")then
  797.     args = args:gsub("%s+","")
  798.     local sign = args:sub(2,#args):sub(1,1)
  799.     local num = signedHextoDec(args:sub(3,#args))
  800.     if(num > 127)then error("Out of bounds Error: " .. op) end
  801.     if(num < -127)then error("Out of bounds Error: " .. op) end
  802.     if(num == nil)then error("Syntax Error: " .. op) end
  803.     if(sign == "-")then
  804.       num = toHex(tonumber("FF",16) - (tonumber(toHex(math.abs(num)-1),16)))
  805.     else
  806.       num = toHex(num)
  807.     end
  808.     optype = "REL"
  809.     if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
  810.     return instruction, optype, num
  811.   end
  812.   -- Check if Alpha numeric
  813.   if(args:sub(1,1) == "#" and args:sub(2,2) == "'" )then
  814.     if(args:sub(4,4) ~= "'")then if(err)then error("Syntax Error: " .. op) else return "err" end end
  815.     local char = args:sub(3,3)
  816.     local num = toHex(string.byte(char))
  817.     args = args:sub(1,1) .. "$" .. num
  818.   end
  819.   -- Determine type of instruction
  820.   -- Check if not HEX, then convert
  821.   if(args:sub(1,1) == "#" and args:sub(2,2) ~= "$")then
  822.     local num = args:sub(2,#args)
  823.     -- If trying to zero page x or y a decimal, error
  824.     if(args:find(","))then
  825.       if(err)then error("Syntax Error: " .. op) else return "err" end
  826.     end
  827.     -- Convert num to hex
  828.     num = toHex(tonumber(num))
  829.     args = args:sub(1,1) .. "$" .. num
  830.   end
  831.   -- Check if value is an Immeditate address
  832.   if(args:sub(1,1) == "#")then
  833.     local num = args:sub(3,#args)
  834.     if(#num == 2)then -- Instruction is Immeditate
  835.       optype = "IMM"
  836.       if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
  837.       return instruction, optype, num
  838.     else
  839.       if(err)then error("Syntax Error: " .. op) else return "err" end
  840.     end
  841.   end
  842.   -- Zero Page X, Absolute XY checking
  843.   if(args:sub(1,1) == "$")then
  844.     local num = args:sub(2,#args)
  845.     -- Check for , because a Zero Page X can pass as an Absolute numerically wise.
  846.     if(not num:find(","))then
  847.       if(tonumber(num,16) == nil)then error("Syntax Error: " .. op) end
  848.       if(#num == 2)then -- Instruction is Zero Page
  849.         optype = "ZP"
  850.         if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
  851.         return instruction, optype, num
  852.       end
  853.       if(#num == 4)then -- Instruction is absolute
  854.         optype = "AB"
  855.         if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
  856.         return instruction, optype, num
  857.       end
  858.     end
  859.     -- Check for Zero Paged X
  860.     if(num:find(","))then
  861.       local nargs = {}
  862.       -- Take spaces out of string, then split it into 2 variables
  863.       local num = num:gsub("%s+", "")
  864.       -- Split string by comma
  865.       for word in string.gmatch(num, '([^,]+)') do
  866.           table.insert(nargs, word)
  867.       end
  868.       num = nargs[1]
  869.       local reg = string.upper(nargs[2])
  870.       -- If we have more than 2 variables in the string, then the user has seriously screwed up,
  871.       -- Be sure to annoy them with a noice syntax error.
  872.       if(#nargs > 2)then if(err)then error("Syntax Error: " .. op) else return "err" end end
  873.       -- Check if num is zero paged or absolute
  874.       if(#num == 2)then
  875.         -- Looks like we got a Zero Page, check for registered versions
  876.         if(string.upper(reg) == "X")then
  877.           optype = "ZPX"
  878.           if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
  879.           return instruction, optype, num
  880.         elseif(string.upper(reg) == "Y")then
  881.           optype = "ZPY"
  882.           if(debug)then print(instruction .. ":" .. optype .. " -> " .. num) end
  883.           return instruction, optype, num
  884.         end
  885.       end
  886.  
  887.       if(#num == 4)then
  888.         -- Looks like we got a Absolute, check for registered versions
  889.         if(string.upper(reg) == "X")then
  890.           optype = "ABX"
  891.           if(debug)then print(instruction .. ":" .. optype .. " -> " .. num .. ", X") end
  892.           return instruction, optype, num
  893.         elseif(string.upper(reg) == "Y")then
  894.           optype = "ABY"
  895.           if(debug)then print(instruction .. ":" .. optype .. " -> " .. num .. ", Y") end
  896.           return instruction, optype, num
  897.         else
  898.           -- Invalid register
  899.           if(err)then error("Syntax Error: " .. op) else return "err" end
  900.         end
  901.       end
  902.     else
  903.       -- Wut, we got a more than 4 digit value with no registers attached to it?!?!?, wut u smoking boi!
  904.       if(err)then error("Syntax Error: " .. op) else return "err" end
  905.     end
  906.   end
  907.  
  908.   -- Indirect checking
  909.   if(args:sub(1,1) == "(")then
  910.     -- Any multi-argument statement needs to be space checked!
  911.     local args = string.upper(args:gsub("%s+", ""))
  912.     local num = 0
  913.     -- Insert true hex number into indirect instruction
  914.     if(args:sub(2,2) ~= "$")then
  915.       num = tonumber(args:sub(3,4))
  916.       if(num == nil)then if(err)then error("Syntax Error: " .. op) else return "err" end end
  917.       num = toHex(num)
  918.       args = args:sub(1,1) .. "$" .. num .. args:sub(4,#args)
  919.     elseif(args:sub(2,2) == "#")then
  920.       -- If user is trying to pass a value as an address, NOPE 'em!
  921.       if(err)then error("Syntax Error: " .. op) else return "err" end
  922.     else
  923.       -- If hex number is passed by default set that minus its $ symbol
  924.       num = args:sub(3,4)
  925.     end
  926.     if(args:sub(5,7) == "),Y")then
  927.       -- If this is found at 5 we know, this must be a INY
  928.       optype = "INY"
  929.       if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. "), Y") end
  930.       return instruction, optype, num
  931.     end
  932.     if(args:sub(5,7) == ",X)")then
  933.       -- If this is found at 7 we know, this must be a INX
  934.       optype = "INX"
  935.       if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. ", X)") end
  936.       return instruction, optype, num
  937.     end
  938.     if(args:sub(7,7) == ")")then
  939.       if(args:sub(2,2) ~= "$")then if(err)then error("Syntax Error: " .. op) else return "err" end end
  940.       -- If this is found at 7 we know, this must be a IN
  941.       -- Get new number as 2Byte HEX
  942.       num = args:sub(3,6)
  943.       if(#num == 4)then
  944.         optype = "IN"
  945.       else
  946.         if(err)then error("Syntax Error: " .. op) else return "err" end
  947.       end
  948.  
  949.       if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. ")") end
  950.       return instruction, optype, num
  951.     end
  952.     -- Zero paged indirect
  953.     if(args:sub(5,5) == ")")then
  954.       if(args:sub(2,2) ~= "$")then if(err)then error("Syntax Error: " .. op) else return "err" end end
  955.       -- If this is found at 5 we know, this must be a IZP
  956.       -- Get new number as 2Byte HEX
  957.       num = args:sub(3,4)
  958.       if(#num == 2)then
  959.         optype = "IZP"
  960.       else
  961.         if(err)then error("Syntax Error: " .. op) else return "err" end
  962.       end
  963.       if(debug)then print(instruction .. ":" .. optype .. " -> (" .. num .. ")") end
  964.       return instruction, optype, num
  965.     end
  966.   end
  967.  
  968.   if(optype == "undefined")then
  969.     if(err)then error("Syntax Error: " .. op) else return "err" end
  970.   end
  971.  
  972. end
  973.  
  974.  
  975. --- Setting everything up
  976.  
  977. function initalize()
  978.   -- Define sizes in Bytes
  979.   _G.ASM = {}
  980.   _G.ASM.MSIZE = _KBYTE*64
  981.   _G.ASM.SSIZE = _BYTE*32
  982.   local GRAM = {}
  983.   local GREG = {}
  984.   local GSTACK = {}
  985.   -- Initialize Virtual RAM
  986.   for _RINDEX = 1, _G.ASM.MSIZE/_BUSWIDTH do
  987.       GRAM[_RINDEX] = string.rep(string.char("0"),_BUSWIDTH)
  988.   end
  989.   -- Initialize Virtual STACK
  990.   for _SINDEX = 1, _G.ASM.SSIZE/_BUSWIDTH do
  991.       GSTACK[_SINDEX] = string.rep(string.char("0"),_BUSWIDTH)
  992.   end
  993.   -- Initialize Virtual Registers
  994.   GREG['A'] = string.char("0")
  995.   GREG['X'] = string.char("0")
  996.   GREG['Y'] = string.char("0")
  997.   GREG['SP'] = string.char(tonumber("FF",16))
  998.   GREG['PC'] = string.char(tonumber("06",16)) .. string.char(tonumber("00",16))
  999.  
  1000.   _G.ASM.pmode = 1 -- Program execution mode, 1 = text, 2 = graphics
  1001.   _G.ASM.ram = GRAM
  1002.   _G.ASM.stack = GSTACK
  1003.   _G.ASM.reg = GREG
  1004.   _G.ASM.flags = string.char(tonumber("00100000",2))
  1005.   _G.ASM.flagtypes = {
  1006.     ["CRY"] = 8, -- Carry
  1007.     ["ZRO"] = 7, -- Zero Flag
  1008.     ["INT"] = 6, -- Interupt Disable
  1009.     ["DEC"] = 5, -- Decimal
  1010.     ["BRK"] = 4, -- Software interupt
  1011.     ["UNK"] = 3, -- Unknown, logical 1
  1012.     ["OVR"] = 2, -- Overflow
  1013.     ["NEG"] = 1, -- Sign
  1014.   }
  1015.   -- Instruction encoding
  1016.   _G.ASM._HEXENCODE = {
  1017.     ['LDA'] = {
  1018.       ['IZP'] = "B2",
  1019.       ['IMM'] = "A9",
  1020.       ['ZP']  = "A5",
  1021.       ['ZPX'] = "B5",
  1022.       ['AB']  = "AD",
  1023.       ['ABX'] = "BD",
  1024.       ['ABY'] = "B9",
  1025.       ['INX'] = "A1",
  1026.       ['INY'] = "B1",
  1027.     },
  1028.     ['STA'] = {
  1029.       ['IZP'] = "92",
  1030.       ['ZP']  = "85",
  1031.       ['ZPX'] = "95",
  1032.       ['AB']  = "8D",
  1033.       ['ABX'] = "9D",
  1034.       ['ABY'] = "99",
  1035.       ['INX'] = "81",
  1036.       ['INY'] = "91",
  1037.     },
  1038.     ['ADC'] = {
  1039.       ['IZP'] = "72",
  1040.       ['IMM'] = "69",
  1041.       ['ZP']  = "65",
  1042.       ['ZPX'] = "75",
  1043.       ['AB']  = "6D",
  1044.       ['ABX'] = "7D",
  1045.       ['ABY'] = "79",
  1046.       ['INX'] = "61",
  1047.       ['INY'] = "71",
  1048.     },
  1049.     ['AND'] = {
  1050.       ['IZP'] = "32",
  1051.       ['IMM'] = "29",
  1052.       ['ZP']  = "25",
  1053.       ['ZPX'] = "35",
  1054.       ['AB']  = "2D",
  1055.       ['ABX'] = "3D",
  1056.       ['ABY'] = "39",
  1057.       ['INX'] = "21",
  1058.       ['INY'] = "31",
  1059.     },
  1060.     ['ASL'] = {
  1061.       ['ACC'] = "0A",
  1062.       ['ZP']  = "06",
  1063.       ['ZPX'] = "16",
  1064.       ['AB']  = "0E",
  1065.       ['ABX'] = "1E",
  1066.     },
  1067.     ['BCC'] = {
  1068.       ['REL'] = "90",
  1069.     },
  1070.     ['BCS'] = {
  1071.       ['REL'] = "B0",
  1072.     },
  1073.     ['BEQ'] = {
  1074.       ['REL'] = "F0",
  1075.     },
  1076.     ['BIT'] = {
  1077.       ['ZP']  = "24",
  1078.       ['AB']  = "2C",
  1079.     },
  1080.     ['BMI'] = {
  1081.       ['REL'] = "30",
  1082.     },
  1083.     ['BNE'] = {
  1084.       ['REL'] = "D0",
  1085.     },
  1086.     ['BPL'] = {
  1087.       ['REL'] = "10",
  1088.     },
  1089.     ['BRK'] = {
  1090.       ['IMP'] = "00",
  1091.     },
  1092.     ['BVC'] = {
  1093.       ['REL'] = "50",
  1094.     },
  1095.     ['BVS'] = {
  1096.       ['REL'] = "70",
  1097.     },
  1098.     ['CLC'] = {
  1099.       ['IMP'] = "18",
  1100.     },
  1101.     ['CLD'] = {
  1102.       ['IMP'] = "D8",
  1103.     },
  1104.     ['CLI'] = {
  1105.       ['IMP'] = "58",
  1106.     },
  1107.     ['CLV'] = {
  1108.       ['IMP'] = "B8",
  1109.     },
  1110.     ['CMP'] = {
  1111.       ['IZP'] = "D2",
  1112.       ['IMM'] = "C9",
  1113.       ['ZP']  = "C5",
  1114.       ['ZPX'] = "D5",
  1115.       ['AB']  = "CD",
  1116.       ['ABX'] = "DD",
  1117.       ['ABY'] = "D9",
  1118.       ['INX'] = "C1",
  1119.       ['INY'] = "D1",
  1120.     },
  1121.     ['CPX'] = {
  1122.       ['IMM'] = "E0",
  1123.       ['ZP']  = "E4",
  1124.       ['AB']  = "EC",
  1125.     },
  1126.     ['CPY'] = {
  1127.       ['IMM'] = "C0",
  1128.       ['ZP']  = "C4",
  1129.       ['AB']  = "CC",
  1130.     },
  1131.     ['DEC'] = {
  1132.       ['ACC'] = "3A",
  1133.       ['ZP']  = "C6",
  1134.       ['ZPX'] = "D6",
  1135.       ['AB']  = "CE",
  1136.       ['ABX'] = "DE",
  1137.     },
  1138.     ['DEX'] = {
  1139.       ['IMP'] = "CA",
  1140.     },
  1141.     ['DEY'] = {
  1142.       ['IMP'] = "88",
  1143.     },
  1144.     ['EOR'] = {
  1145.       ['IZP'] = "52",
  1146.       ['IMM'] = "49",
  1147.       ['ZP']  = "45",
  1148.       ['ZPX'] = "55",
  1149.       ['AB']  = "4D",
  1150.       ['ABX'] = "5D",
  1151.       ['ABY'] = "59",
  1152.       ['INX'] = "41",
  1153.       ['INY'] = "51",
  1154.     },
  1155.     ['INC'] = {
  1156.       ['ACC'] = "1A",
  1157.       ['ZP']  = "E6",
  1158.       ['ZPX'] = "F6",
  1159.       ['AB']  = "EE",
  1160.       ['ABX'] = "FE",
  1161.     },
  1162.     ['INX'] = {
  1163.       ['IMP'] = "E8",
  1164.     },
  1165.     ['INY'] = {
  1166.       ['IMP'] = "C8",
  1167.     },
  1168.     ['JMP'] = {
  1169.       ['AB']  = "4C",
  1170.       ['IN']  = "6C",
  1171.     },
  1172.     ['JSR'] = {
  1173.       ['AB'] = "20",
  1174.     },
  1175.     ['LDX'] = {
  1176.       ['IMM'] = "A2",
  1177.       ['ZP']  = "A6",
  1178.       ['ZPY'] = "B6",
  1179.       ['AB']  = "AE",  
  1180.       ['ABY'] = "BE",
  1181.     },
  1182.     ['LDY'] = {
  1183.       ['IMM'] = "A0",
  1184.       ['ZP']  = "A4",
  1185.       ['ZPX'] = "B4",
  1186.       ['AB']  = "AC",  
  1187.       ['ABX'] = "BC",
  1188.     },
  1189.     ['LSR'] = {
  1190.       ['ACC'] = "4A",
  1191.       ['ZP']  = "46",
  1192.       ['ZPX'] = "56",
  1193.       ['AB']  = "4E",
  1194.       ['ABX'] = "5E",
  1195.     },
  1196.     ['NOP'] = {
  1197.       ['IMP'] = "EA",
  1198.     },
  1199.     ['ORA'] = {
  1200.       ['IZP'] = "12",
  1201.       ['IMM'] = "09",
  1202.       ['ZP']  = "05",
  1203.       ['ZPX'] = "15",
  1204.       ['AB']  = "0D",
  1205.       ['ABX'] = "1D",
  1206.       ['ABY'] = "19",
  1207.       ['INX'] = "01",
  1208.       ['INY'] = "11",
  1209.     },
  1210.     ['PHA'] = {
  1211.       ['IMP'] = "48",
  1212.     },
  1213.     ['PHP'] = {
  1214.       ['IMP'] = "08",
  1215.     },
  1216.     ['PLA'] = {
  1217.       ['IMP'] = "68",
  1218.     },
  1219.     ['PLP'] = {
  1220.       ['IMP'] = "28",
  1221.     },
  1222.     ['ROL'] = {
  1223.       ['ACC'] = "2A",
  1224.       ['ZP']  = "26",
  1225.       ['ZPX'] = "36",
  1226.       ['AB']  = "2E",
  1227.       ['ABX'] = "3E",
  1228.     },
  1229.     ['ROR'] = {
  1230.       ['ACC'] = "6A",
  1231.       ['ZP']  = "66",
  1232.       ['ZPX'] = "76",
  1233.       ['AB']  = "6E",
  1234.       ['ABX'] = "7E",
  1235.     },
  1236.     ['RTI'] = {
  1237.       ['IMP'] = "40",
  1238.     },
  1239.     ['RTS'] = {
  1240.       ['IMP'] = "60",
  1241.     },
  1242.     ['SBC'] = {
  1243.       ['IZP'] = "F2",
  1244.       ['IMM'] = "E9",
  1245.       ['ZP']  = "E5",
  1246.       ['ZPX'] = "F5",
  1247.       ['AB']  = "ED",
  1248.       ['ABX'] = "FD",
  1249.       ['ABY'] = "F9",
  1250.       ['INX'] = "E1",
  1251.       ['INY'] = "F1",
  1252.     },
  1253.     ['SEC'] = {
  1254.       ['IMP'] = "38",
  1255.     },
  1256.     ['SED'] = {
  1257.       ['IMP'] = "F8",
  1258.     },
  1259.     ['SEI'] = {
  1260.       ['IMP'] = "78",
  1261.     },
  1262.     ['STX'] = {
  1263.       ['ZP']  = "86",
  1264.       ['ZPY'] = "96",
  1265.       ['AB']  = "8E",
  1266.     },
  1267.     ['STY'] = {
  1268.       ['ZP']  = "84",
  1269.       ['ZPX'] = "94",
  1270.       ['AB']  = "8C",
  1271.     },
  1272.     ['TAX'] = {
  1273.       ['IMP'] = "AA",
  1274.     },
  1275.     ['TAY'] = {
  1276.       ['IMP'] = "A8",
  1277.     },
  1278.     ['TSX'] = {
  1279.       ['IMP'] = "BA",
  1280.     },
  1281.     ['TXA'] = {
  1282.       ['IMP'] = "8A",
  1283.     },
  1284.     ['TXS'] = {
  1285.       ['IMP'] = "9A",
  1286.     },
  1287.     ['TYA'] = {
  1288.       ['IMP'] = "98",
  1289.     },
  1290.   }
  1291.   _G.ASM._OPCODES = {
  1292.   -- Bytes = How many more bytes to read
  1293.     -- Assembler will convert values to hex
  1294.     -- TODO: REMINDER!!!
  1295.     -- ACCUMULATIVE INSTRUCTIONS: Use 01 = A, 02 = X, 03 = Y
  1296.     --]] LDA instructions
  1297.     ["B2"] = {bytes=1,exe=function(self,val)
  1298.        -- Zero paged Indirect
  1299.       loadRegIndirect("A",val)
  1300.       updateResultFlags(readRegDec("A"))
  1301.     end},-- LDA ($00)
  1302.     ['A9'] = {bytes=1,exe=function(self,val)
  1303.       -- Load a value into A
  1304.       writeReg("A",val)
  1305.       updateResultFlags(val)
  1306.     end}, -- LDA #00
  1307.     ['A5'] = {bytes=1,exe=function(self,mem)
  1308.       -- Load a value from memory into A
  1309.       writeReg("A",readByteHex(mem))
  1310.       updateResultFlags(readByteDec(mem))
  1311.     end}, -- LDA $00
  1312.     ['B5'] = {bytes=1,exe=function(self,val)
  1313.       local val =  ( tonumber(val,16) + decodeByte(readReg("X")) )
  1314.       writeReg("A",readDecByte(val))
  1315.       updateResultFlags(val)
  1316.     end}, -- LDA $00, X
  1317.     ['AD'] = {bytes=2,exe=function(self,lsb,msb)
  1318.       local val = readByteHex(msb .. lsb)
  1319.       writeReg('A',val)
  1320.       updateResultFlags(val)
  1321.     end}, -- LDA $0000
  1322.     ['BD'] = {bytes=2,exe=function(self,lsb,msb)
  1323.       local val = readAddressByte(msb..lsb,"X")
  1324.       writeReg('A', val)
  1325.       updateResultFlags(val)
  1326.     end}, -- LDA $0000, X
  1327.     ['B9'] = {bytes=2,exe=function(self,lsb,msb)
  1328.       local val = readAddressByte(msb..lsb,"Y")
  1329.       writeReg('A',val)
  1330.       updateResultFlags(val)
  1331.     end}, -- LDA $0000, Y
  1332.     ['A1'] = {bytes=1,exe=function(self,val)
  1333.       loadRegIndirect("A",val,"X")
  1334.       updateResultFlags(decodeByte(readReg("A")))
  1335.     end}, -- LDA ($00, X)
  1336.     ['B1'] = {bytes=1,exe=function(self,val)
  1337.       loadRegIndirect("A",val,"Y")
  1338.       updateResultFlags(decodeByte(readReg("A")))
  1339.     end}, -- LDA ($00), Y
  1340.   --]] STA instructions
  1341.     ['92'] = {bytes=1,exe=function(self,val)
  1342.       storeRegIndirect("A",val)
  1343.     end}, -- STA ($00)
  1344.     ['85'] = {bytes=1,exe=function(self,val) writeByteDec(val,readRegDec("A")) end}, -- STA $00  
  1345.     ['95'] = {bytes=1,exe=function(self,val)
  1346.       local val = (tonumber(val,16) + decodeByte(readReg("X")))
  1347.       writeDecByte(val,readRegDec("A"))
  1348.     end}, -- STA $00, X
  1349.     ['8D'] = {bytes=2,exe=function(self,lsb,msb) writeByteDec(msb .. lsb,readRegDec("A")) end}, -- STA $0000
  1350.     ['9D'] = {bytes=2,exe=function(self,lsb,msb)
  1351.       local val = msb .. lsb
  1352.       local val = (tonumber(val,16) + decodeByte(readReg("X")))
  1353.       writeDecByte(val,readRegDec("A"))
  1354.     end}, -- STA $0000, X
  1355.     ['99'] = {bytes=2,exe=function(self,lsb,msb)
  1356.       local val = msb .. lsb
  1357.       local val = (tonumber(val,16) + decodeByte(readReg("Y")))
  1358.       writeDecByte(val,readRegDec("A"))
  1359.     end}, -- STA $0000, Y
  1360.     ['81'] = {bytes=1,exe=function(self,val)
  1361.       storeRegIndirect("A",val,"X")
  1362.      end}, -- STA ($00, X)
  1363.     ['91'] = {bytes=1,exe=function(self,val)
  1364.       storeRegIndirect("A",val,"Y")
  1365.     end}, -- STA ($00), Y
  1366.   -- ADC (Add with carry) Adds to A
  1367.     ['72'] = {bytes=1,exe=function(self,val)
  1368.       local num = signedAdd(readRegHex("A"),readByteHex(readIndirectByte(val)))
  1369.       writeReg("A",num)
  1370.       updateResultFlags(decodeByte(readReg("A")))
  1371.     end}, -- ADC ($00)
  1372.     ['69'] = {bytes=1,exe=function(self,val)  
  1373.       local num = signedAdd(readRegHex("A"), val)
  1374.       writeReg("A",num)
  1375.       updateResultFlags(decodeByte(readReg("A")))
  1376.     end},-- ADC #00
  1377.     ['65'] = {bytes=1,exe=function(self,val)
  1378.       local num = signedAdd(readRegHex("A"), readByteHex(val) )
  1379.       writeReg("A",num)
  1380.       updateResultFlags(decodeByte(readReg("A")))
  1381.     end},-- ADC $00
  1382.     ['75'] = {bytes=1,exe=function(self,val)  
  1383.       local num = signedAdd(readRegHex("A"),readAddressByte(val,"X"))
  1384.       writeReg("A",num)
  1385.       updateResultFlags(decodeByte(readReg("A")))
  1386.     end},-- ADC $00, X
  1387.     ['6D'] = {bytes=2,exe=function(self,lsb,msb)  
  1388.       local num = signedAdd(readRegHex("A"), readByteHex(msb..lsb))
  1389.       writeReg("A",num)
  1390.       updateResultFlags(decodeByte(readReg("A")))
  1391.     end},-- ADC $0000
  1392.     ['7D'] = {bytes=2,exe=function(self,lsb,msb)  
  1393.       local num = signedAdd(readRegHex("A"),readAddressByte(msb..lsb,"X"))
  1394.       writeReg("A",num)
  1395.       updateResultFlags(decodeByte(readReg("A")))
  1396.     end},-- ADC $0000, X
  1397.     ['79'] = {bytes=2,exe=function(self,lsb,msb)  
  1398.       local num = signedAdd(readRegHex("A"),readAddressByte(msb..lsb,"Y"))
  1399.       writeReg("A",num)
  1400.       updateResultFlags(decodeByte(readReg("A")))
  1401.     end},-- ADC $0000, Y
  1402.     ['61'] = {bytes=1,exe=function(self,val)  
  1403.       local num = signedAdd(readRegHex("A"),readByteHex(readIndirectByte(val,"X")))
  1404.       writeReg("A",num)
  1405.       updateResultFlags(decodeByte(readReg("A")))
  1406.     end},-- ADC ($00, X)
  1407.     ['71'] = {bytes=1,exe=function(self,val)
  1408.       local num = signedAdd(readRegHex("A"),readByteHex(readIndirectByte(val,"Y")))
  1409.       writeReg("A",num)
  1410.       updateResultFlags(decodeByte(readReg("A")))
  1411.     end},-- ADC ($00), Y
  1412.   -- AND  (Logical And)
  1413.     ['32'] = {bytes=1,exe=function(self,val)  
  1414.        local num = bit.band(decodeByte(readReg("A")), tonumber( readByteHex(readIndirectByte(val)), 16) )
  1415.        updateResultFlags(num)
  1416.        writeRegDec("A",num)
  1417.     end}, -- AND ($00)
  1418.     ['29'] = {bytes=1,exe=function(self,val)
  1419.        local num = bit.band(decodeByte(readReg("A")), tonumber(val,16))
  1420.        updateResultFlags(num)
  1421.        writeRegDec("A",num)
  1422.     end},-- AND #00
  1423.     ['25'] = {bytes=1,exe=function(self,val)  
  1424.       local num = bit.band(decodeByte(readReg("A")), decodeByte(readByte(val)))
  1425.        updateResultFlags(num)
  1426.        writeRegDec("A",num)
  1427.     end},-- AND $00
  1428.     ['35'] = {bytes=1,exe=function(self,val)  
  1429.        local num = bit.band(decodeByte(readReg("A")), tonumber(readAddressByte(val,"X"),16) )
  1430.        updateResultFlags(num)
  1431.        writeRegDec("A",num)
  1432.     end},-- AND $00, X
  1433.     ['2D'] = {bytes=2,exe=function(self,lsb,msb)  
  1434.       local num = bit.band(decodeByte(readReg("A")), decodeByte(readByte(msb..lsb)))
  1435.        updateResultFlags(num)
  1436.        writeRegDec("A",num)
  1437.     end},-- AND $0000
  1438.     ['3D'] = {bytes=2,exe=function(self,lsb,msb)  
  1439.        local num = bit.band(decodeByte(readReg("A")), tonumber(readAddressByte(msb..lsb,"X"),16) )
  1440.        updateResultFlags(num)
  1441.        writeRegDec("A",num)
  1442.     end},-- AND $0000, X
  1443.     ['39'] = {bytes=2,exe=function(self,lsb,msb)  
  1444.        local num = bit.band(decodeByte(readReg("A")), tonumber(readAddressByte(msb..lsb,"Y"),16) )
  1445.        updateResultFlags(num)
  1446.        writeRegDec("A",num)
  1447.     end},-- AND $0000, Y
  1448.     ['21'] = {bytes=1,exe=function(self,val)
  1449.        local num = bit.band(decodeByte(readReg("A")), tonumber( readByteHex(readIndirectByte(val,"X")), 16) )
  1450.        updateResultFlags(num)
  1451.        writeRegDec("A",num)
  1452.     end},-- AND ($00, X)
  1453.     ['31'] = {bytes=1,exe=function(self,val)  
  1454.        local num = bit.band(decodeByte(readReg("A")), tonumber( readByteHex(readIndirectByte(val,"Y"))),16)
  1455.        updateResultFlags(num)
  1456.        writeRegDec("A",num)
  1457.     end},-- AND ($00), Y
  1458.   -- ASL  (Arithmetic Shift Left)
  1459.     ['0A'] = {bytes=1,exe=function(self,val)
  1460.        if(val == "01")then val = "A" end
  1461.        if(val == "02")then val = "X" end
  1462.        if(val == "03")then val = "Y" end
  1463.        local num = bit.blshift(decodeByte(readReg(val)), 1)
  1464.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1465.        updateResultFlags(num)
  1466.        if(num > 255)then num = 255 setFlag("NEG",0) end
  1467.        writeRegDec(val,num)
  1468.     end},-- ASL A/X/Y
  1469.     ['06'] = {bytes=1,exe=function(self,val)  
  1470.        local num = bit.blshift(decodeByte(readByte(val)), 1)
  1471.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1472.        updateResultFlags((num))
  1473.        if(num > 255)then num = 255 setFlag("NEG",0) end
  1474.        writeByteDec(val,num)
  1475.     end},-- ASL $00
  1476.     ['16'] = {bytes=1,exe=function(self,val)  
  1477.        local num = bit.blshift(tonumber(readAddressByte(val,"X"),16), 1)
  1478.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1479.        updateResultFlags((num))
  1480.        if(num > 255)then num = 255 setFlag("NEG",0) end
  1481.        writeByteDec(addHex(val,readRegHex("X")),num)
  1482.     end},-- ADC $00, X
  1483.     ['0E'] = {bytes=2,exe=function(self,lsb,msb)  
  1484.        local num = bit.blshift(decodeByte(readByte(msb..lsb)), 1)
  1485.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1486.        updateResultFlags((num))
  1487.        if(num > 255)then num = 255 setFlag("NEG",0) end
  1488.        writeByteDec(msb..lsb,num)
  1489.     end},-- ADC $0000
  1490.     ['1E'] = {bytes=2,exe=function(self,lsb,msb)  
  1491.        local num = bit.blshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
  1492.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1493.        updateResultFlags((num))
  1494.        if(num > 255)then num = 255 setFlag("NEG",0) end
  1495.        writeByteDec(addHex(msb..lsb,readRegHex("Y")),num)
  1496.     end},-- ADC $0000, X
  1497.   -- BCC   (Branch if Carry Clear)
  1498.     ['90'] = {bytes=1,exe=function(self,val)  
  1499.       local num = signedHextoDec(val)
  1500.       if(getFlag("CRY") == "0")then movePC(num) end
  1501.     end},-- BCC *+val
  1502.   -- BCS   (Branch if Carry Set)
  1503.     ['B0'] = {bytes=1,exe=function(self,val)  
  1504.       local num = signedHextoDec(val)
  1505.       if(getFlag("CRY") == "1")then movePC(num) end
  1506.     end},-- BCS *+val
  1507.   -- BEQ   (Branch if Equal)
  1508.     ['F0'] = {bytes=1,exe=function(self,val)  
  1509.       local num = signedHextoDec(val)
  1510.       if(getFlag("ZRO") == "1")then movePC(num) end
  1511.     end},-- BCS *+val
  1512.   -- BIT  (Bit Test)
  1513.     ['24'] = {bytes=1,exe=function(self,val)  
  1514.       local num = bit.band(decodeByte(readReg("A")), decodeByte(readByte(val)))
  1515.       if(toBin(num):sub(2,2))then setFlag("OVR",1) end
  1516.       updateResultFlags(num)
  1517.     end},-- BIT $00
  1518.     ['2C'] = {bytes=2,exe=function(self,val)  
  1519.     end},-- BIT $0000
  1520.   -- BMI  (Branch if Minus)
  1521.     ['30'] = {bytes=1,exe=function(self,val)  
  1522.       local num = signedHextoDec(val)
  1523.       if(getFlag("NEG") == "1")then movePC(num) end
  1524.     end},-- BMI *+val
  1525.   -- BNE  (Branch if Not Equal)
  1526.     ['D0'] = {bytes=1,exe=function(self,val)  
  1527.       local num = signedHextoDec(val)
  1528.  
  1529.       if(getFlag("ZRO") == "0")then movePC(num) end
  1530.     end},-- BNE *+val
  1531.   -- BPL  (Branch if Positive)
  1532.     ['10'] = {bytes=1,exe=function(self,val)  
  1533.       local num = signedHextoDec(val)
  1534.       if(getFlag("NEG") == "0")then movePC(num) end
  1535.     end},-- BPL *+val
  1536.   -- BRK  (Force Interrupt)
  1537.     ['00'] = {bytes=0,exe=function(self)  
  1538.       pushStack(toHex(decodeByte(getFlagsByte())))
  1539.       local pc = "0" .. tostring(tonumber(readPC(),16)+1)
  1540.       pushStack(tostring(readPC()):sub(1,2))
  1541.       pushStack(tostring(readPC()):sub(3,4))
  1542.       -- Push status to stack, stop program wait for re-run program executor will check for interupt flag and pull from stacks and resume program
  1543.       setFlag("BRK",1)
  1544.     end},-- BRK
  1545.   -- BVC  (Branch if Overflow Clear)
  1546.     ['50'] = {bytes=1,exe=function(self,val)  
  1547.       local num = signedHextoDec(val)
  1548.       if(getFlag("OVR") == "0")then movePC(num) end
  1549.     end},-- BVC *+val
  1550.   -- BVS  (Branch if Overflow Set)
  1551.     ['70'] = {bytes=1,exe=function(self,val)  
  1552.       local num = signedHextoDec(val)
  1553.       if(getFlag("OVR") == "1")then movePC(num) end
  1554.     end},-- BVC *+val
  1555.   -- CLC  (Clear Carry Flag)
  1556.     ['18'] = {bytes=0,exe=function(self,val)  
  1557.       setFlag("CRY",0)
  1558.     end},-- CLC
  1559.   -- CLD  (Clear Decimal Mode)
  1560.     ['D8'] = {bytes=0,exe=function(self,val)  
  1561.       setFlag("DEC",0)
  1562.     end},-- CLD
  1563.   -- CLI  (Clear Interrupt Disable)
  1564.     ['58'] = {bytes=0,exe=function(self,val)  
  1565.       setFlag("INT",0)
  1566.     end},-- CLI
  1567.   -- CLV  (Clear Overflow Flag)
  1568.     ['B8'] = {bytes=0,exe=function(self,val)  
  1569.       setFlag("OVR",0)
  1570.     end},-- CLV
  1571.   -- CMP  (Compare)
  1572.     ['D2'] = {bytes=1,exe=function(self,val)  
  1573.         local num = tonumber(readByteHex(readIndirectByte(val)),16) - decodeByte(readReg("A"))
  1574.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1575.         updateResultFlags(num)
  1576.     end}, -- CMP ($00)
  1577.     ['C9'] = {bytes=1,exe=function(self,val)  
  1578.         local num = decodeByte(readReg("A")) - tonumber(val,16)
  1579.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1580.         updateResultFlags(num)
  1581.     end},-- CMP #00
  1582.     ['C5'] = {bytes=1,exe=function(self,val)  
  1583.         local num = decodeByte(readByte(val)) - decodeByte(readReg("A"))
  1584.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1585.         updateResultFlags(num)
  1586.     end},-- CMP $00
  1587.     ['D5'] = {bytes=1,exe=function(self,val)  
  1588.         local num = tonumber(readAddressByte(val,"X"),16) - decodeByte(readReg("A"))
  1589.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1590.         updateResultFlags(num)
  1591.     end},-- CMP $00, X
  1592.     ['CD'] = {bytes=2,exe=function(self,lsb,msb)  
  1593.         local num = decodeByte(readByte(msb..lsb)) - decodeByte(readReg("A"))
  1594.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1595.         updateResultFlags(num)
  1596.     end},-- CMP $0000
  1597.     ['DD'] = {bytes=2,exe=function(self,lsb,msb)  
  1598.         local num = tonumber(readAddressByte(msb..lsb,"X"),16) - decodeByte(readReg("A"))
  1599.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1600.         updateResultFlags(num)
  1601.     end},-- CMP $0000, X
  1602.     ['D9'] = {bytes=2,exe=function(self,lsb,msb)
  1603.         local num = tonumber(readAddressByte(msb..lsb,"Y"),16) - decodeByte(readReg("A"))
  1604.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1605.         updateResultFlags(num)
  1606.     end},-- CMP $0000, Y
  1607.     ['C1'] = {bytes=1,exe=function(self,val)  
  1608.         local num = tonumber(readByteHex(readIndirectByte(val,"X")),16) - decodeByte(readReg("A"))
  1609.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1610.         updateResultFlags(num)
  1611.     end},-- CMP ($00, X)
  1612.     ['D1'] = {bytes=1,exe=function(self,val)  
  1613.         local num = tonumber(readByteHex(readIndirectByte(val,"Y")),16) - decodeByte(readReg("A"))
  1614.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1615.         updateResultFlags(num)
  1616.     end},-- CMP ($00), Y
  1617.   -- CPX  (Compare X Register)
  1618.     ['E0'] = {bytes=1,exe=function(self,val)  
  1619.         local num = tonumber(val,16) - decodeByte(readReg("X"))
  1620.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1621.         updateResultFlags(num)
  1622.     end},-- CPX #00
  1623.     ['E4'] = {bytes=1,exe=function(self,val)  
  1624.         local num = decodeByte(readByte(val)) - decodeByte(readReg("X"))
  1625.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1626.         updateResultFlags(num)
  1627.     end},-- CPX $00
  1628.     ['EC'] = {bytes=2,exe=function(self,lsb,msb)  
  1629.         local num = decodeByte(readByte(msb..lsb)) - decodeByte(readReg("X"))
  1630.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1631.         updateResultFlags(num)
  1632.     end},-- CPX $0000
  1633.   -- CPY  (Compare Y Register)
  1634.     ['C0'] = {bytes=1,exe=function(self,val)  
  1635.         local num = tonumber(val,16) - decodeByte(readReg("Y"))
  1636.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1637.         updateResultFlags(num)
  1638.     end},-- CPY #00
  1639.     ['C4'] = {bytes=1,exe=function(self,val)  
  1640.         local num = decodeByte(readByte(val)) - decodeByte(readReg("Y"))
  1641.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1642.         updateResultFlags(num)
  1643.     end},-- CPY $00
  1644.     ['CC'] = {bytes=2,exe=function(self,lsb,msb)  
  1645.         local num = decodeByte(readByte(msb..lsb)) - decodeByte(readReg("Y"))
  1646.         if(num >= 0)then setFlag("CRY",1) else setFlag("CRY",0) end -- If A >= M
  1647.         updateResultFlags(num)
  1648.     end},-- CPY $0000
  1649.   -- DEC  (Decrement Memory)
  1650.     ['3A'] = {bytes=1,exe=function(self,val)
  1651.       if(val == "01")then val = "A" end
  1652.       if(val == "02")then val = "X" end
  1653.       if(val == "03")then val = "Y" end
  1654.       local num = subHex(readRegHex(val),"01")
  1655.       writeReg(val,num)
  1656.     end}, -- INC A/X/Y
  1657.     ['C6'] = {bytes=1,exe=function(self,val)  
  1658.       local num = subSignedDec(readByteHex(val),"01")
  1659.       writeByteDec(val,num)
  1660.     end},-- DEC $00
  1661.     ['D6'] = {bytes=1,exe=function(self,val)  
  1662.       local num = subSignedDec(readAddressByte(val,"X"),"01")
  1663.       writeByteDec(addHex(val,readRegHex("X")),num)
  1664.     end},-- DEC $00, X
  1665.     ['CE'] = {bytes=2,exe=function(self,lsb,msb)  
  1666.       local num = subSignedDec(readByteHex(msb..lsb),"01")
  1667.       writeByteDec(msb..lsb,num)
  1668.     end},-- DEC $0000
  1669.     ['DE'] = {bytes=2,exe=function(self,lsb,msb)  
  1670.       local num = subSignedDec(readAddressByte(msb..lsb,"X"),"01")
  1671.       writeByteDec(addHex(msb..lsb,readRegHex("X")),num)
  1672.     end},-- DEC $0000, X
  1673.   -- DEX  (Decrement X Register)
  1674.     ['CA'] = {bytes=0,exe=function(self,val)  
  1675.       local num = subSignedDec(readRegHex('X'),"01")
  1676.       updateResultFlags(num)
  1677.       writeRegDec("X",num)
  1678.     end},-- DEX
  1679.   -- DEY  (Decrement Y Register)
  1680.     ['88'] = {bytes=0,exe=function(self,val)
  1681.       local num = subSignedDec(readRegHex('Y'),"01")
  1682.       updateResultFlags(num)
  1683.       writeRegDec("Y",num)
  1684.     end},-- DEY
  1685.   -- EOR   (Exclusive OR)
  1686.     ['52'] = {bytes=1,exe=function(self,val)  
  1687.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val)),16))
  1688.        updateResultFlags(num)
  1689.        writeRegDec("A",num)
  1690.     end}, -- EOR ($00)
  1691.     ['49'] = {bytes=1,exe=function(self,val)  
  1692.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(val,16))
  1693.        updateResultFlags(num)
  1694.        writeRegDec("A",num)
  1695.     end},-- EOR #00
  1696.     ['45'] = {bytes=1,exe=function(self,val)  
  1697.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(val),16))
  1698.        updateResultFlags(num)
  1699.        writeRegDec("A",num)
  1700.     end},-- EOR $00
  1701.     ['55'] = {bytes=1,exe=function(self,val)  
  1702.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(val,"X"),16))
  1703.        updateResultFlags(num)
  1704.        writeRegDec("A",num)
  1705.     end},-- EOR $00, X
  1706.     ['4D'] = {bytes=2,exe=function(self,lsb,msb)  
  1707.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(msb..lsb),16))
  1708.        updateResultFlags(num)
  1709.        writeRegDec("A",num)
  1710.     end},-- EOR $0000
  1711.     ['5D'] = {bytes=2,exe=function(self,lsb,msb)  
  1712.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"X"),16))
  1713.        updateResultFlags(num)
  1714.        writeRegDec("A",num)
  1715.     end},-- EOR $0000, X
  1716.     ['59'] = {bytes=2,exe=function(self,lsb,msb)  
  1717.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"Y"),16))
  1718.        updateResultFlags(num)
  1719.        writeRegDec("A",num)
  1720.     end},-- EOR $0000, Y
  1721.     ['41'] = {bytes=1,exe=function(self,val)  
  1722.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"X")),16))
  1723.        updateResultFlags(num)
  1724.        writeRegDec("A",num)
  1725.     end},-- EOR ($00, X)
  1726.     ['51'] = {bytes=1,exe=function(self,val)  
  1727.        local num = bit.bxor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"Y")),16))
  1728.        updateResultFlags(num)
  1729.        writeRegDec("A",num)
  1730.     end},-- EOR ($00), Y
  1731.   -- INC  (Increment Memory)
  1732.     ['1A'] = {bytes=1,exe=function(self,val)
  1733.       if(val == "01")then val = "A" end
  1734.       if(val == "02")then val = "X" end
  1735.       if(val == "03")then val = "Y" end
  1736.       local num = addHex(readRegHex(val),"01")
  1737.       writeReg(val,num)
  1738.     end}, -- INC A/X/Y
  1739.     ['E6'] = {bytes=1,exe=function(self,val)
  1740.       local num = addSignedDec(readByteHex(val),"01")
  1741.       writeByteDec(val,num)
  1742.     end},-- INC $00
  1743.     ['F6'] = {bytes=1,exe=function(self,val)  
  1744.       local num = addSignedDec(readAddressByte(val,"X"),"01")
  1745.       writeByteDec(addHex(val,readRegHex("X")),num)
  1746.     end},-- INC $00, X
  1747.     ['EE'] = {bytes=2,exe=function(self,lsb,msb)  
  1748.       local num = addSignedDec(readByteHex(msb..lsb),"01")
  1749.       writeByteDec(msb..lsb,num)
  1750.     end},-- INC $0000
  1751.     ['FE'] = {bytes=2,exe=function(self,val)  
  1752.       local num = addSignedDec(readAddressByte(msb..lsb,"X"),"01")
  1753.       writeByteDec(addHex(msb..lsb,readRegHex("X")),num)
  1754.     end},-- INC $0000, X
  1755.   -- INX  (Increment X Register)
  1756.     ['E8'] = {bytes=0,exe=function(self,val)  
  1757.       local num = addSignedDec(readRegHex('X'),"01")
  1758.       updateResultFlags(num)
  1759.       writeRegDec("X",num)
  1760.     end},-- INX
  1761.   -- INY  (Increment Y Register)
  1762.     ['C8'] = {bytes=0,exe=function(self,val)  
  1763.       local num = addSignedDec(readRegHex('Y'),"01")
  1764.       updateResultFlags(num)
  1765.       writeRegDec("Y",num)
  1766.     end},-- INY
  1767.   -- JMP  (Jump)
  1768.     ['4C'] = {bytes=2,exe=function(self,lsb,msb)  
  1769.       setPC(msb..lsb)
  1770.     end},-- JMP $0000
  1771.     ['6C'] = {bytes=2,exe=function(self,lsb,msb)  
  1772.       setPC(readIndirectByte(msb..lsb))
  1773.     end},-- JMP ($0000)
  1774.   -- JSR
  1775.     ['20'] = {bytes=2,exe=function(self,lsb,msb)
  1776.       pushStack(readPC():sub(1,2))
  1777.       pushStack(readPC():sub(3,4))
  1778.       setPC(msb..lsb)  
  1779.     end},-- JSR $0000
  1780.   -- LDX  (Load X Register)
  1781.     ['A2'] = {bytes=1,exe=function(self,val)  
  1782.       writeReg("X",val)
  1783.       updateResultFlags(val)
  1784.     end},-- LDX #00
  1785.     ['A6'] = {bytes=1,exe=function(self,val)
  1786.       writeReg("X",readByteHex(val))
  1787.       updateResultFlags(readByteDec(val))
  1788.     end},-- LDX $00
  1789.     ['B6'] = {bytes=1,exe=function(self,val)  
  1790.       local val =  ( tonumber(val,16) + decodeByte(readReg("Y")) )
  1791.       writeRegDec("X",val)
  1792.       updateResultFlags(val)
  1793.     end},-- LDX $00, Y
  1794.     ['AE'] = {bytes=2,exe=function(self,lsb,msb)  
  1795.       local val = readByteHex(msb .. lsb)
  1796.       writeRegDec('X',val)
  1797.       updateResultFlags(val)
  1798.     end},-- LDX $0000
  1799.     ['BE'] = {bytes=2,exe=function(self,lsb,msb)  
  1800.       local val = readAddressByte(msb..lsb,"Y")
  1801.       writeReg('X', val)
  1802.       updateResultFlags(val)
  1803.     end},-- LDX $0000, Y
  1804.   -- LDY  (Load Y Register)
  1805.     ['A0'] = {bytes=1,exe=function(self,val)  
  1806.       writeReg("Y",val)
  1807.       updateResultFlags(val)
  1808.     end},-- LDY #00
  1809.     ['A4'] = {bytes=1,exe=function(self,val)  
  1810.       writeReg("Y",readByteHex(val))
  1811.       updateResultFlags(readByteDec(val))
  1812.     end},-- LDY $00
  1813.     ['B4'] = {bytes=1,exe=function(self,val)  
  1814.       local val =  ( tonumber(val,16) + decodeByte(readReg("X")) )
  1815.       writeRegDec("Y",val)
  1816.       updateResultFlags(val)
  1817.     end},-- LDY $00, X
  1818.     ['AC'] = {bytes=2,exe=function(self,lsb,msb)
  1819.       local val = readByteHex(msb .. lsb)
  1820.       writeReg('Y',val)
  1821.       updateResultFlags(val)
  1822.     end},-- LDY $0000
  1823.     ['BC'] = {bytes=2,exe=function(self,lsb,msb)  
  1824.       local val = readAddressByte(msb..lsb,"X")
  1825.       writeReg('Y', val)
  1826.       updateResultFlags(val)
  1827.     end},-- LDY $0000, X
  1828.   -- LSR  (Logical Shift Right)
  1829.     ['4A'] = {bytes=1,exe=function(self,val)  
  1830.          if(val == "01")then val = "A" end
  1831.        if(val == "02")then val = "X" end
  1832.        if(val == "03")then val = "Y" end
  1833.        local num = bit.brshift(decodeByte(readReg(val)), 1)
  1834.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1835.        updateResultFlags(num)
  1836.        writeRegDec(val,num)
  1837.     end},-- LSR A/X/Y
  1838.     ['46'] = {bytes=1,exe=function(self,val)  
  1839.        local num = bit.brshift(decodeByte(readByte(val)), 1)
  1840.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1841.        updateResultFlags(num)
  1842.        writeByteDec(val,num)
  1843.     end},-- LSR $00
  1844.     ['56'] = {bytes=1,exe=function(self,val)
  1845.        local num = bit.brshift(tonumber(readAddressByte(val,"X"),16), 1)
  1846.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1847.        updateResultFlags(num)
  1848.        writeByteDec(val,num)  
  1849.     end},-- LSR $00, X
  1850.     ['4E'] = {bytes=2,exe=function(self,lsb,msb)
  1851.        local num = bit.brshift(decodeByte(readByte(msb..lsb)), 1)
  1852.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1853.        updateResultFlags(num)
  1854.        writeByteDec(msb..lsb,num)
  1855.     end},-- LSR $0000
  1856.     ['5E'] = {bytes=2,exe=function(self,lsb,msb)  
  1857.        local num = bit.brshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
  1858.        setFlag("CRY",tonumber(toBin(num):sub(8,8)))
  1859.        updateResultFlags(num)
  1860.        writeByteDec(msb..lsb,num)
  1861.     end},-- LSR $0000, X
  1862.   -- NOP (No Operation)
  1863.     ['EA'] = {bytes=0,exe=function(self,val)
  1864.       sleep(0) -- CC is alot faster than ur average 6502
  1865.     end},-- NOP
  1866.   -- ORA (Logical Inclusive OR)
  1867.     ['12'] = {bytes=1,exe=function(self,val)  
  1868.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val)),16))
  1869.        updateResultFlags(num)
  1870.        writeRegDec("A",num)
  1871.     end}, -- ORA ($00)
  1872.     ['09'] = {bytes=1,exe=function(self,val)  
  1873.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(val,16))
  1874.        updateResultFlags((num))
  1875.        writeRegDec("A",(num))
  1876.     end},-- ORA #00
  1877.     ['05'] = {bytes=1,exe=function(self,val)  
  1878.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(val),16))
  1879.        updateResultFlags((num))
  1880.        writeRegDec("A",(num))
  1881.     end},-- ORA $00
  1882.     ['15'] = {bytes=1,exe=function(self,val)
  1883.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(val,"X"),16))
  1884.        updateResultFlags((num))
  1885.        writeRegDec("A",(num))  
  1886.     end},-- ORA $00, X
  1887.     ['0D'] = {bytes=2,exe=function(self,lsb,msb)  
  1888.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(msb..lsb),16))
  1889.        updateResultFlags((num))
  1890.        writeRegDec("A",(num))
  1891.     end},-- ORA $0000
  1892.     ['1D'] = {bytes=2,exe=function(self,lsb,msb)
  1893.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"X"),16))
  1894.        updateResultFlags((num))
  1895.        writeRegDec("A",(num))
  1896.     end},-- ORA $0000, X
  1897.     ['19'] = {bytes=2,exe=function(self,lsb,msb)  
  1898.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readAddressByte(msb..lsb,"Y"),16))
  1899.        updateResultFlags((num))
  1900.        writeRegDec("A",(num))
  1901.     end},-- ORA $0000, Y
  1902.     ['01'] = {bytes=1,exe=function(self,val)
  1903.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"X")),16))
  1904.        updateResultFlags((num))
  1905.        writeRegDec("A",(num))
  1906.     end},-- ORA ($00, X)
  1907.     ['11'] = {bytes=1,exe=function(self,val)  
  1908.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val,"Y")),16))
  1909.        updateResultFlags((num))
  1910.        writeRegDec("A",(num))
  1911.     end},-- ORA ($00), Y
  1912.   -- PHA (Push Accumulator)
  1913.     ['48'] = {bytes=0,exe=function(self,val)
  1914.       pushStack(readRegHex("A"))
  1915.     end},-- PHA
  1916.   -- PHP (Push Processor Status)
  1917.     ['08'] = {bytes=0,exe=function(self,val)
  1918.       pushStack(toHex(decodeByte(getFlagsByte())))
  1919.     end},-- PHP
  1920.   -- PLA (Pull Accumulator)
  1921.     ['68'] = {bytes=0,exe=function(self,val)
  1922.       writeRegDec("A", decodeByte(pullStack()))
  1923.       updateResultFlags(readRegDec("A"))
  1924.     end},-- PLA
  1925.   -- PLP (Pull Processor Status)
  1926.     ['28'] = {bytes=0,exe=function(self,val)
  1927.       setAllFlags(pullStack())
  1928.     end},-- PLP
  1929.   -- ROL (Rotate Left)
  1930.     ['2A'] = {bytes=1,exe=function(self,val)  
  1931.        if(val == "01")then val = "A" end
  1932.        if(val == "02")then val = "X" end
  1933.        if(val == "03")then val = "Y" end
  1934.        setFlag("CRY",tonumber(toBin(decodeByte(readReg(val))):sub(8,8)))
  1935.        local num = bit.blshift(decodeByte(readReg(val)), 1)
  1936.        updateResultFlags(num)
  1937.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1938.        writeRegDec(val,num)
  1939.     end},-- ROL A/X/Y
  1940.     ['26'] = {bytes=1,exe=function(self,val)  
  1941.        local num = bit.blshift(decodeByte(readByte(val)), 1)
  1942.        setFlag("CRY",tonumber(toBin(decodeByte(readByte(val))):sub(8,8)))
  1943.        updateResultFlags((num))
  1944.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1945.        writeByteDec(val,(num))
  1946.     end},-- ROL $00
  1947.     ['36'] = {bytes=1,exe=function(self,val)  
  1948.        local num = bit.blshift(tonumber(readAddressByte(val,"X"),16), 1)
  1949.        setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(val,"X"),16)):sub(8,8)))
  1950.        updateResultFlags((num))
  1951.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1952.        writeByteDec(readAddressByte(val,"X"),(num))
  1953.     end},-- ROL $00, X
  1954.     ['2E'] = {bytes=2,exe=function(self,lsb,msb)  
  1955.        local num = bit.blshift(decodeByte(readByte(msb..lsb)), 1)
  1956.        setFlag("CRY",tonumber(toBin(decodeByte(readByte(msb..lsb))):sub(8,8)))
  1957.        updateResultFlags((num))
  1958.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1959.        writeByteDec(msb..lsb,(num))
  1960.     end},-- ROL $0000
  1961.     ['3E'] = {bytes=2,exe=function(self,lsb,msb)  
  1962.        local num = bit.blshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
  1963.        setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(msb..lsb,"X"),16)):sub(8,8)))
  1964.        updateResultFlags((num))
  1965.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1966.        writeByteDec(readAddressByte(msb..lsb,"X"),(num))
  1967.     end},-- ROL $0000, X
  1968.   -- ROR (Rotate Right)
  1969.     ['6A'] = {bytes=1,exe=function(self,val)  
  1970.        if(val == "01")then val = "A" end
  1971.        if(val == "02")then val = "X" end
  1972.        if(val == "03")then val = "Y" end
  1973.        setFlag("CRY",tonumber(toBin(decodeByte(readReg(val))):sub(8,8)))
  1974.        local num = bit.brshift(decodeByte(readReg(val)), 1)
  1975.        updateResultFlags((num))
  1976.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1977.        writeRegDec(val,(num))
  1978.     end},-- ROR A/X/Y
  1979.     ['66'] = {bytes=1,exe=function(self,val)  
  1980.        local num = bit.brshift(decodeByte(readByte(val)), 1)
  1981.        setFlag("CRY",tonumber(toBin(decodeByte(readByte(val))):sub(8,8)))
  1982.        updateResultFlags((num))
  1983.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1984.        writeByteDec(val,(num))
  1985.     end},-- ROR $00
  1986.     ['76'] = {bytes=1,exe=function(self,val)  
  1987.        local num = bit.brshift(tonumber(readAddressByte(val,"X"),16), 1)
  1988.        setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(val,"X"),16)):sub(8,8)))
  1989.        updateResultFlags((num))
  1990.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1991.        writeByteDec(readAddressByte(val,"X"),(num))
  1992.     end},-- ROR $00, X
  1993.     ['6E'] = {bytes=2,exe=function(self,lsb,msb)  
  1994.        local num = bit.brshift(decodeByte(readByte(msb..lsb)), 1)
  1995.        setFlag("CRY",tonumber(toBin(decodeByte(readByte(msb..lsb))):sub(8,8)))
  1996.        updateResultFlags((num))
  1997.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  1998.        writeByteDec(msb..lsb,(num))
  1999.     end},-- ROR $0000
  2000.     ['7E'] = {bytes=2,exe=function(self,lsb,msb)
  2001.        local num = bit.brshift(tonumber(readAddressByte(msb..lsb,"X"),16), 1)
  2002.        setFlag("CRY",tonumber(toBin(tonumber(readAddressByte(msb..lsb,"X"),16)):sub(8,8)))
  2003.        updateResultFlags((num))
  2004.        if(num > 255)then num = tonumber(toHex(num):sub(#toHex(num)-1,#toHex(num)),16) end
  2005.        writeByteDec(readAddressByte(msb..lsb,"X"),(num))  
  2006.     end},-- ROR $0000, X
  2007.   -- RTI (Return from Interrupt)
  2008.     ['40'] = {bytes=0,exe=function(self,val)
  2009.       local lsb = toHex(decodeByte(pullStack()))
  2010.       local msb = toHex(decodeByte(pullStack()))
  2011.       local status = pullStack()
  2012.       setAllFlags(status)
  2013.       setPC(msb..lsb)
  2014.     end},-- RTI
  2015.   -- RTS (Return from Subroutine)
  2016.     ['60'] = {bytes=0,exe=function(self,val)
  2017.       local lsb =  toHex(decodeByte(pullStack()))
  2018.       local msb =  toHex(decodeByte(pullStack()))
  2019.       setPC(msb..lsb)
  2020.     end},-- RTS
  2021.   -- SBC (Subtract with Carry)
  2022.     ['F2'] = {bytes=1,exe=function(self,val)  
  2023.        local num = bit.bor(tonumber(readRegHex("A"),16), tonumber(readByteHex(readIndirectByte(val)),16))
  2024.        updateResultFlags((num))
  2025.        writeRegDec("A",(num))
  2026.     end}, -- SBC ($00)
  2027.     ['E9'] = {bytes=1,exe=function(self,val)
  2028.       local num = signedSub(readRegHex("A"), val)
  2029.       writeReg("A",num)
  2030.       updateResultFlags(decodeByte(readReg("A")))  
  2031.     end},-- SBC #00
  2032.     ['E5'] = {bytes=1,exe=function(self,val)  
  2033.       local num = signedSub(readRegHex("A"), readByteHex(val) )
  2034.       writeReg("A",num)
  2035.       updateResultFlags(decodeByte(readReg("A")))
  2036.     end},-- SBC $00
  2037.     ['F5'] = {bytes=1,exe=function(self,val)  
  2038.       local num = signedSub(readRegHex("A"),readAddressByte(val,"X"))
  2039.       writeReg("A",num)
  2040.       updateResultFlags(decodeByte(readReg("A")))
  2041.     end},-- SBC $00, X
  2042.     ['ED'] = {bytes=2,exe=function(self,lsb,msb)  
  2043.       local num = signedSub(readRegHex("A"), readByteHex(msb..lsb))
  2044.       writeReg("A",num)
  2045.       updateResultFlags(decodeByte(readReg("A")))
  2046.     end},-- SBC $0000
  2047.     ['FD'] = {bytes=2,exe=function(self,lsb,msb)  
  2048.       local num = signedSub(readRegHex("A"),readAddressByte(msb..lsb,"X"))
  2049.       writeReg("A",num)
  2050.       updateResultFlags(decodeByte(readReg("A")))
  2051.     end},-- SBC $0000, X
  2052.     ['F9'] = {bytes=2,exe=function(self,lsb,msb)  
  2053.       local num = signedSub(readRegHex("A"),readAddressByte(msb..lsb,"Y"))
  2054.       writeReg("A",num)
  2055.       updateResultFlags(decodeByte(readReg("A")))
  2056.     end},-- SBC $0000, Y
  2057.     ['E1'] = {bytes=2,exe=function(self,val)  
  2058.       local num = signedSub(readRegHex("A"),readByteHex(readIndirectByte(val,"X")))
  2059.       writeReg("A",num)
  2060.       updateResultFlags(decodeByte(readReg("A")))
  2061.     end},-- SBC ($00, X)
  2062.     ['F1'] = {bytes=2,exe=function(self,val)
  2063.       local num = signedSub(readRegHex("A"),readByteHex(readIndirectByte(val,"Y")))
  2064.       writeReg("A",num)
  2065.       updateResultFlags(decodeByte(readReg("A")))  
  2066.     end},-- SBC ($00), Y
  2067.   -- SEC (Set Carry Flag)
  2068.     ['38'] = {bytes=0,exe=function(self,val)
  2069.       setFlag("CRY",1)
  2070.     end},-- SEC
  2071.   -- SED (Set Decimal Flag)
  2072.     ['F8'] = {bytes=0,exe=function(self,val)
  2073.       setFlag("DEC",1)
  2074.     end},-- SED
  2075.   -- SEI (Set Interrupt Disable)
  2076.     ['78'] = {bytes=0,exe=function(self,val)
  2077.       setFlag("INT",1)
  2078.     end},-- SEI
  2079.   -- STX (Store X Register)
  2080.     ['86'] = {bytes=1,exe=function(self,val)
  2081.       writeByte(val,readRegHex("X"))  
  2082.     end},-- STX $00
  2083.     ['96'] = {bytes=1,exe=function(self,val)  
  2084.       local val = toHex(tonumber(val,16) + decodeByte(readReg("Y")))
  2085.       writeByteDec(addHex(val,readRegHex("Y")),decodeByte(readReg("X")))
  2086.     end},-- STX $00, Y
  2087.     ['8E'] = {bytes=2,exe=function(self,lsb,msb)  
  2088.       writeByte(msb .. lsb,readRegHex("X"))
  2089.     end},-- STX $0000
  2090.   -- STY (Store Y Register)
  2091.     ['84'] = {bytes=1,exe=function(self,val)  
  2092.       writeByte(val,readRegHex("Y"))
  2093.     end},-- STY $00
  2094.     ['94'] = {bytes=1,exe=function(self,val)
  2095.       local val = toHex(tonumber(val,16) + decodeByte(readReg("X")))
  2096.       writeByteDec(addHex(val,readRegHex("X"),decodeByte(readReg("Y"))))  
  2097.     end},-- STY $00, X
  2098.     ['8C'] = {bytes=2,exe=function(self,lsb,msb)
  2099.       writeByte(msb .. lsb,readRegHex("Y"))
  2100.     end},-- STY $0000
  2101.   -- TAX (Transfer Accumulator to X)
  2102.     ['AA'] = {bytes=0,exe=function(self,val)
  2103.         moveRegs("A","X",true)
  2104.     end},-- TAX
  2105.   -- TAY (Transfer Accumulator to Y)
  2106.     ['A8'] = {bytes=0,exe=function(self,val)
  2107.         moveRegs("A","Y",true)
  2108.     end},-- TAX
  2109.   -- TSX (Transfer Stack Pointer to X)
  2110.     ['BA'] = {bytes=1,exe=function(self,val)
  2111.         moveRegs("SP`","X",true)
  2112.     end},-- TSX
  2113.   -- TXA (Transfer X to Accumulator)
  2114.     ['8A'] = {bytes=0,exe=function(self,val)
  2115.         moveRegs("X","A",true)
  2116.     end},-- TXA
  2117.   -- TXS (Transfer X to Stack Pointer)
  2118.     ['9A'] = {bytes=0,exe=function(self,val)
  2119.         moveRegs("X","SP",true)
  2120.     end},-- TXS
  2121.   -- TYA (Transfer Y to Accumulator)
  2122.     ['98'] = {bytes=0,exe=function(self,val)
  2123.         moveRegs("Y","A",true)
  2124.     end},-- TYA
  2125. }
  2126. end
  2127.  
  2128. function getInstuctionBytes(op,type)
  2129.   if(_G.ASM._HEXENCODE[op])then
  2130.     if(_G.ASM._OPCODES[_G.ASM._HEXENCODE[op][type]] == nil)then
  2131.       print(type)
  2132.     end
  2133.     return _G.ASM._OPCODES[_G.ASM._HEXENCODE[op][type]].bytes+1
  2134.   else
  2135.     return "err"
  2136.   end
  2137. end
  2138.  
  2139. function str_shearWord(str,word)
  2140.   local str = str:gsub("%s+","")
  2141.   return str:sub(#word+1,#str)
  2142. end
  2143.  
  2144. function AssembleHEX(code,ln)
  2145.   local op, otype, num = procInstructionType(code,false,false)
  2146.   if(op == "err")then error("Syntax error line " .. ln .. ": " .. code:gsub("%s+","")) end
  2147.   local hex = runOpperation(op,otype,num,false,true)
  2148.   return hex
  2149. end
  2150.  
  2151. function DecodeOpCodeHex(hex,args)
  2152.     for k, v in pairs(_G.ASM._HEXENCODE) do
  2153.         for kk, vv in pairs(v) do
  2154.             if(vv == hex)then
  2155.                 local format = k .. " "
  2156.                 if(kk == "IMP")then
  2157.                 elseif(kk == "IMM")then
  2158.                     format = format .. "#$" .. args[1]
  2159.                 elseif(kk == "AB")then
  2160.                     format = format .. "$" .. args[2] .. args[1]
  2161.                 elseif(kk == "ABX")then
  2162.                     format = format .. "$" .. args[2] .. args[1] .. ", X"
  2163.                 elseif(kk == "ABY")then
  2164.                     format = format .. "$" .. args[2] .. args[1] .. ", Y"
  2165.                 elseif(kk == "IN")then
  2166.                     format = format .. "($" .. args[1] .. ")"
  2167.                 elseif(kk == "INX")then
  2168.                     format = format .. "($" .. args[1] .. ", X)"
  2169.                 elseif(kk == "INY")then
  2170.                     format = format .. "($" .. args[1] .. "), Y"
  2171.                 elseif(kk == "ACC")then
  2172.                     format = format .. "$" .. args[1]
  2173.                 elseif(kk == "REL")then
  2174.                     format = format .. "$" .. args[1]
  2175.                 elseif(kk == "ZP")then
  2176.                     format = format .. "$" .. args[1]
  2177.                 end
  2178.                 return format
  2179.             end
  2180.         end
  2181.     end
  2182. end
  2183.  
  2184. function disassembleASM(input)
  2185.     local code = ""
  2186.     local hex = {}
  2187.     local f = fs.open(input,"rb")
  2188.     local progstart = ""
  2189.     local counter = 1
  2190.     local index = 1
  2191.       for byte in f.read do -- Iterate over every byte in the file.
  2192.          if(index > 2)then
  2193.              hex[#hex+1] = toHex(byte)
  2194.          else
  2195.             progstart = progstart .. toHex(byte)
  2196.          end
  2197.          index = index + 1
  2198.       end
  2199.       f.close()
  2200.  
  2201.       print("Read " .. index .. " Bytes.")
  2202.       local codeindex = 1
  2203.     while codeindex < #hex do
  2204.         local args = {}
  2205.         local dump = hex[codeindex]
  2206.         local opBytes = 0
  2207.         local opperation = "???"
  2208.         if(_G.ASM._OPCODES[hex[codeindex]] ~= nil)then
  2209.             opBytes = _G.ASM._OPCODES[hex[codeindex]].bytes
  2210.             if(opBytes >= 1)then
  2211.                 for byteIndex = 1, opBytes do
  2212.                     args[#args+1] = hex[codeindex+byteIndex]
  2213.                     dump = dump .. " " .. hex[codeindex+byteIndex]
  2214.                 end
  2215.             end
  2216.             opperation = DecodeOpCodeHex(hex[codeindex],args)
  2217.         end
  2218.         -- Example:
  2219.         -- Address  Hexdump    Disassembly
  2220.         -- -------------------------------
  2221.         -- $600     A9 02 03    LDA $0302
  2222.         -- $601     A9 02       LDA $02
  2223.         -- ..............................
  2224.         local addr = toHex(tonumber(progstart,16) + codeindex-1)
  2225.  
  2226.         code = code .. "\n" .. "$" .. string.rep("0",4-#addr) .. addr .. "    " .. dump .. string.rep(" ",(8-#dump)+4) .. opperation
  2227.         codeindex = codeindex + 1
  2228.         codeindex = codeindex + opBytes
  2229.     end
  2230.     return code
  2231. end
  2232.  
  2233. function runCompiledASM(input,mode,debug)
  2234.   local step = true
  2235.   if(mode == "-s")then step = true else step = false end
  2236.   if(debug == nil)then debug = true end
  2237.   if(not fs.exists(input))then error("File doesnt exist: " .. input) end
  2238.   -- Convert Bytes to hex
  2239.   local dump = ""
  2240.   local hex = {}
  2241.   local f = fs.open(input,"rb")
  2242.   local progstart = ""
  2243.   local index = 1
  2244.   for byte in f.read do -- Iterate over every byte in the file.
  2245.      if(index > 2)then
  2246.          hex[#hex+1] = toHex(byte)
  2247.          dump = dump .. " " .. toHex(byte)
  2248.      else
  2249.         progstart = progstart .. toHex(byte)
  2250.      end
  2251.      index = index + 1
  2252.   end
  2253.   f.close()
  2254.   print("Read " .. index .. " Bytes.")
  2255.  
  2256.   -- Load Hex into program memory
  2257.   -- Make sure interupt hasnt been called, if it has dont reset the program counter.
  2258.   if(tonumber(getFlag("BRK")) == 0)then
  2259.     setPC(progstart)
  2260.   else
  2261.     print("Break detected, resuming program.")
  2262.     print("press any key. ")
  2263.     setFlag("BRK",0)
  2264.     os.pullEvent("key")
  2265.   end
  2266.   -- Insert HEX into Program memory
  2267.   for i = 1, #hex do
  2268.     writeByte(toHex( tonumber(progstart,16)+(i-1) ),hex[i])
  2269.   end
  2270.   -- With program loaded, start running through it base on the program counter index
  2271.   local line = 1
  2272.   local hexstart = tonumber(progstart,16)
  2273.   -- Run program till its hex limit is reached.
  2274.   term.clear()
  2275.   term.setCursorPos(1, 1)
  2276.   while tonumber(readPC(),16) <= hexstart+(#hex-1) do
  2277.     if(tonumber(getFlag("BRK")) == 1)then
  2278.       term.setTextColor(colors.white)
  2279.       print("\nProgram brk at PC=$" .. readPC())
  2280.       break
  2281.     end
  2282.     -- Get key inputs / generate random numbers
  2283.     os.queueEvent("ASMWait")
  2284.     local ev = {os.pullEvent()}
  2285.     if(ev[1] == "key")then writeByte("FF",toHex(tonumber(ev[2]))) end
  2286.     writeByte("FE",toHex(math.random(0,255)))
  2287.     local args = {}
  2288.     local opperation = readByteHex(readPC())
  2289.     if(_G.ASM._OPCODES[opperation] == nil)then print(opperation .. " nil?") end
  2290.     local opBytes = _G.ASM._OPCODES[opperation].bytes
  2291.     for byteIndex = 1, opBytes do
  2292.       args[#args+1] = readByteHex(toHex((tonumber(readPC(),16)+byteIndex)))
  2293.     end
  2294.     -- Run command
  2295.     if(debug and _G.ASM.pmode ~= 2)then
  2296.       term.current().setVisible(false)
  2297.       term.clear()
  2298.       term.setCursorPos(1, 1)
  2299.       print("A: " .. readRegHex("A") .. " X: ".. readRegHex("X") .. " Y: " .. readRegHex("Y") .. " SP: " .. readRegHex("SP") .. " PC: " .. readPC())
  2300.       print("NZ-BDIZC")
  2301.       print(toBin(decodeByte(getFlagsByte())))
  2302.       for i = 1, #hex do
  2303.         local found = false
  2304.         local ind = tonumber(readPC(),16) - tonumber(progstart,16)
  2305.         if( (i-1) == ind)then
  2306.           term.setTextColor(colors.orange)
  2307.           write(hex[i] .. " ")
  2308.         else
  2309.           if(opBytes > 0)then
  2310.             for x = 1, opBytes do
  2311.               if((i-1)-x == ind)then
  2312.                 term.setTextColor(colors.green)
  2313.                 write(hex[i] .. " ")
  2314.                 found = true
  2315.               end
  2316.             end
  2317.           end
  2318.           if not found then
  2319.             term.setTextColor(colors.white)
  2320.             write(hex[i] .. " ")
  2321.           end
  2322.         end
  2323.       end
  2324.     end
  2325.     term.current().setVisible(true)
  2326.     movePC(1)
  2327.     movePC(opBytes)
  2328.     _G.ASM._OPCODES[opperation]:exe(unpack(args))
  2329.     line = line + 1
  2330.     if(step)then
  2331.       if(_G.ASM.pmode ~= 2)then term.setCursorPos(1, 1) end
  2332.       term.setTextColor(colors.white)
  2333.       print("\nPress any key. ")
  2334.       os.pullEvent("key")
  2335.     end
  2336.   end
  2337.   if(tonumber(getFlag("BRK")) == 0)then
  2338.     term.setTextColor(colors.white)
  2339.     print("\nProgram end at PC=$" .. readPC())
  2340.   end
  2341. end
  2342.  
  2343. function AssembleASM(input,output,nout)
  2344.   if(nout == nil)then nout = false
  2345.   elseif(nout ~= "-y")then nout = false end
  2346.   if(nout == "-y")then nout = true end
  2347.   if(not fs.exists(input))then error("File doesnt exist: " .. input) end
  2348.   if(fs.exists(output))then error("File exists: " .. output) end
  2349.   local labels = {}
  2350.   local vars = {}
  2351.   bytearray = {}
  2352.   local keyword_var = "define"
  2353.   local keyword_label = ":"
  2354.   local keyword_begin = ".begin"
  2355.   local keyword_bytes = "dcb"
  2356.   local online = 1
  2357.   local codeline = 0
  2358.   local programstart = "0600"
  2359.   print("Reading file...")
  2360.   -- Safer to read file first, then compile as the fs hook is closed, and they is no risk of data loss.
  2361.   local source = fs.open(input,"r")
  2362.   local code = {}
  2363.   local line = source.readLine()
  2364.   while line do
  2365.     code[#code+1] = line
  2366.     line = source.readLine()
  2367.   end
  2368.   source.close()
  2369.   -- Compile Variables and labels, check for syntax errors
  2370.   print("Initializing...")
  2371.   for i = 1, #code do
  2372.     -- Handle variables
  2373.     if(code[i]:find(";"))then
  2374.       local nargs = {}
  2375.        for word in string.gmatch(code[i], '([^;]+)') do
  2376.           table.insert(nargs, word)
  2377.        end
  2378.        if(#nargs <= 1)then
  2379.         code[i] = ""
  2380.        else
  2381.         code[i] = nargs[1]
  2382.        end
  2383.     end
  2384.  
  2385.      if(code[i]:find(keyword_bytes))then
  2386.         local val = str_shearWord(code[i],keyword_bytes)
  2387.         if(code[i]:find(","))then
  2388.             for word in string.gmatch(val, '([^,]+)') do
  2389.                 word = word:gsub("%s","")
  2390.                 if(word:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2391.                 if(word:sub(2,2) == "'")then
  2392.                     if(#word:sub(3,#word-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
  2393.                     word = "$" .. toHex((string.byte(word:sub(3,#word-1))))
  2394.                 end
  2395.                 if(#word == 5)then
  2396.                     -- Divide and reverse order
  2397.                     word = "$" .. word:sub(4,5) .. word:sub(2,3)
  2398.                 end
  2399.  
  2400.                 bytearray[codeline] = word:sub(2,#word)
  2401.                 codeline = codeline + 1
  2402.             end
  2403.         else
  2404.             if(val:sub(2,2) == "'")then
  2405.                 if(#val:sub(3,#val-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
  2406.                 val = "$" .. toHex((string.byte(val:sub(3,#val-1))))
  2407.             end
  2408.             if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2409.             bytearray[codeline] = val:sub(2,#val)
  2410.             codeline = codeline + 1
  2411.         end
  2412.     end
  2413.  
  2414.     if(code[i]:find(keyword_begin))then
  2415.         local val = str_shearWord(code[i],keyword_begin)
  2416.         if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2417.         if(codeline ~= 0)then error("Syntax error line " .. online .. ": " .. code[i] .. " :>  Must be placed only at start of file.") end
  2418.         programstart = val:sub(2,#val)
  2419.     end
  2420.     if(code[i]:find(keyword_var))then
  2421.        local val = str_shearWord(code[i],keyword_var)
  2422.        local nargs = {}
  2423.        -- Take spaces out of string, then split it into 2 variables
  2424.        val = val:gsub("%s+", "")
  2425.        -- Split string by $
  2426.        for word in string.gmatch(val, '([^$]+)') do
  2427.           table.insert(nargs, word)
  2428.        end
  2429.         if(#nargs > 2)then error("Syntax error line " .. online .. ": " .. code[i]) end
  2430.         -- Convert ASCII to hex
  2431.         if(nargs[2]:sub(1,1) == "'")then
  2432.           if(nargs[2]:sub(3,3) ~= "'")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2433.           nargs[2] = toHex(string.byte(nargs[2]:sub(2,#nargs))) -- ToHex needed upon converted chars their respective byte.
  2434.           -- Using SUB because the string is split up into sections from the $ char, sub is needed to remove the ''.
  2435.         end
  2436.          -- if(_G.ASM._HEXENCODE[string.upper(nargs[1])])then error("Syntax error line " .. online .. ": " .. code[i]) end
  2437.        vars[nargs[1]] = nargs[2]
  2438.       -- print(nargs[1] .. ": " .. vars[nargs[1]])
  2439.     end
  2440.     -- Handle labels
  2441.     if(code[i]:find(keyword_label))then
  2442.       local val = code[i]:gsub("%s+","")
  2443.       local nargs = {}
  2444.        for word in string.gmatch(val, '([^:]+)') do
  2445.           table.insert(nargs, word)
  2446.        end
  2447.        if(#nargs > 1 or nargs == nil)then
  2448.          error("Syntax error line " .. online .. ": " .. code[i])
  2449.        end
  2450.        labels[nargs[1]] = codeline
  2451.       -- print(nargs[1] .. ": " .. labels[nargs[1]])
  2452.     end
  2453.     online = online + 1
  2454.     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
  2455.       codeline = codeline + 1
  2456.     end
  2457.   end
  2458.  
  2459.   -- Get Bytes Per line
  2460.   codeline = 0
  2461.   online = 1
  2462.   linebytes = {}
  2463.   local loadedbytes = false
  2464.   code_backup = code -- LUA bug where this variable acts like a pointer and still writes to code.
  2465.   print("Getting Bytes...")
  2466.   -- Process each defined byte
  2467.   for i = 1, #code_backup do
  2468.     if(code[i]:find(";"))then
  2469.       local nargs = {}
  2470.        for word in string.gmatch(code[i], '([^;]+)') do
  2471.           table.insert(nargs, word)
  2472.        end
  2473.        if(#nargs <= 1)then
  2474.         code[i] = ""
  2475.        else
  2476.         code[i] = nargs[1]
  2477.        end
  2478.     end
  2479.     -- Calculate defined bytes
  2480.      if(code_backup[i]:find(keyword_bytes))then
  2481.         local val = str_shearWord(code[i],keyword_bytes)
  2482.         if(code_backup[i]:find(","))then
  2483.             for word in string.gmatch(val, '([^,]+)') do
  2484.                 word = word:gsub("%s","")
  2485.                 if(word:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  2486.                 if(word:sub(2,2) == "'")then
  2487.                     if(#word:sub(3,#word-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  2488.                 end
  2489.                 if(#word == 5)then
  2490.                     -- Divide and reverse order
  2491.                     linebytes[#linebytes+1] = 2
  2492.                 else
  2493.                     linebytes[#linebytes+1] = 1
  2494.                 end
  2495.             end
  2496.         else
  2497.             if(val:sub(2,2) == "'")then
  2498.                 if(#val:sub(3,#val-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
  2499.                 linebytes[#linebytes+1] = 1
  2500.             else
  2501.                 linebytes[#linebytes+1] = 1
  2502.             end
  2503.             if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2504.             codeline = codeline + 1
  2505.         end
  2506.     end
  2507.  
  2508.     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
  2509.       local op  = string.upper(code_backup[i]:gsub("%s+",""):sub(1,3))
  2510.       local vtype = code_backup[i]:gsub("%s+",""):sub(4,4)
  2511.       local opperand = ""
  2512.       local prefix = ""
  2513.       local val = code_backup[i]:gsub("%s+",""):sub(4,#code_backup[i])
  2514.       if(code[i]:find(","))then
  2515.             local ends = {}
  2516.             for word in string.gmatch(code[i], '([^,]+)') do
  2517.                 table.insert(ends, word)
  2518.             end
  2519.             val = str_shearWord(ends[1],op)
  2520.             opperand = ", " .. ends[2]:gsub("%s","")
  2521.             if(code[i]:find("%("))then
  2522.                 if(string.lower(ends[2]:gsub("%s","")) == "y")then
  2523.                     opperand = ")" .. opperand
  2524.                 end
  2525.                 prefix = "("
  2526.             end
  2527.       end
  2528.       if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
  2529.       if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  2530.       if(vars[val] ~= nil)then
  2531.         if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  2532.           error("Syntax error line " .. online .. ": " .. code_backup[i])
  2533.         end
  2534.         if(vtype == "#")then
  2535.           code_backup[i] = op .. " #$" .. vars[val] .. opperand
  2536.         else
  2537.           if(not tonumber(vars[val],16))then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  2538.           code_backup[i] = op .. " $" .. vars[val] .. opperand
  2539.         end
  2540.       elseif(labels[val] ~= nil)then
  2541.         if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  2542.           code_backup[i] = op .. " *+" .. "00"
  2543.         else
  2544.           code_backup[i] = op .. " $" .. "0000" .. opperand
  2545.         end
  2546.       end
  2547.           -- Variable encoding
  2548.          val = val:gsub("[()]","")
  2549.         if(vars[val] ~= nil)then
  2550.             if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  2551.               -- No variable branching!
  2552.               error("Syntax error line " .. online .. ": " .. code_backup[i])
  2553.             end
  2554.             if(vtype == "#")then
  2555.               code[i] = op .. " " .. prefix .. "#$" .. vars[val] .. opperand
  2556.               --print(code[i])
  2557.             else
  2558.               -- Direct index
  2559.               if(not tonumber(vars[val],16))then error("Syntax error line " .. online .. ": " .. code[i]) end
  2560.               code[i] = op .. " " .. prefix .. "$" .. vars[val] .. opperand
  2561.               --print(code[i])
  2562.             end
  2563.         end
  2564.       codeline = codeline + 1
  2565.       local opr, otype, num = procInstructionType(code_backup[i],false,false)
  2566.       if(lineB == "op")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  2567.       if(otype == nil)then otype = "err" end
  2568.       print(opr .. ": " .. otype)
  2569.       local lineB = getInstuctionBytes(opr,otype)
  2570.       if(lineB == "err")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  2571.       linebytes[#linebytes+1] = lineB
  2572.       --print(#linebytes .. ": " .. lineB)
  2573.       --os.pullEvent("key")
  2574.     end
  2575.     online = online + 1
  2576.   end
  2577.   -- Compile Code substitute variables and labels, check syntax
  2578.   -- Branch labels and jump labels, are controlled based on additions to the base program start
  2579.   codeline = 0
  2580.   online = 1
  2581.   local source = fs.open(input,"r")
  2582.   local code = {}
  2583.   local line = source.readLine()
  2584.   while line do
  2585.     code[#code+1] = line
  2586.     line = source.readLine()
  2587.   end
  2588.   source.close()
  2589.   local hexdump = ""
  2590.   print("Compiling code...")
  2591.   for i = 1, #code do
  2592.     if(code[i]:find(";"))then
  2593.       local nargs = {}
  2594.        for word in string.gmatch(code[i], '([^;]+)') do
  2595.           table.insert(nargs, word)
  2596.        end
  2597.        if(#nargs <= 1)then
  2598.         code[i] = ""
  2599.        else
  2600.         code[i] = nargs[1]
  2601.        end
  2602.     end
  2603.     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
  2604.       -- Check if code references label or variable
  2605.       local op  = string.upper(code[i]:gsub("%s+",""):sub(1,3))
  2606.       local vtype = code[i]:gsub("%s+",""):sub(4,4)
  2607.       local opperand = ""
  2608.       local prefix = ""
  2609.       local val = code[i]:gsub("%s+",""):sub(4,#code[i])
  2610.       if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
  2611.       if(code[i]:find(","))then
  2612.             local ends = {}
  2613.             for word in string.gmatch(code[i], '([^,]+)') do
  2614.                 table.insert(ends, word)
  2615.             end
  2616.             val = str_shearWord(ends[1],op)
  2617.             opperand = ", " .. ends[2]:gsub("%s","")
  2618.             if(code[i]:find("%("))then
  2619.                 if(string.lower(ends[2]:gsub("%s","")) == "y")then
  2620.                     opperand = ")" .. opperand
  2621.                 end
  2622.                 prefix = "("
  2623.             end
  2624.       end
  2625.       val = val:gsub("[()]","")
  2626.       if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code[i]) end
  2627.       if(vars[val] ~= nil)then
  2628.         if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  2629.           -- No variable branching!
  2630.           error("Syntax error line " .. online .. ": " .. code[i])
  2631.         end
  2632.         if(vtype == "#")then
  2633.           code[i] = op .. " " .. prefix .. "#$" .. vars[val] .. opperand
  2634.           --print(code[i])
  2635.         else
  2636.           -- Direct index
  2637.           if(not tonumber(vars[val],16))then error("Syntax error line " .. online .. ": " .. code[i]) end
  2638.           code[i] = op .. " " .. prefix .. "$" .. vars[val] .. opperand
  2639.           --print(code[i])
  2640.         end
  2641.       elseif(labels[val] ~= nil)then
  2642.         -- Insert for relative branching
  2643.         --error("Labels do not work yet (And may never work)")
  2644.         local bytediff = 0  
  2645.         branches = {}
  2646.           for i = 1, #linebytes do
  2647.             if(i > 1)then
  2648.               branches[i] = branches[i-1] + linebytes[i]
  2649.             else
  2650.               branches[i] = linebytes[i]
  2651.             end
  2652.           end
  2653.         if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  2654.  
  2655.           -- Jump difference
  2656.           local difference = (branches[labels[val]] - branches[codeline+1])
  2657.  
  2658.           if(difference < -128 or difference > 127)then
  2659.               error("Out of range branch on line " .. online .. " (branches are limited to -128 to +127): " .. code[i] .. "(" .. difference .. ") ")
  2660.           end
  2661.  
  2662.           if(difference < 0)then
  2663.             -- Subtract the amount of bytes taken by branch
  2664.             difference = 256 + difference
  2665.           end
  2666.           difference = toHex(difference)
  2667.           -- Insert branch difference into code
  2668.           code[i] = op .. " *+" .. difference
  2669.           --print(code[i])
  2670.         else
  2671.           -- Insert for jumping
  2672.           local newBase = toHex(tonumber(programstart,16) + branches[labels[val]])
  2673.           if(#newBase < 4)then newBase = string.rep("0",4-#newBase) .. newBase end
  2674.           code[i] = op .. " $" .. newBase .. opperand
  2675.           --print(code[i])
  2676.         end
  2677.       end
  2678.       local hex = AssembleHEX(code[i],online)
  2679.       hexdump = hexdump .. hex
  2680.       codeline = codeline + 1
  2681.     end
  2682.     online = online + 1
  2683.    
  2684.     -- if DCB, replace with the raw bytes
  2685.     -- Calculate defined bytes
  2686.      if(code[i]:find(keyword_bytes))then
  2687.         local val = str_shearWord(code[i],keyword_bytes)
  2688.         local hex = ""
  2689.         local wInd = 0
  2690.         if(code[i]:find(","))then
  2691.             for word in string.gmatch(val, '([^,]+)') do
  2692.                 word = word:gsub("%s","")
  2693.                 if(word:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2694.                 if(word:sub(2,2) == "'")then
  2695.                     if(#word:sub(3,#word-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
  2696.                     word = "$" .. toHex(string.byte(word:sub(3,3)))
  2697.                 end
  2698.                 code[wInd] = word:sub(2,#word)
  2699.                 hex = word:sub(2,#word)
  2700.                 wInd = wInd +1
  2701.                 if(#hex == 4)then
  2702.                     hex = hex:sub(1,2) .. " " .. hex:sub(3,4)
  2703.                 end
  2704.                 hexdump = hexdump .. hex .. " "
  2705.                 codeline = codeline+1
  2706.             end
  2707.         else
  2708.             if(val:sub(2,2) == "'")then
  2709.                 if(#val:sub(3,#val-1) ~= 1)then error("Syntax error line " .. online .. ": " .. code[i]) end
  2710.                 val = toHex(string.byte(val:sub(3,3)))
  2711.                 code[i] = val
  2712.                 hex = val
  2713.             else
  2714.                 code[i] = val:sub(2,#val)
  2715.                 hex = val:sub(2,#val)
  2716.             end
  2717.             if(val:sub(1,1) ~= "$")then error("Syntax error line " .. online .. ": " .. code[i]) end
  2718.             if(#hex == 4)then
  2719.                 hex = hex:sub(1,2) .. " " .. hex:sub(3,4)
  2720.             end
  2721.             hexdump = hexdump .. hex .. " "
  2722.             codeline = codeline + 1
  2723.         end
  2724.     end
  2725.   end
  2726.  
  2727.   -- Compile hex to bytes
  2728.   local hexbytes = ""
  2729.   local _hexdump = hexdump
  2730.   hexdump = hexdump:gsub("%s+","")  
  2731.   if(hexdump == "")then
  2732.      print("No code to run.")
  2733.      return
  2734.   end
  2735.   if(#hexdump > 2)then
  2736.       for i=1, #hexdump, 2 do
  2737.           hexbytes = hexbytes .. string.char(tonumber(hexdump:sub(i,i+1),16))        
  2738.       end
  2739.   else
  2740.     hexbytes = string.char(tonumber(hexdump,16))
  2741.   end
  2742.   print("Hex Compiled: " .. _hexdump)
  2743.   if(nout == false)then
  2744.     local f = fs.open(output,"wb")
  2745.     for i=1, #hexdump, 2 do
  2746.         if(i == 1)then
  2747.             -- Program counter encoding.
  2748.             f.write(tonumber(programstart:sub(1,2),16))
  2749.             f.write(tonumber(programstart:sub(3,4),16))
  2750.         end
  2751.         f.write(tonumber(hexdump:sub(i, i + 1), 16))
  2752.     end
  2753.     f.close()
  2754.     print("Hex outputed to: " .. output)
  2755.     print("Done. ")
  2756.     --os.pullEvent("key")
  2757.   end
  2758. end
  2759.  
  2760. local function StartSyntaxInterpreter()
  2761.   print("Starting Syntax Interpreter (type \"exit\" to exit.)")
  2762.   local running = true
  2763.   local function getinp()
  2764.     local opperation = read()
  2765.     if(opperation == "exit")then
  2766.       if(_CCENV)then
  2767.          print("Returning to CraftOS.")
  2768.       else
  2769.          print("Returning to LUA.")
  2770.       end
  2771.       running = false
  2772.     end
  2773.     local op, type, val = procInstructionType(opperation,true)
  2774.     runOpperation(op,type,val,true)
  2775.     print("A: " .. readRegHex("A") .. " X: ".. readRegHex("X") .. " Y: " .. readRegHex("Y") .. " SP: " .. readRegHex("SP") .. " PC: " .. readPC())
  2776.     print(toBin(decodeByte(getFlagsByte())))
  2777.   end
  2778.   while running do
  2779.  
  2780.     write("Ready :> ")
  2781.     local gd, err = pcall(getinp)
  2782.     if(not ok and err and running)then print(err) end --print(err:sub(11,#err)) end
  2783.   end
  2784. end
  2785.  
  2786. if(not _G.ASM and shell)then
  2787.   print("6502: Not Initialized, press any key. ")
  2788.   os.pullEvent("key")
  2789.   initalize()
  2790.   print("Memory testing...")
  2791.   writeByte("1","0C")
  2792.   writeByte("2","0C")
  2793.   writeByte("3","0C")
  2794.   writeByte("FFFF","0C")
  2795.   print("Retrieving...")
  2796.   readByte("1",true)
  2797.   readByte("2",true)
  2798.   readByte("3",true)
  2799.   readByte("FFFF",true)
  2800.   print("Memory check successful!, re-initalizing...")
  2801.   writeByte("1","0")
  2802.   writeByte("2","0")
  2803.   writeByte("3","0")
  2804.   writeByte("FFFF","0")
  2805.   print("Memory: " .. _G.ASM.MSIZE .. "B free. \n")
  2806.   print("Ready. ")
  2807.   sleep(0.5)
  2808.   term.clear()
  2809.   term.setCursorPos(1,1)
  2810. elseif(not shell and not _G.ASM)then
  2811.     initalize()
  2812. end
  2813.  
  2814.  
  2815. -- Program Arguments Use
  2816. local progargs = { ... }
  2817. -- Arguments -i, -c, -r, interpreter, compile, run
  2818. -- If this program is not being loaded as an API
  2819. if(shell ~= nil)then
  2820.     if(#progargs == 0)then
  2821.       print("Usage: " .. shell.resolve(shell.getRunningProgram()) .. " -<mode> <args> \n")
  2822.       print("Modes -> -i, -c, -r, -rn, -m, -d")
  2823.       print("-i  Starts 6502 Interpreter. ")
  2824.       print("-c  Compiles <file>, outputs hex to <output>.")
  2825.       print("-r  Runs compiled ASM hex <file>. ")
  2826.       print("-rn Runs the <file> without exporting it.")
  2827.       print("-m  Sets run <mode>: [1 - Text] [2 - Graphics]" )
  2828.       print("-d  Exports Disassembled ASM from <source> to <output>")
  2829.     end
  2830.     if(not _CCENV)then
  2831.         local mode = io.read()
  2832.         for word in string.gmatch(mode, '([^ ]+)') do
  2833.           table.insert(progargs, word)
  2834.         end
  2835.     end
  2836.  
  2837.     if(progargs[1] == "-i")then
  2838.       StartSyntaxInterpreter()
  2839.     elseif(progargs[1] == "-c")then
  2840.       if(#progargs < 3)then error("Usage: -i <source> <output>") end
  2841.       AssembleASM(progargs[2],progargs[3],progargs[4])
  2842.     elseif(progargs[1] == "-r")then
  2843.       if(#progargs < 2)then error("Usage: -r <compiled asm>") end
  2844.       runCompiledASM(progargs[2],progargs[3],progargs[4])
  2845.     elseif(progargs[1] == "-rn")then
  2846.       if(#progargs < 2)then error("Usage: -rn <source>") end
  2847.       if(fs.exists("/.tempasm"))then fs.delete("/.tempasm") end
  2848.       AssembleASM(progargs[2],"/.tempasm",progargs[3])
  2849.     if(fs.exists("/.tempasm"))then
  2850.         runCompiledASM("/.tempasm",progargs[3],progargs[4])
  2851.     end
  2852.       fs.delete("/.tempasm")
  2853.     elseif(progargs[1] == "-m")then
  2854.        if(#progargs < 2)then error("Usage: -m <mode>") end
  2855.        local mode = tonumber(progargs[2])
  2856.        if(progargs[2] == "2")then
  2857.           print("Programs set to run in Graphics mode.")
  2858.        elseif(progargs[2] == "1")then
  2859.           print("Programs set to run in Text mode.")
  2860.        else
  2861.           print("Unknown mode: " .. progargs[2])
  2862.           mode = 1
  2863.        end
  2864.        _G.ASM.pmode = mode
  2865.     elseif(progargs[1] == "-d")then
  2866.           if(#progargs < 3)then error("Usage: -d <compiled asm> <output>") end
  2867.           if(not fs.exists(progargs[2]))then error("No such file: " .. progargs[2]) end
  2868.           local asmc = disassembleASM(progargs[2])
  2869.           local f = fs.open(progargs[3],"w")
  2870.           f.writeLine("Address  Hexdump   Dissassembly")
  2871.           f.writeLine("-------------------------------")
  2872.           f.write(asmc)
  2873.           f.close()
  2874.           print("Disassembly outputed to: " .. progargs[3])
  2875.     end
  2876. end
Add Comment
Please, Sign In to add comment