Advertisement
Redxone

[WIP] 6502 - Extended: Extra Run mode.

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