/* VirtualNascom, a Nascom II emulator. Copyright (C) 2000 Tomuxmy Thorn Copyright (C) 1995,1998 Frank D. Cringle. Added bit to open doug.z80 from assembler directory . doug rice NasEmu 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 #include #include #include #include #include #include #include #include #include #include #include "simz80.h" #include "xvirtualnascom.h" #define VERSION "1.0" #define YAZEVERSION "1.10" /* macro for file header */ #define _Z80HEADER ( const char * ) "Z80ASM\032\n" /* Z80 registers */ WORD af[2]; /* accumulator and flags (2 banks) */ int af_sel; /* bank select for af */ struct ddregs regs[2]; /* bc,de,hl */ int regs_sel; /* bank select for ddregs */ WORD ir; /* other Z80 registers */ WORD ix; WORD iy; WORD sp; WORD pc; WORD IFF; BYTE ram[MEMSIZE*1024]; /* Z80 memory space */ #ifdef MMU BYTE *pagetable[MEMSIZE/4]; /* MMU page table */ #endif #ifndef LIBDIR #define LIBDIR "/usr/local/lib/" #endif static char *monitor = "nassys3.nal"; static char *progname; int vflag = 0; static void usage(void) { fprintf(stderr, "Usage: %s {flags} {commands}\n" " -m use as monitor (default is nasysy3.nal)\n" " -v verbose\n" ,progname); exit (1); } /* * original routine void load_nascom(char *file) { FILE *f = fopen(file, "r"); int a, b1, b2, b3, b4, b5, b6, b7, b8; int count = 0; int ch; if (!f) { perror(file); exit(1); } if (vflag) printf("Loading %s", file); for (;!feof(f);) { if (fscanf(f, "%x %x %x %x %x %x %x %x %x", &a, &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8) == 9) { RAM(a) = b1; RAM(a+1) = b2; RAM(a+2) = b3; RAM(a+3) = b4; RAM(a+4) = b5; RAM(a+5) = b6; RAM(a+6) = b7; RAM(a+7) = b8; count += 8; } do ch = fgetc(f); while (ch != -1 && ch != '\n'); if (ch == -1) break; } fclose(f); if (vflag) printf(". Successfully loaded %d bytes\n", count); } */ /* * ================================================================== * Try and add ability to read .z80 files. */ /* reads header of a file and tests if it's Z80 ASM file, reads address */ /* return value: 0=OK, 1=this is not a z80 asm file */ int read_header(FILE *stream,unsigned short *address, int *len) { unsigned char tmp[9]; unsigned char c[2]; unsigned a,b; int ret=0; b=strlen(_Z80HEADER); tmp[b]=0; a=0; if ((fread(tmp,1,b,stream))!=b) ret=1; else if (strcmp(tmp,_Z80HEADER)) ret=1; else if (fread(c,1,2,stream)!=2) ret=1; else { *address=(c[1]<<8)|c[0]; a=b+2; } fseek(stream,0,SEEK_END); b=ftell(stream); fseek(stream,a,SEEK_SET); *len=b-a; return ret; } unsigned dma_write(unsigned short offset, unsigned count, FILE *from) { /* return fread(memory+offset,1,count+offset<65536U?count:65536U-offset,from); */ return fread(ram+offset,1,count+offset<65536U?count:65536U-offset,from); } unsigned dma_read(unsigned short offset, unsigned count, FILE *to) { /* return fwrite(memory+offset,1,count+offset<65536U?count:65536U-offset,to); */ return fwrite(ram+offset,1,count+offset<65536U?count:65536U-offset,to); } int load_nascom_new(char *file) { unsigned short start; int x ; /* length */ printf("load_nascom_new(char *file)"); FILE *stream = fopen( file,"rb"); if (!stream) { stream=0; /* error_msg(file,"Can't read file"); */ printf("error load_nascom_new(char *file)"); return 0; } if (read_header(stream,&start,&x)) { fclose(stream); printf("error read hearer load_nascom_new(char *file)"); return 0; /* error */ } else { dma_write(start,x,stream); fclose(stream); stream=0; } return 1 ; } /* * * :0E 1000 00 210C10E5CD5F10F1210100C96865 DB :0E 100E 00 6C6C6F20646F75670A00DDE5DD21 F4 :07 101C 00 0000DD39DDE1C9 30 :0E102300DDE5DD210000DD39DD7E04F533CD95 :0E103100181033DDE1C9DDE5DD210000DD39F9 :0E103F00DD6E06DD6607E5DD6E04DD6605E5A7 :0E104D00210000E5212310E5CDE611F1F1F1BF :0D105B00F1DDE1C9DDE5DD210000DD392119 :0E1068000400392323E5DD6E04DD6605E52175 :0E1076000000E5212310E5CDE611F1F1F1F1C6 * * */ int load_nascom_ihx(char *file) { unsigned short start; int x ; /* length */ uint hex_read, hex_len, hex_addr, hex_cmd ; uint hex_count, hex_data, hex_check ; FILE *stream = fopen( file,"rb"); printf("load_nascom_ihx(char *file)"); if (!stream) { stream=0; /* error_msg(file,"Can't read file"); */ printf("error load_nascom_ihx(char *file)"); return 0; } while ( !feof( stream ) ) { /*:0E 100E 00 6C6C6F20646F75670A00DDE5DD21 F4 */ hex_read = fscanf(stream,":%2x%4x%2x",&hex_len,&hex_addr,&hex_cmd); if (hex_read ){ printf( "\n%x %2d, %2d, %x : ", hex_read, hex_len, hex_addr, hex_cmd ); for( hex_count= 0 ; hex_count < hex_len ; hex_count++ ){ hex_read = fscanf(stream, "%2x",&hex_data ); printf(" %02X", hex_data ); RAM( hex_addr ) = hex_data ; hex_addr ++; } hex_read = fscanf(stream, "%2x\n",&hex_check); } } fclose(stream); stream=0; printf(" exit from load_nascom_ihx()\n"); /* hex_read = getchar() ; */ return 1 ; } /* * ==================================================== */ void load_nascom(char *file) { FILE *f ; if ( ! load_nascom_new( file) ) { f = fopen(file, "r"); int a, b1, b2, b3, b4, b5, b6, b7, b8; int count = 0; int ch; if (!f) { perror(file); exit(1); } if (vflag) printf("Loading %s", file); for (;!feof(f);) { if (fscanf(f, "%x %x %x %x %x %x %x %x %x", &a, &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8) == 9) { RAM(a) = b1; RAM(a+1) = b2; RAM(a+2) = b3; RAM(a+3) = b4; RAM(a+4) = b5; RAM(a+5) = b6; RAM(a+6) = b7; RAM(a+7) = b8; count += 8; } do ch = fgetc(f); while (ch != -1 && ch != '\n'); if (ch == -1) break; } fclose(f); if (vflag) printf(". Successfully loaded %d bytes\n", count); } } extern char *optarg; extern int optind, opterr, optopt; int getopt(int argc, char * const *argv, const char *optstring); int main(int argc, char **argv) { int c; progname = argv[0]; xsetup(1, argv); #ifdef MMU for (c=0; ctype ); */ XSetInputFocus(dpy, win, RevertToParent, CurrentTime); /* end - added by DHR */ if (!isMapped) return; /* * Redraw the array */ if (ev && ev->xexpose.count == 0) { XEvent event; /* Skip all excess redraws */ while (XCheckTypedEvent(dpy, Expose, &event)) ; } /* The Nascom screen memory has the top line be line 15 with line 0-14 just following it. Yes, stupid indeed */ for (x = 0; x < 48; ++x) xputch(x, 0, RAM(0x80a+64*15+x)); for (y = 0; y < 15; ++y) for (x = 0; x < 48; ++x) xputch(x, y+1, RAM(0x80a+y*64+x)); XFlush(dpy); } void RecordMapStatus(Widget w, caddr_t data, XEvent *ev) { printf("RecordMapStatus(\n"); if (ev->type == MapNotify) { #ifdef WINDOWDEBUG (void) printf("window mapped\n"); #endif isMapped = TRUE; } else if (ev->type == ConfigureNotify) { #ifdef WINDOWDEBUG (void) printf("window resized\n"); #endif } } void xputch(int x, int y, unsigned char v) { /* FIXME: Are Nascom characters really 16 pixels high? */ XPutImage(dpy, win, gc, chars_bitmap, 0, v*16, x*8, y*16, 8, 16); /* XFlush(dpy); An unsuccessful attempt to improve some games */ } void xhandleevent() { XEvent ev; /* fprintf(stderr,"HALT\n\r"); fprintf(stderr,"PC SP IR IX IY AF BC DE HL AF' BC' DE' HL'\n\r"); fprintf(stderr,"%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n\r",pc,sp,ir,ix,iy,af[af_sel],regs[regs_sel].bc,regs[regs_sel].de,regs[regs_sel].hl,af[1-af_sel],regs[1-regs_sel].bc,regs[1-regs_sel].de,regs[1-regs_sel].hl); */ /* if (XtPending()) {*/ while (XtPending()) { XtNextEvent(&ev); printf("event: %X \n",(unsigned int) ev.xany.type ); /* added by DHR */ /* XSetInputFocus(dpy, win, RevertToParent, CurrentTime); */ XtDispatchEvent(&ev); } }