Mapper016.sflp

Bandai chip

Bandai chip

  • タグ:
  • sfl
/*
	Mapper 016
	Bandai chip
		PRG-ROM 16KB banks 8 16 32 max 512KB
		CHR-ROM 8KB banks 4 (8) 16 32 max 256KB
*/
 
circuit Mapper016
{
	// 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;
 
	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<19>; // PRG_ROM max 512KB
//	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<18>; // CHR_ROM max 256KB
//	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_bank0<8>, chr_bank1<8>, chr_bank2<8> ,chr_bank3<8>;
	reg_wr chr_bank4<8>, chr_bank5<8>, chr_bank6<8>, chr_bank7<8>;
 
	instrself map_rom, map_exrom, map_exram;
 
	reg_ws IRQn_reg;
	reg_wr irq_counter<16>, irq_latch_L<8>, irq_latch_H<8>, irq_enabled;
 
	sel prg_read_bank<6>;
	sel chr_read_bank<8>;
 
	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: VRAM_A10 = chr_A<11>; // 水平ミラー, 垂直スクロールタイプ
			case 0b01: VRAM_A10 = chr_A<10>; // 垂直ミラー, 水平スクロールタイプ
			case 0b10: VRAM_A10 = 0b0; // mirror $2000
			case 0b11: VRAM_A10 = 0b1; // mirror $2400
		}
 
		// chr_bank<8> + chr_A<10> = <18>
	//	sel chr_read_bank<8>;
		switch(chr_A<12:10>){
			case 0b000: chr_read_bank = chr_bank0;
			case 0b001: chr_read_bank = chr_bank1;
			case 0b010: chr_read_bank = chr_bank2;
			case 0b011: chr_read_bank = chr_bank3;
			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;
	}
 
	instruct init par{
		prg_bank0 := 0b000000;
		prg_bank1 := 0b000001;
		prg_last_bank := (n16kRomBanks - 0b000001)<4:0>;
		irq_counter := 0;
		irq_latch_L := 0;
		irq_latch_H := 0;
		irq_enabled := 0;
 
		chr_bank0 := 0x00;
		chr_bank1 := 0x01;
		chr_bank2 := 0x02;
		chr_bank3 := 0x03;
		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>;
			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 || prg_A<12:0>);
		}
		map_exram : exram_read(prg_A<12:0>);
	}
 
	instruct prg_write any{
		map_rom : par{
			switch(prg_A<3:0>){
				case 0x0: chr_bank0 := prg_Din;
				case 0x1: chr_bank1 := prg_Din;
				case 0x2: chr_bank2 := prg_Din;
				case 0x3: chr_bank3 := prg_Din;
				case 0x4: chr_bank4 := prg_Din;
				case 0x5: chr_bank5 := prg_Din;
				case 0x6: chr_bank6 := prg_Din;
				case 0x7: chr_bank7 := prg_Din;
				case 0x8: par{
					prg_bank0 := prg_Din<4:0> || 0b0;
					prg_bank1 := prg_Din<4:0> || 0b1;
				}
				case 0x9: fMirroringType_reg := prg_Din<1:0>;
				case 0xA: par{
					irq_enabled := prg_Din<0>;
					irq_counter := irq_latch_H || irq_latch_L;
					IRQn_reg := 0b1;
				}
				case 0xB: irq_latch_L := prg_Din;
				case 0xC: irq_latch_H := prg_Din;
			}
		}
		map_exram : exram_write(prg_A<12:0>, prg_Din);
	}
 
	instruct chr_read par{
		if(chr_A<13>==0b0){
			chr_ram_read(chr_read_bank || chr_A<9:0>);
		}
	}
 
	instruct hblank par{
		if(irq_enabled){
			if(irq_counter<15>){
				IRQn_reg := 0b0;
				irq_enabled := 0b0;
			}
			else irq_counter -= 113;
		}
	}
}