]>
Commit | Line | Data |
---|---|---|
be8a9b96 MG |
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 | -- **** | |
782690d0 MG |
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: | |
be8a9b96 | 50 | -- http://www.opencores.org/cvsweb.shtml/t80/ |
782690d0 MG |
51 | -- |
52 | -- Limitations : | |
53 | -- | |
54 | -- File history : | |
55 | -- | |
be8a9b96 | 56 | -- 0208 : First complete release |
782690d0 | 57 | -- |
be8a9b96 | 58 | -- 0211 : Fixed IM 1 |
782690d0 | 59 | -- |
be8a9b96 | 60 | -- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test |
782690d0 | 61 | -- |
be8a9b96 | 62 | -- 0235 : Added IM 2 fix by Mike Johnson |
782690d0 | 63 | -- |
be8a9b96 | 64 | -- 0238 : Added NoRead signal |
782690d0 | 65 | -- |
be8a9b96 | 66 | -- 0238b: Fixed instruction timing for POP and DJNZ |
782690d0 | 67 | -- |
be8a9b96 MG |
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 | |
782690d0 | 71 | -- |
be8a9b96 | 72 | -- 0242 : Fixed I/O instruction timing, cleanup |
782690d0 MG |
73 | -- |
74 | ||
75 | library IEEE; | |
76 | use IEEE.std_logic_1164.all; | |
77 | use IEEE.numeric_std.all; | |
be8a9b96 | 78 | use work.T80_Pack.all; |
782690d0 MG |
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( | |
be8a9b96 MG |
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); | |
782690d0 | 110 | -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None |
be8a9b96 MG |
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 | |
782690d0 MG |
146 | ); |
147 | end T80_MCode; | |
148 | ||
149 | architecture rtl of T80_MCode is | |
150 | ||
be8a9b96 MG |
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"; | |
782690d0 MG |
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 | -- | |
be8a9b96 | 258 | -- Unprefixed instructions |
782690d0 MG |
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; | |
be8a9b96 | 932 | Set_BusB_To <= "0111"; |
782690d0 MG |
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; | |
be8a9b96 | 1186 | Set_BusB_To <= "0111"; |
782690d0 MG |
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"; | |
be8a9b96 | 1208 | Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! |
782690d0 MG |
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" => | |
be8a9b96 | 1223 | -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! |
782690d0 MG |
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; | |
be8a9b96 | 1308 | Set_BusB_To <= "0111"; |
782690d0 MG |
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 | -- | |
be8a9b96 | 1343 | -- CB prefixed instructions |
782690d0 MG |
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 | |
be8a9b96 MG |
1368 | ALU_Op <= "1000"; |
1369 | Read_To_Reg <= '1'; | |
1370 | Save_ALU <= '1'; | |
782690d0 MG |
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 | |
be8a9b96 MG |
1405 | Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
1406 | ALU_Op <= "1001"; | |
782690d0 MG |
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 | |
be8a9b96 | 1412 | when 1 | 7=> |
782690d0 MG |
1413 | Set_Addr_To <= aXY; |
1414 | when 2 => | |
1415 | ALU_Op <= "1001"; | |
1416 | TStates <= "100"; | |
be8a9b96 | 1417 | when others => null; |
782690d0 MG |
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 | |
be8a9b96 MG |
1429 | ALU_Op <= "1010"; |
1430 | Read_To_Reg <= '1'; | |
1431 | Save_ALU <= '1'; | |
782690d0 MG |
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 | |
be8a9b96 | 1437 | when 1 | 7=> |
782690d0 MG |
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'; | |
be8a9b96 | 1447 | when others => null; |
782690d0 MG |
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'; | |
be8a9b96 | 1477 | when others => null; |
782690d0 MG |
1478 | end case; |
1479 | end case; | |
1480 | ||
1481 | when others => | |
1482 | ||
1483 | ------------------------------------------------------------------------------ | |
1484 | -- | |
be8a9b96 | 1485 | -- ED prefixed instructions |
782690d0 MG |
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; | |
be8a9b96 | 1819 | Set_BusB_To(2 downto 0) <= IR(5 downto 3); |
782690d0 MG |
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 | |
be8a9b96 | 1830 | -- note B is decremented AFTER being put on the bus |
782690d0 MG |
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 | |
be8a9b96 MG |
1846 | --IncDec_16 <= "0010"; |
1847 | IncDec_16 <= "0110"; | |
782690d0 | 1848 | else |
be8a9b96 MG |
1849 | --IncDec_16 <= "1010"; |
1850 | IncDec_16 <= "1110"; | |
782690d0 MG |
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 | |
be8a9b96 MG |
1862 | -- note B is decremented BEFORE being put on the bus. |
1863 | -- mikej fix for hl inc | |
782690d0 MG |
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 | |
be8a9b96 | 1879 | IncDec_16 <= "0110"; -- mikej |
782690d0 | 1880 | else |
be8a9b96 | 1881 | IncDec_16 <= "1110"; -- mikej |
782690d0 MG |
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 | |
be8a9b96 | 1897 | -- TStates <= "100"; |
782690d0 MG |
1898 | else |
1899 | TStates <= "011"; | |
1900 | end if; | |
1901 | end if; | |
1902 | ||
1903 | if Mode = 3 then | |
1904 | if MCycle = "001" then | |
be8a9b96 | 1905 | -- TStates <= "100"; |
782690d0 MG |
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; |