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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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