IGS MMC3
IGS MMC3
/* Mapper 118 IGS MMC3 PRG-ROM 16KB banks 16 max 256KB CHR-ROM 8KB banks 16 max 128KB */ circuit Mapper118 { // PRG-ROM input ROM_SELn; instrin prg_read, prg_write; input prg_A<15>, prg_Din<8>; output prg_Dout<8>; output IRQn; // CHR-ROM instrin chr_read;//, chr_write; // RDn, WEn input chr_A<14>;//, chr_Din<8>; // chr_A13n output chr_Dout<8>; output VRAM_CSn, VRAM_A10; // instrin Phi; // 1.789MHz output usound<11>, ssound<14>; instrout exram_read(exram_adrs); output exram_adrs<13>; // EX_RAM 8KB output 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; // 0x00 chr_bank23 := 0b0000001; // 0x02 chr_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 Command chr_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 Select fMirroringType_reg := ^prg_Din<0>; } case 0b011: par{ // $A001 SaveRAM Toggle fSaveRAMenable := prg_Din<7>; } */ case 0b100: par{ // $C000 irq_counter := prg_Din; } case 0b101: par{ // $C001 irq_latch := prg_Din; } case 0b110: par{ // $E000 irq_enabled := 0b0; IRQn_reg := 0b1; } case 0b111: par{ // $E001 irq_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{ // 21 vcount := 0x00; vblank := 0b0; } (^vblank) & (vcount==0xEF) : par{ // 239 vcount := 0x00; vblank := 0b1; } else : vcount++; } if(irq_enabled & (^vblank)){ if(irq_counter==0x00){ irq_counter := irq_latch; IRQn_reg := 0b0; } else irq_counter--; } } }