mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-04-19 03:04:09 +00:00
Rework cartridge bus & add open bus behavior
Fix freezes in Tokyo Disneyland - Fantasy Tour (Minnie's house) & Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Stage 1-4)
This commit is contained in:
14
Gameboy.sv
14
Gameboy.sv
@@ -347,6 +347,7 @@ wire [14:0] cart1_addr;
|
||||
wire cart1_a15;
|
||||
wire cart1_rd;
|
||||
wire cart1_wr;
|
||||
wire cart1_oe;
|
||||
wire [7:0] cart1_di;
|
||||
wire [7:0] cart1_do;
|
||||
wire [22:0] mbc1_addr;
|
||||
@@ -356,6 +357,7 @@ wire [14:0] cart2_addr;
|
||||
wire cart2_a15;
|
||||
wire cart2_rd;
|
||||
wire cart2_wr;
|
||||
wire cart2_oe;
|
||||
wire [7:0] cart2_di;
|
||||
wire [7:0] cart2_do;
|
||||
wire [22:0] mbc2_addr;
|
||||
@@ -463,6 +465,7 @@ cart_top cart1 (
|
||||
.cart_wr ( cart1_wr ),
|
||||
.cart_do ( cart1_do ),
|
||||
.cart_di ( cart1_di ),
|
||||
.cart_oe ( cart1_oe ),
|
||||
|
||||
.nCS ( gb1_nCS ),
|
||||
|
||||
@@ -540,12 +543,13 @@ gb gb1 (
|
||||
.joy_din ( joy1_do ),
|
||||
|
||||
// interface to the "external" game cartridge
|
||||
.cart_addr ( cart1_addr ),
|
||||
.cart_a15 ( cart1_a15 ),
|
||||
.ext_bus_addr( cart1_addr ),
|
||||
.ext_bus_a15 ( cart1_a15 ),
|
||||
.cart_rd ( cart1_rd ),
|
||||
.cart_wr ( cart1_wr ),
|
||||
.cart_do ( cart1_do ),
|
||||
.cart_di ( cart1_di ),
|
||||
.cart_oe ( cart1_oe ),
|
||||
|
||||
.nCS ( gb1_nCS ),
|
||||
|
||||
@@ -651,6 +655,7 @@ cart_top cart2 (
|
||||
.cart_wr ( cart2_wr ),
|
||||
.cart_do ( cart2_do ),
|
||||
.cart_di ( cart2_di ),
|
||||
.cart_oe ( cart2_oe ),
|
||||
|
||||
.nCS ( gb2_nCS ),
|
||||
|
||||
@@ -728,12 +733,13 @@ gb gb2 (
|
||||
.joy_din ( joy2_do ),
|
||||
|
||||
// interface to the "external" game cartridge
|
||||
.cart_addr ( cart2_addr ),
|
||||
.cart_a15 ( cart2_a15 ),
|
||||
.ext_bus_addr( cart2_addr ),
|
||||
.ext_bus_a15 ( cart2_a15 ),
|
||||
.cart_rd ( cart2_rd ),
|
||||
.cart_wr ( cart2_wr ),
|
||||
.cart_do ( cart2_do ),
|
||||
.cart_di ( cart2_di ),
|
||||
.cart_oe ( cart2_oe ),
|
||||
|
||||
.nCS ( gb2_nCS ),
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ module cart_top (
|
||||
input cart_wr,
|
||||
output [7:0] cart_do,
|
||||
input [7:0] cart_di, // data from cpu to cart
|
||||
output cart_oe,
|
||||
|
||||
input nCS,
|
||||
|
||||
@@ -151,8 +152,10 @@ mappers mappers (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe ( cart_oe ),
|
||||
|
||||
.rom_di ( rom_di ),
|
||||
.rom_do ( rom_do ),
|
||||
@@ -377,7 +380,6 @@ assign ram_mask_file = // 0 - no ram
|
||||
assign has_save = mbc_battery && (cart_ram_size > 0 || mbc2 || mbc7 || tama);
|
||||
|
||||
// Up to 8kb * 16banks of Cart Ram (128kb)
|
||||
|
||||
dpram #(16) cram_l (
|
||||
.clock_a (clk_sys),
|
||||
.address_a (cram_addr[16:1]),
|
||||
|
||||
171
rtl/gb.v
171
rtl/gb.v
@@ -34,12 +34,13 @@ module gb (
|
||||
|
||||
// cartridge interface
|
||||
// can adress up to 1MB ROM
|
||||
output [14:0] cart_addr,
|
||||
output cart_a15,
|
||||
output [14:0] ext_bus_addr,
|
||||
output ext_bus_a15,
|
||||
output cart_rd,
|
||||
output cart_wr,
|
||||
input [7:0] cart_do,
|
||||
output [7:0] cart_di,
|
||||
input cart_oe,
|
||||
|
||||
// WRAM or Cart RAM CS
|
||||
output nCS,
|
||||
@@ -120,14 +121,17 @@ wire [7:0] Savestate_RAMReadData_WRAM, Savestate_RAMReadData_VRAM, Savestate_RAM
|
||||
wire [19:0] Savestate_RAMAddr;
|
||||
wire [4:0] Savestate_RAMRWrEn;
|
||||
|
||||
localparam SAVESTATE_MODULES = 7;
|
||||
localparam SAVESTATE_MODULES = 8;
|
||||
wire [63:0] SaveStateBus_wired_or[0:SAVESTATE_MODULES-1];
|
||||
|
||||
wire [54:0] SS_Top;
|
||||
wire [54:0] SS_Top_BACK;
|
||||
|
||||
eReg_SavestateV #(0, 31, 54, 0, 64'h0000000000800001) iREG_SAVESTATE_Top (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[6], SS_Top_BACK, SS_Top);
|
||||
|
||||
wire [10:0] SS_Top2;
|
||||
wire [10:0] SS_Top2_BACK;
|
||||
eReg_SavestateV #(0, 38, 10, 0, 64'h0000000000000000) iREG_SAVESTATE_Top2 (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[7], SS_Top2_BACK, SS_Top2);
|
||||
|
||||
// include cpu
|
||||
reg boot_rom_enabled;
|
||||
|
||||
@@ -150,19 +154,32 @@ wire sel_zpram = (cpu_addr[15:7] == 9'b111111111) && // 127 bytes zero pageram a
|
||||
(cpu_addr != 16'hffff);
|
||||
wire sel_audio = (cpu_addr[15:8] == 8'hff) && // audio reg ff10 - ff3f and ff76/ff77 PCM12/PCM34 (undocumented registers)
|
||||
((cpu_addr[7:5] == 3'b001) || (cpu_addr[7:4] == 4'b0001) || (cpu_addr[7:0] == 8'h76) || (cpu_addr[7:0] == 8'h77));
|
||||
|
||||
wire sel_ext_bus = sel_rom | sel_cram | sel_iram;
|
||||
|
||||
wire sel_boot_rom, sel_boot_rom_cgb;
|
||||
|
||||
// unused cgb registers
|
||||
wire sel_FF72 = isGBC && cpu_addr == 16'hff72; // unused register, all bits read/write
|
||||
wire sel_FF73 = isGBC && cpu_addr == 16'hff73; // unused register, all bits read/write
|
||||
wire sel_FF74 = isGBC && isGBC_game && (cpu_addr == 16'hff74); // unused register, all bits read/write, only in CGB mode
|
||||
wire sel_FF75 = isGBC && cpu_addr == 16'hff75; // unused register, bits 4-6 read/write
|
||||
|
||||
//DMA can select from $0000 to $F100
|
||||
|
||||
wire ext_bus_wram_sel, ext_bus_cram_sel, ext_bus_rom_sel;
|
||||
wire ext_bus_rd, ext_bus_wr;
|
||||
wire [7:0] ext_bus_di;
|
||||
wire cart_sel;
|
||||
|
||||
|
||||
// From Game Boy: Complete Technical Reference:
|
||||
// DMA register value, Selected bus, Asserted CS:
|
||||
// 0x00-0x7F, external bus, external ROM (A15)
|
||||
// 0x80-0x9F, video RAM bus, video RAM (MCS)
|
||||
// 0xA0-0xFF, external bus, external RAM (CS)
|
||||
wire [15:0] dma_addr;
|
||||
wire dma_sel_rom = !dma_addr[15]; // lower 32k are rom
|
||||
wire dma_sel_cram = dma_addr[15:13] == 3'b101; // 8k cart ram at $a000
|
||||
wire dma_sel_vram = dma_addr[15:13] == 3'b100; // 8k video ram at $8000
|
||||
wire dma_sel_iram = (dma_addr[15:8] >= 8'hC0 && dma_addr[15:8] <= 8'hF1); // 8k internal ram at $c000
|
||||
wire dma_sel_rom = ~dma_addr[15]; // lower 32k are rom
|
||||
wire dma_sel_vram = dma_addr[15:13] == 3'b100; // 8k video ram at $8000-$9FFF
|
||||
wire dma_sel_ext_bus = ~dma_sel_vram; // WRAM or Cart ROM/RAM
|
||||
wire dma_sel_ext_ram = ~dma_sel_rom; // External RAM CS
|
||||
|
||||
//CGB
|
||||
wire sel_vram_bank = (cpu_addr==16'hff4f);
|
||||
@@ -177,6 +194,7 @@ wire [15:0] hdma_source_addr;
|
||||
wire hdma_sel_rom = !hdma_source_addr[15]; // lower 32k are rom
|
||||
wire hdma_sel_cram = hdma_source_addr[15:13] == 3'b101; // 8k cart ram at $a000
|
||||
wire hdma_sel_iram = hdma_source_addr[15:13] == 3'b110; // 8k internal ram at $c000-$dff0
|
||||
wire hdma_sel_ext_bus = hdma_sel_rom | hdma_sel_cram | hdma_sel_iram;
|
||||
|
||||
|
||||
// the boot roms sees a special $42 flag in $ff50 if it's supposed to to a fast boot
|
||||
@@ -209,7 +227,7 @@ wire [7:0] sb_o;
|
||||
wire [7:0] timer_do;
|
||||
wire [7:0] video_do;
|
||||
wire [7:0] audio_do;
|
||||
wire [7:0] rom_do;
|
||||
wire [7:0] bios_do;
|
||||
wire [7:0] vram_do;
|
||||
wire [7:0] vram1_do;
|
||||
wire [7:0] zpram_do;
|
||||
@@ -237,11 +255,10 @@ wire [7:0] cpu_di =
|
||||
sel_video_reg?video_do: // video registers
|
||||
(sel_video_oam&&oam_cpu_allow)?video_do: // video object attribute memory
|
||||
sel_audio?audio_do: // audio registers
|
||||
sel_rom?rom_do: // boot rom + cartridge rom
|
||||
sel_cram?rom_do: // cartridge ram
|
||||
sel_boot_rom?bios_do: // boot rom
|
||||
sel_ext_bus?ext_bus_di: // wram + cartridge rom/ram
|
||||
(sel_vram&&vram_cpu_allow)?(isGBC&&vram_bank)?vram1_do:vram_do: // vram (GBC bank 0+1)
|
||||
sel_zpram?zpram_do: // zero page ram
|
||||
sel_iram?iram_do: // internal ram
|
||||
sel_ie?ie_r: // interrupt enable register
|
||||
sel_FF72?FF72: // unused register, all bits read/write
|
||||
sel_FF73?FF73: // unused register, all bits read/write
|
||||
@@ -592,8 +609,9 @@ timer timer (
|
||||
// cpu tries to read or write the lcd controller registers
|
||||
wire [12:0] video_addr;
|
||||
wire video_rd, dma_rd;
|
||||
wire [7:0] dma_data = dma_sel_iram?iram_do:dma_sel_vram?(isGBC&&vram_bank)?vram1_do:vram_do:cart_do;
|
||||
|
||||
wire [7:0] dma_data = dma_sel_ext_bus ? ext_bus_di :
|
||||
(isGBC & vram_bank) ? vram1_do : vram_do;
|
||||
|
||||
video video (
|
||||
.reset ( reset_ss ),
|
||||
@@ -650,14 +668,9 @@ video video (
|
||||
wire cpu_wr_vram = sel_vram && !cpu_wr_n && vram_cpu_allow;
|
||||
|
||||
wire hdma_rd;
|
||||
wire is_hdma_cart_addr;
|
||||
wire [7:0] vram_di = (hdma_rd&&isGBC)?
|
||||
hdma_sel_iram?iram_do:
|
||||
is_hdma_cart_addr?cart_do:
|
||||
8'hFF:
|
||||
cpu_do;
|
||||
|
||||
|
||||
wire [7:0] vram_di = (hdma_rd & isGBC) ? ext_bus_di : cpu_do;
|
||||
|
||||
wire vram_wren = video_rd?1'b0:!vram_bank&&((hdma_rd&&isGBC)||cpu_wr_vram);
|
||||
wire vram1_wren = video_rd?1'b0:vram_bank&&((hdma_rd&&isGBC)||cpu_wr_vram);
|
||||
|
||||
@@ -764,22 +777,13 @@ dpram #(7) zpram (
|
||||
);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// ------------------------ 8k/32k(GBC) internal ram -----------------
|
||||
// -------------------------- 8k/32k(GBC) work ram -------------------
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
wire cpu_wr_iram = sel_iram && !cpu_wr_n;
|
||||
wire iram_wren = (dma_rd&&dma_sel_iram)||(isGBC&&hdma_rd&&hdma_sel_iram)?1'b0:cpu_wr_iram;
|
||||
wire iram_wren = ext_bus_wram_sel & ext_bus_wr;
|
||||
wire [14:0] iram_addr = (ext_bus_addr[12]) ? { iram_bank, ext_bus_addr[11:0] } // bank 1-7 $D000-DFFF
|
||||
: { 3'd0, ext_bus_addr[11:0] }; // bank 0 $C000-CFFF
|
||||
|
||||
wire [14:0] iram_addr = (isGBC&&hdma_rd&&hdma_sel_iram)? //hdma transfer?
|
||||
(hdma_source_addr[12])?{iram_bank,hdma_source_addr[11:0]}: //bank 1-7 D000-DFFF
|
||||
{3'd0,hdma_source_addr[11:0]}: //bank 0
|
||||
(dma_rd&&dma_sel_iram)? //dma transfer?
|
||||
(dma_addr[12])?{iram_bank,dma_addr[11:0]}: //bank 1-7
|
||||
{3'd0,dma_addr[11:0]}: //bank 0
|
||||
//cpu
|
||||
(cpu_addr[12])?{iram_bank,cpu_addr[11:0]}: //bank 1-7
|
||||
{3'd0,cpu_addr[11:0]}; //bank 0
|
||||
|
||||
dpram #(15) iram (
|
||||
.clock_a (clk_cpu),
|
||||
.address_a (iram_addr),
|
||||
@@ -837,35 +841,15 @@ wire [15:0] boot_rom_addr = (isGBC && hdma_rd) ? hdma_source_addr : cpu_addr;
|
||||
// 0- FF bootrom 1st part
|
||||
//100-1FF Cart Header
|
||||
//200-8FF bootrom 2nd part
|
||||
wire boot_rom_cgb_sel = isGBC && (boot_rom_addr[15:8] >= 8'h02 && boot_rom_addr[15:8] <= 8'h08);
|
||||
wire boot_rom_sel = boot_rom_enabled && (!boot_rom_addr[15:8] || boot_rom_cgb_sel);
|
||||
assign sel_boot_rom_cgb = isGBC && (boot_rom_addr[15:8] >= 8'h02 && boot_rom_addr[15:8] <= 8'h08);
|
||||
assign sel_boot_rom = boot_rom_enabled && (!boot_rom_addr[15:8] || sel_boot_rom_cgb);
|
||||
|
||||
assign rom_do = ~boot_rom_sel ? cart_do :
|
||||
isGBC ? gbc_bios_do :
|
||||
isSGB ? boot_rom_sgb_do :
|
||||
fast_boot ? fast_boot_rom_do : boot_rom_do;
|
||||
|
||||
|
||||
wire is_dma_cart_addr = (dma_sel_rom || dma_sel_cram); //rom or external ram
|
||||
assign is_hdma_cart_addr = (hdma_sel_rom || hdma_sel_cram); //rom or external ram
|
||||
|
||||
assign cart_di = cpu_do;
|
||||
|
||||
wire [15:0] cart_addr_i = (isGBC&&hdma_rd&&is_hdma_cart_addr)?hdma_source_addr:(dma_rd&&is_dma_cart_addr)?dma_addr:cpu_addr;
|
||||
|
||||
// External A15 is not directly connected to internal A15. It does not go low when accessing the boot rom.
|
||||
assign cart_a15 = cart_addr_i[15] | boot_rom_sel;
|
||||
assign cart_addr = cart_addr_i[14:0];
|
||||
|
||||
assign cart_rd = (isGBC&&hdma_rd&&is_hdma_cart_addr) || (dma_rd&&is_dma_cart_addr) || ((sel_rom || sel_cram) && !cpu_rd_n);
|
||||
assign cart_wr = (sel_rom || sel_cram) && !cpu_wr_n_edge && !hdma_rd;
|
||||
|
||||
assign nCS = ~( (sel_cram | sel_iram) | (dma_rd & (dma_sel_cram | dma_sel_iram)) | (isGBC & hdma_rd & (hdma_sel_cram | hdma_sel_iram)) );
|
||||
assign bios_do = isGBC ? gbc_bios_do :
|
||||
isSGB ? boot_rom_sgb_do :
|
||||
fast_boot ? fast_boot_rom_do : boot_rom_do;
|
||||
|
||||
assign gbc_bios_addr = boot_rom_addr[11:0];
|
||||
|
||||
assign DMA_on = (hdma_active && is_hdma_cart_addr) || (dma_rd && is_dma_cart_addr);
|
||||
|
||||
boot_rom boot_rom (
|
||||
.addr ( cpu_addr[7:0] ),
|
||||
.clk ( clk_sys ),
|
||||
@@ -884,6 +868,66 @@ boot_rom_sgb boot_rom_sgb (
|
||||
.data ( boot_rom_sgb_do)
|
||||
);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// ------------------ External bus (WRAM, Cartridge) ------------------
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Emulate cartridge open bus behavior.
|
||||
// Some games read from Cart RAM while it is disabled or not present and
|
||||
// expect to read the previous ROM byte instead of $FF otherwise they freeze.
|
||||
// Ex. Tokyo Disneyland - Fantasy Tour (in Minnie's house) and
|
||||
// Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Stage 1-4)
|
||||
|
||||
reg [7:0] open_bus_data;
|
||||
reg [2:0] open_bus_cnt;
|
||||
|
||||
assign SS_Top2_BACK[ 7: 0] = open_bus_data;
|
||||
assign SS_Top2_BACK[10: 8] = open_bus_cnt;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(reset_ss) begin
|
||||
open_bus_data <= SS_Top2[ 7: 0]; // 8'd0;
|
||||
open_bus_cnt <= SS_Top2[10: 8]; // 3'd0;
|
||||
end else if (ce) begin
|
||||
open_bus_data <= ext_bus_di;
|
||||
if (ext_bus_wram_sel | (cart_sel & cart_oe) ) begin
|
||||
open_bus_cnt <= 0;
|
||||
end else if (~&open_bus_cnt) begin
|
||||
open_bus_cnt <= open_bus_cnt + 1'b1;
|
||||
if (open_bus_cnt == 3'd4) open_bus_data <= 8'hFF; // Slow pull-up
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign cart_di = cpu_do;
|
||||
|
||||
wire hdma_read_ext_bus = (isGBC & hdma_rd & hdma_sel_ext_bus);
|
||||
wire dma_read_ext_bus = (dma_rd & dma_sel_ext_bus);
|
||||
|
||||
assign nCS = ~( hdma_read_ext_bus ? (hdma_sel_cram | hdma_sel_iram) : dma_read_ext_bus ? dma_sel_ext_ram : (sel_cram | sel_iram) );
|
||||
|
||||
wire [15:0] ext_bus_i = hdma_read_ext_bus ? hdma_source_addr : dma_read_ext_bus ? dma_addr : cpu_addr;
|
||||
|
||||
// External A15 is not directly connected to internal A15. It does not go low when accessing the boot rom.
|
||||
assign ext_bus_a15 = ext_bus_i[15] | sel_boot_rom;
|
||||
assign ext_bus_addr = ext_bus_i[14:0];
|
||||
|
||||
assign ext_bus_rd = hdma_read_ext_bus | dma_read_ext_bus | (sel_ext_bus & ~cpu_rd_n);
|
||||
assign ext_bus_wr = (sel_ext_bus & ~cpu_wr_n_edge) & ~hdma_read_ext_bus & ~dma_read_ext_bus;
|
||||
|
||||
assign ext_bus_wram_sel = ~nCS & ext_bus_addr[14];
|
||||
assign ext_bus_cram_sel = ~nCS & ~ext_bus_addr[14];
|
||||
assign ext_bus_rom_sel = ~ext_bus_a15;
|
||||
|
||||
assign ext_bus_di = ext_bus_wram_sel ? iram_do :
|
||||
(cart_sel & cart_oe) ? cart_do : open_bus_data;
|
||||
|
||||
assign cart_sel = ext_bus_rom_sel | ext_bus_cram_sel;
|
||||
assign cart_rd = cart_sel & ext_bus_rd;
|
||||
assign cart_wr = cart_sel & ext_bus_wr;
|
||||
|
||||
assign DMA_on = cart_sel & (hdma_active | dma_rd);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// ------------------------ savestates -------------------------
|
||||
// --------------------------------------------------------------------
|
||||
@@ -904,8 +948,9 @@ assign Savestate_CRAMAddr = Savestate_RAMAddr;
|
||||
assign Savestate_CRAMRWrEn = Savestate_RAMRWrEn[4];
|
||||
assign Savestate_CRAMWriteData = Savestate_RAMWriteData;
|
||||
|
||||
wire [63:0] SaveStateBus_Dout = SaveStateBus_wired_or[0] | SaveStateBus_wired_or[1] | SaveStateBus_wired_or[2] | SaveStateBus_wired_or[3] |
|
||||
SaveStateBus_wired_or[4] | SaveStateBus_wired_or[5] | SaveStateBus_wired_or[6] | SaveStateExt_Dout;
|
||||
wire [63:0] SaveStateBus_Dout = SaveStateBus_wired_or[0] | SaveStateBus_wired_or[1] | SaveStateBus_wired_or[2] | SaveStateBus_wired_or[3] |
|
||||
SaveStateBus_wired_or[4] | SaveStateBus_wired_or[5] | SaveStateBus_wired_or[6] | SaveStateBus_wired_or[7] |
|
||||
SaveStateExt_Dout;
|
||||
|
||||
wire sleep_rewind, sleep_savestates;
|
||||
|
||||
|
||||
@@ -17,9 +17,12 @@ module gb_camera (
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
inout cart_oe_b,
|
||||
|
||||
input cram_rd,
|
||||
input [7:0] cram_di,
|
||||
inout [7:0] cram_do_b,
|
||||
inout [16:0] cram_addr_b,
|
||||
@@ -32,6 +35,7 @@ module gb_camera (
|
||||
wire [22:0] mbc_addr;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire cart_oe;
|
||||
wire ram_enabled;
|
||||
wire has_battery;
|
||||
wire [15:0] savestate_back;
|
||||
@@ -39,6 +43,7 @@ wire [15:0] savestate_back;
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
assign cram_addr_b = enable ? cram_addr : 17'hZ;
|
||||
assign cart_oe_b = enable ? cart_oe : 1'hZ;
|
||||
assign ram_enabled_b = enable ? ram_enabled : 1'hZ;
|
||||
assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 16'hZ;
|
||||
@@ -47,7 +52,7 @@ assign savestate_back_b = enable ? savestate_back : 16'hZ;
|
||||
|
||||
reg [5:0] rom_bank_reg;
|
||||
reg [3:0] ram_bank_reg;
|
||||
reg ram_enable;
|
||||
reg ram_write_en;
|
||||
reg cam_en;
|
||||
|
||||
assign savestate_back[ 5: 0] = rom_bank_reg;
|
||||
@@ -55,23 +60,23 @@ assign savestate_back[ 8: 6] = 0;
|
||||
assign savestate_back[12: 9] = ram_bank_reg;
|
||||
assign savestate_back[ 13] = 0;
|
||||
assign savestate_back[ 14] = cam_en;
|
||||
assign savestate_back[ 15] = ram_enable;
|
||||
assign savestate_back[ 15] = ram_write_en;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(savestate_load & enable) begin
|
||||
rom_bank_reg <= savestate_data[ 5: 0]; //6'd1;
|
||||
ram_bank_reg <= savestate_data[12: 9]; //4'd0;
|
||||
cam_en <= savestate_data[ 14]; //1'b0;
|
||||
ram_enable <= savestate_data[ 15]; //1'b0;
|
||||
ram_write_en <= savestate_data[ 15]; //1'b0;
|
||||
end else if(~enable) begin
|
||||
rom_bank_reg <= 6'd1;
|
||||
ram_bank_reg <= 4'd0;
|
||||
cam_en <= 1'b0;
|
||||
ram_enable <= 1'b0;
|
||||
ram_write_en <= 1'b0;
|
||||
end else if(ce_cpu) begin
|
||||
if (cart_wr & ~cart_a15) begin
|
||||
case(cart_addr[14:13])
|
||||
2'b00: ram_enable <= (cart_di[3:0] == 4'ha); //RAM enable/disable
|
||||
2'b00: ram_write_en <= (cart_di[3:0] == 4'ha); //RAM write enable/disable
|
||||
2'b01: rom_bank_reg <= cart_di[5:0]; //write to ROM bank register
|
||||
2'b10: begin
|
||||
if (cart_di[4]) begin
|
||||
@@ -99,7 +104,9 @@ assign mbc_addr = { 3'b000, rom_bank_m, cart_addr[13:0] }; // 16k ROM Bank 0-63
|
||||
assign cram_do = cam_en ? 8'h00 : cram_di; // Reading from RAM or CAM is always enabled
|
||||
assign cram_addr = { ram_bank, cart_addr[12:0] };
|
||||
|
||||
assign cart_oe = (cart_rd & ~cart_a15) | cram_rd;
|
||||
|
||||
assign has_battery = 1;
|
||||
assign ram_enabled = ~cam_en & ram_enable; // Writing RAM
|
||||
assign ram_enabled = ~cam_en & ram_write_en; // Writing RAM
|
||||
|
||||
endmodule
|
||||
@@ -17,9 +17,12 @@ module huc1 (
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
inout cart_oe_b,
|
||||
|
||||
input cram_rd,
|
||||
input [7:0] cram_di,
|
||||
inout [7:0] cram_do_b,
|
||||
inout [16:0] cram_addr_b,
|
||||
@@ -33,12 +36,14 @@ wire [22:0] mbc_addr;
|
||||
wire ram_enabled;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire cart_oe;
|
||||
wire has_battery;
|
||||
wire [15:0] savestate_back;
|
||||
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
assign cram_addr_b = enable ? cram_addr : 17'hZ;
|
||||
assign cart_oe_b = enable ? cart_oe : 1'hZ;
|
||||
assign ram_enabled_b = enable ? ram_enabled : 1'hZ;
|
||||
assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 16'hZ;
|
||||
@@ -86,12 +91,14 @@ wire [5:0] rom_bank = (~cart_addr[14]) ? 6'd0 : rom_bank_reg;
|
||||
wire [5:0] rom_bank_m = rom_bank & rom_mask[5:0]; //64
|
||||
|
||||
assign mbc_addr = { 3'b000, rom_bank_m, cart_addr[13:0] }; // 16k ROM Bank 0-63
|
||||
assign ram_enabled = ~ir_en & has_ram;
|
||||
|
||||
// 0xC0 is no light detected
|
||||
assign cram_do = ir_en ? 8'hC0 : ram_enabled ? cram_di : 8'hFF;
|
||||
assign cram_do = ir_en ? 8'hC0 : cram_di;
|
||||
assign cram_addr = { 2'b00, ram_bank, cart_addr[12:0] };
|
||||
|
||||
assign cart_oe = (cart_rd & ~cart_a15) | (cram_rd & (ir_en | ram_enabled));
|
||||
|
||||
assign ram_enabled = ~ir_en & has_ram;
|
||||
assign has_battery = 1;
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -26,8 +26,10 @@ module huc3 (
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
inout cart_oe_b,
|
||||
|
||||
input nCS,
|
||||
|
||||
@@ -44,6 +46,7 @@ wire [22:0] mbc_addr;
|
||||
wire ram_enabled;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire cart_oe;
|
||||
wire has_battery;
|
||||
wire [63:0] savestate_back;
|
||||
|
||||
@@ -51,9 +54,12 @@ reg [31:0] RTC_timestampOut;
|
||||
reg [47:0] RTC_savedtimeOut;
|
||||
wire RTC_inuse = 1;
|
||||
|
||||
wire is_cram_addr = ~nCS & ~cart_addr[14];
|
||||
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
assign cram_addr_b = enable ? cram_addr : 17'hZ;
|
||||
assign cart_oe_b = enable ? cart_oe : 1'hZ;
|
||||
assign ram_enabled_b = enable ? ram_enabled : 1'hZ;
|
||||
assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 64'hZ;
|
||||
@@ -163,7 +169,7 @@ always @(posedge clk_sys) begin
|
||||
rtc_index <= 8'd0;
|
||||
rtc_flags <= 4'd0;
|
||||
rtc_out <= 4'd0;
|
||||
end else if(ce_cpu & cart_wr & ~nCS & ~cart_addr[14]) begin // $A000-BFFF
|
||||
end else if(ce_cpu & cart_wr & is_cram_addr) begin // $A000-BFFF
|
||||
if (mode == 4'hB) begin
|
||||
if (cart_di[7:4] == 4'd1) begin
|
||||
case(rtc_index)
|
||||
@@ -233,10 +239,13 @@ always @* begin
|
||||
end
|
||||
|
||||
assign mbc_addr = { 2'b00, rom_bank_m, cart_addr[13:0] }; // 16k ROM Bank 0-127
|
||||
assign ram_enabled = (mode == 4'hA) & has_ram; // RAM write enable
|
||||
|
||||
assign cram_do = cram_do_r;
|
||||
assign cram_addr = { 2'b00, ram_bank, cart_addr[12:0] };
|
||||
|
||||
assign cart_oe = cart_rd & (~cart_a15 | is_cram_addr);
|
||||
|
||||
assign ram_enabled = (mode == 4'hA) & has_ram; // RAM write enable
|
||||
assign has_battery = has_ram;
|
||||
|
||||
|
||||
|
||||
@@ -52,8 +52,10 @@ module mappers(
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
output cart_oe,
|
||||
|
||||
input [7:0] rom_di,
|
||||
output [7:0] rom_do,
|
||||
@@ -83,6 +85,7 @@ tri0 [15:0] savestate_back_b;
|
||||
tri0 [63:0] savestate_back2_b;
|
||||
tri0 [7:0] cram_wr_do_b;
|
||||
tri0 cram_wr_b;
|
||||
tri0 cart_oe_b;
|
||||
tri0 [31:0] RTC_timestampOut_b;
|
||||
tri0 [47:0] RTC_savedtimeOut_b;
|
||||
tri0 RTC_inuse_b;
|
||||
@@ -91,6 +94,7 @@ tri0 RTC_inuse_b;
|
||||
wire ce = speed ? ce_cpu2x : ce_cpu;
|
||||
wire no_mapper = ~(mbc1 | mbc2 | mbc3 | mbc5 | mbc6 | mbc7 | mmm01 | huc1 | huc3 | gb_camera | tama | rocket | sachen);
|
||||
wire rom_override = (rocket);
|
||||
wire cart_oe_override = (mbc3 | mbc7 | huc1 | huc3 | gb_camera | tama);
|
||||
|
||||
mbc1 map_mbc1 (
|
||||
.enable ( mbc1 ),
|
||||
@@ -186,8 +190,10 @@ mbc3 map_mbc3 (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe_b ( cart_oe_b ),
|
||||
|
||||
.nCS ( nCS ),
|
||||
|
||||
@@ -286,8 +292,10 @@ mbc7 map_mbc7 (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe_b ( cart_oe_b ),
|
||||
|
||||
.nCS ( nCS ),
|
||||
|
||||
@@ -353,9 +361,12 @@ huc1 map_huc1 (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe_b ( cart_oe_b ),
|
||||
|
||||
.cram_rd ( cram_rd ),
|
||||
.cram_di ( cram_di ),
|
||||
.cram_do_b ( cram_do_b ),
|
||||
.cram_addr_b ( cram_addr_b ),
|
||||
@@ -393,8 +404,10 @@ huc3 map_huc3 (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe_b ( cart_oe_b ),
|
||||
|
||||
.nCS ( nCS ),
|
||||
|
||||
@@ -426,9 +439,12 @@ gb_camera map_gb_camera (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe_b ( cart_oe_b ),
|
||||
|
||||
.cram_rd ( cram_rd ),
|
||||
.cram_di ( cram_di ),
|
||||
.cram_do_b ( cram_do_b ),
|
||||
.cram_addr_b ( cram_addr_b ),
|
||||
@@ -459,8 +475,10 @@ tama map_tama (
|
||||
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.cart_rd ( cart_rd ),
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
.cart_oe_b ( cart_oe_b ),
|
||||
|
||||
.cram_rd ( cram_rd ),
|
||||
.cram_di ( cram_di ),
|
||||
@@ -538,7 +556,7 @@ sachen map_sachen (
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
assign { cram_do, ram_enabled } = { cram_do_b, ram_enabled_b };
|
||||
assign { cram_do } = { cram_do_b };
|
||||
assign { savestate_back, savestate_back2 } = { savestate_back_b, savestate_back2_b };
|
||||
assign { RTC_timestampOut, RTC_savedtimeOut, RTC_inuse } = { RTC_timestampOut_b, RTC_savedtimeOut_b, RTC_inuse_b };
|
||||
assign { cram_wr_do, cram_wr } = { cram_wr_do_b, cram_wr_b };
|
||||
@@ -546,6 +564,8 @@ assign { cram_wr_do, cram_wr } = { cram_wr_do_b, cram_wr_b };
|
||||
assign mbc_addr = no_mapper ? {8'd0, cart_addr[14:0]} : mbc_addr_b;
|
||||
assign cram_addr = no_mapper ? {4'd0, cart_addr[12:0]} : cram_addr_b;
|
||||
assign has_battery = no_mapper ? (cart_mbc_type == 8'h09) : has_battery_b;
|
||||
assign ram_enabled = no_mapper ? has_ram : ram_enabled_b;
|
||||
assign rom_do = rom_override ? rom_do_b : rom_di;
|
||||
assign cart_oe = cart_oe_override ? cart_oe_b : ((cart_rd & ~cart_a15) | (cram_rd & ram_enabled));
|
||||
|
||||
endmodule
|
||||
@@ -30,8 +30,10 @@ module mbc3 (
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
inout cart_oe_b,
|
||||
|
||||
input nCS,
|
||||
|
||||
@@ -47,9 +49,11 @@ module mbc3 (
|
||||
wire [22:0] mbc_addr;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire cart_oe;
|
||||
wire ram_enabled;
|
||||
wire has_battery;
|
||||
wire [15:0] savestate_back;
|
||||
wire is_cram_addr = ~nCS & ~cart_addr[14];
|
||||
|
||||
reg [31:0] RTC_timestampOut;
|
||||
reg [47:0] RTC_savedtimeOut;
|
||||
@@ -58,6 +62,7 @@ reg RTC_inuse;
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
assign cram_addr_b = enable ? cram_addr : 17'hZ;
|
||||
assign cart_oe_b = enable ? cart_oe : 1'hZ;
|
||||
assign ram_enabled_b = enable ? ram_enabled : 1'hZ;
|
||||
assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 16'hZ;
|
||||
@@ -134,8 +139,10 @@ end
|
||||
assign cram_do = cram_do_r;
|
||||
assign cram_addr = { 1'b0, mbc3_ram_bank, cart_addr[12:0] };
|
||||
|
||||
assign cart_oe = cart_rd & (~cart_a15 | (is_cram_addr & mbc_ram_enable & (mbc3_mode | has_ram)) );
|
||||
|
||||
assign has_battery = (cart_mbc_type == 8'h0F || cart_mbc_type == 8'h10 || cart_mbc_type == 8'h13);
|
||||
assign ram_enabled = mbc_ram_enable & has_ram;
|
||||
assign ram_enabled = mbc_ram_enable & ~mbc3_mode & has_ram;
|
||||
|
||||
///////////////////////////// RTC ///////////////////////////////
|
||||
reg [2:0] rtc_index;
|
||||
@@ -214,7 +221,7 @@ always @(posedge clk_sys) begin
|
||||
|
||||
RTC_inuse <= 1'b1;
|
||||
|
||||
end else if(ce_cpu && cart_wr && ~nCS && ~cart_addr[14] && mbc3_mode == 1'b1) begin // setting RTC registers from game
|
||||
end else if(ce_cpu && cart_wr && is_cram_addr && mbc3_mode == 1'b1) begin // setting RTC registers from game
|
||||
|
||||
case (rtc_index)
|
||||
0: begin
|
||||
|
||||
@@ -24,8 +24,10 @@ module mbc7 (
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
inout cart_oe_b,
|
||||
|
||||
input nCS,
|
||||
|
||||
@@ -44,16 +46,19 @@ module mbc7 (
|
||||
wire [22:0] mbc_addr;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire cart_oe;
|
||||
wire ram_enabled;
|
||||
wire has_battery;
|
||||
wire [15:0] savestate_back;
|
||||
wire [63:0] savestate_back2;
|
||||
wire [7:0] cram_wr_do;
|
||||
wire cram_wr;
|
||||
wire is_cram_addr = ~nCS & ~cart_addr[14];
|
||||
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
assign cram_addr_b = enable ? cram_addr : 17'hZ;
|
||||
assign cart_oe_b = enable ? cart_oe : 1'hZ;
|
||||
assign ram_enabled_b = enable ? ram_enabled : 1'hZ;
|
||||
assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 16'hZ;
|
||||
@@ -71,6 +76,7 @@ reg accel_latched;
|
||||
reg eeprom_di, eeprom_clk, eeprom_cs;
|
||||
|
||||
wire ram_reg_en = ram_enable1 & ram_enable2;
|
||||
wire ram_reg_sel = is_cram_addr & ~cart_addr[12]; // $A000-AFFF
|
||||
|
||||
assign savestate_back[ 6: 0] = rom_bank_reg;
|
||||
assign savestate_back[ 7] = ram_enable1;
|
||||
@@ -108,7 +114,7 @@ always @(posedge clk_sys) begin
|
||||
2'b10: ram_enable2 <= (cart_di == 8'h40); //RAM enable/disable
|
||||
endcase
|
||||
end
|
||||
if (ram_reg_en & ~nCS & ~cart_addr[14] & ~cart_addr[12]) begin // A000-AFFF
|
||||
if (ram_reg_en & ram_reg_sel) begin
|
||||
case(cart_addr[7:4])
|
||||
0: if (cart_di == 8'h55) begin
|
||||
accel_latched <= 1'b0;
|
||||
@@ -155,7 +161,7 @@ eeprom93LC56 eeprom(
|
||||
reg [7:0] cram_do_r;
|
||||
always @* begin
|
||||
cram_do_r = 8'hFF;
|
||||
if (ram_reg_en & ~cart_addr[12]) begin // cram_rd & A000-AFFF
|
||||
if (ram_reg_en & ram_reg_sel) begin
|
||||
case(cart_addr[7:4])
|
||||
2: cram_do_r = accelerometer_x[ 7:0];
|
||||
3: cram_do_r = accelerometer_x[15:8];
|
||||
@@ -180,6 +186,8 @@ assign mbc_addr = { 2'b00, rom_bank_m, cart_addr[13:0] }; // 16k ROM Bank 0-511
|
||||
assign cram_do = cram_do_r;
|
||||
assign cram_addr = { 9'd0, cram_addr_e };
|
||||
|
||||
assign cart_oe = cart_rd & (~cart_a15 | (ram_reg_en & ram_reg_sel));
|
||||
|
||||
assign has_battery = 1;
|
||||
assign ram_enabled = 0; // EEPROM
|
||||
|
||||
|
||||
@@ -18,8 +18,10 @@ module tama (
|
||||
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
input cart_rd,
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
inout cart_oe_b,
|
||||
|
||||
input nCS,
|
||||
|
||||
@@ -44,6 +46,7 @@ wire has_battery;
|
||||
wire [63:0] savestate_back;
|
||||
wire [7:0] cram_wr_do;
|
||||
wire cram_wr;
|
||||
wire cart_oe;
|
||||
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
@@ -53,6 +56,7 @@ assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 64'hZ;
|
||||
assign cram_wr_do_b = enable ? cram_wr_do : 8'hZ;
|
||||
assign cram_wr_b = enable ? cram_wr : 1'hZ;
|
||||
assign cart_oe_b = enable ? cart_oe : 1'hZ;
|
||||
|
||||
// --------------------- CPU register interface ------------------
|
||||
// https://gbdev.gg8.se/forums/viewtopic.php?id=469
|
||||
@@ -321,6 +325,8 @@ assign cram_wr_do = reg_data_in;
|
||||
assign cram_do = { 4'hF, cram_do_r };
|
||||
assign cram_addr = { 12'd0, reg_addr };
|
||||
|
||||
assign cart_oe = (cart_rd & ~cart_a15) | (cram_rd & ~cart_addr[0]);
|
||||
|
||||
assign has_battery = 1;
|
||||
assign ram_enabled = 0;
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ package pReg_savestates is
|
||||
constant REG_SAVESTATE_Wave1_GBC : regmap_type := ( 35, 63, 0, 1, x"FF00FF00FF00FF00");
|
||||
constant REG_SAVESTATE_Wave2_GBC : regmap_type := ( 36, 63, 0, 1, x"FF00FF00FF00FF00");
|
||||
|
||||
constant REG_SAVESTATE_Top : regmap_type := ( 31, 53, 0, 1, x"0000000000800001");
|
||||
constant REG_SAVESTATE_Top : regmap_type := ( 31, 54, 0, 1, x"0000000000800001");
|
||||
constant REG_SAVESTATE_Top2 : regmap_type := ( 38, 10, 0, 1, x"0000000000000000");
|
||||
constant REG_SAVESTATE_Ext : regmap_type := ( 32, 15, 0, 1, x"0000000000000001");
|
||||
constant REG_SAVESTATE_Ext2 : regmap_type := ( 37, 63, 0, 1, x"0000000000000000");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user