Download lua/lua6502.lua from Snapkitty/sovereign-trinity-kernel: direct link, hf CLI and curl.
- Browser
- Download file 3.75 kB
-
https://huggingface.co/Snapkitty/sovereign-trinity-kernel/resolve/main/lua/lua6502.lua
- Command line
-
hf download hf://Snapkitty/sovereign-trinity-kernel/lua/lua6502.lua
-
curl -L -o lua6502.lua https://huggingface.co/Snapkitty/sovereign-trinity-kernel/resolve/main/lua/lua6502.lua
3.75 kB
| -- lua6502.lua | |
| -- Minimal 6502 NMOS emulator for use as a Mixture-of-Agents orchestrator | |
| -- inside LuaLaTeX compilation. | |
| -- | |
| -- Memory Map: | |
| -- 0x2000 : ANU Quantum Entropy input (write before vm:execute()) | |
| -- 0x2001 : MoA multiplier output (read after vm:execute()) | |
| -- | |
| -- Authors: Ahmad Ali Parr, Jessica L. Williams (SNAPKITTYWEST) | |
| -- Part of: sovereign-trinity-kernel | |
| local vm = { | |
| PC = 0x0600, | |
| A = 0x00, | |
| X = 0x00, | |
| Y = 0x00, | |
| SP = 0xFF, | |
| P = 0x20, -- processor status (unused flag set) | |
| flags = { C = 0, Z = 0, N = 0, V = 0 }, | |
| mem = {} | |
| } | |
| function vm:reset() | |
| self.PC = 0x0600 | |
| self.A = 0x00 | |
| self.X = 0x00 | |
| self.Y = 0x00 | |
| self.SP = 0xFF | |
| self.flags = { C = 0, Z = 0, N = 0, V = 0 } | |
| end | |
| function vm:write_mem(addr, val) | |
| self.mem[addr] = val & 0xFF | |
| end | |
| function vm:read_mem(addr) | |
| return self.mem[addr] or 0x00 | |
| end | |
| function vm:load_hex(hex_str, start_addr) | |
| self:reset() | |
| self.PC = start_addr | |
| local addr = start_addr | |
| for byte in hex_str:gmatch("%S+") do | |
| self:write_mem(addr, tonumber(byte, 16)) | |
| addr = addr + 1 | |
| end | |
| end | |
| function vm:set_nz(val) | |
| self.flags.Z = (val == 0) and 1 or 0 | |
| self.flags.N = ((val & 0x80) ~= 0) and 1 or 0 | |
| end | |
| function vm:execute(max_cycles) | |
| max_cycles = max_cycles or 1000 | |
| local cycles = 0 | |
| while cycles < max_cycles do | |
| local opcode = self:read_mem(self.PC) | |
| self.PC = self.PC + 1 | |
| cycles = cycles + 1 | |
| if opcode == 0x00 then -- BRK | |
| break | |
| elseif opcode == 0xA9 then -- LDA imm | |
| self.A = self:read_mem(self.PC) | |
| self.PC = self.PC + 1 | |
| self:set_nz(self.A) | |
| elseif opcode == 0xAD then -- LDA abs | |
| local lo = self:read_mem(self.PC) | |
| local hi = self:read_mem(self.PC + 1) | |
| local addr = lo + hi * 256 | |
| self.A = self:read_mem(addr) | |
| self.PC = self.PC + 2 | |
| self:set_nz(self.A) | |
| elseif opcode == 0x8D then -- STA abs | |
| local lo = self:read_mem(self.PC) | |
| local hi = self:read_mem(self.PC + 1) | |
| local addr = lo + hi * 256 | |
| self:write_mem(addr, self.A) | |
| self.PC = self.PC + 2 | |
| elseif opcode == 0xC9 then -- CMP imm | |
| local val = self:read_mem(self.PC) | |
| self.PC = self.PC + 1 | |
| self.flags.C = (self.A >= val) and 1 or 0 | |
| self.flags.Z = (self.A == val) and 1 or 0 | |
| local result = (self.A - val) & 0xFF | |
| self.flags.N = ((result & 0x80) ~= 0) and 1 or 0 | |
| elseif opcode == 0x90 then -- BCC rel | |
| local rel = self:read_mem(self.PC) | |
| self.PC = self.PC + 1 | |
| if self.flags.C == 0 then | |
| if rel > 127 then rel = rel - 256 end | |
| self.PC = self.PC + rel | |
| end | |
| elseif opcode == 0xB0 then -- BCS rel | |
| local rel = self:read_mem(self.PC) | |
| self.PC = self.PC + 1 | |
| if self.flags.C == 1 then | |
| if rel > 127 then rel = rel - 256 end | |
| self.PC = self.PC + rel | |
| end | |
| elseif opcode == 0xEA then -- NOP | |
| -- nothing | |
| else | |
| if tex then | |
| tex.print("\\PackageWarning{lua6502}{Illegal opcode: " | |
| .. string.format("$%02X", opcode) .. " at PC=" | |
| .. string.format("$%04X", self.PC - 1) .. "}") | |
| end | |
| break | |
| end | |
| end | |
| return self:read_mem(0x2001) | |
| end | |
| return vm | |