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

Subversion Repositories t80

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

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

powered by: WebSVN 2.1.0

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