Advertisement
nonogamer9

Super Mario Bros 1 For OpenComputers

Jul 27th, 2024 (edited)
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 30.46 KB | Gaming | 0 0
  1. local component = require("component")
  2. local gpu = component.gpu
  3. local computer = require("computer")
  4. local filesystem = require("filesystem")
  5. local event = require("event")
  6. local keyboard = require("keyboard")
  7.  
  8. local bit = require("bit32")
  9. local band, bor, bxor, bnot, lshift, rshift = bit.band, bit.bor, bit.bxor, bit.bnot, bit.lshift, bit.rshift
  10.  
  11. -- Utility functions
  12. local function nthBitIsSet(value, n)
  13.     return band(value, lshift(1, n)) ~= 0
  14. end
  15.  
  16. local function nthBitIsSetInt(value, n)
  17.     return band(value, lshift(1, n)) ~= 0 and 1 or 0
  18. end
  19.  
  20. -- CPU Emulation
  21. local CPU = {}
  22. CPU.__index = CPU
  23.  
  24. CPU.RP2A03_CC = 12
  25. CPU.FOREVER_CLOCK = 0xffffffff
  26. CPU.CLK = {}
  27. do
  28.     local clocks = {1, 2, 3, 4, 5, 6, 7, 8}
  29.     for i = 1, #clocks do
  30.         CPU.CLK[i] = clocks[i] * CPU.RP2A03_CC
  31.     end
  32. end
  33.  
  34. CPU.RAM_SIZE = 0x0800
  35. CPU.MAINMEM_SIZE = 0x10000
  36. CPU.NMI_VECTOR = 0xfffa
  37. CPU.RESET_VECTOR = 0xfffc
  38. CPU.IRQ_VECTOR = 0xfffe
  39. CPU.IRQ_EXT = 0x01
  40. CPU.IRQ_FRAME = 0x40
  41. CPU.IRQ_DMC = 0x80
  42.  
  43. CPU.ClockRates = {
  44.     Ntsc = 1789773,
  45.     Pal = 1662607,
  46.     Dendy = 1773448
  47. }
  48.  
  49. function CPU:new(conf)
  50.     local cpu = setmetatable({}, CPU)
  51.     cpu:initialize(conf)
  52.     return cpu
  53. end
  54.  
  55. function CPU:initialize(conf)
  56.     self.conf = conf or {loglevel = 0, pc = nil}
  57.     self.ram = {}
  58.     for i = 0, CPU.RAM_SIZE - 1 do
  59.         self.ram[i] = 0
  60.     end
  61.     self._store = {}
  62.     self._fetch = {}
  63.     for i = 0, CPU.MAINMEM_SIZE - 1 do
  64.         self._store[i] = CPU.PokeNop
  65.         self._fetch[i] = CPU.peek_nop
  66.     end
  67.     self.peeks = {}
  68.     self.pokes = {}
  69.     self.clk_rate = CPU.ClockRates.Ntsc
  70.     self.clk = 0
  71.     self.clk_frame = 0
  72.     self.clk_target = 0
  73.     self.clk_total = 0
  74.     self.clk_nmi = CPU.FOREVER_CLOCK
  75.     self.clk_irq = CPU.FOREVER_CLOCK
  76.     self.irq_flags = 0
  77.     self.jammed = false
  78.     self:reset()
  79.     self.data = 0
  80.     self.addr = 0
  81.     self.opcode = nil
  82.     self.ppu_sync = nil
  83.     -- DUMMY APU
  84.     self.apu = {
  85.         clock_dma = function(clk) end,
  86.         do_clock = function() return CPU.CLK[1] end
  87.     }
  88. end
  89.  
  90. function CPU:reset()
  91.     self._a = 0
  92.     self._x = 0
  93.     self._y = 0
  94.     self._sp = 0xfd
  95.     self._pc = 0xfffc
  96.     self._p_nz = 1
  97.     self._p_c = 0
  98.     self._p_v = 0
  99.     self._p_i = 0x04
  100.     self._p_d = 0
  101.     for i = 0, CPU.RAM_SIZE - 1 do
  102.         self.ram[i] = 0xff
  103.     end
  104.     self.clk = 0
  105.     self.clk_total = 0
  106.     self:add_mappings(0x0000, 0x07ff, self.peek_ram, self.poke_ram)
  107.     self:add_mappings(0x0800, 0x1fff, self.peek_ram, self.poke_ram)
  108.     self:add_mappings(0x2000, 0xffff, self.peek_nop, CPU.PokeNop)
  109. end
  110.  
  111. function CPU:add_mappings(start_addr, end_addr, peek, poke)
  112.     for addr = start_addr, end_addr do
  113.         self._fetch[addr] = peek
  114.         self._store[addr] = poke
  115.     end
  116. end
  117.  
  118. function CPU:peek_nop(addr)
  119.     return rshift(addr, 8)
  120. end
  121.  
  122. function CPU:peek_ram(addr)
  123.     return self.ram[addr % CPU.RAM_SIZE]
  124. end
  125.  
  126. function CPU:poke_ram(addr, data)
  127.     self.ram[addr % CPU.RAM_SIZE] = data
  128. end
  129.  
  130. CPU.PokeNop = function() end
  131.  
  132. function CPU:fetch(addr)
  133.     return self._fetch[addr](self, addr)
  134. end
  135.  
  136. function CPU:store(addr, value)
  137.     return self._store[addr](self, addr, value)
  138. end
  139.  
  140. function CPU:peek16(addr)
  141.     return self:fetch(addr) + lshift(self:fetch(addr + 1), 8)
  142. end
  143.  
  144. function CPU:push8(data)
  145.     self:store(0x0100 + self._sp, data)
  146.     self._sp = band(self._sp - 1, 0xff)
  147. end
  148.  
  149. function CPU:push16(data)
  150.     self:push8(rshift(data, 8))
  151.     self:push8(band(data, 0xff))
  152. end
  153.  
  154. function CPU:pull8()
  155.     self._sp = band(self._sp + 1, 0xff)
  156.     return self:fetch(0x0100 + self._sp)
  157. end
  158.  
  159. function CPU:pull16()
  160.     local lo = self:pull8()
  161.     local hi = self:pull8()
  162.     return lo + hi * 256
  163. end
  164.  
  165. function CPU:flags_pack()
  166.     local nz = self._p_nz
  167.     return bor(
  168.         bor(
  169.             bor(
  170.                 bor(
  171.                     bor(
  172.                         bor(
  173.                             band(bor(rshift(nz, 1), nz), 0x80),
  174.                             (band(nz, 0xff) ~= 0 and 0 or 2)
  175.                         ),
  176.                         self._p_c
  177.                     ),
  178.                     self._p_v ~= 0 and 0x40 or 0
  179.                 ),
  180.                 self._p_i
  181.             ),
  182.             self._p_d
  183.         ),
  184.         0x20
  185.     )
  186. end
  187.  
  188. function CPU:flags_unpack(f)
  189.     self._p_nz = bor(band(bnot(f), 2), lshift(band(f, 0x80), 1))
  190.     self._p_c = band(f, 0x01)
  191.     self._p_v = band(f, 0x40)
  192.     self._p_i = band(f, 0x04)
  193.     self._p_d = band(f, 0x08)
  194. end
  195.  
  196. function CPU:branch(cond)
  197.     if cond then
  198.         local tmp = self._pc + 1
  199.         local rel = self:fetch(self._pc)
  200.         self._pc = band(tmp + (rel < 128 and rel or bor(rel, 0xff00)), 0xffff)
  201.         self.clk = self.clk + (nthBitIsSetInt(tmp, 8) == nthBitIsSetInt(self._pc, 8) and CPU.CLK[3] or CPU.CLK[4])
  202.     else
  203.         self._pc = self._pc + 1
  204.         self.clk = self.clk + CPU.CLK[2]
  205.     end
  206. end
  207.  
  208. function CPU:do_irq(line, clk)
  209.     self.irq_flags = bor(self.irq_flags, line)
  210.     if self.clk_irq == CPU.FOREVER_CLOCK and self._p_i == 0 then
  211.         self.clk_irq = self:next_interrupt_clock(clk)
  212.     end
  213. end
  214.  
  215. function CPU:do_nmi(clk)
  216.     if self.clk_nmi == CPU.FOREVER_CLOCK then
  217.         self.clk_nmi = self:next_interrupt_clock(clk)
  218.     end
  219. end
  220.  
  221. function CPU:do_isr(vector)
  222.     if self.jammed then return end
  223.     self:push16(self._pc)
  224.     self:push8(self:flags_pack())
  225.     self._p_i = 0x04
  226.     self.clk = self.clk + CPU.CLK[7]
  227.     local addr = vector == CPU.NMI_VECTOR and CPU.NMI_VECTOR or self:fetch_irq_isr_vector()
  228.     self._pc = self:peek16(addr)
  229. end
  230.  
  231. function CPU:fetch_irq_isr_vector()
  232.     if self.clk >= self.clk_frame then
  233.         self:fetch(0x3000)
  234.     end
  235.     if self.clk_nmi ~= CPU.FOREVER_CLOCK then
  236.         if self.clk_nmi + CPU.CLK[2] <= self.clk then
  237.             self.clk_nmi = CPU.FOREVER_CLOCK
  238.             return CPU.NMI_VECTOR
  239.         end
  240.         self.clk_nmi = self.clk + 1
  241.     end
  242.     return CPU.IRQ_VECTOR
  243. end
  244.  
  245. function CPU:step()
  246.     local opcode = self:fetch(self._pc)
  247.     self._pc = band(self._pc + 1, 0xffff)
  248.     self:executeInstruction(opcode)
  249. end
  250.  
  251. function CPU:executeInstruction(opcode)
  252.     local instructions = {
  253.         [0x00] = function() self:BRK() end,
  254.         [0x01] = function() self:ORA(self:IndirectX()) end,
  255.         [0x05] = function() self:ORA(self:ZeroPage()) end,
  256.         [0x06] = function() self:ASL(self:ZeroPage()) end,
  257.         [0x08] = function() self:PHP() end,
  258.         [0x09] = function() self:ORA(self:Immediate()) end,
  259.         [0x0A] = function() self:ASL_A() end,
  260.         [0x0D] = function() self:ORA(self:Absolute()) end,
  261.         [0x0E] = function() self:ASL(self:Absolute()) end,
  262.         [0x10] = function() self:BPL() end,
  263.         [0x11] = function() self:ORA(self:IndirectY()) end,
  264.         [0x15] = function() self:ORA(self:ZeroPageX()) end,
  265.         [0x16] = function() self:ASL(self:ZeroPageX()) end,
  266.         [0x18] = function() self:CLC() end,
  267.         [0x19] = function() self:ORA(self:AbsoluteY()) end,
  268.         [0x1D] = function() self:ORA(self:AbsoluteX()) end,
  269.         [0x1E] = function() self:ASL(self:AbsoluteX()) end,
  270.         [0x20] = function() self:JSR() end,
  271.         [0x21] = function() self:AND(self:IndirectX()) end,
  272.         [0x24] = function() self:BIT(self:ZeroPage()) end,
  273.         [0x25] = function() self:AND(self:ZeroPage()) end,
  274.         [0x26] = function() self:ROL(self:ZeroPage()) end,
  275.         [0x28] = function() self:PLP() end,
  276.         [0x29] = function() self:AND(self:Immediate()) end,
  277.         [0x2A] = function() self:ROL_A() end,
  278.         [0x2C] = function() self:BIT(self:Absolute()) end,
  279.         [0x2D] = function() self:AND(self:Absolute()) end,
  280.         [0x2E] = function() self:ROL(self:Absolute()) end,
  281.         [0x30] = function() self:BMI() end,
  282.         [0x31] = function() self:AND(self:IndirectY()) end,
  283.         [0x35] = function() self:AND(self:ZeroPageX()) end,
  284.         [0x36] = function() self:ROL(self:ZeroPageX()) end,
  285.         [0x38] = function() self:SEC() end,
  286.         [0x39] = function() self:AND(self:AbsoluteY()) end,
  287.         [0x3D] = function() self:AND(self:AbsoluteX()) end,
  288.         [0x3E] = function() self:ROL(self:AbsoluteX()) end,
  289.         [0x40] = function() self:RTI() end,
  290.         [0x41] = function() self:EOR(self:IndirectX()) end,
  291.         [0x45] = function() self:EOR(self:ZeroPage()) end,
  292.         [0x46] = function() self:LSR(self:ZeroPage()) end,
  293.         [0x48] = function() self:PHA() end,
  294.         [0x49] = function() self:EOR(self:Immediate()) end,
  295.         [0x4A] = function() self:LSR_A() end,
  296.         [0x4C] = function() self:JMP_ABS() end,
  297.         [0x4D] = function() self:EOR(self:Absolute()) end,
  298.         [0x4E] = function() self:LSR(self:Absolute()) end,
  299.         [0x50] = function() self:BVC() end,
  300.         [0x51] = function() self:EOR(self:IndirectY()) end,
  301.         [0x55] = function() self:EOR(self:ZeroPageX()) end,
  302.         [0x56] = function() self:LSR(self:ZeroPageX()) end,
  303.         [0x58] = function() self:CLI() end,
  304.         [0x59] = function() self:EOR(self:AbsoluteY()) end,
  305.         [0x5D] = function() self:EOR(self:AbsoluteX()) end,
  306.         [0x5E] = function() self:LSR(self:AbsoluteX()) end,
  307.         [0x60] = function() self:RTS() end,
  308.         [0x61] = function() self:ADC(self:IndirectX()) end,
  309.         [0x65] = function() self:ADC(self:ZeroPage()) end,
  310.         [0x66] = function() self:ROR(self:ZeroPage()) end,
  311.         [0x68] = function() self:PLA() end,
  312.         [0x69] = function() self:ADC(self:Immediate()) end,
  313.         [0x6A] = function() self:ROR_A() end,
  314.         [0x6C] = function() self:JMP_IND() end,
  315.         [0x6D] = function() self:ADC(self:Absolute()) end,
  316.         [0x6E] = function() self:ROR(self:Absolute()) end,
  317.         [0x70] = function() self:BVS() end,
  318.         [0x71] = function() self:ADC(self:IndirectY()) end,
  319.         [0x75] = function() self:ADC(self:ZeroPageX()) end,
  320.         [0x76] = function() self:ROR(self:ZeroPageX()) end,
  321.         [0x78] = function() self:SEI() end,
  322.         [0x79] = function() self:ADC(self:AbsoluteY()) end,
  323.         [0x7D] = function() self:ADC(self:AbsoluteX()) end,
  324.         [0x7E] = function() self:ROR(self:AbsoluteX()) end,
  325.         [0x81] = function() self:STA(self:IndirectX()) end,
  326.         [0x84] = function() self:STY(self:ZeroPage()) end,
  327.         [0x85] = function() self:STA(self:ZeroPage()) end,
  328.         [0x86] = function() self:STX(self:ZeroPage()) end,
  329.         [0x88] = function() self:DEY() end,
  330.         [0x8A] = function() self:TXA() end,
  331.         [0x8C] = function() self:STY(self:Absolute()) end,
  332.         [0x8D] = function() self:STA(self:Absolute()) end,
  333.         [0x8E] = function() self:STX(self:Absolute()) end,
  334.         [0x90] = function() self:BCC() end,
  335.         [0x91] = function() self:STA(self:IndirectY()) end,
  336.         [0x94] = function() self:STY(self:ZeroPageX()) end,
  337.         [0x95] = function() self:STA(self:ZeroPageX()) end,
  338.         [0x96] = function() self:STX(self:ZeroPageY()) end,
  339.         [0x98] = function() self:TYA() end,
  340.         [0x99] = function() self:STA(self:AbsoluteY()) end,
  341.         [0x9A] = function() self:TXS() end,
  342.         [0x9D] = function() self:STA(self:AbsoluteX()) end,
  343.         [0xA0] = function() self:LDY(self:Immediate()) end,
  344.         [0xA1] = function() self:LDA(self:IndirectX()) end,
  345.         [0xA2] = function() self:LDX(self:Immediate()) end,
  346.         [0xA4] = function() self:LDY(self:ZeroPage()) end,
  347.         [0xA5] = function() self:LDA(self:ZeroPage()) end,
  348.         [0xA6] = function() self:LDX(self:ZeroPage()) end,
  349.         [0xA8] = function() self:TAY() end,
  350.         [0xA9] = function() self:LDA(self:Immediate()) end,
  351.         [0xAA] = function() self:TAX() end,
  352.         [0xAC] = function() self:LDY(self:Absolute()) end,
  353.         [0xAD] = function() self:LDA(self:Absolute()) end,
  354.         [0xAE] = function() self:LDX(self:Absolute()) end,
  355.         [0xB0] = function() self:BCS() end,
  356.         [0xB1] = function() self:LDA(self:IndirectY()) end,
  357.         [0xB4] = function() self:LDY(self:ZeroPageX()) end,
  358.         [0xB5] = function() self:LDA(self:ZeroPageX()) end,
  359.         [0xB6] = function() self:LDX(self:ZeroPageY()) end,
  360.         [0xB8] = function() self:CLV() end,
  361.         [0xB9] = function() self:LDA(self:AbsoluteY()) end,
  362.         [0xBA] = function() self:TSX() end,
  363.         [0xBC] = function() self:LDY(self:AbsoluteX()) end,
  364.         [0xBD] = function() self:LDA(self:AbsoluteX()) end,
  365.         [0xBE] = function() self:LDX(self:AbsoluteY()) end,
  366.         [0xC0] = function() self:CPY(self:Immediate()) end,
  367.         [0xC1] = function() self:CMP(self:IndirectX()) end,
  368.         [0xC4] = function() self:CPY(self:ZeroPage()) end,
  369.         [0xC5] = function() self:CMP(self:ZeroPage()) end,
  370.         [0xC6] = function() self:DEC(self:ZeroPage()) end,
  371.         [0xC8] = function() self:INY() end,
  372.         [0xC9] = function() self:CMP(self:Immediate()) end,
  373.         [0xCA] = function() self:DEX() end,
  374.         [0xCC] = function() self:CPY(self:Absolute()) end,
  375.         [0xCD] = function() self:CMP(self:Absolute()) end,
  376.         [0xCE] = function() self:DEC(self:Absolute()) end,
  377.         [0xD0] = function() self:BNE() end,
  378.         [0xD1] = function() self:CMP(self:IndirectY()) end,
  379.         [0xD5] = function() self:CMP(self:ZeroPageX()) end,
  380.         [0xD6] = function() self:DEC(self:ZeroPageX()) end,
  381.         [0xD8] = function() self:CLD() end,
  382.         [0xD9] = function() self:CMP(self:AbsoluteY()) end,
  383.         [0xDD] = function() self:CMP(self:AbsoluteX()) end,
  384.         [0xDE] = function() self:DEC(self:AbsoluteX()) end,
  385.         [0xE0] = function() self:CPX(self:Immediate()) end,
  386.         [0xE1] = function() self:SBC(self:IndirectX()) end,
  387.         [0xE4] = function() self:CPX(self:ZeroPage()) end,
  388.         [0xE5] = function() self:SBC(self:ZeroPage()) end,
  389.         [0xE6] = function() self:INC(self:ZeroPage()) end,
  390.         [0xE8] = function() self:INX() end,
  391.         [0xE9] = function() self:SBC(self:Immediate()) end,
  392.         [0xEA] = function() self:NOP() end,
  393.         [0xEC] = function() self:CPX(self:Absolute()) end,
  394.         [0xED] = function() self:SBC(self:Absolute()) end,
  395.         [0xEE] = function() self:INC(self:Absolute()) end,
  396.         [0xF0] = function() self:BEQ() end,
  397.         [0xF1] = function() self:SBC(self:IndirectY()) end,
  398.         [0xF5] = function() self:SBC(self:ZeroPageX()) end,
  399.         [0xF6] = function() self:INC(self:ZeroPageX()) end,
  400.         [0xF8] = function() self:SED() end,
  401.         [0xF9] = function() self:SBC(self:AbsoluteY()) end,
  402.         [0xFD] = function() self:SBC(self:AbsoluteX()) end,
  403.         [0xFE] = function() self:INC(self:AbsoluteX()) end,
  404.     }
  405.  
  406.     local instruction = instructions[opcode]
  407.     if instruction then
  408.         instruction()
  409.     else
  410.         print("Unknown opcode: " .. string.format("%02X", opcode))
  411.     end
  412. end
  413.  
  414. -- Implement all CPU instructions here
  415. function CPU:ADC(value)
  416.     local result = self._a + value + self._p_c
  417.     self._p_c = result > 0xFF and 1 or 0
  418.     self._p_v = ((self._a ^ result) & (value ^ result) & 0x80) ~= 0 and 1 or 0
  419.     self._a = band(result, 0xFF)
  420.     self:setZN(self._a)
  421. end
  422.  
  423. function CPU:AND(value)
  424.     self._a = band(self._a, value)
  425.     self:setZN(self._a)
  426. end
  427.  
  428. function CPU:ASL(addr)
  429.     local value = self:read(addr)
  430.     self._p_c = band(value, 0x80) ~= 0 and 1 or 0
  431.     value = band(lshift(value, 1), 0xFF)
  432.     self:write(addr, value)
  433.     self:setZN(value)
  434. end
  435.  
  436. function CPU:BCC()
  437.     self:branch(self._p_c == 0)
  438. end
  439.  
  440. function CPU:BCS()
  441.     self:branch(self._p_c == 1)
  442. end
  443.  
  444. function CPU:BEQ()
  445.     self:branch(self._p_nz == 0)
  446. end
  447.  
  448. function CPU:BIT(value)
  449.     self._p_v = band(value, 0x40) ~= 0 and 1 or 0
  450.     self._p_nz = bor(band(value, 0x80), band(self._a, value) == 0 and 0x02 or 0)
  451. end
  452.  
  453. function CPU:BMI()
  454.     self:branch(band(self._p_nz, 0x80) ~= 0)
  455. end
  456.  
  457. function CPU:BNE()
  458.     self:branch(self._p_nz ~= 0)
  459. end
  460.  
  461. function CPU:BPL()
  462.     self:branch(band(self._p_nz, 0x80) == 0)
  463. end
  464.  
  465. function CPU:BRK()
  466.     self:push16(self._pc + 1)
  467.     self:push8(bor(self:flags_pack(), 0x10))
  468.     self._p_i = 1
  469.     self._pc = self:peek16(CPU.IRQ_VECTOR)
  470. end
  471.  
  472. function CPU:BVC()
  473.     self:branch(self._p_v == 0)
  474. end
  475.  
  476. function CPU:BVS()
  477.     self:branch(self._p_v == 1)
  478. end
  479.  
  480. function CPU:CLC()
  481.     self._p_c = 0
  482. end
  483.  
  484. function CPU:CLD()
  485.     self._p_d = 0
  486. end
  487.  
  488. function CPU:CLI()
  489.     self._p_i = 0
  490. end
  491.  
  492. function CPU:CLV()
  493.     self._p_v = 0
  494. end
  495.  
  496. function CPU:CMP(value)
  497.     local result = self._a - value
  498.     self._p_c = result >= 0 and 1 or 0
  499.     self:setZN(band(result, 0xFF))
  500. end
  501.  
  502. function CPU:CPX(value)
  503.     local result = self._x - value
  504.     self._p_c = result >= 0 and 1 or 0
  505.     self:setZN(band(result, 0xFF))
  506. end
  507.  
  508. function CPU:CPY(value)
  509.     local result = self._y - value
  510.     self._p_c = result >= 0 and 1 or 0
  511.     self:setZN(band(result, 0xFF))
  512. end
  513.  
  514. function CPU:DEC(addr)
  515.     local value = band(self:read(addr) - 1, 0xFF)
  516.     self:write(addr, value)
  517.     self:setZN(value)
  518. end
  519.  
  520. function CPU:DEX()
  521.     self._x = band(self._x - 1, 0xFF)
  522.     self:setZN(self._x)
  523. end
  524.  
  525. function CPU:DEY()
  526.     self._y = band(self._y - 1, 0xFF)
  527.     self:setZN(self._y)
  528. end
  529.  
  530. function CPU:EOR(value)
  531.     self._a = bxor(self._a, value)
  532.     self:setZN(self._a)
  533. end
  534.  
  535. function CPU:INC(addr)
  536.     local value = band(self:read(addr) + 1, 0xFF)
  537.     self:write(addr, value)
  538.     self:setZN(value)
  539. end
  540.  
  541. function CPU:INX()
  542.     self._x = band(self._x + 1, 0xFF)
  543.     self:setZN(self._x)
  544. end
  545.  
  546. function CPU:INY()
  547.     self._y = band(self._y + 1, 0xFF)
  548.     self:setZN(self._y)
  549. end
  550.  
  551. function CPU:JMP_ABS()
  552.     self._pc = self:peek16(self._pc)
  553. end
  554.  
  555. function CPU:JMP_IND()
  556.     local addr = self:peek16(self._pc)
  557.     if band(addr, 0xFF) == 0xFF then
  558.         self._pc = bor(self:read(addr), lshift(self:read(band(addr, 0xFF00)), 8))
  559.     else
  560.         self._pc = self:peek16(addr)
  561.     end
  562. end
  563.  
  564. function CPU:JSR()
  565.     self:push16(self._pc + 1)
  566.     self._pc = self:peek16(self._pc)
  567. end
  568.  
  569. function CPU:LDA(value)
  570.     self._a = value
  571.     self:setZN(self._a)
  572. end
  573.  
  574. function CPU:LDX(value)
  575.     self._x = value
  576.     self:setZN(self._x)
  577. end
  578.  
  579. function CPU:LDY(value)
  580.     self._y = value
  581.     self:setZN(self._y)
  582. end
  583.  
  584. function CPU:LSR(addr)
  585.     local value = self:read(addr)
  586.     self._p_c = band(value, 0x01)
  587.     value = rshift(value, 1)
  588.     self:write(addr, value)
  589.     self:setZN(value)
  590. end
  591.  
  592. function CPU:NOP()
  593.     -- Do nothing
  594. end
  595.  
  596. function CPU:ORA(value)
  597.     self._a = bor(self._a, value)
  598.     self:setZN(self._a)
  599. end
  600.  
  601. function CPU:PHA()
  602.     self:push8(self._a)
  603. end
  604.  
  605. function CPU:PHP()
  606.     self:push8(bor(self:flags_pack(), 0x10))
  607. end
  608.  
  609. function CPU:PLA()
  610.     self._a = self:pull8()
  611.     self:setZN(self._a)
  612. end
  613.  
  614. function CPU:PLP()
  615.     self:flags_unpack(band(self:pull8(), 0xEF))
  616. end
  617.  
  618. function CPU:ROL(addr)
  619.     local value = self:read(addr)
  620.     local newCarry = band(value, 0x80) ~= 0 and 1 or 0
  621.     value = bor(lshift(value, 1), self._p_c)
  622.     self._p_c = newCarry
  623.     self:write(addr, band(value, 0xFF))
  624.     self:setZN(band(value, 0xFF))
  625. end
  626.  
  627. function CPU:ROR(addr)
  628.     local value = self:read(addr)
  629.     local newCarry = band(value, 0x01)
  630.     value = bor(rshift(value, 1), lshift(self._p_c, 7))
  631.     self._p_c = newCarry
  632.     self:write(addr, value)
  633.     self:setZN(value)
  634. end
  635.  
  636. function CPU:RTI()
  637.     self:flags_unpack(band(self:pull8(), 0xEF))
  638.     self._pc = self:pull16()
  639. end
  640.  
  641. function CPU:RTS()
  642.     self._pc = band(self:pull16() + 1, 0xFFFF)
  643. end
  644.  
  645. function CPU:SBC(value)
  646.     local result = self._a - value - (1 - self._p_c)
  647.     self._p_c = result >= 0 and 1 or 0
  648.     self._p_v = ((self._a ^ result) & (self._a ^ value) & 0x80) ~= 0 and 1 or 0
  649.     self._a = band(result, 0xFF)
  650.     self:setZN(self._a)
  651. end
  652.  
  653. function CPU:SEC()
  654.     self._p_c = 1
  655. end
  656.  
  657. function CPU:SED()
  658.     self._p_d = 1
  659. end
  660.  
  661. function CPU:SEI()
  662.     self._p_i = 1
  663. end
  664.  
  665. function CPU:STA(addr)
  666.     self:write(addr, self._a)
  667. end
  668.  
  669. function CPU:STX(addr)
  670.     self:write(addr, self._x)
  671. end
  672.  
  673. function CPU:STY(addr)
  674.     self:write(addr, self._y)
  675. end
  676.  
  677. function CPU:TAX()
  678.     self._x = self._a
  679.     self:setZN(self._x)
  680. end
  681.  
  682. function CPU:TAY()
  683.     self._y = self._a
  684.     self:setZN(self._y)
  685. end
  686.  
  687. function CPU:TSX()
  688.     self._x = self._sp
  689.     self:setZN(self._x)
  690. end
  691.  
  692. function CPU:TXA()
  693.     self._a = self._x
  694.     self:setZN(self._a)
  695. end
  696.  
  697. function CPU:TXS()
  698.     self._sp = self._x
  699. end
  700.  
  701. function CPU:TYA()
  702.     self._a = self._y
  703.     self:setZN(self._a)
  704. end
  705.  
  706. -- PPU Emulation
  707. local PPU = {}
  708. PPU.__index = PPU
  709.  
  710. function PPU:new(nes)
  711.     local ppu = setmetatable({}, PPU)
  712.     ppu:initialize(nes)
  713.     return ppu
  714. end
  715.  
  716. function PPU:initialize(nes)
  717.     self.nes = nes
  718.     self.vram = {}
  719.     for i = 0, 0x3FFF do
  720.         self.vram[i] = 0
  721.     end
  722.     self.oam = {}
  723.     for i = 0, 255 do
  724.         self.oam[i] = 0
  725.     end
  726.     self.palette = {}
  727.     for i = 0, 31 do
  728.         self.palette[i] = 0
  729.     end
  730.     self.scanline = 0
  731.     self.cycle = 0
  732.     self.frame = 0
  733.     self.v = 0  -- Current VRAM address (15 bits)
  734.     self.t = 0  -- Temporary VRAM address (15 bits)
  735.     self.x = 0  -- Fine X scroll (3 bits)
  736.     self.w = 0  -- First or second write toggle (1 bit)
  737.     self.f = 0  -- Even/odd frame flag (1 bit)
  738.     self.register = 0
  739.     self.nmi_output = false
  740.     self.nmi_occurred = false
  741.     self.sprite_zero_hit = false
  742.     self.sprite_overflow = false
  743. end
  744.  
  745. function PPU:read(address)
  746.     address = address % 0x4000
  747.     if address < 0x2000 then
  748.         return self.vram[address]
  749.     elseif address < 0x3F00 then
  750.         -- Handle mirroring
  751.         return self.vram[address % 0x1000]
  752.     else
  753.         -- Palette RAM
  754.         return self.palette[address % 32]
  755.     end
  756. end
  757.  
  758. function PPU:write(address, value)
  759.     address = address % 0x4000
  760.     if address < 0x2000 then
  761.         self.vram[address] = value
  762.     elseif address < 0x3F00 then
  763.         -- Handle mirroring
  764.         self.vram[address % 0x1000] = value
  765.     else
  766.         -- Palette RAM
  767.         self.palette[address % 32] = value
  768.     end
  769. end
  770.  
  771. function PPU:step()
  772.     self.cycle = self.cycle + 1
  773.     if self.cycle > 340 then
  774.         self.cycle = 0
  775.         self.scanline = self.scanline + 1
  776.         if self.scanline > 261 then
  777.             self.scanline = 0
  778.             self.frame = self.frame + 1
  779.             self.f = band(self.f + 1, 1)
  780.         end
  781.     end
  782.  
  783.     if self.scanline < 240 and self.cycle < 256 then
  784.         self:renderPixel()
  785.     elseif self.scanline == 241 and self.cycle == 1 then
  786.         self.nmi_occurred = true
  787.         if self.nmi_output then
  788.             self.nes.cpu:do_nmi(self.nes.cpu.clk)
  789.         end
  790.     end
  791. end
  792.  
  793. function PPU:renderPixel()
  794.     local x = self.cycle - 1
  795.     local y = self.scanline
  796.  
  797.     -- Simplified background rendering
  798.     local tileX = band(rshift(x, 3), 31)
  799.     local tileY = band(rshift(y, 3), 29)
  800.     local nameTableAddr = 0x2000 | (band(self.v, 0x0C00))
  801.     local attributeTableAddr = 0x23C0 | (band(self.v, 0x0C00))
  802.    
  803.     local tileIndex = self:read(nameTableAddr + tileY * 32 + tileX)
  804.     local tileAddr = 0x1000 * band(rshift(self.register, 4), 1) + tileIndex * 16 + band(y, 7)
  805.    
  806.     local lowTileByte = self:read(tileAddr)
  807.     local highTileByte = self:read(tileAddr + 8)
  808.    
  809.     local colorBit0 = band(rshift(lowTileByte, 7 - band(x, 7)), 1)
  810.     local colorBit1 = band(rshift(highTileByte, 7 - band(x, 7)), 1)
  811.     local colorNum = bor(lshift(colorBit1, 1), colorBit0)
  812.    
  813.     -- Simplified palette handling
  814.     local paletteIndex = band(self:read(0x3F00 + colorNum), 63)
  815.    
  816.     self:setPixel(x, y, paletteIndex)
  817. end
  818.  
  819. function PPU:setPixel(x, y, paletteIndex)
  820.     -- Implement this based on your rendering method
  821.     -- For example, if using OpenComputers' GPU:
  822.     local color = paletteIndex * 4  -- Simple color mapping
  823.     self.nes.gpu.setBackground(color)
  824.     self.nes.gpu.set(x + 1, y + 1, " ")
  825. end
  826.  
  827. -- NES Emulator
  828. local NES = {}
  829. NES.__index = NES
  830.  
  831. function NES:new()
  832.     local nes = setmetatable({}, NES)
  833.     nes.cpu = CPU:new()
  834.     nes.ppu = PPU:new(nes)
  835.     nes.gpu = component.gpu
  836.     nes.mapper = nil
  837.     nes.frameBuffer = {}
  838.     nes.controller1 = {up = false, down = false, left = false, right = false, a = false, b = false, start = false, select = false}
  839.     return nes
  840. end
  841.  
  842. function NES:loadROM(filename)
  843.     if not filesystem.exists(filename) then
  844.         error("ROM file not found: " .. filename)
  845.     end
  846.  
  847.     local file = filesystem.open(filename, "rb")
  848.     if not file then
  849.         error("Could not open ROM file: " .. filename)
  850.     end
  851.  
  852.     -- Read NES header
  853.     local header = file:read(16)
  854.     if not header or #header < 16 or header:sub(1, 4) ~= "NES\x1A" then
  855.         file:close()
  856.         error("Invalid NES ROM file")
  857.     end
  858.  
  859.     local prgRomSize = string.byte(header, 5) * 16384
  860.     local chrRomSize = string.byte(header, 6) * 8192
  861.     local flags6 = string.byte(header, 7)
  862.     local flags7 = string.byte(header, 8)
  863.  
  864.     -- Determine mapper number
  865.     local mapper = bor(band(flags7, 0xF0), rshift(band(flags6, 0xF0), 4))
  866.  
  867.     -- Load PRG ROM
  868.     local prgRom = file:read(prgRomSize)
  869.     -- Load CHR ROM
  870.     local chrRom = file:read(chrRomSize)
  871.  
  872.     file:close()
  873.  
  874.     print("Loaded NES ROM. Mapper: " .. mapper .. ", PRG ROM: " .. prgRomSize .. " bytes, CHR ROM: " .. chrRomSize .. " bytes")
  875.  
  876.     -- Set up mapper
  877.     self:setupMapper(mapper, prgRom, chrRom, prgRomSize, chrRomSize)
  878.  
  879.     -- Reset CPU and PPU
  880.     self.cpu:reset()
  881.     self.ppu:reset()
  882. end
  883.  
  884. function NES:setupMapper(mapperNumber, prgRom, chrRom, prgRomSize, chrRomSize)
  885.     local mappers = {
  886.         [0] = function() return NROM:new(prgRom, chrRom, prgRomSize, chrRomSize) end,
  887.         [1] = function() return MMC1:new(prgRom, chrRom, prgRomSize, chrRomSize) end,
  888.         [2] = function() return UxROM:new(prgRom, chrRom, prgRomSize, chrRomSize) end,
  889.         [3] = function() return CNROM:new(prgRom, chrRom, prgRomSize, chrRomSize) end,
  890.         [4] = function() return MMC3:new(prgRom, chrRom, prgRomSize, chrRomSize) end,
  891.     }
  892.  
  893.     local mapperConstructor = mappers[mapperNumber]
  894.     if mapperConstructor then
  895.         self.mapper = mapperConstructor()
  896.     else
  897.         error("Unsupported mapper: " .. mapperNumber)
  898.     end
  899.  
  900.     -- Set up CPU and PPU memory mappings
  901.     self.cpu:setMapper(self.mapper)
  902.     self.ppu:setMapper(self.mapper)
  903. end
  904.  
  905. function NES:run()
  906.     local running = true
  907.     local frameTime = 1 / 60  -- 60 FPS
  908.     local lastTime = computer.uptime()
  909.  
  910.     while running do
  911.         local currentTime = computer.uptime()
  912.         local deltaTime = currentTime - lastTime
  913.  
  914.         if deltaTime >= frameTime then
  915.             lastTime = currentTime
  916.  
  917.             -- Run one frame of emulation
  918.             for i = 1, 29780 do  -- Approximate CPU cycles per frame
  919.                 self.cpu:step()
  920.                 self.ppu:step()
  921.                 self.ppu:step()
  922.                 self.ppu:step()
  923.             end
  924.  
  925.             -- Render frame
  926.             self:renderFrame()
  927.  
  928.             -- Handle input
  929.             running = self:handleInput()
  930.         end
  931.     end
  932. end
  933.  
  934. function NES:renderFrame()
  935.     -- Clear frame buffer
  936.     self.frameBuffer = {}
  937.  
  938.     -- Render frame to buffer
  939.     for y = 0, 239 do
  940.         self.frameBuffer[y] = {}
  941.         for x = 0, 255 do
  942.             self.frameBuffer[y][x] = self.ppu:getPixel(x, y)
  943.         end
  944.     end
  945.  
  946.     -- Render frame buffer to GPU
  947.     for y = 0, 239 do
  948.         local row = self.frameBuffer[y]
  949.         local gpuRow = {}
  950.         for x = 0, 255 do
  951.             gpuRow[x + 1] = string.char(row[x])
  952.         end
  953.         self.gpu.set(1, y + 1, table.concat(gpuRow))
  954.     end
  955. end
  956.  
  957. function NES:handleInput()
  958.     -- Handle input using OpenComputers event API
  959.     while true do
  960.         local _, _, code = event.pull(0, "key_down")
  961.         if code == keyboard.keys.q then
  962.             return false  -- Quit emulator
  963.         elseif code == keyboard.keys.up then
  964.             self.controller1.up = true
  965.         elseif code == keyboard.keys.down then
  966.             self.controller1.down = true
  967.         elseif code == keyboard.keys.left then
  968.             self.controller1.left = true
  969.         elseif code == keyboard.keys.right then
  970.             self.controller1.right = true
  971.         elseif code == keyboard.keys.z then
  972.             self.controller1.a = true
  973.         elseif code == keyboard.keys.x then
  974.             self.controller1.b = true
  975.         elseif code == keyboard.keys.leftCtrl then
  976.             self.controller1.start = true
  977.         elseif code == keyboard.keys.leftAlt then
  978.             self.controller1.select = true
  979.         end
  980.  
  981.         local _, _, code = event.pull(0, "key_up")
  982.         if code == keyboard.keys.up then
  983.             self.controller1.up = false
  984.         elseif code == keyboard.keys.down then
  985.             self.controller1.down = false
  986.         elseif code == keyboard.keys.left then
  987.             self.controller1.left = false
  988.         elseif code == keyboard.keys.right then
  989.             self.controller1.right = false
  990.         elseif code == keyboard.keys.z then
  991.             self.controller1.a = false
  992.         elseif code == keyboard.keys.x then
  993.             self.controller1.b = false
  994.         elseif code == keyboard.keys.leftCtrl then
  995.             self.controller1.start = false
  996.         elseif code == keyboard.keys.leftAlt then
  997.             self.controller1.select = false
  998.         end
  999.     end
  1000.     return true
  1001. end
  1002.  
  1003. -- Mapper base class
  1004. local Mapper = {}
  1005. Mapper.__index = Mapper
  1006.  
  1007. function Mapper:new(prgRom, chrRom, prgRomSize, chrRomSize)
  1008.     local mapper = setmetatable({}, Mapper)
  1009.     mapper.prgRom = prgRom
  1010.     mapper.chrRom = chrRom
  1011.     mapper.prgRomSize = prgRomSize
  1012.     mapper.chrRomSize = chrRomSize
  1013.     return mapper
  1014. end
  1015.  
  1016. -- NROM (Mapper 0)
  1017. local NROM = setmetatable({}, {__index = Mapper})
  1018. NROM.__index = NROM
  1019.  
  1020. function NROM:new(prgRom, chrRom, prgRomSize, chrRomSize)
  1021.     local nrom = setmetatable(Mapper:new(prgRom, chrRom, prgRomSize, chrRomSize), NROM)
  1022.     nrom.prgBankCount = prgRomSize / 16384
  1023.     return nrom
  1024. end
  1025.  
  1026. function NROM:cpuRead(address)
  1027.     if address >= 0x8000 then
  1028.         local index = (address - 0x8000) % self.prgRomSize
  1029.         return string.byte(self.prgRom, index + 1)
  1030.     end
  1031.     return 0
  1032. end
  1033.  
  1034. function NROM:cpuWrite(address, value)
  1035.     -- NROM doesn't support writes to ROM
  1036. end
  1037.  
  1038. function NROM:ppuRead(address)
  1039.     if address < 0x2000 then
  1040.         return string.byte(self.chrRom, address + 1)
  1041.     end
  1042.     return 0
  1043. end
  1044.  
  1045. function NROM:ppuWrite(address, value)
  1046.     -- NROM doesn't support writes to CHR ROM
  1047. end
  1048.  
  1049. -- Main
  1050. local nes = NES:new()
  1051. local romFile = "/home/super_mario_bros.nes"
  1052.  
  1053. -- Load and run the ROM
  1054. nes:loadROM(romFile)
  1055. nes:run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement