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
18 module gtia_pmunit(clk_i
, dat_i
, pmdat_i
, dmadat_i
,
19 hpos_we
, size_we
, graf_we
, grafdma_we
,
26 input clk_i
, dat_i
, pmdat_i
, dmadat_i
;
27 input hpos_we
, size_we
, graf_we
, grafdma_we
;
28 input vdelay_we
, vdelay
;
36 wire [size
- 1:0] pmdat_i
, dmadat_i
;
37 wire hpos_we
, size_we
, graf_we
, grafdma_we
;
38 wire vdelay_we
, vdelay
;
46 reg [size
- 1:0] graf
;
47 reg [size
- 1:0] shift
;
52 assign out
= shift
[size
- 1];
54 always @ (posedge clk_i
) begin
66 always @ (posedge clk2_i
)
70 shift
<= {shift
[size
- 2:0], 1'b0};
72 always @ (posedge clk2_i
)
78 assign shift_en
= (size
== 2'b00) ||
(size
== 2'b10) ||
79 (size
== 2'b01 && cyccnt
[0]) ||
80 (size
== 2'b11 && cyccnt
== 2'b11);
84 module gtia_antic_input(clk2_i
,
94 output pf2c
, pf1lum_sel
;
104 wire pf2c
, pf1lum_sel
;
112 assign vsync
= (antic_out
== 3'b001);
113 assign blank
= (antic_out
== 3'b010 || antic_out
== 3'b011);
115 always @ (posedge clk2_i
)
116 if (!nrm || antic_out
== 3'b010)
118 else if (antic_out
== 3'b011)
121 // TODO: replace it with HCOUNT?
122 always @ (posedge clk2_i
)
128 always @ (posedge clk2_i
)
130 b
[3:2] <= antic_out
[1:0];
132 b
[1:0] <= antic_out
[1:0];
134 assign pf
[0] = (nrm
&& !chr40l
&& antic_out
== 3'b100) ||
135 (cl9
&& b
[2:0] == 3'b100);
136 assign pf
[1] = (nrm
&& !chr40l
&& antic_out
== 3'b101) ||
137 (cl9
&& b
[2:0] == 3'b101);
138 assign pf
[2] = (nrm
&& !chr40l
&& antic_out
== 3'b110) ||
139 (chr40l
&& antic_out
[2]) ||
140 (cl9
&& b
[2:0] == 3'b110);
141 assign pf
[3] = (nrm
&& !chr40l
&& antic_out
== 3'b111) ||
142 (cl9
&& b
[2:0] == 3'b111);
143 assign pf2c
= (nrm
&& !chr40l
&& antic_out
== 3'b110) ||
144 (cl9
&& b
[2:0] == 3'b110) ||
145 (chr40l
&& (antic_out
[1] || antic_out
[0]));
148 for (i
= 0; i
< 4; i
= i
+ 1)
149 adpl
[i
] = cl9
&& (b
== i
);
151 assign pf1lum_sel
= chr40l
&& !blank
&&
152 (clk2_i ? antic_out
[1] : antic_out
[0]);
155 module gtia_out(clk_i
,
157 colpm_we
, colpf_we
, colbak_we
, gtiactl_we
,
159 blank
, pl
, adpl
, mi
, pf
, pf1lum_sel
, b
,
163 input colpm_we
, colpf_we
, colbak_we
, gtiactl_we
;
164 input blank
, pl
, adpl
, mi
, pf
, pf1lum_sel
, b
;
177 wire nrm
, cl9
, c
, lu
;
194 reg [7:1] colpf
[0:3];
195 wire [7:1] colpf1
= colpf
[1];
196 reg [7:1] colpm
[0:3];
205 always @ (posedge clk_i
) begin
206 for (i
= 0; i
< 4; i
= i
+ 1)
208 colpm
[i
] <= dat_i
[7:1];
209 else if (colpf_we
[i
])
210 colpf
[i
] <= dat_i
[7:1];
212 colbak
<= dat_i
[7:1];
213 if (gtiactl_we
) begin
216 multi_colp
<= dat_i
[5];
221 assign pm
= pl | adpl |
(mi
& {4{~pl5th
}});
223 assign nrm
= (mode
== 2'b00);
224 assign cl9
= (mode
== 2'b10) && ! blank
;
225 assign c
= (mode
== 2'b11) && !blank
&& (pm
== 0);
226 assign lu
= (mode
== 2'b01) && !blank
&& (pm
== 0);
228 assign pf3_p5
= pf
[3] ||
(pl5th
&& (mi
!= 0));
230 assign sp
[0] = !blank
&& pm
[0] &&
231 (!(pf
[0] || pf
[1]) ||
(!prior
[2] && !prior
[3])) &&
232 (!(pf
[2] || pf3_p5
) ||
!prior
[2]);
233 assign sp
[1] = !blank
&& pm
[1] &&
234 (!(pf
[0] || pf
[1]) ||
(!prior
[2] && !prior
[3])) &&
235 (!(pf
[2] || pf3_p5
) ||
!prior
[2]) &&
236 (multi_colp ||
!pm
[0]);
237 assign sp
[2] = !blank
&& pm
[2] && !(pm
[0] || pm
[1]) &&
238 (!(pf
[0] || pf
[1]) || prior
[0]) &&
239 (!(pf
[2] || pf3_p5
) ||
(!prior
[1]) && !prior
[2]);
240 assign sp
[3] = !blank
&& pm
[3] && !(pm
[0] || pm
[1]) &&
241 (!(pf
[0] || pf
[1]) || prior
[0]) &&
242 (!(pf
[2] || pf3_p5
) ||
(!prior
[1]) && !prior
[2]) &&
243 (multi_colp ||
!pm
[2]);
245 assign sf
[3] = !blank
&& pf3_p5
&&
246 (!(pm
[0] || pm
[1]) || prior
[2]) &&
247 (!(pm
[2] || pm
[3]) ||
(!prior
[0] && !prior
[3]));
248 assign sf
[2] = !blank
&& pf
[2] && !sf
[3] &&
249 (!(pm
[0] || pm
[1]) || prior
[2]) &&
250 (!(pm
[2] || pm
[3]) ||
(!prior
[0] && !prior
[3]));
251 assign sf
[1] = !blank
&& pf
[1] && !sf
[3] &&
252 (!(pm
[0] || pm
[1]) ||
(!prior
[0] && !prior
[1])) &&
253 (!(pm
[2] || pm
[3]) ||
!prior
[0]);
254 assign sf
[0] = !blank
&& pf
[0] && !sf
[3] &&
255 (!(pm
[0] || pm
[1]) ||
(!prior
[0] && !prior
[1])) &&
256 (!(pm
[2] || pm
[3]) ||
!prior
[0]);
258 assign sb
= !blank
&& (pf
[2:0] == 0) && !pf3_p5
&& (pm
== 0);
260 always @ (sf
or sp
or sb
or pf1lum_sel
or b
or lu
or c
or
261 colpf
[0] or colpf
[1] or colpf
[2] or colpf
[3] or
262 colpm
[0] or colpm
[1] or colpm
[2] or colpm
[3] or colbak
) begin
264 for (si
= 0; si
< 4; si
= si
+ 1) begin
266 color
= color |
{colpm
[si
], 1'b0};
268 color
= color |
{colpf
[si
], 1'b0};
271 color
= color |
{colbak
, 1'b0};
273 color
= {color
[7:4], colpf1
[3:1], 1'b0};
275 color
= {color
[7:4], b
};
277 color
= {b
, color
[3:0]};
281 module gtia(rst_i
, clk_i
,
323 wire [2:0] antic_out
;
338 reg [3:0] grafpdma_we
;
350 wire [3:0] pl
, mi
, adpl
;
361 wire [3:0] consol_in
, consol_out
;
362 reg [3:0] consol_out_reg
;
369 assign ack_o
= stb_i
;
372 always @ (adr_i
or trig_reg
or consol_in
or consol_out_reg
)
373 if (adr_i
>= 0 && adr_i
< 4)
374 dat_o
= {4'h0
, mxpf
[adr_i
]};
375 else if (adr_i
>= 4 && adr_i
< 8)
376 dat_o
= {4'h0
, pxpf
[adr_i
- 4]};
377 else if (adr_i
>= 8 && adr_i
< 'hc
)
378 dat_o
= {4'h0
, mxpl
[adr_i
- 8]};
379 else if (adr_i
>= 'hc
&& adr_i
< 'h10
)
380 dat_o
= {4'h0
, pxpl
[adr_i
- 'hc
]};
381 else if (adr_i
>= 'h10
&& adr_i
< 'h14
)
382 dat_o
= {7'h0
, trig_reg
[adr_i
- 'h10
]};
383 else if (adr_i
== 'h14
)
384 dat_o
= 8'h1
; // 'h0f for NTSC
385 else if (adr_i
== 'h1f
)
386 dat_o
= {4'h0
, consol_in
&~ consol_out_reg
};
390 always @ (posedge clk_i
)
392 if (adr_i
== 'h1d
) begin
395 trig_latch
<= dat_i
[2];
396 end else if (adr_i
== 'h1f
) begin
397 consol_out_reg
<= dat_i
[3:0];
400 always @ (posedge clk_i
)
401 trig_reg
<= trig_latch ?
(trig_reg
& trig_in
) : trig_in
;
403 always @ (we_i
or stb_i
or adr_i
) begin
416 if (adr_i
>= 0 && adr_i
< 4)
418 else if (adr_i
>= 4 && adr_i
< 8)
419 hposm_we
[adr_i
- 4] = 1;
420 else if (adr_i
>= 8 && adr_i
< 'hc
)
421 sizep_we
[adr_i
- 8] = 1;
422 else if (adr_i
== 'hc
)
424 else if (adr_i
>= 'hd
&& adr_i
< 'h11
)
425 grafp_we
[adr_i
- 'hd
] = 1;
426 else if (adr_i
== 'h11
)
428 else if (adr_i
>= 'h12
&& adr_i
< 'h16
)
429 colpm_we
[adr_i
- 'h12
] = 1;
430 else if (adr_i
>= 'h16
&& adr_i
< 'h1a
)
431 colpf_we
[adr_i
- 'h16
] = 1;
432 else if (adr_i
== 'h1a
)
434 else if (adr_i
== 'h1b
)
436 else if (adr_i
== 'h1c
)
440 always @ (dmap
or dmam
or hcount
) begin
441 // TODO: GTIA count cycles from HALT (see datasheet).
442 for (gi
= 0; gi
< 4; gi
= gi
+ 1)
443 grafpdma_we
[gi
] = dmap
&& (hcount
== 4 + 2 * gi
);
444 grafmdma_we
= dmam
&& (hcount
== 0);
447 assign hsync
= (hcount
< 16);
449 gtia_antic_input
u_antic_input(clk2_i
, nrm
, cl9
,
456 always @ (posedge clk_i
)
457 if (stb_i
&& we_i
&& adr_i
== 'h1e
)
463 always @ (posedge clk2_i
)
465 for (ki
= 0; ki
< 4; ki
= ki
+ 1) begin
472 for (ki
= 0; ki
< 4; ki
= ki
+ 1) begin
474 mxpf
[ki
] <= mxpf
[ki
] | pf
[ki
];
475 mxpl
[ki
] <= mxpl
[ki
] | pl
[ki
];
478 pxpf
[ki
] <= pxpf
[ki
] | pf
[ki
];
479 pxpl
[ki
] <= pxpl
[ki
] |
(pl
[ki
] & ~(1 << ki
));
483 always @ (posedge clk2_i
)
486 always @ (posedge clk2_i
)
487 if (!last_blank
&& blank
)
489 else if (hcount
== 227)
492 hcount
<= hcount
+ 1;
494 gtia_out
u_out(.
clk_i(clk_i
), .
dat_i(dat_i
),
495 .
colpm_we(colpm_we
), .
colpf_we(colpf_we
),
496 .
colbak_we(colbak_we
), .
gtiactl_we(gtiactl_we
),
497 .
nrm(nrm
), .
cl9(cl9
),
498 .
blank(blank
), .
pl(pl
), .
adpl(adpl
), .
mi(mi
), .
pf(pf
), .
b(b
),
499 .
pf1lum_sel(pf1lum_sel
),
502 gtia_pmunit
u_pl0(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
),
504 .
hpos_we(hposp_we
[0]), .
size_we(sizep_we
[0]),
505 .
graf_we(grafp_we
[0]), .
grafdma_we(grafpdma_we
[0]),
506 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[4]),
507 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(pl
[0]));
508 gtia_pmunit
u_pl1(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
),
510 .
hpos_we(hposp_we
[1]), .
size_we(sizep_we
[1]),
511 .
graf_we(grafp_we
[1]), .
grafdma_we(grafpdma_we
[1]),
512 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[5]),
513 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(pl
[1]));
514 gtia_pmunit
u_pl2(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
),
516 .
hpos_we(hposp_we
[2]), .
size_we(sizep_we
[2]),
517 .
graf_we(grafp_we
[2]), .
grafdma_we(grafpdma_we
[2]),
518 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[6]),
519 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(pl
[2]));
520 gtia_pmunit
u_pl3(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
),
522 .
hpos_we(hposp_we
[3]), .
size_we(sizep_we
[3]),
523 .
graf_we(grafp_we
[3]), .
grafdma_we(grafpdma_we
[3]),
524 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[7]),
525 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(pl
[3]));
527 defparam u_m0.size
= 2;
528 defparam u_m1.size
= 2;
529 defparam u_m2.size
= 2;
530 defparam u_m3.size
= 2;
531 gtia_pmunit
u_m0(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
[1:0]),
532 .
dmadat_i(dmadat_i
[1:0]),
533 .
hpos_we(hposm_we
[0]), .
size_we(sizem_we
),
534 .
graf_we(grafm_we
), .
grafdma_we(grafmdma_we
),
535 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[0]),
536 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(mi
[0]));
537 gtia_pmunit
u_m1(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
[3:2]),
538 .
dmadat_i(dmadat_i
[3:2]),
539 .
hpos_we(hposm_we
[1]), .
size_we(sizem_we
),
540 .
graf_we(grafm_we
), .
grafdma_we(grafmdma_we
),
541 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[1]),
542 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(mi
[1]));
543 gtia_pmunit
u_m2(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
[5:4]),
544 .
dmadat_i(dmadat_i
[5:4]),
545 .
hpos_we(hposm_we
[2]), .
size_we(sizem_we
),
546 .
graf_we(grafm_we
), .
grafdma_we(grafmdma_we
),
547 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[2]),
548 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(mi
[2]));
549 gtia_pmunit
u_m3(.
clk_i(clk_i
), .
dat_i(dat_i
), .
pmdat_i(dat_i
[7:6]),
550 .
dmadat_i(dmadat_i
[7:6]),
551 .
hpos_we(hposm_we
[3]), .
size_we(sizem_we
),
552 .
graf_we(grafm_we
), .
grafdma_we(grafmdma_we
),
553 .
vdelay_we(vdelay_we
), .
vdelay(dat_i
[3]),
554 .
clk2_i(clk2_i
), .
hcount(hcount
), .
out(mi
[3]));
556 assign consol_out
= ~consol_out_reg
;