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

Subversion Repositories t80

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

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

powered by: WebSVN 2.1.0

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