Have a full cycle to load playfield and char data
[AtosmChip.git] / cpu6502_old.v
blob36bda57578adbb6b5e58c2e627d09efcb1e92bc1
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 else if (ir[4:0] == 'h01) begin
19 // ALU (b,x)
20 case (cyccnt)
21 1: begin
22 adro_sel = adr.ADRO_PC;
23 aluop = alu.OPB;
24 dreg_ld = 1;
25 end
26 2: begin
27 // TODO: add X to DREG here?
28 adro_sel = adr.ADR0_BASE;
29 adr_zp = 1;
30 adr_base_sel = 1;
31 pcinc = 0;
32 end
33 3: begin
34 adro_sel = adr.ADRO_DREGIND;
35 pcinc = 0;
36 adr_low_ld = 1;
37 alua_sel = ALUA_D;
38 aluop = alu.OPINC;
39 dreg_ld = 1;
40 end
41 4: begin
42 adro_sel = adr.ADRO_DREGIND;
43 pcinc = 0;
44 adr_high_ld = 1;
45 end
46 5: begin
47 adro_sel = adr.ADR_BASE;
48 pcinc = 0;
49 lastcyc = 1;
50 end
51 endcase
52 end else if (ir[4:0] == 'h05) begin
53 // ALU b
54 case (cyccnt)
55 1: begin
56 adro_sel = adr.ADRO_PC;
57 aluop = alu.OPB;
58 dreg_ld = 1;
59 end
60 2: begin
61 adro_sel = ADRO_BASE;
62 adr_base_sel = 1;
63 adr_zp = 1;
64 lastcyc = 1;
65 pcinc = 0;
66 end
67 endcase
68 end else if (ir[4:0] == 'h09) begin
69 // ALU #b
70 case (cyccnt)
71 1: begin
72 adro_sel = adr.ADRO_PC;
73 lastcyc = 1;
74 end
75 endcase
76 end else if (ir[4:0] == 'h0d) begin
77 // ALU a
78 case (cyccnt)
79 1: adr_low_ld = 1;
80 2: adr_high_ld = 1;
81 3: begin
82 adro_sel = adr.ADRO_BASE;
83 lastcyc = 1;
84 pcinc = 0;
85 end
86 endcase
87 end else if (ir[4:0] == 'h11) begin
88 // ALU (b),y
89 case (cyccnt)
90 1: begin
91 adro_sel = adr.ADRO_PC;
92 aluop = alu.OPB;
93 dreg_ld = 1;
94 end
95 2: begin
96 adro_sel = adr.ADRO_DREG;
97 pcinc = 0;
98 adr_low_ld = 1;
99 alua_sel = ALUA_D;
100 aluop = alu.OPINC;
101 dreg_ld = 1;
103 3: begin
104 adro_sel = adr.ADRO_DREG;
105 pcinc = 0;
106 adr_high_ld = 1;
107 adr_indx_sel = 0;
109 4: begin
110 adro_sel = adr.ADRO_BASEIND;
111 adr_indx_sel = 0;
112 pcinc = 0;
113 lastcyc = 1;
115 endcase
116 end else if (ir[4:0] == 'h15) begin
117 // ALU b,x
118 case (cyccnt)
119 1: begin
120 adro_sel = adr.ADRO_PC;
121 aluop = alu.OPB;
122 dreg_ld = 1;
124 2: begin
125 adro_sel = ADRO_BASE;
126 adr_base_sel = 1;
127 adr_zp = 1;
128 pcinc = 0;
130 3: begin
131 adro_sel = ADRO_BASEIND;
132 adr_base_sel = 1;
133 adr_zp = 1;
134 adr_indx_sel = 1;
135 pcinc = 0;
136 lastcyc = 1;
138 endcase
139 end else if (ir[4:0] == 'h19) begin
140 // ALU a,y
141 case (cyccnt)
142 1: begin
143 adr_low_ld = 1;
145 2: begin
146 adr_high_ld = 1;
147 adr_indx_sel = 0;
148 adr_delay_en = 1;
150 3: begin
151 adro_sel = adr.ADRO_BASEIND;
152 adr_indx_sel = 0;
153 lastcyc = 1;
154 pcinc = 0;
156 endcase
157 end else if (ir[4:0] == 'h1d) begin
158 // ALU a,x
159 case (cyccnt)
160 1: begin
161 adr_low_ld = 1;
163 2: begin
164 adr_high_ld = 1;
165 adr_indx_sel = 1;
166 adr_delay_en = 1;
168 3: begin
169 adro_sel = adr.ADRO_BASEIND;
170 adr_indx_sel = 1;
171 lastcyc = 1;
172 pcinc = 0;
174 endcase
175 end else if ((ir == 'ha0 || ir == 'ha2)) begin
176 // LDX/LDY #imm
177 case (cyccnt)
178 1: begin
179 adro_sel = adr.ADRO_PC;
180 ldxy_exec = 1;
181 lastcyc = 1;
183 endcase
184 end else if (ir == 'ha4 || ir == 'ha6 || ir == 'h84 || ir == 'h86) begin
185 // LDX/LDY b or ST*
186 case (cyccnt)
187 1: begin
188 adro_sel = adr.ADRO_PC;
189 aluop = alu.OPB;
190 dreg_ld = 1;
192 2: begin
193 adro_sel = ADRO_BASE;
194 adr_base_sel = 1;
195 adr_zp = 1;
196 ldxy_exec = (ir[7:4] == 'ha);
197 stxy_exec = (ir[7:4] == 'h8);
198 lastcyc = 1;
199 pcinc = 0;
201 endcase
202 end else if (ir == 'hac || ir == 'hae || ir == 'h8c || ir == 'h8e) begin
203 // LDX/LDY a or ST*
204 case (cyccnt)
205 1: adr_low_ld = 1;
206 2: adr_high_ld = 1;
207 3: begin
208 adro_sel = adr.ADRO_BASE;
209 ldxy_exec = (ir[7:4] == 'ha);
210 stxy_exec = (ir[7:4] == 'h8);
211 lastcyc = 1;
212 pcinc = 0;
214 endcase
215 end else if (ir == 'hb4 || ir == 'hb6 || ir == 'h94 || ir == 'h96) begin
216 // LDX/LDY b,y/x or ST*
217 case (cyccnt)
218 1: begin
219 adro_sel = adr.ADRO_PC;
220 aluop = alu.OPB;
221 dreg_ld = 1;
223 2: begin
224 adro_sel = ADRO_BASE;
225 adr_base_sel = 1;
226 adr_zp = 1;
227 pcinc = 0;
229 3: begin
230 adro_sel = ADRO_BASEIND;
231 adr_base_sel = 1;
232 adr_zp = 1;
233 adr_indx_sel = (ir == 'hb4);
234 ldxy_exec = (ir[7:4] == 'hb);
235 stxy_exec = (ir[7:4] == 'h9);
236 pcinc = 0;
237 lastcyc = 1;
239 endcase
240 end else if (ir == 'hbc || ir == 'hbe) begin
241 // LDX/LDY b,y/x
242 case (cyccnt)
243 1: begin
244 adr_low_ld = 1;
246 2: begin
247 adr_high_ld = 1;
248 adr_indx_sel = (ir == 'hbc);
249 adr_delay_en = 1;
251 3: begin
252 adro_sel = adr.ADRO_BASEIND;
253 adr_indx_sel = (ir == 'hbc);
254 ldxy_exec = 1;
255 lastcyc = 1;
256 pcinc = 0;
258 endcase
259 end else if (ir == 'hc0 || ir == 'he0) begin
260 // CPX/Y #b
261 case (cyccnt)
262 1: begin
263 adro_sel = adr.ADRO_PC;
264 cpxy_exec = 1;
265 lastcyc = 1;
267 endcase
268 end else if (ir == 'hc4 || ir == 'he4) begin
269 // CPX/Y b
270 case (cyccnt)
271 1: begin
272 adro_sel = adr.ADRO_PC;
273 aluop = alu.OPB;
274 dreg_ld = 1;
276 2: begin
277 adro_sel = ADRO_BASE;
278 adr_base_sel = 1;
279 adr_zp = 1;
280 lastcyc = 1;
281 pcinc = 0;
283 endcase
284 end else if (ir[4:0] == 'h10) begin
285 // Branch
286 case (cyccnt)
287 1: begin
288 adro_sel = adr.ADRO_PC;
289 if (br_taken)
290 dreg_ld = 1;
291 else
292 lastcyc = 1;
294 2: begin
295 pcinc = 0;
296 pc_rel_low_ld = 1;
297 lastcyc = (pc_c & dreg[7]) | (~pc_c & ~dreg[7]);
299 3: begin
300 pcinc = 0;
301 pc_rel_high_ld = 1;
302 lastcyc = 1;
304 endcase
305 end else if (ir == 'h18 || ir == 'h38 || ir == 'h58 || ir == 'h78 ||
306 ir == 'hb8 || ir == 'hd8 || ir == 'hf8) begin
307 // CLx / SEx
308 // Everything is done in regf process.
309 pcinc = 0;
310 lastcyc = 1;
313 // execute ALU
314 if ((interrupt == INT_NONE) && (ir[1:0] == 2'b01) &&
315 lastcyc && !adr_delay) begin
316 aluop = {1'b0, ir[7:5]};
317 accld = 1;
318 nld = 1;
319 zld = 1;
320 if (ir[7:5] == 3'b100) begin
321 dato_sel = DATO_ACC;
322 we_o = 1;
323 nld = 0;
324 zld = 0;
325 accld = 0;
326 end else if (ir[7:5] == alu.OPCMP) begin
327 accld = 0;
328 cld = 1;
329 vld = 1;
330 end else if (ir[7:5] == alu.OPADC) begin
331 // TODO: delay with decimal mode
332 cld = 1;
333 vld = 1;
334 end else if (ir[7:5] == alu.OPSBC) begin
335 cld = 1;
336 vld = 1;
340 // execute LDX/LDY
341 if ((interrupt == INT_NONE) && ldxy_exec && adr_delay == 0) begin
342 aluop = alu.OPB;
343 regxld = (ir[1] == 1);
344 regyld = (ir[1] == 0);
345 nld = 1;
346 zld = 1;
349 // execute STX/STY
350 if ((interrupt == INT_NONE) && stxy_exec && adr_delay == 0) begin
351 dato_sel = (ir[1] == 1) ? DATO_X : DATO_Y;
352 we_o = 1;