-
Notifications
You must be signed in to change notification settings - Fork 17
/
GB MBC5-1 Hybrid - R1 (2MB ROM, 128KB SRAM).txt
151 lines (129 loc) · 3.74 KB
/
GB MBC5-1 Hybrid - R1 (2MB ROM, 128KB SRAM).txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
Gameboy MBC5/MBC1 Hybrid (For 2MB ROM and 128KB SRAM)
Version: 1.0
Author: Alex from insideGadgets (www.insidegadgets.com)
Created: 18/04/2018
Last Modified: 6/08/2018
License: CC-BY
Note: Having some MBC1 support may break a few MBC5 games.
Our MBC5 implementation differs from the standard, switching to bank 0 gives bank 1 like in MBC1/3.
Our MBC1 support is limited to 512KB ROM / 8 KBytes RAM, it’s locked in “ROM Banking Mode” but without the 2MB ROM support.
*/
module mbc5_2mb_v1 (
//clockin, // For ModelSim
reset,
inputAddress, inputData, inputCE, inputWR, inputRD,
highAddress, ramCE);
// Inputs
input reset;
input [3:0] inputAddress; // a15 - a12
input [6:0] inputData; // d6 - d0
input inputCE;
input inputRD;
input inputWR;
// Outputs / Registers
output [7:0] highAddress; // a20 - a13
reg [7:0] highAddress;
reg [6:0] romBank; // a20 - a14
reg [3:0] ramBank; // a16 - a13
reg ramEnabled;
output ramCE;
reg ramCE;
reg mbc1Detect303FOn;
reg mbc1Detected607F;
reg mbc3or5Locked;
// For ModelSim
/*input clockin;
reg clockin;
reg reset;
reg [3:0] inputAddress; // a12 - a15
reg [6:0] inputData; // d0 - d7
reg inputCE;
reg inputRD;
reg inputWR;
reg audioIn;
*/
// ROM a0-a13 straight through, a14-a21 from CPLD highAddress [1:8]
// RAM a0-a12 straight through, a13-a16 from CPLD highAddress [0:3]
// input RD, WR, CS straight through to ROM
// input RD, WR, straight through to RAM, CE handled by CPLD
// romCE to A15
always @ (reset or inputCE or inputRD or inputWR) begin
if (!reset) begin
highAddress <= 8'b0;
romBank <= 7'b1;
ramBank <= 4'b0;
ramEnabled <= 1'b0;
ramCE <= 1'b1;
mbc1Detect303FOn <= 1'b0;
mbc1Detected607F <= 1'b0;
mbc3or5Locked <= 1'b0;
end
else begin
// *** ROM Functions ***
// Only pass through on 0x0000-7FFF if reading or writing flash
if (inputAddress <= 4'd7 && (!inputRD || !inputWR)) begin
if (inputAddress <= 4'd3) begin // 0x0000-3FFF, Bank 0 always
highAddress <= 8'b0; // All set to 0
end
else begin
highAddress <= (romBank << 1); // Start at a14 for ROM
end
end
// 0x2000-3FFF - Low 7 bits of ROM Bank Number (Write Only) with little MBC1 detection hack
if (((inputAddress == 4'd2) || inputAddress == 4'd3 && mbc1Detect303FOn) && !inputWR && inputRD && inputCE) begin
if (inputData == 7'd0) begin
romBank <= 1'b1;
mbc1Detect303FOn <= 1'b1;
end
else begin
if (inputData >= 7'd32) begin
mbc3or5Locked <= 1'b1;
end
romBank <= inputData;
end
end
// *** RAM Functions ***
ramCE <= 1'b1;
// Only pass through on 0xA000-BFFF if RAM is enabled
if ((inputAddress == 4'hA || inputAddress == 4'hB) && ramEnabled && (!inputRD || !inputWR)) begin
ramCE <= inputCE;
highAddress <= ramBank;
end
// 0x0000-1FFF - RAM Enable (Write Only). 0x0A = Enable, 0x00 Disable
if ((inputAddress == 4'd1 || inputAddress == 4'd0) && !inputWR && inputRD && inputCE) begin
if (inputData == 7'hA) begin // Enable RAM
ramEnabled <= 1'd1;
end
else begin // Disable RAM
ramEnabled <= 1'd0;
end
end
// 0x4000-5FFF - RAM Bank Number (Write Only)
if ((inputAddress == 4'd4 || inputAddress == 4'd5) && !inputWR && inputRD && inputCE) begin
if ((mbc1Detect303FOn && mbc1Detected607F) && !mbc3or5Locked) begin // Ignore RAM banking requests
end
else begin
ramBank <= inputData[3:0];
end
end
// 0x6000-7FFF - ROM/RAM Mode MBC1 Detection
if ((inputAddress == 4'd6 || inputAddress == 4'd7) && !inputWR && inputRD && inputCE) begin
mbc1Detected607F <= 1'b1;
end
end
end
// For ModelSim
/*initial
begin
reset = 1'b0;
clockin = 1'b0;
inputAddress = 1'b0;
inputData = 1'b0;
inputCE = 1'b1;
inputRD = 1'b1;
inputWR = 1'b1;
audioIn = 1'b1;
forever #5 clockin = ~clockin;
end*/
endmodule