#include #include #include #include "6502.h" #include "nes.h" #include "ppu.h" #include "mmc1.h" // LSB first: A, B, Select, Start, Up, Down, Left, Right int buttons = (1<<20), buttoni = 0; int pr = 0; byte cpureg[32]; int readhandler(int addr) { if(addr >= 0x2000 && addr <= 0x2007) return ppuread(addr); if(addr == 0x4016 || addr == 0x4017) { if(buttoni >= 32) return 1; return ((buttons >> (buttoni++)) & 1); } if(addr >= 0x4000 && addr <= 0x4017) return cpureg[addr - 0x4000]; sysfatal("read from non-present address %.4x", addr & 0xffff); return 0; } void writehandler(int val, int addr) { if(addr >= 0x2000 && addr <= 0x2007) ppuwrite(addr, val); else if(addr >= 0x8000) mmc1write(addr, val); else if(addr == 0x4014) oamfill(val & 0xff); else if(addr == 0x4016) { if((val & 0xFF) == 0) buttoni = 0; } else if(addr >= 0x4000 && addr <= 0x4017) cpureg[addr - 0x4000] = val & 0xff; else sysfatal("write of %.2x to non-present address %.4x", val & 0xff, addr & 0xffff); } void printreg(void) { char* s = disasm(mem+regPC); fprint(2, "A %.2x X %.2x Y %.2x P %.2x S %.2x PC %.4x (%.2x) [%c%c%c%c%c%c%c] %s\n", regA, regX, regY, regP, regS, regPC, mem[regPC], (regP & (1<<7)) ? 'N' : ' ', (regP & (1<<6)) ? 'V' : ' ', (regP & (1<<4)) ? 'B' : ' ', (regP & (1<<3)) ? 'D' : ' ', (regP & (1<<2)) ? 'I' : ' ', (regP & (1<<1)) ? 'Z' : ' ', (regP & (1<<0)) ? 'C' : ' ', s ); free(s); } void undefined(void) { fprint(2, "undefined opcode\n"); regPC--; printreg(); regPC++; exits("undefined opcode"); } NESHeader header; byte mapper; char** prg = 0, ** chr = 0; void loadrom(char* file) { int i; int f = open(file, OREAD); if(!f) sysfatal("can't open %s: %r\n", file); char magic[4]; read(f, magic, 4); if(strncmp(magic, "NES\x1A", 4)) sysfatal("invalid rom"); read(f, &header.nprg, 1); read(f, &header.nchr, 1); read(f, &header.flags6, 1); read(f, &header.nram, 1); read(f, &header.flags7, 1); char pad[7]; read(f, pad, 7); print("%d * 16 KB PRG ROM, %d * 8 KB CHR ROM\n", header.nprg, header.nchr); if(header.flags6 & (1<<2)) seek(f, 512, 1); mapper = (header.flags6 >> 4) | (header.flags7 & 0xF0); if(mapper > 1) sysfatal("mapper %d unsupported\n", mapper); prg = calloc(sizeof(char*), header.nprg); for(i=0;i