?? makez80.c
字號:
{ fprintf(fp, " mov dl, [esi] ; Fetch our offset\n"); fprintf(fp, " inc esi ; Move past the offset\n"); fprintf(fp, " or dl, dl ; Is this bad boy signed?\n"); fprintf(fp, " jns notSigned%ld ; Nope!\n", dwGlobalLabel); fprintf(fp, " dec dh ; Make it FFable\n"); fprintf(fp, "notSigned%ld:\n", dwGlobalLabel); fprintf(fp, " add dx, [_z80%s] ; Our offset!\n", Localmz80Index); ++dwGlobalLabel;}void CBHandler(UINT32 dwOpcode){ if (MZ80_ASSEMBLY_X86 == bWhat) { fprintf(fp, ";\n"); fprintf(fp, "; Handler for all CBxx instructions\n"); fprintf(fp, ";\n"); sprintf(string, "RegInst%.2x", dwOpcode); ProcBegin(0xffffffff); fprintf(fp, " mov dl, [esi]\n"); fprintf(fp, " inc esi\n"); fprintf(fp, " jmp dword [z80PrefixCB+edx*4]\n\n"); fprintf(fp, "\n\n"); } else if (MZ80_C == bWhat) { fprintf(fp, " CBHandler();\n"); } else { assert(0); }}void EDHandler(UINT32 dwOpcode){ if (MZ80_ASSEMBLY_X86 == bWhat) { fprintf(fp, ";\n"); fprintf(fp, "; Handler for all EDxx instructions\n"); fprintf(fp, ";\n"); sprintf(string, "RegInst%.2x", dwOpcode); ProcBegin(0xffffffff); fprintf(fp, " mov dl, [esi]\n"); fprintf(fp, " inc esi\n"); fprintf(fp, " jmp dword [z80PrefixED+edx*4]\n\n"); fprintf(fp, "\n\n"); } else if (MZ80_C == bWhat) { fprintf(fp, " EDHandler();\n"); } else { assert(0); }}void DDHandler(UINT32 dwOpcode){ if (MZ80_ASSEMBLY_X86 == bWhat) { fprintf(fp, ";\n"); fprintf(fp, "; Handler for all DDxx instructions\n"); fprintf(fp, ";\n"); sprintf(string, "RegInst%.2x", dwOpcode); ProcBegin(0xffffffff); fprintf(fp, " mov dl, [esi]\n"); fprintf(fp, " inc esi\n"); fprintf(fp, " jmp dword [z80PrefixDD+edx*4]\n\n"); fprintf(fp, "\n\n"); } else if (MZ80_C == bWhat) { fprintf(fp, " DDHandler();\n"); } else { assert(0); }}void FDHandler(UINT32 dwOpcode){ if (MZ80_ASSEMBLY_X86 == bWhat) { fprintf(fp, ";\n"); fprintf(fp, "; Handler for all FDxx instructions\n"); fprintf(fp, ";\n"); sprintf(string, "RegInst%.2x", dwOpcode); ProcBegin(0xffffffff); fprintf(fp, " mov dl, [esi]\n"); fprintf(fp, " inc esi\n"); fprintf(fp, " jmp dword [z80PrefixFD+edx*4]\n\n"); fprintf(fp, "\n\n"); } else if (MZ80_C == bWhat) { fprintf(fp, " FDHandler();\n"); } else { assert(0); }}StandardHeader(){ if (MZ80_ASSEMBLY_X86 == bWhat) { fprintf(fp,"; For assembly by NASM only\n"); fprintf(fp,"bits 32\n\n"); fprintf(fp,"; Theory of operation\n\n"); fprintf(fp,"; EDI=General purpose\n"); fprintf(fp,"; ESI=Program counter + base address\n"); fprintf(fp,"; EBP=z80Base\n"); fprintf(fp,"; AX=AF\n"); fprintf(fp,"; BX=HL\n"); fprintf(fp,"; CX=BC\n"); fprintf(fp,"; DX=General purpose\n\n"); if (bUseStack) fprintf(fp, "; Using stack calling conventions\n"); else fprintf(fp, "; Using register calling conventions\n"); if (b16BitIo) fprintf(fp, "; Extended input/output instructions treat (BC) as I/O address\n"); else fprintf(fp, "; Extended input/output instructions treat (C) as I/O address\n\n"); fprintf(fp, "IFF1 equ 01h\n"); fprintf(fp, "IFF2 equ 02h\n"); fprintf(fp, "CPUREG_PC equ 00h\n"); fprintf(fp, "CPUREG_SP equ 01h\n"); fprintf(fp, "CPUREG_AF equ 02h\n"); fprintf(fp, "CPUREG_BC equ 03h\n"); fprintf(fp, "CPUREG_DE equ 04h\n"); fprintf(fp, "CPUREG_HL equ 05h\n"); fprintf(fp, "CPUREG_AFPRIME equ 06h\n"); fprintf(fp, "CPUREG_BCPRIME equ 07h\n"); fprintf(fp, "CPUREG_DEPRIME equ 08h\n"); fprintf(fp, "CPUREG_HLPRIME equ 09h\n"); fprintf(fp, "CPUREG_IX equ 0ah\n"); fprintf(fp, "CPUREG_IY equ 0bh\n"); fprintf(fp, "CPUREG_I equ 0ch\n"); fprintf(fp, "CPUREG_A equ 0dh\n"); fprintf(fp, "CPUREG_F equ 0eh\n"); fprintf(fp, "CPUREG_B equ 0fh\n"); fprintf(fp, "CPUREG_C equ 10h\n"); fprintf(fp, "CPUREG_D equ 11h\n"); fprintf(fp, "CPUREG_E equ 12h\n"); fprintf(fp, "CPUREG_H equ 13h\n"); fprintf(fp, "CPUREG_L equ 14h\n"); fprintf(fp, "CPUREG_IFF1 equ 15h\n"); fprintf(fp, "CPUREG_IFF2 equ 16h\n"); fprintf(fp, "CPUREG_CARRY equ 17h\n"); fprintf(fp, "CPUREG_NEGATIVE equ 18h\n"); fprintf(fp, "CPUREG_PARITY equ 19h\n"); fprintf(fp, "CPUREG_OVERFLOW equ 1ah\n"); fprintf(fp, "CPUREG_HALFCARRY equ 1bh\n"); fprintf(fp, "CPUREG_ZERO equ 1ch\n"); fprintf(fp, "CPUREG_SIGN equ 1dh\n"); fprintf(fp, "CPUREG_MAXINDEX equ 1eh\n\n"); } else if (MZ80_C == bWhat) { fprintf(fp, "/* Multi-Z80 32 Bit emulator */\n"); fprintf(fp, "\n"); fprintf(fp, "/* Copyright 1996-2000 Neil Bradley, All rights reserved\n"); fprintf(fp, " *\n"); fprintf(fp, " * License agreement:\n"); fprintf(fp, " *\n"); fprintf(fp, " * (MZ80 Refers to both the assembly code emitted by makeZ80.c and makeZ80.c\n"); fprintf(fp, " * itself)\n"); fprintf(fp, " *\n"); fprintf(fp, " * MZ80 May be distributed in unmodified form to any medium.\n"); fprintf(fp, " *\n"); fprintf(fp, " * MZ80 May not be sold, or sold as a part of a commercial package without\n"); fprintf(fp, " * the express written permission of Neil Bradley (neil@synthcom.com). This\n"); fprintf(fp, " * includes shareware.\n"); fprintf(fp, " *\n"); fprintf(fp, " * Modified versions of MZ80 may not be publicly redistributed without author\n"); fprintf(fp, " * approval (neil@synthcom.com). This includes distributing via a publicly\n"); fprintf(fp, " * accessible LAN. You may make your own source modifications and distribute\n"); fprintf(fp, " * MZ80 in source or object form, but if you make modifications to MZ80\n"); fprintf(fp, " * then it should be noted in the top as a comment in makeZ80.c.\n"); fprintf(fp, " *\n"); fprintf(fp, " * MZ80 Licensing for commercial applications is available. Please email\n"); fprintf(fp, " * neil@synthcom.com for details.\n"); fprintf(fp, " *\n"); fprintf(fp, " * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for\n"); fprintf(fp, " * any damage done by the use of MZ80. It is purely \"as-is\".\n"); fprintf(fp, " *\n"); fprintf(fp, " * If you use MZ80 in a freeware application, credit in the following text:\n"); fprintf(fp, " *\n"); fprintf(fp, " * \"Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)\"\n"); fprintf(fp, " *\n"); fprintf(fp, " * must accompany the freeware application within the application itself or\n"); fprintf(fp, " * in the documentation.\n"); fprintf(fp, " *\n"); fprintf(fp, " * Legal stuff aside:\n"); fprintf(fp, " *\n"); fprintf(fp, " * If you find problems with MZ80, please email the author so they can get\n"); fprintf(fp, " * resolved. If you find a bug and fix it, please also email the author so\n"); fprintf(fp, " * that those bug fixes can be propogated to the installed base of MZ80\n"); fprintf(fp, " * users. If you find performance improvements or problems with MZ80, please\n"); fprintf(fp, " * email the author with your changes/suggestions and they will be rolled in\n"); fprintf(fp, " * with subsequent releases of MZ80.\n"); fprintf(fp, " *\n"); fprintf(fp, " * The whole idea of this emulator is to have the fastest available 32 bit\n"); fprintf(fp, " * Multi-Z80 emulator for the PC, giving maximum performance. \n"); fprintf(fp, " */\n\n"); fprintf(fp, "#include <stdio.h>\n"); fprintf(fp, "#include <stdlib.h>\n"); fprintf(fp, "#include <string.h>\n"); fprintf(fp, "#include \"mz80.h\"\n"); // HACK HACK fprintf(fp, "UINT32 z80intAddr;\n"); fprintf(fp, "UINT32 z80pc;\n"); } else { // Whoops. Unknown emission type. assert(0); } fprintf(fp, "\n\n");}Alignment(){ fprintf(fp, "\ntimes ($$-$) & 3 nop ; pad with NOPs to 4-byte boundary\n\n");}void ProcBegin(UINT32 dwOpcode){ Alignment(); fprintf(fp, "%s:\n", procname);}void SetSubFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight){ fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n"); fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n"); fprintf(fp, " pbSubSbcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);}void SetSbcFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight){ fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n"); fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n"); fprintf(fp, " pbSubSbcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);}void SetAddFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight){ fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n"); fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n"); fprintf(fp, " pbAddAdcTable[((UINT32) %s << 8) | %s];\n", pszLeft, pszRight);}void SetAdcFlagsSZHVC(UINT8 *pszLeft, UINT8 *pszRight){ fprintf(fp, " cpu.z80F = (cpu.z80F & ~(Z80_FLAG_CARRY | Z80_FLAG_NEGATIVE | Z80_FLAG_OVERFLOW_PARITY | \n"); fprintf(fp, " Z80_FLAG_HALF_CARRY | Z80_FLAG_ZERO | Z80_FLAG_SIGN)) |\n"); fprintf(fp, " pbAddAdcTable[((UINT32) %s << 8) | %s | (((UINT32) cpu.z80F & Z80_FLAG_CARRY) << 16)];\n", pszLeft, pszRight);}UINT32 dwOverflowCount = 0;SetOverflow(){ fprintf(fp, " seto dl\n"); fprintf(fp, " and ah, 0fbh ; Knock out parity/overflow\n"); fprintf(fp, " shl dl, 2\n"); fprintf(fp, " or ah, dl\n");} void FetchNextInstruction(UINT32 dwOpcode){ if (0xffffffff != dwOpcode) { fprintf(fp, " sub edi, byte %ld\n", Timing(bCurrentMode, dwOpcode)); if (bCurrentMode == TIMING_REGULAR) fprintf(fp, " js near noMoreExec\n"); else fprintf(fp, " js near noMoreExec\n"); } fprintf(fp, " mov dl, byte [esi] ; Get our next instruction\n"); fprintf(fp, " inc esi ; Increment PC\n"); fprintf(fp, " jmp dword [z80regular+edx*4]\n\n");}void WriteValueToMemory(UINT8 *pszAddress, UINT8 *pszValue){ if (MZ80_ASSEMBLY_X86 == bWhat) { fprintf(fp, " mov [cyclesRemaining], edi\n"); fprintf(fp, " mov [_z80af], ax ; Store AF\n"); // First off, load our byte to write into al after we've saved AF if (strcmp(pszValue, "al") != 0) fprintf(fp, " mov al, %s ; And our data to write\n", pszValue); if (strcmp(pszValue, "[esi]") == 0) // Immediate value? fprintf(fp, " inc esi ; Increment our program counter\n"); // Now get the address in DX - regardless of what it is if (strcmp(pszAddress, "[_z80de]") == 0 || strcmp(pszAddress, "[_orgval]") == 0 || strcmp(pszAddress, "[_z80ix]") == 0 || strcmp(pszAddress, "[_z80iy]") == 0) fprintf(fp, " mov dx, %s\n", pszAddress); fprintf(fp, " mov edi, [_z80MemWrite] ; Point to the write array\n\n", cpubasename); fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel); fprintf(fp, " cmp [edi], word 0ffffh ; End of our list?\n"); fprintf(fp, " je memoryWrite%ld ; Yes - go write it!\n", dwGlobalLabel); if (strcmp(pszAddress, "[_z80de]") == 0 || strcmp(pszAddress, "[_orgval]") == 0 || strcmp(pszAddress, "[_z80ix]") == 0 || strcmp(pszAddress, "[_z80iy]") == 0) fprintf(fp, " cmp dx, [edi] ; Are we smaller?\n", pszAddress); else fprintf(fp, " cmp %s, [edi] ; Are we smaller?\n", pszAddress); fprintf(fp, " jb nextAddr%ld ; Yes... go to the next addr\n", dwGlobalLabel); if (strcmp(pszAddress, "[_z80de]") == 0 || strcmp(pszAddress, "[_orgval]") == 0 || strcmp(pszAddress, "[_z80ix]") == 0 || strcmp(pszAddress, "[_z80iy]") == 0) fprintf(fp, " cmp dx, [edi+4] ; Are we smaller?\n", pszAddress); else fprintf(fp, " cmp %s, [edi+4] ; Are we smaller?\n", pszAddress); fprintf(fp, " jbe callRoutine%ld ; If not, go call it!\n\n", dwGlobalLabel); fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel); fprintf(fp, " add edi, 10h ; Next structure, please\n"); fprintf(fp, " jmp short checkLoop%ld\n\n", dwGlobalLabel); // ---- [Kayamon] - Check internal/external write ---------------------- fprintf(fp, "callRoutine%ld: \n", dwGlobalLabel); fprintf(fp, " cmp dword[edi+8],byte 0 ; Use internal write?\n"); fprintf(fp, " je short memoryWrite%ld \n", dwGlobalLabel); // ---- External write ------------------------------------------------- // Save off our registers! if ((strcmp(pszAddress, "dx") != 0) && (strcmp(pszAddress, "[_z80de]") != 0) && (strcmp(pszAddress, "[_z80ix]") != 0) && (strcmp(pszAddress, "[_orgval]") != 0) && (strcmp(pszAddress, "[_z80iy]") != 0)) fprintf(fp, " mov dx, %s ; Get our address to target\n", pszAddress); fprintf(fp, " call WriteMemoryByte ; Go write the data!\n"); fprintf(fp, " jmp short WriteMacroExit%ld\n", dwGlobalLabel); // ---- Internal write ------------------------------------------------- // [Kayamon] - modified to use custom offsets fprintf(fp, "memoryWrite%ld:\n", dwGlobalLabel); fprintf(fp, " mov edi, [edi+12] ; [Kayamon] - Get offset\n"); if (strcmp(pszValue, "[esi]") == 0) fprintf(fp, " mov [edi + e%s], al ; Store our direct value\n", pszAddress); else { if (pszValue[0] == 'b' && pszValue[1] == 'y' && pszValue[2] == 't') { fprintf(fp, " push edx\n"); fprintf(fp, " add edi, e%s\n", pszAddress); assert(strcmp(pszValue, "dl") != 0); fprintf(fp, " mov dl, %s\n", pszValue); fprintf(fp, " mov [edi], dl\n"); fprintf(fp, " pop edx\n"); } else { if (strcmp(pszAddress, "[_z80de]") != 0 && strcmp(pszAddress, "[_orgval]") != 0 && strcmp(pszAddress, "[_z80ix]") != 0 && strcmp(pszAddress, "[_z80iy]") != 0) fprintf(fp, " mov [edi + e%s], %s\n", pszAddress, pszValue); else fprintf(fp, " mov [edi + edx], al\n"); } } // ---- Exit ----------------------------------------------------------- fprintf(fp, " mov ax, [_z80af] ; Get our accumulator and flags\n"); fprintf(fp, "WriteMacroExit%ld:\n", dwGlobalLabel); fprintf(fp, " mov edi, [cyclesRemaining]\n"); ++dwGlobalLabel; } else if (MZ80_C == bWhat)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -