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 romNesRom 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();// initmap.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 writev_adrs = data;}else{ // 下位8bit second writev_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;}