398fa0dff71a28a767d5c0087d0880ac65d89686
[fpga-games] / galaxian / t80_ip / T80.vhd
1 --
2 -- Z80 compatible microprocessor core
3 --
4 -- Version : 0247
5 --
6 -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
7 --
8 -- All rights reserved
9 --
10 -- Redistribution and use in source and synthezised forms, with or without
11 -- modification, are permitted provided that the following conditions are met:
12 --
13 -- Redistributions of source code must retain the above copyright notice,
14 -- this list of conditions and the following disclaimer.
15 --
16 -- Redistributions in synthesized form must reproduce the above copyright
17 -- notice, this list of conditions and the following disclaimer in the
18 -- documentation and/or other materials provided with the distribution.
19 --
20 -- Neither the name of the author nor the names of other contributors may
21 -- be used to endorse or promote products derived from this software without
22 -- specific prior written permission.
23 --
24 -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26 -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
28 -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 -- POSSIBILITY OF SUCH DAMAGE.
35 --
36 -- Please report bugs to the author, but before you do so, please
37 -- make sure that this is not a derivative work and that
38 -- you have the latest version of this file.
39 --
40 -- The latest version of this file can be found at:
41 -- http://www.opencores.org/cvsweb.shtml/t80/
42 --
43 -- Limitations :
44 --
45 -- File history :
46 --
47 -- 0208 : First complete release
48 --
49 -- 0210 : Fixed wait and halt
50 --
51 -- 0211 : Fixed Refresh addition and IM 1
52 --
53 -- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
54 --
55 -- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
56 --
57 -- 0235 : Added clock enable and IM 2 fix by Mike Johnson
58 --
59 -- 0237 : Changed 8080 I/O address output, added IntE output
60 --
61 -- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
62 --
63 -- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
64 --
65 -- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
66 --
67 -- 0247 : Fixed bus req/ack cycle
68 --
69
70 library IEEE;
71 use IEEE.std_logic_1164.all;
72 use IEEE.numeric_std.all;
73 use work.T80_Pack.all;
74
75 entity T80 is
76 generic(
77 Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
78 IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
79 Flag_C : integer := 0;
80 Flag_N : integer := 1;
81 Flag_P : integer := 2;
82 Flag_X : integer := 3;
83 Flag_H : integer := 4;
84 Flag_Y : integer := 5;
85 Flag_Z : integer := 6;
86 Flag_S : integer := 7
87 );
88 port(
89 RESET_n : in std_logic;
90 CLK_n : in std_logic;
91 CEN : in std_logic;
92 WAIT_n : in std_logic;
93 INT_n : in std_logic;
94 NMI_n : in std_logic;
95 BUSRQ_n : in std_logic;
96 M1_n : out std_logic;
97 IORQ : out std_logic;
98 NoRead : out std_logic;
99 Write : out std_logic;
100 RFSH_n : out std_logic;
101 HALT_n : out std_logic;
102 BUSAK_n : out std_logic;
103 A : out std_logic_vector(15 downto 0);
104 DInst : in std_logic_vector(7 downto 0);
105 DI : in std_logic_vector(7 downto 0);
106 DO : out std_logic_vector(7 downto 0);
107 MC : out std_logic_vector(2 downto 0);
108 TS : out std_logic_vector(2 downto 0);
109 IntCycle_n : out std_logic;
110 IntE : out std_logic;
111 Stop : out std_logic
112 );
113 end T80;
114
115 architecture rtl of T80 is
116
117 constant aNone : std_logic_vector(2 downto 0) := "111";
118 constant aBC : std_logic_vector(2 downto 0) := "000";
119 constant aDE : std_logic_vector(2 downto 0) := "001";
120 constant aXY : std_logic_vector(2 downto 0) := "010";
121 constant aIOA : std_logic_vector(2 downto 0) := "100";
122 constant aSP : std_logic_vector(2 downto 0) := "101";
123 constant aZI : std_logic_vector(2 downto 0) := "110";
124
125 -- Registers
126 signal ACC, F : std_logic_vector(7 downto 0);
127 signal Ap, Fp : std_logic_vector(7 downto 0);
128 signal I : std_logic_vector(7 downto 0);
129 signal R : unsigned(7 downto 0);
130 signal SP, PC : unsigned(15 downto 0);
131 signal RegDIH : std_logic_vector(7 downto 0);
132 signal RegDIL : std_logic_vector(7 downto 0);
133 signal RegBusA : std_logic_vector(15 downto 0);
134 signal RegBusB : std_logic_vector(15 downto 0);
135 signal RegBusC : std_logic_vector(15 downto 0);
136 signal RegAddrA_r : std_logic_vector(2 downto 0);
137 signal RegAddrA : std_logic_vector(2 downto 0);
138 signal RegAddrB_r : std_logic_vector(2 downto 0);
139 signal RegAddrB : std_logic_vector(2 downto 0);
140 signal RegAddrC : std_logic_vector(2 downto 0);
141 signal RegWEH : std_logic;
142 signal RegWEL : std_logic;
143 signal Alternate : std_logic;
144
145 -- Help Registers
146 signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register
147 signal IR : std_logic_vector(7 downto 0); -- Instruction register
148 signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
149 signal RegBusA_r : std_logic_vector(15 downto 0);
150
151 signal ID16 : signed(15 downto 0);
152 signal Save_Mux : std_logic_vector(7 downto 0);
153
154 signal TState : unsigned(2 downto 0);
155 signal MCycle : std_logic_vector(2 downto 0);
156 signal IntE_FF1 : std_logic;
157 signal IntE_FF2 : std_logic;
158 signal Halt_FF : std_logic;
159 signal BusReq_s : std_logic;
160 signal BusAck : std_logic;
161 signal ClkEn : std_logic;
162 signal NMI_s : std_logic;
163 signal INT_s : std_logic;
164 signal IStatus : std_logic_vector(1 downto 0);
165
166 signal DI_Reg : std_logic_vector(7 downto 0);
167 signal T_Res : std_logic;
168 signal XY_State : std_logic_vector(1 downto 0);
169 signal Pre_XY_F_M : std_logic_vector(2 downto 0);
170 signal NextIs_XY_Fetch : std_logic;
171 signal XY_Ind : std_logic;
172 signal No_BTR : std_logic;
173 signal BTR_r : std_logic;
174 signal Auto_Wait : std_logic;
175 signal Auto_Wait_t1 : std_logic;
176 signal Auto_Wait_t2 : std_logic;
177 signal IncDecZ : std_logic;
178
179 -- ALU signals
180 signal BusB : std_logic_vector(7 downto 0);
181 signal BusA : std_logic_vector(7 downto 0);
182 signal ALU_Q : std_logic_vector(7 downto 0);
183 signal F_Out : std_logic_vector(7 downto 0);
184
185 -- Registered micro code outputs
186 signal Read_To_Reg_r : std_logic_vector(4 downto 0);
187 signal Arith16_r : std_logic;
188 signal Z16_r : std_logic;
189 signal ALU_Op_r : std_logic_vector(3 downto 0);
190 signal Save_ALU_r : std_logic;
191 signal PreserveC_r : std_logic;
192 signal MCycles : std_logic_vector(2 downto 0);
193
194 -- Micro code outputs
195 signal MCycles_d : std_logic_vector(2 downto 0);
196 signal TStates : std_logic_vector(2 downto 0);
197 signal IntCycle : std_logic;
198 signal NMICycle : std_logic;
199 signal Inc_PC : std_logic;
200 signal Inc_WZ : std_logic;
201 signal IncDec_16 : std_logic_vector(3 downto 0);
202 signal Prefix : std_logic_vector(1 downto 0);
203 signal Read_To_Acc : std_logic;
204 signal Read_To_Reg : std_logic;
205 signal Set_BusB_To : std_logic_vector(3 downto 0);
206 signal Set_BusA_To : std_logic_vector(3 downto 0);
207 signal ALU_Op : std_logic_vector(3 downto 0);
208 signal Save_ALU : std_logic;
209 signal PreserveC : std_logic;
210 signal Arith16 : std_logic;
211 signal Set_Addr_To : std_logic_vector(2 downto 0);
212 signal Jump : std_logic;
213 signal JumpE : std_logic;
214 signal JumpXY : std_logic;
215 signal Call : std_logic;
216 signal RstP : std_logic;
217 signal LDZ : std_logic;
218 signal LDW : std_logic;
219 signal LDSPHL : std_logic;
220 signal IORQ_i : std_logic;
221 signal Special_LD : std_logic_vector(2 downto 0);
222 signal ExchangeDH : std_logic;
223 signal ExchangeRp : std_logic;
224 signal ExchangeAF : std_logic;
225 signal ExchangeRS : std_logic;
226 signal I_DJNZ : std_logic;
227 signal I_CPL : std_logic;
228 signal I_CCF : std_logic;
229 signal I_SCF : std_logic;
230 signal I_RETN : std_logic;
231 signal I_BT : std_logic;
232 signal I_BC : std_logic;
233 signal I_BTR : std_logic;
234 signal I_RLD : std_logic;
235 signal I_RRD : std_logic;
236 signal I_INRC : std_logic;
237 signal SetDI : std_logic;
238 signal SetEI : std_logic;
239 signal IMode : std_logic_vector(1 downto 0);
240 signal Halt : std_logic;
241
242 begin
243
244 mcode : T80_MCode
245 generic map(
246 Mode => Mode,
247 Flag_C => Flag_C,
248 Flag_N => Flag_N,
249 Flag_P => Flag_P,
250 Flag_X => Flag_X,
251 Flag_H => Flag_H,
252 Flag_Y => Flag_Y,
253 Flag_Z => Flag_Z,
254 Flag_S => Flag_S)
255 port map(
256 IR => IR,
257 ISet => ISet,
258 MCycle => MCycle,
259 F => F,
260 NMICycle => NMICycle,
261 IntCycle => IntCycle,
262 MCycles => MCycles_d,
263 TStates => TStates,
264 Prefix => Prefix,
265 Inc_PC => Inc_PC,
266 Inc_WZ => Inc_WZ,
267 IncDec_16 => IncDec_16,
268 Read_To_Acc => Read_To_Acc,
269 Read_To_Reg => Read_To_Reg,
270 Set_BusB_To => Set_BusB_To,
271 Set_BusA_To => Set_BusA_To,
272 ALU_Op => ALU_Op,
273 Save_ALU => Save_ALU,
274 PreserveC => PreserveC,
275 Arith16 => Arith16,
276 Set_Addr_To => Set_Addr_To,
277 IORQ => IORQ_i,
278 Jump => Jump,
279 JumpE => JumpE,
280 JumpXY => JumpXY,
281 Call => Call,
282 RstP => RstP,
283 LDZ => LDZ,
284 LDW => LDW,
285 LDSPHL => LDSPHL,
286 Special_LD => Special_LD,
287 ExchangeDH => ExchangeDH,
288 ExchangeRp => ExchangeRp,
289 ExchangeAF => ExchangeAF,
290 ExchangeRS => ExchangeRS,
291 I_DJNZ => I_DJNZ,
292 I_CPL => I_CPL,
293 I_CCF => I_CCF,
294 I_SCF => I_SCF,
295 I_RETN => I_RETN,
296 I_BT => I_BT,
297 I_BC => I_BC,
298 I_BTR => I_BTR,
299 I_RLD => I_RLD,
300 I_RRD => I_RRD,
301 I_INRC => I_INRC,
302 SetDI => SetDI,
303 SetEI => SetEI,
304 IMode => IMode,
305 Halt => Halt,
306 NoRead => NoRead,
307 Write => Write);
308
309 alu : T80_ALU
310 generic map(
311 Mode => Mode,
312 Flag_C => Flag_C,
313 Flag_N => Flag_N,
314 Flag_P => Flag_P,
315 Flag_X => Flag_X,
316 Flag_H => Flag_H,
317 Flag_Y => Flag_Y,
318 Flag_Z => Flag_Z,
319 Flag_S => Flag_S)
320 port map(
321 Arith16 => Arith16_r,
322 Z16 => Z16_r,
323 ALU_Op => ALU_Op_r,
324 IR => IR(5 downto 0),
325 ISet => ISet,
326 BusA => BusA,
327 BusB => BusB,
328 F_In => F,
329 Q => ALU_Q,
330 F_Out => F_Out);
331
332 ClkEn <= CEN and not BusAck;
333
334 T_Res <= '1' when TState = unsigned(TStates) else '0';
335
336 NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and
337 ((Set_Addr_To = aXY) or
338 (MCycle = "001" and IR = "11001011") or
339 (MCycle = "001" and IR = "00110110")) else '0';
340
341 Save_Mux <= BusB when ExchangeRp = '1' else
342 DI_Reg when Save_ALU_r = '0' else
343 ALU_Q;
344
345 process (RESET_n, CLK_n)
346 begin
347 if RESET_n = '0' then
348 PC <= (others => '0'); -- Program Counter
349 A <= (others => '0');
350 TmpAddr <= (others => '0');
351 IR <= "00000000";
352 ISet <= "00";
353 XY_State <= "00";
354 IStatus <= "00";
355 MCycles <= "000";
356 DO <= "00000000";
357
358 ACC <= (others => '1');
359 F <= (others => '1');
360 Ap <= (others => '1');
361 Fp <= (others => '1');
362 I <= (others => '0');
363 R <= (others => '0');
364 SP <= (others => '1');
365 Alternate <= '0';
366
367 Read_To_Reg_r <= "00000";
368 F <= (others => '1');
369 Arith16_r <= '0';
370 BTR_r <= '0';
371 Z16_r <= '0';
372 ALU_Op_r <= "0000";
373 Save_ALU_r <= '0';
374 PreserveC_r <= '0';
375 XY_Ind <= '0';
376
377 elsif CLK_n'event and CLK_n = '1' then
378
379 if ClkEn = '1' then
380
381 ALU_Op_r <= "0000";
382 Save_ALU_r <= '0';
383 Read_To_Reg_r <= "00000";
384
385 MCycles <= MCycles_d;
386
387 if IMode /= "11" then
388 IStatus <= IMode;
389 end if;
390
391 Arith16_r <= Arith16;
392 PreserveC_r <= PreserveC;
393 if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
394 Z16_r <= '1';
395 else
396 Z16_r <= '0';
397 end if;
398
399 if MCycle = "001" and TState(2) = '0' then
400 -- MCycle = 1 and TState = 1, 2, or 3
401
402 if TState = 2 and Wait_n = '1' then
403 if Mode < 2 then
404 A(7 downto 0) <= std_logic_vector(R);
405 A(15 downto 8) <= I;
406 R(6 downto 0) <= R(6 downto 0) + 1;
407 end if;
408
409 if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then
410 PC <= PC + 1;
411 end if;
412
413 if IntCycle = '1' and IStatus = "01" then
414 IR <= "11111111";
415 elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then
416 IR <= "00000000";
417 else
418 IR <= DInst;
419 end if;
420
421 ISet <= "00";
422 if Prefix /= "00" then
423 if Prefix = "11" then
424 if IR(5) = '1' then
425 XY_State <= "10";
426 else
427 XY_State <= "01";
428 end if;
429 else
430 if Prefix = "10" then
431 XY_State <= "00";
432 XY_Ind <= '0';
433 end if;
434 ISet <= Prefix;
435 end if;
436 else
437 XY_State <= "00";
438 XY_Ind <= '0';
439 end if;
440 end if;
441
442 else
443 -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
444
445 if MCycle = "110" then
446 XY_Ind <= '1';
447 if Prefix = "01" then
448 ISet <= "01";
449 end if;
450 end if;
451
452 if T_Res = '1' then
453 BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
454 if Jump = '1' then
455 A(15 downto 8) <= DI_Reg;
456 A(7 downto 0) <= TmpAddr(7 downto 0);
457 PC(15 downto 8) <= unsigned(DI_Reg);
458 PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
459 elsif JumpXY = '1' then
460 A <= RegBusC;
461 PC <= unsigned(RegBusC);
462 elsif Call = '1' or RstP = '1' then
463 A <= TmpAddr;
464 PC <= unsigned(TmpAddr);
465 elsif MCycle = MCycles and NMICycle = '1' then
466 A <= "0000000001100110";
467 PC <= "0000000001100110";
468 elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
469 A(15 downto 8) <= I;
470 A(7 downto 0) <= TmpAddr(7 downto 0);
471 PC(15 downto 8) <= unsigned(I);
472 PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
473 else
474 case Set_Addr_To is
475 when aXY =>
476 if XY_State = "00" then
477 A <= RegBusC;
478 else
479 if NextIs_XY_Fetch = '1' then
480 A <= std_logic_vector(PC);
481 else
482 A <= TmpAddr;
483 end if;
484 end if;
485 when aIOA =>
486 if Mode = 3 then
487 -- Memory map I/O on GBZ80
488 A(15 downto 8) <= (others => '1');
489 elsif Mode = 2 then
490 -- Duplicate I/O address on 8080
491 A(15 downto 8) <= DI_Reg;
492 else
493 A(15 downto 8) <= ACC;
494 end if;
495 A(7 downto 0) <= DI_Reg;
496 when aSP =>
497 A <= std_logic_vector(SP);
498 when aBC =>
499 if Mode = 3 and IORQ_i = '1' then
500 -- Memory map I/O on GBZ80
501 A(15 downto 8) <= (others => '1');
502 A(7 downto 0) <= RegBusC(7 downto 0);
503 else
504 A <= RegBusC;
505 end if;
506 when aDE =>
507 A <= RegBusC;
508 when aZI =>
509 if Inc_WZ = '1' then
510 A <= std_logic_vector(unsigned(TmpAddr) + 1);
511 else
512 A(15 downto 8) <= DI_Reg;
513 A(7 downto 0) <= TmpAddr(7 downto 0);
514 end if;
515 when others =>
516 A <= std_logic_vector(PC);
517 end case;
518 end if;
519
520 Save_ALU_r <= Save_ALU;
521 ALU_Op_r <= ALU_Op;
522
523 if I_CPL = '1' then
524 -- CPL
525 ACC <= not ACC;
526 F(Flag_Y) <= not ACC(5);
527 F(Flag_H) <= '1';
528 F(Flag_X) <= not ACC(3);
529 F(Flag_N) <= '1';
530 end if;
531 if I_CCF = '1' then
532 -- CCF
533 F(Flag_C) <= not F(Flag_C);
534 F(Flag_Y) <= ACC(5);
535 F(Flag_H) <= F(Flag_C);
536 F(Flag_X) <= ACC(3);
537 F(Flag_N) <= '0';
538 end if;
539 if I_SCF = '1' then
540 -- SCF
541 F(Flag_C) <= '1';
542 F(Flag_Y) <= ACC(5);
543 F(Flag_H) <= '0';
544 F(Flag_X) <= ACC(3);
545 F(Flag_N) <= '0';
546 end if;
547 end if;
548
549 if TState = 2 and Wait_n = '1' then
550 if ISet = "01" and MCycle = "111" then
551 IR <= DInst;
552 end if;
553 if JumpE = '1' then
554 PC <= unsigned(signed(PC) + signed(DI_Reg));
555 elsif Inc_PC = '1' then
556 PC <= PC + 1;
557 end if;
558 if BTR_r = '1' then
559 PC <= PC - 2;
560 end if;
561 if RstP = '1' then
562 TmpAddr <= (others =>'0');
563 TmpAddr(5 downto 3) <= IR(5 downto 3);
564 end if;
565 end if;
566 if TState = 3 and MCycle = "110" then
567 TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
568 end if;
569
570 if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
571 if IncDec_16(2 downto 0) = "111" then
572 if IncDec_16(3) = '1' then
573 SP <= SP - 1;
574 else
575 SP <= SP + 1;
576 end if;
577 end if;
578 end if;
579
580 if LDSPHL = '1' then
581 SP <= unsigned(RegBusC);
582 end if;
583 if ExchangeAF = '1' then
584 Ap <= ACC;
585 ACC <= Ap;
586 Fp <= F;
587 F <= Fp;
588 end if;
589 if ExchangeRS = '1' then
590 Alternate <= not Alternate;
591 end if;
592 end if;
593
594 if TState = 3 then
595 if LDZ = '1' then
596 TmpAddr(7 downto 0) <= DI_Reg;
597 end if;
598 if LDW = '1' then
599 TmpAddr(15 downto 8) <= DI_Reg;
600 end if;
601
602 if Special_LD(2) = '1' then
603 case Special_LD(1 downto 0) is
604 when "00" =>
605 ACC <= I;
606 F(Flag_P) <= IntE_FF2;
607 when "01" =>
608 ACC <= std_logic_vector(R);
609 F(Flag_P) <= IntE_FF2;
610 when "10" =>
611 I <= ACC;
612 when others =>
613 R <= unsigned(ACC);
614 end case;
615 end if;
616 end if;
617
618 if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then
619 if Mode = 3 then
620 F(6) <= F_Out(6);
621 F(5) <= F_Out(5);
622 F(7) <= F_Out(7);
623 if PreserveC_r = '0' then
624 F(4) <= F_Out(4);
625 end if;
626 else
627 F(7 downto 1) <= F_Out(7 downto 1);
628 if PreserveC_r = '0' then
629 F(Flag_C) <= F_Out(0);
630 end if;
631 end if;
632 end if;
633 if T_Res = '1' and I_INRC = '1' then
634 F(Flag_H) <= '0';
635 F(Flag_N) <= '0';
636 if DI_Reg(7 downto 0) = "00000000" then
637 F(Flag_Z) <= '1';
638 else
639 F(Flag_Z) <= '0';
640 end if;
641 F(Flag_S) <= DI_Reg(7);
642 F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor
643 DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
644 end if;
645
646 if TState = 1 and Auto_Wait_t1 = '0' then
647 DO <= BusB;
648 if I_RLD = '1' then
649 DO(3 downto 0) <= BusA(3 downto 0);
650 DO(7 downto 4) <= BusB(3 downto 0);
651 end if;
652 if I_RRD = '1' then
653 DO(3 downto 0) <= BusB(7 downto 4);
654 DO(7 downto 4) <= BusA(3 downto 0);
655 end if;
656 end if;
657
658 if T_Res = '1' then
659 Read_To_Reg_r(3 downto 0) <= Set_BusA_To;
660 Read_To_Reg_r(4) <= Read_To_Reg;
661 if Read_To_Acc = '1' then
662 Read_To_Reg_r(3 downto 0) <= "0111";
663 Read_To_Reg_r(4) <= '1';
664 end if;
665 end if;
666
667 if TState = 1 and I_BT = '1' then
668 F(Flag_X) <= ALU_Q(3);
669 F(Flag_Y) <= ALU_Q(1);
670 F(Flag_H) <= '0';
671 F(Flag_N) <= '0';
672 end if;
673 if I_BC = '1' or I_BT = '1' then
674 F(Flag_P) <= IncDecZ;
675 end if;
676
677 if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
678 (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
679 case Read_To_Reg_r is
680 when "10111" =>
681 ACC <= Save_Mux;
682 when "10110" =>
683 DO <= Save_Mux;
684 when "11000" =>
685 SP(7 downto 0) <= unsigned(Save_Mux);
686 when "11001" =>
687 SP(15 downto 8) <= unsigned(Save_Mux);
688 when "11011" =>
689 F <= Save_Mux;
690 when others =>
691 end case;
692 end if;
693
694 end if;
695
696 end if;
697
698 end process;
699
700 ---------------------------------------------------------------------------
701 --
702 -- BC('), DE('), HL('), IX and IY
703 --
704 ---------------------------------------------------------------------------
705 process (CLK_n)
706 begin
707 if CLK_n'event and CLK_n = '1' then
708 if ClkEn = '1' then
709 -- Bus A / Write
710 RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
711 if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then
712 RegAddrA_r <= XY_State(1) & "11";
713 end if;
714
715 -- Bus B
716 RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1);
717 if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then
718 RegAddrB_r <= XY_State(1) & "11";
719 end if;
720
721 -- Address from register
722 RegAddrC <= Alternate & Set_Addr_To(1 downto 0);
723 -- Jump (HL), LD SP,HL
724 if (JumpXY = '1' or LDSPHL = '1') then
725 RegAddrC <= Alternate & "10";
726 end if;
727 if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then
728 RegAddrC <= XY_State(1) & "11";
729 end if;
730
731 if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then
732 IncDecZ <= F_Out(Flag_Z);
733 end if;
734 if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
735 if ID16 = 0 then
736 IncDecZ <= '0';
737 else
738 IncDecZ <= '1';
739 end if;
740 end if;
741
742 RegBusA_r <= RegBusA;
743 end if;
744 end if;
745 end process;
746
747 RegAddrA <=
748 -- 16 bit increment/decrement
749 Alternate & IncDec_16(1 downto 0) when (TState = 2 or
750 (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else
751 XY_State(1) & "11" when (TState = 2 or
752 (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
753 -- EX HL,DL
754 Alternate & "10" when ExchangeDH = '1' and TState = 3 else
755 Alternate & "01" when ExchangeDH = '1' and TState = 4 else
756 -- Bus A / Write
757 RegAddrA_r;
758
759 RegAddrB <=
760 -- EX HL,DL
761 Alternate & "01" when ExchangeDH = '1' and TState = 3 else
762 -- Bus B
763 RegAddrB_r;
764
765 ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
766 signed(RegBusA) + 1;
767
768 process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
769 ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
770 begin
771 RegWEH <= '0';
772 RegWEL <= '0';
773 if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
774 (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
775 case Read_To_Reg_r is
776 when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" =>
777 RegWEH <= not Read_To_Reg_r(0);
778 RegWEL <= Read_To_Reg_r(0);
779 when others =>
780 end case;
781 end if;
782
783 if ExchangeDH = '1' and (TState = 3 or TState = 4) then
784 RegWEH <= '1';
785 RegWEL <= '1';
786 end if;
787
788 if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
789 case IncDec_16(1 downto 0) is
790 when "00" | "01" | "10" =>
791 RegWEH <= '1';
792 RegWEL <= '1';
793 when others =>
794 end case;
795 end if;
796 end process;
797
798 process (Save_Mux, RegBusB, RegBusA_r, ID16,
799 ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
800 begin
801 RegDIH <= Save_Mux;
802 RegDIL <= Save_Mux;
803
804 if ExchangeDH = '1' and TState = 3 then
805 RegDIH <= RegBusB(15 downto 8);
806 RegDIL <= RegBusB(7 downto 0);
807 end if;
808 if ExchangeDH = '1' and TState = 4 then
809 RegDIH <= RegBusA_r(15 downto 8);
810 RegDIL <= RegBusA_r(7 downto 0);
811 end if;
812
813 if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
814 RegDIH <= std_logic_vector(ID16(15 downto 8));
815 RegDIL <= std_logic_vector(ID16(7 downto 0));
816 end if;
817 end process;
818
819 Regs : T80_Reg
820 port map(
821 Clk => CLK_n,
822 CEN => ClkEn,
823 WEH => RegWEH,
824 WEL => RegWEL,
825 AddrA => RegAddrA,
826 AddrB => RegAddrB,
827 AddrC => RegAddrC,
828 DIH => RegDIH,
829 DIL => RegDIL,
830 DOAH => RegBusA(15 downto 8),
831 DOAL => RegBusA(7 downto 0),
832 DOBH => RegBusB(15 downto 8),
833 DOBL => RegBusB(7 downto 0),
834 DOCH => RegBusC(15 downto 8),
835 DOCL => RegBusC(7 downto 0));
836
837 ---------------------------------------------------------------------------
838 --
839 -- Buses
840 --
841 ---------------------------------------------------------------------------
842 process (CLK_n)
843 begin
844 if CLK_n'event and CLK_n = '1' then
845 if ClkEn = '1' then
846 case Set_BusB_To is
847 when "0111" =>
848 BusB <= ACC;
849 when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
850 if Set_BusB_To(0) = '1' then
851 BusB <= RegBusB(7 downto 0);
852 else
853 BusB <= RegBusB(15 downto 8);
854 end if;
855 when "0110" =>
856 BusB <= DI_Reg;
857 when "1000" =>
858 BusB <= std_logic_vector(SP(7 downto 0));
859 when "1001" =>
860 BusB <= std_logic_vector(SP(15 downto 8));
861 when "1010" =>
862 BusB <= "00000001";
863 when "1011" =>
864 BusB <= F;
865 when "1100" =>
866 BusB <= std_logic_vector(PC(7 downto 0));
867 when "1101" =>
868 BusB <= std_logic_vector(PC(15 downto 8));
869 when "1110" =>
870 BusB <= "00000000";
871 when others =>
872 BusB <= "--------";
873 end case;
874
875 case Set_BusA_To is
876 when "0111" =>
877 BusA <= ACC;
878 when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
879 if Set_BusA_To(0) = '1' then
880 BusA <= RegBusA(7 downto 0);
881 else
882 BusA <= RegBusA(15 downto 8);
883 end if;
884 when "0110" =>
885 BusA <= DI_Reg;
886 when "1000" =>
887 BusA <= std_logic_vector(SP(7 downto 0));
888 when "1001" =>
889 BusA <= std_logic_vector(SP(15 downto 8));
890 when "1010" =>
891 BusA <= "00000000";
892 when others =>
893 BusB <= "--------";
894 end case;
895 end if;
896 end if;
897 end process;
898
899 ---------------------------------------------------------------------------
900 --
901 -- Generate external control signals
902 --
903 ---------------------------------------------------------------------------
904 process (RESET_n,CLK_n)
905 begin
906 if RESET_n = '0' then
907 RFSH_n <= '1';
908 elsif CLK_n'event and CLK_n = '1' then
909 if CEN = '1' then
910 if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
911 RFSH_n <= '0';
912 else
913 RFSH_n <= '1';
914 end if;
915 end if;
916 end if;
917 end process;
918
919 MC <= std_logic_vector(MCycle);
920 TS <= std_logic_vector(TState);
921 DI_Reg <= DI;
922 HALT_n <= not Halt_FF;
923 BUSAK_n <= not BusAck;
924 IntCycle_n <= not IntCycle;
925 IntE <= IntE_FF1;
926 IORQ <= IORQ_i;
927 Stop <= I_DJNZ;
928
929 -------------------------------------------------------------------------
930 --
931 -- Syncronise inputs
932 --
933 -------------------------------------------------------------------------
934 process (RESET_n, CLK_n)
935 variable OldNMI_n : std_logic;
936 begin
937 if RESET_n = '0' then
938 BusReq_s <= '0';
939 INT_s <= '0';
940 NMI_s <= '0';
941 OldNMI_n := '0';
942 elsif CLK_n'event and CLK_n = '1' then
943 if CEN = '1' then
944 BusReq_s <= not BUSRQ_n;
945 INT_s <= not INT_n;
946 if NMICycle = '1' then
947 NMI_s <= '0';
948 elsif NMI_n = '0' and OldNMI_n = '1' then
949 NMI_s <= '1';
950 end if;
951 OldNMI_n := NMI_n;
952 end if;
953 end if;
954 end process;
955
956 -------------------------------------------------------------------------
957 --
958 -- Main state machine
959 --
960 -------------------------------------------------------------------------
961 process (RESET_n, CLK_n)
962 begin
963 if RESET_n = '0' then
964 MCycle <= "001";
965 TState <= "000";
966 Pre_XY_F_M <= "000";
967 Halt_FF <= '0';
968 BusAck <= '0';
969 NMICycle <= '0';
970 IntCycle <= '0';
971 IntE_FF1 <= '0';
972 IntE_FF2 <= '0';
973 No_BTR <= '0';
974 Auto_Wait_t1 <= '0';
975 Auto_Wait_t2 <= '0';
976 M1_n <= '1';
977 elsif CLK_n'event and CLK_n = '1' then
978 if CEN = '1' then
979 if T_Res = '1' then
980 Auto_Wait_t1 <= '0';
981 else
982 Auto_Wait_t1 <= Auto_Wait or IORQ_i;
983 end if;
984 Auto_Wait_t2 <= Auto_Wait_t1;
985 No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
986 (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or
987 (I_BTR and (not IR(4) or F(Flag_Z)));
988 if TState = 2 then
989 if SetEI = '1' then
990 IntE_FF1 <= '1';
991 IntE_FF2 <= '1';
992 end if;
993 if I_RETN = '1' then
994 IntE_FF1 <= IntE_FF2;
995 end if;
996 end if;
997 if TState = 3 then
998 if SetDI = '1' then
999 IntE_FF1 <= '0';
1000 IntE_FF2 <= '0';
1001 end if;
1002 end if;
1003 if IntCycle = '1' or NMICycle = '1' then
1004 Halt_FF <= '0';
1005 end if;
1006 if MCycle = "001" and TState = 2 and Wait_n = '1' then
1007 M1_n <= '1';
1008 end if;
1009 if BusReq_s = '1' and BusAck = '1' then
1010 else
1011 BusAck <= '0';
1012 if TState = 2 and Wait_n = '0' then
1013 elsif T_Res = '1' then
1014 if Halt = '1' then
1015 Halt_FF <= '1';
1016 end if;
1017 if BusReq_s = '1' then
1018 BusAck <= '1';
1019 else
1020 TState <= "001";
1021 if NextIs_XY_Fetch = '1' then
1022 MCycle <= "110";
1023 Pre_XY_F_M <= MCycle;
1024 if IR = "00110110" and Mode = 0 then
1025 Pre_XY_F_M <= "010";
1026 end if;
1027 elsif (MCycle = "111") or
1028 (MCycle = "110" and Mode = 1 and ISet /= "01") then
1029 MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
1030 elsif (MCycle = MCycles) or
1031 No_BTR = '1' or
1032 (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
1033 M1_n <= '0';
1034 MCycle <= "001";
1035 IntCycle <= '0';
1036 NMICycle <= '0';
1037 if NMI_s = '1' and Prefix = "00" then
1038 NMICycle <= '1';
1039 IntE_FF1 <= '0';
1040 elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
1041 IntCycle <= '1';
1042 IntE_FF1 <= '0';
1043 IntE_FF2 <= '0';
1044 end if;
1045 else
1046 MCycle <= std_logic_vector(unsigned(MCycle) + 1);
1047 end if;
1048 end if;
1049 else
1050 if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor
1051 (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then
1052 TState <= TState + 1;
1053 end if;
1054 end if;
1055 end if;
1056 if TState = 0 then
1057 M1_n <= '0';
1058 end if;
1059 end if;
1060 end if;
1061 end process;
1062
1063 process (IntCycle, NMICycle, MCycle)
1064 begin
1065 Auto_Wait <= '0';
1066 if IntCycle = '1' or NMICycle = '1' then
1067 if MCycle = "001" then
1068 Auto_Wait <= '1';
1069 end if;
1070 end if;
1071 end process;
1072
1073 end;
Impressum, Datenschutz