IGS MMC3
IGS MMC3
/*Mapper 118IGS MMC3PRG-ROM 16KB banks 16 max 256KBCHR-ROM 8KB banks 16 max 128KB*/circuit Mapper118{// PRG-ROMinput ROM_SELn;instrin prg_read, prg_write;input prg_A<15>, prg_Din<8>;output prg_Dout<8>;output IRQn;// CHR-ROMinstrin chr_read;//, chr_write; // RDn, WEninput chr_A<14>;//, chr_Din<8>; // chr_A13noutput chr_Dout<8>;output VRAM_CSn, VRAM_A10;// instrin Phi; // 1.789MHzoutput usound<11>, ssound<14>;instrout exram_read(exram_adrs);output exram_adrs<13>; // EX_RAM 8KBoutput exram_wdata<8>;instrout exram_write(exram_adrs, exram_wdata);input exram_rdata<8>;// 外部RAMへのアクセスinstrout prg_ram_read(prg_ram_adrs);output prg_ram_adrs<18>; // PRG_ROM max 256KB// output prg_ram_wdata<8>;// instrout prg_ram_write(prg_ram_adrs, prg_ram_wdata);input prg_ram_rdata<8>;instrout chr_ram_read(chr_ram_adrs);output chr_ram_adrs<17>; // CHR_ROM max 128KB// output chr_ram_wdata<8>;// instrout chr_ram_write(chr_ram_adrs, chr_ram_wdata);input chr_ram_rdata<8>;instrin init;instrin hblank;input n16kRomBanks<6>, /*n8kVRomBanks<6>,*/ fMirroringType;reg_wr fMirroringType_reg<2>;reg_wr prg_bank0<6>, prg_bank1<6>, prg_last_bank<5>;reg_wr chr_bank01<7>, chr_bank23<7>; // 偶数のみreg_wr chr_bank4<8>, chr_bank5<8>, chr_bank6<8>, chr_bank7<8>;instrself map_rom, map_exram;reg_wr prg_swap, chr_swap;// reg_wr fSaveRAMenable;reg_ws IRQn_reg;reg_wr command<3>;reg_wr irq_counter<8>, irq_latch<8>, irq_enabled;sel prg_read_bank<6>, chr_read_bank<8>;reg_wr vcount<8>;reg_ws vblank;par{if(ROM_SELn==0b0){map_rom();}else any{// prg_A<14:13>==0b10 : map_exrom();prg_A<14:13>==0b11 : map_exram();}any{map_rom : prg_Dout = prg_ram_rdata;map_exram : prg_Dout = exram_rdata;}VRAM_CSn = ^chr_A<13>;// ここ追加switch(fMirroringType_reg){case 0b00: ;case 0b01: ;case 0b10: VRAM_A10 = 0b0;case 0b11: VRAM_A10 = 0b1;}// VRAMでもchr_bankは使用している// chr_bank<8> + chr_A<10> = <18>// sel chr_read_bank<8>;if(chr_swap){switch(chr_A<12:10>){case 0b000: chr_read_bank = chr_bank4;case 0b001: chr_read_bank = chr_bank5;case 0b010: chr_read_bank = chr_bank6;case 0b011: chr_read_bank = chr_bank7;case 0b100: chr_read_bank = chr_bank01 || 0b0;case 0b101: chr_read_bank = chr_bank01 || 0b1;case 0b110: chr_read_bank = chr_bank23 || 0b0;case 0b111: chr_read_bank = chr_bank23 || 0b1;}}else{switch(chr_A<12:10>){case 0b000: chr_read_bank = chr_bank01 || 0b0;case 0b001: chr_read_bank = chr_bank01 || 0b1;case 0b010: chr_read_bank = chr_bank23 || 0b0;case 0b011: chr_read_bank = chr_bank23 || 0b1;case 0b100: chr_read_bank = chr_bank4;case 0b101: chr_read_bank = chr_bank5;case 0b110: chr_read_bank = chr_bank6;case 0b111: chr_read_bank = chr_bank7;}}chr_Dout = chr_ram_rdata;IRQn = IRQn_reg;usound = // <11>0b00000000000;ssound = // <14s>0b00000000000000;}instruct init par{chr_swap := 0;prg_swap := 0;command := 0;prg_bank0 := 0b000000;prg_bank1 := 0b000001;prg_last_bank := (n16kRomBanks - 0b000001)<4:0>;irq_counter := 0;irq_latch := 0;irq_enabled := 0;chr_bank01 := 0b0000000; // 0x00chr_bank23 := 0b0000001; // 0x02chr_bank4 := 0x04;chr_bank5 := 0x05;chr_bank6 := 0x06;chr_bank7 := 0x07;fMirroringType_reg := 0b0 || fMirroringType;IRQn_reg := 0b1;}instruct prg_read any{map_rom : par{// prg_bank<6> + prg_A<13> = <19>// sel prg_read_bank<6>;if(prg_swap){switch(prg_A<14:13>){case 0b00: prg_read_bank = prg_last_bank || 0b0;case 0b01: prg_read_bank = prg_bank1;case 0b10: prg_read_bank = prg_bank0;case 0b11: prg_read_bank = prg_last_bank || 0b1;}}else{switch(prg_A<14:13>){case 0b00: prg_read_bank = prg_bank0;case 0b01: prg_read_bank = prg_bank1;case 0b10: prg_read_bank = prg_last_bank || 0b0;case 0b11: prg_read_bank = prg_last_bank || 0b1;}}prg_ram_read(prg_read_bank<4:0> || prg_A<12:0>);}map_exram : exram_read(prg_A<12:0>);}instruct prg_write any{map_rom : par{switch(prg_A<14:13>||prg_A<0>){case 0b000: par{ // $8000 Commandchr_swap := prg_Din<7>;prg_swap := prg_Din<6>;command := prg_Din<2:0>;}case 0b001: par{ // $8001 Page Number for Command// ここ追加if(((chr_swap==0b0) & (command==0b000)) |((chr_swap==0b1) & (command==0b010)) ){fMirroringType_reg := 0b1 || ^prg_Din<7>;}switch(command){case 0b000: chr_bank01 := prg_Din<7:1>;case 0b001: chr_bank23 := prg_Din<7:1>;case 0b010: chr_bank4 := prg_Din;case 0b011: chr_bank5 := prg_Din;case 0b100: chr_bank6 := prg_Din;case 0b101: chr_bank7 := prg_Din;case 0b110: prg_bank0 := prg_Din<5:0>;case 0b111: prg_bank1 := prg_Din<5:0>;}}/*case 0b010: par{ // $A000 Mirroring SelectfMirroringType_reg := ^prg_Din<0>;}case 0b011: par{ // $A001 SaveRAM TogglefSaveRAMenable := prg_Din<7>;}*/case 0b100: par{ // $C000irq_counter := prg_Din;}case 0b101: par{ // $C001irq_latch := prg_Din;}case 0b110: par{ // $E000irq_enabled := 0b0;IRQn_reg := 0b1;}case 0b111: par{ // $E001irq_enabled := 0b1;}}}map_exram : /*if(fSaveRAMenable)*/ exram_write(prg_A<12:0>, prg_Din);}instruct chr_read par{if(chr_A<13>==0b0){chr_ram_read(chr_read_bank<6:0> || chr_A<9:0>);}}instruct hblank par{// VBlank中はIRQは発生させないこと// vcountはVBlankから開始するでok// reg_wr vcount<8>;// reg_ws vblank;any{vblank & (vcount==0x15) : par{ // 21vcount := 0x00;vblank := 0b0;}(^vblank) & (vcount==0xEF) : par{ // 239vcount := 0x00;vblank := 0b1;}else : vcount++;}if(irq_enabled & (^vblank)){if(irq_counter==0x00){irq_counter := irq_latch;IRQn_reg := 0b0;}else irq_counter--;}}}