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

Subversion Repositories next186

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

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

powered by: WebSVN 2.1.0

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