this repo has no description
1/*
2 MINEM68K.c
3
4 Copyright (C) 2009 Bernd Schmidt, Paul C. Pratt
5
6 You can redistribute this file and/or modify it under the terms
7 of version 2 of the GNU General Public License as published by
8 the Free Software Foundation. You should have received a copy
9 of the license along with this file; see the file COPYING.
10
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 license for more details.
15*/
16
17/*
18 EMulator of 68K cpu with GENeric c code (not assembly)
19
20 This code descends from a simple 68000 emulator that I
21 (Paul C. Pratt) wrote long ago. That emulator ran on a 680x0,
22 and used the cpu it ran on to do some of the work. This
23 descendent fills in those holes with code from the
24 Un*x Amiga Emulator by Bernd Schmidt, as found being used in vMac.
25
26 This emulator is about 10 times smaller than the UAE,
27 at the cost of being 2 to 3 times slower.
28
29 FPU Emulation added 9/12/2009 by Ross Martin
30 (this code now located in "FPCPEMDV.h")
31*/
32
33#include "PICOMMON.h"
34
35#include "M68KITAB.h"
36
37#if WantDisasm
38#include "DISAM68K.h"
39#endif
40
41#include "MINEM68K.h"
42
43/*
44 ReportAbnormalID unused 0x0123 - 0x01FF
45*/
46
47#ifndef DisableLazyFlagAll
48#define DisableLazyFlagAll 0
49#endif
50 /*
51 useful for debugging, to tell if an observed bug is
52 being cause by lazy flag evaluation stuff.
53 Can also disable parts of it individually:
54 */
55
56#ifndef ForceFlagsEval
57#if DisableLazyFlagAll
58#define ForceFlagsEval 1
59#else
60#define ForceFlagsEval 0
61#endif
62#endif
63
64#ifndef UseLazyZ
65#if DisableLazyFlagAll || ForceFlagsEval
66#define UseLazyZ 0
67#else
68#define UseLazyZ 1
69#endif
70#endif
71
72#ifndef UseLazyCC
73#if DisableLazyFlagAll
74#define UseLazyCC 0
75#else
76#define UseLazyCC 1
77#endif
78#endif
79
80
81typedef unsigned char flagtype; /* must be 0 or 1, not boolean */
82
83
84/* Memory Address Translation Cache record */
85
86struct MATCr {
87 ui5r cmpmask;
88 ui5r cmpvalu;
89 ui5r usemask;
90 ui3p usebase;
91};
92typedef struct MATCr MATCr;
93typedef MATCr *MATCp;
94
95#ifndef USE_PCLIMIT
96#define USE_PCLIMIT 1
97#endif
98
99#define AKMemory 0
100#define AKRegister 1
101
102union ArgAddrT {
103 ui5r mem;
104 ui5r *rga;
105};
106typedef union ArgAddrT ArgAddrT;
107
108enum {
109 kLazyFlagsDefault,
110 kLazyFlagsTstB,
111 kLazyFlagsTstW,
112 kLazyFlagsTstL,
113 kLazyFlagsCmpB,
114 kLazyFlagsCmpW,
115 kLazyFlagsCmpL,
116 kLazyFlagsSubB,
117 kLazyFlagsSubW,
118 kLazyFlagsSubL,
119 kLazyFlagsAddB,
120 kLazyFlagsAddW,
121 kLazyFlagsAddL,
122 kLazyFlagsNegB,
123 kLazyFlagsNegW,
124 kLazyFlagsNegL,
125 kLazyFlagsAsrB,
126 kLazyFlagsAsrW,
127 kLazyFlagsAsrL,
128 kLazyFlagsAslB,
129 kLazyFlagsAslW,
130 kLazyFlagsAslL,
131#if UseLazyZ
132 kLazyFlagsZSet,
133#endif
134
135 kNumLazyFlagsKinds
136};
137
138typedef void (my_reg_call *ArgSetDstP)(ui5r f);
139
140#define FasterAlignedL 0
141 /*
142 If most long memory access is long aligned,
143 this should be faster. But on the Mac, this
144 doesn't seem to be the case, so an
145 unpredictable branch slows it down.
146 */
147
148#ifndef HaveGlbReg
149#define HaveGlbReg 0
150#endif
151
152LOCALVAR struct regstruct
153{
154 ui5r regs[16]; /* Data and Address registers */
155
156 ui3p pc_p;
157 ui3p pc_pHi;
158 si5rr MaxCyclesToGo;
159
160#if WantCloserCyc
161 DecOpR *CurDecOp;
162#endif
163 DecOpYR CurDecOpY;
164
165 ui3r LazyFlagKind;
166 ui3r LazyXFlagKind;
167#if UseLazyZ
168 ui3r LazyFlagZSavedKind;
169#endif
170 ui5r LazyFlagArgSrc;
171 ui5r LazyFlagArgDst;
172 ui5r LazyXFlagArgSrc;
173 ui5r LazyXFlagArgDst;
174
175 ArgAddrT ArgAddr;
176 ArgSetDstP ArgSetDst;
177 ui5b SrcVal;
178
179 ui3p pc_pLo;
180 ui5r pc; /* Program Counter */
181
182 MATCr MATCrdB;
183 MATCr MATCwrB;
184 MATCr MATCrdW;
185 MATCr MATCwrW;
186#if FasterAlignedL
187 MATCr MATCrdL;
188 MATCr MATCwrL;
189#endif
190 ATTep HeadATTel;
191
192 si5r MoreCyclesToGo;
193 si5r ResidualCycles;
194 ui3b fakeword[2];
195
196 /* Status Register */
197 ui5r intmask; /* bits 10-8 : interrupt priority mask */
198 flagtype t1; /* bit 15: Trace mode 1 */
199#if Use68020
200 flagtype t0; /* bit 14: Trace mode 0 */
201#endif
202 flagtype s; /* bit 13: Supervisor or user privilege level */
203#if Use68020
204 flagtype m; /* bit 12: Master or interrupt mode */
205#endif
206
207 flagtype x; /* bit 4: eXtend */
208 flagtype n; /* bit 3: Negative */
209 flagtype z; /* bit 2: Zero */
210 flagtype v; /* bit 1: oVerflow */
211 flagtype c; /* bit 0: Carry */
212
213#if EmMMU | EmFPU
214 ui5b ArgKind;
215#endif
216
217 blnr TracePending;
218 blnr ExternalInterruptPending;
219#if 0
220 blnr ResetPending;
221#endif
222 ui3b *fIPL;
223#ifdef r_regs
224 struct regstruct *save_regs;
225#endif
226
227 CPTR usp; /* User Stack Pointer */
228 CPTR isp; /* Interrupt Stack Pointer */
229#if Use68020
230 CPTR msp; /* Master Stack Pointer */
231 ui5b sfc; /* Source Function Code register */
232 ui5b dfc; /* Destination Function Code register */
233 ui5b vbr; /* Vector Base Register */
234 ui5b cacr; /* Cache Control Register */
235 /*
236 bit 0 : Enable Cache
237 bit 1 : Freeze Cache
238 bit 2 : Clear Entry In Cache (write only)
239 bit 3 : Clear Cache (write only)
240 */
241 ui5b caar; /* Cache Address Register */
242#endif
243
244#define disp_table_sz (256 * 256)
245#if SmallGlobals
246 DecOpR *disp_table;
247#else
248 DecOpR disp_table[disp_table_sz];
249#endif
250} regs;
251
252#define ui5r_MSBisSet(x) (((si5r)(x)) < 0)
253
254#define Bool2Bit(x) ((x) ? 1 : 0)
255
256
257#ifdef r_regs
258register struct regstruct *g_regs asm (r_regs);
259#define V_regs (*g_regs)
260#else
261#define V_regs regs
262#endif
263
264#ifdef r_pc_p
265register ui3p g_pc_p asm (r_pc_p);
266#define V_pc_p g_pc_p
267#else
268#define V_pc_p V_regs.pc_p
269#endif
270
271#ifdef r_MaxCyclesToGo
272register si5rr g_MaxCyclesToGo asm (r_MaxCyclesToGo);
273#define V_MaxCyclesToGo g_MaxCyclesToGo
274#else
275#define V_MaxCyclesToGo V_regs.MaxCyclesToGo
276#endif
277
278#ifdef r_pc_pHi
279register ui3p g_pc_pHi asm (r_pc_pHi);
280#define V_pc_pHi g_pc_pHi
281#else
282#define V_pc_pHi V_regs.pc_pHi
283#endif
284
285#define ZFLG V_regs.z
286#define NFLG V_regs.n
287#define CFLG V_regs.c
288#define VFLG V_regs.v
289#define XFLG V_regs.x
290
291#define m68k_dreg(num) (V_regs.regs[(num)])
292#define m68k_areg(num) (V_regs.regs[(num) + 8])
293
294
295#ifndef WantDumpTable
296#define WantDumpTable 0
297#endif
298
299#if WantDumpTable
300LOCALVAR ui5b DumpTable[kNumIKinds];
301#endif
302
303#if USE_PCLIMIT
304FORWARDPROC Recalc_PC_Block(void);
305FORWARDFUNC ui5r my_reg_call Recalc_PC_BlockReturnUi5r(ui5r v);
306#endif
307
308LOCALINLINEFUNC ui4r nextiword(void)
309/* NOT sign extended */
310{
311 ui4r r = do_get_mem_word(V_pc_p);
312 V_pc_p += 2;
313
314#if USE_PCLIMIT
315 if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
316 Recalc_PC_Block();
317 }
318#endif
319
320 return r;
321}
322
323LOCALINLINEFUNC ui5r nextiSByte(void)
324{
325 ui5r r = ui5r_FromSByte(do_get_mem_byte(V_pc_p + 1));
326 V_pc_p += 2;
327
328#if USE_PCLIMIT
329 if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
330 return Recalc_PC_BlockReturnUi5r(r);
331 }
332#endif
333
334 return r;
335}
336
337LOCALINLINEFUNC ui5r nextiSWord(void)
338/* NOT sign extended */
339{
340 ui5r r = ui5r_FromSWord(do_get_mem_word(V_pc_p));
341 V_pc_p += 2;
342
343#if USE_PCLIMIT
344 if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
345 return Recalc_PC_BlockReturnUi5r(r);
346 }
347#endif
348
349 return r;
350}
351
352FORWARDFUNC ui5r nextilong_ext(void);
353
354LOCALINLINEFUNC ui5r nextilong(void)
355{
356 ui5r r = do_get_mem_long(V_pc_p);
357 V_pc_p += 4;
358
359#if USE_PCLIMIT
360 /* could be two words in different blocks */
361 if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
362 r = nextilong_ext();
363 }
364#endif
365
366 return r;
367}
368
369LOCALINLINEPROC BackupPC(void)
370{
371 V_pc_p -= 2;
372
373#if USE_PCLIMIT
374 if (my_cond_rare(V_pc_p < V_regs.pc_pLo)) {
375 Recalc_PC_Block();
376 }
377#endif
378}
379
380LOCALINLINEFUNC CPTR m68k_getpc(void)
381{
382 return V_regs.pc + (V_pc_p - V_regs.pc_pLo);
383}
384
385
386FORWARDPROC DoCodeTst(void);
387FORWARDPROC DoCodeCmpB(void);
388FORWARDPROC DoCodeCmpW(void);
389FORWARDPROC DoCodeCmpL(void);
390FORWARDPROC DoCodeBccB(void);
391FORWARDPROC DoCodeBccW(void);
392FORWARDPROC DoCodeBraB(void);
393FORWARDPROC DoCodeBraW(void);
394FORWARDPROC DoCodeDBcc(void);
395FORWARDPROC DoCodeDBF(void);
396FORWARDPROC DoCodeSwap(void);
397FORWARDPROC DoCodeMoveL(void);
398FORWARDPROC DoCodeMoveW(void);
399FORWARDPROC DoCodeMoveB(void);
400FORWARDPROC DoCodeMoveA(void);
401FORWARDPROC DoCodeMoveQ(void);
402FORWARDPROC DoCodeAddB(void);
403FORWARDPROC DoCodeAddW(void);
404FORWARDPROC DoCodeAddL(void);
405FORWARDPROC DoCodeSubB(void);
406FORWARDPROC DoCodeSubW(void);
407FORWARDPROC DoCodeSubL(void);
408FORWARDPROC DoCodeLea(void);
409FORWARDPROC DoCodePEA(void);
410FORWARDPROC DoCodeA(void);
411FORWARDPROC DoCodeBsrB(void);
412FORWARDPROC DoCodeBsrW(void);
413FORWARDPROC DoCodeJsr(void);
414FORWARDPROC DoCodeLinkA6(void);
415FORWARDPROC DoCodeMOVEMRmML(void);
416FORWARDPROC DoCodeMOVEMApRL(void);
417FORWARDPROC DoCodeUnlkA6(void);
418FORWARDPROC DoCodeRts(void);
419FORWARDPROC DoCodeJmp(void);
420FORWARDPROC DoCodeClr(void);
421FORWARDPROC DoCodeAddA(void);
422FORWARDPROC DoCodeSubA(void);
423FORWARDPROC DoCodeCmpA(void);
424FORWARDPROC DoCodeAddXB(void);
425FORWARDPROC DoCodeAddXW(void);
426FORWARDPROC DoCodeAddXL(void);
427FORWARDPROC DoCodeSubXB(void);
428FORWARDPROC DoCodeSubXW(void);
429FORWARDPROC DoCodeSubXL(void);
430FORWARDPROC DoCodeAslB(void);
431FORWARDPROC DoCodeAslW(void);
432FORWARDPROC DoCodeAslL(void);
433FORWARDPROC DoCodeAsrB(void);
434FORWARDPROC DoCodeAsrW(void);
435FORWARDPROC DoCodeAsrL(void);
436FORWARDPROC DoCodeLslB(void);
437FORWARDPROC DoCodeLslW(void);
438FORWARDPROC DoCodeLslL(void);
439FORWARDPROC DoCodeLsrB(void);
440FORWARDPROC DoCodeLsrW(void);
441FORWARDPROC DoCodeLsrL(void);
442FORWARDPROC DoCodeRxlB(void);
443FORWARDPROC DoCodeRxlW(void);
444FORWARDPROC DoCodeRxlL(void);
445FORWARDPROC DoCodeRxrB(void);
446FORWARDPROC DoCodeRxrW(void);
447FORWARDPROC DoCodeRxrL(void);
448FORWARDPROC DoCodeRolB(void);
449FORWARDPROC DoCodeRolW(void);
450FORWARDPROC DoCodeRolL(void);
451FORWARDPROC DoCodeRorB(void);
452FORWARDPROC DoCodeRorW(void);
453FORWARDPROC DoCodeRorL(void);
454FORWARDPROC DoCodeBTstB(void);
455FORWARDPROC DoCodeBChgB(void);
456FORWARDPROC DoCodeBClrB(void);
457FORWARDPROC DoCodeBSetB(void);
458FORWARDPROC DoCodeBTstL(void);
459FORWARDPROC DoCodeBChgL(void);
460FORWARDPROC DoCodeBClrL(void);
461FORWARDPROC DoCodeBSetL(void);
462FORWARDPROC DoCodeAnd(void);
463FORWARDPROC DoCodeOr(void);
464FORWARDPROC DoCodeEor(void);
465FORWARDPROC DoCodeNot(void);
466FORWARDPROC DoCodeScc(void);
467FORWARDPROC DoCodeNegXB(void);
468FORWARDPROC DoCodeNegXW(void);
469FORWARDPROC DoCodeNegXL(void);
470FORWARDPROC DoCodeNegB(void);
471FORWARDPROC DoCodeNegW(void);
472FORWARDPROC DoCodeNegL(void);
473FORWARDPROC DoCodeEXTW(void);
474FORWARDPROC DoCodeEXTL(void);
475FORWARDPROC DoCodeMulU(void);
476FORWARDPROC DoCodeMulS(void);
477FORWARDPROC DoCodeDivU(void);
478FORWARDPROC DoCodeDivS(void);
479FORWARDPROC DoCodeExg(void);
480FORWARDPROC DoCodeMoveEaCR(void);
481FORWARDPROC DoCodeMoveSREa(void);
482FORWARDPROC DoCodeMoveEaSR(void);
483FORWARDPROC DoCodeOrISR(void);
484FORWARDPROC DoCodeAndISR(void);
485FORWARDPROC DoCodeEorISR(void);
486FORWARDPROC DoCodeOrICCR(void);
487FORWARDPROC DoCodeAndICCR(void);
488FORWARDPROC DoCodeEorICCR(void);
489FORWARDPROC DoCodeMOVEMApRW(void);
490FORWARDPROC DoCodeMOVEMRmMW(void);
491FORWARDPROC DoCodeMOVEMrmW(void);
492FORWARDPROC DoCodeMOVEMrmL(void);
493FORWARDPROC DoCodeMOVEMmrW(void);
494FORWARDPROC DoCodeMOVEMmrL(void);
495FORWARDPROC DoCodeAbcd(void);
496FORWARDPROC DoCodeSbcd(void);
497FORWARDPROC DoCodeNbcd(void);
498FORWARDPROC DoCodeRte(void);
499FORWARDPROC DoCodeNop(void);
500FORWARDPROC DoCodeMoveP0(void);
501FORWARDPROC DoCodeMoveP1(void);
502FORWARDPROC DoCodeMoveP2(void);
503FORWARDPROC DoCodeMoveP3(void);
504FORWARDPROC op_illg(void);
505FORWARDPROC DoCodeChk(void);
506FORWARDPROC DoCodeTrap(void);
507FORWARDPROC DoCodeTrapV(void);
508FORWARDPROC DoCodeRtr(void);
509FORWARDPROC DoCodeLink(void);
510FORWARDPROC DoCodeUnlk(void);
511FORWARDPROC DoCodeMoveRUSP(void);
512FORWARDPROC DoCodeMoveUSPR(void);
513FORWARDPROC DoCodeTas(void);
514FORWARDPROC DoCodeFdefault(void);
515FORWARDPROC DoCodeStop(void);
516FORWARDPROC DoCodeReset(void);
517
518#if Use68020
519FORWARDPROC DoCodeCallMorRtm(void);
520FORWARDPROC DoCodeBraL(void);
521FORWARDPROC DoCodeBccL(void);
522FORWARDPROC DoCodeBsrL(void);
523FORWARDPROC DoCodeEXTBL(void);
524FORWARDPROC DoCodeTRAPcc(void);
525FORWARDPROC DoCodeBkpt(void);
526FORWARDPROC DoCodeDivL(void);
527FORWARDPROC DoCodeMulL(void);
528FORWARDPROC DoCodeRtd(void);
529FORWARDPROC DoCodeMoveCCREa(void);
530FORWARDPROC DoMoveFromControl(void);
531FORWARDPROC DoMoveToControl(void);
532FORWARDPROC DoCodeLinkL(void);
533FORWARDPROC DoCodePack(void);
534FORWARDPROC DoCodeUnpk(void);
535FORWARDPROC DoCHK2orCMP2(void);
536FORWARDPROC DoCAS2(void);
537FORWARDPROC DoCAS(void);
538FORWARDPROC DoMOVES(void);
539FORWARDPROC DoBitField(void);
540#endif
541
542#if EmMMU
543FORWARDPROC DoCodeMMU(void);
544#endif
545
546#if EmFPU
547FORWARDPROC DoCodeFPU_md60(void);
548FORWARDPROC DoCodeFPU_DBcc(void);
549FORWARDPROC DoCodeFPU_Trapcc(void);
550FORWARDPROC DoCodeFPU_Scc(void);
551FORWARDPROC DoCodeFPU_FBccW(void);
552FORWARDPROC DoCodeFPU_FBccL(void);
553FORWARDPROC DoCodeFPU_Save(void);
554FORWARDPROC DoCodeFPU_Restore(void);
555FORWARDPROC DoCodeFPU_dflt(void);
556#endif
557
558typedef void (*func_pointer_t)(void);
559
560LOCALVAR const func_pointer_t OpDispatch[kNumIKinds + 1] = {
561 DoCodeTst /* kIKindTst */,
562 DoCodeCmpB /* kIKindCmpB */,
563 DoCodeCmpW /* kIKindCmpW */,
564 DoCodeCmpL /* kIKindCmpL */,
565 DoCodeBccB /* kIKindBccB */,
566 DoCodeBccW /* kIKindBccW */,
567 DoCodeBraB /* kIKindBraB */,
568 DoCodeBraW /* kIKindBraW */,
569 DoCodeDBcc /* kIKindDBcc */,
570 DoCodeDBF /* kIKindDBF */,
571 DoCodeSwap /* kIKindSwap */,
572 DoCodeMoveL /* kIKindMoveL */,
573 DoCodeMoveW /* kIKindMoveW */,
574 DoCodeMoveB /* kIKindMoveB */,
575 DoCodeMoveA /* kIKindMoveAL */,
576 DoCodeMoveA /* kIKindMoveAW */,
577 DoCodeMoveQ /* kIKindMoveQ */,
578 DoCodeAddB /* kIKindAddB */,
579 DoCodeAddW /* kIKindAddW */,
580 DoCodeAddL /* kIKindAddL */,
581 DoCodeSubB /* kIKindSubB */,
582 DoCodeSubW /* kIKindSubW */,
583 DoCodeSubL /* kIKindSubL */,
584 DoCodeLea /* kIKindLea */,
585 DoCodePEA /* kIKindPEA */,
586 DoCodeA /* kIKindA */,
587 DoCodeBsrB /* kIKindBsrB */,
588 DoCodeBsrW /* kIKindBsrW */,
589 DoCodeJsr /* kIKindJsr */,
590 DoCodeLinkA6 /* kIKindLinkA6 */,
591 DoCodeMOVEMRmML /* kIKindMOVEMRmML */,
592 DoCodeMOVEMApRL /* kIKindMOVEMApRL */,
593 DoCodeUnlkA6 /* kIKindUnlkA6 */,
594 DoCodeRts /* kIKindRts */,
595 DoCodeJmp /* kIKindJmp */,
596 DoCodeClr /* kIKindClr */,
597 DoCodeAddA /* kIKindAddA */,
598 DoCodeAddA /* kIKindAddQA */,
599 DoCodeSubA /* kIKindSubA */,
600 DoCodeSubA /* kIKindSubQA */,
601 DoCodeCmpA /* kIKindCmpA */,
602 DoCodeAddXB /* kIKindAddXB */,
603 DoCodeAddXW /* kIKindAddXW */,
604 DoCodeAddXL /* kIKindAddXL */,
605 DoCodeSubXB /* kIKindSubXB */,
606 DoCodeSubXW /* kIKindSubXW */,
607 DoCodeSubXL /* kIKindSubXL */,
608 DoCodeAslB /* kIKindAslB */,
609 DoCodeAslW /* kIKindAslW */,
610 DoCodeAslL /* kIKindAslL */,
611 DoCodeAsrB /* kIKindAsrB */,
612 DoCodeAsrW /* kIKindAsrW */,
613 DoCodeAsrL /* kIKindAsrL */,
614 DoCodeLslB /* kIKindLslB */,
615 DoCodeLslW /* kIKindLslW */,
616 DoCodeLslL /* kIKindLslL */,
617 DoCodeLsrB /* kIKindLsrB */,
618 DoCodeLsrW /* kIKindLsrW */,
619 DoCodeLsrL /* kIKindLsrL */,
620 DoCodeRxlB /* kIKindRxlB */,
621 DoCodeRxlW /* kIKindRxlW */,
622 DoCodeRxlL /* kIKindRxlL */,
623 DoCodeRxrB /* kIKindRxrB */,
624 DoCodeRxrW /* kIKindRxrW */,
625 DoCodeRxrL /* kIKindRxrL */,
626 DoCodeRolB /* kIKindRolB */,
627 DoCodeRolW /* kIKindRolW */,
628 DoCodeRolL /* kIKindRolL */,
629 DoCodeRorB /* kIKindRorB */,
630 DoCodeRorW /* kIKindRorW */,
631 DoCodeRorL /* kIKindRorL */,
632 DoCodeBTstB /* kIKindBTstB */,
633 DoCodeBChgB /* kIKindBChgB */,
634 DoCodeBClrB /* kIKindBClrB */,
635 DoCodeBSetB /* kIKindBSetB */,
636 DoCodeBTstL /* kIKindBTstL */,
637 DoCodeBChgL /* kIKindBChgL */,
638 DoCodeBClrL /* kIKindBClrL */,
639 DoCodeBSetL /* kIKindBSetL */,
640 DoCodeAnd /* kIKindAndI */,
641 DoCodeAnd /* kIKindAndEaD */,
642 DoCodeAnd /* kIKindAndDEa */,
643 DoCodeOr /* kIKindOrI */,
644 DoCodeOr /* kIKindOrDEa */,
645 DoCodeOr /* kIKindOrEaD */,
646 DoCodeEor /* kIKindEor */,
647 DoCodeEor /* kIKindEorI */,
648 DoCodeNot /* kIKindNot */,
649 DoCodeScc /* kIKindScc */,
650 DoCodeNegXB /* kIKindNegXB */,
651 DoCodeNegXW /* kIKindNegXW */,
652 DoCodeNegXL /* kIKindNegXL */,
653 DoCodeNegB /* kIKindNegB */,
654 DoCodeNegW /* kIKindNegW */,
655 DoCodeNegL /* kIKindNegL */,
656 DoCodeEXTW /* kIKindEXTW */,
657 DoCodeEXTL /* kIKindEXTL */,
658 DoCodeMulU /* kIKindMulU */,
659 DoCodeMulS /* kIKindMulS */,
660 DoCodeDivU /* kIKindDivU */,
661 DoCodeDivS /* kIKindDivS */,
662 DoCodeExg /* kIKindExg */,
663 DoCodeMoveEaCR /* kIKindMoveEaCCR */,
664 DoCodeMoveSREa /* kIKindMoveSREa */,
665 DoCodeMoveEaSR /* kIKindMoveEaSR */,
666 DoCodeOrISR /* kIKindOrISR */,
667 DoCodeAndISR /* kIKindAndISR */,
668 DoCodeEorISR /* kIKindEorISR */,
669 DoCodeOrICCR /* kIKindOrICCR */,
670 DoCodeAndICCR /* kIKindAndICCR */,
671 DoCodeEorICCR /* kIKindEorICCR */,
672 DoCodeMOVEMApRW /* kIKindMOVEMApRW */,
673 DoCodeMOVEMRmMW /* kIKindMOVEMRmMW */,
674 DoCodeMOVEMrmW /* kIKindMOVEMrmW */,
675 DoCodeMOVEMrmL /* kIKindMOVEMrmL */,
676 DoCodeMOVEMmrW /* kIKindMOVEMmrW */,
677 DoCodeMOVEMmrL /* kIKindMOVEMmrL */,
678 DoCodeAbcd /* kIKindAbcd */,
679 DoCodeSbcd /* kIKindSbcd */,
680 DoCodeNbcd /* kIKindNbcd */,
681 DoCodeRte /* kIKindRte */,
682 DoCodeNop /* kIKindNop */,
683 DoCodeMoveP0 /* kIKindMoveP0 */,
684 DoCodeMoveP1 /* kIKindMoveP1 */,
685 DoCodeMoveP2 /* kIKindMoveP2 */,
686 DoCodeMoveP3 /* kIKindMoveP3 */,
687 op_illg /* kIKindIllegal */,
688 DoCodeChk /* kIKindChkW */,
689 DoCodeTrap /* kIKindTrap */,
690 DoCodeTrapV /* kIKindTrapV */,
691 DoCodeRtr /* kIKindRtr */,
692 DoCodeLink /* kIKindLink */,
693 DoCodeUnlk /* kIKindUnlk */,
694 DoCodeMoveRUSP /* kIKindMoveRUSP */,
695 DoCodeMoveUSPR /* kIKindMoveUSPR */,
696 DoCodeTas /* kIKindTas */,
697 DoCodeFdefault /* kIKindFdflt */,
698 DoCodeStop /* kIKindStop */,
699 DoCodeReset /* kIKindReset */,
700
701#if Use68020
702 DoCodeCallMorRtm /* kIKindCallMorRtm */,
703 DoCodeBraL /* kIKindBraL */,
704 DoCodeBccL /* kIKindBccL */,
705 DoCodeBsrL /* kIKindBsrL */,
706 DoCodeEXTBL /* kIKindEXTBL */,
707 DoCodeTRAPcc /* kIKindTRAPcc */,
708 DoCodeChk /* kIKindChkL */,
709 DoCodeBkpt /* kIKindBkpt */,
710 DoCodeDivL /* kIKindDivL */,
711 DoCodeMulL /* kIKindMulL */,
712 DoCodeRtd /* kIKindRtd */,
713 DoCodeMoveCCREa /* kIKindMoveCCREa */,
714 DoMoveFromControl /* kIKindMoveCEa */,
715 DoMoveToControl /* kIKindMoveEaC */,
716 DoCodeLinkL /* kIKindLinkL */,
717 DoCodePack /* kIKindPack */,
718 DoCodeUnpk /* kIKindUnpk */,
719 DoCHK2orCMP2 /* kIKindCHK2orCMP2 */,
720 DoCAS2 /* kIKindCAS2 */,
721 DoCAS /* kIKindCAS */,
722 DoMOVES /* kIKindMoveS */,
723 DoBitField /* kIKindBitField */,
724#endif
725#if EmMMU
726 DoCodeMMU /* kIKindMMU */,
727#endif
728#if EmFPU
729 DoCodeFPU_md60 /* kIKindFPUmd60 */,
730 DoCodeFPU_DBcc /* kIKindFPUDBcc */,
731 DoCodeFPU_Trapcc /* kIKindFPUTrapcc */,
732 DoCodeFPU_Scc /* kIKindFPUScc */,
733 DoCodeFPU_FBccW /* kIKindFPUFBccW */,
734 DoCodeFPU_FBccL /* kIKindFPUFBccL */,
735 DoCodeFPU_Save /* kIKindFPUSave */,
736 DoCodeFPU_Restore /* kIKindFPURestore */,
737 DoCodeFPU_dflt /* kIKindFPUdflt */,
738#endif
739
740 0
741};
742
743#ifndef WantBreakPoint
744#define WantBreakPoint 0
745#endif
746
747#if WantBreakPoint
748
749#define BreakPointAddress 0xD198
750
751LOCALPROC BreakPointAction(void)
752{
753 dbglog_StartLine();
754 dbglog_writeCStr("breakpoint A0=");
755 dbglog_writeHex(m68k_areg(0));
756 dbglog_writeCStr(" A1=");
757 dbglog_writeHex(m68k_areg(1));
758 dbglog_writeReturn();
759}
760
761#endif
762
763LOCALINLINEPROC DecodeNextInstruction(func_pointer_t *d, ui4rr *Cycles,
764 DecOpYR *y)
765{
766 ui5r opcode;
767 DecOpR *p;
768 ui4rr MainClas;
769
770 opcode = nextiword();
771
772 p = &V_regs.disp_table[opcode];
773
774#if WantCloserCyc
775 V_regs.CurDecOp = p;
776#endif
777 MainClas = p->x.MainClas;
778 *Cycles = p->x.Cycles;
779 *y = p->y;
780#if WantDumpTable
781 DumpTable[MainClas] ++;
782#endif
783 *d = OpDispatch[MainClas];
784}
785
786LOCALINLINEPROC UnDecodeNextInstruction(ui4rr Cycles)
787{
788 V_MaxCyclesToGo += Cycles;
789
790 BackupPC();
791
792#if WantDumpTable
793 {
794 ui5r opcode = do_get_mem_word(V_pc_p);
795 DecOpR *p = &V_regs.disp_table[opcode];
796 ui4rr MainClas = p->x.MainClas;
797
798 DumpTable[MainClas] --;
799 }
800#endif
801}
802
803LOCALPROC m68k_go_MaxCycles(void)
804{
805 ui4rr Cycles;
806 DecOpYR y;
807 func_pointer_t d;
808
809 /*
810 Main loop of emulator.
811
812 Always execute at least one instruction,
813 even if V_regs.MaxInstructionsToGo == 0.
814 Needed for trace flag to work.
815 */
816
817 DecodeNextInstruction(&d, &Cycles, &y);
818
819 V_MaxCyclesToGo -= Cycles;
820
821 do {
822 V_regs.CurDecOpY = y;
823
824#if WantDisasm || WantBreakPoint
825 {
826 CPTR pc = m68k_getpc() - 2;
827#if WantDisasm
828 DisasmOneOrSave(pc);
829#endif
830#if WantBreakPoint
831 if (BreakPointAddress == pc) {
832 BreakPointAction();
833 }
834#endif
835 }
836#endif
837
838 d();
839
840 DecodeNextInstruction(&d, &Cycles, &y);
841
842 } while (((si5rr)(V_MaxCyclesToGo -= Cycles)) > 0);
843
844 /* abort instruction that have started to decode */
845
846 UnDecodeNextInstruction(Cycles);
847}
848
849FORWARDFUNC ui5r my_reg_call get_byte_ext(CPTR addr);
850
851LOCALFUNC ui5r my_reg_call get_byte(CPTR addr)
852{
853 ui3p m = (addr & V_regs.MATCrdB.usemask) + V_regs.MATCrdB.usebase;
854
855 if ((addr & V_regs.MATCrdB.cmpmask) == V_regs.MATCrdB.cmpvalu) {
856 return ui5r_FromSByte(*m);
857 } else {
858 return get_byte_ext(addr);
859 }
860}
861
862FORWARDPROC my_reg_call put_byte_ext(CPTR addr, ui5r b);
863
864LOCALPROC my_reg_call put_byte(CPTR addr, ui5r b)
865{
866 ui3p m = (addr & V_regs.MATCwrB.usemask) + V_regs.MATCwrB.usebase;
867 if ((addr & V_regs.MATCwrB.cmpmask) == V_regs.MATCwrB.cmpvalu) {
868 *m = b;
869 } else {
870 put_byte_ext(addr, b);
871 }
872}
873
874FORWARDFUNC ui5r my_reg_call get_word_ext(CPTR addr);
875
876LOCALFUNC ui5r my_reg_call get_word(CPTR addr)
877{
878 ui3p m = (addr & V_regs.MATCrdW.usemask) + V_regs.MATCrdW.usebase;
879 if ((addr & V_regs.MATCrdW.cmpmask) == V_regs.MATCrdW.cmpvalu) {
880 return ui5r_FromSWord(do_get_mem_word(m));
881 } else {
882 return get_word_ext(addr);
883 }
884}
885
886FORWARDPROC my_reg_call put_word_ext(CPTR addr, ui5r w);
887
888LOCALPROC my_reg_call put_word(CPTR addr, ui5r w)
889{
890 ui3p m = (addr & V_regs.MATCwrW.usemask) + V_regs.MATCwrW.usebase;
891 if ((addr & V_regs.MATCwrW.cmpmask) == V_regs.MATCwrW.cmpvalu) {
892 do_put_mem_word(m, w);
893 } else {
894 put_word_ext(addr, w);
895 }
896}
897
898FORWARDFUNC ui5r my_reg_call get_long_misaligned_ext(CPTR addr);
899
900LOCALFUNC ui5r my_reg_call get_long_misaligned(CPTR addr)
901{
902 CPTR addr2 = addr + 2;
903 ui3p m = (addr & V_regs.MATCrdW.usemask) + V_regs.MATCrdW.usebase;
904 ui3p m2 = (addr2 & V_regs.MATCrdW.usemask) + V_regs.MATCrdW.usebase;
905 if (((addr & V_regs.MATCrdW.cmpmask) == V_regs.MATCrdW.cmpvalu)
906 && ((addr2 & V_regs.MATCrdW.cmpmask) == V_regs.MATCrdW.cmpvalu))
907 {
908 ui5r hi = do_get_mem_word(m);
909 ui5r lo = do_get_mem_word(m2);
910 ui5r Data = ((hi << 16) & 0xFFFF0000)
911 | (lo & 0x0000FFFF);
912
913 return ui5r_FromSLong(Data);
914 } else {
915 return get_long_misaligned_ext(addr);
916 }
917}
918
919#if FasterAlignedL
920FORWARDFUNC ui5r my_reg_call get_long_ext(CPTR addr);
921#endif
922
923#if FasterAlignedL
924LOCALFUNC ui5r my_reg_call get_long(CPTR addr)
925{
926 if (0 == (addr & 0x03)) {
927 ui3p m = (addr & V_regs.MATCrdL.usemask)
928 + V_regs.MATCrdL.usebase;
929 if ((addr & V_regs.MATCrdL.cmpmask) == V_regs.MATCrdL.cmpvalu) {
930 return ui5r_FromSLong(do_get_mem_long(m));
931 } else {
932 return get_long_ext(addr);
933 }
934 } else {
935 return get_long_misaligned(addr);
936 }
937}
938#else
939#define get_long get_long_misaligned
940#endif
941
942FORWARDPROC my_reg_call put_long_misaligned_ext(CPTR addr, ui5r l);
943
944LOCALPROC my_reg_call put_long_misaligned(CPTR addr, ui5r l)
945{
946 CPTR addr2 = addr + 2;
947 ui3p m = (addr & V_regs.MATCwrW.usemask) + V_regs.MATCwrW.usebase;
948 ui3p m2 = (addr2 & V_regs.MATCwrW.usemask) + V_regs.MATCwrW.usebase;
949 if (((addr & V_regs.MATCwrW.cmpmask) == V_regs.MATCwrW.cmpvalu)
950 && ((addr2 & V_regs.MATCwrW.cmpmask) == V_regs.MATCwrW.cmpvalu))
951 {
952 do_put_mem_word(m, l >> 16);
953 do_put_mem_word(m2, l);
954 } else {
955 put_long_misaligned_ext(addr, l);
956 }
957}
958
959#if FasterAlignedL
960FORWARDPROC my_reg_call put_long_ext(CPTR addr, ui5r l);
961#endif
962
963#if FasterAlignedL
964LOCALPROC my_reg_call put_long(CPTR addr, ui5r l)
965{
966 if (0 == (addr & 0x03)) {
967 ui3p m = (addr & V_regs.MATCwrL.usemask)
968 + V_regs.MATCwrL.usebase;
969 if ((addr & V_regs.MATCwrL.cmpmask) == V_regs.MATCwrL.cmpvalu) {
970 do_put_mem_long(m, l);
971 } else {
972 put_long_ext(addr, l);
973 }
974 } else {
975 put_long_misaligned(addr, l);
976 }
977}
978#else
979#define put_long put_long_misaligned
980#endif
981
982LOCALFUNC ui5b my_reg_call get_disp_ea(ui5b base)
983{
984 ui4b dp = nextiword();
985 int regno = (dp >> 12) & 0x0F;
986 si5b regd = V_regs.regs[regno];
987 if ((dp & 0x0800) == 0) {
988 regd = (si5b)(si4b)regd;
989 }
990#if Use68020
991 regd <<= (dp >> 9) & 3;
992#if ExtraAbnormalReports
993 if (((dp >> 9) & 3) != 0) {
994 /* ReportAbnormal("Have scale in Extension Word"); */
995 /* apparently can happen in Sys 7.5.5 boot on 68000 */
996 }
997#endif
998 if (dp & 0x0100) {
999 if ((dp & 0x80) != 0) {
1000 base = 0;
1001 /* ReportAbnormal("Extension Word: suppress base"); */
1002 /* used by Sys 7.5.5 boot */
1003 }
1004 if ((dp & 0x40) != 0) {
1005 regd = 0;
1006 /* ReportAbnormal("Extension Word: suppress regd"); */
1007 /* used by Mac II boot */
1008 }
1009
1010 switch ((dp >> 4) & 0x03) {
1011 case 0:
1012 /* reserved */
1013 ReportAbnormalID(0x0101, "Extension Word: dp reserved");
1014 break;
1015 case 1:
1016 /* no displacement */
1017 /* ReportAbnormal("Extension Word: no displacement"); */
1018 /* used by Sys 7.5.5 boot */
1019 break;
1020 case 2:
1021 base += nextiSWord();
1022 /*
1023 ReportAbnormal("Extension Word: word displacement");
1024 */
1025 /* used by Sys 7.5.5 boot */
1026 break;
1027 case 3:
1028 base += nextilong();
1029 /*
1030 ReportAbnormal("Extension Word: long displacement");
1031 */
1032 /* used by Mac II boot from system 6.0.8? */
1033 break;
1034 }
1035
1036 if ((dp & 0x03) == 0) {
1037 base += regd;
1038 if ((dp & 0x04) != 0) {
1039 ReportAbnormalID(0x0102,
1040 "Extension Word: reserved dp form");
1041 }
1042 /* ReportAbnormal("Extension Word: noindex"); */
1043 /* used by Sys 7.5.5 boot */
1044 } else {
1045 if ((dp & 0x04) != 0) {
1046 base = get_long(base);
1047 base += regd;
1048 /* ReportAbnormal("Extension Word: postindex"); */
1049 /* used by Sys 7.5.5 boot */
1050 } else {
1051 base += regd;
1052 base = get_long(base);
1053 /* ReportAbnormal("Extension Word: preindex"); */
1054 /* used by Sys 7.5.5 boot */
1055 }
1056 switch (dp & 0x03) {
1057 case 1:
1058 /* null outer displacement */
1059 /*
1060 ReportAbnormal(
1061 "Extension Word: null outer displacement");
1062 */
1063 /* used by Sys 7.5.5 boot */
1064 break;
1065 case 2:
1066 base += nextiSWord();
1067 /*
1068 ReportAbnormal(
1069 "Extension Word: word outer displacement");
1070 */
1071 /* used by Mac II boot from system 6.0.8? */
1072 break;
1073 case 3:
1074 base += nextilong();
1075 /*
1076 ReportAbnormal(
1077 "Extension Word: long outer displacement");
1078 */
1079 /* used by Mac II boot from system 6.0.8? */
1080 break;
1081 }
1082 }
1083
1084 return base;
1085 } else
1086#endif
1087 {
1088 return base + (si3b)(dp) + regd;
1089 }
1090}
1091
1092LOCALFUNC ui5r my_reg_call DecodeAddr_Indirect(ui3rr ArgDat)
1093{
1094 return V_regs.regs[ArgDat];
1095}
1096
1097LOCALFUNC ui5r my_reg_call DecodeAddr_APosIncB(ui3rr ArgDat)
1098{
1099 ui5r *p = &V_regs.regs[ArgDat];
1100 ui5r a = *p;
1101
1102 *p = a + 1;
1103
1104 return a;
1105}
1106
1107LOCALFUNC ui5r my_reg_call DecodeAddr_APosIncW(ui3rr ArgDat)
1108{
1109 ui5r *p = &V_regs.regs[ArgDat];
1110 ui5r a = *p;
1111
1112 *p = a + 2;
1113
1114 return a;
1115}
1116
1117LOCALFUNC ui5r my_reg_call DecodeAddr_APosIncL(ui3rr ArgDat)
1118{
1119 ui5r *p = &V_regs.regs[ArgDat];
1120 ui5r a = *p;
1121
1122 *p = a + 4;
1123
1124 return a;
1125}
1126
1127LOCALFUNC ui5r my_reg_call DecodeAddr_APreDecB(ui3rr ArgDat)
1128{
1129 ui5r *p = &V_regs.regs[ArgDat];
1130 ui5r a = *p - 1;
1131
1132 *p = a;
1133
1134 return a;
1135}
1136
1137LOCALFUNC ui5r my_reg_call DecodeAddr_APreDecW(ui3rr ArgDat)
1138{
1139 ui5r *p = &V_regs.regs[ArgDat];
1140 ui5r a = *p - 2;
1141
1142 *p = a;
1143
1144 return a;
1145}
1146
1147LOCALFUNC ui5r my_reg_call DecodeAddr_APreDecL(ui3rr ArgDat)
1148{
1149 ui5r *p = &V_regs.regs[ArgDat];
1150 ui5r a = *p - 4;
1151
1152 *p = a;
1153
1154 return a;
1155}
1156
1157LOCALFUNC ui5r my_reg_call DecodeAddr_ADisp(ui3rr ArgDat)
1158{
1159 return V_regs.regs[ArgDat] + nextiSWord();
1160}
1161
1162LOCALFUNC ui5r my_reg_call DecodeAddr_AIndex(ui3rr ArgDat)
1163{
1164 return get_disp_ea(V_regs.regs[ArgDat]);
1165}
1166
1167LOCALFUNC ui5r my_reg_call DecodeAddr_AbsW(ui3rr ArgDat)
1168{
1169 UnusedParam(ArgDat);
1170 return nextiSWord();
1171}
1172
1173LOCALFUNC ui5r my_reg_call DecodeAddr_AbsL(ui3rr ArgDat)
1174{
1175 UnusedParam(ArgDat);
1176 return nextilong();
1177}
1178
1179LOCALFUNC ui5r my_reg_call DecodeAddr_PCDisp(ui3rr ArgDat)
1180{
1181 CPTR pc = m68k_getpc();
1182
1183 UnusedParam(ArgDat);
1184 return pc + nextiSWord();
1185}
1186
1187LOCALFUNC ui5r my_reg_call DecodeAddr_PCIndex(ui3rr ArgDat)
1188{
1189 UnusedParam(ArgDat);
1190 return get_disp_ea(m68k_getpc());
1191}
1192
1193typedef ui5r (my_reg_call *DecodeAddrP)(ui3rr ArgDat);
1194
1195LOCALVAR const DecodeAddrP DecodeAddrDispatch[kNumAMds] = {
1196 (DecodeAddrP)nullpr /* kAMdRegB */,
1197 (DecodeAddrP)nullpr /* kAMdRegW */,
1198 (DecodeAddrP)nullpr /* kAMdRegL */,
1199 DecodeAddr_Indirect /* kAMdIndirectB */,
1200 DecodeAddr_Indirect /* kAMdIndirectW */,
1201 DecodeAddr_Indirect /* kAMdIndirectL */,
1202 DecodeAddr_APosIncB /* kAMdAPosIncB */,
1203 DecodeAddr_APosIncW /* kAMdAPosIncW */,
1204 DecodeAddr_APosIncL /* kAMdAPosIncL */,
1205 DecodeAddr_APosIncW /* kAMdAPosInc7B */,
1206 DecodeAddr_APreDecB /* kAMdAPreDecB */,
1207 DecodeAddr_APreDecW /* kAMdAPreDecW */,
1208 DecodeAddr_APreDecL /* kAMdAPreDecL */,
1209 DecodeAddr_APreDecW /* kAMdAPreDec7B */,
1210 DecodeAddr_ADisp /* kAMdADispB */,
1211 DecodeAddr_ADisp /* kAMdADispW */,
1212 DecodeAddr_ADisp /* kAMdADispL */,
1213 DecodeAddr_AIndex /* kAMdAIndexB */,
1214 DecodeAddr_AIndex /* kAMdAIndexW */,
1215 DecodeAddr_AIndex /* kAMdAIndexL */,
1216 DecodeAddr_AbsW /* kAMdAbsWB */,
1217 DecodeAddr_AbsW /* kAMdAbsWW */,
1218 DecodeAddr_AbsW /* kAMdAbsWL */,
1219 DecodeAddr_AbsL /* kAMdAbsLB */,
1220 DecodeAddr_AbsL /* kAMdAbsLW */,
1221 DecodeAddr_AbsL /* kAMdAbsLL */,
1222 DecodeAddr_PCDisp /* kAMdPCDispB */,
1223 DecodeAddr_PCDisp /* kAMdPCDispW */,
1224 DecodeAddr_PCDisp /* kAMdPCDispL */,
1225 DecodeAddr_PCIndex /* kAMdPCIndexB */,
1226 DecodeAddr_PCIndex /* kAMdPCIndexW */,
1227 DecodeAddr_PCIndex /* kAMdPCIndexL */,
1228 (DecodeAddrP)nullpr /* kAMdImmedB */,
1229 (DecodeAddrP)nullpr /* kAMdImmedW */,
1230 (DecodeAddrP)nullpr /* kAMdImmedL */,
1231 (DecodeAddrP)nullpr /* kAMdDat4 */
1232};
1233
1234LOCALINLINEFUNC ui5r DecodeAddrSrcDst(DecArgR *f)
1235{
1236 return (DecodeAddrDispatch[f->AMd])(f->ArgDat);
1237}
1238
1239LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_RegB(ui3rr ArgDat)
1240{
1241 return ui5r_FromSByte(V_regs.regs[ArgDat]);
1242}
1243
1244LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_RegW(ui3rr ArgDat)
1245{
1246 return ui5r_FromSWord(V_regs.regs[ArgDat]);
1247}
1248
1249LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_RegL(ui3rr ArgDat)
1250{
1251 return ui5r_FromSLong(V_regs.regs[ArgDat]);
1252}
1253
1254LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_IndirectB(ui3rr ArgDat)
1255{
1256 return get_byte(V_regs.regs[ArgDat]);
1257}
1258
1259LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_IndirectW(ui3rr ArgDat)
1260{
1261 return get_word(V_regs.regs[ArgDat]);
1262}
1263
1264LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_IndirectL(ui3rr ArgDat)
1265{
1266 return get_long(V_regs.regs[ArgDat]);
1267}
1268
1269LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosIncB(ui3rr ArgDat)
1270{
1271 ui5r *p = &V_regs.regs[ArgDat];
1272 ui5r a = *p;
1273
1274 *p = a + 1;
1275
1276 return get_byte(a);
1277}
1278
1279LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosIncW(ui3rr ArgDat)
1280{
1281 ui5r *p = &V_regs.regs[ArgDat];
1282 ui5r a = *p;
1283
1284 *p = a + 2;
1285
1286 return get_word(a);
1287}
1288
1289LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosIncL(ui3rr ArgDat)
1290{
1291 ui5r *p = &V_regs.regs[ArgDat];
1292 ui5r a = *p;
1293
1294 *p = a + 4;
1295
1296 return get_long(a);
1297}
1298
1299LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosInc7B(ui3rr ArgDat)
1300{
1301 ui5r *p = &V_regs.regs[ArgDat];
1302 ui5r a = *p;
1303
1304 *p = a + 2;
1305
1306 return get_byte(a);
1307}
1308
1309LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDecB(ui3rr ArgDat)
1310{
1311 ui5r *p = &V_regs.regs[ArgDat];
1312 ui5r a = *p - 1;
1313
1314 *p = a;
1315
1316 return get_byte(a);
1317}
1318
1319LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDecW(ui3rr ArgDat)
1320{
1321 ui5r *p = &V_regs.regs[ArgDat];
1322 ui5r a = *p - 2;
1323
1324 *p = a;
1325
1326 return get_word(a);
1327}
1328
1329LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDecL(ui3rr ArgDat)
1330{
1331 ui5r *p = &V_regs.regs[ArgDat];
1332 ui5r a = *p - 4;
1333
1334 *p = a;
1335
1336 return get_long(a);
1337}
1338
1339LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDec7B(ui3rr ArgDat)
1340{
1341 ui5r *p = &V_regs.regs[ArgDat];
1342 ui5r a = *p - 2;
1343
1344 *p = a;
1345
1346 return get_byte(a);
1347}
1348
1349LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ADispB(ui3rr ArgDat)
1350{
1351 return get_byte(DecodeAddr_ADisp(ArgDat));
1352}
1353
1354LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ADispW(ui3rr ArgDat)
1355{
1356 return get_word(DecodeAddr_ADisp(ArgDat));
1357}
1358
1359LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ADispL(ui3rr ArgDat)
1360{
1361 return get_long(DecodeAddr_ADisp(ArgDat));
1362}
1363
1364LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AIndexB(ui3rr ArgDat)
1365{
1366 return get_byte(get_disp_ea(V_regs.regs[ArgDat]));
1367}
1368
1369LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AIndexW(ui3rr ArgDat)
1370{
1371 return get_word(get_disp_ea(V_regs.regs[ArgDat]));
1372}
1373
1374LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AIndexL(ui3rr ArgDat)
1375{
1376 return get_long(get_disp_ea(V_regs.regs[ArgDat]));
1377}
1378
1379LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsWB(ui3rr ArgDat)
1380{
1381 return get_byte(DecodeAddr_AbsW(ArgDat));
1382}
1383
1384LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsWW(ui3rr ArgDat)
1385{
1386 return get_word(DecodeAddr_AbsW(ArgDat));
1387}
1388
1389LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsWL(ui3rr ArgDat)
1390{
1391 return get_long(DecodeAddr_AbsW(ArgDat));
1392}
1393
1394LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsLB(ui3rr ArgDat)
1395{
1396 return get_byte(DecodeAddr_AbsL(ArgDat));
1397}
1398
1399LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsLW(ui3rr ArgDat)
1400{
1401 return get_word(DecodeAddr_AbsL(ArgDat));
1402}
1403
1404LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsLL(ui3rr ArgDat)
1405{
1406 return get_long(DecodeAddr_AbsL(ArgDat));
1407}
1408
1409LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCDispB(ui3rr ArgDat)
1410{
1411 return get_byte(DecodeAddr_PCDisp(ArgDat));
1412}
1413
1414LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCDispW(ui3rr ArgDat)
1415{
1416 return get_word(DecodeAddr_PCDisp(ArgDat));
1417}
1418
1419LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCDispL(ui3rr ArgDat)
1420{
1421 return get_long(DecodeAddr_PCDisp(ArgDat));
1422}
1423
1424LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCIndexB(ui3rr ArgDat)
1425{
1426 return get_byte(DecodeAddr_PCIndex(ArgDat));
1427}
1428
1429LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCIndexW(ui3rr ArgDat)
1430{
1431 return get_word(DecodeAddr_PCIndex(ArgDat));
1432}
1433
1434LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCIndexL(ui3rr ArgDat)
1435{
1436 return get_long(DecodeAddr_PCIndex(ArgDat));
1437}
1438
1439LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ImmedB(ui3rr ArgDat)
1440{
1441 UnusedParam(ArgDat);
1442 return nextiSByte();
1443}
1444
1445LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ImmedW(ui3rr ArgDat)
1446{
1447 UnusedParam(ArgDat);
1448 return nextiSWord();
1449}
1450
1451LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ImmedL(ui3rr ArgDat)
1452{
1453 UnusedParam(ArgDat);
1454 return ui5r_FromSLong(nextilong());
1455}
1456
1457LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_Dat4(ui3rr ArgDat)
1458{
1459 return ArgDat;
1460}
1461
1462typedef ui5r (my_reg_call *DecodeGetSrcDstP)(ui3rr ArgDat);
1463
1464LOCALVAR const DecodeGetSrcDstP DecodeGetSrcDstDispatch[kNumAMds] = {
1465 DecodeGetSrcDst_RegB /* kAMdRegB */,
1466 DecodeGetSrcDst_RegW /* kAMdRegW */,
1467 DecodeGetSrcDst_RegL /* kAMdRegL */,
1468 DecodeGetSrcDst_IndirectB /* kAMdIndirectB */,
1469 DecodeGetSrcDst_IndirectW /* kAMdIndirectW */,
1470 DecodeGetSrcDst_IndirectL /* kAMdIndirectL */,
1471 DecodeGetSrcDst_APosIncB /* kAMdAPosIncB */,
1472 DecodeGetSrcDst_APosIncW /* kAMdAPosIncW */,
1473 DecodeGetSrcDst_APosIncL /* kAMdAPosIncL */,
1474 DecodeGetSrcDst_APosInc7B /* kAMdAPosInc7B */,
1475 DecodeGetSrcDst_APreDecB /* kAMdAPreDecB */,
1476 DecodeGetSrcDst_APreDecW /* kAMdAPreDecW */,
1477 DecodeGetSrcDst_APreDecL /* kAMdAPreDecL */,
1478 DecodeGetSrcDst_APreDec7B /* kAMdAPreDec7B */,
1479 DecodeGetSrcDst_ADispB /* kAMdADispB */,
1480 DecodeGetSrcDst_ADispW /* kAMdADispW */,
1481 DecodeGetSrcDst_ADispL /* kAMdADispL */,
1482 DecodeGetSrcDst_AIndexB /* kAMdAIndexB */,
1483 DecodeGetSrcDst_AIndexW /* kAMdAIndexW */,
1484 DecodeGetSrcDst_AIndexL /* kAMdAIndexL */,
1485 DecodeGetSrcDst_AbsWB /* kAMdAbsWB */,
1486 DecodeGetSrcDst_AbsWW /* kAMdAbsWW */,
1487 DecodeGetSrcDst_AbsWL /* kAMdAbsWL */,
1488 DecodeGetSrcDst_AbsLB /* kAMdAbsLB */,
1489 DecodeGetSrcDst_AbsLW /* kAMdAbsLW */,
1490 DecodeGetSrcDst_AbsLL /* kAMdAbsLL */,
1491 DecodeGetSrcDst_PCDispB /* kAMdPCDispB */,
1492 DecodeGetSrcDst_PCDispW /* kAMdPCDispW */,
1493 DecodeGetSrcDst_PCDispL /* kAMdPCDispL */,
1494 DecodeGetSrcDst_PCIndexB /* kAMdPCIndexB */,
1495 DecodeGetSrcDst_PCIndexW /* kAMdPCIndexW */,
1496 DecodeGetSrcDst_PCIndexL /* kAMdPCIndexL */,
1497 DecodeGetSrcDst_ImmedB /* kAMdImmedB */,
1498 DecodeGetSrcDst_ImmedW /* kAMdImmedW */,
1499 DecodeGetSrcDst_ImmedL /* kAMdImmedL */,
1500 DecodeGetSrcDst_Dat4 /* kAMdDat4 */
1501};
1502
1503LOCALINLINEFUNC ui5r DecodeGetSrcDst(DecArgR *f)
1504{
1505 return (DecodeGetSrcDstDispatch[f->AMd])(f->ArgDat);
1506}
1507
1508LOCALPROC my_reg_call DecodeSetSrcDst_RegB(ui5r v, ui3rr ArgDat)
1509{
1510 ui5r *p = &V_regs.regs[ArgDat];
1511
1512#if LittleEndianUnaligned
1513 *(ui3b *)p = v;
1514#else
1515 *p = (*p & ~ 0xff) | ((v) & 0xff);
1516#endif
1517}
1518
1519LOCALPROC my_reg_call DecodeSetSrcDst_RegW(ui5r v, ui3rr ArgDat)
1520{
1521 ui5r *p = &V_regs.regs[ArgDat];
1522
1523#if LittleEndianUnaligned
1524 *(ui4b *)p = v;
1525#else
1526 *p = (*p & ~ 0xffff) | ((v) & 0xffff);
1527#endif
1528}
1529
1530LOCALPROC my_reg_call DecodeSetSrcDst_RegL(ui5r v, ui3rr ArgDat)
1531{
1532 V_regs.regs[ArgDat] = v;
1533}
1534
1535LOCALPROC my_reg_call DecodeSetSrcDst_IndirectB(ui5r v, ui3rr ArgDat)
1536{
1537 put_byte(V_regs.regs[ArgDat], v);
1538}
1539
1540LOCALPROC my_reg_call DecodeSetSrcDst_IndirectW(ui5r v, ui3rr ArgDat)
1541{
1542 put_word(V_regs.regs[ArgDat], v);
1543}
1544
1545LOCALPROC my_reg_call DecodeSetSrcDst_IndirectL(ui5r v, ui3rr ArgDat)
1546{
1547 put_long(V_regs.regs[ArgDat], v);
1548}
1549
1550LOCALPROC my_reg_call DecodeSetSrcDst_APosIncB(ui5r v, ui3rr ArgDat)
1551{
1552 ui5r *p = &V_regs.regs[ArgDat];
1553 ui5r a = *p;
1554
1555 *p = a + 1;
1556
1557 put_byte(a, v);
1558}
1559
1560LOCALPROC my_reg_call DecodeSetSrcDst_APosIncW(ui5r v, ui3rr ArgDat)
1561{
1562 ui5r *p = &V_regs.regs[ArgDat];
1563 ui5r a = *p;
1564
1565 *p = a + 2;
1566
1567 put_word(a, v);
1568}
1569
1570LOCALPROC my_reg_call DecodeSetSrcDst_APosIncL(ui5r v, ui3rr ArgDat)
1571{
1572 ui5r *p = &V_regs.regs[ArgDat];
1573 ui5r a = *p;
1574
1575 *p = a + 4;
1576
1577 put_long(a, v);
1578}
1579
1580LOCALPROC my_reg_call DecodeSetSrcDst_APosInc7B(ui5r v, ui3rr ArgDat)
1581{
1582 ui5r *p = &V_regs.regs[ArgDat];
1583 ui5r a = *p;
1584
1585 *p = a + 2;
1586
1587 put_byte(a, v);
1588}
1589
1590LOCALPROC my_reg_call DecodeSetSrcDst_APreDecB(ui5r v, ui3rr ArgDat)
1591{
1592 ui5r *p = &V_regs.regs[ArgDat];
1593 ui5r a = *p - 1;
1594
1595 *p = a;
1596
1597 put_byte(a, v);
1598}
1599
1600LOCALPROC my_reg_call DecodeSetSrcDst_APreDecW(ui5r v, ui3rr ArgDat)
1601{
1602 ui5r *p = &V_regs.regs[ArgDat];
1603 ui5r a = *p - 2;
1604
1605 *p = a;
1606
1607 put_word(a, v);
1608}
1609
1610LOCALPROC my_reg_call DecodeSetSrcDst_APreDecL(ui5r v, ui3rr ArgDat)
1611{
1612 ui5r *p = &V_regs.regs[ArgDat];
1613 ui5r a = *p - 4;
1614
1615 *p = a;
1616
1617 put_long(a, v);
1618}
1619
1620LOCALPROC my_reg_call DecodeSetSrcDst_APreDec7B(ui5r v, ui3rr ArgDat)
1621{
1622 ui5r *p = &V_regs.regs[ArgDat];
1623 ui5r a = *p - 2;
1624
1625 *p = a;
1626
1627 put_byte(a, v);
1628}
1629
1630LOCALPROC my_reg_call DecodeSetSrcDst_ADispB(ui5r v, ui3rr ArgDat)
1631{
1632 put_byte(V_regs.regs[ArgDat]
1633 + nextiSWord(), v);
1634}
1635
1636LOCALPROC my_reg_call DecodeSetSrcDst_ADispW(ui5r v, ui3rr ArgDat)
1637{
1638 put_word(V_regs.regs[ArgDat]
1639 + nextiSWord(), v);
1640}
1641
1642LOCALPROC my_reg_call DecodeSetSrcDst_ADispL(ui5r v, ui3rr ArgDat)
1643{
1644 put_long(V_regs.regs[ArgDat]
1645 + nextiSWord(), v);
1646}
1647
1648LOCALPROC my_reg_call DecodeSetSrcDst_AIndexB(ui5r v, ui3rr ArgDat)
1649{
1650 put_byte(get_disp_ea(V_regs.regs[ArgDat]), v);
1651}
1652
1653LOCALPROC my_reg_call DecodeSetSrcDst_AIndexW(ui5r v, ui3rr ArgDat)
1654{
1655 put_word(get_disp_ea(V_regs.regs[ArgDat]), v);
1656}
1657
1658LOCALPROC my_reg_call DecodeSetSrcDst_AIndexL(ui5r v, ui3rr ArgDat)
1659{
1660 put_long(get_disp_ea(V_regs.regs[ArgDat]), v);
1661}
1662
1663LOCALPROC my_reg_call DecodeSetSrcDst_AbsWB(ui5r v, ui3rr ArgDat)
1664{
1665 put_byte(DecodeAddr_AbsW(ArgDat), v);
1666}
1667
1668LOCALPROC my_reg_call DecodeSetSrcDst_AbsWW(ui5r v, ui3rr ArgDat)
1669{
1670 put_word(DecodeAddr_AbsW(ArgDat), v);
1671}
1672
1673LOCALPROC my_reg_call DecodeSetSrcDst_AbsWL(ui5r v, ui3rr ArgDat)
1674{
1675 put_long(DecodeAddr_AbsW(ArgDat), v);
1676}
1677
1678LOCALPROC my_reg_call DecodeSetSrcDst_AbsLB(ui5r v, ui3rr ArgDat)
1679{
1680 put_byte(DecodeAddr_AbsL(ArgDat), v);
1681}
1682
1683LOCALPROC my_reg_call DecodeSetSrcDst_AbsLW(ui5r v, ui3rr ArgDat)
1684{
1685 put_word(DecodeAddr_AbsL(ArgDat), v);
1686}
1687
1688LOCALPROC my_reg_call DecodeSetSrcDst_AbsLL(ui5r v, ui3rr ArgDat)
1689{
1690 put_long(DecodeAddr_AbsL(ArgDat), v);
1691}
1692
1693LOCALPROC my_reg_call DecodeSetSrcDst_PCDispB(ui5r v, ui3rr ArgDat)
1694{
1695 put_byte(DecodeAddr_PCDisp(ArgDat), v);
1696}
1697
1698LOCALPROC my_reg_call DecodeSetSrcDst_PCDispW(ui5r v, ui3rr ArgDat)
1699{
1700 put_word(DecodeAddr_PCDisp(ArgDat), v);
1701}
1702
1703LOCALPROC my_reg_call DecodeSetSrcDst_PCDispL(ui5r v, ui3rr ArgDat)
1704{
1705 put_long(DecodeAddr_PCDisp(ArgDat), v);
1706}
1707
1708LOCALPROC my_reg_call DecodeSetSrcDst_PCIndexB(ui5r v, ui3rr ArgDat)
1709{
1710 put_byte(DecodeAddr_PCIndex(ArgDat), v);
1711}
1712
1713LOCALPROC my_reg_call DecodeSetSrcDst_PCIndexW(ui5r v, ui3rr ArgDat)
1714{
1715 put_word(DecodeAddr_PCIndex(ArgDat), v);
1716}
1717
1718LOCALPROC my_reg_call DecodeSetSrcDst_PCIndexL(ui5r v, ui3rr ArgDat)
1719{
1720 put_long(DecodeAddr_PCIndex(ArgDat), v);
1721}
1722
1723typedef void (my_reg_call *DecodeSetSrcDstP)(ui5r v, ui3rr ArgDat);
1724
1725LOCALVAR const DecodeSetSrcDstP DecodeSetSrcDstDispatch[kNumAMds] = {
1726 DecodeSetSrcDst_RegB /* kAMdRegB */,
1727 DecodeSetSrcDst_RegW /* kAMdRegW */,
1728 DecodeSetSrcDst_RegL /* kAMdRegL */,
1729 DecodeSetSrcDst_IndirectB /* kAMdIndirectB */,
1730 DecodeSetSrcDst_IndirectW /* kAMdIndirectW */,
1731 DecodeSetSrcDst_IndirectL /* kAMdIndirectL*/,
1732 DecodeSetSrcDst_APosIncB /* kAMdAPosIncB */,
1733 DecodeSetSrcDst_APosIncW /* kAMdAPosIncW */,
1734 DecodeSetSrcDst_APosIncL /* kAMdAPosIncL */,
1735 DecodeSetSrcDst_APosInc7B /* kAMdAPosInc7B */,
1736 DecodeSetSrcDst_APreDecB /* kAMdAPreDecB */,
1737 DecodeSetSrcDst_APreDecW /* kAMdAPreDecW */,
1738 DecodeSetSrcDst_APreDecL /* kAMdAPreDecL */,
1739 DecodeSetSrcDst_APreDec7B /* kAMdAPreDec7B */,
1740 DecodeSetSrcDst_ADispB /* kAMdADispB */,
1741 DecodeSetSrcDst_ADispW /* kAMdADispW */,
1742 DecodeSetSrcDst_ADispL /* kAMdADispL */,
1743 DecodeSetSrcDst_AIndexB /* kAMdAIndexB */,
1744 DecodeSetSrcDst_AIndexW /* kAMdAIndexW */,
1745 DecodeSetSrcDst_AIndexL /* kAMdAIndexL */,
1746 DecodeSetSrcDst_AbsWB /* kAMdAbsWB */,
1747 DecodeSetSrcDst_AbsWW /* kAMdAbsWW */,
1748 DecodeSetSrcDst_AbsWL /* kAMdAbsWL */,
1749 DecodeSetSrcDst_AbsLB /* kAMdAbsLB */,
1750 DecodeSetSrcDst_AbsLW /* kAMdAbsLW */,
1751 DecodeSetSrcDst_AbsLL /* kAMdAbsLL */,
1752 DecodeSetSrcDst_PCDispB /* kAMdPCDispB */,
1753 DecodeSetSrcDst_PCDispW /* kAMdPCDispW */,
1754 DecodeSetSrcDst_PCDispL /* kAMdPCDispL */,
1755 DecodeSetSrcDst_PCIndexB /* kAMdPCIndexB */,
1756 DecodeSetSrcDst_PCIndexW /* kAMdPCIndexW */,
1757 DecodeSetSrcDst_PCIndexL /* kAMdPCIndexL */,
1758 (DecodeSetSrcDstP)nullpr /* kAMdImmedB */,
1759 (DecodeSetSrcDstP)nullpr /* kAMdImmedW */,
1760 (DecodeSetSrcDstP)nullpr /* kAMdImmedL */,
1761 (DecodeSetSrcDstP)nullpr /* kAMdDat4 */
1762};
1763
1764LOCALINLINEPROC DecodeSetSrcDst(ui5r v, DecArgR *f)
1765{
1766 (DecodeSetSrcDstDispatch[f->AMd])(v, f->ArgDat);
1767}
1768
1769LOCALPROC my_reg_call ArgSetDstRegBValue(ui5r v)
1770{
1771 ui5r *p = V_regs.ArgAddr.rga;
1772
1773#if LittleEndianUnaligned
1774 *(ui3b *)p = v;
1775#else
1776 *p = (*p & ~ 0xff) | ((v) & 0xff);
1777#endif
1778}
1779
1780LOCALPROC my_reg_call ArgSetDstRegWValue(ui5r v)
1781{
1782 ui5r *p = V_regs.ArgAddr.rga;
1783
1784#if LittleEndianUnaligned
1785 *(ui4b *)p = v;
1786#else
1787 *p = (*p & ~ 0xffff) | ((v) & 0xffff);
1788#endif
1789}
1790
1791LOCALPROC my_reg_call ArgSetDstRegLValue(ui5r v)
1792{
1793 ui5r *p = V_regs.ArgAddr.rga;
1794
1795 *p = v;
1796}
1797
1798LOCALPROC my_reg_call ArgSetDstMemBValue(ui5r v)
1799{
1800 put_byte(V_regs.ArgAddr.mem, v);
1801}
1802
1803LOCALPROC my_reg_call ArgSetDstMemWValue(ui5r v)
1804{
1805 put_word(V_regs.ArgAddr.mem, v);
1806}
1807
1808LOCALPROC my_reg_call ArgSetDstMemLValue(ui5r v)
1809{
1810 put_long(V_regs.ArgAddr.mem, v);
1811}
1812
1813LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_RegB(ui3rr ArgDat)
1814{
1815 ui5r *p = &V_regs.regs[ArgDat];
1816
1817 V_regs.ArgAddr.rga = p;
1818 V_regs.ArgSetDst = ArgSetDstRegBValue;
1819
1820 return ui5r_FromSByte(*p);
1821}
1822
1823LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_RegW(ui3rr ArgDat)
1824{
1825 ui5r *p = &V_regs.regs[ArgDat];
1826
1827 V_regs.ArgAddr.rga = p;
1828 V_regs.ArgSetDst = ArgSetDstRegWValue;
1829
1830 return ui5r_FromSWord(*p);
1831}
1832
1833LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_RegL(ui3rr ArgDat)
1834{
1835 ui5r *p = &V_regs.regs[ArgDat];
1836
1837 V_regs.ArgAddr.rga = p;
1838 V_regs.ArgSetDst = ArgSetDstRegLValue;
1839
1840 return ui5r_FromSLong(*p);
1841}
1842
1843LOCALFUNC ui5r my_reg_call getarg_byte(ui5r a)
1844{
1845 V_regs.ArgAddr.mem = a;
1846 V_regs.ArgSetDst = ArgSetDstMemBValue;
1847
1848 return get_byte(a);
1849}
1850
1851LOCALFUNC ui5r my_reg_call getarg_word(ui5r a)
1852{
1853 V_regs.ArgAddr.mem = a;
1854 V_regs.ArgSetDst = ArgSetDstMemWValue;
1855
1856 return get_word(a);
1857}
1858
1859LOCALFUNC ui5r my_reg_call getarg_long(ui5r a)
1860{
1861 V_regs.ArgAddr.mem = a;
1862 V_regs.ArgSetDst = ArgSetDstMemLValue;
1863
1864 return get_long(a);
1865}
1866
1867LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_IndirectB(ui3rr ArgDat)
1868{
1869 return getarg_byte(V_regs.regs[ArgDat]);
1870}
1871
1872LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_IndirectW(ui3rr ArgDat)
1873{
1874 return getarg_word(V_regs.regs[ArgDat]);
1875}
1876
1877LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_IndirectL(ui3rr ArgDat)
1878{
1879 return getarg_long(V_regs.regs[ArgDat]);
1880}
1881
1882LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosIncB(ui3rr ArgDat)
1883{
1884 ui5r *p = &V_regs.regs[ArgDat];
1885 ui5r a = *p;
1886
1887 *p = a + 1;
1888
1889 return getarg_byte(a);
1890}
1891
1892LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosIncW(ui3rr ArgDat)
1893{
1894 ui5r *p = &V_regs.regs[ArgDat];
1895 ui5r a = *p;
1896
1897 *p = a + 2;
1898
1899 return getarg_word(a);
1900}
1901
1902LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosIncL(ui3rr ArgDat)
1903{
1904 ui5r *p = &V_regs.regs[ArgDat];
1905 ui5r a = *p;
1906
1907 *p = a + 4;
1908
1909 return getarg_long(a);
1910}
1911
1912LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosInc7B(ui3rr ArgDat)
1913{
1914 ui5r *p = &V_regs.regs[ArgDat];
1915 ui5r a = *p;
1916
1917 *p = a + 2;
1918
1919 return getarg_byte(a);
1920}
1921
1922LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDecB(ui3rr ArgDat)
1923{
1924 ui5r *p = &V_regs.regs[ArgDat];
1925 ui5r a = *p - 1;
1926
1927 *p = a;
1928
1929 return getarg_byte(a);
1930}
1931
1932LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDecW(ui3rr ArgDat)
1933{
1934 ui5r *p = &V_regs.regs[ArgDat];
1935 ui5r a = *p - 2;
1936
1937 *p = a;
1938
1939 return getarg_word(a);
1940}
1941
1942LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDecL(ui3rr ArgDat)
1943{
1944 ui5r *p = &V_regs.regs[ArgDat];
1945 ui5r a = *p - 4;
1946
1947 *p = a;
1948
1949 return getarg_long(a);
1950}
1951
1952LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDec7B(ui3rr ArgDat)
1953{
1954 ui5r *p = &V_regs.regs[ArgDat];
1955 ui5r a = *p - 2;
1956
1957 *p = a;
1958
1959 return getarg_byte(a);
1960}
1961
1962LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_ADispB(ui3rr ArgDat)
1963{
1964 return getarg_byte(V_regs.regs[ArgDat]
1965 + nextiSWord());
1966}
1967
1968LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_ADispW(ui3rr ArgDat)
1969{
1970 return getarg_word(V_regs.regs[ArgDat]
1971 + nextiSWord());
1972}
1973
1974LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_ADispL(ui3rr ArgDat)
1975{
1976 return getarg_long(V_regs.regs[ArgDat]
1977 + nextiSWord());
1978}
1979
1980LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AIndexB(ui3rr ArgDat)
1981{
1982 return getarg_byte(get_disp_ea(V_regs.regs[ArgDat]));
1983}
1984
1985LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AIndexW(ui3rr ArgDat)
1986{
1987 return getarg_word(get_disp_ea(V_regs.regs[ArgDat]));
1988}
1989
1990LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AIndexL(ui3rr ArgDat)
1991{
1992 return getarg_long(get_disp_ea(V_regs.regs[ArgDat]));
1993}
1994
1995LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsWB(ui3rr ArgDat)
1996{
1997 return getarg_byte(DecodeAddr_AbsW(ArgDat));
1998}
1999
2000LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsWW(ui3rr ArgDat)
2001{
2002 return getarg_word(DecodeAddr_AbsW(ArgDat));
2003}
2004
2005LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsWL(ui3rr ArgDat)
2006{
2007 return getarg_long(DecodeAddr_AbsW(ArgDat));
2008}
2009
2010LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsLB(ui3rr ArgDat)
2011{
2012 return getarg_byte(DecodeAddr_AbsL(ArgDat));
2013}
2014
2015LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsLW(ui3rr ArgDat)
2016{
2017 return getarg_word(DecodeAddr_AbsL(ArgDat));
2018}
2019
2020LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsLL(ui3rr ArgDat)
2021{
2022 return getarg_long(DecodeAddr_AbsL(ArgDat));
2023}
2024
2025LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCDispB(ui3rr ArgDat)
2026{
2027 return getarg_byte(DecodeAddr_PCDisp(ArgDat));
2028}
2029
2030LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCDispW(ui3rr ArgDat)
2031{
2032 return getarg_word(DecodeAddr_PCDisp(ArgDat));
2033}
2034
2035LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCDispL(ui3rr ArgDat)
2036{
2037 return getarg_long(DecodeAddr_PCDisp(ArgDat));
2038}
2039
2040LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCIndexB(ui3rr ArgDat)
2041{
2042 return getarg_byte(DecodeAddr_PCIndex(ArgDat));
2043}
2044
2045LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCIndexW(ui3rr ArgDat)
2046{
2047 return getarg_word(DecodeAddr_PCIndex(ArgDat));
2048}
2049
2050LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCIndexL(ui3rr ArgDat)
2051{
2052 return getarg_long(DecodeAddr_PCIndex(ArgDat));
2053}
2054
2055typedef ui5r (my_reg_call *DecodeGetSetSrcDstP)(ui3rr ArgDat);
2056
2057LOCALVAR const DecodeGetSetSrcDstP
2058 DecodeGetSetSrcDstDispatch[kNumAMds] =
2059{
2060 DecodeGetSetSrcDst_RegB /* kAMdRegB */,
2061 DecodeGetSetSrcDst_RegW /* kAMdRegW */,
2062 DecodeGetSetSrcDst_RegL /* kAMdRegL */,
2063 DecodeGetSetSrcDst_IndirectB /* kAMdIndirectB */,
2064 DecodeGetSetSrcDst_IndirectW /* kAMdIndirectW */,
2065 DecodeGetSetSrcDst_IndirectL /* kAMdIndirectL*/,
2066 DecodeGetSetSrcDst_APosIncB /* kAMdAPosIncB */,
2067 DecodeGetSetSrcDst_APosIncW /* kAMdAPosIncW */,
2068 DecodeGetSetSrcDst_APosIncL /* kAMdAPosIncL */,
2069 DecodeGetSetSrcDst_APosInc7B /* kAMdAPosInc7B */,
2070 DecodeGetSetSrcDst_APreDecB /* kAMdAPreDecB */,
2071 DecodeGetSetSrcDst_APreDecW /* kAMdAPreDecW */,
2072 DecodeGetSetSrcDst_APreDecL /* kAMdAPreDecL */,
2073 DecodeGetSetSrcDst_APreDec7B /* kAMdAPreDec7B */,
2074 DecodeGetSetSrcDst_ADispB /* kAMdADispB */,
2075 DecodeGetSetSrcDst_ADispW /* kAMdADispW */,
2076 DecodeGetSetSrcDst_ADispL /* kAMdADispL */,
2077 DecodeGetSetSrcDst_AIndexB /* kAMdAIndexB */,
2078 DecodeGetSetSrcDst_AIndexW /* kAMdAIndexW */,
2079 DecodeGetSetSrcDst_AIndexL /* kAMdAIndexL */,
2080 DecodeGetSetSrcDst_AbsWB /* kAMdAbsWB */,
2081 DecodeGetSetSrcDst_AbsWW /* kAMdAbsWW */,
2082 DecodeGetSetSrcDst_AbsWL /* kAMdAbsWL */,
2083 DecodeGetSetSrcDst_AbsLB /* kAMdAbsLB */,
2084 DecodeGetSetSrcDst_AbsLW /* kAMdAbsLW */,
2085 DecodeGetSetSrcDst_AbsLL /* kAMdAbsLL */,
2086 DecodeGetSetSrcDst_PCDispB /* kAMdPCDispB */,
2087 DecodeGetSetSrcDst_PCDispW /* kAMdPCDispW */,
2088 DecodeGetSetSrcDst_PCDispL /* kAMdPCDispL */,
2089 DecodeGetSetSrcDst_PCIndexB /* kAMdPCIndexB */,
2090 DecodeGetSetSrcDst_PCIndexW /* kAMdPCIndexW */,
2091 DecodeGetSetSrcDst_PCIndexL /* kAMdPCIndexL */,
2092 (DecodeGetSetSrcDstP)nullpr /* kAMdImmedB */,
2093 (DecodeGetSetSrcDstP)nullpr /* kAMdImmedW */,
2094 (DecodeGetSetSrcDstP)nullpr /* kAMdImmedL */,
2095 (DecodeGetSetSrcDstP)nullpr /* kAMdDat4 */
2096};
2097
2098LOCALINLINEFUNC ui5r DecodeGetSetSrcDst(DecArgR *f)
2099{
2100 return (DecodeGetSetSrcDstDispatch[f->AMd])(f->ArgDat);
2101}
2102
2103
2104LOCALINLINEFUNC ui5r DecodeDst(void)
2105{
2106 return DecodeAddrSrcDst(&V_regs.CurDecOpY.v[1]);
2107}
2108
2109LOCALINLINEFUNC ui5r DecodeGetSetDstValue(void)
2110{
2111 return DecodeGetSetSrcDst(&V_regs.CurDecOpY.v[1]);
2112}
2113
2114LOCALINLINEPROC ArgSetDstValue(ui5r v)
2115{
2116 V_regs.ArgSetDst(v);
2117}
2118
2119LOCALINLINEPROC DecodeSetDstValue(ui5r v)
2120{
2121 DecodeSetSrcDst(v, &V_regs.CurDecOpY.v[1]);
2122}
2123
2124LOCALINLINEFUNC ui5r DecodeGetSrcValue(void)
2125{
2126 return DecodeGetSrcDst(&V_regs.CurDecOpY.v[0]);
2127}
2128
2129LOCALINLINEFUNC ui5r DecodeGetDstValue(void)
2130{
2131 return DecodeGetSrcDst(&V_regs.CurDecOpY.v[1]);
2132}
2133
2134LOCALINLINEFUNC ui5r DecodeGetSrcSetDstValue(void)
2135{
2136 V_regs.SrcVal = DecodeGetSrcValue();
2137
2138 return DecodeGetSetDstValue();
2139}
2140
2141LOCALINLINEFUNC ui5r DecodeGetSrcGetDstValue(void)
2142{
2143 V_regs.SrcVal = DecodeGetSrcValue();
2144
2145 return DecodeGetDstValue();
2146}
2147
2148
2149typedef void (*cond_actP)(void);
2150
2151LOCALPROC my_reg_call cctrue_T(cond_actP t_act, cond_actP f_act)
2152{
2153 UnusedParam(f_act);
2154 t_act();
2155}
2156
2157LOCALPROC my_reg_call cctrue_F(cond_actP t_act, cond_actP f_act)
2158{
2159 UnusedParam(t_act);
2160 f_act();
2161}
2162
2163LOCALPROC my_reg_call cctrue_HI(cond_actP t_act, cond_actP f_act)
2164{
2165 if (0 == (CFLG | ZFLG)) {
2166 t_act();
2167 } else {
2168 f_act();
2169 }
2170}
2171
2172LOCALPROC my_reg_call cctrue_LS(cond_actP t_act, cond_actP f_act)
2173{
2174 if (0 != (CFLG | ZFLG)) {
2175 t_act();
2176 } else {
2177 f_act();
2178 }
2179}
2180
2181LOCALPROC my_reg_call cctrue_CC(cond_actP t_act, cond_actP f_act)
2182{
2183 if (0 == (CFLG)) {
2184 t_act();
2185 } else {
2186 f_act();
2187 }
2188}
2189
2190LOCALPROC my_reg_call cctrue_CS(cond_actP t_act, cond_actP f_act)
2191{
2192 if (0 != (CFLG)) {
2193 t_act();
2194 } else {
2195 f_act();
2196 }
2197}
2198
2199LOCALPROC my_reg_call cctrue_NE(cond_actP t_act, cond_actP f_act)
2200{
2201 if (0 == (ZFLG)) {
2202 t_act();
2203 } else {
2204 f_act();
2205 }
2206}
2207
2208LOCALPROC my_reg_call cctrue_EQ(cond_actP t_act, cond_actP f_act)
2209{
2210 if (0 != (ZFLG)) {
2211 t_act();
2212 } else {
2213 f_act();
2214 }
2215}
2216
2217LOCALPROC my_reg_call cctrue_VC(cond_actP t_act, cond_actP f_act)
2218{
2219 if (0 == (VFLG)) {
2220 t_act();
2221 } else {
2222 f_act();
2223 }
2224}
2225
2226LOCALPROC my_reg_call cctrue_VS(cond_actP t_act, cond_actP f_act)
2227{
2228 if (0 != (VFLG)) {
2229 t_act();
2230 } else {
2231 f_act();
2232 }
2233}
2234
2235LOCALPROC my_reg_call cctrue_PL(cond_actP t_act, cond_actP f_act)
2236{
2237 if (0 == (NFLG)) {
2238 t_act();
2239 } else {
2240 f_act();
2241 }
2242}
2243
2244LOCALPROC my_reg_call cctrue_MI(cond_actP t_act, cond_actP f_act)
2245{
2246 if (0 != (NFLG)) {
2247 t_act();
2248 } else {
2249 f_act();
2250 }
2251}
2252
2253LOCALPROC my_reg_call cctrue_GE(cond_actP t_act, cond_actP f_act)
2254{
2255 if (0 == (NFLG ^ VFLG)) {
2256 t_act();
2257 } else {
2258 f_act();
2259 }
2260}
2261
2262LOCALPROC my_reg_call cctrue_LT(cond_actP t_act, cond_actP f_act)
2263{
2264 if (0 != (NFLG ^ VFLG)) {
2265 t_act();
2266 } else {
2267 f_act();
2268 }
2269}
2270
2271LOCALPROC my_reg_call cctrue_GT(cond_actP t_act, cond_actP f_act)
2272{
2273 if (0 == (ZFLG | (NFLG ^ VFLG))) {
2274 t_act();
2275 } else {
2276 f_act();
2277 }
2278}
2279
2280LOCALPROC my_reg_call cctrue_LE(cond_actP t_act, cond_actP f_act)
2281{
2282 if (0 != (ZFLG | (NFLG ^ VFLG))) {
2283 t_act();
2284 } else {
2285 f_act();
2286 }
2287}
2288
2289#if Have_ASR
2290#define Ui5rASR(x, s) ((ui5r)(((si5r)(x)) >> (s)))
2291#else
2292LOCALFUNC ui5r Ui5rASR(ui5r x, ui5r s)
2293{
2294 ui5r v;
2295
2296 if (ui5r_MSBisSet(x)) {
2297 v = ~ ((~ x) >> s);
2298 } else {
2299 v = x >> s;
2300 }
2301
2302 return v;
2303}
2304#endif
2305
2306#if UseLazyCC
2307
2308LOCALPROC my_reg_call cctrue_TstL_HI(cond_actP t_act, cond_actP f_act)
2309{
2310 if (((ui5b)V_regs.LazyFlagArgDst) > ((ui5b)0)) {
2311 t_act();
2312 } else {
2313 f_act();
2314 }
2315}
2316
2317LOCALPROC my_reg_call cctrue_TstL_LS(cond_actP t_act, cond_actP f_act)
2318{
2319 if (((ui5b)V_regs.LazyFlagArgDst) <= ((ui5b)0)) {
2320 t_act();
2321 } else {
2322 f_act();
2323 }
2324}
2325
2326#if 0 /* always true */
2327LOCALPROC my_reg_call cctrue_TstL_CC(cond_actP t_act, cond_actP f_act)
2328{
2329 if (((ui5b)V_regs.LazyFlagArgDst) >= ((ui5b)0)) {
2330 t_act();
2331 } else {
2332 f_act();
2333 }
2334}
2335#endif
2336
2337#if 0 /* always false */
2338LOCALPROC my_reg_call cctrue_TstL_CS(cond_actP t_act, cond_actP f_act)
2339{
2340 if (((ui5b)V_regs.LazyFlagArgDst) < ((ui5b)0)) {
2341 t_act();
2342 } else {
2343 f_act();
2344 }
2345}
2346#endif
2347
2348LOCALPROC my_reg_call cctrue_TstL_NE(cond_actP t_act, cond_actP f_act)
2349{
2350 if (V_regs.LazyFlagArgDst != 0) {
2351 t_act();
2352 } else {
2353 f_act();
2354 }
2355}
2356
2357LOCALPROC my_reg_call cctrue_TstL_EQ(cond_actP t_act, cond_actP f_act)
2358{
2359 if (V_regs.LazyFlagArgDst == 0) {
2360 t_act();
2361 } else {
2362 f_act();
2363 }
2364}
2365
2366LOCALPROC my_reg_call cctrue_TstL_PL(cond_actP t_act, cond_actP f_act)
2367{
2368 if (((si5b)(V_regs.LazyFlagArgDst)) >= 0) {
2369 t_act();
2370 } else {
2371 f_act();
2372 }
2373}
2374
2375LOCALPROC my_reg_call cctrue_TstL_MI(cond_actP t_act, cond_actP f_act)
2376{
2377 if (((si5b)(V_regs.LazyFlagArgDst)) < 0) {
2378 t_act();
2379 } else {
2380 f_act();
2381 }
2382}
2383
2384LOCALPROC my_reg_call cctrue_TstL_GE(cond_actP t_act, cond_actP f_act)
2385{
2386 if (((si5b)V_regs.LazyFlagArgDst) >= ((si5b)0)) {
2387 t_act();
2388 } else {
2389 f_act();
2390 }
2391}
2392
2393LOCALPROC my_reg_call cctrue_TstL_LT(cond_actP t_act, cond_actP f_act)
2394{
2395 if (((si5b)V_regs.LazyFlagArgDst) < ((si5b)0)) {
2396 t_act();
2397 } else {
2398 f_act();
2399 }
2400}
2401
2402LOCALPROC my_reg_call cctrue_TstL_GT(cond_actP t_act, cond_actP f_act)
2403{
2404 if (((si5b)V_regs.LazyFlagArgDst) > ((si5b)0)) {
2405 t_act();
2406 } else {
2407 f_act();
2408 }
2409}
2410
2411LOCALPROC my_reg_call cctrue_TstL_LE(cond_actP t_act, cond_actP f_act)
2412{
2413 if (((si5b)V_regs.LazyFlagArgDst) <= ((si5b)0)) {
2414 t_act();
2415 } else {
2416 f_act();
2417 }
2418}
2419
2420LOCALPROC my_reg_call cctrue_CmpB_HI(cond_actP t_act, cond_actP f_act)
2421{
2422 if (((ui3b)V_regs.LazyFlagArgDst) > ((ui3b)V_regs.LazyFlagArgSrc)) {
2423 t_act();
2424 } else {
2425 f_act();
2426 }
2427}
2428
2429LOCALPROC my_reg_call cctrue_CmpB_LS(cond_actP t_act, cond_actP f_act)
2430{
2431 if (((ui3b)V_regs.LazyFlagArgDst) <= ((ui3b)V_regs.LazyFlagArgSrc))
2432 {
2433 t_act();
2434 } else {
2435 f_act();
2436 }
2437}
2438
2439LOCALPROC my_reg_call cctrue_CmpB_CC(cond_actP t_act, cond_actP f_act)
2440{
2441 if (((ui3b)V_regs.LazyFlagArgDst) >= ((ui3b)V_regs.LazyFlagArgSrc))
2442 {
2443 t_act();
2444 } else {
2445 f_act();
2446 }
2447}
2448
2449LOCALPROC my_reg_call cctrue_CmpB_CS(cond_actP t_act, cond_actP f_act)
2450{
2451 if (((ui3b)V_regs.LazyFlagArgDst) < ((ui3b)V_regs.LazyFlagArgSrc))
2452 {
2453 t_act();
2454 } else {
2455 f_act();
2456 }
2457}
2458
2459LOCALPROC my_reg_call cctrue_CmpB_NE(cond_actP t_act, cond_actP f_act)
2460{
2461 if (((ui3b)V_regs.LazyFlagArgDst) != ((ui3b)V_regs.LazyFlagArgSrc))
2462 {
2463 t_act();
2464 } else {
2465 f_act();
2466 }
2467}
2468
2469LOCALPROC my_reg_call cctrue_CmpB_EQ(cond_actP t_act, cond_actP f_act)
2470{
2471 if (((ui3b)V_regs.LazyFlagArgDst) == ((ui3b)V_regs.LazyFlagArgSrc))
2472 {
2473 t_act();
2474 } else {
2475 f_act();
2476 }
2477}
2478
2479LOCALPROC my_reg_call cctrue_CmpB_PL(cond_actP t_act, cond_actP f_act)
2480{
2481 if (((si3b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) >= 0) {
2482 t_act();
2483 } else {
2484 f_act();
2485 }
2486}
2487
2488LOCALPROC my_reg_call cctrue_CmpB_MI(cond_actP t_act, cond_actP f_act)
2489{
2490 if (((si3b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) < 0) {
2491 t_act();
2492 } else {
2493 f_act();
2494 }
2495}
2496
2497LOCALPROC my_reg_call cctrue_CmpB_GE(cond_actP t_act, cond_actP f_act)
2498{
2499 if (((si3b)V_regs.LazyFlagArgDst) >= ((si3b)V_regs.LazyFlagArgSrc))
2500 {
2501 t_act();
2502 } else {
2503 f_act();
2504 }
2505}
2506
2507LOCALPROC my_reg_call cctrue_CmpB_LT(cond_actP t_act, cond_actP f_act)
2508{
2509 if (((si3b)V_regs.LazyFlagArgDst) < ((si3b)V_regs.LazyFlagArgSrc)) {
2510 t_act();
2511 } else {
2512 f_act();
2513 }
2514}
2515
2516LOCALPROC my_reg_call cctrue_CmpB_GT(cond_actP t_act, cond_actP f_act)
2517{
2518 if (((si3b)V_regs.LazyFlagArgDst) > ((si3b)V_regs.LazyFlagArgSrc)) {
2519 t_act();
2520 } else {
2521 f_act();
2522 }
2523}
2524
2525LOCALPROC my_reg_call cctrue_CmpB_LE(cond_actP t_act, cond_actP f_act)
2526{
2527 if (((si3b)V_regs.LazyFlagArgDst) <= ((si3b)V_regs.LazyFlagArgSrc))
2528 {
2529 t_act();
2530 } else {
2531 f_act();
2532 }
2533}
2534
2535LOCALPROC my_reg_call cctrue_CmpW_HI(cond_actP t_act, cond_actP f_act)
2536{
2537 if (((ui4b)V_regs.LazyFlagArgDst) > ((ui4b)V_regs.LazyFlagArgSrc))
2538 {
2539 t_act();
2540 } else {
2541 f_act();
2542 }
2543}
2544
2545LOCALPROC my_reg_call cctrue_CmpW_LS(cond_actP t_act, cond_actP f_act)
2546{
2547 if (((ui4b)V_regs.LazyFlagArgDst) <= ((ui4b)V_regs.LazyFlagArgSrc))
2548 {
2549 t_act();
2550 } else {
2551 f_act();
2552 }
2553}
2554
2555LOCALPROC my_reg_call cctrue_CmpW_CC(cond_actP t_act, cond_actP f_act)
2556{
2557 if (((ui4b)V_regs.LazyFlagArgDst) >= ((ui4b)V_regs.LazyFlagArgSrc))
2558 {
2559 t_act();
2560 } else {
2561 f_act();
2562 }
2563}
2564
2565LOCALPROC my_reg_call cctrue_CmpW_CS(cond_actP t_act, cond_actP f_act)
2566{
2567 if (((ui4b)V_regs.LazyFlagArgDst) < ((ui4b)V_regs.LazyFlagArgSrc)) {
2568 t_act();
2569 } else {
2570 f_act();
2571 }
2572}
2573
2574LOCALPROC my_reg_call cctrue_CmpW_NE(cond_actP t_act, cond_actP f_act)
2575{
2576 if (((ui4b)V_regs.LazyFlagArgDst) != ((ui4b)V_regs.LazyFlagArgSrc))
2577 {
2578 t_act();
2579 } else {
2580 f_act();
2581 }
2582}
2583
2584LOCALPROC my_reg_call cctrue_CmpW_EQ(cond_actP t_act, cond_actP f_act)
2585{
2586 if (((ui4b)V_regs.LazyFlagArgDst) == ((ui4b)V_regs.LazyFlagArgSrc))
2587 {
2588 t_act();
2589 } else {
2590 f_act();
2591 }
2592}
2593
2594LOCALPROC my_reg_call cctrue_CmpW_PL(cond_actP t_act, cond_actP f_act)
2595{
2596 if (((si4b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) >= 0) {
2597 t_act();
2598 } else {
2599 f_act();
2600 }
2601}
2602
2603LOCALPROC my_reg_call cctrue_CmpW_MI(cond_actP t_act, cond_actP f_act)
2604{
2605 if (((si4b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) < 0) {
2606 t_act();
2607 } else {
2608 f_act();
2609 }
2610}
2611
2612LOCALPROC my_reg_call cctrue_CmpW_GE(cond_actP t_act, cond_actP f_act)
2613{
2614 if (((si4b)V_regs.LazyFlagArgDst) >= ((si4b)V_regs.LazyFlagArgSrc))
2615 {
2616 t_act();
2617 } else {
2618 f_act();
2619 }
2620}
2621
2622LOCALPROC my_reg_call cctrue_CmpW_LT(cond_actP t_act, cond_actP f_act)
2623{
2624 if (((si4b)V_regs.LazyFlagArgDst) < ((si4b)V_regs.LazyFlagArgSrc)) {
2625 t_act();
2626 } else {
2627 f_act();
2628 }
2629}
2630
2631LOCALPROC my_reg_call cctrue_CmpW_GT(cond_actP t_act, cond_actP f_act)
2632{
2633 if (((si4b)V_regs.LazyFlagArgDst) > ((si4b)V_regs.LazyFlagArgSrc)) {
2634 t_act();
2635 } else {
2636 f_act();
2637 }
2638}
2639
2640LOCALPROC my_reg_call cctrue_CmpW_LE(cond_actP t_act, cond_actP f_act)
2641{
2642 if (((si4b)V_regs.LazyFlagArgDst) <= ((si4b)V_regs.LazyFlagArgSrc))
2643 {
2644 t_act();
2645 } else {
2646 f_act();
2647 }
2648}
2649
2650LOCALPROC my_reg_call cctrue_CmpL_HI(cond_actP t_act, cond_actP f_act)
2651{
2652 if (((ui5b)V_regs.LazyFlagArgDst) > ((ui5b)V_regs.LazyFlagArgSrc)) {
2653 t_act();
2654 } else {
2655 f_act();
2656 }
2657}
2658
2659LOCALPROC my_reg_call cctrue_CmpL_LS(cond_actP t_act, cond_actP f_act)
2660{
2661 if (((ui5b)V_regs.LazyFlagArgDst) <= ((ui5b)V_regs.LazyFlagArgSrc))
2662 {
2663 t_act();
2664 } else {
2665 f_act();
2666 }
2667}
2668
2669LOCALPROC my_reg_call cctrue_CmpL_CC(cond_actP t_act, cond_actP f_act)
2670{
2671 if (((ui5b)V_regs.LazyFlagArgDst) >= ((ui5b)V_regs.LazyFlagArgSrc))
2672 {
2673 t_act();
2674 } else {
2675 f_act();
2676 }
2677}
2678
2679LOCALPROC my_reg_call cctrue_CmpL_CS(cond_actP t_act, cond_actP f_act)
2680{
2681 if (((ui5b)V_regs.LazyFlagArgDst) < ((ui5b)V_regs.LazyFlagArgSrc)) {
2682 t_act();
2683 } else {
2684 f_act();
2685 }
2686}
2687
2688LOCALPROC my_reg_call cctrue_CmpL_NE(cond_actP t_act, cond_actP f_act)
2689{
2690 if (V_regs.LazyFlagArgDst != V_regs.LazyFlagArgSrc) {
2691 t_act();
2692 } else {
2693 f_act();
2694 }
2695}
2696
2697LOCALPROC my_reg_call cctrue_CmpL_EQ(cond_actP t_act, cond_actP f_act)
2698{
2699 if (V_regs.LazyFlagArgDst == V_regs.LazyFlagArgSrc) {
2700 t_act();
2701 } else {
2702 f_act();
2703 }
2704}
2705
2706LOCALPROC my_reg_call cctrue_CmpL_PL(cond_actP t_act, cond_actP f_act)
2707{
2708 if ((((si5b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) >= 0))
2709 {
2710 t_act();
2711 } else {
2712 f_act();
2713 }
2714}
2715
2716LOCALPROC my_reg_call cctrue_CmpL_MI(cond_actP t_act, cond_actP f_act)
2717{
2718 if ((((si5b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) < 0)) {
2719 t_act();
2720 } else {
2721 f_act();
2722 }
2723}
2724
2725LOCALPROC my_reg_call cctrue_CmpL_GE(cond_actP t_act, cond_actP f_act)
2726{
2727 if (((si5b)V_regs.LazyFlagArgDst) >= ((si5b)V_regs.LazyFlagArgSrc))
2728 {
2729 t_act();
2730 } else {
2731 f_act();
2732 }
2733}
2734
2735LOCALPROC my_reg_call cctrue_CmpL_LT(cond_actP t_act, cond_actP f_act)
2736{
2737 if (((si5b)V_regs.LazyFlagArgDst) < ((si5b)V_regs.LazyFlagArgSrc)) {
2738 t_act();
2739 } else {
2740 f_act();
2741 }
2742}
2743
2744LOCALPROC my_reg_call cctrue_CmpL_GT(cond_actP t_act, cond_actP f_act)
2745{
2746 if (((si5b)V_regs.LazyFlagArgDst) > ((si5b)V_regs.LazyFlagArgSrc)) {
2747 t_act();
2748 } else {
2749 f_act();
2750 }
2751}
2752
2753LOCALPROC my_reg_call cctrue_CmpL_LE(cond_actP t_act, cond_actP f_act)
2754{
2755 if (((si5b)V_regs.LazyFlagArgDst) <= ((si5b)V_regs.LazyFlagArgSrc))
2756 {
2757 t_act();
2758 } else {
2759 f_act();
2760 }
2761}
2762
2763LOCALPROC my_reg_call cctrue_Asr_CC(cond_actP t_act, cond_actP f_act)
2764{
2765 if (0 ==
2766 ((V_regs.LazyFlagArgDst >> (V_regs.LazyFlagArgSrc - 1)) & 1))
2767 {
2768 t_act();
2769 } else {
2770 f_act();
2771 }
2772}
2773
2774LOCALPROC my_reg_call cctrue_Asr_CS(cond_actP t_act, cond_actP f_act)
2775{
2776 if (0 !=
2777 ((V_regs.LazyFlagArgDst >> (V_regs.LazyFlagArgSrc - 1)) & 1))
2778 {
2779 t_act();
2780 } else {
2781 f_act();
2782 }
2783}
2784
2785LOCALPROC my_reg_call cctrue_AslB_CC(cond_actP t_act, cond_actP f_act)
2786{
2787 if (0 ==
2788 ((V_regs.LazyFlagArgDst >> (8 - V_regs.LazyFlagArgSrc)) & 1))
2789 {
2790 t_act();
2791 } else {
2792 f_act();
2793 }
2794}
2795
2796LOCALPROC my_reg_call cctrue_AslB_CS(cond_actP t_act, cond_actP f_act)
2797{
2798 if (0 !=
2799 ((V_regs.LazyFlagArgDst >> (8 - V_regs.LazyFlagArgSrc)) & 1))
2800 {
2801 t_act();
2802 } else {
2803 f_act();
2804 }
2805}
2806
2807LOCALPROC my_reg_call cctrue_AslB_VC(cond_actP t_act, cond_actP f_act)
2808{
2809 ui5r cnt = V_regs.LazyFlagArgSrc;
2810 ui5r dst = ui5r_FromSByte(V_regs.LazyFlagArgDst << cnt);
2811
2812 if (Ui5rASR(dst, cnt) == V_regs.LazyFlagArgDst) {
2813 t_act();
2814 } else {
2815 f_act();
2816 }
2817}
2818
2819LOCALPROC my_reg_call cctrue_AslB_VS(cond_actP t_act, cond_actP f_act)
2820{
2821 ui5r cnt = V_regs.LazyFlagArgSrc;
2822 ui5r dst = ui5r_FromSByte(V_regs.LazyFlagArgDst << cnt);
2823
2824 if (Ui5rASR(dst, cnt) != V_regs.LazyFlagArgDst) {
2825 t_act();
2826 } else {
2827 f_act();
2828 }
2829}
2830
2831LOCALPROC my_reg_call cctrue_AslW_CC(cond_actP t_act, cond_actP f_act)
2832{
2833 if (0 ==
2834 ((V_regs.LazyFlagArgDst >> (16 - V_regs.LazyFlagArgSrc)) & 1))
2835 {
2836 t_act();
2837 } else {
2838 f_act();
2839 }
2840}
2841
2842LOCALPROC my_reg_call cctrue_AslW_CS(cond_actP t_act, cond_actP f_act)
2843{
2844 if (0 !=
2845 ((V_regs.LazyFlagArgDst >> (16 - V_regs.LazyFlagArgSrc)) & 1))
2846 {
2847 t_act();
2848 } else {
2849 f_act();
2850 }
2851}
2852
2853LOCALPROC my_reg_call cctrue_AslW_VC(cond_actP t_act, cond_actP f_act)
2854{
2855 ui5r cnt = V_regs.LazyFlagArgSrc;
2856 ui5r dst = ui5r_FromSWord(V_regs.LazyFlagArgDst << cnt);
2857
2858 if (Ui5rASR(dst, cnt) == V_regs.LazyFlagArgDst) {
2859 t_act();
2860 } else {
2861 f_act();
2862 }
2863}
2864
2865LOCALPROC my_reg_call cctrue_AslW_VS(cond_actP t_act, cond_actP f_act)
2866{
2867 ui5r cnt = V_regs.LazyFlagArgSrc;
2868 ui5r dst = ui5r_FromSWord(V_regs.LazyFlagArgDst << cnt);
2869
2870 if (Ui5rASR(dst, cnt) != V_regs.LazyFlagArgDst) {
2871 t_act();
2872 } else {
2873 f_act();
2874 }
2875}
2876
2877LOCALPROC my_reg_call cctrue_AslL_CC(cond_actP t_act, cond_actP f_act)
2878{
2879 if (0 ==
2880 ((V_regs.LazyFlagArgDst >> (32 - V_regs.LazyFlagArgSrc)) & 1))
2881 {
2882 t_act();
2883 } else {
2884 f_act();
2885 }
2886}
2887
2888LOCALPROC my_reg_call cctrue_AslL_CS(cond_actP t_act, cond_actP f_act)
2889{
2890 if (0 !=
2891 ((V_regs.LazyFlagArgDst >> (32 - V_regs.LazyFlagArgSrc)) & 1))
2892 {
2893 t_act();
2894 } else {
2895 f_act();
2896 }
2897}
2898
2899LOCALPROC my_reg_call cctrue_AslL_VC(cond_actP t_act, cond_actP f_act)
2900{
2901 ui5r cnt = V_regs.LazyFlagArgSrc;
2902 ui5r dst = ui5r_FromSLong(V_regs.LazyFlagArgDst << cnt);
2903
2904 if (Ui5rASR(dst, cnt) == V_regs.LazyFlagArgDst) {
2905 t_act();
2906 } else {
2907 f_act();
2908 }
2909}
2910
2911LOCALPROC my_reg_call cctrue_AslL_VS(cond_actP t_act, cond_actP f_act)
2912{
2913 ui5r cnt = V_regs.LazyFlagArgSrc;
2914 ui5r dst = ui5r_FromSLong(V_regs.LazyFlagArgDst << cnt);
2915
2916 if (Ui5rASR(dst, cnt) != V_regs.LazyFlagArgDst) {
2917 t_act();
2918 } else {
2919 f_act();
2920 }
2921}
2922
2923FORWARDPROC my_reg_call cctrue_Dflt(cond_actP t_act, cond_actP f_act);
2924
2925#endif /* UseLazyCC */
2926
2927#if UseLazyCC
2928#define CCdispSz (16 * kNumLazyFlagsKinds)
2929#else
2930#define CCdispSz 16
2931#endif
2932
2933typedef void (my_reg_call *cctrueP)(cond_actP t_act, cond_actP f_act);
2934
2935LOCALVAR const cctrueP cctrueDispatch[CCdispSz + 1] = {
2936 cctrue_T /* kLazyFlagsDefault T */,
2937 cctrue_F /* kLazyFlagsDefault F */,
2938 cctrue_HI /* kLazyFlagsDefault HI */,
2939 cctrue_LS /* kLazyFlagsDefault LS */,
2940 cctrue_CC /* kLazyFlagsDefault CC */,
2941 cctrue_CS /* kLazyFlagsDefault CS */,
2942 cctrue_NE /* kLazyFlagsDefault NE */,
2943 cctrue_EQ /* kLazyFlagsDefault EQ */,
2944 cctrue_VC /* kLazyFlagsDefault VC */,
2945 cctrue_VS /* kLazyFlagsDefault VS */,
2946 cctrue_PL /* kLazyFlagsDefault PL */,
2947 cctrue_MI /* kLazyFlagsDefault MI */,
2948 cctrue_GE /* kLazyFlagsDefault GE */,
2949 cctrue_LT /* kLazyFlagsDefault LT */,
2950 cctrue_GT /* kLazyFlagsDefault GT */,
2951 cctrue_LE /* kLazyFlagsDefault LE */,
2952
2953#if UseLazyCC
2954 cctrue_T /* kLazyFlagsTstB T */,
2955 cctrue_F /* kLazyFlagsTstB F */,
2956 cctrue_Dflt /* kLazyFlagsTstB HI */,
2957 cctrue_Dflt /* kLazyFlagsTstB LS */,
2958 cctrue_Dflt /* kLazyFlagsTstB CC */,
2959 cctrue_Dflt /* kLazyFlagsTstB CS */,
2960 cctrue_Dflt /* kLazyFlagsTstB NE */,
2961 cctrue_Dflt /* kLazyFlagsTstB EQ */,
2962 cctrue_Dflt /* kLazyFlagsTstB VC */,
2963 cctrue_Dflt /* kLazyFlagsTstB VS */,
2964 cctrue_Dflt /* kLazyFlagsTstB PL */,
2965 cctrue_Dflt /* kLazyFlagsTstB MI */,
2966 cctrue_Dflt /* kLazyFlagsTstB GE */,
2967 cctrue_Dflt /* kLazyFlagsTstB LT */,
2968 cctrue_Dflt /* kLazyFlagsTstB GT */,
2969 cctrue_Dflt /* kLazyFlagsTstB LE */,
2970
2971 cctrue_T /* kLazyFlagsTstW T */,
2972 cctrue_F /* kLazyFlagsTstW F */,
2973 cctrue_Dflt /* kLazyFlagsTstW HI */,
2974 cctrue_Dflt /* kLazyFlagsTstW LS */,
2975 cctrue_Dflt /* kLazyFlagsTstW CC */,
2976 cctrue_Dflt /* kLazyFlagsTstW CS */,
2977 cctrue_Dflt /* kLazyFlagsTstW NE */,
2978 cctrue_Dflt /* kLazyFlagsTstW EQ */,
2979 cctrue_Dflt /* kLazyFlagsTstW VC */,
2980 cctrue_Dflt /* kLazyFlagsTstW VS */,
2981 cctrue_Dflt /* kLazyFlagsTstW PL */,
2982 cctrue_Dflt /* kLazyFlagsTstW MI */,
2983 cctrue_Dflt /* kLazyFlagsTstW GE */,
2984 cctrue_Dflt /* kLazyFlagsTstW LT */,
2985 cctrue_Dflt /* kLazyFlagsTstW GT */,
2986 cctrue_Dflt /* kLazyFlagsTstW LE */,
2987
2988 cctrue_T /* kLazyFlagsTstL T */,
2989 cctrue_F /* kLazyFlagsTstL F */,
2990 cctrue_TstL_HI /* kLazyFlagsTstL HI */,
2991 cctrue_TstL_LS /* kLazyFlagsTstL LS */,
2992 cctrue_T /* cctrue_TstL_CC */ /* kLazyFlagsTstL CC */,
2993 cctrue_F /* cctrue_TstL_CS */ /* kLazyFlagsTstL CS */,
2994 cctrue_TstL_NE /* kLazyFlagsTstL NE */,
2995 cctrue_TstL_EQ /* kLazyFlagsTstL EQ */,
2996 cctrue_T /* cctrue_Dflt */ /* kLazyFlagsTstL VC */,
2997 cctrue_F /* cctrue_Dflt */ /* kLazyFlagsTstL VS */,
2998 cctrue_TstL_PL /* kLazyFlagsTstL PL */,
2999 cctrue_TstL_MI /* kLazyFlagsTstL MI */,
3000 cctrue_TstL_GE /* kLazyFlagsTstL GE */,
3001 cctrue_TstL_LT /* kLazyFlagsTstL LT */,
3002 cctrue_TstL_GT /* kLazyFlagsTstL GT */,
3003 cctrue_TstL_LE /* kLazyFlagsTstL LE */,
3004
3005 cctrue_T /* kLazyFlagsCmpB T */,
3006 cctrue_F /* kLazyFlagsCmpB F */,
3007 cctrue_CmpB_HI /* kLazyFlagsCmpB HI */,
3008 cctrue_CmpB_LS /* kLazyFlagsCmpB LS */,
3009 cctrue_CmpB_CC /* kLazyFlagsCmpB CC */,
3010 cctrue_CmpB_CS /* kLazyFlagsCmpB CS */,
3011 cctrue_CmpB_NE /* kLazyFlagsCmpB NE */,
3012 cctrue_CmpB_EQ /* kLazyFlagsCmpB EQ */,
3013 cctrue_Dflt /* kLazyFlagsCmpB VC */,
3014 cctrue_Dflt /* kLazyFlagsCmpB VS */,
3015 cctrue_CmpB_PL /* kLazyFlagsCmpB PL */,
3016 cctrue_CmpB_MI /* kLazyFlagsCmpB MI */,
3017 cctrue_CmpB_GE /* kLazyFlagsCmpB GE */,
3018 cctrue_CmpB_LT /* kLazyFlagsCmpB LT */,
3019 cctrue_CmpB_GT /* kLazyFlagsCmpB GT */,
3020 cctrue_CmpB_LE /* kLazyFlagsCmpB LE */,
3021
3022 cctrue_T /* kLazyFlagsCmpW T */,
3023 cctrue_F /* kLazyFlagsCmpW F */,
3024 cctrue_CmpW_HI /* kLazyFlagsCmpW HI */,
3025 cctrue_CmpW_LS /* kLazyFlagsCmpW LS */,
3026 cctrue_CmpW_CC /* kLazyFlagsCmpW CC */,
3027 cctrue_CmpW_CS /* kLazyFlagsCmpW CS */,
3028 cctrue_CmpW_NE /* kLazyFlagsCmpW NE */,
3029 cctrue_CmpW_EQ /* kLazyFlagsCmpW EQ */,
3030 cctrue_Dflt /* kLazyFlagsCmpW VC */,
3031 cctrue_Dflt /* kLazyFlagsCmpW VS */,
3032 cctrue_CmpW_PL /* kLazyFlagsCmpW PL */,
3033 cctrue_CmpW_MI /* kLazyFlagsCmpW MI */,
3034 cctrue_CmpW_GE /* kLazyFlagsCmpW GE */,
3035 cctrue_CmpW_LT /* kLazyFlagsCmpW LT */,
3036 cctrue_CmpW_GT /* kLazyFlagsCmpW GT */,
3037 cctrue_CmpW_LE /* kLazyFlagsCmpW LE */,
3038
3039 cctrue_T /* kLazyFlagsCmpL T */,
3040 cctrue_F /* kLazyFlagsCmpL F */,
3041 cctrue_CmpL_HI /* kLazyFlagsCmpL HI */,
3042 cctrue_CmpL_LS /* kLazyFlagsCmpL LS */,
3043 cctrue_CmpL_CC /* kLazyFlagsCmpL CC */,
3044 cctrue_CmpL_CS /* kLazyFlagsCmpL CS */,
3045 cctrue_CmpL_NE /* kLazyFlagsCmpL NE */,
3046 cctrue_CmpL_EQ /* kLazyFlagsCmpL EQ */,
3047 cctrue_Dflt /* kLazyFlagsCmpL VC */,
3048 cctrue_Dflt /* kLazyFlagsCmpL VS */,
3049 cctrue_CmpL_PL /* kLazyFlagsCmpL PL */,
3050 cctrue_CmpL_MI /* kLazyFlagsCmpL MI */,
3051 cctrue_CmpL_GE /* kLazyFlagsCmpL GE */,
3052 cctrue_CmpL_LT /* kLazyFlagsCmpL LT */,
3053 cctrue_CmpL_GT /* kLazyFlagsCmpL GT */,
3054 cctrue_CmpL_LE /* kLazyFlagsCmpL LE */,
3055
3056 cctrue_T /* kLazyFlagsSubB T */,
3057 cctrue_F /* kLazyFlagsSubB F */,
3058 cctrue_CmpB_HI /* kLazyFlagsSubB HI */,
3059 cctrue_CmpB_LS /* kLazyFlagsSubB LS */,
3060 cctrue_CmpB_CC /* kLazyFlagsSubB CC */,
3061 cctrue_CmpB_CS /* kLazyFlagsSubB CS */,
3062 cctrue_CmpB_NE /* kLazyFlagsSubB NE */,
3063 cctrue_CmpB_EQ /* kLazyFlagsSubB EQ */,
3064 cctrue_Dflt /* kLazyFlagsSubB VC */,
3065 cctrue_Dflt /* kLazyFlagsSubB VS */,
3066 cctrue_CmpB_PL /* kLazyFlagsSubB PL */,
3067 cctrue_CmpB_MI /* kLazyFlagsSubB MI */,
3068 cctrue_CmpB_GE /* kLazyFlagsSubB GE */,
3069 cctrue_CmpB_LT /* kLazyFlagsSubB LT */,
3070 cctrue_CmpB_GT /* kLazyFlagsSubB GT */,
3071 cctrue_CmpB_LE /* kLazyFlagsSubB LE */,
3072
3073 cctrue_T /* kLazyFlagsSubW T */,
3074 cctrue_F /* kLazyFlagsSubW F */,
3075 cctrue_CmpW_HI /* kLazyFlagsSubW HI */,
3076 cctrue_CmpW_LS /* kLazyFlagsSubW LS */,
3077 cctrue_CmpW_CC /* kLazyFlagsSubW CC */,
3078 cctrue_CmpW_CS /* kLazyFlagsSubW CS */,
3079 cctrue_CmpW_NE /* kLazyFlagsSubW NE */,
3080 cctrue_CmpW_EQ /* kLazyFlagsSubW EQ */,
3081 cctrue_Dflt /* kLazyFlagsSubW VC */,
3082 cctrue_Dflt /* kLazyFlagsSubW VS */,
3083 cctrue_CmpW_PL /* kLazyFlagsSubW PL */,
3084 cctrue_CmpW_MI /* kLazyFlagsSubW MI */,
3085 cctrue_CmpW_GE /* kLazyFlagsSubW GE */,
3086 cctrue_CmpW_LT /* kLazyFlagsSubW LT */,
3087 cctrue_CmpW_GT /* kLazyFlagsSubW GT */,
3088 cctrue_CmpW_LE /* kLazyFlagsSubW LE */,
3089
3090 cctrue_T /* kLazyFlagsSubL T */,
3091 cctrue_F /* kLazyFlagsSubL F */,
3092 cctrue_CmpL_HI /* kLazyFlagsSubL HI */,
3093 cctrue_CmpL_LS /* kLazyFlagsSubL LS */,
3094 cctrue_CmpL_CC /* kLazyFlagsSubL CC */,
3095 cctrue_CmpL_CS /* kLazyFlagsSubL CS */,
3096 cctrue_CmpL_NE /* kLazyFlagsSubL NE */,
3097 cctrue_CmpL_EQ /* kLazyFlagsSubL EQ */,
3098 cctrue_Dflt /* kLazyFlagsSubL VC */,
3099 cctrue_Dflt /* kLazyFlagsSubL VS */,
3100 cctrue_CmpL_PL /* kLazyFlagsSubL PL */,
3101 cctrue_CmpL_MI /* kLazyFlagsSubL MI */,
3102 cctrue_CmpL_GE /* kLazyFlagsSubL GE */,
3103 cctrue_CmpL_LT /* kLazyFlagsSubL LT */,
3104 cctrue_CmpL_GT /* kLazyFlagsSubL GT */,
3105 cctrue_CmpL_LE /* kLazyFlagsSubL LE */,
3106
3107 cctrue_T /* kLazyFlagsAddB T */,
3108 cctrue_F /* kLazyFlagsAddB F */,
3109 cctrue_Dflt /* kLazyFlagsAddB HI */,
3110 cctrue_Dflt /* kLazyFlagsAddB LS */,
3111 cctrue_Dflt /* kLazyFlagsAddB CC */,
3112 cctrue_Dflt /* kLazyFlagsAddB CS */,
3113 cctrue_Dflt /* kLazyFlagsAddB NE */,
3114 cctrue_Dflt /* kLazyFlagsAddB EQ */,
3115 cctrue_Dflt /* kLazyFlagsAddB VC */,
3116 cctrue_Dflt /* kLazyFlagsAddB VS */,
3117 cctrue_Dflt /* kLazyFlagsAddB PL */,
3118 cctrue_Dflt /* kLazyFlagsAddB MI */,
3119 cctrue_Dflt /* kLazyFlagsAddB GE */,
3120 cctrue_Dflt /* kLazyFlagsAddB LT */,
3121 cctrue_Dflt /* kLazyFlagsAddB GT */,
3122 cctrue_Dflt /* kLazyFlagsAddB LE */,
3123
3124 cctrue_T /* kLazyFlagsAddW T */,
3125 cctrue_F /* kLazyFlagsAddW F */,
3126 cctrue_Dflt /* kLazyFlagsAddW HI */,
3127 cctrue_Dflt /* kLazyFlagsAddW LS */,
3128 cctrue_Dflt /* kLazyFlagsAddW CC */,
3129 cctrue_Dflt /* kLazyFlagsAddW CS */,
3130 cctrue_Dflt /* kLazyFlagsAddW NE */,
3131 cctrue_Dflt /* kLazyFlagsAddW EQ */,
3132 cctrue_Dflt /* kLazyFlagsAddW VC */,
3133 cctrue_Dflt /* kLazyFlagsAddW VS */,
3134 cctrue_Dflt /* kLazyFlagsAddW PL */,
3135 cctrue_Dflt /* kLazyFlagsAddW MI */,
3136 cctrue_Dflt /* kLazyFlagsAddW GE */,
3137 cctrue_Dflt /* kLazyFlagsAddW LT */,
3138 cctrue_Dflt /* kLazyFlagsAddW GT */,
3139 cctrue_Dflt /* kLazyFlagsAddW LE */,
3140
3141 cctrue_T /* kLazyFlagsAddL T */,
3142 cctrue_F /* kLazyFlagsAddL F */,
3143 cctrue_Dflt /* kLazyFlagsAddL HI */,
3144 cctrue_Dflt /* kLazyFlagsAddL LS */,
3145 cctrue_Dflt /* kLazyFlagsAddL CC */,
3146 cctrue_Dflt /* kLazyFlagsAddL CS */,
3147 cctrue_Dflt /* kLazyFlagsAddL NE */,
3148 cctrue_Dflt /* kLazyFlagsAddL EQ */,
3149 cctrue_Dflt /* kLazyFlagsAddL VC */,
3150 cctrue_Dflt /* kLazyFlagsAddL VS */,
3151 cctrue_Dflt /* kLazyFlagsAddL PL */,
3152 cctrue_Dflt /* kLazyFlagsAddL MI */,
3153 cctrue_Dflt /* kLazyFlagsAddL GE */,
3154 cctrue_Dflt /* kLazyFlagsAddL LT */,
3155 cctrue_Dflt /* kLazyFlagsAddL GT */,
3156 cctrue_Dflt /* kLazyFlagsAddL LE */,
3157
3158 cctrue_T /* kLazyFlagsNegB T */,
3159 cctrue_F /* kLazyFlagsNegB F */,
3160 cctrue_Dflt /* kLazyFlagsNegB HI */,
3161 cctrue_Dflt /* kLazyFlagsNegB LS */,
3162 cctrue_Dflt /* kLazyFlagsNegB CC */,
3163 cctrue_Dflt /* kLazyFlagsNegB CS */,
3164 cctrue_Dflt /* kLazyFlagsNegB NE */,
3165 cctrue_Dflt /* kLazyFlagsNegB EQ */,
3166 cctrue_Dflt /* kLazyFlagsNegB VC */,
3167 cctrue_Dflt /* kLazyFlagsNegB VS */,
3168 cctrue_Dflt /* kLazyFlagsNegB PL */,
3169 cctrue_Dflt /* kLazyFlagsNegB MI */,
3170 cctrue_Dflt /* kLazyFlagsNegB GE */,
3171 cctrue_Dflt /* kLazyFlagsNegB LT */,
3172 cctrue_Dflt /* kLazyFlagsNegB GT */,
3173 cctrue_Dflt /* kLazyFlagsNegB LE */,
3174
3175 cctrue_T /* kLazyFlagsNegW T */,
3176 cctrue_F /* kLazyFlagsNegW F */,
3177 cctrue_Dflt /* kLazyFlagsNegW HI */,
3178 cctrue_Dflt /* kLazyFlagsNegW LS */,
3179 cctrue_Dflt /* kLazyFlagsNegW CC */,
3180 cctrue_Dflt /* kLazyFlagsNegW CS */,
3181 cctrue_Dflt /* kLazyFlagsNegW NE */,
3182 cctrue_Dflt /* kLazyFlagsNegW EQ */,
3183 cctrue_Dflt /* kLazyFlagsNegW VC */,
3184 cctrue_Dflt /* kLazyFlagsNegW VS */,
3185 cctrue_Dflt /* kLazyFlagsNegW PL */,
3186 cctrue_Dflt /* kLazyFlagsNegW MI */,
3187 cctrue_Dflt /* kLazyFlagsNegW GE */,
3188 cctrue_Dflt /* kLazyFlagsNegW LT */,
3189 cctrue_Dflt /* kLazyFlagsNegW GT */,
3190 cctrue_Dflt /* kLazyFlagsNegW LE */,
3191
3192 cctrue_T /* kLazyFlagsNegL T */,
3193 cctrue_F /* kLazyFlagsNegL F */,
3194 cctrue_Dflt /* kLazyFlagsNegL HI */,
3195 cctrue_Dflt /* kLazyFlagsNegL LS */,
3196 cctrue_Dflt /* kLazyFlagsNegL CC */,
3197 cctrue_Dflt /* kLazyFlagsNegL CS */,
3198 cctrue_Dflt /* kLazyFlagsNegL NE */,
3199 cctrue_Dflt /* kLazyFlagsNegL EQ */,
3200 cctrue_Dflt /* kLazyFlagsNegL VC */,
3201 cctrue_Dflt /* kLazyFlagsNegL VS */,
3202 cctrue_Dflt /* kLazyFlagsNegL PL */,
3203 cctrue_Dflt /* kLazyFlagsNegL MI */,
3204 cctrue_Dflt /* kLazyFlagsNegL GE */,
3205 cctrue_Dflt /* kLazyFlagsNegL LT */,
3206 cctrue_Dflt /* kLazyFlagsNegL GT */,
3207 cctrue_Dflt /* kLazyFlagsNegL LE */,
3208
3209 cctrue_T /* kLazyFlagsAsrB T */,
3210 cctrue_F /* kLazyFlagsAsrB F */,
3211 cctrue_Dflt /* kLazyFlagsAsrB HI */,
3212 cctrue_Dflt /* kLazyFlagsAsrB LS */,
3213 cctrue_Asr_CC /* kLazyFlagsAsrB CC */,
3214 cctrue_Asr_CS /* kLazyFlagsAsrB CS */,
3215 cctrue_Dflt /* kLazyFlagsAsrB NE */,
3216 cctrue_Dflt /* kLazyFlagsAsrB EQ */,
3217 cctrue_Dflt /* kLazyFlagsAsrB VC */,
3218 cctrue_Dflt /* kLazyFlagsAsrB VS */,
3219 cctrue_Dflt /* kLazyFlagsAsrB PL */,
3220 cctrue_Dflt /* kLazyFlagsAsrB MI */,
3221 cctrue_Dflt /* kLazyFlagsAsrB GE */,
3222 cctrue_Dflt /* kLazyFlagsAsrB LT */,
3223 cctrue_Dflt /* kLazyFlagsAsrB GT */,
3224 cctrue_Dflt /* kLazyFlagsAsrB LE */,
3225
3226 cctrue_T /* kLazyFlagsAsrW T */,
3227 cctrue_F /* kLazyFlagsAsrW F */,
3228 cctrue_Dflt /* kLazyFlagsAsrW HI */,
3229 cctrue_Dflt /* kLazyFlagsAsrW LS */,
3230 cctrue_Asr_CC /* kLazyFlagsAsrW CC */,
3231 cctrue_Asr_CS /* kLazyFlagsAsrW CS */,
3232 cctrue_Dflt /* kLazyFlagsAsrW NE */,
3233 cctrue_Dflt /* kLazyFlagsAsrW EQ */,
3234 cctrue_Dflt /* kLazyFlagsAsrW VC */,
3235 cctrue_Dflt /* kLazyFlagsAsrW VS */,
3236 cctrue_Dflt /* kLazyFlagsAsrW PL */,
3237 cctrue_Dflt /* kLazyFlagsAsrW MI */,
3238 cctrue_Dflt /* kLazyFlagsAsrW GE */,
3239 cctrue_Dflt /* kLazyFlagsAsrW LT */,
3240 cctrue_Dflt /* kLazyFlagsAsrW GT */,
3241 cctrue_Dflt /* kLazyFlagsAsrW LE */,
3242
3243 cctrue_T /* kLazyFlagsAsrL T */,
3244 cctrue_F /* kLazyFlagsAsrL F */,
3245 cctrue_Dflt /* kLazyFlagsAsrL HI */,
3246 cctrue_Dflt /* kLazyFlagsAsrL LS */,
3247 cctrue_Asr_CC /* kLazyFlagsAsrL CC */,
3248 cctrue_Asr_CS /* kLazyFlagsAsrL CS */,
3249 cctrue_Dflt /* kLazyFlagsAsrL NE */,
3250 cctrue_Dflt /* kLazyFlagsAsrL EQ */,
3251 cctrue_Dflt /* kLazyFlagsAsrL VC */,
3252 cctrue_Dflt /* kLazyFlagsAsrL VS */,
3253 cctrue_Dflt /* kLazyFlagsAsrL PL */,
3254 cctrue_Dflt /* kLazyFlagsAsrL MI */,
3255 cctrue_Dflt /* kLazyFlagsAsrL GE */,
3256 cctrue_Dflt /* kLazyFlagsAsrL LT */,
3257 cctrue_Dflt /* kLazyFlagsAsrL GT */,
3258 cctrue_Dflt /* kLazyFlagsAsrL LE */,
3259
3260 cctrue_T /* kLazyFlagsAslB T */,
3261 cctrue_F /* kLazyFlagsAslB F */,
3262 cctrue_Dflt /* kLazyFlagsAslB HI */,
3263 cctrue_Dflt /* kLazyFlagsAslB LS */,
3264 cctrue_AslB_CC /* kLazyFlagsAslB CC */,
3265 cctrue_AslB_CS /* kLazyFlagsAslB CS */,
3266 cctrue_Dflt /* kLazyFlagsAslB NE */,
3267 cctrue_Dflt /* kLazyFlagsAslB EQ */,
3268 cctrue_AslB_VC /* kLazyFlagsAslB VC */,
3269 cctrue_AslB_VS /* kLazyFlagsAslB VS */,
3270 cctrue_Dflt /* kLazyFlagsAslB PL */,
3271 cctrue_Dflt /* kLazyFlagsAslB MI */,
3272 cctrue_Dflt /* kLazyFlagsAslB GE */,
3273 cctrue_Dflt /* kLazyFlagsAslB LT */,
3274 cctrue_Dflt /* kLazyFlagsAslB GT */,
3275 cctrue_Dflt /* kLazyFlagsAslB LE */,
3276
3277 cctrue_T /* kLazyFlagsAslW T */,
3278 cctrue_F /* kLazyFlagsAslW F */,
3279 cctrue_Dflt /* kLazyFlagsAslW HI */,
3280 cctrue_Dflt /* kLazyFlagsAslW LS */,
3281 cctrue_AslW_CC /* kLazyFlagsAslW CC */,
3282 cctrue_AslW_CS /* kLazyFlagsAslW CS */,
3283 cctrue_Dflt /* kLazyFlagsAslW NE */,
3284 cctrue_Dflt /* kLazyFlagsAslW EQ */,
3285 cctrue_AslW_VC /* kLazyFlagsAslW VC */,
3286 cctrue_AslW_VS /* kLazyFlagsAslW VS */,
3287 cctrue_Dflt /* kLazyFlagsAslW PL */,
3288 cctrue_Dflt /* kLazyFlagsAslW MI */,
3289 cctrue_Dflt /* kLazyFlagsAslW GE */,
3290 cctrue_Dflt /* kLazyFlagsAslW LT */,
3291 cctrue_Dflt /* kLazyFlagsAslW GT */,
3292 cctrue_Dflt /* kLazyFlagsAslW LE */,
3293
3294 cctrue_T /* kLazyFlagsAslL T */,
3295 cctrue_F /* kLazyFlagsAslL F */,
3296 cctrue_Dflt /* kLazyFlagsAslL HI */,
3297 cctrue_Dflt /* kLazyFlagsAslL LS */,
3298 cctrue_AslL_CC /* kLazyFlagsAslL CC */,
3299 cctrue_AslL_CS /* kLazyFlagsAslL CS */,
3300 cctrue_Dflt /* kLazyFlagsAslL NE */,
3301 cctrue_Dflt /* kLazyFlagsAslL EQ */,
3302 cctrue_AslL_VC /* kLazyFlagsAslL VC */,
3303 cctrue_AslL_VS /* kLazyFlagsAslL VS */,
3304 cctrue_Dflt /* kLazyFlagsAslL PL */,
3305 cctrue_Dflt /* kLazyFlagsAslL MI */,
3306 cctrue_Dflt /* kLazyFlagsAslL GE */,
3307 cctrue_Dflt /* kLazyFlagsAslL LT */,
3308 cctrue_Dflt /* kLazyFlagsAslL GT */,
3309 cctrue_Dflt /* kLazyFlagsAslL LE */,
3310
3311#if UseLazyZ
3312 cctrue_T /* kLazyFlagsZSet T */,
3313 cctrue_F /* kLazyFlagsZSet F */,
3314 cctrue_Dflt /* kLazyFlagsZSet HI */,
3315 cctrue_Dflt /* kLazyFlagsZSet LS */,
3316 cctrue_Dflt /* kLazyFlagsZSet CC */,
3317 cctrue_Dflt /* kLazyFlagsZSet CS */,
3318 cctrue_NE /* kLazyFlagsZSet NE */,
3319 cctrue_EQ /* kLazyFlagsZSet EQ */,
3320 cctrue_Dflt /* kLazyFlagsZSet VC */,
3321 cctrue_Dflt /* kLazyFlagsZSet VS */,
3322 cctrue_Dflt /* kLazyFlagsZSet PL */,
3323 cctrue_Dflt /* kLazyFlagsZSet MI */,
3324 cctrue_Dflt /* kLazyFlagsZSet GE */,
3325 cctrue_Dflt /* kLazyFlagsZSet LT */,
3326 cctrue_Dflt /* kLazyFlagsZSet GT */,
3327 cctrue_Dflt /* kLazyFlagsZSet LE */,
3328#endif
3329#endif /* UseLazyCC */
3330
3331 0
3332};
3333
3334#if UseLazyCC
3335LOCALINLINEPROC cctrue(cond_actP t_act, cond_actP f_act)
3336{
3337 (cctrueDispatch[V_regs.LazyFlagKind * 16
3338 + V_regs.CurDecOpY.v[0].ArgDat])(t_act, f_act);
3339}
3340#endif
3341
3342
3343LOCALPROC NeedDefaultLazyXFlagSubB(void)
3344{
3345 XFLG = Bool2Bit(((ui3b)V_regs.LazyXFlagArgDst)
3346 < ((ui3b)V_regs.LazyXFlagArgSrc));
3347 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3348}
3349
3350LOCALPROC NeedDefaultLazyXFlagSubW(void)
3351{
3352 XFLG = Bool2Bit(((ui4b)V_regs.LazyXFlagArgDst)
3353 < ((ui4b)V_regs.LazyXFlagArgSrc));
3354 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3355}
3356
3357LOCALPROC NeedDefaultLazyXFlagSubL(void)
3358{
3359 XFLG = Bool2Bit(((ui5b)V_regs.LazyXFlagArgDst)
3360 < ((ui5b)V_regs.LazyXFlagArgSrc));
3361 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3362}
3363
3364LOCALPROC NeedDefaultLazyXFlagAddB(void)
3365{
3366 ui3b src = (ui3b)V_regs.LazyXFlagArgSrc;
3367 ui3b dst = (ui3b)V_regs.LazyXFlagArgDst;
3368 ui3b result = dst + src;
3369
3370 XFLG = Bool2Bit(result < src);
3371 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3372}
3373
3374LOCALPROC NeedDefaultLazyXFlagAddW(void)
3375{
3376 ui4b src = (ui4b)V_regs.LazyXFlagArgSrc;
3377 ui4b dst = (ui4b)V_regs.LazyXFlagArgDst;
3378 ui4b result = dst + src;
3379
3380 XFLG = Bool2Bit(result < src);
3381 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3382}
3383
3384LOCALPROC NeedDefaultLazyXFlagAddL(void)
3385{
3386 ui5b src = (ui5b)V_regs.LazyXFlagArgSrc;
3387 ui5b dst = (ui5b)V_regs.LazyXFlagArgDst;
3388 ui5b result = dst + src;
3389
3390 XFLG = Bool2Bit(result < src);
3391 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3392}
3393
3394LOCALPROC NeedDefaultLazyXFlagNegB(void)
3395{
3396 XFLG = Bool2Bit(((ui3b)0)
3397 < ((ui3b)V_regs.LazyXFlagArgDst));
3398 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3399}
3400
3401LOCALPROC NeedDefaultLazyXFlagNegW(void)
3402{
3403 XFLG = Bool2Bit(((ui4b)0)
3404 < ((ui4b)V_regs.LazyXFlagArgDst));
3405 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3406}
3407
3408LOCALPROC NeedDefaultLazyXFlagNegL(void)
3409{
3410 XFLG = Bool2Bit(((ui5b)0)
3411 < ((ui5b)V_regs.LazyXFlagArgDst));
3412 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3413}
3414
3415LOCALPROC NeedDefaultLazyXFlagAsr(void)
3416{
3417 ui5r cnt = V_regs.LazyFlagArgSrc;
3418 ui5r dst = V_regs.LazyFlagArgDst;
3419
3420 XFLG = ((dst >> (cnt - 1)) & 1);
3421
3422 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3423}
3424
3425LOCALPROC NeedDefaultLazyXFlagAslB(void)
3426{
3427 XFLG = (V_regs.LazyFlagArgDst >> (8 - V_regs.LazyFlagArgSrc)) & 1;
3428
3429 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3430}
3431
3432LOCALPROC NeedDefaultLazyXFlagAslW(void)
3433{
3434 XFLG = (V_regs.LazyFlagArgDst >> (16 - V_regs.LazyFlagArgSrc)) & 1;
3435
3436 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3437}
3438
3439LOCALPROC NeedDefaultLazyXFlagAslL(void)
3440{
3441 XFLG = (V_regs.LazyFlagArgDst >> (32 - V_regs.LazyFlagArgSrc)) & 1;
3442
3443 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3444}
3445
3446LOCALPROC NeedDefaultLazyXFlagDefault(void)
3447{
3448}
3449
3450typedef void (*NeedLazyFlagP)(void);
3451
3452LOCALVAR const NeedLazyFlagP
3453 NeedLazyXFlagDispatch[kNumLazyFlagsKinds + 1] =
3454{
3455 NeedDefaultLazyXFlagDefault /* kLazyFlagsDefault */,
3456 0 /* kLazyFlagsTstB */,
3457 0 /* kLazyFlagsTstW */,
3458 0 /* kLazyFlagsTstL */,
3459 0 /* kLazyFlagsCmpB */,
3460 0 /* kLazyFlagsCmpW */,
3461 0 /* kLazyFlagsCmpL */,
3462 NeedDefaultLazyXFlagSubB /* kLazyFlagsSubB */,
3463 NeedDefaultLazyXFlagSubW /* kLazyFlagsSubW */,
3464 NeedDefaultLazyXFlagSubL /* kLazyFlagsSubL */,
3465 NeedDefaultLazyXFlagAddB /* kLazyFlagsAddB */,
3466 NeedDefaultLazyXFlagAddW /* kLazyFlagsAddW */,
3467 NeedDefaultLazyXFlagAddL /* kLazyFlagsAddL */,
3468 NeedDefaultLazyXFlagNegB /* kLazyFlagsNegB */,
3469 NeedDefaultLazyXFlagNegW /* kLazyFlagsNegW */,
3470 NeedDefaultLazyXFlagNegL /* kLazyFlagsNegL */,
3471 NeedDefaultLazyXFlagAsr /* kLazyFlagsAsrB */,
3472 NeedDefaultLazyXFlagAsr /* kLazyFlagsAsrW */,
3473 NeedDefaultLazyXFlagAsr /* kLazyFlagsAsrL */,
3474 NeedDefaultLazyXFlagAslB /* kLazyFlagsAslB */,
3475 NeedDefaultLazyXFlagAslW /* kLazyFlagsAslW */,
3476 NeedDefaultLazyXFlagAslL /* kLazyFlagsAslL */,
3477#if UseLazyZ
3478 0 /* kLazyFlagsZSet */,
3479#endif
3480
3481 0
3482};
3483
3484LOCALPROC NeedDefaultLazyXFlag(void)
3485{
3486#if ForceFlagsEval
3487 if (kLazyFlagsDefault != V_regs.LazyXFlagKind) {
3488 ReportAbnormalID(0x0103,
3489 "not kLazyFlagsDefault in NeedDefaultLazyXFlag");
3490 }
3491#else
3492 (NeedLazyXFlagDispatch[V_regs.LazyXFlagKind])();
3493#endif
3494}
3495
3496LOCALPROC NeedDefaultLazyFlagsTstL(void)
3497{
3498 ui5r dst = V_regs.LazyFlagArgDst;
3499
3500 VFLG = CFLG = 0;
3501 ZFLG = Bool2Bit(dst == 0);
3502 NFLG = Bool2Bit(ui5r_MSBisSet(dst));
3503
3504 V_regs.LazyFlagKind = kLazyFlagsDefault;
3505 NeedDefaultLazyXFlag();
3506}
3507
3508LOCALPROC NeedDefaultLazyFlagsCmpB(void)
3509{
3510 ui5r src = V_regs.LazyFlagArgSrc;
3511 ui5r dst = V_regs.LazyFlagArgDst;
3512 ui5r result0 = dst - src;
3513 ui5r result1 = ui5r_FromUByte(dst)
3514 - ui5r_FromUByte(src);
3515 ui5r result = ui5r_FromSByte(result0);
3516
3517 ZFLG = Bool2Bit(result == 0);
3518 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3519 VFLG = (((result0 >> 1) ^ result0) >> 7) & 1;
3520 CFLG = (result1 >> 8) & 1;
3521
3522 V_regs.LazyFlagKind = kLazyFlagsDefault;
3523 NeedDefaultLazyXFlag();
3524}
3525
3526LOCALPROC NeedDefaultLazyFlagsCmpW(void)
3527{
3528 ui5r result0 = V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc;
3529 ui5r result = ui5r_FromSWord(result0);
3530
3531 ZFLG = Bool2Bit(result == 0);
3532 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3533
3534 VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
3535 {
3536 ui5r result1 = ui5r_FromUWord(V_regs.LazyFlagArgDst)
3537 - ui5r_FromUWord(V_regs.LazyFlagArgSrc);
3538
3539 CFLG = (result1 >> 16) & 1;
3540 }
3541
3542 V_regs.LazyFlagKind = kLazyFlagsDefault;
3543 NeedDefaultLazyXFlag();
3544}
3545
3546LOCALPROC NeedDefaultLazyFlagsCmpL(void)
3547{
3548 ui5r src = V_regs.LazyFlagArgSrc;
3549 ui5r dst = V_regs.LazyFlagArgDst;
3550 ui5r result = ui5r_FromSLong(dst - src);
3551
3552 ZFLG = Bool2Bit(result == 0);
3553
3554 {
3555 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
3556 flagtype flgs = Bool2Bit(ui5r_MSBisSet(src));
3557 flagtype flgo = Bool2Bit(ui5r_MSBisSet(dst)) ^ 1;
3558 flagtype flgsando = flgs & flgo;
3559 flagtype flgsoro = flgs | flgo;
3560
3561 NFLG = flgn;
3562 VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
3563 CFLG = flgsando | (flgn & flgsoro);
3564 }
3565
3566 V_regs.LazyFlagKind = kLazyFlagsDefault;
3567 NeedDefaultLazyXFlag();
3568}
3569
3570LOCALPROC NeedDefaultLazyFlagsSubB(void)
3571{
3572 ui5r src = V_regs.LazyFlagArgSrc;
3573 ui5r dst = V_regs.LazyFlagArgDst;
3574 ui5r result0 = dst - src;
3575 ui5r result1 = ui5r_FromUByte(dst)
3576 - ui5r_FromUByte(src);
3577 ui5r result = ui5r_FromSByte(result0);
3578
3579 ZFLG = Bool2Bit(result == 0);
3580 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3581 VFLG = (((result0 >> 1) ^ result0) >> 7) & 1;
3582 CFLG = (result1 >> 8) & 1;
3583
3584 XFLG = CFLG;
3585 V_regs.LazyFlagKind = kLazyFlagsDefault;
3586 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3587}
3588
3589LOCALPROC NeedDefaultLazyFlagsSubW(void)
3590{
3591 ui5r result0 = V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc;
3592 ui5r result = ui5r_FromSWord(result0);
3593
3594 ZFLG = Bool2Bit(result == 0);
3595 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3596
3597 VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
3598 {
3599 ui5r result1 = ui5r_FromUWord(V_regs.LazyFlagArgDst)
3600 - ui5r_FromUWord(V_regs.LazyFlagArgSrc);
3601
3602 CFLG = (result1 >> 16) & 1;
3603 }
3604
3605 XFLG = CFLG;
3606 V_regs.LazyFlagKind = kLazyFlagsDefault;
3607 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3608}
3609
3610LOCALPROC NeedDefaultLazyFlagsSubL(void)
3611{
3612 ui5r src = V_regs.LazyFlagArgSrc;
3613 ui5r dst = V_regs.LazyFlagArgDst;
3614 ui5r result = ui5r_FromSLong(dst - src);
3615
3616 ZFLG = Bool2Bit(result == 0);
3617
3618 {
3619 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
3620 flagtype flgs = Bool2Bit(ui5r_MSBisSet(src));
3621 flagtype flgo = Bool2Bit(ui5r_MSBisSet(dst)) ^ 1;
3622 flagtype flgsando = flgs & flgo;
3623 flagtype flgsoro = flgs | flgo;
3624
3625 NFLG = flgn;
3626 VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
3627 CFLG = flgsando | (flgn & flgsoro);
3628 }
3629
3630 XFLG = CFLG;
3631 V_regs.LazyFlagKind = kLazyFlagsDefault;
3632 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3633}
3634
3635LOCALPROC NeedDefaultLazyFlagsAddB(void)
3636{
3637 ui5r src = V_regs.LazyFlagArgSrc;
3638 ui5r dst = V_regs.LazyFlagArgDst;
3639 ui5r result0 = dst + src;
3640 ui5r result1 = ui5r_FromUByte(dst)
3641 + ui5r_FromUByte(src);
3642 ui5r result = ui5r_FromSByte(result0);
3643
3644 ZFLG = Bool2Bit(result == 0);
3645 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3646 VFLG = (((result0 >> 1) ^ result0) >> 7) & 1;
3647 CFLG = (result1 >> 8);
3648
3649 XFLG = CFLG;
3650 V_regs.LazyFlagKind = kLazyFlagsDefault;
3651 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3652}
3653
3654LOCALPROC NeedDefaultLazyFlagsAddW(void)
3655{
3656 ui5r src = V_regs.LazyFlagArgSrc;
3657 ui5r dst = V_regs.LazyFlagArgDst;
3658 ui5r result0 = dst + src;
3659 ui5r result1 = ui5r_FromUWord(dst)
3660 + ui5r_FromUWord(src);
3661 ui5r result = ui5r_FromSWord(result0);
3662
3663 ZFLG = Bool2Bit(result == 0);
3664 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3665 VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
3666 CFLG = (result1 >> 16);
3667
3668 XFLG = CFLG;
3669 V_regs.LazyFlagKind = kLazyFlagsDefault;
3670 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3671}
3672
3673#if 0
3674LOCALPROC NeedDefaultLazyFlagsAddCommon(ui5r result)
3675{
3676 ZFLG = Bool2Bit(result == 0);
3677 {
3678 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
3679 flagtype flgs = Bool2Bit(ui5r_MSBisSet(V_regs.LazyFlagArgSrc));
3680 flagtype flgo = Bool2Bit(ui5r_MSBisSet(V_regs.LazyFlagArgDst));
3681 flagtype flgsando = flgs & flgo;
3682 flagtype flgsoro = flgs | flgo;
3683
3684 NFLG = flgn;
3685 flgn ^= 1;
3686 VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
3687 CFLG = flgsando | (flgn & flgsoro);
3688 }
3689
3690 XFLG = CFLG;
3691 V_regs.LazyFlagKind = kLazyFlagsDefault;
3692 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3693}
3694#endif
3695
3696LOCALPROC NeedDefaultLazyFlagsAddL(void)
3697{
3698#if 1
3699 ui5r src = V_regs.LazyFlagArgSrc;
3700 ui5r dst = V_regs.LazyFlagArgDst;
3701 ui5r result = ui5r_FromSLong(dst + src);
3702
3703 ZFLG = Bool2Bit(result == 0);
3704 NFLG = Bool2Bit(ui5r_MSBisSet(result));
3705
3706 {
3707 ui5r result1;
3708 ui5r result0;
3709 ui5r MidCarry = (ui5r_FromUWord(dst)
3710 + ui5r_FromUWord(src)) >> 16;
3711
3712 dst >>= 16;
3713 src >>= 16;
3714
3715 result1 = ui5r_FromUWord(dst)
3716 + ui5r_FromUWord(src)
3717 + MidCarry;
3718 CFLG = (result1 >> 16);
3719 result0 = ui5r_FromSWord(dst)
3720 + ui5r_FromSWord(src)
3721 + MidCarry;
3722 VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
3723 }
3724
3725 XFLG = CFLG;
3726 V_regs.LazyFlagKind = kLazyFlagsDefault;
3727 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3728#else
3729 ui5r result = ui5r_FromSLong(V_regs.LazyFlagArgDst
3730 + V_regs.LazyFlagArgSrc);
3731
3732 NeedDefaultLazyFlagsAddCommon(result);
3733#endif
3734}
3735
3736LOCALPROC NeedDefaultLazyFlagsNegCommon(ui5r dstvalue, ui5r result)
3737{
3738 flagtype flgs = Bool2Bit(ui5r_MSBisSet(dstvalue));
3739 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
3740
3741 ZFLG = Bool2Bit(result == 0);
3742 NFLG = flgn;
3743 VFLG = flgs & flgn;
3744 CFLG = flgs | flgn;
3745
3746 XFLG = CFLG;
3747 V_regs.LazyFlagKind = kLazyFlagsDefault;
3748 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3749}
3750
3751LOCALPROC NeedDefaultLazyFlagsNegB(void)
3752{
3753 ui5r dstvalue = V_regs.LazyFlagArgDst;
3754 ui5r result = ui5r_FromSByte(0 - dstvalue);
3755
3756 NeedDefaultLazyFlagsNegCommon(dstvalue, result);
3757}
3758
3759LOCALPROC NeedDefaultLazyFlagsNegW(void)
3760{
3761 ui5r dstvalue = V_regs.LazyFlagArgDst;
3762 ui5r result = ui5r_FromSWord(0 - dstvalue);
3763
3764 NeedDefaultLazyFlagsNegCommon(dstvalue, result);
3765}
3766
3767LOCALPROC NeedDefaultLazyFlagsNegL(void)
3768{
3769 ui5r dstvalue = V_regs.LazyFlagArgDst;
3770 ui5r result = ui5r_FromSLong(0 - dstvalue);
3771
3772 NeedDefaultLazyFlagsNegCommon(dstvalue, result);
3773}
3774
3775LOCALPROC NeedDefaultLazyFlagsAsr(void)
3776{
3777 ui5r cnt = V_regs.LazyFlagArgSrc;
3778 ui5r dst = V_regs.LazyFlagArgDst;
3779
3780 NFLG = Bool2Bit(ui5r_MSBisSet(dst));
3781 VFLG = 0;
3782
3783 CFLG = ((dst >> (cnt - 1)) & 1);
3784 dst = Ui5rASR(dst, cnt);
3785 ZFLG = Bool2Bit(dst == 0);
3786
3787 XFLG = CFLG;
3788 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3789 V_regs.LazyFlagKind = kLazyFlagsDefault;
3790}
3791
3792LOCALPROC NeedDefaultLazyFlagsAslB(void)
3793{
3794 ui5r cnt = V_regs.LazyFlagArgSrc;
3795 ui5r dst = V_regs.LazyFlagArgDst;
3796 ui5r dstvalue0 = dst;
3797 ui5r comparevalue;
3798
3799 dst = dst << (cnt - 1);
3800 dst = ui5r_FromSByte(dst);
3801 CFLG = Bool2Bit(ui5r_MSBisSet(dst));
3802 dst = dst << 1;
3803 dst = ui5r_FromSByte(dst);
3804 comparevalue = Ui5rASR(dst, cnt);
3805 VFLG = Bool2Bit(comparevalue != dstvalue0);
3806 ZFLG = Bool2Bit(dst == 0);
3807 NFLG = Bool2Bit(ui5r_MSBisSet(dst));
3808
3809 XFLG = CFLG;
3810 V_regs.LazyFlagKind = kLazyFlagsDefault;
3811 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3812}
3813
3814LOCALPROC NeedDefaultLazyFlagsAslW(void)
3815{
3816 ui5r cnt = V_regs.LazyFlagArgSrc;
3817 ui5r dst = V_regs.LazyFlagArgDst;
3818 ui5r dstvalue0 = dst;
3819 ui5r comparevalue;
3820
3821 dst = dst << (cnt - 1);
3822 dst = ui5r_FromSWord(dst);
3823 CFLG = Bool2Bit(ui5r_MSBisSet(dst));
3824 dst = dst << 1;
3825 dst = ui5r_FromSWord(dst);
3826 comparevalue = Ui5rASR(dst, cnt);
3827 VFLG = Bool2Bit(comparevalue != dstvalue0);
3828 ZFLG = Bool2Bit(dst == 0);
3829 NFLG = Bool2Bit(ui5r_MSBisSet(dst));
3830
3831 XFLG = CFLG;
3832 V_regs.LazyFlagKind = kLazyFlagsDefault;
3833 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3834}
3835
3836LOCALPROC NeedDefaultLazyFlagsAslL(void)
3837{
3838 ui5r cnt = V_regs.LazyFlagArgSrc;
3839 ui5r dst = V_regs.LazyFlagArgDst;
3840 ui5r dstvalue0 = dst;
3841 ui5r comparevalue;
3842
3843 dst = dst << (cnt - 1);
3844 dst = ui5r_FromSLong(dst);
3845 CFLG = Bool2Bit(ui5r_MSBisSet(dst));
3846 dst = dst << 1;
3847 dst = ui5r_FromSLong(dst);
3848 comparevalue = Ui5rASR(dst, cnt);
3849 VFLG = Bool2Bit(comparevalue != dstvalue0);
3850 ZFLG = Bool2Bit(dst == 0);
3851 NFLG = Bool2Bit(ui5r_MSBisSet(dst));
3852
3853 XFLG = CFLG;
3854 V_regs.LazyFlagKind = kLazyFlagsDefault;
3855 V_regs.LazyXFlagKind = kLazyFlagsDefault;
3856}
3857
3858#if UseLazyZ
3859FORWARDPROC NeedDefaultLazyFlagsZSet(void);
3860#endif
3861
3862LOCALVAR const NeedLazyFlagP
3863 NeedLazyFlagDispatch[kNumLazyFlagsKinds + 1] =
3864{
3865 NeedDefaultLazyXFlag /* kLazyFlagsDefault */,
3866 0 /* kLazyFlagsTstB */,
3867 0 /* kLazyFlagsTstW */,
3868 NeedDefaultLazyFlagsTstL /* kLazyFlagsTstL */,
3869 NeedDefaultLazyFlagsCmpB /* kLazyFlagsCmpB */,
3870 NeedDefaultLazyFlagsCmpW /* kLazyFlagsCmpW */,
3871 NeedDefaultLazyFlagsCmpL /* kLazyFlagsCmpL */,
3872 NeedDefaultLazyFlagsSubB /* kLazyFlagsSubB */,
3873 NeedDefaultLazyFlagsSubW /* kLazyFlagsSubW */,
3874 NeedDefaultLazyFlagsSubL /* kLazyFlagsSubL */,
3875 NeedDefaultLazyFlagsAddB /* kLazyFlagsAddB */,
3876 NeedDefaultLazyFlagsAddW /* kLazyFlagsAddW */,
3877 NeedDefaultLazyFlagsAddL /* kLazyFlagsAddL */,
3878 NeedDefaultLazyFlagsNegB /* kLazyFlagsNegB */,
3879 NeedDefaultLazyFlagsNegW /* kLazyFlagsNegW */,
3880 NeedDefaultLazyFlagsNegL /* kLazyFlagsNegL */,
3881 NeedDefaultLazyFlagsAsr /* kLazyFlagsAsrB */,
3882 NeedDefaultLazyFlagsAsr /* kLazyFlagsAsrW */,
3883 NeedDefaultLazyFlagsAsr /* kLazyFlagsAsrL */,
3884 NeedDefaultLazyFlagsAslB /* kLazyFlagsAslB */,
3885 NeedDefaultLazyFlagsAslW /* kLazyFlagsAslW */,
3886 NeedDefaultLazyFlagsAslL /* kLazyFlagsAslL */,
3887#if UseLazyZ
3888 NeedDefaultLazyFlagsZSet /* kLazyFlagsZSet */,
3889#endif
3890
3891 0
3892};
3893
3894LOCALPROC NeedDefaultLazyAllFlags0(void)
3895{
3896 (NeedLazyFlagDispatch[V_regs.LazyFlagKind])();
3897}
3898
3899#if ForceFlagsEval
3900LOCALPROC NeedDefaultLazyAllFlags(void)
3901{
3902 if (kLazyFlagsDefault != V_regs.LazyFlagKind) {
3903 ReportAbnormalID(0x0104,
3904 "not kLazyFlagsDefault in NeedDefaultLazyAllFlags");
3905#if dbglog_HAVE
3906 dbglog_writelnNum("LazyFlagKind", V_regs.LazyFlagKind);
3907#endif
3908 }
3909}
3910#else
3911#define NeedDefaultLazyAllFlags NeedDefaultLazyAllFlags0
3912#endif
3913
3914#if ForceFlagsEval
3915#define HaveSetUpFlags NeedDefaultLazyAllFlags0
3916#else
3917#define HaveSetUpFlags()
3918#endif
3919
3920#if UseLazyZ
3921LOCALPROC NeedDefaultLazyFlagsZSet(void)
3922{
3923 flagtype SaveZFLG = ZFLG;
3924
3925 V_regs.LazyFlagKind = V_regs.LazyFlagZSavedKind;
3926 NeedDefaultLazyAllFlags();
3927
3928 ZFLG = SaveZFLG;
3929}
3930#endif
3931
3932#if UseLazyCC
3933LOCALPROC my_reg_call cctrue_Dflt(cond_actP t_act, cond_actP f_act)
3934{
3935 NeedDefaultLazyAllFlags();
3936 cctrue(t_act, f_act);
3937}
3938#endif
3939
3940#if ! UseLazyCC
3941LOCALINLINEPROC cctrue(cond_actP t_act, cond_actP f_act)
3942{
3943 NeedDefaultLazyAllFlags();
3944 (cctrueDispatch[V_regs.CurDecOpY.v[0].ArgDat])(t_act, f_act);
3945}
3946#endif
3947
3948
3949#define LOCALIPROC LOCALPROC /* LOCALPROCUSEDONCE */
3950
3951LOCALIPROC DoCodeCmpB(void)
3952{
3953 ui5r dstvalue = DecodeGetSrcGetDstValue();
3954
3955 V_regs.LazyFlagKind = kLazyFlagsCmpB;
3956 V_regs.LazyFlagArgSrc = V_regs.SrcVal;
3957 V_regs.LazyFlagArgDst = dstvalue;
3958
3959 HaveSetUpFlags();
3960}
3961
3962LOCALIPROC DoCodeCmpW(void)
3963{
3964 ui5r dstvalue = DecodeGetSrcGetDstValue();
3965
3966 V_regs.LazyFlagKind = kLazyFlagsCmpW;
3967 V_regs.LazyFlagArgSrc = V_regs.SrcVal;
3968 V_regs.LazyFlagArgDst = dstvalue;
3969
3970 HaveSetUpFlags();
3971}
3972
3973LOCALIPROC DoCodeCmpL(void)
3974{
3975 ui5r dstvalue = DecodeGetSrcGetDstValue();
3976
3977 V_regs.LazyFlagKind = kLazyFlagsCmpL;
3978 V_regs.LazyFlagArgSrc = V_regs.SrcVal;
3979 V_regs.LazyFlagArgDst = dstvalue;
3980
3981 HaveSetUpFlags();
3982}
3983
3984LOCALIPROC DoCodeMoveL(void)
3985{
3986 ui5r src = DecodeGetSrcValue();
3987
3988 V_regs.LazyFlagKind = kLazyFlagsTstL;
3989 V_regs.LazyFlagArgDst = src;
3990
3991 HaveSetUpFlags();
3992
3993 DecodeSetDstValue(src);
3994}
3995
3996LOCALIPROC DoCodeMoveW(void)
3997{
3998 ui5r src = DecodeGetSrcValue();
3999
4000 V_regs.LazyFlagKind = kLazyFlagsTstL;
4001 V_regs.LazyFlagArgDst = src;
4002
4003 HaveSetUpFlags();
4004
4005 DecodeSetDstValue(src);
4006}
4007
4008LOCALIPROC DoCodeMoveB(void)
4009{
4010 ui5r src = DecodeGetSrcValue();
4011
4012 V_regs.LazyFlagKind = kLazyFlagsTstL;
4013 V_regs.LazyFlagArgDst = src;
4014
4015 HaveSetUpFlags();
4016
4017 DecodeSetDstValue(src);
4018}
4019
4020LOCALIPROC DoCodeTst(void)
4021{
4022 /* Tst 01001010ssmmmrrr */
4023
4024 ui5r srcvalue = DecodeGetDstValue();
4025
4026 V_regs.LazyFlagKind = kLazyFlagsTstL;
4027 V_regs.LazyFlagArgDst = srcvalue;
4028
4029 HaveSetUpFlags();
4030}
4031
4032LOCALIPROC DoCodeBraB(void)
4033{
4034 si5r offset = (si5r)(si3b)(ui3b)(V_regs.CurDecOpY.v[1].ArgDat);
4035 ui3p s = V_pc_p + offset;
4036
4037 V_pc_p = s;
4038
4039#if USE_PCLIMIT
4040 if (my_cond_rare(s >= V_pc_pHi)
4041 || my_cond_rare(s < V_regs.pc_pLo))
4042 {
4043 Recalc_PC_Block();
4044 }
4045#endif
4046}
4047
4048LOCALIPROC DoCodeBraW(void)
4049{
4050 si5r offset = (si5r)(si4b)(ui4b)do_get_mem_word(V_pc_p);
4051 /* note that pc not incremented here */
4052 ui3p s = V_pc_p + offset;
4053
4054 V_pc_p = s;
4055
4056#if USE_PCLIMIT
4057 if (my_cond_rare(s >= V_pc_pHi)
4058 || my_cond_rare(s < V_regs.pc_pLo))
4059 {
4060 Recalc_PC_Block();
4061 }
4062#endif
4063}
4064
4065#if WantCloserCyc
4066LOCALPROC DoCodeBccB_t(void)
4067{
4068 V_MaxCyclesToGo -= (10 * kCycleScale + 2 * RdAvgXtraCyc);
4069 DoCodeBraB();
4070}
4071#else
4072#define DoCodeBccB_t DoCodeBraB
4073#endif
4074
4075LOCALPROC DoCodeBccB_f(void)
4076{
4077#if WantCloserCyc
4078 V_MaxCyclesToGo -= (8 * kCycleScale + RdAvgXtraCyc);
4079#endif
4080 /* do nothing */
4081}
4082
4083LOCALIPROC DoCodeBccB(void)
4084{
4085 /* Bcc 0110ccccnnnnnnnn */
4086 cctrue(DoCodeBccB_t, DoCodeBccB_f);
4087}
4088
4089LOCALPROC SkipiWord(void)
4090{
4091 V_pc_p += 2;
4092
4093#if USE_PCLIMIT
4094 if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
4095 Recalc_PC_Block();
4096 }
4097#endif
4098}
4099
4100#if WantCloserCyc
4101LOCALPROC DoCodeBccW_t(void)
4102{
4103 V_MaxCyclesToGo -= (10 * kCycleScale + 2 * RdAvgXtraCyc);
4104 DoCodeBraW();
4105}
4106#else
4107#define DoCodeBccW_t DoCodeBraW
4108#endif
4109
4110#if WantCloserCyc
4111LOCALPROC DoCodeBccW_f(void)
4112{
4113 V_MaxCyclesToGo -= (12 * kCycleScale + 2 * RdAvgXtraCyc);
4114 SkipiWord();
4115}
4116#else
4117#define DoCodeBccW_f SkipiWord
4118#endif
4119
4120LOCALIPROC DoCodeBccW(void)
4121{
4122 /* Bcc 0110ccccnnnnnnnn */
4123 cctrue(DoCodeBccW_t, DoCodeBccW_f);
4124}
4125
4126
4127LOCALIPROC DoCodeDBF(void)
4128{
4129 /* DBcc 0101cccc11001ddd */
4130
4131 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
4132 ui5r *dstp = &V_regs.regs[dstreg];
4133 ui5r dstvalue = ui5r_FromSWord(*dstp);
4134
4135 --dstvalue;
4136#if LittleEndianUnaligned
4137 *(ui4b *)dstp = dstvalue;
4138#else
4139 *dstp = (*dstp & ~ 0xffff) | ((dstvalue) & 0xffff);
4140#endif
4141
4142 if ((si5b)dstvalue == -1) {
4143#if WantCloserCyc
4144 V_MaxCyclesToGo -= (14 * kCycleScale + 3 * RdAvgXtraCyc);
4145#endif
4146 SkipiWord();
4147 } else {
4148#if WantCloserCyc
4149 V_MaxCyclesToGo -= (10 * kCycleScale + 2 * RdAvgXtraCyc);
4150#endif
4151 DoCodeBraW();
4152 }
4153}
4154
4155#if WantCloserCyc
4156LOCALPROC DoCodeDBcc_t(void)
4157{
4158 V_MaxCyclesToGo -= (12 * kCycleScale + 2 * RdAvgXtraCyc);
4159 SkipiWord();
4160}
4161#else
4162#define DoCodeDBcc_t SkipiWord
4163#endif
4164
4165LOCALIPROC DoCodeDBcc(void)
4166{
4167 /* DBcc 0101cccc11001ddd */
4168
4169 cctrue(DoCodeDBcc_t, DoCodeDBF);
4170}
4171
4172LOCALIPROC DoCodeSwap(void)
4173{
4174 /* Swap 0100100001000rrr */
4175 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
4176 ui5r *dstp = &V_regs.regs[dstreg];
4177 ui5r src = *dstp;
4178 ui5r dst = ui5r_FromSLong(((src >> 16) & 0xFFFF)
4179 | ((src & 0xFFFF) << 16));
4180
4181 V_regs.LazyFlagKind = kLazyFlagsTstL;
4182 V_regs.LazyFlagArgDst = dst;
4183
4184 HaveSetUpFlags();
4185
4186 *dstp = dst;
4187}
4188
4189LOCALIPROC DoCodeMoveA(void) /* MOVE */
4190{
4191 ui5r src = DecodeGetSrcValue();
4192 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
4193
4194 m68k_areg(dstreg) = src;
4195}
4196
4197LOCALIPROC DoCodeMoveQ(void)
4198{
4199 /* MoveQ 0111ddd0nnnnnnnn */
4200 ui5r src = ui5r_FromSByte(V_regs.CurDecOpY.v[0].ArgDat);
4201 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
4202
4203 V_regs.LazyFlagKind = kLazyFlagsTstL;
4204 V_regs.LazyFlagArgDst = src;
4205
4206 HaveSetUpFlags();
4207
4208 m68k_dreg(dstreg) = src;
4209}
4210
4211LOCALIPROC DoCodeAddB(void)
4212{
4213 ui5r dstvalue = DecodeGetSrcSetDstValue();
4214 ui5r srcvalue = V_regs.SrcVal;
4215 ui5r result = ui5r_FromSByte(dstvalue + srcvalue);
4216
4217 V_regs.LazyFlagKind = kLazyFlagsAddB;
4218 V_regs.LazyFlagArgSrc = srcvalue;
4219 V_regs.LazyFlagArgDst = dstvalue;
4220
4221 V_regs.LazyXFlagKind = kLazyFlagsAddB;
4222 V_regs.LazyXFlagArgSrc = srcvalue;
4223 V_regs.LazyXFlagArgDst = dstvalue;
4224
4225 HaveSetUpFlags();
4226
4227 ArgSetDstValue(result);
4228}
4229
4230LOCALIPROC DoCodeAddW(void)
4231{
4232 ui5r dstvalue = DecodeGetSrcSetDstValue();
4233 ui5r srcvalue = V_regs.SrcVal;
4234 ui5r result = ui5r_FromSWord(dstvalue + srcvalue);
4235
4236 V_regs.LazyFlagKind = kLazyFlagsAddW;
4237 V_regs.LazyFlagArgSrc = srcvalue;
4238 V_regs.LazyFlagArgDst = dstvalue;
4239
4240 V_regs.LazyXFlagKind = kLazyFlagsAddW;
4241 V_regs.LazyXFlagArgSrc = srcvalue;
4242 V_regs.LazyXFlagArgDst = dstvalue;
4243
4244 HaveSetUpFlags();
4245
4246 ArgSetDstValue(result);
4247}
4248
4249LOCALIPROC DoCodeAddL(void)
4250{
4251 ui5r dstvalue = DecodeGetSrcSetDstValue();
4252 ui5r srcvalue = V_regs.SrcVal;
4253 ui5r result = ui5r_FromSLong(dstvalue + srcvalue);
4254
4255 V_regs.LazyFlagKind = kLazyFlagsAddL;
4256 V_regs.LazyFlagArgSrc = srcvalue;
4257 V_regs.LazyFlagArgDst = dstvalue;
4258
4259 V_regs.LazyXFlagKind = kLazyFlagsAddL;
4260 V_regs.LazyXFlagArgSrc = srcvalue;
4261 V_regs.LazyXFlagArgDst = dstvalue;
4262
4263 HaveSetUpFlags();
4264
4265 ArgSetDstValue(result);
4266}
4267
4268LOCALIPROC DoCodeSubB(void)
4269{
4270 ui5r dstvalue = DecodeGetSrcSetDstValue();
4271 ui5r srcvalue = V_regs.SrcVal;
4272 ui5r result = ui5r_FromSByte(dstvalue - srcvalue);
4273
4274 V_regs.LazyFlagKind = kLazyFlagsSubB;
4275 V_regs.LazyFlagArgSrc = srcvalue;
4276 V_regs.LazyFlagArgDst = dstvalue;
4277
4278 V_regs.LazyXFlagKind = kLazyFlagsSubB;
4279 V_regs.LazyXFlagArgSrc = srcvalue;
4280 V_regs.LazyXFlagArgDst = dstvalue;
4281
4282 HaveSetUpFlags();
4283
4284 ArgSetDstValue(result);
4285}
4286
4287LOCALIPROC DoCodeSubW(void)
4288{
4289 ui5r dstvalue = DecodeGetSrcSetDstValue();
4290 ui5r srcvalue = V_regs.SrcVal;
4291 ui5r result = ui5r_FromSWord(dstvalue - srcvalue);
4292
4293 V_regs.LazyFlagKind = kLazyFlagsSubW;
4294 V_regs.LazyFlagArgSrc = srcvalue;
4295 V_regs.LazyFlagArgDst = dstvalue;
4296
4297 V_regs.LazyXFlagKind = kLazyFlagsSubW;
4298 V_regs.LazyXFlagArgSrc = srcvalue;
4299 V_regs.LazyXFlagArgDst = dstvalue;
4300
4301 HaveSetUpFlags();
4302
4303 ArgSetDstValue(result);
4304}
4305
4306LOCALIPROC DoCodeSubL(void)
4307{
4308 ui5r dstvalue = DecodeGetSrcSetDstValue();
4309 ui5r srcvalue = V_regs.SrcVal;
4310 ui5r result = ui5r_FromSLong(dstvalue - srcvalue);
4311
4312 V_regs.LazyFlagKind = kLazyFlagsSubL;
4313 V_regs.LazyFlagArgSrc = srcvalue;
4314 V_regs.LazyFlagArgDst = dstvalue;
4315
4316 V_regs.LazyXFlagKind = kLazyFlagsSubL;
4317 V_regs.LazyXFlagArgSrc = srcvalue;
4318 V_regs.LazyXFlagArgDst = dstvalue;
4319
4320 HaveSetUpFlags();
4321
4322 ArgSetDstValue(result);
4323}
4324
4325LOCALIPROC DoCodeLea(void)
4326{
4327 /* Lea 0100aaa111mmmrrr */
4328 ui5r DstAddr = DecodeDst();
4329 ui5r dstreg = V_regs.CurDecOpY.v[0].ArgDat;
4330
4331 m68k_areg(dstreg) = DstAddr;
4332}
4333
4334LOCALIPROC DoCodePEA(void)
4335{
4336 /* PEA 0100100001mmmrrr */
4337 ui5r DstAddr = DecodeDst();
4338
4339 m68k_areg(7) -= 4;
4340 put_long(m68k_areg(7), DstAddr);
4341}
4342
4343LOCALIPROC DoCodeBsrB(void)
4344{
4345 m68k_areg(7) -= 4;
4346 put_long(m68k_areg(7), m68k_getpc());
4347 DoCodeBraB();
4348}
4349
4350LOCALIPROC DoCodeBsrW(void)
4351{
4352 m68k_areg(7) -= 4;
4353 put_long(m68k_areg(7), m68k_getpc() + 2);
4354 DoCodeBraW();
4355}
4356
4357#define m68k_logExceptions (dbglog_HAVE && 0)
4358
4359
4360#ifndef WantDumpAJump
4361#define WantDumpAJump 0
4362#endif
4363
4364#if WantDumpAJump
4365LOCALPROCUSEDONCE DumpAJump(CPTR toaddr)
4366{
4367 CPTR fromaddr = m68k_getpc();
4368 if ((toaddr > fromaddr) || (toaddr < V_regs.pc))
4369 {
4370 dbglog_writeHex(fromaddr);
4371 dbglog_writeCStr(",");
4372 dbglog_writeHex(toaddr);
4373 dbglog_writeReturn();
4374 }
4375}
4376#endif
4377
4378LOCALPROC my_reg_call m68k_setpc(CPTR newpc)
4379{
4380#if WantDumpAJump
4381 DumpAJump(newpc);
4382#endif
4383
4384#if 0
4385 if (newpc == 0xBD50 /* 401AB4 */) {
4386 /* Debugger(); */
4387 /* Exception(5); */ /* try and get macsbug */
4388 }
4389#endif
4390
4391 V_pc_p = V_regs.pc_pLo + (newpc - V_regs.pc);
4392 if (my_cond_rare(V_pc_p >= V_pc_pHi)
4393 || my_cond_rare(V_pc_p < V_regs.pc_pLo))
4394 {
4395 Recalc_PC_Block();
4396 }
4397}
4398
4399LOCALIPROC DoCodeJsr(void)
4400{
4401 /* Jsr 0100111010mmmrrr */
4402 ui5r DstAddr = DecodeDst();
4403
4404 m68k_areg(7) -= 4;
4405 put_long(m68k_areg(7), m68k_getpc());
4406 m68k_setpc(DstAddr);
4407}
4408
4409LOCALIPROC DoCodeLinkA6(void)
4410{
4411 CPTR stackp = m68k_areg(7);
4412 stackp -= 4;
4413 put_long(stackp, m68k_areg(6));
4414 m68k_areg(6) = stackp;
4415 m68k_areg(7) = stackp + nextiSWord();
4416}
4417
4418LOCALIPROC DoCodeUnlkA6(void)
4419{
4420 ui5r src = m68k_areg(6);
4421 m68k_areg(6) = get_long(src);
4422 m68k_areg(7) = src + 4;
4423}
4424
4425LOCALIPROC DoCodeRts(void)
4426{
4427 /* Rts 0100111001110101 */
4428 ui5r NewPC = get_long(m68k_areg(7));
4429 m68k_areg(7) += 4;
4430 m68k_setpc(NewPC);
4431}
4432
4433LOCALIPROC DoCodeJmp(void)
4434{
4435 /* JMP 0100111011mmmrrr */
4436 ui5r DstAddr = DecodeDst();
4437
4438 m68k_setpc(DstAddr);
4439}
4440
4441LOCALIPROC DoCodeClr(void)
4442{
4443 /* Clr 01000010ssmmmrrr */
4444
4445 V_regs.LazyFlagKind = kLazyFlagsTstL;
4446 V_regs.LazyFlagArgDst = 0;
4447
4448 HaveSetUpFlags();
4449
4450 DecodeSetDstValue(0);
4451}
4452
4453LOCALIPROC DoCodeAddA(void)
4454{
4455 /* ADDA 1101dddm11mmmrrr */
4456 ui5r dstvalue = DecodeGetSrcSetDstValue();
4457
4458 ArgSetDstValue(dstvalue + V_regs.SrcVal);
4459}
4460
4461LOCALIPROC DoCodeSubA(void)
4462{
4463 ui5r dstvalue = DecodeGetSrcSetDstValue();
4464
4465 ArgSetDstValue(dstvalue - V_regs.SrcVal);
4466}
4467
4468LOCALIPROC DoCodeCmpA(void)
4469{
4470 ui5r dstvalue = DecodeGetSrcGetDstValue();
4471
4472 V_regs.LazyFlagKind = kLazyFlagsCmpL;
4473 V_regs.LazyFlagArgSrc = V_regs.SrcVal;
4474 V_regs.LazyFlagArgDst = dstvalue;
4475
4476 HaveSetUpFlags();
4477}
4478
4479LOCALFUNC ui4rr m68k_getCR(void)
4480{
4481 NeedDefaultLazyAllFlags();
4482
4483 return (XFLG << 4) | (NFLG << 3) | (ZFLG << 2)
4484 | (VFLG << 1) | CFLG;
4485}
4486
4487LOCALPROC my_reg_call m68k_setCR(ui4rr newcr)
4488{
4489 XFLG = (newcr >> 4) & 1;
4490 NFLG = (newcr >> 3) & 1;
4491 ZFLG = (newcr >> 2) & 1;
4492 VFLG = (newcr >> 1) & 1;
4493 CFLG = newcr & 1;
4494
4495 V_regs.LazyFlagKind = kLazyFlagsDefault;
4496 V_regs.LazyXFlagKind = kLazyFlagsDefault;
4497}
4498
4499
4500LOCALFUNC ui4rr m68k_getSR(void)
4501{
4502 return m68k_getCR()
4503 | (V_regs.t1 << 15)
4504#if Use68020
4505 | (V_regs.t0 << 14)
4506#endif
4507 | (V_regs.s << 13)
4508#if Use68020
4509 | (V_regs.m << 12)
4510#endif
4511 | (V_regs.intmask << 8);
4512}
4513
4514LOCALPROC NeedToGetOut(void)
4515{
4516 if (V_MaxCyclesToGo <= 0) {
4517 /*
4518 already have gotten out, and exception processing has
4519 caused another exception, such as because a bad
4520 stack pointer pointing to a memory mapped device.
4521 */
4522 } else {
4523 V_regs.MoreCyclesToGo += V_MaxCyclesToGo;
4524 /* not counting the current instruction */
4525 V_MaxCyclesToGo = 0;
4526 }
4527}
4528
4529LOCALPROC SetExternalInterruptPending(void)
4530{
4531 V_regs.ExternalInterruptPending = trueblnr;
4532 NeedToGetOut();
4533}
4534
4535LOCALPROC my_reg_call m68k_setSR(ui4rr newsr)
4536{
4537 CPTR *pnewstk;
4538 CPTR *poldstk = (V_regs.s != 0) ? (
4539#if Use68020
4540 (V_regs.m != 0) ? &V_regs.msp :
4541#endif
4542 &V_regs.isp) : &V_regs.usp;
4543 ui5r oldintmask = V_regs.intmask;
4544
4545 V_regs.t1 = (newsr >> 15) & 1;
4546#if Use68020
4547 V_regs.t0 = (newsr >> 14) & 1;
4548 if (V_regs.t0 != 0) {
4549 ReportAbnormalID(0x0105, "t0 flag set in m68k_setSR");
4550 }
4551#endif
4552 V_regs.s = (newsr >> 13) & 1;
4553#if Use68020
4554 V_regs.m = (newsr >> 12) & 1;
4555 if (V_regs.m != 0) {
4556 ReportAbnormalID(0x0106, "m flag set in m68k_setSR");
4557 }
4558#endif
4559 V_regs.intmask = (newsr >> 8) & 7;
4560
4561 pnewstk = (V_regs.s != 0) ? (
4562#if Use68020
4563 (V_regs.m != 0) ? &V_regs.msp :
4564#endif
4565 &V_regs.isp) : &V_regs.usp;
4566
4567 if (poldstk != pnewstk) {
4568 *poldstk = m68k_areg(7);
4569 m68k_areg(7) = *pnewstk;
4570 }
4571
4572 if (V_regs.intmask != oldintmask) {
4573 SetExternalInterruptPending();
4574 }
4575
4576 if (V_regs.t1 != 0) {
4577 NeedToGetOut();
4578 } else {
4579 /* V_regs.TracePending = falseblnr; */
4580 }
4581
4582 m68k_setCR(newsr);
4583}
4584
4585LOCALPROC my_reg_call ExceptionTo(CPTR newpc
4586#if Use68020
4587 , int nr
4588#endif
4589 )
4590{
4591 ui4rr saveSR = m68k_getSR();
4592
4593 if (0 == V_regs.s) {
4594 V_regs.usp = m68k_areg(7);
4595 m68k_areg(7) =
4596#if Use68020
4597 (V_regs.m != 0) ? V_regs.msp :
4598#endif
4599 V_regs.isp;
4600 V_regs.s = 1;
4601 }
4602#if Use68020
4603 switch (nr) {
4604 case 5: /* Zero Divide */
4605 case 6: /* CHK, CHK2 */
4606 case 7: /* cpTRAPcc, TRAPCcc, TRAPv */
4607 case 9: /* Trace */
4608 m68k_areg(7) -= 4;
4609 put_long(m68k_areg(7), m68k_getpc());
4610 m68k_areg(7) -= 2;
4611 put_word(m68k_areg(7), 0x2000 + nr * 4);
4612 break;
4613 default:
4614 m68k_areg(7) -= 2;
4615 put_word(m68k_areg(7), nr * 4);
4616 break;
4617 }
4618 /* if V_regs.m should make throw away stack frame */
4619#endif
4620 m68k_areg(7) -= 4;
4621 put_long(m68k_areg(7), m68k_getpc());
4622 m68k_areg(7) -= 2;
4623 put_word(m68k_areg(7), saveSR);
4624 m68k_setpc(newpc);
4625 V_regs.t1 = 0;
4626#if Use68020
4627 V_regs.t0 = 0;
4628 V_regs.m = 0;
4629#endif
4630 V_regs.TracePending = falseblnr;
4631}
4632
4633LOCALPROC my_reg_call Exception(int nr)
4634{
4635 ExceptionTo(get_long(4 * nr
4636#if Use68020
4637 + V_regs.vbr
4638#endif
4639 )
4640#if Use68020
4641 , nr
4642#endif
4643 );
4644}
4645
4646
4647LOCALIPROC DoCodeA(void)
4648{
4649 BackupPC();
4650 Exception(0xA);
4651}
4652
4653LOCALFUNC ui4rr nextiword_nm(void)
4654/* NOT sign extended */
4655{
4656 return nextiword();
4657}
4658
4659LOCALIPROC DoCodeMOVEMRmML(void)
4660{
4661 /* MOVEM reg to mem 01001000111100rrr */
4662 si4b z;
4663 ui5r regmask = nextiword_nm();
4664 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
4665 ui5r *dstp = &V_regs.regs[dstreg];
4666 ui5r p = *dstp;
4667
4668#if Use68020
4669 {
4670 int n = 0;
4671
4672 for (z = 0; z < 16; ++z) {
4673 if ((regmask & (1 << z)) != 0) {
4674 n++;
4675 }
4676 }
4677 *dstp = p - n * 4;
4678 }
4679#endif
4680 for (z = 16; --z >= 0; ) {
4681 if ((regmask & (1 << (15 - z))) != 0) {
4682#if WantCloserCyc
4683 V_MaxCyclesToGo -= (8 * kCycleScale + 2 * WrAvgXtraCyc);
4684#endif
4685 p -= 4;
4686 put_long(p, V_regs.regs[z]);
4687 }
4688 }
4689#if ! Use68020
4690 *dstp = p;
4691#endif
4692}
4693
4694LOCALIPROC DoCodeMOVEMApRL(void)
4695{
4696 /* MOVEM mem to reg 01001100111011rrr */
4697 si4b z;
4698 ui5r regmask = nextiword_nm();
4699 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
4700 ui5r *dstp = &V_regs.regs[dstreg];
4701 ui5r p = *dstp;
4702
4703 for (z = 0; z < 16; ++z) {
4704 if ((regmask & (1 << z)) != 0) {
4705#if WantCloserCyc
4706 V_MaxCyclesToGo -= (8 * kCycleScale + 2 * RdAvgXtraCyc);
4707#endif
4708 V_regs.regs[z] = get_long(p);
4709 p += 4;
4710 }
4711 }
4712 *dstp = p;
4713}
4714
4715LOCALPROC my_reg_call SetCCRforAddX(ui5r dstvalue, ui5r srcvalue,
4716 ui5r result)
4717{
4718 ZFLG &= Bool2Bit(result == 0);
4719
4720 {
4721 flagtype flgs = Bool2Bit(ui5r_MSBisSet(srcvalue));
4722 flagtype flgo = Bool2Bit(ui5r_MSBisSet(dstvalue));
4723 flagtype flgsando = flgs & flgo;
4724 flagtype flgsoro = flgs | flgo;
4725 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
4726
4727 NFLG = flgn;
4728 flgn ^= 1;
4729 VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
4730 XFLG = CFLG = flgsando | (flgn & flgsoro);
4731 }
4732
4733 ArgSetDstValue(result);
4734}
4735
4736LOCALIPROC DoCodeAddXB(void)
4737{
4738 NeedDefaultLazyAllFlags();
4739
4740 {
4741 ui5r dstvalue = DecodeGetSrcSetDstValue();
4742 ui5r srcvalue = V_regs.SrcVal;
4743 ui5r result = ui5r_FromSByte(XFLG + dstvalue + srcvalue);
4744
4745 SetCCRforAddX(dstvalue, srcvalue, result);
4746 }
4747}
4748
4749LOCALIPROC DoCodeAddXW(void)
4750{
4751 if ((kLazyFlagsDefault != V_regs.LazyFlagKind)
4752 || (kLazyFlagsDefault != V_regs.LazyXFlagKind))
4753 {
4754 NeedDefaultLazyAllFlags();
4755 }
4756
4757 {
4758 ui5r dstvalue = DecodeGetSrcSetDstValue();
4759 ui5r srcvalue = V_regs.SrcVal;
4760 ui5r result = ui5r_FromSWord(XFLG + dstvalue + srcvalue);
4761
4762 SetCCRforAddX(dstvalue, srcvalue, result);
4763 }
4764}
4765
4766LOCALIPROC DoCodeAddXL(void)
4767{
4768 if (kLazyFlagsAddL == V_regs.LazyFlagKind) {
4769 ui5r src = V_regs.LazyFlagArgSrc;
4770 ui5r dst = V_regs.LazyFlagArgDst;
4771 ui5r result = ui5r_FromULong(dst + src);
4772
4773 ZFLG = Bool2Bit(result == 0);
4774 XFLG = Bool2Bit(result < src);
4775
4776 V_regs.LazyFlagKind = kLazyFlagsDefault;
4777 V_regs.LazyXFlagKind = kLazyFlagsDefault;
4778 } else
4779 if ((kLazyFlagsDefault == V_regs.LazyFlagKind)
4780 && (kLazyFlagsDefault == V_regs.LazyXFlagKind))
4781 {
4782 /* ok */
4783 } else
4784 {
4785 NeedDefaultLazyAllFlags();
4786 }
4787
4788 {
4789 ui5r dstvalue = DecodeGetSrcSetDstValue();
4790 ui5r srcvalue = V_regs.SrcVal;
4791 ui5r result = ui5r_FromSLong(XFLG + dstvalue + srcvalue);
4792
4793 SetCCRforAddX(dstvalue, srcvalue, result);
4794 }
4795}
4796
4797LOCALPROC my_reg_call SetCCRforSubX(ui5r dstvalue, ui5r srcvalue,
4798 ui5r result)
4799{
4800 ZFLG &= Bool2Bit(result == 0);
4801
4802 {
4803 flagtype flgs = Bool2Bit(ui5r_MSBisSet(srcvalue));
4804 flagtype flgo = Bool2Bit(ui5r_MSBisSet(dstvalue)) ^ 1;
4805 flagtype flgsando = flgs & flgo;
4806 flagtype flgsoro = flgs | flgo;
4807 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
4808
4809 NFLG = flgn;
4810 VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
4811 XFLG = CFLG = flgsando | (flgn & flgsoro);
4812 }
4813
4814 ArgSetDstValue(result);
4815}
4816
4817LOCALIPROC DoCodeSubXB(void)
4818{
4819 NeedDefaultLazyAllFlags();
4820
4821 {
4822 ui5r dstvalue = DecodeGetSrcSetDstValue();
4823 ui5r srcvalue = V_regs.SrcVal;
4824 ui5r result = ui5r_FromSByte(dstvalue - srcvalue - XFLG);
4825
4826 SetCCRforSubX(dstvalue, srcvalue, result);
4827 }
4828}
4829
4830LOCALIPROC DoCodeSubXW(void)
4831{
4832 if ((kLazyFlagsDefault != V_regs.LazyFlagKind)
4833 || (kLazyFlagsDefault != V_regs.LazyXFlagKind))
4834 {
4835 NeedDefaultLazyAllFlags();
4836 }
4837
4838 {
4839 ui5r dstvalue = DecodeGetSrcSetDstValue();
4840 ui5r srcvalue = V_regs.SrcVal;
4841 ui5r result = ui5r_FromSWord(dstvalue - srcvalue - XFLG);
4842
4843 SetCCRforSubX(dstvalue, srcvalue, result);
4844 }
4845}
4846
4847LOCALIPROC DoCodeSubXL(void)
4848{
4849 if (kLazyFlagsSubL == V_regs.LazyFlagKind) {
4850 ui5r src = V_regs.LazyFlagArgSrc;
4851 ui5r dst = V_regs.LazyFlagArgDst;
4852 ui5r result = ui5r_FromSLong(dst - src);
4853
4854 ZFLG = Bool2Bit(result == 0);
4855 XFLG = Bool2Bit(((ui5b)dst) < ((ui5b)src));
4856
4857 V_regs.LazyFlagKind = kLazyFlagsDefault;
4858 V_regs.LazyXFlagKind = kLazyFlagsDefault;
4859 } else
4860 if ((kLazyFlagsDefault == V_regs.LazyFlagKind)
4861 && (kLazyFlagsDefault == V_regs.LazyXFlagKind))
4862 {
4863 /* ok */
4864 } else
4865 {
4866 NeedDefaultLazyAllFlags();
4867 }
4868
4869 {
4870 ui5r dstvalue = DecodeGetSrcSetDstValue();
4871 ui5r srcvalue = V_regs.SrcVal;
4872 ui5r result = ui5r_FromSLong(dstvalue - srcvalue - XFLG);
4873
4874 SetCCRforSubX(dstvalue, srcvalue, result);
4875 }
4876}
4877
4878LOCALPROC my_reg_call DoCodeNullShift(ui5r dstvalue)
4879{
4880 V_regs.LazyFlagKind = kLazyFlagsTstL;
4881 V_regs.LazyFlagArgDst = dstvalue;
4882
4883 HaveSetUpFlags();
4884
4885 ArgSetDstValue(dstvalue);
4886}
4887
4888LOCALPROC DoCodeOverAsl(ui5r dstvalue)
4889{
4890 XFLG = CFLG = 0;
4891 VFLG = Bool2Bit(0 != dstvalue);
4892 ZFLG = 1;
4893 NFLG = 0;
4894
4895 V_regs.LazyXFlagKind = kLazyFlagsDefault;
4896 V_regs.LazyFlagKind = kLazyFlagsDefault;
4897
4898 ArgSetDstValue(0);
4899}
4900
4901LOCALPROC my_reg_call DoCodeMaxAsr(ui5r dstvalue)
4902{
4903 XFLG = CFLG = dstvalue & 1;
4904 VFLG = Bool2Bit(0 != dstvalue);
4905 ZFLG = 1;
4906 NFLG = 0;
4907
4908 V_regs.LazyXFlagKind = kLazyFlagsDefault;
4909 V_regs.LazyFlagKind = kLazyFlagsDefault;
4910
4911 ArgSetDstValue(0);
4912}
4913
4914LOCALIPROC DoCodeAslB(void)
4915{
4916 ui5r dstvalue = DecodeGetSrcSetDstValue();
4917 ui5r cnt = V_regs.SrcVal & 63;
4918
4919 if (0 == cnt) {
4920 DoCodeNullShift(dstvalue);
4921 } else {
4922#if WantCloserCyc
4923 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
4924#endif
4925
4926 if (cnt >= 8) {
4927 if (cnt == 8) {
4928 DoCodeMaxAsr(dstvalue);
4929 } else {
4930 DoCodeOverAsl(dstvalue);
4931 }
4932 } else {
4933 ui5r result = ui5r_FromSByte(dstvalue << cnt);
4934
4935 V_regs.LazyFlagKind = kLazyFlagsAslB;
4936 V_regs.LazyFlagArgSrc = cnt;
4937 V_regs.LazyFlagArgDst = dstvalue;
4938
4939 V_regs.LazyXFlagKind = kLazyFlagsAslB;
4940 V_regs.LazyXFlagArgSrc = cnt;
4941 V_regs.LazyXFlagArgDst = dstvalue;
4942
4943 HaveSetUpFlags();
4944
4945 ArgSetDstValue(result);
4946 }
4947 }
4948}
4949
4950LOCALIPROC DoCodeAslW(void)
4951{
4952 ui5r dstvalue = DecodeGetSrcSetDstValue();
4953 ui5r cnt = V_regs.SrcVal & 63;
4954
4955 if (0 == cnt) {
4956 DoCodeNullShift(dstvalue);
4957 } else {
4958#if WantCloserCyc
4959 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
4960#endif
4961
4962 if (cnt >= 16) {
4963 if (cnt == 16) {
4964 DoCodeMaxAsr(dstvalue);
4965 } else {
4966 DoCodeOverAsl(dstvalue);
4967 }
4968 } else {
4969 ui5r result = ui5r_FromSWord(dstvalue << cnt);
4970
4971 V_regs.LazyFlagKind = kLazyFlagsAslW;
4972 V_regs.LazyFlagArgSrc = cnt;
4973 V_regs.LazyFlagArgDst = dstvalue;
4974
4975 V_regs.LazyXFlagKind = kLazyFlagsAslW;
4976 V_regs.LazyXFlagArgSrc = cnt;
4977 V_regs.LazyXFlagArgDst = dstvalue;
4978
4979 HaveSetUpFlags();
4980
4981 ArgSetDstValue(result);
4982 }
4983 }
4984}
4985
4986LOCALIPROC DoCodeAslL(void)
4987{
4988 ui5r dstvalue = DecodeGetSrcSetDstValue();
4989 ui5r cnt = V_regs.SrcVal & 63;
4990
4991 if (0 == cnt) {
4992 DoCodeNullShift(dstvalue);
4993 } else {
4994#if WantCloserCyc
4995 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
4996#endif
4997
4998 if (cnt >= 32) {
4999 if (cnt == 32) {
5000 DoCodeMaxAsr(dstvalue);
5001 } else {
5002 DoCodeOverAsl(dstvalue);
5003 }
5004 } else {
5005 ui5r result = ui5r_FromSLong(dstvalue << cnt);
5006
5007 V_regs.LazyFlagKind = kLazyFlagsAslL;
5008 V_regs.LazyFlagArgSrc = cnt;
5009 V_regs.LazyFlagArgDst = dstvalue;
5010
5011 V_regs.LazyXFlagKind = kLazyFlagsAslL;
5012 V_regs.LazyXFlagArgSrc = cnt;
5013 V_regs.LazyXFlagArgDst = dstvalue;
5014
5015 HaveSetUpFlags();
5016
5017 ArgSetDstValue(result);
5018 }
5019 }
5020}
5021
5022LOCALPROC DoCodeOverShift(void)
5023{
5024 XFLG = CFLG = 0;
5025 ZFLG = 1;
5026 NFLG = 0;
5027 VFLG = 0;
5028
5029 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5030 V_regs.LazyFlagKind = kLazyFlagsDefault;
5031
5032 ArgSetDstValue(0);
5033}
5034
5035LOCALPROC DoCodeOverShiftN(void)
5036{
5037 NFLG = 1;
5038 VFLG = 0;
5039 CFLG = 1;
5040 XFLG = CFLG;
5041 ZFLG = 0;
5042
5043 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5044 V_regs.LazyFlagKind = kLazyFlagsDefault;
5045
5046 ArgSetDstValue(~ 0);
5047}
5048
5049LOCALPROC DoCodeOverAShift(ui5r dstvalue)
5050{
5051 if (ui5r_MSBisSet(dstvalue)) {
5052 DoCodeOverShiftN();
5053 } else {
5054 DoCodeOverShift();
5055 }
5056}
5057
5058LOCALIPROC DoCodeAsrB(void)
5059{
5060 ui5r dstvalue = DecodeGetSrcSetDstValue();
5061 ui5r cnt = V_regs.SrcVal & 63;
5062
5063 if (0 == cnt) {
5064 DoCodeNullShift(dstvalue);
5065 } else {
5066#if WantCloserCyc
5067 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5068#endif
5069
5070 if (cnt >= 8) {
5071 DoCodeOverAShift(dstvalue);
5072 } else {
5073 ui5r result = Ui5rASR(dstvalue, cnt);
5074
5075 V_regs.LazyFlagKind = kLazyFlagsAsrB;
5076 V_regs.LazyFlagArgSrc = cnt;
5077 V_regs.LazyFlagArgDst = dstvalue;
5078
5079 V_regs.LazyXFlagKind = kLazyFlagsAsrB;
5080 V_regs.LazyXFlagArgSrc = cnt;
5081 V_regs.LazyXFlagArgDst = dstvalue;
5082
5083 HaveSetUpFlags();
5084
5085 ArgSetDstValue(result);
5086 }
5087 }
5088}
5089
5090LOCALIPROC DoCodeAsrW(void)
5091{
5092 ui5r dstvalue = DecodeGetSrcSetDstValue();
5093 ui5r cnt = V_regs.SrcVal & 63;
5094
5095 if (0 == cnt) {
5096 DoCodeNullShift(dstvalue);
5097 } else {
5098#if WantCloserCyc
5099 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5100#endif
5101
5102 if (cnt >= 16) {
5103 DoCodeOverAShift(dstvalue);
5104 } else {
5105 ui5r result = Ui5rASR(dstvalue, cnt);
5106
5107 V_regs.LazyFlagKind = kLazyFlagsAsrW;
5108 V_regs.LazyFlagArgSrc = cnt;
5109 V_regs.LazyFlagArgDst = dstvalue;
5110
5111 V_regs.LazyXFlagKind = kLazyFlagsAsrW;
5112 V_regs.LazyXFlagArgSrc = cnt;
5113 V_regs.LazyXFlagArgDst = dstvalue;
5114
5115 HaveSetUpFlags();
5116
5117 ArgSetDstValue(result);
5118 }
5119 }
5120}
5121
5122LOCALIPROC DoCodeAsrL(void)
5123{
5124 ui5r dstvalue = DecodeGetSrcSetDstValue();
5125 ui5r cnt = V_regs.SrcVal & 63;
5126
5127 if (0 == cnt) {
5128 DoCodeNullShift(dstvalue);
5129 } else {
5130#if WantCloserCyc
5131 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5132#endif
5133
5134 if (cnt >= 32) {
5135 DoCodeOverAShift(dstvalue);
5136 } else {
5137 ui5r result = Ui5rASR(dstvalue, cnt);
5138
5139 V_regs.LazyFlagKind = kLazyFlagsAsrL;
5140 V_regs.LazyFlagArgSrc = cnt;
5141 V_regs.LazyFlagArgDst = dstvalue;
5142
5143 V_regs.LazyXFlagKind = kLazyFlagsAsrL;
5144 V_regs.LazyXFlagArgSrc = cnt;
5145 V_regs.LazyXFlagArgDst = dstvalue;
5146
5147 HaveSetUpFlags();
5148
5149 ArgSetDstValue(result);
5150 }
5151 }
5152}
5153
5154LOCALPROC my_reg_call DoCodeMaxLslShift(ui5r dstvalue)
5155{
5156 XFLG = CFLG = dstvalue & 1;
5157 ZFLG = 1;
5158 NFLG = 0;
5159 VFLG = 0;
5160
5161 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5162 V_regs.LazyFlagKind = kLazyFlagsDefault;
5163
5164 ArgSetDstValue(0);
5165}
5166
5167LOCALIPROC DoCodeLslB(void)
5168{
5169 ui5r dstvalue = DecodeGetSrcSetDstValue();
5170 ui5r cnt = V_regs.SrcVal & 63;
5171
5172 if (0 == cnt) {
5173 DoCodeNullShift(dstvalue);
5174 } else {
5175#if WantCloserCyc
5176 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5177#endif
5178
5179 if (cnt >= 8) {
5180 if (cnt == 8) {
5181 DoCodeMaxLslShift(dstvalue);
5182 } else {
5183 DoCodeOverShift();
5184 }
5185 } else {
5186 CFLG = (dstvalue >> (8 - cnt)) & 1;
5187 dstvalue = dstvalue << cnt;
5188 dstvalue = ui5r_FromSByte(dstvalue);
5189
5190 ZFLG = Bool2Bit(dstvalue == 0);
5191 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5192 VFLG = 0;
5193 XFLG = CFLG;
5194 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5195 V_regs.LazyFlagKind = kLazyFlagsDefault;
5196
5197 ArgSetDstValue(dstvalue);
5198 }
5199 }
5200}
5201
5202LOCALIPROC DoCodeLslW(void)
5203{
5204 ui5r dstvalue = DecodeGetSrcSetDstValue();
5205 ui5r cnt = V_regs.SrcVal & 63;
5206
5207 if (0 == cnt) {
5208 DoCodeNullShift(dstvalue);
5209 } else {
5210#if WantCloserCyc
5211 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5212#endif
5213
5214 if (cnt >= 16) {
5215 if (cnt == 16) {
5216 DoCodeMaxLslShift(dstvalue);
5217 } else {
5218 DoCodeOverShift();
5219 }
5220 } else {
5221 CFLG = (dstvalue >> (16 - cnt)) & 1;
5222 dstvalue = dstvalue << cnt;
5223 dstvalue = ui5r_FromSWord(dstvalue);
5224
5225 ZFLG = Bool2Bit(dstvalue == 0);
5226 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5227 VFLG = 0;
5228 XFLG = CFLG;
5229 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5230 V_regs.LazyFlagKind = kLazyFlagsDefault;
5231
5232 ArgSetDstValue(dstvalue);
5233 }
5234 }
5235}
5236
5237LOCALIPROC DoCodeLslL(void)
5238{
5239 ui5r dstvalue = DecodeGetSrcSetDstValue();
5240 ui5r cnt = V_regs.SrcVal & 63;
5241
5242 if (0 == cnt) {
5243 DoCodeNullShift(dstvalue);
5244 } else {
5245#if WantCloserCyc
5246 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5247#endif
5248
5249 if (cnt >= 32) {
5250 if (cnt == 32) {
5251 DoCodeMaxLslShift(dstvalue);
5252 } else {
5253 DoCodeOverShift();
5254 }
5255 } else {
5256 CFLG = (dstvalue >> (32 - cnt)) & 1;
5257 dstvalue = dstvalue << cnt;
5258 dstvalue = ui5r_FromSLong(dstvalue);
5259
5260 ZFLG = Bool2Bit(dstvalue == 0);
5261 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5262 VFLG = 0;
5263 XFLG = CFLG;
5264 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5265 V_regs.LazyFlagKind = kLazyFlagsDefault;
5266
5267 ArgSetDstValue(dstvalue);
5268 }
5269 }
5270}
5271
5272LOCALIPROC DoCodeLsrB(void)
5273{
5274 ui5r dstvalue = DecodeGetSrcSetDstValue();
5275 ui5r cnt = V_regs.SrcVal & 63;
5276
5277#if WantCloserCyc
5278 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5279#endif
5280
5281 if (0 == cnt) {
5282 DoCodeNullShift(dstvalue);
5283 } else if (cnt > 32) {
5284 DoCodeOverShift();
5285 } else {
5286 dstvalue = ui5r_FromUByte(dstvalue);
5287 dstvalue = dstvalue >> (cnt - 1);
5288 CFLG = XFLG = (dstvalue & 1);
5289 dstvalue = dstvalue >> 1;
5290 ZFLG = Bool2Bit(dstvalue == 0);
5291 NFLG = 0 /* Bool2Bit(ui5r_MSBisSet(dstvalue)) */;
5292 /* if cnt != 0, always false */
5293 VFLG = 0;
5294 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5295 V_regs.LazyFlagKind = kLazyFlagsDefault;
5296
5297 ArgSetDstValue(dstvalue);
5298 }
5299}
5300
5301LOCALIPROC DoCodeLsrW(void)
5302{
5303 ui5r dstvalue = DecodeGetSrcSetDstValue();
5304 ui5r cnt = V_regs.SrcVal & 63;
5305
5306#if WantCloserCyc
5307 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5308#endif
5309
5310 if (0 == cnt) {
5311 DoCodeNullShift(dstvalue);
5312 } else if (cnt > 32) {
5313 DoCodeOverShift();
5314 } else {
5315 dstvalue = ui5r_FromUWord(dstvalue);
5316 dstvalue = dstvalue >> (cnt - 1);
5317 CFLG = XFLG = (dstvalue & 1);
5318 dstvalue = dstvalue >> 1;
5319 ZFLG = Bool2Bit(dstvalue == 0);
5320 NFLG = 0 /* Bool2Bit(ui5r_MSBisSet(dstvalue)) */;
5321 /* if cnt != 0, always false */
5322 VFLG = 0;
5323 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5324 V_regs.LazyFlagKind = kLazyFlagsDefault;
5325
5326 ArgSetDstValue(dstvalue);
5327 }
5328}
5329
5330LOCALIPROC DoCodeLsrL(void)
5331{
5332 ui5r dstvalue = DecodeGetSrcSetDstValue();
5333 ui5r cnt = V_regs.SrcVal & 63;
5334
5335#if WantCloserCyc
5336 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5337#endif
5338
5339 if (0 == cnt) {
5340 DoCodeNullShift(dstvalue);
5341 } else if (cnt > 32) {
5342 DoCodeOverShift();
5343 } else {
5344 dstvalue = ui5r_FromULong(dstvalue);
5345 dstvalue = dstvalue >> (cnt - 1);
5346 CFLG = XFLG = (dstvalue & 1);
5347 dstvalue = dstvalue >> 1;
5348 ZFLG = Bool2Bit(dstvalue == 0);
5349 NFLG = 0 /* Bool2Bit(ui5r_MSBisSet(dstvalue)) */;
5350 /* if cnt != 0, always false */
5351 VFLG = 0;
5352 V_regs.LazyXFlagKind = kLazyFlagsDefault;
5353 V_regs.LazyFlagKind = kLazyFlagsDefault;
5354
5355 ArgSetDstValue(dstvalue);
5356 }
5357}
5358
5359LOCALFUNC ui5r DecodeGetSrcSetDstValueDfltFlags_nm(void)
5360{
5361 NeedDefaultLazyAllFlags();
5362
5363 return DecodeGetSrcSetDstValue();
5364}
5365
5366LOCALPROC my_reg_call DoCodeNullXShift(ui5r dstvalue)
5367{
5368 CFLG = XFLG;
5369
5370 ZFLG = Bool2Bit(dstvalue == 0);
5371 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5372 VFLG = 0;
5373
5374 ArgSetDstValue(dstvalue);
5375}
5376
5377LOCALIPROC DoCodeRxlB(void)
5378{
5379 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
5380 ui5r cnt = V_regs.SrcVal & 63;
5381
5382 if (0 == cnt) {
5383 DoCodeNullXShift(dstvalue);
5384 } else {
5385#if WantCloserCyc
5386 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5387#endif
5388
5389 for (; cnt; --cnt) {
5390 CFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5391 dstvalue = (dstvalue << 1) | XFLG;
5392 dstvalue = ui5r_FromSByte(dstvalue);
5393 XFLG = CFLG;
5394 }
5395
5396 ZFLG = Bool2Bit(dstvalue == 0);
5397 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5398 VFLG = 0;
5399
5400 ArgSetDstValue(dstvalue);
5401 }
5402}
5403
5404LOCALIPROC DoCodeRxlW(void)
5405{
5406 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
5407 ui5r cnt = V_regs.SrcVal & 63;
5408
5409 if (0 == cnt) {
5410 DoCodeNullXShift(dstvalue);
5411 } else {
5412#if WantCloserCyc
5413 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5414#endif
5415
5416 for (; cnt; --cnt) {
5417 CFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5418 dstvalue = (dstvalue << 1) | XFLG;
5419 dstvalue = ui5r_FromSWord(dstvalue);
5420 XFLG = CFLG;
5421 }
5422
5423 ZFLG = Bool2Bit(dstvalue == 0);
5424 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5425 VFLG = 0;
5426
5427 ArgSetDstValue(dstvalue);
5428 }
5429}
5430
5431LOCALIPROC DoCodeRxlL(void)
5432{
5433 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
5434 ui5r cnt = V_regs.SrcVal & 63;
5435
5436 if (0 == cnt) {
5437 DoCodeNullXShift(dstvalue);
5438 } else {
5439#if WantCloserCyc
5440 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5441#endif
5442
5443 for (; cnt; --cnt) {
5444 CFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5445 dstvalue = (dstvalue << 1) | XFLG;
5446 dstvalue = ui5r_FromSLong(dstvalue);
5447 XFLG = CFLG;
5448 }
5449
5450 ZFLG = Bool2Bit(dstvalue == 0);
5451 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5452 VFLG = 0;
5453
5454 ArgSetDstValue(dstvalue);
5455 }
5456}
5457
5458LOCALIPROC DoCodeRxrB(void)
5459{
5460 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
5461 ui5r cnt = V_regs.SrcVal & 63;
5462
5463 if (0 == cnt) {
5464 DoCodeNullXShift(dstvalue);
5465 } else {
5466#if WantCloserCyc
5467 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5468#endif
5469
5470 dstvalue = ui5r_FromUByte(dstvalue);
5471 for (; cnt; --cnt) {
5472 CFLG = dstvalue & 1;
5473 dstvalue = (dstvalue >> 1) | (((ui5r)XFLG) << 7);
5474 XFLG = CFLG;
5475 }
5476 dstvalue = ui5r_FromSByte(dstvalue);
5477
5478 ZFLG = Bool2Bit(dstvalue == 0);
5479 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5480 VFLG = 0;
5481
5482 ArgSetDstValue(dstvalue);
5483 }
5484}
5485
5486LOCALIPROC DoCodeRxrW(void)
5487{
5488 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
5489 ui5r cnt = V_regs.SrcVal & 63;
5490
5491 if (0 == cnt) {
5492 DoCodeNullXShift(dstvalue);
5493 } else {
5494#if WantCloserCyc
5495 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5496#endif
5497
5498 dstvalue = ui5r_FromUWord(dstvalue);
5499 for (; cnt; --cnt) {
5500 CFLG = dstvalue & 1;
5501 dstvalue = (dstvalue >> 1) | (((ui5r)XFLG) << 15);
5502 XFLG = CFLG;
5503 }
5504 dstvalue = ui5r_FromSWord(dstvalue);
5505
5506 ZFLG = Bool2Bit(dstvalue == 0);
5507 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5508 VFLG = 0;
5509
5510 ArgSetDstValue(dstvalue);
5511 }
5512}
5513
5514LOCALIPROC DoCodeRxrL(void)
5515{
5516 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
5517 ui5r cnt = V_regs.SrcVal & 63;
5518
5519 if (0 == cnt) {
5520 DoCodeNullXShift(dstvalue);
5521 } else {
5522#if WantCloserCyc
5523 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5524#endif
5525
5526 dstvalue = ui5r_FromULong(dstvalue);
5527 for (; cnt; --cnt) {
5528 CFLG = dstvalue & 1;
5529 dstvalue = (dstvalue >> 1) | (((ui5r)XFLG) << 31);
5530 XFLG = CFLG;
5531 }
5532 dstvalue = ui5r_FromSLong(dstvalue);
5533
5534 ZFLG = Bool2Bit(dstvalue == 0);
5535 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5536 VFLG = 0;
5537
5538 ArgSetDstValue(dstvalue);
5539 }
5540}
5541
5542LOCALIPROC DoCodeRolB(void)
5543{
5544 ui5r dstvalue = DecodeGetSrcSetDstValue();
5545 ui5r cnt = V_regs.SrcVal & 63;
5546
5547#if WantCloserCyc
5548 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5549#endif
5550
5551 if (0 == cnt) {
5552 DoCodeNullShift(dstvalue);
5553 } else {
5554 cnt &= 7;
5555 if (0 != cnt) {
5556 ui3b dst = (ui3b)dstvalue;
5557
5558 dst = (dst >> (8 - cnt))
5559 | ((dst & ((1 << (8 - cnt)) - 1))
5560 << cnt);
5561
5562 dstvalue = (ui5r)(si5r)(si3b)dst;
5563 }
5564 ZFLG = Bool2Bit(dstvalue == 0);
5565 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5566 VFLG = 0;
5567 CFLG = (dstvalue & 1);
5568 V_regs.LazyFlagKind = kLazyFlagsDefault;
5569
5570 ArgSetDstValue(dstvalue);
5571 }
5572}
5573
5574LOCALIPROC DoCodeRolW(void)
5575{
5576 ui5r dstvalue = DecodeGetSrcSetDstValue();
5577 ui5r cnt = V_regs.SrcVal & 63;
5578
5579#if WantCloserCyc
5580 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5581#endif
5582
5583 if (0 == cnt) {
5584 DoCodeNullShift(dstvalue);
5585 } else {
5586 cnt &= 15;
5587 if (0 != cnt) {
5588 ui4b dst = (ui4b)dstvalue;
5589
5590 dst = (dst >> (16 - cnt))
5591 | ((dst & ((1 << (16 - cnt)) - 1))
5592 << cnt);
5593
5594 dstvalue = (ui5r)(si5r)(si4b)dst;
5595 }
5596 ZFLG = Bool2Bit(dstvalue == 0);
5597 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5598 VFLG = 0;
5599 CFLG = (dstvalue & 1);
5600 V_regs.LazyFlagKind = kLazyFlagsDefault;
5601
5602 ArgSetDstValue(dstvalue);
5603 }
5604}
5605
5606LOCALIPROC DoCodeRolL(void)
5607{
5608 ui5r dstvalue = DecodeGetSrcSetDstValue();
5609 ui5r cnt = V_regs.SrcVal & 63;
5610
5611#if WantCloserCyc
5612 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5613#endif
5614
5615 if (0 == cnt) {
5616 DoCodeNullShift(dstvalue);
5617 } else {
5618 cnt &= 31;
5619 if (0 != cnt) {
5620 ui5b dst = (ui5b)dstvalue;
5621
5622 dst = (dst >> (32 - cnt))
5623 | ((dst & ((1 << (32 - cnt)) - 1))
5624 << cnt);
5625
5626 dstvalue = (ui5r)(si5r)(si5b)dst;
5627 }
5628 ZFLG = Bool2Bit(dstvalue == 0);
5629 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5630 VFLG = 0;
5631 CFLG = (dstvalue & 1);
5632 V_regs.LazyFlagKind = kLazyFlagsDefault;
5633
5634 ArgSetDstValue(dstvalue);
5635 }
5636}
5637
5638LOCALIPROC DoCodeRorB(void)
5639{
5640 ui5r dstvalue = DecodeGetSrcSetDstValue();
5641 ui5r cnt = V_regs.SrcVal & 63;
5642
5643#if WantCloserCyc
5644 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5645#endif
5646
5647 if (0 == cnt) {
5648 DoCodeNullShift(dstvalue);
5649 } else {
5650 cnt &= 7;
5651 if (0 != cnt) {
5652 ui3b dst = (ui3b)dstvalue;
5653
5654 dst = (dst >> cnt)
5655 | ((dst & ((1 << cnt) - 1))
5656 << (8 - cnt));
5657
5658 dstvalue = (ui5r)(si5r)(si3b)dst;
5659 }
5660 ZFLG = Bool2Bit(dstvalue == 0);
5661 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5662 VFLG = 0;
5663 CFLG = NFLG;
5664
5665 V_regs.LazyFlagKind = kLazyFlagsDefault;
5666
5667 ArgSetDstValue(dstvalue);
5668 }
5669}
5670
5671LOCALIPROC DoCodeRorW(void)
5672{
5673 ui5r dstvalue = DecodeGetSrcSetDstValue();
5674 ui5r cnt = V_regs.SrcVal & 63;
5675
5676#if WantCloserCyc
5677 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5678#endif
5679
5680 if (0 == cnt) {
5681 DoCodeNullShift(dstvalue);
5682 } else {
5683 cnt &= 15;
5684 if (0 != cnt) {
5685 ui4b dst = (ui4b)dstvalue;
5686
5687 dst = (dst >> cnt)
5688 | ((dst & ((1 << cnt) - 1))
5689 << (16 - cnt));
5690
5691 dstvalue = (ui5r)(si5r)(si4b)dst;
5692 }
5693 ZFLG = Bool2Bit(dstvalue == 0);
5694 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5695 VFLG = 0;
5696 CFLG = NFLG;
5697
5698 V_regs.LazyFlagKind = kLazyFlagsDefault;
5699
5700 ArgSetDstValue(dstvalue);
5701 }
5702}
5703
5704LOCALIPROC DoCodeRorL(void)
5705{
5706 ui5r dstvalue = DecodeGetSrcSetDstValue();
5707 ui5r cnt = V_regs.SrcVal & 63;
5708
5709#if WantCloserCyc
5710 V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
5711#endif
5712
5713 if (0 == cnt) {
5714 DoCodeNullShift(dstvalue);
5715 } else {
5716 cnt &= 31;
5717 if (0 != cnt) {
5718 ui5b dst = (ui5b)dstvalue;
5719
5720 dst = (dst >> cnt)
5721 | ((dst & ((1 << cnt) - 1))
5722 << (32 - cnt));
5723
5724 dstvalue = (ui5r)(si5r)(si5b)dst;
5725 }
5726 ZFLG = Bool2Bit(dstvalue == 0);
5727 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
5728 VFLG = 0;
5729 CFLG = NFLG;
5730
5731 V_regs.LazyFlagKind = kLazyFlagsDefault;
5732
5733 ArgSetDstValue(dstvalue);
5734 }
5735}
5736
5737
5738#if UseLazyZ
5739LOCALPROC WillSetZFLG(void)
5740{
5741 if (kLazyFlagsZSet == V_regs.LazyFlagKind) {
5742 /* ok */
5743 } else if (kLazyFlagsDefault == V_regs.LazyFlagKind) {
5744 /* also ok */
5745 } else {
5746 V_regs.LazyFlagZSavedKind = V_regs.LazyFlagKind;
5747 V_regs.LazyFlagKind = kLazyFlagsZSet;
5748 }
5749}
5750#else
5751#define WillSetZFLG NeedDefaultLazyAllFlags
5752#endif
5753
5754LOCALINLINEFUNC ui5r DecodeGetSrcGetDstValueSetZ(void)
5755{
5756 WillSetZFLG();
5757
5758 return DecodeGetSrcSetDstValue();
5759}
5760
5761LOCALIPROC DoCodeBTstB(void)
5762{
5763 ui5r dstvalue = DecodeGetSrcGetDstValueSetZ();
5764 ui5r srcvalue = V_regs.SrcVal & 7;
5765
5766 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5767}
5768
5769LOCALIPROC DoCodeBTstL(void)
5770{
5771 ui5r dstvalue = DecodeGetSrcGetDstValueSetZ();
5772 ui5r srcvalue = V_regs.SrcVal & 31;
5773
5774 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5775}
5776
5777LOCALINLINEFUNC ui5r DecodeGetSrcSetDstValueSetZ(void)
5778{
5779 WillSetZFLG();
5780
5781 return DecodeGetSrcSetDstValue();
5782}
5783
5784LOCALIPROC DoCodeBChgB(void)
5785{
5786 ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
5787 ui5r srcvalue = V_regs.SrcVal & 7;
5788
5789 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5790
5791 dstvalue ^= (1 << srcvalue);
5792 ArgSetDstValue(dstvalue);
5793}
5794
5795LOCALIPROC DoCodeBChgL(void)
5796{
5797 ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
5798 ui5r srcvalue = V_regs.SrcVal & 31;
5799
5800 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5801
5802 dstvalue ^= (1 << srcvalue);
5803 ArgSetDstValue(dstvalue);
5804}
5805
5806LOCALIPROC DoCodeBClrB(void)
5807{
5808 ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
5809 ui5r srcvalue = V_regs.SrcVal & 7;
5810
5811 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5812
5813 dstvalue &= ~ (1 << srcvalue);
5814 ArgSetDstValue(dstvalue);
5815}
5816
5817LOCALIPROC DoCodeBClrL(void)
5818{
5819 ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
5820 ui5r srcvalue = V_regs.SrcVal & 31;
5821
5822 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5823
5824 dstvalue &= ~ (1 << srcvalue);
5825 ArgSetDstValue(dstvalue);
5826}
5827
5828LOCALIPROC DoCodeBSetB(void)
5829{
5830 ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
5831 ui5r srcvalue = V_regs.SrcVal & 7;
5832
5833 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5834
5835 dstvalue |= (1 << srcvalue);
5836 ArgSetDstValue(dstvalue);
5837}
5838
5839LOCALIPROC DoCodeBSetL(void)
5840{
5841 ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
5842 ui5r srcvalue = V_regs.SrcVal & 31;
5843
5844 ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
5845
5846 dstvalue |= (1 << srcvalue);
5847 ArgSetDstValue(dstvalue);
5848}
5849
5850LOCALIPROC DoCodeAnd(void)
5851{
5852 /* DoBinOpAnd(DecodeI_xxxxxxxxssmmmrrr()); */
5853 ui5r dstvalue = DecodeGetSrcSetDstValue();
5854
5855 dstvalue &= V_regs.SrcVal;
5856 /*
5857 don't need to extend, since excess high
5858 bits all the same as desired high bit.
5859 */
5860
5861 V_regs.LazyFlagKind = kLazyFlagsTstL;
5862 V_regs.LazyFlagArgDst = dstvalue;
5863
5864 HaveSetUpFlags();
5865
5866 ArgSetDstValue(dstvalue);
5867}
5868
5869LOCALIPROC DoCodeOr(void)
5870{
5871 /* DoBinOr(DecodeI_xxxxxxxxssmmmrrr()); */
5872 ui5r dstvalue = DecodeGetSrcSetDstValue();
5873
5874 dstvalue |= V_regs.SrcVal;
5875 /*
5876 don't need to extend, since excess high
5877 bits all the same as desired high bit.
5878 */
5879
5880 V_regs.LazyFlagKind = kLazyFlagsTstL;
5881 V_regs.LazyFlagArgDst = dstvalue;
5882
5883 HaveSetUpFlags();
5884
5885 ArgSetDstValue(dstvalue);
5886}
5887
5888LOCALIPROC DoCodeEor(void)
5889{
5890 /* Eor 1011ddd1ssmmmrrr */
5891 /* DoBinOpEor(DecodeDEa_xxxxdddxssmmmrrr()); */
5892 ui5r dstvalue = DecodeGetSrcSetDstValue();
5893
5894 dstvalue ^= V_regs.SrcVal;
5895 /*
5896 don't need to extend, since excess high
5897 bits all the same as desired high bit.
5898 */
5899
5900 V_regs.LazyFlagKind = kLazyFlagsTstL;
5901 V_regs.LazyFlagArgDst = dstvalue;
5902
5903 HaveSetUpFlags();
5904
5905 ArgSetDstValue(dstvalue);
5906}
5907
5908LOCALIPROC DoCodeNot(void)
5909{
5910 /* Not 01000110ssmmmrrr */
5911 ui5r dstvalue = DecodeGetSetDstValue();
5912
5913 dstvalue = ~ dstvalue;
5914
5915 V_regs.LazyFlagKind = kLazyFlagsTstL;
5916 V_regs.LazyFlagArgDst = dstvalue;
5917
5918 HaveSetUpFlags();
5919
5920 ArgSetDstValue(dstvalue);
5921}
5922
5923LOCALPROC DoCodeScc_t(void)
5924{
5925#if WantCloserCyc
5926 if (kAMdRegB == V_regs.CurDecOpY.v[1].AMd) {
5927 V_MaxCyclesToGo -= (2 * kCycleScale);
5928 }
5929#endif
5930 DecodeSetDstValue(0xff);
5931}
5932
5933LOCALPROC DoCodeScc_f(void)
5934{
5935 DecodeSetDstValue(0);
5936}
5937
5938LOCALIPROC DoCodeScc(void)
5939{
5940 /* Scc 0101cccc11mmmrrr */
5941 cctrue(DoCodeScc_t, DoCodeScc_f);
5942}
5943
5944LOCALIPROC DoCodeEXTL(void)
5945{
5946 /* EXT.L */
5947 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
5948 ui5r *dstp = &V_regs.regs[dstreg];
5949 ui5r dstvalue = ui5r_FromSWord(*dstp);
5950
5951 V_regs.LazyFlagKind = kLazyFlagsTstL;
5952 V_regs.LazyFlagArgDst = dstvalue;
5953
5954 HaveSetUpFlags();
5955
5956 *dstp = dstvalue;
5957}
5958
5959LOCALIPROC DoCodeEXTW(void)
5960{
5961 /* EXT.W */
5962 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
5963 ui5r *dstp = &V_regs.regs[dstreg];
5964 ui5r dstvalue = ui5r_FromSByte(*dstp);
5965
5966 V_regs.LazyFlagKind = kLazyFlagsTstL;
5967 V_regs.LazyFlagArgDst = dstvalue;
5968
5969 HaveSetUpFlags();
5970
5971#if LittleEndianUnaligned
5972 *(ui4b *)dstp = dstvalue;
5973#else
5974 *dstp = (*dstp & ~ 0xffff) | (dstvalue & 0xffff);
5975#endif
5976}
5977
5978LOCALIPROC DoCodeNegB(void)
5979{
5980 ui5r dstvalue = DecodeGetSetDstValue();
5981 ui5r result = ui5r_FromSByte(0 - dstvalue);
5982
5983 V_regs.LazyFlagKind = kLazyFlagsNegB;
5984 V_regs.LazyFlagArgDst = dstvalue;
5985 V_regs.LazyXFlagKind = kLazyFlagsNegB;
5986 V_regs.LazyXFlagArgDst = dstvalue;
5987
5988 HaveSetUpFlags();
5989
5990 ArgSetDstValue(result);
5991}
5992
5993LOCALIPROC DoCodeNegW(void)
5994{
5995 ui5r dstvalue = DecodeGetSetDstValue();
5996 ui5r result = ui5r_FromSWord(0 - dstvalue);
5997
5998 V_regs.LazyFlagKind = kLazyFlagsNegW;
5999 V_regs.LazyFlagArgDst = dstvalue;
6000 V_regs.LazyXFlagKind = kLazyFlagsNegW;
6001 V_regs.LazyXFlagArgDst = dstvalue;
6002
6003 HaveSetUpFlags();
6004
6005 ArgSetDstValue(result);
6006}
6007
6008LOCALIPROC DoCodeNegL(void)
6009{
6010 ui5r dstvalue = DecodeGetSetDstValue();
6011 ui5r result = ui5r_FromSLong(0 - dstvalue);
6012
6013 V_regs.LazyFlagKind = kLazyFlagsNegL;
6014 V_regs.LazyFlagArgDst = dstvalue;
6015 V_regs.LazyXFlagKind = kLazyFlagsNegL;
6016 V_regs.LazyXFlagArgDst = dstvalue;
6017
6018 HaveSetUpFlags();
6019
6020 ArgSetDstValue(result);
6021}
6022
6023LOCALPROC my_reg_call SetCCRforNegX(ui5r dstvalue, ui5r result)
6024{
6025 ZFLG &= Bool2Bit(result == 0);
6026
6027 {
6028 flagtype flgs = Bool2Bit(ui5r_MSBisSet(dstvalue));
6029 flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
6030
6031 NFLG = flgn;
6032 VFLG = flgs & flgn;
6033 XFLG = CFLG = flgs | flgn;
6034 }
6035
6036 ArgSetDstValue(result);
6037}
6038
6039LOCALIPROC DoCodeNegXB(void)
6040{
6041 NeedDefaultLazyAllFlags();
6042
6043 {
6044 ui5r dstvalue = DecodeGetSetDstValue();
6045 ui5r result = ui5r_FromSByte(0 - (XFLG + dstvalue));
6046
6047 SetCCRforNegX(dstvalue, result);
6048 }
6049}
6050
6051LOCALIPROC DoCodeNegXW(void)
6052{
6053 if ((kLazyFlagsDefault != V_regs.LazyFlagKind)
6054 || (kLazyFlagsDefault != V_regs.LazyXFlagKind))
6055 {
6056 NeedDefaultLazyAllFlags();
6057 }
6058
6059 {
6060 ui5r dstvalue = DecodeGetSetDstValue();
6061 ui5r result = ui5r_FromSWord(0 - (XFLG + dstvalue));
6062
6063 SetCCRforNegX(dstvalue, result);
6064 }
6065}
6066
6067LOCALIPROC DoCodeNegXL(void)
6068{
6069 if (kLazyFlagsNegL == V_regs.LazyFlagKind) {
6070 NeedDefaultLazyFlagsNegL();
6071 } else
6072 if ((kLazyFlagsDefault == V_regs.LazyFlagKind)
6073 && (kLazyFlagsDefault == V_regs.LazyXFlagKind))
6074 {
6075 /* ok */
6076 } else
6077 {
6078 NeedDefaultLazyAllFlags();
6079 }
6080
6081 {
6082 ui5r dstvalue = DecodeGetSetDstValue();
6083 ui5r result = ui5r_FromSLong(0 - (XFLG + dstvalue));
6084
6085 SetCCRforNegX(dstvalue, result);
6086 }
6087}
6088
6089LOCALIPROC DoCodeMulU(void)
6090{
6091 /* MulU 1100ddd011mmmrrr */
6092 ui5r srcvalue = DecodeGetSrcValue();
6093 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6094 ui5r *dstp = &V_regs.regs[dstreg];
6095 ui5r dstvalue = *dstp;
6096
6097 dstvalue = ui5r_FromSLong(ui5r_FromUWord(dstvalue)
6098 * ui5r_FromUWord(srcvalue));
6099#if WantCloserCyc
6100 {
6101 ui5r v = srcvalue;
6102
6103 while (v != 0) {
6104 if ((v & 1) != 0) {
6105 V_MaxCyclesToGo -= (2 * kCycleScale);
6106 }
6107 v >>= 1;
6108 }
6109 }
6110#endif
6111
6112 V_regs.LazyFlagKind = kLazyFlagsTstL;
6113 V_regs.LazyFlagArgDst = dstvalue;
6114
6115 HaveSetUpFlags();
6116
6117 *dstp = dstvalue;
6118}
6119
6120LOCALIPROC DoCodeMulS(void)
6121{
6122 /* MulS 1100ddd111mmmrrr */
6123 ui5r srcvalue = DecodeGetSrcValue();
6124 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6125 ui5r *dstp = &V_regs.regs[dstreg];
6126 ui5r dstvalue = *dstp;
6127
6128 dstvalue = ui5r_FromSLong((si5b)(si4b)dstvalue
6129 * (si5b)(si4b)srcvalue);
6130#if WantCloserCyc
6131 {
6132 ui5r v = (srcvalue << 1);
6133
6134 while (v != 0) {
6135 if ((v & 1) != ((v >> 1) & 1)) {
6136 V_MaxCyclesToGo -= (2 * kCycleScale);
6137 }
6138 v >>= 1;
6139 }
6140 }
6141#endif
6142
6143 V_regs.LazyFlagKind = kLazyFlagsTstL;
6144 V_regs.LazyFlagArgDst = dstvalue;
6145
6146 HaveSetUpFlags();
6147
6148 *dstp = dstvalue;
6149}
6150
6151LOCALIPROC DoCodeDivU(void)
6152{
6153 /* DivU 1000ddd011mmmrrr */
6154 ui5r srcvalue = DecodeGetSrcValue();
6155 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6156 ui5r *dstp = &V_regs.regs[dstreg];
6157 ui5r dstvalue = *dstp;
6158
6159 if (srcvalue == 0) {
6160#if WantCloserCyc
6161 V_MaxCyclesToGo -=
6162 (38 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
6163#endif
6164 Exception(5);
6165#if m68k_logExceptions
6166 dbglog_WriteNote("*** zero devide exception");
6167#endif
6168 } else {
6169 ui5b newv = (ui5b)dstvalue / (ui5b)(ui4b)srcvalue;
6170 ui5b rem = (ui5b)dstvalue % (ui5b)(ui4b)srcvalue;
6171#if WantCloserCyc
6172 V_MaxCyclesToGo -= (133 * kCycleScale);
6173#endif
6174 if (newv > 0xffff) {
6175 NeedDefaultLazyAllFlags();
6176
6177 VFLG = NFLG = 1;
6178 CFLG = 0;
6179 } else {
6180 VFLG = CFLG = 0;
6181 ZFLG = Bool2Bit(((si4b)(newv)) == 0);
6182 NFLG = Bool2Bit(((si4b)(newv)) < 0);
6183
6184 V_regs.LazyFlagKind = kLazyFlagsDefault;
6185
6186 newv = (newv & 0xffff) | ((ui5b)rem << 16);
6187 dstvalue = newv;
6188 }
6189 }
6190
6191 *dstp = dstvalue;
6192}
6193
6194LOCALIPROC DoCodeDivS(void)
6195{
6196 /* DivS 1000ddd111mmmrrr */
6197 ui5r srcvalue = DecodeGetSrcValue();
6198 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6199 ui5r *dstp = &V_regs.regs[dstreg];
6200 ui5r dstvalue = *dstp;
6201
6202 if (srcvalue == 0) {
6203#if WantCloserCyc
6204 V_MaxCyclesToGo -=
6205 (38 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
6206#endif
6207 Exception(5);
6208#if m68k_logExceptions
6209 dbglog_WriteNote("*** zero devide exception");
6210#endif
6211 } else {
6212 si5b newv = (si5b)dstvalue / (si5b)(si4b)srcvalue;
6213 ui4b rem = (si5b)dstvalue % (si5b)(si4b)srcvalue;
6214#if WantCloserCyc
6215 V_MaxCyclesToGo -= (150 * kCycleScale);
6216#endif
6217 if (((newv & 0xffff8000) != 0) &&
6218 ((newv & 0xffff8000) != 0xffff8000))
6219 {
6220 NeedDefaultLazyAllFlags();
6221
6222 VFLG = NFLG = 1;
6223 CFLG = 0;
6224 } else {
6225 if (((si4b)rem < 0) != ((si5b)dstvalue < 0)) {
6226 rem = - rem;
6227 }
6228 VFLG = CFLG = 0;
6229 ZFLG = Bool2Bit(((si4b)(newv)) == 0);
6230 NFLG = Bool2Bit(((si4b)(newv)) < 0);
6231
6232 V_regs.LazyFlagKind = kLazyFlagsDefault;
6233
6234 newv = (newv & 0xffff) | ((ui5b)rem << 16);
6235 dstvalue = newv;
6236 }
6237 }
6238
6239 *dstp = dstvalue;
6240}
6241
6242LOCALIPROC DoCodeExg(void)
6243{
6244 /* Exg dd 1100ddd101000rrr, opsize = 4 */
6245 /* Exg aa 1100ddd101001rrr, opsize = 4 */
6246 /* Exg da 1100ddd110001rrr, opsize = 4 */
6247
6248 ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
6249 ui5r *srcp = &V_regs.regs[srcreg];
6250 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6251 ui5r *dstp = &V_regs.regs[dstreg];
6252 ui5r srcvalue = *srcp;
6253
6254 *srcp = *dstp;
6255 *dstp = srcvalue;
6256}
6257
6258LOCALIPROC DoCodeMoveEaCR(void)
6259{
6260 /* 0100010011mmmrrr */
6261 m68k_setCR(DecodeGetDstValue());
6262}
6263
6264LOCALPROC DoPrivilegeViolation(void)
6265{
6266#if WantCloserCyc
6267 V_MaxCyclesToGo += GetDcoCycles(V_regs.CurDecOp);
6268 V_MaxCyclesToGo -=
6269 (34 * kCycleScale + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
6270#endif
6271 BackupPC();
6272 Exception(8);
6273#if m68k_logExceptions
6274 dbglog_WriteNote("*** Privilege Violation exception");
6275#endif
6276}
6277
6278LOCALIPROC DoCodeMoveSREa(void)
6279{
6280 /* Move from SR 0100000011mmmrrr */
6281#if Use68020
6282 if (0 == V_regs.s) {
6283 DoPrivilegeViolation();
6284 } else
6285#endif
6286 {
6287 DecodeSetDstValue(m68k_getSR());
6288 }
6289}
6290
6291LOCALIPROC DoCodeMoveEaSR(void)
6292{
6293 /* 0100011011mmmrrr */
6294 if (0 == V_regs.s) {
6295 DoPrivilegeViolation();
6296 } else {
6297 m68k_setSR(DecodeGetDstValue());
6298 }
6299}
6300
6301LOCALIPROC DoCodeOrISR(void)
6302{
6303 if (0 == V_regs.s) {
6304 DoPrivilegeViolation();
6305 } else {
6306 V_regs.SrcVal = nextiword_nm();
6307
6308 m68k_setSR(m68k_getSR() | V_regs.SrcVal);
6309 }
6310}
6311
6312LOCALIPROC DoCodeAndISR(void)
6313{
6314 if (0 == V_regs.s) {
6315 DoPrivilegeViolation();
6316 } else {
6317 V_regs.SrcVal = nextiword_nm();
6318
6319 m68k_setSR(m68k_getSR() & V_regs.SrcVal);
6320 }
6321}
6322
6323LOCALIPROC DoCodeEorISR(void)
6324{
6325 if (0 == V_regs.s) {
6326 DoPrivilegeViolation();
6327 } else {
6328 V_regs.SrcVal = nextiword_nm();
6329
6330 m68k_setSR(m68k_getSR() ^ V_regs.SrcVal);
6331 }
6332}
6333
6334LOCALIPROC DoCodeOrICCR(void)
6335{
6336 V_regs.SrcVal = nextiword_nm();
6337
6338 m68k_setCR(m68k_getCR() | V_regs.SrcVal);
6339}
6340
6341LOCALIPROC DoCodeAndICCR(void)
6342{
6343 V_regs.SrcVal = nextiword_nm();
6344
6345 m68k_setCR(m68k_getCR() & V_regs.SrcVal);
6346}
6347
6348LOCALIPROC DoCodeEorICCR(void)
6349{
6350 V_regs.SrcVal = nextiword_nm();
6351
6352 m68k_setCR(m68k_getCR() ^ V_regs.SrcVal);
6353}
6354
6355LOCALIPROC DoCodeMOVEMApRW(void)
6356{
6357 /* MOVEM mem to reg 01001100110011rrr */
6358 si4b z;
6359 ui5r regmask = nextiword_nm();
6360 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6361 ui5r *dstp = &V_regs.regs[dstreg];
6362 ui5r p = *dstp;
6363
6364 for (z = 0; z < 16; ++z) {
6365 if ((regmask & (1 << z)) != 0) {
6366#if WantCloserCyc
6367 V_MaxCyclesToGo -= (4 * kCycleScale + RdAvgXtraCyc);
6368#endif
6369 V_regs.regs[z] = get_word(p);
6370 p += 2;
6371 }
6372 }
6373 *dstp = p;
6374}
6375
6376LOCALIPROC DoCodeMOVEMRmMW(void)
6377{
6378 /* MOVEM reg to mem 01001000110100rrr */
6379 si4b z;
6380 ui5r regmask = nextiword_nm();
6381 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6382 ui5r *dstp = &V_regs.regs[dstreg];
6383 ui5r p = *dstp;
6384
6385#if Use68020
6386 {
6387 int n = 0;
6388
6389 for (z = 0; z < 16; ++z) {
6390 if ((regmask & (1 << z)) != 0) {
6391 n++;
6392 }
6393 }
6394 *dstp = p - n * 2;
6395 }
6396#endif
6397 for (z = 16; --z >= 0; ) {
6398 if ((regmask & (1 << (15 - z))) != 0) {
6399#if WantCloserCyc
6400 V_MaxCyclesToGo -= (4 * kCycleScale + WrAvgXtraCyc);
6401#endif
6402 p -= 2;
6403 put_word(p, V_regs.regs[z]);
6404 }
6405 }
6406#if ! Use68020
6407 *dstp = p;
6408#endif
6409}
6410
6411LOCALIPROC DoCodeMOVEMrmW(void)
6412{
6413 /* MOVEM reg to mem 010010001ssmmmrrr */
6414 si4b z;
6415 ui5r regmask = nextiword_nm();
6416 ui5r p = DecodeDst();
6417
6418 for (z = 0; z < 16; ++z) {
6419 if ((regmask & (1 << z)) != 0) {
6420#if WantCloserCyc
6421 V_MaxCyclesToGo -=
6422 (4 * kCycleScale + WrAvgXtraCyc);
6423#endif
6424 put_word(p, V_regs.regs[z]);
6425 p += 2;
6426 }
6427 }
6428}
6429
6430LOCALIPROC DoCodeMOVEMrmL(void)
6431{
6432 /* MOVEM reg to mem 010010001ssmmmrrr */
6433 si4b z;
6434 ui5r regmask = nextiword_nm();
6435 ui5r p = DecodeDst();
6436
6437 for (z = 0; z < 16; ++z) {
6438 if ((regmask & (1 << z)) != 0) {
6439#if WantCloserCyc
6440 V_MaxCyclesToGo -=
6441 (8 * kCycleScale + 2 * WrAvgXtraCyc);
6442#endif
6443 put_long(p, V_regs.regs[z]);
6444 p += 4;
6445 }
6446 }
6447}
6448
6449LOCALIPROC DoCodeMOVEMmrW(void)
6450{
6451 /* MOVEM mem to reg 0100110011smmmrrr */
6452 si4b z;
6453 ui5r regmask = nextiword_nm();
6454 ui5r p = DecodeDst();
6455
6456 for (z = 0; z < 16; ++z) {
6457 if ((regmask & (1 << z)) != 0) {
6458#if WantCloserCyc
6459 V_MaxCyclesToGo -=
6460 (4 * kCycleScale + RdAvgXtraCyc);
6461#endif
6462 V_regs.regs[z] = get_word(p);
6463 p += 2;
6464 }
6465 }
6466}
6467
6468LOCALIPROC DoCodeMOVEMmrL(void)
6469{
6470 /* MOVEM mem to reg 0100110011smmmrrr */
6471 si4b z;
6472 ui5r regmask = nextiword_nm();
6473 ui5r p = DecodeDst();
6474
6475 for (z = 0; z < 16; ++z) {
6476 if ((regmask & (1 << z)) != 0) {
6477#if WantCloserCyc
6478 V_MaxCyclesToGo -=
6479 (8 * kCycleScale + 2 * RdAvgXtraCyc);
6480#endif
6481 V_regs.regs[z] = get_long(p);
6482 p += 4;
6483 }
6484 }
6485}
6486
6487LOCALIPROC DoCodeAbcd(void)
6488{
6489 /* ABCD r 1100ddd100000rrr */
6490 /* ABCD m 1100ddd100001rrr */
6491
6492 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
6493 ui5r srcvalue = V_regs.SrcVal;
6494
6495 {
6496 /* if (V_regs.opsize != 1) a bug */
6497 int flgs = ui5r_MSBisSet(srcvalue);
6498 int flgo = ui5r_MSBisSet(dstvalue);
6499 ui4b newv_lo =
6500 (srcvalue & 0xF) + (dstvalue & 0xF) + XFLG;
6501 ui4b newv_hi = (srcvalue & 0xF0) + (dstvalue & 0xF0);
6502 ui4b newv;
6503
6504 if (newv_lo > 9) {
6505 newv_lo += 6;
6506 }
6507 newv = newv_hi + newv_lo;
6508 CFLG = XFLG = Bool2Bit((newv & 0x1F0) > 0x90);
6509 if (CFLG != 0) {
6510 newv += 0x60;
6511 }
6512 dstvalue = ui5r_FromSByte(newv);
6513 if (dstvalue != 0) {
6514 ZFLG = 0;
6515 }
6516 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
6517 VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
6518 /*
6519 but according to my reference book,
6520 VFLG is Undefined for ABCD
6521 */
6522 }
6523
6524 ArgSetDstValue(dstvalue);
6525}
6526
6527LOCALIPROC DoCodeSbcd(void)
6528{
6529 ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
6530 ui5r srcvalue = V_regs.SrcVal;
6531
6532 {
6533 int flgs = ui5r_MSBisSet(srcvalue);
6534 int flgo = ui5r_MSBisSet(dstvalue);
6535 ui4b newv_lo =
6536 (dstvalue & 0xF) - (srcvalue & 0xF) - XFLG;
6537 ui4b newv_hi = (dstvalue & 0xF0) - (srcvalue & 0xF0);
6538 ui4b newv;
6539
6540 if (newv_lo > 9) {
6541 newv_lo -= 6;
6542 newv_hi -= 0x10;
6543 }
6544 newv = newv_hi + (newv_lo & 0xF);
6545 CFLG = XFLG = Bool2Bit((newv_hi & 0x1F0) > 0x90);
6546 if (CFLG != 0) {
6547 newv -= 0x60;
6548 }
6549 dstvalue = ui5r_FromSByte(newv);
6550 if (dstvalue != 0) {
6551 ZFLG = 0;
6552 }
6553 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
6554 VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
6555 /*
6556 but according to my reference book,
6557 VFLG is Undefined for SBCD
6558 */
6559 }
6560
6561 ArgSetDstValue(dstvalue);
6562}
6563
6564LOCALIPROC DoCodeNbcd(void)
6565{
6566 /* Nbcd 0100100000mmmrrr */
6567 ui5r dstvalue = DecodeGetSetDstValue();
6568
6569 NeedDefaultLazyAllFlags();
6570
6571 {
6572 ui4b newv_lo = - (dstvalue & 0xF) - XFLG;
6573 ui4b newv_hi = - (dstvalue & 0xF0);
6574 ui4b newv;
6575
6576 if (newv_lo > 9) {
6577 newv_lo -= 6;
6578 newv_hi -= 0x10;
6579 }
6580 newv = newv_hi + (newv_lo & 0xF);
6581 CFLG = XFLG = Bool2Bit((newv_hi & 0x1F0) > 0x90);
6582 if (CFLG != 0) {
6583 newv -= 0x60;
6584 }
6585
6586 dstvalue = ui5r_FromSByte(newv);
6587 NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
6588 if (dstvalue != 0) {
6589 ZFLG = 0;
6590 }
6591 }
6592
6593 ArgSetDstValue(dstvalue);
6594}
6595
6596LOCALIPROC DoCodeRte(void)
6597{
6598 /* Rte 0100111001110011 */
6599 if (0 == V_regs.s) {
6600 DoPrivilegeViolation();
6601 } else {
6602 ui5r NewPC;
6603 CPTR stackp = m68k_areg(7);
6604 ui5r NewSR = get_word(stackp);
6605 stackp += 2;
6606 NewPC = get_long(stackp);
6607 stackp += 4;
6608
6609#if Use68020
6610 {
6611 ui4b format = get_word(stackp);
6612 stackp += 2;
6613
6614 switch ((format >> 12) & 0x0F) {
6615 case 0:
6616 /* ReportAbnormal("rte stack frame format 0"); */
6617 break;
6618 case 1:
6619 ReportAbnormalID(0x0107,
6620 "rte stack frame format 1");
6621 NewPC = m68k_getpc() - 2;
6622 /* rerun instruction */
6623 break;
6624 case 2:
6625 ReportAbnormalID(0x0108,
6626 "rte stack frame format 2");
6627 stackp += 4;
6628 break;
6629 case 9:
6630 ReportAbnormalID(0x0109,
6631 "rte stack frame format 9");
6632 stackp += 12;
6633 break;
6634 case 10:
6635 ReportAbnormalID(0x010A,
6636 "rte stack frame format 10");
6637 stackp += 24;
6638 break;
6639 case 11:
6640 ReportAbnormalID(0x010B,
6641 "rte stack frame format 11");
6642 stackp += 84;
6643 break;
6644 default:
6645 ReportAbnormalID(0x010C,
6646 "unknown rte stack frame format");
6647 Exception(14);
6648 return;
6649 break;
6650 }
6651 }
6652#endif
6653 m68k_areg(7) = stackp;
6654 m68k_setSR(NewSR);
6655 m68k_setpc(NewPC);
6656 }
6657}
6658
6659LOCALIPROC DoCodeNop(void)
6660{
6661 /* Nop 0100111001110001 */
6662}
6663
6664LOCALIPROC DoCodeMoveP0(void)
6665{
6666 /* MoveP 0000ddd1mm001aaa */
6667 ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
6668 ui5r *srcp = &V_regs.regs[srcreg];
6669 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6670 ui5r *dstp = &V_regs.regs[dstreg];
6671
6672 ui5r Displacement = nextiword_nm();
6673 /* shouldn't this sign extend ? */
6674 CPTR memp = *srcp + Displacement;
6675
6676 ui4r val = ((get_byte(memp) & 0x00FF) << 8)
6677 | (get_byte(memp + 2) & 0x00FF);
6678
6679 *dstp =
6680 (*dstp & ~ 0xffff) | (val & 0xffff);
6681
6682#if 0
6683 if ((Displacement & 0x00008000) != 0) {
6684 /* **** for testing only **** */
6685 BackupPC();
6686 op_illg();
6687 }
6688#endif
6689}
6690
6691LOCALIPROC DoCodeMoveP1(void)
6692{
6693 /* MoveP 0000ddd1mm001aaa */
6694 ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
6695 ui5r *srcp = &V_regs.regs[srcreg];
6696 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6697 ui5r *dstp = &V_regs.regs[dstreg];
6698
6699 ui5r Displacement = nextiword_nm();
6700 /* shouldn't this sign extend ? */
6701 CPTR memp = *srcp + Displacement;
6702
6703 ui5r val = ((get_byte(memp) & 0x00FF) << 24)
6704 | ((get_byte(memp + 2) & 0x00FF) << 16)
6705 | ((get_byte(memp + 4) & 0x00FF) << 8)
6706 | (get_byte(memp + 6) & 0x00FF);
6707
6708 *dstp = val;
6709}
6710
6711LOCALIPROC DoCodeMoveP2(void)
6712{
6713 /* MoveP 0000ddd1mm001aaa */
6714 ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
6715 ui5r *srcp = &V_regs.regs[srcreg];
6716 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6717 ui5r *dstp = &V_regs.regs[dstreg];
6718
6719 ui5r Displacement = nextiword_nm();
6720 /* shouldn't this sign extend ? */
6721 CPTR memp = *srcp + Displacement;
6722
6723 ui4r val = *dstp;
6724
6725 put_byte(memp, val >> 8);
6726 put_byte(memp + 2, val);
6727}
6728
6729LOCALIPROC DoCodeMoveP3(void)
6730{
6731 /* MoveP 0000ddd1mm001aaa */
6732 ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
6733 ui5r *srcp = &V_regs.regs[srcreg];
6734 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6735 ui5r *dstp = &V_regs.regs[dstreg];
6736
6737 ui5r Displacement = nextiword_nm();
6738 /* shouldn't this sign extend ? */
6739 CPTR memp = *srcp + Displacement;
6740
6741 ui5r val = *dstp;
6742
6743 put_byte(memp, val >> 24);
6744 put_byte(memp + 2, val >> 16);
6745 put_byte(memp + 4, val >> 8);
6746 put_byte(memp + 6, val);
6747}
6748
6749LOCALPROC op_illg(void)
6750{
6751 BackupPC();
6752 Exception(4);
6753#if m68k_logExceptions
6754 dbglog_WriteNote("*** illegal instruction exception");
6755#endif
6756}
6757
6758LOCALIPROC DoCodeChk(void)
6759{
6760 ui5r dstvalue = DecodeGetSrcGetDstValue();
6761 ui5r srcvalue = V_regs.SrcVal;
6762
6763 if (ui5r_MSBisSet(srcvalue)) {
6764 NeedDefaultLazyAllFlags();
6765
6766#if WantCloserCyc
6767 V_MaxCyclesToGo -=
6768 (30 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
6769#endif
6770 NFLG = 1;
6771 Exception(6);
6772 } else if (((si5r)srcvalue) > ((si5r)dstvalue)) {
6773 NeedDefaultLazyAllFlags();
6774
6775#if WantCloserCyc
6776 V_MaxCyclesToGo -=
6777 (30 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
6778#endif
6779 NFLG = 0;
6780 Exception(6);
6781 }
6782}
6783
6784LOCALIPROC DoCodeTrap(void)
6785{
6786 /* Trap 010011100100vvvv */
6787 Exception(V_regs.CurDecOpY.v[1].ArgDat);
6788}
6789
6790LOCALIPROC DoCodeTrapV(void)
6791{
6792 /* TrapV 0100111001110110 */
6793 NeedDefaultLazyAllFlags();
6794
6795 if (VFLG != 0) {
6796#if WantCloserCyc
6797 V_MaxCyclesToGo += GetDcoCycles(V_regs.CurDecOp);
6798 V_MaxCyclesToGo -=
6799 (34 * kCycleScale + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
6800#endif
6801 Exception(7);
6802 }
6803}
6804
6805LOCALIPROC DoCodeRtr(void)
6806{
6807 /* Rtr 0100111001110111 */
6808 ui5r NewPC;
6809 CPTR stackp = m68k_areg(7);
6810 ui5r NewCR = get_word(stackp);
6811 stackp += 2;
6812 NewPC = get_long(stackp);
6813 stackp += 4;
6814 m68k_areg(7) = stackp;
6815 m68k_setCR(NewCR);
6816 m68k_setpc(NewPC);
6817}
6818
6819LOCALIPROC DoCodeLink(void)
6820{
6821 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6822 ui5r *dstp = &V_regs.regs[dstreg];
6823 CPTR stackp = m68k_areg(7);
6824
6825 stackp -= 4;
6826 m68k_areg(7) = stackp; /* only matters if dstreg == 7 + 8 */
6827 put_long(stackp, *dstp);
6828 *dstp = stackp;
6829 m68k_areg(7) += ui5r_FromSWord(nextiword_nm());
6830}
6831
6832LOCALIPROC DoCodeUnlk(void)
6833{
6834 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6835 ui5r *dstp = &V_regs.regs[dstreg];
6836
6837 if (dstreg != 7 + 8) {
6838 ui5r src = *dstp;
6839 *dstp = get_long(src);
6840 m68k_areg(7) = src + 4;
6841 } else {
6842 /* wouldn't expect this to happen */
6843 m68k_areg(7) = get_long(m68k_areg(7)) + 4;
6844 }
6845}
6846
6847LOCALIPROC DoCodeMoveRUSP(void)
6848{
6849 /* MOVE USP 0100111001100aaa */
6850 if (0 == V_regs.s) {
6851 DoPrivilegeViolation();
6852 } else {
6853 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6854 ui5r *dstp = &V_regs.regs[dstreg];
6855
6856 V_regs.usp = *dstp;
6857 }
6858}
6859
6860LOCALIPROC DoCodeMoveUSPR(void)
6861{
6862 /* MOVE USP 0100111001101aaa */
6863 if (0 == V_regs.s) {
6864 DoPrivilegeViolation();
6865 } else {
6866 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
6867 ui5r *dstp = &V_regs.regs[dstreg];
6868
6869 *dstp = V_regs.usp;
6870 }
6871}
6872
6873LOCALIPROC DoCodeTas(void)
6874{
6875 /* Tas 0100101011mmmrrr */
6876 ui5r dstvalue = DecodeGetSetDstValue();
6877
6878 V_regs.LazyFlagKind = kLazyFlagsTstL;
6879 V_regs.LazyFlagArgDst = dstvalue;
6880
6881 HaveSetUpFlags();
6882
6883 dstvalue |= 0x80;
6884
6885 ArgSetDstValue(dstvalue);
6886}
6887
6888LOCALIPROC DoCodeFdefault(void)
6889{
6890 BackupPC();
6891 Exception(0xB);
6892}
6893
6894LOCALPROC m68k_setstopped(void)
6895{
6896 /* not implemented. doesn't seemed to be used on Mac Plus */
6897 Exception(4); /* fake an illegal instruction */
6898#if m68k_logExceptions
6899 dbglog_WriteNote("*** set stopped");
6900#endif
6901}
6902
6903LOCALIPROC DoCodeStop(void)
6904{
6905 /* Stop 0100111001110010 */
6906 if (0 == V_regs.s) {
6907 DoPrivilegeViolation();
6908 } else {
6909 m68k_setSR(nextiword_nm());
6910 m68k_setstopped();
6911 }
6912}
6913
6914FORWARDPROC local_customreset(void);
6915
6916LOCALIPROC DoCodeReset(void)
6917{
6918 /* Reset 0100111001110000 */
6919 if (0 == V_regs.s) {
6920 DoPrivilegeViolation();
6921 } else {
6922 local_customreset();
6923 }
6924}
6925
6926#if Use68020
6927LOCALIPROC DoCodeCallMorRtm(void)
6928{
6929 /* CALLM or RTM 0000011011mmmrrr */
6930 ReportAbnormalID(0x010D, "CALLM or RTM instruction");
6931}
6932#endif
6933
6934#if Use68020
6935LOCALIPROC DoCodeMoveCCREa(void)
6936{
6937 /* Move from CCR 0100001011mmmrrr */
6938 DecodeSetDstValue(m68k_getCR());
6939}
6940#endif
6941
6942#if Use68020 || EmFPU
6943LOCALIPROC DoCodeBraL(void)
6944{
6945 /* Bra 0110ccccnnnnnnnn */
6946 si5r offset = ((si5b)(ui5b)nextilong()) - 4;
6947 ui3p s = V_pc_p + offset;
6948
6949 V_pc_p = s;
6950
6951#if USE_PCLIMIT
6952 if (my_cond_rare(s >= V_pc_pHi)
6953 || my_cond_rare(s < V_regs.pc_pLo))
6954 {
6955 Recalc_PC_Block();
6956 }
6957#endif
6958}
6959#endif
6960
6961#if Use68020 || EmFPU
6962LOCALPROC SkipiLong(void)
6963{
6964 V_pc_p += 4;
6965
6966#if USE_PCLIMIT
6967 if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
6968 Recalc_PC_Block();
6969 }
6970#endif
6971}
6972#endif
6973
6974#if Use68020
6975LOCALIPROC DoCodeBccL(void)
6976{
6977 /* Bcc 0110ccccnnnnnnnn */
6978 cctrue(DoCodeBraL, SkipiLong);
6979}
6980#endif
6981
6982#if Use68020
6983LOCALIPROC DoCodeBsrL(void)
6984{
6985 si5r offset = ((si5b)(ui5b)nextilong()) - 4;
6986 ui3p s = V_pc_p + offset;
6987
6988 m68k_areg(7) -= 4;
6989 put_long(m68k_areg(7), m68k_getpc());
6990 V_pc_p = s;
6991
6992#if USE_PCLIMIT
6993 if (my_cond_rare(s >= V_pc_pHi)
6994 || my_cond_rare(s < V_regs.pc_pLo))
6995 {
6996 Recalc_PC_Block();
6997 }
6998#endif
6999
7000 /* ReportAbnormal("long branch in DoCode6"); */
7001 /* Used by various Apps */
7002}
7003#endif
7004
7005#if Use68020
7006LOCALIPROC DoCodeEXTBL(void)
7007{
7008 /* EXTB.L */
7009 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
7010 ui5r *dstp = &V_regs.regs[dstreg];
7011 ui5r dstvalue = ui5r_FromSByte(*dstp);
7012
7013 V_regs.LazyFlagKind = kLazyFlagsTstL;
7014 V_regs.LazyFlagArgDst = dstvalue;
7015
7016 HaveSetUpFlags();
7017
7018 *dstp = dstvalue;
7019}
7020#endif
7021
7022#if Use68020
7023LOCALPROC DoCHK2orCMP2(void)
7024{
7025 /* CHK2 or CMP2 00000ss011mmmrrr */
7026 ui5r regv;
7027 ui5r lower;
7028 ui5r upper;
7029 ui5r extra = nextiword_nm();
7030 ui5r DstAddr = DecodeDst();
7031 ui5r srcreg = (extra >> 12) & 0x0F;
7032 ui5r *srcp = &V_regs.regs[srcreg];
7033
7034 /* ReportAbnormal("CHK2 or CMP2 instruction"); */
7035 switch (V_regs.CurDecOpY.v[0].ArgDat) {
7036 case 1:
7037 if ((extra & 0x8000) == 0) {
7038 regv = ui5r_FromSByte(*srcp);
7039 } else {
7040 regv = ui5r_FromSLong(*srcp);
7041 }
7042 lower = get_byte(DstAddr);
7043 upper = get_byte(DstAddr + 1);
7044 break;
7045 case 2:
7046 if ((extra & 0x8000) == 0) {
7047 regv = ui5r_FromSWord(*srcp);
7048 } else {
7049 regv = ui5r_FromSLong(*srcp);
7050 }
7051 lower = get_word(DstAddr);
7052 upper = get_word(DstAddr + 2);
7053 break;
7054 default:
7055#if ExtraAbnormalReports
7056 if (4 != V_regs.CurDecOpY.v[0].ArgDat) {
7057 ReportAbnormalID(0x010E,
7058 "illegal opsize in CHK2 or CMP2");
7059 }
7060#endif
7061 if ((extra & 0x8000) == 0) {
7062 regv = ui5r_FromSLong(*srcp);
7063 } else {
7064 regv = ui5r_FromSLong(*srcp);
7065 }
7066 lower = get_long(DstAddr);
7067 upper = get_long(DstAddr + 4);
7068 break;
7069 }
7070
7071 NeedDefaultLazyAllFlags();
7072
7073 ZFLG = Bool2Bit((upper == regv) || (lower == regv));
7074 CFLG = Bool2Bit((((si5r)lower) <= ((si5r)upper))
7075 ? (((si5r)regv) < ((si5r)lower)
7076 || ((si5r)regv) > ((si5r)upper))
7077 : (((si5r)regv) > ((si5r)upper)
7078 || ((si5r)regv) < ((si5r)lower)));
7079
7080 if ((extra & 0x800) && (CFLG != 0)) {
7081 Exception(6);
7082 }
7083}
7084#endif
7085
7086#if Use68020
7087LOCALPROC DoCAS(void)
7088{
7089 /* CAS 00001ss011mmmrrr */
7090 ui5r srcvalue;
7091 ui5r dstvalue;
7092
7093 ui4b src = nextiword_nm();
7094 int ru = (src >> 6) & 7;
7095 int rc = src & 7;
7096
7097 ReportAbnormalID(0x010F, "CAS instruction");
7098 switch (V_regs.CurDecOpY.v[0].ArgDat) {
7099 case 1:
7100 srcvalue = ui5r_FromSByte(V_regs.regs[rc]);
7101 break;
7102 case 2:
7103 srcvalue = ui5r_FromSWord(V_regs.regs[rc]);
7104 break;
7105 default:
7106#if ExtraAbnormalReports
7107 if (4 != V_regs.CurDecOpY.v[0].ArgDat) {
7108 ReportAbnormalID(0x0110, "illegal opsize in DoCAS");
7109 }
7110#endif
7111 srcvalue = ui5r_FromSLong(V_regs.regs[rc]);
7112 break;
7113 }
7114 dstvalue = DecodeGetSetDstValue();
7115
7116 {
7117 int flgs = ((si5b)srcvalue) < 0;
7118 int flgo = ((si5b)dstvalue) < 0;
7119 ui5r newv = dstvalue - srcvalue;
7120 if (V_regs.CurDecOpY.v[0].ArgDat == 1) {
7121 newv = ui5r_FromSByte(newv);
7122 } else if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7123 newv = ui5r_FromSWord(newv);
7124 } else {
7125 newv = ui5r_FromSLong(newv);
7126 }
7127 ZFLG = Bool2Bit(((si5b)newv) == 0);
7128 NFLG = Bool2Bit(((si5b)newv) < 0);
7129 VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
7130 CFLG = Bool2Bit(
7131 (flgs && ! flgo) || ((NFLG != 0) && ((! flgo) || flgs)));
7132
7133 V_regs.LazyFlagKind = kLazyFlagsDefault;
7134
7135 if (ZFLG != 0) {
7136 ArgSetDstValue(m68k_dreg(ru));
7137 } else {
7138 V_regs.ArgAddr.rga = &V_regs.regs[rc];
7139
7140 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7141 *V_regs.ArgAddr.rga =
7142 (*V_regs.ArgAddr.rga & ~ 0xffff)
7143 | ((dstvalue) & 0xffff);
7144 } else if (V_regs.CurDecOpY.v[0].ArgDat < 2) {
7145 *V_regs.ArgAddr.rga =
7146 (*V_regs.ArgAddr.rga & ~ 0xff)
7147 | ((dstvalue) & 0xff);
7148 } else {
7149 *V_regs.ArgAddr.rga = dstvalue;
7150 }
7151 }
7152 }
7153}
7154#endif
7155
7156#if Use68020
7157LOCALPROC DoCAS2(void)
7158{
7159 /* CAS2 00001ss011111100 */
7160 ui5b extra = nextilong();
7161 int dc2 = extra & 7;
7162 int du2 = (extra >> 6) & 7;
7163 int dc1 = (extra >> 16) & 7;
7164 int du1 = (extra >> 22) & 7;
7165 CPTR rn1 = V_regs.regs[(extra >> 28) & 0x0F];
7166 CPTR rn2 = V_regs.regs[(extra >> 12) & 0x0F];
7167 si5b src = m68k_dreg(dc1);
7168 si5r dst1;
7169 si5r dst2;
7170
7171 ReportAbnormalID(0x0111, "DoCAS2 instruction");
7172 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7173 dst1 = get_word(rn1);
7174 dst2 = get_word(rn2);
7175 src = (si5b)(si4b)src;
7176 } else {
7177 dst1 = get_long(rn1);
7178 dst2 = get_long(rn2);
7179 }
7180 {
7181 int flgs = src < 0;
7182 int flgo = dst1 < 0;
7183 si5b newv = dst1 - src;
7184 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7185 newv = (ui4b)newv;
7186 }
7187 ZFLG = Bool2Bit(newv == 0);
7188 NFLG = Bool2Bit(newv < 0);
7189 VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
7190 CFLG = Bool2Bit(
7191 (flgs && ! flgo) || ((NFLG != 0) && ((! flgo) || flgs)));
7192
7193 V_regs.LazyFlagKind = kLazyFlagsDefault;
7194
7195 if (ZFLG != 0) {
7196 src = m68k_dreg(dc2);
7197 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7198 src = (si5b)(si4b)src;
7199 }
7200 flgs = src < 0;
7201 flgo = dst2 < 0;
7202 newv = dst2 - src;
7203 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7204 newv = (ui4b)newv;
7205 }
7206 ZFLG = Bool2Bit(newv == 0);
7207 NFLG = Bool2Bit(newv < 0);
7208 VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
7209 CFLG = Bool2Bit((flgs && ! flgo)
7210 || ((NFLG != 0) && ((! flgo) || flgs)));
7211
7212 V_regs.LazyFlagKind = kLazyFlagsDefault;
7213 if (ZFLG != 0) {
7214 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7215 put_word(rn1, m68k_dreg(du1));
7216 put_word(rn2, m68k_dreg(du2));
7217 } else {
7218 put_word(rn1, m68k_dreg(du1));
7219 put_word(rn2, m68k_dreg(du2));
7220 }
7221 }
7222 }
7223 }
7224 if (ZFLG == 0) {
7225 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7226 m68k_dreg(du1) =
7227 (m68k_dreg(du1) & ~ 0xffff) | ((ui5b)dst1 & 0xffff);
7228 m68k_dreg(du2) =
7229 (m68k_dreg(du2) & ~ 0xffff) | ((ui5b)dst2 & 0xffff);
7230 } else {
7231 m68k_dreg(du1) = dst1;
7232 m68k_dreg(du2) = dst2;
7233 }
7234 }
7235}
7236#endif
7237
7238#if Use68020
7239LOCALPROC DoMOVES(void)
7240{
7241 /* MoveS 00001110ssmmmrrr */
7242 ReportAbnormalID(0x0112, "MoveS instruction");
7243 if (0 == V_regs.s) {
7244 DoPrivilegeViolation();
7245 } else {
7246 ui4b extra = nextiword_nm();
7247 if (extra & 0x0800) {
7248 ui5b src = V_regs.regs[(extra >> 12) & 0x0F];
7249 DecodeSetDstValue(src);
7250 } else {
7251 ui5r srcvalue = DecodeGetDstValue();
7252 ui5b rr = (extra >> 12) & 7;
7253 if (extra & 0x8000) {
7254 m68k_areg(rr) = srcvalue;
7255 } else {
7256 V_regs.ArgAddr.rga = &V_regs.regs[rr];
7257
7258 if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
7259 *V_regs.ArgAddr.rga =
7260 (*V_regs.ArgAddr.rga & ~ 0xffff)
7261 | ((srcvalue) & 0xffff);
7262 } else if (V_regs.CurDecOpY.v[0].ArgDat < 2) {
7263 *V_regs.ArgAddr.rga =
7264 (*V_regs.ArgAddr.rga & ~ 0xff)
7265 | ((srcvalue) & 0xff);
7266 } else {
7267 *V_regs.ArgAddr.rga = srcvalue;
7268 }
7269 }
7270 }
7271 }
7272}
7273#endif
7274
7275#define ui5b_lo(x) ((x) & 0x0000FFFF)
7276#define ui5b_hi(x) (((x) >> 16) & 0x0000FFFF)
7277
7278#if Use68020
7279struct ui6r0 {
7280 ui5b hi;
7281 ui5b lo;
7282};
7283typedef struct ui6r0 ui6r0;
7284#endif
7285
7286#if Use68020
7287LOCALPROC Ui6r_Negate(ui6r0 *v)
7288{
7289 v->hi = ~ v->hi;
7290 v->lo = - v->lo;
7291 if (v->lo == 0) {
7292 v->hi++;
7293 }
7294}
7295#endif
7296
7297#if Use68020
7298LOCALFUNC blnr my_reg_call Ui6r_IsZero(ui6r0 *v)
7299{
7300 return (v->hi == 0) && (v->lo == 0);
7301}
7302#endif
7303
7304#if Use68020
7305LOCALFUNC blnr my_reg_call Ui6r_IsNeg(ui6r0 *v)
7306{
7307 return ((si5b)v->hi) < 0;
7308}
7309#endif
7310
7311#if Use68020
7312LOCALPROC mul_unsigned(ui5b src1, ui5b src2, ui6r0 *dst)
7313{
7314 ui5b src1_lo = ui5b_lo(src1);
7315 ui5b src2_lo = ui5b_lo(src2);
7316 ui5b src1_hi = ui5b_hi(src1);
7317 ui5b src2_hi = ui5b_hi(src2);
7318
7319 ui5b r0 = src1_lo * src2_lo;
7320 ui5b r1 = src1_hi * src2_lo;
7321 ui5b r2 = src1_lo * src2_hi;
7322 ui5b r3 = src1_hi * src2_hi;
7323
7324 ui5b ra1 = ui5b_hi(r0) + ui5b_lo(r1) + ui5b_lo(r2);
7325
7326 dst->lo = (ui5b_lo(ra1) << 16) | ui5b_lo(r0);
7327 dst->hi = ui5b_hi(ra1) + ui5b_hi(r1) + ui5b_hi(r2) + r3;
7328}
7329#endif
7330
7331#if Use68020
7332LOCALFUNC blnr div_unsigned(ui6r0 *src, ui5b div,
7333 ui5b *quot, ui5b *rem)
7334{
7335 int i;
7336 ui5b q = 0;
7337 ui5b cbit = 0;
7338 ui5b src_hi = src->hi;
7339 ui5b src_lo = src->lo;
7340
7341 if (div <= src_hi) {
7342 return trueblnr;
7343 }
7344 for (i = 0 ; i < 32 ; i++) {
7345 cbit = src_hi & 0x80000000ul;
7346 src_hi <<= 1;
7347 if (src_lo & 0x80000000ul) {
7348 src_hi++;
7349 }
7350 src_lo <<= 1;
7351 q = q << 1;
7352 if (cbit || div <= src_hi) {
7353 q |= 1;
7354 src_hi -= div;
7355 }
7356 }
7357 *quot = q;
7358 *rem = src_hi;
7359 return falseblnr;
7360}
7361#endif
7362
7363#if Use68020
7364LOCALIPROC DoCodeMulL(void)
7365{
7366 /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
7367 /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
7368 ui6r0 dst;
7369 ui4b extra = nextiword();
7370 ui5b r2 = (extra >> 12) & 7;
7371 ui5b dstvalue = m68k_dreg(r2);
7372 ui5r srcvalue = DecodeGetDstValue();
7373
7374 if (extra & 0x800) {
7375 /* MULS.L - signed */
7376
7377 si5b src1 = (si5b)srcvalue;
7378 si5b src2 = (si5b)dstvalue;
7379 blnr s1 = src1 < 0;
7380 blnr s2 = src2 < 0;
7381 blnr sr = s1 != s2;
7382
7383 /* ReportAbnormal("MULS.L"); */
7384 /* used by Sys 7.5.5 boot extensions */
7385 if (s1) {
7386 src1 = - src1;
7387 }
7388 if (s2) {
7389 src2 = - src2;
7390 }
7391 mul_unsigned((ui5b)src1, (ui5b)src2, &dst);
7392 if (sr) {
7393 Ui6r_Negate(&dst);
7394 }
7395 VFLG = CFLG = 0;
7396 ZFLG = Bool2Bit(Ui6r_IsZero(&dst));
7397 NFLG = Bool2Bit(Ui6r_IsNeg(&dst));
7398
7399 V_regs.LazyFlagKind = kLazyFlagsDefault;
7400
7401 if (extra & 0x400) {
7402 m68k_dreg(extra & 7) = dst.hi;
7403 } else {
7404 if ((dst.lo & 0x80000000) != 0) {
7405 if ((dst.hi & 0xffffffff) != 0xffffffff) {
7406 VFLG = 1;
7407 }
7408 } else {
7409 if (dst.hi != 0) {
7410 VFLG = 1;
7411 }
7412 }
7413 }
7414 } else {
7415 /* MULU.L - unsigned */
7416
7417 /* ReportAbnormal("MULU.U"); */
7418 /* Used by various Apps */
7419
7420 mul_unsigned(srcvalue, dstvalue, &dst);
7421
7422 VFLG = CFLG = 0;
7423 ZFLG = Bool2Bit(Ui6r_IsZero(&dst));
7424 NFLG = Bool2Bit(Ui6r_IsNeg(&dst));
7425
7426 V_regs.LazyFlagKind = kLazyFlagsDefault;
7427
7428 if (extra & 0x400) {
7429 m68k_dreg(extra & 7) = dst.hi;
7430 } else {
7431 if (dst.hi != 0) {
7432 VFLG = 1;
7433 }
7434 }
7435 }
7436 m68k_dreg(r2) = dst.lo;
7437}
7438#endif
7439
7440#if Use68020
7441LOCALIPROC DoCodeDivL(void)
7442{
7443 /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
7444 /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
7445 /* ReportAbnormal("DIVS/DIVU long"); */
7446 ui6r0 v2;
7447 ui5b quot;
7448 ui5b rem;
7449 ui4b extra = nextiword();
7450 ui5b rDr = extra & 7;
7451 ui5b rDq = (extra >> 12) & 7;
7452 ui5r src = (ui5b)(si5b)DecodeGetDstValue();
7453
7454 if (src == 0) {
7455 Exception(5);
7456#if m68k_logExceptions
7457 dbglog_WriteNote("*** zero devide exception");
7458#endif
7459 return;
7460 }
7461 if (0 != (extra & 0x0800)) {
7462 /* signed variant */
7463 blnr sr;
7464 blnr s2;
7465 blnr s1 = ((si5b)src < 0);
7466
7467 v2.lo = (si5b)m68k_dreg(rDq);
7468 if (extra & 0x0400) {
7469 v2.hi = (si5b)m68k_dreg(rDr);
7470 } else {
7471 v2.hi = ((si5b)v2.lo) < 0 ? -1 : 0;
7472 }
7473 s2 = Ui6r_IsNeg(&v2);
7474 sr = (s1 != s2);
7475 if (s2) {
7476 Ui6r_Negate(&v2);
7477 }
7478 if (s1) {
7479 src = - src;
7480 }
7481 if (div_unsigned(&v2, src, ", &rem)
7482 || (sr ? quot > 0x80000000 : quot > 0x7fffffff))
7483 {
7484 NeedDefaultLazyAllFlags();
7485
7486 VFLG = NFLG = 1;
7487 CFLG = 0;
7488 } else {
7489 if (sr) {
7490 quot = - quot;
7491 }
7492 if (((si5b)rem < 0) != s2) {
7493 rem = - rem;
7494 }
7495 VFLG = CFLG = 0;
7496 ZFLG = Bool2Bit(((si5b)quot) == 0);
7497 NFLG = Bool2Bit(((si5b)quot) < 0);
7498
7499 V_regs.LazyFlagKind = kLazyFlagsDefault;
7500
7501 m68k_dreg(rDr) = rem;
7502 m68k_dreg(rDq) = quot;
7503 }
7504 } else {
7505 /* unsigned */
7506
7507 v2.lo = (ui5b)m68k_dreg(rDq);
7508 if (extra & 0x400) {
7509 v2.hi = (ui5b)m68k_dreg(rDr);
7510 } else {
7511 v2.hi = 0;
7512 }
7513 if (div_unsigned(&v2, src, ", &rem)) {
7514 NeedDefaultLazyAllFlags();
7515
7516 VFLG = NFLG = 1;
7517 CFLG = 0;
7518 } else {
7519 VFLG = CFLG = 0;
7520 ZFLG = Bool2Bit(((si5b)quot) == 0);
7521 NFLG = Bool2Bit(((si5b)quot) < 0);
7522
7523 V_regs.LazyFlagKind = kLazyFlagsDefault;
7524
7525 m68k_dreg(rDr) = rem;
7526 m68k_dreg(rDq) = quot;
7527 }
7528 }
7529}
7530#endif
7531
7532#if Use68020
7533LOCALIPROC DoMoveToControl(void)
7534{
7535 if (0 == V_regs.s) {
7536 DoPrivilegeViolation();
7537 } else {
7538 ui4b src = nextiword_nm();
7539 int regno = (src >> 12) & 0x0F;
7540 ui5b v = V_regs.regs[regno];
7541
7542 switch (src & 0x0FFF) {
7543 case 0x0000:
7544 V_regs.sfc = v & 7;
7545 /* ReportAbnormal("DoMoveToControl: sfc"); */
7546 /* happens on entering macsbug */
7547 break;
7548 case 0x0001:
7549 V_regs.dfc = v & 7;
7550 /* ReportAbnormal("DoMoveToControl: dfc"); */
7551 break;
7552 case 0x0002:
7553 V_regs.cacr = v & 0x3;
7554 /* ReportAbnormal("DoMoveToControl: cacr"); */
7555 /* used by Sys 7.5.5 boot */
7556 break;
7557 case 0x0800:
7558 V_regs.usp = v;
7559 ReportAbnormalID(0x0113, "DoMoveToControl: usp");
7560 break;
7561 case 0x0801:
7562 V_regs.vbr = v;
7563 /* ReportAbnormal("DoMoveToControl: vbr"); */
7564 /* happens on entering macsbug */
7565 break;
7566 case 0x0802:
7567 V_regs.caar = v &0xfc;
7568 /* ReportAbnormal("DoMoveToControl: caar"); */
7569 /* happens on entering macsbug */
7570 break;
7571 case 0x0803:
7572 V_regs.msp = v;
7573 if (V_regs.m == 1) {
7574 m68k_areg(7) = V_regs.msp;
7575 }
7576 /* ReportAbnormal("DoMoveToControl: msp"); */
7577 /* happens on entering macsbug */
7578 break;
7579 case 0x0804:
7580 V_regs.isp = v;
7581 if (V_regs.m == 0) {
7582 m68k_areg(7) = V_regs.isp;
7583 }
7584 ReportAbnormalID(0x0114, "DoMoveToControl: isp");
7585 break;
7586 default:
7587 op_illg();
7588 ReportAbnormalID(0x0115,
7589 "DoMoveToControl: unknown reg");
7590 break;
7591 }
7592 }
7593}
7594#endif
7595
7596#if Use68020
7597LOCALIPROC DoMoveFromControl(void)
7598{
7599 if (0 == V_regs.s) {
7600 DoPrivilegeViolation();
7601 } else {
7602 ui5b v;
7603 ui4b src = nextiword_nm();
7604 int regno = (src >> 12) & 0x0F;
7605
7606 switch (src & 0x0FFF) {
7607 case 0x0000:
7608 v = V_regs.sfc;
7609 /* ReportAbnormal("DoMoveFromControl: sfc"); */
7610 /* happens on entering macsbug */
7611 break;
7612 case 0x0001:
7613 v = V_regs.dfc;
7614 /* ReportAbnormal("DoMoveFromControl: dfc"); */
7615 /* happens on entering macsbug */
7616 break;
7617 case 0x0002:
7618 v = V_regs.cacr;
7619 /* ReportAbnormal("DoMoveFromControl: cacr"); */
7620 /* used by Sys 7.5.5 boot */
7621 break;
7622 case 0x0800:
7623 v = V_regs.usp;
7624 ReportAbnormalID(0x0116, "DoMoveFromControl: usp");
7625 break;
7626 case 0x0801:
7627 v = V_regs.vbr;
7628 /* ReportAbnormal("DoMoveFromControl: vbr"); */
7629 /* happens on entering macsbug */
7630 break;
7631 case 0x0802:
7632 v = V_regs.caar;
7633 /* ReportAbnormal("DoMoveFromControl: caar"); */
7634 /* happens on entering macsbug */
7635 break;
7636 case 0x0803:
7637 v = (V_regs.m == 1)
7638 ? m68k_areg(7)
7639 : V_regs.msp;
7640 /* ReportAbnormal("DoMoveFromControl: msp"); */
7641 /* happens on entering macsbug */
7642 break;
7643 case 0x0804:
7644 v = (V_regs.m == 0)
7645 ? m68k_areg(7)
7646 : V_regs.isp;
7647 ReportAbnormalID(0x0117, "DoMoveFromControl: isp");
7648 break;
7649 default:
7650 v = 0;
7651 ReportAbnormalID(0x0118,
7652 "DoMoveFromControl: unknown reg");
7653 op_illg();
7654 break;
7655 }
7656 V_regs.regs[regno] = v;
7657 }
7658}
7659#endif
7660
7661#if Use68020
7662LOCALIPROC DoCodeBkpt(void)
7663{
7664 /* BKPT 0100100001001rrr */
7665 ReportAbnormalID(0x0119, "BKPT instruction");
7666 op_illg();
7667}
7668#endif
7669
7670#if Use68020
7671LOCALIPROC DoCodeRtd(void)
7672{
7673 /* Rtd 0100111001110100 */
7674 ui5r NewPC = get_long(m68k_areg(7));
7675 si5b offs = nextiSWord();
7676 /* ReportAbnormal("RTD"); */
7677 /* used by Sys 7.5.5 boot */
7678 m68k_areg(7) += (4 + offs);
7679 m68k_setpc(NewPC);
7680}
7681#endif
7682
7683#if Use68020
7684LOCALIPROC DoCodeLinkL(void)
7685{
7686 /* Link.L 0100100000001rrr */
7687
7688 ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
7689 ui5r *dstp = &V_regs.regs[dstreg];
7690 CPTR stackp = m68k_areg(7);
7691
7692 ReportAbnormalID(0x011A, "Link.L");
7693
7694 stackp -= 4;
7695 m68k_areg(7) = stackp; /* only matters if dstreg == 7 + 8 */
7696 put_long(stackp, *dstp);
7697 *dstp = stackp;
7698 m68k_areg(7) += (si5b)nextilong();
7699}
7700#endif
7701
7702#if Use68020
7703LOCALPROC DoCodeTRAPcc_t(void)
7704{
7705 ReportAbnormalID(0x011B, "TRAPcc trapping");
7706 Exception(7);
7707 /* pc pushed onto stack wrong */
7708}
7709#endif
7710
7711#if Use68020
7712LOCALPROC DoCodeTRAPcc_f(void)
7713{
7714}
7715#endif
7716
7717#if Use68020
7718LOCALIPROC DoCodeTRAPcc(void)
7719{
7720 /* TRAPcc 0101cccc11111sss */
7721 /* ReportAbnormal("TRAPcc"); */
7722 switch (V_regs.CurDecOpY.v[1].ArgDat) {
7723 case 2:
7724 ReportAbnormalID(0x011C, "TRAPcc word data");
7725 SkipiWord();
7726 break;
7727 case 3:
7728 ReportAbnormalID(0x011D, "TRAPcc long data");
7729 SkipiLong();
7730 break;
7731 case 4:
7732 /* ReportAbnormal("TRAPcc no data"); */
7733 /* no optional data */
7734 break;
7735 default:
7736 ReportAbnormalID(0x011E, "TRAPcc illegal format");
7737 op_illg();
7738 break;
7739 }
7740 cctrue(DoCodeTRAPcc_t, DoCodeTRAPcc_f);
7741}
7742#endif
7743
7744#if Use68020
7745LOCALIPROC DoCodePack(void)
7746{
7747 ui5r offs = nextiSWord();
7748 ui5r val = DecodeGetSrcValue();
7749
7750 ReportAbnormalID(0x011F, "PACK");
7751
7752 val += offs;
7753 val = ((val >> 4) & 0xf0) | (val & 0xf);
7754
7755 DecodeSetDstValue(val);
7756}
7757#endif
7758
7759#if Use68020
7760LOCALIPROC DoCodeUnpk(void)
7761{
7762 ui5r offs = nextiSWord();
7763 ui5r val = DecodeGetSrcValue();
7764
7765 ReportAbnormalID(0x0120, "UNPK");
7766
7767 val = (((val & 0xF0) << 4) | (val & 0x0F)) + offs;
7768
7769 DecodeSetDstValue(val);
7770}
7771#endif
7772
7773#if Use68020
7774LOCALIPROC DoBitField(void)
7775{
7776 ui5b tmp;
7777 ui5b newtmp;
7778 CPTR dsta;
7779 ui5b bf0;
7780 ui3b bf1;
7781 ui5b dstreg = V_regs.CurDecOpY.v[1].ArgDat;
7782 ui4b extra = nextiword();
7783 ui5b offset = ((extra & 0x0800) != 0)
7784 ? m68k_dreg((extra >> 6) & 7)
7785 : ((extra >> 6) & 0x1f);
7786 ui5b width = ((extra & 0x0020) != 0)
7787 ? m68k_dreg(extra & 7)
7788 : extra;
7789 ui3b bfa[5];
7790 ui5b offwid;
7791
7792 /* ReportAbnormal("Bit Field operator"); */
7793 /* width = ((width - 1) & 0x1f) + 1; */ /* 0 -> 32 */
7794 width &= 0x001F; /* except width == 0 really means 32 */
7795 if (V_regs.CurDecOpY.v[0].AMd == 0) {
7796 bf0 = m68k_dreg(dstreg);
7797 offset &= 0x1f;
7798 tmp = bf0;
7799 if (0 != offset) {
7800 tmp = (tmp << offset) | (tmp >> (32 - offset));
7801 }
7802 } else {
7803 /*
7804 V_regs.ArgKind == AKMemory,
7805 otherwise illegal and don't get here
7806 */
7807 dsta = DecodeDst();
7808 dsta += Ui5rASR(offset, 3);
7809 offset &= 7;
7810 offwid = offset + ((width == 0) ? 32 : width);
7811
7812 /* if (offwid > 0) */ {
7813 bf1 = get_byte(dsta);
7814 bfa[0] = bf1;
7815 tmp = ((ui5b)bf1) << (24 + offset);
7816 }
7817 if (offwid > 8) {
7818 bf1 = get_byte(dsta + 1);
7819 bfa[1] = bf1;
7820 tmp |= ((ui5b)bf1) << (16 + offset);
7821 }
7822 if (offwid > 16) {
7823 bf1 = get_byte(dsta + 2);
7824 bfa[2] = bf1;
7825 tmp |= ((ui5r)bf1) << (8 + offset);
7826 }
7827 if (offwid > 24) {
7828 bf1 = get_byte(dsta + 3);
7829 bfa[3] = bf1;
7830 tmp |= ((ui5r)bf1) << (offset);
7831 }
7832 if (offwid > 32) {
7833 bf1 = get_byte(dsta + 4);
7834 bfa[4] = bf1;
7835 tmp |= ((ui5r)bf1) >> (8 - offset);
7836 }
7837 }
7838
7839 NFLG = Bool2Bit(((si5b)tmp) < 0);
7840 if (width != 0) {
7841 tmp >>= (32 - width);
7842 }
7843 ZFLG = (tmp == 0);
7844 VFLG = 0;
7845 CFLG = 0;
7846
7847 V_regs.LazyFlagKind = kLazyFlagsDefault;
7848
7849 newtmp = tmp;
7850
7851 switch (V_regs.CurDecOpY.v[0].ArgDat) {
7852 case 0: /* BFTST */
7853 /* do nothing */
7854 break;
7855 case 1: /* BFEXTU */
7856 m68k_dreg((extra >> 12) & 7) = tmp;
7857 break;
7858 case 2: /* BFCHG */
7859 newtmp = ~ newtmp;
7860 if (width != 0) {
7861 newtmp &= ((1 << width) - 1);
7862 }
7863 break;
7864 case 3: /* BFEXTS */
7865 if (NFLG != 0) {
7866 m68k_dreg((extra >> 12) & 7) = tmp
7867 | ((width == 0) ? 0 : (-1 << width));
7868 } else {
7869 m68k_dreg((extra >> 12) & 7) = tmp;
7870 }
7871 break;
7872 case 4: /* BFCLR */
7873 newtmp = 0;
7874 break;
7875 case 5: /* BFFFO */
7876 {
7877 ui5b mask = 1 << ((width == 0) ? 31 : (width - 1));
7878 ui5r i = offset;
7879
7880 while ((0 != mask) && (0 == (tmp & mask))) {
7881 mask >>= 1;
7882 i++;
7883 }
7884 m68k_dreg((extra >> 12) & 7) = i;
7885 }
7886 break;
7887 case 6: /* BFSET */
7888 newtmp = (width == 0) ? ~ 0 : ((1 << width) - 1);
7889 break;
7890 case 7: /* BFINS */
7891 newtmp = m68k_dreg((extra >> 12) & 7);
7892 if (width != 0) {
7893 newtmp &= ((1 << width) - 1);
7894 }
7895
7896 /*
7897 flags set from new value
7898 unlike BFSET/BFCLR/BFCHG
7899 */
7900 {
7901 ui5b t = newtmp;
7902
7903 if (width != 0) {
7904 t <<= (32 - width);
7905 }
7906
7907 NFLG = Bool2Bit(((si5b)t) < 0);
7908 ZFLG = (0 == t);
7909 }
7910 break;
7911 }
7912
7913 if (newtmp != tmp) {
7914
7915 if (width != 0) {
7916 newtmp <<= (32 - width);
7917 }
7918
7919 if (V_regs.CurDecOpY.v[0].AMd == 0) {
7920 ui5b mask = ~ 0;
7921
7922 if (width != 0) {
7923 mask <<= (32 - width);
7924 }
7925
7926 if (0 != offset) {
7927 newtmp = (newtmp >> offset) | (newtmp << (32 - offset));
7928 mask = (mask >> offset) | (mask << (32 - offset));
7929 }
7930
7931 bf0 = (bf0 & ~ mask) | (newtmp);
7932 m68k_dreg(dstreg) = bf0;
7933 } else {
7934
7935 /* if (offwid > 0) */ {
7936 ui3b mask = ~ (0xFF >> offset);
7937
7938 bf1 = newtmp >> (24 + offset);
7939 if (offwid < 8) {
7940 mask |= (0xFF >> offwid);
7941 }
7942 if (mask != 0) {
7943 bf1 |= bfa[0] & mask;
7944 }
7945 put_byte(dsta + 0, bf1);
7946 }
7947 if (offwid > 8) {
7948 bf1 = newtmp >> (16 + offset);
7949 if (offwid < 16) {
7950 bf1 |= (bfa[1] & (0xFF >> (offwid - 8)));
7951 }
7952 put_byte(dsta + 1, bf1);
7953 }
7954 if (offwid > 16) {
7955 bf1 = newtmp >> (8 + offset);
7956 if (offwid < 24) {
7957 bf1 |= (bfa[2] & (0xFF >> (offwid - 16)));
7958 }
7959 put_byte(dsta + 2, bf1);
7960 }
7961 if (offwid > 24) {
7962 bf1 = newtmp >> (offset);
7963 if (offwid < 32) {
7964 bf1 |= (bfa[3] & (0xFF >> (offwid - 24)));
7965 }
7966 put_byte(dsta + 3, bf1);
7967 }
7968 if (offwid > 32) {
7969 bf1 = newtmp << (8 - offset);
7970 bf1 |= (bfa[4] & (0xFF >> (offwid - 32)));
7971 put_byte(dsta + 4, bf1);
7972 }
7973 }
7974 }
7975}
7976#endif
7977
7978#if EmMMU | EmFPU
7979LOCALFUNC blnr DecodeModeRegister(ui5b sz)
7980{
7981 blnr IsOk;
7982 ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
7983 ui4r themode = (Dat >> 3) & 7;
7984 ui4r thereg = Dat & 7;
7985
7986 switch (themode) {
7987 case 0 :
7988 V_regs.ArgKind = AKRegister;
7989 V_regs.ArgAddr.rga = &V_regs.regs[thereg];
7990 IsOk = trueblnr;
7991 break;
7992 case 1 :
7993 V_regs.ArgKind = AKRegister;
7994 V_regs.ArgAddr.rga = &V_regs.regs[thereg + 8];
7995 IsOk = trueblnr;
7996 break;
7997 case 2 :
7998 V_regs.ArgKind = AKMemory;
7999 V_regs.ArgAddr.mem = m68k_areg(thereg);
8000 IsOk = trueblnr;
8001 break;
8002 case 3 :
8003 V_regs.ArgKind = AKMemory;
8004 V_regs.ArgAddr.mem = m68k_areg(thereg);
8005 if ((thereg == 7) && (sz == 1)) {
8006 m68k_areg(thereg) += 2;
8007 } else {
8008 m68k_areg(thereg) += sz;
8009 }
8010 IsOk = trueblnr;
8011 break;
8012 case 4 :
8013 V_regs.ArgKind = AKMemory;
8014 if ((thereg == 7) && (sz == 1)) {
8015 m68k_areg(thereg) -= 2;
8016 } else {
8017 m68k_areg(thereg) -= sz;
8018 }
8019 V_regs.ArgAddr.mem = m68k_areg(thereg);
8020 IsOk = trueblnr;
8021 break;
8022 case 5 :
8023 V_regs.ArgKind = AKMemory;
8024 V_regs.ArgAddr.mem = m68k_areg(thereg)
8025 + nextiSWord();
8026 IsOk = trueblnr;
8027 break;
8028 case 6 :
8029 V_regs.ArgKind = AKMemory;
8030 V_regs.ArgAddr.mem = get_disp_ea(m68k_areg(thereg));
8031 IsOk = trueblnr;
8032 break;
8033 case 7 :
8034 switch (thereg) {
8035 case 0 :
8036 V_regs.ArgKind = AKMemory;
8037 V_regs.ArgAddr.mem = nextiSWord();
8038 IsOk = trueblnr;
8039 break;
8040 case 1 :
8041 V_regs.ArgKind = AKMemory;
8042 V_regs.ArgAddr.mem = nextilong();
8043 IsOk = trueblnr;
8044 break;
8045 case 2 :
8046 V_regs.ArgKind = AKMemory;
8047 V_regs.ArgAddr.mem = m68k_getpc();
8048 V_regs.ArgAddr.mem += nextiSWord();
8049 IsOk = trueblnr;
8050 break;
8051 case 3 :
8052 V_regs.ArgKind = AKMemory;
8053 V_regs.ArgAddr.mem = get_disp_ea(m68k_getpc());
8054 IsOk = trueblnr;
8055 break;
8056 case 4 :
8057 V_regs.ArgKind = AKMemory;
8058 V_regs.ArgAddr.mem = m68k_getpc();
8059 if (sz == 1) {
8060 ++V_regs.ArgAddr.mem;
8061 }
8062 m68k_setpc(V_regs.ArgAddr.mem + sz);
8063 IsOk = trueblnr;
8064 break;
8065 default:
8066 IsOk = falseblnr;
8067 break;
8068 }
8069 break;
8070 default:
8071 IsOk = falseblnr;
8072 break;
8073 }
8074
8075 return IsOk;
8076}
8077#endif
8078
8079#if EmMMU | EmFPU
8080LOCALFUNC ui5r GetArgValueL(void)
8081{
8082 ui5r v;
8083
8084 if (AKMemory == V_regs.ArgKind) {
8085 v = get_long(V_regs.ArgAddr.mem);
8086 } else {
8087 /* must be AKRegister */
8088 v = ui5r_FromSLong(*V_regs.ArgAddr.rga);
8089 }
8090
8091 return v;
8092}
8093#endif
8094
8095#if EmMMU | EmFPU
8096LOCALFUNC ui5r GetArgValueW(void)
8097{
8098 ui5r v;
8099
8100 if (AKMemory == V_regs.ArgKind) {
8101 v = get_word(V_regs.ArgAddr.mem);
8102 } else {
8103 /* must be AKRegister */
8104 v = ui5r_FromSWord(*V_regs.ArgAddr.rga);
8105 }
8106
8107 return v;
8108}
8109#endif
8110
8111#if EmMMU | EmFPU
8112LOCALFUNC ui5r GetArgValueB(void)
8113{
8114 ui5r v;
8115
8116 if (AKMemory == V_regs.ArgKind) {
8117 v = get_byte(V_regs.ArgAddr.mem);
8118 } else {
8119 /* must be AKRegister */
8120 v = ui5r_FromSByte(*V_regs.ArgAddr.rga);
8121 }
8122
8123 return v;
8124}
8125#endif
8126
8127#if EmMMU | EmFPU
8128LOCALPROC SetArgValueL(ui5r v)
8129{
8130 if (AKMemory == V_regs.ArgKind) {
8131 put_long(V_regs.ArgAddr.mem, v);
8132 } else {
8133 /* must be AKRegister */
8134 *V_regs.ArgAddr.rga = v;
8135 }
8136}
8137#endif
8138
8139#if EmMMU | EmFPU
8140LOCALPROC SetArgValueW(ui5r v)
8141{
8142 if (AKMemory == V_regs.ArgKind) {
8143 put_word(V_regs.ArgAddr.mem, v);
8144 } else {
8145 /* must be AKRegister */
8146 *V_regs.ArgAddr.rga =
8147 (*V_regs.ArgAddr.rga & ~ 0xffff) | ((v) & 0xffff);
8148 }
8149}
8150#endif
8151
8152#if EmMMU | EmFPU
8153LOCALPROC SetArgValueB(ui5r v)
8154{
8155 if (AKMemory == V_regs.ArgKind) {
8156 put_byte(V_regs.ArgAddr.mem, v);
8157 } else {
8158 /* must be AKRegister */
8159 *V_regs.ArgAddr.rga =
8160 (*V_regs.ArgAddr.rga & ~ 0xff) | ((v) & 0xff);
8161 }
8162}
8163#endif
8164
8165
8166#if EmMMU
8167LOCALIPROC DoCodeMMU(void)
8168{
8169 /*
8170 Emulate enough of MMU for System 7.5.5 universal
8171 to boot on Mac Plus 68020. There is one
8172 spurious "PMOVE TC, (A0)".
8173 And implement a few more PMOVE operations seen
8174 when running Disk Copy 6.3.3 and MacsBug.
8175 */
8176 ui4r opcode = ((ui4r)(V_regs.CurDecOpY.v[0].AMd) << 8)
8177 | V_regs.CurDecOpY.v[0].ArgDat;
8178 if (opcode == 0xF010) {
8179 ui4b ew = (int)nextiword_nm();
8180 if (ew == 0x4200) {
8181 /* PMOVE TC, (A0) */
8182 /* fprintf(stderr, "0xF010 0x4200\n"); */
8183 if (DecodeModeRegister(4)) {
8184 SetArgValueL(0);
8185 return;
8186 }
8187 } else if ((ew == 0x4E00) || (ew == 0x4A00)) {
8188 /* PMOVE CRP, (A0) and PMOVE SRP, (A0) */
8189 /* fprintf(stderr, "0xF010 %x\n", ew); */
8190 if (DecodeModeRegister(4)) {
8191 SetArgValueL(0x7FFF0001);
8192 V_regs.ArgAddr.mem += 4;
8193 SetArgValueL(0);
8194 return;
8195 }
8196 } else if (ew == 0x6200) {
8197 /* PMOVE MMUSR, (A0) */
8198 /* fprintf(stderr, "0xF010 %x\n", ew); */
8199 if (DecodeModeRegister(2)) {
8200 SetArgValueW(0);
8201 return;
8202 }
8203 }
8204 /* fprintf(stderr, "extensions %x\n", ew); */
8205 BackupPC();
8206 }
8207 /* fprintf(stderr, "opcode %x\n", (int)opcode); */
8208 ReportAbnormalID(0x0121, "MMU op");
8209 DoCodeFdefault();
8210}
8211#endif
8212
8213#if EmFPU
8214
8215#include "FPMATHEM.h"
8216#include "FPCPEMDV.h"
8217
8218#endif
8219
8220#if HaveGlbReg
8221LOCALPROC Em_Swap(void)
8222{
8223#ifdef r_pc_p
8224 {
8225 ui3p t = g_pc_p;
8226 g_pc_p = regs.pc_p;
8227 regs.pc_p = t;
8228 }
8229#endif
8230#ifdef r_MaxCyclesToGo
8231 {
8232 si5rr t = g_MaxCyclesToGo;
8233 g_MaxCyclesToGo = regs.MaxCyclesToGo;
8234 regs.MaxCyclesToGo = t;
8235 }
8236#endif
8237#ifdef r_pc_pHi
8238 {
8239 ui3p t = g_pc_pHi;
8240 g_pc_pHi = regs.pc_pHi;
8241 regs.pc_pHi = t;
8242 }
8243#endif
8244#ifdef r_regs
8245 {
8246 struct regstruct *t = g_regs;
8247 g_regs = regs.save_regs;
8248 regs.save_regs = t;
8249 }
8250#endif
8251}
8252#endif
8253
8254#if HaveGlbReg
8255#define Em_Enter Em_Swap
8256#else
8257#define Em_Enter()
8258#endif
8259
8260#if HaveGlbReg
8261#define Em_Exit Em_Swap
8262#else
8263#define Em_Exit()
8264#endif
8265
8266#if HaveGlbReg
8267LOCALFUNC blnr LocalMemAccessNtfy(ATTep pT)
8268{
8269 blnr v;
8270
8271 Em_Exit();
8272 v = MemAccessNtfy(pT);
8273 Em_Enter();
8274
8275 return v;
8276}
8277#else
8278#define LocalMemAccessNtfy MemAccessNtfy
8279#endif
8280
8281#if HaveGlbReg
8282LOCALFUNC ui5b LocalMMDV_Access(ATTep p, ui5b Data,
8283 blnr WriteMem, blnr ByteSize, CPTR addr)
8284{
8285 ui5b v;
8286
8287 Em_Exit();
8288 v = MMDV_Access(p, Data, WriteMem, ByteSize, addr);
8289 Em_Enter();
8290
8291 return v;
8292}
8293#else
8294#define LocalMMDV_Access MMDV_Access
8295#endif
8296
8297LOCALPROC local_customreset(void)
8298{
8299 Em_Exit();
8300 customreset();
8301 Em_Enter();
8302}
8303
8304LOCALFUNC ATTep LocalFindATTel(CPTR addr)
8305{
8306 ATTep prev;
8307 ATTep p;
8308
8309 p = V_regs.HeadATTel;
8310 if ((addr & p->cmpmask) != p->cmpvalu) {
8311 do {
8312 prev = p;
8313 p = p->Next;
8314 } while ((addr & p->cmpmask) != p->cmpvalu);
8315
8316 {
8317 ATTep next = p->Next;
8318
8319 if (nullpr == next) {
8320 /* don't move the end guard */
8321 } else {
8322 /* move to first */
8323 prev->Next = next;
8324 p->Next = V_regs.HeadATTel;
8325 V_regs.HeadATTel = p;
8326 }
8327 }
8328 }
8329
8330 return p;
8331}
8332
8333LOCALPROC SetUpMATC(
8334 MATCp CurMATC,
8335 ATTep p)
8336{
8337 CurMATC->cmpmask = p->cmpmask;
8338 CurMATC->usemask = p->usemask;
8339 CurMATC->cmpvalu = p->cmpvalu;
8340 CurMATC->usebase = p->usebase;
8341}
8342
8343LOCALFUNC ui5r my_reg_call get_byte_ext(CPTR addr)
8344{
8345 ATTep p;
8346 ui3p m;
8347 ui5r AccFlags;
8348 ui5r Data;
8349
8350Label_Retry:
8351 p = LocalFindATTel(addr);
8352 AccFlags = p->Access;
8353
8354 if (0 != (AccFlags & kATTA_readreadymask)) {
8355 SetUpMATC(&V_regs.MATCrdB, p);
8356 m = p->usebase + (addr & p->usemask);
8357
8358 Data = *m;
8359 } else if (0 != (AccFlags & kATTA_mmdvmask)) {
8360 Data = LocalMMDV_Access(p, 0, falseblnr, trueblnr, addr);
8361 } else if (0 != (AccFlags & kATTA_ntfymask)) {
8362 if (LocalMemAccessNtfy(p)) {
8363 goto Label_Retry;
8364 } else {
8365 Data = 0; /* fail */
8366 }
8367 } else {
8368 Data = 0; /* fail */
8369 }
8370
8371 return ui5r_FromSByte(Data);
8372}
8373
8374LOCALPROC my_reg_call put_byte_ext(CPTR addr, ui5r b)
8375{
8376 ATTep p;
8377 ui3p m;
8378 ui5r AccFlags;
8379
8380Label_Retry:
8381 p = LocalFindATTel(addr);
8382 AccFlags = p->Access;
8383
8384 if (0 != (AccFlags & kATTA_writereadymask)) {
8385 SetUpMATC(&V_regs.MATCwrB, p);
8386 m = p->usebase + (addr & p->usemask);
8387 *m = b;
8388 } else if (0 != (AccFlags & kATTA_mmdvmask)) {
8389 (void) LocalMMDV_Access(p, b & 0x00FF,
8390 trueblnr, trueblnr, addr);
8391 } else if (0 != (AccFlags & kATTA_ntfymask)) {
8392 if (LocalMemAccessNtfy(p)) {
8393 goto Label_Retry;
8394 } else {
8395 /* fail */
8396 }
8397 } else {
8398 /* fail */
8399 }
8400}
8401
8402LOCALFUNC ui5r my_reg_call get_word_ext(CPTR addr)
8403{
8404 ui5r Data;
8405
8406 if (0 != (addr & 0x01)) {
8407 ui5r hi = get_byte(addr);
8408 ui5r lo = get_byte(addr + 1);
8409 Data = ((hi << 8) & 0x0000FF00)
8410 | (lo & 0x000000FF);
8411 } else {
8412 ATTep p;
8413 ui3p m;
8414 ui5r AccFlags;
8415
8416Label_Retry:
8417 p = LocalFindATTel(addr);
8418 AccFlags = p->Access;
8419
8420 if (0 != (AccFlags & kATTA_readreadymask)) {
8421 SetUpMATC(&V_regs.MATCrdW, p);
8422 V_regs.MATCrdW.cmpmask |= 0x01;
8423 m = p->usebase + (addr & p->usemask);
8424 Data = do_get_mem_word(m);
8425 } else if (0 != (AccFlags & kATTA_mmdvmask)) {
8426 Data = LocalMMDV_Access(p, 0, falseblnr, falseblnr, addr);
8427 } else if (0 != (AccFlags & kATTA_ntfymask)) {
8428 if (LocalMemAccessNtfy(p)) {
8429 goto Label_Retry;
8430 } else {
8431 Data = 0; /* fail */
8432 }
8433 } else {
8434 Data = 0; /* fail */
8435 }
8436 }
8437
8438 return ui5r_FromSWord(Data);
8439}
8440
8441LOCALPROC my_reg_call put_word_ext(CPTR addr, ui5r w)
8442{
8443 if (0 != (addr & 0x01)) {
8444 put_byte(addr, w >> 8);
8445 put_byte(addr + 1, w);
8446 } else {
8447 ATTep p;
8448 ui3p m;
8449 ui5r AccFlags;
8450
8451Label_Retry:
8452 p = LocalFindATTel(addr);
8453 AccFlags = p->Access;
8454
8455 if (0 != (AccFlags & kATTA_writereadymask)) {
8456 SetUpMATC(&V_regs.MATCwrW, p);
8457 V_regs.MATCwrW.cmpmask |= 0x01;
8458 m = p->usebase + (addr & p->usemask);
8459 do_put_mem_word(m, w);
8460 } else if (0 != (AccFlags & kATTA_mmdvmask)) {
8461 (void) LocalMMDV_Access(p, w & 0x0000FFFF,
8462 trueblnr, falseblnr, addr);
8463 } else if (0 != (AccFlags & kATTA_ntfymask)) {
8464 if (LocalMemAccessNtfy(p)) {
8465 goto Label_Retry;
8466 } else {
8467 /* fail */
8468 }
8469 } else {
8470 /* fail */
8471 }
8472 }
8473}
8474
8475LOCALFUNC ui5r my_reg_call get_long_misaligned_ext(CPTR addr)
8476{
8477 ui5r hi = get_word(addr);
8478 ui5r lo = get_word(addr + 2);
8479 ui5r Data = ((hi << 16) & 0xFFFF0000)
8480 | (lo & 0x0000FFFF);
8481
8482 return ui5r_FromSLong(Data);
8483}
8484
8485LOCALPROC my_reg_call put_long_misaligned_ext(CPTR addr, ui5r l)
8486{
8487 put_word(addr, l >> 16);
8488 put_word(addr + 2, l);
8489}
8490
8491#if FasterAlignedL
8492LOCALFUNC ui5r my_reg_call get_long_ext(CPTR addr)
8493{
8494 ui5r Data;
8495
8496 if (0 != (addr & 0x03)) {
8497 ui5r hi = get_word(addr);
8498 ui5r lo = get_word(addr + 2);
8499 Data = ((hi << 16) & 0xFFFF0000)
8500 | (lo & 0x0000FFFF);
8501 } else {
8502 ATTep p;
8503 ui3p m;
8504 ui5r AccFlags;
8505
8506Label_Retry:
8507 p = LocalFindATTel(addr);
8508 AccFlags = p->Access;
8509
8510 if (0 != (AccFlags & kATTA_readreadymask)) {
8511 SetUpMATC(&V_regs.MATCrdL, p);
8512 V_regs.MATCrdL.cmpmask |= 0x03;
8513 m = p->usebase + (addr & p->usemask);
8514 Data = do_get_mem_long(m);
8515 } else if (0 != (AccFlags & kATTA_mmdvmask)) {
8516 ui5r hi = LocalMMDV_Access(p, 0,
8517 falseblnr, falseblnr, addr);
8518 ui5r lo = LocalMMDV_Access(p, 0,
8519 falseblnr, falseblnr, addr + 2);
8520 Data = ((hi << 16) & 0xFFFF0000)
8521 | (lo & 0x0000FFFF);
8522 } else if (0 != (AccFlags & kATTA_ntfymask)) {
8523 if (LocalMemAccessNtfy(p)) {
8524 goto Label_Retry;
8525 } else {
8526 Data = 0; /* fail */
8527 }
8528 } else {
8529 Data = 0; /* fail */
8530 }
8531 }
8532
8533 return ui5r_FromSLong(Data);
8534}
8535#endif
8536
8537#if FasterAlignedL
8538LOCALPROC my_reg_call put_long_ext(CPTR addr, ui5r l)
8539{
8540 if (0 != (addr & 0x03)) {
8541 put_word(addr, l >> 16);
8542 put_word(addr + 2, l);
8543 } else {
8544 ATTep p;
8545 ui3p m;
8546 ui5r AccFlags;
8547
8548Label_Retry:
8549 p = LocalFindATTel(addr);
8550 AccFlags = p->Access;
8551
8552 if (0 != (AccFlags & kATTA_writereadymask)) {
8553 SetUpMATC(&V_regs.MATCwrL, p);
8554 V_regs.MATCwrL.cmpmask |= 0x03;
8555 m = p->usebase + (addr & p->usemask);
8556 do_put_mem_long(m, l);
8557 } else if (0 != (AccFlags & kATTA_mmdvmask)) {
8558 (void) LocalMMDV_Access(p, (l >> 16) & 0x0000FFFF,
8559 trueblnr, falseblnr, addr);
8560 (void) LocalMMDV_Access(p, l & 0x0000FFFF,
8561 trueblnr, falseblnr, addr + 2);
8562 } else if (0 != (AccFlags & kATTA_ntfymask)) {
8563 if (LocalMemAccessNtfy(p)) {
8564 goto Label_Retry;
8565 } else {
8566 /* fail */
8567 }
8568 } else {
8569 /* fail */
8570 }
8571 }
8572}
8573#endif
8574
8575LOCALPROC Recalc_PC_Block(void)
8576{
8577 ATTep p;
8578 CPTR curpc = m68k_getpc();
8579
8580Label_Retry:
8581 p = LocalFindATTel(curpc);
8582 if (my_cond_rare(0 == (p->Access & kATTA_readreadymask))) {
8583 if (0 != (p->Access & kATTA_ntfymask)) {
8584 if (LocalMemAccessNtfy(p)) {
8585 goto Label_Retry;
8586 }
8587 }
8588 /* in trouble if get here */
8589#if ExtraAbnormalReports
8590 ReportAbnormalID(0x0122, "Recalc_PC_Block fails");
8591 /* happens on Restart */
8592#endif
8593
8594 V_regs.pc_pLo = V_regs.fakeword;
8595 V_pc_p = V_regs.pc_pLo;
8596 V_pc_pHi = V_regs.pc_pLo + 2;
8597 V_regs.pc = curpc;
8598 } else {
8599 ui5r m2 = p->usemask & ~ p->cmpmask;
8600 m2 = m2 & ~ (m2 + 1);
8601
8602 V_pc_p = p->usebase + (curpc & p->usemask);
8603 V_regs.pc_pLo = V_pc_p - (curpc & m2);
8604 V_pc_pHi = V_regs.pc_pLo + m2 + 1;
8605 V_regs.pc = curpc - (V_pc_p - V_regs.pc_pLo);
8606 }
8607}
8608
8609LOCALFUNC ui5r my_reg_call Recalc_PC_BlockReturnUi5r(ui5r v)
8610{
8611 /*
8612 Used to prevent compiler from saving
8613 register on the stack in calling
8614 functions, when Recalc_PC_Block isn't being called.
8615 */
8616 Recalc_PC_Block();
8617
8618 return v;
8619}
8620
8621LOCALFUNC ui5r nextilong_ext(void)
8622{
8623 ui5r r;
8624
8625 V_pc_p -= 4;
8626
8627 {
8628 ui5r hi = nextiword();
8629 ui5r lo = nextiword();
8630 r = ((hi << 16) & 0xFFFF0000)
8631 | (lo & 0x0000FFFF);
8632 }
8633
8634 return r;
8635}
8636
8637LOCALPROC DoCheckExternalInterruptPending(void)
8638{
8639 ui3r level = *V_regs.fIPL;
8640 if ((level > V_regs.intmask) || (level == 7)) {
8641#if WantCloserCyc
8642 V_MaxCyclesToGo -=
8643 (44 * kCycleScale + 5 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
8644#endif
8645 Exception(24 + level);
8646 V_regs.intmask = level;
8647 }
8648}
8649
8650LOCALPROC do_trace(void)
8651{
8652 V_regs.TracePending = trueblnr;
8653 NeedToGetOut();
8654}
8655
8656GLOBALPROC m68k_go_nCycles(ui5b n)
8657{
8658 Em_Enter();
8659 V_MaxCyclesToGo += (n + V_regs.ResidualCycles);
8660 while (V_MaxCyclesToGo > 0) {
8661
8662#if 0
8663 if (V_regs.ResetPending) {
8664 m68k_DoReset();
8665 }
8666#endif
8667 if (V_regs.TracePending) {
8668#if WantCloserCyc
8669 V_MaxCyclesToGo -= (34 * kCycleScale
8670 + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
8671#endif
8672 Exception(9);
8673 }
8674 if (V_regs.ExternalInterruptPending) {
8675 V_regs.ExternalInterruptPending = falseblnr;
8676 DoCheckExternalInterruptPending();
8677 }
8678 if (V_regs.t1 != 0) {
8679 do_trace();
8680 }
8681 m68k_go_MaxCycles();
8682 V_MaxCyclesToGo += V_regs.MoreCyclesToGo;
8683 V_regs.MoreCyclesToGo = 0;
8684 }
8685
8686 V_regs.ResidualCycles = V_MaxCyclesToGo;
8687 V_MaxCyclesToGo = 0;
8688 Em_Exit();
8689}
8690
8691GLOBALFUNC si5r GetCyclesRemaining(void)
8692{
8693 si5r v;
8694
8695 Em_Enter();
8696 v = V_regs.MoreCyclesToGo + V_MaxCyclesToGo;
8697 Em_Exit();
8698
8699 return v;
8700}
8701
8702GLOBALPROC SetCyclesRemaining(si5r n)
8703{
8704 Em_Enter();
8705
8706 if (V_MaxCyclesToGo >= n) {
8707 V_regs.MoreCyclesToGo = 0;
8708 V_MaxCyclesToGo = n;
8709 } else {
8710 V_regs.MoreCyclesToGo = n - V_MaxCyclesToGo;
8711 }
8712
8713 Em_Exit();
8714}
8715
8716GLOBALFUNC ATTep FindATTel(CPTR addr)
8717{
8718 ATTep v;
8719
8720 Em_Enter();
8721 v = LocalFindATTel(addr);
8722 Em_Exit();
8723
8724 return v;
8725}
8726
8727GLOBALFUNC ui3r get_vm_byte(CPTR addr)
8728{
8729 ui3r v;
8730
8731 Em_Enter();
8732 v = (ui3b) get_byte(addr);
8733 Em_Exit();
8734
8735 return v;
8736}
8737
8738GLOBALFUNC ui4r get_vm_word(CPTR addr)
8739{
8740 ui4r v;
8741
8742 Em_Enter();
8743 v = (ui4b) get_word(addr);
8744 Em_Exit();
8745
8746 return v;
8747}
8748
8749GLOBALFUNC ui5r get_vm_long(CPTR addr)
8750{
8751 ui5r v;
8752
8753 Em_Enter();
8754 v = (ui5b) get_long(addr);
8755 Em_Exit();
8756
8757 return v;
8758}
8759
8760GLOBALPROC put_vm_byte(CPTR addr, ui3r b)
8761{
8762 Em_Enter();
8763 put_byte(addr, ui5r_FromSByte(b));
8764 Em_Exit();
8765}
8766
8767GLOBALPROC put_vm_word(CPTR addr, ui4r w)
8768{
8769 Em_Enter();
8770 put_word(addr, ui5r_FromSWord(w));
8771 Em_Exit();
8772}
8773
8774GLOBALPROC put_vm_long(CPTR addr, ui5r l)
8775{
8776 Em_Enter();
8777 put_long(addr, ui5r_FromSLong(l));
8778 Em_Exit();
8779}
8780
8781GLOBALPROC SetHeadATTel(ATTep p)
8782{
8783 Em_Enter();
8784
8785 V_regs.MATCrdB.cmpmask = 0;
8786 V_regs.MATCrdB.cmpvalu = 0xFFFFFFFF;
8787 V_regs.MATCwrB.cmpmask = 0;
8788 V_regs.MATCwrB.cmpvalu = 0xFFFFFFFF;
8789 V_regs.MATCrdW.cmpmask = 0;
8790 V_regs.MATCrdW.cmpvalu = 0xFFFFFFFF;
8791 V_regs.MATCwrW.cmpmask = 0;
8792 V_regs.MATCwrW.cmpvalu = 0xFFFFFFFF;
8793#if FasterAlignedL
8794 V_regs.MATCrdL.cmpmask = 0;
8795 V_regs.MATCrdL.cmpvalu = 0xFFFFFFFF;
8796 V_regs.MATCwrL.cmpmask = 0;
8797 V_regs.MATCwrL.cmpvalu = 0xFFFFFFFF;
8798#endif
8799 /* force Recalc_PC_Block soon */
8800 V_regs.pc = m68k_getpc();
8801 V_regs.pc_pLo = V_pc_p;
8802 V_pc_pHi = V_regs.pc_pLo + 2;
8803 V_regs.HeadATTel = p;
8804
8805 Em_Exit();
8806}
8807
8808GLOBALPROC DiskInsertedPsuedoException(CPTR newpc, ui5b data)
8809{
8810 Em_Enter();
8811 ExceptionTo(newpc
8812#if Use68020
8813 , 0
8814#endif
8815 );
8816 m68k_areg(7) -= 4;
8817 put_long(m68k_areg(7), data);
8818 Em_Exit();
8819}
8820
8821GLOBALPROC m68k_IPLchangeNtfy(void)
8822{
8823 Em_Enter();
8824 {
8825 ui3r level = *V_regs.fIPL;
8826
8827 if ((level > V_regs.intmask) || (level == 7)) {
8828 SetExternalInterruptPending();
8829 }
8830 }
8831 Em_Exit();
8832}
8833
8834#if WantDumpTable
8835LOCALPROC InitDumpTable(void)
8836{
8837 si5b i;
8838
8839 for (i = 0; i < kNumIKinds; ++i) {
8840 DumpTable[i] = 0;
8841 }
8842}
8843
8844LOCALPROC DumpATable(ui5b *p, ui5b n)
8845{
8846 si5b i;
8847
8848 for (i = 0; i < n; ++i) {
8849 dbglog_writeNum(p[i]);
8850 dbglog_writeReturn();
8851 }
8852}
8853
8854EXPORTPROC DoDumpTable(void);
8855GLOBALPROC DoDumpTable(void)
8856{
8857 DumpATable(DumpTable, kNumIKinds);
8858}
8859#endif
8860
8861GLOBALPROC m68k_reset(void)
8862{
8863 Em_Enter();
8864
8865#if WantDumpTable
8866 InitDumpTable();
8867#endif
8868 V_MaxCyclesToGo = 0;
8869 V_regs.MoreCyclesToGo = 0;
8870 V_regs.ResidualCycles = 0;
8871 V_pc_p = (ui3p)nullpr;
8872 V_pc_pHi = (ui3p)nullpr;
8873 V_regs.pc_pLo = (ui3p)nullpr;
8874
8875 do_put_mem_word(V_regs.fakeword, 0x4AFC);
8876 /* illegal instruction opcode */
8877
8878#if 0
8879 V_regs.ResetPending = trueblnr;
8880 NeedToGetOut();
8881#else
8882/* Sets the MC68000 reset jump vector... */
8883 m68k_setpc(get_long(0x00000004));
8884
8885/* Sets the initial stack vector... */
8886 m68k_areg(7) = get_long(0x00000000);
8887
8888 V_regs.s = 1;
8889#if Use68020
8890 V_regs.m = 0;
8891 V_regs.t0 = 0;
8892#endif
8893 V_regs.t1 = 0;
8894 ZFLG = CFLG = NFLG = VFLG = 0;
8895
8896 V_regs.LazyFlagKind = kLazyFlagsDefault;
8897 V_regs.LazyXFlagKind = kLazyFlagsDefault;
8898
8899 V_regs.ExternalInterruptPending = falseblnr;
8900 V_regs.TracePending = falseblnr;
8901 V_regs.intmask = 7;
8902
8903#if Use68020
8904 V_regs.sfc = 0;
8905 V_regs.dfc = 0;
8906 V_regs.vbr = 0;
8907 V_regs.cacr = 0;
8908 V_regs.caar = 0;
8909#endif
8910#endif
8911
8912 Em_Exit();
8913}
8914
8915#if SmallGlobals
8916GLOBALPROC MINEM68K_ReserveAlloc(void)
8917{
8918 ReserveAllocOneBlock((ui3p *)®s.disp_table,
8919 disp_table_sz * 8, 6, falseblnr);
8920}
8921#endif
8922
8923GLOBALPROC MINEM68K_Init(
8924 ui3b *fIPL)
8925{
8926 regs.fIPL = fIPL;
8927#ifdef r_regs
8928 regs.save_regs = ®s;
8929#endif
8930
8931 M68KITAB_setup(regs.disp_table);
8932}