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

Subversion Repositories t80

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

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

powered by: WebSVN 2.1.0

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