-
Notifications
You must be signed in to change notification settings - Fork 17
/
GB MBC5-1 Hybrid - R1.1 (2MB ROM, 128KB SRAM).txt
177 lines (152 loc) · 4.64 KB
/
GB MBC5-1 Hybrid - R1.1 (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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
Gameboy MBC5/MBC1 Hybrid - 2MB ROM, 128KB SRAM
Firmware: R1.1
Author: Alex from insideGadgets (www.insidegadgets.com)
Created: 7/11/2018
Last Modified: 8/09/2018
Checksum of pof file: D95E3
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.
MBC1 support now allows for ROM banking mode to 2MB but for RAM banking mode it's locked to 8KB RAM.
*/
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;
reg mbc1RomRamSelect;
// 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;
mbc1RomRamSelect <= 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 // Detects MBC1 (most of the time)
if (mbc1Detected607F && !mbc3or5Locked && !mbc1RomRamSelect) begin // Allow for more than 512KB ROM on MBC1
romBank <= (romBank & 7'h60) | 7'b1;
end
else begin // For all others
romBank <= 1'b1;
end
mbc1Detect303FOn <= 1'b1;
end
else begin
if (inputData >= 7'd32) begin // Lock to MBC3/5 mode if bank switched to >= 0x20
mbc3or5Locked <= 1'b1;
end
// MBC1 handling of ROM size
if (mbc1Detected607F && !mbc3or5Locked) begin
if (mbc1RomRamSelect) begin // 32KB RAM mode (not supported)
romBank <= inputData[4:0];
end
else begin // Up to 2MB ROM Mode
romBank <= (romBank & 7'h60) | inputData[4:0];
end
end
else begin // MBC 2/3/5
romBank <= inputData;
end
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 (mbc1Detected607F && !mbc3or5Locked) begin // MBC1 ROM size handling, ignores RAM banking request
if (!mbc1RomRamSelect) begin
romBank <= (romBank & 7'h1F) | (inputData[1:0] << 5); //inputData[1:0] << 5;
end
end
else begin // Allow access to all RAM banks for regular MBC 3/5 carts
ramBank <= inputData[3:0];
end
end
// 0x6000-7FFF - MBC1 ROM/RAM Mode Detection
if ((inputAddress == 4'd6 || inputAddress == 4'd7) && !inputWR && inputRD && inputCE) begin
mbc1Detect303FOn <= 1'b1;
mbc1Detected607F <= 1'b1;
mbc1RomRamSelect <= inputData[0:0];
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