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

Subversion Repositories nextz80

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

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 13 ndumitrach
                                        if(M1 || (fetch98 == 2'b10))    // [DD/FD CB disp op] -  M1 is inactive during <op> byte read, but FETCH is performed
175 2 ndumitrach
                                                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 12 ndumitrach
                REG_RSEL        = 4'bx0xx;                              // prevents default 4'b0100 which leads to incorrect P flag value in some cases (like RLA)
212 2 ndumitrach
                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 13 ndumitrach
                                                                                M1 = !CPUStatus[4];     // [DD/FD CB disp op] -  M1 is inactive during <op> byte read
910 2 ndumitrach
                                                                        end
911
                                                                        2'b01: begin
912
                                                                                ALU160_SEL = 1;                 // PC
913
                                                                                WE              = 6'b010100;    // PC, tmpHI
914
                                                                                next_stage = 1;
915
                                                                                M1              = 0;
916
                                                                        end
917
                                                                endcase
918
                                                        2'b01:                                  // IN A, (n)
919
                                                                case(STAGE[1:0])
920
                                                                        2'b00: begin            //stage1 - read n
921
                                                                                ALU160_SEL = 1;                         // pc
922
                                                                                DINW_SEL = 1;                                   // DI
923
                                                                                WE              = 6'b010x01;            // PC, lo
924
                                                                                next_stage = 1;
925
                                                                                REG_WSEL        = 4'b011x;                      // tmpLO
926
                                                                                M1              = 0;
927
                                                                        end
928
                                                                        2'b01: begin            // stage2 - IN
929
                                                                                ALU160_SEL = 0;                          // regs
930
                                                                                DINW_SEL = 1;                                   // DI
931
                                                                                WE              = 6'b000x1x;            // hi
932
                                                                                next_stage = 1;
933
                                                                                REG_WSEL        = 4'b011x;                      // A
934
                                                                                REG_RSEL        = 4'b011x;                      // A - tmpLO
935
                                                                                M1              = 0;
936
                                                                                MREQ            = 0;
937
                                                                                IORQ            = 1;
938
                                                                        end
939
                                                                        2'b10: begin            // stage3 - fetch
940
                                                                                ALU160_SEL = 1;                 // PC
941
                                                                                WE              = 6'b010x00;    // PC
942
                                                                        end
943
                                                                endcase
944
                                                        2'b10: begin                    // EX DE, HL
945
                                                                ALU160_SEL = 1;                 // PC
946
                                                                WE              = 6'b010x00;    // PC
947
                                                                if(CPUStatus[1]) status[3] = 1;
948
                                                                else status[2] = 1;
949
                                                        end
950
                                                        2'b11: begin                    // EI
951
                                                                ALU160_SEL = 1;                 // PC
952
                                                                WE              = 6'b010x00;    // PC
953
                                                                status[11] = 1'b1;
954
                                                                status[7:6] = 2'b11;
955
                                                        end
956
                                                endcase
957
//                              -----------------------         CALL , IX, ED, IY --------------------
958
                                        4'b1101:
959
                                                case(FETCH[5:4])
960
                                                        2'b00:                                  // CALL
961
                                                                case(STAGE[2:0])
962
                                                                        3'b000, 3'b001: begin           // stage 1,2 - load addr
963
                                                                                ALU160_SEL = 1;                                 // pc
964
                                                                                DINW_SEL = 1;                                           // DI
965
                                                                                WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // PC, hi/lo
966
                                                                                next_stage = 1;
967
                                                                                REG_WSEL        = 4'b111x;                              // tmp7
968
                                                                                M1              = 0;
969
                                                                        end
970
                                                                        3'b010, 3'b011: begin           // stage 3,4 - push pc
971
                                                                                DO_SEL  = {1'b0, STAGE[0]};      // pc hi/lo
972
                                                                                ALU160_SEL = 0;                                  // regs
973
                                                                                WE              = 6'b001x00;                    // SP
974
                                                                                ALU16OP = 5;                                            // DEC
975
                                                                                next_stage = 1;
976
                                                                                REG_WSEL        = 4'b1xxx;                              // pc
977
                                                                                REG_RSEL        = 4'b101x;                              // sp
978
                                                                                M1              = 0;
979
                                                                                WR                      = 1;
980
                                                                        end
981
                                                                        3'b100: begin   // stage5 - jump
982
                                                                                ALU160_SEL = 0;                                  // regs
983
                                                                                WE              = 6'b010x00;                    // PC
984
                                                                                REG_RSEL        = 4'b111x;                              // tmp7
985
                                                                        end
986
                                                                endcase
987
                                                        2'b01: begin                    // DD - IX
988
                                                                ALU160_SEL = 1;                 // PC
989
                                                                WE              = 6'b010x00;    // PC
990
                                                                status[5:4] = 2'b01;
991
                                                        end
992
                                                        2'b10: begin                    // ED prefix
993
                                                                ALU160_SEL = 1;                 // PC
994
                                                                WE              = 6'b010x00;    // PC
995
                                                                fetch98 = 2'b01;
996
                                                        end
997
                                                        2'b11:  begin                   // FD - IY
998
                                                                ALU160_SEL = 1;                 // PC
999
                                                                WE              = 6'b010x00;    // PC
1000
                                                                status[5:4]     = 2'b11;
1001
                                                        end
1002
                                                endcase
1003
                                endcase
1004
 
1005
//      ------------------------------------------- ED + opcode ----------------------------------------------------
1006
                        4'b0100, 4'b0111: begin         // ED + 2'b00, ED + 2'b11               = NOP
1007
                                ALU160_SEL = 1;                 // PC
1008
                                WE              = 6'b010x00;    // PC
1009
                        end
1010
                        4'b0101:
1011
                                case(FETCH[2:0])
1012
//                              -----------------------         in r (C)  --------------------
1013
                                        3'b000:
1014
                                                if(!STAGE[0]) begin
1015
                                                        ALU160_SEL = 0;                                  // regs
1016
                                                        DINW_SEL = 1;                                           // DI
1017
                                                        WE              = {4'b000x, !opd[3], opd[3]} ;  // hi/lo
1018
                                                        next_stage = 1;
1019
                                                        REG_WSEL        = {1'b0, opd[5:4], 1'bx};
1020
                                                        REG_RSEL        = 4'b000x;                              // BC
1021
                                                        M1              = 0;
1022
                                                        MREQ            = 0;
1023
                                                        IORQ            = 1;
1024
                                                end else begin
1025
                                                        ALU160_SEL = 1;                                 // pc
1026
                                                        WE              = 6'b110x00;                    // flags, PC
1027
                                                        ALU8OP  = 29;                                           // IN
1028
                                                        REG_RSEL        = {1'b0, opd[5:3]};     // reg
1029
                                                end
1030
//                              -----------------------         out (C) r  --------------------
1031
                                        3'b001:
1032
                                                if(!STAGE[0]) begin
1033
                                                        DO_SEL  = 2'b00;                                        // ALU80
1034
                                                        ALU160_SEL = 0;                                  // regs
1035
                                                        WE              = 6'b000x00;                    // nothing
1036
                                                        next_stage = 1;
1037
                                                        REG_WSEL        = &opd[5:3] ? 4'b110x : {1'b0, opd[5:3]}; // zero/reg
1038
                                                        REG_RSEL        = 4'b000x;                              // BC
1039
                                                        M1              = 0;
1040
                                                        MREQ            = 0;
1041
                                                        WR                      = 1;
1042
                                                        IORQ            = 1;
1043
                                                end else begin
1044
                                                        ALU160_SEL = 1;                                 // pc
1045
                                                        WE              = 6'b010x00;                    // PC
1046
                                                end
1047
//                              -----------------------         SBC16, ADC16  --------------------
1048
                                        3'b010:
1049
                                                if(!STAGE[0]) begin                      // stage1
1050
                                                        DINW_SEL = 0;                                            // ALU8OUT
1051
                                                        WE              = 6'b100x01;                    // flags, lo
1052
                                                        ALU8OP  = {3'b000, !FETCH[3], 1'b1};    // SBC/ADC
1053
                                                        next_stage = 1;
1054
                                                        REG_WSEL        = 4'b0101;                              // L                    
1055
                                                        REG_RSEL        = {op16, 1'b1};
1056
                                                        M1              = 0;
1057
                                                        MREQ            = 0;
1058
                                                end else begin
1059
                                                        ALU160_SEL = 1;                                 // pc
1060
                                                        DINW_SEL = 0;                                            // ALU8OUT
1061
                                                        WE              = 6'b110x10;                    // flags, PC, hi
1062
                                                        ALU8OP  = {3'b000, !FETCH[3], 1'b1};
1063
                                                        REG_WSEL        = 4'b0100;                              // H
1064
                                                        REG_RSEL        = {op16, 1'b0};
1065
                                                end
1066
//                              -----------------------         LD (nn) r16, ld r16 (nn)  --------------------
1067
                                        3'b011:
1068
                                                case(STAGE[2:1])
1069
                                                        2'b00:  begin // stage 1,2 - read address
1070
                                                                ALU160_SEL = 1;                         // pc
1071
                                                                DINW_SEL = 1;                                   // DI
1072
                                                                WE              = {4'b010x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};   // PC, hi/lo
1073
                                                                next_stage = 1;
1074
                                                                REG_WSEL        = 4'b111x;                      // tmp16
1075
                                                                M1              = 0;
1076
                                                        end
1077
                                                        2'b01: begin
1078
                                                                ALU160_SEL = 0;                  // regs
1079
                                                                next_stage = 1;
1080
                                                                ALU16OP = {2'b00, STAGE[0]};
1081
                                                                REG_RSEL        = 4'b111x;              // tmp16
1082
                                                                REG_WSEL        = {op16, !STAGE[0]};
1083
                                                                M1              = 0;
1084
                                                                if(FETCH[3]) begin      // LD rr, (nn) - stage3,4
1085
                                                                        DINW_SEL = 1;                           // DI
1086
                                                                        WE              = {4'b000x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};   // lo
1087
                                                                end else begin                  // LD (nn), rr - stage3,4
1088
                                                                        DO_SEL  = op16[2] ? {1'b1, !STAGE[0]} : 2'b00;                           // ALU80/sp
1089
                                                                        WE              = 6'b000x00;            // nothing
1090
                                                                        WR                      = 1;
1091
                                                                end
1092
                                                        end
1093
                                                        2'b10:          // stage5 
1094
                                                                if(FETCH[3] & op16[2] & !STAGE[0]) begin // LD sp, (nn) - stage5
1095
                                                                        ALU160_SEL = 0;                                  // regs
1096
                                                                        WE              = 6'b001x00;                    // SP
1097
                                                                        ALU16OP = 4;                                            // NOP
1098
                                                                        next_stage = 1;
1099
                                                                        REG_RSEL        = 4'b101x;                              // tmp SP
1100
                                                                        M1              = 0;
1101
                                                                        MREQ            = 0;
1102
                                                                end else begin
1103
                                                                        ALU160_SEL = 1;                                 // pc
1104
                                                                        WE              = 6'b010x00;                    // PC
1105
                                                                end
1106
                                                        endcase
1107
//                              -----------------------         NEG  --------------------
1108
                                        3'b100: begin
1109
                                                ALU160_SEL = 1;                                 // pc
1110
                                                DINW_SEL = 0;                                            // ALU8OUT
1111
                                                WE              = 6'b110x10;                    // flags, PC, hi
1112
                                                ALU8OP  = 5'b11111;                             // NEG
1113
                                                REG_WSEL        = 4'b011x;                              // A
1114
                                                REG_RSEL        = 4'b0110;                              // A
1115
                                        end
1116
//                              -----------------------         RETN, RETI  --------------------
1117
                                        3'b101:
1118
                                                case(STAGE[1:0])
1119
                                                        2'b00, 2'b01:   begin           // stage1, stage2 - pop addr
1120
                                                                ALU160_SEL = 0;                          // regs
1121
                                                                DINW_SEL = 1;                                   // DI
1122
                                                                WE              = {4'b001x, STAGE[0] ? 1'b1 : 1'bx, !STAGE[0]};           // SP, lo/hi
1123
                                                                next_stage = 1;
1124
                                                                REG_WSEL        = 4'b111x;                      // tmp16
1125
                                                                REG_RSEL        = 4'b101x;                      // SP
1126
                                                                M1              = 0;
1127
                                                        end
1128
                                                        2'b10: begin                    // stage3 - jump
1129
                                                                ALU160_SEL = 0;                                  // regs
1130
                                                                WE              = 6'b010x00;                    // PC
1131
                                                                REG_RSEL        = 4'b111x;                              // tmp16
1132
                                                                status[11] = 1'b1;
1133
                                                                status[7:6] = {CPUStatus[7], CPUStatus[7]};
1134
                                                        end
1135
                                                endcase
1136
//                              -----------------------         IM  --------------------
1137
                                        3'b110: begin
1138
                                                ALU160_SEL = 1;                                 // PC
1139
                                                WE              = 6'b010x00;                    // PC
1140
                                                status[10:8] = {1'b1, FETCH[4:3]};
1141
                                        end
1142
//                              -----------------------         LD I A, LD R A, LD A I, LD A R, RRD, RLD  --------------------
1143
                                        3'b111:
1144
                                                case(FETCH[5:4])
1145
                                                        2'b00: begin    // LD I/R A
1146
                                                                ALU160_SEL = 1;                                 // pc
1147
                                                                DINW_SEL = 1'b0;                                        // ALU8OUT
1148
                                                                WE              = {4'b010x, !FETCH[3], FETCH[3]};       // PC, hi/lo
1149
                                                                ALU8OP  = 29;                                           // pass D1
1150 11 ndumitrach
                                                                REG_WSEL        = 4'b1001;                              // IR, write r
1151 2 ndumitrach
                                                                REG_RSEL        = 4'b0110;                              // A
1152
                                                        end
1153
                                                        2'b01: begin    // LD A I/R
1154
                                                                ALU160_SEL = 1;                                 // pc
1155
                                                                DINW_SEL = 1'b0;                                        // ALU8OUT
1156
                                                                WE              = 6'b110x1x;                    // flags, PC, hi
1157
                                                                ALU8OP  = 29;                                           // PASS D1
1158
                                                                REG_WSEL        = 4'b011x;                              // A
1159
                                                                REG_RSEL        = {3'b100, FETCH[3]};// I/R
1160
                                                        end
1161
                                                        2'b10:                  // RRD, RLD
1162
                                                                case(STAGE[1:0])
1163
                                                                        2'b00:begin             // stage1, read data
1164
                                                                                ALU160_SEL = 0;                                  // regs
1165
                                                                                DINW_SEL = 1;                                           // DI
1166
                                                                                WE              = 6'b000x01;                    // lo
1167
                                                                                next_stage = 1;
1168
                                                                                REG_WSEL        = 4'b011x;                              // tmpLO
1169
                                                                                REG_RSEL        = 4'b010x;                              // HL
1170
                                                                                M1              = 0;
1171
                                                                        end
1172
                                                                        2'b01: begin    // stage2, shift data
1173
                                                                                DINW_SEL = 0;                                            // ALU8OUT
1174
                                                                                WE              = 6'b100x11;                    // flags, hi, lo
1175
                                                                                ALU8OP  = FETCH[3] ? 5'b01100 : 5'b01011;       // RRD/RLD
1176
                                                                                next_stage = 1;
1177
                                                                                REG_WSEL        = 4'b0110;                              // A
1178
                                                                                REG_RSEL        = 4'b0111;                              // tmpLO
1179
                                                                                M1              = 0;
1180
                                                                                MREQ            = 0;
1181
                                                                        end
1182
                                                                        2'b10: begin // stage3 - write
1183
                                                                                DO_SEL  = 2'b00;                                        // ALU80
1184
                                                                                ALU160_SEL = 0;                                  // regs
1185
                                                                                WE              = 6'b000x0x;                    // nothing
1186
                                                                                next_stage = 1;
1187
                                                                                REG_WSEL        = 4'b0111;                              // tmpLO
1188
                                                                                REG_RSEL        = 4'b010x;                              // HL
1189
                                                                                M1              = 0;
1190
                                                                                WR                      = 1;
1191
                                                                        end
1192
                                                                        2'b11: begin
1193
                                                                                ALU160_SEL = 1;                                 // PC
1194
                                                                                WE              = 6'b010x00;                    // PC
1195
                                                                        end
1196
                                                                endcase
1197
                                                        2'b11: begin    // NOP
1198
                                                                ALU160_SEL = 1;                                 // PC
1199
                                                                WE              = 6'b010x00;                    // PC
1200
                                                        end
1201
                                                endcase
1202
                                endcase
1203
//                              -----------------------         block instructions  --------------------
1204
                        4'b0110:
1205
                                if({FETCH[5], FETCH[2]} == 4'b10)
1206
                                        case(FETCH[1:0])
1207
                                                2'b00:  // LDI, LDD, LDIR, LDDR
1208
                                                        case(STAGE[1:0])
1209
                                                                2'b00:  begin                   // stage1, read data, inc/dec HL
1210
                                                                        ALU160_SEL = 0;                                  // regs
1211
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1212
                                                                        WE              = 6'b100111;                    // flags, tmpHI, hi, lo
1213
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC/DEC16
1214
                                                                        next_stage = 1;
1215
                                                                        REG_WSEL        = 4'b0100;                              // H
1216
                                                                        REG_RSEL        = 4'b0101;                              // L
1217
                                                                        M1              = 0;
1218
                                                                end
1219
                                                                2'b01:  begin                   // stage2, dec BC
1220
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1221
                                                                        WE              = 6'b100011;                    // flags, hi, lo (affects PF only)
1222
                                                                        ALU8OP  = 5'b01111;                             // DEC
1223
                                                                        next_stage = 1;
1224
                                                                        REG_WSEL        = 4'b0000;                              // B
1225
                                                                        REG_RSEL        = 4'b0001;                              // C
1226
                                                                        M1              = 0;
1227
                                                                        MREQ            = 0;
1228
                                                                end
1229
                                                                2'b10:  begin                   // stage2, write data, inc/dec DE
1230
                                                                        DO_SEL  = 2'b01;                                        // th
1231
                                                                        ALU160_SEL = 0;                                  // regs
1232
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1233
                                                                        WE              = 6'b000x11;                    // hi, lo
1234
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1235
                                                                        next_stage = FETCH[4] ? !FLAGS[2] : 1'b1;
1236
                                                                        REG_WSEL        = 4'b0010;                              // D
1237
                                                                        REG_RSEL        = 4'b0011;                              // E
1238
                                                                        M1              = 0;
1239
                                                                        WR                      = 1;
1240
                                                                end
1241
                                                                2'b11: begin
1242
                                                                        ALU160_SEL = 1;                                 // PC
1243
                                                                        WE              = 6'b010x00;                    // PC
1244
                                                                end
1245
                                                        endcase
1246
                                                2'b01:  // CPI, CPD, CPIR, CPDR
1247
                                                        case(STAGE[1:0])
1248
                                                                2'b00: begin                    // stage1, load data
1249
                                                                        ALU160_SEL = 0;                                  // regs
1250
                                                                        DINW_SEL = 1;                                           // DI
1251
                                                                        WE              = 6'b000x01;                    // lo
1252
                                                                        next_stage = 1;
1253
                                                                        REG_WSEL        = 4'b011x;                              // tmpLO
1254
                                                                        REG_RSEL        = 4'b010x;                              // HL
1255
                                                                        M1              = 0;
1256
                                                                end
1257
                                                                2'b01: begin                    // stage2, CP
1258
                                                                        WE              = 6'b100x0x;                    // flags
1259
                                                                        ALU8OP  = 7;                                            // CP
1260
                                                                        next_stage = 1;
1261
                                                                        REG_WSEL        = 4'b0110;                              // A
1262
                                                                        REG_RSEL        = 4'b0111;                              // tmpLO
1263
                                                                        M1              = 0;
1264
                                                                        MREQ            = 0;
1265
                                                                end
1266
                                                                2'b10: begin                    // stage3, dec BC
1267
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1268
                                                                        WE              = 6'b100x11;                    // flags, hi, lo
1269
                                                                        ALU8OP  = 5'b01111;                             // DEC16
1270
                                                                        next_stage = 1;
1271
                                                                        REG_WSEL        = 4'b0000;                              // B
1272
                                                                        REG_RSEL        = 4'b0001;                              // C
1273
                                                                        M1              = 0;
1274
                                                                        MREQ            = 0;
1275
                                                                end
1276
                                                                2'b11: begin                    // stage4, inc/dec HL
1277
                                                                        ALU160_SEL = 1;                                 // pc
1278
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1279
                                                                        M1              = FETCH[4] ? (!FLAGS[2] || FLAGS[6]) : 1'b1;
1280
                                                                        WE              = {1'b0, M1, 4'b0x11};  // PC, hi, lo
1281
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1282
                                                                        REG_WSEL        = 4'b0100;                              // H
1283
                                                                        REG_RSEL        = 4'b0101;                              // L
1284
                                                                        MREQ            = M1;
1285
                                                                end
1286
                                                        endcase
1287
                                                2'b10:  // INI, IND, INIR, INDR
1288
                                                        case(STAGE[1:0])
1289
                                                                2'b00:  begin                   // stage1, in data, dec B
1290
                                                                        ALU160_SEL = 0;                                  // regs
1291
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1292
                                                                        WE              = 6'b100110;                    // flags, tmpHI, hi
1293
                                                                        ALU8OP  = 10;                                           // DEC
1294
                                                                        next_stage = 1;
1295
                                                                        REG_WSEL        = 4'b0000;                              // B
1296
                                                                        REG_RSEL        = 4'b000x;                              // BC
1297
                                                                        M1              = 0;
1298
                                                                        MREQ            = 0;
1299
                                                                        IORQ            = 1;
1300
                                                                end
1301
                                                                2'b01:  begin                   // stage2, write data, inc/dec HL
1302
                                                                        DO_SEL  = 2'b01;                                        // th
1303
                                                                        ALU160_SEL = 0;                                  // regs
1304
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1305
                                                                        WE              = 6'b000x11;                    // hi, lo
1306
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1307
                                                                        next_stage = FETCH[4] ? FLAGS[6] : 1'b1;
1308
                                                                        REG_WSEL        = 4'b0100;                              // H
1309
                                                                        REG_RSEL        = 4'b0101;                              // L
1310
                                                                        M1              = 0;
1311
                                                                        WR                      = 1;
1312
                                                                end
1313
                                                                2'b10:  begin                   // stage3
1314
                                                                        ALU160_SEL = 1;                                 // pc
1315
                                                                        WE              = 6'b010x00;                    // PC
1316
                                                                end
1317
                                                        endcase
1318
                                                2'b11:  // OUTI/OUTD/OTIR/OTDR
1319
                                                        case(STAGE[1:0])
1320
                                                                2'b00:  begin                   // stage1, load data, inc/dec HL
1321
                                                                        ALU160_SEL = 0;                                  // regs
1322
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1323
                                                                        WE              = 6'b000111;                    // tmpHI, hi, lo
1324
                                                                        ALU8OP  = {4'b0111, FETCH[3]};  // INC / DEC
1325
                                                                        next_stage = 1;
1326
                                                                        REG_WSEL        = 4'b0100;                              // H
1327
                                                                        REG_RSEL        = 4'b0101;                              // L
1328
                                                                        M1              = 0;
1329
                                                                end
1330
                                                                2'b01:  begin                   // stage2, out data, dec B
1331
                                                                        DO_SEL  = 2'b01;                                        // th
1332
                                                                        ALU160_SEL = 0;                                  // regs
1333
                                                                        DINW_SEL = 0;                                            // ALU8OUT
1334
                                                                        WE              = 6'b100x10;                    // flags, hi
1335
                                                                        ALU8OP  = 10;                                           // DEC
1336
                                                                        next_stage = FETCH[4] ? (ALU80 == 8'b00000001) : 1'b1;
1337
                                                                        REG_WSEL        = 4'b0000;                              // B
1338
                                                                        REG_RSEL        = 4'b000x;                              // BC
1339
                                                                        M1              = 0;
1340
                                                                        MREQ            = 0;
1341
                                                                        IORQ            = 1;
1342
                                                                        WR                      = 1;
1343
                                                                end
1344
                                                                2'b10:  begin                   // stage3
1345
                                                                        ALU160_SEL = 1;                                 // pc
1346
                                                                        WE              = 6'b010x00;                    // PC
1347
                                                                end
1348
                                                        endcase
1349
                                        endcase
1350
                                else begin                      // NOP
1351
                                        ALU160_SEL = 1;                                 // PC
1352
                                        WE              = 6'b010x00;                    // PC
1353
                                end
1354
//------------------------------------------- CB + opcode ----------------------------------------------------
1355
                        4'b1000, 4'b1001, 4'b1010, 4'b1011:                                                                             // CB class (rot/shift, bit/res/set)
1356
                                case({STAGE[1:0], CPUStatus[4], op0mem})
1357
                                        4'b00_0_0: begin                                                // execute reg-reg
1358
                                                DINW_SEL = 0;                                            // ALU8OUT
1359
                                                ALU160_SEL = 1;                                 // pc
1360
                                                WE              = {!FETCH[7], 3'b10x, FETCH[7:6] == 2'b01 ? 2'b00 : {!opd[0], opd[0]}};   // flags, hi/lo
1361
                                                ALU8OP  = 28;                                   // BIT
1362
                                                REG_WSEL        = {1'b0, opd[2:0]};
1363
                                        end
1364
                                        4'b00_0_1, 4'b00_1_0, 4'b00_1_1: begin                          // stage1, (HL-X) - read data
1365
                                                ALU160_SEL = 0;                          // regs
1366
                                                DINW_SEL = 1;                                   // DI
1367
                                                WE              = opd[0] ? 6'b000001 : 6'b000010;        // lo/hi
1368
                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;                                   // ADD - NOP
1369
                                                next_stage = 1;
1370
                                                REG_WSEL = FETCH[7:6] == 2'b01 ? 4'b111x : {1'b0, opd[2:0]};     // dest, tmp16 for BIT
1371
                                                REG_RSEL        = 4'b010x;                      // HL
1372
                                                M1              = 0;
1373
                                        end
1374
                                        4'b01_0_1, 4'b01_1_0, 4'b01_1_1:                // stage2 (HL-X) - execute, write
1375
                                                case(FETCH[7:6])
1376
                                                        2'b00, 2'b10, 2'b11: begin              // exec + write
1377
                                                                DINW_SEL = 0;                                    // ALU8OUT
1378
                                                                DO_SEL  = 2'b11;                                // ALU8OUT[7:0]
1379
                                                                ALU160_SEL = 0;                          // regs
1380
                                                                WE              = {!FETCH[7], 3'b00x, !opd[0], opd[0]};   // flags, hi/lo
1381
                                                                ALU8OP  = 28;
1382
                                                                ALU16OP = CPUStatus[4] ? 3'd3 : 3'd0;
1383
                                                                next_stage = 1;
1384
                                                                REG_WSEL        = {1'b0, opd[2:0]};
1385
                                                                REG_RSEL        = 4'b010x;                              // HL
1386
                                                                M1              = 0;
1387
                                                                WR                      = 1;
1388
                                                        end
1389
                                                        2'b01: begin                                                    // BIT, no write
1390
                                                                ALU160_SEL = 1;                                 // pc
1391
                                                                WE              = 6'b110xxx;                    // flags, PC
1392
                                                                ALU8OP  = 28;                                           // BIT
1393
                                                                REG_WSEL        = {3'b111, opd[0]};      // tmp
1394
                                                        end
1395
                                                endcase
1396
                                        4'b10_0_1, 4'b10_1_0, 4'b10_1_1: begin  // (HL-X) - load next op
1397
                                                ALU160_SEL = 1;                                                 // pc
1398
                                                WE              = 6'b010x00;                                    // PC
1399
                                        end
1400
                                endcase
1401
//------------------------------------------- // RST, NMI, INT ----------------------------------------------------
1402
                        4'b1110: begin                  // RESET: IR <- 0, IM <- 0, IFF1,IFF2 <- 0, pC <- 0
1403
                                        ALU160_SEL = 0;                                  // regs
1404
                                        DINW_SEL = 0;                                            // ALU8OUT
1405
                                        WE              = 6'bx1xx11;                    // PC, hi, lo
1406
                                        ALU8OP  = 29;                                           // pass D1
1407
                                        ALU16OP = 4;                                            // NOP
1408 11 ndumitrach
                                        REG_WSEL        = 4'b1001;                              // IR, write r
1409 2 ndumitrach
                                        REG_RSEL        = 4'b110x;                              // const
1410
                                        M1              = 0;
1411
                                        MREQ            = 0;
1412
                                        status[11:6] = 6'b110000;               // IM0, DI
1413
                                end
1414
                        4'b1101:                                                // NMI
1415
                                case(STAGE[1:0])
1416
                                        2'b00: begin
1417
                                                ALU160_SEL = 1;                         // pc
1418
                                                WE              = 6'b010x00;            // PC
1419
                                                ALU16OP = intop;                                // DEC/DEC2 (if block instruction interrupted)
1420
                                                next_stage = 1;
1421
                                                M1              = 0;
1422
                                                MREQ            = 0;
1423
                                        end
1424
                                        2'b01, 2'b10: begin
1425
                                                DO_SEL  = {1'b0, !STAGE[0]};     // pc hi/lo
1426
                                                ALU160_SEL = 0;                                  // regs
1427
                                                WE              = 6'b001x00;                    // SP
1428
                                                ALU16OP = 5;                                            // DEC
1429
                                                next_stage = 1;
1430
                                                REG_WSEL        = 4'b1xxx;                              // pc
1431
                                                REG_RSEL        = 4'b101x;                              // sp
1432
                                                M1              = 0;
1433
                                                WR                      = 1;
1434
                                                status[11]      = 1'b1;
1435
                                                status[7:6] = {CPUStatus[7], 1'b0};     // reset IFF1
1436
                                        end
1437
                                        2'b11: begin
1438
                                                ALU160_SEL = 0;                                  // regs
1439
                                                WE              = 6'b010x00;                    // PC
1440
                                                REG_RSEL        = 4'b110x;                              // const
1441
                                        end
1442
                                endcase
1443
                        4'b1100:                                // INT
1444
                                case(CPUStatus[9:8])
1445
                                        2'b00, 2'b01, 2'b10: begin              // IM0, IM1     
1446
                                                ALU160_SEL = 1;                                 // pc
1447
                                                WE              = 6'b010x00;                    // PC
1448
                                                ALU16OP = intop;                                        // DEC/DEC2 (if block instruction interrupted)
1449
                                                MREQ            = 0;
1450
                                                IORQ            = 1;
1451
                                                status[11]      = 1'b1;
1452
                                                status[7:6] = 2'b0;                             // reset IFF1, IFF2
1453
                                        end
1454
                                        2'b11:                                                          // IM2
1455
                                                case(STAGE[2:0])
1456
                                                        3'b000: begin
1457
                                                                ALU160_SEL = 1;                         // pc
1458
                                                                DINW_SEL = 1;                                   // DI
1459
                                                                WE              = 6'b010x01;            // PC, lo
1460
                                                                ALU16OP = intop;                                // DEC/DEC2 (if block instruction interrupted)
1461
                                                                next_stage = 1;
1462 11 ndumitrach
                                                                REG_WSEL        = 4'b1000;                      // Itmp, no write r
1463 2 ndumitrach
                                                                MREQ            = 0;
1464
                                                                IORQ            = 1;
1465
                                                                status[11]      = 1'b1;
1466
                                                                status[7:6] = 2'b0;                     // reset IFF1, IFF2
1467
                                                        end
1468
                                                        3'b001, 3'b010: begin                   // push pc
1469
                                                                DO_SEL  = {1'b0, !STAGE[0]};     // pc hi/lo
1470
                                                                ALU160_SEL = 0;                                  // regs
1471
                                                                WE              = 6'b001x00;                    // SP
1472
                                                                ALU16OP = 5;                                            // DEC
1473
                                                                next_stage = 1;
1474
                                                                REG_WSEL        = 4'b1xxx;                              // pc
1475
                                                                REG_RSEL        = 4'b101x;                              // sp
1476
                                                                M1              = 0;
1477
                                                                WR                      = 1;
1478
                                                        end
1479
                                                        3'b011, 3'b100: begin                   // read address
1480
                                                                ALU160_SEL = 0;                                  // regs
1481
                                                                DINW_SEL = 1;                                           // DI
1482
                                                                WE              = {4'b0x0x, STAGE[0] ? 1'bx : 1'b1, STAGE[0]};                            // hi/lo
1483
                                                                ALU16OP = {2'b00, !STAGE[0]};// NOP/INC
1484
                                                                next_stage = 1;
1485
                                                                REG_WSEL        = 4'b111x;                              // tmp16
1486
                                                                REG_RSEL        = 4'b1000;                              // I-Itmp
1487
                                                                M1              = 0;
1488
                                                        end
1489
                                                        3'b101: begin                                           // jump
1490
                                                                ALU160_SEL = 0;                                  // regs
1491
                                                                WE              = 6'b010x00;                    // PC
1492
                                                                REG_RSEL        = 4'b111x;                              // tmp16
1493
                                                        end
1494
                                                endcase
1495
                                endcase
1496
                endcase
1497
        end
1498
 
1499
endmodule

powered by: WebSVN 2.1.0

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