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

Subversion Repositories z80soc

[/] [z80soc/] [tags/] [z80soc05b/] [rtl/] [VHDL/] [t80/] [T80.vhd] - Blame information for rev 33

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

Line No. Rev Author Line
1 2 rrred
--
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;

powered by: WebSVN 2.1.0

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