SHARE
TWEET

NES

a guest Nov 5th, 2012 82 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cstdlib>
  2. #include <cstdio>
  3. #include <cstdint>
  4. #include <cstring>
  5. #include <SDL.h>
  6.  
  7. SDL_Surface *screen = NULL;
  8.  
  9. class PPU
  10. {
  11.         public:
  12.         uint8_t ctrl0;
  13.         uint8_t ctrl1;
  14.  
  15.         uint8_t mapper;
  16.  
  17.         uint16_t addr;
  18.         bool lohi;
  19.  
  20.         uint8_t pat0[0x1000];
  21.         uint8_t pat1[0x1000];
  22.         uint8_t nt0[0x3C0];
  23.         uint8_t at0[0x40];
  24.         uint8_t nt1[0x3C0];
  25.         uint8_t at1[0x40];
  26.         uint8_t nt2[0x3C0];
  27.         uint8_t at2[0x40];
  28.         uint8_t nt3[0x3C0];
  29.         uint8_t at3[0x40];
  30.         uint8_t spr_pal[0x10];
  31.         uint8_t bg_pal[0x10];
  32.         uint8_t oam[0x100];
  33.         uint16_t scanline;
  34.         uint16_t cycles;
  35.         uint16_t cycles_next;
  36.  
  37.         uint16_t vram_addr;
  38.  
  39.         uint8_t nmi;
  40.  
  41.         int tilenum;
  42.  
  43.         PPU()
  44.         {
  45.                 vram_addr = 0x2000;
  46.                 cycles_next = 0;
  47.                 tilenum = 0;
  48.                 lohi = 0;
  49.                 for(int i = 0;i<16;i++) bg_pal[i] = 0;
  50.  
  51.         }
  52.  
  53.         void wb(uint16_t addr, uint8_t value)
  54.         {
  55.                 if(addr >= 0 && addr < 0x1000) pat0[addr] = value;
  56.                 if(addr >= 0x1000 && addr < 0x2000) pat1[addr - 0x1000] = value;
  57.                 if(mapper == 0)
  58.                 {
  59.                         if(addr >= 0x2000 && addr < 0x23C0) nt0[addr - 0x2000] = value;
  60.                         if(addr >= 0x23C0 && addr < 0x2400) at0[addr - 0x23C0] = value;
  61.                         if(addr >= 0x2400 && addr < 0x27C0) nt1[addr - 0x2400] = value;
  62.                         if(addr >= 0x27C0 && addr < 0x2800) at1[addr - 0x27C0] = value;
  63.                         if(addr >= 0x2800 && addr < 0x2BC0) nt0[addr - 0x2800] = value;
  64.                         if(addr >= 0x2BC0 && addr < 0x2C00) at0[addr - 0x2BC0] = value;
  65.                         if(addr >= 0x2C00 && addr < 0x2FC0) nt1[addr - 0x2C00] = value;
  66.                         if(addr >= 0x2FC0 && addr < 0x3000) at1[addr - 0x2FC0] = value;
  67.                 }
  68.                 if(addr >= 0x3F00 && addr < 0x3F10) bg_pal[addr - 0x3F00] = value;
  69.                 if(addr >= 0x3F10 && addr < 0x3F20) spr_pal[addr - 0x3F10] = value;
  70.                 if(addr >= 0x3F20 && addr < 0x3F30) bg_pal[addr - 0x3F20] = value;
  71.                 if(addr >= 0x3F30 && addr < 0x3F40) spr_pal[addr - 0x3F30] = value;
  72.                 if(addr >= 0x3F40 && addr < 0x3F50) bg_pal[addr - 0x3F40] = value;
  73.                 if(addr >= 0x3F50 && addr < 0x3F60) spr_pal[addr - 0x3F50] = value;
  74.                 if(addr >= 0x3F40 && addr < 0x3F50) bg_pal[addr - 0x3F40] = value;
  75.                 if(addr >= 0x3F50 && addr < 0x3F60) spr_pal[addr - 0x3F50] = value;
  76.                 if(addr >= 0x3F60 && addr < 0x3F70) bg_pal[addr - 0x3F60] = value;
  77.                 if(addr >= 0x3F70 && addr < 0x3F80) spr_pal[addr - 0x3F70] = value;
  78.         }
  79.  
  80.         uint8_t rb(uint16_t addr)
  81.         {
  82.                 if(addr >= 0 && addr < 0x1000) return pat0[addr];
  83.                 if(addr >= 0x1000 && addr < 0x2000) return pat1[addr - 0x1000];
  84.                 if(mapper == 0)
  85.                 {
  86.                         if(addr >= 0x2000 && addr < 0x23C0) return nt0[addr - 0x2000];
  87.                         if(addr >= 0x23C0 && addr < 0x2400) return at0[addr - 0x23C0];
  88.                         if(addr >= 0x2400 && addr < 0x27C0) return nt1[addr - 0x2400];
  89.                         if(addr >= 0x27C0 && addr < 0x2800) return at1[addr - 0x27C0];
  90.                         if(addr >= 0x2800 && addr < 0x2BC0) return nt0[addr - 0x2800];
  91.                         if(addr >= 0x2BC0 && addr < 0x2C00) return at0[addr - 0x2BC0];
  92.                         if(addr >= 0x2C00 && addr < 0x2FC0) return nt1[addr - 0x2C00];
  93.                         if(addr >= 0x2FC0 && addr < 0x3000) return at1[addr - 0x2FC0];
  94.                 }
  95.                 if(addr >= 0x3F00 && addr < 0x3F10) return bg_pal[addr - 0x3F00];
  96.                 if(addr >= 0x3F10 && addr < 0x3F20) return spr_pal[addr - 0x3F10];
  97.                 if(addr >= 0x3F20 && addr < 0x3F30) return bg_pal[addr - 0x3F20];
  98.                 if(addr >= 0x3F30 && addr < 0x3F40) return spr_pal[addr - 0x3F30];
  99.                 if(addr >= 0x3F40 && addr < 0x3F50) return bg_pal[addr - 0x3F40];
  100.                 if(addr >= 0x3F50 && addr < 0x3F60) return spr_pal[addr - 0x3F50];
  101.                 if(addr >= 0x3F60 && addr < 0x3F70) return bg_pal[addr - 0x3F60];
  102.                 if(addr >= 0x3F70 && addr < 0x3F80) return spr_pal[addr - 0x3F70];
  103.                 if(addr >= 0x3F80 && addr < 0x3F90) return bg_pal[addr - 0x3F80];
  104.                 if(addr >= 0x3F90 && addr < 0x3FA0) return spr_pal[addr - 0x3F90];
  105.         }
  106.  
  107.         void putpixel(uint8_t color,int x, int y)
  108.         {
  109.                 uint8_t *p = (uint8_t*)screen->pixels + ((y * 256 + x) * 3);
  110.  
  111.                 //printf("PPU color: %02x\n",color);
  112.  
  113.                 switch(color & 0x3F)
  114.                 {
  115.                         case 0x00:
  116.                         p[0] = 124;
  117.                         p[1] = 124;
  118.                         p[2] = 124;
  119.                         break;
  120.                         case 0x0C:
  121.                         p[0] = 88;
  122.                         p[1] = 64;
  123.                         p[2] = 0;
  124.                         break;
  125.                         case 0x0D:
  126.                         p[0] = 0;
  127.                         p[1] = 0;
  128.                         p[2] = 0;
  129.                         break;
  130.                         case 0x0E:
  131.                         p[0] = 0;
  132.                         p[1] = 0;
  133.                         p[2] = 0;
  134.                         break;
  135.                         case 0x0F:
  136.                         p[0] = 0;
  137.                         p[1] = 0;
  138.                         p[2] = 0;
  139.                         break;
  140.                         case 0x20:
  141.                         p[0] = 0xFF;
  142.                         p[1] = 0xFF;
  143.                         p[2] = 0xFF;
  144.                         case 0x21:
  145.                         p[0] = 252;
  146.                         p[1] = 188;
  147.                         p[2] = 60;
  148.                         case 0x22:
  149.                         p[0] = 252;
  150.                         p[1] = 136;
  151.                         p[2] = 104;
  152.                         case 0x30:
  153.                         p[0] = 0xFF;
  154.                         p[1] = 0xFF;
  155.                         p[2] = 0xFF;
  156.                 }
  157.         }
  158.  
  159.         void dumpscan()
  160.         {
  161.                 //printf("Scanline %i\n",scanline);
  162.                 //printf("Cycles %i\n",cycles);
  163.         }
  164.  
  165.         void tick()
  166.         {
  167.                 if(cycles_next > 0)
  168.                 {
  169.                         cycles_next--;
  170.                         return;
  171.                 }
  172.                 if(scanline >= 0 && scanline < 239)
  173.                 {
  174.                         if(cycles<255)
  175.                         {
  176.                                 uint8_t tile_num = rb(0x2000 + (((cycles + 1) >> 3) * ((scanline + 1) >> 3)));
  177.                                 uint8_t tile_pal = 0;
  178.                                 uint8_t tile_pat_0 = (rb((tile_num << 1) + 0x1000) & (1<<(cycles>>5))) >> (1<<(cycles>>5));
  179.                                 uint8_t tile_pat_1 = (rb((tile_num << 1) + 0x1001) & (1<<(cycles>>5))) >> (1<<(cycles>>5));
  180.                                 uint8_t tile_pat = tile_pat_0 | (tile_pat_1 << 1);
  181.                                 uint8_t tile_pix = rb(0x3F00 + tile_pat);
  182.                                 putpixel(tile_pix,cycles,scanline);
  183.                         }
  184.                 }
  185.                 if(scanline == 241 && cycles<=2)
  186.                 {
  187.                         nmi = 1;
  188.                 }
  189.                 else nmi = 0;
  190.                 if(scanline == 261 && cycles == 339)
  191.                 {
  192.                         printf("Frame complete.\n");
  193.                 }
  194.                 cycles++;
  195.                 if(cycles >= 340)
  196.                 {
  197.                         cycles = 0;
  198.                         scanline++;
  199.                 }
  200.                 if(scanline >= 262)
  201.                 {
  202.                         scanline = 0;
  203.                 }
  204.         }
  205. };
  206.  
  207. class CPU
  208. {
  209. public:
  210.         PPU ppu;
  211.         uint8_t mapper;
  212.         uint8_t PRGbanks;
  213.         uint8_t CHRbanks;
  214.         uint8_t ram[0x2000];
  215.         uint8_t ioregs[0x2020];
  216.         uint8_t exprom[0x1980];
  217.         uint8_t sram[0x2000];
  218.         uint8_t rom[0x8000];
  219.         uint8_t* totalrom;
  220.         uint8_t* chrrom;
  221.         uint16_t pc;
  222.         uint8_t a,x,y,s;
  223. /* Processor Status Register
  224.  * Bit 0 - Carry
  225.  * Bit 1 - Zero
  226.  * Bit 2 - Interrupt
  227.  * Bit 3 - Decimal Mode, not used in NES
  228.  * Bit 4 - Software Interrupts
  229.  * Bit 5 - 1
  230.  * Bit 6 - Overflow
  231.  * Bit 7 - Negative
  232.  */
  233.         uint8_t p;
  234.         uint16_t cycles;
  235.  
  236.         uint8_t rb(uint16_t addr)
  237.         {
  238.                 if(addr >= 0x0000 && addr < 0x2000)
  239.                 {
  240.                         return ram[addr];
  241.                 }
  242.                 if(addr >= 0x2000 && addr < 0x4020)
  243.                 {
  244.                         return ioregs[addr - 0x2000];
  245.                 }
  246.                 if(addr >= 0x4020 && addr < 0x6000)
  247.                 {
  248.                         return exprom[addr - 0x4020];
  249.                 }
  250.                 if(addr >= 0x6000 && addr < 0x8000)
  251.                 {
  252.                         return sram[addr - 0x6000];
  253.                 }
  254.                 if(addr >= 0x8000)
  255.                 {
  256.                         return rom[addr - 0x8000];
  257.                 }
  258.         }
  259.  
  260.         CPU()
  261.         {
  262.             a = 0x00;
  263.             x = 0x00;
  264.             y = 0x00;
  265.             s = 0xFD;
  266.             p = 0x34;
  267.             pc = 0x8000;
  268.         cycles = 0;
  269.         }
  270.         void CHRSwap4(uint8_t value, uint16_t addr)
  271.         {
  272.                 memcpy((addr>=0x1000) ? ppu.pat1 : ppu.pat0,chrrom + (value * 0x1000),0x1000);
  273.         }
  274.         void CHRSwap8(uint8_t value, uint16_t addr)
  275.         {
  276.                 memcpy(ppu.pat0,chrrom + (value * 0x1000),0x1000);
  277.                 memcpy(ppu.pat1,chrrom + (value * 0x1000) + 0x1000,0x1000);
  278.         }
  279.         void PRGSwap8(uint8_t value, uint16_t addr)
  280.         {
  281.                 memcpy(rom + (addr - 0x8000),totalrom + (value * 0x2000),0x2000);
  282.         }
  283.         void PRGSwap16(uint8_t value, uint16_t addr)
  284.         {
  285.                 memcpy(rom + (addr - 0x8000),totalrom + (value * 0x4000),0x4000);
  286.         }
  287.         void PRGSwap32(uint8_t value, uint16_t addr)
  288.         {
  289.                 memcpy(rom + (addr - 0x8000),totalrom + (value * 0x8000),0x8000);
  290.         }
  291.         void wb(uint16_t addr, uint8_t value)
  292.         {
  293.                 if(addr >= 0x0000 && addr < 0x2000)
  294.                 {
  295.                         ram[addr] = value;
  296.                 }
  297.                 if(addr >= 0x2000 && addr < 0x4020)
  298.                 {
  299.                         if(addr==0x2000){printf("PPU: CRTL0 write %02x\n",value); ppu.ctrl0 = value;}
  300.                         if(addr==0x2001){printf("PPU: CRTL1 write %02x\n",value); ppu.ctrl1 = value;}
  301.                         if(addr==0x2006){printf("PPU: ADDR write %02x\n",value); if(ppu.lohi == 0){ppu.addr &= 0xFF00; ppu.addr |= value;} else{ppu.addr &= 0xFF; ppu.addr |= (value<<8);} ppu.lohi = ~ppu.lohi;}
  302.                         if(addr==0x2007){printf("PPU: DATA write %02x to PPU address %04x\n",value, ppu.addr); ppu.wb(ppu.addr,value);}
  303.                         ioregs[addr - 0x2000] = value;
  304.                 }
  305.                 if(addr >= 0x4020 && addr < 0x6000)
  306.                 {
  307.                         exprom[addr - 0x4020] = value;
  308.                 }
  309.                 if(addr >= 0x6000 && addr < 0x8000)
  310.                 {
  311.                         sram[addr - 0x6000] = value;
  312.                 }
  313.                 if(addr >= 0x8000)
  314.                 {
  315.                         if(mapper == 0) return; //printf("Why am I trying to write to ROM?\n");
  316.                         else if(mapper == 2) PRGSwap16(value & 7,0x8000);
  317.                         else if(mapper == 3) CHRSwap8(value & 3,0);
  318.                         else if(mapper == 7) PRGSwap32(value & 15,0x8000); //TODO: Mirroring
  319.                         else if(mapper == 9)
  320.                         {
  321.                                 if(addr >= 0xA000 && addr < 0xB000) PRGSwap8(value,0x8000);
  322.                                 if(addr >= 0xB000 && addr < 0xD000) CHRSwap4(value,0x0000);
  323.                                 if(addr >= 0xD000 && addr < 0xE000) CHRSwap4(value,0x1000);
  324.                                 if(addr >= 0xE000 && addr < 0xF000) CHRSwap4(value,0x1000); //TODO: Mirroring
  325.                         }
  326.                         else if(mapper == 13) CHRSwap4(value & 3,0x1000);
  327.                         else if(mapper == 34) PRGSwap32(value & 3,0x8000);
  328.                         else if(mapper == 66)
  329.                         {
  330.                                 PRGSwap32(value & 0x30,0x8000);
  331.                                 CHRSwap8(value & 3,0x0000);
  332.                         }
  333.                         else if(mapper == 75)
  334.                         {
  335.                                 if(addr == 0x8000) PRGSwap8(value & 15,0x8000);
  336.                                 if(addr == 0xA000) PRGSwap8(value & 15,0xA000);
  337.                                 if(addr == 0xC000) PRGSwap8(value & 15,0xC000);
  338.                                 //TODO: CHR swapping
  339.                         }
  340.                         else if(mapper == 180) PRGSwap16(value & 7,0xC000);
  341.                 }
  342.         }
  343.         void LoadROM(FILE* fp)
  344.         {
  345.                 if(mapper == 0)
  346.                 {
  347.                         fseek(fp,0x10,SEEK_SET);
  348.                         if(PRGbanks == 2)
  349.                         {
  350.                                 fread(rom,1,0x8000,fp);
  351.                                 fread(chrrom,1,0x2000*CHRbanks,fp);
  352.                         }
  353.                         if(PRGbanks == 1) fread(rom+0x4000,1,0x4000,fp);
  354.                 }
  355.                 else if(mapper == 2)
  356.                 {
  357.                         uint8_t* rom_ptr = rom + 0x4000;
  358.                         fseek(fp,(PRGbanks - 1) * 0x4000,SEEK_SET);
  359.                         fread(rom_ptr,1,0x4000,fp);
  360.                         fseek(fp,0x10,SEEK_SET);
  361.                         fread(rom,1,0x4000,fp);
  362.                 }
  363.                 else if(mapper == 3)
  364.                 {
  365.                         fseek(fp,(PRGbanks * 0x4000) + 0x10,SEEK_SET);
  366.                         fread(ppu.pat0,1,0x2000,fp);
  367.                 }
  368.                 else if(mapper == 7)
  369.                 {
  370.                         fseek(fp,0x10,SEEK_SET);
  371.                         fread(rom,1,0x8000,fp);
  372.                 }
  373.                 else if(mapper == 13)
  374.                 {
  375.                         fseek(fp,(PRGbanks * 0x4000) + 0x10,SEEK_SET);
  376.                         fread(ppu.pat0,1,0x1000,fp);
  377.                         fread(ppu.pat1,1,0x1000,fp);
  378.                 }
  379.                 else if(mapper == 34)
  380.                 {
  381.                         fseek(fp,0x10,SEEK_SET);
  382.                         fread(rom,1,0x8000,fp);
  383.                 }
  384.                 else if(mapper == 66)
  385.                 {
  386.                         fseek(fp,0x10,SEEK_SET);
  387.                         fread(rom,1,0x8000,fp);
  388.                 }
  389.                 else if(mapper == 75)
  390.                 {
  391.                         uint8_t* rom_ptr = rom + 0x6000;
  392.                         fseek(fp,(PRGbanks - 1) * 0x2000,SEEK_SET);
  393.                         fread(rom_ptr,1,0x2000,fp);
  394.                         fseek(fp,0x10,SEEK_SET);
  395.                         fread(rom,1,0x6000,fp);
  396.                 }
  397.                 else if(mapper == 180)
  398.                 {
  399.                         fseek(fp,0x10,SEEK_SET);
  400.                         fread(rom,1,0x8000,fp);
  401.                 }
  402.         }
  403.         void dumpregs()
  404.         {
  405.                 //printf("a = %02x\n",a);
  406.                 //printf("x = %02x\n",x);
  407.                 //printf("y = %02x\n",y);
  408.                 //printf("s = %02x\n",s);
  409.                 //printf("p = %02x\n",p);
  410.                 //printf("pc = %04x\n",pc);
  411.         }
  412.         int tick()
  413.         {
  414.                 for(int i = 0;i<3;i++) ppu.tick();
  415.                 if(ppu.nmi == 1)
  416.                 {
  417.                         pc = (rb(0xFFFA) << 8) | rb(0xFFFB); //Read NMI vector
  418.                 }
  419.                 if(cycles != 0)
  420.                 {
  421.             cycles--;
  422.                         return 0;
  423.                 }
  424.                 else
  425.                 {
  426.                         uint8_t op = rb(pc);
  427.                         switch(op)
  428.                         {
  429.                                 case 0x00:
  430.                                         //printf("BRK\n");
  431.                                         pc = (rb(0xFFFE) << 8) | rb(0xFFFF); //Read BRK vector
  432.                                         cycles+=6;
  433.                                         break;
  434.                 case 0x01:
  435.                         //printf("ORA ($%02x,X)\n",rb(pc+1));
  436.                         a |= rb(rb(pc+1)+x);
  437.                                         if(a==0) p |= 2;
  438.                                         else p &= 0xFD;
  439.                                         if((a&0x80) == 0x80) p |= 0x80;
  440.                                         else p &= 0x7F;
  441.                                         cycles+=6;
  442.                                         pc+=2;
  443.                                         break;
  444.                                 case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2:
  445.                                         printf("KIL\n");
  446.                                         return 1;
  447.                                         break;
  448.                                 case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64: case 0x74: case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
  449.                                         //printf("NOP\n");
  450.                                         cycles+=1;
  451.                                         pc+=2;
  452.                                         break;
  453.                                 case 0x05:
  454.                                         //printf("ORA $%02x\n",rb(pc+1));
  455.                                         a |= rb(rb(pc+1));
  456.                                         if(a==0) p |= 2;
  457.                                         else p &= 0xFD;
  458.                                         if((a&0x80) == 0x80) p |= 0x80;
  459.                                         else p &= 0x7F;
  460.                                         cycles+=2;
  461.                                         pc+=2;
  462.                                         break;
  463.                                 case 0x06:
  464.                                 {
  465.                                         //printf("ASL $%02x\n",rb(pc+1));
  466.                                         p |= (rb(pc+1) & 0x80) >> 7;
  467.                                         wb(rb(pc+1),(rb(rb(pc+1)) << 1) & 0xFF);
  468.                                         int tmp = (rb(pc+1) << 1) & 0xFF;
  469.                                         if(tmp==0) p |= 2;
  470.                                         else p &= 0xFD;
  471.                                         if((tmp&0x80) == 0x80) p |= 0x80;
  472.                                         else p &= 0x7F;
  473.                                         cycles+=5;
  474.                                         pc+=2;
  475.                                         break;
  476.                                 }
  477.                                 case 0x07:
  478.                                 {
  479.                                         //printf("SLO $%02x\n",rb(pc+1));
  480.                                         p |= (rb(pc+1) & 0x80) >> 7;
  481.                                         wb(rb(pc+1),((rb(rb(pc+1)) << 1) & 0xFF) | a);
  482.                                         int tmp = ((rb(pc+1) << 1) & 0xFF) | a;
  483.                                         if(tmp==0) p |= 2;
  484.                                         else p &= 0xFD;
  485.                                         if((tmp&0x80) == 0x80) p |= 0x80;
  486.                                         else p &= 0x7F;
  487.                                         cycles+=5;
  488.                                         pc+=2;
  489.                                         break;
  490.                                 }
  491.                                 case 0x08:
  492.                                         //printf("PHP\n");
  493.                                         wb(s,p);
  494.                                         s-=1;
  495.                                         cycles+=2;
  496.                                         pc+=1;
  497.                                         break;
  498.                                 case 0x09:
  499.                                         //printf("ORA #$%02x\n",rb(pc+1));
  500.                                         a |= rb(pc+1);
  501.                                         if(a==0) p |= 2;
  502.                                         else p &= 0xFD;
  503.                                         if((a&0x80) == 0x80) p |= 0x80;
  504.                                         else p &= 0x7F;
  505.                                         cycles+=2;
  506.                                         pc+=2;
  507.                                         break;
  508.                                 case 0x0A:
  509.                                         //printf("ASL A\n");
  510.                                         p |= (a & 0x80) >> 7;
  511.                                         a = a << 1;
  512.                                         if(a==0) p |= 2;
  513.                                         else p &= 0xFD;
  514.                                         if((a&0x80) == 0x80) p |= 0x80;
  515.                                         else p &= 0x7F;
  516.                                         cycles+=2;
  517.                                         pc+=1;
  518.                                         break;
  519.                                 case 0x10:
  520.                                         //printf("BPL #$%02x\n",rb(pc+1));
  521.                                         cycles+=2;
  522.                                         if((p & 0x80) != 0x80)
  523.                                         {
  524.                                                 cycles+=1;
  525.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  526.                                                 pc += (int8_t)rb(pc+1);
  527.                                                 pc += 2;
  528.                                         }
  529.                                         else pc+=2;
  530.                                         break;
  531.                                 case 0x18:
  532.                                         //printf("CLC\n");
  533.                                         p &= 0xFE;
  534.                                         cycles+=2;
  535.                                         pc+=1;
  536.                                         break;
  537.                                 case 0x20:
  538.                                         //printf("JSR $%04x\n",(rb(pc+2)<<8) | rb(pc+1));
  539.                                         wb((s-2) | 0x100,pc+2);
  540.                                         wb((s-1) | 0x100,pc+2>>8);
  541.                                         s-=2;
  542.                                         cycles+=6;
  543.                                         pc=(rb(pc+2)<<8) | rb(pc+1);
  544.                                         break;
  545.                                 case 0x24:
  546.                                         //printf("BIT $%02x\n", rb(pc+1));
  547.                                         if((a & rb(rb(pc+1))) == 0) p |= 2;
  548.                                         else p &= 0xFD;
  549.                                         p &= 0x3F;
  550.                                         p |= rb(rb(pc+1)) & 0xC0;
  551.                                         cycles+=2;
  552.                                         pc+=2;
  553.                                         break;
  554.                                 case 0x28:
  555.                                         //printf("PLP\n");
  556.                                         p = rb(s+1);
  557.                                         s+=1;
  558.                                         cycles+=4;
  559.                                         pc+=1;
  560.                                         break;
  561.                                 case 0x29:
  562.                                         //printf("AND #$%02x\n",rb(pc+1));
  563.                                         a &= rb(pc+1);
  564.                                         if(a==0) p |= 2;
  565.                                         else p &= 0xFD;
  566.                                         if((a&0x80) == 0x80) p |= 0x80;
  567.                                         else p &= 0x7F;
  568.                                         cycles+=2;
  569.                                         pc+=2;
  570.                                         break;
  571.                                 case 0x2C:
  572.                                         //printf("BIT $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  573.                                         if((a & rb((rb(pc+2)<<8) | rb(pc+1))) == 0) p |= 2;
  574.                                         else p &= 0xFD;
  575.                                         p |= rb((rb(pc+2)<<8) | rb(pc+1)) & 0xC0;
  576.                                         cycles+=4;
  577.                                         pc+=3;
  578.                                         break;
  579.                                 case 0x30:
  580.                                         //printf("BMI $%02x\n",rb(pc+1));
  581.                                         cycles+=2;
  582.                                         if((p & 0x80) == 0x80)
  583.                                         {
  584.                                                 cycles+=1;
  585.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  586.                                                 pc += (int8_t)rb(pc+1);
  587.                                                 pc += 2;
  588.                                         }
  589.                                         else pc+=2;
  590.                                         break;
  591.                                 case 0x38:
  592.                                         //printf("SEC\n");
  593.                                         p |= 0x01;
  594.                                         cycles+=2;
  595.                                         pc+=1;
  596.                                         break;
  597.                                 case 0x46:
  598.                                     //printf("LSR $%02x\n", rb(pc+1));
  599.                                         if((rb(rb(pc+1)) & 0x01) == 0) p |= 2;
  600.                                         else p &= 0xFD;
  601.                                         if((rb(rb(pc+1)) & 0x80) == 0x80) p |= 0x80;
  602.                                         else p &= 0x7F;
  603.                                         wb(rb(pc+1),rb(rb(pc+1))>>1);
  604.                                         cycles+=5;
  605.                                         pc+=2;
  606.                                         break;
  607.                                 case 0x48:
  608.                                         //printf("PHA\n");
  609.                                         wb(s,a);
  610.                                         s-=1;
  611.                                         cycles+=2;
  612.                                         pc+=1;
  613.                                         break;
  614.                                 case 0x49:
  615.                                         //printf("EOR #$%02x\n",rb(pc+1));
  616.                                         a ^= rb(pc+1);
  617.                                         if(a==0) p |= 2;
  618.                                         else p &= 0xFD;
  619.                                         if((a&0x80) == 0x80) p |= 0x80;
  620.                                         else p &= 0x7F;
  621.                                         cycles+=2;
  622.                                         pc+=2;
  623.                                         break;
  624.                                 case 0x4A:
  625.                                     //printf("LSR A\n");
  626.                                         if((a & 0x01) == 0) p |= 2;
  627.                                         else
  628.                                         {
  629.                                                 p &= 0xFD;
  630.                                                 p |= 1;
  631.                                         }
  632.                                         if((a & 0x80) == 0x80) p |= 0x80;
  633.                                         else p &= 0x7F;
  634.                                         a = a>>1;
  635.                                         cycles+=2;
  636.                                         pc+=1;
  637.                                         break;
  638.                                 case 0x4C:
  639.                                         //printf("JMP $%04x\n",(rb(pc+2)<<8) | rb(pc+1));
  640.                                         cycles+=3;
  641.                                         pc=(rb(pc+2)<<8) | rb(pc+1);
  642.                                         break;
  643.                                 case 0x50:
  644.                                     //printf("BVC $%02x\n",rb(pc+1));
  645.                                         cycles+=2;
  646.                                         if((p & 0x40) == 0)
  647.                                         {
  648.                                                 cycles+=1;
  649.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  650.                                                 pc += (int8_t)rb(pc+1);
  651.                                                 pc += 2;
  652.                                         }
  653.                                         else pc+=2;
  654.                                     break;
  655.                                 case 0x60:
  656.                                         //printf("RTS\n");
  657.                                         pc = (((rb((s+1) | 0x100)<<8) | rb(s | 0x100)) + 1);
  658.                                         s+=2;
  659.                                         cycles+=6;
  660.                                         break;
  661.                                 case 0x65:
  662.                                         //printf("ADC $%02x\n",rb(pc+1));
  663.                                         a += (p&1) + rb(rb(pc+1));
  664.                                         if(a==0) p |= 2;
  665.                                         else p &= 0xFD;
  666.                                         if((a&0x80) == 0x80) p |= 0x80;
  667.                                         else p &= 0x7F;
  668.                                         cycles+=4;
  669.                                         if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  670.                                         pc+=2;
  671.                                         break;
  672.                                 case 0x68:
  673.                                         //printf("PLA\n");
  674.                                         a = rb(s+1);
  675.                                         s+=1;
  676.                                         if(a==0) p |= 2;
  677.                                         else p &= 0xFD;
  678.                                         if((a&0x80) == 0x80) p |= 0x80;
  679.                                         else p &= 0x7F;
  680.                                         cycles+=4;
  681.                                         pc+=1;
  682.                                         break;
  683.                                 case 0x69:
  684.                                 {
  685.                                         //printf("ADC #$%02x\n",rb(pc+1));
  686.                                         uint8_t tmp = a;
  687.                                         a += (p&1) + rb(pc+1);
  688.                                         if(a==0) p |= 2;
  689.                                         else p &= 0xFD;
  690.                                         if((a&0x80) == 0x80) p |= 0x80;
  691.                                         else p &= 0x7F;
  692.                                         if(a>=0x80) p |= 0x40;
  693.                                         else p &= 0xBF;
  694.                                         if(a<tmp) p |= 1;
  695.                                         else p &= 0xFE;
  696.                                         cycles+=1;
  697.                                         pc+=2;
  698.                                         break;
  699.                                 }
  700.                                 case 0x6C:
  701.                                 {
  702.                                         uint16_t tmp = (rb(pc+2)<<8) | rb(pc+1);
  703.                                         //printf("JMP ($%04x)\n",(rb(pc+2)<<8) | rb(pc+1));
  704.                                         cycles+=5;
  705.                                         pc = (rb(tmp)<<8) | rb(tmp+1);
  706.                                         break;
  707.                                 }
  708.                                 case 0x70:
  709.                                     //printf("BVS $%02x\n",rb(pc+1));
  710.                                         cycles+=2;
  711.                                         if((p & 0x40) == 0x40)
  712.                                         {
  713.                                                 cycles+=1;
  714.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  715.                                                 pc += (int8_t)rb(pc+1);
  716.                                                 pc += 2;
  717.                                         }
  718.                                         else pc+=2;
  719.                                     break;
  720.                                 case 0x78:
  721.                                         //printf("SEI\n");
  722.                                         p |= 0x08;
  723.                                         cycles+=2;
  724.                                         pc+=1;
  725.                                         break;
  726.                                 case 0x79:
  727.                                         //printf("ADC $%04x,Y\n",(rb(pc+2)<<8) | rb(pc+1));
  728.                                         a += (p&1) + rb(((rb(pc+2)<<8) | rb(pc+1)) + y);
  729.                                         if(a==0) p |= 2;
  730.                                         else p &= 0xFD;
  731.                                         if((a&0x80) == 0x80) p |= 0x80;
  732.                                         else p &= 0x7F;
  733.                                         cycles+=4;
  734.                                         if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  735.                                         pc+=3;
  736.                                         break;
  737.                                 case 0x85:
  738.                             //printf("STA $%02x\n",rb(pc+1));
  739.                             wb((uint16_t)rb(pc+1),a);
  740.                             cycles+=3;
  741.                             pc+=2;
  742.                             break;
  743.                                 case 0x86:
  744.                             //printf("STX $%02x\n",rb(pc+1));
  745.                             wb((uint16_t)rb(pc+1),x);
  746.                             cycles+=3;
  747.                             pc+=2;
  748.                             break;
  749.                                 case 0x88:
  750.                                         //printf("DEY\n");
  751.                                         y--;
  752.                                         if(y==0) p |= 2;
  753.                                         else p &= 0xFD;
  754.                                         if((y&0x80) == 0x80) p |= 0x80;
  755.                                         else p &= 0x7F;
  756.                                         cycles+=2;
  757.                                         pc+=1;
  758.                                         break;
  759.                                 case 0x8A:
  760.                                         //printf("TXA\n");
  761.                                         a = x;
  762.                                         if(a==0) p |= 2;
  763.                                         else p &= 0xFD;
  764.                                         if((a&0x80) == 0x80) p |= 0x80;
  765.                                         else p &= 0x7F;
  766.                                         cycles+=2;
  767.                                         pc+=1;
  768.                                         break;
  769.                                 case 0x8C:
  770.                                     //printf("STY $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  771.                                     wb((rb(pc+2)<<8) | rb(pc+1),y);
  772.                                     cycles+=4;
  773.                                     pc+=3;
  774.                                     break;
  775.                                 case 0x8D:
  776.                                     //printf("STA $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  777.                                     wb((rb(pc+2)<<8) | rb(pc+1),a);
  778.                                     cycles+=4;
  779.                                     pc+=3;
  780.                                     break;
  781.                                 case 0x8E:
  782.                                     //printf("STX $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  783.                                     wb((rb(pc+2)<<8) | rb(pc+1),x);
  784.                                     cycles+=4;
  785.                                     pc+=3;
  786.                                     break;
  787.                                 case 0x90:
  788.                                     //printf("BCC $%02x\n",rb(pc+1));
  789.                                         cycles+=2;
  790.                                         if((p & 1) != 1)
  791.                                         {
  792.                                                 cycles+=1;
  793.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  794.                                                 pc += (int8_t)rb(pc+1);
  795.                                                 pc += 2;
  796.                                         }
  797.                                         else pc+=2;
  798.                                     break;
  799.                                 case 0x91:
  800.                                         //printf("STA $%02x\n", rb(pc+1));
  801.                                         wb((uint16_t)rb(pc+1) + y,a);
  802.                                         cycles+=6;
  803.                                         pc+=2;
  804.                                         break;
  805.                                 case 0x95:
  806.                             //printf("STA $%02x,X\n",rb(pc+1));
  807.                             wb((uint16_t)rb(pc+1)+x,a);
  808.                             cycles+=3;
  809.                             pc+=2;
  810.                             break;
  811.                                 case 0x98:
  812.                                         //printf("TYA\n");
  813.                                         a = y;
  814.                                         if(a==0) p |= 2;
  815.                                         else p &= 0xFD;
  816.                                         if((a&0x80) == 0x80) p |= 0x80;
  817.                                         else p &= 0x7F;
  818.                                         cycles+=2;
  819.                                         pc+=1;
  820.                                         break;
  821.                                 case 0x99:
  822.                                     //printf("STA $%04x,Y\n", (rb(pc+2)<<8) | rb(pc+1));
  823.                                     wb(((rb(pc+2)<<8) | rb(pc+1)) + y,a);
  824.                                     cycles+=5;
  825.                                     pc+=3;
  826.                                     break;
  827.                                 case 0x9A:
  828.                                         //printf("TXS\n");
  829.                                         s = x;
  830.                                         cycles+=2;
  831.                                         pc+=1;
  832.                                         break;
  833.                                 case 0x9D:
  834.                                     //printf("STA $%04x,X\n", (rb(pc+2)<<8) | rb(pc+1));
  835.                                     wb(((rb(pc+2)<<8) | rb(pc+1)) + x,a);
  836.                                     cycles+=5;
  837.                                     pc+=3;
  838.                                     break;
  839.                                 case 0xA0:
  840.                                         //printf("LDY #$%02x\n", rb(pc+1));
  841.                                         y = rb(pc+1);
  842.                                         if(y==0) p |= 2;
  843.                                         else p &= 0xFD;
  844.                                         if((y&0x80) == 0x80) p |= 0x80;
  845.                                         else p &= 0x7F;
  846.                                         cycles+=2;
  847.                                         pc+=2;
  848.                                         break;
  849.                                 case 0xA2:
  850.                                         //printf("LDX #$%02x\n", rb(pc+1));
  851.                                         x = rb(pc+1);
  852.                                         if(x==0) p |= 2;
  853.                                         else p &= 0xFD;
  854.                                         if((x&0x80) == 0x80) p |= 0x80;
  855.                                         else p &= 0x7F;
  856.                                         cycles+=2;
  857.                                         pc+=2;
  858.                                         break;
  859.                                 case 0xA4:
  860.                                         //printf("LDY $%02x\n",rb(pc+1));
  861.                                         y = rb(rb(pc+1));
  862.                                         if(y==0) p |= 2;
  863.                                         else p &= 0xFD;
  864.                                         if((y&0x80) == 0x80) p |= 0x80;
  865.                                         else p &= 0x7F;
  866.                                         if(y <= 0x80) p |= 0x80;
  867.                                         if(y == 0x00) p &= 0x7F;
  868.                                         cycles+=4;
  869.                                         pc+=2;
  870.                                         break;
  871.                                 case 0xA5:
  872.                                         //printf("LDA $%02x\n", rb(pc+1));
  873.                                         a = rb(pc+1);
  874.                                         if(a==0) p |= 2;
  875.                                         else p &= 0xFD;
  876.                                         if((a&0x80) == 0x80) p |= 0x80;
  877.                                         else p &= 0x7F;
  878.                                         if(a <= 0x80) p |= 0x80;
  879.                                         if(a == 0x00) p &= 0x7F;
  880.                                         cycles+=2;
  881.                                         pc+=2;
  882.                                         break;
  883.                                 case 0xA6:
  884.                                         //printf("LDX $%02x\n", rb(pc+1));
  885.                                         x = rb(pc+1);
  886.                                         if(x==0) p |= 2;
  887.                                         else p &= 0xFD;
  888.                                         if((x&0x80) == 0x80) p |= 0x80;
  889.                                         else p &= 0x7F;
  890.                                         if(x <= 0x80) p |= 0x80;
  891.                                         if(x == 0x00) p &= 0x7F;
  892.                                         cycles+=2;
  893.                                         pc+=2;
  894.                                         break;
  895.                                 case 0xA8:
  896.                                         //printf("TAY\n");
  897.                                         y = a;
  898.                                         if(y==0) p |= 2;
  899.                                         else p &= 0xFD;
  900.                                         if((y&0x80) == 0x80) p |= 0x80;
  901.                                         else p &= 0x7F;
  902.                                         cycles+=2;
  903.                                         pc+=1;
  904.                                         break;
  905.                                 case 0xA9:
  906.                                         //printf("LDA #$%02x\n", rb(pc+1));
  907.                                         a = rb(pc+1);
  908.                                         if(a==0) p |= 2;
  909.                                         else p &= 0xFD;
  910.                                         if((a&0x80) == 0x80) p |= 0x80;
  911.                                         else p &= 0x7F;
  912.                                         cycles+=2;
  913.                                         pc+=2;
  914.                                         break;
  915.                                 case 0xAA:
  916.                                         //printf("TAX\n");
  917.                                         x = a;
  918.                                         if(x==0) p |= 2;
  919.                                         else p &= 0xFD;
  920.                                         if((x&0x80) == 0x80) p |= 0x80;
  921.                                         else p &= 0x7F;
  922.                                         cycles+=2;
  923.                                         pc+=1;
  924.                                         break;
  925.                                 case 0xAC:
  926.                                         //printf("LDY $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  927.                                         y = rb((rb(pc+2)<<8) | rb(pc+1));
  928.                                         if(y==0) p |= 2;
  929.                                         else p &= 0xFD;
  930.                                         if((y&0x80) == 0x80) p |= 0x80;
  931.                                         else p &= 0x7F;
  932.                                         if(y <= 0x80) p |= 0x80;
  933.                                         if(y == 0x00) p &= 0x7F;
  934.                                         cycles+=4;
  935.                                         pc+=3;
  936.                                         break;
  937.                                 case 0xAD:
  938.                                         //printf("LDA $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  939.                                         a = rb((rb(pc+2)<<8) | rb(pc+1));
  940.                                         if(a==0) p |= 2;
  941.                                         else p &= 0xFD;
  942.                                         if((a&0x80) == 0x80) p |= 0x80;
  943.                                         else p &= 0x7F;
  944.                                         if(a <= 0x80) p |= 0x80;
  945.                                         if(a == 0x00) p &= 0x7F;
  946.                                         cycles+=4;
  947.                                         pc+=3;
  948.                                         break;
  949.                                 case 0xAE:
  950.                                         //printf("LDX $%04x\n", (rb(pc+2)<<8) | rb(pc+1));
  951.                                         x = rb((rb(pc+2)<<8) | rb(pc+1));
  952.                                         if(x==0) p |= 2;
  953.                                         else p &= 0xFD;
  954.                                         if((x&0x80) == 0x80) p |= 0x80;
  955.                                         else p &= 0x7F;
  956.                                         if(x <= 0x80) p |= 0x80;
  957.                                         if(x == 0x00) p &= 0x7F;
  958.                                         cycles+=4;
  959.                                         pc+=3;
  960.                                         break;
  961.                                 case 0xB0:
  962.                                         //printf("BCS $%02x\n",rb(pc+1));
  963.                                         cycles+=2;
  964.                                         if((p & 1) != 0)
  965.                                         {
  966.                                                 cycles+=1;
  967.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  968.                                                 pc += (int8_t)rb(pc+1);
  969.                                                 pc += 2;
  970.                                         }
  971.                                         else pc+=2;
  972.                                         break;
  973.                                         case 0xB1:
  974.                                         //printf("LDA ($%02x),Y\n", rb(pc+1));
  975.                                         a = rb(rb(pc+1) + y);
  976.                                         if(a==0) p |= 2;
  977.                                         else p &= 0xFD;
  978.                                         if((a&0x80) == 0x80) p |= 0x80;
  979.                                         else p &= 0x7F;
  980.                                         if(a <= 0x80) p |= 0x80;
  981.                                         if(a == 0x00) p &= 0x7F;
  982.                                         cycles+=4;
  983.                                         if((pc & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  984.                                         pc+=2;
  985.                                         break;
  986.                                 case 0xB4:
  987.                                         //printf("LDY $%02x,X\n",rb(pc+1));
  988.                                         y = rb(rb(pc+1)+x);
  989.                                         if(y==0) p |= 2;
  990.                                         else p &= 0xFD;
  991.                                         if((y&0x80) == 0x80) p |= 0x80;
  992.                                         else p &= 0x7F;
  993.                                         if(y <= 0x80) p |= 0x80;
  994.                                         if(y == 0x00) p &= 0x7F;
  995.                                         cycles+=3;
  996.                                         pc+=2;
  997.                                         break;
  998.                                 case 0xB5:
  999.                                         //printf("LDA $%02x,X\n", rb(pc+1));
  1000.                                         a = rb(rb(pc+1)+x);
  1001.                                         if(a==0) p |= 2;
  1002.                                         else p &= 0xFD;
  1003.                                         if((a&0x80) == 0x80) p |= 0x80;
  1004.                                         else p &= 0x7F;
  1005.                                         if(a <= 0x80) p |= 0x80;
  1006.                                         if(a == 0x00) p &= 0x7F;
  1007.                                         cycles+=4;
  1008.                                         pc+=2;
  1009.                                         break;
  1010.                                 case 0xB8:
  1011.                                         //printf("CLV\n");
  1012.                                         p &= 0xBF;
  1013.                                         cycles+=2;
  1014.                                         pc+=1;
  1015.                                         break;
  1016.                                  case 0xB9:
  1017.                                     //printf("LDA $%04x,Y\n",(rb(pc+2)<<8) | rb(pc+1));
  1018.                                         a = rb(((rb(pc+2)<<8) | rb(pc+1)) + y);
  1019.                                         cycles+=4;
  1020.                                         if((pc & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  1021.                                         pc+=3;
  1022.                                         break;
  1023.                                 case 0xBA:
  1024.                                         //printf("TSX\n");
  1025.                                         x = s;
  1026.                                         cycles+=2;
  1027.                                         pc+=1;
  1028.                                         break;
  1029.                                 case 0xBC:
  1030.                                         //printf("LDY $%04x,X\n", (rb(pc+2)<<8) | rb(pc+1));
  1031.                                         y = rb(((rb(pc+2)<<8) | rb(pc+1))+x);
  1032.                                         if(y==0) p |= 2;
  1033.                                         else p &= 0xFD;
  1034.                                         if((y&0x80) == 0x80) p |= 0x80;
  1035.                                         else p &= 0x7F;
  1036.                                         if(y <= 0x80) p |= 0x80;
  1037.                                         if(y == 0x00) p &= 0x7F;
  1038.                                         cycles+=4;
  1039.                                         pc+=3;
  1040.                                         break;
  1041.                                 case 0xBD:
  1042.                                         //printf("LDA $%04x,X\n",(rb(pc+2)<<8) | rb(pc+1));
  1043.                                         a = rb(((rb(pc+2)<<8) | rb(pc+1)) + x);
  1044.                                         cycles+=4;
  1045.                                         if((pc & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  1046.                                         pc+=3;
  1047.                                         break;
  1048.                                 case 0xBE:
  1049.                                         //printf("LDX $%04x,Y\n", (rb(pc+2)<<8) | rb(pc+1));
  1050.                                         x = rb(((rb(pc+2)<<8) | rb(pc+1))+y);
  1051.                                         if(x==0) p |= 2;
  1052.                                         else p &= 0xFD;
  1053.                                         if((x&0x80) == 0x80) p |= 0x80;
  1054.                                         else p &= 0x7F;
  1055.                                         if(x <= 0x80) p |= 0x80;
  1056.                                         if(x == 0x00) p &= 0x7F;
  1057.                                         cycles+=4;
  1058.                                         if((pc & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  1059.                                         pc+=3;
  1060.                                         break;
  1061.                                 case 0xC0:
  1062.                                         //printf("CPY #$%02x\n",rb(pc+1));
  1063.                                         if((y - rb(pc+1)) == 0) p |= 2;
  1064.                                         else p &= 0xFD;
  1065.                                         if(((y - rb(pc+1)) & 0xFF) >= 0x80) p |= 0x80;
  1066.                                         else p &= 0x7F;
  1067.                                         if((y >= rb(pc+1))) p |= 1;
  1068.                                         else p &= 0xFE;
  1069.                                         cycles+=2;
  1070.                                         pc+=2;
  1071.                                         break;
  1072.                                 case 0xC8:
  1073.                                         //printf("INY\n");
  1074.                                         y++;
  1075.                                         if(y==0) p |= 2;
  1076.                                         else p &= 0xFD;
  1077.                                         if((y&0x80) == 0x80) p |= 0x80;
  1078.                                         else p &= 0x7F;
  1079.                                         cycles+=2;
  1080.                                         pc+=1;
  1081.                                         break;
  1082.                                 case 0xC9:
  1083.                                         //printf("CMP #$%02x\n",rb(pc+1));
  1084.                                         if((a - rb(pc+1)) == 0) p |= 2;
  1085.                                         else p &= 0xFD;
  1086.                                         if(((a - rb(pc+1)) & 0xFF) >= 0x80) p |= 0x80;
  1087.                                         else p &= 0x7F;
  1088.                                         if((a >= rb(pc+1))) p |= 1;
  1089.                                         else p &= 0xFE;
  1090.                                         cycles+=2;
  1091.                                         pc+=2;
  1092.                                         break;
  1093.                                 case 0xCA:
  1094.                                         //printf("DEX\n");
  1095.                                         x--;
  1096.                                         if(x==0) p |= 2;
  1097.                                         else p &= 0xFD;
  1098.                                         if((x&0x80) == 0x80) p |= 0x80;
  1099.                                         else p &= 0x7F;
  1100.                                         cycles+=2;
  1101.                                         pc+=1;
  1102.                                         break;
  1103.                                 case 0xCC:
  1104.                                     //printf("CPY $%04x\n",(rb(pc+2)<<8) | rb(pc+1));
  1105.                                         if((y - ((rb(pc+2)<<8) | rb(pc+1))) == 0) p |= 2;
  1106.                                         else p &= 0xFD;
  1107.                                         if(y >= 0x80) p |= 0x80;
  1108.                                         else p &= 0x7F;
  1109.                                         if((y >= ((rb(pc+2)<<8) | rb(pc+1)))) p |= 1;
  1110.                                         else p &= 0xFE;
  1111.                                         cycles+=2;
  1112.                                         pc+=3;
  1113.                                     break;
  1114.                                 case 0xD0:
  1115.                                         //printf("BNE $%02x\n",rb(pc+1));
  1116.                                         cycles+=2;
  1117.                                         if((p & 2) == 0)
  1118.                                         {
  1119.                                                 cycles+=1;
  1120.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  1121.                                                 pc += (int8_t)rb(pc+1);
  1122.                                                 pc += 2;
  1123.                                         }
  1124.                                         else pc+=2;
  1125.                                         break;
  1126.                                 case 0xD8:
  1127.                                         //printf("CLD\n");
  1128.                                         p &= 0xF7;
  1129.                                         cycles+=2;
  1130.                                         pc+=1;
  1131.                                         break;
  1132.                                 case 0xDE:
  1133.                                         //printf("DEC $%04x,X\n",(rb(pc+2)<<8) | rb(pc+1));
  1134.                                         wb((rb(pc+2)<<8) | rb(pc+1),rb((rb(pc+2)<<8) | rb(pc+1))+1);
  1135.                                         if((rb((rb(pc+2)<<8) | rb(pc+1)))==0) p |= 2;
  1136.                                         else p &= 0xFD;
  1137.                                         if(((rb((rb(pc+2)<<8) | rb(pc+1)))&0x80) == 0x80) p |= 0x80;
  1138.                                         else p &= 0x7F;
  1139.                                         cycles+=6;
  1140.                                         pc+=3;
  1141.                                         break;
  1142.                                 case 0xE0:
  1143.                                         //printf("CPX #$%02x\n",rb(pc+1));
  1144.                                         if((x - rb(pc+1)) == 0) p |= 2;
  1145.                                         else p &= 0xFD;
  1146.                                         if(((x - rb(pc+1)) & 0xFF) >= 0x80) p |= 0x80;
  1147.                                         else p &= 0x7F;
  1148.                                         if((x >= rb(pc+1))) p |= 1;
  1149.                                         else p &= 0xFE;
  1150.                                         cycles+=2;
  1151.                                         pc+=2;
  1152.                                         break;
  1153.                                 case 0xE8:
  1154.                                         //printf("INX\n");
  1155.                                         x++;
  1156.                                         if(x==0) p |= 2;
  1157.                                         else p &= 0xFD;
  1158.                                         if((x&0x80) == 0x80) p |= 0x80;
  1159.                                         else p &= 0x7F;
  1160.                                         cycles+=2;
  1161.                                         pc+=1;
  1162.                                         break;
  1163.                                 case 0xE9:
  1164.                                 {
  1165.                                         uint8_t tmp = a;
  1166.                                         //printf("SBC #$%02x\n",rb(pc+1));
  1167.                                         a = a + ~rb(pc+1) + (p&1);
  1168.                                         if(tmp>=a) p |= 1;
  1169.                                         else p &= 0xFE;
  1170.                                         if(a==0) p |= 2;
  1171.                                         else p &= 0xFD;
  1172.                                         if((tmp ^ rb(pc+1)) & (tmp ^ a) & 0x80) p |= 0x40;
  1173.                                         else p &= 0xBF;
  1174.                                         if((a&0x80) == 0x80) p |= 0x80;
  1175.                                         else p &= 0x7F;
  1176.                                         cycles+=4;
  1177.                                         pc+=2;
  1178.                                         break;
  1179.                                 }
  1180.                                 case 0xEA:
  1181.                                         //printf("NOP\n");
  1182.                                         cycles+=2;
  1183.                                         pc+=1;
  1184.                                         break;
  1185.                                 case 0xED:
  1186.                                         //printf("SBC $%04x\n",(rb(pc+2)<<8) | rb(pc+1));
  1187.                                         a -= (p&1) + rb(((rb(pc+2)<<8) | rb(pc+1)));
  1188.                                         if(a==0) p |= 2;
  1189.                                         else p &= 0xFD;
  1190.                                         if((a&0x80) == 0x80) p |= 0x80;
  1191.                                         else p &= 0x7F;
  1192.                                         cycles+=4;
  1193.                                         pc+=3;
  1194.                                         break;
  1195.                                 case 0xEE:
  1196.                                         //printf("INC $%04x\n",(rb(pc+2)<<8) | rb(pc+1));
  1197.                                         wb((rb(pc+2)<<8) | rb(pc+1),rb((rb(pc+2)<<8) | rb(pc+1))+1);
  1198.                                         if((rb((rb(pc+2)<<8) | rb(pc+1)))==0) p |= 2;
  1199.                                         else p &= 0xFD;
  1200.                                         if(((rb((rb(pc+2)<<8) | rb(pc+1)))&0x80) == 0x80) p |= 0x80;
  1201.                                         else p &= 0x7F;
  1202.                                         cycles+=6;
  1203.                                         pc+=3;
  1204.                                         break;
  1205.                                 case 0xF0:
  1206.                                         //printf("BEQ $%02x\n",rb(pc+1));
  1207.                                         cycles+=2;
  1208.                                         if((p & 2) == 2)
  1209.                                         {
  1210.                                                 cycles+=1;
  1211.                                                 if((((pc) + (int8_t)rb(pc+1)) & 0xFF00) != ((pc+2) & 0xFF00)) cycles+=1;
  1212.                                                 pc += (int8_t)rb(pc+1);
  1213.                                                 pc += 2;
  1214.                                         }
  1215.                                         else pc+=2;
  1216.                                         break;
  1217.                                 case 0xF5:
  1218.                                         //printf("SBC $%02x,X\n",(rb(pc+2)<<8) | rb(pc+1));
  1219.                                         a -= (p&1) + rb(rb(pc+1)+x);
  1220.                                         if(a==0) p |= 2;
  1221.                                         else p &= 0xFD;
  1222.                                         if((a&0x80) == 0x80) p |= 0x80;
  1223.                                         else p &= 0x7F;
  1224.                                         cycles+=4;
  1225.                                         pc+=2;
  1226.                                         break;
  1227.                                 case 0xF6:
  1228.                                         //printf("INC $%02x,X\n",rb(pc+1));
  1229.                                         wb(rb(pc+1),rb(rb(pc+1))+1);
  1230.                                         if((rb(rb(pc+1)))==0) p |= 2;
  1231.                                         else p &= 0xFD;
  1232.                                         if(((rb(rb(pc+1)))&0x80) == 0x80) p |= 0x80;
  1233.                                         else p &= 0x7F;
  1234.                                         cycles+=6;
  1235.                                         pc+=2;
  1236.                                         break;
  1237.                                 case 0xF8:
  1238.                                         //printf("SED\n");
  1239.                                         p |= 8;
  1240.                                         cycles+=2;
  1241.                                         pc+=1;
  1242.                                         break;
  1243.                                 case 0xF9:
  1244.                                         //printf("SBC $%04x,Y\n",(rb(pc+2)<<8) | rb(pc+1));
  1245.                                         a -= (p&1) + rb(((rb(pc+2)<<8) | rb(pc+1))+y);
  1246.                                         if(a==0) p |= 2;
  1247.                                         else p &= 0xFD;
  1248.                                         if((a&0x80) == 0x80) p |= 0x80;
  1249.                                         else p &= 0x7F;
  1250.                                         cycles+=4;
  1251.                                         pc+=3;
  1252.                                         break;
  1253.                                 default:
  1254.                                         printf("Unsupported opcode %02x. Aborting!\n",op);
  1255.                         return 1;
  1256.                                         break;
  1257.                         }
  1258.                         //dumpregs();
  1259.             return 0;
  1260.                 }
  1261.         }
  1262. };
  1263.  
  1264. void banner()
  1265. {
  1266.     //printf("MSE NES driver version v1:\n\n");
  1267.     //printf("Written by Alegend45\n\n\n");
  1268. }
  1269.  
  1270. int main(int ac, char** av)
  1271. {
  1272.     banner();
  1273.     FILE* fp = fopen(av[1],"rb");
  1274.     CPU a;
  1275.  
  1276.     if(fp != NULL)
  1277.     {
  1278.                 fseek(fp,4,SEEK_SET);
  1279.                 a.PRGbanks = fgetc(fp);
  1280.                 a.CHRbanks = fgetc(fp);
  1281.                 fseek(fp,6,SEEK_SET);
  1282.                 a.mapper = fgetc(fp) >> 4;
  1283.                 a.mapper |= fgetc(fp) & 0xF0;
  1284.                 a.ppu.mapper = a.mapper;
  1285.                 fseek(fp,0,SEEK_END);
  1286.                 long pos = ftell(fp);
  1287.                 a.totalrom = (uint8_t*)malloc(pos - 0x10);
  1288.                 a.chrrom = (uint8_t*)malloc(pos - 0x10);
  1289.                 a.LoadROM(fp);
  1290.  
  1291.         fclose(fp);
  1292.  
  1293.                 SDL_Init(SDL_INIT_VIDEO);
  1294.  
  1295.                 screen = SDL_SetVideoMode(256,240,24,SDL_SWSURFACE);
  1296.  
  1297.                 a.dumpregs();
  1298.  
  1299.                 SDL_Event e;
  1300.  
  1301.         for(;;)
  1302.         {
  1303.             if(a.tick() == 1)
  1304.                         {
  1305.                                 SDL_Quit();
  1306.                                 return 1;
  1307.                         }
  1308.                         else
  1309.                         {
  1310.                                 if(SDL_PollEvent(&e)) if(e.type == SDL_QUIT) return 2;
  1311.                                 SDL_Flip(screen);
  1312.                         }
  1313.                 }
  1314.     }
  1315.     return 0;
  1316. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top