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

Subversion Repositories z80soc

[/] [z80soc/] [trunk/] [V0.6/] [S3E/] [T80.vhd] - Blame information for rev 40

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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