1 /*---------------------------------------------------------------
\r
2 * Motorola 68000 32 Bit emulator
\r
4 * Copyright 1998-2001 Mike Coates, All rights reserved
\r
6 *---------------------------------------------------------------
\r
10 * Neil Bradley (lots of optimisation help & ideas)
\r
12 *---------------------------------------------------------------
\r
13 * History (so we know what bugs have been fixed)
\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
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
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
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
109 * None - Let us know if you find any!
\r
112 * Instructions that are supervisor only as per 68000 spec.
\r
113 * move address space not implemented.
\r
116 * only long Bcc instruction implemented.
\r
117 *---------------------------------------------------------------
\r
120 * STALLCHECK should be defined for Pentium Class
\r
121 * undefined for P2/Celerons
\r
123 * ALIGNMENT is normally 4, but seems faster on my P2 as 0 !
\r
125 *---------------------------------------------------------------
\r
129 * 68020 instructions to be completed
\r
130 * assembler memory routines +
\r
132 * and anything else that takes our fancy!
\r
133 *---------------------------------------------------------------*/
\r
135 /* Specials - Switch what program allows/disallows */
\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
148 #include <stdlib.h>
\r
149 #include <string.h>
\r
150 #include <assert.h>
\r
152 /* New Disassembler */
\r
157 #define cpu_readmem24bew(addr) (0)
\r
158 #define cpu_readmem24bew_word(addr) (DisOp)
\r
160 #define MEMORY_H /* so memory.h will not be included... */
\r
166 #undef cpu_readmem24bew
\r
167 #undef cpu_readmem24bew_word
\r
169 #include "cpuintrf.h"
\r
172 * Defines used by Program
\r
176 #define VERSION "0.30"
\r
194 /* Register Location Offsets */
\r
196 #define ICOUNT "_m68k_ICount"
\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
216 #define REG_VBR "R_VBR"
\r
217 #define REG_SFC "R_SFC"
\r
218 #define REG_DFC "R_DFC"
\r
220 #define FASTCALL_FIRST_REG "ecx"
\r
221 #define FASTCALL_SECOND_REG "edx"
\r
232 char *comptab = NULL;
\r
233 char *CPUtype = NULL;
\r
236 int FlagProcess = 0;
\r
237 int CheckInterrupt = 0;
\r
238 int ExternalIO = 0;
\r
240 int TimingCycles = 0;
\r
241 int AddEACycles = 0;
\r
242 int AccessType = NORMAL;
\r
247 /* External register preservation */
\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
255 #elif defined(WIN32)
\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
263 /* Assume nothing preserved */
\r
264 static char SavedRegs[] = "-------";
\r
272 int OpcodeArray[65536];
\r
274 /* Lookup Arrays */
\r
276 static char* regnameslong[] =
\r
277 { "EAX","EBX","ECX","EDX","ESI","EDI","EBP"};
\r
279 static char* regnamesword[] =
\r
280 { "AX","BX","CX","DX", "SI", "DI", "BP"};
\r
282 static char* regnamesshort[] =
\r
283 { "AL","BL","CL","DL"};
\r
287 /*********************************/
\r
288 /* Conversion / Utility Routines */
\r
289 /*********************************/
\r
291 /* Convert EA to Address Mode Number
\r
304 * 11 #x,SR,CCR Read = Immediate, Write = SR or CCR
\r
305 * in order to read SR to AX, use READCCR
\r
313 int EAtoAMN(int EA, int Way)
\r
321 if (Work == 7) Work += ((EA & 0x38) >> 3);
\r
323 if (((Work == 3) || (Work == 4)) && (((EA & 0x38) >> 3) == 7))
\r
330 Work = (EA & 0x38) >> 3;
\r
332 if (Work == 7) Work += (EA & 7);
\r
334 if (((Work == 3) || (Work == 4)) && ((EA & 7) == 7))
\r
344 * Generate Main or Sub label
\r
347 char *GenerateLabel(int ID,int Type)
\r
349 static int LabID,LabNum;
\r
351 static char disasm[80];
\r
352 char *dis = disasm;
\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
364 m68k_disassemble(dis,0);
\r
365 sprintf(codebuf, "OP%d_%4.4x:\t\t\t\t; %s", CPU,ID, dis);
\r
367 sprintf(codebuf, "OP%d_%4.4x:\t\t\t\t;", CPU,ID);
\r
375 sprintf(codebuf, "OP%d_%4.4x_%1x", CPU,LabID, LabNum);
\r
382 * Generate Alignment Line
\r
387 fprintf(fp, "\t\t ALIGN %d\n\n",ALIGNMENT);
\r
391 * Copy X into Carry
\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
399 /* Copy bit 0 from X flag store into Carry */
\r
401 fprintf(fp, "\t\t bt dword [%s],0\n",REG_X);
\r
405 * Immediate 3 bit data
\r
407 * 0=8, anything else is itself
\r
409 * Again, several ways to achieve this
\r
411 * ECX contains data as 3 lowest bits
\r
415 void ClearRegister(int regno)
\r
418 fprintf(fp, "\t\t mov %s,0\n",regnameslong[regno]);
\r
420 fprintf(fp, "\t\t xor %s,%s\n",regnameslong[regno],regnameslong[regno]);
\r
424 void Immediate8(void)
\r
426 /* This takes 3 cycles, 5 bytes, no memory reads */
\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
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
437 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
438 fprintf(fp, "\t\t mov ecx,[ImmTable+ECX*4]\n");
\r
443 * This will check for bank changes before
\r
444 * resorting to calling the C bank select code
\r
446 * Most of the time it does not change!
\r
450 /* forward used by MemoryBanking */
\r
451 void Exception(int Number, int BaseCode) ;
\r
453 void MemoryBanking(int BaseCode)
\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
459 /* trying to run at an odd address */
\r
460 Exception(3,BaseCode);
\r
462 /* Keep Whole PC */
\r
464 fprintf(fp, "OP%d_%5.5x:\n",CPU,BaseCode);
\r
466 /* ASG - always call to the changepc subroutine now, since the number of */
\r
467 /* bits varies based on the memory model */
\r
469 fprintf(fp, "\t\t mov [FullPC],ESI\n");
\r
472 /* Mask to n bits */
\r
473 fprintf(fp, "\t\t and esi,[_mem_amask]\n");
\r
477 fprintf(fp, "\t\t mov [FullPC],ESI\n");
\r
480 /* Mask to 24 bits */
\r
481 // fprintf(fp, "\t\t and esi,0ffffffh\n");
\r
484 /* Assembler bank switch - 64k granularity */
\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
491 fprintf(fp, "\t\t mov [asmbank],eax\n");
\r
493 /* This code is same as macro used by C core */
\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
504 /* Call Banking Routine */
\r
506 if (SavedRegs[ESI] == '-')
\r
508 fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC);
\r
511 if (SavedRegs[EDX] == '-')
\r
513 fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR);
\r
517 fprintf(fp, "\t\t mov %s,esi\n",FASTCALL_FIRST_REG);
\r
519 fprintf(fp, "\t\t push esi\n");
\r
522 fprintf(fp, "\t\t call [_a68k_memory_intf+28]\n");
\r
525 fprintf(fp, "\t\t lea esp,[esp+4]\n");
\r
528 if (SavedRegs[EDX] == '-')
\r
530 fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR);
\r
533 if (SavedRegs[ESI] == '-')
\r
535 fprintf(fp, "\t\t mov esi,[%s]\n",REG_PC);
\r
538 /* Update our copy */
\r
540 fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n");
\r
542 fprintf(fp, "OP%d_%5.5x_Bank:\n",CPU,BaseCode);
\r
546 * Update Previous PC value
\r
550 void SavePreviousPC(void)
\r
553 fprintf(fp, "\t\t mov [R_PPC],esi\t\t\t ; Keep Previous PC\n");
\r
558 * Complete Opcode handling
\r
560 * Any tidying up, end code
\r
564 void Completed(void)
\r
567 /* Flag Processing to be finished off ? */
\r
569 AccessType = NORMAL;
\r
571 /* Use assembler timing routines */
\r
573 if (TimingCycles != 0)
\r
575 if (TimingCycles > 127)
\r
576 fprintf(fp, "\t\t sub dword [%s],%d\n",ICOUNT,TimingCycles);
\r
579 if (TimingCycles != -1)
\r
580 fprintf(fp, "\t\t sub dword [%s],byte %d\n",ICOUNT,TimingCycles);
\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
588 fprintf(fp, "\t\t js near MainExit\n\n");
\r
592 fprintf(fp, "\t\t test dword [%s],0xffffffff\n",ICOUNT);
\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
599 fprintf(fp, "\t\t jle near MainExit\n\n");
\r
605 /* Check for Debug Active */
\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
612 if (CheckInterrupt)
\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
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
626 ClearRegister(ECX);
\r
627 fprintf(fp, "\t\t mov cx,[eax+ebp]\n");
\r
629 fprintf(fp, "\t\t movzx ecx,word [eax+ebp]\n");
\r
634 /* 16 bit memory */
\r
636 ClearRegister(ECX);
\r
637 fprintf(fp, "\t\t mov cx,[esi+ebp]\n");
\r
639 fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");
\r
643 fprintf(fp, "\t\t jmp [%s_OPCODETABLE+ecx*4]\n\n", CPUtype);
\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
657 void TestFlags(char Size,int Sreg)
\r
664 Regname = regnamesshort[Sreg];
\r
668 Regname = regnamesword[Sreg];
\r
672 Regname = regnameslong[Sreg];
\r
676 /* Test does not update register */
\r
677 /* so cannot generate partial stall */
\r
679 fprintf(fp, "\t\t test %s,%s\n",Regname,Regname);
\r
682 void SetFlags(char Size,int Sreg,int Testreg,int SetX,int Delayed)
\r
684 if (Testreg) TestFlags(Size,Sreg);
\r
686 fprintf(fp, "\t\t pushfd\n");
\r
690 /* Rest of code done by Completed routine */
\r
692 if (SetX) FlagProcess = 2;
\r
693 else FlagProcess = 1;
\r
697 fprintf(fp, "\t\t pop EDX\n");
\r
699 if (SetX) fprintf(fp, "\t\t mov [%s],edx\n",REG_X);
\r
703 /******************/
\r
704 /* Check CPU Type */
\r
705 /******************/
\r
707 void CheckCPUtype(int Minimum)
\r
711 /* Only check for > 020 */
\r
715 fprintf(fp, "\t\t mov eax,[CPUversion]\n");
\r
717 fprintf(fp, "\t\t cmp al,%d\n",Minimum);
\r
718 fprintf(fp, "\t\t jb near ILLEGAL\n\n");
\r
723 fprintf(fp, "\t\t mov eax,[CPUversion]\n");
\r
727 fprintf(fp, "\t\t test eax,eax\n");
\r
728 fprintf(fp, "\t\t jz near ILLEGAL\n\n");
\r
732 fprintf(fp, "\t\t cmp al,%d\n",Minimum);
\r
733 fprintf(fp, "\t\t jb near ILLEGAL\n\n");
\r
738 /************************************/
\r
739 /* Pre-increment and Post-Decrement */
\r
740 /************************************/
\r
742 void IncrementEDI(int Size,int Rreg)
\r
750 /* Always does Byte Increment - A7 uses special routine */
\r
752 fprintf(fp, "\t\t inc dword [%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);
\r
756 /* A7 uses same routines, so inc by 2 if A7 */
\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
767 fprintf(fp, "\t\t add dword [%s+%s*4],byte 2\n",REG_ADD,regnameslong[Rreg]);
\r
772 fprintf(fp, "\t\t add dword [%s+%s*4],byte 4\n",REG_ADD,regnameslong[Rreg]);
\r
777 void DecrementEDI(int Size,int Rreg)
\r
785 /* Always does Byte Increment - A7 uses special routine */
\r
787 fprintf(fp, "\t\t dec EDI\n");
\r
791 /* A7 uses same routines, so dec by 2 if A7 */
\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
802 fprintf(fp, "\t\t sub EDI,byte 2\n");
\r
806 fprintf(fp, "\t\t sub EDI,byte 4\n");
\r
812 * Generate an exception
\r
814 * if Number = -1 then assume value in AL already
\r
815 * code must continue running afterwards
\r
819 void Exception(int Number, int BaseCode)
\r
823 fprintf(fp, "\t\t sub esi,byte 2\n");
\r
824 fprintf(fp, "\t\t mov al,%d\n",Number);
\r
827 fprintf(fp, "\t\t call Exception\n\n");
\r
834 /********************/
\r
835 /* Address Routines */
\r
836 /********************/
\r
839 * Decode Intel flags into AX as SR register
\r
841 * Wreg = spare register to use (must not be EAX or EDX)
\r
844 void ReadCCR(char Size, int Wreg)
\r
846 fprintf(fp, "\t\t mov eax,edx\n");
\r
847 fprintf(fp, "\t\t mov ah,byte [%s]\n",REG_X);
\r
849 /* Partial stall so .. switch to new bit of processing */
\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
854 /* Finish what we started */
\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
859 /* and complete second task */
\r
861 fprintf(fp, "\t\t or eax,%s \t\t\t\t; C\n\n",regnameslong[Wreg]);
\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
872 fprintf(fp, "\t\t mov ah,byte [%s] \t; T, S & I\n\n",REG_SRH);
\r
875 fprintf(fp, "\t\t and ax,0A71Fh\t; Mask unused bits\n");
\r
881 * Convert SR into Intel flags
\r
883 * Also handles change of mode from Supervisor to User
\r
885 * n.b. This is also called by EffectiveAddressWrite
\r
888 void WriteCCR(char Size)
\r
892 /* Did we change from Supervisor to User mode ? */
\r
894 char *Label = GenerateLabel(0,1);
\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
899 /* Mode Switch - Update A7 */
\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
906 fprintf(fp, "%s:\n",Label);
\r
907 fprintf(fp, "\t\t mov byte [%s],ah \t;T, S & I\n",REG_SRH);
\r
909 /* Mask may now allow Interrupt */
\r
911 CheckInterrupt += 1;
\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
924 * Interface to Mame memory commands
\r
926 * Flags = "ABCDSDB" - set to '-' if not required to preserve
\r
927 * (order EAX,EBX,ECX,EDX,ESI,EDI,EBP)
\r
929 * AReg = Register containing Address
\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
936 void Memory_Read(char Size,int AReg,char *Flags,int Mask)
\r
942 fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC);
\r
944 /* Check for special mask condition */
\r
946 /* ASG - no longer need to mask addresses here */
\r
948 fprintf(fp, "\t\t and %s,0FFFFFFh\n",regnameslong[AReg]);*/
\r
950 /* Check to see if registers need saving */
\r
952 if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))
\r
954 fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR);
\r
957 if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))
\r
959 fprintf(fp, "\t\t push EBX\n");
\r
962 if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))
\r
964 fprintf(fp, "\t\t push ECX\n");
\r
967 if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))
\r
969 fprintf(fp, "\t\t push EDI\n");
\r
972 /* Sort Address out */
\r
976 fprintf(fp, "\t\t mov %s,%s\n",FASTCALL_FIRST_REG,regnameslong[AReg]);
\r
978 /* ASG - no longer need to mask addresses here */
\r
980 fprintf(fp, "\t\t and %s,0FFFFFFh\n",FASTCALL_FIRST_REG);*/
\r
986 if ((Flags[AReg] != '-') && (SavedRegs[AReg] != '-'))
\r
988 /* Don't trash a wanted safe register */
\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
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
1003 fprintf(fp, "\t\t push %s\n",regnameslong[AReg]);
\r
1009 /* Call Mame memory routine */
\r
1011 /* ASG - changed these to call through the function pointers */
\r
1014 switch (AccessType)
\r
1020 fprintf(fp, "\t\t call [_a68k_memory_intf+4]\n");
\r
1024 fprintf(fp, "\t\t call [_a68k_memory_intf+8]\n");
\r
1028 fprintf(fp, "\t\t call [_a68k_memory_intf+12]\n");
\r
1038 fprintf(fp, "\t\t call [_a68k_memory_intf+32]\n");
\r
1042 fprintf(fp, "\t\t call [_a68k_memory_intf+36]\n");
\r
1046 fprintf(fp, "\t\t call [_a68k_memory_intf+40]\n");
\r
1052 // AccessType = NORMAL;
\r
1059 fprintf(fp, "\t\t call [_a68k_memory_intf+4]\n");
\r
1063 fprintf(fp, "\t\t call [_a68k_memory_intf+8]\n");
\r
1067 fprintf(fp, "\t\t call [_a68k_memory_intf+12]\n");
\r
1072 /* Correct Stack */
\r
1075 fprintf(fp, "\t\t lea esp,[esp+4]\n");
\r
1080 /* Restore registers */
\r
1082 /* Check to see if registers need restoring */
\r
1084 if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))
\r
1086 fprintf(fp, "\t\t pop EDI\n");
\r
1089 if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))
\r
1091 fprintf(fp, "\t\t pop ECX\n");
\r
1094 if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))
\r
1096 fprintf(fp, "\t\t pop EBX\n");
\r
1099 if ((Flags[ESI] != '-') && (SavedRegs[ESI] == '-'))
\r
1101 fprintf(fp, "\t\t mov ESI,[%s]\n",REG_PC);
\r
1104 if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))
\r
1106 fprintf(fp, "\t\t mov EDX,[%s]\n",REG_CCR);
\r
1109 if ((Flags[EBP] != '-') && (SavedRegs[EBP] == '-'))
\r
1111 fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n");
\r
1115 void Memory_Write(char Size,int AReg,int DReg,char *Flags,int Mask)
\r
1121 fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC);
\r
1123 /* Check for special mask condition */
\r
1125 /* ASG - no longer need to mask addresses here */
\r
1127 fprintf(fp, "\t\t and %s,0FFFFFFh\n",regnameslong[AReg]);*/
\r
1129 /* Check to see if registers need saving */
\r
1131 if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))
\r
1133 fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR);
\r
1136 if ((Flags[EAX] != '-') && (SavedRegs[EAX] == '-'))
\r
1138 fprintf(fp, "\t\t push EAX\n");
\r
1141 if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))
\r
1143 fprintf(fp, "\t\t push EBX\n");
\r
1146 if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))
\r
1148 fprintf(fp, "\t\t push ECX\n");
\r
1151 if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))
\r
1153 fprintf(fp, "\t\t push EDI\n");
\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
1161 /* ASG - no longer need to mask addresses here */
\r
1163 fprintf(fp, "\t\t and %s,0FFFFFFh\n",FASTCALL_FIRST_REG);*/
\r
1167 fprintf(fp, "\t\t push %s\n",regnameslong[DReg]);
\r
1171 if ((Flags[AReg] != '-') && (SavedRegs[AReg] != '-'))
\r
1173 /* Don't trash a wanted safe register */
\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
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
1188 fprintf(fp, "\t\t push %s\n",regnameslong[AReg]);
\r
1194 /* Call Mame Routine */
\r
1196 /* ASG - changed these to call through the function pointers */
\r
1200 fprintf(fp, "\t\t call [_a68k_memory_intf+16]\n");
\r
1204 fprintf(fp, "\t\t call [_a68k_memory_intf+20]\n");
\r
1208 fprintf(fp, "\t\t call [_a68k_memory_intf+24]\n");
\r
1212 /* Correct Stack */
\r
1215 fprintf(fp, "\t\t lea esp,[esp+8]\n");
\r
1220 /* Restore registers */
\r
1222 /* Check to see if registers need restoring */
\r
1224 if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-'))
\r
1226 fprintf(fp, "\t\t pop EDI\n");
\r
1229 if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-'))
\r
1231 fprintf(fp, "\t\t pop ECX\n");
\r
1234 if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-'))
\r
1236 fprintf(fp, "\t\t pop EBX\n");
\r
1239 if ((Flags[EAX] != '-') && (SavedRegs[EAX] == '-'))
\r
1241 fprintf(fp, "\t\t pop EAX\n");
\r
1244 if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-'))
\r
1246 fprintf(fp, "\t\t mov EDX,[%s]\n",REG_CCR);
\r
1249 if ((Flags[ESI] != '-') && (SavedRegs[ESI] == '-'))
\r
1251 fprintf(fp, "\t\t mov ESI,[%s]\n",REG_PC);
\r
1254 if ((Flags[EBP] != '-') && (SavedRegs[EBP] == '-'))
\r
1256 fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n");
\r
1262 * Fetch data from Code area
\r
1264 * Dreg = Destination Register
\r
1265 * Extend = Sign Extend Word to Long
\r
1269 void Memory_Fetch(char Size,int Dreg,int Extend)
\r
1271 static int loopcount=0;
\r
1273 /* Always goes via OP_ROM */
\r
1277 /* 16 Bit version */
\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
1284 fprintf(fp, "\t\t mov %s,dword [esi+ebp]\n",regnameslong[Dreg]);
\r
1287 fprintf(fp, "\t\t rol %s,16\n",regnameslong[Dreg]);
\r
1291 /* 32 Bit version */
\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
1298 if (Extend == TRUE)
\r
1299 fprintf(fp, "\t\t movsx %s,word [%s+ebp]\n",regnameslong[Dreg],regnameslong[Dreg]);
\r
1301 fprintf(fp, "\t\t movzx %s,word [%s+ebp]\n",regnameslong[Dreg],regnameslong[Dreg]);
\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
1308 // Always read long
\r
1309 fprintf(fp, "\t\t test esi,2\n");
\r
1311 fprintf(fp, "\t\t mov %s,dword [esi+ebp]\n",regnameslong[Dreg]);
\r
1314 fprintf(fp, "\t\t jz short FL%3.3d\n",loopcount+1);
\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
1321 fprintf(fp, "FL%3.3d:\n",++loopcount);
\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
1331 /**********************/
\r
1332 /* Push PC onto Stack */
\r
1333 /**********************/
\r
1335 void PushPC(int Wreg,int Wreg2,char *Flags, int Mask)
\r
1338 /* Wreg2 is only used when high byte is kept */
\r
1339 /* If it is EBP then the register is restored */
\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
1345 #ifndef KEEPHIGHPC
\r
1347 Memory_Write('L',Wreg,ESI,Flags,Mask);
\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
1355 Memory_Write('L',Wreg,Wreg2,Flags,Mask);
\r
1359 fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n");
\r
1365 void ExtensionDecode(int SaveEDX)
\r
1367 char *Label = GenerateLabel(0,1);
\r
1370 fprintf(fp, "\t\t push edx\n");
\r
1372 Memory_Fetch('W',EAX,FALSE);
\r
1373 fprintf(fp, "\t\t add esi,byte 2\n");
\r
1377 /* 68000 Extension */
\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
1392 /* 68020 Extension */
\r
1394 // eax holds scaled index
\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
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
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
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
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
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
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
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
1448 // **** calc base displacement ****
\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
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
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
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
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
1483 fprintf(fp, "%s_7a:\n",Label);
\r
1484 fprintf(fp, "\t\t lea edi,[edi+eax]\n");
\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
1492 fprintf(fp, "\t\t test edx,0x0001\n");
\r
1493 fprintf(fp, "\t\t jz short %s_i\n",Label);
\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
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
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
1512 fprintf(fp, "\t\t pop edx\n");
\r
1515 /* Calculate Effective Address - Return address in EDI
\r
1517 * mode = Effective Address from Instruction
\r
1518 * Size = Byte,Word or Long
\r
1519 * Rreg = Register with Register Number in
\r
1521 * Only for modes 2 - 10 (5-10 clobber EAX)
\r
1524 void EffectiveAddressCalculate(int mode,char Size,int Rreg,int SaveEDX)
\r
1528 if ((TimingCycles > 0) && (AddEACycles!=0))
\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
1539 case 4: /* -(An) */
\r
1540 case 20: /* -(A7) */
\r
1541 TimingCycles += (CPU==2) ? 5 : 6 ;
\r
1544 case 5: /* x(An) */
\r
1545 case 9: /* x(PC) */
\r
1546 TimingCycles += (CPU==2) ? 5 : 8 ;
\r
1550 TimingCycles += (CPU==2) ? 4 : 8 ;
\r
1553 case 6: /* x(An,xr.s) */
\r
1554 case 10: /* x(PC,xr.s) */
\r
1555 TimingCycles += (CPU==2) ? 7 : 10 ;
\r
1559 TimingCycles += (CPU==2) ? 4 : 12 ;
\r
1563 /* long w/r adds 4 cycles */
\r
1565 if ((mode>1) && (Size == 'L') && (CPU != 2))
\r
1566 TimingCycles += 4 ;
\r
1569 AccessType = NORMAL;
\r
1575 fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);
\r
1579 fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);
\r
1580 IncrementEDI(Size,Rreg);
\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
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
1598 /* Get Address register Value */
\r
1600 fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]);
\r
1602 /* Add Extension Details */
\r
1604 ExtensionDecode(SaveEDX);
\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
1620 Memory_Fetch('L',EDI,FALSE);
\r
1621 fprintf(fp, "\t\t add esi,byte 4\n");
\r
1626 AccessType = PCREL;
\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
1637 AccessType = PCREL;
\r
1641 fprintf(fp, "\t\t mov edi,esi ; Get PC\n");
\r
1643 /* Add Extension Details */
\r
1645 ExtensionDecode(SaveEDX);
\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
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
1669 /* Read from Effective Address
\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
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
1681 void EffectiveAddressRead(int mode,char Size,int Rreg,int Dreg,const char *flags,int SaveEDX)
\r
1687 AccessType = NORMAL;
\r
1689 strcpy(Flags,flags);
\r
1691 /* Which Masking to Use */
\r
1693 if (Flags[5] != '-')
\r
1706 Regname = regnamesshort[Dreg];
\r
1710 Regname = regnamesword[Dreg];
\r
1714 Regname = regnameslong[Dreg];
\r
1718 switch (mode & 15)
\r
1723 /* Read 32 bits - No prefix */
\r
1725 fprintf(fp, "\t\t mov %s,[%s+%s*4]\n",regnameslong[Dreg],REG_DAT,regnameslong[Rreg]);
\r
1730 /* Read 32 bits - No prefix */
\r
1732 fprintf(fp, "\t\t mov %s,[%s+%s*4]\n",regnameslong[Dreg],REG_ADD,regnameslong[Rreg]);
\r
1736 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1738 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1742 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1747 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1749 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1753 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1758 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1760 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1764 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1770 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1772 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1776 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1781 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1783 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1787 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1792 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1794 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1798 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1803 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1805 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1809 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1814 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1816 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1820 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1825 EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1827 Memory_Read(Size,EDI,Flags,MaskMode);
\r
1831 fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]);
\r
1837 /* Immediate - for SR or CCR see ReadCCR() */
\r
1841 Memory_Fetch('L',Dreg,FALSE);
\r
1842 fprintf(fp, "\t\t add esi,byte 4\n");
\r
1846 Memory_Fetch('W',Dreg,FALSE);
\r
1847 fprintf(fp, "\t\t add esi,byte 2\n");
\r
1854 * EA = Effective Address from Instruction
\r
1855 * Size = Byte,Word or Long
\r
1856 * Rreg = Register with Register Number in
\r
1861 void EffectiveAddressWrite(int mode,char Size,int Rreg,int CalcAddress,const char *flags,int SaveEDX)
\r
1868 strcpy(Flags,flags);
\r
1870 /* Which Masking to Use ? */
\r
1874 if (Flags[5] != '-')
\r
1890 Regname = regnamesshort[0];
\r
1894 Regname = regnamesword[0];
\r
1898 Regname = regnameslong[0];
\r
1902 switch (mode & 15)
\r
1906 fprintf(fp, "\t\t mov [%s+%s*4],%s\n",REG_DAT,regnameslong[Rreg],Regname);
\r
1914 fprintf(fp, "DUFF CODE!\n");
\r
1920 fprintf(fp, "\t\t cwde\n");
\r
1923 fprintf(fp, "\t\t mov [%s+%s*4],%s\n",REG_ADD,regnameslong[Rreg],regnameslong[0]);
\r
1928 if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1929 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\r
1933 if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1934 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\r
1938 if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX);
\r
1939 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\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
1949 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\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
1959 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\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
1969 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\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
1979 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\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
1989 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\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
1999 Memory_Write(Size,EDI,EAX,Flags,MaskMode);
\r
2004 /* SR, CCR - Chain to correct routine */
\r
2010 /* Condition Decode Routines */
\r
2013 * mode = condition to check for
\r
2015 * Returns LABEL that is jumped to if condition is Condition
\r
2017 * Some conditions clobber AH
\r
2020 char *ConditionDecode(int mode, int Condition)
\r
2022 char *Label = GenerateLabel(0,1);
\r
2027 case 0: /* A - Always */
\r
2030 fprintf(fp, "\t\t jmp %s ;dave removed near\n",Label);
\r
2034 case 1: /* F - Never */
\r
2037 fprintf(fp, "\t\t jmp near %s\n",Label);
\r
2042 fprintf(fp, "\t\t mov ah,dl\n");
\r
2043 fprintf(fp, "\t\t sahf\n");
\r
2047 fprintf(fp, "\t\t ja near %s\n",Label);
\r
2051 fprintf(fp, "\t\t jbe near %s\n",Label);
\r
2056 fprintf(fp, "\t\t mov ah,dl\n");
\r
2057 fprintf(fp, "\t\t sahf\n");
\r
2061 fprintf(fp, "\t\t jbe near %s\n",Label);
\r
2065 fprintf(fp, "\t\t ja near %s\n",Label);
\r
2070 fprintf(fp, "\t\t test dl,1H\t\t;check carry\n");
\r
2074 fprintf(fp, "\t\t jz near %s\n",Label);
\r
2078 fprintf(fp, "\t\t jnz near %s\n",Label);
\r
2083 fprintf(fp, "\t\t test dl,1H\t\t;check carry\n");
\r
2086 fprintf(fp, "\t\t jnz near %s\n",Label);
\r
2090 fprintf(fp, "\t\t jz near %s\n",Label);
\r
2095 fprintf(fp, "\t\t test dl,40H\t\t;Check zero\n");
\r
2098 fprintf(fp, "\t\t jz near %s\n",Label);
\r
2102 fprintf(fp, "\t\t jnz near %s\n",Label);
\r
2107 fprintf(fp, "\t\t test dl,40H\t\t;Check zero\n");
\r
2110 fprintf(fp, "\t\t jnz near %s\n",Label);
\r
2114 fprintf(fp, "\t\t jz near %s\n",Label);
\r
2119 fprintf(fp, "\t\t test dh,8H\t\t;Check Overflow\n");
\r
2122 fprintf(fp, "\t\t jz near %s\n", Label);
\r
2126 fprintf(fp, "\t\t jnz near %s\n", Label);
\r
2131 fprintf(fp, "\t\t test dh,8H\t\t;Check Overflow\n");
\r
2134 fprintf(fp, "\t\t jnz near %s\n", Label);
\r
2138 fprintf(fp, "\t\t jz near %s\n", Label);
\r
2143 fprintf(fp,"\t\t test dl,80H\t\t;Check Sign\n");
\r
2146 fprintf(fp, "\t\t jz near %s\n", Label);
\r
2150 fprintf(fp, "\t\t jnz near %s\n", Label);
\r
2155 fprintf(fp,"\t\t test dl,80H\t\t;Check Sign\n");
\r
2158 fprintf(fp, "\t\t jnz near %s\n", Label);
\r
2162 fprintf(fp, "\t\t jz near %s\n", Label);
\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
2172 fprintf(fp, "\t\t jge near %s\n",Label);
\r
2176 fprintf(fp, "\t\t jl near %s\n",Label);
\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
2186 fprintf(fp, "\t\t jl near %s\n",Label);
\r
2190 fprintf(fp, "\t\t jge near %s\n",Label);
\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
2200 fprintf(fp, "\t\t jg near %s\n",Label);
\r
2204 fprintf(fp, "\t\t jle near %s\n",Label);
\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
2214 fprintf(fp, "\t\t jle near %s\n",Label);
\r
2218 fprintf(fp, "\t\t jg near %s\n",Label);
\r
2227 * mode = condition to check for
\r
2228 * SetWhat = text for assembler command (usually AL or address descriptor)
\r
2230 * Some conditions clobber AH
\r
2233 void ConditionCheck(int mode, char *SetWhat)
\r
2238 case 0: /* A - Always */
\r
2239 fprintf(fp, "\t\t mov %s,byte 0ffh\n",SetWhat);
\r
2242 case 1: /* F - Never */
\r
2243 if (SetWhat[1] == 'L')
\r
2245 ClearRegister(EAX);
\r
2249 fprintf(fp, "\t\t mov %s,byte 0h\n",SetWhat);
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
2350 /**********************************************************************/
\r
2351 /* Instructions - Each routine generates a range of instruction codes */
\r
2352 /**********************************************************************/
\r
2355 * Immediate Commands
\r
2366 void dump_imm( int type, int leng, int mode, int sreg )
\r
2368 int Opcode,BaseCode ;
\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
2375 Opcode = (type << 9) | ( leng << 6 ) | ( mode << 3 ) | sreg;
\r
2377 BaseCode = Opcode & 0xfff8;
\r
2379 if (mode == 7) BaseCode |= sreg ;
\r
2382 if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5))
\r
2384 BaseCode |= sreg ;
\r
2388 if (type != 4) /* Not Valid (for this routine) */
\r
2390 int Dest = EAtoAMN(Opcode, FALSE);
\r
2393 /* ADDI & SUBI also set X flag */
\r
2395 SetX = ((type == 2) || (type == 3));
\r
2401 Regname = regnamesshort[0];
\r
2402 RegnameEBX = regnamesshort[EBX];
\r
2406 Regname = regnamesword[0];
\r
2407 RegnameEBX = regnamesword[EBX];
\r
2411 Regname = regnameslong[0];
\r
2412 RegnameEBX = regnameslong[EBX];
\r
2418 if (OpcodeArray[BaseCode] == -2)
\r
2421 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
2423 /* Save Previous PC if Memory Access */
\r
2425 if ((Dest >= 2) && (Dest <=10))
\r
2428 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
2433 TimingCycles += (CPU==2) ? 4 : 8;
\r
2436 TimingCycles += (CPU==2) ? 8 : 14;
\r
2437 if ((type != 1) && (type!=6))
\r
2438 TimingCycles += 2 ;
\r
2446 TimingCycles += (CPU==2) ? 4 : 12 ;
\r
2448 TimingCycles += (CPU==2) ? 4 : 20 ;
\r
2453 TimingCycles += (CPU==2) ? 4 : 8 ;
\r
2455 TimingCycles += (CPU==2) ? 4 : 12 ;
\r
2459 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
2461 /* Immediate Mode Data */
\r
2462 EffectiveAddressRead(11,Size,EBX,EBX,"--C-S-B",FALSE);
\r
2465 EffectiveAddressRead(Dest,Size,ECX,EAX,"-BC-SDB",FALSE);
\r
2467 /* The actual work */
\r
2468 fprintf(fp, "\t\t %s %s,%s\n", OpcodeName[type], Regname, RegnameEBX );
\r
2470 SetFlags(Size,EAX,FALSE,SetX,TRUE);
\r
2472 if (type != 6) /* CMP no update */
\r
2473 EffectiveAddressWrite(Dest,Size,ECX,EAX,"---DS-B",FALSE);
\r
2480 /* Logicals are allowed to alter SR/CCR */
\r
2482 if ((!SetX) && (Dest == 11) && (Size != 'L') && (type != 6))
\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
2492 /* If SR then must be in Supervisor Mode */
\r
2494 char *Label = GenerateLabel(0,1);
\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
2499 /* User Mode - Exception */
\r
2501 Exception(8,BaseCode);
\r
2503 fprintf(fp, "%s:\n",Label);
\r
2506 /* Immediate Mode Data */
\r
2507 EffectiveAddressRead(11,Size,EBX,EBX,"---DS-B",TRUE);
\r
2509 ReadCCR(Size,ECX);
\r
2511 fprintf(fp, "\t\t %s %s,%s\n", OpcodeName[type], Regname, RegnameEBX );
\r
2520 /* Illegal Opcode */
\r
2522 OpcodeArray[BaseCode] = -1;
\r
2532 OpcodeArray[Opcode] = BaseCode;
\r
2535 void immediate(void)
\r
2537 int type, size, mode, sreg ;
\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
2552 void dump_bit_dynamic( int sreg, int type, int mode, int dreg )
\r
2554 int Opcode, BaseCode ;
\r
2556 char *EAXReg,*ECXReg, *Label ;
\r
2557 char allow[] = "0-2345678-------" ;
\r
2560 /* BTST allows x(PC) and x(PC,xr.s) - others do not */
\r
2566 allow[11] = 'b'; // dave fix to nhl
\r
2569 Opcode = 0x0100 | (sreg << 9) | (type<<6) | (mode<<3) | dreg ;
\r
2571 BaseCode = Opcode & 0x01f8 ;
\r
2572 if (mode == 7) BaseCode |= dreg ;
\r
2578 if ((mode > 2) && (mode < 5))
\r
2580 if (dreg == 7) BaseCode |= dreg;
\r
2584 Dest = EAtoAMN(Opcode, FALSE);
\r
2586 if (allow[Dest&0xf] != '-')
\r
2588 if (mode == 0) /* long*/
\r
2590 /* Modify register memory directly */
\r
2593 EAXReg = REG_DAT_EBX;
\r
2594 ECXReg = regnameslong[ECX];
\r
2599 EAXReg = regnamesshort[EAX];
\r
2600 ECXReg = regnamesshort[ECX];
\r
2603 if (OpcodeArray[BaseCode] == -2)
\r
2606 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
2608 /* Save Previous PC if Memory Access */
\r
2610 if ((Dest >= 2) && (Dest <=10))
\r
2613 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
2620 TimingCycles += 6 ;
\r
2624 TimingCycles += 8 ;
\r
2627 TimingCycles += 10;
\r
2634 TimingCycles += 4;
\r
2636 TimingCycles += 8;
\r
2639 /* Only need this sorted out if a register is involved */
\r
2643 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
2644 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
2647 /* Get bit number and create mask in ECX */
\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
2654 fprintf(fp, "\t\t and ecx, byte 31\n");
\r
2656 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
2659 fprintf(fp,"\t\t mov eax,1\n");
\r
2661 fprintf(fp,"\t\t xor eax,eax\n");
\r
2662 fprintf(fp,"\t\t inc eax\n");
\r
2665 fprintf(fp,"\t\t shl eax,cl\n");
\r
2666 fprintf(fp,"\t\t mov ecx,eax\n");
\r
2669 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",TRUE);
\r
2672 /* All commands copy existing bit to Zero Flag */
\r
2674 Label = GenerateLabel(0,1);
\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
2682 /* Some then modify the data */
\r
2690 fprintf(fp,"\t\t xor %s,%s\n",EAXReg,ECXReg);
\r
2694 fprintf(fp,"\t\t not ecx\n");
\r
2695 fprintf(fp,"\t\t and %s,%s\n",EAXReg,ECXReg);
\r
2699 fprintf(fp,"\t\t or %s,%s\n",EAXReg,ECXReg);
\r
2703 if ((mode !=0) && (type != 0))
\r
2704 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",TRUE);
\r
2709 OpcodeArray[Opcode] = BaseCode ;
\r
2713 void bitdynamic(void) /* dynamic non-immediate bit operations*/
\r
2715 int type, sreg, mode, dreg ;
\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
2724 void dump_bit_static(int type, int mode, int dreg )
\r
2726 int Opcode, BaseCode ;
\r
2728 char *EAXReg,*ECXReg, *Label ;
\r
2729 char allow[] = "0-2345678-------" ;
\r
2732 /* BTST allows x(PC) and x(PC,xr.s) - others do not */
\r
2740 Opcode = 0x0800 | (type<<6) | (mode<<3) | dreg ;
\r
2741 BaseCode = Opcode & 0x08f8 ;
\r
2742 if (mode == 7) BaseCode |= dreg ;
\r
2747 if ((mode > 2) && (mode < 5))
\r
2749 if (dreg == 7) BaseCode |= dreg;
\r
2753 Dest = EAtoAMN(Opcode, FALSE);
\r
2755 if (allow[Dest&0xf] != '-')
\r
2757 if (mode == 0) /* long*/
\r
2759 /* Modify register memory directly */
\r
2762 EAXReg = REG_DAT_EBX;
\r
2763 ECXReg = regnameslong[ECX];
\r
2768 EAXReg = regnamesshort[EAX];
\r
2769 ECXReg = regnamesshort[ECX];
\r
2772 if (OpcodeArray[BaseCode] == -2)
\r
2775 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
2777 /* Save Previous PC if Memory Access */
\r
2779 if ((Dest >= 2) && (Dest <=10))
\r
2782 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
2789 TimingCycles += 10 ;
\r
2793 TimingCycles += 12 ;
\r
2796 TimingCycles += 14 ;
\r
2803 TimingCycles += 12 ;
\r
2805 TimingCycles += 8 ;
\r
2808 /* Only need this sorted out if a register is involved */
\r
2812 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
2813 fprintf(fp, "\t\t and ebx, byte 7\n");
\r
2816 /* Get bit number and create mask in ECX */
\r
2818 Memory_Fetch('W',ECX,FALSE);
\r
2819 fprintf(fp, "\t\t add esi,byte 2\n");
\r
2822 fprintf(fp, "\t\t and ecx, byte 31\n");
\r
2824 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
2827 fprintf(fp,"\t\t mov eax,1\n");
\r
2829 fprintf(fp,"\t\t xor eax,eax\n");
\r
2830 fprintf(fp,"\t\t inc eax\n");
\r
2833 fprintf(fp,"\t\t shl eax,cl\n");
\r
2834 fprintf(fp,"\t\t mov ecx,eax\n");
\r
2837 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",TRUE);
\r
2839 /* All commands copy existing bit to Zero Flag */
\r
2841 Label = GenerateLabel(0,1);
\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
2849 /* Some then modify the data */
\r
2857 fprintf(fp,"\t\t xor %s,%s\n",EAXReg,ECXReg);
\r
2861 fprintf(fp,"\t\t not ecx\n");
\r
2862 fprintf(fp,"\t\t and %s,%s\n",EAXReg,ECXReg);
\r
2866 fprintf(fp,"\t\t or %s,%s\n",EAXReg,ECXReg);
\r
2870 if ((mode !=0) && (type != 0))
\r
2871 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",TRUE);
\r
2876 OpcodeArray[Opcode] = BaseCode ;
\r
2881 void bitstatic(void) /* static non-immediate bit operations*/
\r
2883 int type, mode, dreg ;
\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
2898 int sreg,dir,leng,dreg ;
\r
2899 int Opcode, BaseCode ;
\r
2901 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
2903 for (dir = 0 ; dir < 2 ; dir++)
\r
2905 for (leng = 0 ; leng < 2 ; leng++)
\r
2907 for (dreg = 0 ; dreg < 8 ; dreg++)
\r
2909 Opcode = 0x0108 | (sreg<<9) | (dir<<7) | (leng<<6) | dreg;
\r
2910 BaseCode = Opcode & 0x01c8 ;
\r
2911 if (OpcodeArray[BaseCode] == -2)
\r
2914 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
2916 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
2918 if (leng == 0) /* word */
\r
2919 TimingCycles += 16 ;
\r
2921 TimingCycles += 24 ;
\r
2923 /* Save Flags Register (so we only do it once) */
\r
2925 fprintf(fp, "\t\t push edx\n");
\r
2927 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
2928 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
2930 /* Get Address to Read/Write in EDI */
\r
2932 EffectiveAddressCalculate(5,'L',EBX,FALSE);
\r
2934 fprintf(fp, "\t\t shr ecx,byte 9\n");
\r
2935 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
2938 if (dir == 0) /* from memory to register*/
\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
2946 if (leng == 0) /* word d(Ax) into Dx.W*/
\r
2948 fprintf(fp,"\t\t mov [%s+ecx*4],bx\n",REG_DAT);
\r
2950 else /* long d(Ax) into Dx.L*/
\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
2962 else /* Register to Memory*/
\r
2964 fprintf(fp,"\t\t mov eax,[%s+ecx*4]\n",REG_DAT);
\r
2966 /* Move bytes into Line */
\r
2969 fprintf(fp,"\t\t rol eax,byte 8\n");
\r
2971 fprintf(fp,"\t\t rol eax,byte 24\n");
\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
2977 if (leng == 1) /* long*/
\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
2986 Memory_Write('B',EDI,EAX,"A---S-B",0);
\r
2989 fprintf(fp, "\t\t pop edx\n");
\r
2993 OpcodeArray[Opcode] = BaseCode ;
\r
3000 void movecodes(int allowfrom[],int allowto[],int Start,char Size) /* MJC */
\r
3007 for (Opcode=Start;Opcode<Start+0x1000;Opcode++)
\r
3009 /* Mask our Registers */
\r
3011 BaseCode = Opcode & (Start + 0x1f8);
\r
3013 /* Unless Mode = 7 */
\r
3015 if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7);
\r
3016 if ((BaseCode & 0x1c0) == 0x1c0) BaseCode |= (Opcode & 0xE00);
\r
3018 /* If mode = 3 or 4 and Size = byte and register = A7 */
\r
3019 /* then make it a separate code */
\r
3024 if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27))
\r
3029 if (((Opcode & 0xFC0) == 0xEC0) || ((Opcode & 0xFC0) == 0xF00))
\r
3031 BaseCode |= 0x0E00;
\r
3036 /* If Source = Data or Address register - combine into same routine */
\r
3038 if (((Opcode & 0x38) == 0x08) && (allowfrom[1]))
\r
3040 BaseCode &= 0xfff7;
\r
3043 if (OpcodeArray[BaseCode] == -2)
\r
3045 Src = EAtoAMN(Opcode, FALSE);
\r
3046 Dest = EAtoAMN(Opcode >> 6, TRUE);
\r
3048 if ((allowfrom[(Src & 15)]) && (allowto[(Dest & 15)]))
\r
3050 /* If we are not going to calculate the flags */
\r
3051 /* we need to preserve the existing ones */
\r
3053 SaveEDX = (Dest == 1);
\r
3056 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3058 if (((Src >= 2) && (Src <= 10)) || ((Dest >= 2) && (Dest <=10)))
\r
3061 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3064 TimingCycles += 4 ;
\r
3070 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
3072 if ((Src == 0) && allowfrom[1])
\r
3073 fprintf(fp, "\t\t and ebx,byte 15\n");
\r
3075 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
3077 EffectiveAddressRead(Src,Size,EBX,EAX,"--CDS-B",SaveEDX);
\r
3081 if ((Src == 0) && allowfrom[1])
\r
3082 fprintf(fp, "\t\t and ecx,byte 15\n");
\r
3084 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
3086 EffectiveAddressRead(Src,Size,ECX,EAX,"---DS-B",SaveEDX);
\r
3092 EffectiveAddressRead(Src,Size,EBX,EAX,"--CDS-B",SaveEDX);
\r
3094 EffectiveAddressRead(Src,Size,EBX,EAX,"---DS-B",SaveEDX);
\r
3097 /* No flags if Destination Ax */
\r
3101 SetFlags(Size,EAX,TRUE,FALSE,TRUE);
\r
3106 fprintf(fp, "\t\t shr ecx,9\n");
\r
3107 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
3110 EffectiveAddressWrite(Dest,Size,ECX,TRUE,"---DS-B",SaveEDX);
\r
3116 BaseCode = -1; /* Invalid Code */
\r
3121 BaseCode = OpcodeArray[BaseCode];
\r
3124 if (OpcodeArray[Opcode] < 0)
\r
3125 OpcodeArray[Opcode] = BaseCode;
\r
3129 void moveinstructions(void)
\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
3136 movecodes(allowfrom,allowto,0x1000,'B');
\r
3138 /* For Word & Long */
\r
3141 movecodes(allowfrom,allowto,0x2000,'L');
\r
3142 movecodes(allowfrom,allowto,0x3000,'W');
\r
3149 * ADDQ,SUBQ,Scc and DBcc
\r
3153 void opcode5(void)
\r
3155 /* ADDQ,SUBQ,Scc and DBcc */
\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
3164 char* RegnameECX="";
\r
3166 for (Opcode = 0x5000;Opcode < 0x6000;Opcode++)
\r
3168 if ((Opcode & 0xc0) == 0xc0)
\r
3172 BaseCode = Opcode & 0x5FF8;
\r
3173 if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7);
\r
3175 /* If mode = 3 or 4 and register = A7 */
\r
3176 /* then make it a separate code */
\r
3179 if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27))
\r
3185 if (OpcodeArray[BaseCode] == -2)
\r
3187 OpcodeArray[BaseCode] = BaseCode;
\r
3189 if ((BaseCode & 0x38) == 0x8)
\r
3194 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3196 TimingCycles += 10 ;
\r
3199 strcpy(Label,GenerateLabel(BaseCode,1)) ;
\r
3200 strcpy(Label2,ConditionDecode((Opcode >> 8) & 0x0F,TRUE));
\r
3202 /* False - Decrement Counter - Loop if not -1 */
\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
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
3216 /* True - Exit Loop */
\r
3217 fprintf(fp, "%s:\n",Label);
\r
3219 fprintf(fp, "%s:\n",Label2);
\r
3220 fprintf(fp, "\t\t add esi,byte 4\n");
\r
3221 TimingCycles += 2 ;
\r
3229 int Dest = EAtoAMN(Opcode, FALSE);
\r
3231 if (allowtoScc[(Dest & 15)])
\r
3234 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3236 if ((Dest >= 2) && (Dest <=10))
\r
3239 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3242 TimingCycles += 8 ;
\r
3244 TimingCycles += 4 ;
\r
3248 fprintf(fp, "\t\t and ecx,byte 7\n");
\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
3258 ConditionCheck((Opcode >> 8) & 0x0F,"AL");
\r
3260 EffectiveAddressWrite(Dest,'B',ECX,FALSE,"---DS-B",TRUE);
\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
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
3271 TimingCycles = -1;
\r
3277 OpcodeArray[BaseCode] = -1;
\r
3284 BaseCode = OpcodeArray[BaseCode];
\r
3287 OpcodeArray[Opcode] = BaseCode;
\r
3291 /* ADDQ or SUBQ */
\r
3293 BaseCode = Opcode & 0x51F8;
\r
3294 if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7);
\r
3296 /* Special for Address Register Direct - Force LONG */
\r
3298 if ((Opcode & 0x38) == 0x8) BaseCode = ((BaseCode & 0xFF3F) | 0x80);
\r
3301 /* If mode = 3 or 4 and Size = byte and register = A7 */
\r
3302 /* then make it a separate code */
\r
3305 if ((Opcode & 0xC0) == 0)
\r
3307 if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27))
\r
3314 if (OpcodeArray[BaseCode] == -2)
\r
3317 int Dest = EAtoAMN(Opcode, FALSE);
\r
3318 int SaveEDX = (Dest == 1);
\r
3320 if (allowtoADDQ[(Dest & 15)])
\r
3322 switch (BaseCode & 0xC0)
\r
3326 Regname = regnamesshort[0];
\r
3327 RegnameECX = regnamesshort[ECX];
\r
3332 Regname = regnamesword[0];
\r
3333 RegnameECX = regnamesword[ECX];
\r
3338 Regname = regnameslong[0];
\r
3339 RegnameECX = regnameslong[ECX];
\r
3343 OpcodeArray[BaseCode] = BaseCode;
\r
3346 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3348 if ((Dest >= 2) && (Dest <=10))
\r
3351 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3353 if (Dest == 0) /* write to Dx */
\r
3356 TimingCycles += 4 ;
\r
3358 TimingCycles += 8 ;
\r
3363 if ((Size == 'L') || (Opcode & 0x100)) /* if long or SUBQ */
\r
3364 TimingCycles += 8 ;
\r
3366 TimingCycles += 4 ;
\r
3369 if (Dest > 1) /* write to mem */
\r
3372 TimingCycles += 8 ;
\r
3374 TimingCycles += 12 ;
\r
3379 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
3380 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
3385 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",SaveEDX);
\r
3388 /* Sub Immediate from Opcode */
\r
3390 fprintf(fp, "\t\t shr ecx,9\n");
\r
3394 if (Opcode & 0x100)
\r
3397 Operation = "sub";
\r
3402 Operation = "add";
\r
3405 /* For Data or Address register, operate directly */
\r
3406 /* on the memory location. Don't load into EAX */
\r
3412 fprintf(fp, "\t\t %s [%s+ebx*4],%s\n",Operation,REG_DAT,RegnameECX);
\r
3416 fprintf(fp, "\t\t %s [%s+ebx*4],%s\n",Operation,REG_ADD,RegnameECX);
\r
3421 fprintf(fp, "\t\t %s %s,%s\n",Operation,Regname,RegnameECX);
\r
3424 /* No Flags for Address Direct */
\r
3428 /* Directly after ADD or SUB, so test not needed */
\r
3430 SetFlags(Size,EAX,FALSE,TRUE,TRUE);
\r
3435 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",FALSE);
\r
3442 OpcodeArray[BaseCode] = -1;
\r
3448 BaseCode = OpcodeArray[BaseCode];
\r
3451 OpcodeArray[Opcode] = BaseCode;
\r
3457 * Branch Instructions
\r
3463 void branchinstructions(void)
\r
3465 int Opcode,BaseCode;
\r
3468 char jmpLabel[40] ;
\r
3470 for (Opcode = 0x60;Opcode < 0x70;Opcode++)
\r
3472 /* Displacement = 0 -> 16 Bit displacement */
\r
3474 BaseCode = Opcode * 0x100;
\r
3475 OpcodeArray[BaseCode] = BaseCode;
\r
3478 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3479 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3481 TimingCycles += 10 ;
\r
3483 if (Opcode == 0x60)
\r
3485 Memory_Fetch('W',EAX,TRUE);
\r
3486 fprintf(fp, "\t\t add esi,eax\n");
\r
3487 MemoryBanking(BaseCode);
\r
3492 if (Opcode != 0x61)
\r
3494 Label = ConditionDecode(Opcode & 0x0F,TRUE);
\r
3496 /* Code for Failed branch */
\r
3498 fprintf(fp, "\t\t add esi,byte 2\n");
\r
3500 /* 2 less cycles for Failure */
\r
3502 TimingCycles -= 2;
\r
3504 TimingCycles += 2;
\r
3506 /* Successful Branch */
\r
3509 fprintf(fp, "%s:\n",Label);
\r
3511 Memory_Fetch('W',EAX,TRUE);
\r
3512 fprintf(fp, "\t\t add esi,eax\n");
\r
3513 MemoryBanking(BaseCode+2);
\r
3519 /* BSR - Special Case */
\r
3521 TimingCycles += 8 ;
\r
3523 Memory_Fetch('W',EBX,TRUE);
\r
3524 fprintf(fp, "\t\t add ebx,esi\n");
\r
3526 fprintf(fp, "\t\t add esi,byte 2\n");
\r
3527 PushPC(ECX,EAX,"-B-DS-B",1);
\r
3529 fprintf(fp, "\t\t mov esi,ebx\n");
\r
3530 MemoryBanking(BaseCode+3);
\r
3535 /* 8 Bit Displacement */
\r
3538 fprintf(fp, "%s:\n",GenerateLabel(BaseCode+1,0));
\r
3539 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3541 TimingCycles += 10 ;
\r
3543 if (Opcode > 0x60)
\r
3545 if (Opcode != 0x61)
\r
3547 Label = ConditionDecode(Opcode & 0x0F,TRUE);
\r
3549 /* Code for Failed branch */
\r
3551 TimingCycles -= 2;
\r
3553 TimingCycles += 2;
\r
3555 /* Successful Branch */
\r
3558 fprintf(fp, "%s:\n",Label);
\r
3562 /* BSR - Special Case */
\r
3564 TimingCycles += 8 ;
\r
3566 PushPC(EDI,EBX,"--CDS-B",1);
\r
3570 /* Common Ending */
\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
3577 /* Fill up Opcode Array */
\r
3579 for (Counter=1;Counter<0x100;Counter++)
\r
3580 OpcodeArray[BaseCode+Counter] = BaseCode+1;
\r
3585 /* 8 bit 0xff & 68020 instruction - 32 bit displacement */
\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
3592 TimingCycles += 10 ;
\r
3594 if (Opcode == 0x60)
\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
3604 if (Opcode != 0x61)
\r
3606 Label = ConditionDecode(Opcode & 0x0F,TRUE);
\r
3608 /* Code for Failed branch */
\r
3609 fprintf(fp, "\t\t add esi,byte 4\n");
\r
3611 TimingCycles -= 2;
\r
3613 TimingCycles += 2;
\r
3615 /* Successful Branch */
\r
3617 fprintf(fp, "%s:\n",Label);
\r
3619 Memory_Fetch('L',EAX,FALSE);
\r
3620 fprintf(fp, "\t\t add esi,eax\n");
\r
3621 MemoryBanking(BaseCode+8);
\r
3626 /* BSR - Special Case */
\r
3628 TimingCycles += 8 ;
\r
3630 Memory_Fetch('L',EBX,TRUE);
\r
3631 fprintf(fp, "\t\t add ebx,esi\n");
\r
3633 fprintf(fp, "\t\t add esi,byte 4\n");
\r
3634 PushPC(ECX,EAX,"-B-DS-B",1);
\r
3636 fprintf(fp, "\t\t mov esi,ebx\n");
\r
3637 MemoryBanking(BaseCode+9);
\r
3642 OpcodeArray[BaseCode+0xff] = BaseCode+0xff;
\r
3648 * Move Quick Commands
\r
3650 * Fairly simple, as only allowed to Data Registers
\r
3661 fprintf(fp, "%s:\n",GenerateLabel(0x7000,0));
\r
3662 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3664 TimingCycles += 4 ;
\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
3673 /* Set OpcodeArray (Not strictly correct, since some are illegal!) */
\r
3675 for (Count=0x7000;Count<0x8000;Count++)
\r
3677 OpcodeArray[Count] = 0x7000;
\r
3682 * Extended version of Add & Sub commands
\r
3686 void addx_subx(void)
\r
3688 int Opcode, BaseCode ;
\r
3689 int regx,type,leng,rm,regy,mode ;
\r
3693 char * Regname="" ;
\r
3694 char * RegnameEBX="" ;
\r
3695 char * Operand="";
\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
3704 Opcode = 0x9100 | (type<<14) | (regx<<9) | (leng<<6) | (rm<<3) | regy ;
\r
3706 BaseCode = Opcode & 0xd1c8 ;
\r
3712 if ((rm == 1) && (leng == 0))
\r
3716 BaseCode |= (regx << 9);
\r
3736 Regname = regnamesshort[0];
\r
3737 RegnameEBX = regnamesshort[EBX];
\r
3741 Regname = regnamesword[0];
\r
3742 RegnameEBX = regnamesword[EBX];
\r
3746 Regname = regnameslong[0];
\r
3747 RegnameEBX = regnameslong[EBX];
\r
3751 if (OpcodeArray[BaseCode] == -2)
\r
3759 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3764 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3766 /* don't add in EA timing for ADDX,SUBX */
\r
3770 if (rm == 0) /* reg to reg */
\r
3773 TimingCycles += 4 ;
\r
3775 TimingCycles += 8 ;
\r
3780 TimingCycles += 18 ;
\r
3782 TimingCycles += 30 ;
\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
3792 EffectiveAddressRead(mode+ModeModX,Size,EBX,EBX,"--CDS-B",FALSE);
\r
3794 /* Get Destination (if needed) */
\r
3797 EffectiveAddressRead(mode+ModeModY,Size,ECX,EAX,"-BCDSDB",FALSE);
\r
3799 /* Copy the X flag into the Carry Flag */
\r
3806 fprintf(fp, "\t\t %s [%s+ecx*4],%s\n",Operand,REG_DAT,RegnameEBX);
\r
3808 fprintf(fp, "\t\t %s %s,%s\n",Operand,Regname,RegnameEBX);
\r
3810 /* Preserve old Z flag */
\r
3812 fprintf(fp, "\t\t mov ebx,edx\n");
\r
3814 /* Set the Flags */
\r
3816 SetFlags(Size,EAX,FALSE,TRUE,FALSE);
\r
3818 /* Handle the Z flag */
\r
3820 Label = GenerateLabel(0,1);
\r
3822 fprintf(fp, "\t\t jnz short %s\n\n",Label);
\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
3829 /* Update the Data (if needed) */
\r
3832 EffectiveAddressWrite(mode,Size,ECX,FALSE,"---DS-B",TRUE);
\r
3837 OpcodeArray[Opcode] = BaseCode ;
\r
3842 * Logicals / Simple Maths (+ and -)
\r
3844 * OR,AND,CMP,EOR,ADD and SUB
\r
3848 void dumpx( int start, int reg, int type, char * Op, int dir, int leng, int mode, int sreg )
\r
3850 int Opcode,BaseCode ;
\r
3852 char * RegnameECX="" ;
\r
3853 char * Regname="" ;
\r
3858 char * allowtypes[] = { "0-23456789ab----", "--2345678-------",
\r
3859 "0123456789ab----", "0-2345678-------"};
\r
3865 case 0: /* or and*/
\r
3867 allow = allowtypes[0];
\r
3869 allow = allowtypes[1];
\r
3873 allow = allowtypes[2] ;
\r
3877 allow = allowtypes[3] ;
\r
3880 case 3: /* adda suba cmpa*/
\r
3881 allow = allowtypes[2] ;
\r
3884 case 4: /* sub add*/
\r
3886 allow = allowtypes[0] ;
\r
3888 allow = allowtypes[1] ;
\r
3892 if ((type == 4) && (dir == 0) && (leng > 0))
\r
3894 allow = allowtypes[2] ; /* word and long ok*/
\r
3897 Opcode = start | (reg << 9 ) | (dir<<8) | (leng<<6) | (mode<<3) | sreg;
\r
3899 BaseCode = Opcode & 0xf1f8;
\r
3901 if (mode == 7) BaseCode |= sreg ;
\r
3904 if ((mode == 3 || mode == 4) && ( leng == 0 ) && (sreg == 7 ))
\r
3905 BaseCode |= sreg ;
\r
3910 /* If Source = Data or Address register - combine into same routine */
\r
3912 if (((Opcode & 0x38) == 0x08) && (allow[1] != '-'))
\r
3914 BaseCode &= 0xfff7;
\r
3917 Dest = EAtoAMN(Opcode, FALSE);
\r
3918 SaveEDX = (Dest == 1) || (type == 3);
\r
3920 if (allow[Dest&0xf] != '-')
\r
3922 if (OpcodeArray[BaseCode] == -2)
\r
3928 Regname = regnamesshort[0];
\r
3929 RegnameECX = regnamesshort[ECX];
\r
3933 Regname = regnamesword[0];
\r
3934 RegnameECX = regnamesword[ECX];
\r
3938 Regname = regnameslong[0];
\r
3939 RegnameECX = regnameslong[ECX];
\r
3942 case 3: /* cmpa adda suba */
\r
3946 Regname = regnamesword[0];
\r
3947 RegnameECX = regnamesword[ECX];
\r
3952 Regname = regnameslong[0];
\r
3953 RegnameECX = regnameslong[ECX];
\r
3960 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
3962 if ((Dest >= 2) && (Dest <=10))
\r
3965 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
3970 TimingCycles += 4;
\r
3972 TimingCycles += 6;
\r
3977 TimingCycles += 8;
\r
3979 TimingCycles += 12;
\r
3982 if ((mode == 0) && (dir==0) && (Size == 'L'))
\r
3983 TimingCycles += 2 ;
\r
3985 if ((mode == 1) && (dir==0) && (Size != 'L'))
\r
3986 TimingCycles += 4 ;
\r
3988 if (Dest < 7) /* Others do not need reg.no. */
\r
3990 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
3992 if ((Dest == 0) & (allow[1] != '-'))
\r
3993 fprintf(fp, "\t\t and ebx,byte 15\n");
\r
3995 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
3998 fprintf(fp, "\t\t shr ecx,byte 9\n");
\r
3999 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4001 EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",SaveEDX);
\r
4007 fprintf(fp, "\t\t %s [%s+ECX*4],%s\n",Op ,REG_DAT ,Regname ) ;
\r
4010 SetFlags(Size,EAX,FALSE,TRUE,FALSE);
\r
4012 SetFlags(Size,EAX,FALSE,FALSE,FALSE);
\r
4017 fprintf(fp, "\t\t cwde\n");
\r
4019 fprintf(fp, "\t\t %s [%s+ECX*4],EAX\n",Op ,REG_ADD);
\r
4023 SetFlags('L',EAX,FALSE,FALSE,FALSE);
\r
4029 fprintf(fp, "\t\t %s %s,[%s+ECX*4]\n", Op, Regname ,REG_DAT ) ;
\r
4032 SetFlags(Size,EAX,FALSE,TRUE,TRUE);
\r
4034 SetFlags(Size,EAX,FALSE,FALSE,TRUE);
\r
4036 EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",FALSE);
\r
4041 OpcodeArray[Opcode] = BaseCode;
\r
4047 void typelogicalmath(void)
\r
4049 int dir, leng, mode, sreg ,reg ;
\r
4051 for (reg = 0 ; reg < 8 ; reg++)
\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
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
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
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
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
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
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
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
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
4119 * Single commands missed out by routines above
\r
4125 int dreg, type, mode, sreg ;
\r
4126 int Opcode, BaseCode ;
\r
4128 char allow[] = "0-23456789ab-----" ;
\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
4135 Opcode = 0xc0c0 | (dreg<<9) | (type<<8) | (mode<<3) | sreg ;
\r
4136 BaseCode = Opcode & 0xc1f8 ;
\r
4139 BaseCode |= sreg ;
\r
4142 Dest = EAtoAMN(Opcode, FALSE);
\r
4143 if (allow[Dest&0x0f] != '-')
\r
4145 if (OpcodeArray[ BaseCode ] == -2)
\r
4148 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
4150 if ((Dest >= 2) && (Dest <=10))
\r
4153 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4155 TimingCycles += 70 ;
\r
4159 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
4160 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
4163 fprintf(fp, "\t\t shr ecx, byte 9\n");
\r
4164 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
4166 EffectiveAddressRead(Dest,'W',EBX,EAX,"ABCDSDB",FALSE);
\r
4169 fprintf(fp, "\t\t mul word [%s+ECX*4]\n",REG_DAT);
\r
4171 fprintf(fp, "\t\t imul word [%s+ECX*4]\n",REG_DAT);
\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
4180 OpcodeArray[Opcode] = BaseCode ;
\r
4188 int Opcode, BaseCode ;
\r
4190 char allow[] = "0-23456789ab-----" ;
\r
4191 char *Label = NULL ;
\r
4193 for (mode = 0 ; mode < 8 ; mode++)
\r
4194 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
4196 Opcode = 0x4c00 | (mode<<3) | sreg ;
\r
4197 BaseCode = Opcode & 0x4c38 ;
\r
4200 BaseCode |= sreg ;
\r
4203 Dest = EAtoAMN(Opcode, FALSE);
\r
4204 if (allow[Dest&0x0f] != '-')
\r
4206 if (OpcodeArray[ BaseCode ] == -2)
\r
4208 TimingCycles += 70 ;
\r
4210 Label = GenerateLabel(BaseCode,0);
\r
4211 fprintf(fp, "%s:\n",Label);
\r
4212 if ((Dest >= 2) && (Dest <=10))
\r
4215 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4219 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4222 Memory_Fetch('W', EBX, FALSE ); // fetch the next word
\r
4223 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4225 EffectiveAddressRead(Dest,'L',ECX,EAX,"ABCDSDB",FALSE); // read from the EA
\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
4231 Label = GenerateLabel(BaseCode,1);
\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
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
4239 fprintf(fp, "%s:\n",Label);
\r
4240 fprintf(fp, "\t\t mul dword [%s+EBX*4]\n",REG_DAT); // unsigned 32x32->64
\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
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
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
4265 fprintf(fp, "%s_3:\n",Label);
\r
4269 OpcodeArray[Opcode] = BaseCode ;
\r
4277 int Opcode, BaseCode ;
\r
4279 char allow[] = "0-23456789ab-----" ;
\r
4280 char *Label = NULL ;
\r
4282 for (mode = 0 ; mode < 8 ; mode++)
\r
4283 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
4285 Opcode = 0x4c40 | (mode<<3) | sreg ;
\r
4286 BaseCode = Opcode & 0x4c78 ;
\r
4289 BaseCode |= sreg ;
\r
4292 Dest = EAtoAMN(Opcode, FALSE);
\r
4293 if (allow[Dest&0x0f] != '-')
\r
4295 if (OpcodeArray[ BaseCode ] == -2)
\r
4297 TimingCycles += 70 ;
\r
4299 Label = GenerateLabel(BaseCode,0);
\r
4300 fprintf(fp, "%s:\n",Label);
\r
4301 if ((Dest >= 2) && (Dest <=10))
\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
4308 Memory_Fetch('W', EDX, FALSE ); // fetch 2nd word in ecx
\r
4309 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4311 EffectiveAddressRead(Dest,'L',ECX,EBX,"---DSDB",FALSE);
\r
4313 fprintf(fp, "\t\t push esi\n"); // save and 0 esi
\r
4314 ClearRegister(ESI);
\r
4316 Label = GenerateLabel(BaseCode,1);
\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
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
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
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
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
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
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
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
4397 fprintf(fp, "%s_OVERFLOW:\n",Label);
\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
4406 OpcodeArray[Opcode] = BaseCode ;
\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
4421 Opcode = 0xe9c0 | (sign<<9) | (mode<<3) | dreg ;
\r
4422 BaseCode = Opcode & 0xebf8 ;
\r
4424 BaseCode |= dreg ;
\r
4425 Dest = EAtoAMN(Opcode, FALSE);
\r
4426 if (allow[Dest&0xf] != '-')
\r
4428 if (OpcodeArray[BaseCode] == -2)
\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
4437 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4441 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4444 Memory_Fetch('W', EAX, FALSE ) ;
\r
4445 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4447 EffectiveAddressRead(Dest,'L',ECX,EDX,"ABCDSDB",FALSE); // edx = dword
\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
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
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
4478 fprintf(fp, "\t\t sar ebx,cl\n");
\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
4487 fprintf(fp, "\t\t or edx,40h\n");
\r
4488 fprintf(fp, "%s_3:\n",Label);
\r
4491 OpcodeArray[Opcode] = BaseCode ;
\r
4506 int type,leng, mode, sreg ;
\r
4507 int Opcode, BaseCode ;
\r
4511 char * Regname="" ;
\r
4512 char * RegnameECX ;
\r
4515 char allow[] = "0-2345678-------" ;
\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
4522 Opcode = 0x4000 | (type<<9) | (leng<<6) | (mode<<3) | sreg ;
\r
4523 BaseCode = Opcode & 0x46f8 ;
\r
4526 BaseCode |= sreg ;
\r
4532 if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5))
\r
4534 BaseCode |= sreg ;
\r
4538 Dest = EAtoAMN(Opcode, FALSE);
\r
4540 if (allow[Dest&0x0f] != '-')
\r
4546 Regname = regnamesshort[0];
\r
4547 RegnameECX = regnamesshort[ECX];
\r
4551 Regname = regnamesword[0];
\r
4552 RegnameECX = regnamesword[ECX];
\r
4556 Regname = regnameslong[0];
\r
4557 RegnameECX = regnameslong[ECX];
\r
4561 if (OpcodeArray[ BaseCode ] == -2)
\r
4564 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
4566 if ((Dest >= 2) && (Dest <=10))
\r
4569 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4572 TimingCycles += 4;
\r
4574 TimingCycles += 6;
\r
4577 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4579 if (type == 0) SaveEDX = TRUE;
\r
4580 else SaveEDX = FALSE;
\r
4582 /* CLR does not need to read source (although it does on a real 68000) */
\r
4586 EffectiveAddressRead(Dest,Size,ECX,EAX,"A-CDS-B",SaveEDX);
\r
4591 case 0: /* negx */
\r
4593 /* Preserve old Z flag */
\r
4595 fprintf(fp, "\t\t mov ebx,edx\n");
\r
4598 fprintf(fp, "\t\t adc %s,byte 0\n", Regname ) ;
\r
4599 fprintf(fp, "\t\t neg %s\n", Regname ) ;
\r
4601 /* Set the Flags */
\r
4603 SetFlags(Size,EAX,FALSE,TRUE,FALSE);
\r
4605 /* Handle the Z flag */
\r
4607 Label = GenerateLabel(0,1);
\r
4609 fprintf(fp, "\t\t jnz short %s\n\n",Label);
\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
4619 ClearRegister(EAX);
\r
4620 EffectiveAddressWrite(Dest,Size,ECX,TRUE,"----S-B",FALSE);
\r
4621 fprintf(fp, "\t\t mov edx,40H\n");
\r
4625 fprintf(fp, "\t\t neg %s\n",Regname ) ;
\r
4626 SetFlags(Size,EAX,FALSE,TRUE,TRUE);
\r
4630 fprintf(fp, "\t\t xor %s,-1\n",Regname ) ;
\r
4631 SetFlags(Size,EAX,FALSE,FALSE,TRUE);
\r
4635 /* Update (unless CLR command) */
\r
4638 EffectiveAddressWrite(Dest,Size,ECX,FALSE,"---DS-B",TRUE);
\r
4643 OpcodeArray[Opcode] = BaseCode ;
\r
4649 * Move to/from USP
\r
4653 void moveusp(void)
\r
4655 int Opcode, BaseCode ;
\r
4659 for (dir = 0 ; dir < 2 ; dir++)
\r
4660 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
4662 Opcode = 0x4e60 | ( dir << 3 ) | sreg ;
\r
4663 BaseCode = Opcode & 0x4e68 ;
\r
4665 if (OpcodeArray[BaseCode] == -2)
\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
4672 TimingCycles += 4;
\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
4677 fprintf(fp, "\t\t and ecx,7\n");
\r
4679 if (dir == 0) /* reg 2 USP */
\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
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
4691 fprintf(fp, "OP%d_%4.4x_Trap:\n",CPU,BaseCode);
\r
4692 Exception(8,BaseCode);
\r
4694 OpcodeArray[Opcode] = BaseCode ;
\r
4706 int dreg,mode,sreg,size ;
\r
4707 int Opcode, BaseCode ;
\r
4711 char *allow = "0-23456789ab----" ;
\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
4718 if (size == 0) /* word */
\r
4719 Opcode = 0x4180 | (dreg<<9) | (mode<<3) | sreg ;
\r
4721 Opcode = 0x4100 | (dreg<<9) | (mode<<3) | sreg ;
\r
4722 BaseCode = Opcode & 0x41f8 ;
\r
4726 BaseCode |= sreg ;
\r
4729 Dest = EAtoAMN(Opcode, FALSE);
\r
4731 if (allow[Dest&0xf] != '-')
\r
4733 if (OpcodeArray[BaseCode] == -2)
\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
4740 TimingCycles += 10;
\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
4747 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4749 EffectiveAddressRead(Dest,(size == 0) ? 'W' : 'L',ECX,EAX,"----S-B",FALSE);
\r
4751 if (size == 0) /* word */
\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
4757 fprintf(fp, "\t\t mov ebx,[%s+EBX*4]\n",REG_DAT);
\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
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
4766 /* N is set if data less than zero */
\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
4773 /* N is cleared if greated than compared number */
\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
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
4786 OpcodeArray[Opcode] = BaseCode ;
\r
4794 int mode,sreg,size ;
\r
4795 int Opcode, BaseCode ;
\r
4799 char *allow = "--2--56789a-----" ;
\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
4805 Opcode = 0x00c0 | (size<<9) | (mode<<3) | sreg;
\r
4806 BaseCode = Opcode & 0xfff8 ;
\r
4810 BaseCode |= sreg ;
\r
4813 Dest = EAtoAMN(Opcode, FALSE);
\r
4815 if (allow[Dest&0xf] != '-')
\r
4817 if (OpcodeArray[BaseCode] == -2)
\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
4824 TimingCycles += 10;
\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
4831 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4833 EffectiveAddressRead(Dest,'W',ECX,EAX,"----S-B",FALSE);
\r
4835 if (size == 0) /* word */
\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
4841 fprintf(fp, "\t\t mov ebx,[%s+EBX*4]\n",REG_DAT);
\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
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
4850 /* N is set if data less than zero */
\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
4857 /* N is cleared if greated than compared number */
\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
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
4870 OpcodeArray[Opcode] = BaseCode ;
\r
4877 * Load Effective Address
\r
4880 void LoadEffectiveAddress(void)
\r
4882 int Opcode, BaseCode ;
\r
4883 int sreg,mode,dreg ;
\r
4885 char allow[] = "--2--56789a-----" ;
\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
4891 Opcode = 0x41c0 | (sreg<<9) | (mode<<3) | dreg ;
\r
4893 BaseCode = Opcode & 0x41f8 ;
\r
4896 BaseCode = BaseCode | dreg ;
\r
4898 Dest = EAtoAMN(BaseCode, FALSE);
\r
4900 if (allow[Dest&0x0f] != '-')
\r
4902 if (OpcodeArray[BaseCode] == -2)
\r
4905 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
4906 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4911 TimingCycles += 4;
\r
4916 TimingCycles += 8;
\r
4921 TimingCycles += 12;
\r
4927 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
4928 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
4931 fprintf(fp, "\t\t shr ecx,byte 9\n");
\r
4932 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
4934 EffectiveAddressCalculate(Dest,'L',EBX,TRUE);
\r
4935 fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD);
\r
4939 OpcodeArray[Opcode] = BaseCode ;
\r
4951 int Opcode, BaseCode ;
\r
4952 int sreg,mode,Dest ;
\r
4953 char allow[] = "0-2345678-------" ;
\r
4955 for (mode = 0 ; mode < 8 ; mode++)
\r
4956 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
4958 Opcode = 0x4800 | (mode<<3) | sreg ;
\r
4959 BaseCode = Opcode & 0x4838 ;
\r
4962 BaseCode |= sreg ;
\r
4967 if ((sreg == 7) && (mode > 2) && (mode < 5))
\r
4973 Dest = EAtoAMN(BaseCode, FALSE);
\r
4975 if (allow[Dest&0xf] != '-')
\r
4977 if (OpcodeArray[BaseCode] == -2)
\r
4980 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
4982 if ((Dest >= 2) && (Dest <=10))
\r
4985 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
4988 TimingCycles += 6;
\r
4990 TimingCycles += 8;
\r
4992 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
4994 EffectiveAddressRead(Dest,'B',ECX,EBX,"--C-SDB",FALSE);
\r
4996 ClearRegister(EAX);
\r
4999 fprintf(fp, "\t\t sbb al,bl\n");
\r
5000 fprintf(fp, "\t\t das\n");
\r
5002 SetFlags('B',EAX,FALSE,TRUE,TRUE);
\r
5004 EffectiveAddressWrite(Dest,'B',ECX,EAX,"----S-B",FALSE);
\r
5007 OpcodeArray[Opcode] = BaseCode ;
\r
5014 int Opcode, BaseCode ;
\r
5015 int sreg,mode,Dest ;
\r
5016 char allow[] = "0-2345678-------" ;
\r
5018 for (mode = 0 ; mode < 8 ; mode++)
\r
5019 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
5021 Opcode = 0x4ac0 | (mode<<3) | sreg ;
\r
5022 BaseCode = Opcode & 0x4af8 ;
\r
5025 BaseCode |= sreg ;
\r
5028 if ((sreg == 7) && (mode > 2) && (mode < 5))
\r
5030 BaseCode |= sreg ;
\r
5034 Dest = EAtoAMN(BaseCode, FALSE);
\r
5036 if (allow[Dest&0xf] != '-')
\r
5038 if (OpcodeArray[BaseCode] == -2)
\r
5041 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5043 if ((Dest >= 2) && (Dest <=10))
\r
5046 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5049 TimingCycles += 4;
\r
5051 TimingCycles += 14;
\r
5053 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
5055 EffectiveAddressRead(Dest,'B',ECX,EAX,"--C-SDB",FALSE);
\r
5057 SetFlags('B',EAX,TRUE,FALSE,TRUE);
\r
5058 fprintf(fp, "\t\t or al,128\n");
\r
5060 EffectiveAddressWrite(Dest,'B',ECX,EAX,"----S-B",FALSE);
\r
5063 OpcodeArray[Opcode] = BaseCode ;
\r
5069 * push Effective Address
\r
5072 void PushEffectiveAddress(void)
\r
5074 int Opcode, BaseCode ;
\r
5077 char allow[] = "--2--56789a-----" ;
\r
5079 for (mode = 0 ; mode < 8 ; mode++)
\r
5080 for (dreg = 0 ; dreg < 8 ; dreg++)
\r
5082 Opcode = 0x4840 | (mode<<3) | dreg ;
\r
5084 BaseCode = Opcode & 0x4878 ;
\r
5087 BaseCode = BaseCode | dreg ;
\r
5089 Dest = EAtoAMN(BaseCode, FALSE);
\r
5091 if (allow[Dest&0x0f] != '-')
\r
5093 if (OpcodeArray[BaseCode] == -2)
\r
5096 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5098 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5103 TimingCycles += 12;
\r
5108 TimingCycles += 16;
\r
5113 TimingCycles += 20;
\r
5119 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
5122 EffectiveAddressCalculate(Dest,'L',ECX,TRUE);
\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
5131 OpcodeArray[Opcode] = BaseCode ;
\r
5143 int leng, mode, sreg ;
\r
5144 int Opcode, BaseCode ;
\r
5148 char * RegnameECX ;
\r
5150 char allow[] = "0-2345678-------" ;
\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
5158 Opcode = 0x4a00 | (leng<<6) | (mode<<3) | sreg ;
\r
5159 BaseCode = Opcode & 0x4af8 ;
\r
5162 BaseCode |= sreg ;
\r
5168 if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5))
\r
5170 BaseCode |= sreg ;
\r
5174 Dest = EAtoAMN(Opcode, FALSE);
\r
5176 if ((allow[Dest&0x0f] != '-') || (( mode == 1 ) && (leng != 0)))
\r
5182 Regname = regnamesshort[0];
\r
5183 RegnameECX = regnamesshort[ECX];
\r
5187 Regname = regnamesword[0];
\r
5188 RegnameECX = regnamesword[ECX];
\r
5192 Regname = regnameslong[0];
\r
5193 RegnameECX = regnameslong[ECX];
\r
5197 if (OpcodeArray[ BaseCode ] == -2)
\r
5200 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5202 if ((Dest >= 2) && (Dest <=10))
\r
5205 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5207 TimingCycles += 4;
\r
5210 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
5212 EffectiveAddressRead(Dest,Size,ECX,EAX,"----S-B",FALSE);
\r
5214 SetFlags(Size,EAX,TRUE,FALSE,FALSE);
\r
5218 OpcodeArray[Opcode] = BaseCode ;
\r
5224 * Move registers too / from memory
\r
5228 void movem_reg_ea(void)
\r
5230 int leng,mode,sreg ;
\r
5231 int Opcode, BaseCode ;
\r
5236 char *allow = "--2-45678-------" ;
\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
5242 Opcode = 0x4880 | ( leng<<6) | (mode<<3) | sreg ;
\r
5243 BaseCode = Opcode & 0x4cf8 ;
\r
5247 BaseCode |= sreg ;
\r
5250 Dest = EAtoAMN(Opcode, FALSE);
\r
5252 Size = "WL"[leng] ;
\r
5254 if (allow[Dest&0xf] != '-')
\r
5256 if (OpcodeArray[BaseCode] == - 2)
\r
5259 Label = GenerateLabel(BaseCode,0);
\r
5260 fprintf(fp, "%s:\n",Label ) ;
\r
5262 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5268 TimingCycles += 8 ;
\r
5272 TimingCycles += 12 ;
\r
5276 TimingCycles += 14 ;
\r
5280 fprintf(fp, "\t\t push edx\n");
\r
5282 Memory_Fetch('W',EDX,FALSE);
\r
5283 fprintf(fp, "\t\t add esi,byte 2\n");
\r
5287 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
5292 fprintf(fp, "\t\t push ecx\n");
\r
5293 fprintf(fp, "\t\t mov edi,[%s+ECX*4]\n",REG_ADD);
\r
5296 EffectiveAddressCalculate(Dest,'L',ECX,TRUE);
\r
5298 fprintf(fp, "\t\t mov ebx,1\n");
\r
5300 /* predecrement uses d0-d7..a0-a7 a7 first*/
\r
5301 /* other modes use a7-a0..d7-d0 d0 first*/
\r
5304 ClearRegister(ECX);
\r
5306 fprintf(fp, "\t\t mov ecx,3Ch\n");
\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
5312 fprintf(fp, "\t\t mov eax,[%s+ecx]\n",REG_DAT); /* load eax with current reg data */
\r
5316 if (Size == 'W') /* adjust pointer before write */
\r
5317 fprintf(fp, "\t\t sub edi,byte 2\n");
\r
5319 fprintf(fp, "\t\t sub edi,byte 4\n");
\r
5322 Memory_Write(Size,EDI,EAX,"-BCDSDB",1);
\r
5326 if (Size == 'W') /* adjust pointer after write */
\r
5327 fprintf(fp, "\t\t add edi,byte 2\n");
\r
5329 fprintf(fp, "\t\t add edi,byte 4\n");
\r
5332 /* Update Cycle Count */
\r
5335 fprintf(fp, "\t\t sub dword [%s],byte 4\n",ICOUNT);
\r
5337 fprintf(fp, "\t\t sub dword [%s],byte 8\n",ICOUNT);
\r
5339 fprintf(fp, "OP%d_%4.4x_Skip:\n",CPU,BaseCode);
\r
5342 fprintf(fp, "\t\t add ecx,byte 4h\n");
\r
5344 fprintf(fp, "\t\t sub ecx,byte 4h\n");
\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
5352 fprintf(fp, "\t\t pop ecx\n");
\r
5353 fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD);
\r
5356 fprintf(fp, "\t\t pop edx\n");
\r
5360 OpcodeArray[Opcode] = BaseCode ;
\r
5365 void movem_ea_reg(void)
\r
5367 int leng,mode,sreg ;
\r
5368 int Opcode, BaseCode ;
\r
5373 char *allow = "--23-56789a-----" ;
\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
5379 Opcode = 0x4c80 | ( leng<<6) | (mode<<3) | sreg ;
\r
5380 BaseCode = Opcode & 0x4cf8 ;
\r
5384 BaseCode |= sreg ;
\r
5387 Dest = EAtoAMN(Opcode, FALSE);
\r
5389 Size = "WL"[leng] ;
\r
5391 if (allow[Dest&0xf] != '-')
\r
5393 if (OpcodeArray[BaseCode] == - 2)
\r
5396 Label = GenerateLabel(BaseCode,0);
\r
5398 fprintf(fp, "%s:\n",Label ) ;
\r
5400 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5406 TimingCycles += 8 ;
\r
5410 TimingCycles += 12 ;
\r
5414 TimingCycles += 14 ;
\r
5418 fprintf(fp, "\t\t push edx\n"); /* save edx because sr is unaffected */
\r
5420 Memory_Fetch('W',EDX,FALSE);
\r
5421 fprintf(fp, "\t\t add esi,byte 2\n");
\r
5425 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
5429 fprintf(fp, "\t\t push ecx\n"); /* if (An)+ then it needed later */
\r
5431 EffectiveAddressCalculate(Dest,'L',ECX,TRUE);
\r
5433 fprintf(fp, "\t\t mov ebx,1\n"); /* setup register list mask */
\r
5435 /* predecrement uses d0-d7..a0-a7 a7 first*/
\r
5436 /* other modes use a7-a0..d7-d0 d0 first*/
\r
5438 ClearRegister(ECX); /* always start with D0 */
\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
5444 Memory_Read(Size,EDI,"-BCDSDB",1);
\r
5447 fprintf(fp, "\t\t cwde\n"); /* word size must be sign extended */
\r
5449 fprintf(fp, "\t\t mov [%s+ecx],eax\n",REG_DAT); /* load current reg with eax */
\r
5451 if (Size == 'W') /* adjust pointer after write */
\r
5452 fprintf(fp, "\t\t add edi,byte 2\n");
\r
5454 fprintf(fp, "\t\t add edi,byte 4\n");
\r
5456 /* Update Cycle Count */
\r
5459 fprintf(fp, "\t\t sub dword [%s],byte 4\n",ICOUNT);
\r
5461 fprintf(fp, "\t\t sub dword [%s],byte 8\n",ICOUNT);
\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
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
5475 fprintf(fp, "\t\t pop edx\n"); /* restore flags */
\r
5479 OpcodeArray[Opcode] = BaseCode ;
\r
5487 * Local stack space
\r
5494 int Opcode, BaseCode ;
\r
5496 for (sreg = 0 ; sreg < 8; sreg++)
\r
5498 Opcode = 0x4e50 | sreg ;
\r
5499 BaseCode = 0x4e50 ;
\r
5501 if (OpcodeArray[BaseCode] == - 2)
\r
5504 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5506 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5508 TimingCycles += 16;
\r
5510 fprintf(fp, "\t\t sub dword [%s],byte 4\n",REG_A7);
\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
5517 Memory_Write('L',EDI,EAX,"---DS-B",1);
\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
5526 OpcodeArray[Opcode] = BaseCode ;
\r
5530 void unlinkasm(void)
\r
5533 int Opcode, BaseCode ;
\r
5535 for (sreg = 0 ; sreg < 8; sreg++)
\r
5537 Opcode = 0x4e58 | sreg ;
\r
5538 BaseCode = 0x4e58 ;
\r
5540 if (OpcodeArray[BaseCode] == - 2)
\r
5543 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5545 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5547 TimingCycles += 12;
\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
5553 Memory_Read('L',EDI,"-B-DSDB",1);
\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
5561 OpcodeArray[Opcode] = BaseCode ;
\r
5568 int BaseCode = 0x4E40;
\r
5570 if (OpcodeArray[BaseCode] == -2)
\r
5573 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5574 fprintf(fp, "\t\t add esi,byte 2\n\n");
\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
5583 for (Count=0;Count<=15;Count++)
\r
5584 OpcodeArray[BaseCode+Count] = BaseCode;
\r
5589 int BaseCode = 0x4E70;
\r
5592 if (OpcodeArray[BaseCode] == -2)
\r
5595 Label = GenerateLabel(BaseCode,0);
\r
5597 TimingCycles += 132;
\r
5599 fprintf(fp, "%s:\n", Label );
\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
5607 fprintf(fp, "\nOP%d_%4.4x_RESET:\n",CPU,BaseCode);
\r
5609 /* Prefetch next instruction */
\r
5613 /* 32 bit memory version */
\r
5615 fprintf(fp, "\t\t xor esi,2\n"); /* ASG */
\r
5617 ClearRegister(ECX);
\r
5618 fprintf(fp, "\t\t mov cx,[esi+ebp]\n");
\r
5620 fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");
\r
5622 fprintf(fp, "\t\t xor esi,2\n"); /* ASG */
\r
5626 /* 16 bit memory */
\r
5628 ClearRegister(ECX);
\r
5629 fprintf(fp, "\t\t mov cx,[esi+ebp]\n");
\r
5631 fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");
\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
5639 /* Callback for Reset */
\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
5645 fprintf(fp, "\t\t call [eax]\n");
\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
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
5656 OpcodeArray[BaseCode] = BaseCode ;
\r
5661 int BaseCode = 0x4e71 ;
\r
5663 if (OpcodeArray[BaseCode] == -2)
\r
5666 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5667 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5669 TimingCycles += 4;
\r
5672 OpcodeArray[BaseCode] = BaseCode ;
\r
5678 char TrueLabel[16];
\r
5679 int BaseCode = 0x4e72 ;
\r
5681 if (OpcodeArray[BaseCode] == -2)
\r
5684 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5685 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5687 TimingCycles += 4;
\r
5689 /* Must be in Supervisor Mode */
\r
5691 sprintf(TrueLabel,GenerateLabel(0,1));
\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
5696 /* Next WORD is new SR */
\r
5698 Memory_Fetch('W',EAX,FALSE);
\r
5699 fprintf(fp, "\t\t add esi,byte 2\n");
\r
5703 /* See if Valid interrupt waiting */
\r
5705 CheckInterrupt = 0;
\r
5707 fprintf(fp, "\t\t mov eax,[%s]\n",REG_IRQ);
\r
5708 fprintf(fp, "\t\t and eax,byte 07H\n");
\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
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
5718 /* No int waiting - clear count, set stop */
\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
5725 /* User Mode - Exception */
\r
5728 fprintf(fp, "%s:\n",TrueLabel);
\r
5729 Exception(8,BaseCode);
\r
5731 OpcodeArray[BaseCode] = BaseCode ;
\r
5735 void ReturnFromException(void)
\r
5737 char TrueLabel[16];
\r
5739 int BaseCode = 0x4e73;
\r
5742 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5744 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5746 TimingCycles += 20;
\r
5748 /* Check in Supervisor Mode */
\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
5754 /* Get SR - Save in EBX */
\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
5764 Memory_Read('L',EDI,"----S-B",0);
\r
5765 fprintf(fp, "\t\t xchg esi,eax\n");
\r
5767 /* Update CCR (and A7) */
\r
5771 MemoryBanking(BaseCode);
\r
5774 fprintf(fp, "%s:\n",TrueLabel);
\r
5775 Exception(8,0x10000+BaseCode);
\r
5777 OpcodeArray[BaseCode] = BaseCode;
\r
5782 int BaseCode = 0x4E76;
\r
5785 if (OpcodeArray[BaseCode] == -2)
\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
5792 TimingCycles += 4;
\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
5798 fprintf(fp, "OP%d_%4.4x_Clear:\n",CPU,BaseCode);
\r
5801 OpcodeArray[BaseCode] = BaseCode ;
\r
5804 void illegal_opcode(void)
\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
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
5818 Exception(4,0xFFFE);
\r
5822 * Return from subroutine
\r
5823 * restoring flags as well
\r
5827 void ReturnandRestore(void)
\r
5829 int BaseCode = 0x4e77;
\r
5832 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5834 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5836 TimingCycles += 20;
\r
5838 /* Get SR into ESI */
\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
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
5849 Memory_Read('L',EDI,"----SDB",0);
\r
5850 fprintf(fp, "\t\t xchg esi,eax\n");
\r
5852 /* Update flags */
\r
5856 MemoryBanking(BaseCode);
\r
5859 OpcodeArray[BaseCode] = BaseCode;
\r
5863 * Return from Subroutine
\r
5869 int BaseCode = 0x4e75 ;
\r
5871 if (OpcodeArray[BaseCode] == -2)
\r
5874 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5877 TimingCycles += 16;
\r
5879 OpcodeArray[BaseCode] = BaseCode ;
\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
5890 void jmp_jsr(void)
\r
5892 int Opcode, BaseCode ;
\r
5893 int dreg,mode,type ;
\r
5895 char allow[] = "--2--56789a-----" ;
\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
5901 Opcode = 0x4e80 | (type<<6) | (mode<<3) | dreg ;
\r
5902 BaseCode = Opcode & 0x4ef8 ;
\r
5904 BaseCode = BaseCode | dreg ;
\r
5906 Dest = EAtoAMN(BaseCode, FALSE);
\r
5907 if (allow[Dest&0x0f] != '-')
\r
5909 if (OpcodeArray[BaseCode] == -2)
\r
5912 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
5914 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
5919 TimingCycles += 8;
\r
5924 TimingCycles += 10;
\r
5927 TimingCycles += 12;
\r
5931 TimingCycles += 14;
\r
5935 if (type == 0) /* jsr takes 8 more than jmp */
\r
5936 TimingCycles += 8;
\r
5940 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
5942 EffectiveAddressCalculate(Dest,'L',ECX,TRUE);
\r
5944 /* jsr needs to push PC onto stack */
\r
5948 PushPC(EBX,EAX,"---D-DB",1);
\r
5951 fprintf(fp, "\t\t mov esi,edi\n");
\r
5952 MemoryBanking(BaseCode);
\r
5956 OpcodeArray[Opcode] = BaseCode ;
\r
5963 int Opcode, BaseCode ;
\r
5964 int regx,leng,regy ;
\r
5965 int ModeModX, ModeModY;
\r
5967 char * Regname="" ;
\r
5968 char * RegnameEBX="" ;
\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
5974 Opcode = 0xb108 | (regx<<9) | (leng<<6) | regy ;
\r
5975 BaseCode = Opcode & 0xb1c8 ;
\r
5985 BaseCode |= (regx<<9);
\r
6001 Regname = regnamesshort[EAX];
\r
6002 RegnameEBX = regnamesshort[EBX];
\r
6006 Regname = regnamesword[EAX];
\r
6007 RegnameEBX = regnamesword[EBX];
\r
6011 Regname = regnameslong[EAX];
\r
6012 RegnameEBX = regnameslong[EBX];
\r
6016 if (OpcodeArray[BaseCode] == -2)
\r
6019 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6021 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6026 TimingCycles += 12 ;
\r
6028 TimingCycles += 20 ;
\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
6035 EffectiveAddressRead(3+ModeModY,Size,EBX,EBX,"--C-S-B",FALSE);
\r
6036 EffectiveAddressRead(3+ModeModX,Size,ECX,EAX,"-B--S-B",FALSE);
\r
6038 fprintf(fp, "\t\t cmp %s,%s\n",Regname,RegnameEBX);
\r
6039 SetFlags(Size,EAX,FALSE,FALSE,FALSE);
\r
6043 OpcodeArray[Opcode] = BaseCode ;
\r
6049 int Opcode, BaseCode ;
\r
6050 int regx,type,regy ;
\r
6051 int opmask[3] = { 0x08, 0x09, 0x11} ;
\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
6057 Opcode = 0xc100 | (regx<<9) | (opmask[type]<<3) | regy ;
\r
6058 BaseCode = Opcode & 0xc1c8 ;
\r
6060 if (OpcodeArray[BaseCode] == -2)
\r
6063 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6064 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6066 TimingCycles += 6 ;
\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
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
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
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
6098 OpcodeArray[Opcode] = BaseCode ;
\r
6104 int Opcode, BaseCode ;
\r
6107 for (type = 2 ; type < 8 ; type++)
\r
6108 for (regy = 0 ; regy < 8 ; regy++)
\r
6110 if (type > 3 && type < 7)
\r
6112 Opcode = 0x4800 | (type<<6) | regy ;
\r
6113 BaseCode = Opcode & 0x48c0 ;
\r
6115 if (OpcodeArray[BaseCode] == -2)
\r
6118 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6119 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6121 TimingCycles += 4 ;
\r
6123 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
6125 if (type == 2) /* byte to word */
\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
6131 if (type == 3) /* word to long */
\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
6137 if (type == 7) /* byte to long */
\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
6146 OpcodeArray[Opcode] = BaseCode ;
\r
6152 int Opcode, BaseCode ;
\r
6155 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
6157 Opcode = 0x4840 | sreg ;
\r
6158 BaseCode = Opcode & 0x4840;
\r
6160 if (OpcodeArray[BaseCode] == -2)
\r
6163 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6164 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6166 TimingCycles += 4 ;
\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
6177 OpcodeArray[Opcode] = BaseCode ;
\r
6182 * Line A and Line F commands
\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
6197 for (Count=0xA000;Count<0xB000;Count++)
\r
6199 OpcodeArray[Count] = 0xA000;
\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
6214 for (Count=0xF000;Count<0x10000;Count++)
\r
6216 OpcodeArray[Count] = 0xF000;
\r
6221 * Moves To/From CCR and SR
\r
6223 * (Move from CCR is 68010 command)
\r
6229 int Opcode, BaseCode ;
\r
6230 int type, mode, sreg ;
\r
6232 char allow[] = "0-2345678-------" ;
\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
6239 Opcode = 0x40c0 | (type << 9) | ( mode << 3 ) | sreg ;
\r
6241 /* To has extra modes */
\r
6247 allow[0xb] = 'b' ;
\r
6250 if ((type == 0) | (type == 3))
\r
6251 Size = 'W'; /* SR */
\r
6253 Size = 'B'; /* CCR */
\r
6255 BaseCode = Opcode & 0x46f8 ;
\r
6258 BaseCode |= sreg ;
\r
6260 Dest = EAtoAMN(BaseCode, FALSE);
\r
6262 if (allow[Dest&0xf] != '-')
\r
6264 if (OpcodeArray[BaseCode] == -2)
\r
6266 char TrueLabel[16];
\r
6269 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6271 if ((Dest >= 2) && (Dest <=10))
\r
6274 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6276 if (type > 1) /* move to */
\r
6277 TimingCycles += 12 ;
\r
6281 TimingCycles += 6 ;
\r
6283 TimingCycles += 8 ;
\r
6286 /* If Move to SR then must be in Supervisor Mode */
\r
6290 sprintf(TrueLabel,GenerateLabel(0,1));
\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
6296 /* 68010 Command ? */
\r
6297 if (type==1) CheckCPUtype(1);
\r
6302 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
6305 /* Always read/write word 2 bytes */
\r
6308 ReadCCR(Size,EBX);
\r
6309 EffectiveAddressWrite(Dest & 15,'W',ECX,TRUE,"---DS-B",TRUE);
\r
6313 EffectiveAddressRead(Dest & 15,'W',ECX,EAX,"----S-B",FALSE);
\r
6318 /* Exception if not Supervisor Mode */
\r
6322 /* Was in User Mode - Exception */
\r
6324 fprintf(fp, "%s:\n",TrueLabel);
\r
6325 Exception(8,BaseCode);
\r
6329 OpcodeArray[Opcode] = BaseCode ;
\r
6335 * Decimal mode Add / Subtracts
\r
6339 void abcd_sbcd(void)
\r
6341 int Opcode, BaseCode ;
\r
6342 int regx,type,rm,regy,mode ;
\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
6352 Opcode = 0x8100 | (type<<14) | (regx<<9) | (rm<<3) | regy ;
\r
6353 BaseCode = Opcode & 0xc108 ;
\r
6368 BaseCode |= (regx << 9);
\r
6380 if (OpcodeArray[BaseCode] == -2)
\r
6383 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6388 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6393 TimingCycles += 6 ;
\r
6395 TimingCycles += 18 ;
\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
6402 EffectiveAddressRead(mode+ModeModX,'B',EBX,EBX,"--C-S-B",TRUE);
\r
6403 EffectiveAddressRead(mode+ModeModY,'B',ECX,EAX,"-BC-SDB",TRUE);
\r
6409 fprintf(fp, "\t\t sbb al,bl\n");
\r
6410 fprintf(fp, "\t\t das\n");
\r
6414 fprintf(fp, "\t\t adc al,bl\n");
\r
6415 fprintf(fp, "\t\t daa\n");
\r
6418 /* Should only clear Zero flag if not zero */
\r
6420 Label = GenerateLabel(0,1);
\r
6422 fprintf(fp, "\t\t mov ebx,edx\n");
\r
6423 fprintf(fp, "\t\t setc dl\n");
\r
6425 fprintf(fp, "\t\t jnz short %s\n\n",Label);
\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
6431 fprintf(fp, "%s:\n",Label);
\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
6439 fprintf(fp, "\t\t mov [%s],edx\n",REG_X);
\r
6441 EffectiveAddressWrite(mode,'B',ECX,EAX,"---DS-B",TRUE);
\r
6445 OpcodeArray[Opcode] = BaseCode ;
\r
6450 * Rotate Left / Right
\r
6454 void rol_ror(void)
\r
6456 int Opcode, BaseCode ;
\r
6457 int dreg, dr, leng, ir, sreg ;
\r
6460 char * Regname="" ;
\r
6461 char * RegnameECX ;
\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
6469 Opcode = 0xe018 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;
\r
6470 BaseCode = Opcode & 0xe1f8 ;
\r
6476 Regname = regnamesshort[0];
\r
6477 RegnameECX = regnamesshort[ECX];
\r
6481 Regname = regnamesword[0];
\r
6482 RegnameECX = regnamesword[ECX];
\r
6486 Regname = regnameslong[0];
\r
6487 RegnameECX = regnameslong[ECX];
\r
6491 if (OpcodeArray[ BaseCode ] == -2)
\r
6494 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6495 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6498 TimingCycles += 6 ;
\r
6500 TimingCycles += 8 ;
\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
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
6517 EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE);
\r
6519 /* shift 0 - no time, no shift and clear carry */
\r
6521 Label = GenerateLabel(0,1);
\r
6522 fprintf(fp, "\t\t jecxz %s\n",Label);
\r
6524 /* allow 2 cycles per shift */
\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
6531 fprintf(fp, "\t\t ror %s,cl\n",Regname);
\r
6533 fprintf(fp, "\t\t rol %s,cl\n",Regname);
\r
6535 fprintf(fp, "\t\t setc ch\n");
\r
6537 fprintf(fp, "%s:\n",Label);
\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
6543 EffectiveAddressWrite(0,Size,EBX,EAX,"--C-S-B",TRUE);
\r
6548 OpcodeArray[Opcode] = BaseCode ;
\r
6552 void rol_ror_ea(void)
\r
6554 int Opcode, BaseCode ;
\r
6555 int dr, mode, sreg ;
\r
6557 char allow[] = "--2345678-------" ;
\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
6563 Opcode = 0xe6c0 | (dr<<8) | (mode<<3) | sreg ;
\r
6564 BaseCode = Opcode & 0xfff8 ;
\r
6567 BaseCode |= sreg ;
\r
6569 Dest = EAtoAMN(BaseCode, FALSE);
\r
6571 if (allow[Dest&0xf] != '-')
\r
6573 if (OpcodeArray[ BaseCode ] == -2)
\r
6576 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6578 if ((Dest >= 2) && (Dest <=10))
\r
6581 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6583 TimingCycles += 8 ;
\r
6585 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
6586 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);
\r
6589 fprintf(fp, "\t\t ror ax,1\n");
\r
6591 fprintf(fp, "\t\t rol ax,1\n");
\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
6598 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE);
\r
6603 OpcodeArray[Opcode] = BaseCode ;
\r
6609 * Logical Shift Left / Right
\r
6613 void lsl_lsr(void)
\r
6615 int Opcode, BaseCode ;
\r
6616 int dreg, dr, leng, ir, sreg ;
\r
6618 char * Regname="" ;
\r
6619 char * RegnameECX="" ;
\r
6620 char * RegnameEDX="" ;
\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
6629 Opcode = 0xe008 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;
\r
6630 BaseCode = Opcode & 0xe1f8 ;
\r
6636 Regname = regnamesshort[0];
\r
6637 RegnameECX = regnamesshort[ECX];
\r
6638 RegnameEDX = regnamesshort[EDX];
\r
6642 Regname = regnamesword[0];
\r
6643 RegnameECX = regnamesword[ECX];
\r
6644 RegnameEDX = regnamesword[EDX];
\r
6648 Regname = regnameslong[0];
\r
6649 RegnameECX = regnameslong[ECX];
\r
6650 RegnameEDX = regnameslong[EDX];
\r
6654 if (OpcodeArray[ BaseCode ] == -2)
\r
6657 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6658 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6661 TimingCycles += 6 ;
\r
6663 TimingCycles += 8 ;
\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
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
6680 /* and 2 cycles per shift */
\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
6686 EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE);
\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
6695 fprintf(fp, "%s_Continue:\n",Label);
\r
6697 fprintf(fp, "\t\t shr %s,cl\n",Regname);
\r
6699 fprintf(fp, "\t\t shl %s,cl\n",Regname);
\r
6701 SetFlags(Size,EAX,FALSE,FALSE,FALSE);
\r
6703 /* Clear Overflow flag */
\r
6704 fprintf(fp, "\t\t xor dh,dh\n");
\r
6706 EffectiveAddressWrite(0,Size,EBX,EAX,"--CDS-B",TRUE);
\r
6708 /* if shift count is zero clear carry */
\r
6710 fprintf(fp, "\t\t jecxz %s\n",Label);
\r
6712 fprintf(fp, "\t\t mov [%s],edx\n",REG_X);
\r
6716 fprintf(fp, "%s:\n",Label);
\r
6717 fprintf(fp, "\t\t and dl,254\t\t;clear C flag\n");
\r
6720 fprintf(fp, "%s_BigShift:\n",Label);
\r
6723 fprintf(fp, "\t\t shr %s,16\n",Regname);
\r
6724 fprintf(fp, "\t\t shr %s,16\n",Regname);
\r
6728 fprintf(fp, "\t\t shl %s,16\n",Regname);
\r
6729 fprintf(fp, "\t\t shl %s,16\n",Regname);
\r
6731 fprintf(fp, "\t\t jmp %s_Continue\n",Label);
\r
6734 OpcodeArray[Opcode] = BaseCode ;
\r
6738 void lsl_lsr_ea(void)
\r
6740 int Opcode, BaseCode ;
\r
6741 int dr, mode, sreg ;
\r
6743 char allow[] = "--2345678-------" ;
\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
6749 Opcode = 0xe2c0 | (dr<<8) | (mode<<3) | sreg ;
\r
6750 BaseCode = Opcode & 0xfff8 ;
\r
6753 BaseCode |= sreg ;
\r
6755 Dest = EAtoAMN(BaseCode, FALSE);
\r
6757 if (allow[Dest&0xf] != '-')
\r
6759 if (OpcodeArray[ BaseCode ] == -2)
\r
6763 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6765 if ((Dest >= 2) && (Dest <=10))
\r
6768 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6770 TimingCycles += 8 ;
\r
6772 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
6773 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);
\r
6776 fprintf(fp, "\t\t shr ax,1\n");
\r
6778 fprintf(fp, "\t\t shl ax,1\n");
\r
6780 SetFlags('W',EAX,FALSE,TRUE,FALSE);
\r
6782 /* Clear Overflow flag */
\r
6784 fprintf(fp, "\t\t xor dh,dh\n");
\r
6786 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE);
\r
6790 OpcodeArray[Opcode] = BaseCode ;
\r
6796 * Rotate Left / Right though Extend
\r
6800 void roxl_roxr(void)
\r
6802 int Opcode, BaseCode ;
\r
6803 int dreg, dr, leng, ir, sreg ;
\r
6805 char * Regname="" ;
\r
6806 char * RegnameECX="" ;
\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
6815 Opcode = 0xe010 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;
\r
6816 BaseCode = Opcode & 0xe1f8 ;
\r
6822 Regname = regnamesshort[0];
\r
6823 RegnameECX = regnamesshort[ECX];
\r
6827 Regname = regnamesword[0];
\r
6828 RegnameECX = regnamesword[ECX];
\r
6832 Regname = regnameslong[0];
\r
6833 RegnameECX = regnameslong[ECX];
\r
6837 if (OpcodeArray[ BaseCode ] == -2)
\r
6840 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6841 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6844 TimingCycles += 6 ;
\r
6846 TimingCycles += 8 ;
\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
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
6863 /* allow 2 cycles per shift */
\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
6869 EffectiveAddressRead(0,Size,EBX,EAX,"-BC-SDB",FALSE);
\r
6871 /* move X into C so RCR & RCL can be used */
\r
6872 /* RCR & RCL only set the carry flag */
\r
6877 fprintf(fp, "\t\t rcr %s,cl\n",Regname);
\r
6879 fprintf(fp, "\t\t rcl %s,cl\n",Regname);
\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
6885 EffectiveAddressWrite(0,Size,EBX,EAX,"--CDS-B",TRUE);
\r
6887 /* if shift count is zero clear carry */
\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
6893 /* Add in Carry Flag */
\r
6895 fprintf(fp, "\t\t or dl,ch\n");
\r
6896 fprintf(fp, "\t\t mov [%s],dl\n",REG_X);
\r
6900 /* copy X onto C when shift is zero */
\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
6910 OpcodeArray[Opcode] = BaseCode ;
\r
6914 void roxl_roxr_ea(void)
\r
6916 int Opcode, BaseCode ;
\r
6917 int dr, mode, sreg ;
\r
6919 char allow[] = "--2345678-------" ;
\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
6925 Opcode = 0xe4c0 | (dr<<8) | (mode<<3) | sreg ;
\r
6926 BaseCode = Opcode & 0xfff8 ;
\r
6929 BaseCode |= sreg ;
\r
6931 Dest = EAtoAMN(BaseCode, FALSE);
\r
6933 if (allow[Dest&0xf] != '-')
\r
6935 if (OpcodeArray[ BaseCode ] == -2)
\r
6938 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
6940 if ((Dest >= 2) && (Dest <=10))
\r
6943 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
6945 TimingCycles += 8 ;
\r
6947 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
6948 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);
\r
6950 /* move X into C so RCR & RCL can be used */
\r
6951 /* RCR & RCL only set the carry flag */
\r
6956 fprintf(fp, "\t\t rcr ax,1\n");
\r
6958 fprintf(fp, "\t\t rcl ax,1\n");
\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
6965 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE);
\r
6967 fprintf(fp, "\t\t mov [%s],edx\n",REG_X);
\r
6971 OpcodeArray[Opcode] = BaseCode ;
\r
6977 * Arithmetic Shift Left / Right
\r
6981 void asl_asr(void)
\r
6983 int Opcode, BaseCode ;
\r
6984 int dreg, dr, leng, ir, sreg ;
\r
6986 char * Sizename="" ;
\r
6987 char * Regname="" ;
\r
6988 char * RegnameEDX="" ;
\r
6989 char * RegnameECX="" ;
\r
6992 /* Normal routines for codes */
\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
7000 Opcode = 0xe000 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ;
\r
7001 BaseCode = Opcode & 0xe1f8 ;
\r
7007 Regname = regnamesshort[0];
\r
7008 RegnameECX = regnamesshort[ECX];
\r
7009 RegnameEDX = regnamesshort[EDX];
\r
7013 Regname = regnamesword[0];
\r
7014 RegnameECX = regnamesword[ECX];
\r
7015 RegnameEDX = regnamesword[EDX];
\r
7019 Regname = regnameslong[0];
\r
7020 RegnameECX = regnameslong[ECX];
\r
7021 RegnameEDX = regnameslong[EDX];
\r
7025 if (OpcodeArray[ BaseCode ] == -2)
\r
7028 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
7029 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
7031 Label = GenerateLabel(0,1);
\r
7034 TimingCycles += 6 ;
\r
7036 TimingCycles += 8 ;
\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
7042 EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE);
\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
7056 /* allow 2 cycles per shift */
\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
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
7074 fprintf(fp, "\t\t sar %s,cl\n",Regname);
\r
7076 /* Mode 0 write does not affect Flags */
\r
7077 EffectiveAddressWrite(0,Size,EBX,EAX,"---DS-B",TRUE);
\r
7079 /* Update Flags */
\r
7080 fprintf(fp, "\t\t lahf\n");
\r
7083 ClearRegister(EDX);
\r
7084 fprintf(fp, "\t\t mov dl,ah\n");
\r
7086 fprintf(fp, "\t\t movzx edx,ah\n");
\r
7089 fprintf(fp, "\t\t mov [%s],edx\n",REG_X);
\r
7095 /* Check to see if Overflow should be set */
\r
7097 fprintf(fp,"\t\t mov edi,eax\t\t; Save It\n");
\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
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
7112 fprintf(fp,"%s_V:\n",Label);
\r
7113 ClearRegister(EDX);
\r
7115 fprintf(fp,"%s_OV:\n",Label);
\r
7117 /* more than 31 shifts and long */
\r
7119 if ((ir==1) && (leng==2))
\r
7121 fprintf(fp,"\t\t test cl,0x20\n");
\r
7122 fprintf(fp,"\t\t jnz short %s_32\n\n",Label);
\r
7125 fprintf(fp,"\t\t mov eax,edi\t\t; Restore It\n");
\r
7127 fprintf(fp, "\t\t sal %s,cl\n",Regname);
\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
7139 fprintf(fp, "%s:\n",Label);
\r
7144 /* ASR - Test clears V and C */
\r
7145 SetFlags(Size,EAX,TRUE,FALSE,FALSE);
\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
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
7172 OpcodeArray[Opcode] = BaseCode ;
\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
7181 for (leng = 0 ; leng < 3 ; leng++)
\r
7182 for (sreg = 0 ; sreg < 8 ; sreg++)
\r
7184 Opcode = 0xe300 | (leng<<6) | sreg ;
\r
7185 BaseCode = Opcode & 0xe3c8 ;
\r
7190 Sizename = "byte";
\r
7193 Sizename = "word";
\r
7196 Sizename = "long";
\r
7203 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
7204 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
7206 Label = GenerateLabel(0,1);
\r
7209 TimingCycles += 6 ;
\r
7211 TimingCycles += 8 ;
\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
7220 OpcodeArray[Opcode] = BaseCode ;
\r
7224 void asl_asr_ea(void)
\r
7226 int Opcode, BaseCode ;
\r
7227 int dr, mode, sreg ;
\r
7229 char allow[] = "--2345678-------" ;
\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
7235 Opcode = 0xe0c0 | (dr<<8) | (mode<<3) | sreg ;
\r
7236 BaseCode = Opcode & 0xfff8 ;
\r
7239 BaseCode |= sreg ;
\r
7241 Dest = EAtoAMN(BaseCode, FALSE);
\r
7243 if (allow[Dest&0xf] != '-')
\r
7245 if (OpcodeArray[ BaseCode ] == -2)
\r
7249 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
7251 if ((Dest >= 2) && (Dest <=10))
\r
7254 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
7256 TimingCycles += 8 ;
\r
7258 fprintf(fp, "\t\t and ecx,byte 7\n");
\r
7259 EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE);
\r
7262 fprintf(fp, "\t\t sar ax,1\n");
\r
7264 fprintf(fp, "\t\t sal ax,1\n");
\r
7266 SetFlags('W',EAX,FALSE,TRUE,TRUE);
\r
7268 EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"----S-B",FALSE);
\r
7272 OpcodeArray[Opcode] = BaseCode ;
\r
7281 void divides(void)
\r
7283 int dreg, type, mode, sreg ;
\r
7284 int Opcode, BaseCode ;
\r
7286 char allow[] = "0-23456789ab-----" ;
\r
7287 char TrapLabel[16];
\r
7290 int divide_cycles[12] =
\r
7292 38,0,42,42,44,46,50,46,50,46,48,42
\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
7300 Opcode = 0x80c0 | (dreg<<9) | (type<<8) | (mode<<3) | sreg ;
\r
7301 BaseCode = Opcode & 0x81f8 ;
\r
7304 BaseCode |= sreg ;
\r
7307 Dest = EAtoAMN(Opcode, FALSE);
\r
7308 if (allow[Dest&0x0f] != '-')
\r
7310 if (OpcodeArray[ BaseCode ] == -2)
\r
7313 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
7315 if ((Dest >= 2) && (Dest <=10))
\r
7318 fprintf(fp, "\t\t add esi,byte 2\n\n");
\r
7321 /* Save EDX (in case of overflow) */
\r
7323 fprintf(fp, "\t\t and edx,byte -2\n");
\r
7324 fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR);
\r
7327 /* Cycle Timing (if succeeds OK) */
\r
7329 Cycles = divide_cycles[Dest & 0x0f] + 95 + (type * 17);
\r
7332 fprintf(fp, "\t\t sub dword [%s],%d\n",ICOUNT,Cycles);
\r
7334 fprintf(fp, "\t\t sub dword [%s],byte %d\n",ICOUNT,Cycles);
\r
7338 fprintf(fp, "\t\t mov ebx,ecx\n");
\r
7339 fprintf(fp, "\t\t and ebx,byte 7\n");
\r
7342 fprintf(fp, "\t\t shr ecx, byte 9\n");
\r
7343 fprintf(fp, "\t\t and ecx, byte 7\n");
\r
7345 sprintf(TrapLabel, "%s", GenerateLabel(0,1) ) ;
\r
7347 EffectiveAddressRead(Dest,'W',EBX,EAX,"A-C-SDB",FALSE); /* source */
\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
7352 if (type == 1) /* signed */
\r
7354 fprintf(fp, "\t\t movsx ebx,ax\n");
\r
7358 fprintf(fp, "\t\t movzx ebx,ax\n");
\r
7361 EffectiveAddressRead(0,'L',ECX,EAX,"ABC-SDB",FALSE); /* dest */
\r
7363 if (type == 1) /* signed */
\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
7368 /* Check for Overflow */
\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
7376 ClearRegister(EDX);
\r
7377 fprintf(fp, "\t\t div ebx\n");
\r
7379 /* Check for Overflow */
\r
7381 fprintf(fp, "\t\t test eax, 0FFFF0000H\n");
\r
7382 fprintf(fp, "\t\t jnz short %s_OVER\n",TrapLabel);
\r
7385 /* Sort out Result */
\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
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
7404 /* Division by Zero */
\r
7407 fprintf(fp, "%s_ZERO:\t\t ;Do divide by zero trap\n", TrapLabel);
\r
7409 /* Correct cycle counter for error */
\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
7417 OpcodeArray[Opcode] = BaseCode ;
\r
7424 * 68010 Extra Opcodes
\r
7426 * move from CCR is done above
\r
7430 void ReturnandDeallocate(void)
\r
7432 int BaseCode = 0x4e74 ;
\r
7434 if (OpcodeArray[BaseCode] == -2)
\r
7437 fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0));
\r
7443 TimingCycles += 16;
\r
7445 OpcodeArray[BaseCode] = BaseCode ;
\r
7447 /* Get Return Address */
\r
7449 fprintf(fp, "\t\t mov eax,[%s]\n",REG_A7);
\r
7450 Memory_Read('L',EAX,"---D--B",1);
\r
7453 /* Get Displacement */
\r
7455 Memory_Fetch('W',EBX,TRUE);
\r
7458 /* Set PC = New Address */
\r
7460 fprintf(fp, "\t\t mov esi,eax\n");
\r
7463 /* Correct Stack for Return Address and Displacement */
\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
7468 MemoryBanking(BaseCode);
\r
7473 void MoveControlRegister(void)
\r
7476 int BaseCode = 0x4e7a ;
\r
7478 for (Direction=0;Direction<2;Direction++)
\r
7481 fprintf(fp, "%s:\n",GenerateLabel(BaseCode+Direction,0));
\r
7483 TimingCycles += 4; /* Assume same as move usp */
\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
7490 fprintf(fp, "\t\t add esi,byte 2\n");
\r
7492 fprintf(fp, "\t\t xor esi,2\n"); /* ASG */
\r
7494 ClearRegister(EBX);
\r
7495 fprintf(fp, "\t\t mov bx,[esi+ebp]\n");
\r
7497 fprintf(fp, "\t\t movzx ebx,word [esi+ebp]\n");
\r
7500 fprintf(fp, "\t\t xor esi,2\n"); /* ASG */
\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
7506 /* Sort out Register */
\r
7508 fprintf(fp, "\t\t shr ebx,12\n");
\r
7510 /* Sort out Control Register ID */
\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
7519 /* from Control */
\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
7528 fprintf(fp, "\t\t mov eax,%s\n",REG_DAT_EBX);
\r
7530 /* Mask out for SFC & DFC */
\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
7537 /* Write to control */
\r
7539 fprintf(fp, "\t\t mov [%s+ecx*4],eax\n",REG_SFC);
\r
7544 /* Not Supervisor Mode */
\r
7547 fprintf(fp, "OP%d_%4.4x_Trap:\n",CPU,BaseCode+Direction);
\r
7548 Exception(8,BaseCode+Direction);
\r
7550 OpcodeArray[BaseCode+Direction] = BaseCode+Direction;
\r
7554 void MoveAddressSpace(void)
\r
7559 * Generate Jump Table
\r
7563 void JumpTable(void)
\r
7567 fprintf(fp, "DD OP%d_1000\n",CPU);
\r
7570 for (Opcode=0x0;Opcode<0x10000;)
\r
7573 op = OpcodeArray[Opcode];
\r
7575 fprintf(fp, "DD ");
\r
7578 while (op == OpcodeArray[Opcode+l] && ((Opcode+l) & 0xfff) != 0)
\r
7588 fprintf(fp, "OP%d_%4.4x - OP%d_1000\n",CPU,op,CPU);
\r
7590 fprintf(fp, "ILLEGAL - OP%d_1000\n",CPU);
\r
7592 fprintf(fp, "DW %d\n", l);
\r
7597 fprintf(fp, "(OP%d_%4.4x - OP%d_1000) + (%d * 1000000h)\n",CPU,op,CPU,l);
\r
7599 fprintf(fp, "(ILLEGAL - OP%d_1000) + (%d * 1000000h)\n",CPU,l);
\r
7604 void CodeSegmentBegin(void)
\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
7612 /* Needed code to make it work! */
\r
7614 fprintf(fp, "\t\t BITS 32\n\n");
\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
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
7627 fprintf(fp, "; Vars Mame declares / needs access to\n\n");
\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
7633 fprintf(fp, "\t\t EXTERN _OP_ROM\n");
\r
7634 fprintf(fp, "\t\t EXTERN _OP_RAM\n");
\r
7636 fprintf(fp, "\t\t EXTERN _opcode_entry\n");
\r
7637 fprintf(fp, "\t\t EXTERN _cur_mrhard\n");
\r
7639 //#ifdef MAME_DEBUG
\r
7640 fprintf(fp, "\t\t EXTERN _m68k_illegal_opcode\n");
\r
7644 fprintf(fp, "\t\t SECTION maincode USE32 FLAT CLASS=CODE\n\n");
\r
7646 fprintf(fp, "\t\t SECTION .text\n\n");
\r
7651 /* Reset routine */
\r
7653 fprintf(fp, "%s_RESET:\n",CPUtype);
\r
7655 fprintf(fp, "\t\t pushad\n\n");
\r
7657 fprintf(fp, "; Build Jump Table (not optimised!)\n\n");
\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
7662 /* Reference Point in EBP */
\r
7664 fprintf(fp, "\t\t mov ebp,[esi]\n");
\r
7665 fprintf(fp, "\t\t add esi,byte 4\n");
\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
7674 /* if count is zero, then it's a word RLE length */
\r
7676 fprintf(fp, "\t\t shr ecx,24\n");
\r
7677 fprintf(fp, "\t\t jne short RESET1\n");
\r
7680 ClearRegister(ECX);
\r
7681 fprintf(fp, "\t\t mov cx,[esi]\t\t; Repeats\n");
\r
7683 fprintf(fp, "\t\t movzx ecx,word [esi]\t\t; Repeats\n");
\r
7686 fprintf(fp, "\t\t add esi,byte 2\n");
\r
7687 fprintf(fp, "\t\t jecxz RESET2\t\t; Finished!\n");
\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
7696 fprintf(fp, "RESET2:\n");
\r
7697 fprintf(fp, "\t\t popad\n");
\r
7698 fprintf(fp, "\t\t ret\n\n");
\r
7700 /* Emulation Entry Point */
\r
7704 fprintf(fp, "%s_RUN:\n",CPUtype);
\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
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
7715 fprintf(fp, "IntCont:\n");
\r
7717 /* See if was only called to check for Interrupt */
\r
7719 fprintf(fp, "\t\t test dword [%s],-1\n",ICOUNT);
\r
7720 fprintf(fp, "\t\t js short MainExit\n\n");
\r
7725 fprintf(fp, "\t\t mov eax,2\n"); /* ASG */
\r
7726 fprintf(fp, "\t\t xor eax,esi\n"); /* ASG */
\r
7728 ClearRegister(ECX);
\r
7729 fprintf(fp, "\t\t mov cx,[eax+ebp]\n");
\r
7731 fprintf(fp, "\t\t movzx ecx,word [eax+ebp]\n");
\r
7736 /* 16 Bit Fetch */
\r
7738 ClearRegister(ECX);
\r
7739 fprintf(fp, "\t\t mov cx,[esi+ebp]\n");
\r
7741 fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n");
\r
7744 fprintf(fp, "\t\t jmp [%s_OPCODETABLE+ecx*4]\n", CPUtype);
\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
7760 /* If in Debug mode make normal SR register */
\r
7764 ReadCCR('W', ECX);
\r
7765 fprintf(fp, "\t\t mov [%s],eax\n\n",REG_S);
\r
7769 fprintf(fp, "\t\t popad\n");
\r
7770 fprintf(fp, "\t\t ret\n");
\r
7772 /* Check for Pending Interrupts */
\r
7775 fprintf(fp, "; Interrupt check\n\n");
\r
7777 fprintf(fp, "interrupt:\n");
\r
7779 /* check to exclude interrupts */
\r
7781 fprintf(fp, "\t\t mov eax,[%s]\n",REG_IRQ);
\r
7782 fprintf(fp, "\t\t and eax,byte 07H\n");
\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
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
7792 /* Take pending Interrupt */
\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
7798 /* Get Interrupt Vector from callback */
\r
7800 fprintf(fp, "\t\t push eax\t\t; save level\n\n");
\r
7802 if (SavedRegs[EBX] == '-')
\r
7804 fprintf(fp, "\t\t push EBX\n");
\r
7808 fprintf(fp, "\t\t mov ebx,eax\n");
\r
7811 if (SavedRegs[ESI] == '-')
\r
7813 fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC);
\r
7816 if (SavedRegs[EDX] == '-')
\r
7818 fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR);
\r
7821 /* ----- Win32 uses FASTCALL (By Kenjo)----- */
\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
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
7832 if (SavedRegs[EDX] == '-')
\r
7834 fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR);
\r
7837 if (SavedRegs[ESI] == '-')
\r
7839 fprintf(fp, "\t\t mov esi,[%s]\n",REG_PC);
\r
7842 /* Do we want to use normal vector number ? */
\r
7845 fprintf(fp, "\t\t test eax,eax\n");
\r
7846 fprintf(fp, "\t\t jns short AUTOVECTOR\n");
\r
7848 /* Only need EBX restored if default vector to be used */
\r
7850 if (SavedRegs[EBX] == '-')
\r
7852 fprintf(fp, "\t\t pop EBX\n");
\r
7855 /* Just get default vector */
\r
7857 fprintf(fp, "\t\t mov eax,ebx\n");
\r
7859 fprintf(fp, "\t\t add eax,byte 24\t\t; Vector\n\n");
\r
7861 fprintf(fp, "AUTOVECTOR:\n\n");
\r
7863 Exception(-1,0xFFFF);
\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
7872 /* Exception Routine */
\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
7879 fprintf(fp, "\t\t push eax\t\t; Save for Later\n");
\r
7881 /* Update Cycle Count */
\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
7888 fprintf(fp, "\t\t mov edi,[%s]\t\t; Get A7\n",REG_A7);
\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
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
7897 /* Write SR first (since it's in a register) */
\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
7904 /* Then write PC */
\r
7906 fprintf(fp, "\t\t add edi,byte 2\n");
\r
7907 Memory_Write('L',EDI,ESI,"------B",0);
\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
7917 Memory_Read('L',EAX,"------B",0);
\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
7922 /* Sort out any bank changes */
\r
7925 fprintf(fp, "\t\t ret\n");
\r
7928 void CodeSegmentEnd(void)
\r
7931 fprintf(fp, "\t\t SECTION maindata USE32 FLAT CLASS=DATA\n\n");
\r
7933 fprintf(fp, "\t\t SECTION .data\n");
\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
7940 /* Memory structure for 68000 registers */
\r
7941 /* Same layout as structure in CPUDEFS.H */
\r
7943 fprintf(fp, "\n\n; Register Structure\n\n");
\r
7944 fprintf(fp, "%s_regs\n",CPUtype);
\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
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
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
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
7973 fprintf(fp, "R_IRQ_CALLBACK\t DD 0\t\t\t ; irq callback (get vector)\n\n");
\r
7975 fprintf(fp, "R_PPC\t DD 0\t\t\t ; Previous Program Counter\n");
\r
7977 fprintf(fp, "R_RESET_CALLBACK\t DD 0\t\t\t ; Reset Callback\n");
\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
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
7988 /* Extra space for variables mame uses for debugger */
\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
7999 /* Safe Memory Locations */
\r
8001 fprintf(fp, "\t\t ALIGN 16\n");
\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
8010 fprintf(fp, "\n\nImmTable\n");
\r
8011 fprintf(fp, "\t\t DD 8,1,2,3,4,5,6,7\n\n");
\r
8016 /* Exception Timing Table */
\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
8023 fprintf(fp, "; RLE Compressed Jump Table\n\n");
\r
8025 fprintf(fp, "%s_COMPTABLE\n\n", CPUtype);
\r
8027 fprintf(fp, "%cinclude '%s'\n\n",'%', comptab);
\r
8029 fprintf(fp, "\t\tDW 0,0,0\n\n");
\r
8032 /* If Win32, put the table area in .data section (Kenjo) */
\r
8036 fprintf(fp, "%s_OPCODETABLE\tTIMES 65536 DD 0\n\n", CPUtype);
\r
8041 fprintf(fp, "\t\t SECTION tempdata USE32 FLAT CLASS=BSS\n\n");
\r
8043 fprintf(fp, "\t\t SECTION .bss\n");
\r
8046 fprintf(fp, "%s_OPCODETABLE\tRESD 65536\n\n", CPUtype);
\r
8052 void EmitCode(void)
\r
8054 CodeSegmentBegin();
\r
8056 /* Instructions */
\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
8074 not(); /* also neg negx clr */
\r
8080 ReturnandRestore();
\r
8091 ReturnFromException();
\r
8097 asl_asr(); /* E### Shift Commands */
\r
8105 LineA(); /* A000 to AFFF Line A */
\r
8106 LineF(); /* F000 to FFFF Line F */
\r
8109 ReturnandDeallocate(); /* 68010 Commands */
\r
8110 MoveControlRegister();
\r
8111 MoveAddressSpace();
\r
8113 if(CPU==2) /* 68020 Commands */
\r
8123 int main(int argc, char **argv)
\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
8131 if (argc != 4 && argc != 5)
\r
8133 printf("Usage: %s outfile jumptable-outfile type [ppro]\n", argv[0]);
\r
8137 printf("Building 680%s 2001\n\n",argv[3]);
\r
8139 for (dwLoop=0;dwLoop<65536;) OpcodeArray[dwLoop++] = -2;
\r
8141 codebuf=malloc(64);
\r
8144 printf ("Memory allocation error\n");
\r
8148 /* Emit the code */
\r
8149 fp = fopen(argv[1], "w");
\r
8152 fprintf(stderr, "Can't open %s for writing\n", argv[1]);
\r
8156 comptab = argv[2];
\r
8159 CPUtype = malloc(64);
\r
8161 sprintf(CPUtype,"M680%s",argv[3]);
\r
8163 sprintf(CPUtype,"_M680%s",argv[3]);
\r
8166 if(argv[3][0]=='2') CPU = 2;
\r
8167 if(argc > 4 && !stricmp(argv[4], "ppro"))
\r
8170 printf("Generating ppro opcodes\n");
\r
8177 printf("\n%d Unique Opcodes\n",Opcount);
\r
8179 /* output Jump table to separate file */
\r
8180 fp = fopen(argv[2], "w");
\r
8183 fprintf(stderr, "Can't open %s for writing\n", argv[2]);
\r