Rev 896 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4 | lvd | 1 | -- **** |
2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... |
||
3 | -- |
||
4 | -- |
||
5 | -- Ver 300 started tidyup |
||
6 | -- MikeJ March 2005 |
||
7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) |
||
8 | -- |
||
9 | -- **** |
||
10 | -- |
||
11 | -- Z80 compatible microprocessor core |
||
12 | -- |
||
13 | -- Version : 0242 |
||
14 | -- |
||
15 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
||
16 | -- |
||
17 | -- All rights reserved |
||
18 | -- |
||
19 | -- Redistribution and use in source and synthezised forms, with or without |
||
20 | -- modification, are permitted provided that the following conditions are met: |
||
21 | -- |
||
22 | -- Redistributions of source code must retain the above copyright notice, |
||
23 | -- this list of conditions and the following disclaimer. |
||
24 | -- |
||
25 | -- Redistributions in synthesized form must reproduce the above copyright |
||
26 | -- notice, this list of conditions and the following disclaimer in the |
||
27 | -- documentation and/or other materials provided with the distribution. |
||
28 | -- |
||
29 | -- Neither the name of the author nor the names of other contributors may |
||
30 | -- be used to endorse or promote products derived from this software without |
||
31 | -- specific prior written permission. |
||
32 | -- |
||
33 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||
34 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
||
35 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||
36 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
||
37 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
38 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
39 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
40 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
41 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
42 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
43 | -- POSSIBILITY OF SUCH DAMAGE. |
||
44 | -- |
||
45 | -- Please report bugs to the author, but before you do so, please |
||
46 | -- make sure that this is not a derivative work and that |
||
47 | -- you have the latest version of this file. |
||
48 | -- |
||
49 | -- The latest version of this file can be found at: |
||
50 | -- http://www.opencores.org/cvsweb.shtml/t80/ |
||
51 | -- |
||
52 | -- Limitations : |
||
53 | -- |
||
54 | -- File history : |
||
55 | -- |
||
56 | -- 0208 : First complete release |
||
57 | -- |
||
58 | -- 0211 : Fixed IM 1 |
||
59 | -- |
||
60 | -- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test |
||
61 | -- |
||
62 | -- 0235 : Added IM 2 fix by Mike Johnson |
||
63 | -- |
||
64 | -- 0238 : Added NoRead signal |
||
65 | -- |
||
66 | -- 0238b: Fixed instruction timing for POP and DJNZ |
||
67 | -- |
||
68 | -- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes |
||
69 | |||
70 | -- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR |
||
71 | -- |
||
72 | -- 0242 : Fixed I/O instruction timing, cleanup |
||
73 | -- |
||
74 | |||
75 | library IEEE; |
||
76 | use IEEE.std_logic_1164.all; |
||
77 | use IEEE.numeric_std.all; |
||
78 | use work.T80_Pack.all; |
||
79 | |||
80 | entity T80_MCode is |
||
81 | generic( |
||
82 | Mode : integer := 0; |
||
83 | Flag_C : integer := 0; |
||
84 | Flag_N : integer := 1; |
||
85 | Flag_P : integer := 2; |
||
86 | Flag_X : integer := 3; |
||
87 | Flag_H : integer := 4; |
||
88 | Flag_Y : integer := 5; |
||
89 | Flag_Z : integer := 6; |
||
90 | Flag_S : integer := 7 |
||
91 | ); |
||
92 | port( |
||
93 | IR : in std_logic_vector(7 downto 0); |
||
94 | ISet : in std_logic_vector(1 downto 0); |
||
95 | MCycle : in std_logic_vector(2 downto 0); |
||
96 | F : in std_logic_vector(7 downto 0); |
||
97 | NMICycle : in std_logic; |
||
98 | IntCycle : in std_logic; |
||
99 | MCycles : out std_logic_vector(2 downto 0); |
||
100 | TStates : out std_logic_vector(2 downto 0); |
||
101 | Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD |
||
102 | Inc_PC : out std_logic; |
||
103 | Inc_WZ : out std_logic; |
||
104 | IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc |
||
105 | Read_To_Reg : out std_logic; |
||
106 | Read_To_Acc : out std_logic; |
||
107 | Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F |
||
108 | Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 |
||
109 | ALU_Op : out std_logic_vector(3 downto 0); |
||
110 | -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None |
||
111 | Save_ALU : out std_logic; |
||
112 | PreserveC : out std_logic; |
||
113 | Arith16 : out std_logic; |
||
114 | Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI |
||
115 | IORQ : out std_logic; |
||
116 | Jump : out std_logic; |
||
117 | JumpE : out std_logic; |
||
118 | JumpXY : out std_logic; |
||
119 | Call : out std_logic; |
||
120 | RstP : out std_logic; |
||
121 | LDZ : out std_logic; |
||
122 | LDW : out std_logic; |
||
123 | LDSPHL : out std_logic; |
||
124 | Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None |
||
125 | ExchangeDH : out std_logic; |
||
126 | ExchangeRp : out std_logic; |
||
127 | ExchangeAF : out std_logic; |
||
128 | ExchangeRS : out std_logic; |
||
129 | I_DJNZ : out std_logic; |
||
130 | I_CPL : out std_logic; |
||
131 | I_CCF : out std_logic; |
||
132 | I_SCF : out std_logic; |
||
133 | I_RETN : out std_logic; |
||
134 | I_BT : out std_logic; |
||
135 | I_BC : out std_logic; |
||
136 | I_BTR : out std_logic; |
||
137 | I_RLD : out std_logic; |
||
138 | I_RRD : out std_logic; |
||
139 | I_INRC : out std_logic; |
||
140 | SetDI : out std_logic; |
||
141 | SetEI : out std_logic; |
||
142 | IMode : out std_logic_vector(1 downto 0); |
||
143 | Halt : out std_logic; |
||
144 | NoRead : out std_logic; |
||
145 | Write : out std_logic |
||
146 | ); |
||
147 | end T80_MCode; |
||
148 | |||
149 | architecture rtl of T80_MCode is |
||
150 | |||
151 | constant aNone : std_logic_vector(2 downto 0) := "111"; |
||
152 | constant aBC : std_logic_vector(2 downto 0) := "000"; |
||
153 | constant aDE : std_logic_vector(2 downto 0) := "001"; |
||
154 | constant aXY : std_logic_vector(2 downto 0) := "010"; |
||
155 | constant aIOA : std_logic_vector(2 downto 0) := "100"; |
||
156 | constant aSP : std_logic_vector(2 downto 0) := "101"; |
||
157 | constant aZI : std_logic_vector(2 downto 0) := "110"; |
||
158 | |||
159 | function is_cc_true( |
||
160 | F : std_logic_vector(7 downto 0); |
||
161 | cc : bit_vector(2 downto 0) |
||
162 | ) return boolean is |
||
163 | begin |
||
164 | if Mode = 3 then |
||
165 | case cc is |
||
166 | when "000" => return F(7) = '0'; -- NZ |
||
167 | when "001" => return F(7) = '1'; -- Z |
||
168 | when "010" => return F(4) = '0'; -- NC |
||
169 | when "011" => return F(4) = '1'; -- C |
||
170 | when "100" => return false; |
||
171 | when "101" => return false; |
||
172 | when "110" => return false; |
||
173 | when "111" => return false; |
||
174 | end case; |
||
175 | else |
||
176 | case cc is |
||
177 | when "000" => return F(6) = '0'; -- NZ |
||
178 | when "001" => return F(6) = '1'; -- Z |
||
179 | when "010" => return F(0) = '0'; -- NC |
||
180 | when "011" => return F(0) = '1'; -- C |
||
181 | when "100" => return F(2) = '0'; -- PO |
||
182 | when "101" => return F(2) = '1'; -- PE |
||
183 | when "110" => return F(7) = '0'; -- P |
||
184 | when "111" => return F(7) = '1'; -- M |
||
185 | end case; |
||
186 | end if; |
||
187 | end; |
||
188 | |||
189 | begin |
||
190 | |||
191 | process (IR, ISet, MCycle, F, NMICycle, IntCycle) |
||
192 | variable DDD : std_logic_vector(2 downto 0); |
||
193 | variable SSS : std_logic_vector(2 downto 0); |
||
194 | variable DPair : std_logic_vector(1 downto 0); |
||
195 | variable IRB : bit_vector(7 downto 0); |
||
196 | begin |
||
197 | DDD := IR(5 downto 3); |
||
198 | SSS := IR(2 downto 0); |
||
199 | DPair := IR(5 downto 4); |
||
200 | IRB := to_bitvector(IR); |
||
201 | |||
202 | MCycles <= "001"; |
||
203 | if MCycle = "001" then |
||
204 | TStates <= "100"; |
||
205 | else |
||
206 | TStates <= "011"; |
||
207 | end if; |
||
208 | Prefix <= "00"; |
||
209 | Inc_PC <= '0'; |
||
210 | Inc_WZ <= '0'; |
||
211 | IncDec_16 <= "0000"; |
||
212 | Read_To_Acc <= '0'; |
||
213 | Read_To_Reg <= '0'; |
||
214 | Set_BusB_To <= "0000"; |
||
215 | Set_BusA_To <= "0000"; |
||
216 | ALU_Op <= "0" & IR(5 downto 3); |
||
217 | Save_ALU <= '0'; |
||
218 | PreserveC <= '0'; |
||
219 | Arith16 <= '0'; |
||
220 | IORQ <= '0'; |
||
221 | Set_Addr_To <= aNone; |
||
222 | Jump <= '0'; |
||
223 | JumpE <= '0'; |
||
224 | JumpXY <= '0'; |
||
225 | Call <= '0'; |
||
226 | RstP <= '0'; |
||
227 | LDZ <= '0'; |
||
228 | LDW <= '0'; |
||
229 | LDSPHL <= '0'; |
||
230 | Special_LD <= "000"; |
||
231 | ExchangeDH <= '0'; |
||
232 | ExchangeRp <= '0'; |
||
233 | ExchangeAF <= '0'; |
||
234 | ExchangeRS <= '0'; |
||
235 | I_DJNZ <= '0'; |
||
236 | I_CPL <= '0'; |
||
237 | I_CCF <= '0'; |
||
238 | I_SCF <= '0'; |
||
239 | I_RETN <= '0'; |
||
240 | I_BT <= '0'; |
||
241 | I_BC <= '0'; |
||
242 | I_BTR <= '0'; |
||
243 | I_RLD <= '0'; |
||
244 | I_RRD <= '0'; |
||
245 | I_INRC <= '0'; |
||
246 | SetDI <= '0'; |
||
247 | SetEI <= '0'; |
||
248 | IMode <= "11"; |
||
249 | Halt <= '0'; |
||
250 | NoRead <= '0'; |
||
251 | Write <= '0'; |
||
252 | |||
253 | case ISet is |
||
254 | when "00" => |
||
255 | |||
256 | ------------------------------------------------------------------------------ |
||
257 | -- |
||
258 | -- Unprefixed instructions |
||
259 | -- |
||
260 | ------------------------------------------------------------------------------ |
||
261 | |||
262 | case IRB is |
||
263 | -- 8 BIT LOAD GROUP |
||
264 | when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" |
||
265 | |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" |
||
266 | |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" |
||
267 | |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" |
||
268 | |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" |
||
269 | |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" |
||
270 | |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => |
||
271 | -- LD r,r' |
||
272 | Set_BusB_To(2 downto 0) <= SSS; |
||
273 | ExchangeRp <= '1'; |
||
274 | Set_BusA_To(2 downto 0) <= DDD; |
||
275 | Read_To_Reg <= '1'; |
||
276 | when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => |
||
277 | -- LD r,n |
||
278 | MCycles <= "010"; |
||
279 | case to_integer(unsigned(MCycle)) is |
||
280 | when 2 => |
||
281 | Inc_PC <= '1'; |
||
282 | Set_BusA_To(2 downto 0) <= DDD; |
||
283 | Read_To_Reg <= '1'; |
||
284 | when others => null; |
||
285 | end case; |
||
286 | when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => |
||
287 | -- LD r,(HL) |
||
288 | MCycles <= "010"; |
||
289 | case to_integer(unsigned(MCycle)) is |
||
290 | when 1 => |
||
291 | Set_Addr_To <= aXY; |
||
292 | when 2 => |
||
293 | Set_BusA_To(2 downto 0) <= DDD; |
||
294 | Read_To_Reg <= '1'; |
||
295 | when others => null; |
||
296 | end case; |
||
297 | when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => |
||
298 | -- LD (HL),r |
||
299 | MCycles <= "010"; |
||
300 | case to_integer(unsigned(MCycle)) is |
||
301 | when 1 => |
||
302 | Set_Addr_To <= aXY; |
||
303 | Set_BusB_To(2 downto 0) <= SSS; |
||
304 | Set_BusB_To(3) <= '0'; |
||
305 | when 2 => |
||
306 | Write <= '1'; |
||
307 | when others => null; |
||
308 | end case; |
||
309 | when "00110110" => |
||
310 | -- LD (HL),n |
||
311 | MCycles <= "011"; |
||
312 | case to_integer(unsigned(MCycle)) is |
||
313 | when 2 => |
||
314 | Inc_PC <= '1'; |
||
315 | Set_Addr_To <= aXY; |
||
316 | Set_BusB_To(2 downto 0) <= SSS; |
||
317 | Set_BusB_To(3) <= '0'; |
||
318 | when 3 => |
||
319 | Write <= '1'; |
||
320 | when others => null; |
||
321 | end case; |
||
322 | when "00001010" => |
||
323 | -- LD A,(BC) |
||
324 | MCycles <= "010"; |
||
325 | case to_integer(unsigned(MCycle)) is |
||
326 | when 1 => |
||
327 | Set_Addr_To <= aBC; |
||
328 | when 2 => |
||
329 | Read_To_Acc <= '1'; |
||
330 | when others => null; |
||
331 | end case; |
||
332 | when "00011010" => |
||
333 | -- LD A,(DE) |
||
334 | MCycles <= "010"; |
||
335 | case to_integer(unsigned(MCycle)) is |
||
336 | when 1 => |
||
337 | Set_Addr_To <= aDE; |
||
338 | when 2 => |
||
339 | Read_To_Acc <= '1'; |
||
340 | when others => null; |
||
341 | end case; |
||
342 | when "00111010" => |
||
343 | if Mode = 3 then |
||
344 | -- LDD A,(HL) |
||
345 | MCycles <= "010"; |
||
346 | case to_integer(unsigned(MCycle)) is |
||
347 | when 1 => |
||
348 | Set_Addr_To <= aXY; |
||
349 | when 2 => |
||
350 | Read_To_Acc <= '1'; |
||
351 | IncDec_16 <= "1110"; |
||
352 | when others => null; |
||
353 | end case; |
||
354 | else |
||
355 | -- LD A,(nn) |
||
356 | MCycles <= "100"; |
||
357 | case to_integer(unsigned(MCycle)) is |
||
358 | when 2 => |
||
359 | Inc_PC <= '1'; |
||
360 | LDZ <= '1'; |
||
361 | when 3 => |
||
362 | Set_Addr_To <= aZI; |
||
363 | Inc_PC <= '1'; |
||
364 | when 4 => |
||
365 | Read_To_Acc <= '1'; |
||
366 | when others => null; |
||
367 | end case; |
||
368 | end if; |
||
369 | when "00000010" => |
||
370 | -- LD (BC),A |
||
371 | MCycles <= "010"; |
||
372 | case to_integer(unsigned(MCycle)) is |
||
373 | when 1 => |
||
374 | Set_Addr_To <= aBC; |
||
375 | Set_BusB_To <= "0111"; |
||
376 | when 2 => |
||
377 | Write <= '1'; |
||
378 | when others => null; |
||
379 | end case; |
||
380 | when "00010010" => |
||
381 | -- LD (DE),A |
||
382 | MCycles <= "010"; |
||
383 | case to_integer(unsigned(MCycle)) is |
||
384 | when 1 => |
||
385 | Set_Addr_To <= aDE; |
||
386 | Set_BusB_To <= "0111"; |
||
387 | when 2 => |
||
388 | Write <= '1'; |
||
389 | when others => null; |
||
390 | end case; |
||
391 | when "00110010" => |
||
392 | if Mode = 3 then |
||
393 | -- LDD (HL),A |
||
394 | MCycles <= "010"; |
||
395 | case to_integer(unsigned(MCycle)) is |
||
396 | when 1 => |
||
397 | Set_Addr_To <= aXY; |
||
398 | Set_BusB_To <= "0111"; |
||
399 | when 2 => |
||
400 | Write <= '1'; |
||
401 | IncDec_16 <= "1110"; |
||
402 | when others => null; |
||
403 | end case; |
||
404 | else |
||
405 | -- LD (nn),A |
||
406 | MCycles <= "100"; |
||
407 | case to_integer(unsigned(MCycle)) is |
||
408 | when 2 => |
||
409 | Inc_PC <= '1'; |
||
410 | LDZ <= '1'; |
||
411 | when 3 => |
||
412 | Set_Addr_To <= aZI; |
||
413 | Inc_PC <= '1'; |
||
414 | Set_BusB_To <= "0111"; |
||
415 | when 4 => |
||
416 | Write <= '1'; |
||
417 | when others => null; |
||
418 | end case; |
||
419 | end if; |
||
420 | |||
421 | -- 16 BIT LOAD GROUP |
||
422 | when "00000001"|"00010001"|"00100001"|"00110001" => |
||
423 | -- LD dd,nn |
||
424 | MCycles <= "011"; |
||
425 | case to_integer(unsigned(MCycle)) is |
||
426 | when 2 => |
||
427 | Inc_PC <= '1'; |
||
428 | Read_To_Reg <= '1'; |
||
429 | if DPAIR = "11" then |
||
430 | Set_BusA_To(3 downto 0) <= "1000"; |
||
431 | else |
||
432 | Set_BusA_To(2 downto 1) <= DPAIR; |
||
433 | Set_BusA_To(0) <= '1'; |
||
434 | end if; |
||
435 | when 3 => |
||
436 | Inc_PC <= '1'; |
||
437 | Read_To_Reg <= '1'; |
||
438 | if DPAIR = "11" then |
||
439 | Set_BusA_To(3 downto 0) <= "1001"; |
||
440 | else |
||
441 | Set_BusA_To(2 downto 1) <= DPAIR; |
||
442 | Set_BusA_To(0) <= '0'; |
||
443 | end if; |
||
444 | when others => null; |
||
445 | end case; |
||
446 | when "00101010" => |
||
447 | if Mode = 3 then |
||
448 | -- LDI A,(HL) |
||
449 | MCycles <= "010"; |
||
450 | case to_integer(unsigned(MCycle)) is |
||
451 | when 1 => |
||
452 | Set_Addr_To <= aXY; |
||
453 | when 2 => |
||
454 | Read_To_Acc <= '1'; |
||
455 | IncDec_16 <= "0110"; |
||
456 | when others => null; |
||
457 | end case; |
||
458 | else |
||
459 | -- LD HL,(nn) |
||
460 | MCycles <= "101"; |
||
461 | case to_integer(unsigned(MCycle)) is |
||
462 | when 2 => |
||
463 | Inc_PC <= '1'; |
||
464 | LDZ <= '1'; |
||
465 | when 3 => |
||
466 | Set_Addr_To <= aZI; |
||
467 | Inc_PC <= '1'; |
||
468 | LDW <= '1'; |
||
469 | when 4 => |
||
470 | Set_BusA_To(2 downto 0) <= "101"; -- L |
||
471 | Read_To_Reg <= '1'; |
||
472 | Inc_WZ <= '1'; |
||
473 | Set_Addr_To <= aZI; |
||
474 | when 5 => |
||
475 | Set_BusA_To(2 downto 0) <= "100"; -- H |
||
476 | Read_To_Reg <= '1'; |
||
477 | when others => null; |
||
478 | end case; |
||
479 | end if; |
||
480 | when "00100010" => |
||
481 | if Mode = 3 then |
||
482 | -- LDI (HL),A |
||
483 | MCycles <= "010"; |
||
484 | case to_integer(unsigned(MCycle)) is |
||
485 | when 1 => |
||
486 | Set_Addr_To <= aXY; |
||
487 | Set_BusB_To <= "0111"; |
||
488 | when 2 => |
||
489 | Write <= '1'; |
||
490 | IncDec_16 <= "0110"; |
||
491 | when others => null; |
||
492 | end case; |
||
493 | else |
||
494 | -- LD (nn),HL |
||
495 | MCycles <= "101"; |
||
496 | case to_integer(unsigned(MCycle)) is |
||
497 | when 2 => |
||
498 | Inc_PC <= '1'; |
||
499 | LDZ <= '1'; |
||
500 | when 3 => |
||
501 | Set_Addr_To <= aZI; |
||
502 | Inc_PC <= '1'; |
||
503 | LDW <= '1'; |
||
504 | Set_BusB_To <= "0101"; -- L |
||
505 | when 4 => |
||
506 | Inc_WZ <= '1'; |
||
507 | Set_Addr_To <= aZI; |
||
508 | Write <= '1'; |
||
509 | Set_BusB_To <= "0100"; -- H |
||
510 | when 5 => |
||
511 | Write <= '1'; |
||
512 | when others => null; |
||
513 | end case; |
||
514 | end if; |
||
515 | when "11111001" => |
||
516 | -- LD SP,HL |
||
517 | TStates <= "110"; |
||
518 | LDSPHL <= '1'; |
||
519 | when "11000101"|"11010101"|"11100101"|"11110101" => |
||
520 | -- PUSH qq |
||
521 | MCycles <= "011"; |
||
522 | case to_integer(unsigned(MCycle)) is |
||
523 | when 1 => |
||
524 | TStates <= "101"; |
||
525 | IncDec_16 <= "1111"; |
||
526 | Set_Addr_TO <= aSP; |
||
527 | if DPAIR = "11" then |
||
528 | Set_BusB_To <= "0111"; |
||
529 | else |
||
530 | Set_BusB_To(2 downto 1) <= DPAIR; |
||
531 | Set_BusB_To(0) <= '0'; |
||
532 | Set_BusB_To(3) <= '0'; |
||
533 | end if; |
||
534 | when 2 => |
||
535 | IncDec_16 <= "1111"; |
||
536 | Set_Addr_To <= aSP; |
||
537 | if DPAIR = "11" then |
||
538 | Set_BusB_To <= "1011"; |
||
539 | else |
||
540 | Set_BusB_To(2 downto 1) <= DPAIR; |
||
541 | Set_BusB_To(0) <= '1'; |
||
542 | Set_BusB_To(3) <= '0'; |
||
543 | end if; |
||
544 | Write <= '1'; |
||
545 | when 3 => |
||
546 | Write <= '1'; |
||
547 | when others => null; |
||
548 | end case; |
||
549 | when "11000001"|"11010001"|"11100001"|"11110001" => |
||
550 | -- POP qq |
||
551 | MCycles <= "011"; |
||
552 | case to_integer(unsigned(MCycle)) is |
||
553 | when 1 => |
||
554 | Set_Addr_To <= aSP; |
||
555 | when 2 => |
||
556 | IncDec_16 <= "0111"; |
||
557 | Set_Addr_To <= aSP; |
||
558 | Read_To_Reg <= '1'; |
||
559 | if DPAIR = "11" then |
||
560 | Set_BusA_To(3 downto 0) <= "1011"; |
||
561 | else |
||
562 | Set_BusA_To(2 downto 1) <= DPAIR; |
||
563 | Set_BusA_To(0) <= '1'; |
||
564 | end if; |
||
565 | when 3 => |
||
566 | IncDec_16 <= "0111"; |
||
567 | Read_To_Reg <= '1'; |
||
568 | if DPAIR = "11" then |
||
569 | Set_BusA_To(3 downto 0) <= "0111"; |
||
570 | else |
||
571 | Set_BusA_To(2 downto 1) <= DPAIR; |
||
572 | Set_BusA_To(0) <= '0'; |
||
573 | end if; |
||
574 | when others => null; |
||
575 | end case; |
||
576 | |||
577 | -- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP |
||
578 | when "11101011" => |
||
579 | if Mode /= 3 then |
||
580 | -- EX DE,HL |
||
581 | ExchangeDH <= '1'; |
||
582 | end if; |
||
583 | when "00001000" => |
||
584 | if Mode = 3 then |
||
585 | -- LD (nn),SP |
||
586 | MCycles <= "101"; |
||
587 | case to_integer(unsigned(MCycle)) is |
||
588 | when 2 => |
||
589 | Inc_PC <= '1'; |
||
590 | LDZ <= '1'; |
||
591 | when 3 => |
||
592 | Set_Addr_To <= aZI; |
||
593 | Inc_PC <= '1'; |
||
594 | LDW <= '1'; |
||
595 | Set_BusB_To <= "1000"; |
||
596 | when 4 => |
||
597 | Inc_WZ <= '1'; |
||
598 | Set_Addr_To <= aZI; |
||
599 | Write <= '1'; |
||
600 | Set_BusB_To <= "1001"; |
||
601 | when 5 => |
||
602 | Write <= '1'; |
||
603 | when others => null; |
||
604 | end case; |
||
605 | elsif Mode < 2 then |
||
606 | -- EX AF,AF' |
||
607 | ExchangeAF <= '1'; |
||
608 | end if; |
||
609 | when "11011001" => |
||
610 | if Mode = 3 then |
||
611 | -- RETI |
||
612 | MCycles <= "011"; |
||
613 | case to_integer(unsigned(MCycle)) is |
||
614 | when 1 => |
||
615 | Set_Addr_TO <= aSP; |
||
616 | when 2 => |
||
617 | IncDec_16 <= "0111"; |
||
618 | Set_Addr_To <= aSP; |
||
619 | LDZ <= '1'; |
||
620 | when 3 => |
||
621 | Jump <= '1'; |
||
622 | IncDec_16 <= "0111"; |
||
623 | I_RETN <= '1'; |
||
624 | SetEI <= '1'; |
||
625 | when others => null; |
||
626 | end case; |
||
627 | elsif Mode < 2 then |
||
628 | -- EXX |
||
629 | ExchangeRS <= '1'; |
||
630 | end if; |
||
631 | when "11100011" => |
||
632 | if Mode /= 3 then |
||
633 | -- EX (SP),HL |
||
634 | MCycles <= "101"; |
||
635 | case to_integer(unsigned(MCycle)) is |
||
636 | when 1 => |
||
637 | Set_Addr_To <= aSP; |
||
638 | when 2 => |
||
639 | Read_To_Reg <= '1'; |
||
640 | Set_BusA_To <= "0101"; |
||
641 | Set_BusB_To <= "0101"; |
||
642 | Set_Addr_To <= aSP; |
||
643 | when 3 => |
||
644 | IncDec_16 <= "0111"; |
||
645 | Set_Addr_To <= aSP; |
||
646 | TStates <= "100"; |
||
647 | Write <= '1'; |
||
648 | when 4 => |
||
649 | Read_To_Reg <= '1'; |
||
650 | Set_BusA_To <= "0100"; |
||
651 | Set_BusB_To <= "0100"; |
||
652 | Set_Addr_To <= aSP; |
||
653 | when 5 => |
||
654 | IncDec_16 <= "1111"; |
||
655 | TStates <= "101"; |
||
656 | Write <= '1'; |
||
657 | when others => null; |
||
658 | end case; |
||
659 | end if; |
||
660 | |||
661 | -- 8 BIT ARITHMETIC AND LOGICAL GROUP |
||
662 | when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" |
||
663 | |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" |
||
664 | |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" |
||
665 | |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" |
||
666 | |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" |
||
667 | |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" |
||
668 | |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" |
||
669 | |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => |
||
670 | -- ADD A,r |
||
671 | -- ADC A,r |
||
672 | -- SUB A,r |
||
673 | -- SBC A,r |
||
674 | -- AND A,r |
||
675 | -- OR A,r |
||
676 | -- XOR A,r |
||
677 | -- CP A,r |
||
678 | Set_BusB_To(2 downto 0) <= SSS; |
||
679 | Set_BusA_To(2 downto 0) <= "111"; |
||
680 | Read_To_Reg <= '1'; |
||
681 | Save_ALU <= '1'; |
||
682 | when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => |
||
683 | -- ADD A,(HL) |
||
684 | -- ADC A,(HL) |
||
685 | -- SUB A,(HL) |
||
686 | -- SBC A,(HL) |
||
687 | -- AND A,(HL) |
||
688 | -- OR A,(HL) |
||
689 | -- XOR A,(HL) |
||
690 | -- CP A,(HL) |
||
691 | MCycles <= "010"; |
||
692 | case to_integer(unsigned(MCycle)) is |
||
693 | when 1 => |
||
694 | Set_Addr_To <= aXY; |
||
695 | when 2 => |
||
696 | Read_To_Reg <= '1'; |
||
697 | Save_ALU <= '1'; |
||
698 | Set_BusB_To(2 downto 0) <= SSS; |
||
699 | Set_BusA_To(2 downto 0) <= "111"; |
||
700 | when others => null; |
||
701 | end case; |
||
702 | when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => |
||
703 | -- ADD A,n |
||
704 | -- ADC A,n |
||
705 | -- SUB A,n |
||
706 | -- SBC A,n |
||
707 | -- AND A,n |
||
708 | -- OR A,n |
||
709 | -- XOR A,n |
||
710 | -- CP A,n |
||
711 | MCycles <= "010"; |
||
712 | if MCycle = "010" then |
||
713 | Inc_PC <= '1'; |
||
714 | Read_To_Reg <= '1'; |
||
715 | Save_ALU <= '1'; |
||
716 | Set_BusB_To(2 downto 0) <= SSS; |
||
717 | Set_BusA_To(2 downto 0) <= "111"; |
||
718 | end if; |
||
719 | when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => |
||
720 | -- INC r |
||
721 | Set_BusB_To <= "1010"; |
||
722 | Set_BusA_To(2 downto 0) <= DDD; |
||
723 | Read_To_Reg <= '1'; |
||
724 | Save_ALU <= '1'; |
||
725 | PreserveC <= '1'; |
||
726 | ALU_Op <= "0000"; |
||
727 | when "00110100" => |
||
728 | -- INC (HL) |
||
729 | MCycles <= "011"; |
||
730 | case to_integer(unsigned(MCycle)) is |
||
731 | when 1 => |
||
732 | Set_Addr_To <= aXY; |
||
733 | when 2 => |
||
734 | TStates <= "100"; |
||
735 | Set_Addr_To <= aXY; |
||
736 | Read_To_Reg <= '1'; |
||
737 | Save_ALU <= '1'; |
||
738 | PreserveC <= '1'; |
||
739 | ALU_Op <= "0000"; |
||
740 | Set_BusB_To <= "1010"; |
||
741 | Set_BusA_To(2 downto 0) <= DDD; |
||
742 | when 3 => |
||
743 | Write <= '1'; |
||
744 | when others => null; |
||
745 | end case; |
||
746 | when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => |
||
747 | -- DEC r |
||
748 | Set_BusB_To <= "1010"; |
||
749 | Set_BusA_To(2 downto 0) <= DDD; |
||
750 | Read_To_Reg <= '1'; |
||
751 | Save_ALU <= '1'; |
||
752 | PreserveC <= '1'; |
||
753 | ALU_Op <= "0010"; |
||
754 | when "00110101" => |
||
755 | -- DEC (HL) |
||
756 | MCycles <= "011"; |
||
757 | case to_integer(unsigned(MCycle)) is |
||
758 | when 1 => |
||
759 | Set_Addr_To <= aXY; |
||
760 | when 2 => |
||
761 | TStates <= "100"; |
||
762 | Set_Addr_To <= aXY; |
||
763 | ALU_Op <= "0010"; |
||
764 | Read_To_Reg <= '1'; |
||
765 | Save_ALU <= '1'; |
||
766 | PreserveC <= '1'; |
||
767 | Set_BusB_To <= "1010"; |
||
768 | Set_BusA_To(2 downto 0) <= DDD; |
||
769 | when 3 => |
||
770 | Write <= '1'; |
||
771 | when others => null; |
||
772 | end case; |
||
773 | |||
774 | -- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS |
||
775 | when "00100111" => |
||
776 | -- DAA |
||
777 | Set_BusA_To(2 downto 0) <= "111"; |
||
778 | Read_To_Reg <= '1'; |
||
779 | ALU_Op <= "1100"; |
||
780 | Save_ALU <= '1'; |
||
781 | when "00101111" => |
||
782 | -- CPL |
||
783 | I_CPL <= '1'; |
||
784 | when "00111111" => |
||
785 | -- CCF |
||
786 | I_CCF <= '1'; |
||
787 | when "00110111" => |
||
788 | -- SCF |
||
789 | I_SCF <= '1'; |
||
790 | when "00000000" => |
||
791 | if NMICycle = '1' then |
||
792 | -- NMI |
||
793 | MCycles <= "011"; |
||
794 | case to_integer(unsigned(MCycle)) is |
||
795 | when 1 => |
||
796 | TStates <= "101"; |
||
797 | IncDec_16 <= "1111"; |
||
798 | Set_Addr_To <= aSP; |
||
799 | Set_BusB_To <= "1101"; |
||
800 | when 2 => |
||
801 | TStates <= "100"; |
||
802 | Write <= '1'; |
||
803 | IncDec_16 <= "1111"; |
||
804 | Set_Addr_To <= aSP; |
||
805 | Set_BusB_To <= "1100"; |
||
806 | when 3 => |
||
807 | TStates <= "100"; |
||
808 | Write <= '1'; |
||
809 | when others => null; |
||
810 | end case; |
||
811 | elsif IntCycle = '1' then |
||
812 | -- INT (IM 2) |
||
813 | MCycles <= "101"; |
||
814 | case to_integer(unsigned(MCycle)) is |
||
815 | when 1 => |
||
816 | LDZ <= '1'; |
||
817 | TStates <= "101"; |
||
818 | IncDec_16 <= "1111"; |
||
819 | Set_Addr_To <= aSP; |
||
820 | Set_BusB_To <= "1101"; |
||
821 | when 2 => |
||
822 | TStates <= "100"; |
||
823 | Write <= '1'; |
||
824 | IncDec_16 <= "1111"; |
||
825 | Set_Addr_To <= aSP; |
||
826 | Set_BusB_To <= "1100"; |
||
827 | when 3 => |
||
828 | TStates <= "100"; |
||
829 | Write <= '1'; |
||
830 | when 4 => |
||
831 | Inc_PC <= '1'; |
||
832 | LDZ <= '1'; |
||
833 | when 5 => |
||
834 | Jump <= '1'; |
||
835 | when others => null; |
||
836 | end case; |
||
837 | else |
||
838 | -- NOP |
||
839 | end if; |
||
840 | when "01110110" => |
||
841 | -- HALT |
||
842 | Halt <= '1'; |
||
843 | when "11110011" => |
||
844 | -- DI |
||
845 | SetDI <= '1'; |
||
846 | when "11111011" => |
||
847 | -- EI |
||
848 | SetEI <= '1'; |
||
849 | |||
850 | -- 16 BIT ARITHMETIC GROUP |
||
851 | when "00001001"|"00011001"|"00101001"|"00111001" => |
||
852 | -- ADD HL,ss |
||
853 | MCycles <= "011"; |
||
854 | case to_integer(unsigned(MCycle)) is |
||
855 | when 2 => |
||
856 | NoRead <= '1'; |
||
857 | ALU_Op <= "0000"; |
||
858 | Read_To_Reg <= '1'; |
||
859 | Save_ALU <= '1'; |
||
860 | Set_BusA_To(2 downto 0) <= "101"; |
||
861 | case to_integer(unsigned(IR(5 downto 4))) is |
||
862 | when 0|1|2 => |
||
863 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
864 | Set_BusB_To(0) <= '1'; |
||
865 | when others => |
||
866 | Set_BusB_To <= "1000"; |
||
867 | end case; |
||
868 | TStates <= "100"; |
||
869 | Arith16 <= '1'; |
||
870 | when 3 => |
||
871 | NoRead <= '1'; |
||
872 | Read_To_Reg <= '1'; |
||
873 | Save_ALU <= '1'; |
||
874 | ALU_Op <= "0001"; |
||
875 | Set_BusA_To(2 downto 0) <= "100"; |
||
876 | case to_integer(unsigned(IR(5 downto 4))) is |
||
877 | when 0|1|2 => |
||
878 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
879 | when others => |
||
880 | Set_BusB_To <= "1001"; |
||
881 | end case; |
||
882 | Arith16 <= '1'; |
||
883 | when others => |
||
884 | end case; |
||
885 | when "00000011"|"00010011"|"00100011"|"00110011" => |
||
886 | -- INC ss |
||
887 | TStates <= "110"; |
||
888 | IncDec_16(3 downto 2) <= "01"; |
||
889 | IncDec_16(1 downto 0) <= DPair; |
||
890 | when "00001011"|"00011011"|"00101011"|"00111011" => |
||
891 | -- DEC ss |
||
892 | TStates <= "110"; |
||
893 | IncDec_16(3 downto 2) <= "11"; |
||
894 | IncDec_16(1 downto 0) <= DPair; |
||
895 | |||
896 | -- ROTATE AND SHIFT GROUP |
||
897 | when "00000111" |
||
898 | -- RLCA |
||
899 | |"00010111" |
||
900 | -- RLA |
||
901 | |"00001111" |
||
902 | -- RRCA |
||
903 | |"00011111" => |
||
904 | -- RRA |
||
905 | Set_BusA_To(2 downto 0) <= "111"; |
||
906 | ALU_Op <= "1000"; |
||
907 | Read_To_Reg <= '1'; |
||
908 | Save_ALU <= '1'; |
||
909 | |||
910 | -- JUMP GROUP |
||
911 | when "11000011" => |
||
912 | -- JP nn |
||
913 | MCycles <= "011"; |
||
914 | case to_integer(unsigned(MCycle)) is |
||
915 | when 2 => |
||
916 | Inc_PC <= '1'; |
||
917 | LDZ <= '1'; |
||
918 | when 3 => |
||
919 | Inc_PC <= '1'; |
||
920 | Jump <= '1'; |
||
921 | when others => null; |
||
922 | end case; |
||
923 | when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => |
||
924 | if IR(5) = '1' and Mode = 3 then |
||
925 | case IRB(4 downto 3) is |
||
926 | when "00" => |
||
927 | -- LD ($FF00+C),A |
||
928 | MCycles <= "010"; |
||
929 | case to_integer(unsigned(MCycle)) is |
||
930 | when 1 => |
||
931 | Set_Addr_To <= aBC; |
||
932 | Set_BusB_To <= "0111"; |
||
933 | when 2 => |
||
934 | Write <= '1'; |
||
935 | IORQ <= '1'; |
||
936 | when others => |
||
937 | end case; |
||
938 | when "01" => |
||
939 | -- LD (nn),A |
||
940 | MCycles <= "100"; |
||
941 | case to_integer(unsigned(MCycle)) is |
||
942 | when 2 => |
||
943 | Inc_PC <= '1'; |
||
944 | LDZ <= '1'; |
||
945 | when 3 => |
||
946 | Set_Addr_To <= aZI; |
||
947 | Inc_PC <= '1'; |
||
948 | Set_BusB_To <= "0111"; |
||
949 | when 4 => |
||
950 | Write <= '1'; |
||
951 | when others => null; |
||
952 | end case; |
||
953 | when "10" => |
||
954 | -- LD A,($FF00+C) |
||
955 | MCycles <= "010"; |
||
956 | case to_integer(unsigned(MCycle)) is |
||
957 | when 1 => |
||
958 | Set_Addr_To <= aBC; |
||
959 | when 2 => |
||
960 | Read_To_Acc <= '1'; |
||
961 | IORQ <= '1'; |
||
962 | when others => |
||
963 | end case; |
||
964 | when "11" => |
||
965 | -- LD A,(nn) |
||
966 | MCycles <= "100"; |
||
967 | case to_integer(unsigned(MCycle)) is |
||
968 | when 2 => |
||
969 | Inc_PC <= '1'; |
||
970 | LDZ <= '1'; |
||
971 | when 3 => |
||
972 | Set_Addr_To <= aZI; |
||
973 | Inc_PC <= '1'; |
||
974 | when 4 => |
||
975 | Read_To_Acc <= '1'; |
||
976 | when others => null; |
||
977 | end case; |
||
978 | end case; |
||
979 | else |
||
980 | -- JP cc,nn |
||
981 | MCycles <= "011"; |
||
982 | case to_integer(unsigned(MCycle)) is |
||
983 | when 2 => |
||
984 | Inc_PC <= '1'; |
||
985 | LDZ <= '1'; |
||
986 | when 3 => |
||
987 | Inc_PC <= '1'; |
||
988 | if is_cc_true(F, to_bitvector(IR(5 downto 3))) then |
||
989 | Jump <= '1'; |
||
990 | end if; |
||
991 | when others => null; |
||
992 | end case; |
||
993 | end if; |
||
994 | when "00011000" => |
||
995 | if Mode /= 2 then |
||
996 | -- JR e |
||
997 | MCycles <= "011"; |
||
998 | case to_integer(unsigned(MCycle)) is |
||
999 | when 2 => |
||
1000 | Inc_PC <= '1'; |
||
1001 | when 3 => |
||
1002 | NoRead <= '1'; |
||
1003 | JumpE <= '1'; |
||
1004 | TStates <= "101"; |
||
1005 | when others => null; |
||
1006 | end case; |
||
1007 | end if; |
||
1008 | when "00111000" => |
||
1009 | if Mode /= 2 then |
||
1010 | -- JR C,e |
||
1011 | MCycles <= "011"; |
||
1012 | case to_integer(unsigned(MCycle)) is |
||
1013 | when 2 => |
||
1014 | Inc_PC <= '1'; |
||
1015 | if F(Flag_C) = '0' then |
||
1016 | MCycles <= "010"; |
||
1017 | end if; |
||
1018 | when 3 => |
||
1019 | NoRead <= '1'; |
||
1020 | JumpE <= '1'; |
||
1021 | TStates <= "101"; |
||
1022 | when others => null; |
||
1023 | end case; |
||
1024 | end if; |
||
1025 | when "00110000" => |
||
1026 | if Mode /= 2 then |
||
1027 | -- JR NC,e |
||
1028 | MCycles <= "011"; |
||
1029 | case to_integer(unsigned(MCycle)) is |
||
1030 | when 2 => |
||
1031 | Inc_PC <= '1'; |
||
1032 | if F(Flag_C) = '1' then |
||
1033 | MCycles <= "010"; |
||
1034 | end if; |
||
1035 | when 3 => |
||
1036 | NoRead <= '1'; |
||
1037 | JumpE <= '1'; |
||
1038 | TStates <= "101"; |
||
1039 | when others => null; |
||
1040 | end case; |
||
1041 | end if; |
||
1042 | when "00101000" => |
||
1043 | if Mode /= 2 then |
||
1044 | -- JR Z,e |
||
1045 | MCycles <= "011"; |
||
1046 | case to_integer(unsigned(MCycle)) is |
||
1047 | when 2 => |
||
1048 | Inc_PC <= '1'; |
||
1049 | if F(Flag_Z) = '0' then |
||
1050 | MCycles <= "010"; |
||
1051 | end if; |
||
1052 | when 3 => |
||
1053 | NoRead <= '1'; |
||
1054 | JumpE <= '1'; |
||
1055 | TStates <= "101"; |
||
1056 | when others => null; |
||
1057 | end case; |
||
1058 | end if; |
||
1059 | when "00100000" => |
||
1060 | if Mode /= 2 then |
||
1061 | -- JR NZ,e |
||
1062 | MCycles <= "011"; |
||
1063 | case to_integer(unsigned(MCycle)) is |
||
1064 | when 2 => |
||
1065 | Inc_PC <= '1'; |
||
1066 | if F(Flag_Z) = '1' then |
||
1067 | MCycles <= "010"; |
||
1068 | end if; |
||
1069 | when 3 => |
||
1070 | NoRead <= '1'; |
||
1071 | JumpE <= '1'; |
||
1072 | TStates <= "101"; |
||
1073 | when others => null; |
||
1074 | end case; |
||
1075 | end if; |
||
1076 | when "11101001" => |
||
1077 | -- JP (HL) |
||
1078 | JumpXY <= '1'; |
||
1079 | when "00010000" => |
||
1080 | if Mode = 3 then |
||
1081 | I_DJNZ <= '1'; |
||
1082 | elsif Mode < 2 then |
||
1083 | -- DJNZ,e |
||
1084 | MCycles <= "011"; |
||
1085 | case to_integer(unsigned(MCycle)) is |
||
1086 | when 1 => |
||
1087 | TStates <= "101"; |
||
1088 | I_DJNZ <= '1'; |
||
1089 | Set_BusB_To <= "1010"; |
||
1090 | Set_BusA_To(2 downto 0) <= "000"; |
||
1091 | Read_To_Reg <= '1'; |
||
1092 | Save_ALU <= '1'; |
||
1093 | ALU_Op <= "0010"; |
||
1094 | when 2 => |
||
1095 | I_DJNZ <= '1'; |
||
1096 | Inc_PC <= '1'; |
||
1097 | when 3 => |
||
1098 | NoRead <= '1'; |
||
1099 | JumpE <= '1'; |
||
1100 | TStates <= "101"; |
||
1101 | when others => null; |
||
1102 | end case; |
||
1103 | end if; |
||
1104 | |||
1105 | -- CALL AND RETURN GROUP |
||
1106 | when "11001101" => |
||
1107 | -- CALL nn |
||
1108 | MCycles <= "101"; |
||
1109 | case to_integer(unsigned(MCycle)) is |
||
1110 | when 2 => |
||
1111 | Inc_PC <= '1'; |
||
1112 | LDZ <= '1'; |
||
1113 | when 3 => |
||
1114 | IncDec_16 <= "1111"; |
||
1115 | Inc_PC <= '1'; |
||
1116 | TStates <= "100"; |
||
1117 | Set_Addr_To <= aSP; |
||
1118 | LDW <= '1'; |
||
1119 | Set_BusB_To <= "1101"; |
||
1120 | when 4 => |
||
1121 | Write <= '1'; |
||
1122 | IncDec_16 <= "1111"; |
||
1123 | Set_Addr_To <= aSP; |
||
1124 | Set_BusB_To <= "1100"; |
||
1125 | when 5 => |
||
1126 | Write <= '1'; |
||
1127 | Call <= '1'; |
||
1128 | when others => null; |
||
1129 | end case; |
||
1130 | when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => |
||
1131 | if IR(5) = '0' or Mode /= 3 then |
||
1132 | -- CALL cc,nn |
||
1133 | MCycles <= "101"; |
||
1134 | case to_integer(unsigned(MCycle)) is |
||
1135 | when 2 => |
||
1136 | Inc_PC <= '1'; |
||
1137 | LDZ <= '1'; |
||
1138 | when 3 => |
||
1139 | Inc_PC <= '1'; |
||
1140 | LDW <= '1'; |
||
1141 | if is_cc_true(F, to_bitvector(IR(5 downto 3))) then |
||
1142 | IncDec_16 <= "1111"; |
||
1143 | Set_Addr_TO <= aSP; |
||
1144 | TStates <= "100"; |
||
1145 | Set_BusB_To <= "1101"; |
||
1146 | else |
||
1147 | MCycles <= "011"; |
||
1148 | end if; |
||
1149 | when 4 => |
||
1150 | Write <= '1'; |
||
1151 | IncDec_16 <= "1111"; |
||
1152 | Set_Addr_To <= aSP; |
||
1153 | Set_BusB_To <= "1100"; |
||
1154 | when 5 => |
||
1155 | Write <= '1'; |
||
1156 | Call <= '1'; |
||
1157 | when others => null; |
||
1158 | end case; |
||
1159 | end if; |
||
1160 | when "11001001" => |
||
1161 | -- RET |
||
1162 | MCycles <= "011"; |
||
1163 | case to_integer(unsigned(MCycle)) is |
||
1164 | when 1 => |
||
1165 | TStates <= "101"; |
||
1166 | Set_Addr_TO <= aSP; |
||
1167 | when 2 => |
||
1168 | IncDec_16 <= "0111"; |
||
1169 | Set_Addr_To <= aSP; |
||
1170 | LDZ <= '1'; |
||
1171 | when 3 => |
||
1172 | Jump <= '1'; |
||
1173 | IncDec_16 <= "0111"; |
||
1174 | when others => null; |
||
1175 | end case; |
||
1176 | when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => |
||
1177 | if IR(5) = '1' and Mode = 3 then |
||
1178 | case IRB(4 downto 3) is |
||
1179 | when "00" => |
||
1180 | -- LD ($FF00+nn),A |
||
1181 | MCycles <= "011"; |
||
1182 | case to_integer(unsigned(MCycle)) is |
||
1183 | when 2 => |
||
1184 | Inc_PC <= '1'; |
||
1185 | Set_Addr_To <= aIOA; |
||
1186 | Set_BusB_To <= "0111"; |
||
1187 | when 3 => |
||
1188 | Write <= '1'; |
||
1189 | when others => null; |
||
1190 | end case; |
||
1191 | when "01" => |
||
1192 | -- ADD SP,n |
||
1193 | MCycles <= "011"; |
||
1194 | case to_integer(unsigned(MCycle)) is |
||
1195 | when 2 => |
||
1196 | ALU_Op <= "0000"; |
||
1197 | Inc_PC <= '1'; |
||
1198 | Read_To_Reg <= '1'; |
||
1199 | Save_ALU <= '1'; |
||
1200 | Set_BusA_To <= "1000"; |
||
1201 | Set_BusB_To <= "0110"; |
||
1202 | when 3 => |
||
1203 | NoRead <= '1'; |
||
1204 | Read_To_Reg <= '1'; |
||
1205 | Save_ALU <= '1'; |
||
1206 | ALU_Op <= "0001"; |
||
1207 | Set_BusA_To <= "1001"; |
||
1208 | Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! |
||
1209 | when others => |
||
1210 | end case; |
||
1211 | when "10" => |
||
1212 | -- LD A,($FF00+nn) |
||
1213 | MCycles <= "011"; |
||
1214 | case to_integer(unsigned(MCycle)) is |
||
1215 | when 2 => |
||
1216 | Inc_PC <= '1'; |
||
1217 | Set_Addr_To <= aIOA; |
||
1218 | when 3 => |
||
1219 | Read_To_Acc <= '1'; |
||
1220 | when others => null; |
||
1221 | end case; |
||
1222 | when "11" => |
||
1223 | -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! |
||
1224 | MCycles <= "101"; |
||
1225 | case to_integer(unsigned(MCycle)) is |
||
1226 | when 2 => |
||
1227 | Inc_PC <= '1'; |
||
1228 | LDZ <= '1'; |
||
1229 | when 3 => |
||
1230 | Set_Addr_To <= aZI; |
||
1231 | Inc_PC <= '1'; |
||
1232 | LDW <= '1'; |
||
1233 | when 4 => |
||
1234 | Set_BusA_To(2 downto 0) <= "101"; -- L |
||
1235 | Read_To_Reg <= '1'; |
||
1236 | Inc_WZ <= '1'; |
||
1237 | Set_Addr_To <= aZI; |
||
1238 | when 5 => |
||
1239 | Set_BusA_To(2 downto 0) <= "100"; -- H |
||
1240 | Read_To_Reg <= '1'; |
||
1241 | when others => null; |
||
1242 | end case; |
||
1243 | end case; |
||
1244 | else |
||
1245 | -- RET cc |
||
1246 | MCycles <= "011"; |
||
1247 | case to_integer(unsigned(MCycle)) is |
||
1248 | when 1 => |
||
1249 | if is_cc_true(F, to_bitvector(IR(5 downto 3))) then |
||
1250 | Set_Addr_TO <= aSP; |
||
1251 | else |
||
1252 | MCycles <= "001"; |
||
1253 | end if; |
||
1254 | TStates <= "101"; |
||
1255 | when 2 => |
||
1256 | IncDec_16 <= "0111"; |
||
1257 | Set_Addr_To <= aSP; |
||
1258 | LDZ <= '1'; |
||
1259 | when 3 => |
||
1260 | Jump <= '1'; |
||
1261 | IncDec_16 <= "0111"; |
||
1262 | when others => null; |
||
1263 | end case; |
||
1264 | end if; |
||
1265 | when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => |
||
1266 | -- RST p |
||
1267 | MCycles <= "011"; |
||
1268 | case to_integer(unsigned(MCycle)) is |
||
1269 | when 1 => |
||
1270 | TStates <= "101"; |
||
1271 | IncDec_16 <= "1111"; |
||
1272 | Set_Addr_To <= aSP; |
||
1273 | Set_BusB_To <= "1101"; |
||
1274 | when 2 => |
||
1275 | Write <= '1'; |
||
1276 | IncDec_16 <= "1111"; |
||
1277 | Set_Addr_To <= aSP; |
||
1278 | Set_BusB_To <= "1100"; |
||
1279 | when 3 => |
||
1280 | Write <= '1'; |
||
1281 | RstP <= '1'; |
||
1282 | when others => null; |
||
1283 | end case; |
||
1284 | |||
1285 | -- INPUT AND OUTPUT GROUP |
||
1286 | when "11011011" => |
||
1287 | if Mode /= 3 then |
||
1288 | -- IN A,(n) |
||
1289 | MCycles <= "011"; |
||
1290 | case to_integer(unsigned(MCycle)) is |
||
1291 | when 2 => |
||
1292 | Inc_PC <= '1'; |
||
1293 | Set_Addr_To <= aIOA; |
||
1294 | when 3 => |
||
1295 | Read_To_Acc <= '1'; |
||
1296 | IORQ <= '1'; |
||
1297 | when others => null; |
||
1298 | end case; |
||
1299 | end if; |
||
1300 | when "11010011" => |
||
1301 | if Mode /= 3 then |
||
1302 | -- OUT (n),A |
||
1303 | MCycles <= "011"; |
||
1304 | case to_integer(unsigned(MCycle)) is |
||
1305 | when 2 => |
||
1306 | Inc_PC <= '1'; |
||
1307 | Set_Addr_To <= aIOA; |
||
1308 | Set_BusB_To <= "0111"; |
||
1309 | when 3 => |
||
1310 | Write <= '1'; |
||
1311 | IORQ <= '1'; |
||
1312 | when others => null; |
||
1313 | end case; |
||
1314 | end if; |
||
1315 | |||
1316 | ------------------------------------------------------------------------------ |
||
1317 | ------------------------------------------------------------------------------ |
||
1318 | -- MULTIBYTE INSTRUCTIONS |
||
1319 | ------------------------------------------------------------------------------ |
||
1320 | ------------------------------------------------------------------------------ |
||
1321 | |||
1322 | when "11001011" => |
||
1323 | if Mode /= 2 then |
||
1324 | Prefix <= "01"; |
||
1325 | end if; |
||
1326 | |||
1327 | when "11101101" => |
||
1328 | if Mode < 2 then |
||
1329 | Prefix <= "10"; |
||
1330 | end if; |
||
1331 | |||
1332 | when "11011101"|"11111101" => |
||
1333 | if Mode < 2 then |
||
1334 | Prefix <= "11"; |
||
1335 | end if; |
||
1336 | |||
1337 | end case; |
||
1338 | |||
1339 | when "01" => |
||
1340 | |||
1341 | ------------------------------------------------------------------------------ |
||
1342 | -- |
||
1343 | -- CB prefixed instructions |
||
1344 | -- |
||
1345 | ------------------------------------------------------------------------------ |
||
1346 | |||
1347 | Set_BusA_To(2 downto 0) <= IR(2 downto 0); |
||
1348 | Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
||
1349 | |||
1350 | case IRB is |
||
1351 | when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" |
||
1352 | |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" |
||
1353 | |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" |
||
1354 | |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" |
||
1355 | |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" |
||
1356 | |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" |
||
1357 | |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" |
||
1358 | |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => |
||
1359 | -- RLC r |
||
1360 | -- RL r |
||
1361 | -- RRC r |
||
1362 | -- RR r |
||
1363 | -- SLA r |
||
1364 | -- SRA r |
||
1365 | -- SRL r |
||
1366 | -- SLL r (Undocumented) / SWAP r |
||
1367 | if MCycle = "001" then |
||
1368 | ALU_Op <= "1000"; |
||
1369 | Read_To_Reg <= '1'; |
||
1370 | Save_ALU <= '1'; |
||
1371 | end if; |
||
1372 | when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => |
||
1373 | -- RLC (HL) |
||
1374 | -- RL (HL) |
||
1375 | -- RRC (HL) |
||
1376 | -- RR (HL) |
||
1377 | -- SRA (HL) |
||
1378 | -- SRL (HL) |
||
1379 | -- SLA (HL) |
||
1380 | -- SLL (HL) (Undocumented) / SWAP (HL) |
||
1381 | MCycles <= "011"; |
||
1382 | case to_integer(unsigned(MCycle)) is |
||
1383 | when 1 | 7 => |
||
1384 | Set_Addr_To <= aXY; |
||
1385 | when 2 => |
||
1386 | ALU_Op <= "1000"; |
||
1387 | Read_To_Reg <= '1'; |
||
1388 | Save_ALU <= '1'; |
||
1389 | Set_Addr_To <= aXY; |
||
1390 | TStates <= "100"; |
||
1391 | when 3 => |
||
1392 | Write <= '1'; |
||
1393 | when others => |
||
1394 | end case; |
||
1395 | when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" |
||
1396 | |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" |
||
1397 | |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" |
||
1398 | |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" |
||
1399 | |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" |
||
1400 | |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" |
||
1401 | |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" |
||
1402 | |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => |
||
1403 | -- BIT b,r |
||
1404 | if MCycle = "001" then |
||
1405 | Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
||
1406 | ALU_Op <= "1001"; |
||
1407 | end if; |
||
1408 | when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => |
||
1409 | -- BIT b,(HL) |
||
1410 | MCycles <= "010"; |
||
1411 | case to_integer(unsigned(MCycle)) is |
||
1412 | when 1 | 7=> |
||
1413 | Set_Addr_To <= aXY; |
||
1414 | when 2 => |
||
1415 | ALU_Op <= "1001"; |
||
1416 | TStates <= "100"; |
||
1417 | when others => null; |
||
1418 | end case; |
||
1419 | when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" |
||
1420 | |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" |
||
1421 | |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" |
||
1422 | |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" |
||
1423 | |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" |
||
1424 | |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" |
||
1425 | |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" |
||
1426 | |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => |
||
1427 | -- SET b,r |
||
1428 | if MCycle = "001" then |
||
1429 | ALU_Op <= "1010"; |
||
1430 | Read_To_Reg <= '1'; |
||
1431 | Save_ALU <= '1'; |
||
1432 | end if; |
||
1433 | when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => |
||
1434 | -- SET b,(HL) |
||
1435 | MCycles <= "011"; |
||
1436 | case to_integer(unsigned(MCycle)) is |
||
1437 | when 1 | 7=> |
||
1438 | Set_Addr_To <= aXY; |
||
1439 | when 2 => |
||
1440 | ALU_Op <= "1010"; |
||
1441 | Read_To_Reg <= '1'; |
||
1442 | Save_ALU <= '1'; |
||
1443 | Set_Addr_To <= aXY; |
||
1444 | TStates <= "100"; |
||
1445 | when 3 => |
||
1446 | Write <= '1'; |
||
1447 | when others => null; |
||
1448 | end case; |
||
1449 | when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" |
||
1450 | |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" |
||
1451 | |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" |
||
1452 | |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" |
||
1453 | |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" |
||
1454 | |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" |
||
1455 | |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" |
||
1456 | |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => |
||
1457 | -- RES b,r |
||
1458 | if MCycle = "001" then |
||
1459 | ALU_Op <= "1011"; |
||
1460 | Read_To_Reg <= '1'; |
||
1461 | Save_ALU <= '1'; |
||
1462 | end if; |
||
1463 | when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => |
||
1464 | -- RES b,(HL) |
||
1465 | MCycles <= "011"; |
||
1466 | case to_integer(unsigned(MCycle)) is |
||
1467 | when 1 | 7 => |
||
1468 | Set_Addr_To <= aXY; |
||
1469 | when 2 => |
||
1470 | ALU_Op <= "1011"; |
||
1471 | Read_To_Reg <= '1'; |
||
1472 | Save_ALU <= '1'; |
||
1473 | Set_Addr_To <= aXY; |
||
1474 | TStates <= "100"; |
||
1475 | when 3 => |
||
1476 | Write <= '1'; |
||
1477 | when others => null; |
||
1478 | end case; |
||
1479 | end case; |
||
1480 | |||
1481 | when others => |
||
1482 | |||
1483 | ------------------------------------------------------------------------------ |
||
1484 | -- |
||
1485 | -- ED prefixed instructions |
||
1486 | -- |
||
1487 | ------------------------------------------------------------------------------ |
||
1488 | |||
1489 | case IRB is |
||
1490 | when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" |
||
1491 | |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" |
||
1492 | |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" |
||
1493 | |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" |
||
1494 | |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" |
||
1495 | |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" |
||
1496 | |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" |
||
1497 | |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" |
||
1498 | |||
1499 | |||
1500 | |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" |
||
1501 | |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" |
||
1502 | |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" |
||
1503 | |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" |
||
1504 | | "10100100"|"10100101"|"10100110"|"10100111" |
||
1505 | | "10101100"|"10101101"|"10101110"|"10101111" |
||
1506 | | "10110100"|"10110101"|"10110110"|"10110111" |
||
1507 | | "10111100"|"10111101"|"10111110"|"10111111" |
||
1508 | |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" |
||
1509 | |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" |
||
1510 | |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" |
||
1511 | |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" |
||
1512 | |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" |
||
1513 | |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" |
||
1514 | |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" |
||
1515 | |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => |
||
1516 | null; -- NOP, undocumented |
||
1517 | when "01111110"|"01111111" => |
||
1518 | -- NOP, undocumented |
||
1519 | null; |
||
1520 | -- 8 BIT LOAD GROUP |
||
1521 | when "01010111" => |
||
1522 | -- LD A,I |
||
1523 | Special_LD <= "100"; |
||
1524 | TStates <= "101"; |
||
1525 | when "01011111" => |
||
1526 | -- LD A,R |
||
1527 | Special_LD <= "101"; |
||
1528 | TStates <= "101"; |
||
1529 | when "01000111" => |
||
1530 | -- LD I,A |
||
1531 | Special_LD <= "110"; |
||
1532 | TStates <= "101"; |
||
1533 | when "01001111" => |
||
1534 | -- LD R,A |
||
1535 | Special_LD <= "111"; |
||
1536 | TStates <= "101"; |
||
1537 | -- 16 BIT LOAD GROUP |
||
1538 | when "01001011"|"01011011"|"01101011"|"01111011" => |
||
1539 | -- LD dd,(nn) |
||
1540 | MCycles <= "101"; |
||
1541 | case to_integer(unsigned(MCycle)) is |
||
1542 | when 2 => |
||
1543 | Inc_PC <= '1'; |
||
1544 | LDZ <= '1'; |
||
1545 | when 3 => |
||
1546 | Set_Addr_To <= aZI; |
||
1547 | Inc_PC <= '1'; |
||
1548 | LDW <= '1'; |
||
1549 | when 4 => |
||
1550 | Read_To_Reg <= '1'; |
||
1551 | if IR(5 downto 4) = "11" then |
||
1552 | Set_BusA_To <= "1000"; |
||
1553 | else |
||
1554 | Set_BusA_To(2 downto 1) <= IR(5 downto 4); |
||
1555 | Set_BusA_To(0) <= '1'; |
||
1556 | end if; |
||
1557 | Inc_WZ <= '1'; |
||
1558 | Set_Addr_To <= aZI; |
||
1559 | when 5 => |
||
1560 | Read_To_Reg <= '1'; |
||
1561 | if IR(5 downto 4) = "11" then |
||
1562 | Set_BusA_To <= "1001"; |
||
1563 | else |
||
1564 | Set_BusA_To(2 downto 1) <= IR(5 downto 4); |
||
1565 | Set_BusA_To(0) <= '0'; |
||
1566 | end if; |
||
1567 | when others => null; |
||
1568 | end case; |
||
1569 | when "01000011"|"01010011"|"01100011"|"01110011" => |
||
1570 | -- LD (nn),dd |
||
1571 | MCycles <= "101"; |
||
1572 | case to_integer(unsigned(MCycle)) is |
||
1573 | when 2 => |
||
1574 | Inc_PC <= '1'; |
||
1575 | LDZ <= '1'; |
||
1576 | when 3 => |
||
1577 | Set_Addr_To <= aZI; |
||
1578 | Inc_PC <= '1'; |
||
1579 | LDW <= '1'; |
||
1580 | if IR(5 downto 4) = "11" then |
||
1581 | Set_BusB_To <= "1000"; |
||
1582 | else |
||
1583 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
1584 | Set_BusB_To(0) <= '1'; |
||
1585 | Set_BusB_To(3) <= '0'; |
||
1586 | end if; |
||
1587 | when 4 => |
||
1588 | Inc_WZ <= '1'; |
||
1589 | Set_Addr_To <= aZI; |
||
1590 | Write <= '1'; |
||
1591 | if IR(5 downto 4) = "11" then |
||
1592 | Set_BusB_To <= "1001"; |
||
1593 | else |
||
1594 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
1595 | Set_BusB_To(0) <= '0'; |
||
1596 | Set_BusB_To(3) <= '0'; |
||
1597 | end if; |
||
1598 | when 5 => |
||
1599 | Write <= '1'; |
||
1600 | when others => null; |
||
1601 | end case; |
||
1602 | when "10100000" | "10101000" | "10110000" | "10111000" => |
||
1603 | -- LDI, LDD, LDIR, LDDR |
||
1604 | MCycles <= "100"; |
||
1605 | case to_integer(unsigned(MCycle)) is |
||
1606 | when 1 => |
||
1607 | Set_Addr_To <= aXY; |
||
1608 | IncDec_16 <= "1100"; -- BC |
||
1609 | when 2 => |
||
1610 | Set_BusB_To <= "0110"; |
||
1611 | Set_BusA_To(2 downto 0) <= "111"; |
||
1612 | ALU_Op <= "0000"; |
||
1613 | Set_Addr_To <= aDE; |
||
1614 | if IR(3) = '0' then |
||
1615 | IncDec_16 <= "0110"; -- IX |
||
1616 | else |
||
1617 | IncDec_16 <= "1110"; |
||
1618 | end if; |
||
1619 | when 3 => |
||
1620 | I_BT <= '1'; |
||
1621 | TStates <= "101"; |
||
1622 | Write <= '1'; |
||
1623 | if IR(3) = '0' then |
||
1624 | IncDec_16 <= "0101"; -- DE |
||
1625 | else |
||
1626 | IncDec_16 <= "1101"; |
||
1627 | end if; |
||
1628 | when 4 => |
||
1629 | NoRead <= '1'; |
||
1630 | TStates <= "101"; |
||
1631 | when others => null; |
||
1632 | end case; |
||
1633 | when "10100001" | "10101001" | "10110001" | "10111001" => |
||
1634 | -- CPI, CPD, CPIR, CPDR |
||
1635 | MCycles <= "100"; |
||
1636 | case to_integer(unsigned(MCycle)) is |
||
1637 | when 1 => |
||
1638 | Set_Addr_To <= aXY; |
||
1639 | IncDec_16 <= "1100"; -- BC |
||
1640 | when 2 => |
||
1641 | Set_BusB_To <= "0110"; |
||
1642 | Set_BusA_To(2 downto 0) <= "111"; |
||
1643 | ALU_Op <= "0111"; |
||
1644 | Save_ALU <= '1'; |
||
1645 | PreserveC <= '1'; |
||
1646 | if IR(3) = '0' then |
||
1647 | IncDec_16 <= "0110"; |
||
1648 | else |
||
1649 | IncDec_16 <= "1110"; |
||
1650 | end if; |
||
1651 | when 3 => |
||
1652 | NoRead <= '1'; |
||
1653 | I_BC <= '1'; |
||
1654 | TStates <= "101"; |
||
1655 | when 4 => |
||
1656 | NoRead <= '1'; |
||
1657 | TStates <= "101"; |
||
1658 | when others => null; |
||
1659 | end case; |
||
1660 | when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => |
||
1661 | -- NEG |
||
1662 | Alu_OP <= "0010"; |
||
1663 | Set_BusB_To <= "0111"; |
||
1664 | Set_BusA_To <= "1010"; |
||
1665 | Read_To_Acc <= '1'; |
||
1666 | Save_ALU <= '1'; |
||
1667 | when "01000110"|"01001110"|"01100110"|"01101110" => |
||
1668 | -- IM 0 |
||
1669 | IMode <= "00"; |
||
1670 | when "01010110"|"01110110" => |
||
1671 | -- IM 1 |
||
1672 | IMode <= "01"; |
||
1673 | when "01011110"|"01110111" => |
||
1674 | -- IM 2 |
||
1675 | IMode <= "10"; |
||
1676 | -- 16 bit arithmetic |
||
1677 | when "01001010"|"01011010"|"01101010"|"01111010" => |
||
1678 | -- ADC HL,ss |
||
1679 | MCycles <= "011"; |
||
1680 | case to_integer(unsigned(MCycle)) is |
||
1681 | when 2 => |
||
1682 | NoRead <= '1'; |
||
1683 | ALU_Op <= "0001"; |
||
1684 | Read_To_Reg <= '1'; |
||
1685 | Save_ALU <= '1'; |
||
1686 | Set_BusA_To(2 downto 0) <= "101"; |
||
1687 | case to_integer(unsigned(IR(5 downto 4))) is |
||
1688 | when 0|1|2 => |
||
1689 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
1690 | Set_BusB_To(0) <= '1'; |
||
1691 | when others => |
||
1692 | Set_BusB_To <= "1000"; |
||
1693 | end case; |
||
1694 | TStates <= "100"; |
||
1695 | when 3 => |
||
1696 | NoRead <= '1'; |
||
1697 | Read_To_Reg <= '1'; |
||
1698 | Save_ALU <= '1'; |
||
1699 | ALU_Op <= "0001"; |
||
1700 | Set_BusA_To(2 downto 0) <= "100"; |
||
1701 | case to_integer(unsigned(IR(5 downto 4))) is |
||
1702 | when 0|1|2 => |
||
1703 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
1704 | Set_BusB_To(0) <= '0'; |
||
1705 | when others => |
||
1706 | Set_BusB_To <= "1001"; |
||
1707 | end case; |
||
1708 | when others => |
||
1709 | end case; |
||
1710 | when "01000010"|"01010010"|"01100010"|"01110010" => |
||
1711 | -- SBC HL,ss |
||
1712 | MCycles <= "011"; |
||
1713 | case to_integer(unsigned(MCycle)) is |
||
1714 | when 2 => |
||
1715 | NoRead <= '1'; |
||
1716 | ALU_Op <= "0011"; |
||
1717 | Read_To_Reg <= '1'; |
||
1718 | Save_ALU <= '1'; |
||
1719 | Set_BusA_To(2 downto 0) <= "101"; |
||
1720 | case to_integer(unsigned(IR(5 downto 4))) is |
||
1721 | when 0|1|2 => |
||
1722 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
1723 | Set_BusB_To(0) <= '1'; |
||
1724 | when others => |
||
1725 | Set_BusB_To <= "1000"; |
||
1726 | end case; |
||
1727 | TStates <= "100"; |
||
1728 | when 3 => |
||
1729 | NoRead <= '1'; |
||
1730 | ALU_Op <= "0011"; |
||
1731 | Read_To_Reg <= '1'; |
||
1732 | Save_ALU <= '1'; |
||
1733 | Set_BusA_To(2 downto 0) <= "100"; |
||
1734 | case to_integer(unsigned(IR(5 downto 4))) is |
||
1735 | when 0|1|2 => |
||
1736 | Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
||
1737 | when others => |
||
1738 | Set_BusB_To <= "1001"; |
||
1739 | end case; |
||
1740 | when others => |
||
1741 | end case; |
||
1742 | when "01101111" => |
||
1743 | -- RLD |
||
1744 | MCycles <= "100"; |
||
1745 | case to_integer(unsigned(MCycle)) is |
||
1746 | when 2 => |
||
1747 | NoRead <= '1'; |
||
1748 | Set_Addr_To <= aXY; |
||
1749 | when 3 => |
||
1750 | Read_To_Reg <= '1'; |
||
1751 | Set_BusB_To(2 downto 0) <= "110"; |
||
1752 | Set_BusA_To(2 downto 0) <= "111"; |
||
1753 | ALU_Op <= "1101"; |
||
1754 | TStates <= "100"; |
||
1755 | Set_Addr_To <= aXY; |
||
1756 | Save_ALU <= '1'; |
||
1757 | when 4 => |
||
1758 | I_RLD <= '1'; |
||
1759 | Write <= '1'; |
||
1760 | when others => |
||
1761 | end case; |
||
1762 | when "01100111" => |
||
1763 | -- RRD |
||
1764 | MCycles <= "100"; |
||
1765 | case to_integer(unsigned(MCycle)) is |
||
1766 | when 2 => |
||
1767 | Set_Addr_To <= aXY; |
||
1768 | when 3 => |
||
1769 | Read_To_Reg <= '1'; |
||
1770 | Set_BusB_To(2 downto 0) <= "110"; |
||
1771 | Set_BusA_To(2 downto 0) <= "111"; |
||
1772 | ALU_Op <= "1110"; |
||
1773 | TStates <= "100"; |
||
1774 | Set_Addr_To <= aXY; |
||
1775 | Save_ALU <= '1'; |
||
1776 | when 4 => |
||
1777 | I_RRD <= '1'; |
||
1778 | Write <= '1'; |
||
1779 | when others => |
||
1780 | end case; |
||
1781 | when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => |
||
1782 | -- RETI, RETN |
||
1783 | MCycles <= "011"; |
||
1784 | case to_integer(unsigned(MCycle)) is |
||
1785 | when 1 => |
||
1786 | Set_Addr_TO <= aSP; |
||
1787 | when 2 => |
||
1788 | IncDec_16 <= "0111"; |
||
1789 | Set_Addr_To <= aSP; |
||
1790 | LDZ <= '1'; |
||
1791 | when 3 => |
||
1792 | Jump <= '1'; |
||
1793 | IncDec_16 <= "0111"; |
||
1794 | I_RETN <= '1'; |
||
1795 | when others => null; |
||
1796 | end case; |
||
1797 | when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => |
||
1798 | -- IN r,(C) |
||
1799 | MCycles <= "010"; |
||
1800 | case to_integer(unsigned(MCycle)) is |
||
1801 | when 1 => |
||
1802 | Set_Addr_To <= aBC; |
||
1803 | when 2 => |
||
1804 | IORQ <= '1'; |
||
1805 | if IR(5 downto 3) /= "110" then |
||
1806 | Read_To_Reg <= '1'; |
||
1807 | Set_BusA_To(2 downto 0) <= IR(5 downto 3); |
||
1808 | end if; |
||
1809 | I_INRC <= '1'; |
||
1810 | when others => |
||
1811 | end case; |
||
1812 | when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => |
||
1813 | -- OUT (C),r |
||
1814 | -- OUT (C),0 |
||
1815 | MCycles <= "010"; |
||
1816 | case to_integer(unsigned(MCycle)) is |
||
1817 | when 1 => |
||
1818 | Set_Addr_To <= aBC; |
||
1819 | Set_BusB_To(2 downto 0) <= IR(5 downto 3); |
||
1820 | if IR(5 downto 3) = "110" then |
||
1821 | Set_BusB_To(3) <= '1'; |
||
1822 | end if; |
||
1823 | when 2 => |
||
1824 | Write <= '1'; |
||
1825 | IORQ <= '1'; |
||
1826 | when others => |
||
1827 | end case; |
||
1828 | when "10100010" | "10101010" | "10110010" | "10111010" => |
||
1829 | -- INI, IND, INIR, INDR |
||
1830 | -- note B is decremented AFTER being put on the bus |
||
1831 | MCycles <= "100"; |
||
1832 | case to_integer(unsigned(MCycle)) is |
||
1833 | when 1 => |
||
1834 | Set_Addr_To <= aBC; |
||
1835 | Set_BusB_To <= "1010"; |
||
1836 | Set_BusA_To <= "0000"; |
||
1837 | Read_To_Reg <= '1'; |
||
1838 | Save_ALU <= '1'; |
||
1839 | ALU_Op <= "0010"; |
||
1840 | when 2 => |
||
1841 | IORQ <= '1'; |
||
1842 | Set_BusB_To <= "0110"; |
||
1843 | Set_Addr_To <= aXY; |
||
1844 | when 3 => |
||
1845 | if IR(3) = '0' then |
||
1846 | --IncDec_16 <= "0010"; |
||
1847 | IncDec_16 <= "0110"; |
||
1848 | else |
||
1849 | --IncDec_16 <= "1010"; |
||
1850 | IncDec_16 <= "1110"; |
||
1851 | end if; |
||
1852 | TStates <= "100"; |
||
1853 | Write <= '1'; |
||
1854 | I_BTR <= '1'; |
||
1855 | when 4 => |
||
1856 | NoRead <= '1'; |
||
1857 | TStates <= "101"; |
||
1858 | when others => null; |
||
1859 | end case; |
||
1860 | when "10100011" | "10101011" | "10110011" | "10111011" => |
||
1861 | -- OUTI, OUTD, OTIR, OTDR |
||
1862 | -- note B is decremented BEFORE being put on the bus. |
||
1863 | -- mikej fix for hl inc |
||
1864 | MCycles <= "100"; |
||
1865 | case to_integer(unsigned(MCycle)) is |
||
1866 | when 1 => |
||
1867 | TStates <= "101"; |
||
1868 | Set_Addr_To <= aXY; |
||
1869 | Set_BusB_To <= "1010"; |
||
1870 | Set_BusA_To <= "0000"; |
||
1871 | Read_To_Reg <= '1'; |
||
1872 | Save_ALU <= '1'; |
||
1873 | ALU_Op <= "0010"; |
||
1874 | when 2 => |
||
1875 | Set_BusB_To <= "0110"; |
||
1876 | Set_Addr_To <= aBC; |
||
1877 | when 3 => |
||
1878 | if IR(3) = '0' then |
||
1879 | IncDec_16 <= "0110"; -- mikej |
||
1880 | else |
||
1881 | IncDec_16 <= "1110"; -- mikej |
||
1882 | end if; |
||
1883 | IORQ <= '1'; |
||
1884 | Write <= '1'; |
||
1885 | I_BTR <= '1'; |
||
1886 | when 4 => |
||
1887 | NoRead <= '1'; |
||
1888 | TStates <= "101"; |
||
1889 | when others => null; |
||
1890 | end case; |
||
1891 | end case; |
||
1892 | |||
1893 | end case; |
||
1894 | |||
1895 | if Mode = 1 then |
||
1896 | if MCycle = "001" then |
||
1897 | -- TStates <= "100"; |
||
1898 | else |
||
1899 | TStates <= "011"; |
||
1900 | end if; |
||
1901 | end if; |
||
1902 | |||
1903 | if Mode = 3 then |
||
1904 | if MCycle = "001" then |
||
1905 | -- TStates <= "100"; |
||
1906 | else |
||
1907 | TStates <= "100"; |
||
1908 | end if; |
||
1909 | end if; |
||
1910 | |||
1911 | if Mode < 2 then |
||
1912 | if MCycle = "110" then |
||
1913 | Inc_PC <= '1'; |
||
1914 | if Mode = 1 then |
||
1915 | Set_Addr_To <= aXY; |
||
1916 | TStates <= "100"; |
||
1917 | Set_BusB_To(2 downto 0) <= SSS; |
||
1918 | Set_BusB_To(3) <= '0'; |
||
1919 | end if; |
||
1920 | if IRB = "00110110" or IRB = "11001011" then |
||
1921 | Set_Addr_To <= aNone; |
||
1922 | end if; |
||
1923 | end if; |
||
1924 | if MCycle = "111" then |
||
1925 | if Mode = 0 then |
||
1926 | TStates <= "101"; |
||
1927 | end if; |
||
1928 | if ISet /= "01" then |
||
1929 | Set_Addr_To <= aXY; |
||
1930 | end if; |
||
1931 | Set_BusB_To(2 downto 0) <= SSS; |
||
1932 | Set_BusB_To(3) <= '0'; |
||
1933 | if IRB = "00110110" or ISet = "01" then |
||
1934 | -- LD (HL),n |
||
1935 | Inc_PC <= '1'; |
||
1936 | else |
||
1937 | NoRead <= '1'; |
||
1938 | end if; |
||
1939 | end if; |
||
1940 | end if; |
||
1941 | |||
1942 | end process; |
||
1943 | |||
1944 | end; |