OpenCores
URL https://opencores.org/ocsvn/t80/t80/trunk

Subversion Repositories t80

[/] [t80/] [trunk/] [rtl/] [vhdl/] [T80.vhd] - Blame information for rev 35

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.