Code:
module MBC5
(
input not_reset,
input not_cs,
input not_wr,
input [7:0] data, // data bus value
input [3:0] address, // top 4 bits of address
output [8:0] out_rom_bank, // 9-bit ROM bank to use
output reg [3:0] ram_bank, // 4-bit RAM bank to use
output out_ram_enable // active low RAM enable
);
reg [8:0] rom_bank; // currently selected ROM bank
reg ram_enable; // is RAM enabled?
always@(posedge not_wr or negedge not_reset) begin // may need negedge instead?
if (!not_reset) begin
ram_enable <= 0;
rom_bank <= 1;
ram_bank <= 0;
end
else if(!not_wr) begin
case(address) // select based on top 4 bits of address
0, 1:
ram_enable <= data == 8'h0a;
2:
rom_bank[7:0] <= data;
3:
rom_bank[8] <= data[0];
4, 5:
ram_bank <= data[3:0];
// anything 6 or above ignored
endcase
end
end
// select fixed bank or switchable bank
assign out_rom_bank = address[2] ? rom_bank : 0;
// select external RAM at 0xA000 - 0xBFFF
assign out_ram_enable = !(ram_enable && address[3:1] == 3'b101);
endmodule
(
input not_reset,
input not_cs,
input not_wr,
input [7:0] data, // data bus value
input [3:0] address, // top 4 bits of address
output [8:0] out_rom_bank, // 9-bit ROM bank to use
output reg [3:0] ram_bank, // 4-bit RAM bank to use
output out_ram_enable // active low RAM enable
);
reg [8:0] rom_bank; // currently selected ROM bank
reg ram_enable; // is RAM enabled?
always@(posedge not_wr or negedge not_reset) begin // may need negedge instead?
if (!not_reset) begin
ram_enable <= 0;
rom_bank <= 1;
ram_bank <= 0;
end
else if(!not_wr) begin
case(address) // select based on top 4 bits of address
0, 1:
ram_enable <= data == 8'h0a;
2:
rom_bank[7:0] <= data;
3:
rom_bank[8] <= data[0];
4, 5:
ram_bank <= data[3:0];
// anything 6 or above ignored
endcase
end
end
// select fixed bank or switchable bank
assign out_rom_bank = address[2] ? rom_bank : 0;
// select external RAM at 0xA000 - 0xBFFF
assign out_ram_enable = !(ram_enable && address[3:1] == 3'b101);
endmodule
I don't know if the lack (is there one? Tepples keeps mentioning it) of >32KB Game Boy boards is because of a lack of open MBC implementations or some other reasons, but I really doubt it's a cost problem because the parts to implement a mapper are so cheap. In any case, here's a (public domain) MBC5 I wrote, that works in simulation at least. I'm not entirely confident in the clocking being correct, or what the reset values should be, but it should hopefully only require minor changes. It easily fits in an Xilinx XC9536XL, using 24 of the 36 macrocells.