📄 z80sim.c
字号:
/* Z80Sim - A simulator/debugger for the Zilog Z80 processor Copyright (C) 2003 Lorenzo J. Lucchini This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "types.h"#include "sizes.h"#include "cpu.h"#include "debug.h"#include "symbols.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#include <assert.h>static logic SingleStepping;static sig_atomic_t UserBreak=0;void Quit() { fprintf(stdout, "Aborting.\n"); exit(1);}void Break(int Signal) { if(SingleStepping) Quit(); fflush(stdout); UserBreak=1;}void Usage(const char* ProgramName, const char* Message) { if(Message) fprintf(stdout, "%s\n\n", Message); fprintf(stdout, "Usage: %s [<options>] <binaryfile>\n", ProgramName); fprintf(stdout, "Run, debug and profile a Z80 program compiled with SDCC\n"); fprintf(stdout, "\n<binaryfile> contains a raw Z80 program, which is loaded at\n"); fprintf(stdout, "location 0x0000 by default.\n"); fprintf(stdout, "<options> can be one or more of the following:\n"); fprintf(stdout, " --trace shows the state of the processor after each\n"); fprintf(stdout, " instruction executed\n"); fprintf(stdout, " --symbols <file.sym> uses a .sym file as generated by SDCC\n"); fprintf(stdout, " to learn about global symbols used in\n"); fprintf(stdout, " the program\n"); fprintf(stdout, " --dbg <file.dbg> uses a .dbg file as generated by MakeDBG to\n"); fprintf(stdout, " be able to refer to C source code lines\n"); fprintf(stdout, "\n"); Quit();}void ReadFileLine(FILE* Handle, unsigned int Line, char* String) { unsigned int i; fseek(Handle, 0, SEEK_SET); for(i=0; i<Line; i++) fgets(String, MAX_STRING, Handle); String[strlen(String)-1]='\0';}void Stop(word Address) { char Mnemonic[MAX_NAME]; source SourceSpec; SingleStepping=TRUE; fprintf(stdout, "\nFrame %ld - Stopping at address %04x: ", GetFrame(), Address); Disassemble(&Address, Mnemonic); fprintf(stdout, "%s\n", Mnemonic); PrintRegisters(stdout); fprintf(stdout, "\n"); SourceSpec=SearchSource(Address); if(SourceSpec.File!=NULL) { char SourceLine[MAX_STRING]; ReadFileLine(SourceSpec.File, SourceSpec.Line-1, SourceLine); fprintf(stdout, " %s\n", SourceLine); ReadFileLine(SourceSpec.File, SourceSpec.Line, SourceLine); fprintf(stdout, "%5d -> %s\n", SourceSpec.Line, SourceLine); ReadFileLine(SourceSpec.File, SourceSpec.Line+1, SourceLine); fprintf(stdout, " %s\n", SourceLine); } else fprintf(stdout, "(no C source line showable)\n");}#if 0void Debug(word* Address) { char CommandLine[MAX_STRING]; char Command[MAX_NAME]; char* Arguments; char Mnemonic[MAX_NAME]; fprintf(stdout, "$ "); fgets(CommandLine, MAX_STRING, stdin); do sscanf(CommandLine, "%s", Command); while(strlen(Command)==0); Arguments=&CommandLine[strlen(Command)+1]; if(!strcmp(Command, "irq")) { RaiseIRQ(); } else if(!strcmp(Command, "quit")) { Quit(); } else { fprintf(stdout, "Invalid command '%s'\n", Command); }}#endifint main(int argc, char* argv[]) { FILE* ProgramFile; FILE* SymbolsFile; FILE* DebugFile; FILE* StateLog; int i=0; logic TraceExecution; word InstructionAddress; char Mnemonic[MAX_NAME]; ProgramFile=SymbolsFile=DebugFile=StateLog=NULL; SingleStepping=TRUE; TraceExecution=FALSE; for(i=1; i<argc; i++) { if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { Usage(argv[0], NULL); } else if(!strcmp(argv[i], "--trace") || !strcmp(argv[i], "-t")) { TraceExecution=TRUE; } else if(!strcmp(argv[i], "--symbols") || !strcmp(argv[i], "-s")) { i++; if(i==argc) Usage(argv[0], "Option '--symbols' requires a parameter"); SymbolsFile=fopen(argv[i], "r"); if(SymbolsFile==NULL) fprintf(stdout, "Could not open symbols file '%s'\n", argv[i]); } else if(!strcmp(argv[i], "--dbg")) { i++; if(i==argc) Usage(argv[0], "Option '--dbg' requires a parameter"); DebugFile=fopen(argv[i], "r"); if(DebugFile==NULL) fprintf(stdout, "Could not open debug file '%s'", argv[i]); } else if(!strcmp(argv[i], "--statelog") || !strcmp(argv[i], "-l")) { i++; if(i==argc) Usage(argv[0], "Option '--statelog' requires a parameter"); StateLog=fopen(argv[i], "w"); if(StateLog==NULL) fprintf(stdout, "Could not open state log file '%s'\n", argv[i]); } else if(argv[i][0]=='-') { char Error[MAX_STRING]; sprintf(Error, "Unknown option '%s'", argv[i]); Usage(argv[0], Error); } else { ProgramFile=fopen(argv[i], "r"); if(ProgramFile==NULL) { fprintf(stdout, "Could not open program file '%s'\n", argv[i+1]); Quit(); } } } if(ProgramFile) { Init(); fprintf(stdout, "Loading program...\n"); LoadROM(ProgramFile); fclose(ProgramFile); } else Usage(argv[0], "A valid program file must be specified"); InitSymbols(); if(SymbolsFile) { fprintf(stdout, "Loading symbols...\n"); LoadSymbols(SymbolsFile); fclose(SymbolsFile); } InitDebugger(); if(DebugFile) { fprintf(stdout, "Loading debug information...\n"); LoadSourcePointers(DebugFile); fclose(DebugFile); } InstructionAddress=0x0000; fprintf(stdout, "Starting simulation...\n"); signal(SIGINT, Break); for(;;) { if(UserBreak==1) { UserBreak=0; SingleStepping=TRUE; } if(SingleStepping || BreakRequest()) SingleStepping=Debugger(); else { InstructionAddress=GetRegister(REG_PC); if(TraceExecution) { PrintRegisters(stdout); fprintf(stdout, " - %04x: ", InstructionAddress); Disassemble(&InstructionAddress, Mnemonic); fprintf(stdout, "%s\n", Mnemonic); } switch(Step()) { case TRAP_NONE: case TRAP_NOEFFECT: break; case TRAP_METACALL: fprintf(stdout, "\nTRAP: Metacall not implemented (illegal instruction)\n"); Stop(InstructionAddress); break; case TRAP_ILLEGAL: fprintf(stdout, "\nTRAP: Illegal instruction executed\n"); Stop(InstructionAddress); break; case TRAP_MEMORY: fprintf(stdout, "\nTRAP: Memory protection violation\n"); Stop(InstructionAddress); break; default: fprintf(stdout, "\nTRAP: Unknown exception\n"); Stop(InstructionAddress); break; } if(GetFrame()%1000==0) RaiseIRQ(); if(StateLog) SnapshotState(StateLog); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -