Mapper118.sflp

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--;
		}
	}
}