2 // Copyright (C) 2008 Tomasz Malesinski <tmal@mimuw.edu.pl>
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.
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
25 module delay(clk
, in
, out
);
33 always @ (posedge clk
) begin
43 // TODO: do something with reset, maybe reset Atari only with registers
44 module atari(clk_i
, clk2_i
, rst_i
,
50 key_code
, key_pressed
,
52 key_start
, key_select
, key_option
,
57 input ext_rst_i
, ext_clk_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
;
66 output ext_dat_o
, ext_ack_o
;
71 wire ext_rst_i
, ext_clk_i
;
75 wire ext_we_i
, ext_stb_i
, ext_ack_o
;
78 wire key_shift
, key_break
;
79 wire key_start
, key_select
, key_option
;
91 wire [7:0] gtia_dmadat_i
;
92 wire [3:0] consol_out
;
94 // Serial input/output signals.
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
;
102 // Common interconnect signals.
104 reg [7:0] slavedat_o
;
105 reg [7:0] masterdat_o
;
112 wire [15:0] cpuadr_o
, anticadr_o
;
114 wire cpustb_o
, anticstb_o
;
116 wire cpucyc_o
, anticcyc_o
;
118 // Outputs from address decoder.
119 reg ramsel
, romsel
, bassel
;
120 reg anticsel
, gtiasel
, pokeysel
, piasel
;
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
;
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
;
147 if (ext_adr_i
== 'h0
)
149 else if (ext_adr_i
== 'h2
)
151 serout_rdy_d
&& !serout_ack
,
152 !serin_ack_d
&& !serin_rdy
};
156 // Serial input data and control signals.
157 always @ (posedge ext_clk_i
) begin
161 if (ext_we_i
&& ext_stb_i
&& ext_adr_i
== 'h1
) begin
171 // Serial output control signals.
172 always @ (posedge ext_clk_i
)
175 else if (!ext_we_i
&& ext_stb_i
&& ext_adr_i
== 'h0
&& serout_rdy_d
)
177 else if (!serout_rdy_d
)
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
));
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
203 masterdat_o
= cpudat_o
;
210 always @ (adr
or portb
) begin
220 if (adr
[15:7] == {'h50
, 1'b1} && !portb
[7])
222 else if (adr
[15:8] >= 'ha0
&& adr
[15:8] < 'hc0
&& !portb
[1])
224 else if (adr
[15:8] == 'hd0
)
226 else if (adr
[15:8] == 'hd2
)
228 else if (adr
[15:8] == 'hd3
)
230 else if (adr
[15:8] == 'hd4
)
232 else if (adr
[15:8] == 'hd1 || adr
[15:8] == 'hd5 || adr
[15:8] == 'hd6 ||
235 else if (adr
[15:8] >= 'hc0
&& portb
[0])
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
264 slavedat_o
= ramdat_o
;
266 slavedat_o
= romdat_o
;
268 slavedat_o
= basdat_o
;
270 slavedat_o
= anticdat_o
;
272 slavedat_o
= gtiadat_o
;
274 slavedat_o
= pokeydat_o
;
276 slavedat_o
= piadat_o
;
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
),
296 defparam u_rom.size
= 'h4000
;
297 defparam u_rom.adrbits
= 14;
299 rom
u_rom(.
clk_i(clk_i
),
306 defparam u_basic_rom.size
= 'h2000
;
307 defparam u_basic_rom.adrbits
= 13;
309 rom
u_basic_rom(.
clk_i(clk_i
),
316 cpu6502
u_cpu(.
clk_i(clk_i
),
328 antic
u_antic(.
clk_i(clk_i
),
331 .
slavedat_i(cpudat_o
),
332 .
masterdat_i(slavedat_o
),
343 .
antic_out(antic_out
));
345 assign gtia_dmadat_i
= we ? masterdat_o
: slavedat_o
;
347 gtia
u_gtia(.
clk_i(clk_i
),
356 .
dmadat_i(gtia_dmadat_i
),
357 .
antic_out(antic_out
),
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
),
378 pokey
u_pokey(.
clk_i(clk_i
),
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
));