Have a full cycle to load playfield and char data
[AtosmChip.git] / pia.v
blobc34c975e3937416d33a0dec04bf4fa1b979375ac
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 // TODO: interrupt input/outputs
20 module pia(rst_i, clk_i,
21 adr_i,
22 dat_i,
23 dat_o,
24 we_i,
25 stb_i,
26 ack_o,
27 pa_i,
28 pb_i,
29 pa_o,
30 pb_o);
31 input rst_i;
32 input clk_i;
33 input adr_i;
34 input dat_i;
35 input we_i;
36 input stb_i;
37 input pa_i, pb_i;
39 output dat_o;
40 output ack_o;
41 output pa_o, pb_o;
43 wire rst_i, clk_i;
44 wire [1:0] adr_i;
45 wire [7:0] dat_i;
46 wire we_i;
47 wire stb_i;
49 wire ack_o;
51 reg [7:0] dat_o;
53 wire [7:0] pa_i, pb_i;
54 wire [7:0] pa_o, pb_o;
56 reg [7:0] pa_out_reg, pb_out_reg;
57 reg [7:0] pa_dir_reg, pb_dir_reg;
58 reg [1:0] ca1ctl, cb1ctl;
59 reg ddir_a, ddir_b;
60 reg [2:0] ca2ctl, cb2ctl;
62 assign ack_o = stb_i;
64 assign pa_o = (pa_out_reg & pa_dir_reg) | ~pa_dir_reg;
65 assign pb_o = (pb_out_reg & pb_dir_reg) | ~pb_dir_reg;
67 // Read registers.
68 always @ (adr_i or pa_i or pb_i)
69 case (adr_i)
70 0: dat_o = ddir_a ?
71 (pa_i & ~pa_dir_reg) | (pa_out_reg & pa_dir_reg) :
72 pa_dir_reg;
73 1: dat_o = ddir_b ?
74 (pb_i & ~pb_dir_reg) | (pb_out_reg & pb_dir_reg) :
75 pb_dir_reg;
76 2: dat_o = {2'b00, ca2ctl, ddir_a, ca1ctl};
77 3: dat_o = {2'b00, cb2ctl, ddir_b, cb1ctl};
78 endcase
80 // Port A output.
81 always @ (posedge clk_i)
82 if (rst_i)
83 pa_out_reg <= 0;
84 else if (stb_i && we_i && adr_i == 0 && ddir_a)
85 pa_out_reg <= dat_i;
87 // Port A direction.
88 always @ (posedge clk_i)
89 if (rst_i)
90 pa_dir_reg <= 0;
91 else if (stb_i && we_i && adr_i == 0 && !ddir_a)
92 pa_dir_reg <= dat_i;
94 // Port B output.
95 always @ (posedge clk_i)
96 if (rst_i)
97 pb_out_reg <= 0;
98 else if (stb_i && we_i && adr_i == 1 && ddir_b)
99 pb_out_reg <= dat_i;
101 // Port B direction.
102 always @ (posedge clk_i)
103 if (rst_i)
104 pb_dir_reg <= 0;
105 else if (stb_i && we_i && adr_i == 1 && !ddir_b)
106 pb_dir_reg <= dat_i;
108 // Port A control.
109 always @ (posedge clk_i)
110 if (rst_i) begin
111 ca2ctl <= 0;
112 ddir_a <= 0;
113 ca1ctl <= 0;
114 end else if (stb_i && we_i && adr_i == 2) begin
115 ca2ctl <= dat_i[5:3];
116 ddir_a <= dat_i[2];
117 ca1ctl <= dat_i[1:0];
120 // Port B control.
121 always @ (posedge clk_i)
122 if (rst_i) begin
123 cb2ctl <= 0;
124 ddir_b <= 0;
125 cb1ctl <= 0;
126 end else if (stb_i && we_i && adr_i == 3) begin
127 cb2ctl <= dat_i[5:3];
128 ddir_b <= dat_i[2];
129 cb1ctl <= dat_i[1:0];
132 endmodule