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

Subversion Repositories next186

[/] [next186/] [trunk/] [Next186_CPU.v] - Blame information for rev 11

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

Line No. Rev Author Line
1 11 ndumitrach
//////////////////////////////////////////////////////////////////////////////////
2
//
3
// This file is part of the Next186 project
4
// http://opencores.org/project,next186
5
//
6
// Filename: Next186_CPU.v
7
// Description: Implementation of 80186 instruction compatible CPU
8
// Version 1.0
9
// Creation date: 24Mar2011 - 07Jun2011
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
//      Next186 processor features:
45 3 ndumitrach
//              All 80186 intstructions are implemented according with the 80186 specifications (excepting ENTER instruction, 
46 11 ndumitrach
//              which uses always 0 as the second parameter - level).
47 2 ndumitrach
//              Designed with 2 buses: 16bit/20bit data/data_address and 48bit/20bit instruction/instruction_address.
48
//              This allows most instructions to be executed in one clock cycle.
49
//              In order to couple the CPU unit with a single bus, these sepparate data/instruction buses must be multiplexed by
50 3 ndumitrach
//              a dedicated bus interface unit (BIU).
51 11 ndumitrach
//              It is able to execute up to 40Mips on Spartan XC3S700AN speed grade -4, performances comparable with a 486 CPU.
52
//              Small size, the CPU + BIU requires ~25%  or 1500 slices - on Spartan XC3S700AN
53 5 ndumitrach
// 
54 8 ndumitrach
//      16May2012 - fixed REP CMPS/SCAS bug when interrupted on the <equal> item
55 10 ndumitrach
// 23Dec2012 - fixed DIV bug (exception on sign bit)
56 11 ndumitrach
// 27Feb2013 - fixed MUL/IMUL 8bit flags bug
57
// 03Apr2013 - fix RET n alignment bug
58
// 04Apr2013 - fix TRAP interrupt acknowledge
59
///////////////////////////////////////////////////////////////////////////////////
60 2 ndumitrach
`timescale 1ns / 1ps
61
 
62
module Next186_CPU(
63
    output [19:0] ADDR,
64
    input [15:0] DIN,
65
    output [15:0] DOUT,
66
         input CLK,
67
         input CE,
68
         input INTR,
69
         input NMI,
70
         input RST,
71
         output reg MREQ,
72
         output wire IORQ,
73
         output reg INTA,
74
         output reg WR,
75
         output reg WORD,
76
         output LOCK,
77
         output [19:0]IADDR,
78
         input [47:0]INSTR,
79
         output reg IFETCH,
80
         output FLUSH,
81
         output reg [2:0]ISIZE,
82
         output reg HALT
83
    );
84
 
85
// connections  
86
        wire [15:0]RA;
87
        wire [15:0]RB;
88
        wire [15:0]TMP16;
89
        wire [15:0]SP;
90
        wire [15:0]IP;
91
        wire [15:0]AX;
92
        wire [15:0]BX;
93
        wire [15:0]BP;
94
        wire [15:0]SI;
95
        wire [15:0]DI;
96
        wire [15:0]DX;
97
        wire [15:0]FLAGS;
98
        wire [15:0]FIN;
99
        wire [15:0]ALUOUT;
100
        wire [15:0]AIMM1;
101
        reg [15:0]DIMM1;
102
        wire [15:0]RS;
103
        wire [15:0]ADDR16;
104
        wire [15:0]CS;
105
        wire ALUCONT;
106
        wire NULLSHIFT;
107
        wire [1:0]CXZ;
108
        wire COUT; // adder carry out
109
        wire DIVEXC; // exit carry for unsigned DIV 
110
        wire SOUT; // adder sign out
111
 
112
// Registers
113
        reg [7:0]FETCH[5:0];
114
        reg [6:0]STAGE = 0;
115
        reg [5:0]CPUStatus = 0;   //1:0=SR override, 2=override ON/OFF, 3=Z(REP), 4=REP ON/OFF, 5=LOCK
116
        reg TZF = 0, TLF = 0;
117
        reg SRST = 0;
118
        reg SNMI = 0, FNMI = 0;
119
        reg SINTR = 0;
120
        reg [15:0]CRTIP; // current instruction ptr (used by interrupts)
121
        reg DIVQSGN;
122
        reg RDIVEXC;
123
 
124
// control      
125
        reg [2:0]RASEL;
126
        reg [2:0]RBSEL;
127
        reg BASEL;
128
        reg [1:0]BBSEL;
129
        reg [1:0]RSSEL;
130
        reg [4:0]WE; // 4=flags, 3=TMP16, 2=RSSEL, 1=RASEL_HI, 0=RASEL_LO
131
        reg [4:0]ALUOP;
132
        reg [3:0]EAC;
133
        reg [1:0]DISEL;
134
        reg [1:0]ISEL;
135
        reg ASEL;
136
        reg AEXT;
137
        reg DEXT;
138
        reg [1:0]DOSEL;
139
        reg IPWSEL;
140
        reg [5:0]status; //1:0=SR override, 2=override ON/OFF, 3=Z(REP), 4=REP ON/OFF, 5=lock
141
        reg NOBP;
142
        reg ALUSTAGE;   // inc STAGE with 2
143
        reg DIVSTAGE;  // inc STAGE with 4
144
        reg DISP16;
145
        reg DECCX;
146
        reg IRQ;
147
        reg [2:0]IRQL;
148
        reg REPINT;
149
        reg [5:0]ICODE1 = 23;
150
        reg NULLSEG;
151
        reg DIVOP;
152
 
153
// signals
154
        assign IORQ = &EAC;
155
        assign LOCK = CPUStatus[5];
156
        assign FLUSH = ~IPWSEL || (ISIZE == 3'b000);
157
        wire [15:0]IPADD = ISIZE == 3'b000 ? CRTIP : IP + ISIZE;
158
        wire [15:0]IPIN = IPWSEL ? IPADD : ALUOUT;
159
        wire [1:0]MOD = FETCH[1][7:6];
160
        wire [2:0]REG = FETCH[1][5:3];
161
        wire [2:0]RM  = FETCH[1][2:0];
162
        wire USEBP = RM[1] && ~&RM;
163
        wire POP = {EAC[3], EAC[1:0]} == 3'b101;
164
        wire [15:0]ADDR16_SP = POP ? SP : ADDR16;
165
        wire [1:0]WBIT = {WORD | RASEL[2], WORD | !RASEL[2]};
166
        wire [1:0]ISELS = {DISP16 | AEXT, DISP16 | ~AEXT};
167
        wire [2:0]ISIZES = DISP16 ? 4 : AEXT ? 3 : 2;
168
        reg  [2:0]ISIZEW;
169
        reg  [2:0]ISIZEI;        // ise imm
170
        wire [1:0]WRBIT = WR ? 2'b00 : WBIT;
171
        wire RCXZ = CPUStatus[4] && ~|CXZ;
172
        wire NRORCXLE1 = ~CPUStatus[4] || ~CXZ[1];
173
        wire [7:0]JMPC = {(FLAGS[7] ^ FLAGS[11]) | FLAGS[6], FLAGS[7] ^ FLAGS[11], FLAGS[2], FLAGS[7], FLAGS[0] | FLAGS[6], FLAGS[6], FLAGS[0], FLAGS[11]};
174
        wire [3:0]LOOPC = {CXZ != 2'b00, CXZ == 2'b01, CXZ == 2'b01 || !FLAGS[6], CXZ == 2'b01 || FLAGS[6]};
175
        wire IDIV = FETCH[0][1] & FETCH[1][3];
176
        wire DIVRSGN = (WORD ? FETCH[3][7] : FETCH[2][7]) & IDIV;
177
        wire DIVSGN = DIVQSGN ^ DIVRSGN;
178
        wire DIVEND = FETCH[0][0] ? STAGE[6] : STAGE[5];
179
        wire DIVC = ((COUT & ~RDIVEXC) ^ ~DIVRSGN);
180
        wire QSGN = (WORD ? DX[15] : AX[15]) & IDIV;
181
// interrupts
182
        wire SAMPLEINT = ~(WE[2] & RASEL[1:0] == 2'b10) & ~status[2] & ~status[4] & ~status[5]; // not load SS, no prefix
183
        wire NMIACK = SNMI & ~FNMI;     // NMI acknowledged
184
        wire INTRACK = FLAGS[9] & (~WE[4] | FIN[9]) & SINTR;                    // INTR acknowledged (IF and not CLI in progress)
185 11 ndumitrach
        wire IACK = IRQ | (SAMPLEINT & (NMIACK | INTRACK | (~HALT & FLAGS[8]))); // interrupt acknowledged (fixed 04Apr2013)
186 5 ndumitrach
        reg CMPS;       // early EQ test for CMPS
187
        reg SCAS;   // early EQ test for SCAS
188 2 ndumitrach
 
189
        Next186_Regs REGS (
190
    .RASEL(RASEL),
191
    .RBSEL(RBSEL),
192
    .BASEL(BASEL),
193
    .BBSEL(BBSEL),
194
    .RSSEL(RSSEL),
195
    .DIN(DIN),
196
         .ALUOUT(ALUOUT),
197
         .ADDR16(ADDR16),
198
         .DIMM(DEXT ? {{8{DIMM1[7]}}, DIMM1[7:0]} : DIMM1),
199
    .WE(WE),
200
         .IFETCH(IFETCH),
201
    .RA(RA),
202
    .RB(RB),
203
    .TMP16(TMP16),
204
    .SP(SP),
205
    .IP(IP),
206
         .AX(AX),
207
         .BX(BX),
208
         .BP(BP),
209
         .SI(SI),
210
         .DI(DI),
211
         .DX(DX),
212
         .RS(RS),
213
         .FIN(FIN),
214
         .FOUT(FLAGS),
215
         .DISEL(DISEL),
216
         .WORD(WORD | &DISEL),
217
         .IPIN(IPIN),
218
         .CLK(CLK),
219
         .CLKEN(CE),
220
         .CS(CS),
221
         .INCSP(POP),
222
         .CXZ(CXZ),
223
         .DECCX(DECCX),
224
         .DIVOP(DIVOP),
225
         .DIVEND(DIVEND),
226
         .DIVSGN(DIVSGN),
227
         .DIVC(DIVC),
228
         .DIVEXC(DIVEXC)
229
    );
230
 
231
        Next186_ALU ALU16 (
232
         .RA(DOSEL == 2'b01 ? IPADD : RA),
233
         .RB(RB),
234
         .TMP16(TMP16),
235
         .FETCH23({FETCH[3], FETCH[2]}),
236
         .FIN(FLAGS),
237
         .FOUT(FIN),
238
         .ALUOP(ALUOP),
239
         .EXOP(FETCH[1][5:3]),
240
         .FLAGOP(FETCH[0][3:0]),
241
         .ALUOUT(ALUOUT),
242
         .WORD(WORD),
243
         .ALUCONT(ALUCONT),
244
         .NULLSHIFT(NULLSHIFT),
245
         .STAGE(STAGE[2:0]),
246
         .INC2(&DISEL), // when DISEL == 2'b11, inc/dec value is 2 if WORD and 1 if ~WORD
247
         .COUT(COUT),
248
         .SOUT(SOUT),
249
         .CLK(CLK)
250
         );
251
 
252
        Next186_EA EA (
253
    .SP(SP),
254
    .BX(BX),
255
    .BP(NOBP ? 16'h0000 : BP),
256
    .SI(SI),
257
    .DI(DI),
258
         .PIO(FETCH[0][3] ? DX : {8'h00, FETCH[1]}),
259
         .TMP16(TMP16),
260
         .AL(AX[7:0]),
261
    .AIMM(AEXT ? {{8{AIMM1[7]}}, AIMM1[7:0]} : (DISP16 ? AIMM1 : 16'h0000)),
262
    .ADDR16(ADDR16),
263
         .EAC(EAC)
264
    );
265
 
266
         assign DOUT = DOSEL[1] ? DOSEL[0] ? AX : TMP16 : DOSEL[0] ? IPADD : ALUOUT;
267
         assign ADDR = {{NULLSEG ? 16'h0000 : RS} + {4'b0000, ADDR16_SP[15:4]}, ADDR16_SP[3:0]};
268
         assign IADDR = {CS + {4'b0000, IPIN[15:4]}, IPIN[3:0]};
269
         assign AIMM1 = ASEL ? {FETCH[3], FETCH[2]} : {FETCH[2], FETCH[1]};
270
 
271
         always @(posedge CLK)
272
                if(CE) begin
273
                        if(SRST) begin          // reset
274
//                              FETCH[0] <= 8'h0f;
275
                                FETCH[0][0] <= 1'b1; // for word=1
276
                                ICODE1 <= 54;
277
                                FETCH[5][1:0] <= 2'b01;  // RESET
278
                                STAGE <= 4'b1000;
279
                        end else begin
280
                                if(IACK & (IFETCH | HALT | REPINT)) begin // interrupt sampled and acknowledged
281
                                        FETCH[0][1:0] <= 2'b11;
282
                                        ICODE1 <= 54;
283
                                        STAGE <= 4'b1000;
284
                                        FETCH[5][2:0] <= {HALT, 2'b00};
285
                                        if(IRQ) FETCH[2] <= IRQL != 3'b010 ? {5'b00000, IRQL} : FETCH[1];
286
                                        else if(NMIACK) begin
287
                                                FETCH[2] <= 8'h02;
288
                                                FNMI <= 1'b1;
289
                                        end else if(INTRACK) FETCH[5][1:0] <= 2'b10;
290
                                        else FETCH[2] <= 8'h01; // trap
291
                                end else if(IFETCH) begin               // no interrupt, fetch
292
                                        FETCH[5] <= INSTR[47:40];
293
                                        FETCH[4] <= INSTR[39:32];
294
                                        FETCH[3] <= INSTR[31:24];
295
                                        FETCH[2] <= INSTR[23:16];
296
                                        FETCH[1] <= INSTR[15:8];
297
                                        FETCH[0] <= INSTR[7:0];
298
                                        STAGE <= 0;
299
                                        CPUStatus[5:0] <= status[5:0];
300
                                        ICODE1 <= ICODE(INSTR[7:0]);
301
                                end else begin          // no interrupt, no fetch
302
                                        STAGE <= STAGE + {DIVSTAGE, ALUSTAGE} + 1;
303
                                        if(&DOSEL) {FETCH[3], FETCH[2]} <= |DISEL ? DIN : RB;
304 5 ndumitrach
                                        TZF <= FIN[6];          // zero flag for BOUND
305 2 ndumitrach
                                        TLF <= FIN[7] != FIN[11];       // less flag for BOUND
306
                                end
307
                        end
308
                        if(IFETCH & ~status[2] & ~status[4] & ~status[5]) CRTIP <= IPIN; // no prefix
309
                        SRST <= RST;                            // level detection RST
310
                        SINTR <= INTR;                          // level detection INTR
311
                        if(NMI) SNMI <= 1'b1;   // edge detection NMI
312
                        else if(FNMI) begin
313
                                SNMI <= 1'b0;
314
                                FNMI <= 1'b0;
315
                        end
316
                        if(~|STAGE[1:0]) DIVQSGN <= QSGN;
317
                        RDIVEXC <= DIVOP & DIVEXC & ~IDIV; // bit 8/16 for unsigned DIV
318 5 ndumitrach
                        CMPS <= (~FETCH[0][0] | (FETCH[3] == DIN[15:8])) & (FETCH[2] == DIN[7:0]); // early EQ test for CMPS
319
                        SCAS <= (~FETCH[0][0] | (AX[15:8] == DIN[15:8])) & (AX[7:0] == DIN[7:0]);  // early EQ test for SCAS
320 2 ndumitrach
                end
321
 
322
        always @(ISEL, FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5])
323
                case(ISEL)
324
                        2'b00: DIMM1 = {FETCH[2], FETCH[1]};
325
                        2'b01: DIMM1 = {FETCH[3], FETCH[2]};
326
                        2'b10: DIMM1 = {FETCH[4], FETCH[3]};
327
                        2'b11: DIMM1 = {FETCH[5], FETCH[4]};
328
                endcase
329
 
330
        always @(FETCH[0], WORD, DISP16, AEXT) begin
331
                case({WORD, DISP16, AEXT})
332
                        3'b000: ISIZEW = 3;
333
                        3'b001, 3'b100: ISIZEW = 4;
334
                        3'b010, 3'b101: ISIZEW = 5;
335
                        default: ISIZEW = 6;
336
                endcase
337
                case({FETCH[0][1:0] == 2'b01, DISP16, AEXT})
338
                        3'b000: ISIZEI = 3;
339
                        3'b001, 3'b100: ISIZEI = 4;
340
                        3'b110: ISIZEI = 6;
341
                        default: ISIZEI = 5;
342
                endcase
343
        end
344
 
345 5 ndumitrach
         always @(FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5], MOD, REG, RM, CPUStatus, USEBP, NOBP, RASEL, ISIZEI, TLF, EAC, COUT, DIVEND, DIVC, QSGN, CMPS, SCAS,
346 11 ndumitrach
                                 WBIT, ISIZES, ISELS, WRBIT, ISIZEW, STAGE, NULLSHIFT, ALUCONT, FLAGS, CXZ, RCXZ, NRORCXLE1, TZF, JMPC, LOOPC, ICODE1, DIVQSGN, DIVSGN, DIVRSGN, SOUT, IDIV) begin
347 2 ndumitrach
                WORD = FETCH[0][0];
348
                BASEL = FETCH[0][1] | &MOD;
349
                RASEL = FETCH[0][1] ? REG : RM; // destination
350
                BBSEL = {1'b0, !FETCH[0][1] | &MOD};
351
                RBSEL = FETCH[0][1] ? RM : REG; // source
352
                RSSEL = CPUStatus[2] ? CPUStatus[1:0] : (USEBP && !NOBP ? 2'b10 : 2'b11);
353
                WE = 5'b00000;          // 5=flags, 3=TMP16, 2=RSSEL, 1=RASEL_HI, 0=RASEL_LO
354
                ALUOP = 5'bxxxxx;
355
                EAC = {1'b0, RM};
356
                DISEL = 2'b01;          // ALU
357
                ISEL = 2'bxx;
358
                ASEL = 1'bx;
359
                AEXT = MOD == 2'b01;
360
                DEXT = 1'b0;
361
                DOSEL = 2'b00;  // ALU   
362
                MREQ = 1'b1;
363
                WR = 1'b0;
364
                ISIZE = 3'bxxx;
365
                IPWSEL = 1'b1;          // IP + ISIZE
366
                IFETCH = 1'b1;
367
                status = 6'b00x0xx;
368
 
369
                DISP16 = MOD == 2'b10 || NOBP;
370
                NOBP = {MOD, RM} == 5'b00110;
371
                HALT = 1'b0;
372
                INTA = 1'b0;
373
                ALUSTAGE = 1'b0;
374
                DIVSTAGE = 1'b0;
375
                DECCX = 1'b0;
376
                IRQ = 1'b0;
377
                IRQL = 3'b110;  // unused opcode
378
                REPINT = 1'b0;
379
                NULLSEG = 1'b0;
380
                DIVOP = 1'b0;
381
 
382
                case(ICODE1) // one hot synthesis
383
// --------------------------------  mov R/M to/from R/SR  --------------------------------
384
                        0: begin
385
                                if(FETCH[0][2]) WORD = 1'b1;
386
                                if(FETCH[0][2:1] == 2'b10) BBSEL = 2'b11; // RB = SR
387
                                ALUOP = 31;     // PASS B
388
                                DISEL = {1'b0, &MOD};
389
                                ASEL = 1'b1;
390
                                MREQ = ~&MOD;
391
                                WR = MREQ & !FETCH[0][1];
392
                                WE = WR ? 5'b00000 : &FETCH[0][2:1] ? {2'b00, FETCH[1][4:3] != 2'b01, 2'b00} : {3'b000, WBIT};           // RSSEL, RASEL_HI/RASEL_LO
393
                                ISIZE = ISIZES;
394
                        end
395
// --------------------------------  mov IMM to R/M  --------------------------------
396
                        1: begin
397
                                RASEL = RM; // destination
398
                                BBSEL = 2'b10;
399
                                ALUOP = 31;     // PASS B
400
                                ISEL = ISELS;
401
                                ASEL = 1'b1;
402
                                MREQ = ~&MOD;
403
                                WR = MREQ;
404
                                WE[1:0] = WRBIT;         // RASEL_HI/RASEL_LO
405
                                ISIZE = ISIZEW;
406
                        end
407
// --------------------------------  mov IMM to R --------------------------------
408
                        2: begin
409
                                WORD = FETCH[0][3];
410
                                RASEL = FETCH[0][2:0]; // destination
411
                                BBSEL = 2'b10;                          // imm
412
                                WE[1:0] = WBIT;          // RASEL_HI/RASEL_LO
413
                                ALUOP = 31;     // PASS B
414
                                ISEL = 2'b00;
415
                                MREQ = 1'b0;
416
                                ISIZE = WORD ? 3 : 2;
417
                        end
418
// --------------------------------  mov mem to/from ACC --------------------------------
419
                        3: begin
420
                                RASEL = 0; // ACC
421
                                BBSEL = 2'b01;          // reg
422
                                RBSEL = 0; // ACC
423
                                ALUOP = 31;     // PASS B
424
                                EAC = 4'b0110;
425
                                DISEL = 2'b00;
426
                                ASEL = 1'b0;
427
                                AEXT = 1'b0;
428
                                MREQ = 1'b1;
429
                                WR = FETCH[0][1];
430
                                WE[1:0] = WRBIT;         // IP, RASEL_HI/RASEL_LO
431
                                ISIZE = 3;
432
                                NOBP = 1'b1;
433
                        end
434
// --------------------------------  segment override prefix --------------------------------
435
                        4: begin
436
                                status = {CPUStatus[5:3], 1'b1, FETCH[0][4:3]};
437
                                MREQ = 1'b0;
438
                                ISIZE = 1;
439
                        end
440
// --------------------------------  rep prefix --------------------------------
441
                        5: begin
442
                                status = {CPUStatus[5], 1'b1, FETCH[0][0], CPUStatus[2:0]};
443
                                MREQ = 1'b0;
444
                                ISIZE = 1;
445
                        end
446
// --------------------------------  lock prefix --------------------------------
447
                        6: begin
448
                                status = {1'b1, CPUStatus[4:0]};
449
                                MREQ = 1'b0;
450
                                ISIZE = 1;
451
                        end
452
// --------------------------------  FF block --------------------------------
453
                        7:      begin
454
                                ISIZE = ISIZES;
455
                                case({FETCH[0][0], REG})
456
                // --------------------------------  push R/M --------------------------------
457
                                        4'b1110:
458
                                                if(!(&MOD || STAGE[0])) begin    // stage1, read data in TMP16
459
                                                        WE[3] = 1'b1;           // TMP16
460
                                                        DISEL = 2'b00;
461
                                                        ASEL = 1'b1;
462
                                                        IFETCH = 1'b0;
463
                                                end else begin          // stage2, push R/TMP16
464
                                                        RASEL = 3'b100;         // write SP
465
                                                        RSSEL = 2'b10;                  // SS
466
                                                        ALUOP = 31;     // PASS B
467
                                                        WE[1:0] = 2'b11;         // RASEL_HI/RASEL_LO
468
                                                        EAC = 4'b1000;                  // SP - 2
469
                                                        DISEL = 2'b10;                  // ADDR
470
                                                        WR = 1'b1;
471
                                                end
472
                // --------------------------------  inc/dec R/M --------------------------------
473
                                        4'b0000, 4'b1000, 4'b0001, 4'b1001: begin
474
                                                ASEL = 1'b1;
475
                                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
476
                                                        WE[3] = 1'b1;           // TMP16
477
                                                        DISEL = 2'b00;                  // DIN
478
                                                        IFETCH = 1'b0;
479
                                                end else begin                                          // stage2, execute and write            
480
                                                        BASEL = &MOD;
481
                                                        RASEL = RM;                     // destination
482
                                                        ALUOP = {2'b01, FETCH[1][5:3]};
483
                                                        MREQ = ~BASEL;
484
                                                        WR = MREQ;
485
                                                        WE = {3'b100, WRBIT};           // flags, IP, RASEL_HI, RASEL_LO
486
                                                end
487
                                        end
488
                // --------------------------------  call/jmp near R/M --------------------------------
489
                                        4'b1010, 4'b1100: begin
490
                                                if(!STAGE[0] && ~&MOD) begin     // stage1, load op in TMP16
491
                                                        ASEL = 1'b1;
492
                                                        WE[3] = 1'b1;           // TMP16
493
                                                        DISEL = 2'b00;                  // DIN
494
                                                        IFETCH = 1'b0;
495
                                                end else begin          // stage2, push IP, jump
496
                                                        RASEL = 3'b100;         // write SP
497
                                                        RSSEL = 2'b10;          // SS
498
                                                        ALUOP = 31;     // PASS B
499
                                                        EAC = 4'b1000;          // SP - 2
500
                                                        DISEL = 2'b10;          // ADDR
501
                                                        DOSEL = 2'b01;  // IP    
502
                                                        MREQ = REG[1];
503
                                                        WR = MREQ;
504
                                                        WE[1:0] = {WR, WR};
505
                                                        IPWSEL = 1'b0;          // ALU
506
                                                end
507
                                        end
508
                // --------------------------------  call/jmp far R/M --------------------------------
509
                                        4'b1011, 4'b1101: begin
510
                                                ALUOP = 31;                             // PASS B
511
                                                IRQ = &MOD;
512
                                                case({STAGE[1:0], REG[1]})
513
                                                        3'b001: begin   // stage1, push CS
514
                                                                RASEL = 3'b100;         // write SP
515
                                                                BBSEL = 2'b11;
516
                                                                RBSEL = 3'b001;                 // CS
517
                                                                RSSEL = 2'b10;                  // SS
518
                                                                EAC = 4'b1000;                  // SP - 2
519
                                                                DISEL = 2'b10;                  // ADDR
520
                                                                MREQ = ~IRQ;
521
                                                                WR = MREQ;
522
                                                                IFETCH = IRQ;
523
                                                                WE[1:0] = IRQ ? 2'b00 : 2'b11;                   // RASEL_HI/RASEL_LO
524
                                                                ISIZE = 0;
525
                                                        end
526
                                                        3'b011, 3'b000: begin   // stage2, read offset in FETCH, ADDR16 in TMP16
527
                                                                RASEL = 3'b100;                 // SP   - write SP to SP for getting ADDR16 to TMP16
528
                                                                BBSEL = 2'b01;
529
                                                                RBSEL = 3'b100;                 // SP
530
                                                                WE[3:0] = IRQ ? 4'b0000 : 4'b1011;                       // TMP16, RASEL_HI, RASEL_LO
531
                                                                ASEL = 1'b1;
532
                                                                DOSEL = 2'b11;                  // load FETCH with DIN
533
                                                                IFETCH = IRQ;
534
                                                                MREQ = ~IRQ;
535
                                                                ISIZE = 0;
536
                                                        end
537
                                                        3'b101, 3'b010: begin   // stage3, read CS
538
                                                                RASEL = 3'b001;                 // CS
539
                                                                WE[2] = 1'b1;                   // RSSEL
540
                                                                EAC = 4'b1011;                  // TMP16 + 2
541
                                                                DISEL = 2'b00;                  // DIN
542
                                                                IFETCH = 1'b0;
543
                                                        end
544
                                                        3'b111, 3'b100: begin   // stage4, push IP, jump
545
                                                                RASEL = 3'b100;         // write SP
546
                                                                BBSEL = 2'b10;          // imm
547
                                                                RSSEL = 2'b10;          // SS
548
                                                                EAC = 4'b1000;          // SP - 2
549
                                                                DISEL = 2'b10;          // ADDR
550
                                                                DOSEL = 2'b01;          // IP    
551
                                                                ISEL = 2'b01;
552
                                                                MREQ = REG[1];
553
                                                                WR = MREQ;
554
                                                                WE[1:0] = {WR, WR};
555
                                                                IPWSEL = 1'b0;          // ALU
556
                                                        end
557
                                                endcase
558
                                        end
559
                // --------------------------------  bad opcode --------------------------------
560
                                        default: begin
561
                                                MREQ = 1'b0;
562
                                                IRQ = 1'b1;
563
                                                ISIZE = 0;
564
                                        end
565
                                endcase
566
                        end
567
// --------------------------------  push R/SR --------------------------------
568
                        8: begin
569
                                WORD = 1'b1;
570
                                RASEL = 3'b100;         // write SP
571
                                BBSEL = {~FETCH[0][6], 1'b1};
572
                                RBSEL = FETCH[0][6] ? FETCH[0][2:0] : {1'b0, FETCH[0][4:3]}; // source
573
                                RSSEL = 2'b10;                  // SS
574
                                EAC = 4'b1000;                  // SP - 2
575
                                DISEL = 2'b10;                  // ADDR
576
                                WE[1:0] = 2'b11;         // RASEL_HI/RASEL_LO
577
                                ALUOP = 31;                             // PASS B
578
                                WR = 1'b1;
579
                                ISIZE = 1;
580
                        end
581
// --------------------------------  push Imm --------------------------------
582
                        9: begin
583
                                WORD = 1'b1;
584
                                RASEL = 3'b100;         // write SP
585
                                BBSEL = 2'b10;                  // imm
586
                                RSSEL = 2'b10;                  // SS
587
                                WE[1:0] = 2'b11;         // RASEL_HI/RASEL_LO
588
                                ALUOP = 31;                             // PASS B
589
                                EAC = 4'b1000;                  // SP - 2
590
                                DISEL = 2'b10;                  // ADDR
591
                                ISEL = 2'b00;
592
                                DEXT = FETCH[0][1];
593
                                WR = 1'b1;
594
                                ISIZE = FETCH[0][1] ? 2 : 3;
595
                        end
596
// --------------------------------  pusha --------------------------------
597
                        10: begin
598
                                WORD = 1'b1;
599
                                RASEL = 3'b100;         // write SP
600
                                RBSEL = STAGE[2:0];  // source
601
                                RSSEL = 2'b10;                  // SS
602
                                ALUOP = 31;                             // PASS B
603
                                EAC = 4'b1000;                  // SP - 2
604
                                DISEL = 2'b10;                  // ADDR
605
                                WR = 1'b1;
606
                                ISIZE = 1;
607
                                IFETCH = &STAGE[2:0];
608
                                WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
609
                        end
610
// --------------------------------  pop R/M --------------------------------
611
                        11:
612
                                case(REG)
613
                                        3'b000: begin
614
                                                ISIZE = ISIZES;
615
                                                if(!STAGE[0]) begin      // pop TMP16/REG
616
                                                        RASEL = RM;             // destination
617
                                                        RSSEL = 2'b10;                  // SS
618
                                                        EAC = 4'b1001;                  // SP
619
                                                        DISEL = 2'b00;                  // DIN
620
                                                        IFETCH = &MOD;
621
                                                        WE[3:0] = IFETCH ? 4'b0011 : 4'b1000;            // TMP16, RASEL_HI, RASEL_LO
622
                                                end else begin                  // R/M <- TMP16
623
                                                        RASEL = RM; // destination
624
                                                        BBSEL = 2'b00;                  // TMP
625
                                                        ALUOP = 31;                             // PASS B
626
                                                        ASEL = 1'b1;
627
                                                        MREQ = ~&MOD;
628
                                                        WR = MREQ;
629
                                                        WE[1:0] = WR ? 2'b00 : 2'b11;            // RASEL_HI, RASEL_LO
630
                                                end
631
                                        end
632
                                        default:        begin           // bad opcode
633
                                                MREQ = 1'b0;
634
                                                ISIZE = 0;
635
                                                IRQ = 1'b1;
636
                                        end
637
                                endcase
638
// --------------------------------  pop R / SR --------------------------------
639
                        12: begin
640
                                WORD = 1'b1;
641
                                RASEL = FETCH[0][6] ? FETCH[0][2:0] : {1'b0, FETCH[0][4:3]}; // destination
642
                                RSSEL = 2'b10;                  // SS
643
                                WE[2:0] = FETCH[0][6] ? 3'b011 : 3'b100;          // RSSEL, RASEL_HI, RASEL_LO
644
                                EAC = 4'b1001;                  // SP
645
                                DISEL = 2'b00;                  // DIN
646
                                ISIZE = 1;
647
                        end
648
// --------------------------------  popa --------------------------------
649
                        13: begin
650
                                RASEL = ~STAGE[2:0]; // destination
651
                                RSSEL = 2'b10;                  // SS
652
                                EAC = 4'b1001;                  // SP
653
                                DISEL = 2'b00;                  // DIN
654
                                ISIZE = 1;
655
                                IFETCH = &STAGE[2:0];
656
                                WE[1:0] = {STAGE[2:0] == 3'b011 ? 2'b00 : 2'b11};         // IP, RASEL_HI, RASEL_LO (skip SP)
657
                        end
658
// --------------------------------  xchg R with R/M/Acc --------------------------------
659
                        14: begin
660
                                WORD = FETCH[0][0] | FETCH[0][4];
661
                                ASEL = 1'b1;
662
                                MREQ = ~&MOD && !FETCH[0][4];
663
                                ALUOP = 31;                             // PASS B
664
                                ISIZE = FETCH[0][4] ? 1 : ISIZES;
665
                                if(!STAGE[0]) begin              // stage1, R/M/Acc -> REG -> TMP16
666
                                        BASEL = 1'b1;
667
                                        RASEL = FETCH[0][4] ? FETCH[0][2:0] : REG; // destination
668
                                        BBSEL = 2'b01;          // reg
669
                                        RBSEL = FETCH[0][4] ? 3'b000 : RM; // source
670
                                        DISEL = {1'b0, !MREQ};
671
                                        WE[1:0] = WBIT;          // RASEL_HI, RASEL_LO
672
                                        IFETCH = ~|FETCH[0][2:0]; // nop
673
                                end else begin          // stage2, TMP16 -> R/M/Acc
674
                                        RASEL = FETCH[0][4] ? 3'b000 : RM; // destination
675
                                        BBSEL = 2'b00;          // TMP16
676
                                        WR = MREQ;
677
                                        WE[1:0] = WRBIT;         // RASEL_HI, RASEL_LO
678
                                end
679
                        end
680
// --------------------------------  in --------------------------------
681
                        15:     begin
682
                                RASEL = 3'b000; // AX/AL
683
                                WE[1:0] = {WORD, 1'b1};          // RASEL_HI, RASEL_LO
684
                                DISEL = 2'b00;  //DIN
685
                                MREQ = 1'b0;
686
                                ISIZE = FETCH[0][3] ? 1 : 2;
687
                                EAC = 4'b1111;
688
                                NULLSEG = 1'b1;
689
                        end
690
// --------------------------------  out --------------------------------
691
                        16:     begin
692
                                DOSEL = 2'b11;  // AX
693
                                MREQ = 1'b0;
694
                                WR = 1'b1;
695
                                ISIZE = FETCH[0][3] ? 1 : 2;
696
                                EAC = 4'b1111;
697
                                NULLSEG = 1'b1;
698
                        end
699
// --------------------------------  xlat --------------------------------
700
                        17: begin
701
                                WORD = 1'b0;
702
                                RASEL = 3'b000;         // AL
703
                                WE[0] = 1'b1;            // RASEL_LO
704
                                EAC = 4'b1010;          // XLAT
705
                                DISEL = 2'b00;          // DIN 
706
                                ISIZE = 1;
707
                                NOBP = 1'b1;    // for RSSEL
708
                        end
709
// --------------------------------  lea --------------------------------
710
                        18: begin
711
                                RASEL = REG;                    // destination
712
                                WE[1:0] = {&MOD ? 2'b00 : 2'b11};                // RASEL_HI, RASEL_LO
713
                                DISEL = 2'b10;                  // EA
714
                                ASEL = 1'b1;
715
                                MREQ = 1'b0;
716
                                ISIZE = ISIZES;
717
                        end
718
// --------------------------------  lds, les --------------------------------
719
                        19: begin
720
                                WORD = 1'b1;
721
                                DISEL = 2'b00;                  // DIN
722
                                ASEL = 1'b1;
723
                                if(!STAGE[0]) begin              // stage1, load offset
724
                                        RASEL = REG;                    // destination
725
                                        IFETCH = &MOD;                  // bad opcode
726
                                        IRQ = IFETCH;
727
                                        ISIZE = 0;
728
                                        WE[3:0] = {2'b10, IFETCH ? 2'b00 : 2'b11};               // TMP16, RASEL_HI, RASEL_LO
729
                                end else begin                          // stage2, load segment
730
                                        RASEL = FETCH[0][0] ? 3'b011 : 3'b000; // ds/es
731
                                        WE[2] = 1'b1;                   // RSSEL
732
                                        EAC = 4'b1011;                  // TMP16 + 2
733
                                        ISIZE = ISIZES;
734
                                end
735
                        end
736
// --------------------------------  lahf, sahf --------------------------------
737
                        20: begin
738
                                WORD = 1'b0;
739
                                RASEL = 3'b100;                 // AH
740
                                WE = {!FETCH[0][0], 2'b00, FETCH[0][0], 1'b0};              // FLAGS, IP, RASEL_HI
741
                                ALUOP = FETCH[0][0] ? 30 : 31;                    // PASS/STORE FLAGS
742
                                MREQ = 1'b0;
743
                                ISIZE = 1;
744
                        end
745
// --------------------------------  pushf --------------------------------
746
                        21: begin
747
                                WORD = 1'b1;
748
                                RASEL = 3'b100;         // write SP
749
                                RSSEL = 2'b10;                  // SS
750
                                WE[1:0] = 2'b11;
751
                                ALUOP = 30;                             // pass flags
752
                                EAC = 4'b1000;                  // SP - 2
753
                                DISEL = 2'b10;                  // ADDR
754
                                WR = 1'b1;
755
                                ISIZE = 1;
756
                        end
757
// --------------------------------  popf --------------------------------
758
                        22: begin
759
                                ISIZE = 1;
760
                                IFETCH = STAGE[0];
761
                                if(!STAGE[0]) begin      // stage1, pop TMP16
762
                                        RSSEL = 2'b10;                  // SS
763
                                        WE[3] = 1'b1;                   // TMP16
764
                                        EAC = 4'b1001;                  // SP
765
                                        DISEL = 2'b00;
766
                                end else begin                  // stage2, TMP16 to FLAGS
767
                                        BASEL = 1'b0;
768
                                        WE[4] = 1'b1;                   // flags
769
                                        ALUOP = 31;                             // store flags
770
                                        MREQ = 1'b0;
771
                                end
772
                        end
773
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp, test R/M with R --------------------------------
774
                        23: begin
775
                                ASEL = 1'b1;
776
                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
777
                                        WE[3] = 1'b1;           // TMP16
778
                                        DISEL = 2'b00;                  // DIN
779
                                        IFETCH = 1'b0;
780
                                end else begin                                          // stage2, execute and write                    
781
                                        ALUOP = {2'b00, FETCH[0][2] ? 3'b100 : FETCH[0][5:3]};    // test = and
782
                                        MREQ = ~&MOD & ~|FETCH[0][2:1] & ~&FETCH[0][5:3];         // no cmp or test
783
                                        WR = MREQ;
784
                                        WE = {3'b100, WR | &FETCH[0][5:3] | FETCH[0][2] ? 2'b00 : WBIT};          // flags, RASEL_HI, RASEL_LO
785
                                        ISIZE = ISIZES;
786
                                end
787
                        end
788
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp R/M with Imm --------------------------------
789
                        24: begin
790
                                ASEL = 1'b1;
791
                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
792
                                        WE[3] = 1'b1;                   // TMP16
793
                                        DISEL = 2'b00;                  // DIN
794
                                        IFETCH = 1'b0;
795
                                end else begin                                          // stage2, execute and write            
796
                                        BASEL = &MOD;
797
                                        RASEL = RM;
798
                                        BBSEL = 2'b10;                  // imm
799
                                        ALUOP = {2'b00, FETCH[1][5:3]};
800
                                        ISEL = ISELS;
801
                                        DEXT = FETCH[0][1];
802
                                        MREQ = ~BASEL & ~&FETCH[1][5:3];
803
                                        WR = MREQ;
804
                                        WE = {3'b100, WR  | &FETCH[1][5:3]? 2'b00 : WBIT};              // flags, RASEL_HI, RASEL_LO
805
                                        ISIZE = ISIZEI;
806
                                end
807
                        end
808
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp, test Acc with Imm --------------------------------
809
                        25: begin // test
810
                                BASEL = 1'b1;
811
                                RASEL = 3'b000;         // acc
812
                                BBSEL = 2'b10;                                  // imm
813
                                WE = {3'b100, &FETCH[0][5:3] | FETCH[0][7] ? 2'b00 : WBIT};               // flags, RASEL_HI, RASEL_LO
814
                                ALUOP = {2'b00, FETCH[0][7] ? 3'b100 : FETCH[0][5:3]};
815
                                ISEL = 2'b00;
816
                                MREQ = 1'b0;
817
                                ISIZE = WORD ? 3 : 2;
818
                        end
819
// --------------------------------  inc/dec R16 --------------------------------
820
                        26: begin
821
                                WORD = 1'b1;
822
                                BASEL = 1'b1;
823
                                RASEL = FETCH[0][2:0]; // destination
824
                                WE = 5'b10011;          // flags, RASEL_HI, RASEL_LO
825
                                ALUOP = {2'b01, FETCH[0][5:3]};
826
                                MREQ = 1'b0;
827
                                ISIZE = 1;
828
                        end
829
// --------------------------------  test/???/not/neg/mul/imul/div/idiv --------------------------------
830
                        27: begin
831
                                ASEL = 1'b1;
832
                                case(REG)
833
                                        3'b000: begin           // TEST R/M with Imm
834
                                                if(!(&MOD || |STAGE[1:0])) begin // stage1, load op from memory in TMP16
835
                                                        DISEL = 2'b00;
836
                                                        WE[3] = 1'b1;                                   // mem in TMP16
837
                                                        IFETCH = 1'b0;
838
                                                end else begin
839
                                                        BASEL = &MOD;
840
                                                        RASEL = RM;     // destination
841
                                                        BBSEL = 2'b10;                  // imm
842
                                                        ALUOP = 5'b00100;               // AND
843
                                                        ISEL = ISELS;
844
                                                        MREQ = 1'b0;
845
                                                        WE[4] = 1'b1;                   // flags
846
                                                        ISIZE = ISIZEW;
847
                                                end
848
                                        end
849
                                        3'b010, 3'b011: begin   // NOT/NEG R/M
850
                                                if(!(&MOD || |STAGE[1:0])) begin // stage1, load op from memory in TMP16
851
                                                        DISEL = 2'b00;
852
                                                        WE[3] = 1'b1;                                   // mem in TMP16
853
                                                        IFETCH = 1'b0;
854
                                                end else begin
855
                                                        BASEL = &MOD;
856
                                                        RASEL = RM;     // destination
857
                                                        ALUOP = {2'b01, REG};
858
                                                        MREQ = ~&MOD;
859
                                                        WR = MREQ;
860
                                                        WE = {REG[0], 2'b00, WRBIT};             // flags, RASEL_HI, RASEL_LO
861
                                                        ISIZE = ISIZES;
862
                                                end
863
                                        end
864
                                        3'b100, 3'b101: begin   // MUL, IMUL
865
                                                ISIZE = ISIZES;
866
                                                ALUOP = {4'b1000, REG[0]};               // BASEL = FETCH[0][1] = 1
867 10 ndumitrach
                                                WE[4] = 1'b1;                   // fix MUL/IMUL 8bit flags bug
868 2 ndumitrach
                                                case(STAGE[1:0])
869
                                                        2'b00: begin            // stage1, RA -> TMP16, RB (mem) -> FETCH
870
                                                                MREQ = ~&MOD;
871
                                                                DISEL = {1'b0, MREQ};
872
                                                                RASEL = 3'b000; // AX
873
                                                                DOSEL = 2'b11;
874
                                                                IFETCH = 1'b0;
875
                                                        end
876 10 ndumitrach
                                                        2'b01: begin                    // stage2, write AX
877
                                                                WE[1:0] = 2'b11; // flags, RASEL_HI, RASEL_LO 
878 2 ndumitrach
                                                                RASEL = 3'b000; // AX
879
                                                                MREQ = 1'b0;
880
                                                                IFETCH = ~FETCH[0][0];
881
                                                        end
882
                                                        2'b10: begin                    // stage 2, write DX
883 10 ndumitrach
                                                                WE[1:0] = 2'b11; // flags, RASEL_HI, RASEL_LO    
884 2 ndumitrach
                                                                RASEL = 3'b010; // DX
885
                                                                MREQ = 1'b0;
886
                                                        end
887
                                                endcase
888
                                        end
889
                                        3'b110, 3'b111: begin   // div, idiv
890
                                                ISIZE = ISIZES;
891
                                                IRQL = 3'b000;  // divide overflow
892
                                                MREQ = 1'b0;
893
                                                case({DIVEND, STAGE[1:0]})
894
                                                        3'b000: begin           // stage1, RB (mem) -> FETCH
895
                                                                MREQ = ~&MOD;
896
                                                                DISEL = {1'b0, MREQ};
897
                                                                DOSEL = 2'b11;
898
                                                                IFETCH = 1'b0;
899
                                                                DIVSTAGE = ~QSGN;
900
                                                        end
901
                                                        3'b001: begin   // stage2, pre dec AX
902
//                                                              WORD = 1'b1;
903
                                                                RASEL = 3'b000; // AX
904
                                                                WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
905
                                                                ALUOP = 5'b01001;               // DEC
906
                                                                IFETCH = 1'b0;
907
                                                                ALUSTAGE = ~(DIVQSGN && FETCH[0][0] && COUT);
908
                                                        end
909
                                                        3'b010: begin // stage3, pre dec DX
910
                                                                RASEL = 3'b010;         // DX
911
                                                                WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
912
                                                                ALUOP = 5'b01001;               // DEC
913
                                                                IFETCH = 1'b0;
914
                                                        end
915
                                                        3'b011, 3'b111: begin   // stage4, div loop
916
                                                                RASEL = WORD ? 3'b010 : 3'b100; // DX/AH
917
                                                                BBSEL = 2'b10;          // imm
918
                                                                WE[1:0] = {1'b1, WORD};          // RASEL_HI, RASEL_LO
919
                                                                ALUOP = {2'b00, DIVSGN ? 3'b000 : 3'b101};      // add/sub
920
                                                                ISEL = 2'b01;
921
                                                                DIVSTAGE = ~DIVEND;
922
                                                                ALUSTAGE = ~DIVEND | ~DIVQSGN;
923
                                                                DIVOP = 1'b1;
924 8 ndumitrach
//                                                              IRQ = ~|STAGE[6:3] & DIVC & ~(STAGE[2] & DIVSGN); - DIV bug, fixed 23Dec2012
925
                                                                IRQ = ~|STAGE[6:3] & DIVC & (~STAGE[2] | (~DIVSGN & IDIV)); // early overflow for positive quotient
926 2 ndumitrach
                                                                IFETCH = (DIVEND && ~DIVQSGN && ~DIVRSGN) || IRQ;
927
                                                        end
928
                                                        3'b100: begin           // stage5, post inc R
929
                                                                RASEL = WORD ? 3'b010 : 3'b100; // DX/AH
930
                                                                WE[1:0] = {1'b1, WORD};          // RASEL_HI, RASEL_LO
931
                                                                ALUOP = 5'b01000;       // inc
932
                                                                IFETCH = ~DIVSGN;
933
                                                        end
934
                                                        default: begin  // stage6, post inc Q
935
                                                                RASEL = 3'b000; // AX/AL
936
                                                                WE[1:0] = {WORD, 1'b1};          // RASEL_HI, RASEL_LO
937
                                                                ALUOP = 5'b01000;       // inc
938
                                                                IRQ = SOUT ^ DIVSGN;    // overflow for negative quotient
939
                                                        end
940
                                                endcase
941
                                        end
942
                                        default: begin          // bad opcode
943
                                                MREQ = 1'b0;
944
                                                ISIZE = 0;
945
                                                IRQ = 1'b1;
946
                                        end
947
                                endcase
948
                        end
949
// --------------------------------  imul imm --------------------------------
950
                        28: begin
951
                                ASEL = 1'b1;
952
                                if(!STAGE[0]) begin      // stage1, load op from memory (or RA) in TMP16
953
                                        RASEL = RM;
954
                                        DISEL = 2'b00;                  // DIN
955
                                        DOSEL = 2'b11;
956
                                        ISEL = ISELS;
957
                                        DEXT = FETCH[0][1];
958
                                        BBSEL = 2'b10;                  // imm
959
                                        MREQ = ~&MOD;
960
                                        WE[3] = MREQ;                   // TMP16
961
                                        IFETCH = 1'b0;
962
                                end else begin                                          // stage2, execute and write            
963
                                        RASEL = REG;
964
                                        ALUOP = 5'b10001;               // imul
965
                                        MREQ = 1'b0;
966
                                        WE = 5'b10011;          // flags, RASEL_HI, RASEL_LO
967
                                        ISIZE = ISIZEI;
968
                                end
969
                        end
970
// --------------------------------  aad --------------------------------
971
                        29: begin
972
                                MREQ = 1'b0;
973
                                WORD = 1'b0;
974
                                BASEL = 1'b1;
975
                                IFETCH = &STAGE[1:0];
976
                                case(STAGE[1:0])
977
                                        2'b00: begin    // stage1, load AH in TMP16, move imm in FETCH
978
                                                RASEL = 3'b100;         // AH
979
                                                DISEL = 2'b00;                  // DIN
980
                                                DOSEL = 2'b11;                  // write FETCH
981
                                                ISEL = 2'b00;                   // RB -> FETCH
982
                                                BBSEL = 2'b10;                  // imm
983
                                        end
984
                                        2'b01: begin                            // stage2, TMP16 <- TMP16 * 10
985
                                                ALUOP = 5'b10000;               // mul
986
                                                WE[3] = 1'b1;                   // TMP16
987
                                        end
988
                                        2'b10: begin                    // stage3, AL <- TMP16 + AL
989
                                                RASEL = 3'b000;         // AL
990
                                                BBSEL = 2'b00;          // TMP16
991
                                                WE = 5'b10001;          // flags, RASEL_LO
992
                                                ALUOP = 5'b00000;       // ADD
993
                                        end
994
                                        2'b11: begin                    // stage4, AH <- 0
995
                                                RASEL = 3'b100;         // AH
996
                                                RBSEL = 3'b100;         // AH
997
                                                WE[1] = 1'b1;           // RASEL_HI
998
                                                ALUOP = 5'b00101;       // SUB
999
                                                ISIZE = 2;
1000
                                        end
1001
                                endcase
1002
                        end
1003
// --------------------------------  daa, das, aaa, aas --------------------------------
1004
                        30: begin
1005
                                WORD = FETCH[0][4];
1006
                                RASEL = 3'b000;         // AX,AL
1007
                                WE = {3'b100, FETCH[0][4], 1'b1};                // flags, RASEL_HI, RASEL_LO
1008
                                ALUOP = {2'b01, FETCH[0][5:3]};
1009
                                MREQ = 1'b0;
1010
                                ISIZE = 1;
1011
                        end
1012
// --------------------------------  shift/rot --------------------------------
1013
                        31: begin       // imm
1014
                                ALUOP = {4'b1110, FETCH[0][4:1] != 4'b1000};
1015
                                ASEL = 1'b1;
1016
                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
1017
                                        WE[3] = 1'b1;                   // TMP16
1018
                                        DISEL = 2'b00;                  // DIN
1019
                                        IFETCH = 1'b0;
1020
                                end else begin                                          // stage2, execute and write            
1021
                                        BASEL = &MOD && ~|STAGE[2:1];
1022
                                        RASEL = RM;
1023
                                        BBSEL = FETCH[0][1] ? 2'b01 : 2'b10; // imm/reg
1024
                                        RBSEL = 3'b001;         // CL
1025
                                        ISEL = ISELS;
1026
                                        IRQ = REG == 3'b110;
1027
                                        MREQ = ~&MOD && ~NULLSHIFT && ~ALUCONT && ~IRQ;
1028
                                        WR = MREQ;
1029
                                        WE = NULLSHIFT || IRQ ? 5'b00000 : ALUCONT ? 5'b11000 : {3'b100, WRBIT};                // flags, TMP16, RASEL_HI, RASEL_LO
1030
                                        IFETCH = ~ALUCONT || IRQ;
1031
                                        ALUSTAGE = 1'b1;
1032
                                        if(IRQ) ISIZE = 0;
1033
                                        else case({|FETCH[0][4:1], DISP16, AEXT})
1034
                                                3'b100: ISIZE = 2;
1035
                                                3'b000, 3'b101: ISIZE = 3;
1036
                                                3'b001, 3'b110: ISIZE = 4;
1037
                                                default: ISIZE = 5;
1038
                                        endcase
1039
                                end
1040
                        end
1041
// --------------------------------  (rep)movs --------------------------------
1042
                        32: begin
1043
                                BASEL = 1'b1;
1044
                                AEXT = 1'b0;
1045
                                DISP16 = 1'b0;
1046
                                NOBP = 1'b1;    // for RSSEL
1047
                                if(!STAGE[0]) begin              // stage1, read DS:[SI] in TMP16, inc/dec SI
1048
                                        RASEL = 3'b110;         // SI
1049
                                        ALUOP = {4'b0100, FLAGS[10]};
1050
                                        EAC = 4'b0100;          // SI+DISP
1051
                                        DISEL = 2'b11;          // ALU 16bit
1052
                                        IFETCH = RCXZ;  // REP & CX==0
1053
                                        MREQ = ~RCXZ;
1054
                                        WE = IFETCH ? 5'b00000 : 5'b01011;              // TMP16, RASEL_HI, RASEL_LO
1055
                                end else begin                  // stage2, write TMP16 in ES:[DI], inc/dec DI, dec CX
1056
                                        RASEL = 3'b111;         // DI
1057
                                        RSSEL = 2'b00;          // ES
1058
                                        WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
1059
                                        ALUOP = {4'b0100, FLAGS[10]};
1060
                                        EAC = 4'b0101;          // DI + DISP
1061
                                        DISEL = 2'b11;          // ALU 16bit
1062
                                        DOSEL = 2'b10;          // TMP16                
1063
                                        WR = 1'b1;
1064
                                        IFETCH = NRORCXLE1;  // not REP or CX<=1
1065
                                        DECCX = CPUStatus[4];
1066
                                        REPINT = 1'b1;
1067
                                end
1068
                                ISIZE = IFETCH ? 1 : 0;
1069
                        end
1070
// --------------------------------  (rep)cmps --------------------------------
1071
                        33: begin
1072
                                DISP16 = 1'b0;
1073
                                AEXT = 1'b0;
1074
                                NOBP = 1'b1;    // for RSSEL
1075
                                case(STAGE[1:0])
1076 5 ndumitrach
                                        2'b00: begin            // stage1, read ES:[DI] in FETCH[3:2], inc/dec DI
1077 2 ndumitrach
                                                RASEL = 3'b111;         // SI
1078
                                                RSSEL = 2'b00;          // ES
1079
                                                ALUOP = {4'b0100, FLAGS[10]};
1080
                                                EAC = 4'b0101;          // DI+DISP
1081
                                                DISEL = 2'b11;          // ALU 16bit
1082
                                                DOSEL = 2'b11;          // read data to FETCH
1083 5 ndumitrach
                                                IFETCH = RCXZ;//(~|CXZ || (CPUStatus[3] ^ TZF));        // REP & CX==0
1084
                                                MREQ = ~RCXZ;
1085 2 ndumitrach
                                                WE[1:0] = IFETCH ? 2'b00 : 2'b11;                // RASEL_HI, RASEL_LO
1086
                                        end
1087
                                        2'b01: begin            // stage2, read DS:[SI] in TMP16, inc/dec SI
1088
                                                RASEL = 3'b110;         // DI
1089
                                                ALUOP = {4'b0100, FLAGS[10]};
1090
                                                EAC = 4'b0100;          // SI+DISP
1091
                                                DISEL = 2'b11;          // ALU 16bit
1092
                                                IFETCH = 1'b0;
1093
                                                WE[3:0] = 4'b1011;               // RASEL_HI, RASEL_LO
1094
                                        end
1095 5 ndumitrach
                                        2'b10: begin            // stage3, compare TMP16 with imm, set flags, dec CX
1096 2 ndumitrach
                                                BASEL = 1'b0;                   // TMP16
1097
                                                BBSEL = 2'b10;                  // imm
1098
                                                ISEL = 2'b01;
1099
                                                WE[4] = 1'b1;                   // flags
1100
                                                ALUOP = 5'b00111;               // cmp
1101
                                                MREQ = 1'b0;
1102 5 ndumitrach
                                                IFETCH = NRORCXLE1 | (CPUStatus[3] ^ CMPS);
1103 2 ndumitrach
                                                DECCX = CPUStatus[4];
1104
                                                ALUSTAGE = 1'b1;
1105
                                                REPINT = 1'b1;
1106
                                        end
1107
                                endcase
1108
                                ISIZE = IFETCH ? 1 : 0;
1109
                        end
1110
// --------------------------------  (rep)scas --------------------------------
1111
                        34: begin
1112
                                DISP16 = 1'b0;
1113
                                AEXT = 1'b0;
1114
                                if(!STAGE[0]) begin      // stage1, read ES:[DI] in TMP16, inc/dec DI
1115
                                        RASEL = 3'b111;         // DI
1116
                                        RSSEL = 2'b00;          // ES
1117
                                        ALUOP = {4'b0100, FLAGS[10]};
1118
                                        EAC = 4'b0101;          // DI+DISP
1119
                                        DISEL = 2'b11;          // ALU 16bit
1120 5 ndumitrach
                                        IFETCH = RCXZ;//(~|CXZ || (CPUStatus[3] ^ TZF));        // REP & CX==0
1121
                                        MREQ = ~RCXZ;
1122 2 ndumitrach
                                        WE[3:0] = IFETCH ? 4'b0000 : 4'b1011;            // TMP16, RASEL_HI, RASEL_LO
1123
                                end else begin  //stage2, compare AL/AX with TMP16, set flags, dec CX
1124
                                        RASEL = 3'b000;         // AL/AX
1125
                                        BBSEL = 2'b00;                  // TMP16
1126
                                        WE[4] = 1'b1;                   // flags
1127
                                        ALUOP = 5'b00111;               // cmp
1128
                                        MREQ = 1'b0;
1129 5 ndumitrach
                                        IFETCH = NRORCXLE1 | (CPUStatus[3] ^ SCAS);
1130 2 ndumitrach
                                        DECCX = CPUStatus[4];
1131
                                        REPINT = 1'b1;
1132
                                end
1133
                                ISIZE = IFETCH ? 1 : 0;
1134
                        end
1135
// --------------------------------  (rep)lods --------------------------------
1136
                        35: begin
1137
                                BASEL = 1'b1;
1138
                                DISP16 = 1'b0;
1139
                                AEXT = 1'b0;
1140
                                NOBP = 1'b1;    // for RSSEL
1141
                                if(!STAGE[0]) begin              // stage1, read DS:[SI] in AL/AX
1142
                                        RASEL = 3'b000;         // AX
1143
                                        EAC = 4'b0100;          // SI+DISP
1144
                                        DISEL = 2'b00;          // DIN
1145
                                        IFETCH = RCXZ;  // REP & CX==0
1146
                                        MREQ = ~RCXZ;
1147
                                        WE[1:0] = IFETCH ? 2'b00 : {WORD, 1'b1};         // RASEL_HI, RASEL_LO
1148
                                end else begin          // stage2, inc/dec SI, dec CX
1149
                                        RASEL = 3'b110;         // SI
1150
                                        ALUOP = {4'b0100, FLAGS[10]};
1151
                                        DISEL = 2'b11;          // ALU 16bit
1152
                                        IFETCH = NRORCXLE1;  // nor REP or CX<=1
1153
                                        MREQ = 1'b0;
1154
                                        WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
1155
                                        DECCX = CPUStatus[4];
1156
                                        REPINT = 1'b1;
1157
                                end
1158
                                ISIZE = IFETCH ? 1 : 0;
1159
                        end
1160
// --------------------------------  (rep)stos --------------------------------
1161
                        36: begin  // stage1, write AL/AX in ES:[DI], inc/dec DI, dec CX
1162
                                BASEL = 1'b1;
1163
                                DISP16 = 1'b0;
1164
                                AEXT = 1'b0;
1165
                                RASEL = 3'b111;         // DI
1166
                                RSSEL = 2'b00;          // ES
1167
                                ALUOP = {4'b0100, FLAGS[10]};
1168
                                EAC = 4'b0101;          // DI + DISP
1169
                                DISEL = 2'b11;          // ALU 16bit
1170
                                DOSEL = 2'b11;          // AX
1171
                                IFETCH = NRORCXLE1;  // not REP or CX<=1
1172
                                MREQ = ~RCXZ;
1173
                                WR = ~RCXZ;
1174
                                WE[1:0] = {MREQ, MREQ};          // RASEL_HI, RASEL_LO
1175
                                DECCX = CPUStatus[4] && |CXZ;
1176
                                REPINT = 1'b1;
1177
                                ISIZE = IFETCH ? 1 : 0;
1178
                        end
1179
// --------------------------------  (rep)ins --------------------------------
1180
                        37: begin
1181
                                BASEL = 1'b1;
1182
                                DISP16 = 1'b0;
1183
                                AEXT = 1'b0;
1184
                                if(!STAGE[0]) begin      // stage1, input in TMP16
1185
                                        WE[3] = 1'b1;           // TMP16
1186
                                        DISEL = 2'b00;          //DIN
1187
                                        IFETCH = RCXZ;          // REP & CX==0
1188
                                        MREQ = 1'b0;
1189
                                        EAC = {~RCXZ, 3'b111};
1190
                                        NULLSEG = 1'b1;
1191
                                end else begin                  // stage2, write TMP16 in ES:[DI], inc/dec DI, dec CX
1192
                                        RASEL = 3'b111;         // DI
1193
                                        RSSEL = 2'b00;          // ES
1194
                                        WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
1195
                                        ALUOP = {4'b0100, FLAGS[10]};
1196
                                        EAC = 4'b0101;          // DI + DISP
1197
                                        DISEL = 2'b11;          // ALU 16bit
1198
                                        DOSEL = 2'b10;          // TMP16                
1199
                                        WR = 1'b1;
1200
                                        IFETCH = NRORCXLE1;  // not REP or CX<=1
1201
                                        DECCX = CPUStatus[4];
1202
                                        REPINT = 1'b1;
1203
                                end
1204
                                ISIZE = IFETCH ? 1 : 0;
1205
                        end
1206
// --------------------------------  (rep)outs --------------------------------
1207
                        38: begin
1208
                                BASEL = 1'b1;
1209
                                DISP16 = 1'b0;
1210
                                NOBP = 1'b1;    // for RSSEL
1211
                                if(!STAGE[0]) begin              // stage1, read DS:[SI] in TMP16, inc/dec SI
1212
                                        AEXT = 1'b0;            // tweak for speed (can be moved outside <if>)
1213
                                        RASEL = 3'b110;         // SI
1214
                                        ALUOP = {4'b0100, FLAGS[10]};
1215
                                        EAC = 4'b0100;          // SI+DISP
1216
                                        DISEL = 2'b11;          // ALU 16bit
1217
                                        IFETCH = RCXZ;  // REP & CX==0
1218
                                        MREQ = ~RCXZ;
1219
                                        WE[3:0] = IFETCH ? 4'b0000 : 4'b1011;            // TMP16, RASEL_HI, RASEL_LO
1220
                                end else begin                  // stage2, out TMP16 at port DX, dec CX
1221
                                        DOSEL = 2'b10;          // TMP16                
1222
                                        MREQ = 1'b0;
1223
                                        EAC = 4'b1111;
1224
                                        WR = 1'b1;
1225
                                        IFETCH = NRORCXLE1;  // not REP or CX<=1
1226
                                        DECCX = CPUStatus[4];
1227
                                        REPINT = 1'b1;
1228
                                        NULLSEG = 1'b1;
1229
                                end
1230
                                ISIZE = IFETCH ? 1 : 0;
1231
                        end
1232
// --------------------------------  call/jmp direct near --------------------------------
1233
                        39: begin       // jump long
1234
                                WORD = 1'b1;
1235
                                ALUOP = 0;                       // ADD
1236
                                DISEL = 2'b10;          // ADDR
1237
                                ISIZE = FETCH[0][1] ? 2 : 3;
1238
                                RASEL = 3'b100; // write SP
1239
                                RSSEL = 2'b10;          // SS
1240
                                DOSEL = 2'b01;          // IP
1241
                                EAC = 4'b1000;          // SP - 2
1242
                                BBSEL = 2'b10;          // imm
1243
                                ISEL = 2'b00;
1244
                                DEXT = FETCH[0][1];
1245
                                MREQ = !FETCH[0][0];
1246
                                WR = MREQ;
1247
                                WE[1:0] = FETCH[0][0] ? 2'b00 : 2'b11;             // RASEL_HI/RASEL_LO
1248
                                IPWSEL = 1'b0;          // ALU
1249
                        end
1250
// --------------------------------  call/jmp far imm --------------------------------
1251
                        40: begin
1252
                                WORD = 1'b1;
1253
                                ALUOP = 31;                             // PASS B
1254
                                case({STAGE[1:0], FETCH[0][6]})
1255
                                        3'b000: begin   // stage1, push CS
1256
                                                RASEL = 3'b100;         // write SP
1257
                                                BBSEL = 2'b11;
1258
                                                RBSEL = 3'b001;                 // CS
1259
                                                RSSEL = 2'b10;                  // SS
1260
                                                EAC = 4'b1000;                  // SP - 2
1261
                                                DISEL = 2'b10;                  // ADDR
1262
                                                WR = 1'b1;
1263
                                                IFETCH = 1'b0;
1264
                                                WE[1:0] = 2'b11;                 // RASEL_HI/RASEL_LO
1265
                                        end
1266
                                        3'b010, 3'b001: begin   // stage2, load CS
1267
                                                RASEL = 3'b001;         // CS
1268
                                                BBSEL = 2'b10;          // imm
1269
                                                WE[2] = 1'b1;           // RSSEL
1270
                                                ISEL = 2'b10;
1271
                                                MREQ = 1'b0;
1272
                                                IFETCH = 1'b0;
1273
                                        end
1274
                                        3'b100, 3'b011: begin   // stage3, push IP, load IP
1275
                                                RASEL = 3'b100;         // write SP
1276
                                                BBSEL = 2'b10;          // imm
1277
                                                RSSEL = 2'b10;          // SS
1278
                                                EAC = 4'b1000;          // SP - 2
1279
                                                DISEL = 2'b10;          // ADDR
1280
                                                DOSEL = 2'b01;          // IP    
1281
                                                ISEL = 2'b00;
1282
                                                MREQ = FETCH[0][4];
1283
                                                WR = MREQ;
1284
                                                WE[1:0] = {WR, WR};
1285
                                                IPWSEL = 1'b0;          // ALU
1286
                                                ISIZE = 5;
1287
                                        end
1288
                                endcase
1289
                        end
1290
// --------------------------------  ret near --------------------------------
1291
                        41: begin
1292 11 ndumitrach
                                WORD = 1'b1;            // fix RET n alignment bug - 03Apr2013
1293 2 ndumitrach
                                ISIZE = FETCH[0][0] ? 1 : 3;
1294
                                IFETCH = STAGE[0];
1295
                                ALUOP = 31;                     // PASS B
1296
                                if(!STAGE[0]) begin      // stage1, pop TMP16
1297
                                        RSSEL = 2'b10;                  // SS
1298
                                        WE[3] = 1'b1;                   // TMP16
1299
                                        ASEL = 1'b0;
1300
                                        AEXT = 1'b0;
1301
                                        DISP16 = 1'b1;
1302
                                        EAC = {1'b1, !FETCH[0][0], 2'b01};                        // SP + 2 (+ imm) 
1303
                                        DISEL = 2'b00;
1304
                                end else begin                  // stage2, TMP16 to IP
1305
                                        BBSEL = 2'b00;          // TMP16        
1306
                                        IPWSEL = 1'b0;          // ALU
1307
                                        MREQ = 1'b0;
1308
                                end
1309
                        end
1310
// --------------------------------  ret far --------------------------------
1311
                        42: begin
1312 11 ndumitrach
                                WORD = 1'b1;            // fix RET n alignment bug - 03Apr2013
1313 2 ndumitrach
                                ALUOP = 31;                     // PASS B
1314
                                RSSEL = 2'b10;                  // SS
1315
                                IFETCH = STAGE[1];
1316
                                DISEL = 2'b00;                  // DIN
1317
                                case(STAGE[1:0])
1318
                                        2'b00: begin    // stage1, pop IP in TMP16
1319
                                                WE[3] = 1'b1;                   // TMP16
1320
                                                EAC = 4'b1001;                  // SP + 2
1321
                                        end
1322
                                        2'b01: begin            // stage2, pop CS, TMP16 <- RA
1323
                                                RASEL = 3'b001; // CS
1324
                                                WE[2] = 1'b1;
1325
                                                EAC = {1'b1, !FETCH[0][0], 2'b01};
1326
                                                ASEL = 1'b0;
1327
                                                AEXT = 1'b0;
1328
                                                DISP16 = 1'b1;
1329
                                                BASEL = 1'b0;           // RA <- TMP16
1330
                                        end
1331
                                        2'b10: begin            // stage3, IP <- TMP16
1332
                                                BBSEL = 2'b00;          // TMP16
1333
                                                IPWSEL = 1'b0;          // ALU
1334
                                                MREQ = 1'b0;
1335
                                                ISIZE = FETCH[0][0] ? 1 : 3;
1336
                                        end
1337
                                endcase
1338
                        end
1339
// --------------------------------  iret --------------------------------
1340
                        43: begin
1341
                                ALUOP = 31;                     // PASS B
1342
                                RSSEL = 2'b10;                  // SS
1343
                                ISIZE = 1;
1344
                                IFETCH = &STAGE[1:0];
1345
                                case(STAGE[1:0])
1346
                                        2'b00: begin    // stage1, pop IP in FETCH
1347
                                                EAC = 4'b1001;                  // SP + 2
1348
                                                DOSEL = 2'b11;                  // write FETCH
1349
                                        end
1350
                                        2'b01: begin            // stage2, pop CS
1351
                                                RASEL = 3'b001; // CS
1352
                                                WE[2] = 1'b1;
1353
                                                EAC = {1'b1, !FETCH[0][0], 2'b01};
1354
                                                DISEL = 2'b00;
1355
                                                ASEL = 1'b0;
1356
                                                AEXT = 1'b0;
1357
                                                DISP16 = 1'b1;
1358
                                        end
1359
                                        2'b10: begin            // stage3, pop flags in TMP16
1360
                                                WE[3] = 1'b1;                   // TMP16
1361
                                                EAC = 4'b1001;                  // SP
1362
                                                DISEL = 2'b00;
1363
                                        end
1364
                                        2'b11: begin            // stage4, IP <- FETCH, FLAGS <- TM
1365
                                                BASEL = 1'b0;
1366
                                                BBSEL = 2'b10;          // imm
1367
                                                WE[4] = 1'b1;           // flags
1368
                                                ISEL = 2'b01;
1369
                                                DEXT = 1'b0;
1370
                                                IPWSEL = 1'b0;          // ALU
1371
                                                MREQ = 1'b0;
1372
                                        end
1373
                                endcase
1374
                        end
1375
// --------------------------------  cbw/cwd --------------------------------
1376
                        44: begin
1377
                                RASEL = FETCH[0][0] ? 3'b010 : 3'b100; // AH/DX
1378
                                RBSEL = 3'b000; // AX
1379
                                WE[1:0] = {1'b1, FETCH[0][0]};             // RASEL_HI, RASEL_LO
1380
                                ALUOP = {4'b1101, FETCH[0][0]};   // cbw/cwd
1381
                                MREQ = 1'b0;
1382
                                ISIZE = 1;
1383
                        end
1384
// --------------------------------  JMP cond, LOOP, LOOPZ, LOOPNZ, JCXZ --------------------------------
1385
                        45: begin  // loop/loopz/loopnz/jcxz
1386
                                ALUOP = 0;                       // add
1387
                                ISIZE = 2;
1388
                                DOSEL = 2'b01;          // IP
1389
                                BBSEL = 2'b10;          // imm
1390
                                ISEL = 2'b00;
1391
                                DEXT = 1'b1;
1392
                                MREQ = 1'b0;
1393
                                IPWSEL = FETCH[0][7] ? LOOPC[FETCH[0][1:0]] : (JMPC[FETCH[0][3:1]] ~^ FETCH[0][0]);
1394
                                DECCX = FETCH[0][7] && (FETCH[0][1:0] != 2'b11);
1395
                        end
1396
// --------------------------------  CLC, CMC, STC, CLD, STD, CLI, STI --------------------------------
1397
                        46: begin
1398
                                WE[4] = 1'b1;           // flags
1399
                                ALUOP = 5'b11001;       // flag op
1400
                                ISIZE = 1;
1401
                                MREQ = 1'b0;
1402
                        end
1403
// --------------------------------  enter --------------------------------
1404
                        47: begin
1405
                                WORD = 1'b1;
1406
                                WE[1:0] = 2'b11;                 // RASEL_HI/RASEL_LO
1407
                                case(STAGE[1:0])
1408
                                        2'b00: begin            // push BP
1409
                                                RASEL = 3'b100;         // write SP
1410
                                                RBSEL = 3'b101;                 // BP
1411
                                                RSSEL = 2'b10;                  // SS
1412
                                                EAC = 4'b1000;                  // SP - 2
1413
                                                DISEL = 2'b10;                  // ADDR
1414
                                                ALUOP = 31;                             // PASS B
1415
                                                WR = 1'b1;
1416
                                                IFETCH = 1'b0;
1417
                                        end
1418
                                        2'b01: begin            // mov BP, SP
1419
                                                RASEL = 3'b101; // BP
1420
                                                RBSEL = 3'b100; // SP
1421
                                                ALUOP = 31;                             // PASS B
1422
                                                MREQ = 1'b0;
1423
                                                IFETCH = 1'b0;
1424
                                        end
1425
                                        2'b10: begin            // sub SP, imm
1426
                                                BASEL = 1'b1;
1427
                                                RASEL = 3'b100; // SP
1428
                                                BBSEL = 2'b10;
1429
                                                ALUOP = 5'b00101;       // sub
1430
                                                ISEL = 2'b00;
1431
                                                MREQ = 1'b0;
1432
                                                ISIZE = 4;
1433
                                        end
1434
                                endcase
1435
                        end
1436
// --------------------------------  leave --------------------------------
1437
                        48: begin
1438
                                WE[1:0] = 2'b11;                 // RASEL_HI/RASEL_LO
1439
                                if(!STAGE[0]) begin      // stage1, mov sp, bp
1440
                                        RASEL = 3'b100; // BP
1441
                                        RBSEL = 3'b101; // SP
1442
                                        ALUOP = 31;                             // PASS B
1443
                                        MREQ = 1'b0;
1444
                                        IFETCH = 1'b0;
1445
                                end else begin                  // stage2, pop bp
1446
                                        RASEL = 3'b101;         // BP
1447
                                        RSSEL = 2'b10;                  // SS
1448
                                        EAC = 4'b1001;                  // SP
1449
                                        DISEL = 2'b00;                  // DIN
1450
                                        ISIZE = 1;
1451
                                end
1452
                        end
1453
// --------------------------------  int, int 3, into --------------------------------
1454
                        49: begin
1455
                                MREQ = 1'b0;
1456
                                ISIZE = FETCH[0][1:0] == 2'b01 ? 2 : 1;
1457
                                IRQ = ~FETCH[0][1] | FLAGS[11];
1458
                                IRQL = FETCH[0][1] ? 3'b100 : {1'b0, ~FETCH[0][1:0]};      // 4, 2, 3
1459
                        end
1460
// --------------------------------  bound --------------------------------
1461
                        50: begin
1462
                                WORD = 1'b1;
1463
                                DOSEL = 2'b11;                  // load FETCH with DIN
1464
                                case(STAGE[1:0])
1465
                                        2'b00: begin // stage1,  read min in FETCH, ADDR16 in TMP16
1466
                                                RASEL = 3'b100;                 // SP   - write SP to SP for getting ADDR16 to TMP16
1467
                                                BBSEL = 2'b01;
1468
                                                RBSEL = 3'b100;                 // SP
1469
                                                ALUOP = 31;                             // PASS B
1470
                                                WE[3:0] = 4'b1011;                       // TMP16, RASEL_HI, RASEL_LO
1471
                                                ASEL = 1'b1;
1472
                                                IRQ = &MOD;             // illegal instruction
1473
                                                ISIZE = 0;
1474
                                                IFETCH = IRQ;
1475
                                        end
1476
                                        2'b01, 2'b10, 2'b11: begin      // stage2,3,4 load min/max in TMP16, compare reg with imm
1477
                                                BBSEL = 2'b10;                  // imm
1478
                                                ALUOP = 5'b00111;               // cmp
1479
                                                EAC = 4'b1011;                  // TMP16 + 2
1480
                                                ISEL = 2'b01;
1481
                                                IRQ = STAGE[1] & (STAGE[0] ? ~TLF & ~TZF : TLF);
1482
                                                MREQ = ~&STAGE[1:0];
1483
                                                IFETCH = IRQ | ~MREQ;
1484
                                                IRQL = 3'b101;
1485
                                                ISIZE = IRQ ? 0 : ISIZES;        // return address is BOUND
1486
                                        end
1487
                                endcase
1488
                        end
1489
// --------------------------------  hlt --------------------------------
1490
                        51: begin
1491
                                IFETCH = 1'b0;
1492
                                HALT = 1'b1;
1493
                                MREQ = 1'b0;
1494
                        end
1495
// --------------------------------  wait --------------------------------
1496
                        52: begin       // do nothing
1497
                                ISIZE = 1;
1498
                                MREQ = 1'b0;
1499
                        end
1500
// --------------------------------  aam --------------------------------
1501
                        53: begin
1502
                                MREQ = 1'b0;
1503
                                IRQL = 3'b000;  // divide overflow
1504
                                ISIZE = 2;
1505
                                case({DIVEND, STAGE[1:0]})
1506
                                        3'b000: begin   // stage1, clear AH
1507
                                                BASEL = 1'b0;    // TMP16
1508
                                                RASEL = 3'b100; // AH
1509
                                                BBSEL = 2'b00;   // TMP16
1510
                                                WE[1] = 1'b1;    // RASEL_HI
1511
                                                ALUOP = 5'b00101;       // sub
1512
                                                IFETCH = 1'b0;
1513
                                        end
1514
                                        3'b001, 3'b101: begin   // stage2, div
1515
                                                RASEL = 3'b100; // AH
1516
                                                BASEL = 1'b1;
1517
                                                BBSEL = 2'b10;   // imm
1518
                                                WE[1] = 1'b1;    // RASEL_HI
1519
                                                ALUOP = 5'b00101;       // sub
1520
                                                ISEL = 2'b00;
1521
                                                DIVSTAGE = ~DIVEND;
1522
                                                ALUSTAGE = ~DIVEND;
1523
                                                DIVOP = 1'b1;
1524
                                                IRQ = ~|STAGE[6:2] & DIVC;
1525
                                                IFETCH = IRQ;
1526
                                        end
1527
                                        3'b110: begin   // stage 3, AH <- AL, TMP16 <- AH
1528
                                                RASEL = 3'b100; // AH
1529
                                                BASEL = 1'b1;
1530
                                                RBSEL = 3'b000; // AL
1531
                                                WE[1] = 1'b1;   // RASEL_HI
1532
                                                ALUOP = 31;                     // PASS B
1533
                                                IFETCH = 1'b0;
1534
                                        end
1535
                                        3'b111: begin // stage4, AL <- TMP16 | TMP16, set flags
1536
                                                RASEL = 3'b000; // dest = AL
1537
                                                BASEL = 1'b0;    // TMP16
1538
                                                BBSEL = 2'b00;   // TMP16
1539
                                                WE = 5'b10001;   // FLAGS, RASEL_LO
1540
                                                ALUOP = 5'b00001;               // OR
1541
                                        end
1542
                                endcase
1543
                        end
1544
// --------------------------------  reset, irq, nmi, intr --------------------------------
1545
                        54:
1546
                                if(STAGE[3]) begin
1547
                                        if(FETCH[5][0]) begin    // reset
1548
                                                RASEL = {1'b0, STAGE[1:0]};      // ES, CS, SS, DS
1549
                                                WE = 5'b11100;          // FLAGS, TMP16, RSSEL
1550
                                                BASEL = 1'b0;           // TMP16
1551
                                                BBSEL = 2'b00;          // TMP16
1552
                                                ALUOP = STAGE[0] ? STAGE[1] ? 31 : 5'b01001 : 5'b00101;  // pass, dec, sub
1553
                                                MREQ = 1'b0;
1554
                                                IPWSEL = 1'b0;          // ALU16
1555
                                                IFETCH = &STAGE[1:0];
1556
                                        end else case({FETCH[5][1], STAGE[2:0]})
1557
                                                4'b1000: begin          // stage1 intr
1558
                                                        DOSEL = 2'b11;  // read FETCH[2]         
1559
                                                        MREQ = 1'b0;
1560
                                                        IFETCH = 1'b0;
1561
                                                        INTA = 1'b1;
1562
                                                end
1563
                                                4'b1001, 4'b0000: begin // stage1 irq, nmi, tf, stage2 intr - push flags, clear TF, IF
1564
                                                        RASEL = 3'b100;         // write SP
1565
                                                        RSSEL = 2'b10;                  // SS
1566
                                                        WE = 5'b10011;                  // flags, SP    
1567
                                                        ALUOP = 30;                             // pass flags
1568
                                                        EAC = 4'b1000;                  // SP - 2
1569
                                                        DISEL = 2'b10;                  // ADDR
1570
                                                        WR = 1'b1;
1571
                                                        IFETCH = 1'b0;
1572
                                                end
1573
                                                4'b1010, 4'b0001: begin // stage2 irq, nmi, tf, stage3 intr - push CS
1574
                                                        RASEL = 3'b100;         // write SP
1575
                                                        BBSEL = 2'b11;
1576
                                                        RBSEL = 3'b001;                 // CS
1577
                                                        RSSEL = 2'b10;                  // SS
1578
                                                        ALUOP = 31;                             // PASS B
1579
                                                        EAC = 4'b1000;                  // SP - 2
1580
                                                        DISEL = 2'b10;                  // ADDR
1581
                                                        WR = 1'b1;
1582
                                                        IFETCH = 1'b0;
1583
                                                        WE[1:0] = 2'b11;                 // RASEL_HI/RASEL_LO
1584
                                                end
1585
                                                4'b1011, 4'b0010: begin // stage3 irq, nmi, tf, stage4 intr - read offset in FETCH, ADDR16 in TMP16
1586
                                                        RASEL = 3'b100;                 // SP   - write SP to SP for getting ADDR16 to TMP16
1587
                                                        BBSEL = 2'b01;
1588
                                                        RBSEL = 3'b100;                 // SP
1589
                                                        ALUOP = 31;                             // PASS B
1590
                                                        EAC = 4'b1110;                  // int vector
1591
                                                        WE[3:0] = 4'b1011;       // TMP16, RASEL_HI, RASEL_LO
1592
                                                        ASEL = 1'b1;
1593
                                                        DISP16 = 1'b1;
1594
                                                        DOSEL = 2'b11;                  // load FETCH with DIN
1595
                                                        IFETCH = 1'b0;
1596
                                                        NULLSEG = 1'b1;
1597
                                                end
1598
                                                4'b1100, 4'b0011: begin // stage4 irq, nmi, tf, stage5 intr - read CS
1599
                                                        RASEL = 3'b001;                 // CS
1600
                                                        WE[2] = 1'b1;                   // RSSEL
1601
                                                        EAC = 4'b1011;                  // TMP16 + 2
1602
                                                        DISEL = 2'b00;                  // DIN
1603
                                                        IFETCH = 1'b0;
1604
                                                        NULLSEG = 1'b1;
1605
                                                end
1606
                                                4'b1101, 4'b0100: begin // stage5 irq, nmi, tf, stage6 intr - push IP, jump
1607
                                                        RASEL = 3'b100;         // write SP
1608
                                                        BBSEL = 2'b10;          // imm
1609
                                                        RSSEL = 2'b10;          // SS
1610
                                                        ALUOP = 31;                     // PASS B
1611
                                                        EAC = 4'b1000;          // SP - 2
1612
                                                        DISEL = 2'b10;          // ADDR
1613
                                                        DOSEL = 2'b01;          // IP    
1614
                                                        ISEL = 2'b01;
1615
                                                        WR = 1'b1;
1616
                                                        WE[1:0] = 2'b11;
1617
                                                        ISIZE = FETCH[5][2] ? 1 : 0;
1618
                                                        IPWSEL = 1'b0;          // ALU
1619
                                                end
1620
                                        endcase
1621
                                end else begin
1622
                                        MREQ = 1'b0;
1623
                                        ISIZE = 0;
1624
                                        IRQ = 1'b1;
1625
                                end
1626
 
1627
// --------------------------------  bad opcode/esc --------------------------------
1628
                        default: begin
1629
                                MREQ = 1'b0;
1630
                                ISIZE = 0;
1631
                                IRQ = 1'b1;
1632
                                if(FETCH[0][7:3] == 5'b11011) IRQL = 3'b111; // esc
1633
                        end
1634
                endcase
1635
         end
1636
 
1637
 
1638
 
1639
// instruction pre-decoder
1640
function [5:0]ICODE;
1641
        input [7:0]INSTR;
1642
        begin
1643
                case(INSTR[7:0])
1644
// --------------------------------  mov R/M to/from R/SR  --------------------------------
1645
                        8'b10001000, 8'b10001001, 8'b10001010, 8'b10001011,
1646
                        8'b10001110, 8'b10001100: ICODE = 0;
1647
// --------------------------------  mov IMM to R/M  --------------------------------
1648
                        8'b11000110, 8'b11000111: ICODE = 1;
1649
// --------------------------------  mov IMM to R --------------------------------
1650
                        8'b10110_000, 8'b10110_001, 8'b10110_010, 8'b10110_011, 8'b10110_100, 8'b10110_101, 8'b10110_110, 8'b10110_111,
1651
                        8'b10111_000, 8'b10111_001, 8'b10111_010, 8'b10111_011, 8'b10111_100, 8'b10111_101, 8'b10111_110, 8'b10111_111: ICODE = 2;
1652
// --------------------------------  mov mem to/from ACC --------------------------------
1653
                        8'b10100000, 8'b10100001,
1654
                        8'b10100010, 8'b10100011: ICODE = 3;
1655
// --------------------------------  segment override prefix --------------------------------
1656
                        8'b001_00_110, 8'b001_01_110, 8'b001_10_110, 8'b001_11_110: ICODE = 4;
1657
// --------------------------------  rep prefix --------------------------------
1658
                        8'b11110010, 8'b11110011: ICODE = 5;
1659
// --------------------------------  lock prefix --------------------------------
1660
                        8'b11110000: ICODE = 6;
1661
// --------------------------------  FF block --------------------------------
1662
                        8'b11111111, 8'b11111110:       ICODE = 7;
1663
// --------------------------------  push R/SR --------------------------------
1664
                        8'b01010_000, 8'b01010_001, 8'b01010_010, 8'b01010_011, 8'b01010_100, 8'b01010_101, 8'b01010_110, 8'b01010_111,
1665
                        8'b000_00_110, 8'b000_01_110, 8'b000_10_110, 8'b000_11_110: ICODE = 8;
1666
// --------------------------------  push Imm --------------------------------
1667
                        8'b01101000, 8'b01101010: ICODE = 9;
1668
// --------------------------------  pusha --------------------------------
1669
                        8'b01100000: ICODE = 10;
1670
// --------------------------------  pop R/M --------------------------------
1671
                        8'b10001111: ICODE = 11;
1672
// --------------------------------  pop R / SR --------------------------------
1673
                        8'b01011_000, 8'b01011_001, 8'b01011_010, 8'b01011_011, 8'b01011_100, 8'b01011_101, 8'b01011_110, 8'b01011_111,
1674
                        8'b000_00_111, 8'b000_10_111, 8'b000_11_111: ICODE = 12;
1675
// --------------------------------  popa --------------------------------
1676
                        8'b01100001: ICODE = 13;
1677
// --------------------------------  xchg R with R/M/Acc --------------------------------
1678
                        8'b10000110, 8'b10000111,
1679
                        8'b10010000, 8'b10010001, 8'b10010010, 8'b10010011, 8'b10010100, 8'b10010101, 8'b10010110, 8'b10010111: ICODE = 14;
1680
// --------------------------------  in --------------------------------
1681
                        8'b11100100, 8'b11100101,
1682
                        8'b11101100, 8'b11101101:       ICODE = 15;
1683
// --------------------------------  out --------------------------------
1684
                        8'b11100110, 8'b11100111,
1685
                        8'b11101110, 8'b11101111:       ICODE = 16;
1686
// --------------------------------  xlat --------------------------------
1687
                        8'b11010111: ICODE = 17;
1688
// --------------------------------  lea --------------------------------
1689
                        8'b10001101: ICODE = 18;
1690
// --------------------------------  lds, les --------------------------------
1691
                        8'b11000101, 8'b11000100: ICODE = 19;
1692
// --------------------------------  lahf, sahf --------------------------------
1693
                        8'b10011111, 8'b10011110: ICODE = 20;
1694
// --------------------------------  pushf --------------------------------
1695
                        8'b10011100: ICODE = 21;
1696
// --------------------------------  popf --------------------------------
1697
                        8'b10011101: ICODE = 22;
1698
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp, test R/M with R --------------------------------
1699
                        8'b00000000, 8'b00000001, 8'b00000010, 8'b00000011,             // add
1700
                        8'b00001000, 8'b00001001, 8'b00001010, 8'b00001011,             // or
1701
                        8'b00010000, 8'b00010001, 8'b00010010, 8'b00010011,             // adc
1702
                        8'b00011000, 8'b00011001, 8'b00011010, 8'b00011011,             // sbb
1703
                        8'b00100000, 8'b00100001, 8'b00100010, 8'b00100011,             // and
1704
                        8'b00101000, 8'b00101001, 8'b00101010, 8'b00101011,             // sub
1705
                        8'b00110000, 8'b00110001, 8'b00110010, 8'b00110011,             // xor
1706
                        8'b00111000, 8'b00111001, 8'b00111010, 8'b00111011,             // cmp
1707
                        8'b10000100, 8'b10000101: ICODE = 23;                                                                   // test 
1708
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp R/M with Imm --------------------------------
1709
                        8'b10000000, 8'b10000001, 8'b10000010, 8'b10000011: ICODE = 24;
1710
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp, test Acc with Imm --------------------------------
1711
                        8'b00000100, 8'b00000101,               // add
1712
                        8'b00001100, 8'b00001101,               // or
1713
                        8'b00010100, 8'b00010101,               // adc
1714
                        8'b00011100, 8'b00011101,               // sbb
1715
                        8'b00100100, 8'b00100101,               // and
1716
                        8'b00101100, 8'b00101101,               // sub
1717
                        8'b00110100, 8'b00110101,               // xor
1718
                        8'b00111100, 8'b00111101,       // cmp
1719
                        8'b10101000, 8'b10101001: ICODE = 25; // test
1720
// --------------------------------  inc/dec R16 --------------------------------
1721
                        8'b01000000, 8'b01000001, 8'b01000010, 8'b01000011, 8'b01000100, 8'b01000101, 8'b01000110, 8'b01000111,
1722
                        8'b01001000, 8'b01001001, 8'b01001010, 8'b01001011, 8'b01001100, 8'b01001101, 8'b01001110, 8'b01001111: ICODE = 26;
1723
// --------------------------------  test/???/not/neg/mul/imul/div/idiv --------------------------------
1724
                        8'b11110110, 8'b11110111: ICODE = 27;
1725
// --------------------------------  imul imm --------------------------------
1726
                        8'b01101001, 8'b01101011: ICODE = 28;
1727
// --------------------------------  aad --------------------------------
1728
                        8'b11010101: ICODE = 29;
1729
// --------------------------------  daa, das, aaa, aas --------------------------------
1730
                        8'b00_100_111, 8'b00_101_111, 8'b00_110_111, 8'b00_111_111: ICODE = 30;
1731
// --------------------------------  shift/rot --------------------------------
1732
                        8'b11010000, 8'b11010001,                       // 1
1733
                        8'b11010010, 8'b11010011,                       // CL
1734
                        8'b11000000, 8'b11000001: ICODE = 31;   // imm
1735
// --------------------------------  (rep)movs --------------------------------
1736
                        8'b10100100, 8'b10100101: ICODE = 32;
1737
// --------------------------------  (rep)cmps --------------------------------
1738
                        8'b10100110, 8'b10100111: ICODE = 33;
1739
// --------------------------------  (rep)scas --------------------------------
1740
                        8'b10101110, 8'b10101111: ICODE = 34;
1741
// --------------------------------  (rep)lods --------------------------------
1742
                        8'b10101100, 8'b10101101: ICODE = 35;
1743
// --------------------------------  (rep)stos --------------------------------
1744
                        8'b10101010, 8'b10101011: ICODE = 36;  // stage1, write AL/AX in ES:[DI], inc/dec DI, dec CX
1745
// --------------------------------  (rep)ins --------------------------------
1746
                        8'b01101100, 8'b01101101: ICODE = 37;
1747
// --------------------------------  (rep)outs --------------------------------
1748
                        8'b01101110, 8'b01101111: ICODE = 38;
1749
// --------------------------------  call/jmp direct near --------------------------------
1750
                        8'b11101000,                    // call long
1751
                        8'b11101011,                    // jump short
1752
                        8'b11101001: ICODE = 39;        // jump long
1753
// --------------------------------  call/jmp far imm --------------------------------
1754
                        8'b10011010, 8'b11101010: ICODE = 40;
1755
// --------------------------------  ret near --------------------------------
1756
                        8'b11000011, 8'b11000010: ICODE = 41;
1757
// --------------------------------  ret far --------------------------------
1758
                        8'b11001011, 8'b11001010: ICODE = 42;
1759
// --------------------------------  iret --------------------------------
1760
                        8'b11001111: ICODE = 43;
1761
// --------------------------------  cbw/cwd --------------------------------
1762
                        8'b10011000, 8'b10011001: ICODE = 44;
1763
// --------------------------------  JMP cond, LOOP, LOOPZ, LOOPNZ, JCXZ --------------------------------
1764
                        8'b01110000, 8'b01110001,       // JO/JNO
1765
                        8'b01110010, 8'b01110011,       // JB/JNB
1766
                        8'b01110100, 8'b01110101,       // JE/JNE
1767
                        8'b01110110, 8'b01110111,       // JBE/JA
1768
                        8'b01111000, 8'b01111001,       // JS/JNS
1769
                        8'b01111010, 8'b01111011,       // JP/JNP
1770
                        8'b01111100, 8'b01111101,       // JL/JNL
1771
                        8'b01111110, 8'b01111111,       // JLE/JG
1772
                        8'b11100010, 8'b11100001, 8'b11100000, 8'b11100011: ICODE = 45;  // loop/loopz/loopnz/jcxz
1773
// --------------------------------  CLC, CMC, STC, CLD, STD, CLI, STI --------------------------------
1774
                        8'b11111000, 8'b11110101, 8'b11111001, 8'b11111100, 8'b11111101, 8'b11111010, 8'b11111011: ICODE = 46;
1775
// --------------------------------  enter --------------------------------
1776
                        8'b11001000: ICODE = 47;
1777
// --------------------------------  leave --------------------------------
1778
                        8'b11001001: ICODE = 48;
1779
// --------------------------------  int, int 3, into --------------------------------
1780
                        8'b11001101, 8'b11001100, 8'b11001110: ICODE = 49;
1781
// --------------------------------  bound --------------------------------
1782
                        8'b01100010: ICODE = 50;
1783
// --------------------------------  hlt --------------------------------
1784
                        8'b11110100: ICODE = 51;
1785
// --------------------------------  wait --------------------------------
1786
                        8'b10011011: ICODE = 52;        // do nothing
1787
// --------------------------------  aam --------------------------------
1788
                        8'b11010100: ICODE = 53;
1789
// --------------------------------  reset, irq, nmi, intr --------------------------------
1790
                        8'b00001111: ICODE = 54;
1791
// --------------------------------  bad opcode/esc --------------------------------
1792
                        default: ICODE = 55;
1793
                endcase
1794
        end
1795
endfunction
1796
 
1797
endmodule
1798
 

powered by: WebSVN 2.1.0

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