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

Subversion Repositories next186

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

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 12 ndumitrach
// 12Apr2013 - fix IDIV when Q=0
60 11 ndumitrach
///////////////////////////////////////////////////////////////////////////////////
61 2 ndumitrach
`timescale 1ns / 1ps
62
 
63
module Next186_CPU(
64
    output [19:0] ADDR,
65
    input [15:0] DIN,
66
    output [15:0] DOUT,
67
         input CLK,
68
         input CE,
69
         input INTR,
70
         input NMI,
71
         input RST,
72
         output reg MREQ,
73
         output wire IORQ,
74
         output reg INTA,
75
         output reg WR,
76
         output reg WORD,
77
         output LOCK,
78
         output [19:0]IADDR,
79
         input [47:0]INSTR,
80
         output reg IFETCH,
81
         output FLUSH,
82
         output reg [2:0]ISIZE,
83
         output reg HALT
84
    );
85
 
86
// connections  
87
        wire [15:0]RA;
88
        wire [15:0]RB;
89
        wire [15:0]TMP16;
90
        wire [15:0]SP;
91
        wire [15:0]IP;
92
        wire [15:0]AX;
93
        wire [15:0]BX;
94
        wire [15:0]BP;
95
        wire [15:0]SI;
96
        wire [15:0]DI;
97
        wire [15:0]DX;
98
        wire [15:0]FLAGS;
99
        wire [15:0]FIN;
100
        wire [15:0]ALUOUT;
101
        wire [15:0]AIMM1;
102
        reg [15:0]DIMM1;
103
        wire [15:0]RS;
104
        wire [15:0]ADDR16;
105
        wire [15:0]CS;
106
        wire ALUCONT;
107
        wire NULLSHIFT;
108
        wire [1:0]CXZ;
109
        wire COUT; // adder carry out
110
        wire DIVEXC; // exit carry for unsigned DIV 
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
         .CLK(CLK)
249
         );
250
 
251
        Next186_EA EA (
252
    .SP(SP),
253
    .BX(BX),
254
    .BP(NOBP ? 16'h0000 : BP),
255
    .SI(SI),
256
    .DI(DI),
257
         .PIO(FETCH[0][3] ? DX : {8'h00, FETCH[1]}),
258
         .TMP16(TMP16),
259
         .AL(AX[7:0]),
260
    .AIMM(AEXT ? {{8{AIMM1[7]}}, AIMM1[7:0]} : (DISP16 ? AIMM1 : 16'h0000)),
261
    .ADDR16(ADDR16),
262
         .EAC(EAC)
263
    );
264
 
265
         assign DOUT = DOSEL[1] ? DOSEL[0] ? AX : TMP16 : DOSEL[0] ? IPADD : ALUOUT;
266
         assign ADDR = {{NULLSEG ? 16'h0000 : RS} + {4'b0000, ADDR16_SP[15:4]}, ADDR16_SP[3:0]};
267
         assign IADDR = {CS + {4'b0000, IPIN[15:4]}, IPIN[3:0]};
268
         assign AIMM1 = ASEL ? {FETCH[3], FETCH[2]} : {FETCH[2], FETCH[1]};
269
 
270
         always @(posedge CLK)
271
                if(CE) begin
272
                        if(SRST) begin          // reset
273
//                              FETCH[0] <= 8'h0f;
274
                                FETCH[0][0] <= 1'b1; // for word=1
275
                                ICODE1 <= 54;
276
                                FETCH[5][1:0] <= 2'b01;  // RESET
277
                                STAGE <= 4'b1000;
278
                        end else begin
279
                                if(IACK & (IFETCH | HALT | REPINT)) begin // interrupt sampled and acknowledged
280
                                        FETCH[0][1:0] <= 2'b11;
281
                                        ICODE1 <= 54;
282
                                        STAGE <= 4'b1000;
283
                                        FETCH[5][2:0] <= {HALT, 2'b00};
284
                                        if(IRQ) FETCH[2] <= IRQL != 3'b010 ? {5'b00000, IRQL} : FETCH[1];
285
                                        else if(NMIACK) begin
286
                                                FETCH[2] <= 8'h02;
287
                                                FNMI <= 1'b1;
288
                                        end else if(INTRACK) FETCH[5][1:0] <= 2'b10;
289
                                        else FETCH[2] <= 8'h01; // trap
290
                                end else if(IFETCH) begin               // no interrupt, fetch
291
                                        FETCH[5] <= INSTR[47:40];
292
                                        FETCH[4] <= INSTR[39:32];
293
                                        FETCH[3] <= INSTR[31:24];
294
                                        FETCH[2] <= INSTR[23:16];
295
                                        FETCH[1] <= INSTR[15:8];
296
                                        FETCH[0] <= INSTR[7:0];
297
                                        STAGE <= 0;
298
                                        CPUStatus[5:0] <= status[5:0];
299
                                        ICODE1 <= ICODE(INSTR[7:0]);
300
                                end else begin          // no interrupt, no fetch
301
                                        STAGE <= STAGE + {DIVSTAGE, ALUSTAGE} + 1;
302
                                        if(&DOSEL) {FETCH[3], FETCH[2]} <= |DISEL ? DIN : RB;
303 5 ndumitrach
                                        TZF <= FIN[6];          // zero flag for BOUND
304 2 ndumitrach
                                        TLF <= FIN[7] != FIN[11];       // less flag for BOUND
305
                                end
306
                        end
307
                        if(IFETCH & ~status[2] & ~status[4] & ~status[5]) CRTIP <= IPIN; // no prefix
308
                        SRST <= RST;                            // level detection RST
309
                        SINTR <= INTR;                          // level detection INTR
310
                        if(NMI) SNMI <= 1'b1;   // edge detection NMI
311
                        else if(FNMI) begin
312
                                SNMI <= 1'b0;
313
                                FNMI <= 1'b0;
314
                        end
315
                        if(~|STAGE[1:0]) DIVQSGN <= QSGN;
316
                        RDIVEXC <= DIVOP & DIVEXC & ~IDIV; // bit 8/16 for unsigned DIV
317 5 ndumitrach
                        CMPS <= (~FETCH[0][0] | (FETCH[3] == DIN[15:8])) & (FETCH[2] == DIN[7:0]); // early EQ test for CMPS
318
                        SCAS <= (~FETCH[0][0] | (AX[15:8] == DIN[15:8])) & (AX[7:0] == DIN[7:0]);  // early EQ test for SCAS
319 2 ndumitrach
                end
320
 
321
        always @(ISEL, FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5])
322
                case(ISEL)
323
                        2'b00: DIMM1 = {FETCH[2], FETCH[1]};
324
                        2'b01: DIMM1 = {FETCH[3], FETCH[2]};
325
                        2'b10: DIMM1 = {FETCH[4], FETCH[3]};
326
                        2'b11: DIMM1 = {FETCH[5], FETCH[4]};
327
                endcase
328
 
329
        always @(FETCH[0], WORD, DISP16, AEXT) begin
330
                case({WORD, DISP16, AEXT})
331
                        3'b000: ISIZEW = 3;
332
                        3'b001, 3'b100: ISIZEW = 4;
333
                        3'b010, 3'b101: ISIZEW = 5;
334
                        default: ISIZEW = 6;
335
                endcase
336
                case({FETCH[0][1:0] == 2'b01, DISP16, AEXT})
337
                        3'b000: ISIZEI = 3;
338
                        3'b001, 3'b100: ISIZEI = 4;
339
                        3'b110: ISIZEI = 6;
340
                        default: ISIZEI = 5;
341
                endcase
342
        end
343
 
344 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,
345 12 ndumitrach
                                 WBIT, ISIZES, ISELS, WRBIT, ISIZEW, STAGE, NULLSHIFT, ALUCONT, FLAGS, CXZ, RCXZ, NRORCXLE1, TZF, JMPC, LOOPC, ICODE1, DIVQSGN, DIVSGN, DIVRSGN, FIN, IDIV, AX) begin
346 2 ndumitrach
                WORD = FETCH[0][0];
347
                BASEL = FETCH[0][1] | &MOD;
348
                RASEL = FETCH[0][1] ? REG : RM; // destination
349
                BBSEL = {1'b0, !FETCH[0][1] | &MOD};
350
                RBSEL = FETCH[0][1] ? RM : REG; // source
351
                RSSEL = CPUStatus[2] ? CPUStatus[1:0] : (USEBP && !NOBP ? 2'b10 : 2'b11);
352
                WE = 5'b00000;          // 5=flags, 3=TMP16, 2=RSSEL, 1=RASEL_HI, 0=RASEL_LO
353
                ALUOP = 5'bxxxxx;
354
                EAC = {1'b0, RM};
355
                DISEL = 2'b01;          // ALU
356
                ISEL = 2'bxx;
357
                ASEL = 1'bx;
358
                AEXT = MOD == 2'b01;
359
                DEXT = 1'b0;
360
                DOSEL = 2'b00;  // ALU   
361
                MREQ = 1'b1;
362
                WR = 1'b0;
363
                ISIZE = 3'bxxx;
364
                IPWSEL = 1'b1;          // IP + ISIZE
365
                IFETCH = 1'b1;
366
                status = 6'b00x0xx;
367
 
368
                DISP16 = MOD == 2'b10 || NOBP;
369
                NOBP = {MOD, RM} == 5'b00110;
370
                HALT = 1'b0;
371
                INTA = 1'b0;
372
                ALUSTAGE = 1'b0;
373
                DIVSTAGE = 1'b0;
374
                DECCX = 1'b0;
375
                IRQ = 1'b0;
376
                IRQL = 3'b110;  // unused opcode
377
                REPINT = 1'b0;
378
                NULLSEG = 1'b0;
379
                DIVOP = 1'b0;
380
 
381
                case(ICODE1) // one hot synthesis
382
// --------------------------------  mov R/M to/from R/SR  --------------------------------
383
                        0: begin
384
                                if(FETCH[0][2]) WORD = 1'b1;
385
                                if(FETCH[0][2:1] == 2'b10) BBSEL = 2'b11; // RB = SR
386
                                ALUOP = 31;     // PASS B
387
                                DISEL = {1'b0, &MOD};
388
                                ASEL = 1'b1;
389
                                MREQ = ~&MOD;
390
                                WR = MREQ & !FETCH[0][1];
391
                                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
392
                                ISIZE = ISIZES;
393
                        end
394
// --------------------------------  mov IMM to R/M  --------------------------------
395
                        1: begin
396
                                RASEL = RM; // destination
397
                                BBSEL = 2'b10;
398
                                ALUOP = 31;     // PASS B
399
                                ISEL = ISELS;
400
                                ASEL = 1'b1;
401
                                MREQ = ~&MOD;
402
                                WR = MREQ;
403
                                WE[1:0] = WRBIT;         // RASEL_HI/RASEL_LO
404
                                ISIZE = ISIZEW;
405
                        end
406
// --------------------------------  mov IMM to R --------------------------------
407
                        2: begin
408
                                WORD = FETCH[0][3];
409
                                RASEL = FETCH[0][2:0]; // destination
410
                                BBSEL = 2'b10;                          // imm
411
                                WE[1:0] = WBIT;          // RASEL_HI/RASEL_LO
412
                                ALUOP = 31;     // PASS B
413
                                ISEL = 2'b00;
414
                                MREQ = 1'b0;
415
                                ISIZE = WORD ? 3 : 2;
416
                        end
417
// --------------------------------  mov mem to/from ACC --------------------------------
418
                        3: begin
419
                                RASEL = 0; // ACC
420
                                BBSEL = 2'b01;          // reg
421
                                RBSEL = 0; // ACC
422
                                ALUOP = 31;     // PASS B
423
                                EAC = 4'b0110;
424
                                DISEL = 2'b00;
425
                                ASEL = 1'b0;
426
                                AEXT = 1'b0;
427
                                MREQ = 1'b1;
428
                                WR = FETCH[0][1];
429
                                WE[1:0] = WRBIT;         // IP, RASEL_HI/RASEL_LO
430
                                ISIZE = 3;
431
                                NOBP = 1'b1;
432
                        end
433
// --------------------------------  segment override prefix --------------------------------
434
                        4: begin
435
                                status = {CPUStatus[5:3], 1'b1, FETCH[0][4:3]};
436
                                MREQ = 1'b0;
437
                                ISIZE = 1;
438
                        end
439
// --------------------------------  rep prefix --------------------------------
440
                        5: begin
441
                                status = {CPUStatus[5], 1'b1, FETCH[0][0], CPUStatus[2:0]};
442
                                MREQ = 1'b0;
443
                                ISIZE = 1;
444
                        end
445
// --------------------------------  lock prefix --------------------------------
446
                        6: begin
447
                                status = {1'b1, CPUStatus[4:0]};
448
                                MREQ = 1'b0;
449
                                ISIZE = 1;
450
                        end
451
// --------------------------------  FF block --------------------------------
452
                        7:      begin
453
                                ISIZE = ISIZES;
454
                                case({FETCH[0][0], REG})
455
                // --------------------------------  push R/M --------------------------------
456
                                        4'b1110:
457
                                                if(!(&MOD || STAGE[0])) begin    // stage1, read data in TMP16
458
                                                        WE[3] = 1'b1;           // TMP16
459
                                                        DISEL = 2'b00;
460
                                                        ASEL = 1'b1;
461
                                                        IFETCH = 1'b0;
462
                                                end else begin          // stage2, push R/TMP16
463
                                                        RASEL = 3'b100;         // write SP
464
                                                        RSSEL = 2'b10;                  // SS
465
                                                        ALUOP = 31;     // PASS B
466
                                                        WE[1:0] = 2'b11;         // RASEL_HI/RASEL_LO
467
                                                        EAC = 4'b1000;                  // SP - 2
468
                                                        DISEL = 2'b10;                  // ADDR
469
                                                        WR = 1'b1;
470
                                                end
471
                // --------------------------------  inc/dec R/M --------------------------------
472
                                        4'b0000, 4'b1000, 4'b0001, 4'b1001: begin
473
                                                ASEL = 1'b1;
474
                                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
475
                                                        WE[3] = 1'b1;           // TMP16
476
                                                        DISEL = 2'b00;                  // DIN
477
                                                        IFETCH = 1'b0;
478
                                                end else begin                                          // stage2, execute and write            
479
                                                        BASEL = &MOD;
480
                                                        RASEL = RM;                     // destination
481
                                                        ALUOP = {2'b01, FETCH[1][5:3]};
482
                                                        MREQ = ~BASEL;
483
                                                        WR = MREQ;
484
                                                        WE = {3'b100, WRBIT};           // flags, IP, RASEL_HI, RASEL_LO
485
                                                end
486
                                        end
487
                // --------------------------------  call/jmp near R/M --------------------------------
488
                                        4'b1010, 4'b1100: begin
489
                                                if(!STAGE[0] && ~&MOD) begin     // stage1, load op in TMP16
490
                                                        ASEL = 1'b1;
491
                                                        WE[3] = 1'b1;           // TMP16
492
                                                        DISEL = 2'b00;                  // DIN
493
                                                        IFETCH = 1'b0;
494
                                                end else begin          // stage2, push IP, jump
495
                                                        RASEL = 3'b100;         // write SP
496
                                                        RSSEL = 2'b10;          // SS
497
                                                        ALUOP = 31;     // PASS B
498
                                                        EAC = 4'b1000;          // SP - 2
499
                                                        DISEL = 2'b10;          // ADDR
500
                                                        DOSEL = 2'b01;  // IP    
501
                                                        MREQ = REG[1];
502
                                                        WR = MREQ;
503
                                                        WE[1:0] = {WR, WR};
504
                                                        IPWSEL = 1'b0;          // ALU
505
                                                end
506
                                        end
507
                // --------------------------------  call/jmp far R/M --------------------------------
508
                                        4'b1011, 4'b1101: begin
509
                                                ALUOP = 31;                             // PASS B
510
                                                IRQ = &MOD;
511
                                                case({STAGE[1:0], REG[1]})
512
                                                        3'b001: begin   // stage1, push CS
513
                                                                RASEL = 3'b100;         // write SP
514
                                                                BBSEL = 2'b11;
515
                                                                RBSEL = 3'b001;                 // CS
516
                                                                RSSEL = 2'b10;                  // SS
517
                                                                EAC = 4'b1000;                  // SP - 2
518
                                                                DISEL = 2'b10;                  // ADDR
519
                                                                MREQ = ~IRQ;
520
                                                                WR = MREQ;
521
                                                                IFETCH = IRQ;
522
                                                                WE[1:0] = IRQ ? 2'b00 : 2'b11;                   // RASEL_HI/RASEL_LO
523
                                                                ISIZE = 0;
524
                                                        end
525
                                                        3'b011, 3'b000: begin   // stage2, read offset in FETCH, ADDR16 in TMP16
526
                                                                RASEL = 3'b100;                 // SP   - write SP to SP for getting ADDR16 to TMP16
527
                                                                BBSEL = 2'b01;
528
                                                                RBSEL = 3'b100;                 // SP
529
                                                                WE[3:0] = IRQ ? 4'b0000 : 4'b1011;                       // TMP16, RASEL_HI, RASEL_LO
530
                                                                ASEL = 1'b1;
531
                                                                DOSEL = 2'b11;                  // load FETCH with DIN
532
                                                                IFETCH = IRQ;
533
                                                                MREQ = ~IRQ;
534
                                                                ISIZE = 0;
535
                                                        end
536
                                                        3'b101, 3'b010: begin   // stage3, read CS
537
                                                                RASEL = 3'b001;                 // CS
538
                                                                WE[2] = 1'b1;                   // RSSEL
539
                                                                EAC = 4'b1011;                  // TMP16 + 2
540
                                                                DISEL = 2'b00;                  // DIN
541
                                                                IFETCH = 1'b0;
542
                                                        end
543
                                                        3'b111, 3'b100: begin   // stage4, push IP, jump
544
                                                                RASEL = 3'b100;         // write SP
545
                                                                BBSEL = 2'b10;          // imm
546
                                                                RSSEL = 2'b10;          // SS
547
                                                                EAC = 4'b1000;          // SP - 2
548
                                                                DISEL = 2'b10;          // ADDR
549
                                                                DOSEL = 2'b01;          // IP    
550
                                                                ISEL = 2'b01;
551
                                                                MREQ = REG[1];
552
                                                                WR = MREQ;
553
                                                                WE[1:0] = {WR, WR};
554
                                                                IPWSEL = 1'b0;          // ALU
555
                                                        end
556
                                                endcase
557
                                        end
558
                // --------------------------------  bad opcode --------------------------------
559
                                        default: begin
560
                                                MREQ = 1'b0;
561
                                                IRQ = 1'b1;
562
                                                ISIZE = 0;
563
                                        end
564
                                endcase
565
                        end
566
// --------------------------------  push R/SR --------------------------------
567
                        8: begin
568
                                WORD = 1'b1;
569
                                RASEL = 3'b100;         // write SP
570
                                BBSEL = {~FETCH[0][6], 1'b1};
571
                                RBSEL = FETCH[0][6] ? FETCH[0][2:0] : {1'b0, FETCH[0][4:3]}; // source
572
                                RSSEL = 2'b10;                  // SS
573
                                EAC = 4'b1000;                  // SP - 2
574
                                DISEL = 2'b10;                  // ADDR
575
                                WE[1:0] = 2'b11;         // RASEL_HI/RASEL_LO
576
                                ALUOP = 31;                             // PASS B
577
                                WR = 1'b1;
578
                                ISIZE = 1;
579
                        end
580
// --------------------------------  push Imm --------------------------------
581
                        9: begin
582
                                WORD = 1'b1;
583
                                RASEL = 3'b100;         // write SP
584
                                BBSEL = 2'b10;                  // imm
585
                                RSSEL = 2'b10;                  // SS
586
                                WE[1:0] = 2'b11;         // RASEL_HI/RASEL_LO
587
                                ALUOP = 31;                             // PASS B
588
                                EAC = 4'b1000;                  // SP - 2
589
                                DISEL = 2'b10;                  // ADDR
590
                                ISEL = 2'b00;
591
                                DEXT = FETCH[0][1];
592
                                WR = 1'b1;
593
                                ISIZE = FETCH[0][1] ? 2 : 3;
594
                        end
595
// --------------------------------  pusha --------------------------------
596
                        10: begin
597
                                WORD = 1'b1;
598
                                RASEL = 3'b100;         // write SP
599
                                RBSEL = STAGE[2:0];  // source
600
                                RSSEL = 2'b10;                  // SS
601
                                ALUOP = 31;                             // PASS B
602
                                EAC = 4'b1000;                  // SP - 2
603
                                DISEL = 2'b10;                  // ADDR
604
                                WR = 1'b1;
605
                                ISIZE = 1;
606
                                IFETCH = &STAGE[2:0];
607
                                WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
608
                        end
609
// --------------------------------  pop R/M --------------------------------
610
                        11:
611
                                case(REG)
612
                                        3'b000: begin
613
                                                ISIZE = ISIZES;
614
                                                if(!STAGE[0]) begin      // pop TMP16/REG
615
                                                        RASEL = RM;             // destination
616
                                                        RSSEL = 2'b10;                  // SS
617
                                                        EAC = 4'b1001;                  // SP
618
                                                        DISEL = 2'b00;                  // DIN
619
                                                        IFETCH = &MOD;
620
                                                        WE[3:0] = IFETCH ? 4'b0011 : 4'b1000;            // TMP16, RASEL_HI, RASEL_LO
621
                                                end else begin                  // R/M <- TMP16
622
                                                        RASEL = RM; // destination
623
                                                        BBSEL = 2'b00;                  // TMP
624
                                                        ALUOP = 31;                             // PASS B
625
                                                        ASEL = 1'b1;
626
                                                        MREQ = ~&MOD;
627
                                                        WR = MREQ;
628
                                                        WE[1:0] = WR ? 2'b00 : 2'b11;            // RASEL_HI, RASEL_LO
629
                                                end
630
                                        end
631
                                        default:        begin           // bad opcode
632
                                                MREQ = 1'b0;
633
                                                ISIZE = 0;
634
                                                IRQ = 1'b1;
635
                                        end
636
                                endcase
637
// --------------------------------  pop R / SR --------------------------------
638
                        12: begin
639
                                WORD = 1'b1;
640
                                RASEL = FETCH[0][6] ? FETCH[0][2:0] : {1'b0, FETCH[0][4:3]}; // destination
641
                                RSSEL = 2'b10;                  // SS
642
                                WE[2:0] = FETCH[0][6] ? 3'b011 : 3'b100;          // RSSEL, RASEL_HI, RASEL_LO
643
                                EAC = 4'b1001;                  // SP
644
                                DISEL = 2'b00;                  // DIN
645
                                ISIZE = 1;
646
                        end
647
// --------------------------------  popa --------------------------------
648
                        13: begin
649
                                RASEL = ~STAGE[2:0]; // destination
650
                                RSSEL = 2'b10;                  // SS
651
                                EAC = 4'b1001;                  // SP
652
                                DISEL = 2'b00;                  // DIN
653
                                ISIZE = 1;
654
                                IFETCH = &STAGE[2:0];
655
                                WE[1:0] = {STAGE[2:0] == 3'b011 ? 2'b00 : 2'b11};         // IP, RASEL_HI, RASEL_LO (skip SP)
656
                        end
657
// --------------------------------  xchg R with R/M/Acc --------------------------------
658
                        14: begin
659
                                WORD = FETCH[0][0] | FETCH[0][4];
660
                                ASEL = 1'b1;
661
                                MREQ = ~&MOD && !FETCH[0][4];
662
                                ALUOP = 31;                             // PASS B
663
                                ISIZE = FETCH[0][4] ? 1 : ISIZES;
664
                                if(!STAGE[0]) begin              // stage1, R/M/Acc -> REG -> TMP16
665
                                        BASEL = 1'b1;
666
                                        RASEL = FETCH[0][4] ? FETCH[0][2:0] : REG; // destination
667
                                        BBSEL = 2'b01;          // reg
668
                                        RBSEL = FETCH[0][4] ? 3'b000 : RM; // source
669
                                        DISEL = {1'b0, !MREQ};
670
                                        WE[1:0] = WBIT;          // RASEL_HI, RASEL_LO
671
                                        IFETCH = ~|FETCH[0][2:0]; // nop
672
                                end else begin          // stage2, TMP16 -> R/M/Acc
673
                                        RASEL = FETCH[0][4] ? 3'b000 : RM; // destination
674
                                        BBSEL = 2'b00;          // TMP16
675
                                        WR = MREQ;
676
                                        WE[1:0] = WRBIT;         // RASEL_HI, RASEL_LO
677
                                end
678
                        end
679
// --------------------------------  in --------------------------------
680
                        15:     begin
681
                                RASEL = 3'b000; // AX/AL
682
                                WE[1:0] = {WORD, 1'b1};          // RASEL_HI, RASEL_LO
683
                                DISEL = 2'b00;  //DIN
684
                                MREQ = 1'b0;
685
                                ISIZE = FETCH[0][3] ? 1 : 2;
686
                                EAC = 4'b1111;
687
                                NULLSEG = 1'b1;
688
                        end
689
// --------------------------------  out --------------------------------
690
                        16:     begin
691
                                DOSEL = 2'b11;  // AX
692
                                MREQ = 1'b0;
693
                                WR = 1'b1;
694
                                ISIZE = FETCH[0][3] ? 1 : 2;
695
                                EAC = 4'b1111;
696
                                NULLSEG = 1'b1;
697
                        end
698
// --------------------------------  xlat --------------------------------
699
                        17: begin
700
                                WORD = 1'b0;
701
                                RASEL = 3'b000;         // AL
702
                                WE[0] = 1'b1;            // RASEL_LO
703
                                EAC = 4'b1010;          // XLAT
704
                                DISEL = 2'b00;          // DIN 
705
                                ISIZE = 1;
706
                                NOBP = 1'b1;    // for RSSEL
707
                        end
708
// --------------------------------  lea --------------------------------
709
                        18: begin
710
                                RASEL = REG;                    // destination
711
                                WE[1:0] = {&MOD ? 2'b00 : 2'b11};                // RASEL_HI, RASEL_LO
712
                                DISEL = 2'b10;                  // EA
713
                                ASEL = 1'b1;
714
                                MREQ = 1'b0;
715
                                ISIZE = ISIZES;
716
                        end
717
// --------------------------------  lds, les --------------------------------
718
                        19: begin
719
                                WORD = 1'b1;
720
                                DISEL = 2'b00;                  // DIN
721
                                ASEL = 1'b1;
722
                                if(!STAGE[0]) begin              // stage1, load offset
723
                                        RASEL = REG;                    // destination
724
                                        IFETCH = &MOD;                  // bad opcode
725
                                        IRQ = IFETCH;
726
                                        ISIZE = 0;
727
                                        WE[3:0] = {2'b10, IFETCH ? 2'b00 : 2'b11};               // TMP16, RASEL_HI, RASEL_LO
728
                                end else begin                          // stage2, load segment
729
                                        RASEL = FETCH[0][0] ? 3'b011 : 3'b000; // ds/es
730
                                        WE[2] = 1'b1;                   // RSSEL
731
                                        EAC = 4'b1011;                  // TMP16 + 2
732
                                        ISIZE = ISIZES;
733
                                end
734
                        end
735
// --------------------------------  lahf, sahf --------------------------------
736
                        20: begin
737
                                WORD = 1'b0;
738
                                RASEL = 3'b100;                 // AH
739
                                WE = {!FETCH[0][0], 2'b00, FETCH[0][0], 1'b0};              // FLAGS, IP, RASEL_HI
740
                                ALUOP = FETCH[0][0] ? 30 : 31;                    // PASS/STORE FLAGS
741
                                MREQ = 1'b0;
742
                                ISIZE = 1;
743
                        end
744
// --------------------------------  pushf --------------------------------
745
                        21: begin
746
                                WORD = 1'b1;
747
                                RASEL = 3'b100;         // write SP
748
                                RSSEL = 2'b10;                  // SS
749
                                WE[1:0] = 2'b11;
750
                                ALUOP = 30;                             // pass flags
751
                                EAC = 4'b1000;                  // SP - 2
752
                                DISEL = 2'b10;                  // ADDR
753
                                WR = 1'b1;
754
                                ISIZE = 1;
755
                        end
756
// --------------------------------  popf --------------------------------
757
                        22: begin
758
                                ISIZE = 1;
759
                                IFETCH = STAGE[0];
760
                                if(!STAGE[0]) begin      // stage1, pop TMP16
761
                                        RSSEL = 2'b10;                  // SS
762
                                        WE[3] = 1'b1;                   // TMP16
763
                                        EAC = 4'b1001;                  // SP
764
                                        DISEL = 2'b00;
765
                                end else begin                  // stage2, TMP16 to FLAGS
766
                                        BASEL = 1'b0;
767
                                        WE[4] = 1'b1;                   // flags
768
                                        ALUOP = 31;                             // store flags
769
                                        MREQ = 1'b0;
770
                                end
771
                        end
772
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp, test R/M with R --------------------------------
773
                        23: begin
774
                                ASEL = 1'b1;
775
                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
776
                                        WE[3] = 1'b1;           // TMP16
777
                                        DISEL = 2'b00;                  // DIN
778
                                        IFETCH = 1'b0;
779
                                end else begin                                          // stage2, execute and write                    
780
                                        ALUOP = {2'b00, FETCH[0][2] ? 3'b100 : FETCH[0][5:3]};    // test = and
781
                                        MREQ = ~&MOD & ~|FETCH[0][2:1] & ~&FETCH[0][5:3];         // no cmp or test
782
                                        WR = MREQ;
783
                                        WE = {3'b100, WR | &FETCH[0][5:3] | FETCH[0][2] ? 2'b00 : WBIT};          // flags, RASEL_HI, RASEL_LO
784
                                        ISIZE = ISIZES;
785
                                end
786
                        end
787
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp R/M with Imm --------------------------------
788
                        24: begin
789
                                ASEL = 1'b1;
790
                                if(!(&MOD || STAGE[0])) begin    // stage1, load op from memory in TMP16
791
                                        WE[3] = 1'b1;                   // TMP16
792
                                        DISEL = 2'b00;                  // DIN
793
                                        IFETCH = 1'b0;
794
                                end else begin                                          // stage2, execute and write            
795
                                        BASEL = &MOD;
796
                                        RASEL = RM;
797
                                        BBSEL = 2'b10;                  // imm
798
                                        ALUOP = {2'b00, FETCH[1][5:3]};
799
                                        ISEL = ISELS;
800
                                        DEXT = FETCH[0][1];
801
                                        MREQ = ~BASEL & ~&FETCH[1][5:3];
802
                                        WR = MREQ;
803
                                        WE = {3'b100, WR  | &FETCH[1][5:3]? 2'b00 : WBIT};              // flags, RASEL_HI, RASEL_LO
804
                                        ISIZE = ISIZEI;
805
                                end
806
                        end
807
// --------------------------------  add, or, adc, sbb, and, sub, xor, cmp, test Acc with Imm --------------------------------
808
                        25: begin // test
809
                                BASEL = 1'b1;
810
                                RASEL = 3'b000;         // acc
811
                                BBSEL = 2'b10;                                  // imm
812
                                WE = {3'b100, &FETCH[0][5:3] | FETCH[0][7] ? 2'b00 : WBIT};               // flags, RASEL_HI, RASEL_LO
813
                                ALUOP = {2'b00, FETCH[0][7] ? 3'b100 : FETCH[0][5:3]};
814
                                ISEL = 2'b00;
815
                                MREQ = 1'b0;
816
                                ISIZE = WORD ? 3 : 2;
817
                        end
818
// --------------------------------  inc/dec R16 --------------------------------
819
                        26: begin
820
                                WORD = 1'b1;
821
                                BASEL = 1'b1;
822
                                RASEL = FETCH[0][2:0]; // destination
823
                                WE = 5'b10011;          // flags, RASEL_HI, RASEL_LO
824
                                ALUOP = {2'b01, FETCH[0][5:3]};
825
                                MREQ = 1'b0;
826
                                ISIZE = 1;
827
                        end
828
// --------------------------------  test/???/not/neg/mul/imul/div/idiv --------------------------------
829
                        27: begin
830
                                ASEL = 1'b1;
831
                                case(REG)
832
                                        3'b000: begin           // TEST R/M with Imm
833
                                                if(!(&MOD || |STAGE[1:0])) begin // stage1, load op from memory in TMP16
834
                                                        DISEL = 2'b00;
835
                                                        WE[3] = 1'b1;                                   // mem in TMP16
836
                                                        IFETCH = 1'b0;
837
                                                end else begin
838
                                                        BASEL = &MOD;
839
                                                        RASEL = RM;     // destination
840
                                                        BBSEL = 2'b10;                  // imm
841
                                                        ALUOP = 5'b00100;               // AND
842
                                                        ISEL = ISELS;
843
                                                        MREQ = 1'b0;
844
                                                        WE[4] = 1'b1;                   // flags
845
                                                        ISIZE = ISIZEW;
846
                                                end
847
                                        end
848
                                        3'b010, 3'b011: begin   // NOT/NEG R/M
849
                                                if(!(&MOD || |STAGE[1:0])) begin // stage1, load op from memory in TMP16
850
                                                        DISEL = 2'b00;
851
                                                        WE[3] = 1'b1;                                   // mem in TMP16
852
                                                        IFETCH = 1'b0;
853
                                                end else begin
854
                                                        BASEL = &MOD;
855
                                                        RASEL = RM;     // destination
856
                                                        ALUOP = {2'b01, REG};
857
                                                        MREQ = ~&MOD;
858
                                                        WR = MREQ;
859
                                                        WE = {REG[0], 2'b00, WRBIT};             // flags, RASEL_HI, RASEL_LO
860
                                                        ISIZE = ISIZES;
861
                                                end
862
                                        end
863
                                        3'b100, 3'b101: begin   // MUL, IMUL
864
                                                ISIZE = ISIZES;
865
                                                ALUOP = {4'b1000, REG[0]};               // BASEL = FETCH[0][1] = 1
866 10 ndumitrach
                                                WE[4] = 1'b1;                   // fix MUL/IMUL 8bit flags bug
867 2 ndumitrach
                                                case(STAGE[1:0])
868
                                                        2'b00: begin            // stage1, RA -> TMP16, RB (mem) -> FETCH
869
                                                                MREQ = ~&MOD;
870
                                                                DISEL = {1'b0, MREQ};
871
                                                                RASEL = 3'b000; // AX
872
                                                                DOSEL = 2'b11;
873
                                                                IFETCH = 1'b0;
874
                                                        end
875 10 ndumitrach
                                                        2'b01: begin                    // stage2, write AX
876
                                                                WE[1:0] = 2'b11; // flags, RASEL_HI, RASEL_LO 
877 2 ndumitrach
                                                                RASEL = 3'b000; // AX
878
                                                                MREQ = 1'b0;
879
                                                                IFETCH = ~FETCH[0][0];
880
                                                        end
881
                                                        2'b10: begin                    // stage 2, write DX
882 10 ndumitrach
                                                                WE[1:0] = 2'b11; // flags, RASEL_HI, RASEL_LO    
883 2 ndumitrach
                                                                RASEL = 3'b010; // DX
884
                                                                MREQ = 1'b0;
885
                                                        end
886
                                                endcase
887
                                        end
888
                                        3'b110, 3'b111: begin   // div, idiv
889
                                                ISIZE = ISIZES;
890
                                                IRQL = 3'b000;  // divide overflow
891
                                                MREQ = 1'b0;
892
                                                case({DIVEND, STAGE[1:0]})
893
                                                        3'b000: begin           // stage1, RB (mem) -> FETCH
894
                                                                MREQ = ~&MOD;
895
                                                                DISEL = {1'b0, MREQ};
896
                                                                DOSEL = 2'b11;
897
                                                                IFETCH = 1'b0;
898
                                                                DIVSTAGE = ~QSGN;
899
                                                        end
900
                                                        3'b001: begin   // stage2, pre dec AX
901
//                                                              WORD = 1'b1;
902
                                                                RASEL = 3'b000; // AX
903
                                                                WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
904
                                                                ALUOP = 5'b01001;               // DEC
905
                                                                IFETCH = 1'b0;
906
                                                                ALUSTAGE = ~(DIVQSGN && FETCH[0][0] && COUT);
907
                                                        end
908
                                                        3'b010: begin // stage3, pre dec DX
909
                                                                RASEL = 3'b010;         // DX
910
                                                                WE[1:0] = 2'b11;         // RASEL_HI, RASEL_LO
911
                                                                ALUOP = 5'b01001;               // DEC
912
                                                                IFETCH = 1'b0;
913
                                                        end
914
                                                        3'b011, 3'b111: begin   // stage4, div loop
915
                                                                RASEL = WORD ? 3'b010 : 3'b100; // DX/AH
916
                                                                BBSEL = 2'b10;          // imm
917
                                                                WE[1:0] = {1'b1, WORD};          // RASEL_HI, RASEL_LO
918
                                                                ALUOP = {2'b00, DIVSGN ? 3'b000 : 3'b101};      // add/sub
919
                                                                ISEL = 2'b01;
920
                                                                DIVSTAGE = ~DIVEND;
921
                                                                ALUSTAGE = ~DIVEND | ~DIVQSGN;
922
                                                                DIVOP = 1'b1;
923 8 ndumitrach
//                                                              IRQ = ~|STAGE[6:3] & DIVC & ~(STAGE[2] & DIVSGN); - DIV bug, fixed 23Dec2012
924
                                                                IRQ = ~|STAGE[6:3] & DIVC & (~STAGE[2] | (~DIVSGN & IDIV)); // early overflow for positive quotient
925 2 ndumitrach
                                                                IFETCH = (DIVEND && ~DIVQSGN && ~DIVRSGN) || IRQ;
926
                                                        end
927
                                                        3'b100: begin           // stage5, post inc R
928
                                                                RASEL = WORD ? 3'b010 : 3'b100; // DX/AH
929
                                                                WE[1:0] = {1'b1, WORD};          // RASEL_HI, RASEL_LO
930
                                                                ALUOP = 5'b01000;       // inc
931
                                                                IFETCH = ~DIVSGN;
932
                                                        end
933
                                                        default: begin  // stage6, post inc Q
934
                                                                RASEL = 3'b000; // AX/AL
935
                                                                WE[1:0] = {WORD, 1'b1};          // RASEL_HI, RASEL_LO
936
                                                                ALUOP = 5'b01000;       // inc
937 12 ndumitrach
//                                                              IRQ = SOUT ^ DIVSGN;    // overflow for negative quotient - fixed 12Apr2013 - IDIV bug when Q=0
938
                                                                IRQ = ~(FIN[7] | (FETCH[0][0] ? AX[15] : AX[7])); // overflow for negative quotient
939 2 ndumitrach
                                                        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.