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

Subversion Repositories nextz80

[/] [nextz80/] [trunk/] [NextZ80CPU.v] - Blame information for rev 7

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ndumitrach
//////////////////////////////////////////////////////////////////////////////////
2
//
3
// This file is part of the NextZ80 project
4
// http://www.opencores.org/cores/nextz80/
5
//
6
// Filename: NextZ80CPU.v
7
// Description: Implementation of Z80 compatible CPU
8
// Version 1.0
9
// Creation date: 28Jan2011 - 18Mar2011
10
//
11
// Author: Nicolae Dumitrache 
12
// e-mail: ndumitrache@opencores.org
13
//
14
/////////////////////////////////////////////////////////////////////////////////
15
// 
16
// Copyright (C) 2011 Nicolae Dumitrache
17
// 
18
// This source file may be used and distributed without 
19
// restriction provided that this copyright statement is not 
20
// removed from the file and that any derivative work contains 
21
// the original copyright notice and the associated disclaimer.
22
// 
23
// This source file is free software; you can redistribute it 
24
// and/or modify it under the terms of the GNU Lesser General 
25
// Public License as published by the Free Software Foundation;
26
// either version 2.1 of the License, or (at your option) any 
27
// later version. 
28
// 
29
// This source is distributed in the hope that it will be 
30
// useful, but WITHOUT ANY WARRANTY; without even the implied 
31
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
32
// PURPOSE. See the GNU Lesser General Public License for more 
33
// details. 
34
// 
35
// You should have received a copy of the GNU Lesser General 
36
// Public License along with this source; if not, download it 
37
// from http://www.opencores.org/lgpl.shtml 
38
// 
39
///////////////////////////////////////////////////////////////////////////////////
40
//
41
// Comments:
42
// This project was developed and tested on a XILINX Spartan3AN board.
43
//
44
//      NextZ80 processor features:
45
//              All documented/undocumented intstructions are implemented
46
//              All documented/undocumented flags are implemented
47
//              All (doc/undoc)flags are changed accordingly by all (doc/undoc)instructions. 
48
//                      The block instructions (LDx, CPx, INx, OUTx) have only the documented effects on flags. 
49
//                      The Bit n,(IX/IY+d) and BIT n,(HL) undocumented flags XF and YF are implemented like the BIT n,r and not actually like on the real Z80 CPU.
50
//              All interrupt modes implemented: NMI, IM0, IM1, IM2
51
//              R register available
52
//              Fast conditional jump/call/ret takes only 1 T state if not executed
53
//              Fast block instructions: LDxR - 3 T states/byte, INxR/OTxR - 2 T states/byte, CPxR - 4 T states / byte
54
//              Each CPU machine cycle takes (mainly) one clock T state. This makes this processor over 4 times faster than a Z80 at the same 
55
//                      clock frequency (some instructions are up to 10 times faster). 
56
//              Works at ~40MHZ on Spartan XC3S700AN speed grade -4)
57
//              Small size ( ~12%  ~700 slices - on Spartan XC3S700AN )
58
//              Tested with ZEXDOC (fully compliant).
59
//              Tested with ZEXALL (all OK except CPx(R), LDx(R), BIT n, (IX/IY+d), BIT n, (HL) - fail because of the un-documented XF and YF flags).
60
// 
61
///////////////////////////////////////////////////////////////////////////////////
62
`timescale 1ns / 1ps
63
 
64
module NextZ80
65
(
66
                input wire[7:0] DI,
67
                output wire[7:0] DO,
68
                output wire[15:0] ADDR,
69
                output reg WR,
70
                output reg MREQ,
71
                output reg IORQ,
72
                output reg HALT,
73
                output reg M1,
74
                input wire CLK,
75
                input wire RESET,
76
                input wire INT,
77
                input wire NMI,
78
                input   wire WAIT
79
);
80
 
81
// connections and registers
82
        reg     [9:0] CPUStatus = 0;      // 0=AF-AF', 1=HL-HL', 2=DE-HL, 3=DE'-HL', 4=HL-X, 5=IX-IY, 6=IFF1,7=IFF2, 9:8=IMODE
83
        wire    [7:0] ALU8FLAGS;
84
        wire    [7:0]    FLAGS;
85
        wire    [7:0] ALU80;
86
        wire    [7:0] ALU81;
87
        wire    [15:0]ALU160;
88
        wire    [7:0] ALU161;
89
        wire    [15:0]ALU8OUT;
90
 
91
        reg     [9:0]    FETCH = 0;
92
        reg     [2:0]    STAGE = 0;
93
        wire    [5:0]    opd;
94
        wire    [2:0] op16;
95
        wire    op0mem = FETCH[2:0] == 6;
96
        wire    op1mem = FETCH[5:3] == 6;
97
        reg     [1:0]fetch98;
98
 
99
// stage status
100
        reg     [1:0]DO_SEL;                     // ALU80 - th - flags - ALU8OUT[7:0]
101
        reg     ALU160_SEL;                             // regs - pc
102
        reg     DINW_SEL;                               // ALU8OUT - DI
103
        reg     [5:0]WE;                                 // 5 = flags, 4 = PC, 3 = SP, 2 = tmpHI, 1 = hi, 0 = lo
104
        reg     [4:0] ALU8OP;
105
        reg     [2:0] ALU16OP;
106
        reg     next_stage;
107
        reg     [3:0]REG_WSEL;
108
        reg     [3:0]REG_RSEL;
109
        reg     [11:0]status;                    // 0=AF-AF', 1=HL-HL', 2=DE-HL, 3=DE'-HL', 4=HL-X, 5=IX-IY, 7:6=IFFVAL, 9:8=imode, 10=setIMODE, 11=set IFFVAL
110
// FETCH[5:3]: 000 NZ, 001 Z, 010 NC, 011 C, 100 PO, 101 PE, 110 P, 111 M
111
        wire    [7:0]FlagMux = {FLAGS[7], !FLAGS[7], FLAGS[2], !FLAGS[2], FLAGS[0], !FLAGS[0], FLAGS[6], !FLAGS[6]};
112
        reg     tzf;
113
        reg     FNMI = 0, SNMI = 0;
114
        reg     SRESET = 0;
115
        reg     SINT = 0;
116
        wire    [2:0]intop = FETCH[1] ? 4 : (FETCH[0] ? 5 : 6);
117
        reg     xmask;
118
 
119
        Z80Reg CPU_REGS (
120
                 .rstatus(CPUStatus[7:0]),
121
                 .M1(M1),
122
                 .WE(WE),
123
                 .CLK(CLK),
124
                 .ALU8OUT(ALU8OUT),
125
                 .DI(DI),
126
                 .DO(DO),
127
                 .ADDR(ADDR),
128
                 .CONST(FETCH[7] ? {2'b00, FETCH[5:3], 3'b000} : 8'h66),        // RST/NMI address
129
                 .ALU80(ALU80),
130
                 .ALU81(ALU81),
131
                 .ALU160(ALU160),
132
                 .ALU161(ALU161),
133
                 .ALU8FLAGS(ALU8FLAGS),
134
                 .FLAGS(FLAGS),
135
                 .DO_SEL(DO_SEL),
136
                 .ALU160_sel(ALU160_SEL),
137
                 .REG_WSEL(REG_WSEL),
138
                 .REG_RSEL(REG_RSEL),
139
                 .DINW_SEL(DINW_SEL),
140
                 .XMASK(xmask),
141
                 .ALU16OP(ALU16OP),                     // used for post increment for ADDR, SP mux re-direct
142
                 .WAIT(WAIT)
143
                 );
144
 
145
        ALU8 CPU_ALU8 (
146
                 .D0(ALU80),
147
                 .D1(ALU81),
148
                 .FIN(FLAGS),
149
                 .FOUT(ALU8FLAGS),
150
                 .ALU8DOUT(ALU8OUT),
151
                 .OP(ALU8OP),
152
                 .EXOP(FETCH[8:3]),
153
                 .LDIFLAGS(REG_WSEL[2]),        // inc16 HL
154
                 .DSTHI(!REG_WSEL[0])
155
                 );
156
 
157
        ALU16 CPU_ALU16 (
158
                 .D0(ALU160),
159
                 .D1(ALU161),
160
                 .DOUT(ADDR),
161
                 .OP(ALU16OP)
162
                 );
163
 
164
        always @(posedge CLK)
165
                if(!WAIT) begin
166
                        SRESET <= RESET;
167
                        SNMI <= NMI;
168
                        SINT <= INT;
169
                        if(!SNMI) FNMI <= 0;
170
                        if(SRESET) FETCH <= 10'b1110000000;
171
                        else
172
                                if(FETCH[9:6] == 4'b1110) {FETCH[9:7]} <= 3'b000;       // exit RESET state
173
                                else begin
174
                                        if(M1)
175
                                                case({MREQ, CPUStatus[9:8]})
176
                                                        3'b000, 3'b001, 3'b100, 3'b101, 3'b110, 3'b111: FETCH <= {fetch98, DI};
177
                                                        3'b010: FETCH <= {fetch98, 8'hff};      // IM1 - RST38
178
                                                        3'b011: ; // IM2 - get addrLO
179
                                                endcase
180
                                        if(~|{next_stage, fetch98[1:0], status[4]})                              // INT or NMI sample
181
                                                if(SNMI & !FNMI) begin                                          // NMI posedge
182
                                                        {FETCH[9:6], FETCH[1:0]} <= {4'b1101, HALT, M1};
183
                                                        FNMI <= 1;      // NMI acknowledged
184
                                                end else if(SINT & CPUStatus[6] & !status[11]) {FETCH[9:6], FETCH[1:0]} <= {4'b1100, HALT, M1};  // INT request
185
                                end
186
                        if(next_stage) STAGE <= STAGE + 3'b001;
187
                        else STAGE <= 0;
188
                        if(status[4]) CPUStatus[5:4] <= status[5:4];
189
                        else if(~|{next_stage, fetch98[1]} | fetch98[0]) CPUStatus[4] <= 1'b0;           // clear X
190
                        CPUStatus[3:0] <= CPUStatus[3:0] ^ status[3:0];
191
                        if(status[11]) CPUStatus[7:6] <= status[7:6];   // IFF2:1
192
                        if(status[10]) CPUStatus[9:8] <= status[9:8];   // IMM
193
                        tzf <= ALU8FLAGS[6];
194
                end
195
 
196
        assign opd[0] = FETCH[0] ^ &FETCH[2:1];
197
        assign opd[2:1] = FETCH[2:1];
198
        assign opd[3] = FETCH[3] ^ &FETCH[5:4];
199
        assign opd[5:4] = FETCH[5:4];
200
        assign op16[2:0] = &FETCH[5:4] ? 3'b101 : {1'b0, FETCH[5:4]};
201
 
202
        always @* begin
203
                DO_SEL  = 2'bxx;                                                // ALU80 - th - flags - ALU8OUT[7:0]
204
                ALU160_SEL = 1'bx;                                      // regs - pc
205
                DINW_SEL = 1'bx;                                                // ALU8OUT - DI
206
                WE              = 6'bxxxxxx;                            // 5 = flags, 4 = PC, 3 = SP, 2 = tmpHI, 1 = hi, 0 = lo
207
                ALU8OP  = 5'bxxxxx;
208
                ALU16OP = 3'b000;                                       // NOP, post inc
209
                next_stage = 0;
210
                REG_WSEL        = 4'bxxxx;
211
                REG_RSEL        = 4'bxxxx;
212
                M1              = 1;
213
                MREQ            = 1;
214
                WR                      = 0;
215
 
216
                HALT = 0;
217
                IORQ = 0;
218
                status  = 12'b00xxxxx00000;
219
                fetch98 = 2'b00;
220
 
221
                case({FETCH[7:6], op1mem, op0mem})
222
                        4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b1000, 4'b1100: xmask = 1;
223
                        default: xmask = 0;
224
                endcase
225
 
226
                case(FETCH[9:6])
227
//------------------------------------------- block 00 ----------------------------------------------------
228
                        4'b0000:
229
                                case(FETCH[3:0])
230
//                              -----------------------         NOP, EX AF, AF', DJNZ, JR, JR c --------------------
231
                                        4'b0000, 4'b1000:
232
                                                case(FETCH[5:4])
233
                                                        2'b00: begin                                    // NOP, EX AF, AF'
234
                                                                DO_SEL  = 2'bxx;
235
                                                                ALU160_SEL = 1;                 // PC
236
                                                                WE              = 6'b010x00;    // PC
237
                                                                status[0] = FETCH[3];
238
                                                        end
239
                                                        2'b01:
240
                                                                if(!STAGE[0]) begin              // DJNZ, JR - stage1
241
                                                                        ALU160_SEL = 1;                         // pc
242
                                                                        WE              = 6'b010100;            // PC, tmpHI
243
                                                                        if(!FETCH[3]) begin
244
                                                                                ALU8OP  = 5'b01010;                     // DEC, for tzf only
245
                                                                                REG_WSEL        = 4'b0000;                      // B
246
                                                                        end
247
                                                                        next_stage = 1;
248
                                                                        M1              = 0;
249
                                                                end else if(FETCH[3]) begin     // JR - stage2
250
                                                                        ALU160_SEL = 1;                         // pc
251
                                                                        WE              = 6'b010x00;            // PC
252
                                                                        ALU16OP = 3;                                    // ADD
253
                                                                end else begin                          // DJNZ - stage2
254
                                                                        ALU160_SEL = 1;                         // pc
255
                                                                        DINW_SEL = 0;                                    // ALU8OUT
256
                                                                        WE              = 6'b010x10;            // PC, hi
257
                                                                        ALU8OP  = 5'b01010;                     // DEC
258
                                                                        ALU16OP = tzf ? 3'd0 : 3'd3;            // NOP/ADD
259
                                                                        REG_WSEL        = 4'b0000;                      // B
260
                                                                end
261
                                                        2'b10, 2'b11:                                                   // JR cc, stage1, stage2
262
                                                                case({STAGE[0], FlagMux[{1'b0, FETCH[4:3]}]})
263
                                                                        2'b00, 2'b11: begin
264
                                                                                ALU160_SEL = 1;                         // pc
265
                                                                                WE              = 6'b010x00;            // PC
266
                                                                                ALU16OP = STAGE[0] ? 3'd3 : 3'd1;                // ADD/ INC, post inc
267
                                                                        end
268
                                                                        2'b01: begin
269
                                                                                ALU160_SEL = 1;                         // pc
270
                                                                                WE              = 6'b010100;            // PC, tmpHI
271
                                                                                next_stage = 1;
272
                                                                                M1              = 0;
273
                                                                        end
274
                                                                endcase
275
                                                endcase
276
//                              -----------------------         LD rr,nn  --------------------
277
                                        4'b0001:                        // LD rr,nn, stage1
278
                                                case({STAGE[1:0], op16[2]})
279
                                                        3'b00_0, 3'b00_1, 3'b01_0, 3'b01_1: begin                       // LD rr,nn, stage1,2
280
                                                                ALU160_SEL = 1;                 // pc
281
                                                                DINW_SEL = 1;                           // DI
282
                                                                WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};   // PC, lo/HI
283
                                                                next_stage = 1;
284
                                                                REG_WSEL        = {op16, 1'bx};
285
                                                                M1              = 0;
286
                                                        end
287
                                                        3'b10_0, 3'b11_1: begin         // BC, DE, HL, stage3, SP stage4
288
                                                                ALU160_SEL = 1;                 // pc
289
                                                                WE              = 6'b010x00;    // PC
290
                                                        end
291
                                                        3'b10_1: begin                          // SP stage3
292
                                                                ALU160_SEL = 0;                  // regs
293
                                                                WE              = 6'b001x00;    // SP
294
                                                                ALU16OP = 4;                            // NOP
295
                                                                next_stage = 1;
296
                                                                REG_RSEL        = 4'b101x;              // tmpSP
297
                                                                M1              = 0;
298
                                                                MREQ            = 0;
299
                                                        end
300
                                                endcase
301
//                              -----------------------         LD (BC) A -  LD (DE) A - LD (nn) HL, LD (nn),A   --------------------
302
//                              -----------------------         LD A (BC) -  LD A (DE) - LD HL (nn), LD A (nn)   --------------------
303
                                        4'b0010,        4'b1010:
304
                                                case(STAGE[2:0])
305
                                                        3'b000:
306
                                                                if(FETCH[5] == 0) begin                  // LD (BC) A, LD (DE) A - stage1
307
                                                                        if(FETCH[3]) DINW_SEL = 1;              // DI
308
                                                                        else DO_SEL     = 2'b00;                                // ALU80
309
                                                                        ALU160_SEL = 0;                          // regs
310
                                                                        WE              = {4'b000x, FETCH[3], 1'bx};            // hi
311
                                                                        next_stage = 1;
312
                                                                        REG_WSEL        = FETCH[3] ? 4'b011x : 4'b0110; // A
313
                                                                        REG_RSEL        = {op16, 1'bx};
314
                                                                        M1              = 0;
315
                                                                        WR = !FETCH[3];
316
                                                                end else begin                                          // LD (nn) A - LD (nn) HL - stage 1
317
                                                                        ALU160_SEL = 1;                         // PC
318
                                                                        DINW_SEL = 1;                                   // DI
319
                                                                        WE              = 6'b010xx1;            // PC, lo
320
                                                                        next_stage = 1;
321
                                                                        REG_WSEL        = 4'b111x;
322
                                                                        M1              = 0;
323
                                                                end
324
                                                        3'b001:
325
                                                                if(FETCH[5] == 0) begin                  // LD (BC), A, LD (DE), A - stage2
326
                                                                        ALU160_SEL = 1;                         // pc
327
                                                                        WE              = 6'b010x00;            // PC
328
                                                                end else begin                                          // LD (nn),A  - LH (nn),HL - stage 2
329
                                                                        ALU160_SEL = 1;                         // pc
330
                                                                        DINW_SEL = 1;                                   // DI
331
                                                                        WE              = 6'b010x10;            // PC, hi
332
                                                                        next_stage = 1;
333
                                                                        REG_WSEL        = 4'b111x;
334
                                                                        M1              = 0;
335
                                                                end
336
                                                        3'b010: begin
337
                                                                ALU160_SEL = 1'b0;              // regs
338
                                                                REG_RSEL        = 4'b111x;
339
                                                                M1              = 0;
340
                                                                WR                      = !FETCH[3];
341
                                                                next_stage = 1;
342
                                                                if(FETCH[3]) begin              // LD A (nn)  - LD HL (nn) - stage 3
343
                                                                        DINW_SEL = 1;                           // DI
344
                                                                        WE              = {4'b000x, FETCH[4] ? 1'b1 : 1'bx, FETCH[4] ? 1'bx : 1'b1};    // lo/hi
345
                                                                        REG_WSEL = FETCH[4] ? 4'b011x : 4'b010x;        // A or L
346
                                                                end else begin                          // LD (nn),A  - LD (nn),HL - stage 3
347
                                                                        DO_SEL  = 2'b00;                        // ALU80
348
                                                                        WE              = 6'b000x00;    // nothing
349
                                                                        REG_WSEL = FETCH[4] ? 4'b0110 : 4'b0101;        // A or L
350
                                                                end
351
                                                        end
352
                                                        3'b011:
353
                                                                if(FETCH[4]) begin                      // LD (nn),A - stage 4
354
                                                                        ALU160_SEL = 1;                 // pc
355
                                                                        WE              = 6'b010x00;    // PC
356
                                                                end else begin
357
                                                                        REG_RSEL        = 4'b111x;
358
                                                                        M1              = 0;
359
                                                                        WR                      = !FETCH[3];
360
                                                                        ALU160_SEL = 1'b0;              // regs
361
                                                                        ALU16OP = 1;                            // INC
362
                                                                        next_stage = 1;
363
                                                                        if(FETCH[3]) begin      // LD HL (nn) - stage 4
364
                                                                                DINW_SEL = 1;                           // DI
365
                                                                                WE              = 6'b000x10;    // hi
366
                                                                                REG_WSEL = 4'b010x;             // H
367
                                                                        end else begin                  // LD (nn),HL - stage 4
368
                                                                                DO_SEL  = 2'b00;                        // ALU80
369
                                                                                WE              = 6'b000x00;    // nothing
370
                                                                                REG_WSEL = 4'b0100;             // H
371
                                                                        end
372
                                                                end
373
                                                        3'b100: begin                           // LD (nn),HL - stage 5
374
                                                                ALU160_SEL = 1;                 // pc
375
                                                                WE              = 6'b010x00;    // PC
376
                                                        end
377
                                                endcase
378
//                              -----------------------         inc/dec rr   --------------------
379
                                        4'b0011, 4'b1011:
380
                                                if(!STAGE[0])
381
                                                        if(op16[2]) begin                               // SP - stage1
382
                                                                ALU160_SEL = 0;                  // regs
383
                                                                WE              = 6'b001x00;    // SP
384
                                                                ALU16OP = {FETCH[3], 1'b0, FETCH[3]};           // post inc, dec
385
                                                                next_stage = 1;
386
                                                                REG_RSEL        = 4'b101x;              // sp
387
                                                                M1              = 0;
388
                                                                MREQ            = 0;
389
                                                        end else begin                                  // BC, DE, HL - stage 1
390
                                                                ALU160_SEL = 1;                 // pc
391
                                                                DINW_SEL = 0;                            // ALU8OUT
392
                                                                WE              = 6'b010x11;    // PC, hi, lo
393
                                                                ALU8OP  = {4'b0111, FETCH[3]};                  // INC16 / DEC16
394
                                                                REG_WSEL        = {op16, 1'b0}; // hi
395
                                                                REG_RSEL        = {op16, 1'b1}; // lo
396
                                                        end
397
                                                else    begin                           // SP, stage2
398
                                                        ALU160_SEL = 1;                 // pc
399
                                                        WE              = 6'b010x00;    // PC
400
                                                end
401
//                              -----------------------         inc/dec 8  --------------------
402
                                        4'b0100, 4'b0101, 4'b1100, 4'b1101:
403
                                                if(!op1mem) begin                                               //regs
404
                                                        DINW_SEL = 0;                                            // ALU8OUT
405
                                                        ALU160_SEL = 1;                                 // pc
406
                                                        WE              = opd[3] ? 6'b110x01 : 6'b110x10;       // flags, PC, hi/lo
407
                                                        ALU8OP  = {3'b010, FETCH[0], 1'b0};              // inc / dec
408
                                                        REG_WSEL        = {1'b0, opd[5:3]};
409
                                                end else case({STAGE[1:0], CPUStatus[4]})
410
                                                        3'b00_0, 3'b01_1: begin                         // (HL) - stage1, (X) - stage2
411
                                                                ALU160_SEL = 0;                                  // regs
412
                                                                DINW_SEL = 1;                                           // DI
413
                                                                WE              = 6'b000001;                    // lo
414
                                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;
415
                                                                next_stage = 1;
416
                                                                REG_WSEL        = 4'b011x;                              // tmpLO
417
                                                                REG_RSEL        = 4'b010x;                              // HL
418
                                                                M1              = 0;
419
                                                        end
420
                                                        3'b00_1:        begin                                                   // (X) - stage1
421
                                                                ALU160_SEL = 1;                                 // pc
422
                                                                WE              = 6'b010100;                    // PC, tmpHI
423
                                                                next_stage = 1;
424
                                                                M1              = 0;
425
                                                        end
426
                                                        3'b01_0, 3'b10_1: begin                                 // (HL) stage2, (X) - stage3
427
                                                                DO_SEL  = 2'b11;                                                // ALU80OUT
428
                                                                ALU160_SEL = 0;                                          // regs
429
                                                                WE              = 6'b100x0x;                            // flags
430
                                                                ALU8OP  = {3'b010, FETCH[0], 1'b0};              // inc / dec
431
                                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;
432
                                                                next_stage = 1;
433
                                                                REG_WSEL        = 4'b0111;                                      // tmpLO
434
                                                                REG_RSEL        = 4'b010x;                                      // HL
435
                                                                M1              = 0;
436
                                                                WR                      = 1;
437
                                                        end
438
                                                        3'b10_0, 3'b11_1: begin                                 // (HL) - stage3, (X) - stage 4
439
                                                                ALU160_SEL = 1;                                         // pc
440
                                                                WE              = 6'b010x00;                            // PC
441
                                                        end
442
                                                endcase
443
//                              -----------------------         ld r/(HL-X), n  --------------------                                            
444
                                        4'b0110, 4'b1110:
445
                                                case({STAGE[1:0], CPUStatus[4], op1mem})
446
                                                        4'b00_0_0, 4'b00_0_1, 4'b00_1_0, 4'b01_1_1: begin               // r, (HL) - stage1, (X) - stage2 (read n)
447
                                                                ALU160_SEL = 1;                                 // pc
448
                                                                DINW_SEL = 1;                                           // DI
449
                                                                WE              = opd[3] ? 6'b010001 : 6'b010010;                       // PC, hi/lo
450
                                                                next_stage = 1;
451
                                                                REG_WSEL        = {1'b0, opd[5:4], 1'bx};
452
                                                                M1              = 0;
453
                                                        end
454
                                                        4'b01_0_0, 4'b01_1_0, 4'b10_0_1, 4'b11_1_1: begin               // r - stage2, (HL) - stage3, (X) - stage4
455
                                                                ALU160_SEL = 1;                                         // pc
456
                                                                WE              = 6'b010x00;                            // PC
457
                                                        end
458
                                                        4'b01_0_1, 4'b10_1_1: begin                     // (HL) - stage2, (X) - stage3
459
                                                                DO_SEL  = 2'b00;                                                // ALU80
460
                                                                ALU160_SEL = 0;                                          // regs
461
                                                                WE              = 6'b000x0x;                            // nothing
462
                                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;
463
                                                                next_stage = 1;
464
                                                                REG_WSEL        = 4'b0111;                                      // tmpLO
465
                                                                REG_RSEL        = 4'b010x;                                      // HL
466
                                                                M1              = 0;
467
                                                                WR                      = 1;
468
                                                        end
469
                                                        4'b00_1_1: begin                                                        // (X) - stage1
470
                                                                ALU160_SEL = 1;                                         // pc
471
                                                                WE              = 6'b010100;                            // PC, tmpHI
472
                                                                next_stage = 1;
473
                                                                M1              = 0;
474
                                                        end
475
                                                endcase
476
//                              -----------------------         rlca, rrca, rla, rra, daa, cpl, scf, ccf  --------------------                                          
477
                                        4'b0111, 4'b1111:
478
                                                case(FETCH[5:3])
479
                                                        3'b000, 3'b001, 3'b010, 3'b011, 3'b100, 3'b101: begin           // rlca, rrca, rla, rra, daa, cpl
480
                                                                ALU160_SEL = 1;                                 // pc
481
                                                                DINW_SEL = 0;                                            // ALU8OUT
482
                                                                WE              = 6'b110x1x;                    // flags, PC, hi
483
                                                                ALU8OP  = FETCH[5] ? {2'b01, !FETCH[3], 2'b01} : {3'b110, FETCH[4:3]};
484
                                                                REG_WSEL        = 4'b0110;                              // A
485
                                                        end
486
                                                        3'b110, 3'b111: begin                           // scf, ccf
487
                                                                ALU160_SEL = 1;                                 // pc
488
                                                                DINW_SEL = 0;                                            // ALU8OUT
489
                                                                WE              = 6'b110x0x;                    // flags, PC
490
                                                                ALU8OP  = {4'b1010, !FETCH[3]};
491
                                                        end
492
                                                endcase
493
//                              -----------------------         add 16  --------------------                                            
494
                                        4'b1001:
495
                                                if(!STAGE[0]) begin
496
                                                        DINW_SEL = 0;                                            // ALU8OUT
497
                                                        WE              = 6'b100x01;                    // flags, lo
498
                                                        ALU8OP  = 5'b10000;                             // ADD16LO
499
                                                        next_stage = 1;
500
                                                        REG_WSEL        = 4'b0101;                              // L
501
                                                        REG_RSEL        = {op16, 1'b1};
502
                                                        M1              = 0;
503
                                                        MREQ            = 0;
504
                                                end else begin
505
                                                        ALU160_SEL = 1;                                 // pc
506
                                                        DINW_SEL = 0;                                            // ALU8OUT
507
                                                        WE              = 6'b110x10;                    // flags, PC, hi
508
                                                        ALU8OP  = 5'b10001;                             // ADD16HI
509
                                                        REG_WSEL        = 4'b0100;                              // H
510
                                                        REG_RSEL        = {op16, 1'b0};
511
                                                end
512
                                endcase
513
 
514
// ---------------------------------------------- block 01 LD8 ---------------------------------------------------
515
                        4'b0001:
516
                                case({STAGE[1:0], CPUStatus[4], op1mem, op0mem})
517
                                        5'b00_0_00, 5'b00_1_00,         // LD r, r 1st stage
518
                                        5'b01_0_01,                                             // LD r, (HL) 2nd stage
519
                                        5'b10_1_01:                                             // LD r, (X) 3rd stage
520
                                        begin
521
                                                ALU160_SEL = 1;                 // PC
522
                                                DINW_SEL          = 0;                   // ALU8
523
                                                WE = opd[3] ? 6'b010x01 : 6'b010x10;    // PC and LO or HI
524
                                                ALU8OP = 29;                            // PASS D1
525
                                                REG_WSEL = {1'b0, opd[5:4], 1'bx};
526
                                                REG_RSEL = {1'b0, opd[2:0]};
527
                                        end
528
                                        5'b00_0_01,                                             // LD r, (HL) 1st stage
529
                                        5'b01_1_01:                                             // LD r, (X) 2nd stage
530
                                        begin
531
                                                ALU160_SEL = 0;                  // regs
532
                                                DINW_SEL = 1;                           // DI           
533
                                                WE              = 6'b000x01;    // LO
534
                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;           // ADD - NOP
535
                                                next_stage = 1;
536
                                                REG_WSEL        = 4'b011x;              // A - tmpLO
537
                                                REG_RSEL = 4'b010x;             // HL
538
                                                M1 = 0;
539
                                        end
540
                                        5'b00_1_01,                                             // LD r, (X) 1st stage
541
                                        5'b00_1_10:                                             // LD (X), r 1st stage
542
                                        begin
543
                                                ALU160_SEL = 1;                 // pc
544
                                                WE              = 6'b010100;    // PC, tmpHI
545
                                                next_stage = 1;
546
                                                M1              = 0;
547
                                        end
548
                                        5'b00_0_10,                                     // LD (HL), r 1st stage
549
                                        5'b01_1_10:                                             // LD (X), r 2nd stage
550
                                        begin
551
                                                DO_SEL  = 0;                             // ALU80
552
                                                ALU160_SEL = 0;                  // regs
553
                                                WE              = 6'b000x00;    // no write
554
                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;                   // ADD - NOP
555
                                                next_stage = 1;
556
                                                REG_WSEL        = {1'b0, opd[2:0]};
557
                                                REG_RSEL        = 4'b010x;              // HL
558
                                                M1              = 0;
559
                                                WR                      = 1;
560
                                        end
561
                                        5'b01_0_10,                                     // LD (HL), r 2nd stage
562
                                        5'b10_1_10:                                             // LD (X), r 3rd stage
563
                                        begin
564
                                                ALU160_SEL = 1;                 // pc
565
                                                WE              = 6'b010x00;    // PC
566
                                        end
567
                                        5'b00_0_11, 5'b00_1_11: begin   // HALT
568
                                                WE              = 6'b000x00;    // no write
569
                                                M1              = 0;
570
                                                MREQ            = 0;
571
                                                HALT            = 1;
572
                                        end
573
                                endcase
574
// ---------------------------------------------- block 10 arith8 ---------------------------------------------------
575
                        4'b0010:
576
                                case({STAGE[1:0], CPUStatus[4], op0mem})
577
                                        4'b00_0_0, 4'b00_1_0,           // OP r,r 1st stage
578
                                        4'b01_0_1,                                              // OP r, (HL) 2nd stage
579
                                        4'b10_1_1:                                              // OP r, (X) 3rd stage
580
                                        begin
581
                                                ALU160_SEL = 1;                 // pc
582
                                                DINW_SEL = 0;                            // ALU8OUT
583
                                                WE              = {4'b110x, ~&FETCH[5:3], 1'bx};        // flags, PC, hi
584
                                                ALU8OP  = {2'b00, FETCH[5:3]};
585
                                                REG_WSEL        = 4'b0110;              // A
586
                                                REG_RSEL        = {1'b0, opd[2:0]};
587
                                        end
588
                                        4'b00_0_1,                                              // OP r, (HL) 1st stage
589
                                        4'b01_1_1:                                              // OP r, (X) 2nd stage
590
                                        begin
591
                                                ALU160_SEL = 0;                  // HL
592
                                                DINW_SEL = 1;                           // DI
593
                                                WE              = 6'b000x01;    // lo
594
                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;                   // ADD - NOP
595
                                                next_stage = 1;
596
                                                REG_WSEL        = 4'b011x;              // A-tmpLO
597
                                                REG_RSEL        = 4'b010x;              // HL
598
                                                M1              = 0;
599
                                        end
600
                                        4'b00_1_1:                                              // OP r, (X) 1st stage
601
                                        begin
602
                                                ALU160_SEL = 1;                 // pc
603
                                                WE              = 6'b010100;    // PC, tmpHI
604
                                                next_stage = 1;
605
                                                M1              = 0;
606
                                        end
607
                                endcase
608
//------------------------------------------- block 11 ----------------------------------------------------
609
                        4'b0011:
610
                                case(FETCH[3:0])
611
//                              -----------------------         RET cc --------------------
612
                                        4'b0000, 4'b1000:
613
                                                case(STAGE[1:0])
614
                                                        2'b00, 2'b01:                   // stage1, stage2
615
                                                                if(FlagMux[FETCH[5:3]]) begin   // POP addr
616
                                                                        ALU160_SEL = 0;                          // regs
617
                                                                        DINW_SEL = 1;                                   // DI
618
                                                                        WE              = {4'b001x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // SP, lo/hi
619
                                                                        next_stage = 1;
620
                                                                        REG_WSEL        = 4'b111x;                      // tmp16
621
                                                                        REG_RSEL        = 4'b101x;                      // SP
622
                                                                        M1              = 0;
623
                                                                end else begin
624
                                                                        ALU160_SEL = 1;                         // pc
625
                                                                        WE              = 6'b010x00;            // PC
626
                                                                end
627
                                                        2'b10: begin                    // stage3
628
                                                                ALU160_SEL = 0;                                  // regs
629
                                                                WE              = 6'b010x00;                    // PC
630
                                                                REG_RSEL        = 4'b111x;                              // tmp16
631
                                                        end
632
                                                endcase
633
//                              -----------------------         POP --------------------
634
                                        4'b0001:
635
                                                case(STAGE[1:0])
636
                                                        2'b00, 2'b01: begin
637
                                                                if(op16[2]) begin       // AF
638
                                                                        WE              = STAGE[0] ? 6'b101x1x : 6'b001xx1;              // flags, SP, lo/hi
639
                                                                        REG_WSEL        = {3'b011, STAGE[0] ? 1'b1 : 1'bx};
640
                                                                        if(STAGE[0]) ALU8OP      = 30;                                           // FLAGS <- D0
641
                                                                end else begin          // r16
642
                                                                        WE              = STAGE[0] ? 6'b001x10 : 6'b001xx1;              // SP, lo/hi
643
                                                                        REG_WSEL        = {1'b0, FETCH[5:4], 1'bx};
644
                                                                end
645
                                                                ALU160_SEL = 0;                  // regs
646
                                                                DINW_SEL = 1;                           // DI
647
                                                                next_stage = 1;
648
                                                                REG_RSEL        = 4'b101x;              // SP
649
                                                                M1              = 0;
650
                                                        end
651
                                                        2'b10: begin                                    // stage3
652
                                                                ALU160_SEL = 1;                 // PC
653
                                                                WE              = 6'b010x00;    // PC
654
                                                        end
655
                                                endcase
656
//                              -----------------------         JP cc --------------------
657
                                        4'b0010, 4'b1010:
658
                                                case(STAGE[1:0])
659
                                                        2'b00, 2'b01:   begin                           // stage1,2
660
                                                                if(FlagMux[FETCH[5:3]]) begin
661
                                                                        ALU160_SEL = 1;                                 // pc
662
                                                                        DINW_SEL = 1;                                           // DI
663
                                                                        WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // PC, hi/lo
664
                                                                        next_stage = 1;
665
                                                                        REG_WSEL        = 4'b111x;                              // tmp7
666
                                                                        M1              = 0;
667
                                                                end else begin
668
                                                                        ALU160_SEL = 1;                                 // pc
669
                                                                        WE              = 6'b010x00;                    // PC
670
                                                                        ALU16OP = 2;                                            // add2
671
                                                                end
672
                                                        end
673
                                                        2'b10: begin                                            // stage3
674
                                                                ALU160_SEL = 0;                                  // regs
675
                                                                WE              = 6'b010x00;                    // PC
676
                                                                REG_RSEL        = 4'b111x;                              // tmp7
677
                                                        end
678
                                                endcase
679
//                              -----------------------         JP, OUT (n) A, EX (SP) HL, DI --------------------
680
                                        4'b0011:
681
                                                case(FETCH[5:4])
682
                                                        2'b00:                                  // JP
683
                                                                case(STAGE[1:0])
684
                                                                        2'b00, 2'b01:   begin                           // stage1,2 - read addr
685
                                                                                ALU160_SEL = 1;                                 // pc
686
                                                                                DINW_SEL = 1;                                           // DI
687
                                                                                WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // PC, hi/lo
688
                                                                                next_stage = 1;
689
                                                                                REG_WSEL        = 4'b111x;                              // tmp7
690
                                                                                M1              = 0;
691
                                                                        end
692
                                                                        2'b10: begin                                            // stage3
693
                                                                                ALU160_SEL = 0;                                  // regs
694
                                                                                WE              = 6'b010x00;                    // PC
695
                                                                                REG_RSEL        = 4'b111x;                              // tmp7
696
                                                                        end
697
                                                                endcase
698
                                                        2'b01:                                  // OUT (n), a - stage1 - read n
699
                                                                case(STAGE[1:0])
700
                                                                        2'b00: begin
701
                                                                                ALU160_SEL = 1;                                 // pc
702
                                                                                DINW_SEL = 1;                                           // DI
703
                                                                                WE              = 6'b010x01;                    // PC, lo
704
                                                                                next_stage = 1;
705
                                                                                REG_WSEL        = 4'b011x;                              // tmpLO
706
                                                                                M1              = 0;
707
                                                                        end
708
                                                                        2'b01: begin            // stage2 - OUT
709
                                                                                DO_SEL  = 2'b00;                                        // ALU80
710
                                                                                ALU160_SEL = 0;                                  // regs
711
                                                                                WE              = 6'b000x00;                    // nothing
712
                                                                                next_stage = 1;
713
                                                                                REG_WSEL        = 4'b0110;                              // A
714
                                                                                REG_RSEL        = 4'b011x;                              // A-tmpLO
715
                                                                                M1              = 0;
716
                                                                                MREQ            = 0;
717
                                                                                WR              = 1;
718
                                                                                IORQ            = 1;
719
                                                                        end
720
                                                                        2'b10: begin            // stage3 - fetch
721
                                                                                ALU160_SEL = 1;                 // PC
722
                                                                                WE              = 6'b010x00;    // PC
723
                                                                        end
724
                                                                endcase
725
                                                        2'b10:                          // EX (SP), HL
726
                                                                case(STAGE[2:0])
727
                                                                        3'b000, 3'b001: begin                   // stage1,2 - pop tmp16
728
                                                                                ALU160_SEL = 0;                                  // regs
729
                                                                                DINW_SEL = 1;                                           // DI
730
                                                                                WE              = {4'b001x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};                   // SP, lo/hi
731
                                                                                next_stage = 1;
732
                                                                                REG_WSEL        = 4'b111x;                              // tmp16
733
                                                                                REG_RSEL        = 4'b101x;                              // SP
734
                                                                                M1              = 0;
735
                                                                        end
736
                                                                        3'b010, 3'b011: begin                   // stage3,4 - push hl
737
                                                                                DO_SEL  = 2'b00;                                        // ALU80
738
                                                                                ALU160_SEL = 0;                                  // regs
739
                                                                                WE              = 6'b001x00;                    // SP
740
                                                                                ALU16OP = 5;                                            // dec
741
                                                                                next_stage = 1;
742
                                                                                REG_WSEL        = {3'b010, STAGE[0]};// H/L      
743
                                                                                REG_RSEL        = 4'b101x;                              // SP
744
                                                                                M1              = 0;
745
                                                                                WR                      = 1;
746
                                                                        end
747
                                                                        3'b100, 3'b101: begin           // stage5,6
748
                                                                                ALU160_SEL = 1;                                 // pc
749
                                                                                DINW_SEL = 0;                                            // ALU8OUT
750
                                                                                WE              = {1'b0, STAGE[0], 2'b0x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};      // PC, lo/hi
751
                                                                                ALU8OP  = 29;           // pass D1
752
                                                                                next_stage = !STAGE[0];
753
                                                                                REG_WSEL        = 4'b010x;              // HL
754
                                                                                REG_RSEL        = {3'b111, !STAGE[0]};           // tmp16
755
                                                                                M1              = STAGE[0];
756
                                                                                MREQ            = STAGE[0];
757
                                                                        end
758
                                                                endcase
759
                                                        2'b11:  begin                   // DI
760
                                                                ALU160_SEL = 1;                 // PC
761
                                                                WE              = 6'b010x00;    // PC
762
                                                                status[11] = 1'b1;              // set IFF flags
763
                                                                status[7:6] = 2'b00;
764
                                                        end
765
                                                endcase
766
//                              -----------------------         CALL cc --------------------
767
                                        4'b0100, 4'b1100:
768
                                                case(STAGE[2:0])
769
                                                        3'b000, 3'b001:         // stage 1,2 - load addr
770
                                                                if(FlagMux[FETCH[5:3]]) begin
771
                                                                        ALU160_SEL = 1;                                 // pc
772
                                                                        DINW_SEL = 1;                                           // DI
773
                                                                        WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // PC, hi/lo
774
                                                                        next_stage = 1;
775
                                                                        REG_WSEL        = 4'b111x;                              // tmp7
776
                                                                        M1              = 0;
777
                                                                end else begin
778
                                                                        ALU160_SEL = 1;                                 // pc
779
                                                                        WE              = 6'b010x00;                    // PC
780
                                                                        ALU16OP = 2;                                            // add2
781
                                                                end
782
                                                        3'b010, 3'b011: begin           // stage 3,4 - push pc
783
                                                                DO_SEL  = {1'b0, STAGE[0]};      // pc hi/lo
784
                                                                ALU160_SEL = 0;                                  // regs
785
                                                                WE              = 6'b001x00;                    // SP
786
                                                                ALU16OP = 5;                                            // DEC
787
                                                                next_stage = 1;
788
                                                                REG_WSEL        = 4'b1xxx;                              // pc
789
                                                                REG_RSEL        = 4'b101x;                              // sp
790
                                                                M1              = 0;
791
                                                                WR                      = 1;
792
                                                        end
793
                                                        3'b100: begin   // stage5
794
                                                                ALU160_SEL = 0;                                  // regs
795
                                                                WE              = 6'b010x00;                    // PC
796
                                                                REG_RSEL        = 4'b111x;                              // tmp7
797
                                                        end
798
                                                endcase
799
//                              -----------------------         PUSH --------------------
800
                                        4'b0101:
801
                                                case(STAGE[1:0])
802
                                                        2'b00, 2'b01: begin                     // stage1,2
803
                                                                DO_SEL  = {STAGE[0] & op16[2], 1'b0};            // FLAGS/ALU80
804
                                                                ALU160_SEL = 0;                          // regs
805
                                                                WE              = 6'b001x00;            // SP
806
                                                                ALU16OP = 5;                            // dec
807
                                                                next_stage = 1;
808
                                                                REG_WSEL        = {1'b0, FETCH[5:4], STAGE[0]};
809
                                                                REG_RSEL        = 4'b101x;                              // SP
810
                                                                M1              = 0;
811
                                                                WR                      = 1;
812
                                                        end
813
                                                        2'b10: begin                                    //stage3
814
                                                                ALU160_SEL = 1;                         // PC
815
                                                                WE              = 6'b010x00;            // PC
816
                                                        end
817
                                                endcase
818
//                              -----------------------         op A, n  --------------------
819
                                        4'b0110, 4'b1110:
820
                                                if(!STAGE[0]) begin                      // stage1, read n
821
                                                        ALU160_SEL = 1;                                 // pc
822
                                                        DINW_SEL = 1;                                           // DI
823
                                                        WE              = 6'b010x01;                    // PC, lo
824
                                                        next_stage = 1;
825
                                                        REG_WSEL        = 4'b011x;                              // tmpLO
826
                                                        M1              = 0;
827
                                                end else begin                                  // stage 2
828
                                                        DINW_SEL = 0;                                            // ALU8OUT[7:0]
829
                                                        ALU160_SEL = 1;                                 // pc
830
                                                        WE              = {4'b110x, ~&FETCH[5:3], 1'bx};                        // flags, PC, hi
831
                                                        ALU8OP  = {2'b00, FETCH[5:3]};
832
                                                        REG_WSEL        = 4'b0110;                              // A
833
                                                        REG_RSEL        = 4'b0111;                              // tmpLO
834
                                                end
835
//                              -----------------------         RST  --------------------
836
                                        4'b0111, 4'b1111:
837
                                                case(STAGE[1:0])
838
                                                        2'b00, 2'b01: begin             // stage 1,2 - push pc
839
                                                                DO_SEL  = {1'b0, STAGE[0]};      // pc hi/lo
840
                                                                ALU160_SEL = 0;                                  // regs
841
                                                                WE              = 6'b001x00;                    // SP
842
                                                                ALU16OP = 5;                                            // DEC
843
                                                                next_stage = 1;
844
                                                                REG_WSEL        = 4'b1xxx;                              // pc
845
                                                                REG_RSEL        = 4'b101x;                              // sp
846
                                                                M1              = 0;
847
                                                                WR                      = 1;
848
                                                        end
849
                                                        2'b10:  begin                           // stage3
850
                                                                ALU160_SEL = 0;                                  // regs
851
                                                                WE              = 6'b010x00;                    // PC
852
                                                                REG_RSEL        = 4'b110x;                              // const
853
                                                        end
854
                                                endcase
855
//                              -----------------------         RET, EXX, JP (HL), LD SP HL --------------------
856
                                        4'b1001:
857
                                                case(FETCH[5:4])
858
                                                        2'b00:                          // RET
859
                                                                case(STAGE[1:0])
860
                                                                        2'b00, 2'b01:   begin           // stage1, stage2 - pop addr
861
                                                                                ALU160_SEL = 0;                          // regs
862
                                                                                DINW_SEL = 1;                                   // DI
863
                                                                                WE              = {4'b001x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // SP, lo/hi
864
                                                                                next_stage = 1;
865
                                                                                REG_WSEL        = 4'b111x;                      // tmp16
866
                                                                                REG_RSEL        = 4'b101x;                      // SP
867
                                                                                M1              = 0;
868
                                                                        end
869
                                                                        2'b10: begin                    // stage3 - jump
870
                                                                                ALU160_SEL = 0;                                  // regs
871
                                                                                WE              = 6'b010x00;                    // PC
872
                                                                                REG_RSEL        = 4'b111x;                              // tmp16
873
                                                                        end
874
                                                                endcase
875
                                                        2'b01: begin                    // EXX
876
                                                                ALU160_SEL = 1;                 // PC
877
                                                                WE              = 6'b010x00;    // PC
878
                                                                status[1] = 1;
879
                                                        end
880
                                                        2'b10:  begin           // JP (HL)
881
                                                                ALU160_SEL = 0;                                  // regs
882
                                                                WE              = 6'b010x00;                    // PC
883
                                                                REG_RSEL        = 4'b010x;                              // HL
884
                                                        end
885
                                                        2'b11: begin    // LD SP,HL     
886
                                                                if(!STAGE[0]) begin                      // stage1
887
                                                                        ALU160_SEL = 0;                          // regs
888
                                                                        WE              = 6'b001x00;            // SP
889
                                                                        ALU16OP = 4;                                    // NOP, no post inc
890
                                                                        next_stage = 1;
891
                                                                        REG_RSEL        = 4'b010x;                      // HL
892
                                                                        M1              = 0;
893
                                                                        MREQ            = 0;
894
                                                                end else begin                                          // stage2
895
                                                                        ALU160_SEL = 1;                         // pc
896
                                                                        WE              = 6'b010x00;            // PC
897
                                                                end
898
                                                        end
899
                                                endcase
900
//                              -----------------------         CB, IN A (n), EX DE HL, EI --------------------
901
                                        4'b1011:
902
                                                case(FETCH[5:4])
903
                                                        2'b00:                                          // CB prefix
904
                                                                case({STAGE[0], CPUStatus[4]})
905
                                                                        2'b00, 2'b11: begin
906
                                                                                ALU160_SEL = 1;                 // PC
907
                                                                                WE              = 6'b010000;    // PC
908
                                                                                fetch98 = 2'b10;
909
                                                                        end
910
                                                                        2'b01: begin
911
                                                                                ALU160_SEL = 1;                 // PC
912
                                                                                WE              = 6'b010100;    // PC, tmpHI
913
                                                                                next_stage = 1;
914
                                                                                M1              = 0;
915
                                                                        end
916
                                                                endcase
917
                                                        2'b01:                                  // IN A, (n)
918
                                                                case(STAGE[1:0])
919
                                                                        2'b00: begin            //stage1 - read n
920
                                                                                ALU160_SEL = 1;                         // pc
921
                                                                                DINW_SEL = 1;                                   // DI
922
                                                                                WE              = 6'b010x01;            // PC, lo
923
                                                                                next_stage = 1;
924
                                                                                REG_WSEL        = 4'b011x;                      // tmpLO
925
                                                                                M1              = 0;
926
                                                                        end
927
                                                                        2'b01: begin            // stage2 - IN
928
                                                                                ALU160_SEL = 0;                          // regs
929
                                                                                DINW_SEL = 1;                                   // DI
930
                                                                                WE              = 6'b000x1x;            // hi
931
                                                                                next_stage = 1;
932
                                                                                REG_WSEL        = 4'b011x;                      // A
933
                                                                                REG_RSEL        = 4'b011x;                      // A - tmpLO
934
                                                                                M1              = 0;
935
                                                                                MREQ            = 0;
936
                                                                                IORQ            = 1;
937
                                                                        end
938
                                                                        2'b10: begin            // stage3 - fetch
939
                                                                                ALU160_SEL = 1;                 // PC
940
                                                                                WE              = 6'b010x00;    // PC
941
                                                                        end
942
                                                                endcase
943
                                                        2'b10: begin                    // EX DE, HL
944
                                                                ALU160_SEL = 1;                 // PC
945
                                                                WE              = 6'b010x00;    // PC
946
                                                                if(CPUStatus[1]) status[3] = 1;
947
                                                                else status[2] = 1;
948
                                                        end
949
                                                        2'b11: begin                    // EI
950
                                                                ALU160_SEL = 1;                 // PC
951
                                                                WE              = 6'b010x00;    // PC
952
                                                                status[11] = 1'b1;
953
                                                                status[7:6] = 2'b11;
954
                                                        end
955
                                                endcase
956
//                              -----------------------         CALL , IX, ED, IY --------------------
957
                                        4'b1101:
958
                                                case(FETCH[5:4])
959
                                                        2'b00:                                  // CALL
960
                                                                case(STAGE[2:0])
961
                                                                        3'b000, 3'b001: begin           // stage 1,2 - load addr
962
                                                                                ALU160_SEL = 1;                                 // pc
963
                                                                                DINW_SEL = 1;                                           // DI
964
                                                                                WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // PC, hi/lo
965
                                                                                next_stage = 1;
966
                                                                                REG_WSEL        = 4'b111x;                              // tmp7
967
                                                                                M1              = 0;
968
                                                                        end
969
                                                                        3'b010, 3'b011: begin           // stage 3,4 - push pc
970
                                                                                DO_SEL  = {1'b0, STAGE[0]};      // pc hi/lo
971
                                                                                ALU160_SEL = 0;                                  // regs
972
                                                                                WE              = 6'b001x00;                    // SP
973
                                                                                ALU16OP = 5;                                            // DEC
974
                                                                                next_stage = 1;
975
                                                                                REG_WSEL        = 4'b1xxx;                              // pc
976
                                                                                REG_RSEL        = 4'b101x;                              // sp
977
                                                                                M1              = 0;
978
                                                                                WR                      = 1;
979
                                                                        end
980
                                                                        3'b100: begin   // stage5 - jump
981
                                                                                ALU160_SEL = 0;                                  // regs
982
                                                                                WE              = 6'b010x00;                    // PC
983
                                                                                REG_RSEL        = 4'b111x;                              // tmp7
984
                                                                        end
985
                                                                endcase
986
                                                        2'b01: begin                    // DD - IX
987
                                                                ALU160_SEL = 1;                 // PC
988
                                                                WE              = 6'b010x00;    // PC
989
                                                                status[5:4] = 2'b01;
990
                                                        end
991
                                                        2'b10: begin                    // ED prefix
992
                                                                ALU160_SEL = 1;                 // PC
993
                                                                WE              = 6'b010x00;    // PC
994
                                                                fetch98 = 2'b01;
995
                                                        end
996
                                                        2'b11:  begin                   // FD - IY
997
                                                                ALU160_SEL = 1;                 // PC
998
                                                                WE              = 6'b010x00;    // PC
999
                                                                status[5:4]     = 2'b11;
1000
                                                        end
1001
                                                endcase
1002
                                endcase
1003
 
1004
//      ------------------------------------------- ED + opcode ----------------------------------------------------
1005
                        4'b0100, 4'b0111: begin         // ED + 2'b00, ED + 2'b11               = NOP
1006
                                ALU160_SEL = 1;                 // PC
1007
                                WE              = 6'b010x00;    // PC
1008
                        end
1009
                        4'b0101:
1010
                                case(FETCH[2:0])
1011
//                              -----------------------         in r (C)  --------------------
1012
                                        3'b000:
1013
                                                if(!STAGE[0]) begin
1014
                                                        ALU160_SEL = 0;                                  // regs
1015
                                                        DINW_SEL = 1;                                           // DI
1016
                                                        WE              = {4'b000x, !opd[3], opd[3]} ;  // hi/lo
1017
                                                        next_stage = 1;
1018
                                                        REG_WSEL        = {1'b0, opd[5:4], 1'bx};
1019
                                                        REG_RSEL        = 4'b000x;                              // BC
1020
                                                        M1              = 0;
1021
                                                        MREQ            = 0;
1022
                                                        IORQ            = 1;
1023
                                                end else begin
1024
                                                        ALU160_SEL = 1;                                 // pc
1025
                                                        WE              = 6'b110x00;                    // flags, PC
1026
                                                        ALU8OP  = 29;                                           // IN
1027
                                                        REG_RSEL        = {1'b0, opd[5:3]};     // reg
1028
                                                end
1029
//                              -----------------------         out (C) r  --------------------
1030
                                        3'b001:
1031
                                                if(!STAGE[0]) begin
1032
                                                        DO_SEL  = 2'b00;                                        // ALU80
1033
                                                        ALU160_SEL = 0;                                  // regs
1034
                                                        WE              = 6'b000x00;                    // nothing
1035
                                                        next_stage = 1;
1036
                                                        REG_WSEL        = &opd[5:3] ? 4'b110x : {1'b0, opd[5:3]}; // zero/reg
1037
                                                        REG_RSEL        = 4'b000x;                              // BC
1038
                                                        M1              = 0;
1039
                                                        MREQ            = 0;
1040
                                                        WR                      = 1;
1041
                                                        IORQ            = 1;
1042
                                                end else begin
1043
                                                        ALU160_SEL = 1;                                 // pc
1044
                                                        WE              = 6'b010x00;                    // PC
1045
                                                end
1046
//                              -----------------------         SBC16, ADC16  --------------------
1047
                                        3'b010:
1048
                                                if(!STAGE[0]) begin                      // stage1
1049
                                                        DINW_SEL = 0;                                            // ALU8OUT
1050
                                                        WE              = 6'b100x01;                    // flags, lo
1051
                                                        ALU8OP  = {3'b000, !FETCH[3], 1'b1};    // SBC/ADC
1052
                                                        next_stage = 1;
1053
                                                        REG_WSEL        = 4'b0101;                              // L                    
1054
                                                        REG_RSEL        = {op16, 1'b1};
1055
                                                        M1              = 0;
1056
                                                        MREQ            = 0;
1057
                                                end else begin
1058
                                                        ALU160_SEL = 1;                                 // pc
1059
                                                        DINW_SEL = 0;                                            // ALU8OUT
1060
                                                        WE              = 6'b110x10;                    // flags, PC, hi
1061
                                                        ALU8OP  = {3'b000, !FETCH[3], 1'b1};
1062
                                                        REG_WSEL        = 4'b0100;                              // H
1063
                                                        REG_RSEL        = {op16, 1'b0};
1064
                                                end
1065
//                              -----------------------         LD (nn) r16, ld r16 (nn)  --------------------
1066
                                        3'b011:
1067
                                                case(STAGE[2:1])
1068
                                                        2'b00:  begin // stage 1,2 - read address
1069
                                                                ALU160_SEL = 1;                         // pc
1070
                                                                DINW_SEL = 1;                                   // DI
1071
                                                                WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};   // PC, hi/lo
1072
                                                                next_stage = 1;
1073
                                                                REG_WSEL        = 4'b111x;                      // tmp16
1074
                                                                M1              = 0;
1075
                                                        end
1076
                                                        2'b01: begin
1077
                                                                ALU160_SEL = 0;                  // regs
1078
                                                                next_stage = 1;
1079
                                                                ALU16OP = {2'b00, STAGE[0]};
1080
                                                                REG_RSEL        = 4'b111x;              // tmp16
1081
                                                                REG_WSEL        = {op16, !STAGE[0]};
1082
                                                                M1              = 0;
1083
                                                                if(FETCH[3]) begin      // LD rr, (nn) - stage3,4
1084
                                                                        DINW_SEL = 1;                           // DI
1085
                                                                        WE              = {4'b000x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};   // lo
1086
                                                                end else begin                  // LD (nn), rr - stage3,4
1087
                                                                        DO_SEL  = op16[2] ? {1'b1, !STAGE[0]} : 2'b00;                           // ALU80/sp
1088
                                                                        WE              = 6'b000x00;            // nothing
1089
                                                                        WR                      = 1;
1090
                                                                end
1091
                                                        end
1092
                                                        2'b10:          // stage5 
1093
                                                                if(FETCH[3] & op16[2] & !STAGE[0]) begin // LD sp, (nn) - stage5
1094
                                                                        ALU160_SEL = 0;                                  // regs
1095
                                                                        WE              = 6'b001x00;                    // SP
1096
                                                                        ALU16OP = 4;                                            // NOP
1097
                                                                        next_stage = 1;
1098
                                                                        REG_RSEL        = 4'b101x;                              // tmp SP
1099
                                                                        M1              = 0;
1100
                                                                        MREQ            = 0;
1101
                                                                end else begin
1102
                                                                        ALU160_SEL = 1;                                 // pc
1103
                                                                        WE              = 6'b010x00;                    // PC
1104
                                                                end
1105
                                                        endcase
1106
//                              -----------------------         NEG  --------------------
1107
                                        3'b100: begin
1108
                                                ALU160_SEL = 1;                                 // pc
1109
                                                DINW_SEL = 0;                                            // ALU8OUT
1110
                                                WE              = 6'b110x10;                    // flags, PC, hi
1111
                                                ALU8OP  = 5'b11111;                             // NEG
1112
                                                REG_WSEL        = 4'b011x;                              // A
1113
                                                REG_RSEL        = 4'b0110;                              // A
1114
                                        end
1115
//                              -----------------------         RETN, RETI  --------------------
1116
                                        3'b101:
1117
                                                case(STAGE[1:0])
1118
                                                        2'b00, 2'b01:   begin           // stage1, stage2 - pop addr
1119
                                                                ALU160_SEL = 0;                          // regs
1120
                                                                DINW_SEL = 1;                                   // DI
1121
                                                                WE              = {4'b001x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // SP, lo/hi
1122
                                                                next_stage = 1;
1123
                                                                REG_WSEL        = 4'b111x;                      // tmp16
1124
                                                                REG_RSEL        = 4'b101x;                      // SP
1125
                                                                M1              = 0;
1126
                                                        end
1127
                                                        2'b10: begin                    // stage3 - jump
1128
                                                                ALU160_SEL = 0;                                  // regs
1129
                                                                WE              = 6'b010x00;                    // PC
1130
                                                                REG_RSEL        = 4'b111x;                              // tmp16
1131
                                                                status[11] = 1'b1;
1132
                                                                status[7:6] = {CPUStatus[7], CPUStatus[7]};
1133
                                                        end
1134
                                                endcase
1135
//                              -----------------------         IM  --------------------
1136
                                        3'b110: begin
1137
                                                ALU160_SEL = 1;                                 // PC
1138
                                                WE              = 6'b010x00;                    // PC
1139
                                                status[10:8] = {1'b1, FETCH[4:3]};
1140
                                        end
1141
//                              -----------------------         LD I A, LD R A, LD A I, LD A R, RRD, RLD  --------------------
1142
                                        3'b111:
1143
                                                case(FETCH[5:4])
1144
                                                        2'b00: begin    // LD I/R A
1145
                                                                ALU160_SEL = 1;                                 // pc
1146
                                                                DINW_SEL = 1'b0;                                        // ALU8OUT
1147
                                                                WE              = {4'b010x, !FETCH[3], FETCH[3]};       // PC, hi/lo
1148
                                                                ALU8OP  = 29;                                           // pass D1
1149
                                                                REG_WSEL        = 4'b100x;                              // IR
1150
                                                                REG_RSEL        = 4'b0110;                              // A
1151
                                                        end
1152
                                                        2'b01: begin    // LD A I/R
1153
                                                                ALU160_SEL = 1;                                 // pc
1154
                                                                DINW_SEL = 1'b0;                                        // ALU8OUT
1155
                                                                WE              = 6'b110x1x;                    // flags, PC, hi
1156
                                                                ALU8OP  = 29;                                           // PASS D1
1157
                                                                REG_WSEL        = 4'b011x;                              // A
1158
                                                                REG_RSEL        = {3'b100, FETCH[3]};// I/R
1159
                                                        end
1160
                                                        2'b10:                  // RRD, RLD
1161
                                                                case(STAGE[1:0])
1162
                                                                        2'b00:begin             // stage1, read data
1163
                                                                                ALU160_SEL = 0;                                  // regs
1164
                                                                                DINW_SEL = 1;                                           // DI
1165
                                                                                WE              = 6'b000x01;                    // lo
1166
                                                                                next_stage = 1;
1167
                                                                                REG_WSEL        = 4'b011x;                              // tmpLO
1168
                                                                                REG_RSEL        = 4'b010x;                              // HL
1169
                                                                                M1              = 0;
1170
                                                                        end
1171
                                                                        2'b01: begin    // stage2, shift data
1172
                                                                                DINW_SEL = 0;                                            // ALU8OUT
1173
                                                                                WE              = 6'b100x11;                    // flags, hi, lo
1174
                                                                                ALU8OP  = FETCH[3] ? 5'b01100 : 5'b01011;       // RRD/RLD
1175
                                                                                next_stage = 1;
1176
                                                                                REG_WSEL        = 4'b0110;                              // A
1177
                                                                                REG_RSEL        = 4'b0111;                              // tmpLO
1178
                                                                                M1              = 0;
1179
                                                                                MREQ            = 0;
1180
                                                                        end
1181
                                                                        2'b10: begin // stage3 - write
1182
                                                                                DO_SEL  = 2'b00;                                        // ALU80
1183
                                                                                ALU160_SEL = 0;                                  // regs
1184
                                                                                WE              = 6'b000x0x;                    // nothing
1185
                                                                                next_stage = 1;
1186
                                                                                REG_WSEL        = 4'b0111;                              // tmpLO
1187
                                                                                REG_RSEL        = 4'b010x;                              // HL
1188
                                                                                M1              = 0;
1189
                                                                                WR                      = 1;
1190
                                                                        end
1191
                                                                        2'b11: begin
1192
                                                                                ALU160_SEL = 1;                                 // PC
1193
                                                                                WE              = 6'b010x00;                    // PC
1194
                                                                        end
1195
                                                                endcase
1196
                                                        2'b11: begin    // NOP
1197
                                                                ALU160_SEL = 1;                                 // PC
1198
                                                                WE              = 6'b010x00;                    // PC
1199
                                                        end
1200
                                                endcase
1201
                                endcase
1202
//                              -----------------------         block instructions  --------------------
1203
                        4'b0110:
1204
                                if({FETCH[5], FETCH[2]} == 4'b10)
1205
                                        case(FETCH[1:0])
1206
                                                2'b00:  // LDI, LDD, LDIR, LDDR
1207
                                                        case(STAGE[1:0])
1208
                                                                2'b00:  begin                   // stage1, read data, inc/dec HL
1209
                                                                        ALU160_SEL = 0;                                  // regs
1210
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1211
                                                                        WE              = 6'b100111;                    // flags, tmpHI, hi, lo
1212
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC/DEC16
1213
                                                                        next_stage = 1;
1214
                                                                        REG_WSEL        = 4'b0100;                              // H
1215
                                                                        REG_RSEL        = 4'b0101;                              // L
1216
                                                                        M1              = 0;
1217
                                                                end
1218
                                                                2'b01:  begin                   // stage2, dec BC
1219
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1220
                                                                        WE              = 6'b100011;                    // flags, hi, lo (affects PF only)
1221
                                                                        ALU8OP  = 5'b01111;                             // DEC
1222
                                                                        next_stage = 1;
1223
                                                                        REG_WSEL        = 4'b0000;                              // B
1224
                                                                        REG_RSEL        = 4'b0001;                              // C
1225
                                                                        M1              = 0;
1226
                                                                        MREQ            = 0;
1227
                                                                end
1228
                                                                2'b10:  begin                   // stage2, write data, inc/dec DE
1229
                                                                        DO_SEL  = 2'b01;                                        // th
1230
                                                                        ALU160_SEL = 0;                                  // regs
1231
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1232
                                                                        WE              = 6'b000x11;                    // hi, lo
1233
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1234
                                                                        next_stage = FETCH[4] ? !FLAGS[2] : 1'b1;
1235
                                                                        REG_WSEL        = 4'b0010;                              // D
1236
                                                                        REG_RSEL        = 4'b0011;                              // E
1237
                                                                        M1              = 0;
1238
                                                                        WR                      = 1;
1239
                                                                end
1240
                                                                2'b11: begin
1241
                                                                        ALU160_SEL = 1;                                 // PC
1242
                                                                        WE              = 6'b010x00;                    // PC
1243
                                                                end
1244
                                                        endcase
1245
                                                2'b01:  // CPI, CPD, CPIR, CPDR
1246
                                                        case(STAGE[1:0])
1247
                                                                2'b00: begin                    // stage1, load data
1248
                                                                        ALU160_SEL = 0;                                  // regs
1249
                                                                        DINW_SEL = 1;                                           // DI
1250
                                                                        WE              = 6'b000x01;                    // lo
1251
                                                                        next_stage = 1;
1252
                                                                        REG_WSEL        = 4'b011x;                              // tmpLO
1253
                                                                        REG_RSEL        = 4'b010x;                              // HL
1254
                                                                        M1              = 0;
1255
                                                                end
1256
                                                                2'b01: begin                    // stage2, CP
1257
                                                                        WE              = 6'b100x0x;                    // flags
1258
                                                                        ALU8OP  = 7;                                            // CP
1259
                                                                        next_stage = 1;
1260
                                                                        REG_WSEL        = 4'b0110;                              // A
1261
                                                                        REG_RSEL        = 4'b0111;                              // tmpLO
1262
                                                                        M1              = 0;
1263
                                                                        MREQ            = 0;
1264
                                                                end
1265
                                                                2'b10: begin                    // stage3, dec BC
1266
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1267
                                                                        WE              = 6'b100x11;                    // flags, hi, lo
1268
                                                                        ALU8OP  = 5'b01111;                             // DEC16
1269
                                                                        next_stage = 1;
1270
                                                                        REG_WSEL        = 4'b0000;                              // B
1271
                                                                        REG_RSEL        = 4'b0001;                              // C
1272
                                                                        M1              = 0;
1273
                                                                        MREQ            = 0;
1274
                                                                end
1275
                                                                2'b11: begin                    // stage4, inc/dec HL
1276
                                                                        ALU160_SEL = 1;                                 // pc
1277
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1278
                                                                        M1              = FETCH[4] ? (!FLAGS[2] || FLAGS[6]) : 1'b1;
1279
                                                                        WE              = {1'b0, M1, 4'b0x11};  // PC, hi, lo
1280
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1281
                                                                        REG_WSEL        = 4'b0100;                              // H
1282
                                                                        REG_RSEL        = 4'b0101;                              // L
1283
                                                                        MREQ            = M1;
1284
                                                                end
1285
                                                        endcase
1286
                                                2'b10:  // INI, IND, INIR, INDR
1287
                                                        case(STAGE[1:0])
1288
                                                                2'b00:  begin                   // stage1, in data, dec B
1289
                                                                        ALU160_SEL = 0;                                  // regs
1290
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1291
                                                                        WE              = 6'b100110;                    // flags, tmpHI, hi
1292
                                                                        ALU8OP  = 10;                                           // DEC
1293
                                                                        next_stage = 1;
1294
                                                                        REG_WSEL        = 4'b0000;                              // B
1295
                                                                        REG_RSEL        = 4'b000x;                              // BC
1296
                                                                        M1              = 0;
1297
                                                                        MREQ            = 0;
1298
                                                                        IORQ            = 1;
1299
                                                                end
1300
                                                                2'b01:  begin                   // stage2, write data, inc/dec HL
1301
                                                                        DO_SEL  = 2'b01;                                        // th
1302
                                                                        ALU160_SEL = 0;                                  // regs
1303
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1304
                                                                        WE              = 6'b000x11;                    // hi, lo
1305
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1306
                                                                        next_stage = FETCH[4] ? FLAGS[6] : 1'b1;
1307
                                                                        REG_WSEL        = 4'b0100;                              // H
1308
                                                                        REG_RSEL        = 4'b0101;                              // L
1309
                                                                        M1              = 0;
1310
                                                                        WR                      = 1;
1311
                                                                end
1312
                                                                2'b10:  begin                   // stage3
1313
                                                                        ALU160_SEL = 1;                                 // pc
1314
                                                                        WE              = 6'b010x00;                    // PC
1315
                                                                end
1316
                                                        endcase
1317
                                                2'b11:  // OUTI/OUTD/OTIR/OTDR
1318
                                                        case(STAGE[1:0])
1319
                                                                2'b00:  begin                   // stage1, load data, inc/dec HL
1320
                                                                        ALU160_SEL = 0;                                  // regs
1321
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1322
                                                                        WE              = 6'b000111;                    // tmpHI, hi, lo
1323
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1324
                                                                        next_stage = 1;
1325
                                                                        REG_WSEL        = 4'b0100;                              // H
1326
                                                                        REG_RSEL        = 4'b0101;                              // L
1327
                                                                        M1              = 0;
1328
                                                                end
1329
                                                                2'b01:  begin                   // stage2, out data, dec B
1330
                                                                        DO_SEL  = 2'b01;                                        // th
1331
                                                                        ALU160_SEL = 0;                                  // regs
1332
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1333
                                                                        WE              = 6'b100x10;                    // flags, hi
1334
                                                                        ALU8OP  = 10;                                           // DEC
1335
                                                                        next_stage = FETCH[4] ? (ALU80 == 8'b00000001) : 1'b1;
1336
                                                                        REG_WSEL        = 4'b0000;                              // B
1337
                                                                        REG_RSEL        = 4'b000x;                              // BC
1338
                                                                        M1              = 0;
1339
                                                                        MREQ            = 0;
1340
                                                                        IORQ            = 1;
1341
                                                                        WR                      = 1;
1342
                                                                end
1343
                                                                2'b10:  begin                   // stage3
1344
                                                                        ALU160_SEL = 1;                                 // pc
1345
                                                                        WE              = 6'b010x00;                    // PC
1346
                                                                end
1347
                                                        endcase
1348
                                        endcase
1349
                                else begin                      // NOP
1350
                                        ALU160_SEL = 1;                                 // PC
1351
                                        WE              = 6'b010x00;                    // PC
1352
                                end
1353
//------------------------------------------- CB + opcode ----------------------------------------------------
1354
                        4'b1000, 4'b1001, 4'b1010, 4'b1011:                                                                             // CB class (rot/shift, bit/res/set)
1355
                                case({STAGE[1:0], CPUStatus[4], op0mem})
1356
                                        4'b00_0_0: begin                                                // execute reg-reg
1357
                                                DINW_SEL = 0;                                            // ALU8OUT
1358
                                                ALU160_SEL = 1;                                 // pc
1359
                                                WE              = {!FETCH[7], 3'b10x, FETCH[7:6] == 2'b01 ? 2'b00 : {!opd[0], opd[0]}};   // flags, hi/lo
1360
                                                ALU8OP  = 28;                                   // BIT
1361
                                                REG_WSEL        = {1'b0, opd[2:0]};
1362
                                        end
1363
                                        4'b00_0_1, 4'b00_1_0, 4'b00_1_1: begin                          // stage1, (HL-X) - read data
1364
                                                ALU160_SEL = 0;                          // regs
1365
                                                DINW_SEL = 1;                                   // DI
1366
                                                WE              = opd[0] ? 6'b000001 : 6'b000010;        // lo/hi
1367
                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;                                   // ADD - NOP
1368
                                                next_stage = 1;
1369
                                                REG_WSEL = FETCH[7:6] == 2'b01 ? 4'b111x : {1'b0, opd[2:0]};     // dest, tmp16 for BIT
1370
                                                REG_RSEL        = 4'b010x;                      // HL
1371
                                                M1              = 0;
1372
                                        end
1373
                                        4'b01_0_1, 4'b01_1_0, 4'b01_1_1:                // stage2 (HL-X) - execute, write
1374
                                                case(FETCH[7:6])
1375
                                                        2'b00, 2'b10, 2'b11: begin              // exec + write
1376
                                                                DINW_SEL = 0;                                    // ALU8OUT
1377
                                                                DO_SEL  = 2'b11;                                // ALU8OUT[7:0]
1378
                                                                ALU160_SEL = 0;                          // regs
1379
                                                                WE              = {!FETCH[7], 3'b00x, !opd[0], opd[0]};   // flags, hi/lo
1380
                                                                ALU8OP  = 28;
1381
                                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;
1382
                                                                next_stage = 1;
1383
                                                                REG_WSEL        = {1'b0, opd[2:0]};
1384
                                                                REG_RSEL        = 4'b010x;                              // HL
1385
                                                                M1              = 0;
1386
                                                                WR                      = 1;
1387
                                                        end
1388
                                                        2'b01: begin                                                    // BIT, no write
1389
                                                                ALU160_SEL = 1;                                 // pc
1390
                                                                WE              = 6'b110xxx;                    // flags, PC
1391
                                                                ALU8OP  = 28;                                           // BIT
1392
                                                                REG_WSEL        = {3'b111, opd[0]};      // tmp
1393
                                                        end
1394
                                                endcase
1395
                                        4'b10_0_1, 4'b10_1_0, 4'b10_1_1: begin  // (HL-X) - load next op
1396
                                                ALU160_SEL = 1;                                                 // pc
1397
                                                WE              = 6'b010x00;                                    // PC
1398
                                        end
1399
                                endcase
1400
//------------------------------------------- // RST, NMI, INT ----------------------------------------------------
1401
                        4'b1110: begin                  // RESET: IR <- 0, IM <- 0, IFF1,IFF2 <- 0, pC <- 0
1402
                                        ALU160_SEL = 0;                                  // regs
1403
                                        DINW_SEL = 0;                                            // ALU8OUT
1404
                                        WE              = 6'bx1xx11;                    // PC, hi, lo
1405
                                        ALU8OP  = 29;                                           // pass D1
1406
                                        ALU16OP = 4;                                            // NOP
1407
                                        REG_WSEL        = 4'b010x;                              // IR
1408
                                        REG_RSEL        = 4'b110x;                              // const
1409
                                        M1              = 0;
1410
                                        MREQ            = 0;
1411
                                        status[11:6] = 6'b110000;               // IM0, DI
1412
                                end
1413
                        4'b1101:                                                // NMI
1414
                                case(STAGE[1:0])
1415
                                        2'b00: begin
1416
                                                ALU160_SEL = 1;                         // pc
1417
                                                WE              = 6'b010x00;            // PC
1418
                                                ALU16OP = intop;                                // DEC/DEC2 (if block instruction interrupted)
1419
                                                next_stage = 1;
1420
                                                M1              = 0;
1421
                                                MREQ            = 0;
1422
                                        end
1423
                                        2'b01, 2'b10: begin
1424
                                                DO_SEL  = {1'b0, !STAGE[0]};     // pc hi/lo
1425
                                                ALU160_SEL = 0;                                  // regs
1426
                                                WE              = 6'b001x00;                    // SP
1427
                                                ALU16OP = 5;                                            // DEC
1428
                                                next_stage = 1;
1429
                                                REG_WSEL        = 4'b1xxx;                              // pc
1430
                                                REG_RSEL        = 4'b101x;                              // sp
1431
                                                M1              = 0;
1432
                                                WR                      = 1;
1433
                                                status[11]      = 1'b1;
1434
                                                status[7:6] = {CPUStatus[7], 1'b0};     // reset IFF1
1435
                                        end
1436
                                        2'b11: begin
1437
                                                ALU160_SEL = 0;                                  // regs
1438
                                                WE              = 6'b010x00;                    // PC
1439
                                                REG_RSEL        = 4'b110x;                              // const
1440
                                        end
1441
                                endcase
1442
                        4'b1100:                                // INT
1443
                                case(CPUStatus[9:8])
1444
                                        2'b00, 2'b01, 2'b10: begin              // IM0, IM1     
1445
                                                ALU160_SEL = 1;                                 // pc
1446
                                                WE              = 6'b010x00;                    // PC
1447
                                                ALU16OP = intop;                                        // DEC/DEC2 (if block instruction interrupted)
1448
                                                MREQ            = 0;
1449
                                                IORQ            = 1;
1450
                                                status[11]      = 1'b1;
1451
                                                status[7:6] = 2'b0;                             // reset IFF1, IFF2
1452
                                        end
1453
                                        2'b11:                                                          // IM2
1454
                                                case(STAGE[2:0])
1455
                                                        3'b000: begin
1456
                                                                ALU160_SEL = 1;                         // pc
1457
                                                                DINW_SEL = 1;                                   // DI
1458
                                                                WE              = 6'b010x01;            // PC, lo
1459
                                                                ALU16OP = intop;                                // DEC/DEC2 (if block instruction interrupted)
1460
                                                                next_stage = 1;
1461
                                                                REG_WSEL        = 4'b100x;                      // Itmp
1462
                                                                MREQ            = 0;
1463
                                                                IORQ            = 1;
1464
                                                                status[11]      = 1'b1;
1465
                                                                status[7:6] = 2'b0;                     // reset IFF1, IFF2
1466
                                                        end
1467
                                                        3'b001, 3'b010: begin                   // push pc
1468
                                                                DO_SEL  = {1'b0, !STAGE[0]};     // pc hi/lo
1469
                                                                ALU160_SEL = 0;                                  // regs
1470
                                                                WE              = 6'b001x00;                    // SP
1471
                                                                ALU16OP = 5;                                            // DEC
1472
                                                                next_stage = 1;
1473
                                                                REG_WSEL        = 4'b1xxx;                              // pc
1474
                                                                REG_RSEL        = 4'b101x;                              // sp
1475
                                                                M1              = 0;
1476
                                                                WR                      = 1;
1477
                                                        end
1478
                                                        3'b011, 3'b100: begin                   // read address
1479
                                                                ALU160_SEL = 0;                                  // regs
1480
                                                                DINW_SEL = 1;                                           // DI
1481
                                                                WE              = {4'b0x0x, STAGE[0] ? 1'bx : 1'b1, STAGE[0]};                            // hi/lo
1482
                                                                ALU16OP = {2'b00, !STAGE[0]};// NOP/INC
1483
                                                                next_stage = 1;
1484
                                                                REG_WSEL        = 4'b111x;                              // tmp16
1485
                                                                REG_RSEL        = 4'b1000;                              // I-Itmp
1486
                                                                M1              = 0;
1487
                                                        end
1488
                                                        3'b101: begin                                           // jump
1489
                                                                ALU160_SEL = 0;                                  // regs
1490
                                                                WE              = 6'b010x00;                    // PC
1491
                                                                REG_RSEL        = 4'b111x;                              // tmp16
1492
                                                        end
1493
                                                endcase
1494
                                endcase
1495
                endcase
1496
        end
1497
 
1498
endmodule

powered by: WebSVN 2.1.0

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