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