-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfpga64_buslogic_roms_mmu.vhd
342 lines (305 loc) · 9.3 KB
/
fpga64_buslogic_roms_mmu.vhd
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
-- -----------------------------------------------------------------------
--
-- FPGA 64
--
-- A fully functional commodore 64 implementation in a single FPGA
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2008 by Peter Wendrich ([email protected])
-- http://www.syntiac.com/fpga64.html
-- -----------------------------------------------------------------------
-- -----------------------------------------------------------------------
-- Dar 08/03/2014
--
-- Based on mixing both fpga64_buslogic_roms and fpga64_buslogic_nommu
-- RAM should be external SRAM
-- Basic, Char and Kernel ROMs are included
-- Original Kernel replaced by JiffyDos
-- -----------------------------------------------------------------------
library IEEE;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
entity fpga64_buslogic is
port (
clk : in std_logic;
reset : in std_logic;
cpuHasBus : in std_logic;
ramData: in unsigned(7 downto 0);
-- 2 CHAREN
-- 1 HIRAM
-- 0 LORAM
bankSwitch: in unsigned(2 downto 0);
-- From cartridge port
game : in std_logic;
exrom : in std_logic;
c64rom_addr: in std_logic_vector(13 downto 0);
c64rom_data: in std_logic_vector(7 downto 0);
c64rom_wr: in std_logic;
cpuWe: in std_logic;
cpuAddr: in unsigned(15 downto 0);
cpuData: in unsigned(7 downto 0);
vicAddr: in unsigned(15 downto 0);
vicData: in unsigned(7 downto 0);
sidData: in unsigned(7 downto 0);
colorData: in unsigned(3 downto 0);
cia1Data: in unsigned(7 downto 0);
cia2Data: in unsigned(7 downto 0);
lastVicData : in unsigned(7 downto 0);
systemWe: out std_logic;
systemAddr: out unsigned(15 downto 0);
dataToCpu : out unsigned(7 downto 0);
dataToVic : out unsigned(7 downto 0);
cs_vic: out std_logic;
cs_sid: out std_logic;
cs_color : out std_logic;
cs_cia1: out std_logic;
cs_cia2: out std_logic;
cs_ram: out std_logic;
-- To catridge port
cs_ioE: out std_logic;
cs_ioF: out std_logic;
cs_romL : out std_logic;
cs_romH : out std_logic;
cs_UMAXromH : out std_logic
);
end fpga64_buslogic;
-- -----------------------------------------------------------------------
architecture rtl of fpga64_buslogic is
component fpga64_colorram is
port (
clk: in std_logic;
cs: in std_logic;
we: in std_logic;
addr: in unsigned(9 downto 0);
di: in unsigned(3 downto 0);
do: out unsigned(3 downto 0)
);
end component;
signal charData: unsigned(7 downto 0);
signal basicData: unsigned(7 downto 0);
signal romData: std_logic_vector(7 downto 0);
signal cs_CharReg : std_logic;
signal cs_romReg : std_logic;
signal vicCharReg : std_logic;
signal cs_ramReg : std_logic;
signal cs_vicReg : std_logic;
signal cs_sidReg : std_logic;
signal cs_colorReg : std_logic;
signal cs_cia1Reg : std_logic;
signal cs_cia2Reg : std_logic;
signal cs_ioEReg : std_logic;
signal cs_ioFReg : std_logic;
signal cs_romLReg : std_logic;
signal cs_romHReg : std_logic;
signal cs_UMAXromHReg : std_logic;
signal ultimax : std_logic;
signal currentAddr: unsigned(15 downto 0);
begin
charrom: entity work.rom_c64_chargen
port map (
clk => clk,
addr => currentAddr(11 downto 0),
do => charData
);
kernelrom: entity work.rom_C64
port map
(
clock => clk,
wren => c64rom_wr,
data => c64rom_data,
wraddress => c64rom_addr,
rdaddress => std_logic_vector(cpuAddr(14) & cpuAddr(12 downto 0)),
q => romData
);
--
--begin
process(ramData, vicData, sidData, colorData, cia1Data, cia2Data, charData, romData, cs_romHReg, cs_romLReg, cs_romReg, cs_CharReg, cs_ramReg, cs_vicReg, cs_sidReg, cs_colorReg, cs_cia1Reg, cs_cia2Reg, lastVicData)
begin
-- If no hardware is addressed the bus is floating.
-- It will contain the last data read by the VIC. (if a C64 is shielded correctly)
dataToCpu <= lastVicData;
if cs_CharReg = '1' then
dataToCpu <= charData;
elsif cs_romReg = '1' then
dataToCpu <= unsigned(romData);
elsif cs_ramReg = '1' then
dataToCpu <= ramData;
elsif cs_vicReg = '1' then
dataToCpu <= vicData;
elsif cs_sidReg = '1' then
dataToCpu <= sidData;
elsif cs_colorReg = '1' then
dataToCpu(3 downto 0) <= colorData;
elsif cs_cia1Reg = '1' then
dataToCpu <= cia1Data;
elsif cs_cia2Reg = '1' then
dataToCpu <= cia2Data;
elsif cs_romLReg = '1' then
dataToCpu <= ramData;
elsif cs_romHReg = '1' then
dataToCpu <= ramData;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
-- if ena = '1' then
currentAddr <= (others => '1'); -- Prevent generation of a latch when neither vic or cpu is using the bus.
systemWe <= '0';
vicCharReg <= '0';
cs_CharReg <= '0';
cs_romReg <= '0';
cs_ramReg <= '0';
cs_vicReg <= '0';
cs_sidReg <= '0';
cs_colorReg <= '0';
cs_cia1Reg <= '0';
cs_cia2Reg <= '0';
cs_ioEReg <= '0';
cs_ioFReg <= '0';
cs_romLReg <= '0';
cs_romHReg <= '0';
cs_UMAXromHReg <= '0'; -- Ultimax flag for the VIC access - LCA
-- ultimax <= '0';
if (exrom = '1') and (game = '0') then
ultimax <= '1';
else
ultimax <= '0';
end if;
if (cpuHasBus = '1') then
-- The 6502 CPU has the bus.
currentAddr <= cpuAddr;
case cpuAddr(15 downto 12) is
when X"E" | X"F" =>
-- if (cpuWe = '0') and (bankSwitch(1) = '1') and (cart_kernal = '1') then
-- if (cpuWe = '0') and (exrom = '1') and (game = '0') then
if (ultimax = '1') then
-- ULTIMAX MODE - drop out the kernal - LCA
cs_romHReg <= '1';
-- ultimax <= '1';
elsif (cpuWe = '0') and (bankSwitch(1) = '1') and (ultimax = '0') then
-- Read kernal
cs_romReg <= '1';
else
-- 64Kbyte RAM layout
cs_ramReg <= '1';
end if;
when X"D" =>
if (bankSwitch(1) = '0') and (bankSwitch(0) = '0') then
-- if (bankSwitch(1) = '0') and (bankSwitch(0) = '0') and (ultimax = '0') then
-- 64Kbyte RAM layout
cs_ramReg <= '1';
elsif bankSwitch(2) = '1' then
case cpuAddr(11 downto 8) is
when X"0" | X"1" | X"2" | X"3" =>
cs_vicReg <= '1';
when X"4" | X"5" | X"6" | X"7" =>
cs_sidReg <= '1';
when X"8" | X"9" | X"A" | X"B" =>
cs_colorReg <= '1';
when X"C" =>
cs_cia1Reg <= '1';
when X"D" =>
cs_cia2Reg <= '1';
when X"E" =>
cs_ioEReg <= '1';
when X"F" =>
cs_ioFReg <= '1';
when others =>
null;
end case;
else
-- I/O space turned off. Read from charrom or write to RAM.
if cpuWe = '0' then
cs_CharReg <= '1';
else
cs_ramReg <= '1';
end if;
end if;
when X"A" | X"B" =>
if (cpuWe = '0') and (exrom = '0') and (game = '0') and (bankSwitch(1) = '1') then
-- Access cartridge with romH
cs_romHReg <= '1';
-- elsif (cpuWe = '0') and (bankSwitch(1) = '1') and (bankSwitch(0) = '1') and (ultimax = '0') then
elsif (cpuWe = '0') and (bankSwitch(1) = '1') and (bankSwitch(0) = '1') then
-- Access basic rom
-- May need turning off if kernal banked out LCA
cs_romReg <= '1';
elsif (exrom = '0') or (game = '1') then
-- If not in Ultimax mode access ram
cs_ramReg <= '1';
end if;
when X"8" | X"9" =>
if (exrom = '1') and (game = '0') then
-- Ultimax access with romL
cs_romLReg <= '1';
elsif (cpuWe = '0')
and (bankSwitch(1) = '1')
and (bankSwitch(0) = '1')
and (exrom = '0') then
-- Access cartridge with romL
cs_romLReg <= '1';
else
cs_ramReg <= '1';
end if;
when X"0" =>
cs_ramReg <= '1';
when others =>
-- If not in Ultimax mode access ram
if (exrom = '0') or (game = '1') then
cs_ramReg <= '1';
end if;
end case;
systemWe <= cpuWe;
else
-- The VIC-II has the bus.
-- currentAddr <= vicAddr;
-- if ultimax = '0' then
-- if vicAddr(14 downto 12)="001" then
-- vicCharReg <= '1';
-- else
-- cs_ramReg <= '1';
-- end if;
-- elsif ultimax = '1' then
-- -- ultimax mode changes vic addressing - LCA
-- if vicAddr(13 downto 12)="11" then
-- cs_romHReg <= '1';
-- else
-- cs_ramReg <= '1';
-- end if;
-- The VIC-II has the bus.
currentAddr <= vicAddr;
if ultimax = '0' and vicAddr(14 downto 12)="001" then
vicCharReg <= '1';
elsif ultimax = '1' and vicAddr(13 downto 12)="11" then
-- ultimax mode changes vic addressing - LCA
cs_UMAXromHReg <= '1';
else
cs_ramReg <= '1';
end if;
end if;
end if;
-- end if;
end process;
-- cs_ram <= cs_ramReg;
cs_ram <= cs_ramReg or cs_romLReg or cs_romHReg or cs_UMAXromHReg; -- need to keep ram active for cartridges LCA
cs_vic <= cs_vicReg;
cs_sid <= cs_sidReg;
cs_color <= cs_colorReg;
cs_cia1 <= cs_cia1Reg;
cs_cia2 <= cs_cia2Reg;
cs_ioE <= cs_ioEReg;
cs_ioF <= cs_ioFReg;
cs_romL <= cs_romLReg;
cs_romH <= cs_romHReg;
cs_UMAXromH <= cs_UMAXromHReg;
process(ramData, charData, vicCharReg)
begin
if vicCharReg = '1' then
dataToVic <= charData;
else
dataToVic <= ramData;
end if;
end process;
systemAddr <= currentAddr;
end architecture;