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

Subversion Repositories thor

[/] [thor/] [trunk/] [software/] [emuThor/] [source/] [clsThor.cpp] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 robfinch
#include "stdafx.h"
2
#include "clsThor.h"
3
#include "insn.h"
4
 
5
extern clsSystem system1;
6
 
7
void clsThor::Reset()
8
{
9
        pc = 0xFFFFFFFFFFFC0000LL;
10
        tick = 0;
11
        gp[0] = 0;
12
        ca[0] = 0;
13 32 robfinch
        StatusHWI = true;
14
        StatusDBG = false;
15
        StatusEXL = 0;
16
        string_pc = 0;
17 30 robfinch
}
18
 
19 32 robfinch
bool clsThor::IsKM()
20
{
21
        return StatusHWI || (StatusEXL > 0) || StatusDBG;
22
}
23
 
24
unsigned __int64 clsThor::ReadByte(int ad) { return system1->ReadByte(ad); };
25
unsigned __int64 clsThor::ReadChar(int ad) { return system1->ReadChar(ad); };
26
unsigned __int64 clsThor::ReadHalf(int ad) { return system1->ReadHalf(ad); };
27
unsigned __int64 clsThor::Read(int ad) { return system1->Read(ad); };
28
 
29
 
30
int clsThor::GetMode()
31
{
32
        if (StatusHWI)
33
                return mode = 1;
34
        if (StatusDBG)
35
                return mode = 3;
36
        if (StatusEXL)
37
                return mode = 2;
38
        return mode = 0;
39
}
40
 
41
__int64 clsThor::GetGP(int rg)
42
{
43
        if (rg < 0 || rg > 63)
44
                return 0xDEADEADDEADDEAD;
45
        switch(rg) {
46
        case 0: return 0; // ignore update to r0.
47
        case 27:
48
                rg = rg + GetMode();
49
                // Fall through
50
        default:
51
                return gp[rg];
52
        }
53
}
54
 
55
 
56
void clsThor::SetGP(int rg, __int64 val)
57
{
58
        if (rg < 0 || rg > 63)
59
                return;
60
        switch(rg) {
61
        case 0:  ;       // ignore update to r0.
62
        case 27:
63
                rg = rg + GetMode();
64
                // Fall through
65
        default:
66
                gp[rg] = val;
67
        }
68
}
69
 
70 30 robfinch
// Compute d[Rn] address info
71
void clsThor::dRn(int b1, int b2, int b3, int *Ra, int *Sg, __int64 *disp)
72
{
73
        if (Ra) *Ra = b1 & 0x3f;
74
        if (Sg) *Sg = (b3 >> 5) & 7;
75
        if (disp) *disp = ((b2 >> 4) & 0xF) | ((b3 & 0x1f) << 4);
76
        if (*disp & 0x100)
77
                *disp |= 0xFFFFFFFFFFFFFE00LL;
78
        if (imm_prefix) {
79
                *disp &= 0xFF;
80
                *disp |= imm;
81
        }
82
}
83
 
84 32 robfinch
// Compute [Rn+Rn*Sc] address info
85
void clsThor::ndx(int b1, int b2, int b3, int *Ra, int *Rb, int *Rt, int *Sg, int *Sc)
86
{
87
        if (Ra) *Ra = b1 & 0x3f;
88
        if (Rb) *Rb = (b1 >> 6) | ((b2 & 0xf) << 2);
89
        if (Rt) *Rt = ((b2 & 0xF0) >> 4) | (( b3 & 3) << 4);
90
        if (Sg) *Sg = (b3 >> 5) & 7;
91
        if (Sc) *Sc = 1 << ((b3 >> 2) & 3);
92
}
93
 
94
int clsThor::WriteMask(int ad, int sz)
95
{
96
        switch(sz) {
97
        case 0:  return 1 << (ad & 7);
98
        case 1: return 3 << (ad & 6);
99
        case 2: return (ad & 4) ? 0xF0 : 0x0F;
100
        case 3: return 0xFF;
101
        }
102
}
103
 
104
__int64 clsThor::GetSpr(int Sprn)
105
{
106
        __int64 tmp;
107
        int nn;
108
 
109
        if (Sprn < 16) {
110
                return pr[Sprn];
111
        }
112
        else if (Sprn < 32) {
113
                Sprn -= 16;
114
                return ca[Sprn];
115
        }
116
        else if (Sprn < 40) {
117
                return seg_base[Sprn-32];
118
        }
119
        else if (Sprn < 48) {
120
                return seg_limit[Sprn-32];
121
        }
122
        else {
123
                switch(Sprn) {
124
                case 50:        return tick; break;
125
                case 51:        return lc; break;
126
                case 52:
127
                        tmp = 0;
128
                        for (nn = 0; nn < 16; nn++) {
129
                                tmp |= pr[nn] << (nn * 4);
130
                        }
131
                        return tmp;
132
                case 60:        return bir; break;
133
                case 61:
134
                        switch(bir) {
135
                        case 0: return dbad0; break;
136
                        case 1: return dbad1; break;
137
                        case 2: return dbad2; break;
138
                        case 3: return dbad3; break;
139
                        case 4: return dbctrl; break;
140
                        case 5: return dbstat; break;
141
                        }
142
                }
143
        }
144
        return 0xDEADDEADDEADDEAD;
145
}
146
 
147
void clsThor::SetSpr(int Sprn, __int64 val)
148
{
149
        int nn;
150
 
151
        if (Sprn < 16)
152
                pr[Sprn] = val;
153
        else if (Sprn < 32) {
154
                Sprn -= 16;
155
                ca[Sprn] = val;
156
                ca[0] = 0;
157
                ca[15] = pc;
158
        }
159
        else if (Sprn < 40) {
160
                seg_base[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
161
        }
162
        else if (Sprn < 48) {
163
                seg_limit[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
164
        }
165
        else {
166
                switch(Sprn) {
167
                case 51:        lc = val; break;
168
                case 52:
169
                        for (nn = 0; nn < 16; nn++) {
170
                                pr[nn] = (val >> (nn * 4)) & 0xF;
171
                        }
172
                        break;
173
                case 60:        bir = val & 0xFFLL; break;
174
                case 61:
175
                        switch(bir) {
176
                        case 0: dbad0 = val; break;
177
                        case 1: dbad1 = val; break;
178
                        case 2: dbad2 = val; break;
179
                        case 3: dbad3 = val; break;
180
                        case 4: dbctrl = val; break;
181
                        case 5: dbstat = val; break;
182
                        }
183
                }
184
        }
185
}
186
 
187
int clsThor::GetBit(__int64 a, int b)
188
{
189
        return (a >> b) & 1;
190
}
191
 
192
void clsThor::SetBit(__int64 *a, int b)
193
{
194
        *a |= (1 << b);
195
}
196
 
197
void clsThor::ClearBit(__int64 *a, int b)
198
{
199
        *a &= ~(1 << b);
200
}
201
 
202 30 robfinch
void clsThor::Step()
203
{
204
        bool ex = true; // execute instruction
205
        unsigned int opcode, func;
206
        __int64 disp;
207
        int Ra,Rb,Rc,Rt,Pn,Cr,Ct;
208 35 robfinch
        int Sprn,Sg,Sc,Sz;
209 30 robfinch
        int b1, b2, b3, b4;
210
        int nn;
211
        __int64 dat;
212 32 robfinch
        unsigned __int64 overflow;
213
        unsigned __int64 carry;
214
        unsigned __int64 a,b,res;
215 30 robfinch
 
216 35 robfinch
        rts = false;
217
        // Capture PC History, but only when the PC changes.
218
        if (pcs[0] != pc) {
219
                for (nn = 39; nn >= 0; nn--)
220
                        pcs[nn] = pcs[nn-1];
221
                pcs[0] = pc;
222
        }
223 32 robfinch
        if (IRQActive()) {
224
                StatusHWI = true;
225
                if (string_pc)
226
                        ca[14] = string_pc;
227 35 robfinch
                else {
228
                        // If a prefix was present, back up to the previous insn.
229
                        if (imm_prefix) {
230
                                ca[14] = pcs[1];
231
                        }
232
                        else
233
                                ca[14] = pc;
234
                }
235 32 robfinch
                pc = ca[12] + (vecno << 4);
236
                ca[15] = pc;
237 35 robfinch
                imm_prefix = false;
238 32 robfinch
        }
239 30 robfinch
        gp[0] = 0;
240
        ca[0] = 0;
241
        if (imcd > 0) {
242
                imcd--;
243
                if (imcd==1)
244
                        im = 0;
245
        }
246
        tick = tick + 1;
247
        pred = ReadByte(pc);
248
        pc++;
249
        switch (pred) {
250
        case 0x00:      // BRK instruction
251 32 robfinch
                isRunning = false;
252 30 robfinch
                return;
253
        case 0x10:      // NOP
254
                return;
255
        case 0x20:
256
                imm = ReadByte(pc) << 8;
257
                pc++;
258
                if (imm & 0x8000LL)
259
                        imm |= 0xFFFFFFFFFFFF0000LL;
260
                imm_prefix = true;
261
                return;
262
        case 0x30:
263
                imm = ReadByte(pc) << 8;
264
                pc++;
265
                imm |= ReadByte(pc) << 16;
266
                pc++;
267
                if (imm & 0x800000LL)
268
                        imm |= 0xFFFFFFFFFF000000LL;
269
                imm_prefix = true;
270
                return;
271
        case 0x40:
272
                imm = ReadByte(pc) << 8;
273
                pc++;
274
                imm |= ReadByte(pc) << 16;
275
                pc++;
276
                imm |= ReadByte(pc) << 24;
277
                pc++;
278
                if (imm & 0x80000000LL)
279
                        imm |= 0xFFFFFFFF00000000LL;
280
                imm_prefix = true;
281
                return;
282
        case 0x50:
283
                imm = ReadByte(pc) << 8;
284
                pc++;
285
                imm |= ReadByte(pc) << 16;
286
                pc++;
287
                imm |= ReadByte(pc) << 24;
288
                pc++;
289
                imm |= ReadByte(pc) << 32;
290
                pc++;
291
                if (imm & 0x8000000000LL)
292
                        imm |= 0xFFFFFF0000000000LL;
293
                imm_prefix = true;
294
                return;
295
        case 0x60:
296
                imm = ReadByte(pc) << 8;
297
                pc++;
298
                imm |= ReadByte(pc) << 16;
299
                pc++;
300
                imm |= ReadByte(pc) << 24;
301
                pc++;
302
                imm |= ReadByte(pc) << 32;
303
                pc++;
304
                imm |= ReadByte(pc) << 40;
305
                pc++;
306
                if (imm & 0x800000000000LL)
307
                        imm |= 0xFFFF000000000000LL;
308
                imm_prefix = true;
309
                return;
310
        case 0x70:
311
                imm = ReadByte(pc) << 8;
312
                pc++;
313
                imm |= ReadByte(pc) << 16;
314
                pc++;
315
                imm |= ReadByte(pc) << 24;
316
                pc++;
317
                imm |= ReadByte(pc) << 32;
318
                pc++;
319
                imm |= ReadByte(pc) << 40;
320
                pc++;
321
                imm |= ReadByte(pc) << 48;
322
                pc++;
323
                if (imm & 0x80000000000000LL)
324
                        imm |= 0xFF00000000000000LL;
325
                imm_prefix = true;
326
                return;
327
        case 0x80:
328
                imm = ReadByte(pc) << 8;
329
                pc++;
330
                imm |= ReadByte(pc) << 16;
331
                pc++;
332
                imm |= ReadByte(pc) << 24;
333
                pc++;
334
                imm |= ReadByte(pc) << 32;
335
                pc++;
336
                imm |= ReadByte(pc) << 40;
337
                pc++;
338
                imm |= ReadByte(pc) << 48;
339
                pc++;
340
                imm |= ReadByte(pc) << 56;
341
                pc++;
342
                imm_prefix = true;
343
                return;
344
        default: {
345
                int rv;
346
 
347
                rv = pr[pred>>4];
348
                switch(pred & 15) {
349
                case PF: ex = false; break;
350
                case PT: ex = true; break;
351
                case PEQ: ex = rv & 1; break;
352
                case PNE: ex = !(rv & 1); break;
353
                case PLE: ex = (rv & 1)||(rv & 2); break;
354
                case PGT: ex = !((rv & 1)||(rv & 2)); break;
355
                case PGE: ex = (rv & 2)==0; break;
356
                case PLT: ex = (rv & 2)!=0; break;
357
                case PLEU: ex = (rv & 1)||(rv & 4); break;
358
                case PGTU: ex = !((rv & 1)||(rv & 4)); break;
359
                case PGEU: ex = (rv & 4)==0; break;
360
                case PLTU: ex = (rv & 4)!=0; break;
361
                default:        ex = false;
362
                }
363
                }
364
        }
365
        opcode = ReadByte(pc);
366
        pc++;
367
        if ((opcode & 0xF0)==0x00) {    // TST
368
                b1 = ReadByte(pc);
369
                pc++;
370
                if (ex) {
371
                        Ra = b1 & 0x3f;
372
                        Pn = opcode & 0x0f;
373
                        pr[Pn] = 0;
374 32 robfinch
                        if (GetGP(Ra)==0)
375 30 robfinch
                                pr[Pn] |= 1;
376 32 robfinch
                        if ((signed)GetGP(Ra) < (signed)0)
377 30 robfinch
                                pr[Pn] |= 2;
378
                }
379
                imm_prefix = false;
380
                return;
381
        }
382 32 robfinch
        if ((opcode & 0xF0)==0x10) {    // CMP
383 30 robfinch
                b1 = ReadByte(pc);
384
                pc++;
385
                b2 = ReadByte(pc);
386
                pc++;
387
                if (ex) {
388
                        Ra = b1 & 0x3f;
389
                        Rb = ((b1 & 0xC0) >> 6) | ((b2 & 0x0f)<<2);
390
                        Pn = opcode & 0x0f;
391
                        pr[Pn] = 0;
392 32 robfinch
                        if (GetGP(Ra)==GetGP(Rb))
393 30 robfinch
                                pr[Pn] |= 1;
394 32 robfinch
                        if (GetGP(Ra) < GetGP(Rb))
395 30 robfinch
                                pr[Pn] |= 2;
396 32 robfinch
                        if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)GetGP(Rb))
397 30 robfinch
                                pr[Pn] |= 4;
398
                }
399
                imm_prefix = false;
400
                return;
401
        }
402 32 robfinch
        if ((opcode & 0xF0)==0x20) {    // CMPI
403 30 robfinch
                b1 = ReadByte(pc);
404
                pc++;
405
                b2 = ReadByte(pc);
406
                pc++;
407
                if (ex) {
408
                        Ra = b1 & 0x3f;
409
                        if (imm_prefix) {
410
                                imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
411
                        }
412
                        else {
413
                                imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
414
                                if (imm & 0x200)
415
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
416
                        }
417
                        Pn = opcode & 0x0f;
418
                        pr[Pn] = 0;
419 32 robfinch
                        if (GetGP(Ra)==imm)
420 30 robfinch
                                pr[Pn] |= 1;
421 32 robfinch
                        if (GetGP(Ra) < (signed)imm)
422 30 robfinch
                                pr[Pn] |= 2;
423 32 robfinch
                        if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)imm)
424 30 robfinch
                                pr[Pn] |= 4;
425
                }
426
                imm_prefix = false;
427
                return;
428
        }
429 32 robfinch
        if ((opcode & 0xF0)==0x30) {    // BR
430 30 robfinch
                disp = ReadByte(pc);
431
                pc++;
432
                if (ex) {
433
                        disp = disp | ((opcode & 0x0F) << 8);
434
                        if (disp & 0x800)
435
                                disp |= 0xFFFFFFFFFFFFF000LL;
436
                        pc = pc + disp;
437
                }
438
                imm_prefix = false;
439
                return;
440
        }
441 32 robfinch
        switch(opcode) {
442
 
443
        case _2ADDUI:
444
                b1 = ReadByte(pc);
445
                pc++;
446
                b2 = ReadByte(pc);
447
                pc++;
448
                b3 = ReadByte(pc);
449
                pc++;
450
                if (ex) {
451
                        Ra = b1 & 0x3f;
452
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
453
                        if (imm_prefix) {
454
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
455 30 robfinch
                        }
456 32 robfinch
                        else {
457
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
458
                                if (imm & 0x800)
459
                                        imm |= 0xFFFFFFFFFFFFF000LL;
460
                        }
461
                        SetGP(Rt,(GetGP(Ra)<<1) + imm);
462
                }
463
                ca[15] = pc;
464
                imm_prefix = false;
465
                return;
466 30 robfinch
 
467 32 robfinch
        case _4ADDUI:
468
                b1 = ReadByte(pc);
469
                pc++;
470
                b2 = ReadByte(pc);
471
                pc++;
472
                b3 = ReadByte(pc);
473
                pc++;
474
                if (ex) {
475
                        Ra = b1 & 0x3f;
476
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
477
                        if (imm_prefix) {
478
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
479 30 robfinch
                        }
480 32 robfinch
                        else {
481
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
482
                                if (imm & 0x800)
483
                                        imm |= 0xFFFFFFFFFFFFF000LL;
484
                        }
485
                        SetGP(Rt,(GetGP(Ra)<<2) + imm);
486
                }
487
                ca[15] = pc;
488
                imm_prefix = false;
489
                return;
490 30 robfinch
 
491 32 robfinch
        case _8ADDUI:
492
                b1 = ReadByte(pc);
493
                pc++;
494
                b2 = ReadByte(pc);
495
                pc++;
496
                b3 = ReadByte(pc);
497
                pc++;
498
                if (ex) {
499
                        Ra = b1 & 0x3f;
500
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
501
                        if (imm_prefix) {
502
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
503
                        }
504
                        else {
505
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
506
                                if (imm & 0x800)
507
                                        imm |= 0xFFFFFFFFFFFFF000LL;
508
                        }
509
                        SetGP(Rt,(GetGP(Ra)<<3) + imm);
510
                }
511
                ca[15] = pc;
512
                imm_prefix = false;
513
                return;
514
 
515
        case _16ADDUI:
516
                b1 = ReadByte(pc);
517
                pc++;
518
                b2 = ReadByte(pc);
519
                pc++;
520
                b3 = ReadByte(pc);
521
                pc++;
522
                if (ex) {
523
                        Ra = b1 & 0x3f;
524
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
525
                        if (imm_prefix) {
526
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
527
                        }
528
                        else {
529
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
530
                                if (imm & 0x800)
531
                                        imm |= 0xFFFFFFFFFFFFF000LL;
532
                        }
533
                        SetGP(Rt,(GetGP(Ra)<<4) + imm);
534
                }
535
                ca[15] = pc;
536
                imm_prefix = false;
537
                return;
538
 
539
        /* ToDo: add overflow exception */
540
        case ADDI:
541
                b1 = ReadByte(pc);
542
                pc++;
543
                b2 = ReadByte(pc);
544
                pc++;
545
                b3 = ReadByte(pc);
546
                pc++;
547
                if (ex) {
548
                        Ra = b1 & 0x3f;
549
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
550
                        if (imm_prefix) {
551
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
552
                        }
553
                        else {
554
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
555
                                if (imm & 0x800)
556
                                        imm |= 0xFFFFFFFFFFFFF000LL;
557
                        }
558
                        a = GetGP(Ra);
559
                        b = imm;
560
                        res = a + b;
561
                        // overflow = 
562
                        SetGP(Rt,res);
563
                }
564
                ca[15] = pc;
565
                imm_prefix = false;
566
                return;
567
 
568
        case ADDUI:
569
                b1 = ReadByte(pc);
570
                pc++;
571
                b2 = ReadByte(pc);
572
                pc++;
573
                b3 = ReadByte(pc);
574
                pc++;
575
                if (ex) {
576
                        Ra = b1 & 0x3f;
577
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
578
                        if (imm_prefix) {
579
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
580
                        }
581
                        else {
582
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
583
                                if (imm & 0x800)
584
                                        imm |= 0xFFFFFFFFFFFFF000LL;
585
                        }
586
                        SetGP(Rt,GetGP(Ra) + imm);
587
                }
588
                ca[15] = pc;
589
                imm_prefix = false;
590
                return;
591
 
592
        case ADDUIS:
593
                b1 = ReadByte(pc);
594
                pc++;
595
                b2 = ReadByte(pc);
596
                pc++;
597
                if (ex) {
598
                        Ra = b1 & 0x3f;
599
                        Rt = Ra;
600
                        if (imm_prefix) {
601
                                imm |= ((b2 << 2)&0xFC) | ((b1 >> 6) & 0x3);
602
                        }
603
                        else {
604
                                imm = ((b2 << 2)&0x3FC) | ((b1 >> 6) & 0x3);
605
                                if (imm & 0x200)
606
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
607
                        }
608
                        SetGP(Rt,GetGP(Ra) + imm);
609
                }
610
                ca[15] = pc;
611
                imm_prefix = false;
612
                return;
613
 
614
        case ANDI:
615
                b1 = ReadByte(pc);
616
                pc++;
617
                b2 = ReadByte(pc);
618
                pc++;
619
                b3 = ReadByte(pc);
620
                pc++;
621
                if (ex) {
622
                        Ra = b1 & 0x3f;
623
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
624
                        if (imm_prefix) {
625
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
626
                        }
627
                        else {
628
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
629
                                if (imm & 0x800)
630
                                        imm |= 0xFFFFFFFFFFFFF000LL;
631
                        }
632
                        SetGP(Rt,GetGP(Ra) & imm);
633
                        gp[0] = 0;
634
                }
635
                ca[15] = pc;
636
                imm_prefix = false;
637
                return;
638
 
639
        case BITI:
640
                b1 = ReadByte(pc);
641
                pc++;
642
                b2 = ReadByte(pc);
643
                pc++;
644
                b3 = ReadByte(pc);
645
                pc++;
646
                if (ex) {
647
                        unsigned __int64 res;
648
                        Ra = b1 & 0x3f;
649
                        Pn = ((b2 & 0x3) << 2) | (( b1 >> 6) & 3);
650
                        if (imm_prefix) {
651
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
652
                        }
653
                        else {
654
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
655
                                if (imm & 0x800)
656
                                        imm |= 0xFFFFFFFFFFFFF000LL;
657
                        }
658
                        res = GetGP(Ra) & imm;
659
                        pr[Pn] = 0;
660
                        if (res == 0)
661
                                pr[Pn] |= 1;
662
                        if (res & 0x8000000000000000LL)
663
                                pr[Pn] |= 2;
664
                        if (res & 1)
665
                                pr[Pn] |= 4;
666
                }
667
                ca[15] = pc;
668
                imm_prefix = false;
669
                return;
670
 
671
        case CLI:
672
                if (ex) {
673
                        imcd = 3;
674
                }
675
                ca[15] = pc;
676
                imm_prefix = false;
677
                break;
678
 
679
        case DIVI:
680
                b1 = ReadByte(pc);
681
                pc++;
682
                b2 = ReadByte(pc);
683
                pc++;
684
                b3 = ReadByte(pc);
685
                pc++;
686
                if (ex) {
687
                        Ra = b1 & 0x3f;
688
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
689
                        if (imm_prefix) {
690
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
691
                        }
692
                        else {
693
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
694
                                if (imm & 0x800)
695
                                        imm |= 0xFFFFFFFFFFFFF000LL;
696
                        }
697
                        SetGP(Rt,GetGP(Ra) / imm);
698
                        gp[0] = 0;
699
                }
700
                ca[15] = pc;
701
                imm_prefix = false;
702
                return;
703
 
704
        case DIVUI:
705
                b1 = ReadByte(pc);
706
                pc++;
707
                b2 = ReadByte(pc);
708
                pc++;
709
                b3 = ReadByte(pc);
710
                pc++;
711
                if (ex) {
712
                        Ra = b1 & 0x3f;
713
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
714
                        if (imm_prefix) {
715
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
716
                        }
717
                        else {
718
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
719
                                if (imm & 0x800)
720
                                        imm |= 0xFFFFFFFFFFFFF000LL;
721
                        }
722
                        SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)imm);
723
                        gp[0] = 0;
724
                }
725
                ca[15] = pc;
726
                imm_prefix = false;
727
                return;
728
 
729
        case EORI:
730
                b1 = ReadByte(pc);
731
                pc++;
732
                b2 = ReadByte(pc);
733
                pc++;
734
                b3 = ReadByte(pc);
735
                pc++;
736
                if (ex) {
737
                        Ra = b1 & 0x3f;
738
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
739
                        if (imm_prefix) {
740
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
741
                        }
742
                        else {
743
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
744
                                if (imm & 0x800)
745
                                        imm |= 0xFFFFFFFFFFFFF000LL;
746
                        }
747
                        SetGP(Rt,GetGP(Ra) ^ imm);
748
                }
749
                ca[15] = pc;
750
                imm_prefix = false;
751
                return;
752
 
753 35 robfinch
        case INC:
754
                b1 = ReadByte(pc);
755
                pc++;
756
                b2 = ReadByte(pc);
757
                pc++;
758
                b3 = ReadByte(pc);
759
                pc++;
760
                b4 = ReadByte(pc);
761
                pc++;
762
                if (ex) {
763
                        int amt;
764
                        __int64 val;
765
                        Ra = b1 & 0x3f;
766
                        Sz = (b1 >> 6) | ((b2 & 1) << 2);
767
                        func = (b2 >> 1) & 7;
768
                        disp = (b2 >> 4) | ((b3 & 31) << 4);
769
                        if (disp & 0x100)
770
                                disp |= 0xFFFFFFFFFFFFFF00LL;
771
                        Sg = b3 >> 5;
772
                        amt = b4;
773
                        if (amt & 0x80)
774
                                amt |= 0xFFFFFFFFFFFFFF00LL;
775
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
776
                        switch(Sz&3) {
777
                        case 0:  val = ReadByte(ea); break;
778
                        case 1: val = ReadChar(ea); break;
779
                        case 2: val = ReadHalf(ea); break;
780
                        case 3: val = Read(ea); break;
781
                        }
782
                        val = val + amt;
783
                        switch(Sz&3) {
784
                        case 0: system1->Write(ea,val,(0x1 << (ea & 7)) & 0xFF); break;
785
                        case 1: system1->Write(ea,val,(0x3 << (ea & 6)) & 0xFF); break;
786
                        case 2: system1->Write(ea,val,(0xF << (ea & 4)) & 0xFF); break;
787
                        case 3: system1->Write(ea,val,0xFF); break;
788
                        }
789
                }
790
                return;
791
 
792 32 robfinch
        case INT:
793
                b1 = ReadByte(pc);
794
                pc++;
795
                b2 = ReadByte(pc);
796
                pc++;
797
                if (ex) {
798
                        Ct = b1 & 0xF;
799
                        Cr = b1 >> 4;
800
                        // Normal INT stores the address of the interrupted instruction.
801
                        // However if the target register indicates a system call or
802
                        // debug interrupt, then the address of the following
803
                        // instruction is stored.
804
                        if (!(Ct==11 || Ct==13))
805
                                pc -= 4;
806
                        ca[Ct] = pc;
807
                        ca[0] = 0;
808
                        pc = (b2 << 4) + ca[Cr];
809
                        if (Ct==11)
810
                                StatusDBG = true;
811
                        else if (Ct==13) {
812
                                if (StatusEXL < 255)
813
                                        StatusEXL++;
814
                        }
815
                        else
816
                                StatusHWI = true;
817
                }
818
                ca[15] = pc;
819
                imm_prefix = false;
820
                return;
821
 
822
        case JSR:
823
                b1 = ReadByte(pc);
824
                pc++;
825
                b2 = ReadByte(pc);
826
                pc++;
827
                b3 = ReadByte(pc);
828
                pc++;
829
                b4 = ReadByte(pc);
830
                pc++;
831
                if (ex) {
832
                        Ct = b1 & 0x0F;
833
                        Cr = (b1 & 0xF0) >> 4;
834 35 robfinch
                        if (Ct != 0) {
835 32 robfinch
                                ca[Ct] = pc;
836 35 robfinch
                                sub_depth++;
837
                        }
838 32 robfinch
                        disp = (b4 << 16) | (b3 << 8) | b2;
839
                        if (disp & 0x800000)
840
                                disp |= 0xFFFFFFFFFF000000LL;
841
                        if (imm_prefix) {
842
                                disp &= 0xFF;
843
                                disp |= imm;
844
                        }
845
                        if (Cr==15)
846
                                pc = disp + pc - 6;
847
                        else
848 30 robfinch
                                pc = disp + ca[Cr];
849 32 robfinch
                }
850
                ca[15] = pc;
851
                imm_prefix = false;
852
                return;
853
 
854
        case JSRI:
855
                b1 = ReadByte(pc);
856
                pc++;
857
                b2 = ReadByte(pc);
858
                pc++;
859
                b3 = ReadByte(pc);
860
                pc++;
861
                if (ex) {
862
                        int Sz;
863
                        unsigned __int64 dat;
864
                        Ra = b1 & 0x3f;
865
                        Ct = (b1 >> 6) | ((b2 << 2) & 0xf);
866
                        Sz = (b2 & 0xC) >> 2;
867
                        Sg = (b3 >> 5);
868 35 robfinch
                        if (Ct != 0) {
869 32 robfinch
                                ca[Ct] = pc;
870 35 robfinch
                                sub_depth++;
871
                        }
872 32 robfinch
                        disp = ((b3 & 0x1f) << 4) | (b2 >> 4);
873
                        if (disp & 0x100)
874
                                disp |= 0xFFFFFFFFFFFFFE00LL;
875
                        if (imm_prefix) {
876
                                disp &= 0xFF;
877
                                disp |= imm;
878 30 robfinch
                        }
879 32 robfinch
                        switch(Sz) {
880
                        case 1:
881
                                dat = ReadChar(disp + seg_base[Sg] + GetGP(Ra)*2);
882
                                dat &= 0xFFFFLL;
883
                                pc = pc & 0xFFFF0000;
884
                                pc |= dat;
885
                                break;
886
                        case 2:
887
                                dat = ReadHalf(disp + seg_base[Sg] + GetGP(Ra)*4);
888
                                dat &= 0xFFFFFFFFLL;
889
                                pc = dat;
890
                                break;
891
                        case 3:
892
                                dat = Read(disp + seg_base[Sg] + GetGP(Ra)*8);
893
                                pc = dat;
894
                                break;
895
                        }
896
                }
897
                ca[15] = pc;
898
                imm_prefix = false;
899
                return;
900 30 robfinch
 
901 32 robfinch
        case JSRS:
902
                b1 = ReadByte(pc);
903
                pc++;
904
                b2 = ReadByte(pc);
905
                pc++;
906
                b3 = ReadByte(pc);
907
                pc++;
908
                if (ex) {
909
                        Ct = b1 & 0x0F;
910
                        Cr = (b1 & 0xF0) >> 4;
911
                        ca[Ct] = pc;
912
                        ca[0] = 0;
913
                        disp = (b3 << 8) | b2;
914
                        if (disp & 0x8000)
915
                                disp |= 0xFFFFFFFFFFFF0000LL;
916
                        if (imm_prefix) {
917
                                disp &= 0xFFLL;
918
                                disp |= imm;
919
                        }
920
                        if (Cr==15)
921
                                pc = disp + pc - 5;
922
                        else
923
                                pc = disp + ca[Cr];
924
                        if (Ct != 0)
925
                                sub_depth++;
926
                }
927
                ca[15] = pc;
928
                imm_prefix = false;
929
                return;
930
 
931
        case JSRR:
932
                b1 = ReadByte(pc);
933
                pc++;
934
                if (ex) {
935
                        Ct = b1 & 0x0F;
936
                        Cr = (b1 & 0xF0) >> 4;
937
                        if (Ct != 0)
938 30 robfinch
                                ca[Ct] = pc;
939 32 robfinch
                        disp = 0;
940
                        if (imm_prefix) {
941
                                disp &= 0xFF;
942
                                disp |= imm;
943 30 robfinch
                        }
944 32 robfinch
                        pc = disp + ca[Cr];
945
                        if (Ct != 0)
946
                                sub_depth++;
947
                }
948
                ca[15] = pc;
949
                imm_prefix = false;
950
                return;
951 30 robfinch
 
952 32 robfinch
        case LB:
953
        case LVB:
954
                b1 = ReadByte(pc);
955
                pc++;
956
                b2 = ReadByte(pc);
957
                pc++;
958
                b3 = ReadByte(pc);
959
                pc++;
960
                if (ex) {
961
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
962
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
963
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
964
                        dat = system1->Read(ea);
965
                        if (ea & 4)
966
                                dat = (dat >> 32);
967
                        if (ea & 2)
968
                                dat = (dat >> 16);
969
                        if (ea & 1)
970
                                dat = (dat >> 8);
971
                        dat &= 0xFFLL;
972
                        if (dat & 0x80LL)
973
                                dat |= 0xFFFFFFFFFFFFFF00LL;
974
                        SetGP(Rt,dat);
975
                }
976
                ca[15] = pc;
977
                imm_prefix = false;
978
                return;
979
 
980
        case LBU:
981
                b1 = ReadByte(pc);
982
                pc++;
983
                b2 = ReadByte(pc);
984
                pc++;
985
                b3 = ReadByte(pc);
986
                pc++;
987
                if (ex) {
988
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
989
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
990
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
991
                        dat = system1->Read(ea);
992
                        if (ea & 4)
993
                                dat = (dat >> 32);
994
                        if (ea & 2)
995
                                dat = (dat >> 16);
996
                        if (ea & 1)
997
                                dat = (dat >> 8);
998
                        dat &= 0xFFLL;
999
                        SetGP(Rt,dat);
1000
                }
1001
                ca[15] = pc;
1002
                imm_prefix = false;
1003
                return;
1004
 
1005
        case LBX:
1006
                b1 = ReadByte(pc);
1007
                pc++;
1008
                b2 = ReadByte(pc);
1009
                pc++;
1010
                b3 = ReadByte(pc);
1011
                pc++;
1012
                if (ex) {
1013
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1014
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1015
                        dat = system1->Read(ea);
1016
                        if (ea & 4)
1017
                                dat = (dat >> 32);
1018
                        if (ea & 2)
1019
                                dat = (dat >> 16);
1020
                        if (ea & 1)
1021
                                dat = (dat >> 8);
1022
                        dat &= 0xFFLL;
1023
                        if (dat & 0x80LL)
1024
                                dat |= 0xFFFFFFFFFFFFFF00LL;
1025
                        SetGP(Rt,dat);
1026
                }
1027
                ca[15] = pc;
1028
                imm_prefix = false;
1029
                return;
1030
 
1031
        case LBUX:
1032
                b1 = ReadByte(pc);
1033
                pc++;
1034
                b2 = ReadByte(pc);
1035
                pc++;
1036
                b3 = ReadByte(pc);
1037
                pc++;
1038
                if (ex) {
1039
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1040
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1041
                        dat = system1->Read(ea);
1042
                        if (ea & 4)
1043
                                dat = (dat >> 32);
1044
                        if (ea & 2)
1045
                                dat = (dat >> 16);
1046
                        if (ea & 1)
1047
                                dat = (dat >> 8);
1048
                        dat &= 0xFFLL;
1049
                        SetGP(Rt,dat);
1050
                }
1051
                ca[15] = pc;
1052
                imm_prefix = false;
1053
                return;
1054
 
1055
        case LC:
1056
        case LVC:
1057
                b1 = ReadByte(pc);
1058
                pc++;
1059
                b2 = ReadByte(pc);
1060
                pc++;
1061
                b3 = ReadByte(pc);
1062
                pc++;
1063
                if (ex) {
1064
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1065
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1066
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1067
                        dat = system1->Read(ea);
1068
                        if (ea & 4)
1069
                                dat = (dat >> 32);
1070
                        if (ea & 2)
1071
                                dat = (dat >> 16);
1072
                        dat &= 0xFFFF;
1073
                        if (dat & 0x8000LL)
1074
                                dat |= 0xFFFFFFFFFFFF0000LL;
1075
                        SetGP(Rt,dat);
1076
                }
1077
                ca[15] = pc;
1078
                imm_prefix = false;
1079
                return;
1080
 
1081
        case LCX:
1082
                b1 = ReadByte(pc);
1083
                pc++;
1084
                b2 = ReadByte(pc);
1085
                pc++;
1086
                b3 = ReadByte(pc);
1087
                pc++;
1088
                if (ex) {
1089
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1090
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1091
                        dat = system1->Read(ea);
1092
                        if (ea & 4)
1093
                                dat = (dat >> 32);
1094
                        if (ea & 2)
1095
                                dat = (dat >> 16);
1096
                        dat &= 0xFFFF;
1097
                        if (dat & 0x8000LL)
1098
                                dat |= 0xFFFFFFFFFFFF0000LL;
1099
                        SetGP(Rt,dat);
1100
                }
1101
                ca[15] = pc;
1102
                imm_prefix = false;
1103
                return;
1104
 
1105
        case LCU:
1106
                b1 = ReadByte(pc);
1107
                pc++;
1108
                b2 = ReadByte(pc);
1109
                pc++;
1110
                b3 = ReadByte(pc);
1111
                pc++;
1112
                if (ex) {
1113
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1114
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1115
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1116
                        dat = system1->Read(ea);
1117
                        if (ea & 4)
1118
                                dat = (dat >> 32);
1119
                        if (ea & 2)
1120
                                dat = (dat >> 16);
1121
                        dat &= 0xFFFFLL;
1122
                        SetGP(Rt,dat);
1123
                }
1124
                ca[15] = pc;
1125
                imm_prefix = false;
1126
                return;
1127
 
1128
        case LCUX:
1129
                b1 = ReadByte(pc);
1130
                pc++;
1131
                b2 = ReadByte(pc);
1132
                pc++;
1133
                b3 = ReadByte(pc);
1134
                pc++;
1135
                if (ex) {
1136
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1137
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1138
                        dat = system1->Read(ea);
1139
                        if (ea & 4)
1140
                                dat = (dat >> 32);
1141
                        if (ea & 2)
1142
                                dat = (dat >> 16);
1143
                        dat &= 0xFFFF;
1144
                        SetGP(Rt,dat);
1145
                }
1146
                ca[15] = pc;
1147
                imm_prefix = false;
1148
                return;
1149
 
1150
        case LDIS:
1151
                b1 = ReadByte(pc);
1152
                pc++;
1153
                b2 = ReadByte(pc);
1154
                pc++;
1155
                if (ex) {
1156
                        Sprn = b1 & 0x3f;
1157
                        if (imm_prefix) {
1158
                                imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
1159
                        }
1160
                        else {
1161
                                imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
1162
                                if (imm & 0x200)
1163
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
1164
                        }
1165
                        if (Sprn < 16) {
1166
                                pr[Sprn] = imm & 0xF;
1167
                        }
1168
                        else if (Sprn < 32) {
1169
                                ca[Sprn-16] = imm;
1170
                                ca[0] = 0;
1171 30 robfinch
                                ca[15] = pc;
1172
                        }
1173 32 robfinch
                        else if (Sprn < 40) {
1174
                                seg_base[Sprn-32] = imm & 0xFFFFFFFFFFFFF000LL;
1175
                        }
1176
                        else if (Sprn < 48) {
1177
                                seg_limit[Sprn-40] = imm & 0xFFFFFFFFFFFFF000LL;
1178
                        }
1179
                        else {
1180
                                switch(Sprn) {
1181
                                case 51:        lc = imm; break;
1182
                                case 52:
1183
                                        for (nn = 0; nn < 16; nn++) {
1184
                                                pr[nn] = (imm >> (nn * 4)) & 0xF;
1185 30 robfinch
                                        }
1186 32 robfinch
                                        break;
1187
                                case 60:        bir = imm & 0xFFLL; break;
1188
                                case 61:
1189
                                        switch(bir) {
1190
                                        case 0: dbad0 = imm; break;
1191
                                        case 1: dbad1 = imm; break;
1192
                                        case 2: dbad2 = imm; break;
1193
                                        case 3: dbad3 = imm; break;
1194
                                        case 4: dbctrl = imm; break;
1195
                                        case 5: dbstat = imm; break;
1196
                                        }
1197 30 robfinch
                                }
1198
                        }
1199 32 robfinch
                }
1200
                imm_prefix = false;
1201
                ca[15] = pc;
1202
                return;
1203 30 robfinch
 
1204 32 robfinch
        case LDI:
1205
                b1 = ReadByte(pc);
1206
                pc++;
1207
                b2 = ReadByte(pc);
1208
                pc++;
1209
                if (ex) {
1210
                        Rt = b1 & 0x3f;
1211
                        if (imm_prefix) {
1212
                                imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
1213 30 robfinch
                        }
1214 32 robfinch
                        else {
1215
                                imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
1216
                                if (imm & 0x200)
1217
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
1218
                        }
1219
                        SetGP(Rt,imm);
1220
                }
1221
                imm_prefix = false;
1222
                ca[15] = pc;
1223
                return;
1224 30 robfinch
 
1225 32 robfinch
        case LH:
1226
        case LVH:
1227
                b1 = ReadByte(pc);
1228
                pc++;
1229
                b2 = ReadByte(pc);
1230
                pc++;
1231
                b3 = ReadByte(pc);
1232
                pc++;
1233
                if (ex) {
1234
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1235
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1236
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1237
                        dat = system1->Read(ea);
1238
                        if (ea & 4)
1239
                                dat = (dat >> 32);
1240
                        dat &= 0xFFFFFFFFLL;
1241
                        if (dat & 0x80000000LL)
1242
                                dat |= 0xFFFFFFFF00000000LL;
1243
                        SetGP(Rt,dat);
1244
                }
1245
                ca[15] = pc;
1246
                imm_prefix = false;
1247
                return;
1248
 
1249
        case LHX:
1250
                b1 = ReadByte(pc);
1251
                pc++;
1252
                b2 = ReadByte(pc);
1253
                pc++;
1254
                b3 = ReadByte(pc);
1255
                pc++;
1256
                if (ex) {
1257
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1258
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1259
                        dat = system1->Read(ea);
1260
                        if (ea & 4)
1261
                                dat = (dat >> 32);
1262
                        dat &= 0xFFFFFFFFLL;
1263
                        if (dat & 0x80000000LL)
1264
                                dat |= 0xFFFFFFFF00000000LL;
1265
                        SetGP(Rt,dat);
1266
                }
1267
                ca[15] = pc;
1268
                imm_prefix = false;
1269
                return;
1270
 
1271
        case LHU:
1272
                b1 = ReadByte(pc);
1273
                pc++;
1274
                b2 = ReadByte(pc);
1275
                pc++;
1276
                b3 = ReadByte(pc);
1277
                pc++;
1278
                if (ex) {
1279
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1280
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1281
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1282
                        dat = system1->Read(ea);
1283
                        if (ea & 4)
1284
                                dat = (dat >> 32);
1285
                        dat &= 0xFFFFFFFFLL;
1286
                        SetGP(Rt,dat);
1287
                }
1288
                ca[15] = pc;
1289
                imm_prefix = false;
1290
                return;
1291
 
1292
        case LHUX:
1293
                b1 = ReadByte(pc);
1294
                pc++;
1295
                b2 = ReadByte(pc);
1296
                pc++;
1297
                b3 = ReadByte(pc);
1298
                pc++;
1299
                if (ex) {
1300
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1301
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1302
                        dat = system1->Read(ea);
1303
                        if (ea & 4)
1304
                                dat = (dat >> 32);
1305
                        dat &= 0xFFFFFFFFLL;
1306
                        SetGP(Rt,dat);
1307
                }
1308
                ca[15] = pc;
1309
                imm_prefix = false;
1310
                return;
1311
 
1312
        case LLA:
1313
                b1 = ReadByte(pc);
1314
                pc++;
1315
                b2 = ReadByte(pc);
1316
                pc++;
1317
                b3 = ReadByte(pc);
1318
                pc++;
1319
                if (ex) {
1320
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1321
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1322
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1323
                        SetGP(Rt,ea);
1324
                }
1325
                ca[15] = pc;
1326
                imm_prefix = false;
1327
                return;
1328
 
1329
        case LOGIC:
1330
                b1 = ReadByte(pc);
1331
                pc++;
1332
                b2 = ReadByte(pc);
1333
                pc++;
1334
                b3 = ReadByte(pc);
1335
                pc++;
1336
                if (ex) {
1337
                        Ra = b1 & 0x3f;
1338
                        Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
1339
                        Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
1340
                        func = b3 >> 2;
1341
                        switch(func) {
1342
                        case AND:
1343
                                SetGP(Rt, GetGP(Ra) & GetGP(Rb));
1344
                                break;
1345
                        case OR:
1346
                                SetGP(Rt, GetGP(Ra) | GetGP(Rb));
1347
                                break;
1348
                        case EOR:
1349
                                SetGP(Rt, GetGP(Ra) ^ GetGP(Rb));
1350
                                break;
1351
                        case NAND:
1352
                                SetGP(Rt, ~(GetGP(Ra) & GetGP(Rb)));
1353
                                break;
1354
                        case NOR:
1355
                                SetGP(Rt, ~(GetGP(Ra) | GetGP(Rb)));
1356
                                break;
1357
                        case ENOR:
1358
                                SetGP(Rt, ~(GetGP(Ra) ^ GetGP(Rb)));
1359
                                break;
1360
                        case ANDC:
1361
                                SetGP(Rt, GetGP(Ra) & ~GetGP(Rb));
1362
                                break;
1363
                        case ORC:
1364
                                SetGP(Rt, GetGP(Ra) | ~GetGP(Rb));
1365
                                break;
1366 30 robfinch
                        }
1367 32 robfinch
                }
1368
                ca[15] = pc;
1369
                imm_prefix = 0;
1370
                return;
1371 30 robfinch
 
1372 32 robfinch
        case LOOP:
1373
                disp = ReadByte(pc);
1374
                pc++;
1375
                if (ex) {
1376
                        if (disp & 0x80LL)
1377
                                disp |= 0xFFFFFFFFFFFFFF00LL;
1378
                        if (lc > 0) {
1379
                                lc--;
1380
                                pc = pc + disp;
1381 30 robfinch
                        }
1382 32 robfinch
                }
1383
                ca[15] = pc;
1384
                imm_prefix = false;
1385
                return;
1386 30 robfinch
 
1387 32 robfinch
        case LW:
1388
                b1 = ReadByte(pc);
1389
                pc++;
1390
                b2 = ReadByte(pc);
1391
                pc++;
1392
                b3 = ReadByte(pc);
1393
                pc++;
1394
                if (ex) {
1395
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1396
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1397
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1398
                        dat = system1->Read(ea);
1399
                        /*
1400
                        if (ea & 4)
1401
                                dat = (dat >> 32);
1402
                        if (ea & 2)
1403
                                dat = (dat >> 16);
1404
                        */
1405
                        SetGP(Rt,dat);
1406
                }
1407
                imm_prefix = false;
1408
                ca[15] = pc;
1409
                return;
1410
 
1411
        case LVWAR:
1412
                b1 = ReadByte(pc);
1413
                pc++;
1414
                b2 = ReadByte(pc);
1415
                pc++;
1416
                b3 = ReadByte(pc);
1417
                pc++;
1418
                if (ex) {
1419
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1420
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1421
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1422
                        dat = system1->Read(ea,1);
1423
                        /*
1424
                        if (ea & 4)
1425
                                dat = (dat >> 32);
1426
                        if (ea & 2)
1427
                                dat = (dat >> 16);
1428
                        */
1429
                        SetGP(Rt,dat);
1430
                }
1431
                imm_prefix = false;
1432
                ca[15] = pc;
1433
                return;
1434
 
1435
        case LWS:
1436
                b1 = ReadByte(pc);
1437
                pc++;
1438
                b2 = ReadByte(pc);
1439
                pc++;
1440
                b3 = ReadByte(pc);
1441
                pc++;
1442
                if (ex) {
1443
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1444
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1445
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1446
                        dat = system1->Read(ea);
1447
                        /*
1448
                        if (ea & 4)
1449
                                dat = (dat >> 32);
1450
                        if (ea & 2)
1451
                                dat = (dat >> 16);
1452
                        if (ea & 1)
1453
                                dat = (dat >> 8);
1454
                        */
1455
                        SetSpr(Rt, dat);
1456
                }
1457
                imm_prefix = false;
1458
                ca[15] = pc;
1459
                return;
1460
 
1461
        case LWX:
1462
                b1 = ReadByte(pc);
1463
                pc++;
1464
                b2 = ReadByte(pc);
1465
                pc++;
1466
                b3 = ReadByte(pc);
1467
                pc++;
1468
                if (ex) {
1469
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1470
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1471
                        dat = system1->Read(ea);
1472
                        /*
1473
                        if (ea & 4)
1474
                                dat = (dat >> 32);
1475
                        if (ea & 2)
1476
                                dat = (dat >> 16);
1477
                        */
1478
                        SetGP(Rt,dat);
1479
                }
1480
                imm_prefix = false;
1481
                ca[15] = pc;
1482
                return;
1483
 
1484
        // Memory synchronization primitives are not useful to the software ISA
1485
        // emulator. They are treated like NOP's.
1486
        case MEMSB:
1487
                ca[15] = pc;
1488
                imm_prefix = false;
1489 35 robfinch
                return;
1490 32 robfinch
 
1491
        case MEMDB:
1492
                ca[15] = pc;
1493
                imm_prefix = false;
1494 35 robfinch
                return;
1495 32 robfinch
 
1496
        case MFSPR:
1497
                b1 = ReadByte(pc);
1498
                pc++;
1499
                b2 = ReadByte(pc);
1500
                pc++;
1501
                if (ex) {
1502
                        Sprn = b1 & 0x3f;
1503
                        Rt = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
1504
                        SetGP(Rt,GetSpr(Sprn));
1505
                }
1506
                ca[15] = pc;
1507
                imm_prefix = false;
1508
                return;
1509
 
1510
        case MODI:
1511
                b1 = ReadByte(pc);
1512
                pc++;
1513
                b2 = ReadByte(pc);
1514
                pc++;
1515
                b3 = ReadByte(pc);
1516
                pc++;
1517
                if (ex) {
1518
                        Ra = b1 & 0x3f;
1519
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1520
                        if (imm_prefix) {
1521
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
1522 30 robfinch
                        }
1523 32 robfinch
                        else {
1524
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
1525
                                if (imm & 0x800)
1526
                                        imm |= 0xFFFFFFFFFFFFF000LL;
1527
                        }
1528
                        SetGP(Rt,GetGP(Ra) % imm);
1529
                        gp[0] = 0;
1530
                }
1531
                ca[15] = pc;
1532
                imm_prefix = false;
1533
                return;
1534 30 robfinch
 
1535 32 robfinch
        case MODUI:
1536
                b1 = ReadByte(pc);
1537
                pc++;
1538
                b2 = ReadByte(pc);
1539
                pc++;
1540
                b3 = ReadByte(pc);
1541
                pc++;
1542
                if (ex) {
1543
                        Ra = b1 & 0x3f;
1544
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1545
                        if (imm_prefix) {
1546
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
1547 30 robfinch
                        }
1548 32 robfinch
                        else {
1549
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
1550
                                if (imm & 0x800)
1551
                                        imm |= 0xFFFFFFFFFFFFF000LL;
1552
                        }
1553
                        SetGP(Rt,(unsigned __int64) GetGP(Ra) % (unsigned __int64)imm);
1554
                        gp[0] = 0;
1555
                }
1556
                ca[15] = pc;
1557
                imm_prefix = false;
1558
                return;
1559 30 robfinch
 
1560 32 robfinch
        case GRPA7:
1561
                b1 = ReadByte(pc);
1562
                pc++;
1563
                b2 = ReadByte(pc);
1564
                pc++;
1565
                if (ex) {
1566
                        Ra = b1 & 0x3f;
1567
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1568
                        switch(b2 >> 4) {
1569
                        case ABS:
1570
                                SetGP(Rt, GetGP(Ra) < 0 ? -GetGP(Ra) : GetGP(Ra));
1571
                                break;
1572
                        case COM:
1573
                                SetGP(Rt, ~GetGP(Ra));
1574
                                break;
1575
                        case MOV:
1576
                                SetGP(Rt, GetGP(Ra));
1577
                                break;
1578
                        case NEG:
1579
                                SetGP(Rt, -GetGP(Ra));
1580
                                break;
1581
                        case NOT:
1582
                                SetGP(Rt, !GetGP(Ra));
1583
                                break;
1584
                        case SGN:
1585
                                SetGP(Rt, (GetGP(Ra) == 0) ? 0 : (GetGP(Ra) < 0) ? -1 : 1);
1586
                                break;
1587
                        case SXB:
1588
                                dat = GetGP(Ra);
1589
                                if (dat & 0x80LL)
1590
                                        dat |= 0xFFFFFFFFFFFFFF80LL;
1591
                                SetGP(Rt,dat);
1592
                                break;
1593
                        case SXC:
1594
                                dat = GetGP(Ra);
1595
                                if (dat & 0x8000LL)
1596
                                        dat |= 0xFFFFFFFFFFFF8000LL;
1597
                                SetGP(Rt,dat);
1598
                                break;
1599
                        case SXH:
1600
                                dat = GetGP(Ra);
1601
                                if (dat & 0x80000000LL)
1602
                                        dat |= 0xFFFFFFFF80000000LL;
1603
                                SetGP(Rt,dat);
1604
                                break;
1605
                        case ZXB:
1606
                                dat = GetGP(Ra);
1607
                                dat &= 0xFFLL;
1608
                                SetGP(Rt,dat);
1609
                                break;
1610
                        case ZXC:
1611
                                dat = GetGP(Ra);
1612
                                dat &= 0xFFFFLL;
1613
                                SetGP(Rt,dat);
1614
                                break;
1615
                        case ZXH:
1616
                                dat = GetGP(Ra);
1617
                                dat &= 0xFFFFFFFFLL;
1618
                                SetGP(Rt,dat);
1619
                                break;
1620 30 robfinch
                        }
1621 32 robfinch
                }
1622
                ca[15] = pc;
1623
                imm_prefix = false;
1624
                return;
1625 30 robfinch
 
1626 32 robfinch
        case MTSPR:
1627
                b1 = ReadByte(pc);
1628
                pc++;
1629
                b2 = ReadByte(pc);
1630
                pc++;
1631
                if (ex) {
1632
                        Ra = b1 & 0x3f;
1633
                        Sprn = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
1634
                        SetSpr(Sprn, GetGP(Ra));
1635
                }
1636
                ca[15] = pc;
1637
                imm_prefix = false;
1638
                return;
1639
 
1640
        case MULI:
1641
                b1 = ReadByte(pc);
1642
                pc++;
1643
                b2 = ReadByte(pc);
1644
                pc++;
1645
                b3 = ReadByte(pc);
1646
                pc++;
1647
                if (ex) {
1648
                        Ra = b1 & 0x3f;
1649
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1650
                        if (imm_prefix) {
1651
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
1652 30 robfinch
                        }
1653 32 robfinch
                        else {
1654
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
1655
                                if (imm & 0x800)
1656
                                        imm |= 0xFFFFFFFFFFFFF000LL;
1657
                        }
1658
                        SetGP(Rt,GetGP(Ra) * imm);
1659
                        gp[0] = 0;
1660
                }
1661
                ca[15] = pc;
1662
                imm_prefix = false;
1663
                return;
1664 30 robfinch
 
1665 32 robfinch
        case MULUI:
1666
                b1 = ReadByte(pc);
1667
                pc++;
1668
                b2 = ReadByte(pc);
1669
                pc++;
1670
                b3 = ReadByte(pc);
1671
                pc++;
1672
                if (ex) {
1673
                        Ra = b1 & 0x3f;
1674
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1675
                        if (imm_prefix) {
1676
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
1677 30 robfinch
                        }
1678 32 robfinch
                        else {
1679
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
1680
                                if (imm & 0x800)
1681
                                        imm |= 0xFFFFFFFFFFFFF000LL;
1682
                        }
1683
                        SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)imm);
1684
                        gp[0] = 0;
1685
                }
1686
                ca[15] = pc;
1687
                imm_prefix = false;
1688
                return;
1689 30 robfinch
 
1690 32 robfinch
        case ORI:
1691
                b1 = ReadByte(pc);
1692
                pc++;
1693
                b2 = ReadByte(pc);
1694
                pc++;
1695
                b3 = ReadByte(pc);
1696
                pc++;
1697
                if (ex) {
1698
                        Ra = b1 & 0x3f;
1699
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1700
                        if (imm_prefix) {
1701
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
1702
                        }
1703
                        else {
1704
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
1705
                                if (imm & 0x800)
1706
                                        imm |= 0xFFFFFFFFFFFFF000LL;
1707
                        }
1708
                        SetGP(Rt,GetGP(Ra) | imm);
1709
                        gp[0] = 0;
1710
                }
1711
                ca[15] = pc;
1712
                imm_prefix = false;
1713
                return;
1714
 
1715
        case R1:
1716
                b1 = ReadByte(pc);
1717
                pc++;
1718
                b2 = ReadByte(pc);
1719
                pc++;
1720
                if (ex) {
1721
                        Ra = b1 & 0x3f;
1722
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1723
                        switch(b2 >> 4) {
1724
                        case CPUID:
1725
                                switch(Ra) {
1726 35 robfinch
                                case 0:  SetGP(Rt,0x0000LL); break;      // Processor ID
1727 32 robfinch
                                case 2: SetGP(Rt,0x4e4F5254494E4966LL); break;  // "Finitron"
1728
                                case 3: SetGP(Rt,0x00LL); break;
1729
                                case 4: SetGP(Rt,0x36346249547373LL); break;    // 64BitSS
1730
                                case 5: SetGP(Rt,0x00LL); break;
1731
                                case 6: SetGP(Rt,0x524F4A74LL); break;  // "Thor"
1732
                                case 7: SetGP(Rt, 0x00LL); break;
1733
                                case 8: SetGP(Rt, 0x316ELL); break;             // "M1"
1734
                                case 9: SetGP(Rt, 0x1235LL); break;
1735
                                case 10:        SetGP(Rt,0x00LL); break;
1736
                                case 11:        SetGP(Rt,0x0000400000008000LL); break;  // 16k,32k cache size
1737
                                default:        SetGP(Rt,0x00LL); break;
1738 30 robfinch
                                }
1739 32 robfinch
                        case REDOR:     SetGP(Rt, GetGP(Ra) != 0); break;
1740
                        case REDAND:    SetGP(Rt, GetGP(Ra)==0xFFFFFFFFFFFFFFFFLL); break;
1741
                        case PAR:       break; /* ToDo */
1742 30 robfinch
                        }
1743 32 robfinch
                }
1744
                ca[15] = pc;
1745
                imm_prefix = false;
1746
                return;
1747 30 robfinch
 
1748 32 robfinch
        case P1:
1749
                b1 = ReadByte(pc);
1750
                pc++;
1751
                b2 = ReadByte(pc);
1752
                pc++;
1753
                b3 = ReadByte(pc);
1754
                pc++;
1755
                if (ex) {
1756
                        int bita,bitb,bitt;
1757
                        Ra = (b1 & 0x3f) >> 2;
1758
                        bita = b1 & 3;
1759
                        a = GetBit(pr[Ra],bita);
1760
                        Rb = (b2 & 0xf);
1761
                        bitb = b1 >> 6;
1762
                        b = GetBit(pr[Rb],bitb);
1763
                        Rt = (b2 >> 6) | ((b3 & 3) << 2);
1764
                        bitt = (b2 >> 4) & 3;
1765
                        switch(b3 >> 2) {
1766
                        case PAND:
1767
                                res = a & b;
1768
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1769
                                break;
1770
                        case POR:
1771
                                res = a | b;
1772
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1773
                                break;
1774
                        case PEOR:
1775
                                res = a ^ b;
1776
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1777
                                break;
1778
                        case PNAND:
1779
                                res = !(a & b);
1780
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1781
                                break;
1782
                        case PNOR:
1783
                                res = !(a | b);
1784
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1785
                                break;
1786
                        case PENOR:
1787
                                res = !(a ^ b);
1788
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1789
                                break;
1790
                        case PANDC:
1791
                                res = a & !b;
1792
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1793
                                break;
1794
                        case PORC:
1795
                                res = a | !b;
1796
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
1797
                                break;
1798 30 robfinch
                        }
1799 32 robfinch
                }
1800
                ca[15] = pc;
1801
                imm_prefix = 0;
1802
                return;
1803 30 robfinch
 
1804 32 robfinch
        case RR:
1805
                b1 = ReadByte(pc);
1806
                pc++;
1807
                b2 = ReadByte(pc);
1808
                pc++;
1809
                b3 = ReadByte(pc);
1810
                pc++;
1811
                if (ex) {
1812
                        Ra = b1 & 0x3f;
1813
                        Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
1814
                        Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
1815
                        func = b3 >> 2;
1816
                        switch(func) {
1817
                        case ADD:
1818
                        case ADDU:
1819
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) + (unsigned __int64)GetGP(Rb));
1820
                                break;
1821
                        case SUB:
1822
                        case SUBU:
1823
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) - (unsigned __int64)GetGP(Rb));
1824
                                break;
1825
                        case MUL:
1826
                                SetGP(Rt,GetGP(Ra) * GetGP(Rb));
1827
                                break;
1828
                        case DIV:
1829 35 robfinch
                                if (GetGP(Rb)==0) {
1830
                                        if (StatusEXL < 255)
1831
                                                StatusEXL++;
1832
                                        ca[13] = pc;
1833
                                        pc = ca[12] + (241 << 4);
1834
                                        ca[15] = pc;
1835
                                }
1836
                                else
1837
                                        SetGP(Rt,GetGP(Ra) / GetGP(Rb));
1838 32 robfinch
                                break;
1839
                        case MOD:
1840 35 robfinch
                                if (GetGP(Rb)==0) {
1841
                                        if (StatusEXL < 255)
1842
                                                StatusEXL++;
1843
                                        ca[13] = pc;
1844
                                        pc = ca[12] + (241 << 4);
1845
                                        ca[15] = pc;
1846
                                }
1847
                                else
1848
                                        SetGP(Rt,GetGP(Ra) % GetGP(Rb));
1849 32 robfinch
                                break;
1850
                        case MULU:
1851
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)GetGP(Rb));
1852
                                break;
1853
                        case DIVU:
1854 35 robfinch
                                if (GetGP(Rb)==0)
1855
                                        SetGP(Rt,-1LL);
1856
                                else
1857
                                        SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)GetGP(Rb));
1858 32 robfinch
                                break;
1859
                        case MODU:
1860 35 robfinch
                                if (GetGP(Rb)==0)
1861
                                        SetGP(Rt,-1LL);
1862
                                else
1863
                                        SetGP(Rt,(unsigned __int64)GetGP(Ra) % (unsigned __int64)GetGP(Rb));
1864 32 robfinch
                                break;
1865
                        case _2ADDU:
1866
                                SetGP(Rt,(GetGP(Ra) << 1) + GetGP(Rb));
1867
                                break;
1868
                        case _4ADDU:
1869
                                SetGP(Rt,(GetGP(Ra) << 2) + GetGP(Rb));
1870
                                break;
1871
                        case _8ADDU:
1872
                                SetGP(Rt,(GetGP(Ra) << 3) + GetGP(Rb));
1873
                                break;
1874
                        case _16ADDU:
1875
                                SetGP(Rt,(GetGP(Ra) << 4) + GetGP(Rb));
1876
                                break;
1877 30 robfinch
                        }
1878 32 robfinch
                }
1879
                ca[15] = pc;
1880
                imm_prefix = 0;
1881
                return;
1882 30 robfinch
 
1883 32 robfinch
        case RTD:
1884
                if (ex) {
1885
                        StatusDBG = false;
1886
                        pc = ca[11];
1887 35 robfinch
                        rts = true;
1888 32 robfinch
                }
1889
                ca[15] = pc;
1890
                imm_prefix = false;
1891
                return;
1892 30 robfinch
 
1893 32 robfinch
        case RTE:
1894
                if (ex) {
1895
                        if (StatusEXL > 0)
1896
                                StatusEXL--;
1897
                        pc = ca[13];
1898 35 robfinch
                        rts = true;
1899 32 robfinch
                }
1900
                ca[15] = pc;
1901
                imm_prefix = false;
1902
                return;
1903 30 robfinch
 
1904 32 robfinch
        case RTI:
1905
                if (ex) {
1906 35 robfinch
                        imcd = 3;
1907 32 robfinch
                        StatusHWI = false;
1908
                        pc = ca[14];
1909 35 robfinch
                        rts = true;
1910 32 robfinch
                }
1911
                ca[15] = pc;
1912
                imm_prefix = false;
1913
                return;
1914
 
1915
        case RTS:
1916
                b1 = ReadByte(pc);
1917
                pc++;
1918
                if (ex) {
1919
                        Cr = (b1 & 0xF0) >> 4;
1920
                        pc = ca[Cr] + (b1 & 0x0F);
1921 35 robfinch
                        rts = true;
1922 32 robfinch
                        if (sub_depth > 0) sub_depth--;
1923
                }
1924
                ca[15] = pc;
1925
                imm_prefix = 0;
1926
                return;
1927
 
1928
        case RTSQ:
1929
                if (ex) {
1930
                        pc = ca[1];
1931 35 robfinch
                        rts = true;
1932 32 robfinch
                        if (sub_depth > 0) sub_depth--;
1933
                }
1934
                ca[15] = pc;
1935
                imm_prefix = 0;
1936
                return;
1937
 
1938
        case SB:
1939
                b1 = ReadByte(pc);
1940
                pc++;
1941
                b2 = ReadByte(pc);
1942
                pc++;
1943
                b3 = ReadByte(pc);
1944
                pc++;
1945
                if (ex) {
1946
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1947
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1948
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1949
                        system1->Write(ea,GetGP(Rb),(0x1 << (ea & 7)) & 0xFF);
1950
                }
1951
                ca[15] = pc;
1952
                imm_prefix = false;
1953
                return;
1954
 
1955
        case SBX:
1956
                b1 = ReadByte(pc);
1957
                pc++;
1958
                b2 = ReadByte(pc);
1959
                pc++;
1960
                b3 = ReadByte(pc);
1961
                pc++;
1962
                if (ex) {
1963
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1964
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1965
                        system1->Write(ea,GetGP(Rt),(0x1 << (ea & 7)) & 0xFF);
1966
                }
1967
                ca[15] = pc;
1968
                imm_prefix = false;
1969
                return;
1970
 
1971
        case SC:
1972
                b1 = ReadByte(pc);
1973
                pc++;
1974
                b2 = ReadByte(pc);
1975
                pc++;
1976
                b3 = ReadByte(pc);
1977
                pc++;
1978
                if (ex) {
1979
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
1980
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
1981
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
1982
                        system1->Write(ea,GetGP(Rb),(0x3 << (ea & 7)) & 0xFF);
1983
                }
1984
                ca[15] = pc;
1985
                imm_prefix = false;
1986
                return;
1987
 
1988
        case SCX:
1989
                b1 = ReadByte(pc);
1990
                pc++;
1991
                b2 = ReadByte(pc);
1992
                pc++;
1993
                b3 = ReadByte(pc);
1994
                pc++;
1995
                if (ex) {
1996
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
1997
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
1998
                        system1->Write(ea,GetGP(Rt),(0x3 << (ea & 7)) & 0xFF);
1999
                }
2000
                ca[15] = pc;
2001
                imm_prefix = false;
2002
                return;
2003
 
2004
        case SEI:
2005
                if (ex) {
2006
                        im = 1;
2007
                }
2008
                ca[15] = pc;
2009
                imm_prefix = false;
2010
                break;
2011
 
2012
        case SH:
2013
                b1 = ReadByte(pc);
2014
                pc++;
2015
                b2 = ReadByte(pc);
2016
                pc++;
2017
                b3 = ReadByte(pc);
2018
                pc++;
2019
                if (ex) {
2020
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2021
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
2022
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
2023
                        system1->Write(ea,GetGP(Rb),(0xF << (ea & 7)) & 0xFF);
2024
                }
2025
                ca[15] = pc;
2026
                imm_prefix = false;
2027
                return;
2028
 
2029
        case SHX:
2030
                b1 = ReadByte(pc);
2031
                pc++;
2032
                b2 = ReadByte(pc);
2033
                pc++;
2034
                b3 = ReadByte(pc);
2035
                pc++;
2036
                if (ex) {
2037
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
2038
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
2039
                        system1->Write(ea,GetGP(Rt),(0xF << (ea & 7)) & 0xFF);
2040
                }
2041
                ca[15] = pc;
2042
                imm_prefix = false;
2043
                return;
2044
 
2045
        case SHIFT:
2046
                b1 = ReadByte(pc);
2047
                pc++;
2048
                b2 = ReadByte(pc);
2049
                pc++;
2050
                b3 = ReadByte(pc);
2051
                pc++;
2052
                if (ex) {
2053
                        unsigned __int64 a,b;
2054
                        Ra = b1 & 0x3f;
2055
                        Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
2056
                        Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
2057
                        func = b3 >> 2;
2058
                        switch(func) {
2059
                        case SHL:
2060
                        case SHLU:
2061
                                SetGP(Rt, GetGP(Ra) << (GetGP(Rb) & 0x3f));
2062
                                break;
2063
                        case SHR:
2064
                                SetGP(Rt, GetGP(Ra) >> (GetGP(Rb) & 0x3f));
2065
                                break;
2066
                        case ROL:
2067
                                a = (unsigned __int64)GetGP(Ra) << (GetGP(Rb) & 0x3f);
2068
                                b = (unsigned __int64)GetGP(Ra) >> (64-(GetGP(Rb) & 0x3f));
2069
                                SetGP(Rt, (unsigned __int64)a|b);
2070
                                break;
2071
                        case ROR:
2072
                                a = (unsigned __int64)GetGP(Ra) >> (GetGP(Rb) & 0x3f);
2073
                                b = (unsigned __int64)GetGP(Ra) << (64-(GetGP(Rb) & 0x3f));
2074
                                SetGP(Rt, (unsigned __int64)a|b);
2075
                                break;
2076
                        case SHLI:
2077
                        case SHLUI:
2078
                                SetGP(Rt, GetGP(Ra) << Rb);
2079
                                break;
2080
                        case SHRI:
2081
                                SetGP(Rt, GetGP(Ra) >> Rb);
2082
                                break;
2083
                        case SHRUI:
2084
                                SetGP(Rt, (unsigned __int64)GetGP(Ra) >> Rb);
2085
                                break;
2086
                        case ROLI:
2087
                                a = (unsigned __int64)GetGP(Ra) << Rb;
2088
                                b = (unsigned __int64)GetGP(Ra) >> (64-Rb);
2089
                                SetGP(Rt, (unsigned __int64)a|b);
2090
                                break;
2091
                        case RORI:
2092
                                a = (unsigned __int64)GetGP(Ra) >> Rb;
2093
                                b = (unsigned __int64)GetGP(Ra) << (64-Rb);
2094
                                SetGP(Rt, (unsigned __int64)a|b);
2095
                                break;
2096 30 robfinch
                        }
2097 32 robfinch
                }
2098
                ca[15] = pc;
2099
                imm_prefix = false;
2100
                return;
2101 30 robfinch
 
2102 32 robfinch
        // The stop instruction controls the clock rate. It's just about useless
2103
        // to try to emulate as the emulation rate is controlled by the user.
2104
        // So for now, it's a NOP.
2105
        case STP:
2106
                b1 = ReadByte(pc);
2107
                pc++;
2108
                b2 = ReadByte(pc);
2109
                pc++;
2110
                ca[15] = pc;
2111
                imm_prefix = false;
2112
                return;
2113
 
2114
        case STSET:
2115
                b1 = ReadByte(pc);
2116
                pc++;
2117
                b2 = ReadByte(pc);
2118
                pc++;
2119
                b3 = ReadByte(pc);
2120
                pc++;
2121
                if (ex) {
2122
                        string_pc = pc - 5;     // address of the string instruction
2123
                        Ra = b1 & 0x3f;
2124
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2125
                        do {
2126
                                Sg = b3 >> 5;
2127
                                ea = GetGP(Ra) + seg_base[Sg];
2128
                                switch((b3 >> 2) & 3) {
2129
                                case 0:
2130
                                        dat = GetGP(Rb) & 0xFFLL;
2131
                                        dat = (dat << 56) | (dat << 48) | (dat << 40) | (dat << 32)
2132
                                                | (dat << 24) | (dat << 16) | (dat << 8) | dat;
2133
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -1 : 1));
2134
                                        system1->Write(ea,dat,WriteMask(ea,0),0);
2135 30 robfinch
                                        break;
2136 32 robfinch
                                case 1:
2137
                                        dat = GetGP(Rb) & 0xFFFFLL;
2138
                                        dat = (dat << 48) | (dat << 32)
2139
                                                | (dat << 16) | dat;
2140
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -2 : 2));
2141
                                        system1->Write(ea,dat,WriteMask(ea,1),0);
2142 30 robfinch
                                        break;
2143 32 robfinch
                                case 2:
2144
                                        dat = GetGP(Rb) & 0xFFFFFFFFLL;
2145
                                        dat = (dat << 32) | dat;
2146
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -4 : 4));
2147
                                        system1->Write(ea,dat,WriteMask(ea,2),0);
2148
                                        break;
2149
                                case 3:
2150
                                        dat = GetGP(Rb);
2151
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -8 : 8));
2152
                                        system1->Write(ea,dat,WriteMask(ea,3),0);
2153
                                        break;
2154 30 robfinch
                                }
2155 32 robfinch
                                if (lc==0) {
2156
                                        string_pc = 0;
2157
                                        break;
2158
                                }
2159
                                lc--;
2160
                        } while (!IRQActive());
2161
                }
2162
                ca[15] = pc;
2163
                imm_prefix = false;
2164
                return;
2165
 
2166
        /* ToDo: cause overflow exception */
2167
        case SUBI:
2168
                b1 = ReadByte(pc);
2169
                pc++;
2170
                b2 = ReadByte(pc);
2171
                pc++;
2172
                b3 = ReadByte(pc);
2173
                pc++;
2174
                if (ex) {
2175
                        Ra = b1 & 0x3f;
2176
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2177
                        if (imm_prefix) {
2178
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
2179 30 robfinch
                        }
2180 32 robfinch
                        else {
2181
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
2182
                                if (imm & 0x800)
2183
                                        imm |= 0xFFFFFFFFFFFFF000LL;
2184
                        }
2185
                        SetGP(Rt,GetGP(Ra) - imm);
2186
                }
2187
                ca[15] = pc;
2188
                imm_prefix = false;
2189
                return;
2190 30 robfinch
 
2191 32 robfinch
        case SUBUI:
2192
                b1 = ReadByte(pc);
2193
                pc++;
2194
                b2 = ReadByte(pc);
2195
                pc++;
2196
                b3 = ReadByte(pc);
2197
                pc++;
2198
                if (ex) {
2199
                        Ra = b1 & 0x3f;
2200
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2201
                        if (imm_prefix) {
2202
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
2203 30 robfinch
                        }
2204 32 robfinch
                        else {
2205
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
2206
                                if (imm & 0x800)
2207
                                        imm |= 0xFFFFFFFFFFFFF000LL;
2208
                        }
2209
                        SetGP(Rt,GetGP(Ra) - imm);
2210
                }
2211
                ca[15] = pc;
2212
                imm_prefix = false;
2213
                return;
2214 30 robfinch
 
2215 32 robfinch
        case SW:
2216
                b1 = ReadByte(pc);
2217
                pc++;
2218
                b2 = ReadByte(pc);
2219
                pc++;
2220
                b3 = ReadByte(pc);
2221
                pc++;
2222
                if (ex) {
2223
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2224
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
2225
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
2226
                        system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF);
2227 30 robfinch
                }
2228 32 robfinch
                ca[15] = pc;
2229
                imm_prefix = false;
2230
                return;
2231
 
2232
        case SWCR:
2233
                b1 = ReadByte(pc);
2234
                pc++;
2235
                b2 = ReadByte(pc);
2236
                pc++;
2237
                b3 = ReadByte(pc);
2238
                pc++;
2239
                if (ex) {
2240
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2241
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
2242
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
2243
                        system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF,1);
2244
                }
2245
                ca[15] = pc;
2246
                imm_prefix = false;
2247
                return;
2248
 
2249
        case SWS:
2250
                b1 = ReadByte(pc);
2251
                pc++;
2252
                b2 = ReadByte(pc);
2253
                pc++;
2254
                b3 = ReadByte(pc);
2255
                pc++;
2256
                if (ex) {
2257
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
2258
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
2259
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
2260
                        system1->Write(ea,GetSpr(Rb),(0xFF << (ea & 7)) & 0xFF);
2261
                }
2262
                ca[15] = pc;
2263
                imm_prefix = false;
2264
                return;
2265
 
2266
        case SWX:
2267
                b1 = ReadByte(pc);
2268
                pc++;
2269
                b2 = ReadByte(pc);
2270
                pc++;
2271
                b3 = ReadByte(pc);
2272
                pc++;
2273
                if (ex) {
2274
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
2275
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
2276
                        system1->Write(ea,GetGP(Rt),(0xFF << (ea & 7)) & 0xFF);
2277
                }
2278
                ca[15] = pc;
2279
                imm_prefix = false;
2280
                return;
2281
 
2282
        // The SYNC instruction is a pipeline control. The pipeline is
2283
        // not emulated by this emulator. So it's treated as a NOP.
2284
        case SYNC:
2285
                ca[15] = pc;
2286
                imm_prefix = false;
2287
                break;
2288
 
2289
        case SYS:
2290
                b1 = ReadByte(pc);
2291
                pc++;
2292
                b2 = ReadByte(pc);
2293
                pc++;
2294
                if (ex) {
2295
                        Ct = b1 & 0xF;
2296
                        Cr = b1 >> 4;
2297
                        ca[Ct] = pc;
2298
                        ca[0] = 0;
2299
                        pc = (b2 << 4) + ca[Cr];
2300
                        if (Ct==11)
2301
                                StatusDBG = true;
2302
                        else if (StatusEXL < 255)
2303
                                StatusEXL++;
2304
                }
2305
                ca[15] = pc;
2306
                imm_prefix = false;
2307
                return;
2308
 
2309
        // The TLB isn't implemented yet. the boot rom currently just
2310
        // sets up the TLB registers and then leaves it disabled.
2311
        case TLB:
2312
                b1 = ReadByte(pc);
2313
                pc++;
2314
                b2 = ReadByte(pc);
2315
                pc++;
2316
                if (ex) {
2317
                        ;
2318
                }
2319
                ca[15] = pc;
2320
                imm_prefix = false;
2321
                return;
2322
 
2323 30 robfinch
        }
2324
}

powered by: WebSVN 2.1.0

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