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

Subversion Repositories zx_ula

[/] [zx_ula/] [branches/] [xilinx/] [spectrum_48k_spartan3a_for_gameduino_mod_vga_timex_hicolor_ulaplus/] [T80.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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