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

Subversion Repositories next186

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

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

powered by: WebSVN 2.1.0

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