Generate out_reg_shift in ms_hcount_seq
[AtosmChip.git] / antic.v
blob6d48bf68f26fb6827624f48b2907bc029bd5000c
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 module antic_ms_hcount_seq(ms_hcount,
19 new_block, dma_block, dma_pf_width, ir,
20 shift_reg_shift, load_pf, load_out, out_reg_shift);
21 input ms_hcount;
22 input new_block, dma_block, dma_pf_width, ir;
23 output shift_reg_shift, load_pf, load_out, out_reg_shift;
25 wire [7:0] ms_hcount;
26 wire new_block, dma_block;
27 wire [1:0] dma_pf_width;
28 wire [7:0] ir;
29 wire shift_reg_shift;
30 reg load_pf, load_out;
31 wire out_reg_shift;
33 reg [3:0] pf_byte_mod;
34 reg [1:0] pf_pixel_mod;
36 always @ (ir)
37 case (ir[3:0])
38 'h2: begin
39 pf_byte_mod = 3;
40 pf_pixel_mod = 0;
41 end
42 'h3: begin
43 pf_byte_mod = 3;
44 pf_pixel_mod = 0;
45 end
46 'h4: begin
47 pf_byte_mod = 3;
48 pf_pixel_mod = 0;
49 end
50 'h5: begin
51 pf_byte_mod = 3;
52 pf_pixel_mod = 0;
53 end
54 'h6: begin
55 pf_byte_mod = 7;
56 pf_pixel_mod = 0;
57 end
58 'h7: begin
59 pf_byte_mod = 7;
60 pf_pixel_mod = 0;
61 end
62 'h8: begin
63 pf_byte_mod = 15;
64 pf_pixel_mod = 3;
65 end
66 'h9: begin
67 pf_byte_mod = 15;
68 pf_pixel_mod = 1;
69 end
70 'ha: begin
71 pf_byte_mod = 7;
72 pf_pixel_mod = 1;
73 end
74 'hb: begin
75 pf_byte_mod = 7;
76 pf_pixel_mod = 0;
77 end
78 'hc: begin
79 pf_byte_mod = 7;
80 pf_pixel_mod = 0;
81 end
82 'hd: begin
83 pf_byte_mod = 3;
84 pf_pixel_mod = 0;
85 end
86 'he: begin
87 pf_byte_mod = 3;
88 pf_pixel_mod = 0;
89 end
90 'hf: begin
91 pf_byte_mod = 3;
92 pf_pixel_mod = 0;
93 end
94 default: begin
95 pf_byte_mod = 3;
96 pf_pixel_mod = 0;
97 end
98 endcase
100 assign shift_reg_shift = (ms_hcount >= 3) && (ms_hcount < 195) &&
101 (ms_hcount[1:0] == 3);
103 assign out_reg_shift = ((ms_hcount[1:0] & pf_pixel_mod) ==
104 (2'd2 & pf_pixel_mod));
106 always @ (new_block or dma_block or dma_pf_width or ms_hcount or
107 pf_byte_mod or ir) begin
108 load_pf = 0;
109 if (new_block && dma_block) begin
110 if (dma_pf_width == 1 && !ir[4])
111 load_pf = ((ms_hcount & pf_byte_mod) == (3 & pf_byte_mod)) &&
112 (ms_hcount >= 35) && (ms_hcount < 163);
113 else if (dma_pf_width == (ir[4] ? 1 : 2))
114 load_pf = ((ms_hcount & pf_byte_mod) == (3 & pf_byte_mod)) &&
115 (ms_hcount >= 19) && (ms_hcount < 179);
116 else if (dma_pf_width == 3 || (ir[4] && dma_pf_width == 2))
117 load_pf = ((ms_hcount & pf_byte_mod) == (3 & pf_byte_mod)) &&
118 (ms_hcount >= 3) && (ms_hcount < 195);
122 always @ (dma_block or dma_pf_width or ms_hcount or pf_byte_mod) begin
123 load_out = 0;
124 if (dma_block)
125 case (dma_pf_width)
126 1: load_out = ((ms_hcount & pf_byte_mod) == (9 & pf_byte_mod)) &&
127 (ms_hcount >= 41 && ms_hcount < 169);
128 2: load_out = ((ms_hcount & pf_byte_mod) == (9 & pf_byte_mod)) &&
129 (ms_hcount >= 25 && ms_hcount < 185);
130 3: load_out = ((ms_hcount & pf_byte_mod) == (9 & pf_byte_mod)) &&
131 (ms_hcount >= 9 && ms_hcount < 201);
132 endcase
134 endmodule
136 module antic_shift_reg(clk_i, shift, load, in, out);
137 input clk_i;
138 input shift;
139 input load;
140 input in;
142 output out;
144 wire clk_i;
145 wire shift;
146 wire load;
147 wire [7:0] in;
148 wire [7:0] out;
150 reg [7:0] shift_reg [0:47];
152 integer i;
154 assign out = shift_reg[1];
156 always @ (posedge clk_i) begin
157 if (shift)
158 for (i = 0; i < 47; i = i + 1)
159 shift_reg[i + 1] <= shift_reg[i];
160 if (load)
161 shift_reg[0] <= in;
162 else if (shift)
163 shift_reg[0] <= shift_reg[47];
165 endmodule
167 module antic(rst_i, clk_i,
168 adr_i, adr_o,
169 slavedat_i, masterdat_i,
170 dat_o,
171 we_i,
172 stb_i, stb_o,
173 ack_i, ack_o,
174 cyc_o,
175 clk2_i,
176 nmi,
177 antic_out);
178 input rst_i;
179 input clk_i;
180 input adr_i;
181 input slavedat_i;
182 input masterdat_i;
183 input we_i;
184 input stb_i;
185 input ack_i;
186 input clk2_i;
188 output adr_o;
189 output dat_o;
190 output stb_o;
191 output ack_o;
192 output cyc_o;
193 output nmi;
194 output antic_out;
196 wire rst_i, clk_i;
197 wire [3:0] adr_i;
198 wire [7:0] slavedat_i;
199 wire [7:0] masterdat_i;
200 wire we_i;
201 wire stb_i;
202 wire ack_i;
203 wire clk2_i;
205 reg [15:0] adr_o;
206 reg [7:0] dat_o;
207 wire stb_o;
208 wire ack_o;
209 wire cyc_o;
210 wire nmi;
211 reg [2:0] antic_out;
213 reg [1:0] dma_pf_width;
214 reg dma_mis_en;
215 reg dma_ply_en;
216 reg dma_pm_1res;
217 reg dma_instr_en;
219 reg [6:0] chbase;
220 reg [2:0] chactl;
221 reg [5:0] pmbase;
222 reg [3:0] hscrol;
223 reg [3:0] vscrol;
225 wire nmireq_dli, nmireq_vbi;
226 reg nmist_dli, nmist_vbi;
227 reg nmien_dli, nmien_vbi;
229 reg [15:0] dlist_ctr;
230 reg [7:0] dlist_ctr_tmp;
231 wire dl_load;
233 reg [15:0] memscan_ctr;
235 reg [7:0] hcount;
236 reg [8:0] vcount;
237 reg [3:0] dcount;
238 reg [7:0] ms_hcount;
240 reg [7:0] ir;
241 reg new_block;
242 reg [3:0] maxline;
243 wire dli;
244 wire wait_vblank;
245 wire dma_block;
246 reg char_block;
247 reg one_bit_pixel;
249 reg wsync;
251 wire load_instr;
252 wire load_dlptrl;
253 wire load_dlptrh;
254 wire load_memscanl;
255 wire load_memscanh;
256 wire load_mis;
257 wire load_ply;
258 wire load_pf;
259 wire load_char;
261 wire [1:0] dma_ply_num;
263 wire load_out;
265 wire hblank, vblank, vsync;
266 reg dwin;
268 wire shift_reg_shift;
269 wire [7:0] shift_reg_out;
270 reg [7:0] out_reg;
271 wire out_reg_shift;
272 reg [1:0] char_color;
274 assign ack_o = stb_i;
276 // Read registers.
277 always @ (adr_i or vcount or nmist_dli or nmist_vbi)
278 case (adr_i)
279 'hb:
280 dat_o = vcount[8:1];
281 'hf:
282 dat_o = {nmist_dli, nmist_vbi, 6'b0};
283 default:
284 dat_o = 'hff;
285 endcase
287 // DMACTL
288 always @ (posedge clk_i)
289 if (stb_i && we_i && adr_i == 'h0) begin
290 dma_pf_width <= slavedat_i[1:0];
291 dma_mis_en <= slavedat_i[2];
292 dma_ply_en <= slavedat_i[3];
293 dma_pm_1res <= slavedat_i[4];
294 dma_instr_en <= slavedat_i[5];
297 // CHACTL
298 always @ (posedge clk_i)
299 if (stb_i && we_i && adr_i == 'h1)
300 chactl <= slavedat_i[2:0];
302 // DLISTL/H
303 always @ (posedge clk_i)
304 if (stb_i && we_i && adr_i == 'h2)
305 dlist_ctr[7:0] <= slavedat_i;
306 else if (stb_i && we_i && adr_i == 'h3)
307 dlist_ctr[15:8] <= slavedat_i;
308 else if (dl_load) begin
309 if (!load_dlptrh)
310 dlist_ctr[9:0] <= dlist_ctr[9:0] + 1;
311 else begin
312 dlist_ctr[15:8] <= masterdat_i;
313 dlist_ctr[7:0] <= dlist_ctr_tmp;
315 if (load_dlptrl)
316 dlist_ctr_tmp <= masterdat_i;
319 // HSCROL
320 always @ (posedge clk_i)
321 if (stb_i && we_i && adr_i == 'h4)
322 hscrol <= slavedat_i[3:0];
324 // VSCROL
325 always @ (posedge clk_i)
326 if (stb_i && we_i && adr_i == 'h5)
327 vscrol <= slavedat_i[3:0];
329 // PMBASE
330 always @ (posedge clk_i)
331 if (stb_i && we_i && adr_i == 'h7)
332 pmbase <= slavedat_i[7:2];
334 // CHBASE
335 always @ (posedge clk_i)
336 if (stb_i && we_i && adr_i == 'h9)
337 chbase <= slavedat_i[7:1];
339 // WSYNC
340 always @ (posedge clk_i)
341 if (rst_i || hcount == 206)
342 wsync <= 0;
343 else if (stb_i && we_i && adr_i == 'ha)
344 wsync <= 1;
346 // NMIEN
347 always @ (posedge clk_i)
348 if (rst_i) begin
349 nmien_vbi <= 0;
350 nmien_dli <= 0;
351 end else if (stb_i && we_i && adr_i == 'he) begin
352 nmien_vbi <= slavedat_i[6];
353 nmien_dli <= slavedat_i[7];
356 // HCOUNT
357 always @ (posedge clk2_i)
358 if (rst_i && !clk_i)
359 hcount <= 0;
360 else if (hcount == 227)
361 hcount <= 0;
362 else
363 hcount <= hcount + 1;
365 // VCOUNT
366 always @ (posedge clk2_i)
367 if (rst_i && !clk_i)
368 vcount <= 0;
369 else if (hcount == 227)
370 if (vcount == 311)
371 vcount <= 0;
372 else
373 vcount <= vcount + 1;
375 // Display list interrupt.
376 assign nmireq_dli = (hcount == 16 && dcount == maxline && dli &&
377 nmien_dli && !vblank && !wait_vblank);
379 // Vertical blank interrupt.
380 assign nmireq_vbi = (hcount == 16 && vcount == 240 && nmien_vbi);
382 always @ (posedge clk_i)
383 if (rst_i) begin
384 nmist_vbi <= 0;
385 nmist_dli <= 0;
386 end else if (nmireq_vbi) begin
387 nmist_vbi <= 1;
388 nmist_dli <= 0;
389 end else if (nmireq_dli) begin
390 nmist_vbi <= 0;
391 nmist_dli <= 1;
392 end else if (stb_i && we_i && adr_i =='hf) begin
393 nmist_vbi <= 0;
394 nmist_dli <= 0;
397 assign nmi = nmireq_dli | nmireq_vbi;
399 always @ (posedge clk2_i)
400 if (hcount == 227)
401 if (dma_instr_en &&
402 (vcount == 7 ||
403 (dcount == maxline && !wait_vblank && !vblank && dma_instr_en)))
404 new_block <= 1;
405 else
406 new_block <= 0;
408 assign load_instr = new_block && (hcount == 2);
410 // DCOUNT
411 always @ (posedge clk2_i)
412 if (vcount == 0)
413 dcount <= 0;
414 else if (hcount == 0)
415 if (new_block)
416 dcount <= 0; // TODO: vscroll
417 else
418 dcount <= dcount + 1;
420 // Memory Scan Counter.
421 always @ (posedge clk_i)
422 if (load_pf)
423 memscan_ctr[11:0] <= memscan_ctr[11:0] + 1;
424 else if (load_memscanl)
425 memscan_ctr[7:0] <= masterdat_i;
426 else if (load_memscanh)
427 memscan_ctr[15:8] <= masterdat_i;
429 // Instruction register.
430 always @ (posedge clk_i)
431 if (load_instr)
432 ir <= masterdat_i;
433 else if (vcount == 0)
434 ir <= 0;
436 // Instruction decoder.
437 always @ (ir) begin
438 maxline = 0;
439 char_block = 0;
440 one_bit_pixel = 0;
441 case (ir[3:0])
442 'h0: maxline = ir[6:4];
443 'h1: maxline = 0;
444 'h2: begin
445 maxline = 7;
446 char_block = 1;
447 one_bit_pixel = 0;
449 'h3: begin
450 maxline = 9;
451 char_block = 1;
452 one_bit_pixel = 0;
454 'h4: begin
455 maxline = 7;
456 char_block = 1;
457 one_bit_pixel = 0;
459 'h5: begin
460 maxline = 15;
461 char_block = 1;
462 one_bit_pixel = 0;
464 'h6: begin
465 maxline = 7;
466 char_block = 1;
467 one_bit_pixel = 1;
469 'h7: begin
470 maxline = 15;
471 char_block = 1;
472 one_bit_pixel = 1;
474 'h8: begin
475 maxline = 7;
476 char_block = 0;
477 one_bit_pixel = 0;
479 'h9: begin
480 maxline = 3;
481 char_block = 0;
482 one_bit_pixel = 1;
484 'ha: begin
485 maxline = 3;
486 char_block = 0;
487 one_bit_pixel = 0;
489 'hb: begin
490 maxline = 1;
491 char_block = 0;
492 one_bit_pixel = 1;
494 'hc: begin
495 maxline = 0;
496 char_block = 0;
497 one_bit_pixel = 1;
499 'hd: begin
500 maxline = 1;
501 char_block = 0;
502 one_bit_pixel = 0;
504 'he: begin
505 maxline = 0;
506 char_block = 0;
507 one_bit_pixel = 0;
509 'hf: begin
510 maxline = 0;
511 char_block = 0;
512 one_bit_pixel = 0;
514 endcase
517 assign dli = ir[7];
518 assign wait_vblank = (ir == 'h41);
519 assign dma_block = (ir[3:0] != 0 && ir[3:0] != 1);
521 assign load_dlptrl = new_block && (ir[3:0] == 1) && (hcount == 12);
522 assign load_dlptrh = new_block && (ir[3:0] == 1) && (hcount == 14);
524 assign load_memscanl = new_block && dma_block && ir[6] && (hcount == 12);
525 assign load_memscanh = new_block && dma_block && ir[6] && (hcount == 14);
527 assign load_mis = !vblank && dma_mis_en && (hcount == 0);
528 assign load_ply = !vblank && dma_ply_en &&
529 (hcount == 4 || hcount == 6 ||
530 hcount == 8 || hcount == 10);
531 assign dma_ply_num = (hcount >> 1) - 2;
533 assign dl_load = load_instr || load_memscanh || load_memscanl ||
534 load_dlptrh || load_dlptrl;
536 always @ (posedge clk2_i)
537 if (hcount == 16 + (ir[4] ? (hscrol & ~1) : 0))
538 ms_hcount <= 0;
539 else
540 ms_hcount <= ms_hcount + 1;
542 antic_ms_hcount_seq u_ms_hcount_seq(.ms_hcount(ms_hcount),
543 .new_block(new_block),
544 .dma_block(dma_block),
545 .dma_pf_width(dma_pf_width),
546 .ir(ir),
547 .shift_reg_shift(shift_reg_shift),
548 .load_pf(load_pf),
549 .load_out(load_out),
550 .out_reg_shift(out_reg_shift));
552 always @ (hcount or dma_pf_width or dma_instr_en or vblank) begin
553 if (!dma_instr_en || vblank)
554 dwin = 0;
555 else
556 case (dma_pf_width)
557 0: dwin = 0;
558 1: dwin = (hcount >= 64 && hcount < 192);
559 2: dwin = (hcount >= 48 && hcount < 208);
560 3: dwin = (hcount >= 44 && hcount < 220);
561 endcase
564 assign hblank = (hcount < 34 || hcount >= 222);
565 assign vblank = (vcount < 8 || vcount >= 240);
567 // TODO: lines here are approximate.
568 assign vsync = (vcount >= 300 && vcount < 303);
570 assign load_char = load_out && char_block;
572 always @ (posedge clk2_i)
573 if (load_out)
574 if (char_block) begin
575 out_reg <= masterdat_i;
576 char_color <= shift_reg_out[7:6];
577 end else
578 out_reg <= shift_reg_out;
579 else if (out_reg_shift)
580 if (one_bit_pixel)
581 out_reg <= {out_reg[6:0], 1'b0};
582 else
583 out_reg <= {out_reg[5:0], 2'b00};
585 always @ (vsync or vblank or hblank or dwin or ir or out_reg or
586 char_color) begin
587 if (vsync)
588 antic_out = 3'b001;
589 else if (hblank || vblank)
590 if (ir[3:0] == 2 || ir[3:0] == 3 || ir[3:0] == 'hf)
591 antic_out = 3'b011;
592 else
593 antic_out = 3'b010;
594 else if (dwin)
595 if (ir[3:0] == 2 || ir[3:0] == 3)
596 if (char_color[1])
597 antic_out = {1'b1,
598 (out_reg[7:6] & ~{2{chactl[0]}}) ^ {2{chactl[1]}}};
599 else
600 antic_out = {1'b1, out_reg[7:6]};
601 else if (ir[3:0] == 'hf)
602 antic_out = {1'b1, out_reg[7:6]};
603 else if (ir[3:0] == 4 || ir[3:0] == 5)
604 case (out_reg[7:6])
605 0: antic_out = 3'b000;
606 1: antic_out = 3'b100;
607 2: antic_out = 3'b101;
608 3: antic_out = char_color[1] ? 3'b111 : 3'b110;
609 endcase
610 else if (ir[3:0] == 6 || ir[3:0] == 7)
611 if (out_reg[7])
612 antic_out = {1'b1, char_color};
613 else
614 antic_out = 3'b000;
615 else if (ir[3:0] == 8 || ir[3:0] == 'ha || ir[3:0] == 'hd ||
616 ir[3:0] == 'he)
617 case (out_reg[7:6])
618 0: antic_out = 3'b000;
619 1: antic_out = 3'b100;
620 2: antic_out = 3'b101;
621 3: antic_out = 3'b110;
622 endcase
623 else if (ir[3:0] == 9 || ir[3:0] == 'hb || ir[3:0] == 'hc)
624 antic_out = out_reg[7] ? 3'b100 : 3'b000;
625 else
626 antic_out = 3'b000;
627 else
628 antic_out = 3'b000;
631 always @ (dl_load or dlist_ctr or load_mis or load_ply or
632 pmbase or vcount or dma_ply_num or
633 load_pf or memscan_ctr or
634 load_char or chbase or shift_reg_out or dcount) begin
635 if (dl_load)
636 adr_o = dlist_ctr;
637 else if (load_mis)
638 adr_o = dma_pm_1res ?
639 {pmbase[5:1], 3'b011, vcount[7:0]} :
640 {pmbase[5:0], 3'b011, vcount[7:1]};
641 else if (load_ply)
642 adr_o = dma_pm_1res ?
643 {pmbase[5:1], 1'b1, dma_ply_num, vcount[7:0]} :
644 {pmbase[5:0], 1'b1, dma_ply_num, vcount[7:1]};
645 else if (load_pf)
646 adr_o = memscan_ctr;
647 else if (load_char)
648 case (ir[3:0])
649 2: adr_o = {chbase[6:1], shift_reg_out[6:0], dcount[2:0]};
650 3: adr_o = {chbase[6:1], shift_reg_out[6:0], dcount[2:0]};
651 4: adr_o = {chbase[6:1], shift_reg_out[6:0], dcount[2:0]};
652 5: adr_o = {chbase[6:1], shift_reg_out[6:0], dcount[3:1]};
653 6: adr_o = {chbase[6:0], shift_reg_out[5:0], dcount[2:0]};
654 7: adr_o = {chbase[6:0], shift_reg_out[5:0], dcount[3:1]};
655 endcase
656 else
657 adr_o = 0; // TODO: load some pointer by default
660 assign stb_o = dl_load || load_mis || load_ply || load_pf || load_char ||
661 wsync;
662 assign cyc_o = stb_o;
664 antic_shift_reg u_shift_reg(.clk_i(clk_i),
665 .shift(shift_reg_shift),
666 .load(load_pf),
667 .in(masterdat_i),
668 .out(shift_reg_out));
669 endmodule