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