/* * Z80SIM - a Z80-CPU simulator * * Copyright (C) 1987-2006 by Udo Munk * * History: * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 * 11-JAN-89 Release 1.1 * 08-FEB-89 Release 1.2 * 13-MAR-89 Release 1.3 * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 * and some optimization * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0 * 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's */ /* * This modul contain the 'main()' function of the simulator, * where the options are checked and variables are initialized. * After initialization of the UNIX interrupts ( int_on() ) * and initialization of the I/O simulation ( init_io() ) * the user interface ( mon() ) is called. */ #include #include #include #include #include #include #include "sim.h" #include "simglb.h" static void save_core(void), load_core(void); extern void int_on(void), int_off(void), mon(void); extern void init_io(void), exit_io(void); extern int exatoi(char *); int main(int argc, char *argv[]) { register char *s, *p; register char *pn = argv[0]; while (--argc > 0 && (*++argv)[0] == '-') for (s = argv[0] + 1; *s != '\0'; s++) switch (*s) { case 's': /* save core and CPU on exit */ s_flag = 1; break; case 'l': /* load core and CPU from file */ l_flag = 1; break; case 'h': /* execute HALT opcode */ break_flag = 0; break; case 'i': /* trap I/O on unused ports */ i_flag = 1; break; case 'm': /* initialize Z80 memory */ m_flag = exatoi(s+1); s += strlen(s+1); break; case 'f': f_flag = atoi(s+1); s += strlen(s+1); freq = (float) 1 / (float) f_flag; break; case 'x': /* get filename with Z80 executable */ x_flag = 1; s++; p = xfn; while (*s) *p++ = *s++; *p = '\0'; s--; break; case '?': goto usage; default: printf("illegal option %c\n", *s); usage: printf("usage:\t%s -s -l -i -h -mn -fn -xfilename\n", pn); puts("\ts = save core and cpu"); puts("\tl = load core and cpu"); puts("\ti = trap on I/O to unused ports"); puts("\th = execute HALT op-code"); puts("\tm = init memory with n"); puts("\tf = CPU frequenzy n in MHz (not implemented yet)"); puts("\tx = load and execute filename"); exit(1); } putchar('\n'); puts("####### ##### ### ##### ### # #"); puts(" # # # # # # # # ## ##"); puts(" # # # # # # # # # # #"); puts(" # ##### # # ##### ##### # # # #"); puts(" # # # # # # # # #"); puts(" # # # # # # # # # #"); puts("####### ##### ### ##### ### # #"); printf("\nRelease %s, %s\n", RELEASE, COPYR); #ifdef USR_COM printf("%s Release %s, %s\n", USR_COM, USR_REL, USR_CPR); #endif putchar('\n'); fflush(stdout); wrk_ram = PC = STACK = ram; memset((char *) ram, m_flag, 32768); memset((char *) ram + 32768, m_flag, 32768); if (l_flag) load_core(); int_on(); init_io(); mon(); if (s_flag) save_core(); exit_io(); int_off(); return(0); } /* * This function saves the CPU and the memory into the file core.z80 * */ static void save_core(void) { int fd; if ((fd = open("core.z80", O_WRONLY | O_CREAT, 0600)) == -1) { puts("can't open file core.z80"); return; } write(fd, (char *) &A, sizeof(A)); write(fd, (char *) &F, sizeof(F)); write(fd, (char *) &B, sizeof(B)); write(fd, (char *) &C, sizeof(C)); write(fd, (char *) &D, sizeof(D)); write(fd, (char *) &E, sizeof(E)); write(fd, (char *) &H, sizeof(H)); write(fd, (char *) &L, sizeof(L)); write(fd, (char *) &A_, sizeof(A_)); write(fd, (char *) &F_, sizeof(F_)); write(fd, (char *) &B_, sizeof(B_)); write(fd, (char *) &C_, sizeof(C_)); write(fd, (char *) &D_, sizeof(D_)); write(fd, (char *) &E_, sizeof(E_)); write(fd, (char *) &H_, sizeof(H_)); write(fd, (char *) &L_, sizeof(L_)); write(fd, (char *) &I, sizeof(I)); write(fd, (char *) &IFF, sizeof(IFF)); write(fd, (char *) &R, sizeof(R)); write(fd, (char *) &PC, sizeof(PC)); write(fd, (char *) &STACK, sizeof(STACK)); write(fd, (char *) &IX, sizeof(IX)); write(fd, (char *) &IY, sizeof(IY)); write(fd, (char *) ram, 32768); write(fd, (char *) ram + 32768, 32768); close(fd); } /* * This function loads the CPU and memory from the file core.z80 * */ static void load_core(void) { int fd; if ((fd = open("core.z80", O_RDONLY)) == -1) { puts("can't open file core.z80"); return; } read(fd, (char *) &A, sizeof(A)); read(fd, (char *) &F, sizeof(F)); read(fd, (char *) &B, sizeof(B)); read(fd, (char *) &C, sizeof(C)); read(fd, (char *) &D, sizeof(D)); read(fd, (char *) &E, sizeof(E)); read(fd, (char *) &H, sizeof(H)); read(fd, (char *) &L, sizeof(L)); read(fd, (char *) &A_, sizeof(A_)); read(fd, (char *) &F_, sizeof(F_)); read(fd, (char *) &B_, sizeof(B_)); read(fd, (char *) &C_, sizeof(C_)); read(fd, (char *) &D_, sizeof(D_)); read(fd, (char *) &E_, sizeof(E_)); read(fd, (char *) &H_, sizeof(H_)); read(fd, (char *) &L_, sizeof(L_)); read(fd, (char *) &I, sizeof(I)); read(fd, (char *) &IFF, sizeof(IFF)); read(fd, (char *) &R, sizeof(R)); read(fd, (char *) &PC, sizeof(PC)); read(fd, (char *) &STACK, sizeof(STACK)); read(fd, (char *) &IX, sizeof(IX)); read(fd, (char *) &IY, sizeof(IY)); read(fd, (char *) ram, 32768); read(fd, (char *) ram + 32768, 32768); close(fd); }