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

Subversion Repositories t80

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

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

powered by: WebSVN 2.1.0

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