-
Notifications
You must be signed in to change notification settings - Fork 0
/
fpga64_buslogic.vhd
364 lines (325 loc) · 9.66 KB
/
fpga64_buslogic.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
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
-- -----------------------------------------------------------------------
--
-- 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;
bios : in std_logic_vector(1 downto 0);
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;
ioE_rom : in std_logic;
ioF_rom : in std_logic;
max_ram : in std_logic;
ioF_ext : in std_logic;
ioE_ext : in std_logic;
io_data : in unsigned(7 downto 0);
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: std_logic_vector(7 downto 0);
signal romData: std_logic_vector(7 downto 0);
signal romData_c64: std_logic_vector(7 downto 0);
signal romData_c64std: std_logic_vector(7 downto 0);
signal romData_c64gs: std_logic_vector(7 downto 0);
signal c64gs_ena : std_logic := '0';
signal c64std_ena : std_logic := '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
chargen: entity work.dprom
generic map ("roms/chargen.mif", 12)
port map
(
wrclock => clk,
rdclock => clk,
rdaddress => std_logic_vector(currentAddr(11 downto 0)),
q => charData
);
kernel_c64gs: entity work.dprom
generic map ("roms/std_C64GS.mif", 14)
port map
(
wrclock => clk,
rdclock => clk,
rdaddress => std_logic_vector(cpuAddr(14) & cpuAddr(12 downto 0)),
q => romData_c64gs
);
kernel_c64: entity work.dprom
generic map ("roms/std_C64.mif", 14)
port map
(
wrclock => clk,
rdclock => clk,
wren => c64rom_wr,
data => c64rom_data,
wraddress => c64rom_addr,
rdaddress => std_logic_vector(cpuAddr(14) & cpuAddr(12 downto 0)),
q => romData_c64
);
kernel_c64std: entity work.dprom
generic map ("roms/std_C64.mif", 14)
port map
(
wrclock => clk,
rdclock => clk,
rdaddress => std_logic_vector(cpuAddr(14) & cpuAddr(12 downto 0)),
q => romData_c64std
);
romData <= romData_c64gs when c64gs_ena = '1' else romData_c64std when c64std_ena = '1' else romData_c64;
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
c64gs_ena <= bios(1);
c64std_ena <= bios(0);
end if;
end if;
end process;
--
--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,
cs_ioEReg, cs_ioFReg, ioE_rom, ioF_rom,
ioE_ext, ioF_ext, io_data)
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 <= unsigned(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;
elsif cs_ioEReg = '1' and ioE_rom = '1' then
dataToCpu <= ramData;
elsif cs_ioFReg = '1' and ioF_rom = '1' then
dataToCpu <= ramData;
elsif cs_ioEReg = '1' and ioE_ext = '1' then
dataToCpu <= io_data;
elsif cs_ioFReg = '1' and ioF_ext = '1' then
dataToCpu <= io_data;
end if;
end process;
ultimax <= exrom and (not game);
process(clk)
begin
if rising_edge(clk) 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
if (cpuHasBus = '1') then
-- The 6502 CPU has the bus.
currentAddr <= cpuAddr;
case cpuAddr(15 downto 12) is
when X"E" | X"F" =>
if ultimax = '1' and cpuWe = '0' then
-- ULTIMAX MODE - drop out the kernal - LCA
cs_romHReg <= '1';
elsif cpuWe = '0' and bankSwitch(1) = '1' then
-- Read kernal
cs_romReg <= '1';
else
-- 64Kbyte RAM layout
cs_ramReg <= '1';
end if;
when X"D" =>
if (ultimax = '0' or max_ram = '1') and bankSwitch(1) = '0' and bankSwitch(0) = '0' then
-- 64Kbyte RAM layout
cs_ramReg <= '1';
elsif ultimax = '1' or 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 exrom = '0' and game = '0' and cpuWe = '0' and bankSwitch(1) = '1' then
-- Access cartridge with romH
cs_romHReg <= '1';
elsif ultimax = '0' and 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 ultimax = '0' or max_ram = '1' then
-- If not in Ultimax mode access ram
cs_ramReg <= '1';
end if;
when X"8" | X"9" =>
if ultimax = '1' then
-- Ultimax access with romL
cs_romLReg <= '1';
elsif exrom = '0' and bankSwitch(1) = '1' and bankSwitch(0) = '1' 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 ultimax = '0' or max_ram = '1' then
cs_ramReg <= '1';
end if;
end case;
systemWe <= cpuWe;
else
-- 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 process;
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;
dataToVic <= unsigned(charData) when vicCharReg = '1' else ramData;
systemAddr <= currentAddr;
end architecture;