initial import
[picodrive.git] / cpu / a68k / make68kd.c
1 /*---------------------------------------------------------------\r
2  * Motorola 68000 32 Bit emulator\r
3  *\r
4  * Copyright 1998-2001 Mike Coates,     All rights reserved\r
5  *                                                      Darren Olafson\r
6  *---------------------------------------------------------------\r
7  *\r
8  * Thanks to ...\r
9  *\r
10  * Neil Bradley  (lots of optimisation help & ideas)\r
11  *\r
12  *---------------------------------------------------------------\r
13  * History (so we know what bugs have been fixed)\r
14  *\r
15  * 02.11.98 MJC - CMPM bug, overwriting first value\r
16  * 04.11.98 MJC - Debug timing - same as C core\r
17  *                                              save PC on calls to C memory routines\r
18  * 05.11.98 NS   - Re-insert changes to make work on OS/2\r
19  * 06.11.98 MJC - Flags saved on ADDA commands\r
20  *                                              X set on ADD commands\r
21  * 23.11.98 MJC - Alternate Memory Read/Write for non DOS ports\r
22  * 24.11.98 CK   - Add WIN32 specific stuff\r
23  * 25.11.98 DEO - ABCD Size not initialised\r
24  * 21.12.98 MJC - Change register saving on Memory Banking\r
25  * 13.01.99 M/D - Change to new C core disassembler\r
26  * 19.01.99 MJC - Proper? support for new Interrupt System\r
27  * 17.02.99 MJC - TRACE68K define added\r
28  *                ABCD,SBCD not keeping Z flag\r
29  *                JMP, JSR for some EA combo's damaging flags\r
30  *                DIVU - Overflow not being set correctly\r
31  *                ASL/ASR - Flag Handling now correct\r
32  *                some minor optimisations\r
33  * 13.03.99 DEO - Added new cycle timing\r
34  * 24.03.99 MJC - TRACE68K define removed\r
35  *                NEW INTERRUPT SYSTEM only\r
36  *                interrupt check sped up (when not taken)\r
37  *                STOP checks for interrupt\r
38  * 01.04.99 MJC - OS2 specifics added\r
39  *                MOVEM reference point moved\r
40  *                Data and Address register mode combined for :-\r
41  *                                              movecodes\r
42  *                dumpx\r
43  * 04.05.99 MJC - Add Previous PC support to MOVE.B #X,XXXXXX.L (F1 Dream)\r
44  *                ABCD/SBCD could corrupt zero flag\r
45  *                DIVS/DIVU overflow should not update register\r
46  * 22.05.99 MJC - Complete support of Previous PC on C calls\r
47  *                Some optional bits now selected by DEFINES\r
48  * 27.05.99 MJC - Interrupt system changed\r
49  * 28.05.99 MJC - Use DEFINES in more places\r
50  *                Interrupt check running one opcode when taken\r
51  * 16.07.99 MJC - Reset - Preload next opcode / external call\r
52  *                68010 commands almost complete\r
53  *                more compression on jump table (16k smaller)\r
54  *                Some optimising\r
55  *                                                shl reg,1 -> add reg,reg\r
56  *                  or ecx,ecx:jz -> jecxz\r
57  * 22.08.99 DEO - SBCD/ABCD sets N flag same as carry\r
58  * 19.10.99 MJC - Change DOS memory routines\r
59  *                Change DOS Clobber flags (ESI no longer safe)\r
60  *                Save EAX around memory write where needed\r
61  *                bit commands optimised\r
62  * 25.10.99  MJC  - Was keeping masked register on read/write\r
63  *                if register was preserved over call\r
64  *                ESI assumed 'safe' again\r
65  * 25.10.99  MJC  - Bank ID moved to CPU context\r
66  * 03.11.99 KENJO - VC++6.0 seems not to preserve EDI. Fixed "ABCD -(A0), -(A0)" crash / "roxr (A0)"-type shift crash\r
67  * 13.11.99 KENJO - Fixed "NABC"\r
68  *                Now Win32 uses FASTCALL type call for interrupt callback\r
69  * 09.02.00  MJC  - Check CPU type before allowing 68010/68020 instructions\r
70  *                remove routines for 5 non existant opcodes\r
71  * 05.03.00  MJC  - not command decrement A7 by 1 for bytes\r
72  * 10.03.00  MJC  - as did btst,cmpm and nbcd\r
73  * 22.03.00  MJC  - Divide by zero should not decrement PC by 2 before push\r
74  *                Move memory banking into exception routine\r
75  * 14.04.00 Dave  - BTST missing Opcode\r
76  *                ASL.L > 31 shift\r
77  * 20.04.00  MJC  - TST.B Also missing A7 specific routine\r
78  *                - Extra Define A7ROUTINE to switch between having seperate\r
79  *                routines for +-(A7) address modes.\r
80  * 24.06.00  MJC  - ADDX/SUBX +-(A7) routines added.\r
81  *                TAS should not touch X flag\r
82  *                LSL/LSR EA not clearing V flag\r
83  *                CHK not all opcodes in jump table\r
84  *                Add define to mask status register\r
85  * 04.07.00  MJC  - Keep high byte of Program Counter on Bxx and Jxx\r
86  *                Fix flag handling on NEGX\r
87  *                Really fix ADDX/SUBX +-(A7)\r
88  *                PC could be set wrong after CHK.W instruction\r
89  *                DIVS/DIVU always clear C flag\r
90  *                ABCD/SBCD missing +-(A7) Routine\r
91  *                TAS missing +-(A7) Routine\r
92  *                Bitwise Static missing +-(A7) Routine\r
93  *                CMPM missing +-(A7) Routine\r
94  * 30.09.00 DEO - added mull, divl, bfextu\r
95  *                added '020 addressing modes\r
96  *                fixed $6xff branching\r
97  * 23.01.01 MJC - Spits out seperate code for 68000 & 68020\r
98  *                allows seperate optimising!\r
99  * 17.02.01 MJC - Support for encrypted PC relative fetch calls\r
100  * 11.03.01 GUTI  - change some cmp reg,0 and or reg,reg with test\r
101  * 13.03.01 MJC - Single Icount for Asm & C cores\r
102  * 16.05.01 ASG - use push/pop around mem calls instead of store to safe_REG\r
103  *                optimized a bit the 020 extension word decoder\r
104  *                removed lots of unnecessary code in branches\r
105  *---------------------------------------------------------------\r
106  * Known Problems / Bugs\r
107  *\r
108  * 68000\r
109  * None - Let us know if you find any!\r
110  *\r
111  * 68010\r
112  * Instructions that are supervisor only as per 68000 spec.\r
113  * move address space not implemented.\r
114  *\r
115  * 68020\r
116  * only long Bcc instruction implemented.\r
117  *---------------------------------------------------------------\r
118  * Notes\r
119  *\r
120  * STALLCHECK should be defined for Pentium Class\r
121  *                                                       undefined for P2/Celerons\r
122  *\r
123  * ALIGNMENT is normally 4, but seems faster on my P2 as 0 !\r
124  *\r
125  *---------------------------------------------------------------\r
126  *\r
127  * Future Changes\r
128  *\r
129  * 68020 instructions to be completed\r
130  * assembler memory routines                                                                                            +\r
131  *\r
132  * and anything else that takes our fancy!\r
133  *---------------------------------------------------------------*/\r
134 \r
135 /* Specials - Switch what program allows/disallows */\r
136 \r
137 #undef  STALLCHECK              /* Affects fetching of Opcode */\r
138 #undef  SAVEPPC     /* Save Previous PC */ // dave \r
139 #define ENCRYPTED               /* PC relative = decrypted */\r
140 #define ASMBANK     /* Memory banking algorithm to use */ // dave\r
141 #define A7ROUTINE               /* Define to use separate routines for -(a7)/(a7)+ */\r
142 #define ALIGNMENT 4             /* Alignment to use for branches */\r
143 #undef  MASKCCR                 /* Mask the status register to filter out unused bits */\r
144 #define KEEPHIGHPC              /* Keep or Ignore bits 24-31 */\r
145 #define QUICKZERO               /* selects XOR r,r or MOV r,0 */\r
146 \r
147 #include <stdio.h>\r
148 #include <stdlib.h>\r
149 #include <string.h>\r
150 #include <assert.h>\r
151 \r
152 /* New Disassembler */\r
153 \r
154 char *  codebuf;\r
155 int             DisOp;\r
156 \r
157 #define cpu_readmem24bew(addr)                  (0)\r
158 #define cpu_readmem24bew_word(addr)             (DisOp)\r
159 \r
160 #define MEMORY_H        /* so memory.h will not be included... */\r
161 /*\r
162 #include "d68k.c"\r
163 */\r
164 #undef MEMORY_H\r
165 \r
166 #undef cpu_readmem24bew\r
167 #undef cpu_readmem24bew_word\r
168 \r
169 #include "cpuintrf.h"\r
170 \r
171 /*\r
172  * Defines used by Program\r
173  *\r
174  */\r
175 \r
176 #define VERSION  "0.30"\r
177 \r
178 #define TRUE -1\r
179 #define FALSE 0\r
180 \r
181 #define EAX 0\r
182 #define EBX 1\r
183 #define ECX 2\r
184 #define EDX 3\r
185 #define ESI 4\r
186 #define PC  ESI\r
187 #define EDI 5\r
188 #define EBP 6\r
189 \r
190 \r
191 #define NORMAL 0\r
192 #define PCREL  1\r
193 \r
194 /* Register Location Offsets */\r
195 \r
196 #define ICOUNT                          "_m68k_ICount"\r
197 \r
198 #define REG_DAT                         "R_D0"\r
199 #define REG_DAT_EBX                     "[R_D0+ebx*4]"\r
200 #define REG_ADD                         "R_A0"\r
201 #define REG_A7                          "R_A7"\r
202 #define REG_USP                         "R_USP"\r
203 #define REG_ISP                         "R_ISP"\r
204 #define REG_SRH                         "R_SR_H"\r
205 #define REG_CCR                         "R_CCR"\r
206 #define REG_X                           "R_XC"\r
207 #define REG_PC                          "R_PC"\r
208 #define REG_IRQ                         "R_IRQ"\r
209 #define REG_S                           "R_SR"\r
210 #define REG_IRQ_CALLBACK        "R_IRQ_CALLBACK"\r
211 #define REG_RESET_CALLBACK      "R_RESET_CALLBACK"\r
212 \r
213 \r
214 /* 68010 Regs */\r
215 \r
216 #define REG_VBR                         "R_VBR"\r
217 #define REG_SFC                         "R_SFC"\r
218 #define REG_DFC                         "R_DFC"\r
219 \r
220 #define FASTCALL_FIRST_REG      "ecx"\r
221 #define FASTCALL_SECOND_REG     "edx"\r
222 \r
223 \r
224 \r
225 /*\r
226  * Global Variables\r
227  *\r
228  */\r
229 \r
230 FILE *fp                        = NULL;\r
231 \r
232 char *comptab           = NULL;\r
233 char *CPUtype           = NULL;\r
234 \r
235 int  CPU                        = 0;\r
236 int  FlagProcess        = 0;\r
237 int  CheckInterrupt = 0;\r
238 int  ExternalIO         = 0;\r
239 int  Opcount            = 0;\r
240 int  TimingCycles       = 0;\r
241 int  AddEACycles        = 0;\r
242 int  AccessType         = NORMAL;\r
243 int  ppro                       = 0;\r
244 \r
245 \r
246 \r
247 /* External register preservation */\r
248 \r
249 #ifdef DOS\r
250 \r
251 /* Registers normally saved around C routines anyway */\r
252 /* GCC 2.9.1 (dos) seems to preserve EBX,EDI and EBP */\r
253 static char SavedRegs[] = "-B--SDB";\r
254 \r
255 #elif defined(WIN32)\r
256 \r
257 /* visual C++, win32, says it preserves ebx, edi, esi, and ebp */\r
258 /* ---------- VC++ deosn't preserve EDI? (Kenjo, 110399) ---------- */\r
259 static char SavedRegs[] = "-B--S-B";\r
260 \r
261 #else\r
262 \r
263 /* Assume nothing preserved */\r
264 static char SavedRegs[] = "-------";\r
265 \r
266 #endif\r
267 \r
268 \r
269 \r
270 /* Jump Table */\r
271 \r
272 int OpcodeArray[65536];\r
273 \r
274 /* Lookup Arrays */\r
275 \r
276 static char* regnameslong[] =\r
277 { "EAX","EBX","ECX","EDX","ESI","EDI","EBP"};\r
278 \r
279 static char* regnamesword[] =\r
280 { "AX","BX","CX","DX", "SI", "DI", "BP"};\r
281 \r
282 static char* regnamesshort[] =\r
283 { "AL","BL","CL","DL"};\r
284 \r
285 \r
286 \r
287 /*********************************/\r
288 /* Conversion / Utility Routines */\r
289 /*********************************/\r
290 \r
291 /* Convert EA to Address Mode Number\r
292  *\r
293  * 0    Dn\r
294  * 1    An\r
295  * 2    (An)\r
296  * 3    (An)+\r
297  * 4    -(An)\r
298  * 5    x(An)\r
299  * 6    x(An,xr.s)\r
300  * 7    x.w\r
301  * 8    x.l\r
302  * 9    x(PC)\r
303  * 10  x(PC,xr.s)\r
304  * 11  #x,SR,CCR                Read = Immediate, Write = SR or CCR\r
305  *                                                       in order to read SR to AX, use READCCR\r
306  * 12-15  INVALID\r
307  *\r
308  * 19  (A7)+\r
309  * 20  -(A7)\r
310  *\r
311  */\r
312 \r
313 int EAtoAMN(int EA, int Way)\r
314 {\r
315         int Work;\r
316 \r
317         if (Way)\r
318         {\r
319                 Work = (EA & 0x7);\r
320 \r
321                 if (Work == 7) Work += ((EA & 0x38) >> 3);\r
322 \r
323                 if (((Work == 3) || (Work == 4)) && (((EA & 0x38) >> 3) == 7))\r
324                 {\r
325                         Work += 16;\r
326                 }\r
327         }\r
328         else\r
329         {\r
330                 Work = (EA & 0x38) >> 3;\r
331 \r
332                 if (Work == 7) Work += (EA & 7);\r
333 \r
334                 if (((Work == 3) || (Work == 4)) && ((EA & 7) == 7))\r
335                 {\r
336                         Work += 16;\r
337                 }\r
338         }\r
339 \r
340         return Work;\r
341 }\r
342 \r
343 /*\r
344  * Generate Main or Sub label\r
345  */\r
346 \r
347 char *GenerateLabel(int ID,int Type)\r
348 {\r
349         static int LabID,LabNum;\r
350 /*\r
351         static char disasm[80];\r
352         char    *dis = disasm;\r
353 */\r
354         if (Type == 0)\r
355         {\r
356                 CheckInterrupt=0;                        /* No need to check for Interrupts */\r
357                 ExternalIO=0;                             /* Not left Assembler Yet */\r
358                 TimingCycles=0;                         /* No timing info for this command */\r
359                 AddEACycles=1;                           /* default to add in EA timing */\r
360                 Opcount++;                                        /* for screen display */\r
361 \r
362                 DisOp = ID;\r
363 /*\r
364                 m68k_disassemble(dis,0);\r
365                 sprintf(codebuf, "OP%d_%4.4x:\t\t\t\t; %s", CPU,ID, dis);\r
366 */\r
367                 sprintf(codebuf, "OP%d_%4.4x:\t\t\t\t;", CPU,ID);\r
368 \r
369                 LabID  = ID;\r
370                 LabNum = 0;\r
371         }\r
372         else\r
373         {\r
374                 LabNum++;\r
375                 sprintf(codebuf, "OP%d_%4.4x_%1x", CPU,LabID, LabNum);\r
376         }\r
377 \r
378         return codebuf;\r
379 }\r
380 \r
381 /*\r
382  * Generate Alignment Line\r
383  */\r
384 \r
385 void Align(void)\r
386 {\r
387         fprintf(fp, "\t\t ALIGN %d\n\n",ALIGNMENT);\r
388 }\r
389 \r
390 /*\r
391  * Copy X into Carry\r
392  *\r
393  * There are several ways this could be done, this allows\r
394  * us to easily change the way we are doing it!\r
395  */\r
396 \r
397 void CopyX(void)\r
398 {\r
399         /* Copy bit 0 from X flag store into Carry */\r
400 \r
401         fprintf(fp, "\t\t bt    dword [%s],0\n",REG_X);\r
402 }\r
403 \r
404 /*\r
405  * Immediate 3 bit data\r
406  *\r
407  * 0=8, anything else is itself\r
408  *\r
409  * Again, several ways to achieve this\r
410  *\r
411  * ECX contains data as 3 lowest bits\r
412  *\r
413  */\r
414 \r
415 void ClearRegister(int regno)\r
416 {\r
417 #ifdef QUICKZERO\r
418         fprintf(fp, "\t\t mov   %s,0\n",regnameslong[regno]);\r
419 #else\r
420         fprintf(fp, "\t\t xor   %s,%s\n",regnameslong[regno],regnameslong[regno]);\r
421 #endif\r
422 }\r
423 \r
424 void Immediate8(void)\r
425 {\r
426         /* This takes 3 cycles, 5 bytes, no memory reads */\r
427 \r
428         fprintf(fp, "\t\t dec   ecx          ; Move range down\n");\r
429         fprintf(fp, "\t\t and   ecx,byte 7   ; Mask out lower bits\n");\r
430         fprintf(fp, "\t\t inc   ecx          ; correct range\n");\r
431 \r
432 \r
433         /* This takes 2 cycles, 10 bytes but has a memory read */\r
434         /* I don't know timing for the mov command - assumed 1 */\r
435 \r
436 #if 0\r
437         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
438         fprintf(fp, "\t\t mov   ecx,[ImmTable+ECX*4]\n");\r
439 #endif\r
440 }\r
441 \r
442 /*\r
443  * This will check for bank changes before\r
444  * resorting to calling the C bank select code\r
445  *\r
446  * Most of the time it does not change!\r
447  *\r
448  */\r
449 \r
450 /* forward used by MemoryBanking */\r
451 void Exception(int Number, int BaseCode) ;\r
452 \r
453 void MemoryBanking(int BaseCode)\r
454 {\r
455         /* check for odd address */\r
456         fprintf(fp, "\t\t test  esi, dword 1\n");\r
457         fprintf(fp, "\t\t jz    near OP%d_%5.5x\n",CPU,BaseCode);\r
458 \r
459         /* trying to run at an odd address */\r
460         Exception(3,BaseCode);\r
461 \r
462         /* Keep Whole PC */\r
463 \r
464         fprintf(fp, "OP%d_%5.5x:\n",CPU,BaseCode);\r
465 \r
466 /* ASG - always call to the changepc subroutine now, since the number of */\r
467 /* bits varies based on the memory model */\r
468 #ifdef KEEPHIGHPC\r
469         fprintf(fp, "\t\t mov   [FullPC],ESI\n");\r
470 #endif\r
471 \r
472         /* Mask to n bits */\r
473         fprintf(fp, "\t\t and   esi,[_mem_amask]\n");\r
474 \r
475 #if 0\r
476 #ifdef KEEPHIGHPC\r
477         fprintf(fp, "\t\t mov   [FullPC],ESI\n");\r
478 #endif\r
479 \r
480         /* Mask to 24 bits */\r
481 //      fprintf(fp, "\t\t and   esi,0ffffffh\n");\r
482 \r
483 #ifdef ASMBANK\r
484         /* Assembler bank switch - 64k granularity */\r
485 \r
486         fprintf(fp, "\t\t mov   eax,esi\n");\r
487         fprintf(fp, "\t\t shr   eax,16\n");\r
488         fprintf(fp, "\t\t cmp   [asmbank],eax\n");\r
489         fprintf(fp, "\t\t je    OP%d_%5.5x_Bank\n",CPU,BaseCode);\r
490 \r
491         fprintf(fp, "\t\t mov   [asmbank],eax\n");\r
492 #else\r
493         /* This code is same as macro used by C core */\r
494 \r
495         fprintf(fp, "\t\t mov   ecx,esi\n");\r
496         fprintf(fp, "\t\t mov   ebx,[_cur_mrhard]\n");\r
497         fprintf(fp, "\t\t shr   ecx,9\n");\r
498         fprintf(fp, "\t\t mov   al,byte [_opcode_entry]\n");\r
499         fprintf(fp, "\t\t cmp   al,[ecx+ebx]\n");\r
500         fprintf(fp, "\t\t je    OP%d_%5.5x_Bank\n",CPU,BaseCode);\r
501 #endif\r
502 #endif\r
503 \r
504         /* Call Banking Routine */\r
505 \r
506         if (SavedRegs[ESI] == '-')\r
507         {\r
508                 fprintf(fp, "\t\t mov   [%s],ESI\n",REG_PC);\r
509         }\r
510 \r
511         if (SavedRegs[EDX] == '-')\r
512         {\r
513                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
514         }\r
515 \r
516 #ifdef FASTCALL\r
517         fprintf(fp, "\t\t mov   %s,esi\n",FASTCALL_FIRST_REG);\r
518 #else\r
519         fprintf(fp, "\t\t push  esi\n");\r
520 #endif\r
521 \r
522         fprintf(fp, "\t\t call  [_a68k_memory_intf+28]\n");\r
523 \r
524 #ifndef FASTCALL\r
525         fprintf(fp, "\t\t lea   esp,[esp+4]\n");\r
526 #endif\r
527 \r
528         if (SavedRegs[EDX] == '-')\r
529         {\r
530                 fprintf(fp, "\t\t mov   edx,[%s]\n",REG_CCR);\r
531         }\r
532 \r
533         if (SavedRegs[ESI] == '-')\r
534         {\r
535                 fprintf(fp, "\t\t mov   esi,[%s]\n",REG_PC);\r
536         }\r
537 \r
538         /* Update our copy */\r
539 \r
540         fprintf(fp, "\t\t mov   ebp,dword [_OP_ROM]\n");\r
541 \r
542         fprintf(fp, "OP%d_%5.5x_Bank:\n",CPU,BaseCode);\r
543 }\r
544 \r
545 /*\r
546  * Update Previous PC value\r
547  *\r
548  */\r
549 \r
550 void SavePreviousPC(void)\r
551 {\r
552 #ifdef SAVEPPC\r
553         fprintf(fp, "\t\t mov   [R_PPC],esi\t\t\t ; Keep Previous PC\n");\r
554 #endif\r
555 }\r
556 \r
557 /*\r
558  * Complete Opcode handling\r
559  *\r
560  * Any tidying up, end code\r
561  *\r
562  */\r
563 \r
564 void Completed(void)\r
565 {\r
566 \r
567         /* Flag Processing to be finished off ? */\r
568 \r
569         AccessType = NORMAL;\r
570 \r
571         /* Use assembler timing routines */\r
572 \r
573         if (TimingCycles != 0)\r
574         {\r
575                 if (TimingCycles > 127)\r
576                         fprintf(fp, "\t\t sub   dword [%s],%d\n",ICOUNT,TimingCycles);\r
577                 else\r
578                 {\r
579                         if (TimingCycles != -1)\r
580                                 fprintf(fp, "\t\t sub   dword [%s],byte %d\n",ICOUNT,TimingCycles);\r
581                 }\r
582                 \r
583                 if (FlagProcess > 0)\r
584                         fprintf(fp, "\t\t pop   EDX\n");\r
585                 if (FlagProcess == 2)\r
586                         fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
587 \r
588                 fprintf(fp, "\t\t js    near MainExit\n\n");\r
589         }\r
590         else\r
591         {\r
592                 fprintf(fp, "\t\t test  dword [%s],0xffffffff\n",ICOUNT);\r
593                 \r
594                 if (FlagProcess > 0)\r
595                         fprintf(fp, "\t\t pop   EDX\n");\r
596                 if (FlagProcess == 2)\r
597                         fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
598 \r
599                 fprintf(fp, "\t\t jle   near MainExit\n\n");\r
600         }\r
601         FlagProcess = 0;\r
602 \r
603 #ifdef MAME_DEBUG\r
604 \r
605         /* Check for Debug Active */\r
606 \r
607         fprintf(fp, "\n\t\t test    byte [_mame_debug],byte 0xff\n");\r
608         fprintf(fp, "\t\t jnz   near MainExit\n\n");\r
609 \r
610 #endif\r
611 \r
612         if (CheckInterrupt)\r
613         {\r
614                 fprintf(fp,"; Check for Interrupt waiting\n\n");\r
615                 fprintf(fp,"\t\t test  byte [%s],07H\n",REG_IRQ);\r
616                 fprintf(fp,"\t\t jne   near interrupt\n\n");\r
617         }\r
618 \r
619         if(CPU==2)\r
620         {\r
621                 /* 32 bit memory version */\r
622                   fprintf(fp, "\t\t mov   eax,2\n");    /* ASG */\r
623                 fprintf(fp, "\t\t xor   eax,esi\n");    /* ASG */\r
624 \r
625 #ifdef STALLCHECK\r
626           ClearRegister(ECX);\r
627                 fprintf(fp, "\t\t mov   cx,[eax+ebp]\n");\r
628 #else\r
629                 fprintf(fp, "\t\t movzx ecx,word [eax+ebp]\n");\r
630 #endif\r
631         }\r
632         else\r
633         {\r
634                 /* 16 bit memory */\r
635 #ifdef STALLCHECK\r
636           ClearRegister(ECX);\r
637                 fprintf(fp, "\t\t mov   cx,[esi+ebp]\n");\r
638 #else\r
639                 fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");\r
640 #endif\r
641         }\r
642 \r
643         fprintf(fp, "\t\t jmp   [%s_OPCODETABLE+ecx*4]\n\n", CPUtype);\r
644 }\r
645 \r
646 /*\r
647  * Flag Routines\r
648  *\r
649  * Size   = B,W or L\r
650  * Sreg   = Register to Test\r
651  * TestReg  = Need to test register (false if flags already set up)\r
652  * SetX   = if C needs to be copied across to X register\r
653  * Delayed  = Delays final processing to end of routine (Completed())\r
654  *\r
655  */\r
656 \r
657 void TestFlags(char Size,int Sreg)\r
658 {\r
659         char* Regname="";\r
660 \r
661         switch (Size)\r
662         {\r
663                 case 66:\r
664                         Regname = regnamesshort[Sreg];\r
665                         break;\r
666 \r
667                 case 87:\r
668                         Regname = regnamesword[Sreg];\r
669                         break;\r
670 \r
671                 case 76:\r
672                         Regname = regnameslong[Sreg];\r
673                         break;\r
674         }\r
675 \r
676         /* Test does not update register         */\r
677         /* so cannot generate partial stall */\r
678 \r
679         fprintf(fp, "\t\t test  %s,%s\n",Regname,Regname);\r
680 }\r
681 \r
682 void SetFlags(char Size,int Sreg,int Testreg,int SetX,int Delayed)\r
683 {\r
684         if (Testreg) TestFlags(Size,Sreg);\r
685 \r
686         fprintf(fp, "\t\t pushfd\n");\r
687 \r
688         if (Delayed)\r
689         {\r
690                 /* Rest of code done by Completed routine */\r
691 \r
692                 if (SetX) FlagProcess = 2;\r
693                 else FlagProcess = 1;\r
694         }\r
695         else\r
696         {\r
697                 fprintf(fp, "\t\t pop   EDX\n");\r
698 \r
699                 if (SetX) fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
700         }\r
701 }\r
702 \r
703 /******************/\r
704 /* Check CPU Type */\r
705 /******************/\r
706 \r
707 void CheckCPUtype(int Minimum)\r
708 {\r
709         if(CPU==2)\r
710         {\r
711                 /* Only check for > 020 */\r
712 \r
713                 if(Minimum>2)\r
714                 {\r
715                         fprintf(fp, "\t\t mov   eax,[CPUversion]\n");\r
716 \r
717                         fprintf(fp, "\t\t cmp   al,%d\n",Minimum);\r
718                         fprintf(fp, "\t\t jb    near ILLEGAL\n\n");\r
719                 }\r
720         }\r
721         else\r
722         {\r
723                 fprintf(fp, "\t\t mov   eax,[CPUversion]\n");\r
724 \r
725                 if (Minimum == 1)\r
726                 {\r
727                         fprintf(fp, "\t\t test  eax,eax\n");\r
728                         fprintf(fp, "\t\t jz    near ILLEGAL\n\n");\r
729                 }\r
730                 else\r
731                 {\r
732                         fprintf(fp, "\t\t cmp   al,%d\n",Minimum);\r
733                         fprintf(fp, "\t\t jb    near ILLEGAL\n\n");\r
734                 }\r
735         }\r
736 }\r
737 \r
738 /************************************/\r
739 /* Pre-increment and Post-Decrement */\r
740 /************************************/\r
741 \r
742 void IncrementEDI(int Size,int Rreg)\r
743 {\r
744         switch (Size)\r
745         {\r
746                 case 66:\r
747 \r
748 #ifdef  A7ROUTINE\r
749 \r
750                         /* Always does Byte Increment - A7 uses special routine */\r
751 \r
752                         fprintf(fp, "\t\t inc   dword [%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);\r
753 \r
754 #else\r
755 \r
756                         /* A7 uses same routines, so inc by 2 if A7 */\r
757 \r
758                         fprintf(fp, "\t\t cmp   %s,7\n",regnamesshort[Rreg]);\r
759                         fprintf(fp, "\t\t cmc\n");\r
760                         fprintf(fp, "\t\t adc   dword [%s+%s*4],byte 1\n",REG_ADD,regnameslong[Rreg]);\r
761 \r
762 #endif\r
763                         break;\r
764 \r
765                 case 87:\r
766 \r
767                         fprintf(fp, "\t\t add   dword [%s+%s*4],byte 2\n",REG_ADD,regnameslong[Rreg]);\r
768                         break;\r
769 \r
770                 case 76:\r
771 \r
772                         fprintf(fp, "\t\t add   dword [%s+%s*4],byte 4\n",REG_ADD,regnameslong[Rreg]);\r
773                         break;\r
774         }\r
775 }\r
776 \r
777 void DecrementEDI(int Size,int Rreg)\r
778 {\r
779         switch (Size)\r
780         {\r
781                 case 66:\r
782 \r
783 #ifdef  A7ROUTINE\r
784 \r
785                         /* Always does Byte Increment - A7 uses special routine */\r
786 \r
787                         fprintf(fp, "\t\t dec   EDI\n");\r
788 \r
789 #else\r
790 \r
791                         /* A7 uses same routines, so dec by 2 if A7 */\r
792 \r
793                         fprintf(fp, "\t\t cmp   %s,7\n",regnamesshort[Rreg]);\r
794                         fprintf(fp, "\t\t cmc\n");\r
795                         fprintf(fp, "\t\t sbb   dword edi,byte 1\n");\r
796 \r
797 #endif\r
798                         break;\r
799 \r
800                 case 87:\r
801 \r
802                         fprintf(fp, "\t\t sub   EDI,byte 2\n");\r
803                         break;\r
804 \r
805                 case 76:\r
806                         fprintf(fp, "\t\t sub   EDI,byte 4\n");\r
807                         break;\r
808         }\r
809 }\r
810 \r
811 /*\r
812  * Generate an exception\r
813  *\r
814  * if Number = -1 then assume value in AL already\r
815  *                                       code must continue running afterwards\r
816  *\r
817  */\r
818 \r
819 void Exception(int Number, int BaseCode)\r
820 {\r
821         if (Number > -1)\r
822         {\r
823                 fprintf(fp, "\t\t sub   esi,byte 2\n");\r
824                 fprintf(fp, "\t\t mov   al,%d\n",Number);\r
825         }\r
826 \r
827         fprintf(fp, "\t\t call  Exception\n\n");\r
828 \r
829         if (Number > -1)\r
830                 Completed();\r
831 }\r
832 \r
833 \r
834 /********************/\r
835 /* Address Routines */\r
836 /********************/\r
837 \r
838 /*\r
839  * Decode Intel flags into AX as SR register\r
840  *\r
841  * Wreg = spare register to use (must not be EAX or EDX)\r
842  */\r
843 \r
844 void ReadCCR(char Size, int Wreg)\r
845 {\r
846         fprintf(fp, "\t\t mov   eax,edx\n");\r
847         fprintf(fp, "\t\t mov   ah,byte [%s]\n",REG_X);\r
848 \r
849         /* Partial stall so .. switch to new bit of processing */\r
850 \r
851         fprintf(fp, "\t\t mov   %s,edx\n",regnameslong[Wreg]);\r
852         fprintf(fp, "\t\t and   %s,byte 1\n",regnameslong[Wreg]);\r
853 \r
854         /* Finish what we started */\r
855 \r
856         fprintf(fp, "\t\t shr   eax,4\n");\r
857         fprintf(fp, "\t\t and   eax,byte 01Ch \t\t; X, N & Z\n\n");\r
858 \r
859         /* and complete second task */\r
860 \r
861         fprintf(fp, "\t\t or    eax,%s \t\t\t\t; C\n\n",regnameslong[Wreg]);\r
862 \r
863         /* and Finally */\r
864 \r
865         fprintf(fp, "\t\t mov   %s,edx\n",regnameslong[Wreg]);\r
866         fprintf(fp, "\t\t shr   %s,10\n",regnameslong[Wreg]);\r
867         fprintf(fp, "\t\t and   %s,byte 2\n",regnameslong[Wreg]);\r
868         fprintf(fp, "\t\t or    eax,%s\t\t\t\t; O\n\n",regnameslong[Wreg]);\r
869 \r
870         if (Size == 'W')\r
871         {\r
872                 fprintf(fp, "\t\t mov   ah,byte [%s] \t; T, S & I\n\n",REG_SRH);\r
873 \r
874 #ifdef MASKCCR\r
875                 fprintf(fp, "\t\t and   ax,0A71Fh\t; Mask unused bits\n");\r
876 #endif\r
877         }\r
878 }\r
879 \r
880 /*\r
881  * Convert SR into Intel flags\r
882  *\r
883  * Also handles change of mode from Supervisor to User\r
884  *\r
885  * n.b. This is also called by EffectiveAddressWrite\r
886  */\r
887 \r
888 void WriteCCR(char Size)\r
889 {\r
890         if (Size == 'W')\r
891         {\r
892                 /* Did we change from Supervisor to User mode ? */\r
893 \r
894                 char *Label = GenerateLabel(0,1);\r
895 \r
896                 fprintf(fp, "\t\t test  ah,20h \t\t\t; User Mode ?\n");\r
897                 fprintf(fp, "\t\t jne   short %s\n\n",Label);\r
898 \r
899                 /* Mode Switch - Update A7 */\r
900 \r
901                 fprintf(fp, "\t\t mov   edx,[%s]\n",REG_A7);\r
902                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_ISP);\r
903                 fprintf(fp, "\t\t mov   edx,[%s]\n",REG_USP);\r
904                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_A7);\r
905 \r
906                 fprintf(fp, "%s:\n",Label);\r
907                 fprintf(fp, "\t\t mov   byte [%s],ah \t;T, S & I\n",REG_SRH);\r
908 \r
909                 /* Mask may now allow Interrupt */\r
910 \r
911                 CheckInterrupt += 1;\r
912         }\r
913 \r
914         /* Flags */\r
915 \r
916         fprintf(fp, "\t\t and   eax,byte 1Fh\n");\r
917         fprintf(fp, "\t\t mov   edx,[IntelFlag+eax*4]\n");\r
918         fprintf(fp, "\t\t mov   [%s],dh\n",REG_X);\r
919         fprintf(fp, "\t\t and   edx,0EFFh\n");\r
920 }\r
921 \r
922 \r
923 /*\r
924  * Interface to Mame memory commands\r
925  *\r
926  * Flags = "ABCDSDB" - set to '-' if not required to preserve\r
927  *                      (order EAX,EBX,ECX,EDX,ESI,EDI,EBP)\r
928  *\r
929  * AReg = Register containing Address\r
930  *\r
931  * Mask 0 : No Masking\r
932  *                1 : Mask top byte, but preserve register\r
933  *                2 : Mask top byte, preserve masked register\r
934  */\r
935 \r
936 void Memory_Read(char Size,int AReg,char *Flags,int Mask)\r
937 {\r
938         ExternalIO = 1;\r
939 \r
940         /* Save PC */\r
941 \r
942         fprintf(fp, "\t\t mov   [%s],ESI\n",REG_PC);\r
943 \r
944         /* Check for special mask condition */\r
945 \r
946         /* ASG - no longer need to mask addresses here */\r
947 /*      if (Mask == 2)\r
948                 fprintf(fp, "\t\t and   %s,0FFFFFFh\n",regnameslong[AReg]);*/\r
949 \r
950         /* Check to see if registers need saving */\r
951 \r
952         if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))\r
953         {\r
954                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
955         }\r
956 \r
957         if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))\r
958         {\r
959                 fprintf(fp, "\t\t push  EBX\n");\r
960         }\r
961 \r
962         if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))\r
963         {\r
964                 fprintf(fp, "\t\t push  ECX\n");\r
965         }\r
966 \r
967         if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))\r
968         {\r
969                 fprintf(fp, "\t\t push  EDI\n");\r
970         }\r
971 \r
972         /* Sort Address out */\r
973 \r
974 #ifdef FASTCALL\r
975 \r
976         fprintf(fp, "\t\t mov   %s,%s\n",FASTCALL_FIRST_REG,regnameslong[AReg]);\r
977 \r
978         /* ASG - no longer need to mask addresses here */\r
979 /*      if (Mask == 1)\r
980                 fprintf(fp, "\t\t and   %s,0FFFFFFh\n",FASTCALL_FIRST_REG);*/\r
981 \r
982 #else\r
983 \r
984         if (Mask == 1)\r
985         {\r
986                 if ((Flags[AReg] != '-') && (SavedRegs[AReg] != '-'))\r
987                 {\r
988                         /* Don't trash a wanted safe register */\r
989 \r
990                         fprintf(fp, "\t\t mov   EAX,%s\n",regnameslong[AReg]);\r
991         /* ASG - no longer need to mask addresses here */\r
992 /*                      fprintf(fp, "\t\t and   EAX,0FFFFFFh\n");*/\r
993                         fprintf(fp, "\t\t push  EAX\n");\r
994                 }\r
995                 else\r
996                 {\r
997         /* ASG - no longer need to mask addresses here */\r
998 /*                      fprintf(fp, "\t\t and   %s,0FFFFFFh\n",regnameslong[AReg]);*/\r
999                         fprintf(fp, "\t\t push  %s\n",regnameslong[AReg]);\r
1000                 }\r
1001         }\r
1002         else\r
1003                 fprintf(fp, "\t\t push  %s\n",regnameslong[AReg]);\r
1004 \r
1005 #endif\r
1006 \r
1007 \r
1008 \r
1009         /* Call Mame memory routine */\r
1010 \r
1011         /* ASG - changed these to call through the function pointers */\r
1012 \r
1013 #ifdef ENCRYPTED\r
1014         switch (AccessType)\r
1015         {\r
1016                   case NORMAL :\r
1017                          switch (Size)\r
1018                          {\r
1019                                  case 66 :\r
1020                                         fprintf(fp, "\t\t call  [_a68k_memory_intf+4]\n");\r
1021                                         break;\r
1022 \r
1023                                  case 87 :\r
1024                                         fprintf(fp, "\t\t call  [_a68k_memory_intf+8]\n");\r
1025                                         break;\r
1026 \r
1027                                  case 76 :\r
1028                                         fprintf(fp, "\t\t call  [_a68k_memory_intf+12]\n");\r
1029                                         break;\r
1030                          }\r
1031                          break;\r
1032 \r
1033                 case PCREL :\r
1034 \r
1035                          switch (Size)\r
1036                          {\r
1037                                  case 66 :\r
1038                                          fprintf(fp, "\t\t call  [_a68k_memory_intf+32]\n");\r
1039                                          break;\r
1040 \r
1041                                  case 87 :\r
1042                                          fprintf(fp, "\t\t call  [_a68k_memory_intf+36]\n");\r
1043                                          break;\r
1044 \r
1045                                  case 76 :\r
1046                                          fprintf(fp, "\t\t call  [_a68k_memory_intf+40]\n");\r
1047                                          break;\r
1048                          }\r
1049                          break;\r
1050         }\r
1051 \r
1052 // AccessType = NORMAL;\r
1053 \r
1054 #else\r
1055 \r
1056         switch (Size)\r
1057         {\r
1058                 case 66 :\r
1059                         fprintf(fp, "\t\t call  [_a68k_memory_intf+4]\n");\r
1060                         break;\r
1061 \r
1062                 case 87 :\r
1063                         fprintf(fp, "\t\t call  [_a68k_memory_intf+8]\n");\r
1064                         break;\r
1065 \r
1066                 case 76 :\r
1067                         fprintf(fp, "\t\t call  [_a68k_memory_intf+12]\n");\r
1068                         break;\r
1069         }\r
1070 #endif\r
1071 \r
1072         /* Correct Stack */\r
1073 \r
1074 #ifndef FASTCALL\r
1075         fprintf(fp, "\t\t lea   esp,[esp+4]\n");\r
1076 #endif\r
1077 \r
1078 \r
1079 \r
1080         /* Restore registers */\r
1081 \r
1082         /* Check to see if registers need restoring */\r
1083 \r
1084         if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))\r
1085         {\r
1086                 fprintf(fp, "\t\t pop   EDI\n");\r
1087         }\r
1088 \r
1089         if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))\r
1090         {\r
1091                 fprintf(fp, "\t\t pop   ECX\n");\r
1092         }\r
1093 \r
1094         if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))\r
1095         {\r
1096                 fprintf(fp, "\t\t pop   EBX\n");\r
1097         }\r
1098 \r
1099         if ((Flags[ESI] != '-') && (SavedRegs[ESI] == '-'))\r
1100         {\r
1101                 fprintf(fp, "\t\t mov   ESI,[%s]\n",REG_PC);\r
1102         }\r
1103 \r
1104         if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))\r
1105         {\r
1106                 fprintf(fp, "\t\t mov   EDX,[%s]\n",REG_CCR);\r
1107         }\r
1108 \r
1109         if ((Flags[EBP] != '-') && (SavedRegs[EBP] == '-'))\r
1110         {\r
1111                 fprintf(fp, "\t\t mov   ebp,dword [_OP_ROM]\n");\r
1112         }\r
1113 }\r
1114 \r
1115 void Memory_Write(char Size,int AReg,int DReg,char *Flags,int Mask)\r
1116 {\r
1117         ExternalIO = 1;\r
1118 \r
1119         /* Save PC */\r
1120 \r
1121         fprintf(fp, "\t\t mov   [%s],ESI\n",REG_PC);\r
1122 \r
1123         /* Check for special mask condition */\r
1124 \r
1125         /* ASG - no longer need to mask addresses here */\r
1126 /*      if (Mask == 2)\r
1127                 fprintf(fp, "\t\t and   %s,0FFFFFFh\n",regnameslong[AReg]);*/\r
1128 \r
1129         /* Check to see if registers need saving */\r
1130 \r
1131         if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))\r
1132         {\r
1133                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
1134         }\r
1135 \r
1136         if ((Flags[EAX] != '-') && (SavedRegs[EAX] == '-'))\r
1137         {\r
1138                 fprintf(fp, "\t\t push  EAX\n");\r
1139         }\r
1140 \r
1141         if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))\r
1142         {\r
1143                 fprintf(fp, "\t\t push  EBX\n");\r
1144         }\r
1145 \r
1146         if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))\r
1147         {\r
1148                 fprintf(fp, "\t\t push  ECX\n");\r
1149         }\r
1150 \r
1151         if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))\r
1152         {\r
1153                 fprintf(fp, "\t\t push  EDI\n");\r
1154         }\r
1155 \r
1156 #ifdef FASTCALL\r
1157 \r
1158         fprintf(fp, "\t\t mov   %s,%s\n",FASTCALL_SECOND_REG,regnameslong[DReg]);\r
1159         fprintf(fp, "\t\t mov   %s,%s\n",FASTCALL_FIRST_REG,regnameslong[AReg]);\r
1160 \r
1161         /* ASG - no longer need to mask addresses here */\r
1162 /*      if (Mask == 1)\r
1163                 fprintf(fp, "\t\t and   %s,0FFFFFFh\n",FASTCALL_FIRST_REG);*/\r
1164 \r
1165 #else\r
1166 \r
1167         fprintf(fp, "\t\t push  %s\n",regnameslong[DReg]);\r
1168 \r
1169         if (Mask == 1)\r
1170         {\r
1171                 if ((Flags[AReg] != '-') && (SavedRegs[AReg] != '-'))\r
1172                 {\r
1173                         /* Don't trash a wanted safe register */\r
1174 \r
1175                         fprintf(fp, "\t\t mov   EAX,%s\n",regnameslong[AReg]);\r
1176         /* ASG - no longer need to mask addresses here */\r
1177 /*                      fprintf(fp, "\t\t and   EAX,0FFFFFFh\n");*/\r
1178                         fprintf(fp, "\t\t push  EAX\n");\r
1179                 }\r
1180                 else\r
1181                 {\r
1182         /* ASG - no longer need to mask addresses here */\r
1183 /*                      fprintf(fp, "\t\t and   %s,0FFFFFFh\n",regnameslong[AReg]);*/\r
1184                         fprintf(fp, "\t\t push  %s\n",regnameslong[AReg]);\r
1185                 }\r
1186         }\r
1187         else\r
1188                 fprintf(fp, "\t\t push  %s\n",regnameslong[AReg]);\r
1189 \r
1190 #endif\r
1191 \r
1192 \r
1193 \r
1194         /* Call Mame Routine */\r
1195 \r
1196         /* ASG - changed these to call through the function pointers */\r
1197         switch (Size)\r
1198         {\r
1199                 case 66 :\r
1200                         fprintf(fp, "\t\t call  [_a68k_memory_intf+16]\n");\r
1201                         break;\r
1202 \r
1203                 case 87 :\r
1204                         fprintf(fp, "\t\t call  [_a68k_memory_intf+20]\n");\r
1205                         break;\r
1206 \r
1207                 case 76 :\r
1208                         fprintf(fp, "\t\t call  [_a68k_memory_intf+24]\n");\r
1209                         break;\r
1210         }\r
1211 \r
1212         /* Correct Stack */\r
1213 \r
1214 #ifndef FASTCALL\r
1215         fprintf(fp, "\t\t lea   esp,[esp+8]\n");\r
1216 #endif\r
1217 \r
1218 \r
1219 \r
1220         /* Restore registers */\r
1221 \r
1222         /* Check to see if registers need restoring */\r
1223 \r
1224         if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))\r
1225         {\r
1226                 fprintf(fp, "\t\t pop   EDI\n");\r
1227         }\r
1228 \r
1229         if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))\r
1230         {\r
1231                 fprintf(fp, "\t\t pop   ECX\n");\r
1232         }\r
1233 \r
1234         if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))\r
1235         {\r
1236                 fprintf(fp, "\t\t pop   EBX\n");\r
1237         }\r
1238 \r
1239         if ((Flags[EAX] != '-') && (SavedRegs[EAX] == '-'))\r
1240         {\r
1241                 fprintf(fp, "\t\t pop   EAX\n");\r
1242         }\r
1243 \r
1244         if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))\r
1245         {\r
1246                 fprintf(fp, "\t\t mov   EDX,[%s]\n",REG_CCR);\r
1247         }\r
1248 \r
1249         if ((Flags[ESI] != '-') && (SavedRegs[ESI] == '-'))\r
1250         {\r
1251                 fprintf(fp, "\t\t mov   ESI,[%s]\n",REG_PC);\r
1252         }\r
1253 \r
1254         if ((Flags[EBP] != '-') && (SavedRegs[EBP] == '-'))\r
1255         {\r
1256                 fprintf(fp, "\t\t mov   ebp,dword [_OP_ROM]\n");\r
1257         }\r
1258 }\r
1259 \r
1260 \r
1261 /*\r
1262  * Fetch data from Code area\r
1263  *\r
1264  * Dreg = Destination Register\r
1265  * Extend = Sign Extend Word to Long\r
1266  *\r
1267  */\r
1268 \r
1269 void Memory_Fetch(char Size,int Dreg,int Extend)\r
1270 {\r
1271         static int loopcount=0;\r
1272 \r
1273         /* Always goes via OP_ROM */\r
1274 \r
1275         if(CPU!=2)\r
1276         {\r
1277                 /* 16 Bit version */\r
1278 \r
1279                 if ((Extend == TRUE) & (Size == 'W'))\r
1280                   fprintf(fp, "\t\t movsx %s,word [esi+ebp]\n",regnameslong[Dreg]);\r
1281                 else if (Size == 'W')\r
1282                   fprintf(fp, "\t\t movzx %s,word [esi+ebp]\n",regnameslong[Dreg]);\r
1283                 else\r
1284                   fprintf(fp, "\t\t mov   %s,dword [esi+ebp]\n",regnameslong[Dreg]);\r
1285 \r
1286                 if (Size == 'L')\r
1287                  fprintf(fp, "\t\t rol   %s,16\n",regnameslong[Dreg]);\r
1288         }\r
1289         else\r
1290         {\r
1291                 /* 32 Bit version */\r
1292 \r
1293                 if (Size == 'W')\r
1294                 {\r
1295                         fprintf(fp, "\t\t mov   %s,esi\n",regnameslong[Dreg]);\r
1296                         fprintf(fp, "\t\t xor   %s,byte 2\n",regnameslong[Dreg]);\r
1297 \r
1298                         if (Extend == TRUE)\r
1299                                 fprintf(fp, "\t\t movsx %s,word [%s+ebp]\n",regnameslong[Dreg],regnameslong[Dreg]);\r
1300                         else\r
1301                                 fprintf(fp, "\t\t movzx %s,word [%s+ebp]\n",regnameslong[Dreg],regnameslong[Dreg]);\r
1302                 }\r
1303                 else\r
1304                 {\r
1305                          // if address is exact multiple of 4, long read will work\r
1306                         // otherwise we need to get words address-2 and address+4\r
1307 \r
1308                         // Always read long\r
1309                  fprintf(fp, "\t\t test  esi,2\n");\r
1310 #if (!ppro)\r
1311                         fprintf(fp, "\t\t mov   %s,dword [esi+ebp]\n",regnameslong[Dreg]);\r
1312 \r
1313                         // OK ?\r
1314                         fprintf(fp, "\t\t jz    short FL%3.3d\n",loopcount+1);\r
1315 \r
1316                         // no, so get high word\r
1317                         fprintf(fp, "\t\t mov   %s,dword [esi+ebp-4]\n",regnameslong[Dreg]);\r
1318                         // and get low word\r
1319                         fprintf(fp, "\t\t mov   %s,word [esi+ebp+4]\n",regnamesword[Dreg]);\r
1320 \r
1321                         fprintf(fp, "FL%3.3d:\n",++loopcount);\r
1322 #else\r
1323                         fprintf(fp, "\t\t cmovnz %s,dword [esi+ebp-4]\n",regnameslong[Dreg]);\r
1324                         fprintf(fp, "\t\t cmovz %s,dword [esi+ebp]\n",regnameslong[Dreg]);\r
1325                         fprintf(fp, "\t\t cmovnz %s,word [esi+ebp+4]\n",regnamesword[Dreg]);\r
1326 #endif\r
1327                 }\r
1328         }\r
1329 }\r
1330 \r
1331 /**********************/\r
1332 /* Push PC onto Stack */\r
1333 /**********************/\r
1334 \r
1335 void PushPC(int Wreg,int Wreg2,char *Flags, int Mask)\r
1336 {\r
1337 \r
1338         /* Wreg2 is only used when high byte is kept  */\r
1339         /* If it is EBP then the register is restored */\r
1340 \r
1341         fprintf(fp, "\t\t mov   %s,[%s]\t ; Push onto Stack\n",regnameslong[Wreg],REG_A7);\r
1342         fprintf(fp, "\t\t sub   %s,byte 4\n",regnameslong[Wreg]);\r
1343         fprintf(fp, "\t\t mov   [%s],%s\n",REG_A7,regnameslong[Wreg]);\r
1344 \r
1345 #ifndef KEEPHIGHPC\r
1346 \r
1347         Memory_Write('L',Wreg,ESI,Flags,Mask);\r
1348 \r
1349 #else\r
1350 \r
1351         fprintf(fp, "\t\t mov   %s,[FullPC]\n",regnameslong[Wreg2]);\r
1352         fprintf(fp, "\t\t and   %s,0xff000000\n",regnameslong[Wreg2]);\r
1353         fprintf(fp, "\t\t or    %s,ESI\n",regnameslong[Wreg2]);\r
1354 \r
1355         Memory_Write('L',Wreg,Wreg2,Flags,Mask);\r
1356 \r
1357         if (Wreg2 == EBP)\r
1358         {\r
1359                 fprintf(fp, "\t\t mov   ebp,dword [_OP_ROM]\n");\r
1360         }\r
1361 \r
1362 #endif\r
1363 }\r
1364 \r
1365 void ExtensionDecode(int SaveEDX)\r
1366 {\r
1367         char *Label = GenerateLabel(0,1);\r
1368 \r
1369         if (SaveEDX)\r
1370                 fprintf(fp, "\t\t push  edx\n");\r
1371 \r
1372         Memory_Fetch('W',EAX,FALSE);\r
1373         fprintf(fp, "\t\t add   esi,byte 2\n");\r
1374 \r
1375         if(CPU!=2)\r
1376         {\r
1377                 /* 68000 Extension */\r
1378 \r
1379                 fprintf(fp, "\t\t mov   edx,eax\n");\r
1380                 fprintf(fp, "\t\t shr   eax,12\n");\r
1381                 fprintf(fp, "\t\t test  edx,0x0800\n");\r
1382                 fprintf(fp, "\t\t mov   eax,[%s+eax*4]\n",REG_DAT);\r
1383                 fprintf(fp, "\t\t jnz   short %s\n",Label);\r
1384                 fprintf(fp, "\t\t cwde\n");\r
1385                 fprintf(fp, "%s:\n",Label);\r
1386                 fprintf(fp, "\t\t lea   edi,[edi+eax]\n");\r
1387                 fprintf(fp, "\t\t movsx edx,dl\n");\r
1388                 fprintf(fp, "\t\t lea   edi,[edi+edx]\n");\r
1389         }\r
1390         else\r
1391         {\r
1392                   /* 68020 Extension */\r
1393 \r
1394                 // eax holds scaled index\r
1395 \r
1396                 // might be faster just to push all regs\r
1397                 fprintf(fp, "\t\t push  ebx\n");\r
1398                 fprintf(fp, "\t\t push  ecx\n");\r
1399 \r
1400                 // copies for later use\r
1401                 fprintf(fp, "\t\t mov   ecx,eax\n");\r
1402                 fprintf(fp, "\t\t mov   edx,eax\n");\r
1403 \r
1404                 // check E bit to see if displacement or full format\r
1405                 fprintf(fp, "\t\t test  edx,0x0100\n");\r
1406                 fprintf(fp, "\t\t jz   short %s_a\n",Label);\r
1407                 // full mode so check IS (index supress)\r
1408                 fprintf(fp, "\t\t test  edx,0x0040\n");\r
1409                 fprintf(fp, "\t\t jz   short %s_b\n",Label);\r
1410                 // set index to 0, it's not added\r
1411                 ClearRegister(EAX);\r
1412                 fprintf(fp, "\t\t jmp  short %s_d\n",Label);  // near\r
1413 \r
1414                 // add displacement\r
1415   fprintf(fp, "%s_a:\n",Label);\r
1416                 fprintf(fp, "\t\t movsx eax,al\n");\r
1417                 fprintf(fp, "\t\t lea   edi,[edi+eax]\n");\r
1418 \r
1419   fprintf(fp, "%s_b:\n",Label);\r
1420                 // calc index always scale (68k will scale by 1)\r
1421                 fprintf(fp, "\t\t mov   eax,edx\n");\r
1422                 fprintf(fp, "\t\t shr   eax,12\n");\r
1423                 fprintf(fp, "\t\t test  edx,0x0800\n");\r
1424                 fprintf(fp, "\t\t mov   eax,[%s+eax*4]\n",REG_DAT);\r
1425                 fprintf(fp, "\t\t jnz   short %s_c\n",Label);\r
1426                 fprintf(fp, "\t\t cwde\n");\r
1427 \r
1428   fprintf(fp, "%s_c:\n",Label);\r
1429                 fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
1430                 fprintf(fp, "\t\t and   ecx,byte 3\n");\r
1431                 fprintf(fp, "\t\t shl   eax,cl\n");\r
1432 \r
1433                 // if brief mode we can add index and exit\r
1434                 fprintf(fp, "\t\t test  edx,0x0100\n");\r
1435                 fprintf(fp, "\t\t jz    near %s_i2\n",Label);\r
1436 \r
1437   fprintf(fp, "%s_d:\n",Label);\r
1438                 // check BS (base supress)\r
1439                 // if BS is 1 then set edi to 0\r
1440                 fprintf(fp, "\t\t test  edx,0x0080\n");\r
1441                 fprintf(fp, "\t\t jz    short %s_4a\n",Label);\r
1442                 ClearRegister(EDI);\r
1443                 // if null displacement skip over\r
1444                 fprintf(fp, "%s_4a:\n",Label);\r
1445                 fprintf(fp, "\t\t test  edx,0x0020\n");\r
1446                 fprintf(fp, "\t\t jz    short %s_f\n",Label);\r
1447 \r
1448                 // **** calc base displacement ****\r
1449                 // is it long\r
1450                 fprintf(fp, "\t\t test  edx,0x0010\n");\r
1451                 fprintf(fp, "\t\t jz    short %s_e\n",Label);\r
1452                 // fetch long base\r
1453                 Memory_Fetch('L',EBX,FALSE);\r
1454                 fprintf(fp, "\t\t lea   edi,[edi+ebx]\n");\r
1455                 fprintf(fp, "\t\t add   esi,byte 4\n");\r
1456                 fprintf(fp, "\t\t jmp   short %s_f\n",Label);\r
1457 \r
1458                 // fetch word base\r
1459   fprintf(fp, "%s_e:\n",Label);\r
1460                 Memory_Fetch('W',EBX,TRUE);\r
1461                 fprintf(fp, "\t\t lea   edi,[edi+ebx]\n");\r
1462                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
1463 \r
1464                 // **** indirect? ****\r
1465   fprintf(fp, "%s_f:\n",Label);\r
1466                 fprintf(fp, "\t\t test  edx,0x0003\n");\r
1467                 fprintf(fp, "\t\t jz    near %s_7a\n",Label);\r
1468                 // pre or post indirect\r
1469                 fprintf(fp, "\t\t test  edx,0x0004\n");\r
1470                 fprintf(fp, "\t\t jnz   short %s_g\n",Label);\r
1471                 // do pre\r
1472                 fprintf(fp, "\t\t lea   edi,[edi+eax]\n");\r
1473                 Memory_Read('L',EDI,"ABCDSDB",2);\r
1474                 fprintf(fp, "\t\t mov   edi,eax\n");\r
1475                 fprintf(fp, "\t\t jmp   short %s_h\n",Label);\r
1476 \r
1477                 // do post\r
1478  fprintf(fp, "%s_g:\n",Label);\r
1479                 fprintf(fp, "\t\t push  eax\n");\r
1480                 Memory_Read('L',EDI,"-B-DS-B",2);\r
1481                 fprintf(fp, "\t\t pop   edi\n");\r
1482 \r
1483  fprintf(fp, "%s_7a:\n",Label);\r
1484                 fprintf(fp, "\t\t lea   edi,[edi+eax]\n");\r
1485 \r
1486                 // **** outer displacement ****\r
1487                 // if null displacement skip over\r
1488  fprintf(fp, "%s_h:\n",Label);\r
1489                 fprintf(fp, "\t\t test  edx,0x0002\n");\r
1490                 fprintf(fp, "\t\t jz    short %s_j\n",Label);\r
1491                 // word or long?\r
1492                 fprintf(fp, "\t\t test  edx,0x0001\n");\r
1493                 fprintf(fp, "\t\t jz    short %s_i\n",Label);\r
1494                 // fetch long\r
1495                 Memory_Fetch('L',EAX,FALSE);\r
1496                 fprintf(fp, "\t\t add   esi,byte 4\n");\r
1497                 fprintf(fp, "\t\t jmp   short %s_i2\n",Label);\r
1498                 // fetch word\r
1499   fprintf(fp, "%s_i:\n",Label);\r
1500                 Memory_Fetch('W',EAX,TRUE);\r
1501                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
1502   fprintf(fp, "%s_i2:\n",Label);\r
1503                 fprintf(fp, "\t\t lea   edi,[edi+eax]\n");\r
1504 \r
1505                 // **** exit ****\r
1506   fprintf(fp, "%s_j:\n",Label);\r
1507                 fprintf(fp, "\t\t pop   ecx\n");\r
1508                 fprintf(fp, "\t\t pop   ebx\n");\r
1509         }\r
1510 \r
1511         if (SaveEDX)\r
1512                 fprintf(fp, "\t\t pop   edx\n");\r
1513 }\r
1514 \r
1515 /* Calculate Effective Address - Return address in EDI\r
1516  *\r
1517  * mode = Effective Address from Instruction\r
1518  * Size = Byte,Word or Long\r
1519  * Rreg = Register with Register Number in\r
1520  *\r
1521  * Only for modes 2 - 10 (5-10 clobber EAX)\r
1522  */\r
1523 \r
1524 void EffectiveAddressCalculate(int mode,char Size,int Rreg,int SaveEDX)\r
1525 {\r
1526         /* timing */\r
1527 \r
1528         if ((TimingCycles > 0) && (AddEACycles!=0))\r
1529         {\r
1530                 switch (mode)\r
1531                 {\r
1532                         case 2:         /* (An) */\r
1533                         case 3:         /* (An)+ */\r
1534                         case 11:        /* #x,SR,CCR */\r
1535                         case 19:        /* (A7)+ */\r
1536                                 TimingCycles += 4 ;\r
1537                                 break ;\r
1538 \r
1539                         case 4:         /* -(An) */\r
1540                         case 20:        /* -(A7) */\r
1541                                 TimingCycles += (CPU==2) ? 5 : 6 ;\r
1542                                 break ;\r
1543 \r
1544                         case 5:         /* x(An) */\r
1545                         case 9:         /* x(PC) */\r
1546                                 TimingCycles += (CPU==2) ? 5 : 8 ;\r
1547                                 break ;\r
1548 \r
1549                         case 7:         /* x.w */\r
1550                                 TimingCycles += (CPU==2) ? 4 : 8 ;\r
1551                                 break ;\r
1552 \r
1553                         case 6:         /* x(An,xr.s) */\r
1554                         case 10:        /* x(PC,xr.s) */\r
1555                                 TimingCycles += (CPU==2) ? 7 : 10 ;\r
1556                                 break ;\r
1557 \r
1558                         case 8:         /* x.l */\r
1559                                 TimingCycles += (CPU==2) ? 4 : 12 ;\r
1560                                 break ;\r
1561                 }\r
1562 \r
1563                 /* long w/r adds 4 cycles */\r
1564 \r
1565                 if ((mode>1) && (Size == 'L') && (CPU != 2))\r
1566                         TimingCycles += 4 ;\r
1567         }\r
1568 \r
1569         AccessType = NORMAL;\r
1570 \r
1571         switch (mode)\r
1572         {\r
1573 \r
1574                 case 2:\r
1575                         fprintf(fp, "\t\t mov   EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);\r
1576                         break;\r
1577 \r
1578                 case 3:\r
1579                         fprintf(fp, "\t\t mov   EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);\r
1580                         IncrementEDI(Size,Rreg);\r
1581                         break;\r
1582 \r
1583                 case 4:\r
1584                         fprintf(fp, "\t\t mov   EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);\r
1585                         DecrementEDI(Size,Rreg);\r
1586                         fprintf(fp, "\t\t mov   [%s+%s*4],EDI\n",REG_ADD,regnameslong[Rreg]);\r
1587                         break;\r
1588 \r
1589                 case 5:\r
1590                         Memory_Fetch('W',EAX,TRUE);\r
1591                         fprintf(fp, "\t\t mov   EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);\r
1592                         fprintf(fp, "\t\t add   esi,byte 2\n");\r
1593                         fprintf(fp, "\t\t add   edi,eax\n");\r
1594                         break;\r
1595 \r
1596                 case 6:\r
1597 \r
1598                         /* Get Address register Value */\r
1599 \r
1600                         fprintf(fp, "\t\t mov   EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);\r
1601 \r
1602                         /* Add Extension Details */\r
1603 \r
1604                         ExtensionDecode(SaveEDX);\r
1605                         break;\r
1606 \r
1607                 case 7:\r
1608 \r
1609                         /* Get Word */\r
1610 \r
1611                         Memory_Fetch('W',EDI,TRUE);\r
1612 //               fprintf(fp, "\t\t movsx edi,di\n");\r
1613                         fprintf(fp, "\t\t add   esi,byte 2\n");\r
1614                         break;\r
1615 \r
1616                 case 8:\r
1617 \r
1618                         /* Get Long */\r
1619 \r
1620                         Memory_Fetch('L',EDI,FALSE);\r
1621                         fprintf(fp, "\t\t add   esi,byte 4\n");\r
1622                         break;\r
1623 \r
1624                 case 9:\r
1625 \r
1626                         AccessType = PCREL;\r
1627 \r
1628                         Memory_Fetch('W',EAX,TRUE);\r
1629 //               fprintf(fp, "\t\t movsx eax,ax\n");\r
1630                         fprintf(fp, "\t\t mov   EDI,ESI           ; Get PC\n");\r
1631                         fprintf(fp, "\t\t add   esi,byte 2\n");\r
1632                         fprintf(fp, "\t\t add   edi,eax         ; Add Offset to PC\n");\r
1633                         break;\r
1634 \r
1635                 case 10:\r
1636 \r
1637                         AccessType = PCREL;\r
1638 \r
1639                         /* Get PC */\r
1640 \r
1641                         fprintf(fp, "\t\t mov   edi,esi           ; Get PC\n");\r
1642 \r
1643                         /* Add Extension Details */\r
1644 \r
1645                         ExtensionDecode(SaveEDX);\r
1646 \r
1647                         break;\r
1648 \r
1649                 case 19:\r
1650 \r
1651                         /* (A7)+ */\r
1652 \r
1653                         fprintf(fp, "\t\t mov   edi,[%s]    ; Get A7\n",REG_A7);\r
1654                         fprintf(fp, "\t\t add   dword [%s],byte 2\n",REG_A7);\r
1655                         break;\r
1656 \r
1657                 case 20:\r
1658 \r
1659                         /* -(A7) */\r
1660 \r
1661                         fprintf(fp, "\t\t mov   edi,[%s]    ; Get A7\n",REG_A7);\r
1662                         fprintf(fp, "\t\t sub   edi,byte 2\n");\r
1663                         fprintf(fp, "\t\t mov   [%s],edi\n",REG_A7);\r
1664                         break;\r
1665 \r
1666         }\r
1667 }\r
1668 \r
1669 /* Read from Effective Address\r
1670  *\r
1671  * mode = Effective Address from Instruction\r
1672  * Size = Byte,Word or Long\r
1673  * Rreg = Register with Register Number in\r
1674  * Flag = Registers to preserve (EDX is handled by SaveEDX)\r
1675  *\r
1676  * Return\r
1677  * Dreg = Register to return result in (EAX is usually most efficient)\r
1678  * (modes 5 to 10) EDI  = Address of data read (masked with FFFFFF)\r
1679  */\r
1680 \r
1681 void EffectiveAddressRead(int mode,char Size,int Rreg,int Dreg,const char *flags,int SaveEDX)\r
1682 {\r
1683         char* Regname="";\r
1684         int     MaskMode;\r
1685         char Flags[8];\r
1686 \r
1687         AccessType = NORMAL;\r
1688 \r
1689         strcpy(Flags,flags);\r
1690 \r
1691         /* Which Masking to Use */\r
1692 \r
1693         if (Flags[5] != '-')\r
1694                 MaskMode = 2;\r
1695         else\r
1696                 MaskMode = 1;\r
1697 \r
1698         if (SaveEDX)\r
1699                 Flags[3] = 'D';\r
1700         else\r
1701                 Flags[3] = '-';\r
1702 \r
1703         switch (Size)\r
1704         {\r
1705                 case 66:\r
1706                         Regname = regnamesshort[Dreg];\r
1707                         break;\r
1708 \r
1709                 case 87:\r
1710                         Regname = regnamesword[Dreg];\r
1711                         break;\r
1712 \r
1713                 case 76:\r
1714                         Regname = regnameslong[Dreg];\r
1715                         break;\r
1716         }\r
1717 \r
1718         switch (mode & 15)\r
1719         {\r
1720 \r
1721                 case 0:\r
1722 \r
1723                         /* Read 32 bits - No prefix */\r
1724 \r
1725                         fprintf(fp, "\t\t mov   %s,[%s+%s*4]\n",regnameslong[Dreg],REG_DAT,regnameslong[Rreg]);\r
1726                         break;\r
1727 \r
1728                 case 1:\r
1729 \r
1730                         /* Read 32 bits - No prefix */\r
1731 \r
1732                         fprintf(fp, "\t\t mov   %s,[%s+%s*4]\n",regnameslong[Dreg],REG_ADD,regnameslong[Rreg]);\r
1733                         break;\r
1734 \r
1735                 case 2:\r
1736                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1737 \r
1738                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1739 \r
1740                         if (Dreg != EAX)\r
1741                         {\r
1742                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1743                         }\r
1744                         break;\r
1745 \r
1746                 case 3:\r
1747                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1748 \r
1749                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1750 \r
1751                         if (Dreg != EAX)\r
1752                         {\r
1753                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1754                         }\r
1755                         break;\r
1756 \r
1757                 case 4:\r
1758                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1759 \r
1760                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1761 \r
1762                         if (Dreg != EAX)\r
1763                         {\r
1764                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1765                         }\r
1766                         break;\r
1767 \r
1768 \r
1769                 case 5:\r
1770                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1771 \r
1772                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1773 \r
1774                         if (Dreg != EAX)\r
1775                         {\r
1776                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1777                         }\r
1778                         break;\r
1779 \r
1780                 case 6:\r
1781                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1782 \r
1783                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1784 \r
1785                         if (Dreg != EAX)\r
1786                         {\r
1787                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1788                         }\r
1789                         break;\r
1790 \r
1791                 case 7:\r
1792                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1793 \r
1794                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1795 \r
1796                         if (Dreg != EAX)\r
1797                         {\r
1798                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1799                         }\r
1800                         break;\r
1801 \r
1802                 case 8:\r
1803                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1804 \r
1805                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1806 \r
1807                         if (Dreg != EAX)\r
1808                         {\r
1809                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1810                         }\r
1811                         break;\r
1812 \r
1813                 case 9:\r
1814                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1815 \r
1816                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1817 \r
1818                         if (Dreg != EAX)\r
1819                         {\r
1820                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1821                         }\r
1822                         break;\r
1823 \r
1824                 case 10:\r
1825                         EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1826 \r
1827                         Memory_Read(Size,EDI,Flags,MaskMode);\r
1828 \r
1829                         if (Dreg != EAX)\r
1830                         {\r
1831                                 fprintf(fp, "\t\t mov   %s,EAX\n",regnameslong[Dreg]);\r
1832                         }\r
1833                         break;\r
1834 \r
1835                 case 11:\r
1836 \r
1837                         /* Immediate - for SR or CCR see ReadCCR() */\r
1838 \r
1839                         if (Size == 'L')\r
1840                         {\r
1841                                 Memory_Fetch('L',Dreg,FALSE);\r
1842                                 fprintf(fp, "\t\t add   esi,byte 4\n");\r
1843                         }\r
1844                         else\r
1845                         {\r
1846                                 Memory_Fetch('W',Dreg,FALSE);\r
1847                                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
1848                         };\r
1849                         break;\r
1850         }\r
1851 }\r
1852 \r
1853 /*\r
1854  * EA   = Effective Address from Instruction\r
1855  * Size = Byte,Word or Long\r
1856  * Rreg = Register with Register Number in\r
1857  *\r
1858  * Writes from EAX\r
1859  */\r
1860 \r
1861 void EffectiveAddressWrite(int mode,char Size,int Rreg,int CalcAddress,const char *flags,int SaveEDX)\r
1862 {\r
1863         int     MaskMode;\r
1864         char* Regname="";\r
1865         char Flags[8];\r
1866 \r
1867 \r
1868         strcpy(Flags,flags);\r
1869 \r
1870         /* Which Masking to Use ? */\r
1871 \r
1872         if (CalcAddress)\r
1873         {\r
1874                 if (Flags[5] != '-')\r
1875                         MaskMode = 2;\r
1876                 else\r
1877                         MaskMode = 1;\r
1878         }\r
1879         else\r
1880                 MaskMode = 0;\r
1881 \r
1882         if (SaveEDX)\r
1883                 Flags[3] = 'D';\r
1884         else\r
1885                 Flags[3] = '-';\r
1886 \r
1887         switch (Size)\r
1888         {\r
1889                 case 66:\r
1890                         Regname = regnamesshort[0];\r
1891                         break;\r
1892 \r
1893                 case 87:\r
1894                         Regname = regnamesword[0];\r
1895                         break;\r
1896 \r
1897                 case 76:\r
1898                         Regname = regnameslong[0];\r
1899                         break;\r
1900         }\r
1901 \r
1902         switch (mode & 15)\r
1903         {\r
1904 \r
1905                 case 0:\r
1906                         fprintf(fp, "\t\t mov   [%s+%s*4],%s\n",REG_DAT,regnameslong[Rreg],Regname);\r
1907                         break;\r
1908 \r
1909                 case 1:\r
1910                         if (Size == 66)\r
1911                         {\r
1912                                 /* Not Allowed */\r
1913 \r
1914                                 fprintf(fp, "DUFF CODE!\n");\r
1915                         }\r
1916                         else\r
1917                         {\r
1918                                 if (Size == 87)\r
1919                                 {\r
1920                                         fprintf(fp, "\t\t cwde\n");\r
1921                                 }\r
1922 \r
1923                                 fprintf(fp, "\t\t mov   [%s+%s*4],%s\n",REG_ADD,regnameslong[Rreg],regnameslong[0]);\r
1924                         }\r
1925                         break;\r
1926 \r
1927                 case 2:\r
1928                         if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1929                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1930                         break;\r
1931 \r
1932                 case 3:\r
1933                         if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1934                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1935                         break;\r
1936 \r
1937                 case 4:\r
1938                         if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1939                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1940                         break;\r
1941 \r
1942                 case 5:\r
1943                         if (CalcAddress)\r
1944                         {\r
1945                                 fprintf(fp, "\t\t push  EAX\n");\r
1946                                 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1947                                 fprintf(fp, "\t\t pop   EAX\n");\r
1948                         }\r
1949                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1950                         break;\r
1951 \r
1952                 case 6:\r
1953                         if (CalcAddress)\r
1954                         {\r
1955                                 fprintf(fp, "\t\t push  EAX\n");\r
1956                                 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1957                                 fprintf(fp, "\t\t pop   EAX\n");\r
1958                         }\r
1959                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1960                         break;\r
1961 \r
1962                 case 7:\r
1963                         if (CalcAddress)\r
1964                         {\r
1965                                 fprintf(fp, "\t\t push  EAX\n");\r
1966                                 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1967                                 fprintf(fp, "\t\t pop   EAX\n");\r
1968                         }\r
1969                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1970                         break;\r
1971 \r
1972                 case 8:\r
1973                         if (CalcAddress)\r
1974                         {\r
1975                                 fprintf(fp, "\t\t push  EAX\n");\r
1976                                 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1977                                 fprintf(fp, "\t\t pop   EAX\n");\r
1978                         }\r
1979                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1980                         break;\r
1981 \r
1982                 case 9:\r
1983                         if (CalcAddress)\r
1984                         {\r
1985                                 fprintf(fp, "\t\t push  EAX\n");\r
1986                                 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1987                                 fprintf(fp, "\t\t pop   EAX\n");\r
1988                         }\r
1989                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
1990                         break;\r
1991 \r
1992                 case 10:\r
1993                         if (CalcAddress)\r
1994                         {\r
1995                                 fprintf(fp, "\t\t push  EAX\n");\r
1996                                 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);\r
1997                                 fprintf(fp, "\t\t pop   EAX\n");\r
1998                         }\r
1999                         Memory_Write(Size,EDI,EAX,Flags,MaskMode);\r
2000                         break;\r
2001 \r
2002                 case 11:\r
2003 \r
2004                         /* SR, CCR - Chain to correct routine */\r
2005 \r
2006                         WriteCCR(Size);\r
2007         }\r
2008 }\r
2009 \r
2010 /* Condition Decode Routines */\r
2011 \r
2012 /*\r
2013  * mode = condition to check for\r
2014  *\r
2015  * Returns LABEL that is jumped to if condition is Condition\r
2016  *\r
2017  * Some conditions clobber AH\r
2018  */\r
2019 \r
2020 char *ConditionDecode(int mode, int Condition)\r
2021 {\r
2022         char *Label = GenerateLabel(0,1);\r
2023 \r
2024         switch (mode)\r
2025         {\r
2026 \r
2027                 case 0: /* A - Always */\r
2028                         if (Condition)\r
2029                         {\r
2030         fprintf(fp, "\t\t jmp   %s ;dave removed near\n",Label);\r
2031                         }\r
2032                         break;\r
2033 \r
2034                 case 1: /* F - Never */\r
2035                         if (!Condition)\r
2036                         {\r
2037                                 fprintf(fp, "\t\t jmp   near %s\n",Label);\r
2038                         }\r
2039                         break;\r
2040 \r
2041                 case 2: /* Hi */\r
2042                         fprintf(fp, "\t\t mov   ah,dl\n");\r
2043                         fprintf(fp, "\t\t sahf\n");\r
2044 \r
2045                         if (Condition)\r
2046                         {\r
2047                                 fprintf(fp, "\t\t ja    near %s\n",Label);\r
2048                         }\r
2049                         else\r
2050                         {\r
2051                                 fprintf(fp, "\t\t jbe   near %s\n",Label);\r
2052                         }\r
2053                         break;\r
2054 \r
2055                 case 3: /* Ls */\r
2056                         fprintf(fp, "\t\t mov   ah,dl\n");\r
2057                         fprintf(fp, "\t\t sahf\n");\r
2058 \r
2059                         if (Condition)\r
2060                         {\r
2061                                 fprintf(fp, "\t\t jbe   near %s\n",Label);\r
2062                         }\r
2063                         else\r
2064                         {\r
2065                                 fprintf(fp, "\t\t ja    near %s\n",Label);\r
2066                         }\r
2067                         break;\r
2068 \r
2069                 case 4: /* CC */\r
2070                         fprintf(fp, "\t\t test  dl,1H\t\t;check carry\n");\r
2071 \r
2072                         if (Condition)\r
2073                         {\r
2074                                 fprintf(fp, "\t\t jz    near %s\n",Label);\r
2075                         }\r
2076                         else\r
2077                         {\r
2078                                 fprintf(fp, "\t\t jnz   near %s\n",Label);\r
2079                         }\r
2080                         break;\r
2081 \r
2082                 case 5: /* CS */\r
2083                         fprintf(fp,  "\t\t test  dl,1H\t\t;check carry\n");\r
2084                         if (Condition)\r
2085                         {\r
2086                                 fprintf(fp, "\t\t jnz   near %s\n",Label);\r
2087                         }\r
2088                         else\r
2089                         {\r
2090                                 fprintf(fp, "\t\t jz    near %s\n",Label);\r
2091                         }\r
2092                         break;\r
2093 \r
2094                 case 6: /* NE */\r
2095                         fprintf(fp, "\t\t test  dl,40H\t\t;Check zero\n");\r
2096                         if (Condition)\r
2097                         {\r
2098                                 fprintf(fp, "\t\t jz    near %s\n",Label);\r
2099                         }\r
2100                         else\r
2101                         {\r
2102                                 fprintf(fp, "\t\t jnz   near %s\n",Label);\r
2103                         }\r
2104                         break;\r
2105 \r
2106                 case 7: /* EQ */\r
2107                         fprintf(fp, "\t\t test  dl,40H\t\t;Check zero\n");\r
2108                         if (Condition)\r
2109                         {\r
2110                                 fprintf(fp, "\t\t jnz   near %s\n",Label);\r
2111                         }\r
2112                         else\r
2113                         {\r
2114                                 fprintf(fp, "\t\t jz    near %s\n",Label);\r
2115                         }\r
2116                         break;\r
2117 \r
2118                 case 8: /* VC */\r
2119                         fprintf(fp, "\t\t test  dh,8H\t\t;Check Overflow\n");\r
2120                         if (Condition)\r
2121                         {\r
2122                                 fprintf(fp, "\t\t jz    near %s\n", Label);\r
2123                         }\r
2124                         else\r
2125                         {\r
2126                                 fprintf(fp, "\t\t jnz   near %s\n", Label);\r
2127                         }\r
2128                         break;\r
2129 \r
2130                 case 9: /* VS */\r
2131                         fprintf(fp, "\t\t test  dh,8H\t\t;Check Overflow\n");\r
2132                         if (Condition)\r
2133                         {\r
2134                                 fprintf(fp, "\t\t jnz   near %s\n", Label);\r
2135                         }\r
2136                         else\r
2137                         {\r
2138                                 fprintf(fp, "\t\t jz    near %s\n", Label);\r
2139                         }\r
2140                         break;\r
2141 \r
2142                 case 10:        /* PL */\r
2143                         fprintf(fp,"\t\t test  dl,80H\t\t;Check Sign\n");\r
2144                         if (Condition)\r
2145                         {\r
2146                                 fprintf(fp, "\t\t jz    near %s\n", Label);\r
2147                         }\r
2148                         else\r
2149                         {\r
2150                                 fprintf(fp, "\t\t jnz   near %s\n", Label);\r
2151                         }\r
2152                         break;\r
2153 \r
2154                 case 11:        /* MI */\r
2155                         fprintf(fp,"\t\t test  dl,80H\t\t;Check Sign\n");\r
2156                         if (Condition)\r
2157                         {\r
2158                                 fprintf(fp, "\t\t jnz   near %s\n", Label);\r
2159                         }\r
2160                         else\r
2161                         {\r
2162                                 fprintf(fp, "\t\t jz    near %s\n", Label);\r
2163                         }\r
2164                         break;\r
2165 \r
2166                 case 12:        /* GE */\r
2167                         fprintf(fp, "\t\t or    edx,200h\n");\r
2168                         fprintf(fp, "\t\t push  edx\n");\r
2169                         fprintf(fp, "\t\t popf\n");\r
2170                         if (Condition)\r
2171                         {\r
2172                                 fprintf(fp, "\t\t jge   near %s\n",Label);\r
2173                         }\r
2174                         else\r
2175                         {\r
2176                                 fprintf(fp, "\t\t jl    near %s\n",Label);\r
2177                         }\r
2178                         break;\r
2179 \r
2180                 case 13:        /* LT */\r
2181                         fprintf(fp, "\t\t or    edx,200h\n");\r
2182                         fprintf(fp, "\t\t push  edx\n");\r
2183                         fprintf(fp, "\t\t popf\n");\r
2184                         if (Condition)\r
2185                         {\r
2186                                 fprintf(fp, "\t\t jl    near %s\n",Label);\r
2187                         }\r
2188                         else\r
2189                         {\r
2190                                 fprintf(fp, "\t\t jge   near %s\n",Label);\r
2191                         }\r
2192                         break;\r
2193 \r
2194                 case 14:        /* GT */\r
2195                         fprintf(fp, "\t\t or    edx,200h\n");\r
2196                         fprintf(fp, "\t\t push  edx\n");\r
2197                         fprintf(fp, "\t\t popf\n");\r
2198                         if (Condition)\r
2199                         {\r
2200                                 fprintf(fp, "\t\t jg    near %s\n",Label);\r
2201                         }\r
2202                         else\r
2203                         {\r
2204                                 fprintf(fp, "\t\t jle   near %s\n",Label);\r
2205                         }\r
2206                         break;\r
2207 \r
2208                 case 15:        /* LE */\r
2209                         fprintf(fp, "\t\t or    edx,200h\n");\r
2210                         fprintf(fp, "\t\t push  edx\n");\r
2211                         fprintf(fp, "\t\t popf\n");\r
2212                         if (Condition)\r
2213                         {\r
2214                                 fprintf(fp, "\t\t jle   near %s\n",Label);\r
2215                         }\r
2216                         else\r
2217                         {\r
2218                                 fprintf(fp, "\t\t jg    near %s\n",Label);\r
2219                         }\r
2220                         break;\r
2221         }\r
2222 \r
2223         return Label;\r
2224 }\r
2225 \r
2226 /*\r
2227  * mode = condition to check for\r
2228  * SetWhat = text for assembler command (usually AL or address descriptor)\r
2229  *\r
2230  * Some conditions clobber AH\r
2231  */\r
2232 \r
2233 void ConditionCheck(int mode, char *SetWhat)\r
2234 {\r
2235         switch (mode)\r
2236         {\r
2237 \r
2238                 case 0: /* A - Always */\r
2239                         fprintf(fp, "\t\t mov   %s,byte 0ffh\n",SetWhat);\r
2240                         break;\r
2241 \r
2242                 case 1: /* F - Never */\r
2243                         if (SetWhat[1] == 'L')\r
2244                         {\r
2245                                 ClearRegister(EAX);\r
2246                         }\r
2247                         else\r
2248                         {\r
2249                                 fprintf(fp, "\t\t mov   %s,byte 0h\n",SetWhat);\r
2250                         }\r
2251                         break;\r
2252 \r
2253                 case 2: /* Hi */\r
2254                         fprintf(fp, "\t\t mov   ah,dl\n");\r
2255                         fprintf(fp, "\t\t sahf\n");\r
2256                         fprintf(fp, "\t\t seta  %s\n",SetWhat);\r
2257                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2258                         break;\r
2259 \r
2260                 case 3: /* Ls */\r
2261                         fprintf(fp, "\t\t mov   ah,dl\n");\r
2262                         fprintf(fp, "\t\t sahf\n");\r
2263                         fprintf(fp, "\t\t setbe %s\n",SetWhat);\r
2264                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2265                         break;\r
2266 \r
2267                 case 4: /* CC */\r
2268                         fprintf(fp, "\t\t test  dl,1\t\t;Check Carry\n");\r
2269                         fprintf(fp, "\t\t setz  %s\n",SetWhat);\r
2270                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2271                         break;\r
2272 \r
2273                 case 5: /* CS */\r
2274                         fprintf(fp, "\t\t test  dl,1\t\t;Check Carry\n");\r
2275                         fprintf(fp, "\t\t setnz %s\n",SetWhat);\r
2276                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2277                         break;\r
2278 \r
2279                 case 6: /* NE */\r
2280                         fprintf(fp, "\t\t test  dl,40H\t\t;Check Zero\n");\r
2281                         fprintf(fp, "\t\t setz  %s\n",SetWhat);\r
2282                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2283                         break;\r
2284 \r
2285                 case 7: /* EQ */\r
2286                         fprintf(fp, "\t\t test  dl,40H\t\t;Check Zero\n");\r
2287                         fprintf(fp, "\t\t setnz %s\n",SetWhat);\r
2288                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2289                         break;\r
2290 \r
2291                 case 8: /* VC */\r
2292                         fprintf(fp, "\t\t test  dh,8H\t\t;Check Overflow\n");\r
2293                         fprintf(fp, "\t\t setz  %s\n",SetWhat);\r
2294                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2295                         break;\r
2296 \r
2297                 case 9: /* VS */\r
2298                         fprintf(fp, "\t\t test  dh,8H\t\t;Check Overflow\n");\r
2299                         fprintf(fp, "\t\t setnz %s\n",SetWhat);\r
2300                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2301                         break;\r
2302 \r
2303                 case 10:        /* PL */\r
2304                         fprintf(fp, "\t\t test  dl,80H\t\t;Check Sign\n");\r
2305                         fprintf(fp, "\t\t setz  %s\n",SetWhat);\r
2306                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2307                         break;\r
2308 \r
2309                 case 11:        /* MI */\r
2310                         fprintf(fp, "\t\t test  dl,80H\t\t;Check Sign\n");\r
2311                         fprintf(fp, "\t\t setnz %s\n",SetWhat);\r
2312                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2313                         break;\r
2314 \r
2315                 case 12:        /* GE */\r
2316                         fprintf(fp, "\t\t or    edx,200h\n");\r
2317                         fprintf(fp, "\t\t push  edx\n");\r
2318                         fprintf(fp, "\t\t popf\n");\r
2319                         fprintf(fp, "\t\t setge %s\n",SetWhat);\r
2320                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2321                         break;\r
2322 \r
2323                 case 13:        /* LT */\r
2324                         fprintf(fp, "\t\t or    edx,200h\n");\r
2325                         fprintf(fp, "\t\t push  edx\n");\r
2326                         fprintf(fp, "\t\t popf\n");\r
2327                         fprintf(fp, "\t\t setl  %s\n",SetWhat);\r
2328                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2329                         break;\r
2330 \r
2331                 case 14:        /* GT */\r
2332                         fprintf(fp, "\t\t or    edx,200h\n");\r
2333                         fprintf(fp, "\t\t push  edx\n");\r
2334                         fprintf(fp, "\t\t popf\n");\r
2335                         fprintf(fp, "\t\t setg  %s\n",SetWhat);\r
2336                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2337                         break;\r
2338 \r
2339                 case 15:        /* LE */\r
2340                         fprintf(fp, "\t\t or    edx,200h\n");\r
2341                         fprintf(fp, "\t\t push  edx\n");\r
2342                         fprintf(fp, "\t\t popf\n");\r
2343                         fprintf(fp, "\t\t setle %s\n",SetWhat);\r
2344                         fprintf(fp, "\t\t neg   byte %s\n",SetWhat);\r
2345                         break;\r
2346         }\r
2347 }\r
2348 \r
2349 \r
2350 /**********************************************************************/\r
2351 /* Instructions - Each routine generates a range of instruction codes */\r
2352 /**********************************************************************/\r
2353 \r
2354 /*\r
2355  * Immediate Commands\r
2356  *\r
2357  * ORI  00xx\r
2358  * ANDI 02xx\r
2359  * SUBI 04xx\r
2360  * ADDI 06xx\r
2361  * EORI 0axx\r
2362  * CMPI 0cxx\r
2363  *\r
2364  */\r
2365 \r
2366 void dump_imm( int type, int leng, int mode, int sreg )\r
2367 {\r
2368         int Opcode,BaseCode ;\r
2369         char Size=' ' ;\r
2370         char * RegnameEBX="" ;\r
2371         char * Regname="" ;\r
2372         char * OpcodeName[16] = {"or ", "and", "sub", "add",0,"xor","cmp",0} ;\r
2373         int allow[] = {1,0,1,1, 1,1,1,1, 1,0,0,0, 0,0,0,0, 0,0,0,1, 1} ;\r
2374 \r
2375         Opcode = (type << 9) | ( leng << 6 ) | ( mode << 3 ) | sreg;\r
2376 \r
2377         BaseCode = Opcode & 0xfff8;\r
2378 \r
2379         if (mode == 7) BaseCode |= sreg ;\r
2380 \r
2381 #ifdef A7ROUTINE\r
2382         if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5))\r
2383         {\r
2384                 BaseCode |= sreg ;\r
2385         }\r
2386 #endif\r
2387 \r
2388         if (type != 4)  /* Not Valid (for this routine) */\r
2389         {\r
2390                 int Dest = EAtoAMN(Opcode, FALSE);\r
2391                 int SetX;\r
2392 \r
2393                 /* ADDI & SUBI also set X flag */\r
2394 \r
2395                 SetX = ((type == 2) || (type == 3));\r
2396 \r
2397                 switch (leng)\r
2398                 {\r
2399                         case 0:\r
2400                                 Size = 'B';\r
2401                                 Regname = regnamesshort[0];\r
2402                                 RegnameEBX = regnamesshort[EBX];\r
2403                                 break;\r
2404                         case 1:\r
2405                                 Size = 'W';\r
2406                                 Regname = regnamesword[0];\r
2407                                 RegnameEBX = regnamesword[EBX];\r
2408                                 break;\r
2409                         case 2:\r
2410                                 Size = 'L';\r
2411                                 Regname = regnameslong[0];\r
2412                                 RegnameEBX = regnameslong[EBX];\r
2413                                 break;\r
2414                 }\r
2415 \r
2416                 if (allow[Dest])\r
2417                 {\r
2418                         if (OpcodeArray[BaseCode] == -2)\r
2419                         {\r
2420                                 Align();\r
2421                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
2422 \r
2423                                 /* Save Previous PC if Memory Access */\r
2424 \r
2425                                 if ((Dest >= 2) && (Dest <=10))\r
2426                                         SavePreviousPC();\r
2427 \r
2428                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
2429 \r
2430                                 if (mode < 2)\r
2431                                 {\r
2432                                         if (Size != 'L')\r
2433                                                 TimingCycles += (CPU==2) ? 4 : 8;\r
2434                                         else\r
2435                                         {\r
2436                                                 TimingCycles += (CPU==2) ? 8 : 14;\r
2437                                                 if ((type != 1) && (type!=6))\r
2438                                                         TimingCycles += 2 ;\r
2439                                         }\r
2440                                 }\r
2441                                 else\r
2442                                 {\r
2443                                         if (type != 6)\r
2444                                         {\r
2445                                                 if (Size != 'L')\r
2446                                                         TimingCycles += (CPU==2) ? 4 : 12 ;\r
2447                                                 else\r
2448                                                         TimingCycles += (CPU==2) ? 4 : 20 ;\r
2449                                         }\r
2450                                         else\r
2451                                         {\r
2452                                                 if (Size != 'L')\r
2453                                                         TimingCycles += (CPU==2) ? 4 : 8 ;\r
2454                                                 else\r
2455                                                         TimingCycles += (CPU==2) ? 4 : 12 ;\r
2456                                         }\r
2457                                 }\r
2458 \r
2459                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
2460 \r
2461                                 /* Immediate Mode Data */\r
2462                                 EffectiveAddressRead(11,Size,EBX,EBX,"--C-S-B",FALSE);\r
2463 \r
2464                                 /* Source Data */\r
2465                                 EffectiveAddressRead(Dest,Size,ECX,EAX,"-BC-SDB",FALSE);\r
2466 \r
2467                                 /* The actual work */\r
2468                                 fprintf(fp, "\t\t %s   %s,%s\n", OpcodeName[type], Regname, RegnameEBX );\r
2469 \r
2470                                 SetFlags(Size,EAX,FALSE,SetX,TRUE);\r
2471 \r
2472                                 if (type != 6) /* CMP no update */\r
2473                                         EffectiveAddressWrite(Dest,Size,ECX,EAX,"---DS-B",FALSE);\r
2474 \r
2475                                 Completed();\r
2476                         }\r
2477                 }\r
2478                 else\r
2479                 {\r
2480                         /* Logicals are allowed to alter SR/CCR */\r
2481 \r
2482                         if ((!SetX) && (Dest == 11) && (Size != 'L') && (type != 6))\r
2483                         {\r
2484                                 Align();\r
2485 \r
2486                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
2487                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
2488                                 TimingCycles += 20 ;\r
2489 \r
2490                                 if (Size=='W')\r
2491                                 {\r
2492                                         /* If SR then must be in Supervisor Mode */\r
2493 \r
2494                                         char *Label = GenerateLabel(0,1);\r
2495 \r
2496                                         fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
2497                                         fprintf(fp, "\t\t jne   near %s\n\n",Label);\r
2498 \r
2499                                         /* User Mode - Exception */\r
2500 \r
2501                                         Exception(8,BaseCode);\r
2502 \r
2503                                         fprintf(fp, "%s:\n",Label);\r
2504                                 }\r
2505 \r
2506                                 /* Immediate Mode Data */\r
2507                                 EffectiveAddressRead(11,Size,EBX,EBX,"---DS-B",TRUE);\r
2508 \r
2509                                 ReadCCR(Size,ECX);\r
2510 \r
2511                                 fprintf(fp, "\t\t %s   %s,%s\n", OpcodeName[type], Regname, RegnameEBX );\r
2512 \r
2513                                 WriteCCR(Size);\r
2514 \r
2515                                 Completed();\r
2516                         }\r
2517                         else\r
2518                         {\r
2519 \r
2520                                 /* Illegal Opcode */\r
2521 \r
2522                                 OpcodeArray[BaseCode] = -1;\r
2523                                 BaseCode = -1;\r
2524                         }\r
2525                 }\r
2526         }\r
2527         else\r
2528         {\r
2529                 BaseCode = -2;\r
2530         }\r
2531 \r
2532         OpcodeArray[Opcode] = BaseCode;\r
2533 }\r
2534 \r
2535 void immediate(void)\r
2536 {\r
2537         int type, size, mode, sreg ;\r
2538 \r
2539         for (type = 0 ; type < 0x7; type++)\r
2540                 for (size = 0 ; size < 3 ; size++)\r
2541                         for (mode = 0 ; mode < 8 ; mode++)\r
2542                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
2543                                         dump_imm( type, size, mode, sreg ) ;\r
2544 }\r
2545 \r
2546 \r
2547 /*\r
2548  * Bitwise Codes\r
2549  *\r
2550  */\r
2551 \r
2552 void dump_bit_dynamic( int sreg, int type, int mode, int dreg )\r
2553 {\r
2554         int  Opcode, BaseCode ;\r
2555         char Size ;\r
2556         char *EAXReg,*ECXReg, *Label ;\r
2557         char allow[] = "0-2345678-------" ;\r
2558         int Dest ;\r
2559 \r
2560         /* BTST allows x(PC) and x(PC,xr.s) - others do not */\r
2561 \r
2562         if (type == 0)\r
2563         {\r
2564                 allow[9]  = '9';\r
2565                 allow[10] = 'a';\r
2566                 allow[11] = 'b'; // dave fix to nhl\r
2567         }\r
2568 \r
2569         Opcode = 0x0100 | (sreg << 9) | (type<<6) | (mode<<3) | dreg ;\r
2570 \r
2571         BaseCode = Opcode & 0x01f8 ;\r
2572         if (mode == 7) BaseCode |= dreg ;\r
2573 \r
2574 \r
2575         // A7+, A7-\r
2576 \r
2577 #ifdef  A7ROUTINE\r
2578         if ((mode > 2) && (mode < 5))\r
2579         {\r
2580                 if (dreg == 7) BaseCode |= dreg;\r
2581         }\r
2582 #endif\r
2583 \r
2584         Dest = EAtoAMN(Opcode, FALSE);\r
2585 \r
2586         if (allow[Dest&0xf] != '-')\r
2587         {\r
2588                 if (mode == 0) /* long*/\r
2589                 {\r
2590                         /* Modify register memory directly */\r
2591 \r
2592                         Size = 'L' ;\r
2593                         EAXReg = REG_DAT_EBX;\r
2594                         ECXReg = regnameslong[ECX];\r
2595                 }\r
2596                 else\r
2597                 {\r
2598                         Size = 'B' ;\r
2599                         EAXReg = regnamesshort[EAX];\r
2600                         ECXReg = regnamesshort[ECX];\r
2601                 }\r
2602 \r
2603                 if (OpcodeArray[BaseCode] == -2)\r
2604                 {\r
2605                         Align();\r
2606                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
2607 \r
2608                         /* Save Previous PC if Memory Access */\r
2609 \r
2610                         if ((Dest >= 2) && (Dest <=10))\r
2611                                 SavePreviousPC();\r
2612 \r
2613                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
2614 \r
2615                         if (mode<2)\r
2616                         {\r
2617                                 switch (type)\r
2618                                 {\r
2619                                         case 0:\r
2620                                                 TimingCycles += 6 ;\r
2621                                                 break;\r
2622                                         case 1:\r
2623                                         case 3:\r
2624                                                 TimingCycles += 8 ;\r
2625                                                 break;\r
2626                                         case 2:\r
2627                                                 TimingCycles += 10;\r
2628                                                 break;\r
2629                                 }\r
2630                         }\r
2631                         else\r
2632                         {\r
2633                                 if (type==0)\r
2634                                         TimingCycles += 4;\r
2635                                 else\r
2636                                         TimingCycles += 8;\r
2637                         }\r
2638 \r
2639                         /* Only need this sorted out if a register is involved */\r
2640 \r
2641                         if (Dest < 7)\r
2642                         {\r
2643                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
2644                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
2645                         }\r
2646 \r
2647                         /* Get bit number and create mask in ECX */\r
2648 \r
2649                         fprintf(fp, "\t\t shr   ecx, byte 9\n");\r
2650                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
2651                         fprintf(fp, "\t\t mov   ecx, [%s+ECX*4]\n",REG_DAT);\r
2652 \r
2653                         if (Size == 'L')\r
2654                                 fprintf(fp, "\t\t and   ecx, byte 31\n");\r
2655                         else\r
2656                                 fprintf(fp, "\t\t and   ecx, byte 7\n");\r
2657 \r
2658                  #ifdef QUICKZERO\r
2659                         fprintf(fp,"\t\t mov   eax,1\n");\r
2660                  #else\r
2661                                 fprintf(fp,"\t\t xor   eax,eax\n");\r
2662                                 fprintf(fp,"\t\t inc   eax\n");\r
2663                  #endif\r
2664 \r
2665                         fprintf(fp,"\t\t shl   eax,cl\n");\r
2666                         fprintf(fp,"\t\t mov   ecx,eax\n");\r
2667 \r
2668                         if (mode != 0)\r
2669                                 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",TRUE);\r
2670 \r
2671 \r
2672                         /* All commands copy existing bit to Zero Flag */\r
2673 \r
2674                         Label = GenerateLabel(0,1);\r
2675 \r
2676                         fprintf(fp,"\t\t or    edx,byte 40h\t; Set Zero Flag\n");\r
2677                         fprintf(fp,"\t\t test  %s,%s\n",EAXReg,ECXReg);\r
2678                         fprintf(fp,"\t\t jz    short %s\n",Label);\r
2679                         fprintf(fp,"\t\t xor   edx,byte 40h\t; Clear Zero Flag\n");\r
2680                         fprintf(fp,"%s:\n",Label);\r
2681 \r
2682                         /* Some then modify the data */\r
2683 \r
2684                         switch (type)\r
2685                         {\r
2686                                 case 0: /* btst*/\r
2687                                         break;\r
2688 \r
2689                                 case 1: /* bchg*/\r
2690                                         fprintf(fp,"\t\t xor   %s,%s\n",EAXReg,ECXReg);\r
2691                                         break;\r
2692 \r
2693                                 case 2: /* bclr*/\r
2694                                         fprintf(fp,"\t\t not   ecx\n");\r
2695                                         fprintf(fp,"\t\t and   %s,%s\n",EAXReg,ECXReg);\r
2696                                         break;\r
2697 \r
2698                                 case 3: /* bset*/\r
2699                                         fprintf(fp,"\t\t or    %s,%s\n",EAXReg,ECXReg);\r
2700                                         break;\r
2701                         }\r
2702 \r
2703                         if ((mode !=0) && (type != 0))\r
2704                                 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",TRUE);\r
2705 \r
2706                         Completed();\r
2707                 }\r
2708 \r
2709                 OpcodeArray[Opcode] = BaseCode ;\r
2710         }\r
2711 }\r
2712 \r
2713 void bitdynamic(void) /* dynamic non-immediate bit operations*/\r
2714 {\r
2715         int type, sreg, mode, dreg ;\r
2716 \r
2717         for (sreg = 0 ; sreg < 8 ; sreg++)\r
2718                 for (type = 0 ; type < 4 ; type++)\r
2719                         for (mode = 0 ; mode < 8 ;mode++)\r
2720                                 for (dreg = 0 ; dreg < 8 ;dreg++)\r
2721                                         dump_bit_dynamic( sreg, type, mode, dreg ) ;\r
2722 }\r
2723 \r
2724 void dump_bit_static(int type, int mode, int dreg )\r
2725 {\r
2726         int  Opcode, BaseCode ;\r
2727         char Size ;\r
2728         char *EAXReg,*ECXReg, *Label ;\r
2729         char allow[] = "0-2345678-------" ;\r
2730         int Dest ;\r
2731 \r
2732         /* BTST allows x(PC) and x(PC,xr.s) - others do not */\r
2733 \r
2734         if (type == 0)\r
2735         {\r
2736                 allow[9] = '9';\r
2737                 allow[10] = 'a';\r
2738         }\r
2739 \r
2740         Opcode = 0x0800 | (type<<6) | (mode<<3) | dreg ;\r
2741         BaseCode = Opcode & 0x08f8 ;\r
2742         if (mode == 7) BaseCode |= dreg ;\r
2743 \r
2744         // A7+, A7-\r
2745 \r
2746 #ifdef  A7ROUTINE\r
2747         if ((mode > 2) && (mode < 5))\r
2748         {\r
2749                 if (dreg == 7) BaseCode |= dreg;\r
2750         }\r
2751 #endif\r
2752 \r
2753         Dest = EAtoAMN(Opcode, FALSE);\r
2754 \r
2755         if (allow[Dest&0xf] != '-')\r
2756         {\r
2757                 if (mode == 0) /* long*/\r
2758                 {\r
2759                         /* Modify register memory directly */\r
2760 \r
2761                         Size = 'L' ;\r
2762                         EAXReg = REG_DAT_EBX;\r
2763                         ECXReg = regnameslong[ECX];\r
2764                 }\r
2765                 else\r
2766                 {\r
2767                         Size = 'B' ;\r
2768                         EAXReg = regnamesshort[EAX];\r
2769                         ECXReg = regnamesshort[ECX];\r
2770                 }\r
2771 \r
2772                 if (OpcodeArray[BaseCode] == -2)\r
2773                 {\r
2774                         Align();\r
2775                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
2776 \r
2777                         /* Save Previous PC if Memory Access */\r
2778 \r
2779                         if ((Dest >= 2) && (Dest <=10))\r
2780                                 SavePreviousPC();\r
2781 \r
2782                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
2783 \r
2784                         if (mode<2)\r
2785                         {\r
2786                                 switch (type)\r
2787                                 {\r
2788                                         case 0:\r
2789                                                 TimingCycles += 10 ;\r
2790                                                 break ;\r
2791                                         case 1:\r
2792                                         case 3:\r
2793                                                 TimingCycles += 12 ;\r
2794                                                 break ;\r
2795                                         case 2:\r
2796                                                 TimingCycles += 14 ;\r
2797                                                 break ;\r
2798                                 }\r
2799                         }\r
2800                         else\r
2801                         {\r
2802                                 if (type != 0)\r
2803                                         TimingCycles += 12 ;\r
2804                                 else\r
2805                                         TimingCycles += 8 ;\r
2806                         }\r
2807 \r
2808                         /* Only need this sorted out if a register is involved */\r
2809 \r
2810                         if (Dest < 7)\r
2811                         {\r
2812                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
2813                                 fprintf(fp, "\t\t and   ebx, byte 7\n");\r
2814                         }\r
2815 \r
2816                         /* Get bit number and create mask in ECX */\r
2817 \r
2818                         Memory_Fetch('W',ECX,FALSE);\r
2819                         fprintf(fp, "\t\t add   esi,byte 2\n");\r
2820 \r
2821                         if (Size == 'L')\r
2822                                 fprintf(fp, "\t\t and   ecx, byte 31\n");\r
2823                         else\r
2824                                 fprintf(fp, "\t\t and   ecx, byte 7\n");\r
2825 \r
2826                  #ifdef QUICKZERO\r
2827                         fprintf(fp,"\t\t mov   eax,1\n");\r
2828                  #else\r
2829                                 fprintf(fp,"\t\t xor   eax,eax\n");\r
2830                                 fprintf(fp,"\t\t inc   eax\n");\r
2831                  #endif\r
2832 \r
2833                         fprintf(fp,"\t\t shl   eax,cl\n");\r
2834                         fprintf(fp,"\t\t mov   ecx,eax\n");\r
2835 \r
2836                         if (mode != 0)\r
2837                                 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",TRUE);\r
2838 \r
2839                         /* All commands copy existing bit to Zero Flag */\r
2840 \r
2841                         Label = GenerateLabel(0,1);\r
2842 \r
2843                         fprintf(fp,"\t\t or    edx,byte 40h\t; Set Zero Flag\n");\r
2844                         fprintf(fp,"\t\t test  %s,%s\n",EAXReg,ECXReg);\r
2845                         fprintf(fp,"\t\t jz    short %s\n",Label);\r
2846                         fprintf(fp,"\t\t xor   edx,byte 40h\t; Clear Zero Flag\n");\r
2847                         fprintf(fp,"%s:\n",Label);\r
2848 \r
2849                         /* Some then modify the data */\r
2850 \r
2851                         switch (type)\r
2852                         {\r
2853                                 case 0: /* btst*/\r
2854                                         break;\r
2855 \r
2856                                 case 1: /* bchg*/\r
2857                                         fprintf(fp,"\t\t xor   %s,%s\n",EAXReg,ECXReg);\r
2858                                         break;\r
2859 \r
2860                                 case 2: /* bclr*/\r
2861                                         fprintf(fp,"\t\t not   ecx\n");\r
2862                                         fprintf(fp,"\t\t and   %s,%s\n",EAXReg,ECXReg);\r
2863                                         break;\r
2864 \r
2865                                 case 3: /* bset*/\r
2866                                         fprintf(fp,"\t\t or    %s,%s\n",EAXReg,ECXReg);\r
2867                                         break;\r
2868                         }\r
2869 \r
2870                         if ((mode !=0) && (type != 0))\r
2871                                 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",TRUE);\r
2872 \r
2873                         Completed();\r
2874                 }\r
2875 \r
2876                 OpcodeArray[Opcode] = BaseCode ;\r
2877         }\r
2878 }\r
2879 \r
2880 \r
2881 void bitstatic(void) /* static non-immediate bit operations*/\r
2882 {\r
2883         int type, mode, dreg ;\r
2884 \r
2885         for (type = 0 ; type < 4 ; type++)\r
2886                 for (mode = 0 ; mode < 8 ;mode++)\r
2887                         for (dreg = 0 ; dreg < 8 ;dreg++)\r
2888                                 dump_bit_static( type, mode, dreg ) ;\r
2889 }\r
2890 \r
2891 /*\r
2892  * Move Peripheral\r
2893  *\r
2894  */\r
2895 \r
2896 void movep(void)\r
2897 {\r
2898         int sreg,dir,leng,dreg ;\r
2899         int     Opcode, BaseCode ;\r
2900 \r
2901         for (sreg = 0 ; sreg < 8 ; sreg++)\r
2902         {\r
2903                 for (dir = 0 ; dir < 2 ; dir++)\r
2904                 {\r
2905                         for (leng = 0 ; leng < 2 ; leng++)\r
2906                         {\r
2907                                 for (dreg = 0 ; dreg < 8 ; dreg++)\r
2908                                 {\r
2909                                         Opcode = 0x0108 | (sreg<<9) | (dir<<7) | (leng<<6) | dreg;\r
2910                                         BaseCode = Opcode & 0x01c8 ;\r
2911                                         if (OpcodeArray[BaseCode] == -2)\r
2912                                         {\r
2913                                                 Align();\r
2914                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
2915                                                 SavePreviousPC();\r
2916                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
2917 \r
2918                                                 if (leng == 0) /* word */\r
2919                                                         TimingCycles += 16 ;\r
2920                                                 else\r
2921                                                         TimingCycles += 24 ;\r
2922 \r
2923                                                 /* Save Flags Register (so we only do it once) */\r
2924 \r
2925                                                 fprintf(fp, "\t\t push  edx\n");\r
2926 \r
2927                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
2928                                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
2929 \r
2930                                                 /* Get Address to Read/Write in EDI */\r
2931 \r
2932                                                 EffectiveAddressCalculate(5,'L',EBX,FALSE);\r
2933 \r
2934                                                 fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
2935                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
2936 \r
2937 \r
2938                                                 if (dir == 0) /* from memory to register*/\r
2939                                                 {\r
2940                                                         Memory_Read('B',EDI,"-BC-SDB",2);               /* mask first call */\r
2941                                                         fprintf(fp,"\t\t mov   bh,al\n");\r
2942                                                         fprintf(fp,"\t\t add   edi,byte 2\n");\r
2943                                                         Memory_Read('B',EDI,"-BC-SDB",0);               /* not needed then */\r
2944                                                         fprintf(fp,"\t\t mov   bl,al\n");\r
2945 \r
2946                                                         if (leng == 0) /* word d(Ax) into Dx.W*/\r
2947                                                         {\r
2948                                                                 fprintf(fp,"\t\t mov   [%s+ecx*4],bx\n",REG_DAT);\r
2949                                                         }\r
2950                                                         else /* long d(Ax) into Dx.L*/\r
2951                                                         {\r
2952                                                                 fprintf(fp,"\t\t add   edi,byte 2\n");\r
2953                                                                 fprintf(fp,"\t\t shl   ebx,16\n");\r
2954                                                                 Memory_Read('B',EDI,"-BC-SDB",0);\r
2955                                                                 fprintf(fp,"\t\t mov   bh,al\n");\r
2956                                                                 fprintf(fp,"\t\t add   edi,byte 2\n");\r
2957                                                                 Memory_Read('B',EDI,"-BC-S-B",0);\r
2958                                                                 fprintf(fp,"\t\t mov   bl,al\n");\r
2959                                                                 fprintf(fp,"\t\t mov   [%s+ecx*4],ebx\n",REG_DAT);\r
2960                                                         }\r
2961                                                 }\r
2962                                                 else /* Register to Memory*/\r
2963                                                 {\r
2964                                                         fprintf(fp,"\t\t mov   eax,[%s+ecx*4]\n",REG_DAT);\r
2965 \r
2966                                                         /* Move bytes into Line */\r
2967 \r
2968                                                         if (leng == 1)\r
2969                                                                 fprintf(fp,"\t\t rol   eax,byte 8\n");\r
2970                                                         else\r
2971                                                                 fprintf(fp,"\t\t rol   eax,byte 24\n");\r
2972 \r
2973                                                         Memory_Write('B',EDI,EAX,"A---SDB",2); /* Mask First */\r
2974                                                         fprintf(fp,"\t\t add   edi,byte 2\n");\r
2975                                                         fprintf(fp,"\t\t rol   eax,byte 8\n");\r
2976 \r
2977                                                         if (leng == 1) /* long*/\r
2978                                                         {\r
2979                                                                 Memory_Write('B',EDI,EAX,"A---SDB",0);\r
2980                                                                 fprintf(fp,"\t\t add   edi,byte 2\n");\r
2981                                                                 fprintf(fp,"\t\t rol   eax,byte 8\n");\r
2982                                                                 Memory_Write('B',EDI,EAX,"A---SDB",0);\r
2983                                                                 fprintf(fp,"\t\t add   edi,byte 2\n");\r
2984                                                                 fprintf(fp,"\t\t rol   eax,byte 8\n");\r
2985                                                         }\r
2986                                                         Memory_Write('B',EDI,EAX,"A---S-B",0);\r
2987                                                 }\r
2988 \r
2989                                                 fprintf(fp, "\t\t pop   edx\n");\r
2990                                                 Completed();\r
2991                                         }\r
2992 \r
2993                                         OpcodeArray[Opcode] = BaseCode ;\r
2994                                 }\r
2995                         }\r
2996                 }\r
2997         }\r
2998 }\r
2999 \r
3000 void movecodes(int allowfrom[],int allowto[],int Start,char Size) /* MJC */\r
3001 {\r
3002         int Opcode;\r
3003         int Src,Dest;\r
3004         int SaveEDX;\r
3005         int BaseCode;\r
3006 \r
3007         for (Opcode=Start;Opcode<Start+0x1000;Opcode++)\r
3008         {\r
3009                 /* Mask our Registers */\r
3010 \r
3011                 BaseCode = Opcode & (Start + 0x1f8);\r
3012 \r
3013                 /* Unless Mode = 7 */\r
3014 \r
3015                 if ((BaseCode & 0x38)  == 0x38)  BaseCode |= (Opcode & 7);\r
3016                 if ((BaseCode & 0x1c0) == 0x1c0) BaseCode |= (Opcode & 0xE00);\r
3017 \r
3018                 /* If mode = 3 or 4 and Size = byte and register = A7 */\r
3019                 /* then make it a separate code                                                   */\r
3020 \r
3021 #ifdef  A7ROUTINE\r
3022                 if (Size == 'B')\r
3023                 {\r
3024                         if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27))\r
3025                         {\r
3026                                 BaseCode |= 0x07;\r
3027                         }\r
3028 \r
3029                         if (((Opcode & 0xFC0) == 0xEC0) || ((Opcode & 0xFC0) == 0xF00))\r
3030                         {\r
3031                                 BaseCode |= 0x0E00;\r
3032                         }\r
3033                 }\r
3034 #endif\r
3035 \r
3036                 /* If Source = Data or Address register - combine into same routine */\r
3037 \r
3038                 if (((Opcode & 0x38) == 0x08) && (allowfrom[1]))\r
3039                 {\r
3040                         BaseCode &= 0xfff7;\r
3041                 }\r
3042 \r
3043                 if (OpcodeArray[BaseCode] == -2)\r
3044                 {\r
3045                         Src  = EAtoAMN(Opcode, FALSE);\r
3046                         Dest = EAtoAMN(Opcode >> 6, TRUE);\r
3047 \r
3048                         if ((allowfrom[(Src & 15)]) && (allowto[(Dest & 15)]))\r
3049                         {\r
3050                                 /* If we are not going to calculate the flags */\r
3051                                 /* we need to preserve the existing ones                */\r
3052 \r
3053                                 SaveEDX = (Dest == 1);\r
3054 \r
3055                                 Align();\r
3056                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3057 \r
3058                                 if (((Src >= 2) && (Src <= 10)) || ((Dest >= 2) && (Dest <=10)))\r
3059                                         SavePreviousPC();\r
3060 \r
3061                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3062 \r
3063 \r
3064                                 TimingCycles += 4 ;\r
3065 \r
3066                                 if (Src < 7)\r
3067                                 {\r
3068                                         if (Dest < 7)\r
3069                                         {\r
3070                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
3071 \r
3072                                                 if ((Src == 0) && allowfrom[1])\r
3073                                                         fprintf(fp, "\t\t and   ebx,byte 15\n");\r
3074                                                 else\r
3075                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
3076 \r
3077                                                 EffectiveAddressRead(Src,Size,EBX,EAX,"--CDS-B",SaveEDX);\r
3078                                         }\r
3079                                         else\r
3080                                         {\r
3081                                                 if ((Src == 0) && allowfrom[1])\r
3082                                                         fprintf(fp, "\t\t and   ecx,byte 15\n");\r
3083                                                 else\r
3084                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
3085 \r
3086                                                 EffectiveAddressRead(Src,Size,ECX,EAX,"---DS-B",SaveEDX);\r
3087                                         }\r
3088                                 }\r
3089                                 else\r
3090                                 {\r
3091                                         if (Dest < 7)\r
3092                                                 EffectiveAddressRead(Src,Size,EBX,EAX,"--CDS-B",SaveEDX);\r
3093                                         else\r
3094                                                 EffectiveAddressRead(Src,Size,EBX,EAX,"---DS-B",SaveEDX);\r
3095                                 }\r
3096 \r
3097                                 /* No flags if Destination Ax */\r
3098 \r
3099                                 if (!SaveEDX)\r
3100                                 {\r
3101                                         SetFlags(Size,EAX,TRUE,FALSE,TRUE);\r
3102                                 }\r
3103 \r
3104                                 if (Dest < 7)\r
3105                                 {\r
3106                                         fprintf(fp, "\t\t shr   ecx,9\n");\r
3107                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
3108                                 }\r
3109 \r
3110                                 EffectiveAddressWrite(Dest,Size,ECX,TRUE,"---DS-B",SaveEDX);\r
3111 \r
3112                                 Completed();\r
3113                         }\r
3114                         else\r
3115                         {\r
3116                                 BaseCode = -1; /* Invalid Code */\r
3117                         }\r
3118                 }\r
3119                 else\r
3120                 {\r
3121                         BaseCode = OpcodeArray[BaseCode];\r
3122                 }\r
3123 \r
3124                 if (OpcodeArray[Opcode] < 0)\r
3125                         OpcodeArray[Opcode] = BaseCode;\r
3126         }\r
3127 }\r
3128 \r
3129 void moveinstructions(void)\r
3130 {\r
3131         int allowfrom[] = {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0};\r
3132         int allowto[]   = {1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0};\r
3133 \r
3134         /* For Byte */\r
3135 \r
3136         movecodes(allowfrom,allowto,0x1000,'B');\r
3137 \r
3138         /* For Word & Long */\r
3139 \r
3140         allowto[1] = 1;\r
3141         movecodes(allowfrom,allowto,0x2000,'L');\r
3142         movecodes(allowfrom,allowto,0x3000,'W');\r
3143 }\r
3144 \r
3145 /*\r
3146  *\r
3147  * Opcodes 5###\r
3148  *\r
3149  * ADDQ,SUBQ,Scc and DBcc\r
3150  *\r
3151  */\r
3152 \r
3153 void opcode5(void)\r
3154 {\r
3155         /* ADDQ,SUBQ,Scc and DBcc */\r
3156 \r
3157         int allowtoScc[]        = {1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0};\r
3158         int allowtoADDQ[]  = {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0};\r
3159         int Opcode,BaseCode;\r
3160         char Label[32];\r
3161         char Label2[32];\r
3162         char Size=' ';\r
3163         char* Regname="";\r
3164         char* RegnameECX="";\r
3165 \r
3166         for (Opcode = 0x5000;Opcode < 0x6000;Opcode++)\r
3167         {\r
3168                 if ((Opcode & 0xc0) == 0xc0)\r
3169                 {\r
3170                         /* Scc or DBcc */\r
3171 \r
3172                         BaseCode = Opcode & 0x5FF8;\r
3173                         if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7);\r
3174 \r
3175                         /* If mode = 3 or 4 and register = A7 */\r
3176                         /* then make it a separate code          */\r
3177 \r
3178 #ifdef  A7ROUTINE\r
3179                         if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27))\r
3180                         {\r
3181                                 BaseCode |= 0x07;\r
3182                         }\r
3183 #endif\r
3184 \r
3185                         if (OpcodeArray[BaseCode] == -2)\r
3186                         {\r
3187                                 OpcodeArray[BaseCode] = BaseCode;\r
3188 \r
3189                                 if ((BaseCode & 0x38) == 0x8)\r
3190                                 {\r
3191                                         /* DBcc */\r
3192 \r
3193                                         Align();\r
3194                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3195 \r
3196                                         TimingCycles += 10 ;\r
3197 \r
3198 \r
3199                                         strcpy(Label,GenerateLabel(BaseCode,1)) ;\r
3200                                         strcpy(Label2,ConditionDecode((Opcode >> 8) & 0x0F,TRUE));\r
3201 \r
3202                                         /* False - Decrement Counter - Loop if not -1 */\r
3203 \r
3204                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
3205                                         fprintf(fp, "\t\t mov   ax,[%s+ecx*4]\n",REG_DAT);\r
3206                                         fprintf(fp, "\t\t dec   ax\n");\r
3207                                         fprintf(fp, "\t\t mov   [%s+ecx*4],ax\n",REG_DAT);\r
3208                                         fprintf(fp, "\t\t inc   ax\t\t; Is it -1\n");\r
3209                                         fprintf(fp, "\t\t jz    short %s\n",Label);\r
3210 \r
3211                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3212                                         Memory_Fetch('W',EAX,TRUE);\r
3213                                         fprintf(fp, "\t\t add   esi,eax\n");\r
3214                                         Completed();\r
3215 \r
3216                                         /* True - Exit Loop */\r
3217                                         fprintf(fp, "%s:\n",Label);\r
3218 \r
3219                                         fprintf(fp, "%s:\n",Label2);\r
3220                                         fprintf(fp, "\t\t add   esi,byte 4\n");\r
3221                                         TimingCycles += 2 ;\r
3222 \r
3223                                         Completed();\r
3224                                 }\r
3225                                 else\r
3226                                 {\r
3227                                         /* Scc */\r
3228 \r
3229                                         int  Dest = EAtoAMN(Opcode, FALSE);\r
3230 \r
3231                                         if (allowtoScc[(Dest & 15)])\r
3232                                         {\r
3233                                                 Align();\r
3234                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3235 \r
3236                                                 if ((Dest >= 2) && (Dest <=10))\r
3237                                                         SavePreviousPC();\r
3238 \r
3239                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3240 \r
3241                                                 if (Dest > 1)\r
3242                                                         TimingCycles += 8 ;\r
3243                                                 else\r
3244                                                         TimingCycles += 4 ;\r
3245 \r
3246                                                 if (Dest < 7)\r
3247                                                 {\r
3248                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
3249                                                 }\r
3250 \r
3251                                                 if (Dest > 1)\r
3252                                                 {\r
3253                                                         EffectiveAddressCalculate(Dest,'B',ECX,TRUE);\r
3254         /* ASG - no longer need to mask addresses here */\r
3255 /*                                                      fprintf(fp,"\t\t and   edi,0FFFFFFh\n");*/\r
3256                                                 }\r
3257 \r
3258                                                 ConditionCheck((Opcode >> 8) & 0x0F,"AL");\r
3259 \r
3260                                                 EffectiveAddressWrite(Dest,'B',ECX,FALSE,"---DS-B",TRUE);\r
3261 \r
3262                                                 /* take advantage of AL being 0 for false, 0xff for true */\r
3263                                                 /* need to add 2 cycles if register and condition is true */\r
3264 \r
3265                                                 if (Dest == 0)\r
3266                                                 {\r
3267                                                         fprintf(fp, "\t\t and   eax,byte 2\n");\r
3268                                                         fprintf(fp, "\t\t add   eax,byte %d\n",TimingCycles);\r
3269                                                         fprintf(fp, "\t\t sub   dword [%s],eax\n",ICOUNT);\r
3270 \r
3271                                                         TimingCycles = -1;\r
3272                                                 }\r
3273                                                 Completed();\r
3274                                         }\r
3275                                         else\r
3276                                         {\r
3277                                                 OpcodeArray[BaseCode] = -1;\r
3278                                                 BaseCode = -1;\r
3279                                         }\r
3280                                 }\r
3281                         }\r
3282                         else\r
3283                         {\r
3284                                 BaseCode = OpcodeArray[BaseCode];\r
3285                         }\r
3286 \r
3287                         OpcodeArray[Opcode] = BaseCode;\r
3288                 }\r
3289                 else\r
3290                 {\r
3291                         /* ADDQ or SUBQ */\r
3292 \r
3293                         BaseCode = Opcode & 0x51F8;\r
3294                         if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7);\r
3295 \r
3296                         /* Special for Address Register Direct - Force LONG */\r
3297 \r
3298                         if ((Opcode & 0x38) == 0x8) BaseCode = ((BaseCode & 0xFF3F) | 0x80);\r
3299 \r
3300 \r
3301                         /* If mode = 3 or 4 and Size = byte and register = A7 */\r
3302                         /* then make it a separate code                                                   */\r
3303 \r
3304 #ifdef  A7ROUTINE\r
3305                         if ((Opcode & 0xC0) == 0)\r
3306                         {\r
3307                                 if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27))\r
3308                                 {\r
3309                                         BaseCode |= 0x07;\r
3310                                 }\r
3311                         }\r
3312 #endif\r
3313 \r
3314                         if (OpcodeArray[BaseCode] == -2)\r
3315                         {\r
3316                                 char *Operation;\r
3317                                 int Dest = EAtoAMN(Opcode, FALSE);\r
3318                                 int SaveEDX = (Dest == 1);\r
3319 \r
3320                                 if (allowtoADDQ[(Dest & 15)])\r
3321                                 {\r
3322                                         switch (BaseCode & 0xC0)\r
3323                                         {\r
3324                                                 case 0:\r
3325                                                         Size = 'B';\r
3326                                                         Regname = regnamesshort[0];\r
3327                                                         RegnameECX = regnamesshort[ECX];\r
3328                                                         break;\r
3329 \r
3330                                                 case 0x40:\r
3331                                                         Size = 'W';\r
3332                                                         Regname = regnamesword[0];\r
3333                                                         RegnameECX = regnamesword[ECX];\r
3334                                                         break;\r
3335 \r
3336                                                 case 0x80:\r
3337                                                         Size = 'L';\r
3338                                                         Regname = regnameslong[0];\r
3339                                                         RegnameECX = regnameslong[ECX];\r
3340                                                         break;\r
3341                                         }\r
3342 \r
3343                                         OpcodeArray[BaseCode] = BaseCode;\r
3344 \r
3345                                         Align();\r
3346                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3347 \r
3348                                         if ((Dest >= 2) && (Dest <=10))\r
3349                                                 SavePreviousPC();\r
3350 \r
3351                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3352 \r
3353                                         if (Dest == 0) /* write to Dx */\r
3354                                         {\r
3355                                                 if (Size != 'L')\r
3356                                                         TimingCycles += 4 ;\r
3357                                                 else\r
3358                                                         TimingCycles += 8 ;\r
3359                                         }\r
3360 \r
3361                                         if (Dest == 1)\r
3362                                         {\r
3363                                                 if ((Size == 'L') || (Opcode & 0x100)) /* if long or SUBQ */\r
3364                                                         TimingCycles += 8 ;\r
3365                                                 else\r
3366                                                         TimingCycles += 4 ;\r
3367                                         }\r
3368 \r
3369                                         if (Dest > 1) /* write to mem */\r
3370                                         {\r
3371                                                 if (Size != 'L')\r
3372                                                         TimingCycles += 8 ;\r
3373                                                 else\r
3374                                                         TimingCycles += 12 ;\r
3375                                         }\r
3376 \r
3377                                         if (Dest < 7)\r
3378                                         {\r
3379                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
3380                                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
3381                                         }\r
3382 \r
3383                                         if (Dest > 1)\r
3384                                         {\r
3385                                                 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",SaveEDX);\r
3386                                         }\r
3387 \r
3388                                         /* Sub Immediate from Opcode */\r
3389 \r
3390                                         fprintf(fp, "\t\t shr   ecx,9\n");\r
3391 \r
3392                                         Immediate8();\r
3393 \r
3394                                         if (Opcode & 0x100)\r
3395                                         {\r
3396                                                 /* SUBQ */\r
3397                                                 Operation = "sub";\r
3398                                         }\r
3399                                         else\r
3400                                         {\r
3401                                                 /* ADDQ */\r
3402                                                 Operation = "add";\r
3403                                         }\r
3404 \r
3405                                         /* For Data or Address register, operate directly */\r
3406                                         /* on the memory location. Don't load into EAX   */\r
3407 \r
3408                                         if (Dest < 2)\r
3409                                         {\r
3410                                                 if (Dest == 0)\r
3411                                                 {\r
3412                                                         fprintf(fp, "\t\t %s   [%s+ebx*4],%s\n",Operation,REG_DAT,RegnameECX);\r
3413                                                 }\r
3414                                                 else\r
3415                                                 {\r
3416                                                         fprintf(fp, "\t\t %s   [%s+ebx*4],%s\n",Operation,REG_ADD,RegnameECX);\r
3417                                                 }\r
3418                                         }\r
3419                                         else\r
3420                                         {\r
3421                                                 fprintf(fp, "\t\t %s   %s,%s\n",Operation,Regname,RegnameECX);\r
3422                                         }\r
3423 \r
3424                                         /* No Flags for Address Direct */\r
3425 \r
3426                                         if (!SaveEDX)\r
3427                                         {\r
3428                                                 /* Directly after ADD or SUB, so test not needed */\r
3429 \r
3430                                                 SetFlags(Size,EAX,FALSE,TRUE,TRUE);\r
3431                                         }\r
3432 \r
3433                                         if (Dest > 1)\r
3434                                         {\r
3435                                                 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",FALSE);\r
3436                                         }\r
3437 \r
3438                                         Completed();\r
3439                                 }\r
3440                                 else\r
3441                                 {\r
3442                                         OpcodeArray[BaseCode] = -1;\r
3443                                         BaseCode = -1;\r
3444                                 }\r
3445                         }\r
3446                         else\r
3447                         {\r
3448                                 BaseCode = OpcodeArray[BaseCode];\r
3449                         }\r
3450 \r
3451                         OpcodeArray[Opcode] = BaseCode;\r
3452                 }\r
3453         }\r
3454 }\r
3455 \r
3456 /*\r
3457  * Branch Instructions\r
3458  *\r
3459  * BSR, Bcc\r
3460  *\r
3461  */\r
3462 \r
3463 void branchinstructions(void)\r
3464 {\r
3465         int Opcode,BaseCode;\r
3466         int Counter;\r
3467         char *Label;\r
3468         char jmpLabel[40] ;\r
3469 \r
3470         for (Opcode = 0x60;Opcode < 0x70;Opcode++)\r
3471         {\r
3472                 /* Displacement = 0 -> 16 Bit displacement */\r
3473 \r
3474                 BaseCode = Opcode * 0x100;\r
3475                 OpcodeArray[BaseCode] = BaseCode;\r
3476 \r
3477                 Align();\r
3478                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3479                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3480 \r
3481                 TimingCycles += 10 ;\r
3482 \r
3483                 if (Opcode == 0x60)\r
3484                 {\r
3485                         Memory_Fetch('W',EAX,TRUE);\r
3486                         fprintf(fp, "\t\t add   esi,eax\n");\r
3487                         MemoryBanking(BaseCode);\r
3488                         Completed();\r
3489                 }\r
3490                 else\r
3491                 {\r
3492                         if (Opcode != 0x61)\r
3493                         {\r
3494                                 Label = ConditionDecode(Opcode & 0x0F,TRUE);\r
3495 \r
3496                                 /* Code for Failed branch */\r
3497 \r
3498                                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
3499 \r
3500                                 /* 2 less cycles for Failure */\r
3501 \r
3502                                 TimingCycles -= 2;\r
3503                                 Completed();\r
3504                                 TimingCycles += 2;\r
3505 \r
3506                                 /* Successful Branch */\r
3507 \r
3508                                 Align();\r
3509                                 fprintf(fp, "%s:\n",Label);\r
3510 \r
3511                                 Memory_Fetch('W',EAX,TRUE);\r
3512                                 fprintf(fp, "\t\t add   esi,eax\n");\r
3513                                 MemoryBanking(BaseCode+2);\r
3514                                 Completed();\r
3515 \r
3516                         }\r
3517                         else\r
3518                         {\r
3519                                 /* BSR - Special Case */\r
3520 \r
3521                                 TimingCycles += 8 ;\r
3522 \r
3523                                 Memory_Fetch('W',EBX,TRUE);\r
3524                                 fprintf(fp, "\t\t add   ebx,esi\n");\r
3525 \r
3526                                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
3527                                 PushPC(ECX,EAX,"-B-DS-B",1);\r
3528 \r
3529                                 fprintf(fp, "\t\t mov   esi,ebx\n");\r
3530                                 MemoryBanking(BaseCode+3);\r
3531                                 Completed();\r
3532                         }\r
3533                 }\r
3534 \r
3535                 /* 8 Bit Displacement */\r
3536 \r
3537                 Align();\r
3538                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode+1,0));\r
3539                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3540 \r
3541                 TimingCycles += 10 ;\r
3542 \r
3543                 if (Opcode > 0x60)\r
3544                 {\r
3545                         if (Opcode != 0x61)\r
3546                         {\r
3547                                 Label = ConditionDecode(Opcode & 0x0F,TRUE);\r
3548 \r
3549                                 /* Code for Failed branch */\r
3550 \r
3551                                 TimingCycles -= 2;\r
3552                                 Completed();\r
3553                                 TimingCycles += 2;\r
3554 \r
3555                                 /* Successful Branch */\r
3556 \r
3557                                 Align();\r
3558                                 fprintf(fp, "%s:\n",Label);\r
3559                         }\r
3560                         else\r
3561                         {\r
3562                                 /* BSR - Special Case */\r
3563 \r
3564                                 TimingCycles += 8 ;\r
3565 \r
3566                                 PushPC(EDI,EBX,"--CDS-B",1);\r
3567                         }\r
3568                 }\r
3569 \r
3570                 /* Common Ending */\r
3571 \r
3572                 fprintf(fp, "\t\t movsx eax,cl               ; Sign Extend displacement\n");\r
3573                 fprintf(fp, "\t\t add   esi,eax\n");\r
3574                 MemoryBanking(BaseCode+5);\r
3575                 Completed();\r
3576 \r
3577                 /* Fill up Opcode Array */\r
3578 \r
3579                 for (Counter=1;Counter<0x100;Counter++)\r
3580                         OpcodeArray[BaseCode+Counter] = BaseCode+1;\r
3581 \r
3582                 if(CPU==2)\r
3583                 {\r
3584 \r
3585                         /* 8 bit 0xff & 68020 instruction - 32 bit displacement */\r
3586 \r
3587                   Align();\r
3588                   fprintf(fp, "%s:\n",GenerateLabel(BaseCode+0xff,0));\r
3589                   sprintf( jmpLabel, GenerateLabel(BaseCode+0xff,1) ) ;\r
3590                   fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3591 \r
3592                   TimingCycles += 10 ;\r
3593 \r
3594                   if (Opcode == 0x60)\r
3595                   {\r
3596                           /* bra - always branch */\r
3597                           Memory_Fetch('L',EAX,FALSE);\r
3598                           fprintf(fp, "\t\t add   esi,eax\n");\r
3599                           MemoryBanking(BaseCode+6);\r
3600                           Completed();\r
3601                   }\r
3602                   else\r
3603                   {\r
3604                           if (Opcode != 0x61)\r
3605                           {\r
3606                                   Label = ConditionDecode(Opcode & 0x0F,TRUE);\r
3607 \r
3608                                   /* Code for Failed branch */\r
3609                                   fprintf(fp, "\t\t add   esi,byte 4\n");\r
3610 \r
3611                                   TimingCycles -= 2;\r
3612                                   Completed();\r
3613                                   TimingCycles += 2;\r
3614 \r
3615                                   /* Successful Branch */\r
3616                                   Align();\r
3617                                   fprintf(fp, "%s:\n",Label);\r
3618 \r
3619                                   Memory_Fetch('L',EAX,FALSE);\r
3620                                   fprintf(fp, "\t\t add   esi,eax\n");\r
3621                                   MemoryBanking(BaseCode+8);\r
3622                                   Completed();\r
3623                           }\r
3624                           else\r
3625                           {\r
3626                                   /* BSR - Special Case */\r
3627 \r
3628                                   TimingCycles += 8 ;\r
3629 \r
3630                                   Memory_Fetch('L',EBX,TRUE);\r
3631                                   fprintf(fp, "\t\t add   ebx,esi\n");\r
3632 \r
3633                                   fprintf(fp, "\t\t add   esi,byte 4\n");\r
3634                                   PushPC(ECX,EAX,"-B-DS-B",1);\r
3635 \r
3636                                   fprintf(fp, "\t\t mov   esi,ebx\n");\r
3637                                   MemoryBanking(BaseCode+9);\r
3638                                   Completed();\r
3639                           }\r
3640                   }\r
3641 \r
3642                   OpcodeArray[BaseCode+0xff] = BaseCode+0xff;\r
3643                 }\r
3644         }\r
3645 }\r
3646 \r
3647 /*\r
3648  * Move Quick Commands\r
3649  *\r
3650  * Fairly simple, as only allowed to Data Registers\r
3651  *\r
3652  */\r
3653 \r
3654 void moveq(void)\r
3655 {\r
3656         int Count;\r
3657 \r
3658         /* The Code */\r
3659 \r
3660         Align();\r
3661         fprintf(fp, "%s:\n",GenerateLabel(0x7000,0));\r
3662         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3663 \r
3664         TimingCycles += 4 ;\r
3665 \r
3666         fprintf(fp, "\t\t movsx eax,cl\n");\r
3667         fprintf(fp, "\t\t shr   ecx,9\n");\r
3668         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
3669         SetFlags('L',EAX,TRUE,FALSE,FALSE);\r
3670         EffectiveAddressWrite(0,'L',ECX,TRUE,"---DS-B",FALSE);\r
3671         Completed();\r
3672 \r
3673         /* Set OpcodeArray (Not strictly correct, since some are illegal!) */\r
3674 \r
3675         for (Count=0x7000;Count<0x8000;Count++)\r
3676         {\r
3677                 OpcodeArray[Count] = 0x7000;\r
3678         }\r
3679 }\r
3680 \r
3681 /*\r
3682  * Extended version of Add & Sub commands\r
3683  *\r
3684  */\r
3685 \r
3686 void addx_subx(void)\r
3687 {\r
3688         int     Opcode, BaseCode ;\r
3689         int     regx,type,leng,rm,regy,mode ;\r
3690         int ModeModX;\r
3691         int ModeModY;\r
3692         char  Size=' ' ;\r
3693         char * Regname="" ;\r
3694         char * RegnameEBX="" ;\r
3695         char * Operand="";\r
3696         char * Label;\r
3697 \r
3698         for (type = 0 ; type < 2 ; type ++) /* 0=subx, 1=addx */\r
3699                 for (regx = 0 ; regx < 8 ; regx++)\r
3700                         for (leng = 0 ; leng < 3 ; leng++)\r
3701                                 for (rm = 0 ; rm < 2 ; rm++)\r
3702                                         for (regy = 0 ; regy < 8 ; regy++)\r
3703                                         {\r
3704                                                 Opcode = 0x9100 | (type<<14) | (regx<<9) | (leng<<6) | (rm<<3) | regy ;\r
3705 \r
3706                                                 BaseCode = Opcode & 0xd1c8 ;\r
3707 \r
3708                                                 ModeModX = 0;\r
3709                                                 ModeModY = 0;\r
3710 \r
3711 #ifdef A7ROUTINE\r
3712                                                 if ((rm == 1) && (leng == 0))\r
3713                                                 {\r
3714                                                         if (regx == 7)\r
3715                                                         {\r
3716                                                                 BaseCode |= (regx << 9);\r
3717                                                                 ModeModY = 16;\r
3718                                                         }\r
3719                                                         if (regy == 7)\r
3720                                                         {\r
3721                                                                 BaseCode |= regy;\r
3722                                                                 ModeModX = 16;\r
3723                                                         }\r
3724                                                 }\r
3725 #endif\r
3726 \r
3727                                                 if (rm == 0)\r
3728                                                         mode = 0 ;\r
3729                                                 else\r
3730                                                         mode = 4 ;\r
3731 \r
3732                                                 switch (leng)\r
3733                                                 {\r
3734                                                         case 0:\r
3735                                                                 Size = 'B';\r
3736                                                                 Regname = regnamesshort[0];\r
3737                                                                 RegnameEBX = regnamesshort[EBX];\r
3738                                                                 break;\r
3739                                                         case 1:\r
3740                                                                 Size = 'W';\r
3741                                                                 Regname = regnamesword[0];\r
3742                                                                 RegnameEBX = regnamesword[EBX];\r
3743                                                                 break;\r
3744                                                         case 2:\r
3745                                                                 Size = 'L';\r
3746                                                                 Regname = regnameslong[0];\r
3747                                                                 RegnameEBX = regnameslong[EBX];\r
3748                                                                 break;\r
3749                                                 }\r
3750 \r
3751                                                 if (OpcodeArray[BaseCode] == -2)\r
3752                                                 {\r
3753                                                         if (type == 0)\r
3754                                                                 Operand = "sbb";\r
3755                                                         else\r
3756                                                                 Operand = "adc";\r
3757 \r
3758                                                         Align();\r
3759                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3760 \r
3761                                                         if (mode == 4)\r
3762                                                                 SavePreviousPC();\r
3763 \r
3764                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3765 \r
3766                                                         /* don't add in EA timing for ADDX,SUBX */\r
3767 \r
3768                                                         AddEACycles = 0 ;\r
3769 \r
3770                                                         if (rm == 0) /* reg to reg */\r
3771                                                         {\r
3772                                                                 if (Size != 'L')\r
3773                                                                         TimingCycles += 4 ;\r
3774                                                                 else\r
3775                                                                         TimingCycles += 8 ;\r
3776                                                         }\r
3777                                                         else\r
3778                                                         {\r
3779                                                                 if (Size != 'L')\r
3780                                                                         TimingCycles += 18 ;\r
3781                                                                 else\r
3782                                                                         TimingCycles += 30 ;\r
3783                                                         }\r
3784 \r
3785                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
3786                                                         fprintf(fp, "\t\t and   ebx, byte 7\n");\r
3787                                                         fprintf(fp, "\t\t shr   ecx, byte 9\n");\r
3788                                                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
3789 \r
3790                                                         /* Get Source */\r
3791 \r
3792                                                         EffectiveAddressRead(mode+ModeModX,Size,EBX,EBX,"--CDS-B",FALSE);\r
3793 \r
3794                                                         /* Get Destination (if needed) */\r
3795 \r
3796                                                         if (mode == 4)\r
3797                                                                 EffectiveAddressRead(mode+ModeModY,Size,ECX,EAX,"-BCDSDB",FALSE);\r
3798 \r
3799                                                         /* Copy the X flag into the Carry Flag */\r
3800 \r
3801                                                         CopyX();\r
3802 \r
3803                                                         /* Do the sums */\r
3804 \r
3805                                                         if (mode == 0)\r
3806                                                                 fprintf(fp, "\t\t %s   [%s+ecx*4],%s\n",Operand,REG_DAT,RegnameEBX);\r
3807                                                         else\r
3808                                                                 fprintf(fp, "\t\t %s   %s,%s\n",Operand,Regname,RegnameEBX);\r
3809 \r
3810                                                         /* Preserve old Z flag */\r
3811 \r
3812                                                         fprintf(fp, "\t\t mov   ebx,edx\n");\r
3813 \r
3814                                                         /* Set the Flags */\r
3815 \r
3816                                                         SetFlags(Size,EAX,FALSE,TRUE,FALSE);\r
3817 \r
3818                                                         /* Handle the Z flag */\r
3819 \r
3820                                                         Label = GenerateLabel(0,1);\r
3821 \r
3822                                                         fprintf(fp, "\t\t jnz   short %s\n\n",Label);\r
3823 \r
3824                                                         fprintf(fp, "\t\t and   dl,0BFh       ; Remove Z\n");\r
3825                                                         fprintf(fp, "\t\t and   bl,40h        ; Mask out Old Z\n");\r
3826                                                         fprintf(fp, "\t\t or    dl,bl         ; Copy across\n\n");\r
3827                                                         fprintf(fp, "%s:\n",Label);\r
3828 \r
3829                                                         /* Update the Data (if needed) */\r
3830 \r
3831                                                         if (mode == 4)\r
3832                                                                 EffectiveAddressWrite(mode,Size,ECX,FALSE,"---DS-B",TRUE);\r
3833 \r
3834                                                         Completed();\r
3835                                                 }\r
3836 \r
3837                                                 OpcodeArray[Opcode] = BaseCode ;\r
3838                                         }\r
3839 }\r
3840 \r
3841 /*\r
3842  * Logicals / Simple Maths (+ and -)\r
3843  *\r
3844  * OR,AND,CMP,EOR,ADD and SUB\r
3845  *\r
3846  */\r
3847 \r
3848 void dumpx( int start, int reg, int type, char * Op, int dir, int leng, int mode, int sreg )\r
3849 {\r
3850         int Opcode,BaseCode ;\r
3851         char Size=' ' ;\r
3852         char * RegnameECX="" ;\r
3853         char * Regname="" ;\r
3854         int Dest ;\r
3855         int SaveEDX ;\r
3856         int SaveDir;\r
3857         char * allow="" ;\r
3858         char * allowtypes[] = { "0-23456789ab----", "--2345678-------",\r
3859                 "0123456789ab----", "0-2345678-------"};\r
3860 \r
3861         SaveDir = dir;\r
3862 \r
3863         switch (type)\r
3864         {\r
3865                 case 0: /* or and*/\r
3866                         if (dir == 0)\r
3867                                 allow = allowtypes[0];\r
3868                         else\r
3869                                 allow = allowtypes[1];\r
3870                         break ;\r
3871 \r
3872                 case 1: /* cmp*/\r
3873                         allow = allowtypes[2] ;\r
3874                         break ;\r
3875 \r
3876                 case 2: /* eor*/\r
3877                         allow = allowtypes[3] ;\r
3878                         break ;\r
3879 \r
3880                 case 3: /* adda suba cmpa*/\r
3881                         allow = allowtypes[2] ;\r
3882                         break ;\r
3883 \r
3884                 case 4: /* sub add*/\r
3885                         if (dir == 0)\r
3886                                 allow = allowtypes[0] ;\r
3887                         else\r
3888                                 allow = allowtypes[1] ;\r
3889                         break ;\r
3890         }\r
3891 \r
3892         if ((type == 4) && (dir == 0) && (leng > 0))\r
3893         {\r
3894                 allow = allowtypes[2] ; /* word and long ok*/\r
3895         }\r
3896 \r
3897         Opcode = start | (reg << 9 ) | (dir<<8) | (leng<<6) | (mode<<3) | sreg;\r
3898 \r
3899         BaseCode = Opcode & 0xf1f8;\r
3900 \r
3901         if (mode == 7) BaseCode |= sreg ;\r
3902 \r
3903 #ifdef A7ROUTINE\r
3904         if ((mode == 3 || mode == 4) && ( leng == 0 ) && (sreg == 7 ))\r
3905                 BaseCode |= sreg ;\r
3906 #endif\r
3907 \r
3908 \r
3909 \r
3910         /* If Source = Data or Address register - combine into same routine */\r
3911 \r
3912         if (((Opcode & 0x38) == 0x08) && (allow[1] != '-'))\r
3913         {\r
3914                 BaseCode &= 0xfff7;\r
3915         }\r
3916 \r
3917         Dest = EAtoAMN(Opcode, FALSE);\r
3918         SaveEDX = (Dest == 1) || (type == 3);\r
3919 \r
3920         if (allow[Dest&0xf] != '-')\r
3921         {\r
3922                 if (OpcodeArray[BaseCode] == -2)\r
3923                 {\r
3924                         switch (leng)\r
3925                         {\r
3926                                 case 0:\r
3927                                         Size = 'B';\r
3928                                         Regname = regnamesshort[0];\r
3929                                         RegnameECX = regnamesshort[ECX];\r
3930                                         break;\r
3931                                 case 1:\r
3932                                         Size = 'W';\r
3933                                         Regname = regnamesword[0];\r
3934                                         RegnameECX = regnamesword[ECX];\r
3935                                         break;\r
3936                                 case 2:\r
3937                                         Size = 'L';\r
3938                                         Regname = regnameslong[0];\r
3939                                         RegnameECX = regnameslong[ECX];\r
3940                                         break;\r
3941 \r
3942                                 case 3: /* cmpa adda suba */\r
3943                                         if (dir == 0)\r
3944                                         {\r
3945                                                 Size = 'W';\r
3946                                                 Regname = regnamesword[0];\r
3947                                                 RegnameECX = regnamesword[ECX];\r
3948                                         }\r
3949                                         else\r
3950                                         {\r
3951                                                 Size = 'L';\r
3952                                                 Regname = regnameslong[0];\r
3953                                                 RegnameECX = regnameslong[ECX];\r
3954                                         }\r
3955                                         dir = 0 ;\r
3956                                         break ;\r
3957                         }\r
3958 \r
3959                         Align();\r
3960                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
3961 \r
3962                         if ((Dest >= 2) && (Dest <=10))\r
3963                                 SavePreviousPC();\r
3964 \r
3965                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
3966 \r
3967                         if (dir==0)\r
3968                         {\r
3969                                 if (Size != 'L')\r
3970                                         TimingCycles += 4;\r
3971                                 else\r
3972                                         TimingCycles += 6;\r
3973                         }\r
3974                         else\r
3975                         {\r
3976                                 if (Size != 'L')\r
3977                                         TimingCycles += 8;\r
3978                                 else\r
3979                                         TimingCycles += 12;\r
3980                         }\r
3981 \r
3982                         if ((mode == 0) && (dir==0) && (Size == 'L'))\r
3983                                 TimingCycles += 2 ;\r
3984 \r
3985                         if ((mode == 1) && (dir==0) && (Size != 'L'))\r
3986                                 TimingCycles += 4 ;\r
3987 \r
3988                         if (Dest < 7)    /* Others do not need reg.no. */\r
3989                         {\r
3990                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
3991 \r
3992                                 if ((Dest == 0) & (allow[1] != '-'))\r
3993                                         fprintf(fp, "\t\t and   ebx,byte 15\n");\r
3994                                 else\r
3995                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
3996                         }\r
3997 \r
3998                         fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
3999                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4000 \r
4001                         EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",SaveEDX);\r
4002 \r
4003                         if (dir == 0)\r
4004                         {\r
4005                                 if (type != 3)\r
4006                                 {\r
4007                                         fprintf(fp, "\t\t %s   [%s+ECX*4],%s\n",Op ,REG_DAT ,Regname ) ;\r
4008 \r
4009                                         if (type == 4)\r
4010                                                 SetFlags(Size,EAX,FALSE,TRUE,FALSE);\r
4011                                         else\r
4012                                                 SetFlags(Size,EAX,FALSE,FALSE,FALSE);\r
4013                                 }\r
4014                                 else\r
4015                                 {\r
4016                                         if (Size == 'W')\r
4017                                                 fprintf(fp, "\t\t cwde\n");\r
4018 \r
4019                                         fprintf(fp, "\t\t %s   [%s+ECX*4],EAX\n",Op ,REG_ADD);\r
4020 \r
4021                                         if (Op[0] == 'c')\r
4022                                         {\r
4023                                                 SetFlags('L',EAX,FALSE,FALSE,FALSE);\r
4024                                         }\r
4025                                 }\r
4026                         }\r
4027                         else\r
4028                         {\r
4029                                 fprintf(fp, "\t\t %s   %s,[%s+ECX*4]\n", Op, Regname ,REG_DAT ) ;\r
4030 \r
4031                                 if (type == 4)\r
4032                                         SetFlags(Size,EAX,FALSE,TRUE,TRUE);\r
4033                                 else\r
4034                                         SetFlags(Size,EAX,FALSE,FALSE,TRUE);\r
4035 \r
4036                                 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",FALSE);\r
4037                         }\r
4038                         Completed();\r
4039                 }\r
4040 \r
4041                 OpcodeArray[Opcode] = BaseCode;\r
4042         }\r
4043 \r
4044         dir = SaveDir;\r
4045 }\r
4046 \r
4047 void typelogicalmath(void)\r
4048 {\r
4049         int dir, leng, mode, sreg ,reg ;\r
4050 \r
4051         for (reg = 0 ; reg < 8 ; reg++)\r
4052         {\r
4053                 /* or */\r
4054                 for (dir = 0 ; dir < 2 ; dir++)\r
4055                         for (leng = 0 ; leng < 3; leng++)\r
4056                                 for (mode = 0 ; mode < 8 ; mode++)\r
4057                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
4058                                                 dumpx( 0x8000, reg, 0, "or ", dir, leng, mode, sreg ) ;\r
4059 \r
4060                 /* sub */\r
4061                 for (dir = 0 ; dir < 2 ; dir++)\r
4062                         for (leng = 0 ; leng < 3; leng++)\r
4063                                 for (mode = 0 ; mode < 8 ; mode++)\r
4064                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
4065                                                 dumpx( 0x9000, reg, 4, "sub", dir, leng, mode, sreg ) ;\r
4066 \r
4067                 /* suba */\r
4068 \r
4069                 for (dir = 0 ; dir < 2 ; dir++)\r
4070                         for (mode = 0 ; mode < 8 ; mode++)\r
4071                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4072                                         dumpx( 0x9000, reg, 3, "sub", dir, 3, mode, sreg ) ;\r
4073 \r
4074 \r
4075                 /* cmp */\r
4076                 for (leng = 0 ; leng < 3; leng++)\r
4077                         for (mode = 0 ; mode < 8 ; mode++)\r
4078                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4079                                         dumpx( 0xb000, reg, 1, "cmp", 0, leng, mode, sreg ) ;\r
4080 \r
4081                 /* cmpa */\r
4082 \r
4083                 for (dir = 0 ; dir < 2 ; dir++)\r
4084                         for (mode = 0 ; mode < 8 ; mode++)\r
4085                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4086                                         dumpx( 0xb000, reg, 3, "cmp", dir, 3, mode, sreg ) ;\r
4087 \r
4088                 /* adda */\r
4089 \r
4090                 for (dir = 0 ; dir < 2 ; dir++)\r
4091                         for (mode = 0 ; mode < 8 ; mode++)\r
4092                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4093                                         dumpx( 0xd000, reg, 3, "add", dir, 3, mode, sreg ) ;\r
4094 \r
4095 \r
4096                 /* eor */\r
4097                 for (leng = 0 ; leng < 3; leng++)\r
4098                         for (mode = 0 ; mode < 8 ; mode++)\r
4099                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4100                                         dumpx( 0xb100, reg, 2, "xor", 1, leng, mode, sreg ) ;\r
4101 \r
4102                 /* and */\r
4103                 for (dir = 0 ; dir < 2 ; dir++)\r
4104                         for (leng = 0 ; leng < 3; leng++)\r
4105                                 for (mode = 0 ; mode < 8 ; mode++)\r
4106                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
4107                                                 dumpx( 0xc000, reg, 0, "and", dir, leng, mode, sreg ) ;\r
4108 \r
4109                 /* add  */\r
4110                 for (dir = 0 ; dir < 2 ; dir++)\r
4111                         for (leng = 0 ; leng < 3; leng++)\r
4112                                 for (mode = 0 ; mode < 8 ; mode++)\r
4113                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
4114                                                 dumpx( 0xd000, reg, 4, "add", dir, leng, mode, sreg ) ;\r
4115         }\r
4116 }\r
4117 \r
4118 /*\r
4119  * Single commands missed out by routines above\r
4120  *\r
4121  */\r
4122 \r
4123 void mul(void)\r
4124 {\r
4125         int dreg, type, mode, sreg ;\r
4126         int Opcode, BaseCode ;\r
4127         int Dest ;\r
4128         char allow[] = "0-23456789ab-----" ;\r
4129 \r
4130         for (dreg = 0 ; dreg < 8 ; dreg++)\r
4131                 for (type = 0 ; type < 2 ; type++)\r
4132                         for (mode = 0 ; mode < 8 ; mode++)\r
4133                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4134                                 {\r
4135                                         Opcode = 0xc0c0 | (dreg<<9) | (type<<8) | (mode<<3) | sreg ;\r
4136                                         BaseCode = Opcode & 0xc1f8 ;\r
4137                                         if (mode == 7)\r
4138                                         {\r
4139                                                 BaseCode |= sreg ;\r
4140                                         }\r
4141 \r
4142                                         Dest = EAtoAMN(Opcode, FALSE);\r
4143                                         if (allow[Dest&0x0f] != '-')\r
4144                                         {\r
4145                                                 if (OpcodeArray[ BaseCode ] == -2)\r
4146                                                 {\r
4147                                                         Align();\r
4148                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
4149 \r
4150                                                         if ((Dest >= 2) && (Dest <=10))\r
4151                                                                 SavePreviousPC();\r
4152 \r
4153                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4154 \r
4155                                                         TimingCycles += 70 ;\r
4156 \r
4157                                                         if (mode < 7)\r
4158                                                         {\r
4159                                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
4160                                                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
4161                                                         }\r
4162 \r
4163                                                         fprintf(fp, "\t\t shr   ecx, byte 9\n");\r
4164                                                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
4165 \r
4166                                                         EffectiveAddressRead(Dest,'W',EBX,EAX,"ABCDSDB",FALSE);\r
4167 \r
4168                                                         if (type == 0)\r
4169                                                                 fprintf(fp, "\t\t mul   word [%s+ECX*4]\n",REG_DAT);\r
4170                                                         else\r
4171                                                                 fprintf(fp, "\t\t imul  word [%s+ECX*4]\n",REG_DAT);\r
4172 \r
4173                                                         fprintf(fp, "\t\t shl   edx, byte 16\n");\r
4174                                                         fprintf(fp, "\t\t mov   dx,ax\n");\r
4175                                                         fprintf(fp, "\t\t mov   [%s+ECX*4],edx\n",REG_DAT);\r
4176                                                         SetFlags('L',EDX,TRUE,FALSE,FALSE);\r
4177                                                         Completed();\r
4178                                                 }\r
4179 \r
4180                                                 OpcodeArray[Opcode] = BaseCode ;\r
4181                                         }\r
4182                                 }\r
4183 }\r
4184 \r
4185 void mull(void)\r
4186 {\r
4187         int mode, sreg ;\r
4188         int Opcode, BaseCode ;\r
4189         int Dest ;\r
4190         char allow[] = "0-23456789ab-----" ;\r
4191         char *Label = NULL ;\r
4192 \r
4193         for (mode = 0 ; mode < 8 ; mode++)\r
4194                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4195                 {\r
4196                         Opcode = 0x4c00 | (mode<<3) | sreg ;\r
4197                         BaseCode = Opcode & 0x4c38 ;\r
4198                         if (mode == 7)\r
4199                         {\r
4200                                 BaseCode |= sreg ;\r
4201                         }\r
4202 \r
4203                         Dest = EAtoAMN(Opcode, FALSE);\r
4204                         if (allow[Dest&0x0f] != '-')\r
4205                         {\r
4206                                 if (OpcodeArray[ BaseCode ] == -2)\r
4207                                 {\r
4208                                         TimingCycles += 70 ;\r
4209                                         Align();\r
4210                                         Label = GenerateLabel(BaseCode,0);\r
4211                                         fprintf(fp, "%s:\n",Label);\r
4212                                         if ((Dest >= 2) && (Dest <=10))\r
4213                                                 SavePreviousPC();\r
4214 \r
4215                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4216 \r
4217                                         if (mode < 7)\r
4218                                         {\r
4219                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4220                                         }\r
4221 \r
4222                                         Memory_Fetch('W', EBX, FALSE );                                                 // fetch the next word\r
4223                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4224 \r
4225                                         EffectiveAddressRead(Dest,'L',ECX,EAX,"ABCDSDB",FALSE); // read from the EA\r
4226 \r
4227                                         fprintf(fp, "\t\t mov   ecx,ebx\n");                                    // save 2nd word in ecx\r
4228                                         fprintf(fp, "\t\t shr   ebx,12\n");                                             // ebx = Dl register\r
4229                                         fprintf(fp, "\t\t and   ebx,7\n");                                              // 0-7\r
4230 \r
4231                                         Label = GenerateLabel(BaseCode,1);\r
4232 \r
4233                                         fprintf(fp, "\t\t test  ecx,0x0800\n");                                 // signed/unsigned?\r
4234                                         fprintf(fp, "\t\t jz    short %s\n",Label);                             // skip if unsigned\r
4235 \r
4236                                         fprintf(fp, "\t\t imul   dword [%s+EBX*4]\n",REG_DAT);  // signed 32x32->64\r
4237                                         fprintf(fp, "\t\t jmp   short %s_1\n",Label);                   // skip\r
4238 \r
4239                                 fprintf(fp, "%s:\n",Label);\r
4240                                         fprintf(fp, "\t\t mul  dword [%s+EBX*4]\n",REG_DAT);    // unsigned 32x32->64\r
4241 \r
4242                                 fprintf(fp, "%s_1:\n",Label);\r
4243                                         fprintf(fp, "\t\t mov   [%s+EBX*4],eax\n",REG_DAT);             // store Dl back\r
4244 \r
4245                                         fprintf(fp, "\t\t test  ecx,0x0400\n");                                 // do we care?\r
4246                                         fprintf(fp, "\t\t jz    short %s_2\n",Label);                   // if not, skip\r
4247                                         fprintf(fp, "\t\t and   ecx,7\n");                                              // get Dh register\r
4248                                         fprintf(fp, "\t\t mov   [%s+ECX*4],edx\n",REG_DAT);             // store upper 32 bits\r
4249                                         SetFlags('L',EDX,TRUE,FALSE,FALSE);                                             // set the flags\r
4250                                         fprintf(fp, "\t\t and   edx,~0x0800\n");                                // clear the overflow\r
4251                                         fprintf(fp, "\t\t jmp   short %s_3\n",Label);                   // skip\r
4252 \r
4253                                 fprintf(fp, "%s_2:\n",Label);\r
4254                                         fprintf(fp, "\t\t mov   ebx,edx\n");                                    // save upper 32 in ebx\r
4255                                         SetFlags('L',EAX,TRUE,FALSE,FALSE);                                             // set the flags\r
4256                                         fprintf(fp, "\t\t sar   eax,31\n");                                             // eax = sign-extended\r
4257                                         fprintf(fp, "\t\t test  ecx,0x0800\n");                                 // signed/unsigned?\r
4258                                         fprintf(fp, "\t\t jnz   short %s_4\n",Label);                   // skip if signed\r
4259                                         fprintf(fp, "\t\t xor   eax,eax\n");                                    // always use 0 for unsigned\r
4260                                 fprintf(fp, "%s_4:\n",Label);\r
4261                                         fprintf(fp, "\t\t cmp   eax,ebx\n");                                    // compare upper 32 against eax\r
4262                                         fprintf(fp, "\t\t je    short %s_3\n",Label);                   // if equal to sign extension, skip\r
4263                                         fprintf(fp, "\t\t or    edx,0x0800\n");                                 // set the overflow\r
4264 \r
4265                                 fprintf(fp, "%s_3:\n",Label);\r
4266                                         Completed();\r
4267                                 }\r
4268 \r
4269                                 OpcodeArray[Opcode] = BaseCode ;\r
4270                         }\r
4271                 }\r
4272 }\r
4273 \r
4274 void divl(void)\r
4275 {\r
4276         int mode, sreg ;\r
4277         int Opcode, BaseCode ;\r
4278         int Dest ;\r
4279         char allow[] = "0-23456789ab-----" ;\r
4280         char *Label = NULL ;\r
4281 \r
4282         for (mode = 0 ; mode < 8 ; mode++)\r
4283                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4284                 {\r
4285                         Opcode = 0x4c40 | (mode<<3) | sreg ;\r
4286                         BaseCode = Opcode & 0x4c78 ;\r
4287                         if (mode == 7)\r
4288                         {\r
4289                                 BaseCode |= sreg ;\r
4290                         }\r
4291 \r
4292                         Dest = EAtoAMN(Opcode, FALSE);\r
4293                         if (allow[Dest&0x0f] != '-')\r
4294                         {\r
4295                                 if (OpcodeArray[ BaseCode ] == -2)\r
4296                                 {\r
4297                                         TimingCycles += 70 ;\r
4298                                         Align();\r
4299                                         Label = GenerateLabel(BaseCode,0);\r
4300                                         fprintf(fp, "%s:\n",Label);\r
4301                                         if ((Dest >= 2) && (Dest <=10))\r
4302                                                 SavePreviousPC();\r
4303 \r
4304                                         fprintf(fp, "\t\t push  edx\n");                                        // save edx\r
4305                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4306                                         fprintf(fp, "\t\t and   ecx,byte 7\n");                         // read from ea\r
4307 \r
4308                                         Memory_Fetch('W', EDX, FALSE );                                         // fetch 2nd word in ecx\r
4309                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4310 \r
4311                                         EffectiveAddressRead(Dest,'L',ECX,EBX,"---DSDB",FALSE);\r
4312 \r
4313                                         fprintf(fp, "\t\t push  esi\n");                                        // save and 0 esi\r
4314                                         ClearRegister(ESI);\r
4315 \r
4316                                         Label = GenerateLabel(BaseCode,1);\r
4317 \r
4318                                         fprintf(fp, "\t\t test  ebx,ebx\n");                            // check divisor against 0\r
4319                                         fprintf(fp, "\t\t jz    near %s_ZERO\n",Label);         // handle divide-by-zero\r
4320 // low part always used\r
4321                                         fprintf(fp, "\t\t mov   ecx,edx\n");                            // ecx = extension word\r
4322                                         fprintf(fp, "\t\t shr   edx,12\n");                                     // edx = Dq register\r
4323                                         fprintf(fp, "\t\t and   edx,7\n");                                      // 0-7\r
4324                                         fprintf(fp, "\t\t mov   eax,[%s+edx*4]\n",REG_DAT);     // eax = Dq register value\r
4325 \r
4326                                         ClearRegister(EDX);                                                                     // edx = 0\r
4327                                         fprintf(fp, "\t\t test  ecx,0x0400\n");                         // check size\r
4328                                         fprintf(fp, "\t\t jz    short %s_1\n",Label);           // skip if 32-bit dividend\r
4329 // high longword (64bit)\r
4330                                         fprintf(fp, "\t\t mov   edx,ecx\n");                            // edx = extension word\r
4331                                         fprintf(fp, "\t\t and   edx,7\n");                                      // 0-7\r
4332                                         fprintf(fp, "\t\t mov   edx,[%s+edx*4]\n",REG_DAT);     // fetch upper 32-bits\r
4333 \r
4334                                         fprintf(fp, "\t\t test  ecx,0x0800\n");                         // signed?\r
4335                                         fprintf(fp, "\t\t jz    near %s_3\n",Label);            // if not, skip to unsigned 64-bit\r
4336                                         fprintf(fp, "\t\t jmp   near %s_2\n",Label);            // skip to signed 64-bit case\r
4337 \r
4338                                 fprintf(fp, "%s_1:\n",Label);                                                   // short case\r
4339                                         ClearRegister(EDX);                                                                     // clear edx\r
4340                                         fprintf(fp, "\t\t test  ecx,0x0800\n");                         // signed?\r
4341                                         fprintf(fp, "\t\t jz    short %s_3\n",Label);           // if not, don't convert\r
4342                                         fprintf(fp, "\t\t cdq\n");                                                      // sign extend into edx\r
4343 // signed\r
4344                                 fprintf(fp, "%s_2:\n",Label);                                                   // signed 32/64-bit case\r
4345                                         fprintf(fp, "\t\t or    esi,1\n");                                      // esi |= 1 to indicate signed\r
4346                                         fprintf(fp, "\t\t test  ebx,ebx\n");                            // check divisor sign\r
4347                                         fprintf(fp, "\t\t jge   short %s_2b\n",Label);          // if >= 0, don't set\r
4348                                         fprintf(fp, "\t\t or    esi,2\n");                                      // esi |= 2 to indicate negative divisor\r
4349                                         fprintf(fp, "\t\t neg   ebx\n");                                        // make positive\r
4350                                 fprintf(fp, "%s_2b:\n",Label);\r
4351                                         fprintf(fp, "\t\t test  edx,edx\n");                            // check dividend sign\r
4352                                         fprintf(fp, "\t\t jge   short %s_3\n",Label);           // if >= 0, don't set\r
4353                                         fprintf(fp, "\t\t push  ebx\n");                                        // save ebx\r
4354                                         fprintf(fp, "\t\t push  ecx\n");                                        // save ecx\r
4355                                         ClearRegister(EBX);                                                                     // clear ebx\r
4356                                         ClearRegister(ECX);                                                                     // clear ecx\r
4357                                         fprintf(fp, "\t\t sub   ebx,eax\n");                            // ebx = 0 - eax\r
4358                                         fprintf(fp, "\t\t sbb   ecx,edx\n");                            // ecx = 0 - edx\r
4359                                         fprintf(fp, "\t\t mov   eax,ebx\n");                            // eax = ebx\r
4360                                         fprintf(fp, "\t\t mov   edx,ecx\n");                            // edx = ecx\r
4361                                         fprintf(fp, "\t\t pop   ecx\n");                                        // restore ecx\r
4362                                         fprintf(fp, "\t\t pop   ebx\n");                                        // restore ebx\r
4363                                         fprintf(fp, "\t\t or    esi,4\n");                                      // esi |= 4 to indicate negative dividend\r
4364 // unsigned\r
4365                                 fprintf(fp, "%s_3:\n",Label);                                                   // unsigned 32/64-bit case\r
4366                                         fprintf(fp, "\t\t cmp   ebx,edx\n");                            // check ebx against upper 32 bits\r
4367                                         fprintf(fp, "\t\t jbe   near %s_OVERFLOW\n",Label);     // generate overflow\r
4368                                         fprintf(fp, "\t\t div   ebx\n");                                        // do the divide\r
4369                                         fprintf(fp, "\t\t test  esi,esi\n");                            // see if we need to post process\r
4370                                         fprintf(fp, "\t\t jz    short %s_4\n",Label);           // if not, skip\r
4371                                         fprintf(fp, "\t\t jpo   short %s_4\n",Label);           // if PO (pos*pos or neg*neg), leave the result\r
4372                                         fprintf(fp, "\t\t neg   eax\n");                                        // negate the result\r
4373 \r
4374 // store results\r
4375                                 fprintf(fp, "%s_4:\n",Label);\r
4376                                         fprintf(fp, "\t\t mov   ebx,ecx\n");                            // ebx = extension word\r
4377                                         fprintf(fp, "\t\t and   ebx,7\n");                                      // get Dr in ebx\r
4378                                         fprintf(fp, "\t\t shr   ecx,12\n");                                     // ecx = Dq\r
4379                                         fprintf(fp, "\t\t and   ecx,7\n");                                      // 0-7\r
4380                                         fprintf(fp, "\t\t mov   [%s+ebx*4],edx\n",REG_DAT);     // store remainder first\r
4381                                         fprintf(fp, "\t\t mov   [%s+ecx*4],eax\n",REG_DAT);     // store quotient second\r
4382                                         fprintf(fp, "\t\t pop   esi\n");                                        // restore esi\r
4383                                         fprintf(fp, "\t\t pop   edx\n");                                        // restore edx\r
4384                                         SetFlags('L',EAX,TRUE,FALSE,FALSE);                                     // set the flags\r
4385                                 fprintf(fp, "%s_5:\n",Label);\r
4386                                         fprintf(fp, "\t\t and   edx,~1\n");                                     // clear the carry\r
4387                                         Completed();\r
4388 \r
4389                                         fprintf(fp, "%s_ZERO:\t\t ;Do divide by zero trap\n", Label);\r
4390                                         /* Correct cycle counter for error */\r
4391                                         fprintf(fp, "\t\t pop   esi\n");                                        // restore esi\r
4392                                         fprintf(fp, "\t\t pop   edx\n");                                        // restore edx\r
4393                                         fprintf(fp, "\t\t add   dword [%s],byte %d\n",ICOUNT,95);\r
4394                                 fprintf(fp,"\t\t jmp short %s_5\n",Label);\r
4395                                         Exception(5,BaseCode);\r
4396 \r
4397                                 fprintf(fp, "%s_OVERFLOW:\n",Label);\r
4398 //set overflow\r
4399                                         fprintf(fp, "\t\t pop   esi\n");                                        // restore esi\r
4400                                         fprintf(fp, "\t\t pop   edx\n");                                        // restore edx\r
4401                                         fprintf(fp, "\t\t or    edx,0x0800\n");                         // set the overflow bit\r
4402                                         fprintf(fp, "\t\t jmp   near %s_5\n",Label);            // done\r
4403 \r
4404                                 }\r
4405 \r
4406                                 OpcodeArray[Opcode] = BaseCode ;\r
4407                         }\r
4408                 }\r
4409 }\r
4410 \r
4411 void bfext(void)\r
4412 {\r
4413 // just bfextu/bfexts for now\r
4414         char allow[] = "0-2--56789a-----" ;\r
4415         char *Label = NULL ;\r
4416         int mode,dreg,sign,Opcode,BaseCode,Dest ;\r
4417         for (mode=0; mode<8; mode++)\r
4418                 for (dreg=0; dreg<8; dreg++)\r
4419                         for (sign=0; sign<2; sign++)\r
4420                         {\r
4421                                 Opcode = 0xe9c0 | (sign<<9) | (mode<<3) | dreg ;\r
4422                                 BaseCode = Opcode & 0xebf8 ;\r
4423                                 if (mode == 7)\r
4424                                         BaseCode |= dreg ;\r
4425                                 Dest = EAtoAMN(Opcode, FALSE);\r
4426                                 if (allow[Dest&0xf] != '-')\r
4427                                 {\r
4428                                         if (OpcodeArray[BaseCode] == -2)\r
4429                                         {\r
4430                                                 Align();\r
4431                                                 Label = GenerateLabel(BaseCode,0);\r
4432                                                 fprintf(fp, "%s:\n",Label);\r
4433                                                 Label = GenerateLabel(BaseCode,1);\r
4434                                                 if ((Dest >= 2) && (Dest <=10))\r
4435                                                         SavePreviousPC();\r
4436 \r
4437                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4438 \r
4439                                                 if (mode < 7)\r
4440                                                 {\r
4441                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4442                                                 }\r
4443 \r
4444                                                 Memory_Fetch('W', EAX, FALSE ) ;\r
4445                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4446 \r
4447                                                 EffectiveAddressRead(Dest,'L',ECX,EDX,"ABCDSDB",FALSE);         // edx = dword\r
4448 \r
4449                                                 fprintf(fp, "\t\t mov   ecx,eax\n");\r
4450                                                 fprintf(fp, "\t\t shr   ecx,byte 6\n");\r
4451                                                 fprintf(fp, "\t\t test  eax,0x0800\n");\r
4452                                                 fprintf(fp, "\t\t je    short %s_1\n",Label);\r
4453         //get offset from Dx\r
4454                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4455                                                 fprintf(fp, "\t\t mov   ecx,[%s+ECX*4]\n",REG_DAT);\r
4456         //get offset from extension\r
4457                                                 fprintf(fp, "%s_1:\n",Label);\r
4458                                                 fprintf(fp, "\t\t and   ecx,31\n");                                                     // ecx = offset\r
4459                                                 fprintf(fp, "\t\t mov   ebx,eax\n");\r
4460                                                 fprintf(fp, "\t\t test  eax,0x0020\n");\r
4461                                                 fprintf(fp, "\t\t je    short %s_2\n",Label);\r
4462         //get width from Dy\r
4463                                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
4464                                                 fprintf(fp, "\t\t mov   ebx,[%s+EBX*4]\n",REG_DAT);\r
4465         //get width from extension\r
4466                                                 fprintf(fp, "%s_2:\n",Label);\r
4467         //fix 0=32\r
4468                                                 fprintf(fp, "\t\t sub   ebx,byte 1\n");\r
4469                                                 fprintf(fp, "\t\t and   ebx,byte 31\n");\r
4470                                                 fprintf(fp, "\t\t add   ebx,byte 1\n");                                         // ebx = width\r
4471                                                 fprintf(fp, "\t\t rol   edx,cl\n");\r
4472         // check for N\r
4473                                                 fprintf(fp, "\t\t mov   ecx,32\n");\r
4474                                                 fprintf(fp, "\t\t sub   ecx,ebx\n");\r
4475                                                 fprintf(fp, "\t\t mov   ebx,edx\n");\r
4476                                                 SetFlags('L',EBX,TRUE,FALSE,FALSE);\r
4477                                                 if (sign)\r
4478                                                         fprintf(fp, "\t\t sar   ebx,cl\n");\r
4479                                                 else\r
4480                                                         fprintf(fp, "\t\t shr   ebx,cl\n");\r
4481                                                 fprintf(fp, "\t\t shr   eax,12\n");\r
4482                                                 fprintf(fp, "\t\t and   eax,7\n");\r
4483                                                 fprintf(fp, "\t\t mov   [%s+EAX*4],ebx\n",REG_DAT);\r
4484                                                 fprintf(fp, "\t\t test  ebx,ebx\n");\r
4485                                                 fprintf(fp, "\t\t jnz   short %s_3\n",Label);\r
4486         //zero flag\r
4487                                                 fprintf(fp, "\t\t or    edx,40h\n");\r
4488                                                 fprintf(fp, "%s_3:\n",Label);\r
4489                                                 Completed();\r
4490                                         }\r
4491                                         OpcodeArray[Opcode] = BaseCode ;\r
4492                                 }\r
4493                         }\r
4494 }\r
4495 \r
4496 /*\r
4497  * not\r
4498  * clr\r
4499  * neg\r
4500  * negx\r
4501  *\r
4502  */\r
4503 \r
4504 void not(void)\r
4505 {\r
4506         int     type,leng, mode, sreg ;\r
4507         int     Opcode, BaseCode ;\r
4508         int     Dest ;\r
4509         int SaveEDX=0;\r
4510         char Size=' ' ;\r
4511         char * Regname="" ;\r
4512         char * RegnameECX ;\r
4513         char * Label;\r
4514 \r
4515         char allow[] = "0-2345678-------" ;\r
4516 \r
4517         for (type = 0 ; type < 4 ; type++)\r
4518                 for (leng = 0 ; leng < 3 ; leng++)\r
4519                         for (mode = 0 ; mode < 8 ; mode++)\r
4520                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4521                                 {\r
4522                                         Opcode = 0x4000 | (type<<9) | (leng<<6) | (mode<<3) | sreg ;\r
4523                                         BaseCode = Opcode & 0x46f8 ;\r
4524                                         if (mode == 7)\r
4525                                         {\r
4526                                                 BaseCode |= sreg ;\r
4527                                         }\r
4528 \r
4529                                         // A7+, A7-\r
4530 \r
4531 #ifdef  A7ROUTINE\r
4532                                         if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5))\r
4533                                         {\r
4534                                                 BaseCode |= sreg ;\r
4535                                         }\r
4536 #endif\r
4537 \r
4538                                         Dest = EAtoAMN(Opcode, FALSE);\r
4539 \r
4540                                         if (allow[Dest&0x0f] != '-')\r
4541                                         {\r
4542                                                 switch (leng)\r
4543                                                 {\r
4544                                                         case 0:\r
4545                                                                 Size = 'B';\r
4546                                                                 Regname = regnamesshort[0];\r
4547                                                                 RegnameECX = regnamesshort[ECX];\r
4548                                                                 break;\r
4549                                                         case 1:\r
4550                                                                 Size = 'W';\r
4551                                                                 Regname = regnamesword[0];\r
4552                                                                 RegnameECX = regnamesword[ECX];\r
4553                                                                 break;\r
4554                                                         case 2:\r
4555                                                                 Size = 'L';\r
4556                                                                 Regname = regnameslong[0];\r
4557                                                                 RegnameECX = regnameslong[ECX];\r
4558                                                                 break;\r
4559                                                 }\r
4560 \r
4561                                                 if (OpcodeArray[ BaseCode ] == -2)\r
4562                                                 {\r
4563                                                         Align();\r
4564                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
4565 \r
4566                                                         if ((Dest >= 2) && (Dest <=10))\r
4567                                                                 SavePreviousPC();\r
4568 \r
4569                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4570 \r
4571                                                         if (Size != 'L')\r
4572                                                                 TimingCycles += 4;\r
4573                                                         else\r
4574                                                                 TimingCycles += 6;\r
4575 \r
4576                                                         if (Dest < 7)\r
4577                                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4578 \r
4579                                                         if (type == 0) SaveEDX = TRUE;\r
4580                                                         else SaveEDX = FALSE;\r
4581 \r
4582                                                         /* CLR does not need to read source (although it does on a real 68000) */\r
4583 \r
4584                                                         if (type != 1)\r
4585                                                         {\r
4586                                                                 EffectiveAddressRead(Dest,Size,ECX,EAX,"A-CDS-B",SaveEDX);\r
4587                                                         }\r
4588 \r
4589                                                         switch (type)\r
4590                                                         {\r
4591                                                                 case 0: /* negx */\r
4592 \r
4593                                                                         /* Preserve old Z flag */\r
4594 \r
4595                                                                         fprintf(fp, "\t\t mov   ebx,edx\n");\r
4596 \r
4597                                                                         CopyX();\r
4598                                                                         fprintf(fp, "\t\t adc   %s,byte 0\n", Regname ) ;\r
4599                                                                         fprintf(fp, "\t\t neg   %s\n", Regname ) ;\r
4600 \r
4601                                                                         /* Set the Flags */\r
4602 \r
4603                                                                         SetFlags(Size,EAX,FALSE,TRUE,FALSE);\r
4604 \r
4605                                                                         /* Handle the Z flag */\r
4606 \r
4607                                                                         Label = GenerateLabel(0,1);\r
4608 \r
4609                                                                         fprintf(fp, "\t\t jnz   short %s\n\n",Label);\r
4610 \r
4611                                                                         fprintf(fp, "\t\t and   edx,byte -65  ; Remove Z\n");\r
4612                                                                         fprintf(fp, "\t\t and   ebx,byte 40h  ; Mask out Old Z\n");\r
4613                                                                         fprintf(fp, "\t\t or    edx,ebx       ; Copy across\n\n");\r
4614                                                                         fprintf(fp, "%s:\n",Label);\r
4615 \r
4616                                                                         break;\r
4617 \r
4618                                                                 case 1: /* clr */\r
4619                                                                         ClearRegister(EAX);\r
4620                                                                         EffectiveAddressWrite(Dest,Size,ECX,TRUE,"----S-B",FALSE);\r
4621                                                                         fprintf(fp, "\t\t mov   edx,40H\n");\r
4622                                                                         break;\r
4623 \r
4624                                                                 case 2: /* neg */\r
4625                                                                         fprintf(fp, "\t\t neg   %s\n",Regname ) ;\r
4626                                                                         SetFlags(Size,EAX,FALSE,TRUE,TRUE);\r
4627                                                                         break;\r
4628 \r
4629                                                                 case 3: /* not */\r
4630                                                                         fprintf(fp, "\t\t xor   %s,-1\n",Regname ) ;\r
4631                                                                         SetFlags(Size,EAX,FALSE,FALSE,TRUE);\r
4632                                                                         break;\r
4633                                                         }\r
4634 \r
4635                                                         /* Update (unless CLR command) */\r
4636 \r
4637                                                         if (type != 1)\r
4638                                                                 EffectiveAddressWrite(Dest,Size,ECX,FALSE,"---DS-B",TRUE);\r
4639 \r
4640                                                         Completed();\r
4641                                                 }\r
4642 \r
4643                                                 OpcodeArray[Opcode] = BaseCode ;\r
4644                                         }\r
4645                                 }\r
4646 }\r
4647 \r
4648 /*\r
4649  * Move to/from USP\r
4650  *\r
4651  */\r
4652 \r
4653 void moveusp(void)\r
4654 {\r
4655         int Opcode, BaseCode ;\r
4656         int dir, sreg ;\r
4657         char * Label;\r
4658 \r
4659         for (dir = 0 ; dir < 2 ; dir++)\r
4660                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4661                 {\r
4662                         Opcode = 0x4e60 | ( dir << 3 ) | sreg ;\r
4663                         BaseCode = Opcode & 0x4e68 ;\r
4664 \r
4665                         if (OpcodeArray[BaseCode] == -2)\r
4666                         {\r
4667                                 Align();\r
4668                                 Label = GenerateLabel(BaseCode,0);\r
4669                                 fprintf(fp, "%s\n", Label );\r
4670                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4671 \r
4672                                 TimingCycles += 4;\r
4673 \r
4674                                 fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
4675                                 fprintf(fp, "\t\t jz    short OP%d_%4.4x_Trap\n",CPU,BaseCode);\r
4676 \r
4677                                 fprintf(fp, "\t\t and   ecx,7\n");\r
4678 \r
4679                                 if (dir == 0) /* reg 2 USP */\r
4680                                 {\r
4681                                         fprintf(fp, "\t\t mov   eax,[%s+ECX*4]\n",REG_ADD);\r
4682                                         fprintf(fp, "\t\t mov   [%s],eax\n",REG_USP);\r
4683                                 }\r
4684                                 else\r
4685                                 {\r
4686                                         fprintf(fp, "\t\t mov   eax,[%s]\n",REG_USP);\r
4687                                         fprintf(fp, "\t\t mov   [%s+ECX*4],eax\n",REG_ADD);\r
4688                                 }\r
4689                                 Completed();\r
4690 \r
4691                                 fprintf(fp, "OP%d_%4.4x_Trap:\n",CPU,BaseCode);\r
4692                                 Exception(8,BaseCode);\r
4693                         }\r
4694                         OpcodeArray[Opcode] = BaseCode ;\r
4695                 }\r
4696 }\r
4697 \r
4698 \r
4699 /*\r
4700  * Check\r
4701  *\r
4702  */\r
4703 \r
4704 void chk(void)\r
4705 {\r
4706         int     dreg,mode,sreg,size ;\r
4707         int     Opcode, BaseCode ;\r
4708         int     Dest ;\r
4709         char * Label ;\r
4710 \r
4711         char  *allow = "0-23456789ab----" ;\r
4712 \r
4713         for (size = 0 ; size < (CPU==2 ? 2 : 1); size++)\r
4714                 for (dreg = 0 ; dreg < 8; dreg++)\r
4715                         for (mode = 0 ; mode < 8; mode++)\r
4716                                 for (sreg = 0 ; sreg < 8; sreg++)\r
4717                                 {\r
4718                                         if (size == 0)  /* word */\r
4719                                                 Opcode = 0x4180 | (dreg<<9) | (mode<<3) | sreg ;\r
4720                                   else                  /* long */\r
4721                                                 Opcode = 0x4100 | (dreg<<9) | (mode<<3) | sreg ;\r
4722                                         BaseCode = Opcode & 0x41f8 ;\r
4723 \r
4724                                         if (mode == 7)\r
4725                                         {\r
4726                                                 BaseCode |= sreg ;\r
4727                                         }\r
4728 \r
4729                                         Dest = EAtoAMN(Opcode, FALSE);\r
4730 \r
4731                                         if (allow[Dest&0xf] != '-')\r
4732                                         {\r
4733                                                 if (OpcodeArray[BaseCode] == -2)\r
4734                                                 {\r
4735                                                         Align();\r
4736                                                         Label = GenerateLabel(BaseCode,0);\r
4737                                                         fprintf(fp, "%s:\n", Label );\r
4738                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4739 \r
4740                                                         TimingCycles += 10;\r
4741 \r
4742                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
4743                                                         fprintf(fp, "\t\t shr   ebx,byte 9\n");\r
4744                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
4745 \r
4746                                                         if (Dest < 7)\r
4747                                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4748 \r
4749                                                         EffectiveAddressRead(Dest,(size == 0) ? 'W' : 'L',ECX,EAX,"----S-B",FALSE);\r
4750 \r
4751                                                         if (size == 0)  /* word */\r
4752                                                         {\r
4753                                                                 fprintf(fp, "\t\t movsx ebx,word [%s+EBX*4]\n",REG_DAT);\r
4754                                                                 fprintf(fp, "\t\t movsx eax,ax\n");\r
4755                                                         }\r
4756                                                         else                    /* long */\r
4757                                                                 fprintf(fp, "\t\t mov   ebx,[%s+EBX*4]\n",REG_DAT);\r
4758 \r
4759                                                         fprintf(fp, "\t\t test  ebx,ebx\n"); /* is word bx < 0 */\r
4760                                                         fprintf(fp, "\t\t jl    near OP%d_%4.4x_Trap_minus\n",CPU,BaseCode);\r
4761 \r
4762                                                         fprintf(fp, "\t\t cmp   ebx,eax\n");\r
4763                                                         fprintf(fp, "\t\t jg    near OP%d_%4.4x_Trap_over\n",CPU,BaseCode);\r
4764                                                         Completed();\r
4765 \r
4766                                                         /* N is set if data less than zero */\r
4767 \r
4768                                                         Align();\r
4769                                                         fprintf(fp, "OP%d_%4.4x_Trap_minus:\n",CPU,BaseCode);\r
4770                                                         fprintf(fp, "\t\t or    edx,0x0080\n");         /* N flag = 80H */\r
4771                                                         fprintf(fp, "\t\t jmp   short OP%d_%4.4x_Trap_Exception\n",CPU,BaseCode);\r
4772 \r
4773                                                         /* N is cleared if greated than compared number */\r
4774 \r
4775                                                         Align();\r
4776                                                         fprintf(fp, "OP%d_%4.4x_Trap_over:\n",CPU,BaseCode);\r
4777                                                         fprintf(fp, "\t\t and   edx,0x007f\n");         /* N flag = 80H */\r
4778 \r
4779                                                         fprintf(fp, "OP%d_%4.4x_Trap_Exception:\n",CPU,BaseCode);\r
4780                                                         fprintf(fp, "\t\t mov   al,6\n");\r
4781                                                         Exception(-1,0x10000+BaseCode);\r
4782                                                         Completed();\r
4783 \r
4784                                                 }\r
4785 \r
4786                                                 OpcodeArray[Opcode] = BaseCode ;\r
4787                                         }\r
4788                                 }\r
4789 }\r
4790 \r
4791 void chk2(void)\r
4792 {\r
4793 #if 0\r
4794         int     mode,sreg,size ;\r
4795         int     Opcode, BaseCode ;\r
4796         int     Dest ;\r
4797         char * Label ;\r
4798 \r
4799         char  *allow = "--2--56789a-----" ;\r
4800 \r
4801         for (size = 0 ; size < 2; size++)\r
4802                 for (mode = 0 ; mode < 8; mode++)\r
4803                         for (sreg = 0 ; sreg < 8; sreg++)\r
4804                         {\r
4805                                 Opcode = 0x00c0 | (size<<9) | (mode<<3) | sreg;\r
4806                                 BaseCode = Opcode & 0xfff8 ;\r
4807 \r
4808                                 if (mode == 7)\r
4809                                 {\r
4810                                         BaseCode |= sreg ;\r
4811                                 }\r
4812 \r
4813                                 Dest = EAtoAMN(Opcode, FALSE);\r
4814 \r
4815                                 if (allow[Dest&0xf] != '-')\r
4816                                 {\r
4817                                         if (OpcodeArray[BaseCode] == -2)\r
4818                                         {\r
4819                                                 Align();\r
4820                                                 Label = GenerateLabel(BaseCode,0);\r
4821                                                 fprintf(fp, "%s:\n", Label );\r
4822                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4823 \r
4824                                                 TimingCycles += 10;\r
4825 \r
4826                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
4827                                                 fprintf(fp, "\t\t shr   ebx,byte 9\n");\r
4828                                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
4829 \r
4830                                                 if (Dest < 7)\r
4831                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4832 \r
4833                                                 EffectiveAddressRead(Dest,'W',ECX,EAX,"----S-B",FALSE);\r
4834 \r
4835                                                 if (size == 0)  /* word */\r
4836                                                 {\r
4837                                                         fprintf(fp, "\t\t movsx ebx,word [%s+EBX*4]\n",REG_DAT);\r
4838                                                         fprintf(fp, "\t\t movsx eax,ax\n");\r
4839                                                  }\r
4840                                                  else                   /* long */\r
4841                                                         fprintf(fp, "\t\t mov   ebx,[%s+EBX*4]\n",REG_DAT);\r
4842 \r
4843                                                 fprintf(fp, "\t\t test  ebx,ebx\n"); /* is word bx < 0 */\r
4844                                                 fprintf(fp, "\t\t jl    near OP%d_%4.4x_Trap_minus\n",CPU,BaseCode);\r
4845 \r
4846                                                 fprintf(fp, "\t\t cmp   ebx,eax\n");\r
4847                                                 fprintf(fp, "\t\t jg    near OP%d_%4.4x_Trap_over\n",CPU,BaseCode);\r
4848                                                 Completed();\r
4849 \r
4850                                                 /* N is set if data less than zero */\r
4851 \r
4852                                                 Align();\r
4853                                                 fprintf(fp, "OP%d_%4.4x_Trap_minus:\n",CPU,BaseCode);\r
4854                                                 fprintf(fp, "\t\t or    edx,0x0080\n");         /* N flag = 80H */\r
4855                                                 fprintf(fp, "\t\t jmp   short OP%d_%4.4x_Trap_Exception\n",CPU,BaseCode);\r
4856 \r
4857                                                 /* N is cleared if greated than compared number */\r
4858 \r
4859                                                 Align();\r
4860                                                 fprintf(fp, "OP%d_%4.4x_Trap_over:\n",CPU,BaseCode);\r
4861                                                 fprintf(fp, "\t\t and   edx,0x007f\n");         /* N flag = 80H */\r
4862 \r
4863                                                 fprintf(fp, "OP%d_%4.4x_Trap_Exception:\n",CPU,BaseCode);\r
4864                                                 fprintf(fp, "\t\t mov   al,6\n");\r
4865                                                 Exception(-1,0x10000+BaseCode);\r
4866                                                 Completed();\r
4867 \r
4868                                         }\r
4869 \r
4870                                         OpcodeArray[Opcode] = BaseCode ;\r
4871                                 }\r
4872                         }\r
4873 #endif\r
4874 }\r
4875 \r
4876 /*\r
4877  * Load Effective Address\r
4878  */\r
4879 \r
4880 void LoadEffectiveAddress(void)\r
4881 {\r
4882         int     Opcode, BaseCode ;\r
4883         int     sreg,mode,dreg ;\r
4884         int     Dest ;\r
4885         char allow[] = "--2--56789a-----" ;\r
4886 \r
4887         for (sreg = 0 ; sreg < 8 ; sreg++)\r
4888                 for (mode = 0 ; mode < 8 ; mode++)\r
4889                         for (dreg = 0 ; dreg < 8 ; dreg++)\r
4890                         {\r
4891                                 Opcode = 0x41c0 | (sreg<<9) | (mode<<3) | dreg ;\r
4892 \r
4893                                 BaseCode = Opcode & 0x41f8 ;\r
4894 \r
4895                                 if (mode == 7)\r
4896                                         BaseCode = BaseCode | dreg ;\r
4897 \r
4898                                 Dest = EAtoAMN(BaseCode, FALSE);\r
4899 \r
4900                                 if (allow[Dest&0x0f] != '-')\r
4901                                 {\r
4902                                         if (OpcodeArray[BaseCode] == -2)\r
4903                                         {\r
4904                                                 Align();\r
4905                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
4906                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4907 \r
4908                                                 switch (mode)\r
4909                                                 {\r
4910                                                         case 2:\r
4911                                                                 TimingCycles += 4;\r
4912                                                                 break;\r
4913                                                         case 5:\r
4914                                                         case 7:\r
4915                                                         case 9:\r
4916                                                                 TimingCycles += 8;\r
4917                                                                 break;\r
4918                                                         case 6:\r
4919                                                         case 8:\r
4920                                                         case 10:\r
4921                                                                 TimingCycles += 12;\r
4922                                                                 break;\r
4923                                                 }\r
4924 \r
4925                                                 if (mode < 7)\r
4926                                                 {\r
4927                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
4928                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
4929                                                 }\r
4930 \r
4931                                                 fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
4932                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
4933 \r
4934                                                 EffectiveAddressCalculate(Dest,'L',EBX,TRUE);\r
4935                                                 fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_ADD);\r
4936                                                 Completed();\r
4937                                         }\r
4938 \r
4939                                         OpcodeArray[Opcode] = BaseCode ;\r
4940                                 }\r
4941                         }\r
4942 }\r
4943 \r
4944 /*\r
4945  * Negate BCD\r
4946  *\r
4947  */\r
4948 \r
4949 void nbcd(void)\r
4950 {\r
4951         int     Opcode, BaseCode ;\r
4952         int     sreg,mode,Dest ;\r
4953         char allow[] = "0-2345678-------" ;\r
4954 \r
4955         for (mode = 0 ; mode < 8 ; mode++)\r
4956                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
4957                 {\r
4958                         Opcode = 0x4800 | (mode<<3) | sreg ;\r
4959                         BaseCode = Opcode & 0x4838 ;\r
4960 \r
4961                         if (mode == 7)\r
4962                                 BaseCode |= sreg ;\r
4963 \r
4964                         // A7+, A7-\r
4965 \r
4966 #ifdef  A7ROUTINE\r
4967                         if ((sreg == 7) && (mode > 2) && (mode < 5))\r
4968                         {\r
4969                                 BaseCode |= sreg;\r
4970                         }\r
4971 #endif\r
4972 \r
4973                         Dest = EAtoAMN(BaseCode, FALSE);\r
4974 \r
4975                         if (allow[Dest&0xf] != '-')\r
4976                         {\r
4977                                 if (OpcodeArray[BaseCode] == -2)\r
4978                                 {\r
4979                                         Align();\r
4980                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
4981 \r
4982                                         if ((Dest >= 2) && (Dest <=10))\r
4983                                                 SavePreviousPC();\r
4984 \r
4985                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
4986 \r
4987                                         if (mode < 2)\r
4988                                                 TimingCycles += 6;\r
4989                                         else\r
4990                                                 TimingCycles += 8;\r
4991 \r
4992                                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
4993 \r
4994                                         EffectiveAddressRead(Dest,'B',ECX,EBX,"--C-SDB",FALSE);\r
4995 \r
4996                                         ClearRegister(EAX);\r
4997                                         CopyX();\r
4998 \r
4999                                         fprintf(fp, "\t\t sbb   al,bl\n");\r
5000                                         fprintf(fp, "\t\t das\n");\r
5001 \r
5002                                         SetFlags('B',EAX,FALSE,TRUE,TRUE);\r
5003 \r
5004                                         EffectiveAddressWrite(Dest,'B',ECX,EAX,"----S-B",FALSE);\r
5005                                         Completed();\r
5006                                 }\r
5007                                 OpcodeArray[Opcode] = BaseCode ;\r
5008                         }\r
5009                 }\r
5010 }\r
5011 \r
5012 void tas(void)\r
5013 {\r
5014         int     Opcode, BaseCode ;\r
5015         int     sreg,mode,Dest ;\r
5016         char allow[] = "0-2345678-------" ;\r
5017 \r
5018         for (mode = 0 ; mode < 8 ; mode++)\r
5019                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
5020                 {\r
5021                         Opcode = 0x4ac0 | (mode<<3) | sreg ;\r
5022                         BaseCode = Opcode & 0x4af8 ;\r
5023 \r
5024                         if (mode == 7)\r
5025                                 BaseCode |= sreg ;\r
5026 \r
5027 #ifdef A7ROUTINE\r
5028                         if ((sreg == 7) && (mode > 2) && (mode < 5))\r
5029                         {\r
5030                                 BaseCode |= sreg ;\r
5031                         }\r
5032 #endif\r
5033 \r
5034                         Dest = EAtoAMN(BaseCode, FALSE);\r
5035 \r
5036                         if (allow[Dest&0xf] != '-')\r
5037                         {\r
5038                                 if (OpcodeArray[BaseCode] == -2)\r
5039                                 {\r
5040                                         Align();\r
5041                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5042 \r
5043                                         if ((Dest >= 2) && (Dest <=10))\r
5044                                                 SavePreviousPC();\r
5045 \r
5046                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5047 \r
5048                                         if (mode < 2)\r
5049                                                 TimingCycles += 4;\r
5050                                         else\r
5051                                                 TimingCycles += 14;\r
5052 \r
5053                                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
5054 \r
5055                                         EffectiveAddressRead(Dest,'B',ECX,EAX,"--C-SDB",FALSE);\r
5056 \r
5057                                         SetFlags('B',EAX,TRUE,FALSE,TRUE);\r
5058                                         fprintf(fp, "\t\t or    al,128\n");\r
5059 \r
5060                                         EffectiveAddressWrite(Dest,'B',ECX,EAX,"----S-B",FALSE);\r
5061                                         Completed();\r
5062                                 }\r
5063                                 OpcodeArray[Opcode] = BaseCode ;\r
5064                         }\r
5065                 }\r
5066 }\r
5067 \r
5068 /*\r
5069  * push Effective Address\r
5070  */\r
5071 \r
5072 void PushEffectiveAddress(void)\r
5073 {\r
5074         int     Opcode, BaseCode ;\r
5075         int     mode,dreg ;\r
5076         int     Dest ;\r
5077         char allow[] = "--2--56789a-----" ;\r
5078 \r
5079         for (mode = 0 ; mode < 8 ; mode++)\r
5080                 for (dreg = 0 ; dreg < 8 ; dreg++)\r
5081                 {\r
5082                         Opcode = 0x4840 | (mode<<3) | dreg ;\r
5083 \r
5084                         BaseCode = Opcode & 0x4878 ;\r
5085 \r
5086                         if (mode == 7)\r
5087                                 BaseCode = BaseCode | dreg ;\r
5088 \r
5089                         Dest = EAtoAMN(BaseCode, FALSE);\r
5090 \r
5091                         if (allow[Dest&0x0f] != '-')\r
5092                         {\r
5093                                 if (OpcodeArray[BaseCode] == -2)\r
5094                                 {\r
5095                                         Align();\r
5096                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5097                                         SavePreviousPC();\r
5098                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5099 \r
5100                                         switch (mode)\r
5101                                         {\r
5102                                                 case 2:\r
5103                                                         TimingCycles += 12;\r
5104                                                         break;\r
5105                                                 case 5:\r
5106                                                 case 7:\r
5107                                                 case 9:\r
5108                                                         TimingCycles += 16;\r
5109                                                         break;\r
5110                                                 case 6:\r
5111                                                 case 8:\r
5112                                                 case 10:\r
5113                                                         TimingCycles += 20;\r
5114                                                         break;\r
5115                                         }\r
5116 \r
5117                                         if (mode < 7)\r
5118                                         {\r
5119                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
5120                                         }\r
5121 \r
5122                                         EffectiveAddressCalculate(Dest,'L',ECX,TRUE);\r
5123 \r
5124                                         fprintf(fp, "\t\t mov   ecx,[%s]\t ; Push onto Stack\n",REG_A7);\r
5125                                         fprintf(fp, "\t\t sub   ecx,byte 4\n");\r
5126                                         fprintf(fp, "\t\t mov   [%s],ecx\n",REG_A7);\r
5127                                         Memory_Write('L',ECX,EDI,"---DS-B",2);\r
5128                                         Completed();\r
5129                                 }\r
5130 \r
5131                                 OpcodeArray[Opcode] = BaseCode ;\r
5132                         }\r
5133                 }\r
5134 }\r
5135 \r
5136 /*\r
5137  * Test\r
5138  *\r
5139  */\r
5140 \r
5141 void tst(void)\r
5142 {\r
5143         int     leng, mode, sreg ;\r
5144         int     Opcode, BaseCode ;\r
5145         int     Dest ;\r
5146         char Size=' ' ;\r
5147         char * Regname ;\r
5148         char * RegnameECX ;\r
5149 \r
5150         char allow[] = "0-2345678-------" ;\r
5151         if (CPU==2)\r
5152                 allow[1] = '1';\r
5153 \r
5154         for (leng = 0 ; leng < 3 ; leng++)\r
5155                 for (mode = 0 ; mode < 8 ; mode++)\r
5156                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
5157                         {\r
5158                                 Opcode = 0x4a00 | (leng<<6) | (mode<<3) | sreg ;\r
5159                                 BaseCode = Opcode & 0x4af8 ;\r
5160                                 if (mode == 7)\r
5161                                 {\r
5162                                         BaseCode |= sreg ;\r
5163                                 }\r
5164 \r
5165                                 // A7+, A7-\r
5166 \r
5167 #ifdef  A7ROUTINE\r
5168                                 if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5))\r
5169                                 {\r
5170                                         BaseCode |= sreg ;\r
5171                                 }\r
5172 #endif\r
5173 \r
5174                                 Dest = EAtoAMN(Opcode, FALSE);\r
5175 \r
5176                                 if ((allow[Dest&0x0f] != '-') || (( mode == 1 ) && (leng != 0)))\r
5177                                 {\r
5178                                         switch (leng)\r
5179                                         {\r
5180                                                 case 0:\r
5181                                                         Size = 'B';\r
5182                                                         Regname = regnamesshort[0];\r
5183                                                         RegnameECX = regnamesshort[ECX];\r
5184                                                         break;\r
5185                                                 case 1:\r
5186                                                         Size = 'W';\r
5187                                                         Regname = regnamesword[0];\r
5188                                                         RegnameECX = regnamesword[ECX];\r
5189                                                         break;\r
5190                                                 case 2:\r
5191                                                         Size = 'L';\r
5192                                                         Regname = regnameslong[0];\r
5193                                                         RegnameECX = regnameslong[ECX];\r
5194                                                         break;\r
5195                                         }\r
5196 \r
5197                                         if (OpcodeArray[ BaseCode ] == -2)\r
5198                                         {\r
5199                                                 Align();\r
5200                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5201 \r
5202                                                 if ((Dest >= 2) && (Dest <=10))\r
5203                                                         SavePreviousPC();\r
5204 \r
5205                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5206 \r
5207                                                 TimingCycles += 4;\r
5208 \r
5209                                                 if (Dest < 7)\r
5210                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
5211 \r
5212                                                 EffectiveAddressRead(Dest,Size,ECX,EAX,"----S-B",FALSE);\r
5213 \r
5214                                                 SetFlags(Size,EAX,TRUE,FALSE,FALSE);\r
5215                                                 Completed();\r
5216                                         }\r
5217 \r
5218                                         OpcodeArray[Opcode] = BaseCode ;\r
5219                                 }\r
5220                         }\r
5221 }\r
5222 \r
5223 /*\r
5224  * Move registers too / from memory\r
5225  *\r
5226  */\r
5227 \r
5228 void movem_reg_ea(void)\r
5229 {\r
5230         int     leng,mode,sreg ;\r
5231         int     Opcode, BaseCode ;\r
5232         int     Dest ;\r
5233         char  Size ;\r
5234         char * Label ;\r
5235 \r
5236         char *allow = "--2-45678-------" ;\r
5237 \r
5238         for (leng = 0 ; leng < 2; leng++)\r
5239                 for (mode = 0 ; mode < 8; mode++)\r
5240                         for (sreg = 0 ; sreg < 8; sreg++)\r
5241                         {\r
5242                                 Opcode = 0x4880 | ( leng<<6) | (mode<<3) | sreg ;\r
5243                                 BaseCode = Opcode & 0x4cf8 ;\r
5244 \r
5245                                 if (mode == 7)\r
5246                                 {\r
5247                                         BaseCode |= sreg ;\r
5248                                 }\r
5249 \r
5250                                 Dest = EAtoAMN(Opcode, FALSE);\r
5251 \r
5252                                 Size = "WL"[leng] ;\r
5253 \r
5254                                 if (allow[Dest&0xf] != '-')\r
5255                                 {\r
5256                                         if (OpcodeArray[BaseCode] == - 2)\r
5257                                         {\r
5258                                                 Align();\r
5259                                                 Label = GenerateLabel(BaseCode,0);\r
5260                                                 fprintf(fp, "%s:\n",Label ) ;\r
5261                                                 SavePreviousPC();\r
5262                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5263 \r
5264                                                 switch (mode)\r
5265                                                 {\r
5266                                                         case 2:\r
5267                                                         case 4:\r
5268                                                                 TimingCycles += 8 ;\r
5269                                                                 break;\r
5270                                                         case 5:\r
5271                                                         case 7:\r
5272                                                                 TimingCycles += 12 ;\r
5273                                                                 break;\r
5274                                                         case 6:\r
5275                                                         case 8:\r
5276                                                                 TimingCycles += 14 ;\r
5277                                                                 break;\r
5278                                                 }\r
5279 \r
5280                                                 fprintf(fp, "\t\t push edx\n");\r
5281 \r
5282                                                 Memory_Fetch('W',EDX,FALSE);\r
5283                                                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
5284 \r
5285                                                 if (mode < 7)\r
5286                                                 {\r
5287                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
5288                                                 }\r
5289 \r
5290                                                 if (mode == 4)\r
5291                                                 {\r
5292                                                         fprintf(fp, "\t\t push  ecx\n");\r
5293                                                         fprintf(fp, "\t\t mov   edi,[%s+ECX*4]\n",REG_ADD);\r
5294                                                 }\r
5295                                                 else\r
5296                                                         EffectiveAddressCalculate(Dest,'L',ECX,TRUE);\r
5297 \r
5298                                                 fprintf(fp, "\t\t mov   ebx,1\n");\r
5299 \r
5300                                                 /* predecrement uses d0-d7..a0-a7  a7 first*/\r
5301                                                 /* other modes use      a7-a0..d7-d0  d0 first*/\r
5302 \r
5303                                                 if (Dest != 4)\r
5304                                                         ClearRegister(ECX);\r
5305                                                 else\r
5306                                                         fprintf(fp, "\t\t mov   ecx,3Ch\n");\r
5307 \r
5308                                                 fprintf(fp, "OP%d_%4.4x_Again:\n",CPU,BaseCode);\r
5309                                                 fprintf(fp, "\t\t test  edx,ebx\n");\r
5310                                                 fprintf(fp, "\t\t je    OP%d_%4.4x_Skip\n",CPU,BaseCode);\r
5311 \r
5312                                                 fprintf(fp, "\t\t mov   eax,[%s+ecx]\n",REG_DAT);  /* load eax with current reg data */\r
5313 \r
5314                                                 if (Dest == 4)\r
5315                                                 {\r
5316                                                         if (Size == 'W')                                                /* adjust pointer before write */\r
5317                                                                 fprintf(fp, "\t\t sub   edi,byte 2\n");\r
5318                                                         else\r
5319                                                                 fprintf(fp, "\t\t sub   edi,byte 4\n");\r
5320                                                 }\r
5321 \r
5322                                                 Memory_Write(Size,EDI,EAX,"-BCDSDB",1);\r
5323 \r
5324                                                 if (Dest != 4)\r
5325                                                 {\r
5326                                                         if (Size == 'W')                                        /* adjust pointer after write */\r
5327                                                                 fprintf(fp, "\t\t add   edi,byte 2\n");\r
5328                                                         else\r
5329                                                                 fprintf(fp, "\t\t add   edi,byte 4\n");\r
5330                                                 }\r
5331 \r
5332                                                 /* Update Cycle Count */\r
5333 \r
5334                                                 if (Size == 'W')\r
5335                                                         fprintf(fp, "\t\t sub   dword [%s],byte 4\n",ICOUNT);\r
5336                                                 else\r
5337                                                         fprintf(fp, "\t\t sub   dword [%s],byte 8\n",ICOUNT);\r
5338 \r
5339                                                 fprintf(fp, "OP%d_%4.4x_Skip:\n",CPU,BaseCode);\r
5340 \r
5341                                                 if (Dest != 4)\r
5342                                                         fprintf(fp, "\t\t add   ecx,byte 4h\n");\r
5343                                                 else\r
5344                                                         fprintf(fp, "\t\t sub   ecx,byte 4h\n");\r
5345 \r
5346                                                 fprintf(fp, "\t\t add   ebx,ebx\n");            /* faster than shl ebx,1 */\r
5347                                                 fprintf(fp, "\t\t test  bx,bx\n");                /* check low 16 bits */\r
5348                                                 fprintf(fp, "\t\t jnz   OP%d_%4.4x_Again\n",CPU,BaseCode);\r
5349 \r
5350                                                 if (Dest == 4)\r
5351                                                 {\r
5352                                                         fprintf(fp, "\t\t pop   ecx\n");\r
5353                                                         fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_ADD);\r
5354                                                 }\r
5355 \r
5356                                                 fprintf(fp, "\t\t pop   edx\n");\r
5357                                                 Completed();\r
5358                                         }\r
5359 \r
5360                                         OpcodeArray[Opcode] = BaseCode ;\r
5361                                 }\r
5362                         }\r
5363 }\r
5364 \r
5365 void movem_ea_reg(void)\r
5366 {\r
5367         int     leng,mode,sreg ;\r
5368         int     Opcode, BaseCode ;\r
5369         int     Dest ;\r
5370         char  Size ;\r
5371         char * Label ;\r
5372 \r
5373         char  *allow = "--23-56789a-----" ;\r
5374 \r
5375         for (leng = 0 ; leng < 2; leng++)\r
5376                 for (mode = 0 ; mode < 8; mode++)\r
5377                         for (sreg = 0 ; sreg < 8; sreg++)\r
5378                         {\r
5379                                 Opcode = 0x4c80 | ( leng<<6) | (mode<<3) | sreg ;\r
5380                                 BaseCode = Opcode & 0x4cf8 ;\r
5381 \r
5382                                 if (mode == 7)\r
5383                                 {\r
5384                                         BaseCode |= sreg ;\r
5385                                 }\r
5386 \r
5387                                 Dest = EAtoAMN(Opcode, FALSE);\r
5388 \r
5389                                 Size = "WL"[leng] ;\r
5390 \r
5391                                 if (allow[Dest&0xf] != '-')\r
5392                                 {\r
5393                                         if (OpcodeArray[BaseCode] == - 2)\r
5394                                         {\r
5395                                                 Align();\r
5396                                                 Label = GenerateLabel(BaseCode,0);\r
5397 \r
5398                                                 fprintf(fp, "%s:\n",Label ) ;\r
5399                                                 SavePreviousPC();\r
5400                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5401 \r
5402                                                 switch (mode)\r
5403                                                 {\r
5404                                                         case 2:\r
5405                                                         case 4:\r
5406                                                                 TimingCycles += 8 ;\r
5407                                                                 break;\r
5408                                                         case 5:\r
5409                                                         case 7:\r
5410                                                                 TimingCycles += 12 ;\r
5411                                                                 break;\r
5412                                                         case 6:\r
5413                                                         case 8:\r
5414                                                                 TimingCycles += 14 ;\r
5415                                                                 break;\r
5416                                                 }\r
5417 \r
5418                                                 fprintf(fp, "\t\t push  edx\n");                         /* save edx because sr is unaffected */\r
5419 \r
5420                                                 Memory_Fetch('W',EDX,FALSE);\r
5421                                                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
5422 \r
5423                                                 if (mode < 7)\r
5424                                                 {\r
5425                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
5426                                                 }\r
5427 \r
5428                                                 if (mode == 3)\r
5429                                                         fprintf(fp, "\t\t push   ecx\n");                       /* if (An)+ then it needed later */\r
5430 \r
5431                                                 EffectiveAddressCalculate(Dest,'L',ECX,TRUE);\r
5432 \r
5433                                                 fprintf(fp, "\t\t mov   ebx,1\n");                        /* setup register list mask */\r
5434 \r
5435                                                 /* predecrement uses d0-d7..a0-a7  a7 first*/\r
5436                                                 /* other modes use      a7-a0..d7-d0  d0 first*/\r
5437 \r
5438                                                 ClearRegister(ECX);                                                               /* always start with D0 */\r
5439 \r
5440                                                 fprintf(fp, "OP%d_%4.4x_Again:\n",CPU,BaseCode);\r
5441                                                 fprintf(fp, "\t\t test  edx,ebx\n");                    /* is bit set for this register? */\r
5442                                                 fprintf(fp, "\t\t je    OP%d_%4.4x_Skip\n",CPU,BaseCode);\r
5443 \r
5444                                                 Memory_Read(Size,EDI,"-BCDSDB",1);\r
5445 \r
5446                                                 if (Size == 'W')\r
5447                                                         fprintf(fp, "\t\t cwde\n");                             /* word size must be sign extended */\r
5448 \r
5449                                                 fprintf(fp, "\t\t mov   [%s+ecx],eax\n",REG_DAT);  /* load current reg with eax */\r
5450 \r
5451                                                 if (Size == 'W')                                                /* adjust pointer after write */\r
5452                                                         fprintf(fp, "\t\t add   edi,byte 2\n");\r
5453                                                 else\r
5454                                                         fprintf(fp, "\t\t add   edi,byte 4\n");\r
5455 \r
5456                                                 /* Update Cycle Count */\r
5457 \r
5458                                                 if (Size == 'W')\r
5459                                                         fprintf(fp, "\t\t sub   dword [%s],byte 4\n",ICOUNT);\r
5460                                                 else\r
5461                                                         fprintf(fp, "\t\t sub   dword [%s],byte 8\n",ICOUNT);\r
5462 \r
5463                                                 fprintf(fp, "OP%d_%4.4x_Skip:\n",CPU,BaseCode);\r
5464                                                 fprintf(fp, "\t\t add   ecx,byte 4\n");                 /* adjust pointer to next reg */\r
5465                                                 fprintf(fp, "\t\t add   ebx,ebx\n");                    /* Faster than shl ebx,1 */\r
5466                                                 fprintf(fp, "\t\t test  bx,bx\n");                        /* check low 16 bits */\r
5467                                                 fprintf(fp, "\t\t jnz   OP%d_%4.4x_Again\n",CPU,BaseCode);\r
5468 \r
5469                                                 if (mode == 3)\r
5470                                                 {\r
5471                                                         fprintf(fp, "\t\t pop   ecx\n");\r
5472                                                         fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_ADD);     /* reset Ax if mode = (Ax)+ */\r
5473                                                 }\r
5474 \r
5475                                                 fprintf(fp, "\t\t pop   edx\n");                         /* restore flags */\r
5476                                                 Completed();\r
5477                                         }\r
5478 \r
5479                                         OpcodeArray[Opcode] = BaseCode ;\r
5480                                 }\r
5481                         }\r
5482 }\r
5483 \r
5484 /*\r
5485  * Link / Unlink\r
5486  *\r
5487  * Local stack space\r
5488  *\r
5489  */\r
5490 \r
5491 void link(void)\r
5492 {\r
5493         int     sreg ;\r
5494         int     Opcode, BaseCode ;\r
5495 \r
5496         for (sreg = 0 ; sreg < 8; sreg++)\r
5497         {\r
5498                 Opcode = 0x4e50 | sreg ;\r
5499                 BaseCode = 0x4e50 ;\r
5500 \r
5501                 if (OpcodeArray[BaseCode] == - 2)\r
5502                 {\r
5503                         Align();\r
5504                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5505                         SavePreviousPC();\r
5506                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5507 \r
5508                         TimingCycles += 16;\r
5509 \r
5510                         fprintf(fp, "\t\t sub   dword [%s],byte 4\n",REG_A7);\r
5511 \r
5512                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
5513                         fprintf(fp, "\t\t mov   eax,[%s+ECX*4]\n",REG_ADD);\r
5514                         fprintf(fp, "\t\t mov   edi,[%s]\n",REG_A7);\r
5515                         fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_ADD);\r
5516 \r
5517                         Memory_Write('L',EDI,EAX,"---DS-B",1);\r
5518 \r
5519                         Memory_Fetch('W',EAX,TRUE);\r
5520                         fprintf(fp, "\t\t add   esi,byte 2\n");\r
5521                         fprintf(fp, "\t\t add   [%s],eax\n",REG_A7);\r
5522 \r
5523                         Completed();\r
5524                 }\r
5525 \r
5526                 OpcodeArray[Opcode] = BaseCode ;\r
5527         }\r
5528 }\r
5529 \r
5530 void unlinkasm(void)\r
5531 {\r
5532         int     sreg ;\r
5533         int     Opcode, BaseCode ;\r
5534 \r
5535         for (sreg = 0 ; sreg < 8; sreg++)\r
5536         {\r
5537                 Opcode = 0x4e58 | sreg ;\r
5538                 BaseCode = 0x4e58 ;\r
5539 \r
5540                 if (OpcodeArray[BaseCode] == - 2)\r
5541                 {\r
5542                         Align();\r
5543                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5544                         SavePreviousPC();\r
5545                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5546 \r
5547                         TimingCycles += 12;\r
5548 \r
5549                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
5550                         fprintf(fp, "\t\t and   ebx, byte 7\n");\r
5551                         fprintf(fp, "\t\t mov   edi,[%s+EBX*4]\n",REG_ADD);\r
5552 \r
5553                         Memory_Read('L',EDI,"-B-DSDB",1);\r
5554 \r
5555                         fprintf(fp, "\t\t mov   [%s+EBX*4],eax\n",REG_ADD);\r
5556                         fprintf(fp, "\t\t add   edi,byte 4\n");\r
5557                         fprintf(fp, "\t\t mov   dword [%s],EDI\n",REG_A7);\r
5558                         Completed();\r
5559                 }\r
5560 \r
5561                 OpcodeArray[Opcode] = BaseCode ;\r
5562         }\r
5563 }\r
5564 \r
5565 void trap(void)\r
5566 {\r
5567         int Count;\r
5568         int BaseCode = 0x4E40;\r
5569 \r
5570         if (OpcodeArray[BaseCode] == -2)\r
5571         {\r
5572                 Align();\r
5573                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5574                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5575 \r
5576                 fprintf(fp, "\t\t mov   eax,ecx\n");\r
5577                 fprintf(fp, "\t\t and   eax,byte 15\n");\r
5578                 fprintf(fp, "\t\t or    eax,byte 32\n");\r
5579                 Exception(-1,BaseCode);\r
5580                 Completed();\r
5581         }\r
5582 \r
5583         for (Count=0;Count<=15;Count++)\r
5584                 OpcodeArray[BaseCode+Count] = BaseCode;\r
5585 }\r
5586 \r
5587 void reset(void)\r
5588 {\r
5589         int BaseCode = 0x4E70;\r
5590         char * Label;\r
5591 \r
5592         if (OpcodeArray[BaseCode] == -2)\r
5593         {\r
5594                 Align();\r
5595                 Label = GenerateLabel(BaseCode,0);\r
5596 \r
5597                 TimingCycles += 132;\r
5598 \r
5599                 fprintf(fp, "%s:\n", Label );\r
5600                 SavePreviousPC();\r
5601 \r
5602                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5603                 fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
5604                 fprintf(fp, "\t\t jnz   near OP%d_%4.4x_RESET\n",CPU,BaseCode);\r
5605                 Exception(8,BaseCode);\r
5606 \r
5607                 fprintf(fp, "\nOP%d_%4.4x_RESET:\n",CPU,BaseCode);\r
5608 \r
5609                 /* Prefetch next instruction */\r
5610 \r
5611                 if(CPU==2)\r
5612                 {\r
5613                         /* 32 bit memory version */\r
5614 \r
5615                         fprintf(fp, "\t\t xor   esi,2\n");      /* ASG */\r
5616 #ifdef STALLCHECK\r
5617                  ClearRegister(ECX);\r
5618                         fprintf(fp, "\t\t mov   cx,[esi+ebp]\n");\r
5619 #else\r
5620                         fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");\r
5621 #endif\r
5622                         fprintf(fp, "\t\t xor   esi,2\n");      /* ASG */\r
5623                 }\r
5624                 else\r
5625                 {\r
5626                         /* 16 bit memory */\r
5627 #ifdef STALLCHECK\r
5628                  ClearRegister(ECX);\r
5629                         fprintf(fp, "\t\t mov   cx,[esi+ebp]\n");\r
5630 #else\r
5631                         fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");\r
5632 #endif\r
5633                 }\r
5634 \r
5635                 fprintf(fp, "\t\t mov  eax,dword [%s]\n", REG_RESET_CALLBACK);\r
5636                 fprintf(fp, "\t\t test eax,eax\n");\r
5637                 fprintf(fp, "\t\t jz   near OP%d_%4.4x_END\n",CPU,BaseCode);\r
5638 \r
5639                 /* Callback for Reset */\r
5640 \r
5641                 fprintf(fp, "\t\t mov   [%s],ESI,\n",REG_PC);\r
5642                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
5643                 fprintf(fp, "\t\t push  ECX\n");\r
5644 \r
5645                 fprintf(fp, "\t\t call  [eax]\n");\r
5646 \r
5647                 fprintf(fp, "\t\t mov   ESI,[%s]\n",REG_PC);\r
5648                 fprintf(fp, "\t\t mov   edx,[%s]\n",REG_CCR);\r
5649                 fprintf(fp, "\t\t pop   ECX\n");\r
5650                 fprintf(fp, "\t\t mov   ebp,dword [_OP_ROM]\n");\r
5651 \r
5652                 fprintf(fp, "OP%d_%4.4x_END:\n",CPU,BaseCode);\r
5653                 fprintf(fp, "\t\t sub   dword [%s],%d\n",ICOUNT,TimingCycles);\r
5654                 fprintf(fp, "\t\t jmp   [%s_OPCODETABLE+ecx*4]\n\n", CPUtype);\r
5655         }\r
5656         OpcodeArray[BaseCode] = BaseCode ;\r
5657 }\r
5658 \r
5659 void nop(void)\r
5660 {\r
5661         int     BaseCode = 0x4e71 ;\r
5662 \r
5663         if (OpcodeArray[BaseCode] == -2)\r
5664         {\r
5665                 Align();\r
5666                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5667                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5668 \r
5669                 TimingCycles += 4;\r
5670 \r
5671                 Completed();\r
5672                 OpcodeArray[BaseCode] = BaseCode ;\r
5673         }\r
5674 }\r
5675 \r
5676 void stop(void)\r
5677 {\r
5678         char TrueLabel[16];\r
5679         int      BaseCode = 0x4e72 ;\r
5680 \r
5681         if (OpcodeArray[BaseCode] == -2)\r
5682         {\r
5683                 Align();\r
5684                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5685                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5686 \r
5687                 TimingCycles += 4;\r
5688 \r
5689                 /* Must be in Supervisor Mode */\r
5690 \r
5691                 sprintf(TrueLabel,GenerateLabel(0,1));\r
5692 \r
5693                 fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
5694                 fprintf(fp, "\t\t je    near %s\n\n",TrueLabel);\r
5695 \r
5696                 /* Next WORD is new SR */\r
5697 \r
5698                 Memory_Fetch('W',EAX,FALSE);\r
5699                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
5700 \r
5701                 WriteCCR('W');\r
5702 \r
5703                 /* See if Valid interrupt waiting */\r
5704 \r
5705                 CheckInterrupt = 0;\r
5706 \r
5707                 fprintf(fp, "\t\t mov   eax,[%s]\n",REG_IRQ);\r
5708                 fprintf(fp, "\t\t and   eax,byte 07H\n");\r
5709 \r
5710                 fprintf(fp, "\t\t cmp   al,7\t\t ; Always take 7\n");\r
5711                 fprintf(fp, "\t\t je    near procint\n\n");\r
5712 \r
5713                 fprintf(fp, "\t\t mov   ebx,[%s]\t\t; int mask\n",REG_SRH);\r
5714                 fprintf(fp, "\t\t and   ebx,byte 07H\n");\r
5715                 fprintf(fp, "\t\t cmp   eax,ebx\n");\r
5716                 fprintf(fp, "\t\t jg    near procint\n\n");\r
5717 \r
5718                 /* No int waiting - clear count, set stop */\r
5719 \r
5720                 ClearRegister(ECX);\r
5721                 fprintf(fp, "\t\t mov   [%s],ecx\n",ICOUNT);\r
5722                 fprintf(fp, "\t\t or    byte [%s],80h\n",REG_IRQ);\r
5723                 Completed();\r
5724 \r
5725                 /* User Mode - Exception */\r
5726 \r
5727                 Align();\r
5728                 fprintf(fp, "%s:\n",TrueLabel);\r
5729                 Exception(8,BaseCode);\r
5730 \r
5731                 OpcodeArray[BaseCode] = BaseCode ;\r
5732         }\r
5733 }\r
5734 \r
5735 void ReturnFromException(void)\r
5736 {\r
5737         char TrueLabel[16];\r
5738 \r
5739         int BaseCode = 0x4e73;\r
5740 \r
5741         Align();\r
5742         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5743         SavePreviousPC();\r
5744         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5745 \r
5746         TimingCycles += 20;\r
5747 \r
5748         /* Check in Supervisor Mode */\r
5749 \r
5750         sprintf(TrueLabel,GenerateLabel(0,1));\r
5751         fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
5752         fprintf(fp, "\t\t je    near %s\n\n",TrueLabel);\r
5753 \r
5754         /* Get SR - Save in EBX */\r
5755 \r
5756         fprintf(fp, "\t\t mov   edi,[%s]\n",REG_A7);\r
5757         fprintf(fp, "\t\t add   dword [%s],byte 6\n",REG_A7);\r
5758         Memory_Read('W',EDI,"-----DB",2);\r
5759         fprintf(fp, "\t\t add   edi,byte 2\n");\r
5760         fprintf(fp, "\t\t mov   esi,eax\n");\r
5761 \r
5762         /* Get PC */\r
5763 \r
5764         Memory_Read('L',EDI,"----S-B",0);\r
5765         fprintf(fp, "\t\t xchg  esi,eax\n");\r
5766 \r
5767         /* Update CCR (and A7) */\r
5768 \r
5769         WriteCCR('W');\r
5770 \r
5771         MemoryBanking(BaseCode);\r
5772         Completed();\r
5773 \r
5774         fprintf(fp, "%s:\n",TrueLabel);\r
5775         Exception(8,0x10000+BaseCode);\r
5776 \r
5777         OpcodeArray[BaseCode] = BaseCode;\r
5778 }\r
5779 \r
5780 void trapv(void)\r
5781 {\r
5782         int BaseCode = 0x4E76;\r
5783         char * Label;\r
5784 \r
5785         if (OpcodeArray[BaseCode] == -2)\r
5786         {\r
5787                 Align();\r
5788                 Label = GenerateLabel(BaseCode,0);\r
5789                 fprintf(fp, "%s\n", Label );\r
5790                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5791 \r
5792                 TimingCycles += 4;\r
5793 \r
5794                 fprintf(fp, "\t\t test  dh,08h\n");\r
5795                 fprintf(fp, "\t\t jz    near OP%d_%4.4x_Clear\n",CPU,BaseCode);\r
5796                 Exception(7,BaseCode);\r
5797 \r
5798                 fprintf(fp, "OP%d_%4.4x_Clear:\n",CPU,BaseCode);\r
5799                 Completed();\r
5800         }\r
5801         OpcodeArray[BaseCode] = BaseCode ;\r
5802 }\r
5803 \r
5804 void illegal_opcode(void)\r
5805 {\r
5806         Align();\r
5807         fprintf(fp, "ILLEGAL:\n");\r
5808         fprintf(fp, "\t\t mov [_illegal_op],ecx\n");\r
5809         fprintf(fp, "\t\t mov [_illegal_pc],esi\n");\r
5810 \r
5811 #ifdef MAME_DEBUG\r
5812         fprintf(fp, "\t\t jmp ecx\n");\r
5813         fprintf(fp, "\t\t pushad\n");\r
5814         fprintf(fp, "\t\t call _m68k_illegal_opcode\n");\r
5815         fprintf(fp, "\t\t popad\n");\r
5816 #endif\r
5817 \r
5818         Exception(4,0xFFFE);\r
5819 }\r
5820 \r
5821 /*\r
5822  * Return from subroutine\r
5823  * restoring flags as well\r
5824  *\r
5825  */\r
5826 \r
5827 void ReturnandRestore(void)\r
5828 {\r
5829         int BaseCode = 0x4e77;\r
5830 \r
5831         Align();\r
5832         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5833         SavePreviousPC();\r
5834         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5835 \r
5836         TimingCycles += 20;\r
5837 \r
5838         /* Get SR into ESI */\r
5839 \r
5840         fprintf(fp, "\t\t mov   edi,[%s]\n",REG_A7);\r
5841         fprintf(fp, "\t\t add   dword [%s],byte 6\n",REG_A7);\r
5842 \r
5843         Memory_Read('W',EDI,"-----DB",2);\r
5844         fprintf(fp, "\t\t add   edi,byte 2\n");\r
5845         fprintf(fp, "\t\t mov   esi,eax\n");\r
5846 \r
5847         /* Get PC */\r
5848 \r
5849         Memory_Read('L',EDI,"----SDB",0);\r
5850         fprintf(fp, "\t\t xchg  esi,eax\n");\r
5851 \r
5852         /* Update flags */\r
5853 \r
5854         WriteCCR('B');\r
5855 \r
5856         MemoryBanking(BaseCode);\r
5857         Completed();\r
5858 \r
5859         OpcodeArray[BaseCode] = BaseCode;\r
5860 }\r
5861 \r
5862 /*\r
5863  * Return from Subroutine\r
5864  *\r
5865  */\r
5866 \r
5867 void rts(void)\r
5868 {\r
5869         int     BaseCode = 0x4e75 ;\r
5870 \r
5871         if (OpcodeArray[BaseCode] == -2)\r
5872         {\r
5873                 Align();\r
5874                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5875                 SavePreviousPC();\r
5876 \r
5877                 TimingCycles += 16;\r
5878 \r
5879                 OpcodeArray[BaseCode] = BaseCode ;\r
5880 \r
5881                 fprintf(fp, "\t\t mov   eax,[%s]\n",REG_A7);\r
5882                 fprintf(fp, "\t\t add   dword [%s],byte 4\n",REG_A7);\r
5883                 Memory_Read('L',EAX,"---D--B",1);\r
5884                 fprintf(fp, "\t\t mov   esi,eax\n");\r
5885                 MemoryBanking(BaseCode);\r
5886                 Completed();\r
5887         }\r
5888 }\r
5889 \r
5890 void jmp_jsr(void)\r
5891 {\r
5892         int     Opcode, BaseCode ;\r
5893         int     dreg,mode,type ;\r
5894         int     Dest ;\r
5895         char allow[] = "--2--56789a-----" ;\r
5896 \r
5897         for (type = 0 ; type < 2 ; type++)\r
5898                 for (mode = 0 ; mode < 8 ; mode++)\r
5899                         for (dreg = 0 ; dreg < 8 ; dreg++)\r
5900                         {\r
5901                                 Opcode = 0x4e80 | (type<<6) | (mode<<3) | dreg ;\r
5902                                 BaseCode = Opcode & 0x4ef8 ;\r
5903                                 if (mode == 7)\r
5904                                         BaseCode = BaseCode | dreg ;\r
5905 \r
5906                                 Dest = EAtoAMN(BaseCode, FALSE);\r
5907                                 if (allow[Dest&0x0f] != '-')\r
5908                                 {\r
5909                                         if (OpcodeArray[BaseCode] == -2)\r
5910                                         {\r
5911                                                 Align();\r
5912                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
5913                                                 SavePreviousPC();\r
5914                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
5915 \r
5916                                                 switch (mode)\r
5917                                                 {\r
5918                                                         case 2:\r
5919                                                                 TimingCycles += 8;\r
5920                                                                 break;\r
5921                                                         case 5:\r
5922                                                         case 7:\r
5923                                                         case 9:\r
5924                                                                 TimingCycles += 10;\r
5925                                                                 break;\r
5926                                                         case 8:\r
5927                                                                 TimingCycles += 12;\r
5928                                                                 break;\r
5929                                                         case 6:\r
5930                                                         case 10:\r
5931                                                                 TimingCycles += 14;\r
5932                                                                 break;\r
5933                                                 }\r
5934 \r
5935                                                 if (type == 0) /* jsr takes 8 more than jmp */\r
5936                                                         TimingCycles += 8;\r
5937 \r
5938                                                 if (mode < 7)\r
5939                                                 {\r
5940                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
5941                                                 }\r
5942                                                 EffectiveAddressCalculate(Dest,'L',ECX,TRUE);\r
5943 \r
5944                                                 /* jsr needs to push PC onto stack */\r
5945 \r
5946                                                 if (type == 0)\r
5947                                                 {\r
5948                                                         PushPC(EBX,EAX,"---D-DB",1);\r
5949                                                 }\r
5950 \r
5951                                                 fprintf(fp, "\t\t mov   esi,edi\n");\r
5952                                                 MemoryBanking(BaseCode);\r
5953                                                 Completed();\r
5954                                         }\r
5955 \r
5956                                         OpcodeArray[Opcode] = BaseCode ;\r
5957                                 }\r
5958                         }\r
5959 }\r
5960 \r
5961 void cmpm(void)\r
5962 {\r
5963         int     Opcode, BaseCode ;\r
5964         int     regx,leng,regy ;\r
5965         int ModeModX, ModeModY;\r
5966         char Size=' ' ;\r
5967         char * Regname="" ;\r
5968         char * RegnameEBX="" ;\r
5969 \r
5970         for (regx = 0 ; regx < 8 ; regx++)\r
5971                 for (leng = 0 ; leng < 3 ; leng++)\r
5972                         for (regy = 0 ; regy < 8 ; regy++)\r
5973                         {\r
5974                                 Opcode = 0xb108 | (regx<<9) | (leng<<6) | regy ;\r
5975                                 BaseCode = Opcode & 0xb1c8 ;\r
5976 \r
5977                                 ModeModX = 0;\r
5978                                 ModeModY = 0;\r
5979 \r
5980 #ifdef A7ROUTINE\r
5981                                 if (leng==0)\r
5982                                 {\r
5983                                         if (regx==7)\r
5984                                         {\r
5985                                                 BaseCode |= (regx<<9);\r
5986                                                 ModeModX = 16;\r
5987                                         }\r
5988 \r
5989                                         if (regy==7)\r
5990                                         {\r
5991                                                 BaseCode |= regy;\r
5992                                                 ModeModY = 16;\r
5993                                         }\r
5994                                 }\r
5995 #endif\r
5996 \r
5997                                 switch (leng)\r
5998                                 {\r
5999                                         case 0:\r
6000                                                 Size = 'B';\r
6001                                                 Regname = regnamesshort[EAX];\r
6002                                                 RegnameEBX = regnamesshort[EBX];\r
6003                                                 break;\r
6004                                         case 1:\r
6005                                                 Size = 'W';\r
6006                                                 Regname = regnamesword[EAX];\r
6007                                                 RegnameEBX = regnamesword[EBX];\r
6008                                                 break;\r
6009                                         case 2:\r
6010                                                 Size = 'L';\r
6011                                                 Regname = regnameslong[EAX];\r
6012                                                 RegnameEBX = regnameslong[EBX];\r
6013                                                 break;\r
6014                                 }\r
6015 \r
6016                                 if (OpcodeArray[BaseCode] == -2)\r
6017                                 {\r
6018                                         Align();\r
6019                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6020                                         SavePreviousPC();\r
6021                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6022 \r
6023                                         AddEACycles = 0 ;\r
6024 \r
6025                                         if (Size != 'L')\r
6026                                                 TimingCycles += 12 ;\r
6027                                         else\r
6028                                                 TimingCycles += 20 ;\r
6029 \r
6030                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
6031                                         fprintf(fp, "\t\t and   ebx, byte 7\n");\r
6032                                         fprintf(fp, "\t\t shr   ecx, byte 9\n");\r
6033                                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
6034 \r
6035                                         EffectiveAddressRead(3+ModeModY,Size,EBX,EBX,"--C-S-B",FALSE);\r
6036                                         EffectiveAddressRead(3+ModeModX,Size,ECX,EAX,"-B--S-B",FALSE);\r
6037 \r
6038                                         fprintf(fp, "\t\t cmp   %s,%s\n",Regname,RegnameEBX);\r
6039                                         SetFlags(Size,EAX,FALSE,FALSE,FALSE);\r
6040                                         Completed();\r
6041                                 }\r
6042 \r
6043                                 OpcodeArray[Opcode] = BaseCode ;\r
6044                         }\r
6045 }\r
6046 \r
6047 void exg(void)\r
6048 {\r
6049         int     Opcode, BaseCode ;\r
6050         int     regx,type,regy ;\r
6051         int     opmask[3] = { 0x08, 0x09, 0x11} ;\r
6052 \r
6053         for (regx = 0 ; regx < 8 ; regx++)\r
6054                 for (type = 0 ; type < 3 ; type++)\r
6055                         for (regy = 0 ; regy < 8 ; regy++)\r
6056                         {\r
6057                                 Opcode = 0xc100 | (regx<<9) | (opmask[type]<<3) | regy ;\r
6058                                 BaseCode = Opcode & 0xc1c8 ;\r
6059 \r
6060                                 if (OpcodeArray[BaseCode] == -2)\r
6061                                 {\r
6062                                         Align();\r
6063                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6064                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6065 \r
6066                                         TimingCycles += 6 ;\r
6067 \r
6068                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
6069                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
6070                                         fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
6071                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6072 \r
6073                                         if (type == 0)\r
6074                                         {\r
6075                                                 fprintf(fp, "\t\t mov   eax,[%s+ECX*4]\n",REG_DAT);\r
6076                                                 fprintf(fp, "\t\t mov   edi,[%s+EBX*4]\n",REG_DAT);\r
6077                                                 fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_DAT);\r
6078                                                 fprintf(fp, "\t\t mov   [%s+EBX*4],eax\n",REG_DAT);\r
6079                                         }\r
6080                                         if (type == 1)\r
6081                                         {\r
6082                                                 fprintf(fp, "\t\t mov   eax,[%s+ECX*4]\n",REG_ADD);\r
6083                                                 fprintf(fp, "\t\t mov   edi,[%s+EBX*4]\n",REG_ADD);\r
6084                                                 fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_ADD);\r
6085                                                 fprintf(fp, "\t\t mov   [%s+EBX*4],eax\n",REG_ADD);\r
6086                                         }\r
6087                                         if (type == 2)\r
6088                                         {\r
6089                                                 fprintf(fp, "\t\t mov   eax,[%s+ECX*4]\n",REG_DAT);\r
6090                                                 fprintf(fp, "\t\t mov   edi,[%s+EBX*4]\n",REG_ADD);\r
6091                                                 fprintf(fp, "\t\t mov   [%s+ECX*4],edi\n",REG_DAT);\r
6092                                                 fprintf(fp, "\t\t mov   [%s+EBX*4],eax\n",REG_ADD);\r
6093                                         }\r
6094 \r
6095                                         Completed();\r
6096                                 }\r
6097 \r
6098                                 OpcodeArray[Opcode] = BaseCode ;\r
6099                         }\r
6100 }\r
6101 \r
6102 void ext(void)\r
6103 {\r
6104         int     Opcode, BaseCode ;\r
6105         int     type,regy ;\r
6106 \r
6107         for (type = 2 ; type < 8 ; type++)\r
6108                 for (regy = 0 ; regy < 8 ; regy++)\r
6109                 {\r
6110                         if (type > 3 && type < 7)\r
6111                                 continue ;\r
6112                         Opcode = 0x4800 | (type<<6) | regy ;\r
6113                         BaseCode = Opcode & 0x48c0 ;\r
6114 \r
6115                         if (OpcodeArray[BaseCode] == -2)\r
6116                         {\r
6117                                 Align();\r
6118                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6119                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6120 \r
6121                                 TimingCycles += 4 ;\r
6122 \r
6123                                 fprintf(fp, "\t\t and   ecx, byte 7\n");\r
6124 \r
6125                                 if (type == 2) /* byte to word */\r
6126                                 {\r
6127                                         fprintf(fp, "\t\t movsx eax,byte [%s+ECX*4]\n",REG_DAT);\r
6128                                         fprintf(fp, "\t\t mov   [%s+ECX*4],ax\n",REG_DAT);\r
6129                                         SetFlags('W',EAX,TRUE,FALSE,FALSE);\r
6130                                 }\r
6131                                 if (type == 3) /* word to long */\r
6132                                 {\r
6133                                         fprintf(fp, "\t\t movsx eax,word [%s+ECX*4]\n",REG_DAT);\r
6134                                         fprintf(fp, "\t\t mov   [%s+ECX*4],eax\n",REG_DAT);\r
6135                                         SetFlags('L',EAX,TRUE,FALSE,FALSE);\r
6136                                 }\r
6137                                 if (type == 7) /* byte to long */\r
6138                                 {\r
6139                                         fprintf(fp, "\t\t movsx eax,byte [%s+ECX*4]\n",REG_DAT);\r
6140                                         fprintf(fp, "\t\t mov   [%s+ECX*4],eax\n",REG_DAT);\r
6141                                         SetFlags('L',EAX,TRUE,FALSE,FALSE);\r
6142                                 }\r
6143                                 Completed();\r
6144                         }\r
6145 \r
6146                         OpcodeArray[Opcode] = BaseCode ;\r
6147                 }\r
6148 }\r
6149 \r
6150 void swap(void)\r
6151 {\r
6152         int     Opcode, BaseCode ;\r
6153         int     sreg ;\r
6154 \r
6155         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6156         {\r
6157                 Opcode = 0x4840 | sreg ;\r
6158                 BaseCode = Opcode & 0x4840;\r
6159 \r
6160                 if (OpcodeArray[BaseCode] == -2)\r
6161                 {\r
6162                         Align();\r
6163                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6164                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6165 \r
6166                         TimingCycles += 4 ;\r
6167 \r
6168                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
6169                         fprintf(fp, "\t\t mov   eax, dword [%s+ECX*4]\n",REG_DAT);\r
6170                         fprintf(fp, "\t\t ror   eax, 16\n");\r
6171                         fprintf(fp, "\t\t test  eax,eax\n");\r
6172                         fprintf(fp, "\t\t mov   dword [%s+ECX*4],eax\n",REG_DAT);\r
6173                         SetFlags('L',EAX,FALSE,FALSE,FALSE);\r
6174                         Completed();\r
6175                 }\r
6176 \r
6177                 OpcodeArray[Opcode] = BaseCode ;\r
6178         }\r
6179 }\r
6180 \r
6181 /*\r
6182  * Line A and Line F commands\r
6183  *\r
6184  */\r
6185 \r
6186 void LineA(void)\r
6187 {\r
6188         int Count;\r
6189 \r
6190         /* Line A */\r
6191 \r
6192         Align();\r
6193         fprintf(fp, "%s:\n",GenerateLabel(0xA000,0));\r
6194         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6195         Exception(0x0A,0xA000);\r
6196 \r
6197         for (Count=0xA000;Count<0xB000;Count++)\r
6198         {\r
6199                 OpcodeArray[Count] = 0xA000;\r
6200         }\r
6201 }\r
6202 \r
6203 void LineF(void)\r
6204 {\r
6205         int Count;\r
6206 \r
6207         /* Line F */\r
6208 \r
6209         Align();\r
6210         fprintf(fp, "%s:\n",GenerateLabel(0xF000,0));\r
6211         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6212         Exception(0x0B,0xF000);\r
6213 \r
6214         for (Count=0xF000;Count<0x10000;Count++)\r
6215         {\r
6216                 OpcodeArray[Count] = 0xF000;\r
6217         }\r
6218 }\r
6219 \r
6220 /*\r
6221  * Moves To/From CCR and SR\r
6222  *\r
6223  * (Move from CCR is 68010 command)\r
6224  *\r
6225  */\r
6226 \r
6227 void movesr(void)\r
6228 {\r
6229         int Opcode, BaseCode ;\r
6230         int type, mode, sreg ;\r
6231         int Dest ;\r
6232         char allow[] = "0-2345678-------" ;\r
6233         char Size;\r
6234 \r
6235         for (type = 0 ; type < 4 ; type++)\r
6236                 for (mode = 0 ; mode < 8 ; mode++)\r
6237                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6238                         {\r
6239                                 Opcode = 0x40c0 | (type << 9) | ( mode << 3 ) | sreg ;\r
6240 \r
6241                                 /* To has extra modes */\r
6242 \r
6243                                 if (type > 1)\r
6244                                 {\r
6245                                         allow[0x9] = '9';\r
6246                                         allow[0xa] = 'a';\r
6247                                         allow[0xb] = 'b' ;\r
6248                                 }\r
6249 \r
6250                                 if ((type == 0) | (type == 3))\r
6251                                         Size = 'W'; /* SR */\r
6252                                 else\r
6253                                         Size = 'B'; /* CCR */\r
6254 \r
6255                                 BaseCode = Opcode & 0x46f8 ;\r
6256 \r
6257                                 if (mode == 7)\r
6258                                         BaseCode |= sreg ;\r
6259 \r
6260                                 Dest = EAtoAMN(BaseCode, FALSE);\r
6261 \r
6262                                 if (allow[Dest&0xf] != '-')\r
6263                                 {\r
6264                                         if (OpcodeArray[BaseCode] == -2)\r
6265                                         {\r
6266                                                 char TrueLabel[16];\r
6267 \r
6268                                                 Align();\r
6269                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6270 \r
6271                                                 if ((Dest >= 2) && (Dest <=10))\r
6272                                                         SavePreviousPC();\r
6273 \r
6274                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6275 \r
6276                                                 if (type > 1) /* move to */\r
6277                                                         TimingCycles += 12 ;\r
6278                                                 else\r
6279                                                 {\r
6280                                                         if (mode < 2)\r
6281                                                                 TimingCycles += 6 ;\r
6282                                                         else\r
6283                                                                 TimingCycles += 8 ;\r
6284                                                 }\r
6285 \r
6286                                                 /* If Move to SR then must be in Supervisor Mode */\r
6287 \r
6288                                                 if (type == 3)\r
6289                                                 {\r
6290                                                         sprintf(TrueLabel,GenerateLabel(0,1));\r
6291 \r
6292                                                         fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
6293                                                         fprintf(fp, "\t\t je    near %s\n\n",TrueLabel);\r
6294                                                 }\r
6295 \r
6296                                                 /* 68010 Command ? */\r
6297                                                 if (type==1) CheckCPUtype(1);\r
6298 \r
6299 \r
6300                                                 if (mode < 7)\r
6301                                                 {\r
6302                                                         fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6303                                                 }\r
6304 \r
6305                                                 /* Always read/write word 2 bytes */\r
6306                                                 if (type < 2)\r
6307                                                 {\r
6308                                                         ReadCCR(Size,EBX);\r
6309                                                         EffectiveAddressWrite(Dest & 15,'W',ECX,TRUE,"---DS-B",TRUE);\r
6310                                                 }\r
6311                                                 else\r
6312                                                 {\r
6313                                                         EffectiveAddressRead(Dest & 15,'W',ECX,EAX,"----S-B",FALSE);\r
6314                                                         WriteCCR(Size);\r
6315                                                 }\r
6316                                                 Completed();\r
6317 \r
6318                                                 /* Exception if not Supervisor Mode */\r
6319 \r
6320                                                 if (type == 3)\r
6321                                                 {\r
6322                                                         /* Was in User Mode - Exception */\r
6323 \r
6324                                                         fprintf(fp, "%s:\n",TrueLabel);\r
6325                                                         Exception(8,BaseCode);\r
6326                                                 }\r
6327                                         }\r
6328 \r
6329                                         OpcodeArray[Opcode] = BaseCode ;\r
6330                                 }\r
6331                         }\r
6332 }\r
6333 \r
6334 /*\r
6335  * Decimal mode Add / Subtracts\r
6336  *\r
6337  */\r
6338 \r
6339 void abcd_sbcd(void)\r
6340 {\r
6341         int     Opcode, BaseCode ;\r
6342         int     regx,type,rm,regy,mode ;\r
6343         int ModeModX;\r
6344         int ModeModY;\r
6345         char *Label;\r
6346 \r
6347         for (type = 0 ; type < 2 ; type ++) /* 0=sbcd, 1=abcd */\r
6348                 for (regx = 0 ; regx < 8 ; regx++)\r
6349                         for (rm = 0 ; rm < 2 ; rm++)\r
6350                                 for (regy = 0 ; regy < 8 ; regy++)\r
6351                                 {\r
6352                                         Opcode = 0x8100 | (type<<14) | (regx<<9) | (rm<<3) | regy ;\r
6353                                         BaseCode = Opcode & 0xc108 ;\r
6354 \r
6355                                         ModeModX = 0;\r
6356                                         ModeModY = 0;\r
6357 \r
6358                                         if (rm == 0)\r
6359                                                 mode = 0 ;\r
6360                                         else\r
6361                                         {\r
6362                                                 mode = 4 ;\r
6363 \r
6364 #ifdef A7ROUTINE\r
6365 \r
6366                                                 if (regx == 7)\r
6367                                                 {\r
6368                                                         BaseCode |= (regx << 9);\r
6369                                                         ModeModY = 16;\r
6370                                                 }\r
6371                                                 if (regy == 7)\r
6372                                                 {\r
6373                                                         BaseCode |= regy;\r
6374                                                         ModeModX = 16;\r
6375                                                 }\r
6376 \r
6377 #endif\r
6378                                         }\r
6379 \r
6380                                         if (OpcodeArray[BaseCode] == -2)\r
6381                                         {\r
6382                                                 Align();\r
6383                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6384 \r
6385                                                 if (mode == 4)\r
6386                                                         SavePreviousPC();\r
6387 \r
6388                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6389 \r
6390                                                 AddEACycles = 0 ;\r
6391 \r
6392                                                 if (rm == 0)\r
6393                                                         TimingCycles += 6 ;\r
6394                                                 else\r
6395                                                         TimingCycles += 18 ;\r
6396 \r
6397                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
6398                                                 fprintf(fp, "\t\t and   ebx, byte 7\n");\r
6399                                                 fprintf(fp, "\t\t shr   ecx, byte 9\n");\r
6400                                                 fprintf(fp, "\t\t and   ecx, byte 7\n");\r
6401 \r
6402                                                 EffectiveAddressRead(mode+ModeModX,'B',EBX,EBX,"--C-S-B",TRUE);\r
6403                                                 EffectiveAddressRead(mode+ModeModY,'B',ECX,EAX,"-BC-SDB",TRUE);\r
6404 \r
6405                                                 CopyX();\r
6406 \r
6407                                                 if (type == 0)\r
6408                                                 {\r
6409                                                         fprintf(fp, "\t\t sbb   al,bl\n");\r
6410                                                         fprintf(fp, "\t\t das\n");\r
6411                                                 }\r
6412                                                 else\r
6413                                                 {\r
6414                                                         fprintf(fp, "\t\t adc   al,bl\n");\r
6415                                                         fprintf(fp, "\t\t daa\n");\r
6416                                                 }\r
6417 \r
6418                                                 /* Should only clear Zero flag if not zero */\r
6419 \r
6420                                                 Label = GenerateLabel(0,1);\r
6421 \r
6422                                                 fprintf(fp, "\t\t mov   ebx,edx\n");\r
6423                                                 fprintf(fp, "\t\t setc  dl\n");\r
6424 \r
6425                                                 fprintf(fp, "\t\t jnz   short %s\n\n",Label);\r
6426 \r
6427                                                 /* Keep original Zero flag */\r
6428                                                 fprintf(fp, "\t\t and   bl,40h        ; Mask out Old Z\n");\r
6429                                                 fprintf(fp, "\t\t or    dl,bl         ; Copy across\n\n");\r
6430 \r
6431                                                 fprintf(fp, "%s:\n",Label);\r
6432 \r
6433                                                 fprintf(fp, "\t\t mov   bl,dl\n");  /* copy carry into sign */\r
6434                                                 fprintf(fp, "\t\t and   bl,1\n");\r
6435                                                 fprintf(fp, "\t\t shl   bl,7\n");\r
6436                                                 fprintf(fp, "\t\t and   dl,7Fh\n");\r
6437                                                 fprintf(fp, "\t\t or    dl,bl\n");\r
6438 \r
6439                                                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
6440 \r
6441                                                 EffectiveAddressWrite(mode,'B',ECX,EAX,"---DS-B",TRUE);\r
6442                                                 Completed();\r
6443                                         }\r
6444 \r
6445                                         OpcodeArray[Opcode] = BaseCode ;\r
6446                                 }\r
6447 }\r
6448 \r
6449 /*\r
6450  * Rotate Left / Right\r
6451  *\r
6452  */\r
6453 \r
6454 void rol_ror(void)\r
6455 {\r
6456         int Opcode, BaseCode ;\r
6457         int dreg, dr, leng, ir, sreg ;\r
6458         char Size=' ';\r
6459         char * Label ;\r
6460         char * Regname="" ;\r
6461         char * RegnameECX ;\r
6462 \r
6463         for (dreg = 0 ; dreg < 8 ; dreg++)\r
6464                 for (dr = 0 ; dr < 2 ; dr++)\r
6465                         for (leng = 0 ; leng < 3 ; leng++)\r
6466                                 for (ir = 0 ; ir < 2 ; ir++)\r
6467                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6468                                         {\r
6469                                                 Opcode = 0xe018 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;\r
6470                                                 BaseCode = Opcode & 0xe1f8 ;\r
6471 \r
6472                                                 switch (leng)\r
6473                                                 {\r
6474                                                         case 0:\r
6475                                                                 Size = 'B';\r
6476                                                                 Regname = regnamesshort[0];\r
6477                                                                 RegnameECX = regnamesshort[ECX];\r
6478                                                                 break;\r
6479                                                         case 1:\r
6480                                                                 Size = 'W';\r
6481                                                                 Regname = regnamesword[0];\r
6482                                                                 RegnameECX = regnamesword[ECX];\r
6483                                                                 break;\r
6484                                                         case 2:\r
6485                                                                 Size = 'L';\r
6486                                                                 Regname = regnameslong[0];\r
6487                                                                 RegnameECX = regnameslong[ECX];\r
6488                                                                 break;\r
6489                                                 }\r
6490 \r
6491                                                 if (OpcodeArray[ BaseCode ] == -2)\r
6492                                                 {\r
6493                                                         Align();\r
6494                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6495                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6496 \r
6497                                                         if (Size != 'L')\r
6498                                                                 TimingCycles += 6 ;\r
6499                                                         else\r
6500                                                                 TimingCycles += 8 ;\r
6501 \r
6502                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
6503                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
6504                                                         fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
6505 \r
6506                                                         if (ir == 0)\r
6507                                                         {\r
6508                                                                 Immediate8();\r
6509                                                         }\r
6510                                                         else\r
6511                                                         {\r
6512                                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6513                                                                 EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE);\r
6514                                                                 fprintf(fp, "\t\t and   ecx,byte 63\n");\r
6515                                                         }\r
6516 \r
6517                                                         EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE);\r
6518 \r
6519                                                         /* shift 0 - no time, no shift and clear carry */\r
6520 \r
6521                                                         Label = GenerateLabel(0,1);\r
6522                                                         fprintf(fp, "\t\t jecxz %s\n",Label);\r
6523 \r
6524                                                         /* allow 2 cycles per shift */\r
6525 \r
6526                                                         fprintf(fp, "\t\t mov   edx,ecx\n");\r
6527                                                         fprintf(fp, "\t\t add   edx,edx\n");\r
6528                                                         fprintf(fp, "\t\t sub   dword [%s],edx\n",ICOUNT);\r
6529 \r
6530                                                         if (dr == 0)\r
6531                                                                 fprintf(fp, "\t\t ror   %s,cl\n",Regname);\r
6532                                                         else\r
6533                                                                 fprintf(fp, "\t\t rol   %s,cl\n",Regname);\r
6534 \r
6535                                                         fprintf(fp, "\t\t setc  ch\n");\r
6536 \r
6537                                                         fprintf(fp, "%s:\n",Label);\r
6538 \r
6539                                                         SetFlags(Size,EAX,TRUE,FALSE,FALSE);\r
6540 /*                      fprintf(fp, "\t\t and   dl,254\n");  Test clears Carry */\r
6541                                                         fprintf(fp, "\t\t or    dl,ch\n");\r
6542 \r
6543                                                         EffectiveAddressWrite(0,Size,EBX,EAX,"--C-S-B",TRUE);\r
6544 \r
6545                                                         Completed();\r
6546                                                 }\r
6547 \r
6548                                                 OpcodeArray[Opcode] = BaseCode ;\r
6549                                         }\r
6550 }\r
6551 \r
6552 void rol_ror_ea(void)\r
6553 {\r
6554         int Opcode, BaseCode ;\r
6555         int dr, mode, sreg ;\r
6556         int Dest ;\r
6557         char allow[] = "--2345678-------" ;\r
6558 \r
6559         for (dr = 0 ; dr < 2 ; dr++)\r
6560                 for (mode = 0 ; mode < 8 ; mode++)\r
6561                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6562                         {\r
6563                                 Opcode = 0xe6c0 | (dr<<8) | (mode<<3) | sreg ;\r
6564                                 BaseCode = Opcode & 0xfff8 ;\r
6565 \r
6566                                 if (mode == 7)\r
6567                                         BaseCode |= sreg ;\r
6568 \r
6569                                 Dest = EAtoAMN(BaseCode, FALSE);\r
6570 \r
6571                                 if (allow[Dest&0xf] != '-')\r
6572                                 {\r
6573                                         if (OpcodeArray[ BaseCode ] == -2)\r
6574                                         {\r
6575                                                 Align();\r
6576                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6577 \r
6578                                                 if ((Dest >= 2) && (Dest <=10))\r
6579                                                         SavePreviousPC();\r
6580 \r
6581                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6582 \r
6583                                                 TimingCycles += 8 ;\r
6584 \r
6585                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6586                                                 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);\r
6587 \r
6588                                                 if (dr == 0)\r
6589                                                         fprintf(fp, "\t\t ror   ax,1\n");\r
6590                                                 else\r
6591                                                         fprintf(fp, "\t\t rol   ax,1\n");\r
6592 \r
6593                                                 fprintf(fp, "\t\t setc  bl\n");\r
6594                                                 SetFlags('W',EAX,TRUE,FALSE,FALSE);\r
6595 /*                              fprintf(fp, "\t\t and   dl,254\n");  Test clears Carry */\r
6596                                                 fprintf(fp, "\t\t or    dl,bl\n");\r
6597 \r
6598                                                 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE);\r
6599 \r
6600                                                 Completed();\r
6601                                         }\r
6602 \r
6603                                         OpcodeArray[Opcode] = BaseCode ;\r
6604                                 }\r
6605                         }\r
6606 }\r
6607 \r
6608 /*\r
6609  * Logical Shift Left / Right\r
6610  *\r
6611  */\r
6612 \r
6613 void lsl_lsr(void)\r
6614 {\r
6615         int Opcode, BaseCode ;\r
6616         int dreg, dr, leng, ir, sreg ;\r
6617         char Size=' ';\r
6618         char * Regname="" ;\r
6619         char * RegnameECX="" ;\r
6620         char * RegnameEDX="" ;\r
6621         char * Label ;\r
6622 \r
6623         for (dreg = 0 ; dreg < 8 ; dreg++)\r
6624                 for (dr = 0 ; dr < 2 ; dr++)\r
6625                         for (leng = 0 ; leng < 3 ; leng++)\r
6626                                 for (ir = 0 ; ir < 2 ; ir++)\r
6627                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6628                                         {\r
6629                                                 Opcode = 0xe008 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;\r
6630                                                 BaseCode = Opcode & 0xe1f8 ;\r
6631 \r
6632                                                 switch (leng)\r
6633                                                 {\r
6634                                                         case 0:\r
6635                                                                 Size = 'B';\r
6636                                                                 Regname = regnamesshort[0];\r
6637                                                                 RegnameECX = regnamesshort[ECX];\r
6638                                                                 RegnameEDX = regnamesshort[EDX];\r
6639                                                                 break;\r
6640                                                         case 1:\r
6641                                                                 Size = 'W';\r
6642                                                                 Regname = regnamesword[0];\r
6643                                                                 RegnameECX = regnamesword[ECX];\r
6644                                                                 RegnameEDX = regnamesword[EDX];\r
6645                                                                 break;\r
6646                                                         case 2:\r
6647                                                                 Size = 'L';\r
6648                                                                 Regname = regnameslong[0];\r
6649                                                                 RegnameECX = regnameslong[ECX];\r
6650                                                                 RegnameEDX = regnameslong[EDX];\r
6651                                                                 break;\r
6652                                                 }\r
6653 \r
6654                                                 if (OpcodeArray[ BaseCode ] == -2)\r
6655                                                 {\r
6656                                                         Align();\r
6657                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6658                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6659 \r
6660                                                         if (Size != 'L')\r
6661                                                                 TimingCycles += 6 ;\r
6662                                                         else\r
6663                                                                 TimingCycles += 8 ;\r
6664 \r
6665                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
6666                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
6667                                                         fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
6668 \r
6669                                                         if (ir == 0)\r
6670                                                         {\r
6671                                                                 Immediate8();\r
6672                                                         }\r
6673                                                         else\r
6674                                                         {\r
6675                                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6676                                                                 EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE);\r
6677                                                                 fprintf(fp, "\t\t and   ecx,byte 63\n");\r
6678                                                         }\r
6679 \r
6680                                                         /* and 2 cycles per shift */\r
6681 \r
6682                                                         fprintf(fp, "\t\t mov   edx,ecx\n");\r
6683                                                         fprintf(fp, "\t\t add   edx,edx\n");\r
6684                                                         fprintf(fp, "\t\t sub   dword [%s],edx\n",ICOUNT);\r
6685 \r
6686                                                         EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE);\r
6687 \r
6688                                                         /* ASG: on the 68k, the shift count is mod 64; on the x86, the */\r
6689                                                         /* shift count is mod 32; we need to check for shifts of 32-63 */\r
6690                                                         /* and produce zero */\r
6691                                                         Label = GenerateLabel(0,1);\r
6692                                                         fprintf(fp, "\t\t test  cl,0x20\n");\r
6693                                                         fprintf(fp, "\t\t jnz   %s_BigShift\n",Label);\r
6694 \r
6695                                                         fprintf(fp, "%s_Continue:\n",Label);\r
6696                                                         if (dr == 0)\r
6697                                                                 fprintf(fp, "\t\t shr   %s,cl\n",Regname);\r
6698                                                         else\r
6699                                                                 fprintf(fp, "\t\t shl   %s,cl\n",Regname);\r
6700 \r
6701                                                         SetFlags(Size,EAX,FALSE,FALSE,FALSE);\r
6702 \r
6703                                                         /* Clear Overflow flag */\r
6704                                                         fprintf(fp, "\t\t xor   dh,dh\n");\r
6705 \r
6706                                                         EffectiveAddressWrite(0,Size,EBX,EAX,"--CDS-B",TRUE);\r
6707 \r
6708                                                         /* if shift count is zero clear carry */\r
6709 \r
6710                                                         fprintf(fp, "\t\t jecxz %s\n",Label);\r
6711 \r
6712                                                         fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
6713                                                         Completed();\r
6714 \r
6715                                                         Align();\r
6716                                                         fprintf(fp, "%s:\n",Label);\r
6717                                                         fprintf(fp, "\t\t and   dl,254\t\t;clear C flag\n");\r
6718                                                         Completed();\r
6719 \r
6720                                                         fprintf(fp, "%s_BigShift:\n",Label);\r
6721                                                         if (dr == 0)\r
6722                                                         {\r
6723                                                                 fprintf(fp, "\t\t shr   %s,16\n",Regname);\r
6724                                                                 fprintf(fp, "\t\t shr   %s,16\n",Regname);\r
6725                                                         }\r
6726                                                         else\r
6727                                                         {\r
6728                                                                 fprintf(fp, "\t\t shl   %s,16\n",Regname);\r
6729                                                                 fprintf(fp, "\t\t shl   %s,16\n",Regname);\r
6730                                                         }\r
6731                                                         fprintf(fp, "\t\t jmp   %s_Continue\n",Label);\r
6732                                                 }\r
6733 \r
6734                                                 OpcodeArray[Opcode] = BaseCode ;\r
6735                                         }\r
6736 }\r
6737 \r
6738 void lsl_lsr_ea(void)\r
6739 {\r
6740         int Opcode, BaseCode ;\r
6741         int dr, mode, sreg ;\r
6742         int Dest ;\r
6743         char allow[] = "--2345678-------" ;\r
6744 \r
6745         for (dr = 0 ; dr < 2 ; dr++)\r
6746                 for (mode = 0 ; mode < 8 ; mode++)\r
6747                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6748                         {\r
6749                                 Opcode = 0xe2c0 | (dr<<8) | (mode<<3) | sreg ;\r
6750                                 BaseCode = Opcode & 0xfff8 ;\r
6751 \r
6752                                 if (mode == 7)\r
6753                                         BaseCode |= sreg ;\r
6754 \r
6755                                 Dest = EAtoAMN(BaseCode, FALSE);\r
6756 \r
6757                                 if (allow[Dest&0xf] != '-')\r
6758                                 {\r
6759                                         if (OpcodeArray[ BaseCode ] == -2)\r
6760                                         {\r
6761 \r
6762                                                 Align();\r
6763                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6764 \r
6765                                                 if ((Dest >= 2) && (Dest <=10))\r
6766                                                         SavePreviousPC();\r
6767 \r
6768                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6769 \r
6770                                                 TimingCycles += 8 ;\r
6771 \r
6772                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6773                                                 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);\r
6774 \r
6775                                                 if (dr == 0)\r
6776                                                         fprintf(fp, "\t\t shr   ax,1\n");\r
6777                                                 else\r
6778                                                         fprintf(fp, "\t\t shl   ax,1\n");\r
6779 \r
6780                                                 SetFlags('W',EAX,FALSE,TRUE,FALSE);\r
6781 \r
6782                                                 /* Clear Overflow flag */\r
6783 \r
6784                                                 fprintf(fp, "\t\t xor   dh,dh\n");\r
6785 \r
6786                                                 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE);\r
6787                                                 Completed();\r
6788                                         }\r
6789 \r
6790                                         OpcodeArray[Opcode] = BaseCode ;\r
6791                                 }\r
6792                         }\r
6793 }\r
6794 \r
6795 /*\r
6796  * Rotate Left / Right though Extend\r
6797  *\r
6798  */\r
6799 \r
6800 void roxl_roxr(void)\r
6801 {\r
6802         int Opcode, BaseCode ;\r
6803         int dreg, dr, leng, ir, sreg ;\r
6804         char Size=' ' ;\r
6805         char * Regname="" ;\r
6806         char * RegnameECX="" ;\r
6807         char * Label ;\r
6808 \r
6809         for (dreg = 0 ; dreg < 8 ; dreg++)\r
6810                 for (dr = 0 ; dr < 2 ; dr++)\r
6811                         for (leng = 0 ; leng < 3 ; leng++)\r
6812                                 for (ir = 0 ; ir < 2 ; ir++)\r
6813                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6814                                         {\r
6815                                                 Opcode = 0xe010 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;\r
6816                                                 BaseCode = Opcode & 0xe1f8 ;\r
6817 \r
6818                                                 switch (leng)\r
6819                                                 {\r
6820                                                         case 0:\r
6821                                                                 Size = 'B';\r
6822                                                                 Regname = regnamesshort[0];\r
6823                                                                 RegnameECX = regnamesshort[ECX];\r
6824                                                                 break;\r
6825                                                         case 1:\r
6826                                                                 Size = 'W';\r
6827                                                                 Regname = regnamesword[0];\r
6828                                                                 RegnameECX = regnamesword[ECX];\r
6829                                                                 break;\r
6830                                                         case 2:\r
6831                                                                 Size = 'L';\r
6832                                                                 Regname = regnameslong[0];\r
6833                                                                 RegnameECX = regnameslong[ECX];\r
6834                                                                 break;\r
6835                                                 }\r
6836 \r
6837                                                 if (OpcodeArray[ BaseCode ] == -2)\r
6838                                                 {\r
6839                                                         Align();\r
6840                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6841                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6842 \r
6843                                                         if (Size != 'L')\r
6844                                                                 TimingCycles += 6 ;\r
6845                                                         else\r
6846                                                                 TimingCycles += 8 ;\r
6847 \r
6848                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
6849                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
6850                                                         fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
6851 \r
6852                                                         if (ir == 0)\r
6853                                                         {\r
6854                                                                 Immediate8();\r
6855                                                         }\r
6856                                                         else\r
6857                                                         {\r
6858                                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6859                                                                 EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE);\r
6860                                                                 fprintf(fp, "\t\t and   ecx,byte 63\n");\r
6861                                                         }\r
6862 \r
6863                                                         /* allow 2 cycles per shift */\r
6864 \r
6865                                                         fprintf(fp, "\t\t mov   edx,ecx\n");\r
6866                                                         fprintf(fp, "\t\t add   edx,edx\n");\r
6867                                                         fprintf(fp, "\t\t sub   dword [%s],edx\n",ICOUNT);\r
6868 \r
6869                                                         EffectiveAddressRead(0,Size,EBX,EAX,"-BC-SDB",FALSE);\r
6870 \r
6871                                                         /* move X into C so RCR & RCL can be used */\r
6872                                                         /* RCR & RCL only set the carry flag            */\r
6873 \r
6874                                                         CopyX();\r
6875 \r
6876                                                         if (dr == 0)\r
6877                                                                 fprintf(fp, "\t\t rcr   %s,cl\n",Regname);\r
6878                                                         else\r
6879                                                                 fprintf(fp, "\t\t rcl   %s,cl\n",Regname);\r
6880 \r
6881                                                         fprintf(fp, "\t\t setc  ch\n");\r
6882                                                         SetFlags(Size,EAX,TRUE,FALSE,FALSE);\r
6883 /*                      fprintf(fp, "\t\t and   dl,254\n"); Test Clears Carry */\r
6884 \r
6885                                                         EffectiveAddressWrite(0,Size,EBX,EAX,"--CDS-B",TRUE);\r
6886 \r
6887                                                         /* if shift count is zero clear carry */\r
6888 \r
6889                                                         Label = GenerateLabel(0,1);\r
6890                                                         fprintf(fp, "\t\t test  cl,cl\n");\r
6891                                                         fprintf(fp, "\t\t jz    %s\n",Label);\r
6892 \r
6893                                                         /* Add in Carry Flag */\r
6894 \r
6895                                                         fprintf(fp, "\t\t or    dl,ch\n");\r
6896                                                         fprintf(fp, "\t\t mov   [%s],dl\n",REG_X);\r
6897                                                         Completed();\r
6898 \r
6899 \r
6900                                                         /* copy X onto C when shift is zero */\r
6901 \r
6902                                                         Align();\r
6903                                                         fprintf(fp, "%s:\n",Label);\r
6904                                                         fprintf(fp, "\t\t mov   ecx,[%s]\n",REG_X);\r
6905                                                         fprintf(fp, "\t\t and   ecx,byte 1\n");\r
6906                                                         fprintf(fp, "\t\t or    edx,ecx\n");\r
6907                                                         Completed();\r
6908                                                 }\r
6909 \r
6910                                                 OpcodeArray[Opcode] = BaseCode ;\r
6911                                         }\r
6912 }\r
6913 \r
6914 void roxl_roxr_ea(void)\r
6915 {\r
6916         int Opcode, BaseCode ;\r
6917         int dr, mode, sreg ;\r
6918         int Dest ;\r
6919         char allow[] = "--2345678-------" ;\r
6920 \r
6921         for (dr = 0 ; dr < 2 ; dr++)\r
6922                 for (mode = 0 ; mode < 8 ; mode++)\r
6923                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6924                         {\r
6925                                 Opcode = 0xe4c0 | (dr<<8) | (mode<<3) | sreg ;\r
6926                                 BaseCode = Opcode & 0xfff8 ;\r
6927 \r
6928                                 if (mode == 7)\r
6929                                         BaseCode |= sreg ;\r
6930 \r
6931                                 Dest = EAtoAMN(BaseCode, FALSE);\r
6932 \r
6933                                 if (allow[Dest&0xf] != '-')\r
6934                                 {\r
6935                                         if (OpcodeArray[ BaseCode ] == -2)\r
6936                                         {\r
6937                                                 Align();\r
6938                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
6939 \r
6940                                                 if ((Dest >= 2) && (Dest <=10))\r
6941                                                         SavePreviousPC();\r
6942 \r
6943                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
6944 \r
6945                                                 TimingCycles += 8 ;\r
6946 \r
6947                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
6948                                                 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);\r
6949 \r
6950                                                 /* move X into C so RCR & RCL can be used */\r
6951                                                 /* RCR & RCL only set the carry flag            */\r
6952 \r
6953                                                 CopyX();\r
6954 \r
6955                                                 if (dr == 0)\r
6956                                                         fprintf(fp, "\t\t rcr   ax,1\n");\r
6957                                                 else\r
6958                                                         fprintf(fp, "\t\t rcl   ax,1\n");\r
6959 \r
6960                                                 fprintf(fp, "\t\t setc  bl\n");\r
6961                                                 SetFlags('W',EAX,TRUE,FALSE,FALSE);\r
6962 /*                              fprintf(fp, "\t\t and   dl,254\n"); - Intel Clears on Test */\r
6963                                                 fprintf(fp, "\t\t or    dl,bl\n");\r
6964 \r
6965                                                 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE);\r
6966 \r
6967                                                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
6968                                                 Completed();\r
6969                                         }\r
6970 \r
6971                                         OpcodeArray[Opcode] = BaseCode ;\r
6972                                 }\r
6973                         }\r
6974 }\r
6975 \r
6976 /*\r
6977  * Arithmetic Shift Left / Right\r
6978  *\r
6979  */\r
6980 \r
6981 void asl_asr(void)\r
6982 {\r
6983         int Opcode, BaseCode ;\r
6984         int dreg, dr, leng, ir, sreg ;\r
6985         char Size=' ';\r
6986         char * Sizename="" ;\r
6987         char * Regname="" ;\r
6988         char * RegnameEDX="" ;\r
6989         char * RegnameECX="" ;\r
6990         char * Label;\r
6991 \r
6992         /* Normal routines for codes */\r
6993 \r
6994         for (dreg = 0 ; dreg < 8 ; dreg++)\r
6995                 for (dr = 0 ; dr < 2 ; dr++)\r
6996                         for (leng = 0 ; leng < 3 ; leng++)\r
6997                                 for (ir = 0 ; ir < 2 ; ir++)\r
6998                                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
6999                                         {\r
7000                                                 Opcode = 0xe000 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;\r
7001                                                 BaseCode = Opcode & 0xe1f8 ;\r
7002 \r
7003                                                 switch (leng)\r
7004                                                 {\r
7005                                                         case 0:\r
7006                                                                 Size = 'B';\r
7007                                                                 Regname = regnamesshort[0];\r
7008                                                                 RegnameECX = regnamesshort[ECX];\r
7009                                                                 RegnameEDX = regnamesshort[EDX];\r
7010                                                                 break;\r
7011                                                         case 1:\r
7012                                                                 Size = 'W';\r
7013                                                                 Regname = regnamesword[0];\r
7014                                                                 RegnameECX = regnamesword[ECX];\r
7015                                                                 RegnameEDX = regnamesword[EDX];\r
7016                                                                 break;\r
7017                                                         case 2:\r
7018                                                                 Size = 'L';\r
7019                                                                 Regname = regnameslong[0];\r
7020                                                                 RegnameECX = regnameslong[ECX];\r
7021                                                                 RegnameEDX = regnameslong[EDX];\r
7022                                                                 break;\r
7023                                                 }\r
7024 \r
7025                                                 if (OpcodeArray[ BaseCode ] == -2)\r
7026                                                 {\r
7027                                                         Align();\r
7028                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
7029                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
7030 \r
7031                                                         Label = GenerateLabel(0,1);\r
7032 \r
7033                                                         if (Size != 'L')\r
7034                                                                 TimingCycles += 6 ;\r
7035                                                         else\r
7036                                                                 TimingCycles += 8 ;\r
7037 \r
7038                                                         fprintf(fp, "\t\t mov   ebx,ecx\n");\r
7039                                                         fprintf(fp, "\t\t and   ebx,byte 7\n");\r
7040                                                         fprintf(fp, "\t\t shr   ecx,byte 9\n");\r
7041 \r
7042                                                         EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE);\r
7043 \r
7044                                                         if (ir == 0)\r
7045                                                         {\r
7046                                                                 Immediate8();\r
7047                                                         }\r
7048                                                         else\r
7049                                                         {\r
7050                                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
7051                                                                 EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE);\r
7052                                                                 fprintf(fp, "\t\t and   ecx,byte 63\n");\r
7053                                                                 fprintf(fp, "\t\t jz   short %s\n",Label);\r
7054                                                         }\r
7055 \r
7056                                                         /* allow 2 cycles per shift */\r
7057 \r
7058                                                         fprintf(fp, "\t\t mov   edx,ecx\n");\r
7059                                                         fprintf(fp, "\t\t add   edx,edx\n");\r
7060                                                         fprintf(fp, "\t\t sub   dword [%s],edx\n",ICOUNT);\r
7061 \r
7062                                                         if (dr == 0)\r
7063                                                         {\r
7064                                                                 /* ASR */\r
7065 \r
7066                                                                 /* ASG: on the 68k, the shift count is mod 64; on the x86, the */\r
7067                                                                 /* shift count is mod 32; we need to check for shifts of 32-63 */\r
7068                                                                 /* and effectively shift 31 */\r
7069                                                                 fprintf(fp, "\t\t shrd  edx,ecx,6\n");\r
7070                                                                 fprintf(fp, "\t\t sar   edx,31\n");\r
7071                                                                 fprintf(fp, "\t\t and   edx,31\n");\r
7072                                                                 fprintf(fp, "\t\t or    ecx,edx\n");\r
7073 \r
7074                                                                 fprintf(fp, "\t\t sar   %s,cl\n",Regname);\r
7075 \r
7076                                                                 /* Mode 0 write does not affect Flags */\r
7077                                                                 EffectiveAddressWrite(0,Size,EBX,EAX,"---DS-B",TRUE);\r
7078 \r
7079                                                                 /* Update Flags */\r
7080                                                                 fprintf(fp, "\t\t lahf\n");\r
7081 \r
7082 #ifdef STALLCHECK\r
7083                                                 ClearRegister(EDX);\r
7084                                                                 fprintf(fp, "\t\t mov   dl,ah\n");\r
7085 #else\r
7086                                                                 fprintf(fp, "\t\t movzx edx,ah\n");\r
7087 #endif\r
7088 \r
7089                                                                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
7090                                                         }\r
7091                                                         else\r
7092                                                         {\r
7093                                                                 /* ASL */\r
7094 \r
7095                                                                 /* Check to see if Overflow should be set */\r
7096 \r
7097                                                                 fprintf(fp,"\t\t mov   edi,eax\t\t; Save It\n");\r
7098 \r
7099                                                                 ClearRegister(EDX);\r
7100                                                                 fprintf(fp,"\t\t stc\n");\r
7101                                                                 fprintf(fp,"\t\t rcr   %s,1\t\t; d=1xxxx\n",RegnameEDX);\r
7102                                                                 fprintf(fp,"\t\t sar   %s,cl\t\t; d=1CCxx\n",RegnameEDX);\r
7103                                                                 fprintf(fp,"\t\t and   eax,edx\n");\r
7104                                                                 fprintf(fp,"\t\t jz    short %s_V\t\t; No Overflow\n",Label);\r
7105                                                                 fprintf(fp,"\t\t cmp   eax,edx\n");\r
7106                                                                 fprintf(fp,"\t\t je    short %s_V\t\t; No Overflow\n",Label);\r
7107 \r
7108                                                                 /* Set Overflow */\r
7109                                                                 fprintf(fp,"\t\t mov   edx,0x800\n");\r
7110                                                                 fprintf(fp,"\t\t jmp   short %s_OV\n",Label);\r
7111 \r
7112                                                                 fprintf(fp,"%s_V:\n",Label);\r
7113                                                                 ClearRegister(EDX);\r
7114 \r
7115                                                                 fprintf(fp,"%s_OV:\n",Label);\r
7116 \r
7117                                                                 /* more than 31 shifts and long */\r
7118 \r
7119                                                                 if ((ir==1) && (leng==2))\r
7120                                                                 {\r
7121                                                                         fprintf(fp,"\t\t test  cl,0x20\n");\r
7122                                                                         fprintf(fp,"\t\t jnz   short %s_32\n\n",Label);\r
7123                                                                 }\r
7124 \r
7125                                                                 fprintf(fp,"\t\t mov   eax,edi\t\t; Restore It\n");\r
7126 \r
7127                                                                 fprintf(fp, "\t\t sal   %s,cl\n",Regname);\r
7128 \r
7129                                                                 EffectiveAddressWrite(0,Size,EBX,EAX,"---DS-B",TRUE);\r
7130                                                                 fprintf(fp, "\t\t lahf\n");\r
7131                                                                 fprintf(fp, "\t\t mov   dl,ah\n");\r
7132                                                                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_X);\r
7133                                                         }\r
7134                                                         Completed();\r
7135 \r
7136                                                         if (ir != 0)\r
7137                                                         {\r
7138                                                                 Align();\r
7139                                                                 fprintf(fp, "%s:\n",Label);\r
7140 \r
7141 \r
7142                                                                 if (dr == 0)\r
7143                                                                 {\r
7144                                                                         /* ASR - Test clears V and C */\r
7145                                                                         SetFlags(Size,EAX,TRUE,FALSE,FALSE);\r
7146                                                                 }\r
7147                                                                 else\r
7148                                                                 {\r
7149                                                                         /* ASL - Keep existing Carry flag, Clear V */\r
7150                                                                         fprintf(fp, "\t\t mov   ebx,edx\n");\r
7151                                                                         fprintf(fp, "\t\t and   ebx,byte 1\n");\r
7152                                                                         SetFlags(Size,EAX,TRUE,FALSE,FALSE);\r
7153                                                                         fprintf(fp, "\t\t or    edx,ebx\n");\r
7154 \r
7155                                                                         if (leng==2)\r
7156                                                                         {\r
7157                                                                                 Completed();\r
7158 \r
7159                                                                                 /* > 31 Shifts */\r
7160 \r
7161                                                                                 fprintf(fp, "%s_32:\n",Label);\r
7162                                                                                 fprintf(fp, "\t\t mov   dl,40h\n");      // Zero flag\r
7163                                                                                 ClearRegister(EAX);\r
7164                                                                                 EffectiveAddressWrite(0,Size,EBX,EAX,"----S-B",TRUE);\r
7165                                                                         }\r
7166                                                                 }\r
7167 \r
7168                                                                 Completed();\r
7169                                                         }\r
7170                                                 }\r
7171 \r
7172                                                 OpcodeArray[Opcode] = BaseCode ;\r
7173                                         }\r
7174 \r
7175         /* End with special routines for ASL.x #1,Dx  */\r
7176         /* To do correct V setting, ASL needs quite a */\r
7177         /* bit of additional code. A Shift of one has */\r
7178         /* correct flags on Intel, and is very common */\r
7179         /* in 68000 programs.                                                            */\r
7180 \r
7181         for (leng = 0 ; leng < 3 ; leng++)\r
7182                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
7183                 {\r
7184                         Opcode = 0xe300 | (leng<<6) | sreg ;\r
7185                         BaseCode = Opcode & 0xe3c8 ;\r
7186 \r
7187                         switch (leng)\r
7188                         {\r
7189                                 case 0:\r
7190                                         Sizename = "byte";\r
7191                                         break;\r
7192                                 case 1:\r
7193                                         Sizename = "word";\r
7194                                         break;\r
7195                                 case 2:\r
7196                                         Sizename = "long";\r
7197                                         break;\r
7198                         }\r
7199 \r
7200                         if (sreg == 0)\r
7201                         {\r
7202                                 Align();\r
7203                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
7204                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
7205 \r
7206                                 Label = GenerateLabel(0,1);\r
7207 \r
7208                                 if (Size != 'L')\r
7209                                         TimingCycles += 6 ;\r
7210                                 else\r
7211                                         TimingCycles += 8 ;\r
7212 \r
7213                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
7214                                 fprintf(fp, "\t\t sal   %s [%s+ecx*4],1\n",Sizename,REG_DAT);\r
7215                                 SetFlags('L',EAX,FALSE,TRUE,FALSE);\r
7216                                 Completed();\r
7217 \r
7218                         }\r
7219 \r
7220                         OpcodeArray[Opcode] = BaseCode ;\r
7221                 }\r
7222 }\r
7223 \r
7224 void asl_asr_ea(void)\r
7225 {\r
7226         int Opcode, BaseCode ;\r
7227         int dr, mode, sreg ;\r
7228         int Dest ;\r
7229         char allow[] = "--2345678-------" ;\r
7230 \r
7231         for (dr = 0 ; dr < 2 ; dr++)\r
7232                 for (mode = 0 ; mode < 8 ; mode++)\r
7233                         for (sreg = 0 ; sreg < 8 ; sreg++)\r
7234                         {\r
7235                                 Opcode = 0xe0c0 | (dr<<8) | (mode<<3) | sreg ;\r
7236                                 BaseCode = Opcode & 0xfff8 ;\r
7237 \r
7238                                 if (mode == 7)\r
7239                                         BaseCode |= sreg ;\r
7240 \r
7241                                 Dest = EAtoAMN(BaseCode, FALSE);\r
7242 \r
7243                                 if (allow[Dest&0xf] != '-')\r
7244                                 {\r
7245                                         if (OpcodeArray[ BaseCode ] == -2)\r
7246                                         {\r
7247 \r
7248                                                 Align();\r
7249                                                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
7250 \r
7251                                                 if ((Dest >= 2) && (Dest <=10))\r
7252                                                         SavePreviousPC();\r
7253 \r
7254                                                 fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
7255 \r
7256                                                 TimingCycles += 8 ;\r
7257 \r
7258                                                 fprintf(fp, "\t\t and   ecx,byte 7\n");\r
7259                                                 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);\r
7260 \r
7261                                                 if (dr == 0)\r
7262                                                         fprintf(fp, "\t\t sar   ax,1\n");\r
7263                                                 else\r
7264                                                         fprintf(fp, "\t\t sal   ax,1\n");\r
7265 \r
7266                                                 SetFlags('W',EAX,FALSE,TRUE,TRUE);\r
7267 \r
7268                                                 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"----S-B",FALSE);\r
7269                                                 Completed();\r
7270                                         }\r
7271 \r
7272                                         OpcodeArray[Opcode] = BaseCode ;\r
7273                                 }\r
7274                         }\r
7275 }\r
7276 \r
7277 /*\r
7278  * Divide Commands\r
7279  */\r
7280 \r
7281 void divides(void)\r
7282 {\r
7283         int dreg, type, mode, sreg ;\r
7284         int Opcode, BaseCode ;\r
7285         int Dest ;\r
7286         char allow[] = "0-23456789ab-----" ;\r
7287         char TrapLabel[16];\r
7288         int Cycles;\r
7289 \r
7290         int divide_cycles[12] =\r
7291         {\r
7292                 38,0,42,42,44,46,50,46,50,46,48,42\r
7293         };\r
7294 \r
7295         for (dreg = 0 ; dreg < 8 ; dreg++)\r
7296                 for (type = 0 ; type < 2 ; type++)\r
7297                         for (mode = 0 ; mode < 8 ; mode++)\r
7298                                 for (sreg = 0 ; sreg < 8 ; sreg++)\r
7299                                 {\r
7300                                         Opcode = 0x80c0 | (dreg<<9) | (type<<8) | (mode<<3) | sreg ;\r
7301                                         BaseCode = Opcode & 0x81f8 ;\r
7302                                         if (mode == 7)\r
7303                                         {\r
7304                                                 BaseCode |= sreg ;\r
7305                                         }\r
7306 \r
7307                                         Dest = EAtoAMN(Opcode, FALSE);\r
7308                                         if (allow[Dest&0x0f] != '-')\r
7309                                         {\r
7310                                                 if (OpcodeArray[ BaseCode ] == -2)\r
7311                                                 {\r
7312                                                         Align();\r
7313                                                         fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
7314 \r
7315                                                         if ((Dest >= 2) && (Dest <=10))\r
7316                                                                 SavePreviousPC();\r
7317 \r
7318                                                         fprintf(fp, "\t\t add   esi,byte 2\n\n");\r
7319 \r
7320 \r
7321                                                         /* Save EDX (in case of overflow) */\r
7322 \r
7323                                                         fprintf(fp, "\t\t and   edx,byte -2\n");\r
7324                                                         fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
7325 \r
7326 \r
7327                                                         /* Cycle Timing (if succeeds OK) */\r
7328 \r
7329                                                         Cycles = divide_cycles[Dest & 0x0f] + 95 + (type * 17);\r
7330 \r
7331                                                         if (Cycles > 127)\r
7332                                                                 fprintf(fp, "\t\t sub   dword [%s],%d\n",ICOUNT,Cycles);\r
7333                                                         else\r
7334                                                                 fprintf(fp, "\t\t sub   dword [%s],byte %d\n",ICOUNT,Cycles);\r
7335 \r
7336                                                         if (mode < 7)\r
7337                                                         {\r
7338                                                                 fprintf(fp, "\t\t mov   ebx,ecx\n");\r
7339                                                                 fprintf(fp, "\t\t and   ebx,byte 7\n");\r
7340                                                         }\r
7341 \r
7342                                                         fprintf(fp, "\t\t shr   ecx, byte 9\n");\r
7343                                                         fprintf(fp, "\t\t and   ecx, byte 7\n");\r
7344 \r
7345                                                         sprintf(TrapLabel, "%s", GenerateLabel(0,1) ) ;\r
7346 \r
7347                                                         EffectiveAddressRead(Dest,'W',EBX,EAX,"A-C-SDB",FALSE); /* source */\r
7348 \r
7349                                                         fprintf(fp, "\t\t test  ax,ax\n");\r
7350                                                         fprintf(fp, "\t\t je    near %s_ZERO\t\t;do div by zero trap\n", TrapLabel);\r
7351 \r
7352                                                         if (type == 1) /* signed */\r
7353                                                         {\r
7354                                                                 fprintf(fp, "\t\t movsx ebx,ax\n");\r
7355                                                         }\r
7356                                                         else\r
7357                                                         {\r
7358                                                                 fprintf(fp, "\t\t movzx ebx,ax\n");\r
7359                                                         }\r
7360 \r
7361                                                         EffectiveAddressRead(0,'L',ECX,EAX,"ABC-SDB",FALSE); /* dest */\r
7362 \r
7363                                                         if (type == 1) /* signed */\r
7364                                                         {\r
7365                                                                 fprintf(fp, "\t\t cdq\n");                       /* EDX:EAX = 64 bit signed */\r
7366                                                                 fprintf(fp, "\t\t idiv  ebx\n");                 /* EBX = 32 bit */\r
7367 \r
7368                                                                 /* Check for Overflow */\r
7369 \r
7370                                                                 fprintf(fp, "\t\t movsx ebx,ax\n");\r
7371                                                                 fprintf(fp, "\t\t cmp   eax,ebx\n");\r
7372                                                                 fprintf(fp, "\t\t jne   short %s_OVER\n",TrapLabel);\r
7373                                                         }\r
7374                                                         else\r
7375                                                         {\r
7376                                                                 ClearRegister(EDX);\r
7377                                                                 fprintf(fp, "\t\t div   ebx\n");\r
7378 \r
7379                                                                 /* Check for Overflow */\r
7380 \r
7381                                                                 fprintf(fp, "\t\t test  eax, 0FFFF0000H\n");\r
7382                                                                 fprintf(fp, "\t\t jnz   short %s_OVER\n",TrapLabel);\r
7383                                                         }\r
7384 \r
7385                                                         /* Sort out Result */\r
7386 \r
7387                                                         fprintf(fp, "\t\t shl   edx, byte 16\n");\r
7388                                                         fprintf(fp, "\t\t mov   dx,ax\n");\r
7389                                                         fprintf(fp, "\t\t mov   [%s+ECX*4],edx\n",REG_DAT);\r
7390                                                         SetFlags('W',EDX,TRUE,FALSE,FALSE);\r
7391 \r
7392                                                         Completed();\r
7393 \r
7394 \r
7395                                                         /* Overflow */\r
7396 \r
7397                                                         Align();\r
7398                                                         fprintf(fp, "%s_OVER:\n",TrapLabel);\r
7399                                                         fprintf(fp, "\t\t mov   edx,[%s]\n",REG_CCR);\r
7400                                                         fprintf(fp, "\t\t or    edx,0x0800\t\t;V flag\n");\r
7401                                                         Completed();\r
7402 \r
7403 \r
7404                                                         /* Division by Zero */\r
7405 \r
7406                                                         Align();\r
7407                                                         fprintf(fp, "%s_ZERO:\t\t ;Do divide by zero trap\n", TrapLabel);\r
7408 \r
7409                                                         /* Correct cycle counter for error */\r
7410 \r
7411                                                         fprintf(fp, "\t\t add   dword [%s],byte %d\n",ICOUNT,95 + (type * 17));\r
7412                                                         fprintf(fp, "\t\t mov   al,5\n");\r
7413                                                         Exception(-1,BaseCode);\r
7414                                                         Completed();\r
7415                                                 }\r
7416 \r
7417                                                 OpcodeArray[Opcode] = BaseCode ;\r
7418                                         }\r
7419                                 }\r
7420 }\r
7421 \r
7422 \r
7423 /*\r
7424  * 68010 Extra Opcodes\r
7425  *\r
7426  * move from CCR is done above\r
7427  *\r
7428  */\r
7429 \r
7430 void ReturnandDeallocate(void)\r
7431 {\r
7432         int     BaseCode = 0x4e74 ;\r
7433 \r
7434         if (OpcodeArray[BaseCode] == -2)\r
7435         {\r
7436                 Align();\r
7437                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));\r
7438 \r
7439                 CheckCPUtype(1);\r
7440 \r
7441                 SavePreviousPC();\r
7442 \r
7443                 TimingCycles += 16;\r
7444 \r
7445                 OpcodeArray[BaseCode] = BaseCode ;\r
7446 \r
7447                 /* Get Return Address */\r
7448 \r
7449                 fprintf(fp, "\t\t mov   eax,[%s]\n",REG_A7);\r
7450                 Memory_Read('L',EAX,"---D--B",1);\r
7451 \r
7452 \r
7453                 /* Get Displacement */\r
7454 \r
7455                 Memory_Fetch('W',EBX,TRUE);\r
7456 \r
7457 \r
7458                 /* Set PC = New Address */\r
7459 \r
7460                 fprintf(fp, "\t\t mov   esi,eax\n");\r
7461 \r
7462 \r
7463                 /* Correct Stack for Return Address and Displacement */\r
7464 \r
7465                 fprintf(fp, "\t\t add   ebx,byte 4\n");\r
7466                 fprintf(fp, "\t\t add   dword [%s],ebx\n",REG_A7);\r
7467 \r
7468                 MemoryBanking(BaseCode);\r
7469                 Completed();\r
7470         }\r
7471 }\r
7472 \r
7473 void MoveControlRegister(void)\r
7474 {\r
7475         int  Direction;\r
7476         int  BaseCode = 0x4e7a ;\r
7477 \r
7478         for (Direction=0;Direction<2;Direction++)\r
7479         {\r
7480                 Align();\r
7481                 fprintf(fp, "%s:\n",GenerateLabel(BaseCode+Direction,0));\r
7482 \r
7483                 TimingCycles += 4; /* Assume same as move usp */\r
7484 \r
7485                 CheckCPUtype(1);\r
7486 \r
7487                 fprintf(fp, "\t\t test  byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH);\r
7488                 fprintf(fp, "\t\t jz    short OP%d_%4.4x_Trap\n",CPU,BaseCode+Direction);\r
7489 \r
7490                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
7491                 if (CPU==2)\r
7492                         fprintf(fp, "\t\t xor   esi,2\n");      /* ASG */\r
7493 #ifdef STALLCHECK\r
7494                 ClearRegister(EBX);\r
7495                 fprintf(fp, "\t\t mov   bx,[esi+ebp]\n");\r
7496 #else\r
7497                 fprintf(fp, "\t\t movzx ebx,word [esi+ebp]\n");\r
7498 #endif\r
7499                 if (CPU==2)\r
7500                         fprintf(fp, "\t\t xor   esi,2\n");      /* ASG */\r
7501 \r
7502                 fprintf(fp, "\t\t add   esi,byte 2\n");\r
7503                 fprintf(fp, "\t\t mov   eax,ebx\n");\r
7504                 fprintf(fp, "\t\t mov   ecx,ebx\n");\r
7505 \r
7506                 /* Sort out Register */\r
7507 \r
7508                 fprintf(fp, "\t\t shr   ebx,12\n");\r
7509 \r
7510                 /* Sort out Control Register ID */\r
7511 \r
7512                 fprintf(fp, "\t\t and   eax,byte 1\n");\r
7513                 fprintf(fp, "\t\t shr   ecx,10\n");\r
7514                 fprintf(fp, "\t\t and   ecx,2\n");\r
7515                 fprintf(fp, "\t\t or    ecx,eax\n");\r
7516 \r
7517                 if (Direction==0)\r
7518                 {\r
7519                         /* from Control */\r
7520 \r
7521                         fprintf(fp, "\t\t mov   eax,[%s+ecx*4]\n",REG_SFC);\r
7522                         fprintf(fp, "\t\t mov   %s,eax\n",REG_DAT_EBX);\r
7523                 }\r
7524                 else\r
7525                 {\r
7526                         /* To Control */\r
7527 \r
7528                         fprintf(fp, "\t\t mov   eax,%s\n",REG_DAT_EBX);\r
7529 \r
7530                         /* Mask out for SFC & DFC */\r
7531 \r
7532                         fprintf(fp, "\t\t test  cl,2\n");\r
7533                         fprintf(fp, "\t\t jne   short OP%d_%4.4x_Mask\n",CPU,BaseCode+Direction);\r
7534                         fprintf(fp, "\t\t and   eax,byte 7\n");\r
7535                         fprintf(fp, "OP%d_%4.4x_Mask:\n",CPU,BaseCode+Direction);\r
7536 \r
7537                         /* Write to control */\r
7538 \r
7539                         fprintf(fp, "\t\t mov   [%s+ecx*4],eax\n",REG_SFC);\r
7540                 }\r
7541 \r
7542                 Completed();\r
7543 \r
7544                 /* Not Supervisor Mode */\r
7545 \r
7546                 Align();\r
7547                 fprintf(fp, "OP%d_%4.4x_Trap:\n",CPU,BaseCode+Direction);\r
7548                 Exception(8,BaseCode+Direction);\r
7549 \r
7550                 OpcodeArray[BaseCode+Direction] = BaseCode+Direction;\r
7551         }\r
7552 }\r
7553 \r
7554 void MoveAddressSpace(void)\r
7555 {\r
7556 }\r
7557 \r
7558 /*\r
7559  * Generate Jump Table\r
7560  *\r
7561  */\r
7562 \r
7563 void JumpTable(void)\r
7564 {\r
7565         int Opcode,l,op;\r
7566 \r
7567         fprintf(fp, "DD OP%d_1000\n",CPU);\r
7568 \r
7569         l = 0 ;\r
7570         for (Opcode=0x0;Opcode<0x10000;)\r
7571         {\r
7572 \r
7573                 op = OpcodeArray[Opcode];\r
7574 \r
7575                 fprintf(fp, "DD ");\r
7576 \r
7577                 l = 1 ;\r
7578                 while (op == OpcodeArray[Opcode+l] && ((Opcode+l) & 0xfff) != 0)\r
7579                 {\r
7580                         l++ ;\r
7581                 }\r
7582 \r
7583                 Opcode += l ;\r
7584 \r
7585                 if (l > 255)\r
7586                 {\r
7587                         if (op > -1)\r
7588                                 fprintf(fp, "OP%d_%4.4x - OP%d_1000\n",CPU,op,CPU);\r
7589                         else\r
7590                                 fprintf(fp, "ILLEGAL - OP%d_1000\n",CPU);\r
7591 \r
7592                         fprintf(fp, "DW %d\n", l);\r
7593                 }\r
7594                 else\r
7595                 {\r
7596                         if (op > -1)\r
7597                                 fprintf(fp, "(OP%d_%4.4x - OP%d_1000) + (%d * 1000000h)\n",CPU,op,CPU,l);\r
7598                         else\r
7599                                 fprintf(fp, "(ILLEGAL - OP%d_1000) + (%d * 1000000h)\n",CPU,l);\r
7600                 }\r
7601         }\r
7602 }\r
7603 \r
7604 void CodeSegmentBegin(void)\r
7605 {\r
7606 \r
7607 /* Messages */\r
7608 \r
7609         fprintf(fp, "; Make68K - V%s - Copyright 1998, Mike Coates (mame@btinternet.com)\n", VERSION);\r
7610         fprintf(fp, ";                               & Darren Olafson (deo@mail.island.net)\n\n");\r
7611 \r
7612 /* Needed code to make it work! */\r
7613 \r
7614         fprintf(fp, "\t\t BITS 32\n\n");\r
7615 \r
7616         fprintf(fp, "\t\t GLOBAL %s_RUN\n",CPUtype);\r
7617         fprintf(fp, "\t\t GLOBAL %s_RESET\n",CPUtype);\r
7618         fprintf(fp, "\t\t GLOBAL %s_regs\n",CPUtype);\r
7619         fprintf(fp, "\t\t GLOBAL %s_COMPTABLE\n",CPUtype);\r
7620         fprintf(fp, "\t\t GLOBAL %s_OPCODETABLE\n",CPUtype);\r
7621 \r
7622         /* ASG - only one interface to memory now */\r
7623         fprintf(fp, "\t\t EXTERN _m68k_ICount\n");\r
7624         fprintf(fp, "\t\t EXTERN _a68k_memory_intf\n");\r
7625         fprintf(fp, "\t\t EXTERN _mem_amask\n");\r
7626 \r
7627         fprintf(fp, "; Vars Mame declares / needs access to\n\n");\r
7628 \r
7629         fprintf(fp, "\t\t EXTERN _mame_debug\n");\r
7630         fprintf(fp, "\t\t EXTERN _illegal_op\n");\r
7631         fprintf(fp, "\t\t EXTERN _illegal_pc\n");\r
7632 \r
7633         fprintf(fp, "\t\t EXTERN _OP_ROM\n");\r
7634         fprintf(fp, "\t\t EXTERN _OP_RAM\n");\r
7635 \r
7636         fprintf(fp, "\t\t EXTERN _opcode_entry\n");\r
7637         fprintf(fp, "\t\t EXTERN _cur_mrhard\n");\r
7638 \r
7639 //#ifdef MAME_DEBUG\r
7640         fprintf(fp, "\t\t EXTERN _m68k_illegal_opcode\n");\r
7641 //#endif\r
7642 \r
7643 #ifdef OS2\r
7644         fprintf(fp, "\t\t SECTION maincode USE32 FLAT CLASS=CODE\n\n");\r
7645 #else\r
7646         fprintf(fp, "\t\t SECTION .text\n\n");\r
7647 #endif\r
7648 \r
7649 \r
7650 \r
7651 /* Reset routine */\r
7652 \r
7653         fprintf(fp, "%s_RESET:\n",CPUtype);\r
7654 \r
7655         fprintf(fp, "\t\t pushad\n\n");\r
7656 \r
7657         fprintf(fp, "; Build Jump Table (not optimised!)\n\n");\r
7658 \r
7659         fprintf(fp, "\t\t lea   edi,[%s_OPCODETABLE]\t\t; Jump Table\n", CPUtype);\r
7660         fprintf(fp, "\t\t lea   esi,[%s_COMPTABLE]\t\t; RLE Compressed Table\n", CPUtype);\r
7661 \r
7662         /* Reference Point in EBP */\r
7663 \r
7664         fprintf(fp, "\t\t mov   ebp,[esi]\n");\r
7665         fprintf(fp, "\t\t add   esi,byte 4\n");\r
7666 \r
7667         fprintf(fp, "RESET0:\n");\r
7668         fprintf(fp, "\t\t mov   eax,[esi]\n");\r
7669         fprintf(fp, "\t\t mov   ecx,eax\n");\r
7670         fprintf(fp, "\t\t and   eax,0xffffff\n");\r
7671         fprintf(fp, "\t\t add   eax,ebp\n");\r
7672         fprintf(fp, "\t\t add   esi,byte 4\n");\r
7673 \r
7674         /* if count is zero, then it's a word RLE length */\r
7675 \r
7676         fprintf(fp, "\t\t shr   ecx,24\n");\r
7677         fprintf(fp, "\t\t jne   short RESET1\n");\r
7678 \r
7679 #ifdef STALLCHECK\r
7680         ClearRegister(ECX);\r
7681         fprintf(fp, "\t\t mov   cx,[esi]\t\t; Repeats\n");\r
7682 #else\r
7683         fprintf(fp, "\t\t movzx ecx,word [esi]\t\t; Repeats\n");\r
7684 #endif\r
7685 \r
7686         fprintf(fp, "\t\t add   esi,byte 2\n");\r
7687         fprintf(fp, "\t\t jecxz RESET2\t\t; Finished!\n");\r
7688 \r
7689         fprintf(fp, "RESET1:\n");\r
7690         fprintf(fp, "\t\t mov   [edi],eax\n");\r
7691         fprintf(fp, "\t\t add   edi,byte 4\n");\r
7692         fprintf(fp, "\t\t dec   ecx\n");\r
7693         fprintf(fp, "\t\t jnz   short RESET1\n");\r
7694         fprintf(fp, "\t\t jmp   short RESET0\n");\r
7695 \r
7696         fprintf(fp, "RESET2:\n");\r
7697         fprintf(fp, "\t\t popad\n");\r
7698         fprintf(fp, "\t\t ret\n\n");\r
7699 \r
7700 /* Emulation Entry Point */\r
7701 \r
7702         Align();\r
7703 \r
7704         fprintf(fp, "%s_RUN:\n",CPUtype);\r
7705 \r
7706         fprintf(fp, "\t\t pushad\n");\r
7707         fprintf(fp, "\t\t mov   esi,[%s]\n",REG_PC);\r
7708         fprintf(fp, "\t\t mov   edx,[%s]\n",REG_CCR);\r
7709         fprintf(fp, "\t\t mov   ebp,dword [_OP_ROM]\n");\r
7710 \r
7711         fprintf(fp,"; Check for Interrupt waiting\n\n");\r
7712         fprintf(fp,"\t\t test  [%s],byte 07H\n",REG_IRQ);\r
7713         fprintf(fp,"\t\t jne   near interrupt\n\n");\r
7714 \r
7715         fprintf(fp, "IntCont:\n");\r
7716 \r
7717         /* See if was only called to check for Interrupt */\r
7718 \r
7719         fprintf(fp, "\t\t test  dword [%s],-1\n",ICOUNT);\r
7720         fprintf(fp, "\t\t js    short MainExit\n\n");\r
7721 \r
7722         if(CPU==2)\r
7723         {\r
7724                   /* 32 Bit */\r
7725                 fprintf(fp, "\t\t mov   eax,2\n");              /* ASG */\r
7726                 fprintf(fp, "\t\t xor   eax,esi\n");                                                    /* ASG */\r
7727 #ifdef STALLCHECK\r
7728                 ClearRegister(ECX);\r
7729                 fprintf(fp, "\t\t mov   cx,[eax+ebp]\n");\r
7730 #else\r
7731                 fprintf(fp, "\t\t movzx ecx,word [eax+ebp]\n");\r
7732 #endif\r
7733         }\r
7734         else\r
7735         {\r
7736                   /* 16 Bit Fetch */\r
7737 #ifdef STALLCHECK\r
7738                 ClearRegister(ECX);\r
7739                 fprintf(fp, "\t\t mov   cx,[esi+ebp]\n");\r
7740 #else\r
7741                 fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");\r
7742 #endif\r
7743         }\r
7744         fprintf(fp, "\t\t jmp   [%s_OPCODETABLE+ecx*4]\n", CPUtype);\r
7745 \r
7746         Align();\r
7747 \r
7748         fprintf(fp, "MainExit:\n");\r
7749         fprintf(fp, "\t\t mov   [%s],esi\t\t; Save PC\n",REG_PC);\r
7750         fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
7751         fprintf(fp, "\t\t test  byte [%s],20H\n",REG_SRH);\r
7752         fprintf(fp, "\t\t mov   eax,[%s]\t\t; Get A7\n",REG_A7);\r
7753         fprintf(fp, "\t\t jne   short ME1\t\t; Mode ?\n");\r
7754         fprintf(fp, "\t\t mov   [%s],eax\t\t;Save in USP\n",REG_USP);\r
7755         fprintf(fp, "\t\t jmp   short MC68Kexit\n");\r
7756         fprintf(fp, "ME1:\n");\r
7757         fprintf(fp, "\t\t mov   [%s],eax\n",REG_ISP);\r
7758         fprintf(fp, "MC68Kexit:\n");\r
7759 \r
7760         /* If in Debug mode make normal SR register */\r
7761 \r
7762 #ifdef MAME_DEBUG\r
7763 \r
7764         ReadCCR('W', ECX);\r
7765         fprintf(fp, "\t\t mov   [%s],eax\n\n",REG_S);\r
7766 \r
7767 #endif\r
7768 \r
7769         fprintf(fp, "\t\t popad\n");\r
7770         fprintf(fp, "\t\t ret\n");\r
7771 \r
7772 /* Check for Pending Interrupts */\r
7773 \r
7774         Align();\r
7775         fprintf(fp, "; Interrupt check\n\n");\r
7776 \r
7777         fprintf(fp, "interrupt:\n");\r
7778 \r
7779         /* check to exclude interrupts */\r
7780 \r
7781         fprintf(fp, "\t\t mov   eax,[%s]\n",REG_IRQ);\r
7782         fprintf(fp, "\t\t and   eax,byte 07H\n");\r
7783 \r
7784         fprintf(fp, "\t\t cmp   al,7\t\t ; Always take 7\n");\r
7785         fprintf(fp, "\t\t je    short procint\n\n");\r
7786 \r
7787         fprintf(fp, "\t\t mov   ebx,[%s]\t\t; int mask\n",REG_SRH);\r
7788         fprintf(fp, "\t\t and   ebx,byte 07H\n");\r
7789         fprintf(fp, "\t\t cmp   eax,ebx\n");\r
7790         fprintf(fp, "\t\t jle   near IntCont\n\n");\r
7791 \r
7792         /* Take pending Interrupt */\r
7793 \r
7794         Align();\r
7795         fprintf(fp, "procint:\n");\r
7796         fprintf(fp, "\t\t and   byte [%s],78h\t\t; remove interrupt & stop\n\n",REG_IRQ);\r
7797 \r
7798         /* Get Interrupt Vector from callback */\r
7799 \r
7800         fprintf(fp, "\t\t push  eax\t\t; save level\n\n");\r
7801 \r
7802         if (SavedRegs[EBX] == '-')\r
7803         {\r
7804                 fprintf(fp, "\t\t push  EBX\n");\r
7805         }\r
7806         else\r
7807         {\r
7808                 fprintf(fp, "\t\t mov   ebx,eax\n");\r
7809         }\r
7810 \r
7811         if (SavedRegs[ESI] == '-')\r
7812         {\r
7813                 fprintf(fp, "\t\t mov   [%s],ESI\n",REG_PC);\r
7814         }\r
7815 \r
7816         if (SavedRegs[EDX] == '-')\r
7817         {\r
7818                 fprintf(fp, "\t\t mov   [%s],edx\n",REG_CCR);\r
7819         }\r
7820 \r
7821 /* ----- Win32 uses FASTCALL (By Kenjo)----- */\r
7822 \r
7823 #ifdef FASTCALL\r
7824         fprintf(fp, "\t\t mov   %s, eax\t\t; irq line #\n",FASTCALL_FIRST_REG);\r
7825         fprintf(fp, "\t\t call  dword [%s]\t; get the IRQ level\n", REG_IRQ_CALLBACK);\r
7826 #else\r
7827         fprintf(fp, "\t\t push  eax\t\t; irq line #\n");\r
7828         fprintf(fp, "\t\t call  dword [%s]\t; get the IRQ level\n", REG_IRQ_CALLBACK);\r
7829         fprintf(fp, "\t\t lea   esp,[esp+4]\n");\r
7830 #endif\r
7831 \r
7832         if (SavedRegs[EDX] == '-')\r
7833         {\r
7834                 fprintf(fp, "\t\t mov   edx,[%s]\n",REG_CCR);\r
7835         }\r
7836 \r
7837         if (SavedRegs[ESI] == '-')\r
7838         {\r
7839                 fprintf(fp, "\t\t mov   esi,[%s]\n",REG_PC);\r
7840         }\r
7841 \r
7842         /* Do we want to use normal vector number ? */\r
7843 \r
7844 \r
7845         fprintf(fp, "\t\t test  eax,eax\n");\r
7846         fprintf(fp, "\t\t jns   short AUTOVECTOR\n");\r
7847 \r
7848         /* Only need EBX restored if default vector to be used */\r
7849 \r
7850         if (SavedRegs[EBX] == '-')\r
7851         {\r
7852                 fprintf(fp, "\t\t pop   EBX\n");\r
7853         }\r
7854 \r
7855         /* Just get default vector */\r
7856 \r
7857         fprintf(fp, "\t\t mov   eax,ebx\n");\r
7858 \r
7859         fprintf(fp, "\t\t add   eax,byte 24\t\t; Vector\n\n");\r
7860 \r
7861         fprintf(fp, "AUTOVECTOR:\n\n");\r
7862 \r
7863         Exception(-1,0xFFFF);\r
7864 \r
7865         fprintf(fp, "\t\t pop   eax\t\t; set Int mask\n");\r
7866         fprintf(fp, "\t\t mov   bl,byte [%s]\n",REG_SRH);\r
7867         fprintf(fp, "\t\t and   bl,0F8h\n");\r
7868         fprintf(fp, "\t\t or    bl,al\n");\r
7869         fprintf(fp, "\t\t mov   byte [%s],bl\n\n",REG_SRH);\r
7870         fprintf(fp, "\t\t jmp   IntCont\n\n");\r
7871 \r
7872 /* Exception Routine */\r
7873 \r
7874         Align();\r
7875         fprintf(fp, "Exception:\n");\r
7876         fprintf(fp, "\t\t push  edx\t\t; Save flags\n");\r
7877         fprintf(fp, "\t\t and   eax,0FFH\t\t; Zero Extend IRQ Vector\n");\r
7878 \r
7879         fprintf(fp, "\t\t push  eax\t\t; Save for Later\n");\r
7880 \r
7881         /*  Update Cycle Count */\r
7882 \r
7883         fprintf(fp, "\t\t mov   al,[exception_cycles+eax]\t\t; Get Cycles\n");\r
7884         fprintf(fp, "\t\t sub   [%s],eax\t\t; Decrement ICount\n",ICOUNT);\r
7885 \r
7886         ReadCCR('W',ECX);\r
7887 \r
7888         fprintf(fp, "\t\t mov   edi,[%s]\t\t; Get A7\n",REG_A7);\r
7889 \r
7890         fprintf(fp, "\t\t test  ah,20H\t; Which Mode ?\n");\r
7891         fprintf(fp, "\t\t jne   short ExSuperMode\t\t; Supervisor\n");\r
7892 \r
7893         fprintf(fp, "\t\t or    byte [%s],20H\t; Set Supervisor Mode\n",REG_SRH);\r
7894         fprintf(fp, "\t\t mov   [%s],edi\t\t; Save in USP\n",REG_USP);\r
7895         fprintf(fp, "\t\t mov   edi,[%s]\t\t; Get ISP\n",REG_ISP);\r
7896 \r
7897         /* Write SR first (since it's in a register) */\r
7898 \r
7899         fprintf(fp, "ExSuperMode:\n");\r
7900         fprintf(fp, "\t\t sub   edi,byte 6\n");\r
7901         fprintf(fp, "\t\t mov   [%s],edi\t\t; Put in A7\n",REG_A7);\r
7902         Memory_Write('W',EDI,EAX,"----S-B",2);\r
7903 \r
7904         /* Then write PC */\r
7905 \r
7906         fprintf(fp, "\t\t add   edi,byte 2\n");\r
7907         Memory_Write('L',EDI,ESI,"------B",0);\r
7908 \r
7909         /* Get new PC */\r
7910 \r
7911         fprintf(fp, "\t\t pop   eax\t\t;Level\n");\r
7912         fprintf(fp, "\t\t shl   eax,2\n");\r
7913         fprintf(fp, "\t\t add   eax,[%s]\n",REG_VBR);     /* 68010+ Vector Base */\r
7914 \r
7915         /* Direct Read */\r
7916 \r
7917         Memory_Read('L',EAX,"------B",0);\r
7918 \r
7919         fprintf(fp, "\t\t mov   esi,eax\t\t;Set PC\n");\r
7920         fprintf(fp, "\t\t pop   edx\t\t; Restore flags\n");\r
7921 \r
7922         /* Sort out any bank changes */\r
7923         MemoryBanking(1);\r
7924 \r
7925         fprintf(fp, "\t\t ret\n");\r
7926 }\r
7927 \r
7928 void CodeSegmentEnd(void)\r
7929 {\r
7930 #ifdef OS2\r
7931         fprintf(fp, "\t\t SECTION maindata USE32 FLAT CLASS=DATA\n\n");\r
7932 #else\r
7933         fprintf(fp, "\t\t SECTION .data\n");\r
7934 #endif\r
7935 \r
7936         fprintf(fp, "\n\t\t align 16\n");\r
7937         fprintf(fp, "%s_ICount\n",CPUtype);\r
7938         fprintf(fp, "asm_count\t DD 0\n\n");\r
7939 \r
7940         /* Memory structure for 68000 registers  */\r
7941         /* Same layout as structure in CPUDEFS.H */\r
7942 \r
7943         fprintf(fp, "\n\n; Register Structure\n\n");\r
7944         fprintf(fp, "%s_regs\n",CPUtype);\r
7945 \r
7946         fprintf(fp, "R_D0\t DD 0\t\t\t ; Data Registers\n");\r
7947         fprintf(fp, "R_D1\t DD 0\n");\r
7948         fprintf(fp, "R_D2\t DD 0\n");\r
7949         fprintf(fp, "R_D3\t DD 0\n");\r
7950         fprintf(fp, "R_D4\t DD 0\n");\r
7951         fprintf(fp, "R_D5\t DD 0\n");\r
7952         fprintf(fp, "R_D6\t DD 0\n");\r
7953         fprintf(fp, "R_D7\t DD 0\n\n");\r
7954 \r
7955         fprintf(fp, "R_A0\t DD 0\t\t\t ; Address Registers\n");\r
7956         fprintf(fp, "R_A1\t DD 0\n");\r
7957         fprintf(fp, "R_A2\t DD 0\n");\r
7958         fprintf(fp, "R_A3\t DD 0\n");\r
7959         fprintf(fp, "R_A4\t DD 0\n");\r
7960         fprintf(fp, "R_A5\t DD 0\n");\r
7961         fprintf(fp, "R_A6\t DD 0\n");\r
7962         fprintf(fp, "R_A7\t DD 0\n\n");\r
7963 \r
7964         fprintf(fp, "R_ISP\t DD 0\t\t\t ; Supervisor Stack\n");\r
7965         fprintf(fp, "R_SR_H\t DD 0\t\t\t ; Status Register High TuSuuIII\n");\r
7966         fprintf(fp, "R_CCR\t DD 0\t\t\t ; CCR Register in Intel Format\n");\r
7967         fprintf(fp, "R_XC\t DD 0\t\t\t ; Extended Carry uuuuuuuX\n");\r
7968 \r
7969         fprintf(fp, "R_PC\t DD 0\t\t\t ; Program Counter\n");\r
7970         fprintf(fp, "R_IRQ\t DD 0\t\t\t ; IRQ Request Level\n\n");\r
7971         fprintf(fp, "R_SR\t DD 0\t\t\t ; Motorola Format SR\n\n");\r
7972 \r
7973         fprintf(fp, "R_IRQ_CALLBACK\t DD 0\t\t\t ; irq callback (get vector)\n\n");\r
7974 \r
7975         fprintf(fp, "R_PPC\t DD 0\t\t\t ; Previous Program Counter\n");\r
7976 \r
7977         fprintf(fp, "R_RESET_CALLBACK\t DD 0\t\t\t ; Reset Callback\n");\r
7978 \r
7979         fprintf(fp, "R_SFC\t DD 0\t\t\t ; Source Function Call\n");\r
7980         fprintf(fp, "R_DFC\t DD 0\t\t\t ; Destination Function Call\n");\r
7981         fprintf(fp, "R_USP\t DD 0\t\t\t ; User Stack\n");\r
7982         fprintf(fp, "R_VBR\t DD 0\t\t\t ; Vector Base\n");\r
7983 \r
7984         fprintf(fp, "asmbank\t DD 0\n\n");\r
7985         fprintf(fp, "CPUversion\t DD 0\n\n");\r
7986         fprintf(fp, "FullPC\t DD 0\n\n");\r
7987 \r
7988         /* Extra space for variables mame uses for debugger */\r
7989 \r
7990         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7991         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7992         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7993         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7994         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7995         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7996         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");\r
7997         fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\n");\r
7998 \r
7999         /* Safe Memory Locations */\r
8000 \r
8001         fprintf(fp, "\t\t ALIGN 16\n");\r
8002 \r
8003         fprintf(fp, "\n\nIntelFlag\t\t\t\t; Intel Flag Lookup Table\n");\r
8004         fprintf(fp, "\t\t DD 0000h,0001h,0800h,0801h,0040h,0041h,0840h,0841h\n");\r
8005         fprintf(fp, "\t\t DD 0080h,0081h,0880h,0881h,00C0h,00C1h,08C0h,08C1h\n");\r
8006         fprintf(fp, "\t\t DD 0100h,0101h,0900h,0901h,0140h,0141h,0940h,0941h\n");\r
8007         fprintf(fp, "\t\t DD 0180h,0181h,0980h,0981h,01C0h,01C1h,09C0h,09C1h\n");\r
8008 \r
8009 #if 0\r
8010         fprintf(fp, "\n\nImmTable\n");\r
8011         fprintf(fp, "\t\t DD 8,1,2,3,4,5,6,7\n\n");\r
8012 #endif\r
8013 \r
8014 \r
8015 \r
8016         /* Exception Timing Table */\r
8017 \r
8018         fprintf(fp, "exception_cycles\n");\r
8019         fprintf(fp, "\t\t DB 0, 0, 0, 0, 38, 42, 44, 38, 38, 0, 38, 38, 0, 0, 0, 0\n");\r
8020         fprintf(fp, "\t\t DB 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46\n");\r
8021         fprintf(fp, "\t\t DB 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38\n\n");\r
8022 \r
8023         fprintf(fp, "; RLE Compressed Jump Table\n\n");\r
8024 \r
8025         fprintf(fp, "%s_COMPTABLE\n\n", CPUtype);\r
8026 \r
8027         fprintf(fp, "%cinclude '%s'\n\n",'%', comptab);\r
8028 \r
8029         fprintf(fp, "\t\tDW   0,0,0\n\n");\r
8030 \r
8031 \r
8032 /* If Win32, put the table area in .data section (Kenjo) */\r
8033 \r
8034 #ifdef WIN32\r
8035 \r
8036         fprintf(fp, "%s_OPCODETABLE\tTIMES  65536  DD 0\n\n", CPUtype);\r
8037 \r
8038 #else\r
8039 \r
8040 #ifdef OS2\r
8041         fprintf(fp, "\t\t SECTION tempdata USE32 FLAT CLASS=BSS\n\n");\r
8042 #else\r
8043         fprintf(fp, "\t\t SECTION .bss\n");\r
8044 #endif\r
8045 \r
8046         fprintf(fp, "%s_OPCODETABLE\tRESD  65536\n\n", CPUtype);\r
8047 \r
8048 #endif\r
8049 \r
8050 }\r
8051 \r
8052 void EmitCode(void)\r
8053 {\r
8054         CodeSegmentBegin();\r
8055 \r
8056         /* Instructions */\r
8057 \r
8058         moveinstructions();                               /* 1000 to 3FFF MOVE.X */\r
8059         immediate();                                            /* 0### XXX.I */\r
8060         bitdynamic();                                                     /* 0### dynamic bit operations */\r
8061         movep();                                                                         /* 0### Move Peripheral */\r
8062         bitstatic();                                            /* 08## static bit operations */\r
8063         LoadEffectiveAddress();                  /* 4### */\r
8064         PushEffectiveAddress();                  /* ???? */\r
8065         movesr();                                                       /* 4#C# */\r
8066         opcode5();                                                                /* 5000 to 5FFF ADDQ,SUBQ,Scc and DBcc */\r
8067         branchinstructions();                           /* 6000 to 6FFF Bcc,BSR */\r
8068         moveq();                                                 /* 7000 to 7FFF MOVEQ */\r
8069         abcd_sbcd();                                            /* 8### Decimal Add/Sub */\r
8070         typelogicalmath();                                              /* Various ranges */\r
8071         addx_subx();\r
8072         divides();\r
8073         swap();\r
8074         not();                                                          /* also neg negx clr */\r
8075         moveusp();\r
8076         chk();\r
8077         exg();\r
8078         cmpm();\r
8079         mul();\r
8080         ReturnandRestore();\r
8081         rts();\r
8082         jmp_jsr();\r
8083         nbcd();\r
8084         tas();\r
8085         trap();\r
8086         trapv();\r
8087         reset();\r
8088         nop();\r
8089         stop();\r
8090         ext();\r
8091         ReturnFromException();\r
8092         tst();\r
8093         movem_reg_ea();\r
8094         movem_ea_reg();\r
8095         link();\r
8096         unlinkasm();\r
8097         asl_asr();                                                /* E### Shift Commands */\r
8098         asl_asr_ea();\r
8099         roxl_roxr();\r
8100         roxl_roxr_ea();\r
8101         lsl_lsr();\r
8102         lsl_lsr_ea();\r
8103         rol_ror();\r
8104         rol_ror_ea();\r
8105         LineA();                                                 /* A000 to AFFF Line A */\r
8106         LineF();                                                        /* F000 to FFFF Line F */\r
8107         illegal_opcode();\r
8108 \r
8109         ReturnandDeallocate();                    /* 68010 Commands */\r
8110         MoveControlRegister();\r
8111         MoveAddressSpace();\r
8112 \r
8113         if(CPU==2)                                              /* 68020 Commands */\r
8114         {\r
8115                 divl();\r
8116                 mull();\r
8117                 bfext();\r
8118         }\r
8119 \r
8120         CodeSegmentEnd();\r
8121 }\r
8122 \r
8123 int main(int argc, char **argv)\r
8124 {\r
8125         int dwLoop;\r
8126 \r
8127         printf("\nMake68K - V%s - Copyright 1998, Mike Coates (mame@btinternet.com)\n", VERSION);\r
8128         printf("                            1999, & Darren Olafson (deo@mail.island.net)\n");\r
8129         printf("                            2000\n");\r
8130 \r
8131         if (argc != 4 && argc != 5)\r
8132         {\r
8133                 printf("Usage: %s outfile jumptable-outfile type [ppro]\n", argv[0]);\r
8134                 exit(1);\r
8135         }\r
8136 \r
8137         printf("Building 680%s              2001\n\n",argv[3]);\r
8138 \r
8139         for (dwLoop=0;dwLoop<65536;)  OpcodeArray[dwLoop++] = -2;\r
8140 \r
8141         codebuf=malloc(64);\r
8142         if (!codebuf)\r
8143         {\r
8144                 printf ("Memory allocation error\n");\r
8145                 exit(3);\r
8146         }\r
8147 \r
8148         /* Emit the code */\r
8149         fp = fopen(argv[1], "w");\r
8150         if (!fp)\r
8151         {\r
8152                 fprintf(stderr, "Can't open %s for writing\n", argv[1]);\r
8153                 exit(1);\r
8154         }\r
8155 \r
8156         comptab = argv[2];\r
8157 \r
8158 \r
8159         CPUtype = malloc(64);\r
8160 #ifdef OS2\r
8161         sprintf(CPUtype,"M680%s",argv[3]);\r
8162 #else\r
8163         sprintf(CPUtype,"_M680%s",argv[3]);\r
8164 #endif\r
8165 \r
8166         if(argv[3][0]=='2') CPU = 2;\r
8167         if(argc > 4 && !stricmp(argv[4], "ppro"))\r
8168         {\r
8169                   ppro = 1;\r
8170                   printf("Generating ppro opcodes\n");\r
8171         }\r
8172 \r
8173         EmitCode();\r
8174 \r
8175         fclose(fp);\r
8176 \r
8177         printf("\n%d Unique Opcodes\n",Opcount);\r
8178 \r
8179         /* output Jump table to separate file */\r
8180         fp = fopen(argv[2], "w");\r
8181         if (!fp)\r
8182         {\r
8183                 fprintf(stderr, "Can't open %s for writing\n", argv[2]);\r
8184                 exit(1);\r
8185         }\r
8186 \r
8187         JumpTable();\r
8188 \r
8189         fclose(fp);\r
8190 \r
8191         exit(0);\r
8192 }\r