cc68a136 |
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 |