sfl2vlでVerilogに変換しVerilatorでC++に変換したものをシミュレーションに使います。
sfl2vlでVerilogに変換しVerilatorでC++に変換したものをシミュレーションに使います。
#include "Vmpu6502.h" #include "NesRom.h" #include "VMapper019.h" int main(/*int argc, char **argv, char **env*/) { Vmpu6502 *mpu = new Vmpu6502; // 外部要因 mpu->din = 0x00; mpu->read_ack = 0; mpu->run = 0; mpu->mpu_reset = 0; mpu->NMI = 0; mpu->IRQn = 0; // リセット mpu->p_reset = 0; mpu->m_clock = 1; mpu->eval(); mpu->p_reset = 1; mpu->m_clock = 0; mpu->eval(); // NES rom NesRom rom; rom.Read("test.nes"); VMapper019 map; map.n16kRomBanks = rom.n16kRomBanks; map.fMirroringType = rom.fMirroringType; // リセット map.p_reset = 0; map.m_clock = 1; map.eval(); map.p_reset = 1; map.m_clock = 0; map.eval(); // init map.init = 1; map.m_clock = 1; map.eval(); map.init = 0; map.m_clock = 0; map.eval(); FILE *fp; fp = fopen("log.txt", "w"); setbuf(fp, NULL); int i; int vblank = 0; int f_2005_2006 = 0; int v_adrs_inc = 0; int v_adrs; unsigned char wram[0x800]; memset(wram, 0, 0x800); unsigned char exram[0x2000]; memset(exram, 0, 0x2000); int hcount = 0; for(i=0; i<500000; i++){ mpu->m_clock = 1; mpu->eval(); mpu->run = (i%3)==1; if(mpu->read_req){ if(mpu->A<0x2000){ mpu->din = wram[mpu->A&0x7FF]; } else if(mpu->A&0x8000){ map.prg_read = 1; map.ROM_SELn = 0; map.prg_A = mpu->A & 0x7FFF; map.m_clock = 1; map.eval(); map.m_clock = 0; map.eval(); map.prg_read = 0; mpu->din = rom.prg_rom[map.prg_ram_adrs]; } else if(mpu->A>=0x6000){ mpu->din = exram[mpu->A&0x1FFF]; } else{ switch(mpu->A){ case 0x2002: mpu->din = (vblank<<7); vblank = 0; f_2005_2006 = 0; break; case 0x2007: printf("read 2007\n"); break; case 0x4016: case 0x4017: mpu->din = 0; break; default: printf("no mem map : %04X\n", mpu->A); } } } static int t_ack = 0; mpu->read_ack = /*mpu->read_req;*/t_ack; t_ack = mpu->read_req; if(mpu->write_req){ if(mpu->A<0x2000){ wram[mpu->A&0x7FF] = mpu->dout; } else if(mpu->A&0x8000){ map.prg_write = 1; map.ROM_SELn = 0; map.prg_A = mpu->A & 0x7FFF; map.prg_Din = mpu->dout; map.m_clock = 1; map.eval(); map.m_clock = 0; map.eval(); map.prg_write = 0; fprintf(fp, "CPU $%04X %02X $%04X %02X ", mpu->A, mpu->dout, map.prg_A, map.prg_Din ); switch(mpu->A){ case 0xE000: fprintf(fp, "bank4 %02X\n", map.v__DOT__prg_bank4); break; case 0xE800: fprintf(fp, "bank5 %02X\n", map.v__DOT__prg_bank5); break; case 0xF000: fprintf(fp, "bank6 %02X\n", map.v__DOT__prg_bank6); break; default: fprintf(fp, "\n"); } } else if(mpu->A>=0x6000){ exram[mpu->A&0x1FFF] = mpu->dout; } else{ unsigned char data = mpu->dout; switch(mpu->A){ case 0x2000: if(data & 0x04) v_adrs_inc = 32; else v_adrs_inc = 1; break; case 0x2005: f_2005_2006 = !f_2005_2006; break; case 0x2006: f_2005_2006 = !f_2005_2006; if(f_2005_2006){ // 上位8bit first write v_adrs = data; } else{ // 下位8bit second write v_adrs = (v_adrs<<8) | data; } break; case 0x2007: // fprintf(fp, "VW %04X:%02X\n", v_adrs, data); v_adrs += v_adrs_inc; break; } } } mpu->m_clock = 0; mpu->eval(); mpu->NMI = 0; mpu->IRQn = 1; static int old_op = 0; if(mpu->v__DOT__ir != old_op){ old_op = mpu->v__DOT__ir; static int base = 0; base++; if(base>0){ fprintf(fp,"%04X %02X : %02X %02X %02X %02X %d%d%d%d%d%d%d\n", mpu->v__DOT__pc-1, mpu->v__DOT__ir, mpu->v__DOT__ra, mpu->v__DOT__rx, mpu->v__DOT__ry, mpu->v__DOT__sp, mpu->v__DOT__fn, mpu->v__DOT__fv, mpu->v__DOT__fb, mpu->v__DOT__fd, mpu->v__DOT__fi, mpu->v__DOT__fz, mpu->v__DOT__fc ); } static int pl = 0; pl++; if(pl==7828 || pl==16336 || pl==24846 || pl==33356 || pl==41866){ vblank = 1; } } } fclose(fp); return 0; }