Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- DO NOT REMOVE THESE LINES --
- -- Original Emulation template created by: Lewisk3 (Redxone)
- -- Original template designed for: 6502ASM (8bit)
- io.stdout:setvbuf("no")
- -- notes for branching
- -- Init mem
- _RAM = ""
- _REGS = {}
- _FLAGS = 0x20
- _ERRS = {}
- takingInput = true
- chrBuff = ""
- code = {}
- --[0xFF] = function() -- AAA AA
- --end,
- OpCodes = {
- ---------- LDA: 1 ---------------
- [0xA9] = function() -- LDA IMM
- writeReg('A', readNext())
- checkMemFlags(readReg('A'))
- stepPC(1)
- end,
- [0xA5] = function() -- LDA ZP
- writeReg('A', readByte(readNext()))
- checkMemFlags(readReg('A'))
- stepPC(1)
- end,
- [0xB5] = function() -- LDA ZPX
- writeReg('A', readByte(readNext()+readReg('X')))
- checkMemFlags(readReg('A'))
- stepPC(1)
- end,
- [0xAD] = function() -- LDA AB
- -- Take 2 next bytes concatenate them then take the data from that location.
- writeReg('A', readByte(byteConcate(readNext(1),readNext())))
- checkMemFlags(readReg('A'))
- stepPC(2)
- end,
- [0xBD] = function() -- LDA ABX
- writeReg('A', readByte( byteConcate(readNext(1),readNext())+readReg('X') ))
- checkMemFlags(readReg('A'))
- stepPC(2)
- end,
- [0xB9] = function() -- LDA ABY
- writeReg('A', readByte( byteConcate(readNext(1),readNext())+readReg('Y') ))
- checkMemFlags(readReg('A'))
- stepPC(2)
- end,
- [0xA1] = function() -- LDA INX
- writeReg('A', readIndirect(readNext(),'X'))
- checkMemFlags(readReg('A'))
- stepPC(1)
- end,
- [0xB1] = function() -- LDA INY
- writeReg('A', readIndirect(readNext(),'Y'))
- checkMemFlags(readReg('A'))
- stepPC(1)
- end,
- ---------- LDX: 2 ---------------
- [0xA2] = function() -- LDX IMM
- writeReg('X', readNext())
- checkMemFlags(readReg('X'))
- stepPC(1)
- end,
- [0xA6] = function() -- LDX ZP
- writeReg('X', readByte(readNext()))
- checkMemFlags(readReg('X'))
- stepPC(1)
- end,
- [0xB6] = function() -- LDX ZPY
- writeReg('X', readByte(readNext()+readReg('Y')))
- checkMemFlags(readReg('X'))
- stepPC(1)
- end,
- [0xAE] = function() -- LDX AB
- -- Take 2 next bytes concatenate them then take the data from that location.
- writeReg('X', readByte(byteConcate(readNext(1),readNext())))
- checkMemFlags(readReg('X'))
- stepPC(2)
- end,
- [0xBE] = function() -- LDX ABY
- writeReg('X', readByte( byteConcate(readNext(1),readNext())+readReg('Y') ))
- checkMemFlags(readReg('X'))
- stepPC(2)
- end,
- ---------- LDY: 3 ---------------
- [0xA0] = function() -- LDY IMM
- writeReg('Y', readNext())
- checkMemFlags(readReg('Y'))
- stepPC(1)
- end,
- [0xA4] = function() -- LDY ZP
- writeReg('Y', readByte(readNext()))
- checkMemFlags(readReg('Y'))
- stepPC(1)
- end,
- [0xB4] = function() -- LDY ZPX
- writeReg('Y', readByte(readNext()+readReg('X')))
- checkMemFlags(readReg('Y'))
- stepPC(1)
- end,
- [0xAC] = function() -- LDY AB
- -- Take 2 next bytes concatenate them then take the data from that location.
- writeReg('Y', readByte(byteConcate(readNext(1),readNext())))
- checkMemFlags(readReg('Y'))
- stepPC(2)
- end,
- [0xBC] = function() -- LDY ABX
- writeReg('Y', readByte( byteConcate(readNext(1),readNext())+readReg('X') ))
- checkMemFlags(readReg('Y'))
- stepPC(2)
- end,
- ---------- STA: 4 ---------------
- [0x85] = function() -- STA ZP
- -- Take A and put it on the ZP
- writeByte(readNext(),readReg('A'))
- stepPC(1)
- end,
- [0x95] = function() -- STA ZPX
- -- Take A and put it on the ZP+X
- writeByte(readNext()+readReg('X'),readReg('A'))
- stepPC(1)
- end,
- [0x8D] = function() -- STA AB
- writeByte(byteConcate(readNext(1), readNext()),readReg('A'))
- stepPC(2)
- end,
- [0x9D] = function() -- STA ABX
- writeByte(byteConcate(readNext(1), readNext())+readReg('X'),readReg('A'))
- stepPC(2)
- end,
- [0x99] = function() -- STA ABY
- writeByte(byteConcate(readNext(1), readNext())+readReg('Y'),readReg('A'))
- stepPC(2)
- end,
- [0x81] = function() -- STA INX
- writeByte(readIndirect(readNext(),'X'),readReg('A'))
- stepPC(1)
- end,
- [0x91] = function() -- STA INY
- writeByte(readIndirect(readNext(),'Y'),readReg('A'))
- stepPC(1)
- end,
- ---------- STX: 5 ---------------
- [0x86] = function() -- STX ZP
- -- Take A and put it on the ZP
- writeByte(readNext(),readReg('X'))
- stepPC(1)
- end,
- [0x96] = function() -- STX ZPY
- -- Take A and put it on the ZP+Y
- writeByte(readNext()+readReg('Y'),readReg('X'))
- stepPC(1)
- end,
- [0x8E] = function() -- STX AB
- writeByte(byteConcate(readNext(1), readNext()),readReg('X'))
- stepPC(2)
- end,
- ---------- STY: 6 --------------
- [0x84] = function() -- STY ZP
- -- Take A and put it on the ZP
- writeByte(readNext(),readReg('Y'))
- stepPC(1)
- end,
- [0x94] = function() -- STY ZPX
- -- Take A and put it on the ZP+Y
- writeByte(readNext()+readReg('X'),readReg('Y'))
- stepPC(1)
- end,
- [0x8C] = function() -- STY AB
- writeByte(byteConcate(readNext(1), readNext()),readReg('Y'))
- stepPC(2)
- end,
- ------------ TAX: 7 --------------
- [0xAA] = function() -- TAX IMP
- writeReg('X', readReg('A'))
- end,
- ------------ TAY: 8 --------------
- [0xA8] = function() -- TAX IMP
- writeReg('Y', readReg('A'))
- end,
- ------------ TXA: 9 --------------
- [0x8A] = function() -- TXA IMP
- writeReg('A', readReg('X'))
- end,
- ------------ TYA: A --------------
- [0x98] = function() -- TYA IMP
- writeReg('A', readReg('Y'))
- end,
- ------------ TSX: B --------------
- [0x9A] = function() -- TSX IMP
- writeReg('X', readReg('SP'))
- end,
- ------------ TXS: C --------------
- [0xBA] = function() -- TXS IMP
- writeReg('SP', readReg('X'))
- end,
- ------------ ADC: D --------------
- ------------ SBC: E --------------
- ------------ AND: F --------------
- ------------ ASL: 10 --------------
- ------------ BCC: 11 --------------
- ------------ BCS: 12 --------------
- ------------ BEQ: 13 --------------
- ------------ BIT: 14 --------------
- ------------ BMI: 15 --------------
- ------------ BNE: 16 --------------
- ------------ BPL: 17 --------------
- ------------ BRK: 18 --------------
- ------------ BVC: 19 --------------
- ------------ BVS: 1A --------------
- ------------ CLC: 1B --------------
- ------------ CLD: 1C --------------
- ------------ CLI: 1D --------------
- ------------ CLV: 1E --------------
- ------------ CMP: 1F --------------
- ------------ CPX: 20 --------------
- ------------ CPY: 21 --------------
- ------------ DEC: 22 --------------
- ------------ DEX: 23 --------------
- ------------ DEY: 24 --------------
- ------------ EOR: 25 --------------
- ------------ INC: 26 --------------
- ------------ INX: 27 --------------
- ------------ INY: 28 --------------
- ------------ JMP: 29 --------------
- ------------ JSR: 2A --------------
- ------------ LSR: 2B --------------
- ------------ NOP: 2C --------------
- ------------ ORA: 2D --------------
- ------------ PHA: 2E --------------
- ------------ PHP: 2F --------------
- ------------ PLA: 30 --------------
- ------------ PLP: 31 --------------
- ------------ ROL: 32 --------------
- ------------ ROR: 33 --------------
- ------------ RTI: 34 --------------
- ------------ RTS: 35 --------------
- ------------ SEC: 36 --------------
- ------------ SED: 37 --------------
- ------------ SEI: 38 --------------
- }
- local colors = {
- nes = {
- -- (https://wiki.nesdev.com/w/index.php/PPU_palettes)
- [0x00] = {84,84,84},
- [0x01] = {0,30,116},
- [0x02] = {8,16,144},
- [0x03] = {48,0,136},
- [0x04] = {68,0,100},
- [0x05] = {92,0,48},
- [0x06] = {84,4,0},
- [0x07] = {60,24,0},
- [0x08] = {32,42,0},
- [0x09] = {8,58,0},
- [0x0A] = {0,64,0},
- [0x0B] = {0,60,0},
- [0x0C] = {0,50,60},
- [0x0D] = {0,0,0},
- [0x0E] = {0,0,0},
- [0x0F] = {0,0,0},
- [0x10] = {152,150,152},
- [0x11] = {8,76,196},
- [0x12] = {48,50,236},
- [0x13] = {92,30,228},
- [0x14] = {136,20,176},
- [0x15] = {160,20,100},
- [0x16] = {152,34,32},
- [0x17] = {120,60,0},
- [0x18] = {84,90,0},
- [0x19] = {40,114,0},
- [0x1A] = {8,124,0},
- [0x1B] = {0,118,40},
- [0x1C] = {0,102,120},
- [0x1D] = {0,0,0},
- [0x1E] = {0,0,0},
- [0x1F] = {0,0,0},
- [0x20] = {236,238,236},
- [0x21] = {76,154,236},
- [0x22] = {120,124,236},
- [0x23] = {176,98,236},
- [0x24] = {228,84,236},
- [0x25] = {236,88,180},
- [0x26] = {236,106,100},
- [0x27] = {212,136,32},
- [0x28] = {160,170,0},
- [0x29] = {116,196,0},
- [0x2A] = {76,208,32},
- [0x2B] = {56,204,108},
- [0x2C] = {56,180,204},
- [0x2D] = {60,60,60},
- [0x2E] = {0,0,0},
- [0x2F] = {0,0,0},
- [0x30] = {236,238,236},
- [0x31] = {168,204,236},
- [0x32] = {188,188,236},
- [0x33] = {212,178,236},
- [0x34] = {236,174,236},
- [0x35] = {236,174,212},
- [0x36] = {236,180,176},
- [0x37] = {228,196,144},
- [0x38] = {204,210,120},
- [0x39] = {180,222,120},
- [0x3A] = {168,226,144},
- [0x3B] = {152,226,180},
- [0x3C] = {160,214,228},
- [0x3D] = {160,162,160},
- [0x3E] = {0,0,0},
- [0x3F] = {0,0,0},
- },
- }
- -- Because Love2D is freaking annoying with prints...
- function sprint(str,x,y)
- x = x or 0
- y = y or 0
- love.graphics.print(tostring(str),x,y)
- end
- function lerror(msg)
- _ERRS[#_ERRS+1] = msg
- print("Error called: " .. msg)
- end
- -- Instruction Execution
- function execute(op)
- if(op == 0x00)then
- lerror("Program ended @PC=" .. toHex(readPC()))
- end
- local func = OpCodes[op]
- -- this is data not code.
- if(func == nil)then
- lerror("No such instruction: " .. op)
- return false
- end
- func()
- return true
- end
- -- Setup functions
- function init_mem()
- -- idk why but i just like to have these :P
- local _RAMSIZE = 64*1024
- _RAM = string.rep(string.char(0x00), _RAMSIZE)
- _FLAGS = 0x00
- _REGS = {
- ['A'] = 0x00,
- ['X'] = 0x00,
- ['Y'] = 0x00,
- ['PC'] = 0x0600,
- ['SP'] = 0xFF,
- }
- print("Mem set.")
- end
- -- Memory
- function readIndirect(byte1,reg)
- -- Take the zeropaged byte and add the register
- local nib = byte1 + readReg(reg)
- -- Take 2 sections of the zeropage example: 0x00 + x = 0x01, b1 = 0x02 and b2 = 0x01.
- local b1 = readByte(nib+1)
- local b2 = readByte(nib)
- -- Take these locations and put them together for the new read addr. 0x02 = 05, 0x01 = 06
- -- Shift 06 by 8, 0600 or 05 = 0605.
- local fByte = byteConcate(b1,b2)
- print("Indirection result of: " .. byte1 .. "+" .. reg .. " :> " .. fByte)
- return fByte
- end
- function checkMemFlags(val)
- if(val == 0)then setFlag("ZR",1) else setFlag("ZR",0) end
- if(val >= 128)then
- setFlag("NEG",1)
- else
- setFlag("NEG",0)
- end
- end
- function toBin(val)
- local bits = ""
- local oval = val
- while val > 0 do
- left = val%2
- bits = left .. bits
- val = (val - left)/2
- end
- -- Now for forced 8bits!
- if(#bits < 8)then
- bits = string.rep('0',8-#bits) .. bits
- end
- -- print(oval .. " BIN " .. bits)
- return bits
- end
- function toHex(val)
- if(val < 0)then
- local num = 256 + val
- end
- if(val == 0)then
- return "00"
- end
- local oval = val
- local hex = ""
- local hexkey = "0123456789ABCDEF"
- local rim
- while val > 0 do
- rim = math.floor(val%16)
- hex = hexkey:sub(rim+1,rim+1) .. hex
- val = math.floor(val/16)
- end
- if(#hex == 1)then
- hex = "0" .. hex
- end
- --print(oval .. " HEX " .. hex)
- return hex
- end
- function readByte(ind)
- return string.byte(_RAM:sub(ind,ind))
- end
- function writeByte(ind,valByte)
- _RAM = _RAM:sub(1,ind-1) .. string.char(valByte) .. _RAM:sub(ind+1)
- print(toHex(ind) .. " :> " .. toHex(valByte))
- end
- function readReg(reg)
- return _REGS[reg]
- end
- function readPC()
- return _REGS['PC']
- end
- function byteConcate(byte1, byte2)
- print("Concating: " .. byte1 .. ", " .. byte2)
- if(byte1 <= 15)then -- Nibble value
- byte1 = bit.rshift(bit.lshift(byte1,4), 4)
- end
- if(byte2 <= 15)then -- Nibble value
- byte2 = bit.rshift(bit.lshift(byte2,4), 4)
- end
- local b1 = bit.lshift(byte1,8)
- print("Concated result: " .. bit.bor(b1,byte2))
- return bit.bor(b1,byte2)
- end
- function setPC(val2Byte)
- _REGS['PC'] = val2Byte
- end
- function stepPC(valByte)
- _REGS['PC'] = _REGS['PC'] + valByte
- end
- function readNext(by)
- by = by or 0
- return readByte(readPC()+by+1)
- end
- function writeReg(reg,valByte)
- _REGS[reg] = valByte
- end
- function setFlags(fByte)
- _FLAGS = fByte
- end
- function stringFlags()
- return toBin(_FLAGS)
- end
- function setFlag(flg,stat)
- local flgs = {
- ['CRY'] = 8,
- ['ZR'] = 7,
- ['IND'] = 6,
- ['DEC'] = 5,
- ['BRK'] = 4,
- ['NIL'] = 3,
- ['OVR'] = 2,
- ['NEG'] = 1,
- }
- ind = flgs[flg]
- stat = tostring(stat)
- local fBin = toBin(_FLAGS)
- if(fBin:sub(ind,ind) ~= stat)then
- fBin = fBin:sub(1,ind-1) .. stat .. fBin:sub(ind+1)
- end
- _FLAGS = tonumber(fBin,2)
- end
- function getFlag(flg)
- local flgs = {
- ['CRY'] = 8,
- ['ZR'] = 7,
- ['IND'] = 6,
- ['DEC'] = 5,
- ['BRK'] = 4,
- ['NIL'] = 3,
- ['OVR'] = 2,
- ['NEG'] = 1,
- }
- bFlgs = toBin(_FLAGS)
- return tonumber(bFlgs:sub(flgs[flg],flgs[flg]))
- end
- -- Math
- function checkMathFlags(val)
- if(val == 0)then
- setFlag("ZR",1)
- else
- setFlag("ZR",0)
- end
- if(val > 255)then
- val = val - 256
- setFlag("CRY",1)
- print("FLAGWARN: Result of arithmetic too large (" .. val+256 .. " < 255)")
- end
- if(val < 0)then
- val = val + 255
- setFlag("CRY",0)
- print("FLAGWARN: Result of arithmetic too small (" .. val-255 .. " > 0)")
- end
- if(val < -127)then
- setFlag("OVR",1)
- print("FLAGWARN: Arithmetic triggered signed bit (" .. val .. ")")
- elseif(val > 127)then
- setFlag("OVR",1)
- print("FLAGWARN: Arithmetic triggered signed bit (" .. val .. ")")
- else
- setFlag("OVR",0)
- end
- if(val >= 128)then
- setFlag("NEG",1)
- print("FLAGWARN: Signed arithmetic is negative (" .. val .. ")")
- else
- setFlag("NEG",0)
- end
- return val
- end
- function signedAdd(b1,b2)
- local bf = b1 + b2
- bf = checkMathFlags(bf)
- return bf
- end
- function signedSub(b1,b2)
- local bf = b1 - b2
- bf = checkMathFlags(bf)
- return bf
- end
- -- Assembly
- function compileProgram()
- end
- function interpretInstr()
- -- just going to code up a simple machine code input thingy
- end
- function getProcStatus()
- return "A: " .. toHex(readReg('A')) .. " X: " .. toHex(readReg('X')) .. " Y: " .. toHex(readReg('Y')) .. "\nPC: " ..
- toHex(readPC()) .. " SP: " .. toHex(readReg('SP')) .. "\nNV-BDIZC\n" .. toBin(_FLAGS)
- end
- function bytesToStr(bytes)
- str = ""
- for i = 1, #bytes do
- str = str .. string.char(bytes[i])
- end
- print("Bytes converted to string: " .. unpack(bytes) .. " to \"" .. str .. "\"")
- return str
- end
- function loadProgram(bytes,clr)
- -- load bytes into PC location
- clr = clr or false
- print("Loading program... ")
- if(clr)then _RAM = string.rep(string.char(0x00),64*1024) end
- for i = 1, #bytes do
- writeByte(readPC()+(i-1), string.byte(bytes:sub(i,i)))
- -- io.write(readPC()+(i-1) .. ":" .. string.byte(bytes:sub(i,i)) .. " ")
- end
- print("Program loaded.")
- end
- function executeProgram()
- while readByte(readPC()) ~= 0x00 do
- inst = execute(readNext(-1))
- if(not inst)then
- print("Unknown instruction: " .. readNext(-1))
- break
- end
- print("Executed: " .. readNext(-1))
- stepPC(1)
- end
- if(readByte(readPC()) == 0x00)then
- lerror("Program ended @PC=" .. toHex(readPC()))
- end
- setPC(0x0600)
- return true
- end
- function drawPixel(x,y,cr,cg,cb)
- love.graphics.setColor(cr,cg,cb)
- love.graphics.point(x,y)
- end
- function love.textinput(t)
- if(takingInput)then
- chrBuff = chrBuff .. t
- if(#chrBuff >= 2)then
- code[#code+1] = tonumber(chrBuff,16)
- chrBuff = ""
- end
- if(t == 'r')then
- chrBuff = ""
- -- Run machineCode
- loadProgram(bytesToStr(code) .. string.char(0x00))
- executeProgram()
- code = {}
- end
- end
- end
- function love.load()
- print("Love2D initalized.")
- end
- function love.update()
- end
- init_mem()
- loadProgram(bytesToStr({0xA9, 0x80, 0xA9, 0x32}))
- signedSub(0x01,0x02)
- signedSub(0x01,0xFF)
- executeProgram()
- function love.draw()
- if(#_ERRS > 0)then
- for i = 1, #_ERRS do
- love.graphics.setColor(colors.nes[0x06])
- love.graphics.print(_ERRS[i],0,60)
- love.graphics.setColor(colors.nes[0x30])
- end
- if(i == #_ERRS)then ERRS = {} end
- end
- sprint(getProcStatus())
- local pcode = ""
- for i = 1, #code do
- pcode = pcode .. " " .. toHex(code[i])
- end
- sprint("Code: " .. pcode:upper(),0,100)
- sprint("Inst: " .. chrBuff,0,80)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement