External Wishbone bus and serial input/output registers
[AtosmChip.git] / atari.v
blob4a431f3a823bc81375994e41ee89d5e51eb5647b
1 // Atosm Chip
2 // Copyright (C) 2008 Tomasz Malesinski <tmal@mimuw.edu.pl>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 `include "cpu6502.v"
19 `include "memory.v"
20 `include "antic.v"
21 `include "gtia.v"
22 `include "pia.v"
23 `include "pokey.v"
25 module delay(clk, in, out);
26 input clk, in;
27 output out;
29 wire clk, in;
30 reg out;
31 reg tmp;
33 always @ (posedge clk) begin
34 tmp <= in;
35 out <= tmp;
36 end
37 endmodule
39 // Clock:
40 // clk2: 01010101
41 // clk: 00110011
43 // TODO: do something with reset, maybe reset Atari only with registers
44 module atari(clk_i, clk2_i, rst_i,
45 ext_rst_i, ext_clk_i,
46 ext_adr_i,
47 ext_dat_i, ext_dat_o,
48 ext_we_i, ext_stb_i,
49 ext_ack_o,
50 key_code, key_pressed,
51 key_shift, key_break,
52 key_start, key_select, key_option,
53 joystick, trig);
54 input clk_i;
55 input clk2_i;
56 input rst_i;
57 input ext_rst_i, ext_clk_i;
58 input ext_adr_i;
59 input ext_dat_i;
60 input ext_we_i, ext_stb_i;
61 input key_code, key_pressed;
62 input key_shift, key_break;
63 input key_start, key_select, key_option;
64 input joystick, trig;
66 output ext_dat_o, ext_ack_o;
68 wire clk_i;
69 wire clk2_i;
70 wire rst_i;
71 wire ext_rst_i, ext_clk_i;
72 wire [3:0] ext_adr_i;
73 wire [7:0] ext_dat_i;
74 reg [7:0] ext_dat_o;
75 wire ext_we_i, ext_stb_i, ext_ack_o;
76 wire [7:0] key_code;
77 wire key_pressed;
78 wire key_shift, key_break;
79 wire key_start, key_select, key_option;
80 wire [7:0] joystick;
81 wire [1:0] trig;
83 wire nmi, irq;
85 wire [7:0] portb;
87 wire [2:0] antic_out;
88 wire [7:0] color;
89 wire hsync, vsync;
91 wire [7:0] gtia_dmadat_i;
92 wire [3:0] consol_out;
94 // Serial input/output signals.
95 reg [7:0] serin;
96 wire [7:0] serout;
97 reg serin_rdy, serout_ack;
98 wire serin_ack, serout_rdy;
99 wire serin_rdy_d, serin_ack_d, serout_rdy_d, serout_ack_d;
100 wire sercmd;
102 // Common interconnect signals.
103 reg [15:0] adr;
104 reg [7:0] slavedat_o;
105 reg [7:0] masterdat_o;
106 reg stb;
107 reg we;
108 wire ack;
109 wire cyc;
111 // Masters outputs.
112 wire [15:0] cpuadr_o, anticadr_o;
113 wire [7:0] cpudat_o;
114 wire cpustb_o, anticstb_o;
115 wire cpuwe_o;
116 wire cpucyc_o, anticcyc_o;
118 // Outputs from address decoder.
119 reg ramsel, romsel, bassel;
120 reg anticsel, gtiasel, pokeysel, piasel;
121 reg dummysel;
123 // Outputs from arbiter.
124 wire cpugnt, anticgnt;
126 // Slaves STB_I signals.
127 wire ramstb, romstb, basstb;
128 wire anticstb_i, gtiastb, pokeystb, piastb;
129 wire dummystb;
131 // Slaves DAT_O signals.
132 wire [7:0] ramdat_o, romdat_o, basdat_o;
133 wire [7:0] anticdat_o, gtiadat_o, pokeydat_o, piadat_o;
135 // Slaves ACK_O signals.
136 wire ramack_o, romack_o, basack_o;
137 wire anticack_o, gtiaack_o, pokeyack_o, piaack_o;
139 // Masters ACK_I signals.
140 wire cpuack_i, anticack_i;
142 // External bus and registers.
144 assign ext_ack_o = ext_stb_i;
146 always @ (ext_adr_i)
147 if (ext_adr_i == 'h0)
148 ext_dat_o = serout;
149 else if (ext_adr_i == 'h2)
150 ext_dat_o = {sercmd,
151 serout_rdy_d && !serout_ack,
152 !serin_ack_d && !serin_rdy};
153 else
154 ext_dat_o = 'hff;
156 // Serial input data and control signals.
157 always @ (posedge ext_clk_i) begin
158 if (rst_i)
159 serin_rdy <= 0;
160 else begin
161 if (ext_we_i && ext_stb_i && ext_adr_i == 'h1) begin
162 serin <= ext_dat_i;
163 if (!serin_ack_d)
164 serin_rdy <= 1;
166 if (serin_ack_d)
167 serin_rdy <= 0;
171 // Serial output control signals.
172 always @ (posedge ext_clk_i)
173 if (rst_i)
174 serout_ack <= 0;
175 else if (!ext_we_i && ext_stb_i && ext_adr_i == 'h0 && serout_rdy_d)
176 serout_ack <= 1;
177 else if (!serout_rdy_d)
178 serout_ack <= 0;
180 delay u_serin_rdy_delay(.clk(clk_i), .in(serin_rdy), .out(serin_rdy_d));
181 delay u_serin_ack_delay(.clk(ext_clk_i), .in(serin_ack), .out(serin_ack_d));
182 delay u_serout_rdy_delay(.clk(ext_clk_i),
183 .in(serout_rdy), .out(serout_rdy_d));
184 delay u_serout_ack_delay(.clk(clk_i), .in(serout_ack), .out(serout_ack_d));
186 // Arbiter.
187 // TODO: should it be synchronous?
188 assign cpugnt = cpucyc_o && !anticcyc_o;
189 assign anticgnt = anticcyc_o;
190 assign cyc = cpucyc_o | anticcyc_o;
192 // Masters outputs multiplexer.
193 always @ (cpuadr_o or cpudat_o or cpuwe_o or cpustb_o or
194 anticadr_o or anticstb_o or
195 cpugnt or anticgnt) begin
196 if (anticgnt) begin
197 adr = anticadr_o;
198 masterdat_o = 0;
199 we = 0;
200 stb = anticstb_o;
201 end else begin
202 adr = cpuadr_o;
203 masterdat_o = cpudat_o;
204 we = cpuwe_o;
205 stb = cpustb_o;
209 // Address decoder.
210 always @ (adr or portb) begin
211 ramsel = 0;
212 romsel = 0;
213 bassel = 0;
214 anticsel = 0;
215 gtiasel = 0;
216 pokeysel = 0;
217 piasel = 0;
218 anticsel = 0;
219 dummysel = 0;
220 if (adr[15:7] == {'h50, 1'b1} && !portb[7])
221 romsel = 1;
222 else if (adr[15:8] >= 'ha0 && adr[15:8] < 'hc0 && !portb[1])
223 bassel = 1;
224 else if (adr[15:8] == 'hd0)
225 gtiasel = 1;
226 else if (adr[15:8] == 'hd2)
227 pokeysel = 1;
228 else if (adr[15:8] == 'hd3)
229 piasel = 1;
230 else if (adr[15:8] == 'hd4)
231 anticsel = 1;
232 else if (adr[15:8] == 'hd1 || adr[15:8] == 'hd5 || adr[15:8] == 'hd6 ||
233 adr[15:8] == 'hd7)
234 dummysel = 1;
235 else if (adr[15:8] >= 'hc0 && portb[0])
236 romsel = 1;
237 else
238 ramsel = 1;
241 // Slaves STB_I.
242 assign ramstb = ramsel & cyc & stb;
243 assign romstb = romsel & cyc & stb;
244 assign basstb = bassel & cyc & stb;
245 assign anticstb_i = anticsel & cyc & stb;
246 assign gtiastb = gtiasel & cyc & stb;
247 assign pokeystb = pokeysel & cyc & stb;
248 assign piastb = piasel & cyc & stb;
249 assign dummystb = dummysel & cyc & stb;
251 // Or'd slaves ACK_O.
252 assign ack = ramack_o | romack_o | basack_o | anticack_o | gtiaack_o |
253 pokeyack_o | piaack_o | dummystb;
255 // Slaves DAT_O multiplexer.
256 always @ (ramsel or ramdat_o or
257 romsel or romdat_o or
258 bassel or basdat_o or
259 anticsel or anticdat_o or
260 gtiasel or gtiadat_o or
261 pokeysel or pokeydat_o or
262 piasel or piadat_o)
263 if (ramsel)
264 slavedat_o = ramdat_o;
265 else if (romsel)
266 slavedat_o = romdat_o;
267 else if (bassel)
268 slavedat_o = basdat_o;
269 else if (anticsel)
270 slavedat_o = anticdat_o;
271 else if (gtiasel)
272 slavedat_o = gtiadat_o;
273 else if (pokeysel)
274 slavedat_o = pokeydat_o;
275 else if (piasel)
276 slavedat_o = piadat_o;
277 else
278 slavedat_o = 'hff;
280 // Masters ACK_I signals.
281 assign anticack_i = ack & anticgnt;
282 assign cpuack_i = ack & cpugnt;
284 defparam u_ram.size = 'h10000;
285 defparam u_ram.adrbits = 16;
287 ram u_ram(.clk_i(clk_i),
288 .adr_i(adr),
289 .dat_i(cpudat_o),
290 .rst_i(rst_i),
291 .stb_i(ramstb),
292 .we_i(we),
293 .ack_o(ramack_o),
294 .dat_o(ramdat_o));
296 defparam u_rom.size = 'h4000;
297 defparam u_rom.adrbits = 14;
299 rom u_rom(.clk_i(clk_i),
300 .adr_i(adr[13:0]),
301 .rst_i(rst_i),
302 .stb_i(romstb),
303 .ack_o(romack_o),
304 .dat_o(romdat_o));
306 defparam u_basic_rom.size = 'h2000;
307 defparam u_basic_rom.adrbits = 13;
309 rom u_basic_rom(.clk_i(clk_i),
310 .adr_i(adr[12:0]),
311 .rst_i(rst_i),
312 .stb_i(basstb),
313 .ack_o(basack_o),
314 .dat_o(basdat_o));
316 cpu6502 u_cpu(.clk_i(clk_i),
317 .adr_o(cpuadr_o),
318 .dat_i(slavedat_o),
319 .rst_i(rst_i),
320 .stb_o(cpustb_o),
321 .we_o(cpuwe_o),
322 .ack_i(cpuack_i),
323 .dat_o(cpudat_o),
324 .cyc_o(cpucyc_o),
325 .nmi(nmi),
326 .irq(irq));
328 antic u_antic(.clk_i(clk_i),
329 .adr_i(adr[3:0]),
330 .adr_o(anticadr_o),
331 .slavedat_i(cpudat_o),
332 .masterdat_i(slavedat_o),
333 .rst_i(rst_i),
334 .stb_i(anticstb_i),
335 .stb_o(anticstb_o),
336 .we_i(we),
337 .ack_i(anticack_i),
338 .ack_o(anticack_o),
339 .dat_o(anticdat_o),
340 .cyc_o(anticcyc_o),
341 .clk2_i(clk2_i),
342 .nmi(nmi),
343 .antic_out(antic_out));
345 assign gtia_dmadat_i = we ? masterdat_o : slavedat_o;
347 gtia u_gtia(.clk_i(clk_i),
348 .adr_i(adr[4:0]),
349 .dat_i(cpudat_o),
350 .rst_i(rst_i),
351 .stb_i(gtiastb),
352 .we_i(we),
353 .ack_o(gtiaack_o),
354 .dat_o(gtiadat_o),
355 .clk2_i(clk2_i),
356 .dmadat_i(gtia_dmadat_i),
357 .antic_out(antic_out),
358 .color(color),
359 .hsync(hsync),
360 .vsync(vsync),
361 // trig[3] = 0 - no cartridge
362 .trig_in({2'b0, ~trig}),
363 .consol_in({1'b0, ~key_start, ~key_select, ~key_option}),
364 .consol_out(consol_out));
366 pia u_pia(.clk_i(clk_i),
367 .adr_i(adr[1:0]),
368 .dat_i(cpudat_o),
369 .rst_i(rst_i),
370 .stb_i(piastb),
371 .we_i(we),
372 .ack_o(piaack_o),
373 .dat_o(piadat_o),
374 .pa_i(~joystick),
375 .pb_o(portb),
376 .cb2_o(sercmd));
378 pokey u_pokey(.clk_i(clk_i),
379 .adr_i(adr[3:0]),
380 .dat_i(cpudat_o),
381 .rst_i(rst_i),
382 .stb_i(pokeystb),
383 .we_i(we),
384 .ack_o(pokeyack_o),
385 .dat_o(pokeydat_o),
386 .irq(irq),
387 .key_code(key_code), .key_pressed(key_pressed),
388 .key_shift(key_shift), .key_break(key_break),
389 .serout(serout), .serout_rdy_o(serout_rdy),
390 .serout_ack_i(serout_ack_d),
391 .serin(serin), .serin_rdy_i(serin_rdy_d),
392 .serin_ack_o(serin_ack));
394 endmodule