-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path6502emu.lua
More file actions
124 lines (113 loc) · 2.89 KB
/
Copy path6502emu.lua
File metadata and controls
124 lines (113 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
local CPU = {
["PC"] = 0,
["SP"] = 0,
["IR"] = {
["A"] = 0,
["X"] = 0,
["Y"] = 0
},
["SF"] = {
["C"] = 0,
["Z"] = 0,
["I"] = 0,
["D"] = 0,
["B"] = 0,
["V"] = 0,
["N"] = 0
},
["INSTR"] = {
["INS_LDA_IM"] = 0xA9,
["INS_LDA_ZP"] = 0xA5,
["INS_LDA_ZPX"] = 0xB5,
["INS_JSR"] = 0x20,
["INS_JMPA"] = 0x4C,
["INS_JMPI"] = 0x6C,
["INS_RTS"] = 0x60
}
}
local MEM = {
["MAX_MEM"] = 1024 * 64, -- no idea why i have this here tbh, eh whatever it isnt causing trouble
["DATA"] = {}
}
function MEM.init()
MEM.DATA = {}
end
function CPU.reset(mem)
CPU.PC = 0xFFFC
CPU.SP = 0x0100
for k,v in pairs(CPU.SF) do
CPU.SF[k] = 0
end
CPU.IR["A"] = 0 CPU.IR["X"] = 0 CPU.IR["Y"] = 0
mem.init()
end
function MEM:operator(addr)
return self.DATA[addr]
end
function CPU.fetchbyte(cycle,mem)
local dta = mem.DATA[CPU.PC]
CPU.PC = CPU.PC + 1
cycle = cycle - 1
return dta
end
function CPU.fetchword(cycle,mem)
local dta1 = mem.DATA[CPU.PC]
CPU.PC = CPU.PC + 1
dta1 = bit32.bor(dta1, bit32.lshift(mem.DATA[CPU.PC], 8))
CPU.PC = CPU.PC + 1
cycle = cycle + 2
return dta1
end
function CPU.readbyte(cycle, addr, mem)
local dta = mem.DATA[addr]
cycle = cycle - 1
return dta
end
function MEM:writeword(dat, addr, cycl)
self.DATA[addr] = bit32.band(dat, 0xFF)
self.DATA[addr+1] = bit32.arshift(dat,8)
cycl = cycl - 2
end
function CPU.LDASetStatus()
if CPU.IR.A == 0 then
CPU.SF.Z = 1
end
if bit32.band(CPU.IR.A, 128) then
CPU.SF.N = 1
end
end
function CPU.exec(cycle, mem)
while cycle > 0 do
local ins = CPU.fetchbyte(cycle,mem)
if ins == CPU.INSTR.INS_LDA_IM then
local val = CPU.fetchbyte(cycle,mem)
CPU.IR.A = val
CPU.LDASetStatus()
elseif ins == CPU.INSTR.INS_LDA_ZP then
local zpa = CPU.fetchbyte(cycle,mem)
CPU.IR.A = CPU.readbyte(cycle, zpa, mem)
CPU.LDASetStatus()
elseif ins == CPU.INSTR.INS_LDA_ZPX then
local zpa = CPU.fetchbyte(cycle,mem)
zpa = zpa + CPU.IR.X
cycle = cycle - 1
CPU.IR.A = CPU.readbyte(cycle, zpa, mem)
CPU.LDASetStatus()
elseif ins == CPU.INSTR.INS_JSR then
local SubADDR = CPU.fetchword(cycle,mem)
MEM:writeword( CPU.PC-1, CPU.SP, cycle)
CPU.PC = SubADDR
cycle = cycle - 1
CPU.SP = CPU.SP + 1
elseif ins == CPU.INSTR.RTS then
-- todo, make this and the other undefined instructions
else
print("Instruction not handled "..ins)
end
end
end
CPU.reset(MEM)
MEM.DATA[0xFFFC] = CPU.INSTR.INS_LDA_ZP
MEM.DATA[0xFFFD] = 0x42
MEM.DATA[0x0042] = 0x84
CPU.exec(3,MEM)