spectemu-0.94/0042755000175000017500000000000007432615600013546 5ustar cjwatsoncjwatsonspectemu-0.94/akey.h0100644000175000017500000000622306505020712014640 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* akey.h * * Header of the AKEY module * * Keyboard handeling routines and key identification labels * * Created: 92/12/01 Szeredi Miklos */ #ifndef _AKEY_H #define _AKEY_H #define NOKEY -1 #define UNKNOWNKEY -2 #define ERRKEY -3 #define MOUSEKEY -256 #define UPKEY (256 + 1) #define DOWNKEY (256 + 2) #define RIGHTKEY (256 + 3) #define LEFTKEY (256 + 4) #define INSKEY (256 + 5) #define DELKEY (256 + 6) #define HOMEKEY (256 + 7) #define ENDKEY (256 + 8) #define PUKEY (256 + 9) #define PDKEY (256 + 10) #define BSKEY (256 + 16) #define FKEYOFFS (256 + 128) #define FKEYFIRST (FKEYOFFS + 1) #define FKEYLAST (FKEYOFFS + 12) #define FKEY(num) (FKEYOFFS + num) #define ALTKEY (1 << 11) #define CTRKEY (1 << 10) #define SHKEY (1 << 9) #define BKTABKEY (TABKEY | SHKEY) #define CTL(ch) ((ch) - 96) #define META(ch) ((ch) | ALTKEY) #define TABKEY 9 #define LFKEY 13 #define CRKEY 10 #define ENTERKEY LFKEY #define ESCKEY 27 #define lastakey() __lastakey #define waitakey() ((void)readakey()) #define setakey(key) ((void)(__lastakey = (key))) #define setakeydo(todo) (__atodo = (todo)) typedef int keytype; typedef void (*__atodotype)(void); #ifdef __cplusplus extern "C" { #endif extern __atodotype __atodo; extern keytype __lastakey; extern keytype getakey(void); /* extern void setakey(keytype); */ /* MACRO */ extern keytype readakey(void); /* extern keytype lastakey(void); */ /* MACRO */ /* extern void waitakey(void); */ /* MACRO */ extern int pressedakey(void); extern void clearakeybuff(void); /* extern void setakeydo(dofn __atodotype); */ /* MACRO */ extern void ungetakey(void); extern int insertakey(keytype key); extern void setasmalldelay(int delay); extern int initakey(void); extern void closeakey(void); #ifdef __cplusplus } #endif #endif /* _AKEY_H */ /* End of akey.h */ spectemu-0.94/ax.c0100644000175000017500000005161706516127134014331 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * * ax.c * * * * Created: 94/11/11 Szeredi Miklos * * Version: 0.1 94/11/11 * 0.2 95/06/12 * */ /* #define DEBUG_EVENTS */ #include "ax.h" #include #include #include #include #include #include #include #include #include #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef int boolean; #define max(x, y) ((x) < (y) ? (y) : (x)) #define min(x, y) ((x) < (y) ? (x) : (y)) #define minmax(a, l, u) ((a) < (l) ? (l) : ((a) > (u) ? (u) : (a))) #define MAX_PROG_NAME_LEN 128 #define MAX_CLASS_NAME_LEN MAX_PROG_NAME_LEN #define MAX_PRES_LEN 256 #define MAX_FILENAME_LEN 1024 static const char *empty_str = ""; typedef void (*eventproc_t)(XEvent *, void *); typedef struct _event_proc_struct { eventproc_t event_proc; unsigned long event_mask; Display *disp; void *ptr; Window event_win; boolean done_proc; struct _event_proc_struct *next_proc; } event_proc_struct; typedef struct { const char *event_name; boolean win_given; event_proc_struct *next_proc; } event_struct; typedef struct _disp_struct{ Display *disp; XFontStruct *font; struct _disp_struct *next_disp; } disp_struct; #define EVENT_NUM LASTEvent static event_struct event_info[EVENT_NUM]; static disp_struct disp_start = {NULL, NULL, NULL}; static boolean disp_chain_modified; static char prog_name[MAX_PROG_NAME_LEN + 1]; static char class_name[MAX_CLASS_NAME_LEN + 1]; static XrmDatabase rDB = NULL; /* Has to be global otherwise Xlib hangs */ static int opTableEntries = 19; static aX_options opTable[] = { {"-display", ".display", XrmoptionSepArg, NULL}, {"-geometry", ".geometry", XrmoptionSepArg, NULL}, {"-bg", ".background", XrmoptionSepArg, NULL}, {"-background", ".background", XrmoptionSepArg, NULL}, {"-bd", ".borderColor", XrmoptionSepArg, NULL}, {"-bordercolor", ".borderColor", XrmoptionSepArg, NULL}, {"-bw", ".borderWidth", XrmoptionSepArg, NULL}, {"-borderwidth", ".borderWidth", XrmoptionSepArg, NULL}, {"-fg", ".foreground", XrmoptionSepArg, NULL}, {"-foreground", ".foreground", XrmoptionSepArg, NULL}, {"-fn", ".font", XrmoptionSepArg, NULL}, {"-font", ".font", XrmoptionSepArg, NULL}, {"-name", ".name", XrmoptionSepArg, NULL}, {"-rv", ".reverseVideo", XrmoptionNoArg, "on"}, {"-reverse", ".reverseVideo", XrmoptionNoArg, "on"}, {"+rv", ".reverseVideo", XrmoptionNoArg, "off"}, {"-bg", ".background", XrmoptionSepArg, NULL}, {"-title", ".title", XrmoptionSepArg, NULL}, {"-xrm", NULL, XrmoptionResArg, NULL} }; static char *addstr(const char str1[], const char str2[], char str12[], unsigned int str12len) { unsigned int i, j, k; str12[str12len-1] = '\0'; for(i=0, j=0, k=0; i + 1 < str12len; ) { if(str1[j]) str12[i] = str1[j++]; else str12[i] = str2[k++]; if(! str12[i++]) break; } return str12; } static char *pname(const char *resource) { static char pnameres[MAX_PRES_LEN]; return addstr(prog_name, resource, pnameres, MAX_PRES_LEN); } static char *pclass(const char *resource) { static char pclassres[MAX_PRES_LEN]; return addstr(class_name, resource, pclassres, MAX_PRES_LEN); } static void fill_event_info(void) { int i; for(i = 0; i < EVENT_NUM; i++) { event_info[i].event_name = empty_str; event_info[i].win_given = TRUE; event_info[i].next_proc = NULL; } event_info[MappingNotify].win_given = FALSE; event_info[ButtonPress].event_name = "ButtonPress"; event_info[ButtonRelease].event_name = "ButtonRelease"; event_info[CirculateNotify].event_name = "CirculateNotify"; event_info[CirculateRequest].event_name = "CirculateRequest"; event_info[ClientMessage].event_name = "ClientMessage"; event_info[ColormapNotify].event_name = "ColormapNotify"; event_info[ConfigureNotify].event_name = "ConfigureNotify"; event_info[ConfigureRequest].event_name = "ConfigureRequest"; event_info[CreateNotify].event_name = "CreateNotify"; event_info[DestroyNotify].event_name = "DestroyNotify"; event_info[EnterNotify].event_name = "EnterNotify"; event_info[LeaveNotify].event_name = "LeaveNotify"; event_info[Expose].event_name = "Expose"; event_info[FocusIn].event_name = "FocusIn"; event_info[FocusOut].event_name = "FocusOut"; event_info[GraphicsExpose].event_name = "GraphicsExpose"; event_info[NoExpose].event_name = "NoExpose"; event_info[GravityNotify].event_name = "GravityNotify"; event_info[KeymapNotify].event_name = "KeymapNotify"; event_info[KeyPress].event_name = "KeyPress"; event_info[KeyRelease].event_name = "KeyRelease"; event_info[MapNotify].event_name = "MapNotify"; event_info[UnmapNotify].event_name = "UnmapNotify"; event_info[MappingNotify].event_name = "MappingNotify"; event_info[MapRequest].event_name = "MapRequest"; event_info[MotionNotify].event_name = "MotionNotify"; event_info[PropertyNotify].event_name = "PropertyNotify"; event_info[ReparentNotify].event_name = "ReparentNotify"; event_info[ResizeRequest].event_name = "ResizeRequest"; event_info[SelectionClear].event_name = "SelectionClear"; event_info[SelectionNotify].event_name = "SelectionNotify"; event_info[SelectionRequest].event_name = "SelectionRequest"; event_info[VisibilityNotify].event_name = "VisibilityNotify"; } static void get_def_res(aX_default_resources *defres) { XrmValue value; char *str_type; int flags; XColor color_def; unsigned long tmp_pixel; Colormap def_map; int font_spec; defres->window_name = prog_name; defres->icon_name = prog_name; defres->scr = DefaultScreen(defres->disp); defres->scr_ptr = ScreenOfDisplay(defres->disp, defres->scr); def_map = DefaultColormapOfScreen(defres->scr_ptr); if(XrmGetResource(rDB, pname(".title"), pclass(".Title"), &str_type, &value)) defres->window_name = (char *) value.addr; defres->sflags = PSize; if(XrmGetResource(rDB, pname(".geometry"), pclass(".Geometry"), &str_type, &value)) { flags = XParseGeometry((char *) value.addr, &(defres->x), &(defres->y), &(defres->width), &(defres->height)); if((XValue | YValue) & flags) defres->sflags |= USPosition; if((WidthValue | HeightValue) & flags) defres->sflags = (defres->sflags & ~PSize) | USSize; } defres->background = defres->background ? WhitePixel(defres->disp, defres->scr) : BlackPixel(defres->disp, defres->scr); if(XrmGetResource(rDB, pname(".background"), pclass(".Background"), &str_type, &value)) { if(XParseColor(defres->disp, def_map, value.addr, &color_def)) { if(XAllocColor(defres->disp, def_map, &color_def)) defres->background = color_def.pixel; } else fprintf(stderr, "%s: aX: warning: Invalid color specification %s\n", prog_name, value.addr); } defres->foreground = defres->foreground ? WhitePixel(defres->disp, defres->scr) : BlackPixel(defres->disp, defres->scr); if(XrmGetResource(rDB, pname(".foreground"), pclass(".Foreground"), &str_type, &value)) { if(XParseColor(defres->disp, def_map, value.addr, &color_def)) { if(XAllocColor(defres->disp, def_map, &color_def)) defres->foreground = color_def.pixel; } else fprintf(stderr, "%s: aX: warning: Invalid color specification %s\n", prog_name, value.addr); } if(XrmGetResource(rDB, pname(".borderWidth"), pclass(".BorderWidth"), &str_type, &value)) { defres->border_width = atoi(value.addr); } defres->border_color = defres->foreground; if(XrmGetResource(rDB, pname(".borderColor"), pclass(".BorderColor"), &str_type, &value)) { if(XParseColor(defres->disp, def_map, value.addr, &color_def)) { if(XAllocColor(defres->disp, def_map, &color_def)) defres->border_color = color_def.pixel; } else fprintf(stderr, "%s: aX: warning: Invalid color specification %s\n", prog_name, value.addr); } font_spec = 0; if(XrmGetResource(rDB, pname(".font"), pclass(".Font"), &str_type, &value)) { defres->font_name = value.addr; if(defres->font_name != NULL) font_spec = 1; } if(XrmGetResource(rDB, pname(".fallbackFont"), pclass(".Font"), &str_type, &value)) defres->fallback_font_name = value.addr; if(defres->font_name == NULL || (defres->font = XLoadQueryFont(defres->disp, defres->font_name)) == NULL) { if(font_spec) fprintf(stderr, "%s: aX: warning: cannot open %s font, ", prog_name, defres->font_name); defres->font_name = defres->fallback_font_name; if(font_spec && defres->font_name != NULL) fprintf(stderr, "trying %s...\n",defres->font_name); if(defres->font_name == NULL || (defres->font = XLoadQueryFont(defres->disp, defres->fallback_font_name)) == NULL) { if(defres->font_name != NULL) { fprintf(stderr, "%s: aX: warning: cannot open %s font, ", prog_name, defres->font_name); } defres->font_name = "fixed"; fprintf(stderr, "trying %s...\n",defres->font_name); if((defres->font = XLoadQueryFont(defres->disp, defres->font_name)) == NULL) { fprintf(stderr, "%s: aX: warning: cannot open %s font\n", prog_name, defres->font_name); exit(-1); } } else defres->font_name = defres->fallback_font_name; } if(XrmGetResource(rDB, pname(".reverseVideo"), pclass(".ReverseVideo"), &str_type, &value)) if(strcmp(value.addr, "on") == 0) { tmp_pixel = defres->foreground; defres->foreground = defres->background; defres->background = tmp_pixel; } } static void add_disp(aX_default_resources *defres) { disp_struct *last; for(last = &disp_start; last->next_disp != NULL; last = last->next_disp); if((last->next_disp = malloc(sizeof(disp_struct))) == NULL) { fprintf(stderr, "%s: aX: Not enough memory.\n", prog_name); exit(-1); }; last = last->next_disp; last->disp = defres->disp; last->font = defres->font; last->next_disp = NULL; disp_chain_modified = TRUE; } void aX_open_disp(aX_options *useropt, int useroptlen, int *argcp, char *argv[], aX_default_resources *defres) { XrmValue value; char *str_type; char *disp_res; char *environment; char *display_name = NULL; char filename[MAX_FILENAME_LEN]; int i; XrmDatabase commandlineDB = NULL, usercommandlineDB = NULL; XrmDatabase homeDB, serverDB, applicationDB; /* if(disp_start.next_disp != NULL) { fprintf(stderr, "aX_open_disp: Cannot open first display twice.\n"); exit(-1); } */ XrmInitialize(); class_name[0] = '\0'; class_name[MAX_CLASS_NAME_LEN] = '\0'; if(defres->class_name != NULL) strncpy(class_name, defres->class_name, MAX_CLASS_NAME_LEN); fill_event_info(); for(i = 1; i < *argcp; i++) if(strcmp(argv[i], "-name") == 0 && ++i < *argcp){ defres->prog_name = argv[i]; break; } prog_name[0] = '\0'; prog_name[MAX_PROG_NAME_LEN] = '\0'; if(defres->prog_name != NULL) strncpy(prog_name, defres->prog_name, MAX_PROG_NAME_LEN); else strncpy(prog_name, argv[0], MAX_PROG_NAME_LEN); defres->prog_name = prog_name; XrmParseCommand(&commandlineDB, (XrmOptionDescRec *) opTable, opTableEntries, prog_name, argcp, argv); if(useropt != NULL) XrmParseCommand(&usercommandlineDB, (XrmOptionDescRec *) useropt, useroptlen, prog_name, argcp, argv); else usercommandlineDB = NULL; /* if(*argcp != 1) { fprintf(stderr, "%s: aX_open_disp: Unrecognised options in command line!\n", prog_name); exit(-1); } */ if(XrmGetResource(commandlineDB, pname(".display"), pclass(".Display"), &str_type, &value)) display_name = (char *) value.addr; if((defres->disp = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "%s: aX_open_disp: cannot connect to X server %s\n", prog_name, XDisplayName(display_name)); exit(-1); } applicationDB = XrmGetFileDatabase( addstr("/usr/lib/X11/app-defaults/", class_name, filename, MAX_FILENAME_LEN)); /* if(defres->disp->xdefaults) serverDB = XrmGetStringDatabase(defres->disp->xdefaults); else serverDB = NULL; */ disp_res = XResourceManagerString(defres->disp); if(disp_res) serverDB = XrmGetStringDatabase(disp_res); else serverDB = NULL; if((environment = getenv("XENVIRONMENT")) != NULL) homeDB = XrmGetFileDatabase(environment); else homeDB = NULL; XrmMergeDatabases(applicationDB, &rDB); XrmMergeDatabases(serverDB, &rDB); XrmMergeDatabases(homeDB, &rDB); XrmMergeDatabases(commandlineDB, &rDB); XrmMergeDatabases(usercommandlineDB, &rDB); get_def_res(defres); add_disp(defres); } void aX_open_second_disp(char *display_name, aX_default_resources *defres) { char *disp_res; XrmDatabase serverDB; if((defres->disp = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "%s: aX_open_second_disp: cannot connect to X server %s\n", prog_name, XDisplayName(display_name)); exit(-1); } disp_res = XResourceManagerString(defres->disp); if(disp_res) serverDB = XrmGetStringDatabase(disp_res); else serverDB = NULL; XrmMergeDatabases(serverDB, &rDB); get_def_res(defres); add_disp(defres); } /* void smallwait(boolean event_prev) { event_prev = event_prev; sleep(1); } */ static void sigalrm_handler(int i) { i = i; signal(SIGALRM, SIG_IGN); } static void smallwait(boolean event_prev) { struct itimerval value; signal(SIGALRM, sigalrm_handler); event_prev = event_prev; value.it_interval.tv_sec = 0L; value.it_interval.tv_usec = 0L; value.it_value.tv_sec = 0L; value.it_value.tv_usec = 100000L; setitimer(ITIMER_REAL, &value, NULL); pause(); } /* This aX_wait_all_muck needs to be cleared out! */ void aX_wait_event(int eventtype) { XEvent ev; event_proc_struct **curr; int i; disp_struct *dsp, *dsp1; boolean event_prev; start:; if(disp_start.next_disp == NULL) { fprintf(stderr, "%s: aX_wait_event: No connection to any display\n", prog_name); exit(-1); } dsp = disp_start.next_disp; do { event_prev = TRUE; dsp1 = dsp; if((disp_start.next_disp)->next_disp != NULL || eventtype == AX_LOOK_EVENTS) while(XPending(dsp->disp) == 0) { dsp = dsp->next_disp; if(dsp == NULL) dsp = disp_start.next_disp; if(dsp == dsp1) { if(eventtype == AX_LOOK_EVENTS) return; smallwait(event_prev); event_prev = FALSE; dsp = dsp1 = disp_start.next_disp; } } XNextEvent(dsp->disp, &ev); #ifdef DEBUG_EVENTS fprintf(stderr,"Event: %s (%i) in win: %li)\n", event_info[ev.type].event_name, ev.type, ev.xany.window); #endif if(dsp->disp != ev.xany.display) fprintf(stderr, "Ha! Event read from wrong display! Stupid XLib!!!\n"); curr = &(event_info[ev.type].next_proc); i = 0; while(*curr != NULL) { if((*curr)->disp == dsp->disp && (!event_info[ev.type].win_given || ev.xany.window == (*curr)->event_win) && !(*curr)->done_proc) { i++; (*curr)->done_proc = TRUE; disp_chain_modified = FALSE; if((*curr)->event_proc != NULL) { (*((*curr)->event_proc))(&ev, (*curr)->ptr); } if(disp_chain_modified) goto start; curr = &(event_info[ev.type].next_proc); } else curr = &((*curr)->next_proc); } curr = &(event_info[ev.type].next_proc); while(*curr != NULL) { (*curr)->done_proc = FALSE; curr = &((*curr)->next_proc); } if(i == 0) fprintf(stderr, "%s: aX_wait_event: warning: " "Unexpected event: %s (%i) in win: %li)\n", prog_name, event_info[ev.type].event_name, ev.type, ev.xany.window); } while(eventtype != ev.type && eventtype != AX_ANY_EVENT); } void aX_look_events(void) { aX_wait_event(AX_LOOK_EVENTS); } char *aX_get_prog_res(const char *resname, const char* resclass) { XrmValue value; char *str_type; if(XrmGetResource(rDB, pname(resname), pclass(resclass), &str_type, &value)) return (char *)value.addr; else return NULL; } char *aX_get_resource(const char *resname, const char* resclass) { XrmValue value; char *str_type; if(XrmGetResource(rDB, resname, resclass, &str_type, &value)) return (char *)value.addr; else return NULL; } static long get_win_mask(Display *disp, Window win) { int evt; event_proc_struct *ep; long winmask; for(evt = 0, winmask = 0; evt < EVENT_NUM; evt++) { ep = event_info[evt].next_proc; while(ep != NULL) { if(ep->event_win == win && ep->disp == disp) winmask |= ep->event_mask; ep = ep->next_proc; } } return winmask; } void aX_add_event_proc(Display *disp, Window win, int eventtype, void (*eventproc)(XEvent *, void *), unsigned long eventmask, void *ptr) { event_proc_struct **epp; long winmask; epp = &(event_info[eventtype].next_proc); while(*epp != NULL) epp = &((*epp)->next_proc); if((*epp = (event_proc_struct *) malloc((size_t) sizeof(event_proc_struct))) == NULL) { fprintf(stderr, "%s: aX_add_event_proc_disp: Not enough memory.\n", prog_name); exit(-1); } (*epp)->event_proc = eventproc; (*epp)->ptr = ptr; (*epp)->event_mask = eventmask; (*epp)->disp = disp; (*epp)->event_win = win; (*epp)->done_proc = FALSE; (*epp)->next_proc = NULL; if(win) { winmask = get_win_mask(disp, win); XSelectInput(disp, win, winmask); } } void aX_remove_event_proc(Display *disp, Window win, int eventtype, void (*eventproc)(XEvent *, void *)) { event_proc_struct **epp; event_proc_struct *tmp; long winmask; epp = &(event_info[eventtype].next_proc); while(*epp != NULL) { if((*epp)->disp == disp && (*epp)->event_win == win && (*epp)->event_proc == eventproc) { tmp = (*epp)->next_proc; free(*epp); *epp = tmp; if(win) { winmask = get_win_mask(disp, win); XSelectInput(disp, win, winmask); } return; } else epp = &((*epp)->next_proc); } fprintf(stderr, "%s: aX_remove_event_proc_disp: warning: " "Could not remove event proc (event: %s (%i), window: %lX)\n", prog_name, event_info[eventtype].event_name, eventtype, win); } void aX_close_one_disp(Display *disp) { /* int evt; event_proc_struct **curr; */ disp_struct *dsp, *dsp_tmp; /* for(evt = 0; evt < EVENT_NUM; evt++) { curr = &(event_info[evt].next_proc); while(*curr != NULL) { if(disp == (*curr)->disp) { aX_remove_event_proc_disp((*curr)->disp, (*curr)->event_win, evt, (*curr)->event_proc); curr = &(event_info[evt].next_proc); } else curr = &((*curr)->next_proc); } } */ for(dsp = &disp_start; dsp->next_disp->disp != disp; dsp = dsp->next_disp) if(dsp->next_disp == NULL) { fprintf(stderr, "%s: aX_close_one_disp: warning: Trying to close unopened display.\n", prog_name); return; } XUnloadFont(dsp->next_disp->disp, dsp->next_disp->font->fid); XCloseDisplay(dsp->next_disp->disp); dsp_tmp = dsp->next_disp; dsp->next_disp = dsp->next_disp->next_disp; free(dsp_tmp); disp_chain_modified = TRUE; } void aX_close_disp(void) { while(disp_start.next_disp != NULL) aX_close_one_disp(disp_start.next_disp->disp); } unsigned long aX_get_color(Display *disp, int scr, unsigned long def_col, const char *color_name) { XColor color_def; Colormap def_map; Screen *scr_ptr; if(color_name == NULL) return def_col; scr_ptr = ScreenOfDisplay(disp, scr); def_map = DefaultColormapOfScreen(scr_ptr); if(XParseColor(disp, def_map, color_name, &color_def)) { if(XAllocColor(disp, def_map, &color_def)) return color_def.pixel; } else fprintf(stderr, "%s: aX_get_color: warning: Invalid color specification %s\n", prog_name, color_name); return def_col; } spectemu-0.94/ax.h0100644000175000017500000000624106507734301014327 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* ax.h * * Header of the AX module * * * Created: 94/11/11 Szeredi Miklos */ #ifndef _AX_H #define _AX_H #include #include /*typedef XrmOptionDescRec aX_options; */ typedef struct { const char *option; /* Option abbreviation in argv */ const char *specifier; /* Resource specifier */ XrmOptionKind argKind; /* Which style of option it is */ const char *value; /* Value to provide if XrmoptionNoArg */ } aX_options; #define AX_NO_EVENT LASTEvent #define AX_ANY_EVENT 0 #define AX_LOOK_EVENTS -1 typedef struct{ Display *disp; int scr; Screen *scr_ptr; unsigned int width; unsigned int height; int x; int y; unsigned int border_width; unsigned long foreground; unsigned long background; unsigned long border_color; const char *font_name; const char *fallback_font_name; XFontStruct *font; long sflags; const char *prog_name; const char *class_name; char *window_name; char *icon_name; } aX_default_resources; #ifdef __cplusplus extern "C" { #endif extern void aX_open_disp(aX_options *useropt, int useroptlen, int *argcp, char *argv[], aX_default_resources *defres); extern void aX_open_second_disp(char *display_name, aX_default_resources *defres); extern void aX_wait_event(int eventtype); extern void aX_look_events(void); extern char *aX_get_prog_res(const char *resname, const char* resclass); extern char *aX_get_resource(const char *resname, const char* resclass); extern void aX_add_event_proc(Display *disp, Window win, int eventtype, void (*eventproc)(XEvent *, void *), unsigned long eventmask, void *ptr); extern void aX_remove_event_proc(Display *disp, Window win, int eventtype, void (*eventproc)(XEvent *, void *)); extern void aX_close_one_disp(Display *disp); extern void aX_close_disp(void); extern unsigned long aX_get_color(Display *disp, int scr, unsigned long def_col, const char *color_name); #ifdef __cplusplus } #endif #endif /* _AX_H */ /* End of ax.h */ spectemu-0.94/spmain.h0100644000175000017500000000170706521610716015207 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPMAIN_H #define SPMAIN_H extern void check_params(int argc, char *argv[]); extern void start_spectemu(int argc, char *argv[]); #endif /* SPMAIN_H */ spectemu-0.94/snapshot.c0100644000175000017500000003664606526331411015561 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "spperif.h" #include "z80.h" #include "snapshot.h" #include "compr.h" #include "interf.h" #include "misc.h" #include "spconf.h" #include "interf.h" #include #include #include #include #include #include #define COMPRESS_SAVE 1 static char quick_snap_file[MAXFILENAME]; static int qsnap_created = 0; typedef struct { int isfile; FILE *fp; unsigned len; byte *at; } SNFILE; #define sngetc(snfp) ((snfp)->isfile ? getc((snfp)->fp) : snmgetc(snfp)) static int snmgetc(SNFILE *snfp) { if(!snfp->len) return EOF; snfp->len--; return *snfp->at++; } static int snread(void *ptr, int size, SNFILE *snfp) { int i; byte *dest; if(snfp->isfile) return (int) fread(ptr, 1, (size_t) size, snfp->fp); dest = (byte *) ptr; for(i = 0; snfp->len && size; i++, snfp->len--, size--) *dest++ = *snfp->at++; return i; } /* These structures are taken from 'spconv' by Henk de Groot */ struct sna_s { byte i; byte lbk; byte hbk; byte ebk; byte dbk; byte cbk; byte bbk; byte fbk; byte abk; byte l; byte h; byte e; byte d; byte c; byte b; byte iyl; byte iyh; byte ixl; byte ixh; byte iff2; byte r; byte f; byte a; byte spl; byte sph; byte im; byte border; }; #define sna_size 27 /* sizeof(struct sna_s)=27 */ struct z80_1_s { byte a; /*00*/ byte f; /*01*/ byte c; /*02*/ byte b; /*03*/ byte l; /*04*/ byte h; /*05*/ byte pcl; /*06*/ byte pch; /*07*/ byte spl; /*08*/ byte sph; /*09*/ byte i; /*0A*/ byte r; /*0B*/ byte data; /*0C*/ byte e; /*0D*/ byte d; /*0E*/ byte cbk; /*0F*/ byte bbk; /*10*/ byte ebk; /*11*/ byte dbk; /*12*/ byte lbk; /*13*/ byte hbk; /*14*/ byte abk; /*15*/ byte fbk; /*16*/ byte iyl; /*17*/ byte iyh; /*18*/ byte ixl; /*19*/ byte ixh; /*1A*/ byte iff1; /*1B*/ byte iff2; /*1C*/ byte im; /*1D*/ }; #define z80_145_size 0x1e /* length of z80 V1.45 header */ struct z80_2_s { /* Extended 2.01 and 3.0 header, flagged with PC=0 */ byte h2_len_l; /*1E*/ byte h2_len_h; /*1F*/ byte n_pcl; /*20*/ byte n_pch; /*21*/ byte hardware; /*22*/ byte samram; /*23*/ byte if1_paged; /*24*/ byte r_ldir_emu; /*25*/ byte last_out; /*26*/ byte sound_reg[16]; /*27*/ /* Continues with extended 3.0 header, but this part is not used anyway */ }; #define z80_201_ext_size 23 /* length of extended z80 V2.01 header */ #define z80_300_ext_size 54 /* length of extended z80 V3.0 header */ struct z80_page_s { byte blklen_l; /*00*/ byte blklen_h; /*01*/ byte page_num; /*02*/ }; #define z80_pg_size 3 /* sizeof(struct z80_page_s)=3 */ static FILE *savfp; static int memptr; int compr_read_byte(void) { if(memptr < 0x10000) return z80_proc.mem[memptr++]; else return -1; } void compr_put_byte(int i) { putc(i, savfp); } #define STORE_NORMAL_REGS(head) \ head.f = RF; /* F reg */ \ head.a = RA; /* A reg */ \ head.b = RB; /* B reg */ \ head.c = RC; /* C reg */ \ head.d = RD; /* D reg */ \ head.e = RE; /* E reg */ \ head.h = RH; /* H reg */ \ head.l = RL; /* L reg */ \ head.fbk = FBK; /* F' reg */ \ head.abk = ABK; /* A' reg */ \ head.bbk = BBK; /* B' reg */ \ head.cbk = CBK; /* C' reg */ \ head.dbk = DBK; /* D' reg */ \ head.ebk = EBK; /* E' reg */ \ head.hbk = HBK; /* H' reg */ \ head.lbk = LBK; /* L' reg */ \ head.iyh = YH; /* IY reg */ \ head.iyl = YL; \ head.ixh = XH; /* IX reg */ \ head.ixl = XL #define LOAD_NORMAL_REGS(head) \ RF = head.f; /* F reg */ \ RA = head.a; /* A reg */ \ RB = head.b; /* B reg */ \ RC = head.c; /* C reg */ \ RD = head.d; /* D reg */ \ RE = head.e; /* E reg */ \ RH = head.h; /* H reg */ \ RL = head.l; /* L reg */ \ FBK = head.fbk; /* F' reg */ \ ABK = head.abk; /* A' reg */ \ BBK = head.bbk; /* B' reg */ \ CBK = head.cbk; /* C' reg */ \ DBK = head.dbk; /* D' reg */ \ EBK = head.ebk; /* E' reg */ \ HBK = head.hbk; /* H' reg */ \ LBK = head.lbk; /* L' reg */ \ YH = head.iyh; /* IY reg */ \ YL = head.iyl; \ XH = head.ixh; /* IX reg */ \ XL = head.ixl static void snsh_z80_save(FILE *fp) { struct z80_1_s z80; int to_comp = COMPRESS_SAVE; STORE_NORMAL_REGS(z80); z80.i = RI; /* I reg */ z80.r = RR; /* R reg */ z80.sph = SPH; /* SP reg */ z80.spl = SPL; z80.pch = PCH; /* PC reg */ z80.pcl = PCL; z80.iff1 = z80_proc.iff1; /* iff1 */ z80.iff2 = z80_proc.iff2; /* iff2 */ z80.im = (z80_proc.it_mode & 0x03) | 0x60; /* Bit 0-1: Interrupt mode (0, 1 or 2) Bit 2 : 1=Issue 2 emulation Bit 3 : 1=Double interrupt frequency Bit 4-5: 1=High video synchronisation 3=Low video synchronisation 0,2=Normal Bit 6-7: 0=Cursor/Protek/AGF joystick 1=Kempston joystick 2=Sinclair 1 joystick 3=Sinclair 2 joystick */ z80.data = ((RR >> 7) & 0x01) | ((z80_proc.ula_outport & 0x07) << 1) | (to_comp ? 0x20 : 0); /* Bit 0 : Bit 7 of the R-register Bit 1-3: Border colour Bit 4 : 1=Basic SamRom switched in Bit 5 : 1=Block of data is compressed Bit 6-7: No meaning */ fwrite(&z80, z80_145_size, 1, fp); if(!to_comp) fwrite(z80_proc.mem + 0x4000, 0xC000, 1, fp); else { memptr = 0x4000; savfp = fp; compr(); } } static void snsh_sna_save(FILE *fp) { struct sna_s sna; byte saves1, saves2; STORE_NORMAL_REGS(sna); sna.i = RI; /* I reg */ sna.r = RR; /* R reg */ sna.border = z80_proc.ula_outport & 0x07; SP -= 2; sna.sph = SPH; /* SP reg */ sna.spl = SPL; saves1 = z80_proc.mem[SP]; saves2 = z80_proc.mem[(dbyte)(SP+1)]; if(SP >= 0x4000) { z80_proc.mem[SP] = PCL; if(SP < 0xFFFF) z80_proc.mem[SP+1] = PCH; } sna.iff2 = z80_proc.iff2 ? 0xff : 0x00; /* iff2 */ sna.im = z80_proc.it_mode & 0x03; fwrite(&sna, sna_size, 1, fp); fwrite(z80_proc.mem + 0x4000, 0xC000, 1, fp); if(SP > 0x4000) { z80_proc.mem[SP] = saves1; if(SP < 0xFFFF) z80_proc.mem[SP+1] = saves2; } SP += 2; } #define GET_DATA(c) { \ if(!datalen) break; \ c = sngetc(fp); \ if(c == EOF) break; \ if(datalen > 0) datalen--; \ } static void read_compressed_data(SNFILE *fp, byte *start, unsigned size, long datalen) { int j; int times, last_ed, ch; byte *p, *end; p = start; end = start+size; last_ed = 0; while(p < end) { GET_DATA(ch); if(ch != 0xED) { last_ed = 0; *p++ = ch; } else { if(last_ed) { last_ed = 0; p--; GET_DATA(times); if(times == 0) break; GET_DATA(ch); if(p + times > end) { put_msg("Warning: Repeat parameter too large in snapshot"); times = (int) ((long) end - (long) p); } for(j = 0; j < times; j++) *p++ = ch; } else { last_ed = 1; *p++ = 0xED; } } } if(datalen < 0) { if(sngetc(fp) != 0 || sngetc(fp) != 0xED || sngetc(fp) != 0xED || sngetc(fp) != 0) put_msg("Warning: Illegal ending of snapshot"); } if(datalen > 0) { while(datalen) { if(sngetc(fp) == EOF) break; datalen--; } put_msg("Warning: Page too long in snapshot"); } if(p < end) put_msg("Warning: Page too short in snapshot"); } static int read_header(void *p, int size, SNFILE *fp) { int res; res = snread(p, size, fp); if(res != size) { put_msg("Error, End Of File in snapshot header"); return 0; } return 1; } static int read_z80_page(SNFILE *fp) { struct z80_page_s page; unsigned datalen; unsigned pos = 0; int validpage; int res; res = snread(&page, z80_pg_size, fp); if(res == 0) return 0; if(res != z80_pg_size) { put_msg("Error, End Of File in page header"); return 0; } datalen = (page.blklen_h << 8) | page.blklen_l; validpage = 1; switch(page.page_num) { case 4: pos = 0x8000; break; case 5: pos = 0xC000; break; case 8: pos = 0x4000; break; default: validpage = 0; while(datalen) { if(sngetc(fp) == EOF) { put_msg("Warning: Page too short in snapshot"); break; } datalen--; } } if(validpage) read_compressed_data(fp, z80_proc.mem+pos, 0x4000, (long) datalen); return 1; } static void snsh_z80_load(SNFILE *fp) { struct z80_1_s z80; if(!read_header(&z80, z80_145_size, fp)) return; if(z80.pch == 0 && z80.pcl == 0) { struct z80_2_s z80_2; int ext_size, rem; if(!read_header(&z80_2, 2, fp)) return; ext_size = z80_2.h2_len_l | (z80_2.h2_len_h << 8); if(ext_size < z80_201_ext_size) { put_msg("Error in Z80 header"); return; } if(!read_header(&z80_2.n_pcl, z80_201_ext_size, fp)) return; rem = ext_size - z80_201_ext_size; for(; rem; rem--) sngetc(fp); if(z80_2.hardware >= 3 && (ext_size == z80_201_ext_size || z80_2.hardware >= 4)) { put_msg("Can't load non 48k snapshot"); return; } if(z80_2.if1_paged) { put_msg("Can't load snapshot: IF1 roma paged in"); return; } PCH = z80_2.n_pch; PCL = z80_2.n_pcl; while(read_z80_page(fp)); } else { if(z80.data == 0xFF) z80.data = 1; if(z80.data & 0x20) read_compressed_data(fp, z80_proc.mem + 0x4000, 0xC000, -1); else { if(snread(z80_proc.mem + 0x4000, 0xC000, fp) != 0xC000) put_msg("Warning: Snapshot file too short"); else if(sngetc(fp) != EOF) put_msg("Warning: Snapshot file too long"); } PCH = z80.pch; PCL = z80.pcl; } LOAD_NORMAL_REGS(z80); RI = z80.i; /* I reg */ RR = (z80.r & 0x7F) | ((z80.data & 0x01) << 7); /* R reg */ SPH = z80.sph; /* SP reg */ SPL = z80.spl; z80_proc.ula_outport = (z80_proc.ula_outport & ~(0x07)) | ((z80.data >> 1) & 0x07); /* Bit 0 : Bit 7 of the R-register Bit 1-3: Border colour Bit 4 : 1=Basic SamRom switched in Bit 5 : 1=Block of data is compressed Bit 6-7: No meaning */ z80_proc.iff1 = z80.iff1 ? 1 : 0; z80_proc.iff2 = z80.iff2 ? 1 : 0; z80_proc.it_mode = z80.im & 0x03; /* Bit 0-1: Interrupt mode (0, 1 or 2) Bit 2 : 1=Issue 2 emulation Bit 3 : 1=Double interrupt frequency Bit 4-5: 1=High video synchronisation 3=Low video synchronisation 0,2=Normal Bit 6-7: 0=Cursor/Protek/AGF joystick 1=Kempston joystick 2=Sinclair 1 joystick 3=Sinclair 2 joystick */ z80_proc.haltstate = 0; sp_init_screen_mark(); } static void snsh_sna_load(SNFILE *fp) { struct sna_s sna; if(!read_header(&sna, sna_size, fp)) return; if(snread(z80_proc.mem+0x4000, 0xC000, fp) != 0xC000) put_msg("Warning: Snapshot file too short"); else if(sngetc(fp) != EOF) put_msg("Warning: Snapshot file too long"); LOAD_NORMAL_REGS(sna); RI = sna.i; /* I reg */ RR = sna.r; /* R reg */ z80_proc.ula_outport = (z80_proc.ula_outport & ~(0x07)) | (sna.border & 0x07); SPH = sna.sph; /* SP reg */ SPL = sna.spl; PCL = z80_proc.mem[SP]; if(SP >= 0x4000) z80_proc.mem[SP] = 0; SP++; PCH = z80_proc.mem[SP]; if(SP >= 0x4000) z80_proc.mem[SP] = 0; SP++; z80_proc.iff1 = z80_proc.iff2 = sna.iff2 ? 1 : 0; z80_proc.it_mode = sna.im & 0x03; z80_proc.haltstate = 0; sp_init_screen_mark(); } static void cleanup_qsnap(void) { if(qsnap_created) remove(quick_snap_file); } static void save_snapshot_file_type(char *name, int type) { FILE *snsh; snsh = fopen(name, "wb"); if(snsh == NULL) { sprintf(msgbuf, "Could not open snapshot file `%s', %s", name, strerror(errno)); put_msg(msgbuf); return; } if(type == SN_SNA) snsh_sna_save(snsh); else if(type == SN_Z80) snsh_z80_save(snsh); fclose(snsh); } void save_snapshot_file(char *name) { int type; strncpy(filenamebuf, name, MAXFILENAME-10); filenamebuf[MAXFILENAME-10] = '\0'; type = SN_Z80; if(check_ext(filenamebuf, "z80")) type = SN_Z80; else if(check_ext(filenamebuf, "sna")) type = SN_SNA; else { add_extension(filenamebuf, "z80"); type = SN_Z80; } save_snapshot_file_type(filenamebuf, type); sprintf(msgbuf, "Saved snapshot to file %s", filenamebuf); put_msg(msgbuf); } void save_quick_snapshot(void) { if(!qsnap_created) { if(tmpnam(quick_snap_file) == NULL) { put_msg("Could not create temporary file for quick snapshot"); return; } qsnap_created = 1; atexit(cleanup_qsnap); } save_snapshot_file_type(quick_snap_file, SN_Z80); } void save_snapshot(void) { char *name; put_msg("Enter name of snapshot file to save:"); name = spif_get_filename(); if(name == NULL) return; save_snapshot_file(name); } void load_snapshot_file_type(char *name, int type) { int filetype = FT_SNAPSHOT; FILE *snsh; SNFILE snfil; strncpy(filenamebuf, name, MAXFILENAME-10); filenamebuf[MAXFILENAME-10] = '\0'; spcf_find_file_type(filenamebuf, &filetype, &type); if(type < 0) type = SN_Z80; snsh = fopen(filenamebuf, "rb"); if(snsh == NULL) { sprintf(msgbuf, "Could not open snapshot file `%s', %s", filenamebuf, strerror(errno)); put_msg(msgbuf); return; } snfil.isfile = 1; snfil.fp = snsh; if(type == SN_SNA) snsh_sna_load(&snfil); else if(type == SN_Z80) snsh_z80_load(&snfil); fclose(snsh); } void snsh_z80_load_intern(byte *p, unsigned len) { SNFILE snfil; snfil.isfile = 0; snfil.at = p; snfil.len = len; snsh_z80_load(&snfil); } void load_quick_snapshot(void) { if(!qsnap_created) { put_msg("No quick snapshot saved yet"); return; } load_snapshot_file_type(quick_snap_file, SN_Z80); } void load_snapshot(void) { char *name; put_msg("Enter name of snapshot file to load:"); name = spif_get_filename(); if(name == NULL) return; load_snapshot_file_type(name, -1); } spectemu-0.94/snapshot.h0100644000175000017500000000231706526324532015560 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SNAPSHOT_H #define SNAPSHOT_H #define SN_SNA 0 #define SN_Z80 1 extern void save_snapshot_file(char *snsh_name); extern void load_snapshot_file_type(char *snsh_name, int type); extern void snsh_z80_load_intern(unsigned char *p, unsigned len); extern void save_snapshot(void); extern void load_snapshot(void); extern void save_quick_snapshot(void); extern void load_quick_snapshot(void); #endif /* SNAPSHOT_H */ spectemu-0.94/sp_to_s.c0100644000175000017500000001727606505732773015403 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #define MAX_TOK_NUM 256 typedef struct { int num; int type; } Token; #define ADD(tokens, i, n, t) \ tokens[i].num = n; tokens[i].type = t; i++ #define BASEOFF 10 #define I_OPENBRACE 20 #define I_CLOSEBRACE 21 #define I_MINUS 22 #define I_NULL 0 #define T_NUM 1 #define T_NOT 2 #define T_NEG 3 #define T_MUL 4 #define T_DIV 5 #define T_MOD 6 #define T_ADD 7 #define T_SUB 8 #define T_SHL 9 #define T_SHR 10 #define P_NE 3 #define P_MU 2 #define P_AD 1 #define P_SH 0 static int line; static int pos; int read_item(char **sp, int *num) { char *s; int val, base; s = *sp; base = 10; val = 0; while(*s == ' ' || *s == '\t') s++; if(!*s) { *sp = s; return I_NULL; } *sp = s+1; switch(*s) { case '+': return T_ADD; case '-': return I_MINUS; case '*': return T_MUL; case '/': return T_DIV; case '%': return T_MOD; case '~': return T_NOT; case '(': return I_OPENBRACE; case ')': return I_CLOSEBRACE; case '<': s++; if(*s != '<') return -1; *sp = s+1; return T_SHL; case '>': s++; if(*s != '>') return -1; *sp = s+1; return T_SHR; case '0': s++; if(*s == 'x') { s++; if(!*s) return -1; base = 16; } else base = 8; break; default: if(*s < '0' || *s > '9') { *sp = s; return I_NULL; } } for(;;) { if((*s >= '0' && *s <= '7') || (base > 8 && *s >= '8' && *s <= '9')) val = val * base + (*s - '0'); else if(base > 10 && ((*s >= 'a' && *s <= 'f') || (*s >= 'A' && *s <= 'F'))) { if(*s < 'a') val = val * base + (*s - 'A' + 10); else val = val * base + (*s - 'a' + 10); } else break; s++; } *num = val; *sp = s; return T_NUM; } int tokenize(char **exps, Token *tokens) { int op; int i; int res, num; int base; op = 1; base = 0; for(i = 0;;) { res = read_item(exps, &num); if(res < 0) return res; switch(res) { case I_NULL: if(op || base != 0) return -1; return i; case T_NUM: if(!op) return -1; ADD(tokens, i, num, res); op = 0; break; case I_OPENBRACE: if(!op) { (*exps)--; if(op || base != 0) return -1; return i; } base += BASEOFF; /* op = 1; */ break; case I_CLOSEBRACE: if(op) return -1; base -= BASEOFF; if(base < 0) return -1; /* op = 0; */ break; case T_NOT: if(!op) return -1; ADD(tokens, i, base+P_NE, res); /* op = 1; */ break; case T_SHL: case T_SHR: if(op) return -1; ADD(tokens, i, base+P_SH, res); op = 1; break; case T_ADD: if(op) return -1; ADD(tokens, i, base+P_AD, res); op = 1; break; case I_MINUS: if(!op) { ADD(tokens, i, base+P_AD, T_SUB); op = 1; } else { ADD(tokens, i, base+P_NE, T_NEG); /* op = 1; */ } break; case T_MUL: case T_DIV: case T_MOD: if(op) return -1; ADD(tokens, i, base+P_MU, res); op = 1; break; default: return -1; } } return -1; } int calculate(Token *tokens, int start, int end, int *valp) { int i; int minprec; int minpos; int lval, rval; int val; int res; if(start == end - 1) { *valp = tokens[start].num; return 0; } val = 0; minprec = -1; minpos = -1; for(i = start; i < end; i++) if(tokens[i].type != T_NUM && (minprec < 0 || tokens[i].num <= minprec)) { minprec = tokens[i].num; minpos = i; } if(tokens[start].type != T_NUM && minprec == tokens[start].num) { res = calculate(tokens, start+1, end, &rval); if(res < 0) return res; if(tokens[start].type == T_NOT) val = ~rval; else val = -rval; *valp = val; return 0; } res = calculate(tokens, start, minpos, &lval); if(res < 0) return res; res = calculate(tokens, minpos+1, end, &rval); if(res < 0) return res; switch(tokens[minpos].type) { case T_SHL: if(rval < 0) return -1; val = lval << rval; break; case T_SHR: if(rval < 0) return -1; val = lval >> rval; break; case T_ADD: val = lval + rval; break; case T_SUB: val = lval - rval; break; case T_MUL: val = lval * rval; break; case T_DIV: val = lval / rval; break; case T_MOD: val = lval % rval; break; } *valp = val; return 0; } int cexpr(char **exps, int *val) { static Token tokens[MAX_TOK_NUM]; int res; res = tokenize(exps, tokens); if(res < 0) return res; if(res == 0) return -1; res = calculate(tokens, 0, res, val); if(res < 0) return res; return 0; } int mygetc(FILE *f) { int c; c = getc(f); pos++; if(c == '\n') { line++; pos = 0; } return c; } int ignore_whitespaces(FILE *in) { int c; while((c = mygetc(in)) != EOF && (c == ' ' || c == '\t')); if(c == EOF) return -1; else { ungetc(c, in); if(c == '\n') line--; if(pos > 0) pos--; return 0; } } int read_asm_line(FILE *in, char *buf) { int c; int is_label = 0; int li = 0; if(ignore_whitespaces(in) == -1) return -1; while((c = mygetc(in)) != EOF && c != ';' && c != '\n') { if(c == ':') is_label = 1; buf[li] = c; li++; } buf[li] = '\0'; if(c == EOF) return -1; else return is_label; } void put_label(char *buf, FILE *out) { putc('\n', out); for(;*buf && *buf != ':';buf++) if(*buf != ' ' && *buf != '\t') putc(*buf, out); if(*buf == ':') putc(*buf, out), buf++; for(;*buf; buf++) if(*buf != ' ' && *buf != '\t') { fprintf(stderr, "Error: instruction after label at line %i, pos %i\n", line, pos); exit(1); } putc('\n', out); } void put_asm(char *buf, FILE *out) { int l; int lastb; int isc; lastb = 0; putc('\t', out); for(l=0;*buf && *buf != ' ' && *buf != '\t';buf++,l++) { putc(*buf, out); lastb = *buf; } putc(' ', out); for(;l < 7; l++) putc(' ', out); for(;*buf && *buf != '#';) { if(*buf == '+' || *buf == '$') { int val; int res; if(*buf == '$') isc = 1; else isc = 0; putc(*buf, out); buf++; res = cexpr(&buf, &val); if(res < 0) { fprintf(stderr, "Error: illegal arithmetic expression at line %i, pos %i\n", line, pos); exit(1); } if(!isc) fprintf(out, "%i", val); else { if(lastb == 'w') val = val & 0xFFFF; else if(lastb == 'b') val = val & 0xFF; fprintf(out, "%i", val); } } else { if(*buf != ' ' && *buf != '\t') putc(*buf, out); buf++; } } putc('\n', out); } int main(void) { FILE *in = stdin; FILE *out = stdout; static char buf[1024]; int res; line = 0; pos = 0; while((res = read_asm_line(in, buf)) != -1) { if(buf[0] != '\0' && buf[0] != '#') { if(res == 0) put_asm(buf, out); else put_label(buf, out); } } return 0; } spectemu-0.94/spmain.c0100644000175000017500000001215006530013666015175 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include "spperif.h" #include "z80.h" #include "spmain.h" #include "sptiming.h" #include "spscr.h" #include "spkey.h" #include "sptape.h" #include "spsound.h" #include "snapshot.h" #include "spver.h" #include "spconf.h" #include "interf.h" #include "misc.h" #include #include #include #include int endofsingle; int sp_nosync = 0; int showframe = 2; int load_immed = 0; qbyte sp_int_ctr = 0; #ifdef USE_DJGPP #define DOS #endif #ifndef DATADIR #ifdef DOS #define DATADIR "." #else #define DATADIR "/usr/local/share/spectemu" #endif #endif #ifndef MULTIUSER #ifdef DOS #define MULTIUSER 0 #else #define MULTIUSER 1 #endif #endif #define GLOBALCFG "spectemu.cfg" #define LOCALCFG ".spectemurc" const char *sp_datadir = DATADIR; extern unsigned char loadim[]; extern unsigned long loadim_size; #define SHOW_OFFS 1 static void update(void) { update_screen(); sp_border_update >>= 1; sp_imag_vert = sp_imag_horiz = 0; } static void run_singlemode(void) { int t = 0; int evenframe, halfsec, updateframe; sp_int_ctr = 0; endofsingle = 0; spti_reset(); while(!endofsingle) { if(sp_paused) { autoclose_sound(); while(sp_paused) { spkb_process_events(1); spti_sleep(SKIPTIME); translate_screen(); update(); } spti_reset(); } halfsec = !(sp_int_ctr % 25); evenframe = !(sp_int_ctr & 1); if(screen_visible) updateframe = sp_nosync ? halfsec : !((sp_int_ctr+SHOW_OFFS) % showframe); else updateframe = 0; if(halfsec) { sp_flash_state = ~sp_flash_state; flash_change(); } if(evenframe) { play_tape(); sp_scline = 0; } spkb_process_events(evenframe); sp_updating = updateframe; t += CHKTICK; t = sp_halfframe(t, evenframe ? EVENHF : ODDHF); if(SPNM(load_trapped)) { SPNM(load_trapped) = 0; DANM(haltstate) = 0; qload(); } z80_interrupt(0xFF); sp_int_ctr++; if(!evenframe) rec_tape(); if(!sp_nosync) { if(!sound_avail) spti_wait(); if(updateframe) update(); play_sound(evenframe); } else if(updateframe) update(); } } void check_params(int argc, char *argv[]) { #if MULTIUSER char *homedir; strncpy(filenamebuf, DATADIR, MAXFILENAME-128); strcat(filenamebuf, "/"); strcat(filenamebuf, GLOBALCFG); spcf_read_conf_file(filenamebuf); homedir = getenv("HOME"); if(homedir == NULL) { sprintf(msgbuf, "Warning: Can't open '%s': HOME environment variable not set", LOCALCFG); put_msg(msgbuf); } else { strncpy(filenamebuf, homedir, MAXFILENAME-128); strcat(filenamebuf, "/"); strcat(filenamebuf, LOCALCFG); if(!file_exist(filenamebuf)) { FILE *fp; fp = fopen(filenamebuf, "wt"); if(fp == NULL) { sprintf(msgbuf, "Note: Failed to create '%s': %s", filenamebuf, strerror(errno)); put_msg(msgbuf); } else { fprintf(fp, "# This is the config file for spectemu.\n\n"); fclose(fp); sprintf(msgbuf, "Created '%s'", filenamebuf); put_msg(msgbuf); } } spcf_read_conf_file(filenamebuf); } #else spcf_read_conf_file(GLOBALCFG); #endif spcf_read_xresources(); spcf_read_command_line(argc, argv); } static void init_load(int argc, char *argv[]) { if(load_immed) snsh_z80_load_intern(loadim, loadim_size); if(spcf_init_snapshot != NULL) { sprintf(msgbuf, "Loading snapshot '%s'", spcf_init_snapshot); put_msg(msgbuf); load_snapshot_file_type(spcf_init_snapshot, spcf_init_snapshot_type); free_string(spcf_init_snapshot); } if(spcf_init_tapefile != NULL) { sprintf(msgbuf, "Loading tape '%s'", spcf_init_tapefile); put_msg(msgbuf); start_play_file_type(spcf_init_tapefile, 0, spcf_init_tapefile_type); if(!load_immed) pause_play(); free_string(spcf_init_tapefile); } } static void print_copyright(void) { sprintf(msgbuf, "Welcome to SPECTEMU version %s/%s (C) Szeredi Miklos 1996-1998", SPECTEMU_VERSION, SPECTEMU_TYPE); put_msg(msgbuf); put_msg("This program comes with NO WARRANTY, see the file COPYING " "for details"); put_msg("Press Ctrl-h for help"); } void start_spectemu(int argc, char *argv[]) { spti_init(); init_spect_scr(); init_spect_sound(); init_spect_key(); print_copyright(); init_load(argc, argv); run_singlemode(); } spectemu-0.94/i386sp.S0100644000175000017500000002437606525576630014750 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ #ifndef COMPARISON #define SPT(s) NAME(sp_ ## s) #else #define SPT(s) NAME(spx_ ## s) #endif #define LOAD_DI 0x0559 #define OS 80 #define EARBIT 0x40 #define NEXT_SCRI DAT(OS,0) #define INPORT_MASK DAT(OS,4) #define ULA_INPORT DAT(OS,8) #define ULA_OUTPORT DAT(OS,12) #define SOUND_SAM DAT(OS,16) #define SOUND_CHANGE DAT(OS,20) #define IMP_CHANGE DAT(OS,24) #define JROM(addr, label) \ testw $0xC000, addr ; \ jz label #define JNROM(addr, label) \ testw $0xC000, addr ; \ jnz label #define JSCR(addr, label) \ cmpw $0x5B00, addr ; \ jb label #define JNSCR(addr, label) \ cmpw $0x5B00, addr ; \ jnb label #define JROMB(addr, label) \ testb $0xC0, addr ; \ jz label #define JNROMB(addr, label) \ testb $0xC0, addr ; \ jnz label #define JSCRB(addr, label) \ cmpb $0x5B, addr ; \ jb label #define JNSCRB(addr, label) \ cmpb $0x5B, addr ; \ jnb label #define MARK_SCR(addr) \ xchgw RAF, addr ; \ btsl SCRP, SPT(scr_mark) ; \ xchgw RAF, addr #define MARK_SCR_VWP(addr) \ movzwl addr, VWP ; \ btsl VWP, SPT(scr_mark) #define MEM_DELAY(l) \ cmpl $0, NEXT_SCRI ; \ jl l ; \ cmpl $86, TC ; \ jle l ; \ subl $2, TC #define PUTMEM_REG(l, reg, regh, regp, val, endf) \ JSCRB(regh, l ## _scr) ; \ movb val, (regp) ; \ endf ; \ l ## _scr: ; \ JROMB(regh, l ## _rom) ; \ movb val, (regp) ; \ MARK_SCR_VWP(reg) ; \ MEM_DELAY(l ## _rom) ; \ endf ; \ l ## _rom: ; \ endf #define PUTMEM_REG_NE(l, reg, regh, regp, val) \ JROMB(regh, l ## _mid) ; \ movb val, (regp) ; \ JNSCRB(regh, l ## _mid) ; \ MARK_SCR(reg) ; \ MEM_DELAY(l ## _mid) ; \ l ## _mid: #define PUTMEM_DREG_NE(l, reg, regp, val) \ JROM(reg, l ## _mid) ; \ movb val, (regp) ; \ JNSCR(reg, l ## _mid) ; \ MARK_SCR(reg) ; \ MEM_DELAY(l ## _mid) ; \ l ## _mid: #define MODMEMF(l, func, endf) \ JSCRB(RH, l ## _scr) ; \ func((HLP)) ; \ endf ; \ l ## _scr: ; \ JROMB(RH, l ## _rom) ; \ func((HLP)) ; \ MARK_SCR_VWP(RHL) ; \ MEM_DELAY(l ## _rend) ; \ endf ; \ l ## _rom: ; \ movb (HLP), RW ; \ func(RW) ; \ l ## _rend: ; \ endf #define PUSH_CMPX(l, rh, rl) \ decw RSP ; \ PUTMEM_DREG_NE(l ## 1, RSP, SPP, rh); \ decw RSP ; \ PUTMEM_DREG_NE(l ## 2, RSP, SPP, rl) #define PUSHT(l, rh, rl, t) \ cmpw $0x5B01, RSP ; \ jb l ## _cmpx ; \ decw RSP ; \ movb rh, (SPP) ; \ decw RSP ; \ movb rl, (SPP) ; \ TIME(t) ; \ l ## _cmpx: ; \ PUSH_CMPX(l, rh, rl) ; \ TIME(t) ; \ #define PUSH(l, rh, rl) \ cmpw $0x5B01, RSP ; \ jb l ## _cmpx ; \ decw RSP ; \ movb rh, (SPP) ; \ decw RSP ; \ movb rl, (SPP) ; \ jmp l ## _end ; \ ALIGN ; \ l ## _cmpx: ; \ PUSH_CMPX(l, rh, rl) ; \ l ## _end: #define TICKPERLINE 224 #define SOUNDPORT 0x10 #define IN(l, porth, portl, rd) \ movl INPORT_MASK, VWP ; \ testb RW, portl ; \ jz l ## _in_active ; \ testb $1, portl ; \ jnz l ## _in_ulabus ; \ cmpl TC,IMP_CHANGE ; \ jg l ## _in_imp ; \ movzbl porth, VWP ; \ movb SPT(fe_inport_high)(VWP), rd; \ andb ULA_INPORT, rd ; \ decl TC ; \ jmp l ## _in_end ; \ ALIGN ; \ l ## _in_imp: ; \ movl $0,IMP_CHANGE ; \ xorb $EARBIT,ULA_INPORT ; \ movzbl porth, VWP ; \ movb SPT(fe_inport_high)(VWP), rd; \ andb ULA_INPORT, rd ; \ decl TC ; \ jmp l ## _in_end ; \ ALIGN ; \ l ## _in_active: ; \ movzbl portl, VWP ; \ movb Z80(inports)(VWP), rd; \ jmp l ## _in_end ; \ ALIGN ; \ l ## _in_ulabus: ; \ movl PCP, VWP ; \ movw NEXT_SCRI, RVW ; \ cmpw $0, RVW ; \ jl l ## _in_ulaidle ; \ cmpl $96, TC ; \ jle l ## _in_ulaidle ; \ pushl TC ; \ shrw $2, %di ; \ shlw $5, RVW ; \ addw $56, RVW ; \ subw %di, RVW ; \ popl TC ; \ movb (VWP), rd ; \ jmp l ## _in_end ; \ l ## _in_ulaidle: ; \ movb $0xFF, rd ; \ jmp l ## _in_end ; \ ALIGN ; \ l ## _in_end: #define OUT(l, porth, portl, rs) \ testb $1, portl ; \ jnz l ## _out_nonfe ; \ movb rs, RV ; \ xorb ULA_OUTPORT, RV ; \ decl TC ; \ movb rs, ULA_OUTPORT ; \ testb $SOUNDPORT, RV ; \ jz l ## _out_end ; \ movl $1, SOUND_CHANGE ; \ testb $SOUNDPORT, rs ; \ jz l ## _out_s_0 ; \ addl TC, SOUND_SAM ; \ jmp l ## _out_end ; \ ALIGN ; \ l ## _out_s_0: ; \ subl TC, SOUND_SAM ; \ jmp l ## _out_end ; \ ALIGN ; \ l ## _out_nonfe: ; \ movzbl portl, VWP ; \ movb rs, Z80(outports)(VWP); \ l ## _out_end: #define DI_CHECK \ cmpw $LOAD_DI+1, RPC ; \ je load_point ; \ di_check_end: load_point: cmpl $0, SPT(quick_load) je di_check_end movl $1, SPT(load_trapped) movl $1, HALTSTATE movl $0, TC jmp loop_end #define SCLINE %ebx #define INC_SCLINE \ incl SCLINE ; \ andl $0x03FF, SCLINE ; \ movl SCLINE, SPT(scline) #define SCRPTR %edi #define SPM %ecx #define SPM0 %cl #define SPM1 %ch #define SPC %ebx #define SPC0 %bl #define SPC1 %bh #define SPMP %esi #define SPCP %ebp #define SPI %edx #define SPIW %dx #define SPI0 %dl #define SPI1 %dh #define SCRI %ebx #define COLI %edx #define COLI0 %dl #define TRANS_SCR \ movl (SPI),%eax ; \ stosl #define SCR_8_PIXELS(spcx, spmx, aa) \ movb spcx,SPI1 ; \ aa ; \ movb spmx,SPI0 ; \ shrb $2,SPI0 ; \ andb $0x3C,SPI0 ; \ TRANS_SCR ; \ movb spmx,SPI0 ; \ shlb $2,SPI0 ; \ andb $0x3C,SPI0 ; \ TRANS_SCR #define SHRLSPC shrl $16, SPC #define SCR_32_PIXELS \ movl (SPMP),SPM ; \ movl (SPCP),SPC ; \ SCR_8_PIXELS(SPC0, SPM0, ); \ addl $4, SPMP ; \ SCR_8_PIXELS(SPC1, SPM1, SHRLSPC); \ shrl $16, SPM ; \ SCR_8_PIXELS(SPC0, SPM0, ); \ addl $4, SPCP ; \ SCR_8_PIXELS(SPC1, SPM1, ); \ #define GET_BORDER \ movb SPT(colors)(,%ecx,1), %cl; \ movb %cl, %ch ; \ movw %cx, %ax ; \ shll $16, %eax ; \ movw %cx, %ax ALIGN .globl SPT(halfframe) /* .type SPT(halfframe),@function */ SPT(halfframe): movl 8(%esp), %eax movl %eax, linesleft movl 4(%esp), %eax pushl %ebp pushl %edi pushl %esi pushl %ebx pushl %es cld movl %eax, TC movl SPT(image), %eax movl %eax, scrptr #ifndef USE_DJGPP movw %ds, %ax #else movw NAME(djsp_video_segment), %ax #endif movw %ax, %es call load_regs new_loop: movl SPT(scline), %eax movl SPT(scri)(,%eax,4), %eax movl %eax, NEXT_SCRI call step_loop pushl SCLINE movl SPT(scline), SCLINE /* store sound */ movb SOUND_SAM, %al movb %al, SPT(sound_buf)(SCLINE) movb ULA_OUTPORT, %al testb $SOUNDPORT, %al jz sound_0 movb $240, SOUND_SAM jmp sound_end ALIGN sound_0: movb $16, SOUND_SAM sound_end: /* change EAR bit, store MIC bit*/ movb %al, SPT(fe_outport_time)(SCLINE) cmpl $0,IMP_CHANGE je no_imp_change xorb $EARBIT, ULA_INPORT no_imp_change: movzbl SPT(tape_impinfo)(SCLINE), %eax movl %eax, IMP_CHANGE /* Check if updating screen */ cmpl $0, SPT(updating) jz not_to_update movl NEXT_SCRI, %eax cmpl $-1, %eax jl not_to_update je only_border scr_update: pushl %ecx pushl %edx pushl %edi movl SPT(coli)(,SCLINE, 4), COLI INC_SCLINE movl %eax, SCRI movl scrptr, SCRPTR movl SCRPTR, %eax addl $320, %eax movl %eax, scrptr movzbl ULA_OUTPORT, %ecx andb $0x07, %cl cmpb %cl, SPT(lastborder) jne sbrd_change cmpl $0, SPT(border_update) jne sbrd_update addl $0x20, SCRPTR sbrd_no_update: movl COLI, %eax shrl $3, %eax testb $0x07, COLI0 jz clear_cm movl SPT(scr_mark)+(0x2C0*4)(,%eax,4), %ecx no_clear_cm: xorl %eax, %eax xchgl SPT(scr_mark)(,SCRI,4), %eax orl %eax, %ecx jz skip_update orl %ecx, SPT(imag_mark)(,COLI,4) orl %ecx, SPT(imag_horiz) shrl $3, COLI btsl COLI, SPT(imag_vert) /* update screen line */ pushl %esi pushl %ebp /* %esi is PCP and SPMP ! */ xorw %si, %si movl %esi, %eax shll $5, SCRI shll $5, COLI addl SCRI, SPMP leal 0x5800(%eax, COLI), SPCP /* Draw pixels */ movl $0xF, %ebx pushl %ecx subl $4, %esp cmpl $0, SPT(flash_state) jnz scr_f1 movl SPT(scr_f0_table), SPI jmp scr_32_pixels ALIGN scr_f1: movl SPT(scr_f1_table), SPI jmp scr_32_pixels ALIGN scr_32_pixels: testl %ebx, %ecx jz skip_32_pixels movl %ebx, (%esp) SCR_32_PIXELS movl (%esp), %ebx shll $4, %ebx jz end_screen_line movl 4(%esp), %ecx jmp scr_32_pixels ALIGN skip_32_pixels: addl $4, SPMP addl $4, SPCP addl $32, SCRPTR shll $4, %ebx jz end_screen_line jmp scr_32_pixels ALIGN end_screen_line: addl $8, %esp popl %ebp popl %esi skip_update: popl %edi popl %edx popl %ecx jmp update_end ALIGN sbrd_change: movl $2, SPT(border_update) xchgb %cl, SPT(lastborder) sbrd_update: GET_BORDER /* Draw border */ xorl %ecx, %ecx movb $8, %cl rep stosl addl $0x100, SCRPTR movb $8, %cl rep stosl subl $0x120, SCRPTR jmp sbrd_no_update ALIGN clear_cm: xorl %ecx, %ecx xchgl SPT(scr_mark)+(0x2C0*4)(,%eax,4), %ecx testl %ecx, %ecx jz no_clear_cm leal SPT(scr_mark)(,SCRI,4), %eax orl %ecx, (%eax) orl %ecx, 0x20(%eax) orl %ecx, 0x40(%eax) orl %ecx, 0x60(%eax) addl $0x80, %eax orl %ecx, (%eax) orl %ecx, 0x20(%eax) orl %ecx, 0x40(%eax) orl %ecx, 0x60(%eax) jmp no_clear_cm ALIGN only_border: INC_SCLINE pushl %edi movl %ecx, %ebx movzbl ULA_OUTPORT, %ecx andb $0x07, %cl cmpb %cl, SPT(lastborder) je brd_no_change movl $2, SPT(border_update) xchgb %cl, SPT(lastborder) brd_no_change: cmpl $0, SPT(border_update) je brd_no_update GET_BORDER movl scrptr, SCRPTR movl $80, %ecx rep stosl brd_no_update: addl $320, scrptr movl %ebx, %ecx popl %edi jmp update_end ALIGN not_to_update: INC_SCLINE update_end: popl SCLINE decl linesleft jz chunk_end addl $TICKPERLINE, TC jmp new_loop ALIGN chunk_end: call store_regs movl TC, %eax popl %es popl %ebx popl %esi popl %edi popl %ebp ret ALIGN .data linesleft: .long 0 scrptr: .long 0 .text spectemu-0.94/spkey.c0100644000175000017500000006417206530013634015047 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* #define DEBUG_KEYS */ #include "spkey.h" #include "spkey_p.h" #include "spperif.h" #include "z80.h" #include "sptape.h" #include "snapshot.h" #include "spsound.h" #include "spscr.h" #include "interf.h" #include "misc.h" #include #include #include int keyboard_type = 0; int cursor_type = 0; int spkb_allow_ascii = 1; int spkb_trueshift = -1; int spkb_funcshift = -1; static unsigned trueshift; static unsigned funcshift; struct spkeydef { int type; spkeyboard kb; }; struct spbasekey { int index; spkeyboard kb; spkeyboard misc; }; struct spnamedkey { const char *name; spkeyboard kb; spkeyboard misc; }; extern int endofsingle; extern int sp_nosync; extern int showframe; extern int privatemap; spkeyboard spkey_state; spkeyboard spmisc_state; static spkeyboard oldstate = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; struct keystate spkb_kbstate[NR_SPKEYS]; struct onekey spkb_last; int spkb_state_changed; #define SKE {0, 0, 0, 0, 0, 0, 0, 0} #define SKP(x) (1 << x) #define SKN0(x) {SKP(x), 0, 0, 0, 0, 0, 0, 0} #define SKN1(x) {0, SKP(x), 0, 0, 0, 0, 0, 0} #define SKN2(x) {0, 0, SKP(x), 0, 0, 0, 0, 0} #define SKN3(x) {0, 0, 0, SKP(x), 0, 0, 0, 0} #define SKN4(x) {0, 0, 0, 0, SKP(x), 0, 0, 0} #define SKN5(x) {0, 0, 0, 0, 0, SKP(x), 0, 0} #define SKN6(x) {0, 0, 0, 0, 0, 0, SKP(x), 0} #define SKN7(x) {0, 0, 0, 0, 0, 0, 0, SKP(x)} #define SKCS0(x) {SKP(0) | SKP(x), 0, 0, 0, 0, 0, 0, 0} #define SKCS1(x) {SKP(0), SKP(x), 0, 0, 0, 0, 0, 0} #define SKCS2(x) {SKP(0), 0, SKP(x), 0, 0, 0, 0, 0} #define SKCS3(x) {SKP(0), 0, 0, SKP(x), 0, 0, 0, 0} #define SKCS4(x) {SKP(0), 0, 0, 0, SKP(x), 0, 0, 0} #define SKCS5(x) {SKP(0), 0, 0, 0, 0, SKP(x), 0, 0} #define SKCS6(x) {SKP(0), 0, 0, 0, 0, 0, SKP(x), 0} #define SKCS7(x) {SKP(0), 0, 0, 0, 0, 0, 0, SKP(x)} #define SKSS0(x) {SKP(x), 0, 0, 0, 0, 0, 0, SKP(1)} #define SKSS1(x) {0, SKP(x), 0, 0, 0, 0, 0, SKP(1)} #define SKSS2(x) {0, 0, SKP(x), 0, 0, 0, 0, SKP(1)} #define SKSS3(x) {0, 0, 0, SKP(x), 0, 0, 0, SKP(1)} #define SKSS4(x) {0, 0, 0, 0, SKP(x), 0, 0, SKP(1)} #define SKSS5(x) {0, 0, 0, 0, 0, SKP(x), 0, SKP(1)} #define SKSS6(x) {0, 0, 0, 0, 0, 0, SKP(x), SKP(1)} #define SKSS7(x) {0, 0, 0, 0, 0, 0, 0, SKP(x) | SKP(1)} #define KEMP(x) {x, 0, 0, 0, 0, 0, 0, 0} #define KEMPR 0x01 #define KEMPL 0x02 #define KEMPD 0x04 #define KEMPU 0x08 #define KEMPF 0x10 #define KEMP_PORT 0x1F #define T_MAIN 0 #define T_CMPX 1 #define T_EXTR 2 #define SPK_SPACE SKN7(0) #define SPK_0 SKN4(0) #define SPK_1 SKN3(0) #define SPK_2 SKN3(1) #define SPK_3 SKN3(2) #define SPK_4 SKN3(3) #define SPK_5 SKN3(4) #define SPK_6 SKN4(4) #define SPK_7 SKN4(3) #define SPK_8 SKN4(2) #define SPK_9 SKN4(1) #define SPK_A SKN1(0) #define SPK_B SKN7(4) #define SPK_C SKN0(3) #define SPK_D SKN1(2) #define SPK_E SKN2(2) #define SPK_F SKN1(3) #define SPK_G SKN1(4) #define SPK_H SKN6(4) #define SPK_I SKN5(2) #define SPK_J SKN6(3) #define SPK_K SKN6(2) #define SPK_L SKN6(1) #define SPK_M SKN7(2) #define SPK_N SKN7(3) #define SPK_O SKN5(1) #define SPK_P SKN5(0) #define SPK_Q SKN2(0) #define SPK_R SKN2(3) #define SPK_S SKN1(1) #define SPK_T SKN2(4) #define SPK_U SKN5(3) #define SPK_V SKN0(4) #define SPK_W SKN2(1) #define SPK_X SKN0(2) #define SPK_Y SKN5(4) #define SPK_Z SKN0(1) #define SPK_ENTER SKN6(0) #define SPK_CAPSSHIFT SKN0(0) #define SPK_SYMBOLSHIFT SKN7(1) #define SPK_BS SKCS4(0) #define SPK_UP SKCS4(3) #define SPK_DOWN SKCS4(4) #define SPK_LEFT SKCS3(4) #define SPK_RIGHT SKCS4(2) #define SPK_CAPSLOCK SKCS3(1) #define SPK_EXTRA SKCS7(1) #define SPK_EDIT SKCS3(0) static spkeyboard spk_extra = SPK_EXTRA; static struct spkeydef spkey_ascii[] = { {T_MAIN, SPK_SPACE}, /* space */ {T_CMPX, SKSS3(0)}, /* ! */ {T_CMPX, SKSS5(0)}, /* " */ {T_CMPX, SKSS3(2)}, /* # */ {T_CMPX, SKSS3(3)}, /* $ */ {T_CMPX, SKSS3(4)}, /* % */ {T_CMPX, SKSS4(4)}, /* & */ {T_CMPX, SKSS4(3)}, /* ' */ {T_CMPX, SKSS4(2)}, /* ( */ {T_CMPX, SKSS4(1)}, /* ) */ {T_CMPX, SKSS7(4)}, /* * */ {T_CMPX, SKSS6(2)}, /* + */ {T_CMPX, SKSS7(3)}, /* , */ {T_CMPX, SKSS6(3)}, /* - */ {T_CMPX, SKSS7(2)}, /* . */ {T_CMPX, SKSS0(4)}, /* / */ {T_MAIN, SPK_0}, /* 0 */ {T_MAIN, SPK_1}, /* 1 */ {T_MAIN, SPK_2}, /* 2 */ {T_MAIN, SPK_3}, /* 3 */ {T_MAIN, SPK_4}, /* 4 */ {T_MAIN, SPK_5}, /* 5 */ {T_MAIN, SPK_6}, /* 6 */ {T_MAIN, SPK_7}, /* 7 */ {T_MAIN, SPK_8}, /* 8 */ {T_MAIN, SPK_9}, /* 9 */ {T_CMPX, SKSS0(1)}, /* : */ {T_CMPX, SKSS5(1)}, /* ; */ {T_CMPX, SKSS2(3)}, /* < */ {T_CMPX, SKSS6(1)}, /* = */ {T_CMPX, SKSS2(4)}, /* > */ {T_CMPX, SKSS0(3)}, /* ? */ {T_CMPX, SKSS3(1)}, /* @ */ {T_CMPX, SKCS1(0)}, /* A */ {T_CMPX, SKCS7(4)}, /* B */ {T_CMPX, SKCS0(3)}, /* C */ {T_CMPX, SKCS1(2)}, /* D */ {T_CMPX, SKCS2(2)}, /* E */ {T_CMPX, SKCS1(3)}, /* F */ {T_CMPX, SKCS1(4)}, /* G */ {T_CMPX, SKCS6(4)}, /* H */ {T_CMPX, SKCS5(2)}, /* I */ {T_CMPX, SKCS6(3)}, /* J */ {T_CMPX, SKCS6(2)}, /* K */ {T_CMPX, SKCS6(1)}, /* L */ {T_CMPX, SKCS7(2)}, /* M */ {T_CMPX, SKCS7(3)}, /* N */ {T_CMPX, SKCS5(1)}, /* O */ {T_CMPX, SKCS5(0)}, /* P */ {T_CMPX, SKCS2(0)}, /* Q */ {T_CMPX, SKCS2(3)}, /* R */ {T_CMPX, SKCS1(1)}, /* S */ {T_CMPX, SKCS2(4)}, /* T */ {T_CMPX, SKCS5(3)}, /* U */ {T_CMPX, SKCS0(4)}, /* V */ {T_CMPX, SKCS2(1)}, /* W */ {T_CMPX, SKCS0(2)}, /* X */ {T_CMPX, SKCS5(4)}, /* Y */ {T_CMPX, SKCS0(1)}, /* Z */ {T_EXTR, SKCS5(4)}, /* [ */ {T_EXTR, SKCS1(2)}, /* backslash */ {T_EXTR, SKCS5(3)}, /* ] */ {T_CMPX, SKSS6(4)}, /* ^ */ {T_CMPX, SKSS4(0)}, /* _ */ {T_CMPX, SKSS0(2)}, /* ` */ {T_MAIN, SPK_A}, /* a */ {T_MAIN, SPK_B}, /* b */ {T_MAIN, SPK_C}, /* c */ {T_MAIN, SPK_D}, /* d */ {T_MAIN, SPK_E}, /* e */ {T_MAIN, SPK_F}, /* f */ {T_MAIN, SPK_G}, /* g */ {T_MAIN, SPK_H}, /* h */ {T_MAIN, SPK_I}, /* i */ {T_MAIN, SPK_J}, /* j */ {T_MAIN, SPK_K}, /* k */ {T_MAIN, SPK_L}, /* l */ {T_MAIN, SPK_M}, /* m */ {T_MAIN, SPK_N}, /* n */ {T_MAIN, SPK_O}, /* o */ {T_MAIN, SPK_P}, /* p */ {T_MAIN, SPK_Q}, /* q */ {T_MAIN, SPK_R}, /* r */ {T_MAIN, SPK_S}, /* s */ {T_MAIN, SPK_T}, /* t */ {T_MAIN, SPK_U}, /* u */ {T_MAIN, SPK_V}, /* v */ {T_MAIN, SPK_W}, /* w */ {T_MAIN, SPK_X}, /* x */ {T_MAIN, SPK_Y}, /* y */ {T_MAIN, SPK_Z}, /* z */ {T_EXTR, SKCS1(3)}, /* { */ {T_EXTR, SKCS1(1)}, /* | */ {T_EXTR, SKCS1(4)}, /* } */ {T_EXTR, SKCS1(0)}, /* ~ */ }; static struct spnamedkey spkey_misc[] = { {"none", SKE, SKE}, {"space", SPK_SPACE, SKE}, {"enter", SPK_ENTER, SKE}, {"capsshift", SPK_CAPSSHIFT, SKE}, {"symbolshift", SPK_SYMBOLSHIFT, SKE}, {"kempston_up", SKE, KEMP(KEMPU)}, {"kempston_down", SKE, KEMP(KEMPD)}, {"kempston_left", SKE, KEMP(KEMPL)}, {"kempston_right", SKE, KEMP(KEMPR)}, {"kempston_fire", SKE, KEMP(KEMPF)}, {NULL, SKE, SKE} }; #define MAXBASEKEYS 128 static struct spbasekey basekeys[MAXBASEKEYS]; static int numbasekeys; static struct spbasekey customkeys[MAXBASEKEYS]; static int numcustomkeys = 0; static struct spbasekey normalkeys[] = { {'0', SPK_0, SKE}, /* 0 */ {'1', SPK_1, SKE}, /* 1 */ {'2', SPK_2, SKE}, /* 2 */ {'3', SPK_3, SKE}, /* 3 */ {'4', SPK_4, SKE}, /* 4 */ {'5', SPK_5, SKE}, /* 5 */ {'6', SPK_6, SKE}, /* 6 */ {'7', SPK_7, SKE}, /* 7 */ {'8', SPK_8, SKE}, /* 8 */ {'9', SPK_9, SKE}, /* 9 */ {'a', SPK_A, SKE}, /* a */ {'b', SPK_B, SKE}, /* b */ {'c', SPK_C, SKE}, /* c */ {'d', SPK_D, SKE}, /* d */ {'e', SPK_E, SKE}, /* e */ {'f', SPK_F, SKE}, /* f */ {'g', SPK_G, SKE}, /* g */ {'h', SPK_H, SKE}, /* h */ {'i', SPK_I, SKE}, /* i */ {'j', SPK_J, SKE}, /* j */ {'k', SPK_K, SKE}, /* k */ {'l', SPK_L, SKE}, /* l */ {'m', SPK_M, SKE}, /* m */ {'n', SPK_N, SKE}, /* n */ {'o', SPK_O, SKE}, /* o */ {'p', SPK_P, SKE}, /* p */ {'q', SPK_Q, SKE}, /* q */ {'r', SPK_R, SKE}, /* r */ {'s', SPK_S, SKE}, /* s */ {'t', SPK_T, SKE}, /* t */ {'u', SPK_U, SKE}, /* u */ {'v', SPK_V, SKE}, /* v */ {'w', SPK_W, SKE}, /* w */ {'x', SPK_X, SKE}, /* x */ {'y', SPK_Y, SKE}, /* y */ {'z', SPK_Z, SKE}, /* z */ {-1, SKE, SKE} }; static struct spbasekey extendedkeys[] = { {' ', SPK_SPACE, SKE}, /* space */ {TRKS(SK_Return), SPK_ENTER, SKE}, /* enter */ {TRKS(SK_KP_Enter), SPK_ENTER, SKE}, {TRKS(SK_Shift_L), SPK_CAPSSHIFT, SKE}, /* caps shift */ {TRKS(SK_Shift_R), SPK_SYMBOLSHIFT, SKE}, /* symbol shift */ {TRKS(SK_BackSpace), SPK_BS, SKE}, /* backspace */ {TRKS(SK_Delete), SPK_BS, SKE}, {TRKS(SK_KP_Delete), SPK_BS, SKE}, {TRKS(SK_Escape), SPK_EDIT, SKE}, /* caps shift + '1' */ {-1, SKE, SKE} }; static struct spbasekey spectrumkeys[] = { {',', SPK_SYMBOLSHIFT, SKE}, {'.', SPK_SPACE, SKE}, {';', SPK_ENTER, SKE}, {-1, SKE, SKE} }; static struct spbasekey compatkeys[] = { {TRKS(SK_Shift_L), SPK_CAPSSHIFT, SKE}, /* caps shift */ {TRKS(SK_Shift_R), SPK_CAPSSHIFT, SKE}, {TRKS(SK_Alt_L), SPK_SYMBOLSHIFT, SKE}, /* symbol shift */ {TRKS(SK_Alt_R), SPK_SYMBOLSHIFT, SKE}, {TRKS(SK_Meta_L), SPK_SYMBOLSHIFT, SKE}, {TRKS(SK_Meta_R), SPK_SYMBOLSHIFT, SKE}, #if TRUEKOMPAT {TRKS(SK_Control_L), SPK_EXTRA, SKE}, /* caps shift + symbol shift */ {TRKS(SK_Control_R), SPK_EXTRA, SKE}, #endif {-1, SKE, SKE} }; static struct spbasekey shiftedcurs[] = { {TRKS(SK_Up), SPK_UP, SKE}, /* up */ {TRKS(SK_KP_Up), SPK_UP, SKE}, {TRKS(SK_Down), SPK_DOWN, SKE}, /* down */ {TRKS(SK_KP_Down), SPK_DOWN, SKE}, {TRKS(SK_Left), SPK_LEFT, SKE}, /* left */ {TRKS(SK_KP_Left), SPK_LEFT, SKE}, {TRKS(SK_Right), SPK_RIGHT, SKE}, /* right */ {TRKS(SK_KP_Right), SPK_RIGHT, SKE}, {-1, SKE, SKE} }; static struct spbasekey rawcurs[] = { {TRKS(SK_Up), SPK_7, SKE}, /* up */ {TRKS(SK_KP_Up), SPK_7, SKE}, {TRKS(SK_Down), SPK_6, SKE}, /* down */ {TRKS(SK_KP_Down), SPK_6, SKE}, {TRKS(SK_Left), SPK_5, SKE}, /* left */ {TRKS(SK_KP_Left), SPK_5, SKE}, {TRKS(SK_Right), SPK_8, SKE}, /* right */ {TRKS(SK_KP_Right), SPK_8, SKE}, {-1, SKE, SKE} }; static struct spbasekey joycurs[] = { {TRKS(SK_Up), SKE, KEMP(KEMPU)}, /* up */ {TRKS(SK_KP_Up), SKE, KEMP(KEMPU)}, {TRKS(SK_Down), SKE, KEMP(KEMPD)}, /* down */ {TRKS(SK_KP_Down), SKE, KEMP(KEMPD)}, {TRKS(SK_Left), SKE, KEMP(KEMPL)}, /* left */ {TRKS(SK_KP_Left), SKE, KEMP(KEMPL)}, {TRKS(SK_Right), SKE, KEMP(KEMPR)}, /* right */ {TRKS(SK_KP_Right), SKE, KEMP(KEMPR)}, {TRKS(SK_KP_Insert), SKE, KEMP(KEMPF)}, /* fire */ {TRKS(SK_Insert), SKE, KEMP(KEMPF)}, {TRKS(SK_KP_Delete), SKE, KEMP(KEMPF)}, {TRKS(SK_KP_Home), SKE, KEMP(KEMPU | KEMPL)}, /* up + left*/ {TRKS(SK_Home), SKE, KEMP(KEMPU | KEMPL)}, {TRKS(SK_KP_Page_Up), SKE, KEMP(KEMPU | KEMPR)}, /* up + right*/ {TRKS(SK_Page_Up), SKE, KEMP(KEMPU | KEMPR)}, {TRKS(SK_KP_End), SKE, KEMP(KEMPD | KEMPL)}, /* down + left*/ {TRKS(SK_End), SKE, KEMP(KEMPD | KEMPL)}, {TRKS(SK_KP_Page_Down), SKE, KEMP(KEMPD | KEMPR)}, /* down + right*/ {TRKS(SK_Page_Down), SKE, KEMP(KEMPD | KEMPR)}, {-1, SKE, SKE} }; int spkey_new_custom(int key) { if(numcustomkeys >= MAXBASEKEYS) return 0; customkeys[numcustomkeys].index = key; SP_SETEMPTY(customkeys[numcustomkeys].kb); SP_SETEMPTY(customkeys[numcustomkeys].misc); numcustomkeys++; return 1; } int spkey_add_custom(const char *name) { int curr; curr = numcustomkeys - 1; if(!name[1] && isalnum(name[0])) { int ai; ai = tolower(name[0])-32; SP_COMBINE(customkeys[curr].kb, spkey_ascii[ai].kb); return 1; } else { int i; for(i = 0; spkey_misc[i].name != NULL; i++) { if(mis_strcasecmp(spkey_misc[i].name, name) == 0) { SP_COMBINE(customkeys[curr].kb, spkey_misc[i].kb); SP_COMBINE(customkeys[curr].misc, spkey_misc[i].misc); return 1; } } } return 0; } static int key_reset(struct keystate *ck) { if(ck->state == 2 && sp_int_ctr >= ck->frame) { ck->state = 0; return 1; } else return 0; } void process_keys(void) { int i; struct keystate *ck; int tsh; int kalone; static int extrai = 0; static qbyte extraendframe; if(extrai && !spkb_kbstate[extrai].state) extrai = 0; if(!spkb_state_changed && (!extrai || !extraendframe)) return; #ifdef DEBUG_KEYS fprintf(stderr, "-- "); for(i = 0; i < NR_SPKEYS; i++) if(spkb_kbstate[i].state) fprintf(stderr, "%03X ", i); fprintf(stderr, "\n"); #endif SP_SETEMPTY(spkey_state); SP_SETEMPTY(spmisc_state); kalone = 0; ck = spkb_kbstate + spkb_last.index; tsh = spkb_last.modif & trueshift; key_reset(ck); if(spkb_allow_ascii && ck->state && (!ck->base || tsh)) { unsigned ks; ks = tsh ? spkb_last.shifted : spkb_last.keysym; if(ks >= 32 && ks < 127) { if(spkey_ascii[ks-32].type <= T_CMPX) { SP_COMBINE(spkey_state, spkey_ascii[ks-32].kb); kalone = 1; } else if(spkey_ascii[ks-32].type == T_EXTR) { if(!extrai || sp_int_ctr < extraendframe) { if(!extrai) { extrai = spkb_last.index; extraendframe = sp_int_ctr + 1; } SP_COMBINE(spkey_state, spk_extra); } else { SP_COMBINE(spkey_state, spkey_ascii[ks-32].kb); extraendframe = 0; } kalone = 1; } } } if(!kalone) { for(i = 0; i < numbasekeys; i++) { ck = spkb_kbstate + basekeys[i].index; key_reset(ck); if(ck->state) { SP_COMBINE(spkey_state, basekeys[i].kb); SP_COMBINE(spmisc_state, basekeys[i].misc); } } } SP_COMBINE(spkey_state, kb_mkey); spkb_refresh(); spkb_state_changed = 0; } void clear_keystates(void) { int i; for(i = 0; i < NR_SPKEYS; i++) spkb_kbstate[i].state = 0; spkb_last.index = 0; SP_SETEMPTY(spkey_state); SP_SETEMPTY(kb_mkey); SP_SETEMPTY(spmisc_state); spkb_refresh(); } static void keycpy(struct spbasekey *to, struct spbasekey *from) { to->index = from->index; SP_COPY(to->kb, from->kb); SP_COPY(to->misc, from->misc); } static void copy_key(struct spbasekey *addk) { int i; int nindex; nindex = addk->index; if(SP_NONEMPTY(addk->kb) || SP_NONEMPTY(addk->misc)) { for(i = 0; i < numbasekeys; i++) { if(basekeys[i].index == nindex) { /* Replace */ keycpy(&basekeys[i], addk); return; } } if(numbasekeys < MAXBASEKEYS - 1) { /* Add */ keycpy(&basekeys[numbasekeys], addk); spkb_kbstate[nindex].base = 1; numbasekeys++; } } else { /* Delete */ for(i = 0; i < numbasekeys; i++) { if(basekeys[i].index == nindex) { i++; for(; i < numbasekeys; i++) keycpy(&basekeys[i-1], &basekeys[i]); spkb_kbstate[nindex].base = 0; numbasekeys--; break; } } } } static void copy_basekeys(struct spbasekey *addk) { int i; for(i = 0; addk[i].index >= 0; i++) copy_key(&addk[i]); } static unsigned transform_shift(int modif) { if(!modif) return 0; else return (1 << (modif - 1)); } void init_basekeys(void) { int i; numbasekeys = 0; for(i = 0; i < NR_SPKEYS; i++) spkb_kbstate[i].base = 0; customkeys[numcustomkeys].index = -1; copy_basekeys(normalkeys); copy_basekeys(extendedkeys); copy_basekeys(shiftedcurs); switch(keyboard_type) { case 0: break; case 1: copy_basekeys(spectrumkeys); break; case 2: if(spkb_trueshift == -1) spkb_trueshift = 0; #if TRUEKOMPAT if(spkb_funcshift == -1) spkb_funcshift = 0; #endif copy_basekeys(compatkeys); break; case 3: copy_basekeys(customkeys); break; } switch(cursor_type) { case 0: break; case 1: copy_basekeys(rawcurs); break; case 2: copy_basekeys(joycurs); break; } if(spkb_trueshift == -1) spkb_trueshift = 4; /* mod1 */ if(spkb_funcshift == -1) spkb_funcshift = 3; /* control */ trueshift = transform_shift(spkb_trueshift); funcshift = transform_shift(spkb_funcshift); } void spkb_refresh(void) { int port, pb; int i, j, changed; byte *km, *kmo; byte mm; byte pv; spkeyboard statemx; km = spkey_state; kmo = oldstate; changed = 0; for(i = 8; i; i--) { if(*km != *kmo) *kmo = *km, changed = 1; km++, kmo++; } if(changed) { /* Matrix behavior: ONLY 1 level, does anybody need more ? */ for(i = 0; i < 8; i++) { pv = spkey_state[i]; mm = pv; if(pv) { km = spkey_state; for(j = 8; j; j--) { if((*km & pv) & 0x1F) mm |= *km; km++; } } statemx[i] = mm; } for(port = 0; port < 256; port++) { km = statemx; pv = 0; pb = port; for(i = 8; i; i--) { if(!(pb & 1)) pv |= *km; pb >>= 1; km++; } sp_fe_inport_high[port] = (sp_fe_inport_high[port] | 0x1F) & ~(pv & 0x1F); } } pv = spmisc_state[0]; if((pv & KEMPR) && (pv & KEMPL)) pv &= ~(KEMPR | KEMPL); if((pv & KEMPU) && (pv & KEMPD)) pv &= ~(KEMPD | KEMPU); z80_inports[KEMP_PORT] = pv; } static void print_help(int lev) { switch(lev) { case 0: printf(" = ZX Spectrum Emulation (C) Szeredi Miklos 1996-98 = \n" " ----------------------------------------------------------\n" " Left Shift Spectrum - CAPS SHIFT \n" " Right Shift Spectrum - SYMBOL SHIFT \n" " Alt \"True\" Shift \n" " Ctrl Commands \n" " ----------------------------------------------------------\n" " Ctrl-c F10 Quit \n" " Ctrl-h F1 More help \n" " Ctrl-t F2 Save snapshot \n" " Ctrl-l F3 Load snapshot \n" " Ctrl-p F4 Play tape \n" " Ctrl-q F5 Reset \n" " Ctrl-o F6 Pause/unpause tape \n" " Ctrl-s F7 Stop tape \n" " Ctrl-f Fast \n" " Ctrl-n Normal speed \n" " Ctrl-b Pause/Unpause emulator \n" " Ctrl-m Toggle sound \n" " Ctrl-y Toggle quick loading of tapes \n" " Ctrl-\\ F9 Refresh screen / reset keyboard \n" " ==========================================================\n"); break; case 1: printf(" = ZX Spectrum Emulation (C) Szeredi Miklos 1996-98 = \n" " ----------------------------------------------------------\n" " More help: \n" " ----------------------------------------------------------\n" " Ctrl-h F1 Normal help \n" " Ctrl-k Display (undisplay) keyboard \n" " Ctrl-w Ctrl-F2 Save temporary snapshot \n" " Ctrl-e Ctrl-F3 Load temporary snapshot \n" " Ctrl-r Save to tapefile \n" " Ctrl-, Reduce screen size (X only) \n" " Ctrl-. Increase screen size (X only) \n" " Ctrl-. Toggle private color-map (X only) \n" " Ctrl-= Decrease frame frequency \n" " Ctrl-- Increase frame frequency \n" " Ctrl-] Increase sound buffer size \n" " Ctrl-[ Decrease sound buffer size \n" " ==========================================================\n"); break; case 2: printf( " --------------------------------------------------------------------- \n" "|BLUE |RED |MAGENT|GREEN |CYAN |YELLOW|WHITE | | |BLACK | \n" "| 1 ! | 2 @ | 3 # | 4 $ | 5 %% | 6 & | 7 ' | 8 ( | 9 ) | 0 _ | \n" "|EDIT |CAPS |TRU VD|INV VD| <- | v | ^ | -> |GRAPH |DELETE| \n" "|DEF FN|FN |LINE |OPEN# |CLOSE#|MOVE |ERASE |POINT |CAT |FORMAT| \n" " ------------------------------------------------------------------------ \n" " |SIN |COS |TAN |INT |RND |STR$ |CHR$ |CODE |PEEK |TAB | \n" " | Q <= | W <> | E >= | R < | T > | Y AND| U OR | I AT | O ; | P \" | \n" " |PLOT |DRAW |REM |RUN |RAND |RETURN|IF |INPUT |POKE |PRINT | \n" " |ASN |ACS |ATN |VERIFY|MERGE | [ | ] |IN |OUT |(C) | \n" " ------------------------------------------------------------------------ \n" " |READ |RESTOR|DATA |SGN |ABS |SQR |VAL |LEN |USR | |\n" " |A STOP| S NOT|D STEP| F TO |G THEN| H ^ | J - | K + | L = | |\n" " |NEW |SAVE |DIM |FOR |GO TO |GO SUB|LOAD |LIST |LET |ENTER|\n" " | ~ | | | \\ | { | } |CIRCLE|VAL$ |SCRN$ |ATTR | |\n" " -------------------------------------------------------------------------- \n" " | |LN |EXP |LPRINT|LLIST |BIN |INKEY$| PI | | | \n" " | CAPS | Z : | X GBP| C ? | V / | B * | N , | M . |SYMBOL| BREAK | \n" " | SHIFT |COPY |CLEAR |CONT |CLS |BORDER|NEXT |PAUSE |SHIFT | SPACE | \n" " | |BEEP |INK |PAPER |FLASH |BRIGHT|OVER |INVERS| | | \n" " ----------------------------------------------------------------------- \n" ); break; } if(need_switch_mode) { printf(" Press ENTER to continue! \n"); while(getchar() != '\n'); } } #ifdef DEBUG_Z80 extern int deb_steps; #endif #define CF(x) ((x) + 12) int spkey_keyfuncs(void) { static int help_mode = 0; int lch; int new_help_mode; lch = spkb_last.keysym; if(!(spkb_last.modif & funcshift) && (lch < SK_F1 || lch > SK_F12 || (spkb_last.modif & SKMod1Mask))) return 0; if(lch >= 'A' && lch <= 'Z') lch += 32; if((spkb_last.modif & funcshift) && lch >= SK_F1 && lch <= SK_F12) lch = CF(lch); new_help_mode = 0; switch(lch) { case 'c': case SK_F10: exit(0); case 'p': case SK_F4: spkey_textmode(); start_play(); spkey_screenmode(); break; case 'r': spkey_textmode(); start_rec(); spkey_screenmode(); break; case 'o': case SK_F6: pause_play(); break; case 's': case SK_F7: stop_play(); break; case 'f': sp_nosync = 1; sp_paused = 0; autoclose_sound(); break; case 'n': sp_nosync = 0; sp_paused = 0; break; case 'b': sp_paused = !sp_paused; if(sp_paused) clear_keystates(); sprintf(msgbuf, "%s emulator", sp_paused ? "Paused" : "Unpaused"); put_msg(msgbuf); break; case 'q': case SK_F5: z80_reset(); break; case 't': case SK_F2: spkey_textmode(); save_snapshot(); spkey_screenmode(); break; case 'l': case SK_F3: spkey_textmode(); load_snapshot(); spkey_screenmode(); break; #ifdef DEBUG_Z80 case 'v': deb_steps = 0; break; #endif case '=': if(showframe < 10) showframe++; sprintf(msgbuf, "showframe: %i", showframe); put_msg(msgbuf); break; case '-': if(showframe > 1) showframe--; sprintf(msgbuf, "showframe: %i", showframe); put_msg(msgbuf); break; case ']': if(bufframes < 25) bufframes++; sprintf(msgbuf, "msgbuf, bufframes: %i", bufframes); put_msg(msgbuf); setbufsize(); break; case '[': if(bufframes > 1) bufframes--; sprintf(msgbuf, "bufframes: %i", bufframes); put_msg(msgbuf); setbufsize(); break; case 'm': sound_on = !sound_on; sprintf(msgbuf, "sound %s", sound_on ? "on" : "off"); put_msg(msgbuf); break; case 'h': case SK_F1: case SK_Help: spkey_textmode(); print_help(help_mode); spkey_screenmode(); new_help_mode = 1 - help_mode; break; case 'k': spkey_textmode(); if(!display_keyboard()) print_help(2); spkey_screenmode(); break; case '\\': case SK_F9: spscr_refresh_colors(); /* sp_init_screen_mark(); already donde in prev fn. */ clear_keystates(); break; case '.': resize_spect_scr(scrmul+1); break; case ',': resize_spect_scr(scrmul-1); break; case 'y': sp_quick_load = !sp_quick_load; sprintf(msgbuf, "Quick load %s", sp_quick_load ? "on" : "off"); put_msg(msgbuf); break; case 'w': case CF(SK_F2): save_quick_snapshot(); break; case 'e': case CF(SK_F3): load_quick_snapshot(); break; case 'j': privatemap = !privatemap; sprintf(msgbuf, "Private colormap %s", privatemap ? "on" : "off"); put_msg(msgbuf); spscr_refresh_colors(); break; } help_mode = new_help_mode; return 1; } spectemu-0.94/spkey.h0100644000175000017500000000200606526050777015056 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPKEY_H #define SPKEY_H extern void spkb_process_events(int evenframe); extern void init_spect_key(void); extern int spkey_new_custom(int key); extern int spkey_add_custom(const char *name); #endif /* SPKEY_H */ spectemu-0.94/spkey_p.h0100644000175000017500000001362506526325756015410 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPKEY_P_H #define SPKEY_P_H #include "z80_type.h" struct keystate { dbyte press; byte state; byte base; qbyte frame; }; struct onekey { int index; unsigned keysym; unsigned shifted; unsigned modif; }; typedef byte spkeyboard[8]; #define SPIP(spk, h) (((qbyte *) (spk))[h]) #define SP_COMBINE(spk1, spk2) \ SPIP(spk1, 0) |= SPIP(spk2, 0), \ SPIP(spk1, 1) |= SPIP(spk2, 1) #define SP_SUBSTRACT(spk1, spk2) \ SPIP(spk1, 0) &= ~SPIP(spk2, 0), \ SPIP(spk1, 1) &= ~SPIP(spk2, 1) #define SP_NONEMPTY(spk) (SPIP(spk, 0) || SPIP(spk, 1)) #define SP_CONTAINS(spk1, spk2) \ ((SPIP(spk1, 0) & SPIP(spk2, 0)) || (SPIP(spk1, 1) & SPIP(spk2, 1))) #define SP_SETEMPTY(spk) \ SPIP(spk, 0) = 0, \ SPIP(spk, 1) = 0 #define SP_COPY(spk1, spk2) \ SPIP(spk1, 0) = SPIP(spk2, 0), \ SPIP(spk1, 1) = SPIP(spk2, 1) #define TRKS(ks) ((ks) - 0xFF00 + 0x100) #define KS_TO_KEY(ks) \ (((ks) >= 0x0000 && (ks) <= 0x00FF) ? (int) (ks) : \ (((ks) >= 0xFF00 && (ks) <= 0xFFFF) ? (int) TRKS(ks) : -1)) /* These are _accidently_ the same as the XK_ counterparts */ #define SK_BackSpace 0xFF08 /* back space, back char */ #define SK_Tab 0xFF09 #define SK_Linefeed 0xFF0A /* Linefeed, LF */ #define SK_Clear 0xFF0B #define SK_Return 0xFF0D /* Return, enter */ #define SK_Pause 0xFF13 /* Pause, hold */ #define SK_Scroll_Lock 0xFF14 #define SK_Sys_Req 0xFF15 #define SK_Escape 0xFF1B #define SK_Delete 0xFFFF /* Delete, rubout */ #define SK_Home 0xFF50 #define SK_Left 0xFF51 /* Move left, left arrow */ #define SK_Up 0xFF52 /* Move up, up arrow */ #define SK_Right 0xFF53 /* Move right, right arrow */ #define SK_Down 0xFF54 /* Move down, down arrow */ #define SK_Page_Up 0xFF55 /* Prior, previous */ #define SK_Page_Down 0xFF56 /* Next */ #define SK_End 0xFF57 /* EOL */ #define SK_Begin 0xFF58 /* BOL */ #define SK_Select 0xFF60 /* Select, mark */ #define SK_Print 0xFF61 #define SK_Execute 0xFF62 /* Execute, run, do */ #define SK_Insert 0xFF63 /* Insert, insert here */ #define SK_Undo 0xFF65 /* Undo, oops */ #define SK_Redo 0xFF66 /* redo, again */ #define SK_Menu 0xFF67 #define SK_Find 0xFF68 /* Find, search */ #define SK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ #define SK_Help 0xFF6A /* Help */ #define SK_Break 0xFF6B #define SK_Mode_switch 0xFF7E /* Character set switch */ #define SK_Num_Lock 0xFF7F #define SK_KP_Space 0xFF80 /* space */ #define SK_KP_Tab 0xFF89 #define SK_KP_Enter 0xFF8D /* enter */ #define SK_KP_F1 0xFF91 /* PF1, KP_A, ... */ #define SK_KP_F2 0xFF92 #define SK_KP_F3 0xFF93 #define SK_KP_F4 0xFF94 #define SK_KP_Home 0xFF95 #define SK_KP_Left 0xFF96 #define SK_KP_Up 0xFF97 #define SK_KP_Right 0xFF98 #define SK_KP_Down 0xFF99 #define SK_KP_Page_Up 0xFF9A #define SK_KP_Page_Down 0xFF9B #define SK_KP_End 0xFF9C #define SK_KP_Begin 0xFF9D #define SK_KP_Insert 0xFF9E #define SK_KP_Delete 0xFF9F #define SK_KP_Equal 0xFFBD /* equals */ #define SK_KP_Multiply 0xFFAA #define SK_KP_Add 0xFFAB #define SK_KP_Separator 0xFFAC /* separator, often comma */ #define SK_KP_Subtract 0xFFAD #define SK_KP_Decimal 0xFFAE #define SK_KP_Divide 0xFFAF #define SK_KP_0 0xFFB0 #define SK_KP_1 0xFFB1 #define SK_KP_2 0xFFB2 #define SK_KP_3 0xFFB3 #define SK_KP_4 0xFFB4 #define SK_KP_5 0xFFB5 #define SK_KP_6 0xFFB6 #define SK_KP_7 0xFFB7 #define SK_KP_8 0xFFB8 #define SK_KP_9 0xFFB9 #define SK_F1 0xFFBE #define SK_F2 0xFFBF #define SK_F3 0xFFC0 #define SK_F4 0xFFC1 #define SK_F5 0xFFC2 #define SK_F6 0xFFC3 #define SK_F7 0xFFC4 #define SK_F8 0xFFC5 #define SK_F9 0xFFC6 #define SK_F10 0xFFC7 #define SK_F11 0xFFC8 #define SK_F12 0xFFC9 #define SK_Shift_L 0xFFE1 /* Left shift */ #define SK_Shift_R 0xFFE2 /* Right shift */ #define SK_Control_L 0xFFE3 /* Left control */ #define SK_Control_R 0xFFE4 /* Right control */ #define SK_Caps_Lock 0xFFE5 /* Caps lock */ #define SK_Shift_Lock 0xFFE6 /* Shift lock */ #define SK_Meta_L 0xFFE7 /* Left meta */ #define SK_Meta_R 0xFFE8 /* Right meta */ #define SK_Alt_L 0xFFE9 /* Left alt */ #define SK_Alt_R 0xFFEA /* Right alt */ #define SK_Super_L 0xFFEB /* Left super */ #define SK_Super_R 0xFFEC /* Right super */ #define SK_Hyper_L 0xFFED /* Left hyper */ #define SK_Hyper_R 0xFFEE /* Right hyper */ /* Modifier masks */ #define SKShiftMask (1<<0) #define SKLockMask (1<<1) #define SKControlMask (1<<2) #define SKMod1Mask (1<<3) #define SKMod2Mask (1<<4) #define SKMod3Mask (1<<5) #define SKMod4Mask (1<<6) #define SKMod5Mask (1<<7) #define NR_SPKEYS 512 #define ISFKEY(ks) ((ks) >= SK_F1 && (ks) <= SK_F12) extern volatile int accept_keys; extern qbyte sp_int_ctr; extern struct keystate spkb_kbstate[]; extern struct onekey spkb_last; extern int spkb_state_changed; extern spkeyboard spkey_state; extern spkeyboard kb_mkey; extern void spkey_textmode(void); extern void spkey_screenmode(void); extern const int need_switch_mode; extern int spkey_keyfuncs(void); extern void spkb_refresh(void); extern void clear_keystates(void); extern int display_keyboard(void); extern void process_keys(void); extern void init_basekeys(void); #endif /* SPKEY_P_H */ spectemu-0.94/spscr.c0100644000175000017500000001354106521635132015043 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "spscr_p.h" #include "spscr.h" #include "spperif.h" #include "z80.h" #include #include int color_type = 0; #define N0 0x04 #define N1 0x34 #define B0 0x08 #define B1 0x3F struct rgb *spscr_crgb; static struct rgb norm_colors[COLORNUM]={ {0,0,0},{N0,N0,N1},{N1,N0,N0},{N1,N0,N1}, {N0,N1,N0},{N0,N1,N1},{N1,N1,N0},{N1,N1,N1}, {0x15,0x15,0x15},{B0,B0,B1},{B1,B0,B0},{B1,B0,B1}, {B0,B1,B0},{B0,B1,B1},{B1,B1,B0},{B1,B1,B1} }; static struct rgb gray_colors[COLORNUM]={ {0,0,0},{20,20,20},{26,26,26},{32,32,32}, {38,38,38},{44,44,44},{50,50,50},{56,56,56}, {16,16,16},{23,23,23},{30,30,30},{36,36,36}, {43,43,43},{50,50,50},{56,56,56},{63,63,63} }; struct rgb custom_colors[COLORNUM]={ {0,0,0},{N0,N0,N1},{N1,N0,N0},{N1,N0,N1}, {N0,N1,N0},{N0,N1,N1},{N1,N1,N0},{N1,N1,N1}, {0x15,0x15,0x15},{B0,B0,B1},{B1,B0,B0},{B1,B0,B1}, {B0,B1,B0},{B0,B1,B1},{B1,B1,B0},{B1,B1,B1} }; #define TABOFFS 2 volatile int screen_visible = 1; volatile int accept_keys = 1; byte *update_screen_line(byte *scrp, int coli, int scri, int border, qbyte *cmarkp) { qbyte *scrptr; qbyte brd_color; int i; qbyte *tmptr, *mptr; qbyte mark, cmark; cmark = *cmarkp; scrptr = (qbyte *) scrp; if(scri >= 0) { /* normal line */ if(SPNM(border_update)) { brd_color = SPNM(colors)[border]; brd_color |= brd_color << 8; brd_color |= brd_color << 16; for(i = 8; i; i--) *scrptr++ = brd_color; scrptr += 0x40; for(i = 8; i; i--) *scrptr++ = brd_color; scrptr -= 0x48; } else scrptr += 0x08; tmptr = SPNM(scr_mark) + 0x2C0 + (coli >> 3); mark = *tmptr; if(!(coli & 0x07)) { cmark = mark; *tmptr = 0; } else cmark |= mark; mptr = SPNM(scr_mark) + scri; mark = *mptr | cmark; if(mark) { byte *spmp, *spcp; qbyte *scr_tab; *mptr = 0; SPNM(imag_mark)[coli] |= mark; SPNM(imag_horiz) |= mark; coli >>= 3; SPNM(imag_vert) |= (1 << coli); spmp = PRNM(proc).mem + (scri << 5); spcp = PRNM(proc).mem + 0x5800 + (coli << 5); if(!SPNM(flash_state)) scr_tab = SPNM(scr_f0_table); else scr_tab = SPNM(scr_f1_table); for(i = 32; i; i--) { register dbyte spcx, spmx; spcx = (*spcp++) << 6; spmx = *spmp++; *scrptr++ = scr_tab[spcx|((spmx & 0xf0) >> 4)]; *scrptr++ = scr_tab[spcx|((spmx & 0x0f))]; } scrptr +=0x08; } else scrptr += 0x48; } else if(scri == -1) { /* only border */ if(SPNM(border_update)) { brd_color = SPNM(colors)[border]; brd_color |= brd_color << 8; brd_color |= brd_color << 16; for(i = 0x50; i; i--) *scrptr++ = brd_color; } else scrptr += 0x50; } *cmarkp = cmark; return (byte *) scrptr; } void translate_screen(void) { int border, scline; byte *scrptr; qbyte cmark = 0; scrptr = (byte *) SPNM(image); border = DANM(ula_outport) & 0x07; if(border != SPNM(lastborder)) { SPNM(border_update) = 2; SPNM(lastborder) = border; } for(scline = 0; scline < (TMNUM / 2); scline++) scrptr = update_screen_line(scrptr, SPNM(coli)[scline], SPNM(scri)[scline], border, &cmark); } void spscr_init_mask_color(void) { int clb; int bwb; int hb; int ix, j; int bc, fc; byte *tab_f0, *tab_f1; sp_scr_f0_table = (qbyte *) (PRNM(proc).mem + 0x10000); sp_scr_f1_table = (qbyte *) (PRNM(proc).mem + 0x20000); sp_colors[8] = sp_colors[0]; for(clb = 0; clb < 256; clb++) for(hb = 0; hb < 16; hb++) { bc = (clb & 0x38) >> 3; fc = clb & 0x07; if(clb & 0x40) { fc |= 0x08; bc |= 0x08; } bwb = hb; ix = (clb << 8) + (hb << TABOFFS); tab_f0 = ((byte *) sp_scr_f0_table) + ix + 3; tab_f1 = ((byte *) sp_scr_f1_table) + ix + 3; for(j = 4; j; bwb >>= 1, j--) { *tab_f0-- = (byte) sp_colors[(bwb & 0x01) ? fc : bc]; *tab_f1-- = (byte) sp_colors[(clb & 0x80) ? ((bwb & 0x01) ? bc : fc) : ((bwb & 0x01) ? fc : bc)]; } } } void flash_change(void) { int i,j; byte *scp; qbyte *mcp; register unsigned int val; mcp = sp_scr_mark + 0x2C0; scp = z80_proc.mem + 0x5800; for(i = 24; i; mcp++, i--) { val = 0; for(j = 32; j; scp++, j--) { val >>= 1; if(*scp & 0x80) val |= (1 << 31); } *mcp |= val; } } void spscr_init_line_pointers(int lines) { int i; int bs; int y; int scline; bs = (lines - 192) / 2; for(i = 0; i < PORT_TIME_NUM; i++) { sp_scri[i] = -2; if(i < ODDHF) scline = i; else scline = i - ODDHF; if(scline >= 64-bs && scline < 256+bs) { if(scline >= 64 && scline < 256) { y = scline - 64; sp_coli[i] = y; sp_scri[i] = 0x200 + (y & 0xC0) + ((y & 0x07) << 3) + ((y & 0x38) >> 3); } else sp_scri[i] = -1; } } } void spscr_init_colors(void) { spscr_crgb = norm_colors; switch(color_type) { case 0: spscr_crgb = norm_colors; break; case 1: spscr_crgb = gray_colors; break; case 2: spscr_crgb = custom_colors; break; } } spectemu-0.94/spscr.h0100644000175000017500000000241606526303667015061 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPSCR_H #define SPSCR_H #include "z80_type.h" extern int scrmul; extern volatile int screen_visible; extern void init_spect_scr(void); extern void destroy_spect_scr(void); extern void resize_spect_scr(int newsize); extern void update_screen(void); extern void flash_change(void); extern void translate_screen(void); extern byte *update_screen_line(byte *scrp, int coli, int scri, int border, qbyte *cmarkp); extern void spscr_refresh_colors(void); #endif /* SPSCR_H */ spectemu-0.94/spscr_p.h0100644000175000017500000000220706524377657015406 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPSCR_P_H #define SPSCR_P_H #define COLORNUM 16 struct rgb { int r, g, b; }; #define SCRSIZE 6912 #define COLORBEG 6144 extern struct rgb *spscr_crgb; extern struct rgb custom_colors[]; extern void spscr_init_mask_color(void); extern void spscr_init_line_pointers(int lines); extern void spscr_init_colors(void); #endif /* SPSCR_P_H */ spectemu-0.94/spsound.c0100644000175000017500000003142206524141515015402 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* #define DEBUG_AUDIO */ #include "spsound.h" #include "config.h" #include "spperif.h" #include "z80.h" #include "misc.h" #include "interf.h" #include int bufframes = 4; int sound_avail = 0; int sound_on = 1; int sound_to_autoclose = 1; char *sound_dev_name = NULL; int sound_sample_rate = 0; int sound_dsp_setfrag = 1; #ifdef HAVE_SOUND #include #include #include #include #include #include #include #include static int snd; static int sample_size = 8; static int channels = 1; #define SKIPTIME 5000 #define AUTOCLOSET 5 static int autocloset; #define REOPENT 5 static int opent = 0; static int last_not_played; #define SPS_OPENED 0 #define SPS_AUTOCLOSED -1 #define SPS_BUSY -2 #define SPS_CLOSED -3 #define SPS_NONEXIST -4 static int sndstate = SPS_CLOSED; static byte open_buf[TMNUM]; static void close_snd(int normal); const byte lin8_ulaw[] = { 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 83, 85, 87, 89, 91, 93, 95, 99, 103, 107, 111, 119, 255, 247, 239, 235, 231, 227, 223, 221, 219, 217, 215, 213, 211, 209, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 191, 190, 190, 189, 189, 188, 188, 187, 187, 186, 186, 185, 185, 184, 184, 183, 183, 182, 182, 181, 181, 180, 180, 179, 179, 178, 178, 177, 177, 176, 176, 175, 175, 175, 175, 174, 174, 174, 174, 173, 173, 173, 173, 172, 172, 172, 172, 171, 171, 171, 171, 170, 170, 170, 170, 169, 169, 169, 169, 168, 168, 168, 168, 167, 167, 167, 167, 166, 166, 166, 166, 165, 165, 165, 165, 164, 164, 164, 164, 163, 163, 163, 163, 162, 162, 162, 162, 161, 161, 161, 161, 160, 160, 160, 160, 159, 159, }; static int open_generic(void) { int openflags; int res; if(sndstate >= SPS_OPENED || sndstate <= SPS_NONEXIST) return 0; openflags = O_WRONLY; snd = open(sound_dev_name, openflags | O_NONBLOCK); if(snd < 0) { int errno_save; errno_save = errno; if(sndstate <= SPS_CLOSED || errno != EBUSY) { sprintf(msgbuf, "Could not open sound device '%s': %s", sound_dev_name, strerror(errno)); put_msg(msgbuf); } if(errno_save == EBUSY) sndstate = SPS_BUSY; else sndstate = SPS_NONEXIST; opent = time(NULL); return 0; } res = fcntl(snd, F_SETFL, openflags); if(res < 0) { sprintf(msgbuf, "Warning: fcntl failed on sound device: %s", strerror(errno)); put_msg(msgbuf); } sndstate = SPS_OPENED; sound_avail = 1; autocloset = time(NULL); last_not_played = 1; return 1; } static void close_generic(void) { if(sndstate >= SPS_OPENED) close(snd); sound_avail = 0; sndstate = SPS_CLOSED; opent = 0; } static void write_generic(int numsam) { int pl_at; int res; for(pl_at = 0; pl_at != numsam; ) { res = write(snd, sp_sound_buf+pl_at, (size_t) (numsam-pl_at)); if(res < 0) { /* Ignore 'Interrupted system call' errors */ if(errno != EINTR) { sprintf(msgbuf, "Error writing sound device: %s", strerror(errno)); put_msg(msgbuf); close_snd(0); return; } else return; } pl_at += res; if(pl_at != numsam) { struct timeval waittv; #ifdef DEBUG_AUDIO fprintf(stderr, "rem: %i\n", numsam - pl_at); #endif waittv.tv_sec = 0; waittv.tv_usec = SKIPTIME; select(0, NULL, NULL, NULL, &waittv); } } } /* -------- Open Sound System support -------- */ #ifdef OSS_SOUND #include #include #define VOLREDUCE 2 static int buffrag = 8; static void close_snd(int normal) { if(sndstate >= SPS_OPENED && normal) { int res; res = ioctl(snd,SOUND_PCM_SYNC,0); if(res < 0) { sprintf(msgbuf, "ioctl(SOUND_PCM_WRITE_SYNC, 0) failed: %s", strerror(errno)); put_msg(msgbuf); } } close_generic(); } #undef FRAG #define FRAG(x, y) ((((x) & 0xFFFF) << 16) | ((y) & 0xFFFF)) static void open_snd(void) { int parm; int frag; int res; int bufseg; int i; if(sound_dev_name == NULL) sound_dev_name = make_string(sound_dev_name, "/dev/dsp"); if(!sound_sample_rate) sound_sample_rate = 15625; if(!open_generic()) return; bufseg = bufframes * (TMNUM / 2) / (1 << buffrag); if(bufseg < 2) bufseg = 2; frag = FRAG(bufseg, buffrag); if(sound_dsp_setfrag) { parm = frag; res = ioctl(snd,SNDCTL_DSP_SETFRAGMENT,&parm); if(res < 0) { sprintf(msgbuf, "ioctl(SNDCTL_DSP_SETFRAGMENT, %i) failed: %s", frag, strerror(errno)); put_msg(msgbuf); } frag = parm; } parm = sample_size; res = ioctl(snd,SOUND_PCM_WRITE_BITS,&parm); if(res < 0) { sprintf(msgbuf, "ioctl(SOUND_PCM_WRITE_BITS, %i) failed: %s", sample_size, strerror(errno)); put_msg(msgbuf); } sample_size = parm; parm = channels; res = ioctl(snd,SOUND_PCM_WRITE_CHANNELS,&parm); if(res < 0) { sprintf(msgbuf, "ioctl(SOUND_PCM_WRITE_CHANNELS, %i) failed: %s", channels, strerror(errno)); put_msg(msgbuf); } channels = parm; parm = sound_sample_rate; res = ioctl(snd,SOUND_PCM_WRITE_RATE,&parm); if(res < 0) { sprintf(msgbuf, "ioctl(SOUND_PCM_WRITE_RATE, %i) failed: %s", sound_sample_rate, strerror(errno)); put_msg(msgbuf); } sound_sample_rate = parm; res = ioctl(snd,SOUND_PCM_SYNC,0); if(res < 0) { sprintf(msgbuf, "ioctl(SOUND_PCM_WRITE_SYNC, 0) failed: %s", strerror(errno)); put_msg(msgbuf); } for(i = TMNUM/2-1; i >= 0; i--) open_buf[i] = 128; write(snd, open_buf, TMNUM/2); } static void write_buf(void) { write_generic(TMNUM); } void setbufsize(void) { struct timeval waittv; close_snd(1); waittv.tv_sec = 0; waittv.tv_usec = 100000; select(0, NULL, NULL, NULL, &waittv); open_snd(); } #endif /* OSS_SOUND */ /* -------- Sun Sound support -------- */ #ifdef SUN_SOUND #include #define HAVE_SOUND_FLUSH #ifdef HAVE_SOUND_FLUSH #include #include #endif #define CONVERT_TO_ULAW #define VOLREDUCE 1 static int written; static int buffernum; static int halving = 0; static int samplenum; static void close_snd(int normal) { #ifdef HAVE_SOUND_FLUSH if(normal) ioctl (snd, I_FLUSH, FLUSHW); #endif close_generic(); } static void open_snd(void) { audio_info_t auinfo; int res; int i; if(sound_dev_name == NULL) sound_dev_name = make_string(sound_dev_name, "/dev/audio"); if(!sound_sample_rate) sound_sample_rate = 16000; if(!open_generic()) return; AUDIO_INITINFO(&auinfo); auinfo.play.sample_rate = sound_sample_rate; auinfo.play.channels = channels; auinfo.play.precision = sample_size; auinfo.play.encoding = AUDIO_ENCODING_ULAW; res = ioctl(snd, AUDIO_SETINFO, &auinfo); if(res < 0) { put_msg("Failed to set audio information, trying samplerate = 8000"); sound_sample_rate = 8000; halving = 1; AUDIO_INITINFO(&auinfo); auinfo.play.sample_rate = sound_sample_rate; auinfo.play.channels = channels; auinfo.play.precision = sample_size; auinfo.play.encoding = AUDIO_ENCODING_ULAW; res = ioctl(snd, AUDIO_SETINFO, &auinfo); if(res < 0) { sprintf(msgbuf, "Could not set audio information: %s", strerror(errno)); put_msg(msgbuf); } } written = 0; buffernum = bufframes * (TMNUM / 2); samplenum = TMNUM; if(halving) { buffernum /= 2; samplenum /= 2; } for(i = samplenum/2-1; i >= 0; i--) open_buf[i] = lin8_ulaw[128]; write(snd, open_buf, (size_t) (samplenum/2)); written += samplenum/2; } static void write_buf(void) { int to_cont; audio_info_t auinfo; if(halving) { byte *sb, *sbd; int i; sb = sbd = sp_sound_buf; if(samplenum == TMNUM/2) sb++; for(i = samplenum; i; sb+=2, sbd++, i--) *sbd = *sb; } write_generic(samplenum); written += samplenum; if(halving) samplenum = TMNUM - samplenum; to_cont = 0; do { int diff; ioctl(snd, AUDIO_GETINFO, &auinfo); diff = written - auinfo.play.samples; if(diff < 0 || diff > TMNUM * 100) { written = auinfo.play.samples; to_cont = 1; put_msg("Major slip in writing sound device"); } else if(diff <= buffernum) to_cont = 1; else { struct timeval waittv; int waitmsec; waitmsec = (written - auinfo.play.samples - buffernum) * 1000 / auinfo.play.sample_rate; waittv.tv_sec = waitmsec / 1000; waittv.tv_usec = (waitmsec % 1000) * 1000; select(0, NULL, NULL, NULL, &waittv); } } while(!to_cont); } void setbufsize(void) { buffernum = bufframes * (TMNUM / 2); if(halving) { buffernum /= 2; } } #endif /* SUN_SOUND */ void init_spect_sound(void) { #if 1 /* TODO: Is this OK? */ open_snd(); #endif } #ifndef VOLREDUCE #define VOLREDUCE 2 #endif #define CONVU8(x) ((byte) (((x) >> VOLREDUCE) + 128)) #ifdef CONVERT_TO_ULAW # define CONV(x) lin8_ulaw[(int) CONVU8(x)] #else # define CONV(x) CONVU8(x) #endif #define HIGH_PASS(hp, sv) (((hp) * 15 + (sv)) >> 4) #define TAPESOUND(tsp) ((*tsp) >> 4) static void process_sound(void) { static int soundhp; int i; byte *sb; register int sv; sb = sp_sound_buf; if(last_not_played) { soundhp = *sb; last_not_played = 0; } if(!sp_playing_tape) { for(i = TMNUM; i; sb++,i--) { sv = *sb; soundhp = HIGH_PASS(soundhp, sv); *sb = CONV(sv - soundhp); } } else { signed char *tsp; tsp = sp_tape_sound; for(i = TMNUM; i; sb++,tsp++,i--) { sv = *sb + TAPESOUND(tsp); soundhp = (soundhp * 15 + sv)>>4; *sb = CONV(sv - soundhp); } } } void autoclose_sound(void) { if(sound_on && sound_to_autoclose && sndstate >= SPS_CLOSED) { #ifdef DEBUG_AUDIO fprintf(stderr, "Autoclosing sound\n"); #endif close_snd(1); sndstate = SPS_AUTOCLOSED; } } void play_sound(int evenframe) { time_t nowt; int snd_change; if(evenframe) return; if(sndstate <= SPS_NONEXIST) return; if(!sound_on) { if(sndstate <= SPS_CLOSED) return; if(sndstate < SPS_OPENED) { sndstate = SPS_CLOSED; return; } close_snd(1); return; } if(sndstate == SPS_CLOSED) { open_snd(); if(sndstate < SPS_OPENED) return; } nowt = time(NULL); snd_change = z80_proc.sound_change | sp_playing_tape; if(snd_change) autocloset = nowt; if(sound_to_autoclose && (sndstate >= SPS_OPENED || sndstate <= SPS_BUSY) && (nowt - autocloset > AUTOCLOSET)) { #ifdef DEBUG_AUDIO fprintf(stderr, "Autoclosing sound\n"); #endif close_snd(1); sndstate = SPS_AUTOCLOSED; return; } if(sndstate <= SPS_BUSY) { if(nowt - opent < REOPENT) return; open_snd(); if(sndstate < SPS_OPENED) return; } if(sndstate <= SPS_AUTOCLOSED) { if(snd_change) { #ifdef DEBUG_AUDIO fprintf(stderr, "Autoopening sound\n"); #endif open_snd(); if(sndstate < SPS_OPENED) return; } else return; } z80_proc.sound_change = 0; process_sound(); write_buf(); } #else /* HAVE_SOUND */ /* Dummy functions */ void setbufsize(void) { } void init_spect_sound(void) { } void play_sound(int evenframe) { evenframe = evenframe; } void autoclose_sound(void) { } #endif /* NO_SOUND */ spectemu-0.94/spsound.h0100644000175000017500000000206506517613002015405 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPSOUND_H #define SPSOUND_H extern int bufframes; extern int sound_avail; extern void setbufsize(void); extern void autoclose_sound(void); extern void init_spect_sound(void); extern void play_sound(int evenframe); extern int sound_on; #endif /* SPSOUND_H */ spectemu-0.94/sptape.c0100644000175000017500000003237206526057470015220 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "sptape.h" #include "tapefile.h" #include "spperif.h" #include "z80.h" #include "interf.h" #include "misc.h" #include "spconf.h" #include #include #include #include #include #define MAXLINELEN 256 int spt_auto_stop = 0; static int playing = 0; static int paused = 0; static FILE *tapefp; static char tapename[MAXFILENAME]; static int tapetype; #define EARBIT 0x40 #define IMPBUFLEN 1024 static int ingroup; static int segtype; static int lastdatak; static int currseg; static void stop_playing(void) { if(playing) close_tapefile(); playing = 0; } static void pause_playing(void) { if(playing) { paused = 1; playing = 0; } } static void unpause_playing(void) { if(paused) { paused = 0; playing = 1; segtype = SEG_END; } } #define MAXDESCLEN 256 static void put_seg_desc(void) { if(segtype != SEG_VIRTUAL) { if(segtype > SEG_END) { if(!ingroup) { long len; int i, ml; char *me; len = get_seglen(); me = msgbuf; sprintf(me, "%4i: ", currseg); me = me+strlen(me); if(segtype >= SEG_DATA && len) { sprintf(me, "%5li bytes, ", len); me = me+strlen(me); } ml = 0; for(i = 0; seg_desc[i]; i++) { if(seg_desc[i] == '\n') { *me = '\0'; put_msg(msgbuf); me = msgbuf; sprintf(me, " "); me = me+strlen(me); ml = 0; } else { if(ml < MAXDESCLEN) *me++ = seg_desc[i]; ml++; } } *me = '\0'; put_msg(msgbuf); } else { sprintf(msgbuf, "%4i:", currseg); put_tmp_msg(msgbuf); } } else put_msg(seg_desc); } #ifdef DEBUG_TAPE else fprintf(stderr, "virtual segment\n"); #endif } static void get_next_segment(void) { int propseg; do { propseg = 1; segtype = next_segment(); currseg = segment_pos(); put_seg_desc(); switch(segtype) { case SEG_ERROR: case SEG_END: stop_playing(); break; case SEG_STOP: pause_playing(); put_msg(" * Tape paused; Press Ctrl-o to restart * "); break; case SEG_SKIP: propseg = 0; break; case SEG_GRP_BEG: ingroup = 1; propseg = 0; break; case SEG_GRP_END: ingroup = 0; propseg = 0; break; } } while(!propseg); lastdatak = 0; } void play_tape(void) { static dbyte impbuf[IMPBUFLEN]; static int clevel; static dbyte *impbufp; static int impbufrem; static long imprem; static int cleared_buffers = 1; int tsn; dbyte *ibp; byte *tsp; int ibr; long ir; int cl; signed char *op; int ov; int ca; tsp = sp_tape_impinfo; op = sp_tape_sound; tsn = TMNUM; if(!playing) { if(cleared_buffers) return; sp_playing_tape = 0; if(!clevel) { ca = CHKTICK; clevel = ~clevel; } else { ca = 0; cleared_buffers = 1; } imprem = CHKTICK * TMNUM; } else if(!sp_playing_tape) { sp_playing_tape = 1; cleared_buffers = 0; impbufrem = 0; imprem = 0; clevel = get_level() ? ~(0) : 0; if(clevel) ca = 0; else ca = 1; } else ca = 0; #ifdef DEBUG_TAPE if(((clevel ? 1 : 0) ^ (DANM(ula_inport) & EARBIT ? 1 : 0) ^ (DANM(imp_change) ? 1 : 0) ^ (ca ? 1 : 0)) == 0) fprintf(stderr, "Levels don't match %i %i\n", imprem, impbufrem); #endif cl = clevel; ibr = impbufrem; ir = imprem; ibp = impbufp; if(cl) ov = CHKTICK/2; else ov = -(CHKTICK/2); do { if(ir > 0) { *tsp++ = ca; *op++ = ov; ir -= CHKTICK; tsn--; if(!tsn) goto done; if(cl) ov = CHKTICK/2; else ov = -(CHKTICK/2); while(ir > 0) { *tsp++ = 0; *op++ = ov; ir -= CHKTICK; tsn--; if(!tsn) goto done; } ca = 0; } if(ibr) { if(!ca) { if(cl) { ov += ir; ca = (CHKTICK/2) - ov + 1; } else { ov -= ir; ca = ov + (CHKTICK/2) + 1; } } else { ca = 0; if(cl) ov += ir; else ov -= ir; } ir += *ibp++; ibr--; cl = ~cl; } else { ibp = impbuf; do { ibr = next_imps(impbuf, IMPBUFLEN, CHKTICK * tsn); if(ibr) break; get_next_segment(); if(!playing) { if(!cl) { if(ca) ca = 0; else ca = CHKTICK; cl = ~cl; } ir = tsn*CHKTICK; ov = -(CHKTICK/2); break; } } while(1); } } while(1); done: clevel = cl; impbufrem = ibr; imprem = ir; impbufp = ibp; if(segtype >= SEG_DATA) { int datak; datak = (int) (get_segpos() / 1000); if(datak > lastdatak) { if(ingroup) sprintf(msgbuf, "%4i: ", currseg); else sprintf(msgbuf, " "); sprintf(msgbuf+strlen(msgbuf), "%3ik", datak); put_tmp_msg(msgbuf); lastdatak = datak; } } } /* 2168 2168 (9-10) 667 735 (2-4) 855 855 (3-5) 1710 1710 (7-9) 945 (4-5) hosszu: 7..9 rovid: 2..5 */ #define MICBIT 0x08 #define RC_NONE 0 #define RC_LEADER 1 #define RC_SYNC 2 #define RC_DATA 3 #define MAXLEN TMNUM #define LEADER_MIN 9 #define LEADER_MAX 10 #define SYNC_MIN 2 #define SYNC_MAX 4 #define BIT0_MIN 3 #define BIT0_MAX 5 #define BIT1_MIN 7 #define BIT1_MAX 9 #define LEADER_MIN_COUNT 512 static int rec_segment; static int recording = 0; static int rec_state = RC_NONE; static byte *recbuf = NULL; static const char *waitchars = "-\\|/"; void rec_tape(void) { static byte lastmic = 0; static int lastlen = 0; static int whole; static int leadercount; static byte data; static byte parity; static int bitnum; static int bytecount; static int recbufsize; static int firsthalf; static int frameswait = 0; int tsl; byte *fep; int thishalf; if(!recording) return; for(fep = sp_fe_outport_time, tsl = TMNUM; tsl; fep++, tsl--) { lastlen++; if((*fep & MICBIT) == lastmic) { if(lastlen < MAXLEN) continue; } else lastmic = ~lastmic & MICBIT; switch(rec_state) { case RC_NONE: if(lastlen >= LEADER_MIN && lastlen <= LEADER_MAX) { rec_state = RC_LEADER; leadercount = 0; break; } if((frameswait++ & 15)) break; frameswait &= 0x3F; sprintf(msgbuf, " %s: WAITING %c", tapename, waitchars[(frameswait >> 4)]); put_tmp_msg(msgbuf); break; case RC_LEADER: if(lastlen >= LEADER_MIN && lastlen <= LEADER_MAX) { leadercount++; if(leadercount == LEADER_MIN_COUNT) { sprintf(msgbuf, " %s: LEADER", tapename); put_tmp_msg(msgbuf); } break; } if(leadercount >= LEADER_MIN_COUNT && lastlen >= SYNC_MIN && lastlen <= SYNC_MAX) rec_state = RC_SYNC; else rec_state = RC_NONE; break; case RC_SYNC: if(lastlen >= SYNC_MIN && lastlen <= SYNC_MAX) { rec_state = RC_DATA; whole = 0; data = 0; bitnum = 0; bytecount = 0; recbuf = NULL; recbufsize = 0; parity = 0; sprintf(msgbuf, " %s: DATA", tapename); put_tmp_msg(msgbuf); } else rec_state = RC_NONE; break; case RC_DATA: thishalf = -1; if(lastlen >= BIT0_MIN && lastlen <= BIT0_MAX) thishalf = 0; else if(lastlen >= BIT1_MIN && lastlen <= BIT1_MAX) thishalf = 1; if(thishalf < 0 || (whole && firsthalf != thishalf)) { char filename[11]; int filesize; int filetype; sprintf(msgbuf, "%s: %03d", tapename, rec_segment); if(bytecount >= 1) { sprintf(msgbuf+strlen(msgbuf), " %02X %5d %3s", recbuf[0], bytecount-2, parity == 0 ? "OK" : "ERR"); if(recbuf[0] == 0 && bytecount - 2 >= 17) { filetype = recbuf[1]; strncpy(filename, (char*) recbuf+2, 10); filename[10] = '\0'; filesize = recbuf[12] + (recbuf[13] << 8); sprintf(msgbuf+strlen(msgbuf), " %02X %10s %5i", filetype, filename, filesize); } } put_msg(msgbuf); putc(bytecount & 0xFF, tapefp); putc((bytecount >> 8) & 0xFF, tapefp); fwrite(recbuf, 1, (size_t) bytecount, tapefp); fflush(tapefp); rec_segment++; free(recbuf); recbuf = NULL; rec_state = RC_NONE; break; } if(!whole) { whole = 1; firsthalf = thishalf; } else { whole = 0; data |= thishalf; bitnum++; if(bitnum == 8) { bitnum = 0; if(recbufsize <= bytecount) { recbufsize += 1024; recbuf = realloc(recbuf, (size_t) recbufsize); if(recbuf == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } } recbuf[bytecount] = data; parity = parity ^ data; data = 0; bytecount++; if(!(bytecount & 1023)) { sprintf(msgbuf, " %s: DATA %i kB", tapename, bytecount >> 10); put_tmp_msg(msgbuf); } } data <<= 1; } break; } lastlen = 0; } } static void stop_recording(void) { if(recording) { recording = 0; free(recbuf); recbuf = NULL; fclose(tapefp); } } static void restart_playing(void) { int res; struct tape_options tapeopt; if(tapetype < 0) { tapetype = TAP_TZX; res = open_tapefile(tapename, tapetype); if(!res) { tapetype = TAP_TAP; res = open_tapefile(tapename, tapetype); } } else res = open_tapefile(tapename, tapetype); if(!res) { put_msg(seg_desc); return; } INITTAPEOPT(tapeopt); #ifndef DEBUG_Z80 tapeopt.blanknoise = 1; #endif set_tapefile_options(&tapeopt); if(currseg) { res = goto_segment(currseg); if(!res) { put_msg(seg_desc); return; } } playing = 1; segtype = SEG_END; } void pause_play(void) { if(playing) { pause_playing(); put_msg(" * Tape paused * "); goto_segment(currseg); } else unpause_playing(); } void start_play_file_type(char *name, int seg, int type) { int filetype = FT_TAPEFILE; strncpy(tapename, name, MAXFILENAME-10); tapename[MAXFILENAME-10] = '\0'; currseg = seg; tapetype = type; spcf_find_file_type(tapename, &filetype, &tapetype); if(currseg < 0) currseg = 0; ingroup = 0; restart_playing(); } void start_play(void) { char *name; int t; int seg; if(playing || paused || recording) { put_msg(" * Stop the tape first! * "); return; } put_msg("Enter tape file path:"); name = spif_get_tape_fileinfo(&seg, &t); if(name == NULL) return; start_play_file_type(name, seg, -1); } void stop_play(void) { if(playing || paused) { put_msg(" * Stopped playing * "); if(playing) stop_playing(); if(paused) paused = 0; } else if(recording) { sprintf(msgbuf, " * Stopped recording tape `%s' * ", tapename); put_msg(msgbuf); stop_recording(); } } void start_rec(void) { char *name; if(playing || paused || recording) return; put_msg("Enter tape file to record (default: '.tap'):"); name = spif_get_filename(); if(name == NULL) return; strncpy(tapename, name, MAXFILENAME-10); tapename[MAXFILENAME-10] = '\0'; if(!check_ext(tapename, "tap")) add_extension(tapename, "tap"); tapefp = fopen(tapename, "ab"); if(tapefp == NULL) { sprintf(msgbuf, "Could not open tape file `%s', %s", tapename, strerror(errno)); put_msg(msgbuf); return; } recording = 1; rec_segment = 0; rec_state = RC_NONE; sprintf(msgbuf, "Recordind tape file `%s'. To stop press Ctrl-s", tapename); put_msg(msgbuf); } #include "spkey_p.h" #define CF 0x01 #define ZF 0x40 void qload(void) { byte type, parity; dbyte length, dest, dtmp; int verify, success, firstbyte; int nextdata; if(recording) { put_msg("Can't quick load tape, because recording"); return; } do { if(!playing) { if(paused) unpause_playing(); else { spkey_textmode(); start_play(); spkey_screenmode(); } } if(!playing) { put_msg("Not quick loading tape"); return; } while(playing && (segtype != SEG_DATA || get_segpos() > 0)) get_next_segment(); } while(!playing); dtmp = AFBK; AFBK = AF; AF = dtmp; type = RA; verify = !(RF & CF); length = DE; firstbyte = !(RF & ZF); dest = IX; parity = 0; success = 0; do { nextdata = next_byte(); if(nextdata < 0) break; parity ^= nextdata; if(!length) { if(!parity) success = 1; break; } if(firstbyte) { firstbyte = 0; if(nextdata != type) break; } else { if(!verify) { if(dest >= 0x4000) DANM(mem)[dest] = nextdata; } else { if(DANM(mem)[dest] != nextdata) break; } dest++; length--; } } while(1); if(success) RF |= (CF | ZF); else RF &= ~(CF | ZF); IX = dest; DE = length; PC = SA_LD_RET; DANM(iff1) = DANM(iff2) = 1; DANM(haltstate) = 1; sp_init_screen_mark(); if(spt_auto_stop) pause_playing(); } spectemu-0.94/sptape.h0100644000175000017500000000215506521605075015214 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPTAPE_H #define SPTAPE_H extern void play_tape(void); extern void rec_tape(void); extern void stop_play(void); extern void pause_play(void); extern void start_play(void); extern void start_play_file_type(char *name, int seg, int type); extern void start_rec(void); extern void qload(void); #endif /* SPTAPE_H */ spectemu-0.94/vgakey.c0100644000175000017500000001307306526033021015171 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include "spkey.h" #include "spkey_p.h" #include "spperif.h" #include "vgascr.h" #include "akey.h" #include const int need_switch_mode = 1; volatile int spvk_after_switch = 0; #define KC_F1 59 #define KC_L_SHIFT 42 #define KC_R_SHIFT 54 #define KC_L_CTRL 29 #define KC_R_CTRL 97 #define KC_L_ALT 56 #define KC_R_ALT 100 #ifndef USE_LIBKB #include static char *kbstate; static void spkb_init(void) { keyboard_init(); keyboard_translatekeys(DONT_CATCH_CTRLC); kbstate = keyboard_getstate(); } #define spkb_close() keyboard_close() #define spkb_raw() keyboard_init() #define spkb_normal() keyboard_close() #define spkb_update() keyboard_update() #define kbst(i) kbstate[i] #else /* !USE_LIBKB */ #include #define spkb_init() kb_install(0) #define spkb_close() kb_remove() #define spkb_raw() kb_install(0) #define spkb_normal() kb_remove() #define spkb_update() kb_update() #define kbst(i) kb_key(i) #endif /* !USE_LIBKB */ #define SDEMPTY {0, 0} #define SDSPEC(x) {x, x} struct spscan_keydef { unsigned norm; unsigned shifted; }; static struct spscan_keydef sp_cp_keycode[] = { SDEMPTY, SDSPEC(SK_Escape), {'1', '!'}, {'2', '@'}, {'3', '#'}, {'4', '$'}, {'5', '%'}, {'6', '^'}, {'7', '&'}, {'8', '*'}, {'9', '('}, {'0', ')'}, {'-', '_'}, {'=', '+'}, SDSPEC(SK_BackSpace), SDSPEC(SK_Tab), {'q', 'Q'}, {'w', 'W'}, {'e', 'E'}, {'r', 'R'}, {'t', 'T'}, {'y', 'Y'}, {'u', 'U'}, {'i', 'I'}, {'o', 'O'}, {'p', 'P'}, {'[', '{'}, {']', '}'}, SDSPEC(SK_Return), SDSPEC(SK_Control_L), {'a', 'A'}, {'s', 'S'}, {'d', 'D'}, {'f', 'F'}, {'g', 'G'}, {'h', 'H'}, {'j', 'J'}, {'k', 'K'}, {'l', 'L'}, {';', ':'}, {'\'', '"'}, {'`', '~'}, SDSPEC(SK_Shift_L), {'\\', '|'}, {'z', 'Z'}, {'x', 'X'}, {'c', 'C'}, {'v', 'V'}, {'b', 'B'}, {'n', 'N'}, {'m', 'M'}, {',', '<'}, {'.', '>'}, {'/', '?'}, SDSPEC(SK_Shift_R), SDSPEC(SK_KP_Multiply), SDSPEC(SK_Alt_L), {' ', ' '}, SDSPEC(SK_Caps_Lock), SDSPEC(SK_F1), SDSPEC(SK_F2), SDSPEC(SK_F3), SDSPEC(SK_F4), SDSPEC(SK_F5), SDSPEC(SK_F6), SDSPEC(SK_F7), SDSPEC(SK_F8), SDSPEC(SK_F9), SDSPEC(SK_F10), SDSPEC(SK_Num_Lock), SDSPEC(SK_Scroll_Lock), SDSPEC(SK_KP_Home), SDSPEC(SK_KP_Up), SDSPEC(SK_KP_Page_Up), SDSPEC(SK_KP_Subtract), SDSPEC(SK_KP_Left), SDSPEC(SK_KP_5), SDSPEC(SK_KP_Right), SDSPEC(SK_KP_Add), SDSPEC(SK_KP_End), SDSPEC(SK_KP_Down), SDSPEC(SK_KP_Page_Down), SDSPEC(SK_KP_Insert), SDSPEC(SK_KP_Delete), SDEMPTY, SDEMPTY, {'<', '>'}, SDSPEC(SK_F11), SDSPEC(SK_F12), SDEMPTY, SDEMPTY, SDEMPTY, SDEMPTY, SDEMPTY, SDEMPTY, SDEMPTY, SDSPEC(SK_KP_Enter), SDSPEC(SK_Control_R), SDSPEC(SK_KP_Divide), SDSPEC(SK_Print), SDSPEC(SK_Alt_R), SDEMPTY, SDSPEC(SK_Home), SDSPEC(SK_Up), SDSPEC(SK_Page_Up), SDSPEC(SK_Left), SDSPEC(SK_Right), SDSPEC(SK_End), SDSPEC(SK_Down), SDSPEC(SK_Page_Down), SDSPEC(SK_Insert), SDSPEC(SK_Delete), }; #define LASTKEYCODE 111 spkeyboard kb_mkey; void spkey_textmode(void) { spkb_normal(); restore_sptextmode(); } void spkey_screenmode(void) { set_vga_spmode(); spkb_raw(); sp_init_screen_mark(); } void spkb_process_events(int evenframe) { int i; int changed; if(evenframe) { spkb_update(); changed = 0; for(i = 0; i <= LASTKEYCODE; i++) { int ki; int sh; int ks; ks = sp_cp_keycode[i].norm; ki = KS_TO_KEY(ks); if(kbst(i) && !spkb_kbstate[ki].press) { /* Press */ changed = 1; spkb_kbstate[ki].press = 1; sh = sp_cp_keycode[i].shifted; /* TODO: Do something with CapsLock, NumLock */ spkb_last.modif = 0; if(kbst(KC_L_SHIFT) || kbst(KC_R_SHIFT)) spkb_last.modif |= SKShiftMask; if(kbst(KC_L_CTRL) || kbst(KC_R_CTRL)) spkb_last.modif |= SKControlMask; if(kbst(KC_L_ALT) || kbst(KC_R_ALT)) spkb_last.modif |= SKMod1Mask; spkb_last.index = ki; spkb_last.shifted = sh; spkb_last.keysym = (spkb_last.modif & SKShiftMask) ? sh : ks; if((!ISFKEY(ks) || !spvk_after_switch) && accept_keys && !spkey_keyfuncs()) { spkb_kbstate[ki].state = 1; spkb_kbstate[i].frame = sp_int_ctr; } else spkb_kbstate[ki].state = 0; spvk_after_switch = 0; } if(!kbst(i) && spkb_kbstate[ki].press) { /* Release */ changed = 1; spkb_kbstate[ki].press = 0; spkb_kbstate[ki].state = 0; } } if(changed) spkb_state_changed = 1; } process_keys(); } static void close_spect_key(void) { spkb_close(); } void init_spect_key(void) { int i; for(i = 0; i < NR_SPKEYS; i++) spkb_kbstate[i].press = 0; clear_keystates(); init_basekeys(); spkb_init(); atexit(close_spect_key); } int display_keyboard(void) { return 0; } spectemu-0.94/vgascr.c0100644000175000017500000001303006526304211015163 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include "vgascr.h" #include "spperif.h" #include "spscr.h" #include "spscr_p.h" #include "spkey_p.h" #include "misc.h" #include "interf.h" #define TV_WIDTH 320 #define TV_HEIGHT_SMALL 200 #define TV_HEIGHT_LARGE 240 #define X_OFF ((TV_WIDTH - WIDTH) / 2) #define Y_OFF_L ((TV_HEIGHT_LARGE - HEIGHT) / 2) #define WIDTH 256 #define HEIGHT 192 int small_screen = 0; int vga_pause_bg = 0; int scrmul; /* DUMMY */ int use_shm; /* DUMMY */ int privatemap; /* DUMMY */ int pause_on_iconify; /* DUMMY */ #ifndef USE_DJGPP #include #include #include static volatile int need_restore = 0; void update_screen(void) { if(need_restore) { need_restore = 0; spscr_init_line_pointers(small_screen ? TV_HEIGHT_SMALL : TV_HEIGHT_LARGE); sp_init_screen_mark(); } if(!small_screen) { int i; /* TODO: Only update if necessary */ for(i = 0; i < TV_HEIGHT_LARGE; i++) { if(sp_border_update || (i >= Y_OFF_L && i < TV_HEIGHT_LARGE - Y_OFF_L && sp_imag_mark[i - Y_OFF_L])) { if(i >= Y_OFF_L && i < TV_HEIGHT_LARGE - Y_OFF_L) sp_imag_mark[i - Y_OFF_L] = 0; vga_drawscanline(i, &sp_image[i * TV_WIDTH]); } } } } #if RUN_IN_BACKGROUND && defined(VGA_GOTOBACK) static void noupdt(void) { int i; for(i = 0; i < PORT_TIME_NUM; i++) sp_scri[i] = -2; screen_visible = 0; accept_keys = 0; } static int paused_bak = 0; static void swto(void) { if(vga_pause_bg) paused_bak = sp_paused, sp_paused = 1; noupdt(); } static void swfrom(void) { if(vga_pause_bg && sp_paused) sp_paused = paused_bak; need_restore = 1; screen_visible = 1; accept_keys = 1; spvk_after_switch = 1; } static void start_background(void) { if(vga_runinbackground_version() == 1) { vga_runinbackground(VGA_GOTOBACK, swto); vga_runinbackground(VGA_COMEFROMBACK, swfrom); vga_runinbackground(1); } } #else /* RUN_IN_BACKGROUND */ static void start_background(void) { } #endif /* RUN_IN_BACKGROUND */ void set_vga_spmode(void) { if(!small_screen) { if(vga_setmode(G320x240x256) < 0) { put_msg("Can't use mode 320x240/256"); small_screen = 1; } } if(small_screen) vga_setmode(G320x200x256); vga_setpalvec(1, COLORNUM, &spscr_crgb[0].r); } void restore_sptextmode(void) { vga_setmode(TEXT); } void init_spect_scr(void) { int i; spscr_init_colors(); start_background(); set_vga_spmode(); if(small_screen) sp_image = (char *) vga_getgraphmem(); else sp_image = (char *) malloc_err(TV_WIDTH * TV_HEIGHT_LARGE); for(i = 0; i < COLORNUM; i++) { sp_colors[i] = i+1; } spscr_init_mask_color(); spscr_init_line_pointers(small_screen ? TV_HEIGHT_SMALL : TV_HEIGHT_LARGE); } void sp_init_vga(void) { vga_init(); printf("\n"); } #else /* !USE_DJGPP */ #ifdef Z80C #warning Compile with i386 assembly! #endif #include #include #include #include #include #include #ifdef USE_ALLEGRO #include "allegro.h" #endif static int origmode; int djsp_video_segment; #define VIDEO_LEN 64000 #define VIDEO_OFFSET 0x000a0000 static void set_video_mode(int mode) { __dpmi_regs r; r.h.ah = 0x00; r.h.al = mode; __dpmi_int(0x10, &r); } static int get_video_mode(void) { __dpmi_regs r; r.h.ah = 0x0f; __dpmi_int(0x10, &r); return r.h.al; } void update_screen(void) { #ifdef Z80C movedata(_my_ds(), (int) sp_image, VIDEO_OFFSET, VIDEO_LEN); #endif } static void set_pal(int start, int num, int *pal) { int i; __dpmi_regs r; for(i = 0; i < num * 3; i++) _farpokeb(_dos_ds, (__tb & 0x000fffff)+i, pal[i]); r.x.ax = 0x1012; r.x.bx = start; r.x.cx = num; r.x.dx = __tb & 0x0f; r.x.es = (__tb >> 4) & 0xffff; __dpmi_int(0x10, &r); } void set_vga_spmode(void) { set_video_mode(0x13); set_pal(1, COLORNUM, &spscr_crgb[0].r); spif_can_print = 0; } void restore_sptextmode(void) { set_video_mode(origmode); spif_can_print = 1; } void init_spect_scr(void) { int i; spscr_init_colors(); #ifdef Z80C sp_image = (char *) malloc_err(VIDEO_LEN); #else djsp_video_segment = _dos_ds; sp_image = (char *) VIDEO_OFFSET; #endif origmode = get_video_mode(); atexit(restore_sptextmode); set_vga_spmode(); for(i = 0; i < COLORNUM; i++) { sp_colors[i] = i+1; } spscr_init_mask_color(); spscr_init_line_pointers(TV_HEIGHT_SMALL); } void sp_init_vga(void) { #ifdef USE_ALLEGRO if(allegro_init() != 0) { fprintf(stderr, "Could not initialize allegro\n"); exit(1); } #endif } #endif /* !USE_DJGPP */ void destroy_spect_scr(void) { } void resize_spect_scr(int s) { s = s; } void spcf_read_xresources(void) { } void spscr_refresh_colors(void) { } spectemu-0.94/z80.c0100644000175000017500000000516106526327773014347 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "z80.h" #include #include #include Z80 PRNM(proc); byte PRNM(inports)[PORTNUM]; byte PRNM(outports)[PORTNUM]; #ifdef SPECT_MEM #define NUM64KSEGS 3 #endif #ifndef NUM64KSEGS #define NUM64KSEGS 1 #endif static byte *a64kmalloc(int num64ksegs) { byte *bigmem; bigmem = (byte *) malloc((unsigned) (0x10000 * (num64ksegs + 1))); if(bigmem == NULL) { fprintf(stderr, "Out of memory!\n"); exit(1); } return (byte *) (( (long) bigmem & ~((long) 0xFFFF)) + 0x10000); } void PRNM(init)(void) { qbyte i; DANM(mem) = a64kmalloc(NUM64KSEGS); srand((unsigned int) time(NULL)); for(i = 0; i < 0x10000; i++) DANM(mem)[i] = (byte) rand(); for(i = 0; i < NUMDREGS; i++) { DANM(nr)[i].p = DANM(mem); DANM(nr)[i].d.d = (dbyte) rand(); } for(i = 0; i < BACKDREGS; i++) { DANM(br)[i].p = DANM(mem); DANM(br)[i].d.d = (dbyte) rand(); } for(i = 0; i < PORTNUM; i++) PRNM(inports)[i] = PRNM(outports)[i] = 0; PRNM(local_init)(); return; } /* TODO: no interrupt immediately afer EI (not important for spectrum) */ void PRNM(nmi)(void) { DANM(iff2) = DANM(iff1); DANM(iff1) = 0; DANM(haltstate) = 0; PRNM(pushpc)(); PC = 0x0066; } /* TODO: IM 0 emulation */ void PRNM(interrupt)(int data) { if(DANM(iff1)) { DANM(haltstate) = 0; DANM(iff1) = DANM(iff2) = 0; switch(DANM(it_mode)) { case 0: PRNM(pushpc)(); PC = 0x0038; break; case 1: PRNM(pushpc)(); PC = 0x0038; break; case 2: PRNM(pushpc)(); PCL = DANM(mem)[(dbyte) (((int) RI << 8) + (data & 0xFF))]; PCH = DANM(mem)[(dbyte) (((int) RI << 8) + (data & 0xFF) + 1)]; break; } } } void PRNM(reset)(void) { DANM(haltstate) = 0; DANM(iff1) = DANM(iff2) = 0; DANM(it_mode) = 0; RI = 0; RR = 0; PC = 0; } spectemu-0.94/vgaspect.c0100644000175000017500000000212406526251375015530 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "spmain.h" #include "spperif.h" #include "vgascr.h" #include "spconf.h" int main(int argc, char *argv[]) { sp_init_vga(); spcf_pre_check_options(argc, argv); check_params(argc, argv); sp_init(); start_spectemu(argc, argv); /* This function DOES NOT return */ return 0; } spectemu-0.94/xkey.c0100644000175000017500000001031306526307776014702 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* #define DEBUG_FOCUS #define DEBUG_KEYS */ #define CORRMAX 5 /* The number of frames under which key timing correction is used */ #include "xkey.h" #include "xscr.h" #include "spkey.h" #include "spkey_p.h" #include "spscr.h" #include "xdispkb.h" #include "ax.h" #include #include #include static int got_focus = 0; static qbyte change_frame = 0; void spkey_textmode(void) { XAutoRepeatOn(xsp_disp); XSync(xsp_disp, False); } void spkey_screenmode(void) { XAutoRepeatOff(xsp_disp); XSync(xsp_disp, False); } void key_call(XEvent *ev) { int i; XKeyEvent *kev; KeySym ks, shks; kev = &((*ev).xkey); if(!got_focus) { #ifdef DEBUG_FOCUS fprintf(stderr, "Got keypress in unfocused mode\n"); #endif XAutoRepeatOff(xsp_disp); got_focus = 1; XSync(xsp_disp, False); } ks = XLookupKeysym(kev, 0); i = KS_TO_KEY(ks); if(change_frame < sp_int_ctr) change_frame = sp_int_ctr; if(i >= 0) { if(ev->type == KeyPress) { char ch; XLookupString(kev, &ch, 1, &ks, NULL); shks = XLookupKeysym(kev, 1); spkb_last.keysym = (unsigned) ks; spkb_last.shifted = (unsigned) shks; spkb_last.modif = kev->state; spkb_last.index = i; if(!spkey_keyfuncs()) { spkb_kbstate[i].state = 1; spkb_kbstate[i].press = (dbyte) kev->time; spkb_kbstate[i].frame = sp_int_ctr; } else spkb_kbstate[i].state = 0; } else if(spkb_kbstate[i].state == 1) { int tdiff, fdiff; spkb_kbstate[i].state = 0; fdiff = sp_int_ctr - spkb_kbstate[i].frame; tdiff = (((dbyte) kev->time) - spkb_kbstate[i].press + 10) / 20; if(tdiff <= 0) tdiff = 1; if(fdiff < CORRMAX && fdiff < tdiff) { qbyte eframe; if(tdiff > CORRMAX) tdiff = CORRMAX; spkb_kbstate[i].state = 2; eframe = spkb_kbstate[i].frame = tdiff; spkb_kbstate[i].frame = eframe; if(change_frame < eframe) change_frame = eframe; #ifdef DEBUG_KEYS fprintf(stderr, "Correcting key timing from %3i to %3i frames\n", fdiff, tdiff); #endif } } } } static void key_call_main(XEvent *ev, void *ptr) { if(!accept_keys) return; key_call(ev); } void spkb_process_events(int evenframe) { if(evenframe) { aX_look_events(); if(spkb_event_processor) (*spkb_event_processor)(); } if(sp_int_ctr <= change_frame) spkb_state_changed = 1; process_keys(); kb_refresh(); } void xkey_focus_change_call(XEvent *ev, void *ptr) { ptr = ptr; if(ev->type == FocusIn) { XAutoRepeatOff(xsp_disp); got_focus = 1; #ifdef DEBUG_FOCUS fprintf(stderr, "Focus In (%i)\n", (*ev).xfocus.detail); #endif } else { clear_keystates(); XAutoRepeatOn(xsp_disp); got_focus = 0; #ifdef DEBUG_FOCUS fprintf(stderr, "Focus Out (%i)\n", (*ev).xfocus.detail); #endif } XSync(xsp_disp, False); } static void close_spect_key(void) { XAutoRepeatOn(xsp_disp); XSync(xsp_disp, False); } static void keymap_event(XEvent *ev, void *ptr) { ptr = ptr; XRefreshKeyboardMapping(&((*ev).xmapping)); } void init_spect_key(void) { clear_keystates(); init_basekeys(); aX_add_event_proc(xsp_disp, xsp_win, KeyPress, key_call_main, KeyPressMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, KeyRelease, key_call_main, KeyReleaseMask, NULL); aX_add_event_proc(xsp_disp, 0, MappingNotify, keymap_event, 0, NULL); atexit(close_spect_key); spkb_event_processor = 0; } spectemu-0.94/xscr.c0100644000175000017500000006666606526327130014711 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include "spperif.h" #include "spscr.h" #include "spscr_p.h" #include "xscr.h" #include "xkey.h" #include "spkey_p.h" #include "ax.h" #include "misc.h" #include "interf.h" #include "run.xbm" #include "pause.xbm" #include "mask.xbm" #include #include #include #include #include #include #include int scrmul = 0; int use_shm = 1; int pause_on_iconify = 0; int small_screen; /* DUMMY */ int vga_pause_bg; /* DUMMY */ static int wwidth; static int wheight; static int shm_avail; static int shm_first_check; int xscr_delayed_expose = 1; static int exp_xmin, exp_xmax, exp_ymin, exp_ymax; static int exp_need = 0; static Pixmap runicon, pauseicon, maskicon; static XWMHints *wm_hints; #define SCRMULMAX 4 #define TV_WIDTH 320 #define TV_HEIGHT 256 #define WIDTH 256 #define HEIGHT 192 #define X_OFF ((TV_WIDTH - WIDTH) / 2) #define Y_OFF ((TV_HEIGHT - HEIGHT) / 2) #ifdef MIN #undef MIN #endif #ifdef MAX #undef MAX #endif #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y)) Window xsp_win; Display *xsp_disp; int xsp_scr; Colormap xsp_cmap; int xsp_bpp; Visual *xsp_visual; unsigned xsp_depth; static XImage *imag; static int immed_image; static Atom delete_atom; static GC xsp_gc; pixt xsp_colors[16]; static char *idp; #ifdef HAVE_MITSHM #include #include #include static XShmSegmentInfo shminfo; static int is_shm_image; #endif static int bits_per_pixel(unsigned dp) { int count; XPixmapFormatValues *fvp; int i; fvp = XListPixmapFormats(xsp_disp, &count); for(i = 0; i < count; i++) if(fvp[i].depth == (int) dp) return fvp[i].bits_per_pixel; if(dp <= 8) return 8; if(dp <= 16) return 16; if(dp <= 32) return 32; return 64; } static void translate_image(void) { if(xsp_bpp == 8 && scrmul == 2) { int i, j; char *zip, *rip1, *rip2; zip = sp_image; rip1 = imag->data; rip2 = imag->data + TV_WIDTH * 2; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; #ifdef I386_ASM for(j = TV_WIDTH / 4; j; j--) { asm volatile( "movl (%2), %%eax\n\t" "movb %%ah, %%dl\n\t" "movb %%ah, %%dh\n\t" "shll $16, %%edx\n\t" "movb %%al, %%dl\n\t" "movb %%al, %%dh\n\t" "movl %%edx, (%0)\n\t" "addl $4, %2\n\t" "movl %%edx, (%1)\n\t" "shrl $16, %%eax\n\t" "movb %%ah, %%dl\n\t" "movb %%ah, %%dh\n\t" "addl $8, %1\n\t" "shll $16, %%edx\n\t" "movb %%al, %%dl\n\t" "movb %%al, %%dh\n\t" "movl %%edx, 4(%0)\n\t" "movl %%edx, -4(%1)\n\t" "addl $8, %0\n\t" : "=r" ((int) rip1), "=r" ((int) rip2), "=r" ((int) zip) :"0" ((int) rip1), "1" ((int) rip2), "2" ((int) zip) :"dx", "ax"); } #else for(j = TV_WIDTH; j; j--) { *rip1++ = *rip2++ = *zip; *rip1++ = *rip2++ = *zip; zip++; } #endif rip1 += TV_WIDTH * 2; rip2 += TV_WIDTH * 2; } else { rip1 += 4 * TV_WIDTH; rip2 += 4 * TV_WIDTH; zip += TV_WIDTH; } } return; } if(xsp_bpp == 8) { int i, j; char k; char *zip; char *rip1, *rip2, *rip3, *rip4; zip = sp_image; rip1 = (char *) imag->data; switch (scrmul) { case 3: rip2 = rip1 + 3 * TV_WIDTH; rip3 = rip2 + 3 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = *zip++; *rip1++ = *rip2++ = *rip3++ = k; *rip1++ = *rip2++ = *rip3++ = k; *rip1++ = *rip2++ = *rip3++ = k; } rip1 += 6 * TV_WIDTH; rip2 += 6 * TV_WIDTH; rip3 += 6 * TV_WIDTH; } else { rip1 += 9 * TV_WIDTH; rip2 += 9 * TV_WIDTH; rip3 += 9 * TV_WIDTH; zip += TV_WIDTH; } } return; case 4: rip2 = rip1 + 4 * TV_WIDTH; rip3 = rip2 + 4 * TV_WIDTH; rip4 = rip3 + 4 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = *zip++; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; } rip1 += 12 * TV_WIDTH; rip2 += 12 * TV_WIDTH; rip3 += 12 * TV_WIDTH; rip4 += 12 * TV_WIDTH; } else { rip1 += 16 * TV_WIDTH; rip2 += 16 * TV_WIDTH; rip3 += 16 * TV_WIDTH; rip4 += 16 * TV_WIDTH; zip += TV_WIDTH; } } return; } } if(xsp_bpp == 16) { int i, j; dbyte k; char *zip; dbyte *rip1, *rip2, *rip3, *rip4; zip = sp_image; rip1 = (dbyte *) imag->data; /* TODO: fix warning */ switch (scrmul) { case 1: for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { *rip1++ = (dbyte) xsp_colors[(int) ((unsigned char) *zip++)]; } } else { rip1 += TV_WIDTH; zip += TV_WIDTH; } } return; case 2: rip2 = rip1 + 2 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = (dbyte) xsp_colors[(int) ((unsigned char) *zip++)]; *rip1++ = *rip2++ = k; *rip1++ = *rip2++ = k; } rip1 += 2 * TV_WIDTH; rip2 += 2 * TV_WIDTH; } else { rip1 += 4 * TV_WIDTH; rip2 += 4 * TV_WIDTH; zip += TV_WIDTH; } } return; case 3: rip2 = rip1 + 3 * TV_WIDTH; rip3 = rip2 + 3 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = (dbyte) xsp_colors[(int) ((unsigned char) *zip++)]; *rip1++ = *rip2++ = *rip3++ = k; *rip1++ = *rip2++ = *rip3++ = k; *rip1++ = *rip2++ = *rip3++ = k; } rip1 += 6 * TV_WIDTH; rip2 += 6 * TV_WIDTH; rip3 += 6 * TV_WIDTH; } else { rip1 += 9 * TV_WIDTH; rip2 += 9 * TV_WIDTH; rip3 += 9 * TV_WIDTH; zip += TV_WIDTH; } } return; case 4: rip2 = rip1 + 4 * TV_WIDTH; rip3 = rip2 + 4 * TV_WIDTH; rip4 = rip3 + 4 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = (dbyte) xsp_colors[(int) ((unsigned char) *zip++)]; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; } rip1 += 12 * TV_WIDTH; rip2 += 12 * TV_WIDTH; rip3 += 12 * TV_WIDTH; rip4 += 12 * TV_WIDTH; } else { rip1 += 16 * TV_WIDTH; rip2 += 16 * TV_WIDTH; rip3 += 16 * TV_WIDTH; rip4 += 16 * TV_WIDTH; zip += TV_WIDTH; } } return; } } if(xsp_bpp == 32) { int i, j; qbyte k; char *zip; qbyte *rip1, *rip2, *rip3, *rip4; zip = sp_image; rip1 = (qbyte *) imag->data; /* TODO: fix warning */ switch (scrmul) { case 1: for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { *rip1++ = (qbyte) xsp_colors[(int) ((unsigned char) *zip++)]; } } else { rip1 += TV_WIDTH; zip += TV_WIDTH; } } return; case 2: rip2 = rip1 + 2 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = (qbyte) xsp_colors[(int) ((unsigned char) *zip++)]; *rip1++ = *rip2++ = k; *rip1++ = *rip2++ = k; } rip1 += 2 * TV_WIDTH; rip2 += 2 * TV_WIDTH; } else { rip1 += 4 * TV_WIDTH; rip2 += 4 * TV_WIDTH; zip += TV_WIDTH; } } return; case 3: rip2 = rip1 + 3 * TV_WIDTH; rip3 = rip2 + 3 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = (qbyte) xsp_colors[(int) ((unsigned char) *zip++)]; *rip1++ = *rip2++ = *rip3++ = k; *rip1++ = *rip2++ = *rip3++ = k; *rip1++ = *rip2++ = *rip3++ = k; } rip1 += 6 * TV_WIDTH; rip2 += 6 * TV_WIDTH; rip3 += 6 * TV_WIDTH; } else { rip1 += 9 * TV_WIDTH; rip2 += 9 * TV_WIDTH; rip3 += 9 * TV_WIDTH; zip += TV_WIDTH; } } return; case 4: rip2 = rip1 + 4 * TV_WIDTH; rip3 = rip2 + 4 * TV_WIDTH; rip4 = rip3 + 4 * TV_WIDTH; for(i = 0; i < TV_HEIGHT; i++) { if(sp_border_update || (i >= Y_OFF && i < TV_HEIGHT - Y_OFF && sp_imag_mark[i - Y_OFF])) { if(i >= Y_OFF && i < TV_HEIGHT - Y_OFF) sp_imag_mark[i - Y_OFF] = 0; for(j = TV_WIDTH; j; j--) { k = (qbyte) xsp_colors[(int) ((unsigned char) *zip++)]; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; *rip1++ = *rip2++ = *rip3++ = *rip4++ = k; } rip1 += 12 * TV_WIDTH; rip2 += 12 * TV_WIDTH; rip3 += 12 * TV_WIDTH; rip4 += 12 * TV_WIDTH; } else { rip1 += 16 * TV_WIDTH; rip2 += 16 * TV_WIDTH; rip3 += 16 * TV_WIDTH; rip4 += 16 * TV_WIDTH; zip += TV_WIDTH; } } return; } } sprintf(msgbuf, "Translation not implemented (bpp: %i; scrmul: %i)", xsp_bpp, scrmul); put_msg(msgbuf); exit(1); } static void put_image(int x, int y, int w, int h, int toflush) { #if 0 static int serial = 0, num = 0; static int percent = 0; percent += (w * h) * 100 / (wwidth * wheight); if(toflush) { fprintf(stderr, "put_image/%i %i %i%%\n", ++num, serial++, percent), num = 0, percent = 0; getchar(); } else num++; #endif #ifdef HAVE_MITSHM if(is_shm_image) { XShmPutImage(xsp_disp, xsp_win, xsp_gc, imag, x, y, x, y, (unsigned) w, (unsigned) h, False); if(toflush) XSync(xsp_disp, False); return; } #endif XPutImage(xsp_disp, xsp_win, xsp_gc, imag, x, y, x, y, (unsigned) w, (unsigned) h); if(toflush) XFlush(xsp_disp); } static void get_min_max(unsigned val, int btnum, int *minp, int *maxp) { int i, j, m; for(i = btnum, j = 0; i && !(val & 1); val >>= 1, j++, i--); *minp = j; for(m = 0; i; val >>=1, j++, i--) if(val & 1) m = j; *maxp = m; } void update_screen(void) { if(!immed_image && (sp_border_update || sp_imag_horiz)) translate_image(); if(sp_border_update && sp_imag_horiz) put_image(0, 0, wwidth, wheight, 1); else { if(exp_need) { int exmin, exmax, eymin, eymax; exmin = MAX(0, MIN(wwidth, exp_xmin)); exmax = MAX(0, MIN(wwidth, exp_xmax)); eymin = MAX(0, MIN(wheight, exp_ymin)); eymax = MAX(0, MIN(wheight, exp_ymax)); put_image(exmin, eymin, exmax - exmin, eymax - eymin, (!sp_border_update && !sp_imag_horiz)); } if(sp_border_update) { register int bhw, bvw, rh; bhw = X_OFF * scrmul; bvw = Y_OFF * scrmul; rh = HEIGHT * scrmul; put_image(0, 0, wwidth, bvw, 0); put_image(0, bvw, bhw, rh, 0); put_image((X_OFF+WIDTH) * scrmul, bvw, bhw, rh, 0); put_image(0, (Y_OFF+HEIGHT) * scrmul, wwidth, bvw, 1); } else if(sp_imag_horiz) { int xmin, xmax; int ymin, ymax; get_min_max(sp_imag_horiz, 32, &xmin, &xmax); get_min_max(sp_imag_vert, 24, &ymin, &ymax); put_image((xmin * 8 + X_OFF) * scrmul, (ymin * 8 + Y_OFF) * scrmul, (xmax - xmin + 1) * 8 * scrmul, (ymax - ymin + 1) * 8 * scrmul, 1); } } exp_need = 0; } static void expose_call(XEvent *ev, void *ptr) { int x1, x2, y1, y2; ptr = ptr; x1 = (*ev).xexpose.x; x2 = x1 + (*ev).xexpose.width; y1 = (*ev).xexpose.y; y2 = y1 +(*ev).xexpose.height; if(!exp_need) { exp_xmin = x1; exp_xmax = x2; exp_ymin = y1; exp_ymax = y2; exp_need = 1; } else { exp_xmin = MIN(exp_xmin, x1); exp_xmax = MAX(exp_xmax, x2); exp_ymin = MIN(exp_ymin, y1); exp_ymax = MAX(exp_ymax, y2); } if((*ev).xexpose.count == 0) { if(!xscr_delayed_expose) { int xmin, xmax, ymin, ymax; xmin = MAX(0, MIN(wwidth, exp_xmin)); xmax = MAX(0, MIN(wwidth, exp_xmax)); ymin = MAX(0, MIN(wheight, exp_ymin)); ymax = MAX(0, MIN(wheight, exp_ymax)); put_image(xmin, ymin, xmax - xmin, ymax - ymin, 1); exp_need = 0; } } } static void misc_event(XEvent *ev, void *ptr) { ptr = ptr; if(ev->type == ClientMessage) { /* If we get a client message which has the value of the delete * atom, it means the window manager wants us to die. */ if ((*ev).xclient.data.l[0] == (unsigned char) delete_atom) exit(0); } } #ifdef HAVE_MITSHM extern int XShmQueryExtension (Display * dpy); static int haderror; static int (*origerrorhandler) (Display *, XErrorEvent *); static int shmattacherrorhandler(Display *disp, XErrorEvent *err) { if (err->error_code == BadAccess) haderror = 1; else (*origerrorhandler) (disp, err); return 0; } static char *create_shm_image(int width, int height, Visual *vis, unsigned dp, int bits) { int scmsize; int status; void *res; scmsize = (bits * width * height) / 8; is_shm_image = 0; imag = XShmCreateImage(xsp_disp, vis, (unsigned) dp, ZPixmap, 0, &shminfo, (unsigned) width, (unsigned) height); if(imag == NULL) { put_msg("XShmCreateImage failed"); return NULL; } shminfo.shmid = shmget(IPC_PRIVATE, (size_t) scmsize, IPC_CREAT | 0777); if(shminfo.shmid < 0) { sprintf(msgbuf, "Warning: shmget failed: %s", strerror(errno)); put_msg(msgbuf); return NULL; } res = shmat(shminfo.shmid, 0, 0); shminfo.shmaddr = (char *) res; if((long) res == -1) { sprintf(msgbuf, "Warning: shmat failed: %s", strerror(errno)); put_msg(msgbuf); return NULL; } imag->data = shminfo.shmaddr; shminfo.readOnly = False; haderror = 0; origerrorhandler = XSetErrorHandler(shmattacherrorhandler); status = XShmAttach(xsp_disp, &shminfo); XSync(xsp_disp, False); /* TODO: Why was this set to True? */ XSetErrorHandler (origerrorhandler); if(!status || haderror) { put_msg("XShmAttach failed"); shmctl(shminfo.shmid, IPC_RMID, 0); shmdt(shminfo.shmaddr); shm_avail = 0; return NULL; } if(shmctl(shminfo.shmid, IPC_RMID, 0) < 0) { sprintf(msgbuf, "shmctl failed: %s", strerror(errno)); put_msg(msgbuf); exit(1); } is_shm_image = 1; return shminfo.shmaddr; } static void destroy_shm_image(void) { XDestroyImage(imag); XShmDetach(xsp_disp, &shminfo); shmdt(shminfo.shmaddr); } static void shm_query_extension(void) { shm_avail = 1; #ifdef HAVE_SHMQUERY if (!XShmQueryExtension(xsp_disp)) shm_avail = 0; #endif } #endif /* HAVE_MITSHM */ static char *create_image(int width, int height, Visual *vis, unsigned dp, int bits) { int scmsize; char *idat; scmsize = (bits * width * height) / 8; idat = (char *) malloc_err((size_t) scmsize); imag = XCreateImage(xsp_disp, vis, (unsigned) dp, ZPixmap, 0, idat, (unsigned) width, (unsigned) height, 32, 0); return idat; } static void destroy_image(void) { XDestroyImage(imag); } void spxs_init_color(void) { if(xsp_bpp == 8) { int i; for(i = 0; i < 16; i++) sp_colors[i] = (unsigned char) xsp_colors[i]; } else { int i; for(i = 0; i < 16; i++) sp_colors[i] = (unsigned char) i; } spscr_init_mask_color(); } void init_spect_scr(void) { idp = NULL; #ifdef HAVE_MITSHM if(shm_avail && use_shm) idp = create_shm_image(wwidth, wheight, xsp_visual, xsp_depth, xsp_bpp); #endif if(idp == NULL) { if(shm_first_check) { put_msg("Note: MITSHM extension not available."); shm_first_check = 0; } idp = create_image(wwidth, wheight, xsp_visual, xsp_depth, xsp_bpp); } if(scrmul != 1 || xsp_bpp != 8) { immed_image = 0; sp_image = (char *) malloc_err(TV_WIDTH * TV_HEIGHT); } else { immed_image = 1; sp_image = idp; } XMapWindow(xsp_disp, xsp_win); XSync(xsp_disp, False); spxs_init_color(); spscr_init_line_pointers(TV_HEIGHT); } void destroy_spect_scr(void) { XSync(xsp_disp, False); if(!immed_image) free(sp_image); #ifdef HAVE_MITSHM if(is_shm_image) { destroy_shm_image(); idp = NULL; } #endif if(idp != NULL) { destroy_image(); idp = NULL; } sp_image = NULL; } void resize_spect_scr(int s) { if(s == scrmul || s > SCRMULMAX || s < 1) return; XResizeWindow(xsp_disp, xsp_win, (unsigned) (TV_WIDTH * s), (unsigned) (TV_HEIGHT * s)); clear_keystates(); } static void resize_call(XEvent *ev, void *ptr) { int w, h, x, y, s; ptr = ptr; #if 0 fprintf(stderr,"Resize Call: %d %d\n", (*ev).xconfigure.width, (*ev).xconfigure.height); #endif w = (*ev).xconfigure.width; h = (*ev).xconfigure.height; if(w == wwidth && h == wheight) return; x = (w + TV_WIDTH / 2) / TV_WIDTH; y = (h + TV_HEIGHT / 2) / TV_HEIGHT; s = MAX(x,y); if(s < 1) s = 1; else if(s > SCRMULMAX) s = SCRMULMAX; if(s != scrmul) { destroy_spect_scr(); scrmul = s; wwidth = TV_WIDTH * scrmul; wheight = TV_HEIGHT * scrmul; init_spect_scr(); sp_init_screen_mark(); /* Redraw screen */ } if(wwidth != w || wheight != h) XResizeWindow(xsp_disp, xsp_win, (unsigned) wwidth, (unsigned) wheight); } static void map_event(XEvent *ev, void *ptr) { static int paused_bak = 0; ptr = ptr; if(ev->type == MapNotify) { if(pause_on_iconify && sp_paused) sp_paused = paused_bak; screen_visible = 1; accept_keys = 1; } else { if(pause_on_iconify) paused_bak = sp_paused, sp_paused = 1; if(wm_hints != NULL) { wm_hints->icon_pixmap = sp_paused ? pauseicon : runicon; wm_hints->flags = IconPixmapHint; XSetWMHints(xsp_disp, xsp_win, wm_hints); } clear_keystates(); screen_visible = 0; accept_keys = 0; } } static void visibility_event(XEvent *ev, void *ptr) { ptr = ptr; if((*ev).xvisibility.state == VisibilityFullyObscured) screen_visible = 0; else screen_visible = 1; } void init_x_scr(aX_default_resources* defres, int *argcp, char *argv[]) { XSetWindowAttributes attr; XSizeHints *size_hints; XClassHint *class_hints; XTextProperty window_name, *wnp; XTextProperty icon_name, *inp; unsigned long valuemask; XGCValues values; Atom proto_atom; shm_avail = 0; shm_first_check = 1; spscr_init_colors(); xsp_disp = defres->disp; xsp_scr = defres->scr; xsp_visual = DefaultVisual(xsp_disp, xsp_scr); xsp_depth = DisplayPlanes(xsp_disp, xsp_scr); xsp_bpp = bits_per_pixel(xsp_depth); #ifdef HAVE_MITSHM shm_query_extension(); #endif if(!shm_avail) { put_msg("Note: MITSHM extension not available"); shm_first_check = 0; } if(!scrmul) { scrmul = 2; if(!shm_avail) scrmul = 1; while(scrmul > 1 && (DisplayWidth(xsp_disp, xsp_scr) < TV_WIDTH * scrmul || DisplayHeight(xsp_disp, xsp_scr) < TV_HEIGHT * scrmul)) scrmul--; } wwidth = TV_WIDTH * scrmul; wheight = TV_HEIGHT * scrmul; xsp_win = XCreateSimpleWindow(xsp_disp, RootWindow(xsp_disp, xsp_scr), 0, 0, /* x, y */ (unsigned) wwidth, (unsigned) wheight, /* width, height */ 0, 0, /* bw, bc */ BlackPixel(xsp_disp, xsp_scr)); if(!allocate_colors()) put_msg("Could not allocate colors"); attr.colormap = xsp_cmap; attr.background_pixel = xsp_colors[7]; attr.bit_gravity = ForgetGravity; XChangeWindowAttributes(xsp_disp, xsp_win, CWBitGravity | CWBackPixel | CWColormap, &attr); runicon = XCreateBitmapFromData(xsp_disp, xsp_win, (char *) run_bits, run_width, run_height); pauseicon = XCreateBitmapFromData(xsp_disp, xsp_win, (char *) pause_bits, pause_width, pause_height); maskicon = XCreateBitmapFromData(xsp_disp, xsp_win, (char *) mask_bits, mask_width, mask_height); size_hints = XAllocSizeHints(); if(size_hints != NULL) { size_hints->min_width = TV_WIDTH; size_hints->min_height = TV_HEIGHT; size_hints->max_width = SCRMULMAX * TV_WIDTH; size_hints->max_height = SCRMULMAX * TV_HEIGHT; size_hints->width_inc = TV_WIDTH; size_hints->height_inc = TV_HEIGHT; size_hints->min_aspect.x = TV_WIDTH; size_hints->min_aspect.y = TV_HEIGHT; size_hints->max_aspect.x = TV_WIDTH; size_hints->max_aspect.y = TV_HEIGHT; size_hints->base_width = 0; size_hints->base_height = 0; #if 1 size_hints->flags = PMinSize | PMaxSize | PResizeInc | PAspect | PBaseSize; #else size_hints->flags = 0; #endif } wm_hints = XAllocWMHints(); if(wm_hints != NULL) { wm_hints->input = True; wm_hints->initial_state = NormalState; wm_hints->icon_pixmap = runicon; wm_hints->icon_mask = maskicon; wm_hints->flags = InputHint | StateHint | IconPixmapHint | IconMaskHint; } class_hints = XAllocClassHint(); if(class_hints != NULL) { class_hints->res_name = (char *) defres->prog_name; class_hints->res_class = (char *) defres->class_name; /* TODO: fix warning */ } wnp = &window_name; if(!XStringListToTextProperty(&defres->window_name, 1, wnp)) wnp = NULL; inp = &icon_name; if(!XStringListToTextProperty(&defres->icon_name, 1, inp)) inp = NULL; XSetWMProperties(xsp_disp, xsp_win, wnp, inp, argv, *argcp, size_hints, wm_hints, class_hints); if(size_hints != NULL) XFree((void *) size_hints); if(class_hints != NULL) XFree((void *) class_hints); /* Delete-Window-Message black magic copied from xloadimage. */ proto_atom = XInternAtom(xsp_disp,"WM_PROTOCOLS", False); delete_atom = XInternAtom(xsp_disp,"WM_DELETE_WINDOW", False); if ((proto_atom != None) && (delete_atom != None)) { XChangeProperty(xsp_disp, xsp_win, proto_atom, XA_ATOM, 32, PropModePrepend, (unsigned char*)&delete_atom, 1); } valuemask = GCForeground; values.foreground = xsp_colors[0]; xsp_gc = XCreateGC(xsp_disp, xsp_win, valuemask, &values); aX_add_event_proc(xsp_disp, xsp_win, Expose, expose_call, ExposureMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, ConfigureNotify, resize_call, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, FocusIn, xkey_focus_change_call, FocusChangeMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, FocusOut, xkey_focus_change_call, FocusChangeMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, ClientMessage, misc_event, 0, NULL); aX_add_event_proc(xsp_disp, xsp_win, CirculateNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, CreateNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, GravityNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, ReparentNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, DestroyNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, MapNotify, map_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, UnmapNotify, map_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, xsp_win, VisibilityNotify, visibility_event, VisibilityChangeMask, NULL); } spectemu-0.94/z80.h0100644000175000017500000001020506526327756014350 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef Z80_H #define Z80_H #ifdef HAVE_CONFIG_H #include "config.h" #else #include #if defined(_BIG_ENDIAN) #define WORDS_BIGENDIAN #endif #endif #ifndef COMPARISON #define PRNM(x) z80_ ## x #else #define PRNM(x) z80x_ ## x #endif #define DANM(x) PRNM(proc).x #include "z80_type.h" #ifndef WORDS_BIGENDIAN union dregp { struct { byte l, h, _b2, _b3; } s; struct { dbyte d, _d1; } d; byte* p; }; #else union dregp { struct { byte _b3, _b2, h, l; } s; struct { dbyte _d1, d; } d; byte* p; }; #endif #define NUMDREGS 9 #define BACKDREGS 4 #define PORTNUM 256 /* Do NOT change the order! */ typedef struct { union dregp nr[NUMDREGS]; union dregp br[BACKDREGS]; int haltstate; int it_mode; int iff1, iff2; byte *mem; int tc; int rl7; #ifdef SPECT_MEM /* WARNING: Do NOT change the order!!! */ int next_scri; int inport_mask; int ula_inport; int ula_outport; int sound_sam; int sound_change; int imp_change; #endif #ifdef Z80C dbyte cbaddr; #ifdef PROCP byte *incf_tbl; byte *decf_tbl; byte *addf_tbl; byte *subf_tbl; byte *orf_tbl; byte *inports; byte *outports; #ifdef SPECT_MEM byte *fe_inport_high; #endif #endif #endif } Z80; extern Z80 PRNM(proc); extern byte PRNM(inports)[]; extern byte PRNM(outports)[]; #define ZI_BC 0 #define ZI_DE 1 #define ZI_HL 2 #define ZI_AF 3 #define ZI_IR 4 #define ZI_IX 5 #define ZI_IY 6 #define ZI_PC 7 #define ZI_SP 8 #define BC (DANM(nr)[ZI_BC].d.d) #define DE (DANM(nr)[ZI_DE].d.d) #define HL (DANM(nr)[ZI_HL].d.d) #define AF (DANM(nr)[ZI_AF].d.d) #define IR (DANM(nr)[ZI_IR].d.d) #define IX (DANM(nr)[ZI_IX].d.d) #define IY (DANM(nr)[ZI_IY].d.d) #define PC (DANM(nr)[ZI_PC].d.d) #define SP (DANM(nr)[ZI_SP].d.d) #define BCP (DANM(nr)[ZI_BC].p) #define DEP (DANM(nr)[ZI_DE].p) #define HLP (DANM(nr)[ZI_HL].p) #define PCP (DANM(nr)[ZI_PC].p) #define SPP (DANM(nr)[ZI_SP].p) #define IXP (DANM(nr)[ZI_IX].p) #define IYP (DANM(nr)[ZI_IY].p) #define RB (DANM(nr)[ZI_BC].s.h) #define RC (DANM(nr)[ZI_BC].s.l) #define RD (DANM(nr)[ZI_DE].s.h) #define RE (DANM(nr)[ZI_DE].s.l) #define RH (DANM(nr)[ZI_HL].s.h) #define RL (DANM(nr)[ZI_HL].s.l) #define RA (DANM(nr)[ZI_AF].s.h) #define RF (DANM(nr)[ZI_AF].s.l) #define RI (DANM(nr)[ZI_IR].s.h) #define RR (DANM(nr)[ZI_IR].s.l) #define XH (DANM(nr)[ZI_IX].s.h) #define XL (DANM(nr)[ZI_IX].s.l) #define YH (DANM(nr)[ZI_IY].s.h) #define YL (DANM(nr)[ZI_IY].s.l) #define PCH (DANM(nr)[ZI_PC].s.h) #define PCL (DANM(nr)[ZI_PC].s.l) #define SPH (DANM(nr)[ZI_SP].s.h) #define SPL (DANM(nr)[ZI_SP].s.l) #define BCBK (DANM(br)[ZI_BC].d.d) #define DEBK (DANM(br)[ZI_DE].d.d) #define HLBK (DANM(br)[ZI_HL].d.d) #define AFBK (DANM(br)[ZI_AF].d.d) #define BBK (DANM(br)[ZI_BC].s.h) #define CBK (DANM(br)[ZI_BC].s.l) #define DBK (DANM(br)[ZI_DE].s.h) #define EBK (DANM(br)[ZI_DE].s.l) #define HBK (DANM(br)[ZI_HL].s.h) #define LBK (DANM(br)[ZI_HL].s.l) #define ABK (DANM(br)[ZI_AF].s.h) #define FBK (DANM(br)[ZI_AF].s.l) #ifdef __cplusplus extern "C" { #endif extern void PRNM(init)(void); extern int PRNM(step)(int ticknum); extern void PRNM(interrupt)(int data); extern void PRNM(nmi)(void); extern void PRNM(reset)(void); extern void PRNM(pushpc)(void); extern void PRNM(local_init)(void); #ifdef __cplusplus } #endif #endif /* Z80_H */ spectemu-0.94/xscr.h0100644000175000017500000000236306526326536014707 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef XSCR_H #define XSCR_H #include "ax.h" typedef unsigned long pixt; extern Window xsp_win; extern Display *xsp_disp; extern int xsp_scr; extern Colormap xsp_cmap; extern int xsp_bpp; extern Visual *xsp_visual; extern unsigned xsp_depth; extern unsigned long xsp_colors[]; extern void init_x_scr(aX_default_resources* defres, int *argc, char *argv[]); extern int allocate_colors(void); extern void spxs_init_color(void); #endif /* XSCR_H */ spectemu-0.94/xspect.c0100644000175000017500000000300506526060004015204 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "spmain.h" #include "spperif.h" #include "misc.h" #include "xscr.h" #include "spconf.h" #include "ax.h" int main(int argc, char *argv[]) { aX_default_resources defres; spcf_pre_check_options(argc, argv); defres.width = 0; defres.height = 0; defres.x = 0; defres.y = 0; defres.border_width = 10; defres.foreground = 0; defres.background = 1; defres.font_name = "7x14"; defres.fallback_font_name = NULL; defres.prog_name = get_base_name(argv[0]); defres.class_name = "XSpscreen"; aX_open_disp(NULL, 0, &argc, argv, &defres); check_params(argc, argv); sp_init(); init_x_scr(&defres, &argc, argv); start_spectemu(argc, argv); /* This function DOES NOT return */ return 0; } spectemu-0.94/spectemu.lsm0100644000175000017500000000166706527773105016126 0ustar cjwatsoncjwatsonBegin3 Title: spectemu Version: 0.94 Entered-date: 18MAJ98 Description: Sinclair 48k ZX Spectrum emulator (very fast) - Console graphics with SVGALIB (Linux only) - X11 (also MITSHM) graphics - Snapshot saving and loading - Sound emulation (Linux and Sun) - Tape emulation Keywords: spectrum ZX emulator Sinclair svgalib games Author: mszeredi@inf.bme.hu (SZEREDI Miklos) Maintained-by: mszeredi@inf.bme.hu (SZEREDI Miklos) Primary-site: http://www.inf.bme.hu/~mszeredi/spectemu/ 190k spectemu-0.94.tar.gz 1k spectemu.lsm Alternate-site: tsx-11.mit.edu /pub/linux/ALPHA/spectemu Alternate-site: sunsite.unc.edu /pub/Linux/system/emulators/zx Platforms: Linux, Solaris, Alpha, Irix, FreeBSD, (DOS experimental) ... Copying-policy: GPL End spectemu-0.94/compr.h0100644000175000017500000000167406505020712015034 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef COMPR_H #define COMPR_H extern void compr(void); extern int compr_read_byte(void); extern void compr_put_byte(int i); #endif /* COMPR_H */ spectemu-0.94/spver.h0100644000175000017500000000166106530014123015044 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #define SPECTEMU_VERSION "0.94" #ifdef Z80C #define SPECTEMU_TYPE "c" #else #define SPECTEMU_TYPE "i" #endif spectemu-0.94/i386step.S0100644000175000017500000007542706505020713015264 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ .text #include "i386def.S" #ifndef COMPARISON #define Z80(s) NAME(z80_ ## s) #else #define Z80(s) NAME(z80x_ ## s) #endif #define NR 0 #define BR 36 #define OT 52 #define DAT(t, o) Z80(proc)+t+o #define NUMDREGS 9 #define BBC DAT(BR,0) #define BDE DAT(BR,4) #define BHL DAT(BR,8) #define BAF DAT(BR,12) #define MBC DAT(NR,0) #define MDE DAT(NR,4) #define MHL DAT(NR,8) #define MAF DAT(NR,12) #define MIX DAT(NR,20) #define MIY DAT(NR,24) #define MPC DAT(NR,28) #define MSP DAT(NR,32) #define MC DAT(NR,0) #define MB DAT(NR,1) #define ME DAT(NR,4) #define MD DAT(NR,5) #define ML DAT(NR,8) #define MH DAT(NR,9) #define MF DAT(NR,12) #define MA DAT(NR,13) #define MR DAT(NR,16) #define MI DAT(NR,17) #define MIXL DAT(NR,20) #define MIXH DAT(NR,21) #define MIYL DAT(NR,24) #define MIYH DAT(NR,25) #define HALTSTATE DAT(OT,0) #define IT_MODE DAT(OT,4) #define IFF1 DAT(OT,8) #define IFF2 DAT(OT,12) /* #define MEM DAT(OT,16) */ /* #define REAL_TC DAT(OT,20) */ #define RL7 DAT(OT,24) #define RV %ah #define RW %al #define RVW %ax #define VWP %eax #define RA %ch #define RF %cl #define RAF %cx #define SCRP %ecx #define RB %bh #define RC %bl #define RBC %bx #define BCP %ebx #define RH %dh #define RL %dl #define RHL %dx #define HLP %edx #define RPC %si #define PCP %esi #define RSP %bp #define SPP %ebp #define INC_R incl RL7 #define DEC_R decl RL7 #define EOI(x) \ INC_R ; \ subl $ ## x,TC ; \ jng loop_end #define IBR \ jmp *intr_table(,VWP,4) #define TIME(x) \ EOI(x) ; \ FETCHL ; \ IBR ; \ ALIGN #define TIMEX(x) \ EOI((x-4)) ; \ FETCHL ; \ IBR ; \ ALIGN #define TIME_NC(x) \ EOI(x) ; \ FETCH ; \ IBR ; \ ALIGN #define SF 128 #define ZF 64 #define HF 16 #define PVF 4 #define NF 2 #define CF 1 #define ALLF 0xD7 #define BUTCF 0xD6 #define SZHF 0xD0 #define SZF 0xC0 #define SZHCF 0xD1 #define SHCF 0x91 #define HNCF 0x13 #define HNF 0x12 #define ZNF 0x42 #define HPNF 0x16 #define HCF 0x11 #define BUTNF 0xD5 #define SZPF 0xC4 #define SZPCF 0xC5 #define ZPF 0x44 #define SZPNF 0xC6 #define SZNF 0xC2 #define VCFLAG(clear, change) \ lahf ; \ seto RW ; \ andb $~ ## clear, RF ; \ andb $ ## change, RV ; \ orb RV, RF ; \ shlb $2, RW ; \ orb RW, RF #define VSFLAG(set, change) \ lahf ; \ setno RW ; \ orb $ ## set, RF ; \ orb $~ ## change, RV ; \ andb RV, RF ; \ shlb $2, RW ; \ notb RW ; \ andb RW, RF #define ALLFLAG() \ lahf ; \ movb RV, RF #define CFLAG(clear, change) \ lahf ; \ andb $~ ## clear, RF ; \ andb $ ## change, RV ; \ orb RV, RF #define SFLAG(set, change) \ lahf ; \ orb $ ## set, RF ; \ orb $~ ## change, RV ; \ andb RV, RF #define CSFLAG(clear, set, change) \ lahf ; \ andb $~ ## clear, RF ; \ orb $ ## set, RF ; \ andb $ ## change, RV ; \ orb RV, RF #define COND(fl) testb $ ## fl, RF #define JCOND(fl, l) \ COND(fl) ; \ jnz l #define JNCOND(fl, l) \ COND(fl) ; \ jz l #define INCPC incw RPC #define DINCPC \ INCPC ; \ INCPC #define SFLAGS \ movb RF, RV ; \ sahf #define FETCHR(ir) \ movb (PCP), ir ; \ INCPC #define FETCHS \ movsbw (PCP), RVW ; \ INCPC #define FETCHL \ movzbl (PCP), VWP ; \ INCPC #define FETCH FETCHR(RW) #define DFETCH \ FETCHR(RW) ; \ FETCHR(RV) #define DFETCHP \ movl HLP, VWP ; \ DFETCH #ifdef SPECT_MEM #include "i386sp.S" #else /* SPECT_MEM */ #define PUTMEM_REG(l, reg, regh, regp, val, endf) \ movb val, (regp) ; \ endf #define PUTMEM_REG_NE(l, reg, regh, regp, val) \ movb val, (regp) #define MODMEMF(l, func, endf) \ func((HLP)) ; \ endf #define PUSH(l, rh, rl) \ decw RSP ; \ movb rh, (SPP) ; \ decw RSP ; \ movb rl, (SPP) #define PUSHT(l, rh, rl, t) \ PUSH(l, rh, rl) ; \ TIME(t) #define IN(l, porth, portl, rd) \ movzbl portl, VWP ; \ movb Z80(inports)(VWP), rd #define OUT(l, porth, portl, rs) \ movzbl portl, VWP ; \ movb rs, Z80(outports)(VWP) #define DI_CHECK #endif #define RSHLTIME(time) \ RSHL ; \ TIMEX(time) #define MODMEM(func, time) \ MODMEMF(func, func, TIME(time)) #define MODMEMID(l, func, time) \ MODMEMF(func ## l, func, RSHLTIME(time)) #define PUTMEM_RVW(l, val, time) \ PUTMEM_REG(l, RVW, RV, VWP, val, TIME(time)) #define PUTMEM_RHL(l, val, time) \ PUTMEM_REG(l, RHL, RH, HLP, val, TIME(time)) #define PUTMEM_RBC(l, val, time) \ PUTMEM_REG(l, RBC, RB, BCP, val, TIME(time)) #define PUTMEMID_RHL(l, val, time) \ PUTMEM_REG(l, RHL, RH, HLP, val, RSHLTIME(time)) #define PUTMEM_RVW_NE(l, val) \ PUTMEM_REG_NE(l, RVW, RV, VWP, val) #define PUTMEM_RHL_NE(l, val) \ PUTMEM_REG_NE(l, RHL, RH, HLP, val) #define PUSHD(l, dr) \ movw dr, RVW ; \ PUSH(l, RV, RW) #define POP(rh, rl) \ movb (SPP), rl ; \ incw RSP ; \ movb (SPP), rh ; \ incw RSP #define POPD(dr) \ POP(RV, RW) ; \ movw RVW, dr #define ADDFL VCFLAG(ALLF, SZHCF) #define SUBFL VSFLAG(ALLF, SZHCF) #define ORFL CFLAG(ALLF, SZPF) #define ANDFL CSFLAG(ALLF, HF, SZPF) #ifdef FASTFLAGS #define ADDFLAGS ADDFL #define SUBFLAGS SUBFL #define ORFLAGS ORFL #define ANDFLAGS ANDFL #else ALIGN addflags: ADDFL ; ret; ALIGN subflags: SUBFL ; ret; ALIGN orflags: ORFL ; ret; ALIGN andflags: ANDFL ; ret; ALIGN #define ADDFLAGS call addflags #define SUBFLAGS call subflags #define ORFLAGS call orflags #define ANDFLAGS call andflags #endif /* fastflags */ #define IXDGET \ pushl HLP ; \ movw MIX, RHL ; \ FETCHS ; \ addw RVW, RHL ; \ #define IYDGET \ pushl HLP ; \ movw MIY, RHL ; \ FETCHS ; \ addw RVW, RHL ; \ #define RSHL \ popl HLP #define ADD_A_R(r) \ addb r, RA ; \ ADDFLAGS #define ADC_A_R(r) \ SFLAGS ; \ adcb r, RA ; \ ADDFLAGS #define SUB_R(r) \ subb r, RA ; \ SUBFLAGS #define SBC_A_R(r) \ SFLAGS ; \ sbbb r, RA ; \ SUBFLAGS #define AND_R(r) \ andb r, RA ; \ ANDFLAGS #define XOR_R(r) \ xorb r, RA ; \ ORFLAGS #define OR_R(r) \ orb r, RA ; \ ORFLAGS #define CP_R(r) \ cmpb r, RA ; \ SUBFLAGS ALIGN .globl Z80(local_init) /* .type Z80(local_init),@function */ Z80(local_init): /* Nothing to initialize */ ret ALIGN .globl Z80(pushpc) /* .type Z80(pushpc),@function */ Z80(pushpc): pushl SPP pushl PCP movl MPC, PCP movl MSP, SPP xorl SCRP, SCRP PUSHD(z80_pushpci, RPC) movl SPP, MSP popl PCP popl SPP ret ALIGN .globl Z80(step) /* .type Z80(step),@function */ Z80(step): movl 4(%esp), %eax pushl %ebp pushl %edi pushl %esi pushl %ebx movl %eax, TC call load_regs call step_loop call store_regs movl TC, %eax popl %ebx popl %esi popl %edi popl %ebp ret ALIGN load_regs: movzwl MAF, SCRP movl MBC, BCP movl MHL, HLP movl MPC, PCP movl MSP, SPP movb MR, RW andb $0x80, MR movb RW, RL7 ret ALIGN store_regs: movw RAF, MAF movl BCP, MBC movl HLP, MHL movl PCP, MPC movl SPP, MSP movb RL7, RW andb $0x7F, RW orb RW, MR ret ALIGN step_loop: cmpl $0, HALTSTATE jnz haltstate FETCHL IBR ALIGN loop_end: ret ALIGN special_cb: INC_R FETCHL jmp *intr_table_cb(,VWP,4) ALIGN special_dd_cb: IXDGET FETCHL jmp *intr_table_dd_fd_cb(,VWP,4) ALIGN special_fd_cb: IYDGET FETCHL jmp *intr_table_dd_fd_cb(,VWP,4) ALIGN special_dd: INC_R subl $4,TC FETCHL jmp *intr_table_dd(,VWP,4) ALIGN special_ed: INC_R FETCHL jmp *intr_table_ed(,VWP,4) ALIGN special_fd: INC_R subl $4,TC FETCHL jmp *intr_table_fd(,VWP,4) ALIGN special_xx: DEC_R cmpl $0, TC jng loop_end IBR ALIGN #include "i386op1.S" #include "i386op2.S" #include "i386op3.S" #include "i386op4.S" #include "i386op5.S" #include "i386op6.S" .data intr_table: .long nop # 00 .long ld_bc_nn .long ld_ibc_a .long inc_bc .long inc_b .long dec_b .long ld_b_n .long rlca .long ex_af_afb .long add_hl_bc .long ld_a_ibc .long dec_bc .long inc_c .long dec_c .long ld_c_n .long rrca .long djnz_e # 10 .long ld_de_nn .long ld_ide_a .long inc_de .long inc_d .long dec_d .long ld_d_n .long rla .long jr_e .long add_hl_de .long ld_a_ide .long dec_de .long inc_e .long dec_e .long ld_e_n .long rra .long jr_nz_e # 20 .long ld_hl_nn .long ld_inn_hl .long inc_hl .long inc_h .long dec_h .long ld_h_n .long daa .long jr_z_e .long add_hl_hl .long ld_hl_inn .long dec_hl .long inc_l .long dec_l .long ld_l_n .long cpl .long jr_nc_e # 30 .long ld_sp_nn .long ld_inn_a .long inc_sp .long inc_ihl .long dec_ihl .long ld_ihl_n .long scf .long jr_c_e .long add_hl_sp .long ld_a_inn .long dec_sp .long inc_a .long dec_a .long ld_a_n .long ccf .long nop # 40 .long ld_b_c .long ld_b_d .long ld_b_e .long ld_b_h .long ld_b_l .long ld_b_ihl .long ld_b_a .long ld_c_b .long nop .long ld_c_d .long ld_c_e .long ld_c_h .long ld_c_l .long ld_c_ihl .long ld_c_a .long ld_d_b # 50 .long ld_d_c .long nop .long ld_d_e .long ld_d_h .long ld_d_l .long ld_d_ihl .long ld_d_a .long ld_e_b .long ld_e_c .long ld_e_d .long nop .long ld_e_h .long ld_e_l .long ld_e_ihl .long ld_e_a .long ld_h_b # 60 .long ld_h_c .long ld_h_d .long ld_h_e .long nop .long ld_h_l .long ld_h_ihl .long ld_h_a .long ld_l_b .long ld_l_c .long ld_l_d .long ld_l_e .long ld_l_h .long nop .long ld_l_ihl .long ld_l_a .long ld_ihl_b # 70 .long ld_ihl_c .long ld_ihl_d .long ld_ihl_e .long ld_ihl_h .long ld_ihl_l .long halt .long ld_ihl_a .long ld_a_b .long ld_a_c .long ld_a_d .long ld_a_e .long ld_a_h .long ld_a_l .long ld_a_ihl .long nop .long add_a_b # 80 .long add_a_c .long add_a_d .long add_a_e .long add_a_h .long add_a_l .long add_a_ihl .long add_a_a .long adc_a_b .long adc_a_c .long adc_a_d .long adc_a_e .long adc_a_h .long adc_a_l .long adc_a_ihl .long adc_a_a .long sub_b # 90 .long sub_c .long sub_d .long sub_e .long sub_h .long sub_l .long sub_ihl .long sub_a .long sbc_a_b .long sbc_a_c .long sbc_a_d .long sbc_a_e .long sbc_a_h .long sbc_a_l .long sbc_a_ihl .long sbc_a_a .long and_b # A0 .long and_c .long and_d .long and_e .long and_h .long and_l .long and_ihl .long and_a .long xor_b .long xor_c .long xor_d .long xor_e .long xor_h .long xor_l .long xor_ihl .long xor_a .long or_b # B0 .long or_c .long or_d .long or_e .long or_h .long or_l .long or_ihl .long or_a .long cp_b .long cp_c .long cp_d .long cp_e .long cp_h .long cp_l .long cp_ihl .long cp_a .long ret_nz # C0 .long pop_bc .long jp_nz_nn .long jp_nn .long call_nz_nn .long push_bc .long add_a_n .long rst_00 .long ret_z .long ret .long jp_z_nn .long special_cb .long call_z_nn .long call_nn .long adc_a_n .long rst_08 .long ret_nc # D0 .long pop_de .long jp_nc_nn .long out_in_a .long call_nc_nn .long push_de .long sub_n .long rst_10 .long ret_c .long exx .long jp_c_nn .long in_a_in .long call_c_nn .long special_dd .long sbc_a_n .long rst_18 .long ret_po # E0 .long pop_hl .long jp_po_nn .long ex_isp_hl .long call_po_nn .long push_hl .long and_n .long rst_20 .long ret_pe .long jp_hl .long jp_pe_nn .long ex_de_hl .long call_pe_nn .long special_ed .long xor_n .long rst_28 .long ret_p # F0 .long pop_af .long jp_p_nn .long di .long call_p_nn .long push_af .long or_n .long rst_30 .long ret_m .long ld_sp_hl .long jp_m_nn .long ei .long call_m_nn .long special_fd .long cp_n .long rst_38 ALIGN intr_table_dd: .long nop # 00 .long ld_bc_nn .long ld_ibc_a .long inc_bc .long inc_b .long dec_b .long ld_b_n .long rlca .long ex_af_afb .long add_ix_bc .long ld_a_ibc .long dec_bc .long inc_c .long dec_c .long ld_c_n .long rrca .long djnz_e # 10 .long ld_de_nn .long ld_ide_a .long inc_de .long inc_d .long dec_d .long ld_d_n .long rla .long jr_e .long add_ix_de .long ld_a_ide .long dec_de .long inc_e .long dec_e .long ld_e_n .long rra .long jr_nz_e # 20 .long ld_ix_nn .long ld_inn_ix .long inc_ix .long inc_ixh .long dec_ixh .long ld_ixh_n .long daa .long jr_z_e .long add_ix_ix .long ld_ix_inn .long dec_ix .long inc_ixl .long dec_ixl .long ld_ixl_n .long cpl .long jr_nc_e # 30 .long ld_sp_nn .long ld_inn_a .long inc_sp .long inc_iixd .long dec_iixd .long ld_iixd_n .long scf .long jr_c_e .long add_ix_sp .long ld_a_inn .long dec_sp .long inc_a .long dec_a .long ld_a_n .long ccf .long nop # 40 .long ld_b_c .long ld_b_d .long ld_b_e .long ld_b_ixh .long ld_b_ixl .long ld_b_iixd .long ld_b_a .long ld_c_b .long nop .long ld_c_d .long ld_c_e .long ld_c_ixh .long ld_c_ixl .long ld_c_iixd .long ld_c_a .long ld_d_b # 50 .long ld_d_c .long nop .long ld_d_e .long ld_d_ixh .long ld_d_ixl .long ld_d_iixd .long ld_d_a .long ld_e_b .long ld_e_c .long ld_e_d .long nop .long ld_e_ixh .long ld_e_ixl .long ld_e_iixd .long ld_e_a .long ld_ixh_b # 60 .long ld_ixh_c .long ld_ixh_d .long ld_ixh_e .long nop .long ld_ixh_ixl .long ld_h_iixd .long ld_ixh_a .long ld_ixl_b .long ld_ixl_c .long ld_ixl_d .long ld_ixl_e .long ld_ixl_ixh .long nop .long ld_l_iixd .long ld_ixl_a .long ld_iixd_b # 70 .long ld_iixd_c .long ld_iixd_d .long ld_iixd_e .long ld_iixd_h .long ld_iixd_l .long halt .long ld_iixd_a .long ld_a_b .long ld_a_c .long ld_a_d .long ld_a_e .long ld_a_ixh .long ld_a_ixl .long ld_a_iixd .long nop .long add_a_b # 80 .long add_a_c .long add_a_d .long add_a_e .long add_a_ixh .long add_a_ixl .long add_a_iixd .long add_a_a .long adc_a_b .long adc_a_c .long adc_a_d .long adc_a_e .long adc_a_ixh .long adc_a_ixl .long adc_a_iixd .long adc_a_a .long sub_b # 90 .long sub_c .long sub_d .long sub_e .long sub_ixh .long sub_ixl .long sub_iixd .long sub_a .long sbc_a_b .long sbc_a_c .long sbc_a_d .long sbc_a_e .long sbc_a_ixh .long sbc_a_ixl .long sbc_a_iixd .long sbc_a_a .long and_b # A0 .long and_c .long and_d .long and_e .long and_ixh .long and_ixl .long and_iixd .long and_a .long xor_b .long xor_c .long xor_d .long xor_e .long xor_ixh .long xor_ixl .long xor_iixd .long xor_a .long or_b # B0 .long or_c .long or_d .long or_e .long or_ixh .long or_ixl .long or_iixd .long or_a .long cp_b .long cp_c .long cp_d .long cp_e .long cp_ixh .long cp_ixl .long cp_iixd .long cp_a .long ret_nz # C0 .long pop_bc .long jp_nz_nn .long jp_nn .long call_nz_nn .long push_bc .long add_a_n .long rst_00 .long ret_z .long ret .long jp_z_nn .long special_dd_cb .long call_z_nn .long call_nn .long adc_a_n .long rst_08 .long ret_nc # D0 .long pop_de .long jp_nc_nn .long out_in_a .long call_nc_nn .long push_de .long sub_n .long rst_10 .long ret_c .long exx .long jp_c_nn .long in_a_in .long call_c_nn .long special_xx .long sbc_a_n .long rst_18 .long ret_po # E0 .long pop_ix .long jp_po_nn .long ex_isp_ix .long call_po_nn .long push_ix .long and_n .long rst_20 .long ret_pe .long jp_ix .long jp_pe_nn .long ex_de_hl .long call_pe_nn .long special_ed .long xor_n .long rst_28 .long ret_p # F0 .long pop_af .long jp_p_nn .long di .long call_p_nn .long push_af .long or_n .long rst_30 .long ret_m .long ld_sp_ix .long jp_m_nn .long ei .long call_m_nn .long special_xx .long cp_n .long rst_38 ALIGN intr_table_fd: .long nop # 00 .long ld_bc_nn .long ld_ibc_a .long inc_bc .long inc_b .long dec_b .long ld_b_n .long rlca .long ex_af_afb .long add_iy_bc .long ld_a_ibc .long dec_bc .long inc_c .long dec_c .long ld_c_n .long rrca .long djnz_e # 10 .long ld_de_nn .long ld_ide_a .long inc_de .long inc_d .long dec_d .long ld_d_n .long rla .long jr_e .long add_iy_de .long ld_a_ide .long dec_de .long inc_e .long dec_e .long ld_e_n .long rra .long jr_nz_e # 20 .long ld_iy_nn .long ld_inn_iy .long inc_iy .long inc_iyh .long dec_iyh .long ld_iyh_n .long daa .long jr_z_e .long add_iy_iy .long ld_iy_inn .long dec_iy .long inc_iyl .long dec_iyl .long ld_iyl_n .long cpl .long jr_nc_e # 30 .long ld_sp_nn .long ld_inn_a .long inc_sp .long inc_iiyd .long dec_iiyd .long ld_iiyd_n .long scf .long jr_c_e .long add_iy_sp .long ld_a_inn .long dec_sp .long inc_a .long dec_a .long ld_a_n .long ccf .long nop # 40 .long ld_b_c .long ld_b_d .long ld_b_e .long ld_b_iyh .long ld_b_iyl .long ld_b_iiyd .long ld_b_a .long ld_c_b .long nop .long ld_c_d .long ld_c_e .long ld_c_iyh .long ld_c_iyl .long ld_c_iiyd .long ld_c_a .long ld_d_b # 50 .long ld_d_c .long nop .long ld_d_e .long ld_d_iyh .long ld_d_iyl .long ld_d_iiyd .long ld_d_a .long ld_e_b .long ld_e_c .long ld_e_d .long nop .long ld_e_iyh .long ld_e_iyl .long ld_e_iiyd .long ld_e_a .long ld_iyh_b # 60 .long ld_iyh_c .long ld_iyh_d .long ld_iyh_e .long nop .long ld_iyh_iyl .long ld_h_iiyd .long ld_iyh_a .long ld_iyl_b .long ld_iyl_c .long ld_iyl_d .long ld_iyl_e .long ld_iyl_iyh .long nop .long ld_l_iiyd .long ld_iyl_a .long ld_iiyd_b # 70 .long ld_iiyd_c .long ld_iiyd_d .long ld_iiyd_e .long ld_iiyd_h .long ld_iiyd_l .long halt .long ld_iiyd_a .long ld_a_b .long ld_a_c .long ld_a_d .long ld_a_e .long ld_a_iyh .long ld_a_iyl .long ld_a_iiyd .long nop .long add_a_b # 80 .long add_a_c .long add_a_d .long add_a_e .long add_a_iyh .long add_a_iyl .long add_a_iiyd .long add_a_a .long adc_a_b .long adc_a_c .long adc_a_d .long adc_a_e .long adc_a_iyh .long adc_a_iyl .long adc_a_iiyd .long adc_a_a .long sub_b # 90 .long sub_c .long sub_d .long sub_e .long sub_iyh .long sub_iyl .long sub_iiyd .long sub_a .long sbc_a_b .long sbc_a_c .long sbc_a_d .long sbc_a_e .long sbc_a_iyh .long sbc_a_iyl .long sbc_a_iiyd .long sbc_a_a .long and_b # A0 .long and_c .long and_d .long and_e .long and_iyh .long and_iyl .long and_iiyd .long and_a .long xor_b .long xor_c .long xor_d .long xor_e .long xor_iyh .long xor_iyl .long xor_iiyd .long xor_a .long or_b # B0 .long or_c .long or_d .long or_e .long or_iyh .long or_iyl .long or_iiyd .long or_a .long cp_b .long cp_c .long cp_d .long cp_e .long cp_iyh .long cp_iyl .long cp_iiyd .long cp_a .long ret_nz # C0 .long pop_bc .long jp_nz_nn .long jp_nn .long call_nz_nn .long push_bc .long add_a_n .long rst_00 .long ret_z .long ret .long jp_z_nn .long special_fd_cb .long call_z_nn .long call_nn .long adc_a_n .long rst_08 .long ret_nc # D0 .long pop_de .long jp_nc_nn .long out_in_a .long call_nc_nn .long push_de .long sub_n .long rst_10 .long ret_c .long exx .long jp_c_nn .long in_a_in .long call_c_nn .long special_xx .long sbc_a_n .long rst_18 .long ret_po # E0 .long pop_iy .long jp_po_nn .long ex_isp_iy .long call_po_nn .long push_iy .long and_n .long rst_20 .long ret_pe .long jp_iy .long jp_pe_nn .long ex_de_hl .long call_pe_nn .long special_ed .long xor_n .long rst_28 .long ret_p # F0 .long pop_af .long jp_p_nn .long di .long call_p_nn .long push_af .long or_n .long rst_30 .long ret_m .long ld_sp_iy .long jp_m_nn .long ei .long call_m_nn .long special_xx .long cp_n .long rst_38 ALIGN intr_table_ed: .long ill_ed # 00 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # 10 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # 20 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # 30 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long in_b_ic # 40 .long out_ic_b .long sbc_hl_bc .long ld_inn_bc .long neg .long retn .long im_0 .long ld_i_a .long in_c_ic .long out_ic_c .long adc_hl_bc .long ld_bc_inn .long neg .long reti .long im_0 .long ld_r_a .long in_d_ic # 50 .long out_ic_d .long sbc_hl_de .long ld_inn_de .long neg .long retn .long im_1 .long ld_a_i .long in_e_ic .long out_ic_e .long adc_hl_de .long ld_de_inn .long neg .long retn .long im_2 .long ld_a_r .long in_h_ic # 60 .long out_ic_h .long sbc_hl_hl .long ld_inn_hl_ed .long neg .long retn .long im_0 .long rrd .long in_l_ic .long out_ic_l .long adc_hl_hl .long ld_hl_inn_ed .long neg .long retn .long im_0 .long rld .long in_f_ic # 70 .long out_ic_0 .long sbc_hl_sp .long ld_inn_sp .long neg .long retn .long im_1 .long ill_ed .long in_a_ic .long out_ic_a .long adc_hl_sp .long ld_sp_inn .long neg .long retn .long im_2 .long ill_ed .long ill_ed # 80 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # 90 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ldi # A0 .long cpi .long ini .long outi .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ldd .long cpd .long ind .long outd .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ldir # B0 .long cpir .long inir .long otir .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long lddr .long cpdr .long indr .long otdr .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # C0 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # D0 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # E0 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed # F0 .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed .long ill_ed ALIGN intr_table_cb: .long rlc_b # 00 .long rlc_c .long rlc_d .long rlc_e .long rlc_h .long rlc_l .long rlc_ihl .long rlc_a .long rrc_b .long rrc_c .long rrc_d .long rrc_e .long rrc_h .long rrc_l .long rrc_ihl .long rrc_a .long rl_b # 10 .long rl_c .long rl_d .long rl_e .long rl_h .long rl_l .long rl_ihl .long rl_a .long rr_b .long rr_c .long rr_d .long rr_e .long rr_h .long rr_l .long rr_ihl .long rr_a .long sla_b # 20 .long sla_c .long sla_d .long sla_e .long sla_h .long sla_l .long sla_ihl .long sla_a .long sra_b .long sra_c .long sra_d .long sra_e .long sra_h .long sra_l .long sra_ihl .long sra_a .long sll_b # 30 .long sll_c .long sll_d .long sll_e .long sll_h .long sll_l .long sll_ihl .long sll_a .long srl_b .long srl_c .long srl_d .long srl_e .long srl_h .long srl_l .long srl_ihl .long srl_a .long bit_0_b # 40 .long bit_0_c .long bit_0_d .long bit_0_e .long bit_0_h .long bit_0_l .long bit_0_ihl .long bit_0_a .long bit_1_b .long bit_1_c .long bit_1_d .long bit_1_e .long bit_1_h .long bit_1_l .long bit_1_ihl .long bit_1_a .long bit_2_b # 50 .long bit_2_c .long bit_2_d .long bit_2_e .long bit_2_h .long bit_2_l .long bit_2_ihl .long bit_2_a .long bit_3_b .long bit_3_c .long bit_3_d .long bit_3_e .long bit_3_h .long bit_3_l .long bit_3_ihl .long bit_3_a .long bit_4_b # 60 .long bit_4_c .long bit_4_d .long bit_4_e .long bit_4_h .long bit_4_l .long bit_4_ihl .long bit_4_a .long bit_5_b .long bit_5_c .long bit_5_d .long bit_5_e .long bit_5_h .long bit_5_l .long bit_5_ihl .long bit_5_a .long bit_6_b # 70 .long bit_6_c .long bit_6_d .long bit_6_e .long bit_6_h .long bit_6_l .long bit_6_ihl .long bit_6_a .long bit_7_b .long bit_7_c .long bit_7_d .long bit_7_e .long bit_7_h .long bit_7_l .long bit_7_ihl .long bit_7_a .long res_0_b # 80 .long res_0_c .long res_0_d .long res_0_e .long res_0_h .long res_0_l .long res_0_ihl .long res_0_a .long res_1_b .long res_1_c .long res_1_d .long res_1_e .long res_1_h .long res_1_l .long res_1_ihl .long res_1_a .long res_2_b # 90 .long res_2_c .long res_2_d .long res_2_e .long res_2_h .long res_2_l .long res_2_ihl .long res_2_a .long res_3_b .long res_3_c .long res_3_d .long res_3_e .long res_3_h .long res_3_l .long res_3_ihl .long res_3_a .long res_4_b # A0 .long res_4_c .long res_4_d .long res_4_e .long res_4_h .long res_4_l .long res_4_ihl .long res_4_a .long res_5_b .long res_5_c .long res_5_d .long res_5_e .long res_5_h .long res_5_l .long res_5_ihl .long res_5_a .long res_6_b # B0 .long res_6_c .long res_6_d .long res_6_e .long res_6_h .long res_6_l .long res_6_ihl .long res_6_a .long res_7_b .long res_7_c .long res_7_d .long res_7_e .long res_7_h .long res_7_l .long res_7_ihl .long res_7_a .long set_0_b # C0 .long set_0_c .long set_0_d .long set_0_e .long set_0_h .long set_0_l .long set_0_ihl .long set_0_a .long set_1_b .long set_1_c .long set_1_d .long set_1_e .long set_1_h .long set_1_l .long set_1_ihl .long set_1_a .long set_2_b # D0 .long set_2_c .long set_2_d .long set_2_e .long set_2_h .long set_2_l .long set_2_ihl .long set_2_a .long set_3_b .long set_3_c .long set_3_d .long set_3_e .long set_3_h .long set_3_l .long set_3_ihl .long set_3_a .long set_4_b # E0 .long set_4_c .long set_4_d .long set_4_e .long set_4_h .long set_4_l .long set_4_ihl .long set_4_a .long set_5_b .long set_5_c .long set_5_d .long set_5_e .long set_5_h .long set_5_l .long set_5_ihl .long set_5_a .long set_6_b # F0 .long set_6_c .long set_6_d .long set_6_e .long set_6_h .long set_6_l .long set_6_ihl .long set_6_a .long set_7_b .long set_7_c .long set_7_d .long set_7_e .long set_7_h .long set_7_l .long set_7_ihl .long set_7_a ALIGN intr_table_dd_fd_cb: .long rlc_b # 00 .long rlc_c .long rlc_d .long rlc_e .long rlc_h .long rlc_l .long rlc_id .long rlc_a .long rrc_b .long rrc_c .long rrc_d .long rrc_e .long rrc_h .long rrc_l .long rrc_id .long rrc_a .long rl_b # 10 .long rl_c .long rl_d .long rl_e .long rl_h .long rl_l .long rl_id .long rl_a .long rr_b .long rr_c .long rr_d .long rr_e .long rr_h .long rr_l .long rr_id .long rr_a .long sla_b # 20 .long sla_c .long sla_d .long sla_e .long sla_h .long sla_l .long sla_id .long sla_a .long sra_b .long sra_c .long sra_d .long sra_e .long sra_h .long sra_l .long sra_id .long sra_a .long sll_b # 30 .long sll_c .long sll_d .long sll_e .long sll_h .long sll_l .long sll_id .long sll_a .long srl_b .long srl_c .long srl_d .long srl_e .long srl_h .long srl_l .long srl_id .long srl_a .long bit_0_b # 40 .long bit_0_c .long bit_0_d .long bit_0_e .long bit_0_h .long bit_0_l .long bit_0_id .long bit_0_a .long bit_1_b .long bit_1_c .long bit_1_d .long bit_1_e .long bit_1_h .long bit_1_l .long bit_1_id .long bit_1_a .long bit_2_b # 50 .long bit_2_c .long bit_2_d .long bit_2_e .long bit_2_h .long bit_2_l .long bit_2_id .long bit_2_a .long bit_3_b .long bit_3_c .long bit_3_d .long bit_3_e .long bit_3_h .long bit_3_l .long bit_3_id .long bit_3_a .long bit_4_b # 60 .long bit_4_c .long bit_4_d .long bit_4_e .long bit_4_h .long bit_4_l .long bit_4_id .long bit_4_a .long bit_5_b .long bit_5_c .long bit_5_d .long bit_5_e .long bit_5_h .long bit_5_l .long bit_5_id .long bit_5_a .long bit_6_b # 70 .long bit_6_c .long bit_6_d .long bit_6_e .long bit_6_h .long bit_6_l .long bit_6_id .long bit_6_a .long bit_7_b .long bit_7_c .long bit_7_d .long bit_7_e .long bit_7_h .long bit_7_l .long bit_7_id .long bit_7_a .long res_0_b # 80 .long res_0_c .long res_0_d .long res_0_e .long res_0_h .long res_0_l .long res_0_id .long res_0_a .long res_1_b .long res_1_c .long res_1_d .long res_1_e .long res_1_h .long res_1_l .long res_1_id .long res_1_a .long res_2_b # 90 .long res_2_c .long res_2_d .long res_2_e .long res_2_h .long res_2_l .long res_2_id .long res_2_a .long res_3_b .long res_3_c .long res_3_d .long res_3_e .long res_3_h .long res_3_l .long res_3_id .long res_3_a .long res_4_b # A0 .long res_4_c .long res_4_d .long res_4_e .long res_4_h .long res_4_l .long res_4_id .long res_4_a .long res_5_b .long res_5_c .long res_5_d .long res_5_e .long res_5_h .long res_5_l .long res_5_id .long res_5_a .long res_6_b # B0 .long res_6_c .long res_6_d .long res_6_e .long res_6_h .long res_6_l .long res_6_id .long res_6_a .long res_7_b .long res_7_c .long res_7_d .long res_7_e .long res_7_h .long res_7_l .long res_7_id .long res_7_a .long set_0_b # C0 .long set_0_c .long set_0_d .long set_0_e .long set_0_h .long set_0_l .long set_0_id .long set_0_a .long set_1_b .long set_1_c .long set_1_d .long set_1_e .long set_1_h .long set_1_l .long set_1_id .long set_1_a .long set_2_b # D0 .long set_2_c .long set_2_d .long set_2_e .long set_2_h .long set_2_l .long set_2_id .long set_2_a .long set_3_b .long set_3_c .long set_3_d .long set_3_e .long set_3_h .long set_3_l .long set_3_id .long set_3_a .long set_4_b # E0 .long set_4_c .long set_4_d .long set_4_e .long set_4_h .long set_4_l .long set_4_id .long set_4_a .long set_5_b .long set_5_c .long set_5_d .long set_5_e .long set_5_h .long set_5_l .long set_5_id .long set_5_a .long set_6_b # F0 .long set_6_c .long set_6_d .long set_6_e .long set_6_h .long set_6_l .long set_6_id .long set_6_a .long set_7_b .long set_7_c .long set_7_d .long set_7_e .long set_7_h .long set_7_l .long set_7_id .long set_7_a ALIGN .text spectemu-0.94/README0100644000175000017500000006237006527773334014446 0ustar cjwatsoncjwatson * * * * * * * * * * * * * * * * * * S P E C T E M U * * * * Version 0.94 * * * * * * * * * * * * * * * * * * This package contains a 48k ZX-Spectrum emulator for Linux and other UNIX operating systems, with full Z80 instruction set, comprehensive screen, sound and tape emulation, and snapshot file saving and loading. It can run on a Linux console, or in an X11 window. The program is free software and is copyrighted under the GNU General Public License. It comes with absolutely no warranty. See the file COPYING for details. Written by Miklos Szeredi Email: mszeredi@inf.bme.hu It can be downloaded by FTP from: tsx-11.mit.edu:/pub/linux/ALPHA/spectemu/spectemu-0.94.tar.gz or sunsite.unc.edu:/pub/Linux/system/emulators/zx/spectemu-0.94.tar.gz For news and updates have a look at the Spectemu Page: http://www.inf.bme.hu/~mszeredi/spectemu/ You can also join a mailing list (at the Spectemu Page), to receive a notice when new versions of spectemu are available. Table of contents ================= 1. Requirements 2. Recommended 3. Features 4. Drawbacks 5. Compiling and installation 6. Using the emulator 6.1 Command line arguments and configuration files (NEW) 6.2 Using the Spectrum keyboard 6.3 Keys that control the emulator 6.4 Effects of changing frame frequency and sound buffer size 7. Where can I get ZX Spectrum games for this emulator 8. Tape files 8.1 Loading a tape file 8.2 Quick loading of tape files 8.3 Saving to a tape file 8.4 Saving a tape file to real tape 8.5 Making a tape file from a real tape 9. Bug reports 10. Credits 1. Requirements =============== Linux or other UNIX OS. Color X11 server (depths 8, 16 and 32 bits are supported) and/or SVGALIB console graphics library on Linux. 2. Recommended ============== A sound-card on Linux for wonderful spectrum 1-bit sound. And well, a fast enough processor... (Especially for the X11 version.) 3. Features =========== - Very fast because of assembly code in emulation (only on Intel processors). - Emulation also in C, which is slower, but supports any processor. - X support (with MITSHM if available, optionally double size window) - Linux console graphics (with SVGALIB) - Sound support (through Linux kernel sound-card driver, or SUN sound drivers) - Snapshot saving and loading (.Z80 and .SNA format) - Tape emulation: loading from tape files (.TAP and .TZX format) - Optional quick loading of tapes. - Saving to tape files. - Separate utility to save tape files to real tape - Configurable with config files and from command line 4. Drawbacks ============ - Poor user interface See the file TODO for a list of things which still need to be done (Maybe by YOU) 5. Compiling and installation ============================= To install the precompiled Linux executables just run 'make install' as root. To recompile the programs on other platforms first type ./configure This tries to determine the system type and parameters. Probably you won't have to give any options to configure, but here is the list of the most important options: --help Print a full list of options --prefix=PREFIX Install files under PREFIX (default is /usr/local) Executables go under PREFIX/bin, ... --without-readline Do not use the readline library (default is to use it if it's available on your system) --without-i386asm Do not use the Intel assembly code (default is to use it, if your system is Intel based) You may want to have a look at the produced `Makefile' and `config.h'. Then just type make clean make Then to install the program, login as root, and run make install (If you want to compile on another machine be sure to `make realclean' before re-configuring and re-making the program!) At the moment, there are two executable programs for running the emulator: xspect the X11 version vgaspect the Linux console version 'vgaspect' uses the SVGALIB library. If you do not have this installed on your system 'vgaspect' cannot be started. You _MUST_ have SVGALIB version 1.2.10 or greater installed, and it is STRONGLY recommended, that you get version 1.2.11 or later! SVGALIB is available at: sunsite.unc.edu:/pub/Linux/libs/graphics/ If you have SVGALIB version 1.2.11 or later, the emulator can run in background when you switch virtual consoles. 6. Using the emulator ===================== After starting 'xspect' or 'vgaspect' you should get the '(C) 1982 Sinclair Research Ltd' message, and after pressing a key, the flashing cursor. If not, then all I can say, is hard luck to you (if you are ambitious, compile the programs with debug information, and try to figure out what is causing the problem). Do not start the emulator processes in the background, the terminal is needed when loading or saving files. To load a snapshot immediately after the start of the emulator, you can enter the name of the snapshot file on the command line. (Also see section 6.1) E.g. xspect snap/chuckie2 In X you can resize the window. Window size can only be a multiple of the smallest window size (320x256). Smaller window means faster emulation, so if emulation doesn't run at full speed, try making the window smaller. 6.1 Command line arguments and configuration files -------------------------------------------------- You can give options to Spectemu in three different ways: 1) In a configuration file (either ~/.spectemurc, or /usr/local/share/spectemu/spectemu.cfg) 2) With the X Resource Database (.Xdefaults), this applies only to 'xspect' 3) On the command line Most of the options are common to all three methods, only the syntax differs slightly. Here are examples of the different syntax: Config File: scale = 1 private-map = true sound = false color-type = grayscale .Xdefaults: xspect.scale: 1 xspect.privateMap: true xspect.sound: false xspect.colorType: grayscale Command line: xspect -scale 1 -private-map -no-sound -color-type grayscale List of common options: ~~~~~~~~~~~~~~~~~~~~~~~ NAME RANGE DEFAULT DESCRIPTION ---- ----- ------- ----------- frame-skip 1... 2 The smaller this is, the more often the screen is updatated scale 1..4 2 Window size of 'xspect' private-map yes/no no Use private colormap in 'xspect' mit-shm yes/no yes Use MIT-SHM extension in X server if available vga-mode 320x200 320x240 Resolution to use in 'vgaspect', 320x240 320x200 is faster (but not so nice) sound yes/no yes Spectrum sound, if availble sound-delay 1... 4 The amount of frames (1/50 seconds) to delay sound. See section 6.4 sound-device filename (system The name of the sound device dependent) sound-sample-rate 4000... ~15625 Sample rate of sound device sound-autoclose yes/no yes Whether to close sound device when unused (so other programs can use it) sound-dsp-setfrag yes/no yes Set this to 'no' if you use PCSND sound driver keyboard-type extended extended Specifies the mapping of the keys, spectrum from the PC keyboard to the spectrum compat keys. See section 6.2 custom cursor-type shifted shifted How to use the arrow keys on the raw PC keyboard. See section 6.2 joystick allow-ascii yes/no yes Interpret other keys on the PC keyboard. See section 6.2 true-shift * alt Modifier to get shifted symbol as on the PC. func_shift * control Modifier to get control functions. color-type normal normal What type of colors to use. Gray- grayscale scale looks better on monochrome custom displays. pause-on-iconify yes/no no Whether to pause emulator, when it is iconified ('xspect' only) vga-pause-bg yes/no no Whether to pasue emulator, when you switch to a different console quick-load yes/no no Use built in (quick) loader for tapefiles. auto-stop yes/no no Pause tape after each segment when quick loading. load-immed yes/no no Load tapefile immediately (as if you typed LOAD "" / ENTER) pause yes/no no Pause the emulator on startup * can be one of: none, shift, lock, control, alt, mod2, mod3, mod4, mod5 Extra command line parameters: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On the command line you may also use the following options: -help Prints usage information, and a list of available options -version Prints out the version Also on the command line, a snapshot file and/or a tapefile can be specified. Spectemu figures out the type of file from the extension. You can omit the extension, e.g. you have a snapshot file 'snap.z80' and you start spectemu with 'xspect snap', then it will add the '.z80' extension. You can specify what type is the file by preceding it with one of '-z80', '-sna', '-tap' or '-tzx' options. This is useful for cases, when the filename does not have an extension (e.g. automatic starting with the midnight commander). Extra config file options: ~~~~~~~~~~~~~~~~~~~~~~~~~~ Color configuration ''''''''''''''''''' You can configure the custom colors in the config files (and the X Resource Database) with: color[0..15] = R G B e.g. color-type = custom color0 = 10 20 30 color7 = 40 50 60 changes the 0-th (black) and the 7-th (white) colors. Keyboard configuration '''''''''''''''''''''' You can set custom key bindings in the config file: Key_ = K ... ... Or in the X resource database: xspect.keys: = K ...; ... The can be set to any keysym (defined in 'spkey_p.h'). The K arguments are the spectrum keys to be assigned to the given PC key. K can be any letter, number (a..z, 0..9) or the following: none, space, enter, capsshift, symbolshift, kempston_up, kempston_down, kempston_left, kempston_right, kempston_fire e.g. keyboard-type = custom true-shift = none Key_Insert = capsshift 9 Key_Tab = capsshift symbolshift Key_Shift_R = kempston_fire Key_Alt_L = symbolshift Key_Alt_R = symbolshift or as it would appear in a .Xdefaults file: xspect.keyboardType: custom xspect.trueShift: none xspect.keys: Insert = capsshift 9; \ Tab = capsshift symbolshift; \ Shift_R = kempston_fire; \ Alt_L = symbolshift; Alt_R = symbolshift 6.2 Using the Spectrum keyboard ------------------------------- Those of you that have at some time used a Spectrum know, that the keyboard of this little computer is something very strange, with a LOT of keywords and symbols on and around each key. If you have not seen this keyboard (or have somehow managed to forget some bit of information that is on it) we produced quite a good copy of it, found in the 'spectkey.gif' file. If you are using 'xspect' than pressing 'Ctrl-k' brings up the picture of the spectrum keyboard. You can press keys with the mouse (even more than one if you like), and it also shows which keys are pressed. (You can see what the emulator does when, for example you press 'BackSpace' or a '[' key on the PC keyboard). The default mapping of the spectrum's keyboard to the PC's is the following: The numbers, the letters, Enter and Space are the same. The left Shift on the PC corresponds to the CAPS SHIFT key of the Spectrum, and the right Shift corresponds to the SYMBOL SHIFT. This is quite simple and with these keys you can get all the functionality of the original Spectrum (assuming of course, you know how). But... To make life a bit easier, you can also use the Backspace, the arrow keys, and the following symbols as on a PC keyboard: ,./;'-=<>?:"_+[]{}\|~ (unless you turn the 'allow-ascii' option off) To get a symbol which is written above the numbers on the PC, and not the function or symbol that is on the Spectrum, press Alt (actually the value of the 'true-shift' option) instead of Shift. You can slightly modify the mapping with the 'keyboard-type' and 'cursor-type' options. Every mapping includes the basic keys (letters, numbers, Space and Enter). Here are the mappings special to each keyboard type and cursor type: PC Key Spectrum Key ------ ------------ (Keyboard Types) extended: (default) Left Shift -> Caps Shift Right Shift -> Symbol Shift Back Space -> Caps Shift + '0' Escape -> Caps Shift + '1' spectrum: (spectrum-like layout, useful for some games, e.g. Jumping Jack) < same as extended, plus: > Comma (,) -> Symbol Shift Period (.) -> Space Semicolon (;) -> Enter compat: (similar to other emulators' layouts, e.g. Z80, X128, XZX ...) Shift (both) -> Caps Shift Alt -> Symbol Shift Back Space -> Caps Shift + '0' Escape -> Caps Shift + '1' custom: Use key bindings specified in the config file (see section 6.1) (Cursor Types) shifted: (default) Left Arrow -> Caps Shift + '5' Down Arrow -> Caps Shift + '6' Up Arrow -> Caps Shift + '7' Right Arrow -> Caps Shift + '8' raw: Left Arrow -> '5' Down Arrow -> '6' Up Arrow -> '7' Right Arrow -> '8' joystick: Left Arrow -> Kempston Left Down Arrow -> Kempston Down Up Arrow -> Kempston Up Right Arrow -> Kempston Right Keypad Ins -> Kempston Fire Keypad Del -> Kempston Fire Keypad Home -> Kempston Up + Left Keypad PgUp -> Kempston Up + Right Keypad End -> Kempston Down + Left Keypad PgDn -> Kempston Down + Right 6.3 Keys that control the emulator ---------------------------------- All control keys are produced by pressing the Ctrl key and another key. Ctrl-c, F10 Quit the emulator immediately Ctrl-l, F3 Load a snapshot file; you must type the path and filename on the terminal where you started the emulator, e.g. 'snap/chuckie2'. The type and extension of the file is determined automatically (.z80 or .sna). Ctrl-t, F2 Save the current state of the emulator in a snapshot file. Format depends on the extension (.z80 or .sna). If no extension is given, .z80 is appended. Ctrl-w, Ctrl-F2 Save a snapshot to a temporary file Ctrl-e, Ctrl-F3 Restore last temporary snapshot saved with 'Ctrl-w' Ctrl-q, F5 Reset the Spectrum Ctrl-f Fast mode Ctrl-n Normal speed mode Ctrl-b Pause/Unpause emulator (you can do operations like loading a snapshot file, etc... in paused mode too) Ctrl-m Toggle sound on/off Ctrl-h, F1 Print help Ctrl-k Display (undisplay) keyboard of spectrum. See section 6.2. Ctrl-p, F4 Play tape. Tape file must be entered on the terminal. Optionally the starting segment can be entered; e.g. 'tape/tape1.tap' or 'tape/tape1.tzx 13' Ctrl-s, F7 Stop tape Ctrl-y Toggle quick loading Ctrl-o, F6 Pause and unpause during tapefile playing (restarts the current segment). Ctrl-r Record to tape file. See section 8.3. Ctrl-\, F9 Refresh screen, reset keyboard state and refresh colors. Ctrl-j Toggle private colormap mode (only X) Ctrl-comma Decrease window size (only X) Ctrl-dot Increase window size (only X) Ctrl-equals Skip more screen frames Ctrl-minus Skip less screen frames Ctrl-] Increase sound buffer size Ctrl-[ Decrease sound buffer size 6.4 Effects of changing frame frequency and sound buffer size ------------------------------------------------------------- ONLY READ THIS IF YOU ARE NOT TOTALLY SATISFIED WITH THE EMULATOR'S PERFORMANCE This should be totally automatic, so I'm now programming you to do what the emulator should. (Luckily you are much easier to program) Frame skipping determines, after how many frames the emulator displays one on the screen. There are 50 frames in one second, and normally every other frame is displayed (25 per second). If the emulator is too slow under X, increasing frame skipping can have a good effect on performance, but at the cost of poorer quality. But the interesting thing is, that increasing frame skipping may cause a worsening of both performance and of picture quality (I will not explain it here why). Decreasing frame skipping has the opposite effect of the above. If the emulator uses sound, but sound is not continuous, then experiment with increasing sound buffer size, and increasing frame skipping. If you are lucky you can make things a bit better. Increasing sound buffer size has also the negative effect of delaying more the sound effects. 7. Where can I get ZX Spectrum games for this emulator ====================================================== On the Spectemu homepage (http://www.inf.bme.hu/~mszeredi/spectemu/) you can find a list of sites worth checking. Here are some: http://www.void.demon.nl/spectrum.html http://www.nvg.unit.no/sinclair/planet/ The fact is, that there were a lot of Spectrum games around on audio tapes, and some of them are really good. There were always cracked and copyable versions around, and nobody was interested in copyrights. Unfortunately the big FTP archives do not allow non free software on their servers, so I can't include any games in this distribution. (Because Spectrums have died out, and perhaps some of the software companies do not exist any more, probably some games could be distributed freely. But I will not check on those things.) I've included a program named 'spconv', written by Henk de Groot (hegr@ensae.ericsson.se) which can convert between snapshot file formats. Alternatively if you have some old spectrum tapes laying around, and you are very brave, you can check out section 8.5. 8. Tape files ============= 8.1 Loading a tape file ----------------------- The emulator now supports G.A. Lunter's .TAP and Tomaz Kac's .TZX tape files. To load a file, enter LOAD "" to the spectrum (by pressing keys j""), then press 'Ctrl-p'. On the terminal enter the name of the tape file to load, e.g. tape/cnamemat The emulator will now load from the tape file 'tape/cnamemat.tzx' or 'tape/cnamemat.tap' whichever exists. Playing automatically stops at the end of the tape file. To stop loading before this press Ctrl-s. The default extensions are '.tap' / '.tzx' or '.TAP' / '.TZX' depending on whether the entered tape file is upper or lower case. While loading try pressing Ctrl-f, which can speed things up. After loading the file press press Ctrl-n to restore normal speed. 8.2 Quick loading of tape files ------------------------------- Quick loading means bypassing of the tape loading routine in the spectrum ROM, and loading of tape blocks directly into the memory. Some programs use their own tape loading routines, and in that case the tape blocks are always "slow loaded" (see above section). Quick loading is optional and can be toggled with the 'Ctrl-y' key. When quick loading is on, after entering 'LOAD ""' you are immediately prompted for a tapefile. If the tapefile can't be loaded, the quick loading of the first header block is cancelled, but you can still load the rest of tape by pressing 'Ctrl-p' and entering the tapefile name. Even in quick load mode, the playing of tapes is not automatically paused, when the program doesn't load more blocks, so with '.tap' files containing multipart games, you have to pause the tape at the end of each part with 'Ctrl-o' ('.tzx' tapefiles can contain a "Stop the Tape" mark, to automatically pause playing). 8.3 Saving to a tape file ------------------------- If you want to save something to a tape file using the spectrum's "SAVE" command, do the following: 1) Enter 'SAVE "file"' on the spectrum 2) press Ctrl-r to start the recording 3) on the terminal enter the name of the tapefile to use 4) press a key on the spectrum 5) wait for the recording to stop 6) press Ctrl-s to stop recording If the specified tape file already exists, the newly saved segments are appended to the old tapefile. 8.4 Saving a tape file to real tape ----------------------------------- The utility 'tapeout' enables you to save tape files (.tap and .tzx) to real tape via the soundcard. At the moment it only works on Linux, because it uses the OSS sound driver. (You can compile it for non linux systems, by adding -DNO_SOUNDCARD to CFLAGS in Makefile. Then instead of writing to the sound device, the program writes to a headerless wav file (bits: 8, sample rate: what you've given).) You can compile 'tapeout' by entering make tapeout in the main directory of spectemu. The command line parameters are: tapeout sample_rate tapefile [start_block [output_file]] The default value for start_block is 0, for output_file it is "/dev/dsp" (or if compiled -DNO_SOUNDCARD it is "tape.out"). You can stop recording to the tape by pressing Ctrl-C. 8.5 Making a tape file from a real tape --------------------------------------- WARNING, ONLY TRY THIS IF YOU REALLY-REALLY WANT TO! Well it's not so bad as that, I've digitized a lot Spectrum tapes with ease, but I have the advantage of having played with tapes a lot on the real Spectrum, and of being able to modify the code which does the digitization. First of all you must have a sound-card to do this. If you've got it, then you have a small chance of succeeding. First get the cassette player which you used to play Spectrum tapes. Then plug it in your sound-card's 'line-in' or 'mic' inputs. Then somehow set the sound driver so that it reads things form the input in which you plugged your cassette (I use 'xmmix' the 'Motif Audio Mixer' to do this). And if you've managed to get this far, go to the directory where you want to store the tape files (remember, there will be a lot of little files: one for each little segment!), and enter the following command: recs - 32000 | filt | spload tapefile or recs - 32000 | spload tapefile (The first type worked better for me) Where 'recs', 'filt' and 'spload' are programs found in the utils directory, and 'tapefile' is the name of the tape file without the '.spt' extension. '.spt' tape files only exist because of historical reasons (the tape digitizing program preceeded the emulator, and also at that time I didn't know of the '.TAP' format), and now it isn't suppurted by the emulator any more. So you must convert '.spt' files to '.tap' with the utility spt2tap (in the utils directory) to use it with the emulator. (The contents of the utils directory can be remade by changing to that directory and entering the command: 'make realclean; make') Now you can put your favorite Spectrum cassette in the cassette player, and press the Play button. 'spload' will write a lot of information on the terminal, of which you might try to make some sense. Also you can do a 'tail -f tapefile.spt' in another terminal, to see what is happening. Again if nothing happens, then you are on your own (and most probably at first nothing will happen). And remember that this digitizer is not better than the real Spectrum, so if you cannot load a program with a Spectrum, you'll most probably will not be able to load it with 'spload'. Good Luck! 9. Bug reports ============== Please send bug reports to: mszeredi@inf.bme.hu If you make any changes to the source, please mail me the 'diff -u' of the file(s) changed, and also why were the changes needed. Please also tell me if you would like to maintain, or to continue developing spectemu. 10. Credits =========== Szeredi Tamas, for testing the emulator, and for helping with the 'spectkey.gif'. Egmont Koblinger for helping to write some parts of the emulator, and for a lot of useful suggestions. Dani Nagy and Zsazsa for helping to test the emulator. G.A. Lunter for a very good description of the Spectrum, the undocumented features of Z80, and the '.z80' snapshot file format. And lots of others, who sent me good ideas and modifications. spectemu-0.94/z80_op2.c0100644000175000017500000000767306505020714015117 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef NO_OPDEF #include "z80_def.h" #include "z80_op2.h" #endif OPDEF(halt, 0x76) { register int nn; DANM(haltstate) = 1; nn = (DANM(tc) - 1) / 4 + 1; DANM(tc) -= 4 * nn; RR += nn-1; ENDOP(); } #define LD_R_R(rdn, rsn, rd, rs, n1, n2) \ OPDEF(ld_ ## rdn ## _ ## rsn, 0x40 + n1 * 8 + n2) \ { \ rd = rs; \ ENTIME(4); \ } #if 0 #define LD_NOOP(rsd, n) \ OPDEF(ld_ ## rsd ## _ ## rsd, 0x40 + n * 8 + n) \ { \ ENTIME(4); \ } LD_NOOP(b, 0) LD_NOOP(c, 1) LD_NOOP(d, 2) LD_NOOP(e, 3) LD_NOOP(h, 4) LD_NOOP(l, 5) LD_NOOP(a, 7) #endif LD_R_R(b, c, RB, RC, 0, 1) LD_R_R(b, d, RB, RD, 0, 2) LD_R_R(b, e, RB, RE, 0, 3) LD_R_R(b, h, RB, RH, 0, 4) LD_R_R(b, l, RB, RL, 0, 5) LD_R_R(b, a, RB, RA, 0, 7) LD_R_R(c, b, RC, RB, 1, 0) LD_R_R(c, d, RC, RD, 1, 2) LD_R_R(c, e, RC, RE, 1, 3) LD_R_R(c, h, RC, RH, 1, 4) LD_R_R(c, l, RC, RL, 1, 5) LD_R_R(c, a, RC, RA, 1, 7) LD_R_R(d, b, RD, RB, 2, 0) LD_R_R(d, c, RD, RC, 2, 1) LD_R_R(d, e, RD, RE, 2, 3) LD_R_R(d, h, RD, RH, 2, 4) LD_R_R(d, l, RD, RL, 2, 5) LD_R_R(d, a, RD, RA, 2, 7) LD_R_R(e, b, RE, RB, 3, 0) LD_R_R(e, c, RE, RC, 3, 1) LD_R_R(e, d, RE, RD, 3, 2) LD_R_R(e, h, RE, RH, 3, 4) LD_R_R(e, l, RE, RL, 3, 5) LD_R_R(e, a, RE, RA, 3, 7) LD_R_R(h, b, RH, RB, 4, 0) LD_R_R(h, c, RH, RC, 4, 1) LD_R_R(h, d, RH, RD, 4, 2) LD_R_R(h, e, RH, RE, 4, 3) LD_R_R(h, l, RH, RL, 4, 5) LD_R_R(h, a, RH, RA, 4, 7) LD_R_R(l, b, RL, RB, 5, 0) LD_R_R(l, c, RL, RC, 5, 1) LD_R_R(l, d, RL, RD, 5, 2) LD_R_R(l, e, RL, RE, 5, 3) LD_R_R(l, h, RL, RH, 5, 4) LD_R_R(l, a, RL, RA, 5, 7) LD_R_R(a, b, RA, RB, 7, 0) LD_R_R(a, c, RA, RC, 7, 1) LD_R_R(a, d, RA, RD, 7, 2) LD_R_R(a, e, RA, RE, 7, 3) LD_R_R(a, h, RA, RH, 7, 4) LD_R_R(a, l, RA, RL, 7, 5) #define LD_R_IHL(rdn, rd, n) \ OPDEF(ld_ ## rdn ## _ihl, 0x46+n*8) \ { \ rd = *HLP; \ ENTIME(7); \ } #define LD_R_ID(ixyn, ixy, rsn, rs, n) \ OPDEF(ld_ ## rsn ## _i ## ixyn ## d, 0x46+n*8) \ { \ register dbyte addr; \ IXDGET(ixy, addr); \ rs = READ(addr); \ ENTIME(15); \ } LD_R_IHL(b, RB, 0) LD_R_IHL(c, RC, 1) LD_R_IHL(d, RD, 2) LD_R_IHL(e, RE, 3) LD_R_IHL(h, RH, 4) LD_R_IHL(l, RL, 5) LD_R_IHL(a, RA, 7) #define LD_IHL_R(rsn, rs, n) \ OPDEF(ld_ihl_ ## rsn, 0x70+n) \ { \ PUTMEM(HL, HLP, rs); \ ENTIME(7); \ } #define LD_ID_R(ixyn, ixy, rsn, rs, n) \ OPDEF(ld_i ## ixyn ## d_ ## rsn, 0x70+n) \ { \ register dbyte addr; \ IXDGET(ixy, addr); \ WRITE(addr, rs); \ ENTIME(15); \ } LD_IHL_R(b, RB, 0) LD_IHL_R(c, RC, 1) LD_IHL_R(d, RD, 2) LD_IHL_R(e, RE, 3) LD_IHL_R(h, RH, 4) LD_IHL_R(l, RL, 5) LD_IHL_R(a, RA, 7) #include "z80_op2x.c" spectemu-0.94/i386op5.S0100644000175000017500000001245506505020712015003 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* instructions prefixed by ED */ #define IN_R_IC(rd) \ IN(in_ ## rd ## _ic, RB, RC, rd); \ testb rd, rd ; \ CFLAG(BUTCF, SZPF) ; \ TIME(12) #define IN_M_IC(rd) \ xchgb rd, RA ; \ IN(in_ ## rd ## _ic, RB, RC, RA); \ testb RA, RA ; \ CFLAG(BUTCF, SZPF) ; \ xchgb rd, RA ; \ TIME(12) in_b_ic: IN_R_IC(RB) in_c_ic: IN_R_IC(RC) in_d_ic: IN_M_IC(MD) in_e_ic: IN_M_IC(ME) in_h_ic: IN_R_IC(RH) in_l_ic: IN_R_IC(RL) in_f_ic: IN_R_IC(RW) /* No load in registers */ in_a_ic: IN_R_IC(RA) #define OUT_IC_R(rs) \ OUT(out_ic_ ## rs, RB, RC, rs); \ TIME(12) #define OUT_IC_M(rs) \ xchgb rs, RA ; \ OUT(out_ic_ ## rs, RB, RC, RA); \ xchgb rs, RA ; \ TIME(12) out_ic_b: OUT_IC_R(RB) out_ic_c: OUT_IC_R(RC) out_ic_d: OUT_IC_M(MD) out_ic_e: OUT_IC_M(ME) out_ic_h: OUT_IC_R(RH) out_ic_l: OUT_IC_R(RL) out_ic_0: xorb RW,RW OUT_IC_R(RW) out_ic_a: OUT_IC_R(RA) #define SBC_HL_RR(rh, rl) \ sbbb rl, RL ; \ sbbb rh, RH ; \ pushfl ; \ testw RHL, RHL ; \ SFLAG(ALLF, ZF) ; \ popfl ; \ VSFLAG(SHCF, SHCF) ; \ TIME(15) sbc_hl_bc: SFLAGS SBC_HL_RR(RB, RC) sbc_hl_de: SFLAGS SBC_HL_RR(MD, ME) sbc_hl_hl: SFLAGS SBC_HL_RR(RH, RL) sbc_hl_sp: SFLAGS movw RSP, RVW SBC_HL_RR(RV, RW) #define ADC_HL_RR(rh, rl) \ adcb rl, RL ; \ adcb rh, RH ; \ pushfl ; \ testw RHL, RHL ; \ CFLAG(ALLF, ZF) ; \ popfl ; \ VCFLAG(SHCF, SHCF) ; \ TIME(15) adc_hl_bc: SFLAGS ADC_HL_RR(RB, RC) adc_hl_de: SFLAGS ADC_HL_RR(MD, ME) adc_hl_hl: SFLAGS ADC_HL_RR(RH, RL) adc_hl_sp: movw RSP, RVW SFLAGS ADC_HL_RR(RV, RW) #define LD_INN_RR(rn, rh, rl) \ DFETCHP ; \ PUTMEM_RVW_NE(ld_inn1_ ## rn, rl); \ incw RVW ; \ PUTMEM_RVW_NE(ld_inn2_ ## rn, rh) ld_inn_bc: LD_INN_RR(bc, RB, RC) TIME(20) ld_inn_de: xchgw MDE, RHL LD_INN_RR(de, RH, RL) xchgw MDE, RHL TIME(20) ld_inn_hl_ed: LD_INN_RR(hl, RH, RL) TIME(20) ld_inn_sp: xchgw RSP, RHL LD_INN_RR(sp, RH, RL) xchgw RSP, RHL TIME(20) #define LD_RR_INN(rh, rl) \ DFETCHP ; \ movb (VWP), rl ; \ incw RVW ; \ movb (VWP), rh ld_bc_inn: LD_RR_INN(RB, RC) TIME(20) ld_de_inn: xchgw MDE, RHL LD_RR_INN(RH, RL) xchgw MDE, RHL TIME(20) ld_hl_inn_ed: LD_RR_INN(RH, RL) TIME(20) ld_sp_inn: xchgw RSP, RHL LD_RR_INN(RH, RL) xchgw RSP, RHL TIME(20) neg: negb RA SUBFLAGS TIME(8) retn: movl IFF2, VWP movl VWP, IFF1 POPD(RPC) TIME(14) reti: POPD(RPC) TIME(14) im_0: movl $0, IT_MODE TIME(8) im_1: movl $1, IT_MODE TIME(8) im_2: movl $2, IT_MODE TIME(8) ld_i_a: movb RA, MI TIME(9) ld_r_a: movb RA, RL7 movb RA, RW andb $0x80, RW movb RW, MR TIME(9) #define AIRFLAGS \ testb RA, RA ; \ CFLAG(BUTCF, SZF) ; \ movl IFF2, VWP ; \ testl VWP, VWP ; \ jz ld_air_end ; \ orb $PVF, RF ; \ TIME(9) ; \ ALIGN ld_air_end: andb $~PVF, RF TIME(9) ld_a_i: movb MI, RA AIRFLAGS ld_a_r: movb MR, RA movb RL7, RW andb $0x7F, RW orb RW, RA AIRFLAGS rrd: movb RA, RV movb (HLP), RW shlw $4, RVW shrb $4, RW andb $0xF0, RA orb RW, RA movb RV, RW CFLAG(BUTCF, SZPF) PUTMEM_RHL(rrd, RW, 18) rld: movb RA, RW movb (HLP), RV shlb $4, RW shrw $4, RVW andb $0xF0, RA orb RV, RA CFLAG(BUTCF, SZPF) PUTMEM_RHL(rld, RW, 18) #define REPEAT \ subw $2, RPC #define LDID(l, dir) \ movb (HLP), RW ; \ xchgw RHL, MDE ; \ PUTMEM_RHL_NE(l, RW) ; \ dir RHL ; \ xchgw RHL, MDE ; \ dir RHL ; \ andb $~HPNF, RF ; \ decw RBC ; \ jz ldid ; \ orb $PVF, RF ldid: TIME(16) ldi: LDID(ldi, incw) TIME(16) ldir: LDID(ldir, incw) REPEAT TIME(21) ldd: LDID(ldd, decw) TIME(16) lddr: LDID(lddr, decw) REPEAT TIME(21) #define CPID(dir) \ cmpb (HLP), RA ; \ SFLAG(BUTCF, SZHF) ; \ dir RHL ; \ decw RBC ; \ jz cpid ; \ JCOND(ZF, ldid) cpid: andb $~PVF, RF TIME(16) cpi: CPID(incw) TIME(16) cpir: CPID(incw) REPEAT TIME(21) cpd: CPID(decw) TIME(16) cpdr: CPID(decw) REPEAT TIME(21) #define INID(l, dir) \ decb RB ; \ VSFLAG(BUTCF, SZHF) ; \ IN(l, RB, RC, RW) ; \ PUTMEM_RHL_NE(l, RW) ; \ dir RHL ; \ testb RB, RB ; \ jz ldid ini: INID(ini, incw) TIME(16) inir: INID(inir, incw) REPEAT TIME(21) ind: INID(ind, decw) TIME(16) indr: INID(indr, decw) REPEAT TIME(21) #define OTID(l, dir) \ decb RB ; \ VSFLAG(BUTCF, SZHF) ; \ movb (HLP), RW ; \ OUT(l, RB, RC, RW) ; \ dir RHL ; \ testb RB, RB ; \ jz ldid outi: OTID(outi, incw) TIME(16) otir: OTID(otir, incw) REPEAT TIME(21) outd: OTID(outd, decw) TIME(16) otdr: INID(otdr, decw) REPEAT TIME(21) ill_ed: TIME(8) spectemu-0.94/ChangeLog0100644000175000017500000001361006530021034015302 0ustar cjwatsoncjwatson98/05/18 Version 0.94 released =============================== 98/05/18 Updated the man page (a more complete man-page is still needed!) 98/05/15 Some bugs fixed 98/05/14 Version 0.93.4 released -------------------------------- 98/05/14 Small additions: - Keyboard matrix is emulated (only 1 level, I hope this is enough) - "color refreshing" (maybe some other aplications could do it!) - Keyboard configuration is now fully implemented 98/05/11 Added DOS timer support with Allegro library 98/05/08 Version 0.93.3 released --------------------------------- 98/05/08 Created README.Z80 to describe how to use Z80 emulation 98/05/06 Small new features + bugfixes - Function keys for commonly used functions - Keyboard config: (extended, spectrum, compat) and (shifted, raw) are now working. No custom keyboard or joystick yet - Small modifications to make z80 emulation separate 98/04/30 Version 0.93.2 released --------------------------------- 98/04/30 I've removed the BROKEN_VGAKEYBOARD part from vgakey.c. I hope nobody's using SVGALIB version smaller than 1.2.11. 98/04/29 Some small new features: (see example.cfg for a complete list) - different icon when the emulator is paused - optional private colormap - configurable colours (grayscale looks better on monochrome displays) - filetype can be given on the command line (tapefiles too) - optional immediate loading of tapes (-load-immed) 98/04/27 Added configurability to spectemu: - global config file (($prefix)/share/spectemu/spectemu.cfg) - user's config file (~/.spectemurc) - X resource database - command line 98/04/23 Mode 320x240 is used in vgaspect (if available) 98/04/22 Version 0.93.1 released --------------------------------- 98/04/21 Handle "extra" ascii keys: []{}|\~ 98/04/19 Added Spectrum keyboard picture, which shows pressed keys, and keys can be pressed with mouse. 98/04/16 Rewrite keyboard handling: - Fixes keyboard bug in X (key remained pressed) - Better configurability: spectrum key definitions are in spkey.c instead of xkey.c and vgakey.c 98/04/07 Added readline support by Christian Sievers 98/03/24 Version 0.92 released =============================== 98/03/23 Last minute bugfixes 98/03/20 Version 0.92p3 released 98/03/20 Eliminated all sorts of minor bugs 98/03/19 Implement LOOP/CALL/RETURN blocks in TZX handling 98/03/17 Fixed (hopefully all) bugs in TZX handling: - There must be a 1ms pause at end of tape. - Pausing after data blocks fixed. - Made tape I/O timing ultra precise (e.g. see Flashpoint) 98/03/14 Fixed small bug in quick load 98/03/13 Sound of tape is now fixed (not perfect, but good enough) Created simple man page 98/03/11 Version 0.92pre2 released 98/03/10 Fixed quick load of tapefiles 98/03/10 Fixed resize bugs 98/03/09 Version 0.92pre1 released 98/03/08 C-version now handles bits 3 and 5 of the Flag register (I hope I didn't break anything with this). 98/03/08 Wrote 'tapeout' utility to save tapefiles to real tape (via soundcard). 98/03/06 Implemented emulator pause. 98/03/06 Added ability to display spectrum keyboard layout on text console (Radovan.Garabik@fmph.uniba.sk). 98/03/05 Rewrite of snapshot handeling: - All versions of Z80 snapshots can now be loaded. - Loading and saving of SNA snapshot format is supported. - Quick loading and saving of temporary snapshot. 98/03/03 Rewrite of tapefile handeling: - Support for most TZX blocks (recognise length of all v1.11 blocks) - SPT tapefiles are no longer supported - Added quick loading of tapefiles - Timing in tape emulation is very exact now, but this makes tape sound ugly (this will be fixed). 98/01/28 Version 0.91a released 98/01/26 Added detection for underlines in asm names to configure 98/01/12 Version 0.91 released =============================== 98/01/08 Changes to configure to detect X libraries better 97/11/29 Use XSetWMProperties instead of XmbSetWMProperties 97/11/26 Created icon for xspect 97/11/20 IO and memory timing are improved (ULA / CPU clash) 97/11/18 Fixed 0xfe port problems 97/11/17 Input from unused ports (others than 0xFE) result in 0xFF, not 0x00 97/11/12 8000 sample/sec sound on SUN 97/11/12 Fixed screen bugs 97/11/11 Window resizing in X (thanks to Egmont) 97/11/11 Fixed FocusIn/FocusOut bug (twm, olwm, ...) 97/11/11 Small changes and bugfixes 97/11/09 Sound on SUN (sample rate 16000, but 8000 is coming for older SUNs. 97/10/26 'Interrupted system call' is not an error on sound device 97/10/26 Fixed screen scramble bug in console background running 97/10/20 Version 0.90pre1 released 97/10/20 Tested on the following Machines/Operating systems/Compilers: o Intel/Linux/gcc (assembly) o Sparc/Solaris/gcc (C) o Alpha/OSF1/cc (C) o Sequent(i486)/Dynix-Ptx/gcc (assembly) 97/10/20 Automatic configuration with 'configure' script 97/10/20 Bugfixes and cleanups 97/10/20 Experimental DOS support with DJGPP (timer missing) 97/10/20 Added emulation in C 97/05/22 Background running for svgalib added (Needs svgalib >= 1.2.11) 97/04/17 Version 0.84 released =============================== 97/04/17 Added SLL to the emulated instructions 97/04/12 The following changes were inspired by Egmont Koblinger: - Resize bug fixed - Implemented tape file pause - Implemented saving to tape file - Snapshot loading from command line - Other small changes 97/04/03 Bug fix in tape handling (thanks to Egmont Koblinger) 97/03/26 Speeded up border drawing in X 97/03/26 Added .TAP support 97/03/10 Version 0.81 released =============================== 97/03/10 Bug fixes and minor changes (thanks to Tamas Meszaros) 97/01/21 Version 0.8: First public release =========================================== spectemu-0.94/z80_op1.c0100644000175000017500000001535306505020714015110 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef NO_OPDEF #include "z80_def.h" #include "z80_op1.h" #endif OPDEF(nop, 0x00) { ENTIME(4); } OPDEF(ex_af_afb, 0x08) { register byte *ptmp; ptmp = DANM(br)[ZI_AF].p; DANM(br)[ZI_AF].p = DANM(nr)[ZI_AF].p; DANM(nr)[ZI_AF].p = ptmp; ENTIME(4); } OPDEF(djnz_e, 0x10) { if(!--RB) { PC++; ENTIME(8); } else { PC += IPCS; PC++; ENTIME(13); } } OPDEF(jr_e, 0x18) { PC += IPCS; PC++; ENTIME(12); } #define JR_CC_E(ccn, cc, n) \ OPDEF(jr_ ## ccn ## _e, 0x20+n*8) \ { \ if(!(cc)) { \ PC++; \ ENTIME(7); \ } \ else { \ PC += IPCS; PC++; \ ENTIME(12); \ } \ } JR_CC_E(nz, !TESTZF, 0) JR_CC_E(z, TESTZF, 1) JR_CC_E(nc, !TESTCF, 2) JR_CC_E(c, TESTCF, 3) #define LD_RR_NN(rrn, rr, n) \ OPDEF(ld_ ## rrn ## _nn, 0x01+n*0x10) \ { \ FETCHD(rr); \ ENTIME(10); \ } LD_RR_NN(bc, BC, 0) LD_RR_NN(de, DE, 1) LD_RR_NN(hl, HL, 2) LD_RR_NN(sp, SP, 3) #define DADD(rr1, rr2) \ register dbyte dtmp; \ register int idx; \ dtmp = rr1; \ rr1 = dtmp + rr2; \ idx = DIDXCALC(dtmp, rr2, rr1); \ SETFLAGS(CF | NF | HF, TAB(addf_tbl)[idx] & (CF | HF)) #define ADD_RR_RR(rrn1, rr1, rrn2, rr2, n) \ OPDEF(add_## rrn1 ## _ ## rrn2, 0x09+n*0x10) \ { \ DADD(rr1, rr2); \ ENTIME(11); \ } ADD_RR_RR(hl, HL, bc, BC, 0) ADD_RR_RR(hl, HL, de, DE, 1) ADD_RR_RR(hl, HL, hl, HL, 2) ADD_RR_RR(hl, HL, sp, SP, 3) #define INC_RR(rrn, rr, n) \ OPDEF(inc_ ## rrn, 0x03+n*0x10) \ { \ rr++; \ ENTIME(6); \ } INC_RR(bc, BC, 0) INC_RR(de, DE, 1) INC_RR(hl, HL, 2) INC_RR(sp, SP, 3) #define DEC_RR(rrn, rr, n) \ OPDEF(dec_ ## rrn, 0x0B+n*0x10) \ { \ rr--; \ ENTIME(6); \ } DEC_RR(bc, BC, 0) DEC_RR(de, DE, 1) DEC_RR(hl, HL, 2) DEC_RR(sp, SP, 3) OPDEF(ld_ibc_a, 0x02) { PUTMEM(BC, BCP, RA); ENTIME(7); } OPDEF(ld_ide_a, 0x12) { PUTMEM(DE, DEP, RA); ENTIME(7); } #define LD_INN_RR(rrn, rr) \ OPDEF(ld_inn_ ## rrn, 0x22) \ { \ register dbyte dtmp; \ FETCHD(dtmp); \ DWRITE(dtmp, rr); \ ENTIME(16); \ } LD_INN_RR(hl, HL) OPDEF(ld_inn_a, 0x32) { register dbyte dtmp; FETCHD(dtmp); WRITE(dtmp, RA); ENTIME(13); } OPDEF(ld_a_ibc, 0x0A) { RA = *BCP; ENTIME(7); } OPDEF(ld_a_ide, 0x1A) { RA = *DEP; ENTIME(7); } #define LD_RR_INN(rrn, rr) \ OPDEF(ld_ ## rrn ## _inn, 0x2A) \ { \ register dbyte dtmp; \ FETCHD(dtmp); \ rr = DREAD(dtmp); \ ENTIME(16); \ } LD_RR_INN(hl, HL) OPDEF(ld_a_inn, 0x3A) { register dbyte dtmp; FETCHD(dtmp); RA = READ(dtmp); ENTIME(13); } #define INC(r) \ r++; \ SETFLAGS(SF | ZF | PVF | B3F | B5F, TAB(incf_tbl)[r]) #define INC_R(rn, r, n) \ OPDEF(inc_ ## rn, 0x04+n*8) \ { \ INC(r); \ ENTIME(4); \ } INC_R(b, RB, 0) INC_R(c, RC, 1) INC_R(d, RD, 2) INC_R(e, RE, 3) INC_R(h, RH, 4) INC_R(l, RL, 5) INC_R(a, RA, 7) OPDEF(inc_ihl, 0x34) { MODMEM(INC); ENTIME(11); } #define DEC(r) \ r--; \ SETFLAGS(SF | ZF | PVF | B3F | B5F, TAB(decf_tbl)[r]) #define DEC_R(rn, r, n) \ OPDEF(dec_ ## rn, 0x05+n*8) \ { \ DEC(r); \ ENTIME(4); \ } DEC_R(b, RB, 0) DEC_R(c, RC, 1) DEC_R(d, RD, 2) DEC_R(e, RE, 3) DEC_R(h, RH, 4) DEC_R(l, RL, 5) DEC_R(a, RA, 7) OPDEF(dec_ihl, 0x35) { MODMEM(DEC); ENTIME(11); } #define LD_R_N(rn, r, n) \ OPDEF(ld_ ## rn ## _n, 0x06+n*8) \ { \ r = *PCP; \ PC++; \ ENTIME(7); \ } LD_R_N(b, RB, 0) LD_R_N(c, RC, 1) LD_R_N(d, RD, 2) LD_R_N(e, RE, 3) LD_R_N(h, RH, 4) LD_R_N(l, RL, 5) LD_R_N(a, RA, 7) OPDEF(ld_ihl_n, 0x36) { PUTMEM(HL, HLP, *PCP); PC++; ENTIME(10); } OPDEF(rlca, 0x07) { register byte btmp; btmp = (RA & 0x80) >> 7; SETFLAGS(HF | NF | CF, btmp); RA = (RA << 1) | btmp; ENTIME(4); } OPDEF(rrca, 0x0F) { register byte btmp; btmp = (RA & 0x01); SETFLAGS(HF | NF | CF, btmp); if(btmp) { RA = (RA >> 1) | 0x80; ENTIME(4); } else { RA >>= 1; ENTIME(4); } } OPDEF(rla, 0x17) { register byte btmp; btmp = RA & 0x80; RA = (RA << 1) | (RF & CF); SETFLAGS(HF | NF | CF, btmp >> 7); ENTIME(4); } OPDEF(rra, 0x1F) { register byte btmp; btmp = TESTCF; SETFLAGS(HF | NF | CF, RA & 0x01); if(btmp) { RA = (RA >> 1) | 0x80; ENTIME(4); } else { RA >>= 1; ENTIME(4); } } OPDEF(daa, 0x27) { register int flag; flag = RF; if(!TESTNF) { if(flag & CF) RA += 0x60; else if(RA > 0x99) RA += 0x60, flag |= CF; if(flag & HF) RA += 0x06; else if((RA & 0x0F) > 9) RA += 0x06, flag |= HF; } else { if(flag & CF) RA -= 0x60; else if(RA > 0x99) RA -= 0x60, flag |= CF; if(flag & HF) RA -= 0x06; else if((RA & 0x0F) > 9) RA -= 0x06, flag |= HF; } flag = (flag & ~(SF | ZF | PVF | B3F | B5F)) | TAB(orf_tbl)[RA]; RF = flag; ENTIME(4); } OPDEF(cpl, 0x2F) { RA = ~RA; SET_FL(HF | NF); ENTIME(4); } OPDEF(scf, 0x37) { SETFLAGS(HF | NF, CF); ENTIME(4); } OPDEF(ccf, 0x3F) { RF = (RF ^ CF) & ~(NF); /* HF undefined */ ENTIME(4); } #include "z80_op1x.c" spectemu-0.94/TODO0100644000175000017500000000150106530024326014223 0ustar cjwatsoncjwatsonGeneral: - Joystick emulation with PC Joystick - improve man page - ? automatic frame rate / sound buffer size - show processor usage Sound: - un-nice the program (optionally) to make sound better. - PC speaker sound Screen: - better z80_mem -> image conversion - on screen menus - ? monochrome displays - if memory problems while resizing do not exit - only update if necessary (border updatate cleanup) - Fix: bug if byte_order of client != byte_order of server Z80 emulation: - implement all known undocumented instructions - optimize LD*R CP*R IN*R OT*R instructions I/O emulation: - EVEN better timing for memory read/write (see aquaplane) DOS Port: - sound support - ? use allegro's keyboard handling Future plans (after version 1.0): - spectrum 128 - AY8192 emulation - ? "mouse" joystick spectemu-0.94/compr.c0100644000175000017500000000300206505732404015022 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "compr.h" void compr(void) { int j, c, lc, lled, rep, num; rep = 0; c = compr_read_byte(); lc = 0; num = 0; while(c >= 0) { if(lc == 0xED) lled = 1; else lled = 0; lc = c; c = compr_read_byte(); if(c == lc && num != 255 && (!lled || rep)) { if(!rep) { num = 1; rep = 1; } num++; } else { if(rep) { if(num < 5 && lc != 0xED) for(j = 0; j < num; j++) compr_put_byte(lc); else{ compr_put_byte(0xED); compr_put_byte(0xED); compr_put_byte(num); compr_put_byte(lc); num = 0; } rep = 0; } else compr_put_byte(lc); } } compr_put_byte(0x00); compr_put_byte(0xED); compr_put_byte(0xED); compr_put_byte(0x00); } spectemu-0.94/z80_type.h0100644000175000017500000000207206512215755015402 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef Z80_TYPE_H #define Z80_TYPE_H typedef unsigned char byte; typedef signed char sbyte; typedef unsigned short dbyte; typedef unsigned int qbyte; typedef signed char gchar; typedef signed short gshort; typedef signed int gint; #endif /* Z80_TYPE_H */ spectemu-0.94/i386def.S0100644000175000017500000000171706524021271015037 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AOUT_FORMAT # define NAME(s) _ ## s #else # define NAME(s) s #endif #define ALIGN .align 4 #define TC %edi spectemu-0.94/COPYING0100644000175000017500000004307006245303706014602 0ustar cjwatsoncjwatson GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. spectemu-0.94/spperif.h0100644000175000017500000000425206521564033015366 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPPERIF_H #define SPPERIF_H #ifndef COMPARISON #define SPNM(x) sp_ ## x #else #define SPNM(x) spx_ ## x #endif #include "z80_type.h" #define ST 140000 #define CHKTICK 224 /* #define TMNUM (ST / CHKTICK) */ #if 0 # define TMNUM 625 # define EVENHF 313 # define ODDHF 312 #else # define TMNUM 624 # define EVENHF 312 # define ODDHF 312 #endif #define LOAD_DI 0x0559 #define SA_LD_RET 0x053F extern int SPNM(quick_load); extern int SPNM(load_trapped); #define SCRMARK_SIZE 2048 extern qbyte SPNM(scr_mark)[]; extern byte SPNM(fe_inport_high)[]; extern int SPNM(playing_tape); extern int SPNM(paused); extern int SPNM(scline); extern unsigned char SPNM(colors)[]; extern int SPNM(flash_state); extern qbyte *SPNM(scr_f0_table); extern qbyte *SPNM(scr_f1_table); extern int SPNM(scri)[]; extern int SPNM(coli)[]; #define PORT_TIME_NUM 1024 extern byte SPNM(tape_impinfo)[]; extern byte SPNM(fe_inport_default); extern byte SPNM(fe_outport_time)[]; extern signed char SPNM(tape_sound)[]; extern byte SPNM(sound_buf)[]; extern char *SPNM(image); extern int SPNM(updating); extern qbyte SPNM(imag_mark)[]; extern qbyte SPNM(imag_horiz); extern qbyte SPNM(imag_vert); extern int SPNM(border_update); extern int SPNM(lastborder); extern void SPNM(init_screen_mark)(void); extern void SPNM(init)(void); extern int SPNM(halfframe)(int firsttick, int numlines); #endif /* SPPERIF_H */ spectemu-0.94/patch/0042755000175000017500000000000006245310172014642 5ustar cjwatsoncjwatsonspectemu-0.94/patch/svgakey-1.2.10.patch0100644000175000017500000000253506245310172020051 0ustar cjwatsoncjwatson*** keyboard.c.old Tue Sep 24 19:01:47 1996 --- keyboard.c Tue Sep 24 19:03:15 1996 *************** *** 211,227 **** /* VT switch. */ /* *** what about F11 & F12? */ int j, vt = 0; for (j = 0; j < 10; j++) if (functionkey_state & (1 << j)) { vt = j + 1; break; } ! /* ! * This will generate a signal catched by ! * svgalib to restore textmode. ! */ ! ioctl(__svgalib_tty_fd, VT_ACTIVATE, vt); ! return 1; } __keyboard_eventhandler(buf[i] & 0x7f, (buf[i] & 0x80) ? KEY_EVENTRELEASE : KEY_EVENTPRESS); --- 211,236 ---- /* VT switch. */ /* *** what about F11 & F12? */ int j, vt = 0; + struct vt_stat vts; for (j = 0; j < 10; j++) if (functionkey_state & (1 << j)) { vt = j + 1; break; } ! ! /* Do not switch vt's if need not to */ ! ioctl(__svgalib_tty_fd, VT_GETSTATE, &vts); ! ! if(vt != vts.v_active) { ! /* if switching vt's, need to clear keystates */ ! keyboard_clearstate(); ! /* ! * This will generate a signal catched by ! * svgalib to restore textmode. ! */ ! ioctl(__svgalib_tty_fd, VT_ACTIVATE, vt); ! return 1; ! } } __keyboard_eventhandler(buf[i] & 0x7f, (buf[i] & 0x80) ? KEY_EVENTRELEASE : KEY_EVENTPRESS); spectemu-0.94/z80_def.h0100644000175000017500000001031006524032377015151 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "z80.h" #ifdef PROCP typedef Z80 *z80t; #define OPDEF(name, num) z80t z80op_ ## name (z80t z80p) #define ENDOP() return z80p #undef DANM #define DANM(x) z80p->x #define TAB(t) DANM(t) #define PORT(t) DANM(t) #define SPECP(t) DANM(t) #else typedef void z80t; #define OPDEF(name, num) void z80op_ ## name (z80t) #define ENDOP() #define TAB(t) z80c_ ## t #define PORT(t) PRNM(t) #define SPECP(t) SPNM(t) #endif typedef z80t (*op_f)(z80t); extern op_f z80c_op_tab[]; extern op_f z80c_op_tab_cb[]; extern op_f z80c_op_tab_dd[]; extern op_f z80c_op_tab_ed[]; extern op_f z80c_op_tab_fd[]; #define TIME(x) DANM(tc) -= (x) #define ENTIME(x) { TIME(x); ENDOP(); } #define READ(addr) (DANM(mem)[addr]) #define WRITE(addr, val) PUTMEM(addr, DANM(mem) + (dbyte) (addr), val) #define DREAD(addr) (DANM(mem)[addr] | (DANM(mem)[(dbyte)(addr+1)] << 8)) #define DWRITE(addr, x) WRITE(addr, (byte) x); \ WRITE((dbyte) (addr+1), (byte) (x >> 8)) #define IPCS ((sbyte) *PCP) #define MODMEM(func) \ { \ register byte bdef; \ bdef = *HLP; \ func(bdef); \ PUTMEM(HL, HLP, bdef); \ } #define MODMEMADDR(func, addr) \ { \ register byte bdef; \ bdef = READ(addr); \ func(bdef); \ WRITE(addr, bdef); \ } #define IXDGET(ixy, addr) addr = ((dbyte) (ixy + IPCS)), PC++ #define FETCHD(x) \ { \ register dbyte ddef; \ ddef = PC; \ x = DREAD(ddef); \ PC = ddef+2; \ } #define POP(x) \ { \ register dbyte ddef; \ ddef = SP; \ x = DREAD(ddef); \ SP = ddef+2; \ } #define PUSH(x) \ { \ register dbyte ddef, dval; \ dval = x; \ ddef = SP-2; \ DWRITE(ddef, dval); \ SP = ddef; \ } #ifdef SPECT_MEM #include "sp_def.h" #else #define PUTMEM(addr, ptr, val) *(ptr) = (val) #define IN(porth, portl, dest) dest = PORT(inports)[portl] #define OUT(porth, portl, source) PORT(outports)[portl] = (source) #define DI_CHECK #endif #define SF 0x80 #define ZF 0x40 #define B5F 0x20 #define HF 0x10 #define B3F 0x08 #define PVF 0x04 #define NF 0x02 #define CF 0x01 #define ALLF (SF | ZF | HF | PVF | NF | CF) #define BUTCF (SF | ZF | HF | PVF | NF) #define AALLF 0xff #define ABUTCF 0xfe #define SETFLAGS(mask, val) (RF = (RF & ~(mask)) | (val)) #define SET_FL(x) (RF |= (x)) #define CLR_FL(x) (RF &= ~(x)) #define TESTZF (RF & ZF) #define TESTCF (RF & CF) #define TESTSF (RF & SF) #define TESTPF (RF & PVF) #define TESTHF (RF & HF) #define TESTNF (RF & NF) #define IDXCALC(v1, v2, res) \ ((res & 0xA8) | ((v1 & 0x88) >> 1) | ((v2 & 0x88) >> 3)) #define DIDXCALC(v1, v2, res) \ (((res & 0x8800) >> 8) | ((v1 & 0x8800) >> 9) | ((v2 & 0x8800) >> 11)) extern byte z80c_incf_tbl[]; extern byte z80c_decf_tbl[]; extern byte z80c_addf_tbl[]; extern byte z80c_subf_tbl[]; extern byte z80c_orf_tbl[]; spectemu-0.94/spperif.c0100644000175000017500000000450106521564672015367 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "spperif.h" #include "z80.h" extern unsigned char rom_imag[]; int SPNM(quick_load) = 0; int SPNM(load_trapped); qbyte SPNM(scr_mark)[SCRMARK_SIZE]; byte SPNM(fe_inport_high)[256]; int SPNM(scline); unsigned char SPNM(colors)[16]; int SPNM(flash_state); qbyte *SPNM(scr_f0_table); qbyte *SPNM(scr_f1_table); byte SPNM(tape_impinfo)[PORT_TIME_NUM]; byte SPNM(fe_inport_default); byte SPNM(fe_outport_time)[PORT_TIME_NUM]; byte SPNM(sound_buf)[PORT_TIME_NUM]; signed char SPNM(tape_sound)[TMNUM]; int SPNM(scri)[PORT_TIME_NUM]; int SPNM(coli)[PORT_TIME_NUM]; int SPNM(playing_tape) = 0; int SPNM(paused) = 0; char *SPNM(image); int SPNM(updating); qbyte SPNM(imag_mark)[192]; qbyte SPNM(imag_horiz); qbyte SPNM(imag_vert); int SPNM(border_update); int SPNM(lastborder); void SPNM(init_screen_mark)(void) { int i; for(i = 0x200; i < 0x2D8; i++) SPNM(scr_mark)[i] = ~((qbyte) 0); SPNM(border_update) = 1; } void SPNM(init)(void) { int i; PRNM(init)(); PRNM(reset)(); SPNM(load_trapped) = 0; for(i = 0; i < PORTNUM; i++) PRNM(inports)[i] = 0x00; DANM(inport_mask) = 0x20; /* TODO: Kempston is always present, this is not nice */ SPNM(fe_inport_default) = 0xBF; /* Issue 3 */ DANM(ula_outport) = 0xFF; for(i = 0; i < 256; i++) SPNM(fe_inport_high)[i] = 0xFF; for(i = 0; i < PORT_TIME_NUM; i++) SPNM(tape_impinfo)[i] = 0; DANM(imp_change) = 0; DANM(ula_inport) = SPNM(fe_inport_default); SPNM(scline) = 0; for(i = 0; i < 0x4000; i++) PRNM(proc).mem[i] = rom_imag[i]; SPNM(init_screen_mark)(); } spectemu-0.94/z80_step.c0100644000175000017500000000702606507725465015403 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "z80_def.h" byte z80c_incf_tbl[256]; byte z80c_decf_tbl[256]; byte z80c_addf_tbl[256]; byte z80c_subf_tbl[256]; byte z80c_orf_tbl[256]; void PRNM(pushpc)(void) { #ifdef PROCP Z80 *z80p; z80p = &PRNM(proc); #endif SP--; PUTMEM(SP, SPP, PCH); SP--; PUTMEM(SP, SPP, PCL); } static int parity(int b) { int i; int par; par = 0; for(i = 8; i; i--) par ^= (b & 1), b >>= 1; return par; } void PRNM(local_init)(void) { int i; #ifdef PROCP Z80 *z80p; z80p = &PRNM(proc); #endif for(i = 0; i < 0x100; i++) { z80c_incf_tbl[i] = z80c_decf_tbl[i] = z80c_orf_tbl[i] = 0; z80c_orf_tbl[i] |= i & (SF | B3F | B5F); z80c_incf_tbl[i] |= i & (SF | B3F | B5F); z80c_decf_tbl[i] |= i & (SF | B3F | B5F); if(!parity(i)) z80c_orf_tbl[i] |= PVF; } z80c_incf_tbl[0] |= ZF; z80c_decf_tbl[0] |= ZF; z80c_orf_tbl[0] |= ZF; z80c_incf_tbl[0x80] |= PVF; z80c_decf_tbl[0x7F] |= PVF; for(i = 0; i < 0x100; i++) { int cr, c1, c2; int hr, h1, h2; int b5r; cr = i & 0x80; c1 = i & 0x40; b5r = i & 0x20; c2 = i & 0x10; hr = i & 0x08; h1 = i & 0x04; h2 = i & 0x01; z80c_addf_tbl[i] = 0; z80c_subf_tbl[i] = 0; if(cr) { z80c_addf_tbl[i] |= SF; z80c_subf_tbl[i] |= SF; } if(b5r) { z80c_addf_tbl[i] |= B5F; z80c_subf_tbl[i] |= B5F; } if(hr) { z80c_addf_tbl[i] |= B3F; z80c_subf_tbl[i] |= B3F; } if((c1 && c2) || (!cr && (c1 || c2))) z80c_addf_tbl[i] |= CF; if((h1 && h2) || (!hr && (h1 || h2))) z80c_addf_tbl[i] |= HF; if((!c1 && !c2 && cr) || (c1 && c2 && !cr)) z80c_addf_tbl[i] |= PVF; if((c2 && cr) || (!c1 && (c2 || cr))) z80c_subf_tbl[i] |= CF; if((h2 && hr) || (!h1 && (h2 || hr))) z80c_subf_tbl[i] |= HF; if((!c2 && !cr && c1) || (c2 && cr && !c1)) z80c_subf_tbl[i] |= PVF; z80c_subf_tbl[i] |= NF; } #ifdef PROCP TAB(incf_tbl) = z80c_incf_tbl; TAB(decf_tbl) = z80c_decf_tbl; TAB(addf_tbl) = z80c_addf_tbl; TAB(subf_tbl) = z80c_subf_tbl; TAB(orf_tbl) = z80c_orf_tbl; PORT(inports) = PRNM(inports); PORT(outports) = PRNM(outports); #ifdef SPECT_MEM SPECP(fe_inport_high) = SPNM(fe_inport_high); #endif #endif } int PRNM(step)(int tc) { #ifdef PROCP Z80 *z80p; z80p = &PRNM(proc); #endif DANM(tc) = tc; DANM(rl7) = RR & 0x80; if(DANM(haltstate)) { register int nn; nn = (DANM(tc) - 1) / 4 + 1; DANM(tc) -= 4 * nn; RR += nn; } else do { register int nextop; #ifdef DEBUG_Z80 debug_z80(); #endif nextop = *PCP; PC++; #ifdef PROCP z80p = (*z80c_op_tab[nextop])(z80p); #else (*z80c_op_tab[nextop])(); #endif RR++; } while(DANM(tc) > 0); RR = (RR & 0x7F) | DANM(rl7); return DANM(tc); } spectemu-0.94/i386op1.S0100644000175000017500000000760006505020712014773 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ #define INC(m) \ incb m ; \ VCFLAG(SZPF, SZF) /* Nagy Dani says N and H don't change */ /* VCFLAG(BUTCF, SZHF) */ #define DEC(m) \ decb m ; \ VCFLAG(SZPF, SZF) /* Nagy Dani says N and H don't change */ /* VSFLAG(BUTCF, SZHF) */ #define DADD(h1, l1, h2, l2) \ addb l2, l1 ; \ adcb h2, h1 ; \ CFLAG(HNCF, HCF) /* instructions from 0x00 to 0x3F */ nop: TIME_NC(4) ex_af_afb: xchgw BAF, RAF TIME_NC(4) djnz_e: decb RB jne djnz_e_1 INCPC TIME_NC(8) djnz_e_1: FETCHS addw RVW, RPC TIME(13) jr_e: FETCHS addw RVW, RPC TIME(12) jr_nz_e: JNCOND(ZF, jr_e) INCPC TIME_NC(7) jr_z_e: JCOND(ZF, jr_e) INCPC TIME_NC(7) jr_nc_e: JNCOND(CF, jr_e) INCPC TIME_NC(7) jr_c_e: JCOND(CF, jr_e) INCPC TIME_NC(7) ld_bc_nn: FETCHR(RC) FETCHR(RB) TIME_NC(10) ld_de_nn: DFETCH movw RVW, MDE TIME(10) ld_hl_nn: FETCHR(RL) FETCHR(RH) TIME(10) ld_sp_nn: DFETCH movw RVW, RSP TIME(10) add_hl_bc: DADD(RH, RL, RB, RC) TIME(11) add_hl_de: DADD(RH, RL, MD, ME) TIME(11) add_hl_hl: DADD(RH, RL, RH, RL) TIME(11) add_hl_sp: movw RSP, RVW DADD(RH, RL, RV, RW) TIME(11) inc_bc: incw RBC TIME_NC(6) inc_de: incw MDE TIME_NC(6) inc_hl: incw RHL TIME_NC(6) inc_sp: incw RSP TIME_NC(6) dec_bc: decw RBC TIME_NC(6) dec_de: decw MDE TIME_NC(6) dec_hl: decw RHL TIME_NC(6) dec_sp: decw RSP TIME_NC(6) ld_ibc_a: PUTMEM_RBC(ld_ibc_a, RA, 7) ld_ide_a: movl MDE, VWP PUTMEM_RVW(ld_ide_a, RA, 7) ld_inn_hl: DFETCHP PUTMEM_RVW_NE(ld_inn_hl, RL) incw RVW PUTMEM_RVW(ld_inn_hl, RH, 16) ld_inn_a: DFETCHP PUTMEM_RVW(ld_inn_a, RA, 13) ld_a_ibc: movb (BCP), RA TIME_NC(7) ld_a_ide: movl MDE, VWP movb (VWP), RA TIME(7) ld_hl_inn: DFETCHP movb (VWP), RL incw RVW movb (VWP), RH TIME(16) ld_a_inn: DFETCHP movb (VWP), RA TIME(13) inc_b: INC(RB) TIME(4) inc_c: INC(RC) TIME(4) inc_d: INC(MD) TIME(4) inc_e: INC(ME) TIME(4) inc_h: INC(RH) TIME(4) inc_l: INC(RL) TIME(4) inc_ihl: MODMEM(INC, 11) inc_a: INC(RA) TIME(4) dec_b: DEC(RB) TIME(4) dec_c: DEC(RC) TIME(4) dec_d: DEC(MD) TIME(4) dec_e: DEC(ME) TIME(4) dec_h: DEC(RH) TIME(4) dec_l: DEC(RL) TIME(4) dec_ihl: MODMEM(DEC, 11) dec_a: DEC(RA) TIME(4) ld_b_n: FETCHR(RB) TIME(7) ld_c_n: FETCHR(RC) TIME(7) ld_d_n: FETCH movb RW, MD TIME(7) ld_e_n: FETCH movb RW, ME TIME(7) ld_h_n: FETCHR(RH) TIME(7) ld_l_n: FETCHR(RL) TIME(7) ld_ihl_n: FETCH PUTMEM_RHL(ld_ihl_n, RW, 10) ld_a_n: FETCHR(RA) TIME_NC(7) rlca: rolb RA CFLAG(HNCF, CF) TIME(4) rrca: rorb RA CFLAG(HNCF, CF) TIME(4) rla: SFLAGS rclb RA CFLAG(HNCF, CF) TIME(4) rra: SFLAGS rcrb RA CFLAG(HNCF, CF) TIME(4) #define DAAFLAGS \ CFLAG(BUTNF, BUTNF) daa: movb RA, RW testb $NF, RF jnz daa_s SFLAGS daa movb RW, RA DAAFLAGS TIME(4) daa_s: SFLAGS das movb RW, RA DAAFLAGS TIME(4) cpl: notb RA orb $HNF, RF TIME_NC(4) scf: andb $~HNF, RF orb $CF, RF TIME_NC(4) ccf: xorb $CF, RF andb $~NF, RF TIME_NC(4) #include "i386op1x.S" spectemu-0.94/i386op1x.S0100644000175000017500000000555406505020712015171 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* IX */ ld_ix_nn: DFETCH movw RVW, MIX TIMEX(14) add_ix_bc: xchgw RHL, MIX DADD(RH, RL, RB, RC) xchgw RHL, MIX TIMEX(15) add_ix_de: xchgw RHL, MIX DADD(RH, RL, MD, ME) xchgw RHL, MIX TIMEX(15) add_ix_ix: xchgw RHL, MIX DADD(RH, RL, RH, RL) xchgw RHL, MIX TIMEX(15) add_ix_sp: movw RSP, RVW xchgw RHL, MIX DADD(RH, RL, RV, RW) xchgw RHL, MIX TIMEX(15) inc_ix: incw MIX TIMEX(10) dec_ix: decw MIX TIMEX(10) ld_inn_ix: DFETCHP xchgw RHL, MIX PUTMEM_RVW_NE(ld_inn_ix1, RL) incw RVW PUTMEM_RVW_NE(ld_inn_ix2, RH) xchgw RHL, MIX TIMEX(20) ld_ix_inn: DFETCHP xchgw RHL, MIX movb (VWP), RL incw RVW movb (VWP), RH xchgw RHL, MIX TIMEX(20) inc_iixd: IXDGET MODMEMID(ix, INC, 23) inc_ixh: INC(MIXH) TIMEX(8) inc_ixl: INC(MIXL) TIMEX(8) dec_iixd: IXDGET MODMEMID(ix, DEC, 23) dec_ixh: DEC(MIXH) TIMEX(8) dec_ixl: DEC(MIXL) TIMEX(8) ld_iixd_n: IXDGET FETCH PUTMEMID_RHL(ld_iixd_n, RW, 19) ld_ixh_n: FETCH movb RW, MIXH TIMEX(11) ld_ixl_n: FETCH movb RW, MIXL TIMEX(11) /* IY */ ld_iy_nn: DFETCH movw RVW, MIY TIMEX(14) add_iy_bc: xchgw RHL, MIY DADD(RH, RL, RB, RC) xchgw RHL, MIY TIMEX(15) add_iy_de: xchgw RHL, MIY DADD(RH, RL, MD, ME) xchgw RHL, MIY TIMEX(15) add_iy_iy: xchgw RHL, MIY DADD(RH, RL, RH, RL) xchgw RHL, MIY TIMEX(15) add_iy_sp: movw RSP, RVW xchgw RHL, MIY DADD(RH, RL, RV, RW) xchgw RHL, MIY TIMEX(15) inc_iy: incw MIY TIMEX(10) dec_iy: decw MIY TIMEX(10) ld_inn_iy: DFETCHP xchgw RHL, MIY PUTMEM_RVW_NE(ld_inn_iy1, RL) incw RVW PUTMEM_RVW_NE(ld_inn_iy2, RH) xchgw RHL, MIY TIMEX(20) ld_iy_inn: DFETCHP xchgw RHL, MIY movb (VWP), RL incw RVW movb (VWP), RH xchgw RHL, MIY TIMEX(20) inc_iiyd: IYDGET MODMEMID(iy, INC, 23) inc_iyh: INC(MIYH) TIMEX(8) inc_iyl: INC(MIYL) TIMEX(8) dec_iiyd: IYDGET MODMEMID(iy, DEC, 23) dec_iyh: DEC(MIYH) TIMEX(8) dec_iyl: DEC(MIYL) TIMEX(8) ld_iiyd_n: IYDGET FETCH PUTMEMID_RHL(ld_iiyd_n, RW, 19) ld_iyh_n: FETCH movb RW, MIYH TIMEX(11) ld_iyl_n: FETCH movb RW, MIYL TIMEX(11) spectemu-0.94/i386op2.S0100644000175000017500000000531406505020712014774 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* instructions from 0x40 to 0x7F */ halt: movl $1, HALTSTATE haltstate: movl TC, VWP testl VWP, VWP jz haltstate_tc0 decl VWP haltstate_tc0: sarl $2, VWP incl VWP addl VWP, RL7 leal 0(,VWP,4), VWP subl VWP, TC jmp loop_end ALIGN #define LD_R_R(rd, rs) \ movb rs, rd ; \ TIME(4) #define LD_R_IHL(rd) \ movb (HLP), rd ; \ TIME(7) #define LD_IHL_R(rs) \ PUTMEM_RHL(ld_ihl_ ## rs, rs, 7) ld_b_c: LD_R_R(RB, RC) ld_b_d: LD_R_R(RB, MD) ld_b_e: LD_R_R(RB, ME) ld_b_h: LD_R_R(RB, RH) ld_b_l: LD_R_R(RB, RL) ld_b_ihl: LD_R_IHL(RB) ld_b_a: LD_R_R(RB, RA) ld_c_b: LD_R_R(RC, RB) ld_c_d: LD_R_R(RC, MD) ld_c_e: LD_R_R(RC, ME) ld_c_h: LD_R_R(RC, RH) ld_c_l: LD_R_R(RC, RL) ld_c_ihl: LD_R_IHL(RC) ld_c_a: LD_R_R(RC, RA) ld_d_b: LD_R_R(MD, RB) ld_d_c: LD_R_R(MD, RC) ld_d_e: movb ME, RW LD_R_R(MD, RW) ld_d_h: LD_R_R(MD, RH) ld_d_l: LD_R_R(MD, RL) ld_d_ihl: movb (HLP), RW movb RW, MD TIME(7) ld_d_a: LD_R_R(MD, RA) ld_e_b: LD_R_R(ME, RB) ld_e_c: LD_R_R(ME, RC) ld_e_d: movb MD, RW LD_R_R(ME, RW) ld_e_h: LD_R_R(ME, RH) ld_e_l: LD_R_R(ME, RL) ld_e_ihl: movb (HLP), RW movb RW, ME TIME(7) ld_e_a: LD_R_R(ME, RA) ld_h_b: LD_R_R(RH, RB) ld_h_c: LD_R_R(RH, RC) ld_h_d: LD_R_R(RH, MD) ld_h_e: LD_R_R(RH, ME) ld_h_l: LD_R_R(RH, RL) ld_h_ihl: LD_R_IHL(RH) ld_h_a: LD_R_R(RH, RA) ld_l_b: LD_R_R(RL, RB) ld_l_c: LD_R_R(RL, RC) ld_l_d: LD_R_R(RL, MD) ld_l_e: LD_R_R(RL, ME) ld_l_h: LD_R_R(RL, RH) ld_l_ihl: LD_R_IHL(RL) ld_l_a: LD_R_R(RL, RA) ld_ihl_b: LD_IHL_R(RB) ld_ihl_c: LD_IHL_R(RC) ld_ihl_d: movb MD, RV LD_IHL_R(RV) ld_ihl_e: movb ME, RW LD_IHL_R(RW) ld_ihl_h: LD_IHL_R(RH) ld_ihl_l: LD_IHL_R(RL) ld_ihl_a: LD_IHL_R(RA) ld_a_b: LD_R_R(RA, RB) ld_a_c: LD_R_R(RA, RC) ld_a_d: LD_R_R(RA, MD) ld_a_e: LD_R_R(RA, ME) ld_a_h: LD_R_R(RA, RH) ld_a_l: LD_R_R(RA, RL) ld_a_ihl: LD_R_IHL(RA) #include "i386op2x.S" spectemu-0.94/i386op2x.S0100644000175000017500000001056606505020712015171 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* IX */ #define LD_R_IIXD(rd) \ movl HLP, VWP ; \ FETCHS ; \ addw MIX, RVW ; \ movb (VWP), rd #define LD_IIXD_R(rs) \ movl HLP, VWP ; \ FETCHS ; \ addw MIX, RVW ; \ PUTMEM_RVW(ld_iixd_ ## rs, rs, 15) #define LD_IIXD_M(rs) \ movl HLP, VWP ; \ FETCHS ; \ addw MIX, RVW ; \ pushl HLP ; \ movb rs, RL ; \ PUTMEM_RVW_NE(ld_iixd_ ## rs, RL); \ popl HLP ; \ TIMEX(19) ld_b_iixd: LD_R_IIXD(RB) TIMEX(19) ld_b_ixh: movb MIXH, RB TIMEX(8) ld_b_ixl: movb MIXL, RB TIMEX(8) ld_c_iixd: LD_R_IIXD(RC) TIMEX(19) ld_c_ixh: movb MIXH, RC TIMEX(8) ld_c_ixl: movb MIXL, RC TIMEX(8) ld_d_iixd: LD_R_IIXD(RW) movb RW, MD TIMEX(19) ld_d_ixh: movb MIXH, RW movb RW, MD TIMEX(8) ld_d_ixl: movb MIXL, RW movb RW, MD TIMEX(8) ld_e_iixd: LD_R_IIXD(RW) movb RW, ME TIMEX(19) ld_e_ixh: movb MIXH, RW movb RW, ME TIMEX(8) ld_e_ixl: movb MIXL, RW movb RW, ME TIMEX(8) ld_h_iixd: LD_R_IIXD(RH) TIMEX(19) ld_ixh_b: movb RB, MIXH TIMEX(8) ld_ixh_c: movb RC, MIXH TIMEX(8) ld_ixh_d: movb MD, RW movb RW, MIXH TIMEX(8) ld_ixh_e: movb ME, RW movb RW, MIXH TIMEX(8) ld_ixh_ixl: movb MIXL, RW movb RW, MIXH TIMEX(8) ld_ixh_a: movb RA, MIXH TIMEX(8) ld_l_iixd: LD_R_IIXD(RL) TIMEX(19) ld_ixl_b: movb RB, MIXL TIMEX(8) ld_ixl_c: movb RC, MIXL TIMEX(8) ld_ixl_d: movb MD, RW movb RW, MIXL TIMEX(8) ld_ixl_e: movb ME, RW movb RW, MIXL TIMEX(8) ld_ixl_ixh: movb MIXH, RW movb RW, MIXL TIMEX(8) ld_ixl_a: movb RA, MIXL TIMEX(8) ld_iixd_b: LD_IIXD_R(RB) ld_iixd_c: LD_IIXD_R(RC) ld_iixd_d: LD_IIXD_M(MD) ld_iixd_e: LD_IIXD_M(ME) ld_iixd_h: LD_IIXD_R(RH) ld_iixd_l: LD_IIXD_R(RL) ld_iixd_a: LD_IIXD_R(RA) ld_a_iixd: LD_R_IIXD(RA) TIMEX(19) ld_a_ixh: movb MIXH, RA TIMEX(8) ld_a_ixl: movb MIXL, RA TIMEX(8) /* IY */ #define LD_R_IIYD(rd) \ movl HLP, VWP ; \ FETCHS ; \ addw MIY, RVW ; \ movb (VWP), rd #define LD_IIYD_R(rs) \ movl HLP, VWP ; \ FETCHS ; \ addw MIY, RVW ; \ PUTMEM_RVW(ld_iiyd_ ## rs, rs, 15) #define LD_IIYD_M(rs) \ movl HLP, VWP ; \ FETCHS ; \ addw MIY, RVW ; \ pushl HLP ; \ movb rs, RL ; \ PUTMEM_RVW_NE(ld_iiyd_ ## rs, RL); \ popl HLP ; \ TIMEX(19) ld_b_iiyd: LD_R_IIYD(RB) TIMEX(19) ld_b_iyh: movb MIYH, RB TIMEX(8) ld_b_iyl: movb MIYL, RB TIMEX(8) ld_c_iiyd: LD_R_IIYD(RC) TIMEX(19) ld_c_iyh: movb MIYH, RC TIMEX(8) ld_c_iyl: movb MIYL, RC TIMEX(8) ld_d_iiyd: LD_R_IIYD(RW) movb RW, MD TIMEX(19) ld_d_iyh: movb MIYH, RW movb RW, MD TIMEX(8) ld_d_iyl: movb MIYL, RW movb RW, MD TIMEX(8) ld_e_iiyd: LD_R_IIYD(RW) movb RW, ME TIMEX(19) ld_e_iyh: movb MIYH, RW movb RW, ME TIMEX(8) ld_e_iyl: movb MIYL, RW movb RW, ME TIMEX(8) ld_h_iiyd: LD_R_IIYD(RH) TIMEX(19) ld_iyh_b: movb RB, MIYH TIMEX(8) ld_iyh_c: movb RC, MIYH TIMEX(8) ld_iyh_d: movb MD, RW movb RW, MIYH TIMEX(8) ld_iyh_e: movb ME, RW movb RW, MIYH TIMEX(8) ld_iyh_iyl: movb MIYL, RW movb RW, MIYH TIMEX(8) ld_iyh_a: movb RA, MIYH TIMEX(8) ld_l_iiyd: LD_R_IIYD(RL) TIMEX(19) ld_iyl_b: movb RB, MIYL TIMEX(8) ld_iyl_c: movb RC, MIYL TIMEX(8) ld_iyl_d: movb MD, RW movb RW, MIYL TIMEX(8) ld_iyl_e: movb ME, RW movb RW, MIYL TIMEX(8) ld_iyl_iyh: movb MIYH, RW movb RW, MIYL TIMEX(8) ld_iyl_a: movb RA, MIYL TIMEX(8) ld_iiyd_b: LD_IIYD_R(RB) ld_iiyd_c: LD_IIYD_R(RC) ld_iiyd_d: LD_IIYD_M(MD) ld_iiyd_e: LD_IIYD_M(ME) ld_iiyd_h: LD_IIYD_R(RH) ld_iiyd_l: LD_IIYD_R(RL) ld_iiyd_a: LD_IIYD_R(RA) ld_a_iiyd: LD_R_IIYD(RA) TIMEX(19) ld_a_iyh: movb MIYH, RA TIMEX(8) ld_a_iyl: movb MIYL, RA TIMEX(8) spectemu-0.94/i386op3.S0100644000175000017500000000541206505020712014774 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* instructions from 0x80 to 0xBF */ add_a_b: ADD_A_R(RB) TIME(4) add_a_c: ADD_A_R(RC) TIME(4) add_a_d: ADD_A_R(MD) TIME(4) add_a_e: ADD_A_R(ME) TIME(4) add_a_h: ADD_A_R(RH) TIME(4) add_a_l: ADD_A_R(RL) TIME(4) add_a_ihl: ADD_A_R((HLP)) TIME(7) add_a_a: ADD_A_R(RA) TIME(4) adc_a_b: ADC_A_R(RB) TIME(4) adc_a_c: ADC_A_R(RC) TIME(4) adc_a_d: ADC_A_R(MD) TIME(4) adc_a_e: ADC_A_R(ME) TIME(4) adc_a_h: ADC_A_R(RH) TIME(4) adc_a_l: ADC_A_R(RL) TIME(4) adc_a_ihl: ADC_A_R((HLP)) TIME(7) adc_a_a: ADC_A_R(RA) TIME(4) sub_b: SUB_R(RB) TIME(4) sub_c: SUB_R(RC) TIME(4) sub_d: SUB_R(MD) TIME(4) sub_e: SUB_R(ME) TIME(4) sub_h: SUB_R(RH) TIME(4) sub_l: SUB_R(RL) TIME(4) sub_ihl: SUB_R((HLP)) TIME(7) sub_a: SUB_R(RA) TIME(4) sbc_a_b: SBC_A_R(RB) TIME(4) sbc_a_c: SBC_A_R(RC) TIME(4) sbc_a_d: SBC_A_R(MD) TIME(4) sbc_a_e: SBC_A_R(ME) TIME(4) sbc_a_h: SBC_A_R(RH) TIME(4) sbc_a_l: SBC_A_R(RL) TIME(4) sbc_a_ihl: SBC_A_R((HLP)) TIME(7) sbc_a_a: SBC_A_R(RA) TIME(4) and_b: AND_R(RB) TIME(4) and_c: AND_R(RC) TIME(4) and_d: AND_R(MD) TIME(4) and_e: AND_R(ME) TIME(4) and_h: AND_R(RH) TIME(4) and_l: AND_R(RL) TIME(4) and_ihl: AND_R((HLP)) TIME(7) and_a: AND_R(RA) TIME(4) xor_b: XOR_R(RB) TIME(4) xor_c: XOR_R(RC) TIME(4) xor_d: XOR_R(MD) TIME(4) xor_e: XOR_R(ME) TIME(4) xor_h: XOR_R(RH) TIME(4) xor_l: XOR_R(RL) TIME(4) xor_ihl: XOR_R((HLP)) TIME(7) xor_a: xorb RA, RA andb $~ALLF, RF orb $ZPF, RF TIME(4) or_b: OR_R(RB) TIME(4) or_c: OR_R(RC) TIME(4) or_d: OR_R(MD) TIME(4) or_e: OR_R(ME) TIME(4) or_h: OR_R(RH) TIME(4) or_l: OR_R(RL) TIME(4) or_ihl: OR_R((HLP)) TIME(7) or_a: OR_R(RA) TIME(4) cp_b: CP_R(RB) TIME(4) cp_c: CP_R(RC) TIME(4) cp_d: CP_R(MD) TIME(4) cp_e: CP_R(ME) TIME(4) cp_h: CP_R(RH) TIME(4) cp_l: CP_R(RL) TIME(4) cp_ihl: CP_R((HLP)) TIME(7) cp_a: CP_R(RA) TIME(4) #include "i386op3x.S" spectemu-0.94/i386op3x.S0100644000175000017500000000530406505020712015164 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* IX */ add_a_iixd: IXDGET ADD_A_R((HLP)) RSHL TIMEX(19) add_a_ixh: ADD_A_R(MIXH) TIMEX(8) add_a_ixl: ADD_A_R(MIXL) TIMEX(8) adc_a_iixd: IXDGET ADC_A_R((HLP)) RSHL TIMEX(19) adc_a_ixh: ADC_A_R(MIXH) TIMEX(8) adc_a_ixl: ADC_A_R(MIXL) TIMEX(8) sub_iixd: IXDGET SUB_R((HLP)) RSHL TIMEX(19) sub_ixh: SUB_R(MIXH) TIMEX(8) sub_ixl: SUB_R(MIXL) TIMEX(8) sbc_a_iixd: IXDGET SBC_A_R((HLP)) RSHL TIMEX(19) sbc_a_ixh: SBC_A_R(MIXH) TIMEX(8) sbc_a_ixl: SBC_A_R(MIXL) TIMEX(8) and_iixd: IXDGET AND_R((HLP)) RSHL TIMEX(19) and_ixh: AND_R(MIXH) TIMEX(8) and_ixl: AND_R(MIXL) TIMEX(8) xor_iixd: IXDGET XOR_R((HLP)) RSHL TIMEX(19) xor_ixh: XOR_R(MIXH) TIMEX(8) xor_ixl: XOR_R(MIXL) TIMEX(8) or_iixd: IXDGET OR_R((HLP)) RSHL TIMEX(19) or_ixh: OR_R(MIXH) TIMEX(8) or_ixl: OR_R(MIXL) TIMEX(8) cp_iixd: IXDGET CP_R((HLP)) RSHL TIMEX(19) cp_ixh: CP_R(MIXH) TIMEX(8) cp_ixl: CP_R(MIXL) TIMEX(8) /* IY */ add_a_iiyd: IYDGET ADD_A_R((HLP)) RSHL TIMEX(19) add_a_iyh: ADD_A_R(MIYH) TIMEX(8) add_a_iyl: ADD_A_R(MIYL) TIMEX(8) adc_a_iiyd: IYDGET ADC_A_R((HLP)) RSHL TIMEX(19) adc_a_iyh: ADC_A_R(MIYH) TIMEX(8) adc_a_iyl: ADC_A_R(MIYL) TIMEX(8) sub_iiyd: IYDGET SUB_R((HLP)) RSHL TIMEX(19) sub_iyh: SUB_R(MIYH) TIMEX(8) sub_iyl: SUB_R(MIYL) TIMEX(8) sbc_a_iiyd: IYDGET SBC_A_R((HLP)) RSHL TIMEX(19) sbc_a_iyh: SBC_A_R(MIYH) TIMEX(8) sbc_a_iyl: SBC_A_R(MIYL) TIMEX(8) and_iiyd: IYDGET AND_R((HLP)) RSHL TIMEX(19) and_iyh: AND_R(MIYH) TIMEX(8) and_iyl: AND_R(MIYL) TIMEX(8) xor_iiyd: IYDGET XOR_R((HLP)) RSHL TIMEX(19) xor_iyh: XOR_R(MIYH) TIMEX(8) xor_iyl: XOR_R(MIYL) TIMEX(8) or_iiyd: IYDGET OR_R((HLP)) RSHL TIMEX(19) or_iyh: OR_R(MIYH) TIMEX(8) or_iyl: OR_R(MIYL) TIMEX(8) cp_iiyd: IYDGET CP_R((HLP)) RSHL TIMEX(19) cp_iyh: CP_R(MIYH) TIMEX(8) cp_iyl: CP_R(MIYL) TIMEX(8) spectemu-0.94/spect.c0100644000175000017500000000370706507725465015047 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "z80.h" #include "spperif.h" #include "spscr.h" #define SOUNDPORT 0x10 int SPNM(halfframe)(int firsttick, int numlines) { int tc, linesleft; int feport, scline, border; byte *scrptr; qbyte cmark = 0; scrptr = (byte *) SPNM(image); tc = firsttick - CHKTICK; for(linesleft = numlines; linesleft; linesleft--) { DANM(next_scri) = SPNM(scri)[SPNM(scline)]; tc += CHKTICK; tc = PRNM(step)(tc); scline = SPNM(scline); /* store sound */ SPNM(sound_buf)[scline] = DANM(sound_sam); feport = DANM(ula_outport); if(feport & SOUNDPORT) DANM(sound_sam) = 240; else DANM(sound_sam) = 16; /* change EAR bit, store MIC bit*/ SPNM(fe_outport_time)[scline] = feport; if(DANM(imp_change)) DANM(ula_inport) ^= 0x40; DANM(imp_change) = SPNM(tape_impinfo)[scline]; /* Check if updating screen */ if(SPNM(updating)) { border = SPNM(lastborder); if((feport & 0x07) != border) { SPNM(border_update) = 2; SPNM(lastborder) = feport & 0x07; } scrptr = update_screen_line(scrptr, SPNM(coli)[scline], DANM(next_scri), border, &cmark); } SPNM(scline)++; } return tc; } spectemu-0.94/i386op4.S0100644000175000017500000001010506505020712014770 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* instructions from 0xC0 to 0xFF */ ret_cc: POPD(RPC) TIME(11) ret: POPD(RPC) TIME(10) ret_nz: JNCOND(ZF, ret_cc) TIME(5) ret_z: JCOND(ZF, ret_cc) TIME(5) ret_nc: JNCOND(CF, ret_cc) TIME(5) ret_c: JCOND(CF, ret_cc) TIME(5) ret_po: JNCOND(PVF, ret_cc) TIME(5) ret_pe: JCOND(PVF, ret_cc) TIME(5) ret_p: JNCOND(SF, ret_cc) TIME(5) ret_m: JCOND(SF, ret_cc) TIME(5) pop_bc: POP(RB, RC) TIME(10) pop_de: POPD(MDE) TIME(10) pop_hl: POP(RH, RL) TIME(10) pop_ix: POPD(MIX) TIMEX(14) pop_iy: POPD(MIY) TIMEX(14) pop_af: POP(RA, RF) TIME(10) exx: xchgw BBC, RBC movw MDE, RVW xchgw BDE, RVW movw RVW, MDE xchgw BHL, RHL TIME(4) jp_hl: movw RHL, RPC TIME(4) jp_ix: movw MIX, RPC TIMEX(8) jp_iy: movw MIY, RPC TIMEX(8) ld_sp_hl: movw RHL, RSP TIME(6) ld_sp_ix: movw MIX, RSP TIMEX(10) ld_sp_iy: movw MIY, RSP TIMEX(10) jp_cc_nn: jp_nn: DFETCH movw RVW, RPC TIME(10) jp_nz_nn: JNCOND(ZF, jp_cc_nn) DINCPC TIME(10) jp_z_nn: JCOND(ZF, jp_cc_nn) DINCPC TIME(10) jp_nc_nn: JNCOND(CF, jp_cc_nn) DINCPC TIME(10) jp_c_nn: JCOND(CF, jp_cc_nn) DINCPC TIME(10) jp_po_nn: JNCOND(PVF, jp_cc_nn) DINCPC TIME(10) jp_pe_nn: JCOND(PVF, jp_cc_nn) DINCPC TIME(10) jp_p_nn: JNCOND(SF, jp_cc_nn) DINCPC TIME(10) jp_m_nn: JCOND(SF, jp_cc_nn) DINCPC TIME(10) out_in_a: OUT(out_in_a, RA, (PCP), RA) INCPC TIME(11) in_a_in: IN(in_a_in, RA, (PCP), RA) INCPC TIME(11) ex_isp_hl: POP(RV, RW) PUSH(ex_isp_hl, RH, RL) movw RVW, RHL TIME(19) ex_isp_ix: POP(RV, RW) xchgw MIX, RHL PUSH(ex_isp_ix, RH, RL) movw RVW, RHL xchgw MIX, RHL TIMEX(23) ex_isp_iy: POP(RV, RW) xchgw MIY, RHL PUSH(ex_isp_iy, RH, RL) movw RVW, RHL xchgw MIY, RHL TIMEX(23) ex_de_hl: xchgw MDE, RHL TIME(4) di: movw $0, IFF1 movw $0, IFF2 DI_CHECK TIME(4) ei: movw $1, IFF1 movw $1, IFF2 TIME(4) call_cc_nn: call_nn: DFETCH xchgw RPC, RHL PUSH(call_nn, RH, RL) xchgw RPC, RHL movw RVW, RPC TIME(17) call_nz_nn: JNCOND(ZF, call_cc_nn) DINCPC TIME(10) call_z_nn: JCOND(ZF, call_cc_nn) DINCPC TIME(10) call_nc_nn: JNCOND(CF, call_cc_nn) DINCPC TIME(10) call_c_nn: JCOND(CF, call_cc_nn) DINCPC TIME(10) call_po_nn: JNCOND(PVF, call_cc_nn) DINCPC TIME(10) call_pe_nn: JCOND(PVF, call_cc_nn) DINCPC TIME(10) call_p_nn: JNCOND(SF, call_cc_nn) DINCPC TIME(10) call_m_nn: JCOND(SF, call_cc_nn) DINCPC TIME(10) push_bc: PUSH(push_bc, RB, RC) TIME(11) push_de: PUSHD(push_de, MDE) TIME(11) push_hl: PUSH(push_hl, RH, RL) TIME(11) push_ix: movw MIX, RVW PUSH(push_ix, RV, RW) TIMEX(15) push_iy: movw MIY, RVW PUSH(push_iy, RV, RW) TIMEX(15) push_af: PUSH(push_af, RA, RF) TIME(11) add_a_n: ADD_A_R((PCP)) INCPC TIME(7) adc_a_n: ADC_A_R((PCP)) INCPC TIME(7) sub_n: SUB_R((PCP)) INCPC TIME(7) sbc_a_n: SBC_A_R((PCP)) INCPC TIME(7) and_n: AND_R((PCP)) INCPC TIME(7) xor_n: XOR_R((PCP)) INCPC TIME(7) or_n: OR_R((PCP)) INCPC TIME(7) cp_n: CP_R((PCP)) INCPC TIME(7) #define RST_NN(n) \ movw RPC, RVW ; \ movw $0x ## n, RPC ; \ jmp rst_nn ; \ ALIGN rst_nn: PUSH(rst_nn, RV, RW) TIME(11) rst_00: RST_NN(00) rst_08: RST_NN(08) rst_10: RST_NN(10) rst_18: RST_NN(18) rst_20: RST_NN(20) rst_28: RST_NN(28) rst_30: RST_NN(30) rst_38: RST_NN(38) spectemu-0.94/i386op6.S0100644000175000017500000002733106505020712015003 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* -*- asm -*- */ /* instructions prefixed by CB */ #define BITFL \ lahf ; \ andb $SF, RW ; \ andb $~SZNF, RF ; \ andb $ZF, RV ; \ orb RV, RF ; \ orb RW, RF #define ROTSHFL \ CFLAG(ALLF, CF) ; \ testb RW,RW ; \ CFLAG(SZPF, SZPF) #ifdef FASTFLAGS #define BITFLAGS BITFL #define ROTSHFLAGS ROTSHFL #else ALIGN bitflags: BITFL ret ALIGN rotshflags: ROTSHFL ret ALIGN #define BITFLAGS \ call bitflags #define ROTSHFLAGS \ call rotshflags #endif #define RLC_R(r) \ rolb r ; \ movb r, RW ; \ ROTSHFLAGS #define RRC_R(r) \ rorb r ; \ movb r, RW ; \ ROTSHFLAGS #define RL_R(r) \ SFLAGS ; \ rclb r ; \ movb r, RW ; \ ROTSHFLAGS #define RR_R(r) \ SFLAGS ; \ rcrb r ; \ movb r, RW ; \ ROTSHFLAGS #define SLA_R(r) \ salb r ; \ movb r, RW ; \ ROTSHFLAGS #define SRA_R(r) \ sarb r ; \ movb r, RW ; \ ROTSHFLAGS #define SLL_R(r) \ shlb r ; \ CFLAG(ALLF, CF) ; \ orb $1, r ; \ CFLAG(SZPF, SZPF) #define SRL_R(r) \ shrb r ; \ movb r, RW ; \ ROTSHFLAGS #define BIT(n, r) \ movb r, RW ; \ testb $(1 << n), RW ; \ BITFLAGS #define SET(n, r) \ orb $(1 << n), r #define RES(n, r) \ andb $~(1 << n), r rlc_b: RLC_R(RB) TIME(8) rlc_c: RLC_R(RC) TIME(8) rlc_d: RLC_R(MD) TIME(8) rlc_e: RLC_R(ME) TIME(8) rlc_h: RLC_R(RH) TIME(8) rlc_l: RLC_R(RL) TIME(8) rlc_ihl: MODMEM(RLC_R, 15) rlc_id: MODMEMID(id, RLC_R, 23) rlc_a: RLC_R(RA) TIME(8) rrc_b: RRC_R(RB) TIME(8) rrc_c: RRC_R(RC) TIME(8) rrc_d: RRC_R(MD) TIME(8) rrc_e: RRC_R(ME) TIME(8) rrc_h: RRC_R(RH) TIME(8) rrc_l: RRC_R(RL) TIME(8) rrc_ihl: MODMEM(RRC_R, 15) rrc_id: MODMEMID(id, RRC_R, 23) rrc_a: RRC_R(RA) TIME(8) rl_b: RL_R(RB) TIME(8) rl_c: RL_R(RC) TIME(8) rl_d: RL_R(MD) TIME(8) rl_e: RL_R(ME) TIME(8) rl_h: RL_R(RH) TIME(8) rl_l: RL_R(RL) TIME(8) rl_ihl: MODMEM(RL_R, 15) rl_id: MODMEMID(id, RL_R, 23) rl_a: RL_R(RA) TIME(8) rr_b: RR_R(RB) TIME(8) rr_c: RR_R(RC) TIME(8) rr_d: RR_R(MD) TIME(8) rr_e: RR_R(ME) TIME(8) rr_h: RR_R(RH) TIME(8) rr_l: RR_R(RL) TIME(8) rr_ihl: MODMEM(RR_R, 15) rr_id: MODMEMID(id, RR_R, 23) rr_a: RR_R(RA) TIME(8) sla_b: SLA_R(RB) TIME(8) sla_c: SLA_R(RC) TIME(8) sla_d: SLA_R(MD) TIME(8) sla_e: SLA_R(ME) TIME(8) sla_h: SLA_R(RH) TIME(8) sla_l: SLA_R(RL) TIME(8) sla_ihl: MODMEM(SLA_R, 15) sla_id: MODMEMID(id, SLA_R, 23) sla_a: SLA_R(RA) TIME(8) sra_b: SRA_R(RB) TIME(8) sra_c: SRA_R(RC) TIME(8) sra_d: SRA_R(MD) TIME(8) sra_e: SRA_R(ME) TIME(8) sra_h: SRA_R(RH) TIME(8) sra_l: SRA_R(RL) TIME(8) sra_ihl: MODMEM(SRA_R, 15) sra_id: MODMEMID(id, SRA_R, 23) sra_a: SRA_R(RA) TIME(8) sll_b: SLL_R(RB) TIME(8) sll_c: SLL_R(RC) TIME(8) sll_d: SLL_R(MD) TIME(8) sll_e: SLL_R(ME) TIME(8) sll_h: SLL_R(RH) TIME(8) sll_l: SLL_R(RL) TIME(8) sll_ihl: MODMEM(SLL_R, 15) sll_id: MODMEMID(id, SLL_R, 23) sll_a: SLL_R(RA) TIME(8) srl_b: SRL_R(RB) TIME(8) srl_c: SRL_R(RC) TIME(8) srl_d: SRL_R(MD) TIME(8) srl_e: SRL_R(ME) TIME(8) srl_h: SRL_R(RH) TIME(8) srl_l: SRL_R(RL) TIME(8) srl_ihl: MODMEM(SRL_R, 15) srl_id: MODMEMID(id, SRL_R, 23) srl_a: SRL_R(RA) TIME(8) bit_0_b: BIT(0, RB) TIME(8) bit_0_c: BIT(0, RC) TIME(8) bit_0_d: BIT(0, MD) TIME(8) bit_0_e: BIT(0, ME) TIME(8) bit_0_h: BIT(0, RH) TIME(8) bit_0_l: BIT(0, RL) TIME(8) bit_0_ihl: BIT(0, (HLP)) TIME(12) bit_0_id: BIT(0, (HLP)) RSHL TIMEX(20) bit_0_a: BIT(0, RA) TIME(8) bit_1_b: BIT(1, RB) TIME(8) bit_1_c: BIT(1, RC) TIME(8) bit_1_d: BIT(1, MD) TIME(8) bit_1_e: BIT(1, ME) TIME(8) bit_1_h: BIT(1, RH) TIME(8) bit_1_l: BIT(1, RL) TIME(8) bit_1_ihl: BIT(1, (HLP)) TIME(12) bit_1_id: BIT(1, (HLP)) RSHL TIMEX(20) bit_1_a: BIT(1, RA) TIME(8) bit_2_b: BIT(2, RB) TIME(8) bit_2_c: BIT(2, RC) TIME(8) bit_2_d: BIT(2, MD) TIME(8) bit_2_e: BIT(2, ME) TIME(8) bit_2_h: BIT(2, RH) TIME(8) bit_2_l: BIT(2, RL) TIME(8) bit_2_ihl: BIT(2, (HLP)) TIME(12) bit_2_id: BIT(2, (HLP)) RSHL TIMEX(20) bit_2_a: BIT(2, RA) TIME(8) bit_3_b: BIT(3, RB) TIME(8) bit_3_c: BIT(3, RC) TIME(8) bit_3_d: BIT(3, MD) TIME(8) bit_3_e: BIT(3, ME) TIME(8) bit_3_h: BIT(3, RH) TIME(8) bit_3_l: BIT(3, RL) TIME(8) bit_3_ihl: BIT(3, (HLP)) TIME(12) bit_3_id: BIT(3, (HLP)) RSHL TIMEX(20) bit_3_a: BIT(3, RA) TIME(8) bit_4_b: BIT(4, RB) TIME(8) bit_4_c: BIT(4, RC) TIME(8) bit_4_d: BIT(4, MD) TIME(8) bit_4_e: BIT(4, ME) TIME(8) bit_4_h: BIT(4, RH) TIME(8) bit_4_l: BIT(4, RL) TIME(8) bit_4_ihl: BIT(4, (HLP)) TIME(12) bit_4_id: BIT(4, (HLP)) RSHL TIMEX(20) bit_4_a: BIT(4, RA) TIME(8) bit_5_b: BIT(5, RB) TIME(8) bit_5_c: BIT(5, RC) TIME(8) bit_5_d: BIT(5, MD) TIME(8) bit_5_e: BIT(5, ME) TIME(8) bit_5_h: BIT(5, RH) TIME(8) bit_5_l: BIT(5, RL) TIME(8) bit_5_ihl: BIT(5, (HLP)) TIME(12) bit_5_id: BIT(5, (HLP)) RSHL TIMEX(20) bit_5_a: BIT(5, RA) TIME(8) bit_6_b: BIT(6, RB) TIME(8) bit_6_c: BIT(6, RC) TIME(8) bit_6_d: BIT(6, MD) TIME(8) bit_6_e: BIT(6, ME) TIME(8) bit_6_h: BIT(6, RH) TIME(8) bit_6_l: BIT(6, RL) TIME(8) bit_6_ihl: BIT(6, (HLP)) TIME(12) bit_6_id: BIT(6, (HLP)) RSHL TIMEX(20) bit_6_a: BIT(6, RA) TIME(8) bit_7_b: BIT(7, RB) TIME(8) bit_7_c: BIT(7, RC) TIME(8) bit_7_d: BIT(7, MD) TIME(8) bit_7_e: BIT(7, ME) TIME(8) bit_7_h: BIT(7, RH) TIME(8) bit_7_l: BIT(7, RL) TIME(8) bit_7_ihl: BIT(7, (HLP)) TIME(12) bit_7_id: BIT(7, (HLP)) RSHL TIMEX(20) bit_7_a: BIT(7, RA) TIME(8) #define PUTMEM_HLP_RW_15 \ jmp pm15 #define PUTMEMID_HLP_RW_23 \ jmp pm23 pm15: PUTMEM_RHL(pm15, RW, 15) pm23: PUTMEMID_RHL(pm23, RW, 23) res_0_b: RES(0, RB) TIME(8) res_0_c: RES(0, RC) TIME(8) res_0_d: RES(0, MD) TIME(8) res_0_e: RES(0, ME) TIME(8) res_0_h: RES(0, RH) TIME(8) res_0_l: RES(0, RL) TIME(8) res_0_ihl: movb (HLP), RW RES(0, RW) PUTMEM_HLP_RW_15 res_0_id: movb (HLP), RW RES(0, RW) PUTMEMID_HLP_RW_23 res_0_a: RES(0, RA) TIME(8) res_1_b: RES(1, RB) TIME(8) res_1_c: RES(1, RC) TIME(8) res_1_d: RES(1, MD) TIME(8) res_1_e: RES(1, ME) TIME(8) res_1_h: RES(1, RH) TIME(8) res_1_l: RES(1, RL) TIME(8) res_1_ihl: movb (HLP), RW RES(1, RW) PUTMEM_HLP_RW_15 res_1_id: movb (HLP), RW RES(1, RW) PUTMEMID_HLP_RW_23 res_1_a: RES(1, RA) TIME(8) res_2_b: RES(2, RB) TIME(8) res_2_c: RES(2, RC) TIME(8) res_2_d: RES(2, MD) TIME(8) res_2_e: RES(2, ME) TIME(8) res_2_h: RES(2, RH) TIME(8) res_2_l: RES(2, RL) TIME(8) res_2_ihl: movb (HLP), RW RES(2, RW) PUTMEM_HLP_RW_15 res_2_id: movb (HLP), RW RES(2, RW) PUTMEMID_HLP_RW_23 res_2_a: RES(2, RA) TIME(8) res_3_b: RES(3, RB) TIME(8) res_3_c: RES(3, RC) TIME(8) res_3_d: RES(3, MD) TIME(8) res_3_e: RES(3, ME) TIME(8) res_3_h: RES(3, RH) TIME(8) res_3_l: RES(3, RL) TIME(8) res_3_ihl: movb (HLP), RW RES(3, RW) PUTMEM_HLP_RW_15 res_3_id: movb (HLP), RW RES(3, RW) PUTMEMID_HLP_RW_23 res_3_a: RES(3, RA) TIME(8) res_4_b: RES(4, RB) TIME(8) res_4_c: RES(4, RC) TIME(8) res_4_d: RES(4, MD) TIME(8) res_4_e: RES(4, ME) TIME(8) res_4_h: RES(4, RH) TIME(8) res_4_l: RES(4, RL) TIME(8) res_4_ihl: movb (HLP), RW RES(4, RW) PUTMEM_HLP_RW_15 res_4_id: movb (HLP), RW RES(4, RW) PUTMEMID_HLP_RW_23 res_4_a: RES(4, RA) TIME(8) res_5_b: RES(5, RB) TIME(8) res_5_c: RES(5, RC) TIME(8) res_5_d: RES(5, MD) TIME(8) res_5_e: RES(5, ME) TIME(8) res_5_h: RES(5, RH) TIME(8) res_5_l: RES(5, RL) TIME(8) res_5_ihl: movb (HLP), RW RES(5, RW) PUTMEM_HLP_RW_15 res_5_id: movb (HLP), RW RES(5, RW) PUTMEMID_HLP_RW_23 res_5_a: RES(5, RA) TIME(8) res_6_b: RES(6, RB) TIME(8) res_6_c: RES(6, RC) TIME(8) res_6_d: RES(6, MD) TIME(8) res_6_e: RES(6, ME) TIME(8) res_6_h: RES(6, RH) TIME(8) res_6_l: RES(6, RL) TIME(8) res_6_ihl: movb (HLP), RW RES(6, RW) PUTMEM_HLP_RW_15 res_6_id: movb (HLP), RW RES(6, RW) PUTMEMID_HLP_RW_23 res_6_a: RES(6, RA) TIME(8) res_7_b: RES(7, RB) TIME(8) res_7_c: RES(7, RC) TIME(8) res_7_d: RES(7, MD) TIME(8) res_7_e: RES(7, ME) TIME(8) res_7_h: RES(7, RH) TIME(8) res_7_l: RES(7, RL) TIME(8) res_7_ihl: movb (HLP), RW RES(7, RW) PUTMEM_HLP_RW_15 res_7_id: movb (HLP), RW RES(7, RW) PUTMEMID_HLP_RW_23 res_7_a: RES(7, RA) TIME(8) set_0_b: SET(0, RB) TIME(8) set_0_c: SET(0, RC) TIME(8) set_0_d: SET(0, MD) TIME(8) set_0_e: SET(0, ME) TIME(8) set_0_h: SET(0, RH) TIME(8) set_0_l: SET(0, RL) TIME(8) set_0_ihl: movb (HLP), RW SET(0, RW) PUTMEM_HLP_RW_15 set_0_id: movb (HLP), RW SET(0, RW) PUTMEMID_HLP_RW_23 set_0_a: SET(0, RA) TIME(8) set_1_b: SET(1, RB) TIME(8) set_1_c: SET(1, RC) TIME(8) set_1_d: SET(1, MD) TIME(8) set_1_e: SET(1, ME) TIME(8) set_1_h: SET(1, RH) TIME(8) set_1_l: SET(1, RL) TIME(8) set_1_ihl: movb (HLP), RW SET(1, RW) PUTMEM_HLP_RW_15 set_1_id: movb (HLP), RW SET(1, RW) PUTMEMID_HLP_RW_23 set_1_a: SET(1, RA) TIME(8) set_2_b: SET(2, RB) TIME(8) set_2_c: SET(2, RC) TIME(8) set_2_d: SET(2, MD) TIME(8) set_2_e: SET(2, ME) TIME(8) set_2_h: SET(2, RH) TIME(8) set_2_l: SET(2, RL) TIME(8) set_2_ihl: movb (HLP), RW SET(2, RW) PUTMEM_HLP_RW_15 set_2_id: movb (HLP), RW SET(2, RW) PUTMEMID_HLP_RW_23 set_2_a: SET(2, RA) TIME(8) set_3_b: SET(3, RB) TIME(8) set_3_c: SET(3, RC) TIME(8) set_3_d: SET(3, MD) TIME(8) set_3_e: SET(3, ME) TIME(8) set_3_h: SET(3, RH) TIME(8) set_3_l: SET(3, RL) TIME(8) set_3_ihl: movb (HLP), RW SET(3, RW) PUTMEM_HLP_RW_15 set_3_id: movb (HLP), RW SET(3, RW) PUTMEMID_HLP_RW_23 set_3_a: SET(3, RA) TIME(8) set_4_b: SET(4, RB) TIME(8) set_4_c: SET(4, RC) TIME(8) set_4_d: SET(4, MD) TIME(8) set_4_e: SET(4, ME) TIME(8) set_4_h: SET(4, RH) TIME(8) set_4_l: SET(4, RL) TIME(8) set_4_ihl: movb (HLP), RW SET(4, RW) PUTMEM_HLP_RW_15 set_4_id: movb (HLP), RW SET(4, RW) PUTMEMID_HLP_RW_23 set_4_a: SET(4, RA) TIME(8) set_5_b: SET(5, RB) TIME(8) set_5_c: SET(5, RC) TIME(8) set_5_d: SET(5, MD) TIME(8) set_5_e: SET(5, ME) TIME(8) set_5_h: SET(5, RH) TIME(8) set_5_l: SET(5, RL) TIME(8) set_5_ihl: movb (HLP), RW SET(5, RW) PUTMEM_HLP_RW_15 set_5_id: movb (HLP), RW SET(5, RW) PUTMEMID_HLP_RW_23 set_5_a: SET(5, RA) TIME(8) set_6_b: SET(6, RB) TIME(8) set_6_c: SET(6, RC) TIME(8) set_6_d: SET(6, MD) TIME(8) set_6_e: SET(6, ME) TIME(8) set_6_h: SET(6, RH) TIME(8) set_6_l: SET(6, RL) TIME(8) set_6_ihl: movb (HLP), RW SET(6, RW) PUTMEM_HLP_RW_15 set_6_id: movb (HLP), RW SET(6, RW) PUTMEMID_HLP_RW_23 set_6_a: SET(6, RA) TIME(8) set_7_b: SET(7, RB) TIME(8) set_7_c: SET(7, RC) TIME(8) set_7_d: SET(7, MD) TIME(8) set_7_e: SET(7, ME) TIME(8) set_7_h: SET(7, RH) TIME(8) set_7_l: SET(7, RL) TIME(8) set_7_ihl: movb (HLP), RW SET(7, RW) PUTMEM_HLP_RW_15 set_7_id: movb (HLP), RW SET(7, RW) PUTMEMID_HLP_RW_23 set_7_a: SET(7, RA) TIME(8) spectemu-0.94/z80optab.h0100644000175000017500000000203106505020714015351 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "z80_op1.h" #include "z80_op2.h" #include "z80_op3.h" #include "z80_op4.h" #include "z80_op5.h" #include "z80_op6.h" extern z80t z80op_special_xx(z80t); extern z80t z80op_special_dd_cb(z80t); extern z80t z80op_special_fd_cb(z80t); spectemu-0.94/z80optab.c0100644000175000017500000005546006505020714015362 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "z80_def.h" #include "z80optab.h" #ifdef PROCP #define NEXTTAB(tab) \ { \ register byte nextop; \ nextop = *PCP; \ PC++; \ return (*z80c_op_tab_ ## tab [nextop])(z80p); \ } #else #define NEXTTAB(tab) \ { \ register byte nextop; \ nextop = *PCP; \ PC++; \ (*z80c_op_tab_ ## tab [nextop])(); \ } #endif OPDEF(special_cb, 0xCB) { RR++; DANM(cbaddr) = HL; NEXTTAB(cb); } OPDEF(special_dd, 0xDD) { RR++; DANM(tc) -= 4; NEXTTAB(dd); } OPDEF(special_ed, 0xED) { RR++; NEXTTAB(ed); } OPDEF(special_fd, 0xFD) { RR++; DANM(tc) -= 4; NEXTTAB(fd); } OPDEF(special_xx, 0xDD 0xFD) { RR--; PC--; ENDOP(); } OPDEF(special_dd_cb, 0xCB) { DANM(tc) -= 4; IXDGET(IX, DANM(cbaddr)); #ifdef DEBUG_Z80 if((*PCP & 0x07) != 6) printf("DD_CB unimplemented!\n"); #endif NEXTTAB(cb); } OPDEF(special_fd_cb, 0xCB) { DANM(tc) -= 4; IXDGET(IY, DANM(cbaddr)); #ifdef DEBUG_Z80 if((*PCP & 0x07) != 6) printf("FD_CB unimplemented!\n"); #endif NEXTTAB(cb); } op_f z80c_op_tab[] = { z80op_nop, z80op_ld_bc_nn, z80op_ld_ibc_a, z80op_inc_bc, z80op_inc_b, z80op_dec_b, z80op_ld_b_n, z80op_rlca, z80op_ex_af_afb, z80op_add_hl_bc, z80op_ld_a_ibc, z80op_dec_bc, z80op_inc_c, z80op_dec_c, z80op_ld_c_n, z80op_rrca, z80op_djnz_e, z80op_ld_de_nn, z80op_ld_ide_a, z80op_inc_de, z80op_inc_d, z80op_dec_d, z80op_ld_d_n, z80op_rla, z80op_jr_e, z80op_add_hl_de, z80op_ld_a_ide, z80op_dec_de, z80op_inc_e, z80op_dec_e, z80op_ld_e_n, z80op_rra, z80op_jr_nz_e, z80op_ld_hl_nn, z80op_ld_inn_hl, z80op_inc_hl, z80op_inc_h, z80op_dec_h, z80op_ld_h_n, z80op_daa, z80op_jr_z_e, z80op_add_hl_hl, z80op_ld_hl_inn, z80op_dec_hl, z80op_inc_l, z80op_dec_l, z80op_ld_l_n, z80op_cpl, z80op_jr_nc_e, z80op_ld_sp_nn, z80op_ld_inn_a, z80op_inc_sp, z80op_inc_ihl, z80op_dec_ihl, z80op_ld_ihl_n, z80op_scf, z80op_jr_c_e, z80op_add_hl_sp, z80op_ld_a_inn, z80op_dec_sp, z80op_inc_a, z80op_dec_a, z80op_ld_a_n, z80op_ccf, z80op_nop, z80op_ld_b_c, z80op_ld_b_d, z80op_ld_b_e, z80op_ld_b_h, z80op_ld_b_l, z80op_ld_b_ihl, z80op_ld_b_a, z80op_ld_c_b, z80op_nop, z80op_ld_c_d, z80op_ld_c_e, z80op_ld_c_h, z80op_ld_c_l, z80op_ld_c_ihl, z80op_ld_c_a, z80op_ld_d_b, z80op_ld_d_c, z80op_nop, z80op_ld_d_e, z80op_ld_d_h, z80op_ld_d_l, z80op_ld_d_ihl, z80op_ld_d_a, z80op_ld_e_b, z80op_ld_e_c, z80op_ld_e_d, z80op_nop, z80op_ld_e_h, z80op_ld_e_l, z80op_ld_e_ihl, z80op_ld_e_a, z80op_ld_h_b, z80op_ld_h_c, z80op_ld_h_d, z80op_ld_h_e, z80op_nop, z80op_ld_h_l, z80op_ld_h_ihl, z80op_ld_h_a, z80op_ld_l_b, z80op_ld_l_c, z80op_ld_l_d, z80op_ld_l_e, z80op_ld_l_h, z80op_nop, z80op_ld_l_ihl, z80op_ld_l_a, z80op_ld_ihl_b, z80op_ld_ihl_c, z80op_ld_ihl_d, z80op_ld_ihl_e, z80op_ld_ihl_h, z80op_ld_ihl_l, z80op_halt, z80op_ld_ihl_a, z80op_ld_a_b, z80op_ld_a_c, z80op_ld_a_d, z80op_ld_a_e, z80op_ld_a_h, z80op_ld_a_l, z80op_ld_a_ihl, z80op_nop, z80op_add_a_b, z80op_add_a_c, z80op_add_a_d, z80op_add_a_e, z80op_add_a_h, z80op_add_a_l, z80op_add_a_ihl, z80op_add_a_a, z80op_adc_a_b, z80op_adc_a_c, z80op_adc_a_d, z80op_adc_a_e, z80op_adc_a_h, z80op_adc_a_l, z80op_adc_a_ihl, z80op_adc_a_a, z80op_sub_b, z80op_sub_c, z80op_sub_d, z80op_sub_e, z80op_sub_h, z80op_sub_l, z80op_sub_ihl, z80op_sub_a, z80op_sbc_a_b, z80op_sbc_a_c, z80op_sbc_a_d, z80op_sbc_a_e, z80op_sbc_a_h, z80op_sbc_a_l, z80op_sbc_a_ihl, z80op_sbc_a_a, z80op_and_b, z80op_and_c, z80op_and_d, z80op_and_e, z80op_and_h, z80op_and_l, z80op_and_ihl, z80op_and_a, z80op_xor_b, z80op_xor_c, z80op_xor_d, z80op_xor_e, z80op_xor_h, z80op_xor_l, z80op_xor_ihl, z80op_xor_a, z80op_or_b, z80op_or_c, z80op_or_d, z80op_or_e, z80op_or_h, z80op_or_l, z80op_or_ihl, z80op_or_a, z80op_cp_b, z80op_cp_c, z80op_cp_d, z80op_cp_e, z80op_cp_h, z80op_cp_l, z80op_cp_ihl, z80op_cp_a, z80op_ret_nz, z80op_pop_bc, z80op_jp_nz_nn, z80op_jp_nn, z80op_call_nz_nn, z80op_push_bc, z80op_add_a_n, z80op_rst_00, z80op_ret_z, z80op_ret, z80op_jp_z_nn, z80op_special_cb, z80op_call_z_nn, z80op_call_nn, z80op_adc_a_n, z80op_rst_08, z80op_ret_nc, z80op_pop_de, z80op_jp_nc_nn, z80op_out_in_a, z80op_call_nc_nn, z80op_push_de, z80op_sub_n, z80op_rst_10, z80op_ret_c, z80op_exx, z80op_jp_c_nn, z80op_in_a_in, z80op_call_c_nn, z80op_special_dd, z80op_sbc_a_n, z80op_rst_18, z80op_ret_po, z80op_pop_hl, z80op_jp_po_nn, z80op_ex_isp_hl, z80op_call_po_nn, z80op_push_hl, z80op_and_n, z80op_rst_20, z80op_ret_pe, z80op_jp_hl, z80op_jp_pe_nn, z80op_ex_de_hl, z80op_call_pe_nn, z80op_special_ed, z80op_xor_n, z80op_rst_28, z80op_ret_p, z80op_pop_af, z80op_jp_p_nn, z80op_di, z80op_call_p_nn, z80op_push_af, z80op_or_n, z80op_rst_30, z80op_ret_m, z80op_ld_sp_hl, z80op_jp_m_nn, z80op_ei, z80op_call_m_nn, z80op_special_fd, z80op_cp_n, z80op_rst_38 }; op_f z80c_op_tab_ed[] = { z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_in_b_ic, z80op_out_ic_b, z80op_sbc_hl_bc, z80op_ld_inn_bc, z80op_neg, z80op_retn, z80op_im_0, z80op_ld_i_a, z80op_in_c_ic, z80op_out_ic_c, z80op_adc_hl_bc, z80op_ld_bc_inn, z80op_neg, z80op_reti, z80op_im_0, z80op_ld_r_a, z80op_in_d_ic, z80op_out_ic_d, z80op_sbc_hl_de, z80op_ld_inn_de, z80op_neg, z80op_retn, z80op_im_1, z80op_ld_a_i, z80op_in_e_ic, z80op_out_ic_e, z80op_adc_hl_de, z80op_ld_de_inn, z80op_neg, z80op_retn, z80op_im_2, z80op_ld_a_r, z80op_in_h_ic, z80op_out_ic_h, z80op_sbc_hl_hl, z80op_ld_inn_hl_ed, z80op_neg, z80op_retn, z80op_im_0, z80op_rrd, z80op_in_l_ic, z80op_out_ic_l, z80op_adc_hl_hl, z80op_ld_hl_inn_ed, z80op_neg, z80op_retn, z80op_im_0, z80op_rld, z80op_in_f_ic, z80op_out_ic_0, z80op_sbc_hl_sp, z80op_ld_inn_sp, z80op_neg, z80op_retn, z80op_im_1, z80op_ill_ed, z80op_in_a_ic, z80op_out_ic_a, z80op_adc_hl_sp, z80op_ld_sp_inn, z80op_neg, z80op_retn, z80op_im_2, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ldi, z80op_cpi, z80op_ini, z80op_outi, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ldd, z80op_cpd, z80op_ind, z80op_outd, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ldir, z80op_cpir, z80op_inir, z80op_otir, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_lddr, z80op_cpdr, z80op_indr, z80op_otdr, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed, z80op_ill_ed }; op_f z80c_op_tab_dd[] = { z80op_nop, z80op_ld_bc_nn, z80op_ld_ibc_a, z80op_inc_bc, z80op_inc_b, z80op_dec_b, z80op_ld_b_n, z80op_rlca, z80op_ex_af_afb, z80op_add_ix_bc, z80op_ld_a_ibc, z80op_dec_bc, z80op_inc_c, z80op_dec_c, z80op_ld_c_n, z80op_rrca, z80op_djnz_e, z80op_ld_de_nn, z80op_ld_ide_a, z80op_inc_de, z80op_inc_d, z80op_dec_d, z80op_ld_d_n, z80op_rla, z80op_jr_e, z80op_add_ix_de, z80op_ld_a_ide, z80op_dec_de, z80op_inc_e, z80op_dec_e, z80op_ld_e_n, z80op_rra, z80op_jr_nz_e, z80op_ld_ix_nn, z80op_ld_inn_ix, z80op_inc_ix, z80op_inc_ixh, z80op_dec_ixh, z80op_ld_ixh_n, z80op_daa, z80op_jr_z_e, z80op_add_ix_ix, z80op_ld_ix_inn, z80op_dec_ix, z80op_inc_ixl, z80op_dec_ixl, z80op_ld_ixl_n, z80op_cpl, z80op_jr_nc_e, z80op_ld_sp_nn, z80op_ld_inn_a, z80op_inc_sp, z80op_inc_iixd, z80op_dec_iixd, z80op_ld_iixd_n, z80op_scf, z80op_jr_c_e, z80op_add_ix_sp, z80op_ld_a_inn, z80op_dec_sp, z80op_inc_a, z80op_dec_a, z80op_ld_a_n, z80op_ccf, z80op_nop, z80op_ld_b_c, z80op_ld_b_d, z80op_ld_b_e, z80op_ld_b_ixh, z80op_ld_b_ixl, z80op_ld_b_iixd, z80op_ld_b_a, z80op_ld_c_b, z80op_nop, z80op_ld_c_d, z80op_ld_c_e, z80op_ld_c_ixh, z80op_ld_c_ixl, z80op_ld_c_iixd, z80op_ld_c_a, z80op_ld_d_b, z80op_ld_d_c, z80op_nop, z80op_ld_d_e, z80op_ld_d_ixh, z80op_ld_d_ixl, z80op_ld_d_iixd, z80op_ld_d_a, z80op_ld_e_b, z80op_ld_e_c, z80op_ld_e_d, z80op_nop, z80op_ld_e_ixh, z80op_ld_e_ixl, z80op_ld_e_iixd, z80op_ld_e_a, z80op_ld_ixh_b, z80op_ld_ixh_c, z80op_ld_ixh_d, z80op_ld_ixh_e, z80op_nop, z80op_ld_ixh_ixl, z80op_ld_h_iixd, z80op_ld_ixh_a, z80op_ld_ixl_b, z80op_ld_ixl_c, z80op_ld_ixl_d, z80op_ld_ixl_e, z80op_ld_ixl_ixh, z80op_nop, z80op_ld_l_iixd, z80op_ld_ixl_a, z80op_ld_iixd_b, z80op_ld_iixd_c, z80op_ld_iixd_d, z80op_ld_iixd_e, z80op_ld_iixd_h, z80op_ld_iixd_l, z80op_halt, z80op_ld_iixd_a, z80op_ld_a_b, z80op_ld_a_c, z80op_ld_a_d, z80op_ld_a_e, z80op_ld_a_ixh, z80op_ld_a_ixl, z80op_ld_a_iixd, z80op_nop, z80op_add_a_b, z80op_add_a_c, z80op_add_a_d, z80op_add_a_e, z80op_add_a_ixh, z80op_add_a_ixl, z80op_add_a_iixd, z80op_add_a_a, z80op_adc_a_b, z80op_adc_a_c, z80op_adc_a_d, z80op_adc_a_e, z80op_adc_a_ixh, z80op_adc_a_ixl, z80op_adc_a_iixd, z80op_adc_a_a, z80op_sub_b, z80op_sub_c, z80op_sub_d, z80op_sub_e, z80op_sub_ixh, z80op_sub_ixl, z80op_sub_iixd, z80op_sub_a, z80op_sbc_a_b, z80op_sbc_a_c, z80op_sbc_a_d, z80op_sbc_a_e, z80op_sbc_a_ixh, z80op_sbc_a_ixl, z80op_sbc_a_iixd, z80op_sbc_a_a, z80op_and_b, z80op_and_c, z80op_and_d, z80op_and_e, z80op_and_ixh, z80op_and_ixl, z80op_and_iixd, z80op_and_a, z80op_xor_b, z80op_xor_c, z80op_xor_d, z80op_xor_e, z80op_xor_ixh, z80op_xor_ixl, z80op_xor_iixd, z80op_xor_a, z80op_or_b, z80op_or_c, z80op_or_d, z80op_or_e, z80op_or_ixh, z80op_or_ixl, z80op_or_iixd, z80op_or_a, z80op_cp_b, z80op_cp_c, z80op_cp_d, z80op_cp_e, z80op_cp_ixh, z80op_cp_ixl, z80op_cp_iixd, z80op_cp_a, z80op_ret_nz, z80op_pop_bc, z80op_jp_nz_nn, z80op_jp_nn, z80op_call_nz_nn, z80op_push_bc, z80op_add_a_n, z80op_rst_00, z80op_ret_z, z80op_ret, z80op_jp_z_nn, z80op_special_dd_cb, z80op_call_z_nn, z80op_call_nn, z80op_adc_a_n, z80op_rst_08, z80op_ret_nc, z80op_pop_de, z80op_jp_nc_nn, z80op_out_in_a, z80op_call_nc_nn, z80op_push_de, z80op_sub_n, z80op_rst_10, z80op_ret_c, z80op_exx, z80op_jp_c_nn, z80op_in_a_in, z80op_call_c_nn, z80op_special_xx, z80op_sbc_a_n, z80op_rst_18, z80op_ret_po, z80op_pop_ix, z80op_jp_po_nn, z80op_ex_isp_ix, z80op_call_po_nn, z80op_push_ix, z80op_and_n, z80op_rst_20, z80op_ret_pe, z80op_jp_ix, z80op_jp_pe_nn, z80op_ex_de_hl, z80op_call_pe_nn, z80op_special_ed, z80op_xor_n, z80op_rst_28, z80op_ret_p, z80op_pop_af, z80op_jp_p_nn, z80op_di, z80op_call_p_nn, z80op_push_af, z80op_or_n, z80op_rst_30, z80op_ret_m, z80op_ld_sp_ix, z80op_jp_m_nn, z80op_ei, z80op_call_m_nn, z80op_special_xx, z80op_cp_n, z80op_rst_38 }; op_f z80c_op_tab_fd[] = { z80op_nop, z80op_ld_bc_nn, z80op_ld_ibc_a, z80op_inc_bc, z80op_inc_b, z80op_dec_b, z80op_ld_b_n, z80op_rlca, z80op_ex_af_afb, z80op_add_iy_bc, z80op_ld_a_ibc, z80op_dec_bc, z80op_inc_c, z80op_dec_c, z80op_ld_c_n, z80op_rrca, z80op_djnz_e, z80op_ld_de_nn, z80op_ld_ide_a, z80op_inc_de, z80op_inc_d, z80op_dec_d, z80op_ld_d_n, z80op_rla, z80op_jr_e, z80op_add_iy_de, z80op_ld_a_ide, z80op_dec_de, z80op_inc_e, z80op_dec_e, z80op_ld_e_n, z80op_rra, z80op_jr_nz_e, z80op_ld_iy_nn, z80op_ld_inn_iy, z80op_inc_iy, z80op_inc_iyh, z80op_dec_iyh, z80op_ld_iyh_n, z80op_daa, z80op_jr_z_e, z80op_add_iy_iy, z80op_ld_iy_inn, z80op_dec_iy, z80op_inc_iyl, z80op_dec_iyl, z80op_ld_iyl_n, z80op_cpl, z80op_jr_nc_e, z80op_ld_sp_nn, z80op_ld_inn_a, z80op_inc_sp, z80op_inc_iiyd, z80op_dec_iiyd, z80op_ld_iiyd_n, z80op_scf, z80op_jr_c_e, z80op_add_iy_sp, z80op_ld_a_inn, z80op_dec_sp, z80op_inc_a, z80op_dec_a, z80op_ld_a_n, z80op_ccf, z80op_nop, z80op_ld_b_c, z80op_ld_b_d, z80op_ld_b_e, z80op_ld_b_iyh, z80op_ld_b_iyl, z80op_ld_b_iiyd, z80op_ld_b_a, z80op_ld_c_b, z80op_nop, z80op_ld_c_d, z80op_ld_c_e, z80op_ld_c_iyh, z80op_ld_c_iyl, z80op_ld_c_iiyd, z80op_ld_c_a, z80op_ld_d_b, z80op_ld_d_c, z80op_nop, z80op_ld_d_e, z80op_ld_d_iyh, z80op_ld_d_iyl, z80op_ld_d_iiyd, z80op_ld_d_a, z80op_ld_e_b, z80op_ld_e_c, z80op_ld_e_d, z80op_nop, z80op_ld_e_iyh, z80op_ld_e_iyl, z80op_ld_e_iiyd, z80op_ld_e_a, z80op_ld_iyh_b, z80op_ld_iyh_c, z80op_ld_iyh_d, z80op_ld_iyh_e, z80op_nop, z80op_ld_iyh_iyl, z80op_ld_h_iiyd, z80op_ld_iyh_a, z80op_ld_iyl_b, z80op_ld_iyl_c, z80op_ld_iyl_d, z80op_ld_iyl_e, z80op_ld_iyl_iyh, z80op_nop, z80op_ld_l_iiyd, z80op_ld_iyl_a, z80op_ld_iiyd_b, z80op_ld_iiyd_c, z80op_ld_iiyd_d, z80op_ld_iiyd_e, z80op_ld_iiyd_h, z80op_ld_iiyd_l, z80op_halt, z80op_ld_iiyd_a, z80op_ld_a_b, z80op_ld_a_c, z80op_ld_a_d, z80op_ld_a_e, z80op_ld_a_iyh, z80op_ld_a_iyl, z80op_ld_a_iiyd, z80op_nop, z80op_add_a_b, z80op_add_a_c, z80op_add_a_d, z80op_add_a_e, z80op_add_a_iyh, z80op_add_a_iyl, z80op_add_a_iiyd, z80op_add_a_a, z80op_adc_a_b, z80op_adc_a_c, z80op_adc_a_d, z80op_adc_a_e, z80op_adc_a_iyh, z80op_adc_a_iyl, z80op_adc_a_iiyd, z80op_adc_a_a, z80op_sub_b, z80op_sub_c, z80op_sub_d, z80op_sub_e, z80op_sub_iyh, z80op_sub_iyl, z80op_sub_iiyd, z80op_sub_a, z80op_sbc_a_b, z80op_sbc_a_c, z80op_sbc_a_d, z80op_sbc_a_e, z80op_sbc_a_iyh, z80op_sbc_a_iyl, z80op_sbc_a_iiyd, z80op_sbc_a_a, z80op_and_b, z80op_and_c, z80op_and_d, z80op_and_e, z80op_and_iyh, z80op_and_iyl, z80op_and_iiyd, z80op_and_a, z80op_xor_b, z80op_xor_c, z80op_xor_d, z80op_xor_e, z80op_xor_iyh, z80op_xor_iyl, z80op_xor_iiyd, z80op_xor_a, z80op_or_b, z80op_or_c, z80op_or_d, z80op_or_e, z80op_or_iyh, z80op_or_iyl, z80op_or_iiyd, z80op_or_a, z80op_cp_b, z80op_cp_c, z80op_cp_d, z80op_cp_e, z80op_cp_iyh, z80op_cp_iyl, z80op_cp_iiyd, z80op_cp_a, z80op_ret_nz, z80op_pop_bc, z80op_jp_nz_nn, z80op_jp_nn, z80op_call_nz_nn, z80op_push_bc, z80op_add_a_n, z80op_rst_00, z80op_ret_z, z80op_ret, z80op_jp_z_nn, z80op_special_fd_cb, z80op_call_z_nn, z80op_call_nn, z80op_adc_a_n, z80op_rst_08, z80op_ret_nc, z80op_pop_de, z80op_jp_nc_nn, z80op_out_in_a, z80op_call_nc_nn, z80op_push_de, z80op_sub_n, z80op_rst_10, z80op_ret_c, z80op_exx, z80op_jp_c_nn, z80op_in_a_in, z80op_call_c_nn, z80op_special_xx, z80op_sbc_a_n, z80op_rst_18, z80op_ret_po, z80op_pop_iy, z80op_jp_po_nn, z80op_ex_isp_iy, z80op_call_po_nn, z80op_push_iy, z80op_and_n, z80op_rst_20, z80op_ret_pe, z80op_jp_iy, z80op_jp_pe_nn, z80op_ex_de_hl, z80op_call_pe_nn, z80op_special_ed, z80op_xor_n, z80op_rst_28, z80op_ret_p, z80op_pop_af, z80op_jp_p_nn, z80op_di, z80op_call_p_nn, z80op_push_af, z80op_or_n, z80op_rst_30, z80op_ret_m, z80op_ld_sp_iy, z80op_jp_m_nn, z80op_ei, z80op_call_m_nn, z80op_special_xx, z80op_cp_n, z80op_rst_38 }; op_f z80c_op_tab_cb[] = { z80op_rlc_b, z80op_rlc_c, z80op_rlc_d, z80op_rlc_e, z80op_rlc_h, z80op_rlc_l, z80op_rlc_ihl, z80op_rlc_a, z80op_rrc_b, z80op_rrc_c, z80op_rrc_d, z80op_rrc_e, z80op_rrc_h, z80op_rrc_l, z80op_rrc_ihl, z80op_rrc_a, z80op_rl_b, z80op_rl_c, z80op_rl_d, z80op_rl_e, z80op_rl_h, z80op_rl_l, z80op_rl_ihl, z80op_rl_a, z80op_rr_b, z80op_rr_c, z80op_rr_d, z80op_rr_e, z80op_rr_h, z80op_rr_l, z80op_rr_ihl, z80op_rr_a, z80op_sla_b, z80op_sla_c, z80op_sla_d, z80op_sla_e, z80op_sla_h, z80op_sla_l, z80op_sla_ihl, z80op_sla_a, z80op_sra_b, z80op_sra_c, z80op_sra_d, z80op_sra_e, z80op_sra_h, z80op_sra_l, z80op_sra_ihl, z80op_sra_a, z80op_sll_b, z80op_sll_c, z80op_sll_d, z80op_sll_e, z80op_sll_h, z80op_sll_l, z80op_sll_ihl, z80op_sll_a, z80op_srl_b, z80op_srl_c, z80op_srl_d, z80op_srl_e, z80op_srl_h, z80op_srl_l, z80op_srl_ihl, z80op_srl_a, z80op_bit_0_b, z80op_bit_0_c, z80op_bit_0_d, z80op_bit_0_e, z80op_bit_0_h, z80op_bit_0_l, z80op_bit_0_ihl, z80op_bit_0_a, z80op_bit_1_b, z80op_bit_1_c, z80op_bit_1_d, z80op_bit_1_e, z80op_bit_1_h, z80op_bit_1_l, z80op_bit_1_ihl, z80op_bit_1_a, z80op_bit_2_b, z80op_bit_2_c, z80op_bit_2_d, z80op_bit_2_e, z80op_bit_2_h, z80op_bit_2_l, z80op_bit_2_ihl, z80op_bit_2_a, z80op_bit_3_b, z80op_bit_3_c, z80op_bit_3_d, z80op_bit_3_e, z80op_bit_3_h, z80op_bit_3_l, z80op_bit_3_ihl, z80op_bit_3_a, z80op_bit_4_b, z80op_bit_4_c, z80op_bit_4_d, z80op_bit_4_e, z80op_bit_4_h, z80op_bit_4_l, z80op_bit_4_ihl, z80op_bit_4_a, z80op_bit_5_b, z80op_bit_5_c, z80op_bit_5_d, z80op_bit_5_e, z80op_bit_5_h, z80op_bit_5_l, z80op_bit_5_ihl, z80op_bit_5_a, z80op_bit_6_b, z80op_bit_6_c, z80op_bit_6_d, z80op_bit_6_e, z80op_bit_6_h, z80op_bit_6_l, z80op_bit_6_ihl, z80op_bit_6_a, z80op_bit_7_b, z80op_bit_7_c, z80op_bit_7_d, z80op_bit_7_e, z80op_bit_7_h, z80op_bit_7_l, z80op_bit_7_ihl, z80op_bit_7_a, z80op_res_0_b, z80op_res_0_c, z80op_res_0_d, z80op_res_0_e, z80op_res_0_h, z80op_res_0_l, z80op_res_0_ihl, z80op_res_0_a, z80op_res_1_b, z80op_res_1_c, z80op_res_1_d, z80op_res_1_e, z80op_res_1_h, z80op_res_1_l, z80op_res_1_ihl, z80op_res_1_a, z80op_res_2_b, z80op_res_2_c, z80op_res_2_d, z80op_res_2_e, z80op_res_2_h, z80op_res_2_l, z80op_res_2_ihl, z80op_res_2_a, z80op_res_3_b, z80op_res_3_c, z80op_res_3_d, z80op_res_3_e, z80op_res_3_h, z80op_res_3_l, z80op_res_3_ihl, z80op_res_3_a, z80op_res_4_b, z80op_res_4_c, z80op_res_4_d, z80op_res_4_e, z80op_res_4_h, z80op_res_4_l, z80op_res_4_ihl, z80op_res_4_a, z80op_res_5_b, z80op_res_5_c, z80op_res_5_d, z80op_res_5_e, z80op_res_5_h, z80op_res_5_l, z80op_res_5_ihl, z80op_res_5_a, z80op_res_6_b, z80op_res_6_c, z80op_res_6_d, z80op_res_6_e, z80op_res_6_h, z80op_res_6_l, z80op_res_6_ihl, z80op_res_6_a, z80op_res_7_b, z80op_res_7_c, z80op_res_7_d, z80op_res_7_e, z80op_res_7_h, z80op_res_7_l, z80op_res_7_ihl, z80op_res_7_a, z80op_set_0_b, z80op_set_0_c, z80op_set_0_d, z80op_set_0_e, z80op_set_0_h, z80op_set_0_l, z80op_set_0_ihl, z80op_set_0_a, z80op_set_1_b, z80op_set_1_c, z80op_set_1_d, z80op_set_1_e, z80op_set_1_h, z80op_set_1_l, z80op_set_1_ihl, z80op_set_1_a, z80op_set_2_b, z80op_set_2_c, z80op_set_2_d, z80op_set_2_e, z80op_set_2_h, z80op_set_2_l, z80op_set_2_ihl, z80op_set_2_a, z80op_set_3_b, z80op_set_3_c, z80op_set_3_d, z80op_set_3_e, z80op_set_3_h, z80op_set_3_l, z80op_set_3_ihl, z80op_set_3_a, z80op_set_4_b, z80op_set_4_c, z80op_set_4_d, z80op_set_4_e, z80op_set_4_h, z80op_set_4_l, z80op_set_4_ihl, z80op_set_4_a, z80op_set_5_b, z80op_set_5_c, z80op_set_5_d, z80op_set_5_e, z80op_set_5_h, z80op_set_5_l, z80op_set_5_ihl, z80op_set_5_a, z80op_set_6_b, z80op_set_6_c, z80op_set_6_d, z80op_set_6_e, z80op_set_6_h, z80op_set_6_l, z80op_set_6_ihl, z80op_set_6_a, z80op_set_7_b, z80op_set_7_c, z80op_set_7_d, z80op_set_7_e, z80op_set_7_h, z80op_set_7_l, z80op_set_7_ihl, z80op_set_7_a }; spectemu-0.94/z80_op3.c0100644000175000017500000000646306505020714015114 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef NO_OPDEF #include "z80_def.h" #include "z80_op3.h" #include "z80_ari.h" #endif #define ARIR(arin, func, an, rn, r, n) \ OPDEF(arin ## _ ## rn, 0x80+an*8+n) \ { \ func(r); \ ENTIME(4); \ } #define ARIIHL(arin, func, an) \ OPDEF(arin ## _ihl, 0x86+an*8) \ { \ func(*HLP); \ ENTIME(7); \ } #define ARIID(arin, func, an, ixyn, ixy) \ OPDEF(arin ## _i ## ixyn ## d, 0x86+an*8)\ { \ register dbyte addr; \ register byte val; \ IXDGET(ixy, addr); \ val = READ(addr); \ func(val); \ ENTIME(15); \ } #define ADD_A_R(rn, r, n) ARIR(add_a, ADD, 0, rn, r, n) #define ADC_A_R(rn, r, n) ARIR(adc_a, ADC, 1, rn, r, n) #define SUB_R(rn, r, n) ARIR(sub, SUB, 2, rn, r, n) #define SBC_A_R(rn, r, n) ARIR(sbc_a, SBC, 3, rn, r, n) #define AND_R(rn, r, n) ARIR(and, AND, 4, rn, r, n) #define XOR_R(rn, r, n) ARIR(xor, XOR, 5, rn, r, n) #define OR_R(rn, r, n) ARIR(or, OR, 6, rn, r, n) #define CP_R(rn, r, n) ARIR(cp, CP, 7, rn, r, n) ADD_A_R(b, RB, 0) ADD_A_R(c, RC, 1) ADD_A_R(d, RD, 2) ADD_A_R(e, RE, 3) ADD_A_R(h, RH, 4) ADD_A_R(l, RL, 5) ADD_A_R(a, RA, 7) ADC_A_R(b, RB, 0) ADC_A_R(c, RC, 1) ADC_A_R(d, RD, 2) ADC_A_R(e, RE, 3) ADC_A_R(h, RH, 4) ADC_A_R(l, RL, 5) ADC_A_R(a, RA, 7) SUB_R(b, RB, 0) SUB_R(c, RC, 1) SUB_R(d, RD, 2) SUB_R(e, RE, 3) SUB_R(h, RH, 4) SUB_R(l, RL, 5) SUB_R(a, RA, 7) SBC_A_R(b, RB, 0) SBC_A_R(c, RC, 1) SBC_A_R(d, RD, 2) SBC_A_R(e, RE, 3) SBC_A_R(h, RH, 4) SBC_A_R(l, RL, 5) SBC_A_R(a, RA, 7) AND_R(b, RB, 0) AND_R(c, RC, 1) AND_R(d, RD, 2) AND_R(e, RE, 3) AND_R(h, RH, 4) AND_R(l, RL, 5) AND_R(a, RA, 7) XOR_R(b, RB, 0) XOR_R(c, RC, 1) XOR_R(d, RD, 2) XOR_R(e, RE, 3) XOR_R(h, RH, 4) XOR_R(l, RL, 5) /* XOR_R(a, RA, 7) */ OPDEF(xor_a, 0xAF) { RA = 0; RF = (RF & ~(ALLF)) | (ZF | PVF); ENTIME(4); } OR_R(b, RB, 0) OR_R(c, RC, 1) OR_R(d, RD, 2) OR_R(e, RE, 3) OR_R(h, RH, 4) OR_R(l, RL, 5) OR_R(a, RA, 7) CP_R(b, RB, 0) CP_R(c, RC, 1) CP_R(d, RD, 2) CP_R(e, RE, 3) CP_R(h, RH, 4) CP_R(l, RL, 5) CP_R(a, RA, 7) ARIIHL(add_a, ADD, 0) ARIIHL(adc_a, ADC, 1) ARIIHL(sub, SUB, 2) ARIIHL(sbc_a, SBC, 3) ARIIHL(and, AND, 4) ARIIHL(xor, XOR, 5) ARIIHL(or, OR, 6) ARIIHL(cp, CP, 7) #include "z80_op3x.c" spectemu-0.94/z80_op4.c0100644000175000017500000001273506505020714015114 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef NO_OPDEF #include "z80_def.h" #include "z80_op4.h" #include "z80_ari.h" #endif #define RET_CC(ccn, cc, n) \ OPDEF(ret_ ## ccn, 0xC0+n*8) \ { \ if(!(cc)) { \ ENTIME(5); \ } \ else { \ POP(PC); \ ENTIME(11); \ } \ } RET_CC(nz, !TESTZF, 0) RET_CC(z, TESTZF, 1) RET_CC(nc, !TESTCF, 2) RET_CC(c, TESTCF, 3) RET_CC(po, !TESTPF, 4) RET_CC(pe, TESTPF, 5) RET_CC(p, !TESTSF, 6) RET_CC(m, TESTSF, 7) #define POP_RR(rrn, rr, n) \ OPDEF(pop_ ## rrn, 0xC1+n*0x10) \ { \ POP(rr); \ ENTIME(10); \ } POP_RR(bc, BC, 0) POP_RR(de, DE, 1) POP_RR(hl, HL, 2) POP_RR(af, AF, 3) OPDEF(ret, 0xC9) { POP(PC); ENTIME(10); } OPDEF(exx, 0xD9) { register dbyte dtmp; dtmp = BCBK, BCBK = BC, BC = dtmp; dtmp = DEBK, DEBK = DE, DE = dtmp; dtmp = HLBK, HLBK = HL, HL = dtmp; ENTIME(4); } #define JP_RR(rrn, rr) \ OPDEF(jp_ ## rrn, 0xE9) \ { \ PC = rr; \ ENTIME(4); \ } JP_RR(hl, HL) #define LD_SP_RR(rrn, rr) \ OPDEF(ld_sp_ ## rrn, 0xF9) \ { \ SP = rr; \ ENTIME(6); \ } LD_SP_RR(hl, HL) #define JP_CC(ccn, cc, n) \ OPDEF(jp_ ## ccn ## _nn, 0xC2+n*8) \ { \ if(!(cc)) { \ PC+=2; \ ENTIME(10); \ } \ else { \ PC = DREAD(PC); \ ENTIME(10); \ } \ } JP_CC(nz, !TESTZF, 0) JP_CC(z, TESTZF, 1) JP_CC(nc, !TESTCF, 2) JP_CC(c, TESTCF, 3) JP_CC(po, !TESTPF, 4) JP_CC(pe, TESTPF, 5) JP_CC(p, !TESTSF, 6) JP_CC(m, TESTSF, 7) OPDEF(jp_nn, 0xC3) { PC = DREAD(PC); ENTIME(10); } OPDEF(out_in_a, 0xD3) { OUT(RA, *PCP, RA); PC++; ENTIME(11); } OPDEF(in_a_in, 0xDB) { IN(RA, *PCP, RA); PC++; ENTIME(11); } #define EX_ISP_RR(rrn, rr) \ OPDEF(ex_isp_ ## rrn, 0xE3) \ { \ register dbyte dtmp; \ dtmp = DREAD(SP); \ DWRITE(SP, rr); \ rr = dtmp; \ ENTIME(19); \ } EX_ISP_RR(hl, HL) OPDEF(ex_de_hl, 0xEB) { register dbyte dtmp; dtmp = DE; DE = HL; HL = dtmp; ENTIME(4); } OPDEF(di, 0xF3) { DANM(iff1) = 0; DANM(iff2) = 0; DI_CHECK ENTIME(4); } OPDEF(ei, 0xFB) { DANM(iff1) = 1; DANM(iff2) = 1; ENTIME(4); } #define CALL_CC(ccn, cc, n) \ OPDEF(call_ ## ccn ## _nn, 0xC4+n*8) \ { \ if(!(cc)) { \ PC+=2; \ ENTIME(10); \ } \ else { \ register dbyte dtmp; \ dtmp = PC; \ PC = DREAD(dtmp); \ dtmp += 2; \ PUSH(dtmp); \ ENTIME(17); \ } \ } CALL_CC(nz, !TESTZF, 0) CALL_CC(z, TESTZF, 1) CALL_CC(nc, !TESTCF, 2) CALL_CC(c, TESTCF, 3) CALL_CC(po, !TESTPF, 4) CALL_CC(pe, TESTPF, 5) CALL_CC(p, !TESTSF, 6) CALL_CC(m, TESTSF, 7) #define PUSH_RR(rrn, rr, n) \ OPDEF(push_ ## rrn, 0xC5+n*0x10) \ { \ PUSH(rr); \ ENTIME(11); \ } PUSH_RR(bc, BC, 0) PUSH_RR(de, DE, 1) PUSH_RR(hl, HL, 2) PUSH_RR(af, AF, 3) OPDEF(call_nn, 0xCD) { register dbyte dtmp; dtmp = PC; PC = DREAD(dtmp); dtmp += 2; PUSH(dtmp); ENTIME(17); } OPDEF(add_a_n, 0xC6) { ADD(*PCP); PC++; ENTIME(7); } OPDEF(adc_a_n, 0xCE) { ADC(*PCP); PC++; ENTIME(7); } OPDEF(sub_n, 0xD6) { SUB(*PCP); PC++; ENTIME(7); } OPDEF(sbc_a_n, 0xDE) { SBC(*PCP); PC++; ENTIME(7); } OPDEF(and_n, 0xE6) { AND(*PCP); PC++; ENTIME(7); } OPDEF(xor_n, 0xEE) { XOR(*PCP); PC++; ENTIME(7); } OPDEF(or_n, 0xF6) { OR(*PCP); PC++; ENTIME(7); } OPDEF(cp_n, 0xFE) { CP(*PCP); PC++; ENTIME(7); } #define RST_NN(nnn, n) \ OPDEF(rst_ ## nnn, 0xC7+n*8) \ { \ PUSH(PC); \ PC = n*8; \ ENTIME(11); \ } RST_NN(00, 0) RST_NN(08, 1) RST_NN(10, 2) RST_NN(18, 3) RST_NN(20, 4) RST_NN(28, 5) RST_NN(30, 6) RST_NN(38, 7) #include "z80_op4x.c" spectemu-0.94/z80_ari.h0100644000175000017500000000527106505020714015167 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define ADDSUB(r, op, tbl) \ { \ register byte res; \ register int idx; \ register int flag; \ res = RA op; \ idx = IDXCALC(RA, r, res); \ RA = res; \ flag = (RF & ~(AALLF)) | \ TAB(tbl)[idx]; \ if(!res) flag |= ZF; \ RF = flag; \ } #define ADD(r) ADDSUB(r, + r, addf_tbl) #define ADC(r) ADDSUB(r, + r + (RF & CF), addf_tbl) #define SUB(r) ADDSUB(r, - r, subf_tbl) #define SBC(r) ADDSUB(r, - r - (RF & CF), subf_tbl) #define AND(r) \ { \ register byte res; \ register byte flag; \ res = RA & r; \ RA = res; \ flag = (RF & ~(AALLF)) | \ TAB(orf_tbl)[res] | HF; \ RF = flag; \ } #define XOR(r) \ { \ register byte res; \ register byte flag; \ res = RA ^ r; \ RA = res; \ flag = (RF & ~(AALLF)) | \ TAB(orf_tbl)[res]; \ RF = flag; \ } #define OR(r) \ { \ register byte res; \ register byte flag; \ res = RA | r; \ RA = res; \ flag = (RF & ~(AALLF)) | \ TAB(orf_tbl)[res]; \ RF = flag; \ } #define CP(r) \ { \ register byte res; \ register int idx; \ register int flag; \ res = RA - r; \ idx = IDXCALC(RA, r, res); \ flag = (RF & ~(AALLF)) | \ TAB(subf_tbl)[idx]; \ if(!res) flag |= ZF; \ RF = flag; \ } spectemu-0.94/z80_op5.c0100644000175000017500000002045206505020714015110 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef NO_OPDEF #include "z80_def.h" #include "z80_op5.h" #endif OPDEF(ill_ed, 0x00) { #ifdef DEBUG_Z80 printf("ILL_ED: %04X - %02X\n", (dbyte) (PC-1), DANM(mem)[(dbyte) (PC-1)]); #endif ENTIME(8); } #define IN_R_IC(rn, r, n) \ OPDEF(in_ ## rn ## _ic, 0x40+8*n) \ { \ register byte res, flag; \ IN(RB, RC, res); \ r = res; \ flag = (RF & ~(ABUTCF)) | \ TAB(orf_tbl)[res]; \ RF = flag; \ ENTIME(12); \ } IN_R_IC(b, RB, 0) IN_R_IC(c, RC, 1) IN_R_IC(d, RD, 2) IN_R_IC(e, RE, 3) IN_R_IC(h, RH, 4) IN_R_IC(l, RL, 5) IN_R_IC(f, res, 6) IN_R_IC(a, RA, 7) #define OUT_IC_R(rn, r, n) \ OPDEF(out_ic_ ## rn, 0x41+8*n) \ { \ OUT(RB, RC, r); \ ENTIME(12); \ } OUT_IC_R(b, RB, 0) OUT_IC_R(c, RC, 1) OUT_IC_R(d, RD, 2) OUT_IC_R(e, RE, 3) OUT_IC_R(h, RH, 4) OUT_IC_R(l, RL, 5) OUT_IC_R(0, 0, 6) OUT_IC_R(a, RA, 7) #define SBC_HL_RR(rrn, rr, n) \ OPDEF(sbc_hl_ ## rrn, 0x42+0x10*n) \ { \ register dbyte res; \ register int idx, flag; \ flag = RF; \ res = HL - rr - (flag & CF); \ idx = DIDXCALC(HL, rr, res); \ HL = res; \ flag = (RF & ~(ALLF)) | \ (TAB(subf_tbl)[idx] & ALLF); \ if(!res) flag |= ZF; \ RF = flag; \ ENTIME(15); \ } SBC_HL_RR(bc, BC, 0) SBC_HL_RR(de, DE, 1) SBC_HL_RR(hl, HL, 2) SBC_HL_RR(sp, SP, 3) #define ADC_HL_RR(rrn, rr, n) \ OPDEF(adc_hl_ ## rrn, 0x4A+0x10*n) \ { \ register dbyte res; \ register int idx, flag; \ flag = RF; \ res = HL + rr + (flag & CF); \ idx = DIDXCALC(HL, rr, res); \ HL = res; \ flag = (RF & ~(ALLF)) | \ (TAB(addf_tbl)[idx] & ALLF); \ if(!res) flag |= ZF; \ RF = flag; \ ENTIME(15); \ } ADC_HL_RR(bc, BC, 0) ADC_HL_RR(de, DE, 1) ADC_HL_RR(hl, HL, 2) ADC_HL_RR(sp, SP, 3) #define LD_INN_RR(rrn, pf, rr, n) \ OPDEF(ld_inn_ ## rrn ## pf, 0x43+0x10*n) \ { \ register dbyte dtmp; \ FETCHD(dtmp); \ DWRITE(dtmp, rr); \ ENTIME(20); \ } LD_INN_RR(bc, , BC, 0) LD_INN_RR(de, , DE, 1) LD_INN_RR(hl, _ed, HL, 2) LD_INN_RR(sp, , SP, 3) #define LD_RR_INN(rrn, pf, rr, n) \ OPDEF(ld_## rrn ## _inn ## pf, 0x4B+0x10*n) \ { \ register dbyte dtmp; \ FETCHD(dtmp); \ rr = DREAD(dtmp); \ ENTIME(20); \ } LD_RR_INN(bc, , BC, 0) LD_RR_INN(de, , DE, 1) LD_RR_INN(hl, _ed, HL, 2) LD_RR_INN(sp, , SP, 3) OPDEF(neg, 0x44 0x4C 0x54 0x5C 0x64 0x6C 0x74 0x7C) { register byte res; register int idx; register int flag; res = 0 - RA; idx = IDXCALC(0, RA, res); RA = res; flag = (RF & ~(AALLF)) | TAB(subf_tbl)[idx]; if(!res) flag |= ZF; RF = flag; ENTIME(8); } OPDEF(retn, 0x45 0x55 0x5D 0x65 0x6D 0x75 0x7D) { DANM(iff1) = DANM(iff2); POP(PC); ENTIME(14); } OPDEF(reti, 0x4D) { POP(PC); ENTIME(14); } OPDEF(im_0, 0x46 0x4E 0x56 0x5E) { DANM(it_mode) = 0; ENTIME(8); } OPDEF(im_1, 0x56 0x76) { DANM(it_mode) = 1; ENTIME(8); } OPDEF(im_2, 0x5E 0x7E) { DANM(it_mode) = 2; ENTIME(8); } OPDEF(ld_i_a, 0x47) { RI = RA; ENTIME(9); } OPDEF(ld_r_a, 0x4F) { DANM(rl7) = RA & 0x80; RR = RA; ENTIME(9); } OPDEF(ld_a_i, 0x57) { register int flag; RA = RI; flag = (RF & ~(BUTCF)) | (RA & SF); if(!RA) flag |= ZF; if(DANM(iff2)) flag |= PVF; RF = flag; ENTIME(9); } OPDEF(ld_a_r, 0x5F) { register int flag; RA = (RR & 0x7F) | DANM(rl7); flag = (RF & ~(BUTCF)) | (RA & SF); if(!RA) flag |= ZF; if(DANM(iff2)) flag |= PVF; RF = flag; ENTIME(9); } OPDEF(rrd, 0x67) { register dbyte dtmp; dtmp = *HLP | (RA << 8); RA = (RA & 0xF0) | (dtmp & 0x0F); SETFLAGS(ABUTCF, TAB(orf_tbl)[RA]); dtmp >>= 4; PUTMEM(HL, HLP, (byte) dtmp); ENTIME(18); } OPDEF(rld, 0x6F) { register dbyte dtmp; dtmp = (*HLP << 4) | (RA & 0x0F); RA = (RA & 0xF0) | ((dtmp >> 8) & 0x0F); SETFLAGS(ABUTCF, TAB(orf_tbl)[RA]); PUTMEM(HL, HLP, (byte) dtmp); ENTIME(18); } #define NOREPEAT() \ if(BC) RF |= PVF; \ ENTIME(16) #define LDREPEAT() \ if(BC) { \ RF |= PVF; \ PC-=2; \ ENTIME(21); \ } \ else { \ ENTIME(16); \ } #define LDID(dir) \ register byte res; \ res = *HLP; \ PUTMEM(DE, DEP, res); \ DE dir, HL dir; \ RF = RF & ~(HF | PVF | NF); \ BC-- OPDEF(ldi, 0xA0) { LDID(++); NOREPEAT(); } OPDEF(ldd, 0xA8) { LDID(--); NOREPEAT(); } OPDEF(ldir, 0xB0) { LDID(++); LDREPEAT(); } OPDEF(lddr, 0xB8) { LDID(--); LDREPEAT(); } #define CPREPEAT() \ if(res && BC) { \ RF |= PVF; \ PC-=2; \ ENTIME(21); \ } \ else { \ ENTIME(16); \ } #define CPID(dir) \ register byte res; \ register int idx; \ res = RA - *HLP; \ idx = IDXCALC(RA, *HLP, res); \ RF = (RF & ~BUTCF) | \ (TAB(subf_tbl)[idx] & \ (SF | HF | NF | B3F | B5F)); \ if(!res) RF |= ZF; \ HL dir; \ BC-- OPDEF(cpi, 0xA1) { CPID(++); NOREPEAT(); } OPDEF(cpd, 0xA9) { CPID(--); NOREPEAT(); } OPDEF(cpir, 0xB1) { CPID(++); CPREPEAT(); } OPDEF(cpdr, 0xB9) { CPID(--); CPREPEAT(); } #define IOREPEAT() \ if(RB) { \ PC-=2; \ ENTIME(21); \ } \ else { \ ENTIME(16); \ } #define INID(dir) \ register byte res; \ register int idx; \ res = RB - 1; \ idx = IDXCALC(RB, 1, res); \ RF = (RF & ~BUTCF) | \ (TAB(subf_tbl)[idx] & \ (SF | HF | PVF | NF | B3F | B5F)); \ if(!res) RF |= ZF; \ RB = res; \ IN(RB, RC, res); \ PUTMEM(HL, HLP, res); \ HL dir OPDEF(ini, 0xA2) { INID(++); ENTIME(16); } OPDEF(ind, 0xAA) { INID(--); ENTIME(16); } OPDEF(inir, 0xB2) { INID(++); IOREPEAT(); } OPDEF(indr, 0xBA) { INID(--); IOREPEAT(); } #define OUTID(dir) \ register byte res; \ register int idx; \ res = RB - 1; \ idx = IDXCALC(RB, 1, res); \ RF = (RF & ~BUTCF) | \ (TAB(subf_tbl)[idx] & \ (SF | HF | PVF | NF )); \ if(!res) RF |= ZF; \ RB = res; \ OUT(RB, RC, *HLP); \ HL dir OPDEF(outi, 0xA3) { OUTID(++); ENTIME(16); } OPDEF(outd, 0xAB) { OUTID(--); ENTIME(16); } OPDEF(otir, 0xB3) { OUTID(++); IOREPEAT(); } OPDEF(otdr, 0xBB) { OUTID(--); IOREPEAT(); } spectemu-0.94/z80_op1.h0100644000175000017500000001001506505020714015103 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ extern z80t z80op_nop(z80t); extern z80t z80op_ld_bc_nn(z80t); extern z80t z80op_ld_ibc_a(z80t); extern z80t z80op_inc_bc(z80t); extern z80t z80op_inc_b(z80t); extern z80t z80op_dec_b(z80t); extern z80t z80op_ld_b_n(z80t); extern z80t z80op_rlca(z80t); extern z80t z80op_ex_af_afb(z80t); extern z80t z80op_add_hl_bc(z80t); extern z80t z80op_ld_a_ibc(z80t); extern z80t z80op_dec_bc(z80t); extern z80t z80op_inc_c(z80t); extern z80t z80op_dec_c(z80t); extern z80t z80op_ld_c_n(z80t); extern z80t z80op_rrca(z80t); extern z80t z80op_djnz_e(z80t); extern z80t z80op_ld_de_nn(z80t); extern z80t z80op_ld_ide_a(z80t); extern z80t z80op_inc_de(z80t); extern z80t z80op_inc_d(z80t); extern z80t z80op_dec_d(z80t); extern z80t z80op_ld_d_n(z80t); extern z80t z80op_rla(z80t); extern z80t z80op_jr_e(z80t); extern z80t z80op_add_hl_de(z80t); extern z80t z80op_ld_a_ide(z80t); extern z80t z80op_dec_de(z80t); extern z80t z80op_inc_e(z80t); extern z80t z80op_dec_e(z80t); extern z80t z80op_ld_e_n(z80t); extern z80t z80op_rra(z80t); extern z80t z80op_jr_nz_e(z80t); extern z80t z80op_ld_hl_nn(z80t); extern z80t z80op_ld_inn_hl(z80t); extern z80t z80op_inc_hl(z80t); extern z80t z80op_inc_h(z80t); extern z80t z80op_dec_h(z80t); extern z80t z80op_ld_h_n(z80t); extern z80t z80op_daa(z80t); extern z80t z80op_jr_z_e(z80t); extern z80t z80op_add_hl_hl(z80t); extern z80t z80op_ld_hl_inn(z80t); extern z80t z80op_dec_hl(z80t); extern z80t z80op_inc_l(z80t); extern z80t z80op_dec_l(z80t); extern z80t z80op_ld_l_n(z80t); extern z80t z80op_cpl(z80t); extern z80t z80op_jr_nc_e(z80t); extern z80t z80op_ld_sp_nn(z80t); extern z80t z80op_ld_inn_a(z80t); extern z80t z80op_inc_sp(z80t); extern z80t z80op_inc_ihl(z80t); extern z80t z80op_dec_ihl(z80t); extern z80t z80op_ld_ihl_n(z80t); extern z80t z80op_scf(z80t); extern z80t z80op_jr_c_e(z80t); extern z80t z80op_add_hl_sp(z80t); extern z80t z80op_ld_a_inn(z80t); extern z80t z80op_dec_sp(z80t); extern z80t z80op_inc_a(z80t); extern z80t z80op_dec_a(z80t); extern z80t z80op_ld_a_n(z80t); extern z80t z80op_ccf(z80t); /* IX */ extern z80t z80op_add_ix_bc(z80t); extern z80t z80op_add_ix_de(z80t); extern z80t z80op_add_ix_ix(z80t); extern z80t z80op_add_ix_sp(z80t); extern z80t z80op_ld_ix_nn(z80t); extern z80t z80op_ld_inn_ix(z80t); extern z80t z80op_ld_ix_inn(z80t); extern z80t z80op_inc_ix(z80t); extern z80t z80op_dec_ix(z80t); extern z80t z80op_inc_ixh(z80t); extern z80t z80op_inc_ixl(z80t); extern z80t z80op_inc_iixd(z80t); extern z80t z80op_dec_ixh(z80t); extern z80t z80op_dec_ixl(z80t); extern z80t z80op_dec_iixd(z80t); extern z80t z80op_ld_ixh_n(z80t); extern z80t z80op_ld_ixl_n(z80t); extern z80t z80op_ld_iixd_n(z80t); /* IY */ extern z80t z80op_add_iy_bc(z80t); extern z80t z80op_add_iy_de(z80t); extern z80t z80op_add_iy_iy(z80t); extern z80t z80op_add_iy_sp(z80t); extern z80t z80op_ld_iy_nn(z80t); extern z80t z80op_ld_inn_iy(z80t); extern z80t z80op_ld_iy_inn(z80t); extern z80t z80op_inc_iy(z80t); extern z80t z80op_dec_iy(z80t); extern z80t z80op_inc_iyh(z80t); extern z80t z80op_inc_iyl(z80t); extern z80t z80op_inc_iiyd(z80t); extern z80t z80op_dec_iyh(z80t); extern z80t z80op_dec_iyl(z80t); extern z80t z80op_dec_iiyd(z80t); extern z80t z80op_ld_iyh_n(z80t); extern z80t z80op_ld_iyl_n(z80t); extern z80t z80op_ld_iiyd_n(z80t); spectemu-0.94/z80_op2.h0100644000175000017500000001273606505020714015120 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* extern z80t z80op_nop(z80t); */ extern z80t z80op_ld_b_c(z80t); extern z80t z80op_ld_b_d(z80t); extern z80t z80op_ld_b_e(z80t); extern z80t z80op_ld_b_h(z80t); extern z80t z80op_ld_b_l(z80t); extern z80t z80op_ld_b_ihl(z80t); extern z80t z80op_ld_b_a(z80t); extern z80t z80op_ld_c_b(z80t); /* extern z80t z80op_nop(z80t); */ extern z80t z80op_ld_c_d(z80t); extern z80t z80op_ld_c_e(z80t); extern z80t z80op_ld_c_h(z80t); extern z80t z80op_ld_c_l(z80t); extern z80t z80op_ld_c_ihl(z80t); extern z80t z80op_ld_c_a(z80t); extern z80t z80op_ld_d_b(z80t); extern z80t z80op_ld_d_c(z80t); /* extern z80t z80op_nop(z80t); */ extern z80t z80op_ld_d_e(z80t); extern z80t z80op_ld_d_h(z80t); extern z80t z80op_ld_d_l(z80t); extern z80t z80op_ld_d_ihl(z80t); extern z80t z80op_ld_d_a(z80t); extern z80t z80op_ld_e_b(z80t); extern z80t z80op_ld_e_c(z80t); extern z80t z80op_ld_e_d(z80t); /* extern z80t z80op_nop(z80t); */ extern z80t z80op_ld_e_h(z80t); extern z80t z80op_ld_e_l(z80t); extern z80t z80op_ld_e_ihl(z80t); extern z80t z80op_ld_e_a(z80t); extern z80t z80op_ld_h_b(z80t); extern z80t z80op_ld_h_c(z80t); extern z80t z80op_ld_h_d(z80t); extern z80t z80op_ld_h_e(z80t); /* extern z80t z80op_nop(z80t); */ extern z80t z80op_ld_h_l(z80t); extern z80t z80op_ld_h_ihl(z80t); extern z80t z80op_ld_h_a(z80t); extern z80t z80op_ld_l_b(z80t); extern z80t z80op_ld_l_c(z80t); extern z80t z80op_ld_l_d(z80t); extern z80t z80op_ld_l_e(z80t); extern z80t z80op_ld_l_h(z80t); /* extern z80t z80op_nop(z80t); */ extern z80t z80op_ld_l_ihl(z80t); extern z80t z80op_ld_l_a(z80t); extern z80t z80op_ld_ihl_b(z80t); extern z80t z80op_ld_ihl_c(z80t); extern z80t z80op_ld_ihl_d(z80t); extern z80t z80op_ld_ihl_e(z80t); extern z80t z80op_ld_ihl_h(z80t); extern z80t z80op_ld_ihl_l(z80t); extern z80t z80op_halt(z80t); extern z80t z80op_ld_ihl_a(z80t); extern z80t z80op_ld_a_b(z80t); extern z80t z80op_ld_a_c(z80t); extern z80t z80op_ld_a_d(z80t); extern z80t z80op_ld_a_e(z80t); extern z80t z80op_ld_a_h(z80t); extern z80t z80op_ld_a_l(z80t); extern z80t z80op_ld_a_ihl(z80t); /* extern z80t z80op_nop(z80t); */ /* IX */ extern z80t z80op_ld_b_ixh(z80t); extern z80t z80op_ld_b_ixl(z80t); extern z80t z80op_ld_c_ixh(z80t); extern z80t z80op_ld_c_ixl(z80t); extern z80t z80op_ld_d_ixh(z80t); extern z80t z80op_ld_d_ixl(z80t); extern z80t z80op_ld_e_ixh(z80t); extern z80t z80op_ld_e_ixl(z80t); extern z80t z80op_ld_ixh_b(z80t); extern z80t z80op_ld_ixh_c(z80t); extern z80t z80op_ld_ixh_d(z80t); extern z80t z80op_ld_ixh_e(z80t); /* extern z80t z80op_ld_ixh_ixh(z80t); */ extern z80t z80op_ld_ixh_ixl(z80t); extern z80t z80op_ld_ixh_a(z80t); extern z80t z80op_ld_ixl_b(z80t); extern z80t z80op_ld_ixl_c(z80t); extern z80t z80op_ld_ixl_d(z80t); extern z80t z80op_ld_ixl_e(z80t); extern z80t z80op_ld_ixl_ixh(z80t); /* extern z80t z80op_ld_ixl_ixl(z80t); */ extern z80t z80op_ld_ixl_a(z80t); extern z80t z80op_ld_a_ixh(z80t); extern z80t z80op_ld_a_ixl(z80t); extern z80t z80op_ld_iixd_b(z80t); extern z80t z80op_ld_iixd_c(z80t); extern z80t z80op_ld_iixd_d(z80t); extern z80t z80op_ld_iixd_e(z80t); extern z80t z80op_ld_iixd_h(z80t); extern z80t z80op_ld_iixd_l(z80t); extern z80t z80op_ld_iixd_a(z80t); extern z80t z80op_ld_b_iixd(z80t); extern z80t z80op_ld_c_iixd(z80t); extern z80t z80op_ld_d_iixd(z80t); extern z80t z80op_ld_e_iixd(z80t); extern z80t z80op_ld_h_iixd(z80t); extern z80t z80op_ld_l_iixd(z80t); extern z80t z80op_ld_a_iixd(z80t); /* IY */ extern z80t z80op_ld_b_iyh(z80t); extern z80t z80op_ld_b_iyl(z80t); extern z80t z80op_ld_c_iyh(z80t); extern z80t z80op_ld_c_iyl(z80t); extern z80t z80op_ld_d_iyh(z80t); extern z80t z80op_ld_d_iyl(z80t); extern z80t z80op_ld_e_iyh(z80t); extern z80t z80op_ld_e_iyl(z80t); extern z80t z80op_ld_iyh_b(z80t); extern z80t z80op_ld_iyh_c(z80t); extern z80t z80op_ld_iyh_d(z80t); extern z80t z80op_ld_iyh_e(z80t); /* extern z80t z80op_ld_iyh_iyh(z80t); */ extern z80t z80op_ld_iyh_iyl(z80t); extern z80t z80op_ld_iyh_a(z80t); extern z80t z80op_ld_iyl_b(z80t); extern z80t z80op_ld_iyl_c(z80t); extern z80t z80op_ld_iyl_d(z80t); extern z80t z80op_ld_iyl_e(z80t); extern z80t z80op_ld_iyl_iyh(z80t); /* extern z80t z80op_ld_iyl_iyl(z80t); */ extern z80t z80op_ld_iyl_a(z80t); extern z80t z80op_ld_a_iyh(z80t); extern z80t z80op_ld_a_iyl(z80t); extern z80t z80op_ld_iiyd_b(z80t); extern z80t z80op_ld_iiyd_c(z80t); extern z80t z80op_ld_iiyd_d(z80t); extern z80t z80op_ld_iiyd_e(z80t); extern z80t z80op_ld_iiyd_h(z80t); extern z80t z80op_ld_iiyd_l(z80t); extern z80t z80op_ld_iiyd_a(z80t); extern z80t z80op_ld_b_iiyd(z80t); extern z80t z80op_ld_c_iiyd(z80t); extern z80t z80op_ld_d_iiyd(z80t); extern z80t z80op_ld_e_iiyd(z80t); extern z80t z80op_ld_h_iiyd(z80t); extern z80t z80op_ld_l_iiyd(z80t); extern z80t z80op_ld_a_iiyd(z80t); spectemu-0.94/z80_op3.h0100644000175000017500000001063006505020714015110 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ extern z80t z80op_add_a_b(z80t); extern z80t z80op_add_a_c(z80t); extern z80t z80op_add_a_d(z80t); extern z80t z80op_add_a_e(z80t); extern z80t z80op_add_a_h(z80t); extern z80t z80op_add_a_l(z80t); extern z80t z80op_add_a_ihl(z80t); extern z80t z80op_add_a_a(z80t); extern z80t z80op_adc_a_b(z80t); extern z80t z80op_adc_a_c(z80t); extern z80t z80op_adc_a_d(z80t); extern z80t z80op_adc_a_e(z80t); extern z80t z80op_adc_a_h(z80t); extern z80t z80op_adc_a_l(z80t); extern z80t z80op_adc_a_ihl(z80t); extern z80t z80op_adc_a_a(z80t); extern z80t z80op_sub_b(z80t); extern z80t z80op_sub_c(z80t); extern z80t z80op_sub_d(z80t); extern z80t z80op_sub_e(z80t); extern z80t z80op_sub_h(z80t); extern z80t z80op_sub_l(z80t); extern z80t z80op_sub_ihl(z80t); extern z80t z80op_sub_a(z80t); extern z80t z80op_sbc_a_b(z80t); extern z80t z80op_sbc_a_c(z80t); extern z80t z80op_sbc_a_d(z80t); extern z80t z80op_sbc_a_e(z80t); extern z80t z80op_sbc_a_h(z80t); extern z80t z80op_sbc_a_l(z80t); extern z80t z80op_sbc_a_ihl(z80t); extern z80t z80op_sbc_a_a(z80t); extern z80t z80op_and_b(z80t); extern z80t z80op_and_c(z80t); extern z80t z80op_and_d(z80t); extern z80t z80op_and_e(z80t); extern z80t z80op_and_h(z80t); extern z80t z80op_and_l(z80t); extern z80t z80op_and_ihl(z80t); extern z80t z80op_and_a(z80t); extern z80t z80op_xor_b(z80t); extern z80t z80op_xor_c(z80t); extern z80t z80op_xor_d(z80t); extern z80t z80op_xor_e(z80t); extern z80t z80op_xor_h(z80t); extern z80t z80op_xor_l(z80t); extern z80t z80op_xor_ihl(z80t); extern z80t z80op_xor_a(z80t); extern z80t z80op_or_b(z80t); extern z80t z80op_or_c(z80t); extern z80t z80op_or_d(z80t); extern z80t z80op_or_e(z80t); extern z80t z80op_or_h(z80t); extern z80t z80op_or_l(z80t); extern z80t z80op_or_ihl(z80t); extern z80t z80op_or_a(z80t); extern z80t z80op_cp_b(z80t); extern z80t z80op_cp_c(z80t); extern z80t z80op_cp_d(z80t); extern z80t z80op_cp_e(z80t); extern z80t z80op_cp_h(z80t); extern z80t z80op_cp_l(z80t); extern z80t z80op_cp_ihl(z80t); extern z80t z80op_cp_a(z80t); /* IX */ extern z80t z80op_add_a_ixh(z80t); extern z80t z80op_add_a_ixl(z80t); extern z80t z80op_add_a_iixd(z80t); extern z80t z80op_adc_a_ixh(z80t); extern z80t z80op_adc_a_ixl(z80t); extern z80t z80op_adc_a_iixd(z80t); extern z80t z80op_sub_ixh(z80t); extern z80t z80op_sub_ixl(z80t); extern z80t z80op_sub_iixd(z80t); extern z80t z80op_sbc_a_ixh(z80t); extern z80t z80op_sbc_a_ixl(z80t); extern z80t z80op_sbc_a_iixd(z80t); extern z80t z80op_and_ixh(z80t); extern z80t z80op_and_ixl(z80t); extern z80t z80op_and_iixd(z80t); extern z80t z80op_xor_ixh(z80t); extern z80t z80op_xor_ixl(z80t); extern z80t z80op_xor_iixd(z80t); extern z80t z80op_or_ixh(z80t); extern z80t z80op_or_ixl(z80t); extern z80t z80op_or_iixd(z80t); extern z80t z80op_cp_ixh(z80t); extern z80t z80op_cp_ixl(z80t); extern z80t z80op_cp_iixd(z80t); /* IY */ extern z80t z80op_add_a_iyh(z80t); extern z80t z80op_add_a_iyl(z80t); extern z80t z80op_add_a_iiyd(z80t); extern z80t z80op_adc_a_iyh(z80t); extern z80t z80op_adc_a_iyl(z80t); extern z80t z80op_adc_a_iiyd(z80t); extern z80t z80op_sub_iyh(z80t); extern z80t z80op_sub_iyl(z80t); extern z80t z80op_sub_iiyd(z80t); extern z80t z80op_sbc_a_iyh(z80t); extern z80t z80op_sbc_a_iyl(z80t); extern z80t z80op_sbc_a_iiyd(z80t); extern z80t z80op_and_iyh(z80t); extern z80t z80op_and_iyl(z80t); extern z80t z80op_and_iiyd(z80t); extern z80t z80op_xor_iyh(z80t); extern z80t z80op_xor_iyl(z80t); extern z80t z80op_xor_iiyd(z80t); extern z80t z80op_or_iyh(z80t); extern z80t z80op_or_iyl(z80t); extern z80t z80op_or_iiyd(z80t); extern z80t z80op_cp_iyh(z80t); extern z80t z80op_cp_iyl(z80t); extern z80t z80op_cp_iiyd(z80t); spectemu-0.94/z80_op4.h0100644000175000017500000000627306505020714015121 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ extern z80t z80op_ret_nz(z80t); extern z80t z80op_pop_bc(z80t); extern z80t z80op_jp_nz_nn(z80t); extern z80t z80op_jp_nn(z80t); extern z80t z80op_call_nz_nn(z80t); extern z80t z80op_push_bc(z80t); extern z80t z80op_add_a_n(z80t); extern z80t z80op_rst_00(z80t); extern z80t z80op_ret_z(z80t); extern z80t z80op_ret(z80t); extern z80t z80op_jp_z_nn(z80t); extern z80t z80op_special_cb(z80t); extern z80t z80op_call_z_nn(z80t); extern z80t z80op_call_nn(z80t); extern z80t z80op_adc_a_n(z80t); extern z80t z80op_rst_08(z80t); extern z80t z80op_ret_nc(z80t); extern z80t z80op_pop_de(z80t); extern z80t z80op_jp_nc_nn(z80t); extern z80t z80op_out_in_a(z80t); extern z80t z80op_call_nc_nn(z80t); extern z80t z80op_push_de(z80t); extern z80t z80op_sub_n(z80t); extern z80t z80op_rst_10(z80t); extern z80t z80op_ret_c(z80t); extern z80t z80op_exx(z80t); extern z80t z80op_jp_c_nn(z80t); extern z80t z80op_in_a_in(z80t); extern z80t z80op_call_c_nn(z80t); extern z80t z80op_special_dd(z80t); extern z80t z80op_sbc_a_n(z80t); extern z80t z80op_rst_18(z80t); extern z80t z80op_ret_po(z80t); extern z80t z80op_pop_hl(z80t); extern z80t z80op_jp_po_nn(z80t); extern z80t z80op_ex_isp_hl(z80t); extern z80t z80op_call_po_nn(z80t); extern z80t z80op_push_hl(z80t); extern z80t z80op_and_n(z80t); extern z80t z80op_rst_20(z80t); extern z80t z80op_ret_pe(z80t); extern z80t z80op_jp_hl(z80t); extern z80t z80op_jp_pe_nn(z80t); extern z80t z80op_ex_de_hl(z80t); extern z80t z80op_call_pe_nn(z80t); extern z80t z80op_special_ed(z80t); extern z80t z80op_xor_n(z80t); extern z80t z80op_rst_28(z80t); extern z80t z80op_ret_p(z80t); extern z80t z80op_pop_af(z80t); extern z80t z80op_jp_p_nn(z80t); extern z80t z80op_di(z80t); extern z80t z80op_call_p_nn(z80t); extern z80t z80op_push_af(z80t); extern z80t z80op_or_n(z80t); extern z80t z80op_rst_30(z80t); extern z80t z80op_ret_m(z80t); extern z80t z80op_ld_sp_hl(z80t); extern z80t z80op_jp_m_nn(z80t); extern z80t z80op_ei(z80t); extern z80t z80op_call_m_nn(z80t); extern z80t z80op_special_fd(z80t); extern z80t z80op_cp_n(z80t); extern z80t z80op_rst_38(z80t); /* IX */ extern z80t z80op_pop_ix(z80t); extern z80t z80op_push_ix(z80t); extern z80t z80op_jp_ix(z80t); extern z80t z80op_ld_sp_ix(z80t); extern z80t z80op_ex_isp_ix(z80t); /* IY */ extern z80t z80op_pop_iy(z80t); extern z80t z80op_push_iy(z80t); extern z80t z80op_jp_iy(z80t); extern z80t z80op_ld_sp_iy(z80t); extern z80t z80op_ex_isp_iy(z80t); spectemu-0.94/z80_op5.h0100644000175000017500000000666006505020714015122 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ extern z80t z80op_ill_ed(z80t); extern z80t z80op_in_b_ic(z80t); extern z80t z80op_out_ic_b(z80t); extern z80t z80op_sbc_hl_bc(z80t); extern z80t z80op_ld_inn_bc(z80t); extern z80t z80op_neg(z80t); extern z80t z80op_retn(z80t); extern z80t z80op_im_0(z80t); extern z80t z80op_ld_i_a(z80t); extern z80t z80op_in_c_ic(z80t); extern z80t z80op_out_ic_c(z80t); extern z80t z80op_adc_hl_bc(z80t); extern z80t z80op_ld_bc_inn(z80t); /* extern z80t z80op_neg(z80t); */ extern z80t z80op_reti(z80t); /*extern z80t z80op_im_0(z80t); */ extern z80t z80op_ld_r_a(z80t); extern z80t z80op_in_d_ic(z80t); extern z80t z80op_out_ic_d(z80t); extern z80t z80op_sbc_hl_de(z80t); extern z80t z80op_ld_inn_de(z80t); /* extern z80t z80op_neg(z80t); */ /* extern z80t z80op_retn(z80t); */ extern z80t z80op_im_1(z80t); extern z80t z80op_ld_a_i(z80t); extern z80t z80op_in_e_ic(z80t); extern z80t z80op_out_ic_e(z80t); extern z80t z80op_adc_hl_de(z80t); extern z80t z80op_ld_de_inn(z80t); /* extern z80t z80op_neg(z80t); */ /* extern z80t z80op_retn(z80t); */ extern z80t z80op_im_2(z80t); extern z80t z80op_ld_a_r(z80t); extern z80t z80op_in_h_ic(z80t); extern z80t z80op_out_ic_h(z80t); extern z80t z80op_sbc_hl_hl(z80t); extern z80t z80op_ld_inn_hl_ed(z80t); /* extern z80t z80op_neg(z80t); */ /* extern z80t z80op_retn(z80t); */ /* extern z80t z80op_im_0(z80t); */ extern z80t z80op_rrd(z80t); extern z80t z80op_in_l_ic(z80t); extern z80t z80op_out_ic_l(z80t); extern z80t z80op_adc_hl_hl(z80t); extern z80t z80op_ld_hl_inn_ed(z80t); /* extern z80t z80op_neg(z80t); */ /* extern z80t z80op_retn(z80t); */ /* extern z80t z80op_im_0(z80t); */ extern z80t z80op_rld(z80t); extern z80t z80op_in_f_ic(z80t); extern z80t z80op_out_ic_0(z80t); extern z80t z80op_sbc_hl_sp(z80t); extern z80t z80op_ld_inn_sp(z80t); /* extern z80t z80op_neg(z80t); */ /* extern z80t z80op_retn(z80t); */ /* extern z80t z80op_im_1(z80t); */ /* extern z80t z80op_ill_ed(z80t); */ extern z80t z80op_in_a_ic(z80t); extern z80t z80op_out_ic_a(z80t); extern z80t z80op_adc_hl_sp(z80t); extern z80t z80op_ld_sp_inn(z80t); /* extern z80t z80op_neg(z80t); */ /* extern z80t z80op_retn(z80t); */ /* extern z80t z80op_im_2(z80t); */ /* extern z80t z80op_ill_ed(z80t); */ extern z80t z80op_ldi(z80t); extern z80t z80op_cpi(z80t); extern z80t z80op_ini(z80t); extern z80t z80op_outi(z80t); extern z80t z80op_ldd(z80t); extern z80t z80op_cpd(z80t); extern z80t z80op_ind(z80t); extern z80t z80op_outd(z80t); extern z80t z80op_ldir(z80t); extern z80t z80op_cpir(z80t); extern z80t z80op_inir(z80t); extern z80t z80op_otir(z80t); extern z80t z80op_lddr(z80t); extern z80t z80op_cpdr(z80t); extern z80t z80op_indr(z80t); extern z80t z80op_otdr(z80t); spectemu-0.94/z80_op1x.c0100644000175000017500000000415606505020714015277 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* IX */ LD_RR_NN(ix, IX, 2) ADD_RR_RR(ix, IX, bc, BC, 0) ADD_RR_RR(ix, IX, de, DE, 1) ADD_RR_RR(ix, IX, ix, IX, 2) ADD_RR_RR(ix, IX, sp, SP, 3) INC_RR(ix, IX, 2) DEC_RR(ix, IX, 2) LD_INN_RR(ix, IX) LD_RR_INN(ix, IX) INC_R(ixh, XH, 4) INC_R(ixl, XL, 5) OPDEF(inc_iixd, 0x34) { register dbyte addr; IXDGET(IX, addr); MODMEMADDR(INC, addr); ENTIME(19); } DEC_R(ixh, XH, 4) DEC_R(ixl, XL, 5) OPDEF(dec_iixd, 0x35) { register dbyte addr; IXDGET(IX, addr); MODMEMADDR(DEC, addr); ENTIME(19); } LD_R_N(ixh, XH, 4) LD_R_N(ixl, XL, 5) OPDEF(ld_iixd_n, 0x36) { register dbyte addr; IXDGET(IX, addr); WRITE(addr, READ(PC)); PC++; ENTIME(15); } /* IY */ LD_RR_NN(iy, IY, 2) ADD_RR_RR(iy, IY, bc, BC, 0) ADD_RR_RR(iy, IY, de, DE, 1) ADD_RR_RR(iy, IY, iy, IY, 2) ADD_RR_RR(iy, IY, sp, SP, 3) INC_RR(iy, IY, 2) DEC_RR(iy, IY, 2) LD_INN_RR(iy, IY) LD_RR_INN(iy, IY) INC_R(iyh, YH, 4) INC_R(iyl, YL, 5) OPDEF(inc_iiyd, 0x34) { register dbyte addr; IXDGET(IY, addr); MODMEMADDR(INC, addr); ENTIME(19); } DEC_R(iyh, YH, 4) DEC_R(iyl, YL, 5) OPDEF(dec_iiyd, 0x35) { register dbyte addr; IXDGET(IY, addr); MODMEMADDR(DEC, addr); ENTIME(19); } LD_R_N(iyh, YH, 4) LD_R_N(iyl, YL, 5) OPDEF(ld_iiyd_n, 0x36) { register dbyte addr; IXDGET(IY, addr); WRITE(addr, READ(PC)); PC++; ENTIME(15); } spectemu-0.94/z80_op6.c0100644000175000017500000002240606505020714015112 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef NO_OPDEF #include "z80_def.h" #include "z80_op6.h" #endif #define GHL DANM(cbaddr) #define B7(r) (((r) & 0x80) >> 7) #define B0(r) ((r) & 0x01) #define SHIFTROTL(r, mod) \ { \ register int carry; \ carry = B7(r); \ r = mod; \ RF = (RF & ~(AALLF)) | carry | \ TAB(orf_tbl)[(byte) r]; \ } #define SHIFTROTR(r, mod) \ { \ register int carry; \ carry = B0(r); \ r = mod; \ RF = (RF & ~(AALLF)) | carry | \ TAB(orf_tbl)[(byte) r]; \ } #define RLC(r) SHIFTROTL(r, (r << 1) | carry) #define RRC(r) SHIFTROTR(r, (r >> 1) | (carry << 7)) #define RLN(r) SHIFTROTL(r, (r << 1) | (RF & CF)) #define RRN(r) SHIFTROTR(r, (r >> 1) | ((RF & CF) << 7)) #define SLA(r) SHIFTROTL(r, r << 1) #define SRA(r) SHIFTROTR(r, (byte) ((sbyte) r >> 1)) #define SLL(r) SHIFTROTL(r, (r << 1) | 0x01) #define SRL(r) SHIFTROTR(r, r >> 1) #define SHRR(shrn, func, an, rn, r, n) \ OPDEF(shrn ## _ ## rn, 0x00+an*8+n) \ { \ func(r); \ ENTIME(8); \ } #define SHRIHL(shrn, func, an) \ OPDEF(shrn ## _ihl, 0x06+an*8) \ { \ register byte btmp; \ btmp = READ(GHL); \ func(btmp); \ WRITE(GHL, btmp); \ ENTIME(15); \ } #define RLC_R(rn, r, n) SHRR(rlc, RLC, 0, rn, r, n) #define RRC_R(rn, r, n) SHRR(rrc, RRC, 1, rn, r, n) #define RL_R(rn, r, n) SHRR(rl, RLN, 2, rn, r, n) #define RR_R(rn, r, n) SHRR(rr, RRN, 3, rn, r, n) #define SLA_R(rn, r, n) SHRR(sla, SLA, 4, rn, r, n) #define SRA_R(rn, r, n) SHRR(sra, SRA, 5, rn, r, n) #define SLL_R(rn, r, n) SHRR(sll, SLL, 6, rn, r, n) #define SRL_R(rn, r, n) SHRR(srl, SRL, 7, rn, r, n) RLC_R(b, RB, 0) RLC_R(c, RC, 1) RLC_R(d, RD, 2) RLC_R(e, RE, 3) RLC_R(h, RH, 4) RLC_R(l, RL, 5) RLC_R(a, RA, 7) RRC_R(b, RB, 0) RRC_R(c, RC, 1) RRC_R(d, RD, 2) RRC_R(e, RE, 3) RRC_R(h, RH, 4) RRC_R(l, RL, 5) RRC_R(a, RA, 7) RL_R(b, RB, 0) RL_R(c, RC, 1) RL_R(d, RD, 2) RL_R(e, RE, 3) RL_R(h, RH, 4) RL_R(l, RL, 5) RL_R(a, RA, 7) RR_R(b, RB, 0) RR_R(c, RC, 1) RR_R(d, RD, 2) RR_R(e, RE, 3) RR_R(h, RH, 4) RR_R(l, RL, 5) RR_R(a, RA, 7) SLA_R(b, RB, 0) SLA_R(c, RC, 1) SLA_R(d, RD, 2) SLA_R(e, RE, 3) SLA_R(h, RH, 4) SLA_R(l, RL, 5) SLA_R(a, RA, 7) SRA_R(b, RB, 0) SRA_R(c, RC, 1) SRA_R(d, RD, 2) SRA_R(e, RE, 3) SRA_R(h, RH, 4) SRA_R(l, RL, 5) SRA_R(a, RA, 7) SLL_R(b, RB, 0) SLL_R(c, RC, 1) SLL_R(d, RD, 2) SLL_R(e, RE, 3) SLL_R(h, RH, 4) SLL_R(l, RL, 5) SLL_R(a, RA, 7) SRL_R(b, RB, 0) SRL_R(c, RC, 1) SRL_R(d, RD, 2) SRL_R(e, RE, 3) SRL_R(h, RH, 4) SRL_R(l, RL, 5) SRL_R(a, RA, 7) SHRIHL(rlc, RLC, 0) SHRIHL(rrc, RRC, 1) SHRIHL(rl, RLN, 2) SHRIHL(rr, RRN, 3) SHRIHL(sla, SLA, 4) SHRIHL(sra, SRA, 5) SHRIHL(sll, SLL, 6) SHRIHL(srl, SRL, 7) #define BIT(r, n) \ RF = (RF & ~(SF | ZF | NF)) | (r & SF) | (((~r >> n) & 0x01) << 6) #define BIT_N_R(bn, rn, r, n) \ OPDEF(bit_ ## bn ## _ ## rn, 0x40+bn*8+n) \ { \ BIT(r, bn); \ ENTIME(8); \ } #define BIT_N_IHL(bn) \ OPDEF(bit_ ## bn ## _ihl, 0x46+bn*8) \ { \ register byte btmp; \ btmp = READ(GHL); \ BIT(btmp, bn); \ ENTIME(12); \ } BIT_N_R(0, b, RB, 0) BIT_N_R(0, c, RC, 1) BIT_N_R(0, d, RD, 2) BIT_N_R(0, e, RE, 3) BIT_N_R(0, h, RH, 4) BIT_N_R(0, l, RL, 5) BIT_N_R(0, a, RA, 7) BIT_N_R(1, b, RB, 0) BIT_N_R(1, c, RC, 1) BIT_N_R(1, d, RD, 2) BIT_N_R(1, e, RE, 3) BIT_N_R(1, h, RH, 4) BIT_N_R(1, l, RL, 5) BIT_N_R(1, a, RA, 7) BIT_N_R(2, b, RB, 0) BIT_N_R(2, c, RC, 1) BIT_N_R(2, d, RD, 2) BIT_N_R(2, e, RE, 3) BIT_N_R(2, h, RH, 4) BIT_N_R(2, l, RL, 5) BIT_N_R(2, a, RA, 7) BIT_N_R(3, b, RB, 0) BIT_N_R(3, c, RC, 1) BIT_N_R(3, d, RD, 2) BIT_N_R(3, e, RE, 3) BIT_N_R(3, h, RH, 4) BIT_N_R(3, l, RL, 5) BIT_N_R(3, a, RA, 7) BIT_N_R(4, b, RB, 0) BIT_N_R(4, c, RC, 1) BIT_N_R(4, d, RD, 2) BIT_N_R(4, e, RE, 3) BIT_N_R(4, h, RH, 4) BIT_N_R(4, l, RL, 5) BIT_N_R(4, a, RA, 7) BIT_N_R(5, b, RB, 0) BIT_N_R(5, c, RC, 1) BIT_N_R(5, d, RD, 2) BIT_N_R(5, e, RE, 3) BIT_N_R(5, h, RH, 4) BIT_N_R(5, l, RL, 5) BIT_N_R(5, a, RA, 7) BIT_N_R(6, b, RB, 0) BIT_N_R(6, c, RC, 1) BIT_N_R(6, d, RD, 2) BIT_N_R(6, e, RE, 3) BIT_N_R(6, h, RH, 4) BIT_N_R(6, l, RL, 5) BIT_N_R(6, a, RA, 7) BIT_N_R(7, b, RB, 0) BIT_N_R(7, c, RC, 1) BIT_N_R(7, d, RD, 2) BIT_N_R(7, e, RE, 3) BIT_N_R(7, h, RH, 4) BIT_N_R(7, l, RL, 5) BIT_N_R(7, a, RA, 7) BIT_N_IHL(0) BIT_N_IHL(1) BIT_N_IHL(2) BIT_N_IHL(3) BIT_N_IHL(4) BIT_N_IHL(5) BIT_N_IHL(6) BIT_N_IHL(7) #define RES(r, n) r &= ~(1 << n) #define RES_N_R(bn, rn, r, n) \ OPDEF(res_ ## bn ## _ ## rn, 0x80+bn*8+n) \ { \ RES(r, bn); \ ENTIME(8); \ } #define RES_N_IHL(bn) \ OPDEF(res_ ## bn ## _ihl, 0x86+bn*8) \ { \ register byte btmp; \ btmp = READ(GHL); \ RES(btmp, bn); \ WRITE(GHL, btmp); \ ENTIME(15); \ } RES_N_R(0, b, RB, 0) RES_N_R(0, c, RC, 1) RES_N_R(0, d, RD, 2) RES_N_R(0, e, RE, 3) RES_N_R(0, h, RH, 4) RES_N_R(0, l, RL, 5) RES_N_R(0, a, RA, 7) RES_N_R(1, b, RB, 0) RES_N_R(1, c, RC, 1) RES_N_R(1, d, RD, 2) RES_N_R(1, e, RE, 3) RES_N_R(1, h, RH, 4) RES_N_R(1, l, RL, 5) RES_N_R(1, a, RA, 7) RES_N_R(2, b, RB, 0) RES_N_R(2, c, RC, 1) RES_N_R(2, d, RD, 2) RES_N_R(2, e, RE, 3) RES_N_R(2, h, RH, 4) RES_N_R(2, l, RL, 5) RES_N_R(2, a, RA, 7) RES_N_R(3, b, RB, 0) RES_N_R(3, c, RC, 1) RES_N_R(3, d, RD, 2) RES_N_R(3, e, RE, 3) RES_N_R(3, h, RH, 4) RES_N_R(3, l, RL, 5) RES_N_R(3, a, RA, 7) RES_N_R(4, b, RB, 0) RES_N_R(4, c, RC, 1) RES_N_R(4, d, RD, 2) RES_N_R(4, e, RE, 3) RES_N_R(4, h, RH, 4) RES_N_R(4, l, RL, 5) RES_N_R(4, a, RA, 7) RES_N_R(5, b, RB, 0) RES_N_R(5, c, RC, 1) RES_N_R(5, d, RD, 2) RES_N_R(5, e, RE, 3) RES_N_R(5, h, RH, 4) RES_N_R(5, l, RL, 5) RES_N_R(5, a, RA, 7) RES_N_R(6, b, RB, 0) RES_N_R(6, c, RC, 1) RES_N_R(6, d, RD, 2) RES_N_R(6, e, RE, 3) RES_N_R(6, h, RH, 4) RES_N_R(6, l, RL, 5) RES_N_R(6, a, RA, 7) RES_N_R(7, b, RB, 0) RES_N_R(7, c, RC, 1) RES_N_R(7, d, RD, 2) RES_N_R(7, e, RE, 3) RES_N_R(7, h, RH, 4) RES_N_R(7, l, RL, 5) RES_N_R(7, a, RA, 7) RES_N_IHL(0) RES_N_IHL(1) RES_N_IHL(2) RES_N_IHL(3) RES_N_IHL(4) RES_N_IHL(5) RES_N_IHL(6) RES_N_IHL(7) #define SET(r, n) r |= (1 << n) #define SET_N_R(bn, rn, r, n) \ OPDEF(set_ ## bn ## _ ## rn, 0xC0+bn*8+n) \ { \ SET(r, bn); \ ENTIME(8); \ } #define SET_N_IHL(bn) \ OPDEF(set_ ## bn ## _ihl, 0x86+bn*8) \ { \ register byte btmp; \ btmp = READ(GHL); \ SET(btmp, bn); \ WRITE(GHL, btmp); \ ENTIME(15); \ } SET_N_R(0, b, RB, 0) SET_N_R(0, c, RC, 1) SET_N_R(0, d, RD, 2) SET_N_R(0, e, RE, 3) SET_N_R(0, h, RH, 4) SET_N_R(0, l, RL, 5) SET_N_R(0, a, RA, 7) SET_N_R(1, b, RB, 0) SET_N_R(1, c, RC, 1) SET_N_R(1, d, RD, 2) SET_N_R(1, e, RE, 3) SET_N_R(1, h, RH, 4) SET_N_R(1, l, RL, 5) SET_N_R(1, a, RA, 7) SET_N_R(2, b, RB, 0) SET_N_R(2, c, RC, 1) SET_N_R(2, d, RD, 2) SET_N_R(2, e, RE, 3) SET_N_R(2, h, RH, 4) SET_N_R(2, l, RL, 5) SET_N_R(2, a, RA, 7) SET_N_R(3, b, RB, 0) SET_N_R(3, c, RC, 1) SET_N_R(3, d, RD, 2) SET_N_R(3, e, RE, 3) SET_N_R(3, h, RH, 4) SET_N_R(3, l, RL, 5) SET_N_R(3, a, RA, 7) SET_N_R(4, b, RB, 0) SET_N_R(4, c, RC, 1) SET_N_R(4, d, RD, 2) SET_N_R(4, e, RE, 3) SET_N_R(4, h, RH, 4) SET_N_R(4, l, RL, 5) SET_N_R(4, a, RA, 7) SET_N_R(5, b, RB, 0) SET_N_R(5, c, RC, 1) SET_N_R(5, d, RD, 2) SET_N_R(5, e, RE, 3) SET_N_R(5, h, RH, 4) SET_N_R(5, l, RL, 5) SET_N_R(5, a, RA, 7) SET_N_R(6, b, RB, 0) SET_N_R(6, c, RC, 1) SET_N_R(6, d, RD, 2) SET_N_R(6, e, RE, 3) SET_N_R(6, h, RH, 4) SET_N_R(6, l, RL, 5) SET_N_R(6, a, RA, 7) SET_N_R(7, b, RB, 0) SET_N_R(7, c, RC, 1) SET_N_R(7, d, RD, 2) SET_N_R(7, e, RE, 3) SET_N_R(7, h, RH, 4) SET_N_R(7, l, RL, 5) SET_N_R(7, a, RA, 7) SET_N_IHL(0) SET_N_IHL(1) SET_N_IHL(2) SET_N_IHL(3) SET_N_IHL(4) SET_N_IHL(5) SET_N_IHL(6) SET_N_IHL(7) spectemu-0.94/z80_op3x.c0100644000175000017500000000355406505020714015302 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* IX */ ADD_A_R(ixh, XH, 4) ADD_A_R(ixl, XL, 5) ADC_A_R(ixh, XH, 4) ADC_A_R(ixl, XL, 5) SUB_R(ixh, XH, 4) SUB_R(ixl, XL, 5) SBC_A_R(ixh, XH, 4) SBC_A_R(ixl, XL, 5) AND_R(ixh, XH, 4) AND_R(ixl, XL, 5) XOR_R(ixh, XH, 4) XOR_R(ixl, XL, 5) OR_R(ixh, XH, 4) OR_R(ixl, XL, 5) CP_R(ixh, XH, 4) CP_R(ixl, XL, 5) ARIID(add_a, ADD, 0, ix, IX) ARIID(adc_a, ADC, 1, ix, IX) ARIID(sub, SUB, 2, ix, IX) ARIID(sbc_a, SBC, 3, ix, IX) ARIID(and, AND, 4, ix, IX) ARIID(xor, XOR, 5, ix, IX) ARIID(or, OR, 6, ix, IX) ARIID(cp, CP, 7, ix, IX) /* IY */ ADD_A_R(iyh, YH, 4) ADD_A_R(iyl, YL, 5) ADC_A_R(iyh, YH, 4) ADC_A_R(iyl, YL, 5) SUB_R(iyh, YH, 4) SUB_R(iyl, YL, 5) SBC_A_R(iyh, YH, 4) SBC_A_R(iyl, YL, 5) AND_R(iyh, YH, 4) AND_R(iyl, YL, 5) XOR_R(iyh, YH, 4) XOR_R(iyl, YL, 5) OR_R(iyh, YH, 4) OR_R(iyl, YL, 5) CP_R(iyh, YH, 4) CP_R(iyl, YL, 5) ARIID(add_a, ADD, 0, iy, IY) ARIID(adc_a, ADC, 1, iy, IY) ARIID(sub, SUB, 2, iy, IY) ARIID(sbc_a, SBC, 3, iy, IY) ARIID(and, AND, 4, iy, IY) ARIID(xor, XOR, 5, iy, IY) ARIID(or, OR, 6, iy, IY) ARIID(cp, CP, 7, iy, IY) spectemu-0.94/z80_op4x.c0100644000175000017500000000175306505020714015302 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* IX */ POP_RR(ix, IX, 2) PUSH_RR(ix, IX, 2) JP_RR(ix, IX) LD_SP_RR(ix, IX) EX_ISP_RR(ix, IX) /* IY */ POP_RR(iy, IY, 2) PUSH_RR(iy, IY, 2) JP_RR(iy, IY) LD_SP_RR(iy, IY) EX_ISP_RR(iy, IY) spectemu-0.94/z80_op2x.c0100644000175000017500000000552306505020714015277 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* IX */ LD_R_R(b, ixh, RB, XH, 0, 4) LD_R_R(b, ixl, RB, XL, 0, 5) LD_R_R(c, ixh, RC, XH, 1, 4) LD_R_R(c, ixl, RC, XL, 1, 5) LD_R_R(d, ixh, RD, XH, 2, 4) LD_R_R(d, ixl, RD, XL, 2, 5) LD_R_R(e, ixh, RE, XH, 3, 4) LD_R_R(e, ixl, RE, XL, 3, 5) LD_R_R(ixh, b, XH, RB, 4, 0) LD_R_R(ixh, c, XH, RC, 4, 1) LD_R_R(ixh, d, XH, RD, 4, 2) LD_R_R(ixh, e, XH, RE, 4, 3) LD_R_R(ixh, ixl, XH, XL, 4, 5) LD_R_R(ixh, a, XH, RA, 4, 7) LD_R_R(ixl, b, XL, RB, 5, 0) LD_R_R(ixl, c, XL, RC, 5, 1) LD_R_R(ixl, d, XL, RD, 5, 2) LD_R_R(ixl, e, XL, RE, 5, 3) LD_R_R(ixl, ixh, XL, XH, 5, 4) LD_R_R(ixl, a, XL, RA, 5, 7) LD_R_R(a, ixh, RA, XH, 7, 4) LD_R_R(a, ixl, RA, XL, 7, 5) LD_ID_R(ix, IX, b, RB, 0) LD_ID_R(ix, IX, c, RC, 1) LD_ID_R(ix, IX, d, RD, 2) LD_ID_R(ix, IX, e, RE, 3) LD_ID_R(ix, IX, h, RH, 4) LD_ID_R(ix, IX, l, RL, 5) LD_ID_R(ix, IX, a, RA, 6) LD_R_ID(ix, IX, b, RB, 0) LD_R_ID(ix, IX, c, RC, 1) LD_R_ID(ix, IX, d, RD, 2) LD_R_ID(ix, IX, e, RE, 3) LD_R_ID(ix, IX, h, RH, 4) LD_R_ID(ix, IX, l, RL, 5) LD_R_ID(ix, IX, a, RA, 6) /* IY */ LD_R_R(b, iyh, RB, YH, 0, 4) LD_R_R(b, iyl, RB, YL, 0, 5) LD_R_R(c, iyh, RC, YH, 1, 4) LD_R_R(c, iyl, RC, YL, 1, 5) LD_R_R(d, iyh, RD, YH, 2, 4) LD_R_R(d, iyl, RD, YL, 2, 5) LD_R_R(e, iyh, RE, YH, 3, 4) LD_R_R(e, iyl, RE, YL, 3, 5) LD_R_R(iyh, b, YH, RB, 4, 0) LD_R_R(iyh, c, YH, RC, 4, 1) LD_R_R(iyh, d, YH, RD, 4, 2) LD_R_R(iyh, e, YH, RE, 4, 3) LD_R_R(iyh, iyl, YH, YL, 4, 5) LD_R_R(iyh, a, YH, RA, 4, 7) LD_R_R(iyl, b, YL, RB, 5, 0) LD_R_R(iyl, c, YL, RC, 5, 1) LD_R_R(iyl, d, YL, RD, 5, 2) LD_R_R(iyl, e, YL, RE, 5, 3) LD_R_R(iyl, iyh, YL, YH, 5, 4) LD_R_R(iyl, a, YL, RA, 5, 7) LD_R_R(a, iyh, RA, YH, 7, 4) LD_R_R(a, iyl, RA, YL, 7, 5) LD_ID_R(iy, IY, b, RB, 0) LD_ID_R(iy, IY, c, RC, 1) LD_ID_R(iy, IY, d, RD, 2) LD_ID_R(iy, IY, e, RE, 3) LD_ID_R(iy, IY, h, RH, 4) LD_ID_R(iy, IY, l, RL, 5) LD_ID_R(iy, IY, a, RA, 6) LD_R_ID(iy, IY, b, RB, 0) LD_R_ID(iy, IY, c, RC, 1) LD_R_ID(iy, IY, d, RD, 2) LD_R_ID(iy, IY, e, RE, 3) LD_R_ID(iy, IY, h, RH, 4) LD_R_ID(iy, IY, l, RL, 5) LD_R_ID(iy, IY, a, RA, 6) spectemu-0.94/xkey.h0100644000175000017500000000201706526307435014701 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef XKEY_H #define XKEY_H #include "spkey_p.h" #include extern void xkey_focus_change_call(XEvent *ev, void *ptr); extern void (*spkb_event_processor)(void); extern void key_call(XEvent *ev); #endif /* XKEY_H */ spectemu-0.94/z80_op6.h0100644000175000017500000002174606505020714015125 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ extern z80t z80op_rlc_b(z80t); extern z80t z80op_rlc_c(z80t); extern z80t z80op_rlc_d(z80t); extern z80t z80op_rlc_e(z80t); extern z80t z80op_rlc_h(z80t); extern z80t z80op_rlc_l(z80t); extern z80t z80op_rlc_ihl(z80t); extern z80t z80op_rlc_a(z80t); extern z80t z80op_rrc_b(z80t); extern z80t z80op_rrc_c(z80t); extern z80t z80op_rrc_d(z80t); extern z80t z80op_rrc_e(z80t); extern z80t z80op_rrc_h(z80t); extern z80t z80op_rrc_l(z80t); extern z80t z80op_rrc_ihl(z80t); extern z80t z80op_rrc_a(z80t); extern z80t z80op_rl_b(z80t); extern z80t z80op_rl_c(z80t); extern z80t z80op_rl_d(z80t); extern z80t z80op_rl_e(z80t); extern z80t z80op_rl_h(z80t); extern z80t z80op_rl_l(z80t); extern z80t z80op_rl_ihl(z80t); extern z80t z80op_rl_a(z80t); extern z80t z80op_rr_b(z80t); extern z80t z80op_rr_c(z80t); extern z80t z80op_rr_d(z80t); extern z80t z80op_rr_e(z80t); extern z80t z80op_rr_h(z80t); extern z80t z80op_rr_l(z80t); extern z80t z80op_rr_ihl(z80t); extern z80t z80op_rr_a(z80t); extern z80t z80op_sla_b(z80t); extern z80t z80op_sla_c(z80t); extern z80t z80op_sla_d(z80t); extern z80t z80op_sla_e(z80t); extern z80t z80op_sla_h(z80t); extern z80t z80op_sla_l(z80t); extern z80t z80op_sla_ihl(z80t); extern z80t z80op_sla_a(z80t); extern z80t z80op_sra_b(z80t); extern z80t z80op_sra_c(z80t); extern z80t z80op_sra_d(z80t); extern z80t z80op_sra_e(z80t); extern z80t z80op_sra_h(z80t); extern z80t z80op_sra_l(z80t); extern z80t z80op_sra_ihl(z80t); extern z80t z80op_sra_a(z80t); extern z80t z80op_sll_b(z80t); extern z80t z80op_sll_c(z80t); extern z80t z80op_sll_d(z80t); extern z80t z80op_sll_e(z80t); extern z80t z80op_sll_h(z80t); extern z80t z80op_sll_l(z80t); extern z80t z80op_sll_ihl(z80t); extern z80t z80op_sll_a(z80t); extern z80t z80op_srl_b(z80t); extern z80t z80op_srl_c(z80t); extern z80t z80op_srl_d(z80t); extern z80t z80op_srl_e(z80t); extern z80t z80op_srl_h(z80t); extern z80t z80op_srl_l(z80t); extern z80t z80op_srl_ihl(z80t); extern z80t z80op_srl_a(z80t); extern z80t z80op_bit_0_b(z80t); extern z80t z80op_bit_0_c(z80t); extern z80t z80op_bit_0_d(z80t); extern z80t z80op_bit_0_e(z80t); extern z80t z80op_bit_0_h(z80t); extern z80t z80op_bit_0_l(z80t); extern z80t z80op_bit_0_ihl(z80t); extern z80t z80op_bit_0_a(z80t); extern z80t z80op_bit_1_b(z80t); extern z80t z80op_bit_1_c(z80t); extern z80t z80op_bit_1_d(z80t); extern z80t z80op_bit_1_e(z80t); extern z80t z80op_bit_1_h(z80t); extern z80t z80op_bit_1_l(z80t); extern z80t z80op_bit_1_ihl(z80t); extern z80t z80op_bit_1_a(z80t); extern z80t z80op_bit_2_b(z80t); extern z80t z80op_bit_2_c(z80t); extern z80t z80op_bit_2_d(z80t); extern z80t z80op_bit_2_e(z80t); extern z80t z80op_bit_2_h(z80t); extern z80t z80op_bit_2_l(z80t); extern z80t z80op_bit_2_ihl(z80t); extern z80t z80op_bit_2_a(z80t); extern z80t z80op_bit_3_b(z80t); extern z80t z80op_bit_3_c(z80t); extern z80t z80op_bit_3_d(z80t); extern z80t z80op_bit_3_e(z80t); extern z80t z80op_bit_3_h(z80t); extern z80t z80op_bit_3_l(z80t); extern z80t z80op_bit_3_ihl(z80t); extern z80t z80op_bit_3_a(z80t); extern z80t z80op_bit_4_b(z80t); extern z80t z80op_bit_4_c(z80t); extern z80t z80op_bit_4_d(z80t); extern z80t z80op_bit_4_e(z80t); extern z80t z80op_bit_4_h(z80t); extern z80t z80op_bit_4_l(z80t); extern z80t z80op_bit_4_ihl(z80t); extern z80t z80op_bit_4_a(z80t); extern z80t z80op_bit_5_b(z80t); extern z80t z80op_bit_5_c(z80t); extern z80t z80op_bit_5_d(z80t); extern z80t z80op_bit_5_e(z80t); extern z80t z80op_bit_5_h(z80t); extern z80t z80op_bit_5_l(z80t); extern z80t z80op_bit_5_ihl(z80t); extern z80t z80op_bit_5_a(z80t); extern z80t z80op_bit_6_b(z80t); extern z80t z80op_bit_6_c(z80t); extern z80t z80op_bit_6_d(z80t); extern z80t z80op_bit_6_e(z80t); extern z80t z80op_bit_6_h(z80t); extern z80t z80op_bit_6_l(z80t); extern z80t z80op_bit_6_ihl(z80t); extern z80t z80op_bit_6_a(z80t); extern z80t z80op_bit_7_b(z80t); extern z80t z80op_bit_7_c(z80t); extern z80t z80op_bit_7_d(z80t); extern z80t z80op_bit_7_e(z80t); extern z80t z80op_bit_7_h(z80t); extern z80t z80op_bit_7_l(z80t); extern z80t z80op_bit_7_ihl(z80t); extern z80t z80op_bit_7_a(z80t); extern z80t z80op_res_0_b(z80t); extern z80t z80op_res_0_c(z80t); extern z80t z80op_res_0_d(z80t); extern z80t z80op_res_0_e(z80t); extern z80t z80op_res_0_h(z80t); extern z80t z80op_res_0_l(z80t); extern z80t z80op_res_0_ihl(z80t); extern z80t z80op_res_0_a(z80t); extern z80t z80op_res_1_b(z80t); extern z80t z80op_res_1_c(z80t); extern z80t z80op_res_1_d(z80t); extern z80t z80op_res_1_e(z80t); extern z80t z80op_res_1_h(z80t); extern z80t z80op_res_1_l(z80t); extern z80t z80op_res_1_ihl(z80t); extern z80t z80op_res_1_a(z80t); extern z80t z80op_res_2_b(z80t); extern z80t z80op_res_2_c(z80t); extern z80t z80op_res_2_d(z80t); extern z80t z80op_res_2_e(z80t); extern z80t z80op_res_2_h(z80t); extern z80t z80op_res_2_l(z80t); extern z80t z80op_res_2_ihl(z80t); extern z80t z80op_res_2_a(z80t); extern z80t z80op_res_3_b(z80t); extern z80t z80op_res_3_c(z80t); extern z80t z80op_res_3_d(z80t); extern z80t z80op_res_3_e(z80t); extern z80t z80op_res_3_h(z80t); extern z80t z80op_res_3_l(z80t); extern z80t z80op_res_3_ihl(z80t); extern z80t z80op_res_3_a(z80t); extern z80t z80op_res_4_b(z80t); extern z80t z80op_res_4_c(z80t); extern z80t z80op_res_4_d(z80t); extern z80t z80op_res_4_e(z80t); extern z80t z80op_res_4_h(z80t); extern z80t z80op_res_4_l(z80t); extern z80t z80op_res_4_ihl(z80t); extern z80t z80op_res_4_a(z80t); extern z80t z80op_res_5_b(z80t); extern z80t z80op_res_5_c(z80t); extern z80t z80op_res_5_d(z80t); extern z80t z80op_res_5_e(z80t); extern z80t z80op_res_5_h(z80t); extern z80t z80op_res_5_l(z80t); extern z80t z80op_res_5_ihl(z80t); extern z80t z80op_res_5_a(z80t); extern z80t z80op_res_6_b(z80t); extern z80t z80op_res_6_c(z80t); extern z80t z80op_res_6_d(z80t); extern z80t z80op_res_6_e(z80t); extern z80t z80op_res_6_h(z80t); extern z80t z80op_res_6_l(z80t); extern z80t z80op_res_6_ihl(z80t); extern z80t z80op_res_6_a(z80t); extern z80t z80op_res_7_b(z80t); extern z80t z80op_res_7_c(z80t); extern z80t z80op_res_7_d(z80t); extern z80t z80op_res_7_e(z80t); extern z80t z80op_res_7_h(z80t); extern z80t z80op_res_7_l(z80t); extern z80t z80op_res_7_ihl(z80t); extern z80t z80op_res_7_a(z80t); extern z80t z80op_set_0_b(z80t); extern z80t z80op_set_0_c(z80t); extern z80t z80op_set_0_d(z80t); extern z80t z80op_set_0_e(z80t); extern z80t z80op_set_0_h(z80t); extern z80t z80op_set_0_l(z80t); extern z80t z80op_set_0_ihl(z80t); extern z80t z80op_set_0_a(z80t); extern z80t z80op_set_1_b(z80t); extern z80t z80op_set_1_c(z80t); extern z80t z80op_set_1_d(z80t); extern z80t z80op_set_1_e(z80t); extern z80t z80op_set_1_h(z80t); extern z80t z80op_set_1_l(z80t); extern z80t z80op_set_1_ihl(z80t); extern z80t z80op_set_1_a(z80t); extern z80t z80op_set_2_b(z80t); extern z80t z80op_set_2_c(z80t); extern z80t z80op_set_2_d(z80t); extern z80t z80op_set_2_e(z80t); extern z80t z80op_set_2_h(z80t); extern z80t z80op_set_2_l(z80t); extern z80t z80op_set_2_ihl(z80t); extern z80t z80op_set_2_a(z80t); extern z80t z80op_set_3_b(z80t); extern z80t z80op_set_3_c(z80t); extern z80t z80op_set_3_d(z80t); extern z80t z80op_set_3_e(z80t); extern z80t z80op_set_3_h(z80t); extern z80t z80op_set_3_l(z80t); extern z80t z80op_set_3_ihl(z80t); extern z80t z80op_set_3_a(z80t); extern z80t z80op_set_4_b(z80t); extern z80t z80op_set_4_c(z80t); extern z80t z80op_set_4_d(z80t); extern z80t z80op_set_4_e(z80t); extern z80t z80op_set_4_h(z80t); extern z80t z80op_set_4_l(z80t); extern z80t z80op_set_4_ihl(z80t); extern z80t z80op_set_4_a(z80t); extern z80t z80op_set_5_b(z80t); extern z80t z80op_set_5_c(z80t); extern z80t z80op_set_5_d(z80t); extern z80t z80op_set_5_e(z80t); extern z80t z80op_set_5_h(z80t); extern z80t z80op_set_5_l(z80t); extern z80t z80op_set_5_ihl(z80t); extern z80t z80op_set_5_a(z80t); extern z80t z80op_set_6_b(z80t); extern z80t z80op_set_6_c(z80t); extern z80t z80op_set_6_d(z80t); extern z80t z80op_set_6_e(z80t); extern z80t z80op_set_6_h(z80t); extern z80t z80op_set_6_l(z80t); extern z80t z80op_set_6_ihl(z80t); extern z80t z80op_set_6_a(z80t); extern z80t z80op_set_7_b(z80t); extern z80t z80op_set_7_c(z80t); extern z80t z80op_set_7_d(z80t); extern z80t z80op_set_7_e(z80t); extern z80t z80op_set_7_h(z80t); extern z80t z80op_set_7_l(z80t); extern z80t z80op_set_7_ihl(z80t); extern z80t z80op_set_7_a(z80t); spectemu-0.94/vgascr.h0100644000175000017500000000176006524375475015221 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef VGASCR_H #define VGASCR_H extern volatile int spvk_after_switch; extern void sp_init_vga(void); extern void set_vga_spmode(void); extern void restore_sptextmode(void); #endif /* VGASCR_H */ spectemu-0.94/config.guess0100555000175000017500000004762206420752662016100 0ustar cjwatsoncjwatson#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. # # This file 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # The master version of this file is at the FSF in /home/gd/gnu/lib. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in alpha:OSF1:*:*) # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-cbm-sysv4 exit 0;; amiga:NetBSD:*:*) echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-cbm-openbsd${UNAME_RELEASE} exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; atari*:NetBSD:*:*) echo m68k-atari-netbsd${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-atari-openbsd${UNAME_RELEASE} exit 0 ;; sun3*:NetBSD:*:*) echo m68k-sun-netbsd${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-sun-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-apple-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >dummy.c int main (argc, argv) int argc; char **argv; { #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF ${CC-cc} dummy.c -o dummy \ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[3478]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; 9000/8?? ) HP_ARCH=hppa1.0 ;; esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; hp3[0-9][05]:NetBSD:*:*) echo m68k-hp-netbsd${UNAME_RELEASE} exit 0 ;; hp3[0-9][05]:OpenBSD:*:*) echo m68k-hp-openbsd${UNAME_RELEASE} exit 0 ;; i?86:BSD/386:*:* | *:BSD/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:NetBSD:*:*) echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo i386-pc-cygwin32 exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin32 exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. ld_help_string=`ld --help 2>&1` if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0 elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0 elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then echo "powerpc-unknown-linux-gnu" ; exit 0 elif test "${UNAME_MACHINE}" = "alpha" ; then echo alpha-unknown-linux-gnu ; exit 0 elif test "${UNAME_MACHINE}" = "sparc" ; then echo sparc-unknown-linux-gnu ; exit 0 else # Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us # useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout. test ! -d /usr/lib/ldscripts/. \ && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 # Determine whether the default compiler is a.out or elf cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 spectemu-0.94/misc.c0100644000175000017500000000547306526333174014657 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "misc.h" #include #include #include #include #include #define DIR_SEP_CHAR '/' char *get_base_name(char *fname) { char *p; p = fname; for(; *p; p++); for(; p >= fname && *p != DIR_SEP_CHAR; p--); return ++p; } int check_ext(const char *filename, const char *ext) { int flen, elen; int i; flen = (int) strlen(filename); elen = (int) strlen(ext); if(flen <= elen + 1) return 0; if(filename[flen-elen-1] != '.') return 0; for(i = 0; i < elen; i++) if(filename[flen-elen+i] != toupper(ext[i])) break; if(i == elen) return 1; for(i = 0; i < elen; i++) if(filename[flen-elen+i] != tolower(ext[i])) break; if(i == elen) return 1; return 0; } void add_extension(char *filename, const char *ext) { int i; int upper; i = (int) strlen(filename); if(filename[i] > 64 && filename[i] < 96) upper = 1; else upper = 0; filename[i++] = '.'; if(upper) for(; *ext; i++, ext++) filename[i] = toupper(*ext); else for(; *ext; i++, ext++) filename[i] = tolower(*ext); } int file_exist(const char *filename) { FILE *fp; fp = fopen(filename, "rb"); if(fp != NULL) { fclose(fp); return 1; } if(errno == ENOENT) return 0; return 1; } int try_extension(char *filename, const char *ext) { int tend; tend = (int) strlen(filename); add_extension(filename, ext); if(file_exist(filename)) return 1; filename[tend] = '\0'; return 0; } void *malloc_err(size_t size) { char *p; p = (char *) malloc(size); if(p == NULL) { fprintf(stderr, "Out of memory!\n"); exit(1); } return (void *) p; } char *make_string(char *ostr, const char *nstr) { if(ostr != NULL) free(ostr); ostr = malloc_err(strlen(nstr) + 1); strcpy(ostr, nstr); return ostr; } void free_string(char *ostr) { if(ostr != NULL) free(ostr); } int mis_strcasecmp(const char *s1, const char *s2) { int c1, c2; for(;; s1++, s2++) { c1 = tolower(*s1); c2 = tolower(*s2); if(!c1 || c1 != c2) break; } return c1-c2; } spectemu-0.94/configure0100755000175000017500000025352306522051314015455 0ustar cjwatsoncjwatson#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.12 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-x use the X Window System" ac_help="$ac_help --with-readline Compile with readline library" ac_help="$ac_help --with-i386asm Compile with intel i386 assembly code" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.12" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=z80.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Make sure we can run config.sub. if $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:557: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`$ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`$ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking if configuration is valid""... $ac_c" 1>&6 echo "configure:579: checking if configuration is valid" >&5 if eval "test \"`echo '$''{'szm_cv_host_system'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else szm_cv_host_system=$host fi if test "$host" = "$szm_cv_host_system"; then validstring="valid" else validstring="invalid" fi echo "$ac_t""$validstring" 1>&6 if test "$validstring" = invalid; then { echo "configure: error: type 'make realclean' before running configure" 1>&2; exit 1; } fi cflags="$CFLAGS" # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:600: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:629: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:677: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:711: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:716: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:740: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then CFLAGS="-g -O2" else CFLAGS="-O2" fi else GCC= test "${CFLAGS+set}" = set || CFLAGS="-g" fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:768: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:789: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:839: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' if test -z "$cflags"; then if test "$GCC" = yes; then CFLAGS="-Wall -O3 -fomit-frame-pointer -funroll-loops" else CFLAGS="-O" fi fi progs="" X_CFLAGS= X_LIBS= olibs="$LIBS" # If we find X, set shell vars x_includes and x_libraries to the # paths, otherwise set no_x=yes. # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 echo "configure:909: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" : fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=NO ac_x_libraries=NO rm -fr conftestdir if mkdir conftestdir; then cd conftestdir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat > Imakefile <<'EOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' EOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case "$ac_im_incroot" in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; esac case "$ac_im_usrlibdir" in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; esac fi cd .. rm -fr conftestdir fi if test "$ac_x_includes" = NO; then # Guess where to find include files, by looking for this one X11 .h file. test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:976: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* # We can compile using X headers with no special include directory. ac_x_includes= else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* # Look for the header file in a standard set of common directories. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in \ /usr/X11/include \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ /usr/include/X11 \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ /usr/local/X11/include \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ /usr/local/include/X11 \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ \ /usr/include \ /usr/local/include \ /usr/unsupported/include \ /usr/athena/include \ /usr/local/x11r5/include \ /usr/lpp/Xamples/include \ \ /usr/openwin/include \ /usr/openwin/share/include \ ; \ do if test -r "$ac_dir/$x_direct_test_include"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest* fi # $ac_x_includes = NO if test "$ac_x_libraries" = NO; then # Check for the libraries. test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries= else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ /usr/X11/lib \ /usr/X11R6/lib \ /usr/X11R5/lib \ /usr/X11R4/lib \ \ /usr/lib/X11 \ /usr/lib/X11R6 \ /usr/lib/X11R5 \ /usr/lib/X11R4 \ \ /usr/local/X11/lib \ /usr/local/X11R6/lib \ /usr/local/X11R5/lib \ /usr/local/X11R4/lib \ \ /usr/local/lib/X11 \ /usr/local/lib/X11R6 \ /usr/local/lib/X11R5 \ /usr/local/lib/X11R4 \ \ /usr/X386/lib \ /usr/x386/lib \ /usr/XFree86/lib/X11 \ \ /usr/lib \ /usr/local/lib \ /usr/unsupported/lib \ /usr/athena/lib \ /usr/local/x11r5/lib \ /usr/lpp/Xamples/lib \ /lib/usr/lib/X11 \ \ /usr/openwin/lib \ /usr/openwin/share/lib \ ; \ do for ac_extension in a so sl; do if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest* fi # $ac_x_libraries = NO if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$ac_t""$have_x" 1>&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 fi if test "$no_x" != yes; then progs="$progs xspect" if test -n "$x_includes"; then X_CFLAGS="-I$x_includes" fi if test -n "$x_libraries"; then X_LIBS="-L$x_libraries" fi oldldflags="$LDFLAGS" LDFLAGS="$LDFLAGS $X_LIBS" echo $ac_n "checking for XOpenDisplay in -lX11""... $ac_c" 1>&6 echo "configure:1153: checking for XOpenDisplay in -lX11" >&5 ac_lib_var=`echo X11'_'XOpenDisplay | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 onlylibx=yes else echo "$ac_t""no" 1>&6 fi if test "$onlylibx" != yes; then echo $ac_n "checking for main in -lXbsd""... $ac_c" 1>&6 echo "configure:1194: checking for main in -lXbsd" >&5 ac_lib_var=`echo Xbsd'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lXbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-lXbsd $alibs" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getmntent in -lseq""... $ac_c" 1>&6 echo "configure:1230: checking for getmntent in -lseq" >&5 ac_lib_var=`echo seq'_'getmntent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-linet -lnsl -lseq $alibs" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 echo "configure:1270: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-ldnet $alibs" else echo "$ac_t""no" 1>&6 fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 echo "configure:1311: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-ldnet_stub $alibs" else echo "$ac_t""no" 1>&6 fi fi LIBS="$alibs $olibs" tocheck_both=0 echo $ac_n "checking for connect""... $ac_c" 1>&6 echo "configure:1355: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else connect(); #endif ; return 0; } EOF if { (eval echo configure:1383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_connect=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_connect=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then echo "$ac_t""yes" 1>&6 tocheck_socket=0 else echo "$ac_t""no" 1>&6 tocheck_socket=1 fi if test "$tocheck_socket" = 1; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 echo "configure:1405: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-lsocket $alibs" else echo "$ac_t""no" 1>&6 tocheck_both=1 fi fi if test "$tocheck_both" = 1; then LIBS="-lsocket -lnsl $alibs $olibs" echo $ac_n "checking for accept""... $ac_c" 1>&6 echo "configure:1450: checking for accept" >&5 if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char accept(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_accept) || defined (__stub___accept) choke me #else accept(); #endif ; return 0; } EOF if { (eval echo configure:1478: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_accept=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_accept=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'accept`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-lsocket -lnsl $alibs" else echo "$ac_t""no" 1>&6 fi fi LIBS="$alibs $olibs" echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 echo "configure:1501: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else gethostbyname(); #endif ; return 0; } EOF if { (eval echo configure:1529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostbyname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 tocheck_nsl=0 else echo "$ac_t""no" 1>&6 tocheck_nsl=1 fi if test "$tocheck_nsl" = 1; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 echo "configure:1551: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="$alibs -lnsl" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for remove""... $ac_c" 1>&6 echo "configure:1593: checking for remove" >&5 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char remove(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_remove) || defined (__stub___remove) choke me #else remove(); #endif ; return 0; } EOF if { (eval echo configure:1621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_remove=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_remove=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 echo "configure:1642: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="$alibs -lposix" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for shmat""... $ac_c" 1>&6 echo "configure:1684: checking for shmat" >&5 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shmat(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_shmat) || defined (__stub___shmat) choke me #else shmat(); #endif ; return 0; } EOF if { (eval echo configure:1712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_shmat=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 echo "configure:1733: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lipc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="$alibs -lipc" else echo "$ac_t""no" 1>&6 fi fi fi alibs="-lX11 $alibs" LIBS="$alibs $olibs" echo $ac_n "checking for XShmCreateImage in -lXext""... $ac_c" 1>&6 echo "configure:1778: checking for XShmCreateImage in -lXext" >&5 ac_lib_var=`echo Xext'_'XShmCreateImage | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lXext $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 alibs="-lXext $alibs" cat >> confdefs.h <<\EOF #define HAVE_MITSHM 1 EOF else echo "$ac_t""no" 1>&6 fi LIBS="$alibs $olibs" echo $ac_n "checking for XShmQueryExtension""... $ac_c" 1>&6 echo "configure:1824: checking for XShmQueryExtension" >&5 if eval "test \"`echo '$''{'ac_cv_func_XShmQueryExtension'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char XShmQueryExtension(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_XShmQueryExtension) || defined (__stub___XShmQueryExtension) choke me #else XShmQueryExtension(); #endif ; return 0; } EOF if { (eval echo configure:1852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_XShmQueryExtension=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_XShmQueryExtension=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'XShmQueryExtension`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SHMQUERY 1 EOF else echo "$ac_t""no" 1>&6 fi xlibs="$LIBS" LDFLAGS="$oldldflags" fi LIBS="$olibs" echo $ac_n "checking for vga_setmode in -lvga""... $ac_c" 1>&6 echo "configure:1881: checking for vga_setmode in -lvga" >&5 ac_lib_var=`echo vga'_'vga_setmode | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lvga $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 no_vga="" else echo "$ac_t""no" 1>&6 no_vga=yes fi if test "$no_vga" != yes; then progs="$progs vgaspect" vgalib=-lvga LIBS="$vgalib $olibs" echo $ac_n "checking for vga_runinbackground_version""... $ac_c" 1>&6 echo "configure:1927: checking for vga_runinbackground_version" >&5 if eval "test \"`echo '$''{'ac_cv_func_vga_runinbackground_version'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vga_runinbackground_version(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vga_runinbackground_version) || defined (__stub___vga_runinbackground_version) choke me #else vga_runinbackground_version(); #endif ; return 0; } EOF if { (eval echo configure:1955: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_vga_runinbackground_version=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vga_runinbackground_version=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vga_runinbackground_version`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define RUN_IN_BACKGROUND 1 EOF else echo "$ac_t""no" 1>&6 fi fi LIBS="$olibs" rllibs="" withrl=yes # Check whether --with-readline or --without-readline was given. if test "${with_readline+set}" = set; then withval="$with_readline" if test "$withval" = no; then withrl=no; fi fi if test "$withrl" = yes; then echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6 echo "configure:1993: checking for readline in -lreadline" >&5 ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lreadline -ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 have_rl=yes else echo "$ac_t""no" 1>&6 have_rl=no fi if test "$have_rl" = yes; then ac_safe=`echo "readline/readline.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for readline/readline.h""... $ac_c" 1>&6 echo "configure:2036: checking for readline/readline.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2046: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_READLINE 1 EOF rllibs="-lreadline -ltermcap" else echo "$ac_t""no" 1>&6 echo "configure: warning: make sure 'readline.h' is in a 'readline' subdirectory" 1>&2 fi fi fi intelarch="" # Check whether --with-i386asm or --without-i386asm was given. if test "${with_i386asm+set}" = set; then withval="$with_i386asm" if test "$withval" = yes; then intelarch=yes; else intelarch=no; fi fi echo $ac_n "checking whether compiling with intel x86 assembly""... $ac_c" 1>&6 echo "configure:2087: checking whether compiling with intel x86 assembly" >&5 if test -z "$intelarch"; then case "$host_cpu" in i[3-9]86) intelarch=yes ;; *) intelarch=no ;; esac fi echo "$ac_t""$intelarch" 1>&6 if test "$intelarch" = yes; then z80objs=z80_i386_objs echo $ac_n "checking whether using inline assembly code""... $ac_c" 1>&6 echo "configure:2100: checking whether using inline assembly code" >&5 if test "$GCC" = yes; then inlineasm=yes cat >> confdefs.h <<\EOF #define I386_ASM 1 EOF else inlineasm=no fi echo "$ac_t""$inlineasm" 1>&6 link_asm='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.s $LIBS 1>&5' echo $ac_n "checking for underscores before function names in assembly""... $ac_c" 1>&6 echo "configure:2115: checking for underscores before function names in assembly" >&5 if eval "test \"`echo '$''{'szm_cv_underscore_prefix'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.s <&5; (eval $link_asm) 2>&5; } && test -s conftest; then rm -rf conftest* szm_cv_underscore_prefix=no else echo "configure: failed program was:" >&5 cat conftest.s >&5 rm -rf conftest* szm_cv_underscore_prefix=yes fi fi echo "$ac_t""$szm_cv_underscore_prefix" 1>&6 if test "$szm_cv_underscore_prefix" = yes; then cat >> confdefs.h <<\EOF #define AOUT_FORMAT 1 EOF fi else z80objs=z80_c_objs cat >> confdefs.h <<\EOF #define Z80C 1 EOF fi ac_safe=`echo "sys/soundcard.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/soundcard.h""... $ac_c" 1>&6 echo "configure:2154: checking for sys/soundcard.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 oss=yes else echo "$ac_t""no" 1>&6 oss=no fi ac_safe=`echo "sys/audioio.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/audioio.h""... $ac_c" 1>&6 echo "configure:2188: checking for sys/audioio.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2198: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 sunss=yes else echo "$ac_t""no" 1>&6 sunss=no fi if test "$sunss" = yes; then echo $ac_n "checking for definitions in sys/audioio.h""... $ac_c" 1>&6 echo "configure:2222: checking for definitions in sys/audioio.h" >&5 if eval "test \"`echo '$''{'szm_cv_defines_sys_audioio'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(AUDIO_SETINFO) && defined(AUDIO_ENCODING_ULAW) sun_audioio_header #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "sun_audioio_header" >/dev/null 2>&1; then rm -rf conftest* szm_cv_defines_sys_audioio=yes else rm -rf conftest* szm_cv_defines_sys_audioio=no fi rm -f conftest* fi echo "$ac_t""$szm_cv_defines_sys_audioio" 1>&6 if test $szm_cv_defines_sys_audioio = no; then sunss=no fi fi if test "$oss" = yes; then cat >> confdefs.h <<\EOF #define HAVE_SOUND 1 EOF cat >> confdefs.h <<\EOF #define OSS_SOUND 1 EOF else if test "$sunss" = yes; then cat >> confdefs.h <<\EOF #define HAVE_SOUND 1 EOF cat >> confdefs.h <<\EOF #define SUN_SOUND 1 EOF fi fi cat >> confdefs.h <<\EOF #define SPECT_MEM 1 EOF echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 echo "configure:2283: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < #include int main() { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } EOF if { (eval echo configure:2301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < #include int main() { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } EOF if { (eval echo configure:2316: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_bigendian=no fi rm -f conftest* else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* if test $ac_cv_c_bigendian = unknown; then if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_bigendian=yes fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_c_bigendian" 1>&6 if test $ac_cv_c_bigendian = yes; then cat >> confdefs.h <<\EOF #define WORDS_BIGENDIAN 1 EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:2375: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:2429: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:2450: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:2530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:2554: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.12" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@vgalib@%$vgalib%g s%@xlibs@%$xlibs%g s%@rllibs@%$rllibs%g s%@progs@%$progs%g s%@z80objs@%$z80objs%g s%@X_LIBS@%$X_LIBS%g s%@X_CFLAGS@%$X_CFLAGS%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 spectemu-0.94/config.sub0100555000175000017500000004544406420752662015543 0ustar cjwatsoncjwatson#! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. if [ x$1 = x ] then echo Configuration name missing. 1>&2 echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 echo "or $0 ALIAS" 1>&2 echo where ALIAS is a recognized configuration type. 1>&2 exit 1 fi # First pass through any local machine types. case $1 in *local*) echo $1 exit 0 ;; *) ;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in linux-gnu*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple) os= basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \ | arme[lb] | pyramid \ | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ | alpha | we32k | ns16k | clipper | i370 | sh \ | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ | pdp11 | mips64el | mips64orion | mips64orionel \ | sparc | sparclet | sparclite | sparc64) basic_machine=$basic_machine-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i[3456]86) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-* | f301-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-cbm ;; amigados) basic_machine=m68k-cbm os=-amigados ;; amigaunix | amix) basic_machine=m68k-cbm os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [ctj]90-cray) basic_machine=c90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[3456]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i[3456]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i[3456]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i[3456]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; np1) basic_machine=np1-gould ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5) basic_machine=i586-intel ;; pentiumpro | p6) basic_machine=i686-intel ;; pentium-* | p5-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; k5) # We don't have specific support for AMD's K5 yet, so just call it a Pentium basic_machine=i586-amd ;; nexen) # We don't have specific support for Nexgen yet, so just call it a Pentium basic_machine=i586-nexgen ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; symmetry) basic_machine=i386-sequent os=-dynix ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. mips) basic_machine=mips-mips ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sparc) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware* | svr4*) os=-sysv4 ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -linux-gnu* | -uxpv*) # Remember, each alternative MUST END IN *, to match a version number. ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -xenix) os=-xenix ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-semi) os=-aout ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-ibm) os=-aix ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigados ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f301-fujitsu) os=-uxpv ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -hpux*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os spectemu-0.94/configure.in0100644000175000017500000001545706522050455016066 0ustar cjwatsoncjwatsondnl Process this file with autoconf to produce a configure script. AC_INIT(z80.c) AC_CONFIG_HEADER(config.h) dnl Check if on the same host if reconfiguring AC_CANONICAL_HOST AC_MSG_CHECKING([if configuration is valid]) AC_CACHE_VAL(szm_cv_host_system, [szm_cv_host_system=$host]) if test "$host" = "$szm_cv_host_system"; then validstring="valid" else validstring="invalid" fi AC_MSG_RESULT([$validstring]) if test "$validstring" = invalid; then AC_MSG_ERROR([type 'make realclean' before running configure]) fi dnl Checks for programs. cflags="$CFLAGS" AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL if test -z "$cflags"; then if test "$GCC" = yes; then CFLAGS="-Wall -O3 -fomit-frame-pointer -funroll-loops" else CFLAGS="-O" fi fi progs="" dnl ----------------------------------------------------------- dnl Checks X availability dnl ----------------------------------------------------------- X_CFLAGS= X_LIBS= olibs="$LIBS" AC_PATH_X if test "$no_x" != yes; then progs="$progs xspect" if test -n "$x_includes"; then X_CFLAGS="-I$x_includes" fi if test -n "$x_libraries"; then X_LIBS="-L$x_libraries" fi oldldflags="$LDFLAGS" LDFLAGS="$LDFLAGS $X_LIBS" AC_CHECK_LIB(X11, XOpenDisplay, onlylibx=yes) if test "$onlylibx" != yes; then AC_CHECK_LIB(Xbsd, main, [alibs="-lXbsd $alibs"]) AC_CHECK_LIB(seq, getmntent, [alibs="-linet -lnsl -lseq $alibs"]) AC_CHECK_LIB(dnet, dnet_ntoa, [alibs="-ldnet $alibs"]) if test $ac_cv_lib_dnet_dnet_ntoa = no; then AC_CHECK_LIB(dnet_stub, dnet_ntoa, [alibs="-ldnet_stub $alibs"]) fi LIBS="$alibs $olibs" tocheck_both=0 AC_CHECK_FUNC(connect, tocheck_socket=0, tocheck_socket=1) if test "$tocheck_socket" = 1; then AC_CHECK_LIB(socket, connect, alibs="-lsocket $alibs", tocheck_both=1) fi if test "$tocheck_both" = 1; then LIBS="-lsocket -lnsl $alibs $olibs" AC_CHECK_FUNC(accept, alibs="-lsocket -lnsl $alibs") fi LIBS="$alibs $olibs" AC_CHECK_FUNC(gethostbyname, tocheck_nsl=0, tocheck_nsl=1) if test "$tocheck_nsl" = 1; then AC_CHECK_LIB(nsl, gethostbyname, alibs="$alibs -lnsl") fi AC_CHECK_FUNC(remove) if test $ac_cv_func_remove = no; then AC_CHECK_LIB(posix, remove, alibs="$alibs -lposix") fi AC_CHECK_FUNC(shmat) if test $ac_cv_func_shmat = no; then AC_CHECK_LIB(ipc, shmat, alibs="$alibs -lipc") fi fi alibs="-lX11 $alibs" LIBS="$alibs $olibs" AC_CHECK_LIB(Xext, XShmCreateImage, alibs="-lXext $alibs" AC_DEFINE(HAVE_MITSHM)) LIBS="$alibs $olibs" AC_CHECK_FUNC(XShmQueryExtension, AC_DEFINE(HAVE_SHMQUERY)) xlibs="$LIBS" LDFLAGS="$oldldflags" fi LIBS="$olibs" dnl ----------------------------------------------------------- dnl Check for SVGALIB dnl ----------------------------------------------------------- AC_CHECK_LIB(vga, vga_setmode, no_vga="", no_vga=yes) if test "$no_vga" != yes; then progs="$progs vgaspect" vgalib=-lvga LIBS="$vgalib $olibs" AC_CHECK_FUNC(vga_runinbackground_version, AC_DEFINE(RUN_IN_BACKGROUND)) fi LIBS="$olibs" dnl ----------------------------------------------------------- dnl Check for libreadline dnl ----------------------------------------------------------- rllibs="" withrl=yes AC_ARG_WITH(readline, [ --with-readline Compile with readline library], [if test "$withval" = no; then withrl=no; fi]) if test "$withrl" = yes; then AC_CHECK_LIB(readline, readline, have_rl=yes, have_rl=no, -ltermcap) if test "$have_rl" = yes; then AC_CHECK_HEADER(readline/readline.h, [ AC_DEFINE(HAVE_READLINE) rllibs="-lreadline -ltermcap"], [ AC_MSG_WARN([make sure 'readline.h' is in a 'readline' subdirectory])]) fi fi dnl ----------------------------------------------------------- dnl Check if compiling on Intel architecture dnl ----------------------------------------------------------- intelarch="" AC_ARG_WITH(i386asm, [ --with-i386asm Compile with intel i386 assembly code], [if test "$withval" = yes; then intelarch=yes; else intelarch=no; fi]) AC_MSG_CHECKING([whether compiling with intel x86 assembly]) if test -z "$intelarch"; then case "$host_cpu" in i[[3-9]]86) intelarch=yes ;; *) intelarch=no ;; esac fi AC_MSG_RESULT($intelarch) if test "$intelarch" = yes; then z80objs=z80_i386_objs AC_MSG_CHECKING([whether using inline assembly code]) if test "$GCC" = yes; then inlineasm=yes AC_DEFINE(I386_ASM) else inlineasm=no fi AC_MSG_RESULT($inlineasm) link_asm='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.s $LIBS 1>&AC_FD_CC' AC_CACHE_CHECK([for underscores before function names in assembly], szm_cv_underscore_prefix, [cat > conftest.s <&AC_FD_CC cat conftest.s >&AC_FD_CC rm -rf conftest* szm_cv_underscore_prefix=yes fi ]) if test "$szm_cv_underscore_prefix" = yes; then AC_DEFINE(AOUT_FORMAT) fi else z80objs=z80_c_objs AC_DEFINE(Z80C) fi dnl ----------------------------------------------------------- dnl Check for sound driver dnl ----------------------------------------------------------- AC_CHECK_HEADER(sys/soundcard.h, oss=yes, oss=no) AC_CHECK_HEADER(sys/audioio.h, sunss=yes, sunss=no) if test "$sunss" = yes; then AC_CACHE_CHECK([for definitions in sys/audioio.h], szm_cv_defines_sys_audioio, [AC_EGREP_CPP(sun_audioio_header, [#include #if defined(AUDIO_SETINFO) && defined(AUDIO_ENCODING_ULAW) sun_audioio_header #endif ], szm_cv_defines_sys_audioio=yes, szm_cv_defines_sys_audioio=no) ]) if test $szm_cv_defines_sys_audioio = no; then sunss=no fi fi if test "$oss" = yes; then AC_DEFINE(HAVE_SOUND) AC_DEFINE(OSS_SOUND) else if test "$sunss" = yes; then AC_DEFINE(HAVE_SOUND) AC_DEFINE(SUN_SOUND) fi fi dnl ----------------------------------------------------------- dnl Misc dnl ----------------------------------------------------------- AC_DEFINE(SPECT_MEM) AC_C_BIGENDIAN dnl Checks for header files. dnl AC_HEADER_STDC dnl AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T dnl AC_HEADER_TIME dnl Checks for library functions. dnl AC_PROG_GCC_TRADITIONAL dnl AC_TYPE_SIGNAL dnl AC_CHECK_FUNCS(gettimeofday select strerror) AC_SUBST(vgalib) AC_SUBST(xlibs) AC_SUBST(rllibs) AC_SUBST(progs) AC_SUBST(z80objs) AC_SUBST(X_LIBS) AC_SUBST(X_CFLAGS) AC_OUTPUT(Makefile) spectemu-0.94/Makefile.in0100644000175000017500000000643206526050573015620 0ustar cjwatsoncjwatsonSHELL = /bin/sh prefix = @prefix@ datadir = @datadir@/spectemu exec_prefix = @exec_prefix@ bindir = @bindir@ mandir = @mandir@/man1 srcdir = @srcdir@ CC = @CC@ CPP = @CPP@ CFLAGS = @CFLAGS@ CPPFLAGS = @DEFS@ @CPPFLAGS@ @X_CFLAGS@ -DDATADIR=\""$(datadir)"\" INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LDFLAGS = @LDFLAGS@ @X_LIBS@ vgalib = @vgalib@ xlibs = @xlibs@ rllibs = @rllibs@ .SUFFIXES: .SUFFIXES: .c .o .s .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $< .c.s: $(CC) -S $(CFLAGS) $(CPPFLAGS) $< progs = @progs@ all: $(progs) installdirs: $(SHELL) $(srcdir)/mkinstalldirs $(bindir) $(mandir) $(datadir) install_prog: $(progs) if test -f xspect; then \ $(INSTALL_PROGRAM) -s xspect $(bindir); fi if test -f vgaspect; then \ $(INSTALL_PROGRAM) -s -m 4755 vgaspect $(bindir); fi install_man: $(INSTALL_DATA) xspect.1 $(mandir) $(INSTALL_DATA) tapeout.1 $(mandir) (cd $(mandir); rm -f vgaspect.1; ln -s xspect.1 vgaspect.1) install_data: $(INSTALL_DATA) spectkey.gif $(datadir) $(INSTALL_DATA) specsinc.xpm $(datadir) $(INSTALL_DATA) example.cfg $(datadir) if test ! -f $(datadir)/spectemu.cfg; then \ $(INSTALL_DATA) spectemu.cfg $(datadir); fi install: installdirs install_prog install_man install_data z80_c_objs=z80.o z80optab.o z80_step.o spperif.o spect.o rom_imag.o \ z80_op1.o z80_op2.o z80_op3.o z80_op4.o z80_op5.o z80_op6.o z80_i386_objs=z80.o spperif.o rom_imag.o i386emul.o spect_objs=spmain.o spscr.o spkey.o spsound.o sptape.o tapefile.o \ snapshot.o compr.o sptiming.o interf.o misc.o spconf.o \ loadim.o keynames.o $(@z80objs@) xspect_objs=xspect.o xscr.o xutils.o xkey.o \ ax.o spectkey.o xdispkb.o $(spect_objs) xspect: $(xspect_objs) $(CC) -o xspect $(LDFLAGS) $(xspect_objs) $(xlibs) $(rllibs) vgaspect_objs=vgaspect.o vgascr.o vgakey.o $(spect_objs) vgaspect: $(vgaspect_objs) $(CC) -o vgaspect $(LDFLAGS) $(vgaspect_objs) $(vgalib) $(rllibs) tapeout.o: tapeout.c $(CC) -c $(CFLAGS) $(CPPFLAGS) tapeout.c tapeout_objs=tapeout.o tapefile.o misc.o tapeout: $(tapeout_objs) $(CC) -o tapeout $(LDFLAGS) $(tapeout_objs) i386emul.sp: i386step.S $(CPP) $(CPPFLAGS) i386step.S > i386emul.sp i386emul.s: i386emul.sp sp_to_s $(srcdir)/sp_to_s < i386emul.sp > i386emul.s i386emul.o: i386emul.s $(CC) -c $(CFLAGS) i386emul.s rom_imag.c: rom bin_to_c $(srcdir)/bin_to_c rom rom_imag loadim.c: loadim.z80 bin_to_c $(srcdir)/bin_to_c loadim.z80 loadim spectkey.c: spectkey.srl bin_to_c $(srcdir)/bin_to_c spectkey.srl spectkey sp_to_s: sp_to_s.o $(CC) -o sp_to_s $(LDFLAGS) sp_to_s.o bin_to_c: bin_to_c.o $(CC) -o bin_to_c $(LDFLAGS) bin_to_c.o distclean: rm -f *~ *.o *.sp z80*.s i386emul.s bin_to_c sp_to_s rm -f spectkey.c rom_imag.c loadim.c rm -f Makefile.old gmon.out clean: distclean rm -f xspect vgaspect tapeout realclean: clean rm -f config.status config.cache config.log rm -f Makefile config.h depend: cp -f Makefile Makefile.old sed '/^# DO NOT REMOVE THIS LINE/q' < Makefile.old > Makefile gcc -MM $(CPPFLAGS) *.c >> Makefile i386emul.sp: i386def.S i386sp.S i386step.S i386emul.sp: i386op1.S i386op1x.S i386op2.S i386op2x.S i386emul.sp: i386op3.S i386op3x.S i386op4.S i386emul.sp: i386op5.S i386op6.S FORCE: # DO NOT REMOVE THIS LINE, OR "make depend" WILL NOT WORK spectemu-0.94/install-sh0100555000175000017500000001272106420752707015554 0ustar cjwatsoncjwatson#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 spectemu-0.94/acconfig.h0100644000175000017500000000230106525576630015472 0ustar cjwatsoncjwatson /* Define this on i386 architectures if the C compiler generates symbols beginning with underscores, eg. on old aout versions of Linux */ #undef AOUT_FORMAT /* Define this to enable running in background on the Linux console. Works only with SVGALIB 1.2.11 or newer */ #undef RUN_IN_BACKGROUND /* Define this if Xlib has the MITSHM extension */ #undef HAVE_MITSHM /* Define this if program can query MITSHM extension */ #undef HAVE_SHMQUERY /* Define this if you have the readline library */ #undef HAVE_READLINE /* Define this to use the C version of the program insead of the i386 assembly. Define this on non intel machines */ #undef Z80C /* Always define this for the spectrum emulator. */ #undef SPECT_MEM /* Define if sound driver is available. */ #undef HAVE_SOUND /* Define if sound driver is Open Sound System (OSS) */ #undef OSS_SOUND /* Define if sound driver is SUN */ #undef SUN_SOUND /* Define this to use the inline intel assembly sections */ #undef I386_ASM /* Define this to use an alternative way of passing the z80 processor data to the z80 instruction emulation functions. May make emulation faster on some machines, but not on intel, and sparc. */ #undef PROCP @TOP@ spectemu-0.94/Makefile.dos0100644000175000017500000000401306526050615015765 0ustar cjwatsoncjwatsonCC = gcc CPP = $(CC) -E CFLAGS = -Wall -O2 -funroll-loops CPPFLAGS = -DHAVE_CONFIG_H LDFLAGS = vgalib = -lkb -lalleg .SUFFIXES: .SUFFIXES: .c .o .s .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $< .c.s: $(CC) -S $(CFLAGS) $(CPPFLAGS) $< progs = vgaspect all: $(progs) install: all z80_c_objs=z80.o z80optab.o z80_step.o spperif.o spect.o rom_imag.o \ z80_op1.o z80_op2.o z80_op3.o z80_op4.o z80_op5.o z80_op6.o z80_i386_objs=z80.o spperif.o rom_imag.o i386emul.o spect_objs=spmain.o spscr.o spkey.o spsound.o sptape.o tapefile.o \ snapshot.o compr.o sptiming.o interf.o misc.o spconf.o \ loadim.o keynames.o $(z80_i386_objs) vgaspect_objs=vgaspect.o vgascr.o vgakey.o $(spect_objs) vgaspect: $(vgaspect_objs) $(CC) -o vgaspect $(LDFLAGS) $(vgaspect_objs) $(vgalib) speedt_objs=speedt.o $(@z80objs@) speedt: $(speedt_objs) $(CC) -o speedt $(LDFLAGS) $(speedt_objs) i386emul.sp: i386step.S $(CPP) $(CPPFLAGS) i386step.S > i386emul.sp i386emul.s: i386emul.sp sp_to_s ./sp_to_s < i386emul.sp > i386emul.s i386emul.o: i386emul.s $(CC) -c $(CFLAGS) i386emul.s rom_imag.c: rom bin_to_c ./bin_to_c rom rom_imag loadim.c: loadim.z80 bin_to_c ./bin_to_c loadim.z80 loadim spectkey.c: spectkey.srl bin_to_c ./bin_to_c spectkey.srl spectkey sp_to_s: sp_to_s.o $(CC) -o sp_to_s $(LDFLAGS) sp_to_s.o bin_to_c: bin_to_c.o $(CC) -o bin_to_c $(LDFLAGS) bin_to_c.o distclean: del *.o del *.sp del *.exe del i386emul.s del rom_imag.c del spectkey.c del loadim.c del bin_to_c del sp_to_s del Makefile.old dist: distclean strip xspect strip vgaspect clean: distclean del *.exe del vgaspect del speedt realclean: clean del Makefile del config.h depend: copy Makefile Makefile.old copy Makefile.dos Makefile gcc -MM $(CPPFLAGS) *.c >> Makefile i386emul.sp: i386def.S i386sp.S i386step.S i386emul.sp: i386op1.S i386op1x.S i386op2.S i386op2x.S i386emul.sp: i386op3.S i386op3x.S i386op4.S i386emul.sp: i386op5.S i386op6.S FORCE: # DO NOT REMOVE THIS LINE, OR "make depend" WILL NOT WORK spectemu-0.94/config.dos0100644000175000017500000000347406525576630015540 0ustar cjwatsoncjwatson/* config.h. Generated automatically by configure. */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define this on i386 architectures if the C compiler generates symbols beginning with underscores, eg. on old aout versions of Linux */ #define AOUT_FORMAT 1 /* Define this to enable running in background on the Linux console. Works only with SVGALIB 1.2.11 or newer */ /* #undef RUN_IN_BACKGROUND */ /* Define this if Xlib has the MITSHM extension */ /* #undef HAVE_MITSHM */ /* Define this if program can query MITSHM extension */ /* #undef HAVE_SHMQUERY */ /* Define this to use the C version of the program insead of the i386 assembly. Define this on non intel machines */ /* #undef Z80C */ /* Always define this for the spectrum emulator. */ #define SPECT_MEM 1 /* Define if sound driver is available. */ /* #undef HAVE_SOUND */ /* Define if sound driver is Open Sound System (OSS) */ /* #undef OSS_SOUND */ /* Define this to use the inline intel assembly sections */ #define I386_ASM 1 /* Define this to use an alternative way of passing the z80 processor data to the z80 instruction emulation functions. May make emulation faster on some machines, but not on intel, and sparc. */ /* #undef PROCP */ /* Define if compiling for DOS */ #define USE_DJGPP 1 #define USE_LIBKB 1 #define USE_ALLEGRO 1 /* Misc define. */ /* #undef DIFFMODE */ /* Misc define. */ /* #undef CRT_COLOR_DEBUG */ /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ /* #undef WORDS_BIGENDIAN */ spectemu-0.94/config.h.in0100644000175000017500000000317606525576630015606 0ustar cjwatsoncjwatson/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define this on i386 architectures if the C compiler generates symbols beginning with underscores, eg. on old aout versions of Linux */ #undef AOUT_FORMAT /* Define this to enable running in background on the Linux console. Works only with SVGALIB 1.2.11 or newer */ #undef RUN_IN_BACKGROUND /* Define this if Xlib has the MITSHM extension */ #undef HAVE_MITSHM /* Define this if program can query MITSHM extension */ #undef HAVE_SHMQUERY /* Define this if you have the readline library */ #undef HAVE_READLINE /* Define this to use the C version of the program insead of the i386 assembly. Define this on non intel machines */ #undef Z80C /* Always define this for the spectrum emulator. */ #undef SPECT_MEM /* Define if sound driver is available. */ #undef HAVE_SOUND /* Define if sound driver is Open Sound System (OSS) */ #undef OSS_SOUND /* Define if sound driver is SUN */ #undef SUN_SOUND /* Define this to use the inline intel assembly sections */ #undef I386_ASM /* Define this to use an alternative way of passing the z80 processor data to the z80 instruction emulation functions. May make emulation faster on some machines, but not on intel, and sparc. */ #undef PROCP /* Define to empty if the keyword does not work. */ #undef const /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN spectemu-0.94/spconf.h0100644000175000017500000000247406526057756015230 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPCONF_H #define SPCONF_H #define FT_SNAPSHOT 0 #define FT_TAPEFILE 1 extern char *spcf_init_snapshot; extern int spcf_init_snapshot_type; extern char *spcf_init_tapefile; extern int spcf_init_tapefile_type; extern void spcf_pre_check_options(int argc, char *argv[]); extern int spcf_read_conf_file(const char *filename); extern void spcf_read_command_line(int argc, char *argv[]); extern void spcf_read_xresources(void); extern int spcf_find_file_type(char *filename, int *ftp, int *ftsubp); #endif /* SPCONF_H */ spectemu-0.94/mask.xbm0100644000175000017500000000353306521363143015210 0ustar cjwatsoncjwatson#define mask_width 48 #define mask_height 48 static unsigned char mask_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; spectemu-0.94/specsinc.xpm0100644000175000017500000003014006210145706016072 0ustar cjwatsoncjwatson/* XPM */ static char *specsinc[] = { /* width height num_colors chars_per_pixel */ " 78 42 10 1", /* colors */ ". c #000000", "# c #0000a8", "a c #00a800", "b c #a800a8", "c c #a8a8a8", "d c #545454", "e c #5454fc", "f c #fc5454", "g c #fcfc54", "h c #fcfcfc", /* pixels */ "..............................................................................", "..............................................................................", ".............d................d........dc.....................................", ".....dddddddcdddddddddddddddddddddddddddcddddddd..............................", ".....ddddddd.dd......dd.......ddddddddddcd....................................", ".....dddddddcdd......dd.......ddddddddddcd....................................", ".....dddddddcdd......dddddddddddddddddddcd....................................", "..............................................................................", ".....d..d.d.dd.dd..d..........................................................", ".....ddd.cd.d.cd.d.dc........................................................f", ".............................................................................f", ".............................................................................f", ".................................................................hhhhh.......f", "............f............a.............g.g.......................hhhhh......ff", ".....h.....hhh...........h......h...................hh.....h.h..............fg", "....ddddd..dddd...dddd..ddddd..ddddd..ddddd..ddddd..ddddd..dddd...dddd......fg", "....dddhd..dddhc..dddh..dhdhd..dhdhd..dddhd..ddddd..hddhd..ddddc..dddd......fg", "....ddddd..ddddc..ddfd..dddfd..ddddd..ddddd..ddddd..ddfdd..ddddc..dddd.....ffg", "....ccccc..ccccc..cccc...cccc..ccccc..ccccc..ccccc..ccccc..ccccc..cccc.....fgg", "......f....f......f.....f.....................f......f.....ff......f.......fgg", "..........................................................................ffga", ".......aa..........................a......a.a....a.a....aa....a.a.....a...fgga", ".......ddddd..ddddd..ddddd..ddddd..dddd..ddddd..ddddd..ddddd..ddddd..dddddfgga", ".......dhddd..dhddd..ddddd..hdddd..ddfd..dhdff..dhdff..dddfd..dhddd..dddddfgaa", ".......dhdhd..ddhhd..ddhhd..ddddd..dddd..dhhhh..ddddd..ddddd..ddddd..dddddfgaa", ".........................................................................fggae", ".....................ff............f.f...f......f......f......f..........fggae", "........................................................................ffgaae", ".........aaa..........aa............aa.....aa............a..............fggaae", ".........ddddc..dddd..ddddd..ddddd..ddddd..ddddd..ddddd..ddddc..dddd..dddddaee", ".........ddddc..dddd..ddddd..ddddd..dhddd..ddddd..hdddd..hdddc..hddd..dddddae.", ".........dhhhc..ddhh..ddhdd..ddhhd..ddddd..hddhd..ddhhd..ddhdc..dddd..dddddae.", ".......................................................................fggaae.", ".......................................................................fggaee.", "......................................................................ffgaae..", "....................a............a.....a......a...a...................ffgaae..", "....dhdhhd..ddddd..ddddd..ddddd..ddddc.ddddd..ddddd..ddddd..ddddd..dddddddde..", "....dddddd..ddddd..ddddd..hdddd..hdddc.ddddd..ddddd..dhddd..fddff..ddddddhde..", "....dhhhdd..dhddd..hddhd..ddhhd..dhdhc.ddddd..dddhd..ddhdd..dfddd..ddhdhhdd...", "............f.f....f.......ff....fff...ff..f..f......fff.f...........fggaae...", ".....................................................................fggaee...", ".....................................................................fgaae...." }; SIMPLE = T BITPIX = 8 NAXIS = 2 NAXIS1 = 78 NAXIS2 = 42 HISTORY Written by XV 3.10 END ЌбTTnЌббTnnЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌббTTnTьььTTTьTTTьTTьTTTььTTьTьЁTTTTTTTTьTTTьTTTЌTTTTTьTььTTTTTTTTTTTTTTTTTTьTTTTьTTTЁTTTTTTTTTTTьTTTЌTTЌЌTTTTTTьTnTьTььTTTTTTTTTTTTTTTTTTTTЁTTTTTTTTTTTTTTTTTTTTTTTTTTTTnTTTTTЌЌбTTnЌЌбTTnЌббTnnЌббTTnTьььЁTTььTTьTTTTььTTTTTTьTTьTTTььTTTьTЁTTTTTTTTTTnTTTTЁTTTTTTTTTTTTTTTьTTTTTTTTьTTTTьTTTЁьTTTTTTTTTnTTTTЁTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTЁTTTTTTTTTTnnTTTTTTTTTTЌббTTnЌЌбTTnЌЌЌЌЌЌЌЌЌббTnЌббTnTьTьTTTььTTTььTTTTTTTTTTTььььTTTTTTTTTTTTTTTTTTTTЌбTTTьTTTTьTTTTTTTTьTTTTTTЌTTьTЌЌTьTЌЌTTTЌTTьTTTTTTTTЌбTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTЌббTTTTTTTTTTTTTЌббTЌЌбTЌЌЌЌЌЌЌЌЌЌббЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЌббTTTTTTTTTЁTTЌTTTTЌTTTTTTTTTTTTTTTTTTЌTTTTTTЁTTTTЌЌбTTTьTTTTьЁTTTьTьTьTTьTьTTTTьTTTTTTьTTьTTTTTЁTTTTЌбTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTЌбььььььььььЌбЌTббьььььЌЌьььььЌЌЌTTTЁTTЁTTTЁЌTTTTTTTTTTTTTTTЁTTTTTTTTTTTTTTTTTTTTTЁTTTTTTTTЁTTTTTTTTTTTTTTЁTTTTTTTTTTTTTTTTTTTTTTЁTTTTTTTTЁTTTTTTTTTTTTTTTTTTTTTTTTTTTЁTTTTTTTTTTЁspectemu-0.94/spectkey.gif0100644000175000017500000002644606210145617016072 0ustar cjwatsoncjwatsonGIF87aЂXуЁЁЁЁЁЁЁTTTTTььTTььTььь,ЂXюИI«Ѕ8лН»я`(ЋdiћhЄ®lлѕp,ПЩAЯx®п|пяА pиіЏИ¤rЙl:џР1J­ZЇШ¬v{zsкФ§wonќ4vТђ°ћB{лХ§! Ј&д—°џяЂэяю@щшџ~"   .@ѓ B(АѓLё‚J`АjИб‡.%“q#VЂХq€hyОµ(Бwаm].2~7Њ6ТЦўЋе Gўq7ј_BВ7Г6рa„H)xаЂPF eюс‡ ‚Tr`!…[Nё%ѓ8ше °a™ћ©aљ/Ё8Х›&NPўз)ќ‹.І€§ћєTч"Ћ1о8cm=ъш#qAN0¤{Љ№ИIVЂ$~SJY`Y^Jа•Rjf…R0¦—Ў¦P¦‡ўiжЄ§®аfњАIgЉr®x'‹дй‰k05 кз‹7ъ*ЧХ)‚|мЩЁzRю0rЯ¤4hjй”N>Yй¦VfЫЃ—6И ѓ‚Kк&ґjf†«¦К* (ўHk¬°ТЄb »тЁktГц( 8ъ*иx…>sЁ»2щ^ІЙLРBкpґX8m¦Ujk`–tЙ%Ёў~о… ‰a†iљлj­р¦ЊІј,У»гћАЮу/їж ¬Њшv§3±ь Lp +›р‘бMБ’8lЄ4–rЉm§hlбФs\* ЄўљоєZ‡ёт¬*ѓНтњ$д3ћgУ ЬЪАсЬіПЖ†Ђ,|s3K·ЭЁ8lџ”Z‰­ДOk1§Ыz+5„бnµ©иj­jЦmК $‰)Yщ«ю'ШіџёО€ Ы Ч…y€fgъЕЖ}ъкPђ^:л°Џ‘єк±ЧоЊлґЫ®ыёзЮЃЋњЗhу 5г›Їз|оју®_]ЅИЯиџПOэж2ПЬoрХ'ПЃх>x>шBђЏCччRџ«ф№я«Ь‡З\ЌВ{ПГмѕЯјцvѕАјжхкНюnv«™Б/{љ{Щc¶ѕ< m2VУзА т‰yїK`Xѕц%F= +Ё@ рw#м_цTh?ЮхоЊ  [CЪрЃь‹a У6AтЏ„L[яМ†Біq0€EМЂыxДюАzжЈnюґѓ–°‡я3 ю1 Вn1‰B№ьw<z‘x”сf€=жl sd_SиЇђ€+МвжКЁEшнp‹2Фыt И(ОаЏ†dБцћЗѕц1Т‡ѓњ#зљ7<8ЋОPpЈ ¬иД?єl~т »xCQ^с„Фc н8D*®т†G„ {GсБ0y‰”b›H(Wж ЂµDў[ёCRКТ”ћФю4IГ;ж] " %yBb•ыУЈ…hFzр”&њ¦B  &†»Ь xљXНО€8\а6­(ОЫЅ n`¦"ЅіД3/ЋҐсМiIn"0‚­дгзHZцP{м•ъю‚\ћпњµ(!1JЖPbQ’UЯ—Xї`A4’;Ј>wЗR· џщ\iKg ’ЮЃ‹¦8µ'&ж-а§@ ЄP‡JФўю4FMЄR‹ЉФҐ:u©M}ЄT‰Х©ZхЁ ёЄV PХ­>µ«^…jVГ*U°’ХЁEёg&oѓі>•cu«Rбъ№.•®°л\гЄWўвµ}5к_9Шўv…х+_ыУГjЂ±Buм‘lКV@6Ё’ЕАeЃљЩ l¶±‹elg-рЩЊ¶Ґ=-RЪДЄv¬­лg_Л‚eVцgЅНPi ЂЬЪf·­µЄn#Ь©іЕ•кq9ю›Ь§.ґІ лsMЫ\§N—·±Нлlп‡;Дщ”¬іjЂ]ЇЋч§б%ny·zЮ ¶—№лХкu«»ФфаЅРХ®tЕ+ткЧјCЕ/uг{Хщё°ШЭnJХк3пО Ё±qnСл_А •6Цеo„Хы_фЪ7©p‚‰єaҐёГµ±о„п[aВ^шГFm/ЊьЯЯЦ7А-F¬{g a#wЅ¶л€=јb·т6¶Ѕ­ H\bЇXД‹-q“!¬a(YЖЖс…sьX&g9А>†/Љїг's9/жпЌ‰lеc9Г[ж°…=¬жъ†9їsѕп›е:d)“щЄGFA’eљю0O№М)–і‹{lзDяёГivІЈЕњз*«XКgЦмЋ…kfEлёОКнфЈ+ЅйFЛ8УћхЎЅдQ/ZП >kџП[dІъ*нйѓ™,бIгщХ`6хЊ‡lI·љТАfуҐOнй.WщП;ЖtіС\кPKЫХџЋґ©Е‹jТЄЪl6_э,дqУzХ[Ѕµ («k0zЩв>0ќЌoHлЭ/ц5ЌIa|G›ЩШvv±ЌНнikъЩаѕ7А‘ќнjњВOхі{}м_g›Ь|67‹эmUuлЃЭJnБ»…]л}';Ц€®ёЙ®н”Ч›ЯгеxёKNм–чXЯДЖ8€пјrюЃЈ|з8ЧшјйMу(«Ь«іЮxВЯЄМоJи#7rpe>Хљ;<¬9?w№е k©_щзйn-Х«.ф®{ЭЮC—µ№µћсЂ<д,€єЪ 'Z±·S<%!“wduЂи~^|Л‡~иT©'gЂрW8UШ~wU#8Ѓ%иЃ§ыGЂ!Ё‚ Иr®%~’чЂ&Ѓэч‚к}мww"шЃXЂxЃО—ЃйgTш7‚>ШWMЁT'hq h‚Hh„mGгG~mх~U(„И|DqЮVЃфW„^8Ђш„Phw,h{?u‚jx…gXTQH‚WЃ]Ёѓ[‡…NзЂі·Yqё†°—„hѓShЂ{0€VЁ„`Ё€s|oѓ2€`mи†lH€‚h€€€з`†‹А`ю и‡Я…‡y8‰у†b€Z8†•Ш‚ЋЁ‡ЊШ€љ‚"Иіx‡ђ€tx‰‹‹ЇhЉNxѓ¦…–Ґ`Ѕhyёx°xvЏ€ЊЗ(zНЌЛЁЊАЁWєиЊџЉ?вЂн¶…ЂШЉбчЊЄ—ЊШ8ЌеXЌ{Ќг(ЋбЁЋнhЋТ5w+ђ]оИwдЏ‡xzа€ЏмиЏчXzщёЋ№‚щЋф1Џ6hРђщђ‘9‘ y‘9‘™‘™‘Щ‘ )‘’$Y‘ P’(yd)Y’#№’Щ’.‰‘0“Й‡ЪёЌЬёђ9µ“HЦ‡ЬИ“@Iѓ x(9IЏ&Б7{sю і уq„Р”К$)i0)¶Р,Kв,Lщ0GГ0‚&”р,O) [Й$Zy•HS4U№aЙ7\ )kЙ–л–fЩ–\™–=щH"–“…•fy–t™—J№—C‰“9)ЊFЈ$ $~©Ri4чcW‰–в§7”y4‹)™лV™eI—Ћy‘Sщ™u©™R )󙈙7Щ–‘щ—.-ўЙ™Xhљ«™$¶№љІi“ѓiEi”HFљ№Щ™ЈI–‰iљ±•ґ)ЗYљµ)›К)•Ѓ©№™У ™zЙПI•А№0[ЩњХiљy–П)њїЩќ®йvґ9љ’9ћз№Ђ»YЅ©“Ыю 7H —K©ќДй™H©ћЏ™њГiџЇIџ^№џЛ№њТ™ћЋ9—чYњщ™ќб№ Vй–^yљљџP§№ћZY й •{IќО2њ›йћ/…OсiёњОЉ ¬ЩўеЩќ‘ Ј0њ© —vy ж™ ЖYЧyЎЄћ4ъ€ 8Єў™iћвЙў ћ–щ,ИIќнi›PJўјS1U”(z™Ѕ0ќCєўд9™ю™ўМЙџВйЎ љ6Ъ¤iJ¦@ЪњB:›2КЈc Jz#Z[AЉ¤Ь)Ґ¬№§_*ќ>Y6)ЎSYњwљ¤yє`kйљ9Є–gљ•дЩ¦DZЎКў–ъ•|к™юЉ—†Ё‰)©ьIҐ} Є№Й—Sљђ~йЎЏќ<Єќt*”%єVЅ”¶ЄЄп џ'z«јz”7Й›с)џЅ:¬Oљ«YZ«Дљ¬‘g¬ЗЄҐКъ¬0ЊЬh2РZ­џzҐ&¬Фj­ХЄђІ­ЬЄ¬Т:­бZ®чЙ¬Ъ ®жЪ«Y“Ќі®Рк­ т®рљ¬г*!#s€Ј8`ўєцЇЭOЧЇҐ"¬#АЇ\BЊ2а]‡c°$°Ї«d›=Х°љ4±°S#. › ±І8,0°°Ni¬Б*щZдІ±{R*{°гІWC6«1;p8`B580F:{і‰3іVCю*=+ІC;І2»ґЎBґГґ"лі1р%Fґqщ«єџ+K-{ґN»-Ucґ;[ґуµћR¶H‹іK;.iы@K¶5лЈµsk¶7іG;xµB+·dkµ% Ї Іµ\+.^лЇaы-vыґЛ¶‹K±‡ыІ?[±h+№ {S]bІ&kЈІ°№%0·y›°Џ«ё›№™ і є )ё#Ј®Mаі6ыі‰Ы1ґkєU[єџЫЇ†;¶:І–«¶ЌЫ·Јл±‰+¶Ђј( єSј[5’«јn[!ыЪ¶­‹µД‘ІЇ«ІkЅУ;єМ+ј;ѕ9 µЂ«єMЛґє №Г+ґюєt›ѕaВє4 ѕт»ѕw Ѕт;µлЅ ё*KёPр±b‹їу‹є¦‹ёГ{ѕS јд«АНKєюЪnAы¶r+&с›јnЛ±§KЅф їўІј°«л›кєЫ[ЇцЉВ¬В·Ъ®УљВ.М®Ш›ЅйЪВNPZfUX;X=ЬW?¬WAlWC,WEмVG|VILVз:« ¦µЇ »H`ЏрHђUЊђыЊ ђWМЕи(‡],ђя(ЖYuчъ­QlTьЕМЖ9Жo\Жј(З’ЕЦШЏdмЖ.ИЖІГЕR|†ЖqQu¤T¶„АЖsu€‚wЁoѕи‰,Й€<ЗЙ¶aюи¶~•њ€GЃ‡§„ЛW†Ћ<†w„`ИЙЈ¬Љяцz·HК Зz~АЂ¬ЖХ†ouhИ©§|•,Й>‡}y|q{–‰8‰ЬWЗ›Шu«ЖЎ Н‡z›зЉ<ёЛRxМ№м†НЧ}ёьМ МЛ›шЙHЗВ2Ъ–Й€,КЭ¦КtsV}=zGёЃЬ\‚Ю ‰Ґx€cЗ„¦чМљј„h|ОмЛ‘ЁЙ©јZј–‰ќЉэm€Пё8Пy7Ёо:ЛU0ОYЦИvиКэ¦Н‘HПзњРХl‰Ж,ПБј‹!Ќ‹‡ Т нКИ,`ыНэПФ·ЙЁ<НґшСЭПXiэЛЅ<Т_}PюГНСi<СµьeЌlИкњTмњТиьКLЗЇFЙ(=МцјtшLwµ·ЃВЗ{/нz¦МП [НФўЊНо¬С<ЭНР·‹@-Ф7\ФT@С±П9ЅИT}УНѕhЧw МjНСVMНЃ-Н­ьФxЧТ}УЌО;-НК<ЦPy}Рќњ‚ЏЅ{NнС…ќnp Е=ЧGХ%ЌСyЅШѓЌЩРfСЌнСЊyxw]П„MОЁНѓaУCШХ†-Ы1­ЧЭУ']Х—ЭР¬ьV5¬ЅЂИD@{ќ]Ъ€ЭЦ{,ЬьhxlЖД|Ь©mТ6-ХЂЭЭ–њЭw¬yu·ЧimЌиЧбю i–|kM‹э¦ЭЉЬp°јЭ¤њЩУ]Ыт=ЯW=Юn6ЬбЭЯй€ЧNЫЄЌ`йЭ›ЛMЇO0ИыЭСdЅiх-ЩЅµК>РnvЋб“]Цm,ЮNЯонЕ xЪ~МТ}в~z ^” ОЬC°sШmЗ!Nг3NШХ Зщ]У”ёЕпНЭ=®г*д,оДD©ЮлЭаЖHЗNдZ,дРНЩ игЮmгnеФ€езЁеXgдGЪЎ-О)qСnЋh–Vp,Fж^бgж ЧЪѕmkѕqjNУN®pоҐжкЬf–^иЬиЬvЌh~lVЧ_§Fи†и}чd<и0жѓюЂЮxЭийФШљ­ ювґLeЌguћe”qМsdозжёинЌ_ЧИкОжrЮб1VpЁЋМkокcлўОлKНb†^лu~ж$6o·nз©бґ^мЎЮмґ¶ЩsѕзНћлЖ~зљћ 0ҐЬ юйМЋм|~зm.мЮ~мд®мngЮкєNЋѕnзлћЃнЋкеоЈ>мЯ>нтмxg_&Ык^п§кАпхОЯ8ЮоФ>пЌµйґЪйЫnФ7чмТ^рДЮн}.сгnоЖeй¬юоНИиоnпOтщ®рі^б•Ћ_Їз!м ^tцмтЮxч^Ь*эoЙЮdµGйюкПY яДярў каѕтoфщзйЋз7_лqзЇNс·>e#?кбҐu —`&_уKџлгетМЮпSgкЗћмІ~т Цл?Ьїeп%сЧfZAЉ.юв0.k?сhoпNЏШ¶nк9ЯфjЇ\‚?сїк‡Яц/еь>шОNмroсѓѕшaїпТNц1щ^џфFщпщZш–oнuOCїЬЬ>ъf~o|Oп^цн>OкmёиYоSoцџшХHр.р]fыўжъ_иOd~ЯшСоъј®aЇ_шџЏь?йЕҐт’®рпuн^ЂҐЪNфbюЌTѕгy^г8юдLюю‹\nЕ|јеепЯзШЋЏа“Аэ`оэмЅдz<дOџгпoЯЂдд¤і\њхжэ’*¬<Ім@15ЧMC6цЬ—’oЌ8цс O0$‰dRiЁ5ќOh€0ҐV­Wlv•hЅЯ,&“ЕeґцњfWЧнцћ–ПЛu;џчтzA@#БЎҐB±CДDЕEЖFЗGИHЙIКJЛKМLНGїО@РAЈBГMУSФTХUЦVЧWШXDПNР@С#R%Y® ?_ бMваќ `SвОадвзfeћcjжЕkiкaдкоЖнШpqдkЦнlееqEZ?[ Ь"Э$Ю(_aггбeюgg}РЊ1ЛЌџ>s=k‡_…lС&gП_7Љ2ьЧЏcCwрвЙ#DЏ‰Е&>Ф¤тЈFs3N”ёђЯE€/Ещ0OtсEc”±Гђ Q—sФqG{„BВ o$ЕG"‹4тHSјЏЕ‘tтI(Јд H[(¤GJ,іФrKнЁ EИRёsL2ЛњМC™ДСL6ЫtI%W”‡Є“ЮґуNзl2ЧaчҐylDђНWйЃБmєm‘ю‘юµc¦чћЩнЂе№аiО9l‡Ћ—к‡}ющV\Щжµhe.¶hJЭЌжЄCё4пѕ•тБ+qjO/еєtїщ5\М]EХе^7g]€«”x—<{чэчs·Uн+Ѓ7юxдYs|$ИyOюyиЈяlщїљwћCІ/@ нqаѕ{ѕџсЗ7Ў|уI@?эЦgчЯП ~щ/ >hлџЃ эOаїя РА ая€6бЂH` €@.°Ѓ/xа"x@ kmЄ`&Ё‚ ~P! BxA–p'Њ Q@ЪЂ…P Ў(ТEў $@‡рCю:q1€latxДJфб„8DFр€;дaxЕ!ЖР"9рГ&2‘Z”¦ёДЉQ‰W\b‹ИЕА±b,а*¦ПЋИcЗ·G>Ж±~Ђ|`С"м1Ћy¤cЃШF5‘†rјЂСшИH>’ЃR¤©Iт°Ќ„,Ђ%IђЙPЋ…Tф¤#CЩH'†’”Ґ$-OЛ:ѕ°’µ4Я,ыИЛ$¶`•АФЈ.хgHA ’ѓЉґ%(3ЂК5:’”¦Ь@4Ј КFNі–Њьў+±йЖIо2РфЯЕМoВт•а|B )ЩНk’`–Мdџ/;юIМnљ`ћФ¬fsiN ЪpѓЛйDЌBРњї$)*ќЙОВС‹§ФйFazТќЉІ‰HU "»8GМ4¦ја3*LЂжґћЖdM‹W"њљ2Ёс*LwйУHU’н|'5еъР№&u«Lэ¦SйJЙҐB’R•eW·йSoКУ¤€ЕAOKXЕ†•Ґ-ЕеюВJУd” ґјjйшЩXтt±E}"B79ФГRЦґћe+U8юRѕ–цҐ-h+У™ЖQ¶ђЌ¬[w«=‘Nцы|lц»H.rv‡Wх*НЉїҐµё1РЄXБ‡Qлv»ѓФн^ЃЫЭм®6Ґґ%кX9zO™у]ug)“[I>ѕч™=+Zл:Э¬JФ»ЯEн~щ«Rбю—¶з 0XџљЪbцЧїЌoЃK*YьКА—сE.|-,_^"3хЕб}У{ЮАц’“!±‚Ч{ЩО–шАїe0€lа—WЕVо‹{г>єw›JU*05\Gw†4†!YеW]о^¶H>І‘?мЫ%;ЩјOЌЇAwlDчж`6Э,Ґњ`(џ8МIs“•,fю"GщМdN3љхzб _9Лпхс–ѓ,dм№т=m™•‹бд¦ШµЊБR‘(з>·9‡^хbsэжљ•Њ¶dOyьЦ лДL&f`KL$іС‡vt[Ќe«.·Фy­jЏ3-з=ГщЗ\о2;9з8ыТ9дх­блS&WщКЄЦu«у\eу™ХЇЕc ќkSїYПОFuІб4Бmрљ[ёСЃЮґ‘яMп›?|Ю~DlЛnЙў§ьЏї3ћ+nKsgЪЮМv7Јі lҐзыеЕ¦ъУ.с…УЪЄЙЈnцшьа±&ыБ}рЩо:Тщё»ћB¦і»Э^—ъЗ№ЮowУщкqїw№U^wЈ#њЪш ыЦЗћa)ўЛ чvЖѕu_ЫрїшШ1ћnЕsюу§–iЮэд"иЩкX·ьОпиДs–З€Ц<ЕЅ~iЪЛЬ„е5/}_iГNъћї>К[Яы\ч|НМU5ССMzLГд„ї;fUУt§{ю9гO†>»?c№«фа/јшїПХнOщьЧЭ°Юч®эсЈ?юЧU:эУпэр»№ьъЇѕщуПжяУ8 s?б4ШДL@+X@¤|@; T.Ё@ Њ ѓ ЬА+€А@”,AЬ кyл©ЉlA|БКHA 9Ѕ4ЋK°БЇ ”@‡r‡¬и хшоxЏЩђ„iА| чИ &o8ЏdЏ‰@›€YБ:Ѓ¤„,¬„-ФBZщВЬшЌИhBµр И(Ќ њ…",„Ђ€34Џ«Ш ъИ -”БЭ©Y XиBља 0ФБЩ° »аCРH ю2l‡"Cъ(Њ6‹нГР0B;ґВбCНШБ?|M Дt )јЩЉ4¬Џ7<ВІђ€ЂЕGф‰QЊ* В>й±Д>D[¬€@ь‡6\ДсёД€C.D]LD_Ь QT‡]ФЉЇxEX|®ЊZ4ВLЬГ?мЊ0м "LЙPЖ3щД^T‰R\C7фЖU¬ЌhDCf|J„БC|…sмE\¤$,¶xB{„Зad b\ \Ђ@Њ_$BGB‚|G ¬‘ґ‰ЕgdG†lHаIAјtHЉ¬ИЮћ[°В+ґHЋмH3БHu”ИИсH’,I,IжЙ‰1I–lI'ЃюИ;ДC—њIљМ”ьЃЙљЬIћD‘ITЙлйIЎJ №ЙкJ™$JҐ\К1КЈ(НbJ©њJyLЗ”TИ‰¤J­ЬJwьI¬ФI® K±l «јJЁ\H-qё!Щ™њОСў)™ЏqљµфЃ±Ф‘І™ЛЩЎѕбњ©IљDРЭјBЭSщ[?=ЅУC­S7•T3кЅвѓµє«Ј d [у4ўK1A=DmФQµ?H}¦Кў>EНћOUJ•У>ҐУXµSGЌФYќ;}ЛХЙУ9гЪTБ€4#¶Ъ‚9;®“jUUҐ8л'dФ™K5¬:*WҐєeхЂfќ:Алў»V‘Ы=KTЫ«ЦG­Uг2TК =їлХ¤ ФJ]4АJ­«.–JХ“6«¦ДbУ{›ґЇЄWcW’тWjЅWk]'}Ѕ»QѓХНШr}#ЬВ$H‚ў!Љ(Fн1L{+†‹°тU«Vw%0P]5l%Tk±›ЧбЇqzю0#XtbYтrЩ$ўЧґѓ0фЧg•ЅkШIR'LR(БЉ«љ…ФiЈЅ=УXZWvэШTKXЮ;ШU /[]XbќYnZ»Ѓ«ХЅЦh…1{-Y€ЅVвЦ/ЪZ®•ЎЩ.љЕЪ¤тЩur(€ќЫЪЛЩФ[јkK8¤эҐеФv]©`н4™­[oЕ©™Ґ®az,ґ%Ь®]°q…4і-ШьB-‘}YЁ%Фе’ZјXЄ Хі…YЅ’ШРЉЫ‰¬‘µ[sЅ“Л\]Э[иЫ_V§m&jтЬУ-\ЗќЄЙu«ќ•VР%7ЫЪаR\ У/НMYы3Л/ИХV8Ѕ·µ ZУe\µюTатPю°^·-<ыЭ®‹Ь*r)О ЧЅ[а­ЪзX±-Юд•=њ-ЬМнЮdµЫиZєнЦЖХЮ?5НҐХ_вв?Є=^д]1&_fЯ–]_ДmЯЮEа¬E_R­*к«W]&ъЎДл,зu№‹­±{]юх[эMЫ-2ЬфНЦБќZМЅЩчН_чќTхНЭжЭа>`уЅХ&ЩJeѕђэЅ3ТЦйбяXґЩm>Rуб3ЦтuVoeXћ%ІКЌв]k`*юWЫ}Ь}­an^ОбЁ-`Фэ[Ё \ЪеЧо}]iЇ2юЦркЁШ3Ur5Щ9¶бRХbVXcЬ-ІюЉЕг0fгoVSJгбЅ’1†…c'“ґву6]Ќfdѕ#cЖ[t¤P[№Ѓ‹·UјМл;Ж» ёЅ`ЯEЦ ¦4жЛeБµвJF‰§UдfdЛ[;ЙГЯкэ·јНg}¶eє+ZЗуд=hє#иКжЦЭжћжs{·^[fiѕ#|^h~ѕfЮК$tЖW'¶dЮCbб bБҐгю`cіҐюgЏќЯ>о<Х#>bОЦЂО±_Уд6»<€ЋfЈ»и~i°є™†ж“лд‰6јwCєѓк_gЗCѕxhЉЈ NUu6WЋ>рЕᦶ#жWАй”оик=·ЃГ'г0ѓnZЂЛjЉke–i„^iС“8–гџlЖФіГhm;e“›kЙJj±Ыkј†§џJg•цh¦Ѕj]FcЧ ђnиµЖUЂл»p3ёjfиМ lО:‚гй1Оl№.зRиnлз9+еКЖФ·va›V6ЙFjБЦ¤Ќж-МюhЇ6йK•>^ѕfYhlЧоTLЋлЮv_%Цl…ы6—hЦЫдђЖнВ¶Pjйюж+3mTFn°vкЛn`ћmЉ+  Xµ.4J;мO»н!fмЖЋc@.hZЅcоlY дц~ХлE=U’¦oЮvмЭNoCЅв<®o§цcь¶cэ–cчpщ†бЯaшЮпФ¶ ddА OА 7А зѓ Пѓ·ѓџѓ‡ѓџp3pROсqOЭYGсЯСЕЮЯ1Е(јс.aГHдВq( мАqW ЏЙ8ИaдЗyДЋлшЌQ „B(Мс|%фс{,эJ@}И1LFѓ,F­итй0CE$H||–атги kTуE6Gу`Ьe< AsеЃТu3ПюВЬrqЊуµ8 Ъу(‡ДKt >ПЖ2dуmґЌ-,Д>чB™tоHF‘сOSфпуєpЬйД'ЇGo іиу$фЖ{8u3јq:LtAпGTЏЌH'‹MЧtQ·rKWТ4µ“:ЯGHw @ПБѓ¤уњ EJЇrEзЌHчЌdot1F;пЊєЂvcДB<7Ѕ]зхCoу±PD;rH<ц7”uCOzTц3gvAGt7З‰plGxФЌwOExПђ+ЧuЋЅИSwтz!_чбђtу8ч2·Gк° oтz И"Oш9dxѓ\B°ЂшQGvџdсїtЯx&Ѕw!НwЋщ­фюш(Хs‘?y©$щ<Пv”oyћМхЏy—џщљTylПrљПщ—їцц3yќящ’„щ§q /ъ зyфyЈ_z†ґщћgy¦Џъtъ¤Зy©їzDъл“R¬пzLЧzЋуz±GЄЯzҐ{ґчќІыґo{^ыЁt{№{$ЌH,—щ№Пы2YыёЧ{їЎ_yЁя{ВIё—ЕВO|(б{ДW|ЗЧСГзъЗџ|›¬ыГД{КПьa|ЙЧ|ПЗuЛзСПэJ¬{»ЗwШ%}Х'О?ыХэ iэБ‡}Ъ_Щ·ъЪП}‰|ЧЧ}ЯчЏЫЗьЯюэюФ'~д/~Юџэдюoю= }w~й—г'ъйїюЖЃ~ЌЗ~оП~sI“нп~сoЏеЗэс?яГРю»?~фoWФ·~чџя:ДшЊ ъПя)„яЎ?dэяrТjОъ о'€#9'љЫє/Л3]Ы7ћл;Яы?0(‹ЖЈlЈ1Ґ§H%ER«Ц+6«Эr»Ю/8¦Ф4AР§T^іЫо7<.џПЗдІз\J§ию?` а aбЏ]^ћћ Я‰!d¤д$eҐҐ"‡ўc”гКeЁи(i©йU¦¦b§§гй+l¬м,iк&gз'(-oЇп/°–н&«Ђn0rІт23Лр*лqу4uµuи3^±фW;spectemu-0.94/tapefile.c0100644000175000017500000005017206526331470015506 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This module deals with the different tape file formats (.TAP and .TZX) */ /* 'sptape.c' uses the functions provided by this module. */ #include "tapefile.h" #include "tapef_p.h" #include #include #include #include #include #define max(x, y) ((x) > (y) ? (x) : (y)) #define DESC_LEN 256 char seg_desc[DESC_LEN]; #define TZXMAJPROG 1 #define TZXMINPROG 2 static FILE *tapefp = NULL; static dbyte segi, currsegi; static int segbeg; static int endtype, endnext, endplay; static dbyte endpause; static int finished; static long firstseg_offs; static struct tape_options tapeopt; long tf_segoffs; struct tapeinfo tf_tpi; static dbyte loopctr, loopbeg; static dbyte callctr, callbeg; #define ST_NORM 0 #define ST_PSEQ 1 #define ST_DIRE 2 #define ST_MISC 3 #define PL_NONE 0 #define PL_PAUSE 1 #define PL_LEADER 2 #define PL_DATA 3 #define PL_END 4 #define PL_PSEQ 5 #define PL_DIRE 6 #define IMP_1MS 3500 static dbyte lead_pause; static int playstate = PL_NONE; static int currlev; #define DEF_LEAD_PAUSE 2000 struct seginfo tf_cseg; struct tzxblock { int type; int lenbytes; int lenmul; int hlen; }; #define NUMBLOCKID 0x60 #define NONE 0 #define COMM 1 #define STAN 2 #define RBUFLEN 1024 static byte rbuf[RBUFLEN]; /* Table containing information on TZX blocks */ static struct tzxblock tzxb[NUMBLOCKID] = { { NONE }, /* ID: 00 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, /* ID: 08 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { COMM, 2, 1, 0x04 }, /* ID: 10 */ { COMM, 3, 1, 0x12 }, { COMM, 0, 1, 0x04 }, { COMM, 1, 2, 0x01 }, { COMM, 3, 1, 0x0A }, { COMM, 3, 1, 0x08 }, { NONE }, { NONE }, { NONE }, /* ID: 18 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { COMM, 0, 1, 0x02 }, /* ID: 20 */ { COMM, 1, 1, 0x01 }, { COMM, 0, 1, 0x00 }, { COMM, 0, 1, 0x02 }, { COMM, 0, 1, 0x02 }, { COMM, 0, 1, 0x00 }, { COMM, 2, 2, 0x02 }, { COMM, 0, 1, 0x00 }, { COMM, 2, 1, 0x02 }, /* ID: 28 */ { NONE }, { STAN, 0, 1, 0x00 }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { COMM, 1, 1, 0x01 }, /* ID: 30 */ { COMM, 1, 1, 0x02 }, { COMM, 2, 1, 0x02 }, { COMM, 1, 3, 0x01 }, { COMM, 0, 1, 0x08 }, { COMM, 4, 1, 0x14 }, { NONE }, { NONE }, { NONE }, /* ID: 38 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { COMM, 3, 1, 0x04 }, /* ID: 40 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, /* ID: 48 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, /* ID: 50 */ { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE }, /* ID: 58 */ { NONE }, { COMM, 0, 1, 0x09 }, { NONE }, { NONE }, { NONE }, { NONE }, { NONE } }; #define PTRDIFF(pe, ps) ((int) (((long) (pe) - (long) (ps)) / sizeof(*pe))) static char tzxheader[] = {'Z','X','T','a','p','e','!',0x1A}; static int readbuf(void *ptr, int size, FILE *fp) { return (int) fread(ptr, 1, (size_t) size, tapefp); } static void premature(struct seginfo *csp) { csp->segtype = SEG_ERROR; sprintf(seg_desc, "Premature end of segment"); } static int read_tzx_header(byte *hb, struct seginfo *csp) { int res; int segid, seght; int lenoffs, lenbytes, lenmul, lenadd; int hlen; long length; byte *hip; segid = getc(tapefp); if(segid == EOF) { csp->segtype = SEG_END; sprintf(seg_desc, "End of Tape"); return 0; } hb[0] = (byte) segid; if(segid < NUMBLOCKID) seght = tzxb[segid].type; else seght = NONE; if(seght == COMM) { lenbytes = tzxb[segid].lenbytes; lenmul = tzxb[segid].lenmul; hlen = tzxb[segid].hlen; lenadd = hlen; lenoffs = hlen - lenbytes; } else { lenoffs = 0x00; lenbytes = 4; lenmul = 1; lenadd = 0x00; hlen = 0x04; } if(seght == STAN) hlen += tzxb[segid].hlen; hip = hb+1; res = readbuf(hip, hlen, tapefp); if(res != hlen) { premature(csp); return 0; } length = 0; for(;lenbytes; lenbytes--) length = (length << 8) + hip[lenoffs + lenbytes - 1]; length = (length * lenmul) + lenadd - hlen; csp->len = length; return 1; } static int read_tap_header(byte *hb, struct seginfo *csp) { int res; res = readbuf(hb, 2, tapefp); if(res < 2) { if(res == 0) { csp->segtype = SEG_END; sprintf(seg_desc, "End of Tape"); } else premature(csp); return 0; } csp->len = DBYTE(hb, 0); return 1; } static int read_header(byte *hb, struct seginfo *csp) { segbeg = 0; csp->ptr = 0; csp->segtype = SEG_OTHER; if(tf_tpi.type == TAP_TAP) return read_tap_header(hb, csp); else if(tf_tpi.type == TAP_TZX) return read_tzx_header(hb, csp); return 0; } static void isbeg(void) { segbeg = 1; tf_cseg.len = tf_cseg.ptr = 0; } static int end_seg(struct seginfo *csp) { if(!segbeg) { if(csp->len != csp->ptr) { fseek(tapefp, tf_cseg.len - tf_cseg.ptr - 1, SEEK_CUR); if(getc(tapefp) == EOF) { premature(csp); return 0; } } segi++; isbeg(); } playstate = PL_NONE; return 1; } static int jump_to_segment(int newsegi, struct seginfo *csp) { if(newsegi <= segi) { segi = 0; isbeg(); fseek(tapefp, firstseg_offs, SEEK_SET); } else if(!end_seg(csp)) return 0; while(segi != newsegi) { if(!read_header(rbuf, csp)) return 0; if(!end_seg(csp)) return 0; } return 1; } static int next_data(void) { int res; if(tf_cseg.ptr == tf_cseg.len) return DAT_END; res = getc(tapefp); if(res == EOF) { sprintf(seg_desc, "Premature end of segment"); return DAT_ERR; } tf_cseg.ptr++; return res; } static void normal_segment(struct seginfo *csp) { sprintf(seg_desc, "Data"); csp->type = ST_NORM; csp->segtype = SEG_DATA; csp->pulse = 2168; /* 2016 */ csp->num = 3220; csp->sync1p = 667; csp->sync2p = 735; csp->zerop = 855; /* 672 */ csp->onep = 1710; /* 1568 */ csp->bused = 8; } static int interpret_tzx_header(byte *hb, struct seginfo *csp) { int res; int segid; byte *hip; int offs; dbyte dtmp; segid = hb[0]; hip = hb+1; switch(segid) { case 0x10: normal_segment(csp); csp->pause = DBYTE(hip, 0x00); break; case 0x11: sprintf(seg_desc, "Turbo Data"); csp->type = ST_NORM; csp->segtype = SEG_DATA_TURBO; csp->pulse = DBYTE(hip, 0x00); csp->sync1p = DBYTE(hip, 0x02); csp->sync2p = DBYTE(hip, 0x04); csp->zerop = DBYTE(hip, 0x06); csp->onep = DBYTE(hip, 0x08); csp->num = DBYTE(hip, 0x0A); csp->bused = BYTE(hip, 0x0C); csp->pause = DBYTE(hip, 0x0D); break; case 0x12: sprintf(seg_desc, "Pure Tone"); csp->type = ST_NORM; csp->segtype = SEG_OTHER; csp->pulse = DBYTE(hip, 0x00); csp->num = DBYTE(hip, 0x02); csp->sync1p = 0; csp->sync2p = 0; csp->zerop = 0; csp->onep = 0; csp->bused = 0; csp->pause = 0; break; case 0x13: sprintf(seg_desc, "Pulse Sequence"); csp->type = ST_PSEQ; csp->segtype = SEG_OTHER; csp->pause = 0; break; case 0x14: sprintf(seg_desc, "Pure Data"); csp->type = ST_NORM; csp->segtype = SEG_DATA_PURE; csp->zerop = DBYTE(hip, 0x00); csp->onep = DBYTE(hip, 0x02); csp->bused = BYTE(hip, 0x04); csp->pause = DBYTE(hip, 0x05); csp->pulse = 0; csp->num = 0; csp->sync1p = 0; csp->sync2p = 0; break; case 0x15: sprintf(seg_desc, "Direct Recording"); csp->type = ST_DIRE; csp->segtype = SEG_OTHER; csp->pulse = DBYTE(hip, 0x00); csp->pause = DBYTE(hip, 0x02); csp->bused = BYTE(hip, 0x04); break; case 0x20: dtmp = DBYTE(hip, 0x00); if(dtmp == 0) { if(!tapeopt.stoppause) { csp->type = ST_MISC; csp->segtype = SEG_STOP; } else { csp->pause = tapeopt.stoppause * 1000; csp->type = ST_NORM; csp->segtype = SEG_PAUSE; } sprintf(seg_desc, "Stop the Tape Mark"); } else { csp->pause = dtmp; csp->type = ST_NORM; csp->segtype = SEG_PAUSE; sprintf(seg_desc, "Pause for %i.%03is", csp->pause / 1000, csp->pause % 1000); } csp->pulse = 0; csp->num = 0; csp->sync1p = 0; csp->sync2p = 0; csp->zerop = 0; csp->onep = 0; csp->bused = 0; break; case 0x21: csp->type = ST_MISC; csp->segtype = SEG_GRP_BEG; res = readbuf(rbuf, csp->len, tapefp); if(res != (int) csp->len) { premature(csp); return 0; } csp->ptr += csp->len; { int blen; sprintf(seg_desc, "Begin Group: "); blen = (int) strlen(seg_desc); strncpy(seg_desc+blen, (char *) rbuf, (unsigned) csp->len); seg_desc[csp->len + blen] = '\0'; } break; case 0x22: sprintf(seg_desc, "End Group"); csp->type = ST_MISC; csp->segtype = SEG_GRP_END; break; case 0x23: offs = (signed short) DBYTE(hip, 0x00); if(offs == 0) { sprintf(seg_desc, "Infinite loop"); csp->type = ST_MISC; csp->segtype = SEG_STOP; } else { csp->type = ST_MISC; csp->segtype = SEG_SKIP; sprintf(seg_desc, "Jump to %i", segi+offs); jump_to_segment(segi + offs, csp); } break; case 0x24: loopctr = DBYTE(hip, 0x00); sprintf(seg_desc, "Loop %i times", loopctr); loopbeg = segi+1; csp->type = ST_MISC; csp->segtype = SEG_SKIP; break; case 0x25: csp->type = ST_MISC; csp->segtype = SEG_SKIP; if(loopctr) loopctr--; if(loopctr) { jump_to_segment(loopbeg, csp); sprintf(seg_desc, "Loop to: %i", loopbeg); } else sprintf(seg_desc, "Loop End"); break; case 0x26: csp->type = ST_MISC; csp->segtype = SEG_SKIP; dtmp = DBYTE(hip, 0x00); if(callctr < dtmp) { int offset; callbeg = segi; fseek(tapefp, callctr*2, SEEK_CUR); csp->ptr += callctr*2; res = readbuf(rbuf, 2, tapefp); if(res != 2) { premature(csp); return 0; } csp->ptr += 2; offset = (signed short) DBYTE(rbuf, 0x00); sprintf(seg_desc, "Call to %i", segi+offset); jump_to_segment(segi+offset, csp); callctr++; } else { callctr = 0; sprintf(seg_desc, "Call Sequence End"); } break; case 0x27: csp->type = ST_MISC; csp->segtype = SEG_SKIP; sprintf(seg_desc, "Return"); if(callctr > 0) jump_to_segment(callbeg, csp); break; case 0x28: sprintf(seg_desc, "Selection (Not yet supported)"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; break; case 0x2A: if(tapeopt.machine == MACHINE_48) { sprintf(seg_desc, "Stop the Tape in 48k Mode (Stopped)"); csp->type = ST_MISC; csp->segtype = SEG_STOP; } else { sprintf(seg_desc, "Stop the Tape in 48k Mode (Not Stopped)"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; } break; case 0x31: case 0x30: csp->type = ST_MISC; csp->segtype = SEG_SKIP; res = readbuf(rbuf, csp->len, tapefp); if(res != (int) csp->len) { premature(csp); return 0; } csp->ptr += csp->len; strncpy(seg_desc, (char *) rbuf, (unsigned) csp->len); seg_desc[csp->len] = '\0'; break; case 0x32: csp->type = ST_MISC; csp->segtype = SEG_SKIP; { int numstr, i; i = 0; numstr = next_data(); for(;numstr > 0; numstr--) { int tlen, tid, b; tid = next_data(); tlen = next_data(); if(tid < 0 || tlen < 0) return 0; for(; tlen; tlen--) { b = next_data(); if(b < 0) return 0; seg_desc[i++] = b; } seg_desc[i++] = '\n'; } seg_desc[i] = '\0'; } break; case 0x33: sprintf(seg_desc, "Hardware Information (Not yet supported)"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; break; case 0x34: sprintf(seg_desc, "Emulation Information (Not yet supported)"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; break; case 0x35: sprintf(seg_desc, "Custom Information (Not yet supported)"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; break; case 0x40: sprintf(seg_desc, "Snapshot (Not yet supported)"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; break; case 0x5A: sprintf(seg_desc, "Tapefile Concatenation Point"); csp->type = ST_MISC; csp->segtype = SEG_SKIP; default: csp->type = ST_MISC; csp->segtype = SEG_SKIP; sprintf(seg_desc, "Unknown TZX block (id: %02X, version: %i.%02i)", segid, tf_tpi.tzxmajver, tf_tpi.tzxminver); break; } return 1; } static int interpret_header(byte *hb, struct seginfo *csp) { if(tf_tpi.type == TAP_TAP) { normal_segment(csp); csp->pause = DEF_LEAD_PAUSE; return 1; } else if(tf_tpi.type == TAP_TZX) return interpret_tzx_header(hb, csp); return 0; } byte *tf_get_block(int i) { seg_desc[0] = '\0'; if(jump_to_segment(i, &tf_cseg)) { tf_segoffs = ftell(tapefp); if(read_header(rbuf, &tf_cseg) && interpret_header(rbuf, &tf_cseg)) return rbuf; } return NULL; } int next_byte(void) { playstate = PL_NONE; return next_data(); } #define DPULSE(v1,v2) (*impbuf++=(v1), *impbuf++=(v2), timelen-=(v1)+(v2)) #define PULSE(v) (*impbuf++=(v), currlev = !currlev, timelen-=(v)) int next_imps(unsigned short *impbuf, int buflen, long timelen) { static int toput; static int bitrem; static dbyte dirpulse; unsigned short *impbufend, *impbufstart; impbufstart = impbuf; impbufend = impbuf + buflen; while(impbuf < impbufend - 1 && timelen > 0) { switch(playstate) { case PL_PAUSE: if(currlev && lead_pause) { PULSE(IMP_1MS); lead_pause --; } else if(lead_pause > 10) { if(tapeopt.blanknoise && !(rand() % 64)) DPULSE(IMP_1MS * 10 - 1000, 1000); else DPULSE(IMP_1MS * 10, 0); lead_pause -= 10; } else if(lead_pause) { DPULSE(IMP_1MS, 0); lead_pause --; } else { if(tf_cseg.num || tf_cseg.sync1p || tf_cseg.sync2p || tf_cseg.ptr != tf_cseg.len) finished = 0; switch (tf_cseg.type) { case ST_NORM: playstate = PL_LEADER; break; case ST_DIRE: playstate = PL_DIRE; dirpulse = 0; break; case ST_PSEQ: playstate = PL_PSEQ; break; default: playstate = PL_NONE; } } break; case PL_LEADER: if(tf_cseg.num >= 2) { DPULSE(tf_cseg.pulse, tf_cseg.pulse); tf_cseg.num -= 2; } else if(tf_cseg.num) { PULSE(tf_cseg.pulse); tf_cseg.num --; } else { /* PL_SYNC */ if(tf_cseg.sync1p || tf_cseg.sync2p) DPULSE(tf_cseg.sync1p, tf_cseg.sync2p); bitrem = 0; playstate = PL_DATA; } break; case PL_DATA: if(!bitrem) { toput = next_data(); if(toput < 0) { playstate = PL_END; break; } if(tf_cseg.ptr != tf_cseg.len) { if(timelen > 16 * max(tf_cseg.onep, tf_cseg.zerop) && impbuf <= impbufend - 16) { int p1, p2, br, tp; p1 = tf_cseg.onep; p2 = tf_cseg.zerop; br = 8; tp = toput; while(br) { if(tp & 0x80) DPULSE(p1, p1); else DPULSE(p2, p2); br--; tp <<= 1; } bitrem = 0; break; } bitrem = 8; } else { bitrem = tf_cseg.bused; if(!bitrem) break; } } if(toput & 0x80) DPULSE(tf_cseg.onep, tf_cseg.onep); else DPULSE(tf_cseg.zerop, tf_cseg.zerop); bitrem--, toput <<= 1; break; case PL_PSEQ: { int b1, b2; dbyte pulse1, pulse2; b1 = next_data(); b2 = next_data(); if(b1 < 0 || b2 < 0) { playstate = PL_END; break; } pulse1 = b1 + (b2 << 8); b1 = next_data(); b2 = next_data(); if(b1 < 0 || b2 < 0) { PULSE(pulse1); playstate = PL_END; break; } pulse2 = b1 + (b2 << 8); DPULSE(pulse1, pulse2); } break; case PL_DIRE: for(;;) { if(!bitrem) { toput = next_data(); if(toput < 0) { playstate = PL_END; DPULSE(dirpulse, 0); break; } if(tf_cseg.ptr != tf_cseg.len) bitrem = 8; else { bitrem = tf_cseg.bused; if(!bitrem) break; } } bitrem--; toput <<= 1; if(((toput & 0x0100) ^ (currlev ? 0x0100 : 0x00))) { PULSE(dirpulse); dirpulse = tf_cseg.pulse; break; } dirpulse += tf_cseg.pulse; if(dirpulse >= 0x8000) { DPULSE(dirpulse, 0); dirpulse = 0; break; } } break; case PL_END: if(tf_cseg.pause) { PULSE(IMP_1MS); tf_cseg.pause--; if(currlev) PULSE(0); finished = 1; } playstate = PL_NONE; break; case PL_NONE: default: return PTRDIFF(impbuf, impbufstart); } } return PTRDIFF(impbuf, impbufstart); } int next_segment(void) { if(endnext) { endnext = 0; tf_cseg.segtype = endtype; tf_cseg.pause = endpause; playstate = endplay; return tf_cseg.segtype; } seg_desc[0] = '\0'; lead_pause = tf_cseg.pause; if(end_seg(&tf_cseg)) { currsegi = segi; if(read_header(rbuf, &tf_cseg)) interpret_header(rbuf, &tf_cseg); } if(tf_cseg.segtype >= SEG_DATA) { playstate = PL_PAUSE; if(lead_pause) finished = 1; } else playstate = PL_NONE; if(tf_cseg.segtype <= SEG_STOP && !finished) { endnext = 1; endtype = tf_cseg.segtype; endpause = tf_cseg.pause; endplay = playstate; if(lead_pause > 0) lead_pause--; tf_cseg.pause = 1; tf_cseg.segtype = SEG_VIRTUAL; playstate = PL_END; } return tf_cseg.segtype; } int goto_segment(int at_seg) { int res; res = jump_to_segment(at_seg, &tf_cseg); tf_cseg.pause = DEF_LEAD_PAUSE; return res; } unsigned segment_pos(void) { return currsegi; } void close_tapefile(void) { if(tapefp != NULL) { playstate = PL_NONE; fclose(tapefp); tapefp = NULL; } } int open_tapefile(char *name, int type) { int res; int ok; seg_desc[0] = '\0'; currlev = 0; if(type != TAP_TAP && type != TAP_TZX) { sprintf(seg_desc, "Illegal tape type"); return 0; } tapefp = fopen(name, "rb"); if(tapefp == NULL) { sprintf(seg_desc, "Could not open `%s': %s", name, strerror(errno)); return 0; } tf_tpi.type = type; tf_cseg.pause = DEF_LEAD_PAUSE; INITTAPEOPT(tapeopt); currsegi = segi = 0; isbeg(); firstseg_offs = 0; ok = 1; if(tf_tpi.type == TAP_TZX) { firstseg_offs = 10; res = readbuf(rbuf, 10, tapefp); if(res == 10 && strncmp((char *)rbuf, tzxheader, 8) == 0) { tf_tpi.tzxmajver = rbuf[8]; tf_tpi.tzxminver = rbuf[9]; if(tf_tpi.tzxmajver > TZXMAJPROG) { sprintf(seg_desc, "Cannot handle TZX file version (%i.%02i)", tf_tpi.tzxmajver, tf_tpi.tzxminver); ok = 0; } } else { sprintf(seg_desc, "Illegal TZX file header"); ok = 0; } } if(!ok) { close_tapefile(); return 0; } endnext = 0; loopctr = 0; callctr = 0; return 1; } int get_level(void) { return currlev; } long get_seglen(void) { return tf_cseg.len; } long get_segpos(void) { return tf_cseg.ptr; } void set_tapefile_options(struct tape_options *to) { memcpy(&tapeopt, to, sizeof(tapeopt)); } spectemu-0.94/tapefile.h0100644000175000017500000000403606505020713015501 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef TAPEFILE_H #define TAPEFILE_H #define DAT_ERR -2 #define DAT_END -1 #define SEG_ERROR -1 #define SEG_END 0 /* ^--- End of tape */ #define SEG_STOP 1 #define SEG_SKIP 2 #define SEG_GRP_BEG 3 #define SEG_GRP_END 4 #define SEG_DATA 10 #define SEG_DATA_TURBO 11 #define SEG_DATA_PURE 12 #define SEG_PAUSE 20 #define SEG_OTHER 21 #define SEG_VIRTUAL 30 #define TAP_TAP 0 #define TAP_TZX 1 #define MACHINE_48 0 #define MACHINE_128 1 struct tape_options { int blanknoise; int stoppause; int machine; }; #define INITTAPEOPT(to) \ (to).blanknoise=0, \ (to).stoppause=0, \ (to).machine=MACHINE_48 extern char seg_desc[]; #ifdef __cplusplus extern "C" { #endif extern int open_tapefile(char *name, int type); extern void close_tapefile(void); extern int goto_segment(int at_seg); extern int next_segment(void); extern int next_byte(void); extern int next_imps(unsigned short *impbuf, int buflen, long timelen); extern void set_tapefile_options(struct tape_options *to); extern int get_level(void); extern long get_seglen(void); extern long get_segpos(void); extern unsigned segment_pos(void); #ifdef __cplusplus } #endif #endif /* TAPEFILE_H */ spectemu-0.94/interf.c0100644000175000017500000000514606525576630015215 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include "interf.h" #include #include #define MAXMSGLEN 2048 char filenamebuf[MAXFILENAME]; char msgbuf[MAXMSGLEN]; int spif_can_print = 1; #ifdef HAVE_READLINE #include #include static char *get_filename_line(void) { static char *buf=NULL; static char empty='\0'; free(buf); return ((buf=readline(&empty)) ? buf : &empty); } #else /* HAVE_READLINE */ static char *get_filename_line(void) { static char buf[MAXFILENAME]; fgets(buf, MAXFILENAME, stdin); buf[MAXFILENAME-1] = '\0'; return buf; } #endif /* HAVE_READLINE */ char *spif_get_filename(void) { char *name, *s; s = get_filename_line(); for(; *s && isspace((int) *s); s++); name = s; for(; *s && isgraph((int) *s); s++); *s = '\0'; if(name == s) { printf("Canceled!\n"); return NULL; } return name; } char *spif_get_tape_fileinfo(int *startp, int *nump) { char *name, *s; int res; s = get_filename_line(); for(; *s && isspace((int) *s); s++); name = s; for(; *s && isgraph((int) *s); s++); if(name != s) res = 1; else res = 0; if(*s) { *s = '\0'; s++; if(*s) { int r1; r1 = sscanf(s, "%d %d", startp, nump); if(r1 > 0) res += r1; } } if(res < 1) { printf("Canceled!\n"); return NULL; } if(res < 2) *startp = -1; if(res < 3) *nump = -1; return name; } static int prevtmp = 0; static void clear_line(void) { if(prevtmp) { prevtmp = 0; fprintf(stderr, " \r"); } } void put_msg(const char *msg) { if(spif_can_print) { clear_line(); fprintf(stderr, "%s\n", msg); } } void put_tmp_msg(const char *msg) { if(spif_can_print) { clear_line(); fprintf(stderr, "%s\r", msg); prevtmp = 1; } } spectemu-0.94/interf.h0100644000175000017500000000217306525576630015217 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef INTERF_H #define INTERF_H #define MAXFILENAME 1024 extern char filenamebuf[]; extern char msgbuf[]; extern int spif_can_print; extern char *spif_get_filename(void); extern char *spif_get_tape_fileinfo(int *startp, int *nump); extern void put_msg(const char *msg); extern void put_tmp_msg(const char *msg); #endif /* INTERF_H */ spectemu-0.94/misc.h0100644000175000017500000000250506526044530014650 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef MISC_H #define MISC_H #include extern char *get_base_name(char *fname); extern int check_ext(const char *filename, const char *ext); extern void add_extension(char *filename, const char *ext); extern int file_exist(const char *filename); extern int try_extension(char *filename, const char *ext); extern void *malloc_err(size_t size); extern char *make_string(char *ostr, const char *nstr); extern void free_string(char *ostr); extern int mis_strcasecmp(const char *s1, const char *s2); #endif /* MISC_H */ spectemu-0.94/tapeout.c0100644000175000017500000001055306505741243015375 0ustar cjwatsoncjwatson/* * Copyright (C) 1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #ifdef HAVE_CONFIG_H # include "config.h" # if !defined(HAVE_SOUND) || !defined(OSS_SOUND) # define NO_SOUNDCARD # endif #endif #ifndef NO_SOUNDCARD #include #include #define SOUND_DEV_NAME "/dev/dsp" #else #define SOUND_DEV_NAME "tape.out" #endif #include "tapefile.h" #include "misc.h" #define SBUFSIZE 1024 #define IMPBUFLEN 1024 #define LOWLEV 64 #define HIGLEV 192 #define LEVDIFF (HIGLEV - LOWLEV) typedef unsigned short dbyte; typedef unsigned char byte; static void record_tapefile(int snd, int plen) { static char soundbuf[SBUFSIZE]; static dbyte impbuf[IMPBUFLEN]; int i; long impsum; int impbufrem; int currlev; int osum; int segtype; int segctr; dbyte impl; dbyte *ibp = 0; impsum = 0; impbufrem = 0; currlev = 1; osum = 0; do { for(i = 0; i < SBUFSIZE; i++) { while(impsum < plen) { while(!impbufrem) { impbufrem = next_imps(impbuf, IMPBUFLEN, plen * (SBUFSIZE - i)); if(!impbufrem) { segtype = next_segment(); segctr = segment_pos(); if(segtype != SEG_VIRTUAL) printf("%4i: %s\n", segctr, seg_desc); if(segtype <= SEG_END) { write(snd, soundbuf, (unsigned) i); return; } } else ibp = impbuf; } currlev = !currlev; impl = *ibp; if(currlev) osum += impl; impsum += impl; ibp++; impbufrem--; } impsum -= plen; if(currlev) osum -= impsum; soundbuf[i] = (osum * LEVDIFF) / plen + LOWLEV; if(currlev) osum = impsum; else osum = 0; } write(snd, soundbuf, SBUFSIZE); } while(1); } int main(int argc, char *argv[]) { int snd; int res; int sound_sample_rate; int start_block; const char *sound_dev_name = SOUND_DEV_NAME; char *tapefile; int type; struct tape_options tapeopt; if(argc < 3) { fprintf(stderr, "usage: %s sample_rate tapefile [start_block [output_file]]\n", argv[0]); exit(1); } sound_sample_rate = atoi(argv[1]); tapefile = argv[2]; start_block = 0; if(argc > 3) start_block = atoi(argv[3]); if(argc > 4) sound_dev_name = argv[4]; snd = open(sound_dev_name, O_WRONLY | O_CREAT, 0644); if(snd < 0) { fprintf(stderr, "Could not open sound device '%s': %s\n", sound_dev_name, strerror(errno)); exit(1); } #ifndef NO_SOUNDCARD { int parm; parm = sound_sample_rate; res = ioctl(snd,SOUND_PCM_WRITE_RATE,&parm); if(res < 0) fprintf(stderr, "ioctl(SOUND_PCM_WRITE_RATE, %i) failed: %s\n", sound_sample_rate, strerror(errno)); sound_sample_rate = parm; res = ioctl(snd,SOUND_PCM_SYNC,0); if(res < 0) fprintf(stderr, "ioctl(SOUND_PCM_WRITE_SYNC, 0) failed: %s\n", strerror(errno)); } #endif if(check_ext(tapefile, "tap")) type = TAP_TAP; else if(check_ext(tapefile, "tzx")) type = TAP_TZX; else { fprintf(stderr, "tapefile must have either '.tap' or '.tzx' extension\n"); exit(1); } res = open_tapefile(tapefile, type); if(!res) { fprintf(stderr, "%s\n", seg_desc); exit(1); } INITTAPEOPT(tapeopt); tapeopt.blanknoise = 0; tapeopt.stoppause = 5; set_tapefile_options(&tapeopt); if(start_block) { res = goto_segment(start_block); if(!res) { fprintf(stderr, "Could not jump to block %i: %s\n", start_block, seg_desc); exit(1); } } fprintf(stderr, "Recording `%s' to audio output at %i sample rate\n", tapefile, sound_sample_rate); record_tapefile(snd, 3500000 / sound_sample_rate); return 0; } spectemu-0.94/tapeout.10100644000175000017500000000357006527773367015334 0ustar cjwatsoncjwatson.TH Tapeout 1 "17 March 1998" "Version 0.94" .SH NAME tapeout \- Output tapefiles to real tape .SH SYNOPSIS .B tapeout .I sample_rate .I tapefile .RI [ start_block .RI [ output_file ]] .SH DESCRIPTION This program lets you copy a tapefile ( .I .tap or .I .tzx ) to real tape via soundcard. .PP You have to connect the soundcard's .B line out socket with the tape recorder's .B mic socket, then start this program. .SH OPERANDS .TP .B sample_rate Sampling rate for the output. The higher this is, the better quality the the result will be. It should be at least 16000. .TP .B tapefile Name of the tape file to interpret, and output to the soundcard. It should have either .I .tap or .I .tzx extension. .TP .B start_block Specifies where to start playing the tapefile. Default is 0. .TP .B output_file If given, the program writes the sound output into this file instead of the soundcard. .SH SEE ALSO xspect (1), vgaspect (1) .PP http://www.inf.bme.hu/~mszeredi/spectemu/spectemu.html .SH BUGS Many parameters are not changeable (like pause between tape blocks). .PP Not interactive (except for Ctrl\-c). .SH AUTHOR Miklos Szeredi (EMAIL: mszeredi@inf.bme.hu) .PP Tapeout is copyright (C) 1998 Miklos Szeredi .PP 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. See the file COPYING. .PP 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. .PP 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., 675 Mass Ave, Cambridge, MA 02139, USA. spectemu-0.94/xspect.10100644000175000017500000000503006527775101015136 0ustar cjwatsoncjwatson.TH Spectemu 1 "18 May 1998" "Version 0.94" .SH NAME xspect, vgaspect \- ZX Spectrum emulator .SH SYNOPSIS .B xspect .RI [ options ] .RI [[ filetype ] .IR filename ] .PP .B vgaspect .RI [ options ] .RI [[ filetype ] .IR filename ] .SH DESCRIPTION Spectemu is a 48k Sinclair ZX Spectrum emulator for Linux and other UNIX operating systems. .PP The program .I xspect can be started in X11, and opens up a window to display the screen of the Spectrum. Do not start .I xspect in the background, because it uses the terminal to read filenames, and to print information on the state of the emulator. .PP The .I vgaspect program can only be started on a Linux console, and uses the SVGALIB library. On non linux systems this program is not available. .SH OPERANDS For both .I xspect and .I vgaspect a snapshot file or a tape file can be specified on the command line. The file can have the extension .I .z80 , .I .sna , .I .tap or .I .tzx (the extension can be ommitted). .PP The option .I -help displays a list of available options. For a more complete list, and description see the file README. .PP For .I xspect The following options also have meaning: .TP .B \-display DISPLAYNAME Open the window on DISPLAYNAME instead of the default .TP .B \-name WINDOWNAME Change the title of the window to WINDOWNAME .SH KEYS You can press Ctrl\-H to get help on what keys to use. .PP For more information on the features available in Spectemu see the file README distributed with the emulator. .SH SEE ALSO tapeout(1) .PP http://www.inf.bme.hu/~mszeredi/spectemu/spectemu.html .SH BUGS I try to keep nasty bugs like "Segmentation Fault" out of Spectemu, so if you notice one, STEP ON IT! There are some cuter and gentler bugs, which are kept in Spectemu to amuse the user (see TODO). .SH AUTHOR Miklos Szeredi (EMAIL: mszeredi@inf.bme.hu) .PP Spectemu is copyright (C) 1996\-1998 Miklos Szeredi .PP 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. See the file COPYING. .PP 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. .PP 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., 675 Mass Ave, Cambridge, MA 02139, USA. spectemu-0.94/tapef_p.h0100644000175000017500000000261606507001305015326 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef TAPEF_P_H #define TAPEF_P_H typedef unsigned char byte; typedef unsigned short dbyte; typedef unsigned long qbyte; #define BYTE(arr, i) (arr[i]) #define DBYTE(arr, i) (arr[i] + (arr[(i)+1] << 8)) struct tapeinfo { int type; int tzxminver, tzxmajver; }; struct seginfo { int type; int segtype; dbyte pulse; dbyte num; dbyte sync1p; dbyte sync2p; dbyte zerop; dbyte onep; dbyte pause; byte bused; long len; long ptr; }; extern struct tapeinfo tf_tpi; extern struct seginfo tf_cseg; extern long tf_segoffs; extern byte *tf_get_block(int i); #endif /* TAPEF_P_H */ spectemu-0.94/utils/0042755000175000017500000000000006517407010014703 5ustar cjwatsoncjwatsonspectemu-0.94/utils/Makefile0100644000175000017500000000044706517407133016351 0ustar cjwatsoncjwatsonCC=gcc CXX=gcc FLAGS=-Wall CPPFLAGS= CFLAGS=$(FLAGS) CXXFLAGS=$(FLAGS) PROGS=filt spload spt2tap tap2spt taplist recs tzxlist all: $(PROGS) tzxlist_objs=tzxlist.o tapefile.o tzxlist: $(tzxlist_objs) $(CC) $(CFLAGS) $(LDFLAGS) -o tzxlist $(tzxlist_objs) clean: rm -f *.o rm -f $(PROGS) spectemu-0.94/utils/filt.c0100644000175000017500000000107006214777722016014 0ustar cjwatsoncjwatson#include int main(int argc, char *argv[]) { FILE *in = stdin; FILE *out = stdout; double av = 0.0; double ex = 0.33; double ex_i = 1.0 - ex; double avu = 0.0; double exu = 0.50; double exu_i = 1.0 - exu; int c; double v; while((c = getc(in)) != EOF) { v = (double) c - 128.0; avu = (avu * exu_i) + (v * exu); av = (av * ex_i) + (v * ex); if(argc < 2) { if(avu - av < 0) putc(64, out); else putc(-64, out); } else { putc((int) ((avu - av) * 5.0) + 128, out); } } return 0; } spectemu-0.94/utils/recs.c0100644000175000017500000000701006245333113015774 0ustar cjwatsoncjwatson#include #include #include #include #include #include #include #ifdef DEBUG_OUTPUT # define DOUT(string) fprintf(stderr, "%s\n", string) #else # define DOUT(string) #endif int init_soundcard(long sample_rate, int sample_size, int channels) { char *devname = "/dev/dsp"; int fd; int parm; int sr; DOUT("Opening the DSP device"); if((fd = open(devname, O_RDONLY)) < 0) { fprintf(stderr, "Could not open device '%s'; %s\n", devname, strerror(errno)); exit(1); } parm=0x0100008; if(ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&parm)>=0) DOUT(" Successful"); else DOUT(" Failed"); DOUT("Resetting the DSP device"); if(ioctl(fd,SOUND_PCM_RESET,0)>=0) DOUT(" Successful"); else DOUT(" Failed"); DOUT("Syncing the DSP device"); if(ioctl(fd,SOUND_PCM_SYNC,0)>=0) DOUT(" Successful"); else DOUT(" Failed"); DOUT("Setting the DSP device bits per sample"); if(ioctl(fd,SOUND_PCM_WRITE_BITS,&sample_size)>=0) DOUT(" Successful"); else DOUT(" Failed"); DOUT("Setting the DSP device number of channels"); if(ioctl(fd,SOUND_PCM_WRITE_CHANNELS,&channels)>=0) DOUT(" Successful"); else DOUT(" Failed"); /* Verify the results */ if((sample_size!=16) && (sample_size!=8)) { fprintf(stderr, "DSP error: returned a sample size of %d bits.\n",sample_size); exit(1); } /* fprintf(stderr, "Sample size: %i\n", sample_size); */ sr = sample_rate; DOUT("Syncing the DSP device"); ioctl(fd,SOUND_PCM_SYNC,0); DOUT("Setting the DSP device sampling rate"); ioctl(fd,SOUND_PCM_WRITE_RATE,&sr); sample_rate=sr; if(sample_rate<1000) { printf("DSP error: returned a sample rate of %ld samples/second.\n", sample_rate); exit(1); } /* fprintf(stderr, "Sample rate: %li\n", sample_rate); */ return fd; } int main(int argc, char *argv[]) { int sample_size = 8; long sample_rate = 8000; int channels = 1; FILE *fp; char *filename; int snd; int to_quit, recordig; int records; int rd; int at; #define BUFSIZE 1024 unsigned char buf[BUFSIZE]; if(argc < 2) { fprintf(stderr, "usage: %s filename [sample_rate] [sample_size]\n", argv[0]); exit(1); } filename = argv[1]; if(strcmp(filename, "-") == 0) fp = stdout; else if((fp = fopen(filename, "wb")) == NULL) { fprintf(stderr, "%s: Could not open `%s', %s\n", argv[0], filename, strerror(errno)); exit(1); } if(argc > 2) { sample_rate = atol(argv[2]); if(sample_rate < 4000 || sample_rate > 41000) { fprintf(stderr, "%s: Illegal sample rate: %s\n", argv[0], argv[2]); exit(1); } } if(argc > 3) { sample_size = atol(argv[3]); if(sample_size != 8 && sample_size != 16) { fprintf(stderr, "%s: Illegal sample size: %s\n", argv[0], argv[3]); exit(1); } } snd = init_soundcard(sample_rate, sample_size, channels); to_quit = 0; recordig = 1; records = 0; /* fprintf(stderr, "\nStart!\n"); */ do { for(at = 0; at < BUFSIZE; at += rd) { rd = read(snd, buf + at, BUFSIZE - at); if(rd < 0) { fprintf(stderr, "\nError on soundcard: %s\n", strerror(errno)); exit(1); } } fwrite(buf, 1, BUFSIZE, fp); records++; /* fprintf(stderr, "records written: %4i \r", records); fflush(stderr); */ } while(!to_quit); /* fprintf(stderr, "\nStop!\n"); */ fclose(fp); return 0; } spectemu-0.94/utils/spconv/0042755000175000017500000000000006507513244016221 5ustar cjwatsoncjwatsonspectemu-0.94/utils/spconv/Makefile0100644000175000017500000000146306430132420017644 0ustar cjwatsoncjwatson# # UNIX Makefile for SPCONV - SPECTRUM SNAPSHOT CONVERTER 1.09 # # Chris Wells # # Called "makefile.unx" under dos, rename to "Makefile" [HDG] #.SILENT: .SUFFIXES: .SUFFIXES: .c .o $(SUFFIXES) CC = gcc CFLAGS = -g \ -ansi \ -pedantic \ -Wall \ -Wwrite-strings \ -Wshadow \ -Wformat \ -Wpointer-arith \ -Wconversion \ -Wstrict-prototypes \ -Wmissing-prototypes \ -I/usr/local/lib/ansi-include NROFF = gnroff -mandoc SRCS = spconv.c OBJS = spconv.o BINARY = spconv DOCS = spconv.doc spconv: $(OBJS) $(CC) $(OBJS) -o $(BINARY) spconv.o: spconv.h clean: rm -f $(OBJS) $(BINARY) $(DOCS) docs: spconv.1 $(NROFF) < spconv.1 > spconv.doc zip: spconv.zip echo "Spconv.zip up to date" spconv.zip: docs zip spconv.zip spconv.doc spconv.1 spconv.h \ spconv.c Makefile history.doc author.doc spectemu-0.94/utils/spconv/author.doc0100644000175000017500000000611206430132420020171 0ustar cjwatsoncjwatsonIn case you wonder who wrote this, well I did. I started it when I worked for Philips (Electronics Company). Our plant was taken over by Digital (Computer Company) so then I was all of a sudden a Digital employe (sorry, it didn't help much for my English I'm afraid). Now I found a new job myself, so now, I now work for Ericsson (Telecom Company). Now Ericsson is Swedish so you can guess what will happen to my English now (ever seen the Swedish cook on the Muppets show... :-) :-) ). Neither Philips nor Digital nor Ericsson have anything to do with this software (the don't even know it exists!), complain to me if you have problems. Note that I can not be forced to do anything about it, so you are just lucky if I will make updates. You can of course modify it yourself, it's not illegal because I made it Public Domain. This means nobody owns it and you can do with it as you see fit. This also means that nobody can be blamed for screwing up your system, not even me! So if you think I hid a nasty HD-formating program in this software than don't use it! If you change something that might be usefull for others please tell me! I may include it in future versions. If you help me in any way than I will put your name in the docs as a reward - unless you don't want it of course! ------------- SKIP the next section if you don't know about PGP ------------- You can always check if the binary is from me using spconv.sig. You need PGP (Pretty Good Privacy version 2 or better) for this, type: 'pgp spconv.sig spconv.exe'. You'll need a trusted public key from me, I have included my public key here but you need a independent key to be sure that I am who I appear to be. You can get my key from various PGP key-servers - info about this is is packed with pgp, pgpshell and pgpfront. If you use PGP you'll probably know about this already. You can also send me a message using this key, I can tell you if this is my key - not secure but better than nothing. By the way I used PGP2.6.i to create these keys. --------- END of SKIP the next section if you don't know about PGP ---------- Please don't ask me to make the converter work for .TAP files, I will not because you need an emulator for that. The Shareware Z80-201.zip or newer will convert .TAP files to .Z80 for you, you can take if from there with this converter to any of the other formats. If you want to E-mail me, my current address is: Henk de Groot, hegr@ensae.ericsson.se If you want to mail me privately use PGP (Pretty Good Privacy from Phil Zimmermann) if it contains material for me only (like snapshots or a message for verification of the public key so you can check spconv.exe with spconv.sig) My public PGP key: -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.i mQBNAizK3zcAAAECANa+YU5JTlRibS0wM3bqtgYpmnHI8377Z8gt1ErRa1zot/2f oa/FG6VVONYDs9s067IzVTU5qYDZmrGVwMaayAEABRG0JkhlbmsgZGUgR3Jvb3Qg PGhlZ3JAZW5zYWUuZXJpY3Nzb24uc2U+tCFIZW5rIGRlIEdyb290IDxncm9vdEBh cGQuZGVjLmNvbT60KUhlbmsgZGUgR3Jvb3QgPGdyb290QGlkY2EudGRzLnBoaWxp cHMubmw+ =U9FR -----END PGP PUBLIC KEY BLOCK----- Good luck with this software! Henk de Groot. spectemu-0.94/utils/spconv/history.doc0100644000175000017500000002045606430132420020377 0ustar cjwatsoncjwatsonRelease date: 15 June 1995 ------------------------------------------------------------------------------- Spconv can now convert .SNX files. These are the eXtended SNApshot files used by one of the Atari ST Spectrum emulators. They contain a header very similar to the SNA format, but use RLE compression on the (48K only) RAM image to obtain a smaller file, much like .Z80 files. Please note: this is not a version released by Henk, but by me, Damien Burke (D.M.Burke-CSSE94@cs.bham.ac.uk or CCS4DMB1@ibm3090.bham.ac.uk). If you have any problems converting to/from .SNX format, don't complain to Henk, complain to me! Release number of spconv updated from 1.08 to 1.09. ------------------------------------------------------------------------------- Release date: 31 may 1995 ------------------------------------------------------------------------------- Spconv can now convert .Z80 files of 3.0 format. Spconv should have warned the user that the .Z80 file had a new format but instead the test failed due to a mistake from me (aka bug). Spconv proceeded as if it was a .Z80 2.01 file. Due to miss-alignment warnings about unhandled and illegal memory banks were given instead. I changed the test. I also made the code dynamic so it will issue a warning about a new .Z80 format but will attempt to convert it anyway. If Gerton sticks to the current scheme it should work in the future (but you have to live with the warning though, unless you patch it out yourself :-) ). Other changes: - I should have removed #include in the cleanup action of 1.07, I forgot it and GCC in pedantic setting gave a warning. I corrected this very important bug :-) Release number of spconv updated from 1.07 to 1.08 ------------------------------------------------------------------------------- Release date: 03 may 1994 ------------------------------------------------------------------------------- This version has a better conversion to .ACH files. Help was given by a sample .sna to .ach converter program and an archimedes snapshot snapped just after startup. Other changes: - Cleanup of code. Make it gcc-pedantic mode proof (thanks Chris Wells). - Inclusion of UNIX make-file (thanks to Chris Wells again). - Inclusion of UNIX style man page (thanks to (guess who...) Chris Wells!). - Make definition of exit-codes clear and consistent. - Add some more comments in the code. - Replace "sizeof" operator by #defines - needed for some environments - Tell about the exit-codes in the documentation. - Rearrange the doc file. Release number of spconv updated from 1.06 to 1.07 ------------------------------------------------------------------------------- Release date: 23 januari 1994 ------------------------------------------------------------------------------- This version will cope with .Z80 files written by Z80-201. The .Z80 format was changed to enable its use for 128K snapshots. Spconv will be able to read and convert this format. The output .Z80 files are in the old format so they can be read by old and new Z80 emulator versions. You can use Spconv also to convert the new-style .Z80 files to the old style so you can use it with your old (probably registered) version of Z80. Spconv will check if the input .Z80 file is for a 48K Spectrum. The code is a little bit reorganized. The number of "if, else if, else if..." began to look rediculous - as if I never heard from 'switch/case'. Well I have and I changed it now. The new .Z80 format forced me to execute read system calls with a low number of bytes. They started to get expensive so I changed everything to file I/O. The Z80 uncompress routine should be faster now because I don't need an intermediate buffer anymore. I still need one for compression so I can output an uncompressed image if the compression actualy expands the file... Maybe I'll change that too in the future and take expansion of worst-case files (files with a lot of '0xed,0xed,0x00' sequences) for granted. Now I hope I didn't break anything... Release number of spconv updated from 1.05 to 1.06 ------------------------------------------------------------------------------- Release date: 10 november 1993 ------------------------------------------------------------------------------- This is a maintenance version. The conversion to/from .zx files should be much better now thanks to info from Peter McGavin. The code is cleaned up, at some places Intel byte-ordering was assumed. Also the use of 'far' pointers are moved into #ifdef __TURBOC__ conditions, compiling under UNIX should not be bothered by it anymore. All functions have prototypes and similar functions are grouped together. The snapshot structures and prototypes are moved to a .h file. Turbo-C++ 1.0 in it's most pedantic mode produces no warnings anymore. I did not split-up the spconv.c file further, I should because its growing to big already but I like building it without needing a Turbo-C project file for Turbo-C's IDE environment. Release number of spconv updated from 1.04 to 1.05 ------------------------------------------------------------------------------- Release date: 17 may 1993 ------------------------------------------------------------------------------- This version can also convert to/from .zx files. These files are used in the KGB emulator for the amiga computer. It's not fool proof, some registers are not found in the KGB snapshot. Release number of spconv updated from 1.03 to 1.04 ------------------------------------------------------------------------------- Release date: 26 february 1993 ------------------------------------------------------------------------------- This version can also convert to/from .ach files. These files are used in an emulator for the archimedes computer. Normaly the files are .arc files but the extension .arc is already used for ARC archives so I used .ach instead. Release number of spconv updated from 1.02 to 1.03 ------------------------------------------------------------------------------- Release date: 14 december 1992 ------------------------------------------------------------------------------- This version can also convert to/from .prg files. These files are used in an Irish emulator. While building it, some ideas came up to enhance the converion to/from .SP files (recognition of IM2). Upgraded call of the program, the program can now take only a suffix as second agrument, the prefix for the first argument is used. This enables easy mass conversion by using a batchfile with a command like: 'for %%i in (*.z80) do spconv %%i .sna' If wildcards are given at the commandline a error is generated. Release number of spconv updated from 1.01 to 1.02 ------------------------------------------------------------------------------- Release date: 13 august 1992 ------------------------------------------------------------------------------- Error discoved in the way IFF was handled for Z80. This bug prevented correct conversion of some programs from .SNA to .Z80. Release number of spconv updated from 1.0 to 1.01 ------------------------------------------------------------------------------- Release date: 10 august 1992 ------------------------------------------------------------------------------- The new SPCONV has a big bug. It will not convert compressed .Z80 files correctly. The program uses JPP format internaly. For JPP the program counter is on the stack. The converter stored the PC in the image *BEFORE* it was de-compressed. This resulted in corrupting other image data. (Converting TO .Z80 works fine). Due to errors I am planning to keep versions more carefully. From now on SPCONV has a release number and a generation date. This will show up if you run SPCONV without arguments. ------------------------------------------------------------------------------- Release date: 5 august 1992 ------------------------------------------------------------------------------- SPCONV : Now handles .Z80 files and new format of .SP. Old format still supported. Bug fixes: General: Clear compilation of all programs under Turbo-C 2.0 Documentation up to date. ------------------------------------------------------------------------------- Release date: ? ???? ???? ------------------------------------------------------------------------------- Initial program to convert between .SNA .SP and RAW. No more history. ------------------------------------------------------------------------------- H. de Groot, hegr@ensae.ericsson.se spectemu-0.94/utils/spconv/spconv.c0100644000175000017500000013147106430132420017663 0ustar cjwatsoncjwatson/* * SPCONV - ZX-Spectrum 48K snapshot converter * * Public Domain software * * Author: Henk de Groot * SNX conversion routines added by Damien Burke (v1.09) */ #if defined(__STDC__) || defined(__TURBOC__) #include #else #include #endif #ifdef __TURBOC__ #include #else #include #endif #include #include #include #include #include #ifdef __TURBOC__ #include #endif #ifndef O_BINARY #define O_BINARY 0 #endif #include "spconv.h" struct snx_s snx; struct sna_s sna; struct vga_s vga; struct z80_s z80; struct prg_s prg; struct ach_s ach; struct kgb_s kgb; /* extra space just in case the Z80 decompress fails due to a corrupt image */ unsigned char image[IMSIZE+0x100]; unsigned int z80_size; signed int intype; signed int outtype; /* Prototype for main */ extern int main(int argc, char *argv[]); /* Path names are limited to 80 characters under MSDOS so this sould be */ /* enough... If you are using UNIX than you may have to make this array */ /* larger. */ char my_directory[120]; int main(int argc, char *argv[]) { char *p; struct stat status; const char *fromstring; const char *tostring; char *outfile; long file_size; #ifdef __TURBOC__ /* for Trubo-C: open all files in binary mode */ extern int _fmode; _fmode = O_BINARY; #endif if(argc != 3) USAG_usage(); if((strchr(argv[1],'*')!=NULL) || (strrchr(argv[1],'?')!=NULL) || (strchr(argv[2],'*')!=NULL) || (strrchr(argv[2],'?')!=NULL)) { fprintf(stderr,"This program can't handle wildcards, sorry!\n"); return EXIT_USAGE; } /* * Find the directory path where this program is started from. * This will be needed for finding the spectrum-rom. Some formats * need the spectrum-rom for proper conversion. */ strcpy(my_directory,argv[0]); if(strrchr(my_directory,'\\')!=NULL) { *strrchr(my_directory,'\\')='\0'; } else if(strrchr(my_directory,'/')!=NULL) { *strrchr(my_directory,'/')='\0'; } else if(strrchr(my_directory,':')!=NULL) { *strrchr(my_directory,':')='\0'; } else { my_directory[0]='\\'; my_directory[1]='\0'; } /* * Check if the input file exists and fetch the file lenght of * the file in the mean time. Two for the prise of one... */ if(stat(argv[1],&status)<0) { perror(argv[1]); return EXIT_FILE_ERROR; } file_size = status.st_size; /* * recognize input type on filename: * * .SNX -> SNX file (used by Atari emulator) * .SNA -> SNA file (used in JPP) * .SP -> SP file (was VGASPEC) * .Z80 -> Z80 file * .PRG -> PRG file * .ACH -> ACH file (from archimedes emulator) * .ZX -> KGB file (from KGB emulator) * other -> if exact 48+header -> raw file * otherwise unknown */ fromstring = DTYP_determine_type(argv[1],&intype); if (intype == UNKNOWN) { if (file_size == (hdr_size+IMSIZE)) { fromstring="RAW"; intype=RAW; } else { fprintf(stderr,"Unknown input file format. Must be a valid .SNX, .SNA, .SP, .Z80, .PRG, .ACH or\n"); fprintf(stderr,".ZX file, or a Raw file\n"); return EXIT_FILE_ERROR; } } /* * recognize output type on filename: * * .SNX -> SNX file * .SNA -> SNA file * .SP -> SP file (was VGASPEC) * .Z80 -> Z80 file * .PRG -> PRG file * .ACH -> ACH file (from archimedes emulator) * .ZX -> KGB file (from KGB emulator) * otherwise unknown */ tostring = DTYP_determine_type(argv[2],&outtype); if(outtype==UNKNOWN) { fprintf(stderr,"Unknown output file format. Must be a .SNX, .SNA, .SP, .Z80, .PRG, .ACH or .ZX file\n"); return EXIT_FILE_ERROR; } /* * if argv[2] only contains the suffix then use the prefix of * argv[1]; */ if(argv[2][0]=='.') { outfile=malloc(strlen(argv[1])+strlen(argv[2])+1); strcpy(outfile,argv[1]); /* copy prefix */ p=strrchr(outfile,'.'); if(p!=NULL) *p='\0'; /* put end of string at position of '.' */ strcat(outfile,argv[2]); /* append suffix */ } else { outfile=malloc(strlen(argv[2])+1); strcpy(outfile,argv[2]); } /* * Special converion between versions of the same type */ if(intype == outtype) return DIRC_direct_convert(intype, argv[1], outfile); /* * General conversion from one type to another */ printf("Converting %s from %s to %s\n",argv[1],fromstring,tostring); /* * convert input_file to SNA */ switch(intype) { case SNX: RSNX_read_snx(argv[1]); SXSN_snx_to_sna(); break; case SNA: if (file_size == (sna_size+IMSIZE)) { RSNA_read_sna(argv[1]); } break; case SP: if ((file_size == (vga_size+IMSIZE))) { RVGA_read_vgaspec(argv[1]); VGSN_vgaspec_to_sna(); } else if ((file_size == (vga_size+IMSIZE-6))) { ROVG_read_old_vgaspec(argv[1]); VGSN_vgaspec_to_sna(); } break; case RAW: RRAW_read_raw(argv[1]); RASN_raw_to_sna(); break; case Z80: RZ80_read_z80(argv[1]); Z8SN_z80_to_sna(); break; case PRG: if(file_size != (prg_size+IMSIZE)) { printf("Warning: the image part of %s is not exactly 48k!\n",argv[1]); printf(" Converting anyway, the converted file may not work\n"); } RPRG_read_prg(argv[1]); PRSN_prg_to_sna(); break; case ACH: if(file_size == (ach_size+16384L+IMSIZE)) { RACH_read_ach(argv[1]); ACSN_ach_to_sna(); } break; case KGB: if(file_size == (132L+IMSIZE+kgb_size)) { RKGB_read_kgb(argv[1]); KGSN_kgb_to_sna(); } break; default: printf("Unrecognized input file type, can't convert\n"); return EXIT_FILE_ERROR; } /* * convert internal SNA format to output file */ switch(outtype) { case SNX: SNSX_sna_to_snx(); WSNX_write_snx(outfile); break; case SNA: WSNA_write_sna(outfile); break; case SP: SNVG_sna_to_vgaspec(); WVGA_write_vgaspec(outfile); break; case Z80: SNZ8_sna_to_z80(); WZ80_write_z80(outfile); break; case PRG: SNPR_sna_to_prg(outfile); WPRG_write_prg(outfile); break; case ACH: SNAC_sna_to_ach(); WACH_write_ach(outfile); break; case KGB: SNKG_sna_to_kgb(); WKGB_write_kgb(outfile); break; default: printf("Unrecognized output file type, can't convert\n"); return EXIT_FILE_ERROR; } /* * That's it, simple isn't it? */ return EXIT_OK; } /* SPECIAL FUNCTIONS */ /* Determine file type and return both type and type-name */ const char * DTYP_determine_type(char * filename, signed int * type) { const char *p; char ext[5]; signed int i; /* * recognize type on filename: * * .SNX -> SNX file * .SNA -> SNA file * .SP -> SP file (was VGASPEC) * .Z80 -> Z80 file * .PRG -> PRG file * .ACH -> ACH file (from archimedes emulator) * .ZX -> KGB file (from KGB emulator) * otherwise unknown */ *type=UNKNOWN; /* default if all ifs below fail */ p=strrchr(filename,'.'); if(p==NULL) p=filename; /* not found, set at begin of string */ /* Take extension and convert to uppercase */ for(i = 0; i < 4; i++) { if(*p != '\0') { ext[i] = toupper(*p); p++; } else { ext[i] = '\0'; } } ext[4] = '\0'; /* termination at least on the fifth char */ if(strcmp(ext,".SNX")==0) { *type=SNX; return ".SNX"; } if(strcmp(ext,".SNA")==0) { *type=SNA; return ".SNA"; } if(strcmp(ext,".Z80")==0) { *type=Z80; return ".Z80"; } if(strcmp(ext,".SP")==0) { *type=SP; return ".SP"; } if(strcmp(ext,".PRG")==0) { *type=PRG; return ".PRG"; } if(strcmp(ext,".ACH")==0) { *type=ACH; return ".ACH"; } if(strcmp(ext,".ZX")==0) { *type=KGB; return ".ZX"; } /* unknown type, return question-mark */ return "?"; } /* Special converion between versions of the same type */ signed int DIRC_direct_convert(signed int type, char * infile, char * outfile) { struct stat status; signed long file_size; /* * Special conversion between versions of the same type. * These conversion don't use the intermediate 'sna' format * to preserve as much information as possible. * * This currently only applies to .SP and the .Z80 formats. * * The .SP formats will convert from the New to the Old format or * from the Old to the New format, controled by the current format * of the input. * * The .Z80 formats will convert to the version 1.45 .Z80 format * since version 1.45 .Z80 files can be read by both old and new * Z80-emulators. */ /* check if it is for the SP format */ if(type == SP) { if(stat(infile,&status)<0) { perror(infile); return EXIT_FILE_ERROR; } file_size = status.st_size; if((file_size == (vga_size+IMSIZE))) { printf("Converting %s from new .SP format to old .SP format.\n",infile); RVGA_read_vgaspec(infile); WOVG_write_old_vgaspec(outfile); return EXIT_OK; } if((file_size == (vga_size+IMSIZE-6))) { RVGH_read_vgaspec_header(infile); if((vga.S=='S')&&(vga.P=='P')) { fprintf(stderr,"Invalid input file format. This could be a new syle .SP file with\n"); fprintf(stderr,"an image of another length than 48Kb. This kind of .SP files cannot\n"); fprintf(stderr,"be converted. All other file formats (including the old .SP format)\n"); fprintf(stderr,"contain images of 48Kb length.\n"); return EXIT_FILE_ERROR; } printf("Converting %s from old .SP format to new .SP format.\n",infile); ROVG_read_old_vgaspec(infile); /* These values are fixed for a full 48K .SP file */ vga.S='S'; vga.P='P'; vga.len_l=0x00; vga.len_h=0xC0; vga.start_l=0x00; vga.start_h=0x40; WVGA_write_vgaspec(outfile); return EXIT_OK; } else { RVGH_read_vgaspec_header(infile); if((vga.S=='S')&&(vga.P=='P')) { fprintf(stderr,"Invalid input file format. This could be a new syle .SP file with\n"); fprintf(stderr,"an image of another length than 48Kb. This kind of .SP files cannot\n"); fprintf(stderr,"be converted. All other file formats (including the old .SP format)\n"); fprintf(stderr,"contain images of 48Kb length.\n"); } else { fprintf(stderr,"Unknown input file format. Must be a valid .SNA, .SP, .Z80, .PRG, .ACH, .ZX or RAW file\n"); } return EXIT_FILE_ERROR; } } if(type == Z80) { printf("Converting %s from .Z80 to .Z80 (output in version 1.45 format)\n",infile); RZ80_read_z80(infile); WZ80_write_z80(outfile); return EXIT_OK; } /* If we get here than we had no special handling for this type */ /* return an error in that case... */ fprintf(stderr,"Input and output file format are the same. "); fprintf(stderr,"What you try to do\n"); fprintf(stderr,"is handled much better by the MSDOS \"COPY\" "); fprintf(stderr,"command!\n"); return EXIT_USAGE; } /* ERROR HANDLING FUNCTIONS */ /* Print Usage and exit */ void USAG_usage() { fprintf(stderr,"SPCONV version 1.09 - %s\n\n",__DATE__); fprintf(stderr,"Usage: spconv \n\n"); fprintf(stderr,"Source must be a valid .SNA, .SP, .Z80, .PRG, .ACH, .ZX, .SNX or RAW file.\n"); fprintf(stderr,"Target must be a .SNA, .SP, .Z80, .PRG, .ACH, .ZX or .SNX file.\n\n"); fprintf(stderr,"If the second parameter contains only a suffix, the prefix\n"); fprintf(stderr,"of the input file will be used (i.e. 'spconv file.sna .z80')\n\n"); fprintf(stderr,"Output .SP files are in the new format, .Z80 files are compressed\n"); fprintf(stderr,"in the version 1.45 .Z80 format\n\n"); fprintf(stderr,"If and are .SP files, convertion from old\n"); fprintf(stderr,"to new format or from new to old format will be performed.\n"); fprintf(stderr,"If and are .Z80 files, convertion to\n"); fprintf(stderr,"the version 1.45 format will be performed.\n"); fprintf(stderr,"If and are of the same type an error message\n"); fprintf(stderr,"will be generated (unless they are both .SP or .Z80 files)\n"); fprintf(stderr,"\n\nPublic Domain, H. de Groot & D. Burke 1995\n\n"); exit(EXIT_USAGE); } void RERR_read_error(char * s, FILE * fd) { perror(s); if(fd != NULL) fclose(fd); exit(EXIT_READ_ERROR); } void WERR_write_error(char * s, FILE * fd) { perror(s); if(fd != NULL) fclose(fd); exit(EXIT_WRITE_ERROR); } /* I/O FUNCTIONS */ /* GENERIC I/O - READ/WRITE SNAPSHOT */ void RGEN_read_generic(char * s, void * header, size_t h_size) { FILE * fd; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); if(fread(header, h_size, 1, fd)!=1) RERR_read_error(s, fd); if(fread(image, (size_t) IMSIZE, 1, fd)!=1) RERR_read_error(s, fd); fclose(fd); } void WGEN_write_generic(char * s, void * header, size_t h_size) { FILE * fd; unlink(s); fd=fopen(s,"w"); if(fd == NULL) WERR_write_error(s, fd); if(fwrite(header, h_size, 1, fd)!=1) WERR_write_error(s, fd); if(fwrite(image, (size_t) IMSIZE, 1, fd)!=1) WERR_write_error(s, fd); fclose(fd); } /* SPECIFIC I/O - READ/WRITE .SNA IMAGE */ void RSNA_read_sna(char * s) { RGEN_read_generic(s, (void *) &sna, sna_size); } void WSNA_write_sna(char * s) { WGEN_write_generic(s, (void *) &sna, sna_size); } /* SPECIFIC I/O - READ NEW .SP HEADER */ void RVGH_read_vgaspec_header(char * s) { FILE * fd; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); if(fread(&vga,vga_size,1,fd)!=1) RERR_read_error(s, fd); fclose(fd); } /* SPECIFIC I/O - READ/WRITE NEW .SP IMAGE */ void RVGA_read_vgaspec(char * s) { RGEN_read_generic(s, (void *) &vga, vga_size); } void WVGA_write_vgaspec(char * s) { WGEN_write_generic(s, (void *) &vga, vga_size); } /* SPECIFIC I/O - READ/WRITE OLD .SP IMAGE */ void ROVG_read_old_vgaspec(char * s) { RGEN_read_generic(s, (void *)(((char *)&vga)+6), (unsigned int) (vga_size-6)); } void WOVG_write_old_vgaspec(char * s) { WGEN_write_generic(s, (void *)(((char *)&vga)+6), (unsigned int) (vga_size-6)); } /* SPECIFIC I/O - READ RAW IMAGE */ void RRAW_read_raw(char * s) { signed int i; FILE * fd; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); if(fread(&h, hdr_size, 1, fd)!=1) RERR_read_error(s, fd); /* check if the image was saved the correct way */ for(i=0;i<9;i++) { if(h.in[i]!=expect[i]) { fprintf(stderr,"Header of Spectrum image not ok, "); fprintf(stderr,"Spectrum image should be saved with:\n"); fprintf(stderr,"SAVE *\"b\"CODE 16384,49152"); fclose(fd); exit(EXIT_FILE_ERROR); } } if(fread(image, (size_t) IMSIZE, 1, fd)!=1) RERR_read_error(s, fd); fclose(fd); } /* SPECIFIC I/O - READ/WRITE .Z80 IMAGE */ void RZ80_read_z80(char * s) { FILE * fd; signed int ext_size; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); /* read old header part */ if(fread(&z80,z80_145_size,1,fd)!=1) RERR_read_error(s, fd); /* check for 2.01 format */ if((z80.pch == (unsigned char) 0) && (z80.pcl == (unsigned char) 0)) { /* 2.01 or better format, check if we can use this */ unsigned char *p; p = (unsigned char *) &z80; /* read an aditional 2 bytes */ if(fread(&p[z80_145_size],2,1,fd)!=1) RERR_read_error(s, fd); ext_size = ((signed int) p[z80_145_size]) + 256 * ((signed int) p[z80_145_size+1]); if(ext_size < z80_201_ext_size) { fprintf(stderr,"%s seems to be a new type Z80 file!\n",s); fprintf(stderr,"This program is only tested for files up to version 3.0 format.\n"); fprintf(stderr,"The .Z80 file doesn't seem to be upwards compatible, since the\n"); fprintf(stderr,"extended header seems to be smaller than the version 2.01 extended\n"); fprintf(stderr,"header. The program can NOT convert this file!\n"); fclose(fd); exit(EXIT_FILE_ERROR); } if( (ext_size != z80_201_ext_size) && (ext_size != z80_300_ext_size ) ) { printf("Warning: %s seems to be a new type Z80 file!\n",s); printf(" This program is only tested for files up to version 3.0 format.\n"); printf(" Assuming upwards compatibiliy, the program will attempt to convert\n"); printf(" the file anyway. The resulting file may not work!.\n"); } /* we passed this test, read the first part of the extended header */ if(fread(&p[z80_145_size+2], z80_201_ext_size, 1, fd) != 1) RERR_read_error(s, fd); /* seek over the remaining extended header part if needed */ if(ext_size > z80_201_ext_size) { if (fseek(fd, (long) (ext_size - z80_201_ext_size), SEEK_CUR) != 0) RERR_read_error(s, fd); } /* we got a complete header now. */ /* check the type of the file... */ switch (ext_size) { case z80_201_ext_size: if((unsigned int) z80.hardware >= 3) { fprintf(stderr,"%s is not a 48K Spectrum Z80 file, can't convert!\n",s); fclose(fd); exit(EXIT_FILE_ERROR); } break; case z80_300_ext_size: if((unsigned int) z80.hardware >= 4) { fprintf(stderr,"%s is not a 48K Spectrum Z80 file, can't convert!\n",s); fclose(fd); exit(EXIT_FILE_ERROR); } break; default: if((unsigned int) z80.hardware >= 4) { printf("Warning: %s might not be a 48K Spectrum Z80 file!\n",s); printf(" (hardware flag in .Z80 file >= 4)\n"); printf(" Assuming 48K Spectrum anyway, continuing...\n"); } break; } /* check if the interface-1 rom was paged in */ if(z80.if1_paged != (unsigned char) 0) { fprintf(stderr,"%s has interface-1 rom paged in, can't convert!\n",s); fclose(fd); exit(EXIT_FILE_ERROR); } /* all fine up till now, put PC back to the old place and reset the */ /* compressed memory bit, the z80_read_page function decompresses. */ z80.pch = z80.n_pch; z80.pcl = z80.n_pcl; z80.data = z80.data & ~0x20; /* reset compressed mode bit to be sure */ while(RDPG_z80_read_page(s, fd)!=0); } else { /* The file is in version 1.45 format. */ /* Read and decompress if the image is compressed, */ /* just read if it is not compressed at all... */ if((z80.data & 0x20)!=0) { Z80D_z80_decompress(fd,0,(unsigned int) IMSIZE); z80.data = z80.data & ~0x20; /* reset compressed mode bit to be sure */ } else { if(fread(image, (size_t) IMSIZE, 1, fd)!=1) RERR_read_error(s, fd); } } fclose(fd); } void WZ80_write_z80(char * s) { FILE * fd; /* Try to compress the data */ z80.data=z80.data | Z80C_z80_compress(); unlink(s); fd=fopen(s,"w"); if(fd == NULL) WERR_write_error(s, fd); if(fwrite(&z80, z80_145_size, 1, fd)!=1) WERR_write_error(s, fd); if(fwrite(image, (size_t) z80_size, 1, fd)!=1) WERR_write_error(s, fd); fclose(fd); } /* SPECIFIC I/O - READ/WRITE .PRG IMAGE */ void RPRG_read_prg(char * s) { RGEN_read_generic(s, (void *) &prg, prg_size); } void WPRG_write_prg(char * s) { WGEN_write_generic(s, (void *) &prg, prg_size); } /* SPECIFIC I/O - READ/WRITE .ACH IMAGE */ void RACH_read_ach(char * s) { FILE * fd; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); if(fread(&ach,ach_size,1,fd)!=1) RERR_read_error(s, fd); /* fseek over the 16K ram area */ if(fseek(fd,16384L,SEEK_CUR)!=0) RERR_read_error(s, fd); if(fread(image, (size_t) IMSIZE, 1, fd)!=1) RERR_read_error(s, fd); fclose(fd); } void WACH_write_ach(char * s) { char buffer[1024]; char * p; signed int i; struct stat status; const char * rom; FILE * fd; signed long file_size; /* clean buffer first */ p=(char *) buffer; for(i=0; i < 1024; i++) p[i]='\0'; unlink(s); fd=fopen(s,"w"); if(fd == NULL) WERR_write_error(s, fd); if(fwrite(&ach,ach_size,1,fd)!=1) WERR_write_error(s, fd); strcat(my_directory,"\\spectrum.rom"); rom=NULL; if(stat("spectrum.rom",&status)>=0) { rom="spectrum.rom"; } else if (stat(my_directory,&status)>=0) { rom=(const char *) my_directory; } file_size = status.st_size; if(rom==NULL) { printf("Warning: The file \"spectrum.rom\" needed for proper conversion to the .ach\n"); printf(" format could not be located, Converting anyway. The ROM space\n"); printf(" will be filled with 0 bytes, the converted file may not work\n"); /* write the 16K ram area as zero's */ for(i=0; i < 16; i++) { if(fwrite(buffer,1024,1,fd)!=1) WERR_write_error(s, fd); } } else { if (file_size != 16384) { printf("Warning: The file \"spectrum.rom\" needed for proper conversion to the .ach\n"); printf(" format has a wrong size (not 16K). Converting anyway. The ROM space\n"); printf(" will be filled with 0 bytes, the converted file may not work\n"); /* copy the 16K ROM area */ for(i=0; i < 16; i++) { if(fwrite(buffer,1024,1,fd)!=1) WERR_write_error(s, fd); } } else { FILE * fd_specrom; printf("Using Spectrum ROM: %s\n",rom); fd_specrom=fopen(rom,"r"); if(fd_specrom==NULL) { perror(rom); fclose(fd); exit(EXIT_WRITE_ERROR); } for(i=0; i < 16; i++) { if(fread(buffer,1024,1,fd_specrom)!=1) { perror(rom); fclose(fd_specrom); fclose(fd); exit(EXIT_WRITE_ERROR); } if(fwrite(buffer,1024,1,fd)!=1) { perror(s); fclose(fd_specrom); fclose(fd); exit(EXIT_WRITE_ERROR); } } fclose(fd_specrom); } } if(fwrite(image, (size_t) IMSIZE, 1, fd)!=1) WERR_write_error(s, fd); fclose(fd); } /* SPECIFIC I/O - READ/WRITE .ZX IMAGE */ void RKGB_read_kgb(char * s) { FILE * fd; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); /* fseek over the first 132 bytes */ if(fseek(fd,132L,SEEK_CUR)!=0) RERR_read_error(s, fd); if(fread(image, (size_t) IMSIZE, 1, fd)!=1) RERR_read_error(s, fd); if(fread(&kgb,kgb_size,1,fd)!=1) RERR_read_error(s,fd); fclose(fd); } void WKGB_write_kgb(char * s) { char buffer[132]; char * p; signed int i; struct stat status; const char * rom; FILE * fd; signed long file_size; /* clean buffer first */ p=(char *) buffer; for(i=0; i < 132; i++) p[i]='\0'; unlink(s); fd=fopen(s,"w"); if(fd == NULL) WERR_write_error(s, fd); strcat(my_directory,"\\spectrum.rom"); rom=NULL; if(stat("spectrum.rom",&status)>=0) { rom="spectrum.rom"; } else if (stat(my_directory,&status)>=0) { rom=(const char *) my_directory; } file_size = status.st_size; if(rom==NULL) { printf("Warning: The file \"spectrum.rom\" needed for proper conversion to the .zx\n"); printf(" format could not be located, Converting anyway. The 132 bytes needed\n"); printf(" from the ROM will be filled with 0 bytes, the converted file may not\n"); printf(" work\n"); /* write the 132 byte area as zero's */ if(fwrite(buffer,132,1,fd)!=1) WERR_write_error(s, fd); } else { if (file_size != 16384) { printf("Warning: The file \"spectrum.rom\" needed for proper conversion to the .zx\n"); printf(" format has a wrong size (not 16K). Converting anyway. The 132 bytes\n"); printf(" needed from the ROM will be filled with 0 bytes, the converted file\n"); printf(" may not work\n"); /* write the 132 byte area as zero's */ if(fwrite(buffer,132,1,fd)!=1) WERR_write_error(s, fd); } else { FILE * fd_specrom; printf("Using Spectrum ROM: %s\n",rom); fd_specrom=fopen(rom,"r"); if(fd_specrom == NULL) { perror(rom); fclose(fd); exit(EXIT_WRITE_ERROR); } /* fseek over the first 16384-132 bytes */ if(fseek(fd_specrom,16252L,SEEK_CUR)!=0) { perror(rom); fclose(fd_specrom); fclose(fd); exit(EXIT_WRITE_ERROR); } if(fread(buffer,132,1,fd_specrom)!=1) { perror(rom); fclose(fd_specrom); fclose(fd); exit(EXIT_WRITE_ERROR); } if(fwrite(buffer,132,1,fd)!=1) { perror(s); fclose(fd_specrom); fclose(fd); exit(EXIT_WRITE_ERROR); } fclose(fd_specrom); } } if(fwrite(image, (size_t) IMSIZE, 1, fd)!=1) WERR_write_error(s, fd); if(fwrite(&kgb,kgb_size,1,fd)!=1) WERR_write_error(s, fd); fclose(fd); } /* SPECIFIC I/O - READ/WRITE .SNX IMAGE */ void RSNX_read_snx(char * s) { FILE * fd; unsigned char counthi, countlo, marker, fill; unsigned int count, i, addr; fd=fopen(s,"r"); if(fd == NULL) RERR_read_error(s, fd); /* read header part */ if(fread(&snx,snx_size,1,fd)!=1) RERR_read_error(s, fd); if((snx.signature[0] != 'X') || (snx.signature[1] != 'S') || (snx.signature[2] != 'N') || (snx.signature[3] != 'A')) { printf("This is not a .SNX file, it should have the 'XSNA' text at the start!\n"); RERR_read_error(s,fd); } /* If the header is an unexpected size, seek past it, ignoring any extra information held in it */ if (snx.headerlenhi * 256 + snx.headerlenlo != snx_size-6) { printf("Warning: the header part of %s is not the expected %u bytes!\n",s,snx_size); printf(" Converting anyway, the converted file may not work\n"); fseek(fd,snx.headerlenhi*256+snx.headerlenlo+6,SEEK_SET); } /* Read and decompress the image. */ addr = 0; while (addr < IMSIZE) { if(fread(&counthi,1,1,fd)!=1) RERR_read_error(s,fd); if (counthi >= 0xE0) { count = (counthi & 0x0F) + 1; if ((counthi & 0xF0) == 0xF0) marker = SNX_COMPRESSED; else marker = SNX_UNCOMPRESSED; } else { if(fread(&countlo,1,1,fd)!=1) RERR_read_error(s,fd); count = (counthi << 8) + countlo; if(fread(&marker,1,1,fd)!=1) RERR_read_error(s,fd); } if (addr + count > IMSIZE) RERR_read_error(s,fd); if (marker == SNX_COMPRESSED) { if(fread(&fill,1,1,fd)!=1) RERR_read_error(s,fd); for(i = 0; i < count; i++) image[addr + i] = fill; addr += count; } else { i = 0; while (i < count) { if(fread(&image[addr + i++],1,1,fd)!=1) RERR_read_error(s,fd); } addr += count; } } fclose(fd); } void WSNX_write_snx(char * s) { FILE * fd; unsigned char marker, countlo, counthi; unsigned int addr, i, j, count, packable; unlink(s); fd=fopen(s,"w"); if(fd == NULL) WERR_write_error(s, fd); /* Write header first */ if(fwrite(&snx,snx_size,1,fd)!=1) WERR_write_error(s, fd); /* Now compress and write RAM image */ addr = 0; while (addr < IMSIZE) { i = addr; j = i; /* First find a run we can compress; must be at least 6 identical bytes in a row. */ while ( (j+5 < IMSIZE) && (image[j] == image[j+1]) && (image[j] == image[j+2]) && (image[j] == image[j+3]) && (image[j] == image[j+4]) && (image[j] == image[j+5]) ) { j++; } if (j > i) { count = (j - i) + 5; if (count <= 16) { counthi = 0xF0 + (count - 1); if(fwrite(&counthi,1,1,fd)!=1) WERR_write_error(s,fd); } else { counthi = count >> 8; countlo = count & 0xFF; if(fwrite(&counthi,1,1,fd)!=1) WERR_write_error(s,fd); if(fwrite(&countlo,1,1,fd)!=1) WERR_write_error(s,fd); marker = SNX_COMPRESSED; if(fwrite(&marker,1,1,fd)!=1) WERR_write_error(s,fd); } if(fwrite(&image[i],1,1,fd)!=1) WERR_write_error(s,fd); addr += count; i = j + 5; } j = i + 1; packable = count = 0; /* Now find a run of non-identical bytes */ do { if (image[j] != image[j-1]) { packable = 0; count++; j++; } else /* Found two consecutive identical bytes */ { if ( (j+3 < IMSIZE) && (image[j] == image[j+1]) && (image[j] == image[j+2]) && (image[j] == image[j+3]) && (image[j] == image[j+4]) ) { /* Found six consecutive identical bytes */ packable = 6; j--; } else { packable = 0; count++; j++; } } } while ( (j < IMSIZE) && (packable < 6) ); if (count > 0) { if (IMSIZE - (i + count) < 6) count = (unsigned int)(IMSIZE - i); if (count <= 16) { counthi = 0xE0 + (count - 1); if(fwrite(&counthi,1,1,fd)!=1) WERR_write_error(s,fd); } else { counthi = count >> 8; countlo = count & 0xFF; if(fwrite(&counthi,1,1,fd)!=1) WERR_write_error(s,fd); if(fwrite(&countlo,1,1,fd)!=1) WERR_write_error(s,fd); marker = SNX_UNCOMPRESSED; if(fwrite(&marker,1,1,fd)!=1) WERR_write_error(s,fd); } while (i < j) { if(fwrite(&image[i++],1,1,fd)!=1) WERR_write_error(s,fd); } addr += count; } } fclose(fd); } /* CONVERSION FUNCTIONS - TO .SNA FORMAT */ void VGSN_vgaspec_to_sna() { unsigned int addr; unsigned int sp; sna.f=vga.f; sna.a=vga.a; sna.b=vga.b; sna.c=vga.c; sna.d=vga.d; sna.e=vga.e; sna.h=vga.h; sna.l=vga.l; sna.fax=vga.fax; sna.aax=vga.aax; sna.bax=vga.bax; sna.cax=vga.cax; sna.dax=vga.dax; sna.eax=vga.eax; sna.hax=vga.hax; sna.lax=vga.lax; sna.ixh=vga.ixh; sna.ixl=vga.ixl; sna.iyh=vga.iyh; sna.iyl=vga.iyl; sna.border=vga.border; sna.i=vga.i; sna.r=vga.r; /* If register I has changed, chances are good that it runs in IM2 mode */ if(sna.i==0x3f) sna.im=0x01; else sna.im=0x02; if((vga.im & 0x01) == 0) sna.iff2=0x00; else sna.iff2=0xff; sp=256*vga.sph+vga.spl; sp=sp-2; addr=sp-0x4000; image[addr]=vga.pcl; image[addr+1]=vga.pch; sna.sph=sp/256; sna.spl=sp%256; } void RASN_raw_to_sna() { unsigned int addr; unsigned int sp; unsigned int pc; pc=0x1bf4; /* entry of "next statement" */ sna.f=0x99; sna.a=0x5f; sna.b=0x1f; sna.c=0xf0; sna.d=0x5d; sna.e=0x0c; sna.h=0x5d; sna.l=0x0e; sna.fax=0x44; sna.aax=0x00; sna.bax=0x18; sna.cax=0x20; sna.dax=0x00; sna.eax=0x07; sna.hax=0x5c; sna.lax=0xf1; sna.ixh=0x03; sna.ixl=0xd4; sna.iyh=0x5c; sna.iyl=0x3a; sna.i=0x3f; sna.r=0x00; sna.im=0x01; sna.iff2=0xFF; /* set sp by means of RAMTOP in the image */ addr=0x5cb2-0x4000; sp=256*image[addr+1]+image[addr]-1; /* Reset ERR NR to no error */ image[0x5c3a-0x4000]=0xff; /* Set border by means of BORDCR */ sna.border=(image[0x5c48-0x4000] & 0x38)>>3; /* put return address to MAIN-4 (0x1303) on stack */ sp=sp-2; addr=sp-0x4000; image[addr]=0x03; image[addr+1]=0x13; sp=sp-2; addr=sp-0x4000; image[addr]=pc%256; image[addr+1]=pc/256; sna.sph=sp/256; sna.spl=sp%256; } void Z8SN_z80_to_sna() { unsigned int addr; unsigned int sp; sna.f=z80.f; sna.a=z80.a; sna.b=z80.b; sna.c=z80.c; sna.d=z80.d; sna.e=z80.e; sna.h=z80.h; sna.l=z80.l; sna.fax=z80.fax; sna.aax=z80.aax; sna.bax=z80.bax; sna.cax=z80.cax; sna.dax=z80.dax; sna.eax=z80.eax; sna.hax=z80.hax; sna.lax=z80.lax; sna.ixh=z80.ixh; sna.ixl=z80.ixl; sna.iyh=z80.iyh; sna.iyl=z80.iyl; sna.border=(z80.data/2) & 0x07; sna.i=z80.i; if(z80.data==0xff) z80.data=0; if((z80.data & 0x01)==1) sna.r=(z80.r & 0x7f)+0x80; else sna.r=z80.r & 0x7f; sna.im=z80.im & 0x03; if(z80.iff2 != 0) sna.iff2=0xff; else sna.iff2=0x00; sp=256*z80.sph+z80.spl; sp=sp-2; addr=sp-0x4000; sna.sph=sp/256; sna.spl=sp%256; image[addr]=z80.pcl; image[addr+1]=z80.pch; } void PRSN_prg_to_sna() { unsigned int addr; unsigned int sp; sna.b=prg.b; sna.c=prg.c; sna.d=prg.d; sna.e=prg.e; sna.h=prg.h; sna.l=prg.l; sna.fax=prg.fax; sna.aax=prg.aax; sna.bax=prg.bax; sna.cax=prg.cax; sna.dax=prg.dax; sna.eax=prg.eax; sna.hax=prg.hax; sna.lax=prg.lax; sna.ixh=prg.ixh; sna.ixl=prg.ixl; sna.iyh=prg.iyh; sna.iyl=prg.iyl; /* Set border by means of BORDCR */ sna.border=(image[0x5c48-0x4000] & 0x38)>>3; sna.i=prg.i; if(prg.i==0x3f) sna.im=0x01; else sna.im=0x02; sp=256*prg.sph+prg.spl; sp=sp+4; /* there are two more words on the stack besides PC */ addr=sp-0x4000; sna.r=image[addr-3]; /* the af combo is on the stack */ sna.f=image[addr-2]; sna.a=image[addr-1]; sna.sph=sp/256; sna.spl=sp%256; /* interrupts always on ??? */ sna.iff2=prg.iff2; } void ACSN_ach_to_sna() { unsigned int addr; unsigned int sp; sna.f=ach.f; sna.a=ach.a; sna.b=ach.b; sna.c=ach.c; sna.d=ach.d; sna.e=ach.e; sna.h=ach.h; sna.l=ach.l; sna.fax=ach.fax; sna.aax=ach.aax; sna.bax=ach.bax; sna.cax=ach.cax; sna.dax=ach.dax; sna.eax=ach.eax; sna.hax=ach.hax; sna.lax=ach.lax; sna.ixh=ach.ixh; sna.ixl=ach.ixl; sna.iyh=ach.iyh; sna.iyl=ach.iyl; sna.border=ach.border; sna.i=ach.i; sna.r=ach.r; sna.im=ach.im & 0x03; if(sna.im == 3) sna.im = 0; sna.iff2=ach.iff2; sp=256*ach.sph+ach.spl; sp=sp-2; addr=sp-0x4000; sna.sph=sp/256; sna.spl=sp%256; image[addr]=ach.pcl; image[addr+1]=ach.pch; } void KGSN_kgb_to_sna() { unsigned int addr; unsigned int sp; sna.f=kgb.f; sna.a=kgb.a; sna.b=kgb.b; sna.c=kgb.c; sna.d=kgb.d; sna.e=kgb.e; sna.h=kgb.h; sna.l=kgb.l; sna.fax=kgb.fax; sna.aax=kgb.aax; sna.bax=kgb.bax; sna.cax=kgb.cax; sna.dax=kgb.dax; sna.eax=kgb.eax; sna.hax=kgb.hax; sna.lax=kgb.lax; sna.ixh=kgb.ixh; sna.ixl=kgb.ixl; sna.iyh=kgb.iyh; sna.iyl=kgb.iyl; sna.i=kgb.i; sna.r=kgb.r; /* border-colour not found in KGB image */ /* Set border by means of BORDCR */ sna.border=(image[0x5c48-0x4000] & 0x38)>>3; /* determine interrupt mode using the value of register I */ if (kgb.i_mode_l==0xff) sna.im=0x00; else if(kgb.i_mode_l==1) sna.im=0x02; else sna.im=0x01; if((kgb.interruptstatus & 0x01) != 0) sna.iff2=0xff; else sna.iff2=0x0; sp=256*kgb.sph+kgb.spl; sp=sp-2; addr=sp-0x4000; sna.sph=sp/256; sna.spl=sp%256; image[addr]=kgb.pcl; image[addr+1]=kgb.pch; } /* CONVERSION FUNCTIONS - FROM .SNA FORMAT */ void SNVG_sna_to_vgaspec() { unsigned int addr; unsigned int sp; unsigned int pc; sp=256*sna.sph+sna.spl; addr=sp-0x4000; pc=image[addr]+256*image[addr+1]; sp=sp+2; vga.S='S'; vga.P='P'; vga.len_l=0x00; vga.len_h=0xC0; vga.start_l=0x00; vga.start_h=0x40; vga.f=sna.f; vga.a=sna.a; vga.b=sna.b; vga.c=sna.c; vga.d=sna.d; vga.e=sna.e; vga.h=sna.h; vga.l=sna.l; vga.fax=sna.fax; vga.aax=sna.aax; vga.bax=sna.bax; vga.cax=sna.cax; vga.dax=sna.dax; vga.eax=sna.eax; vga.hax=sna.hax; vga.lax=sna.lax; vga.ixh=sna.ixh; vga.ixl=sna.ixl; vga.iyh=sna.iyh; vga.iyl=sna.iyl; vga.i=sna.i; vga.r=sna.r; vga.im=sna.im & 0x02; /* 0 for IM1, 2 for IM2 */ /* works? how does it know it was IM1 ? */ if((sna.iff2 & 0x04) != 0) vga.im=vga.im | 0x01; vga.sph=sp/256; vga.spl=sp%256; vga.pch=pc/256; vga.pcl=pc%256; vga.border=sna.border; vga.res2=0; vga.res3=0; vga.res4=0; vga.res5=0; } void SNZ8_sna_to_z80() { unsigned int addr; unsigned int sp; unsigned int pc; sp=256*sna.sph+sna.spl; addr=sp-0x4000; pc=image[addr]+256*image[addr+1]; sp=sp+2; z80.f=sna.f; z80.a=sna.a; z80.b=sna.b; z80.c=sna.c; z80.d=sna.d; z80.e=sna.e; z80.h=sna.h; z80.l=sna.l; z80.fax=sna.fax; z80.aax=sna.aax; z80.bax=sna.bax; z80.cax=sna.cax; z80.dax=sna.dax; z80.eax=sna.eax; z80.hax=sna.hax; z80.lax=sna.lax; z80.ixh=sna.ixh; z80.ixl=sna.ixl; z80.iyh=sna.iyh; z80.iyl=sna.iyl; z80.i=sna.i; z80.r=sna.r | 0x080; /* bit 7 is stored somewhere else, always set */ z80.im=sna.im & 0x03; z80.im=z80.im + 0x60; /* fixed normal video/kempston joystick */ z80.sph=sp/256; z80.spl=sp%256; z80.pch=pc/256; z80.pcl=pc%256; /* all kinds of stuff put in "data" */ z80.data=(sna.border & 0x07)*2; if((sna.r & 0x80)!=0) z80.data=z80.data+1; /* here is bit 7 of r */ /* image is not compressed, compression will be done by the */ /* z80_write function. */ z80.data = z80.data & ~0x20; /* reset compressed mode bit to be sure */ if((sna.iff2 & 0x04) != 0) { z80.iff1=0xff; z80.iff2=0xff; } else { z80.iff1=0; z80.iff2=0; } } void SNPR_sna_to_prg(char * n) { unsigned int addr; unsigned int sp; signed int i; unsigned char * p; /* clean header structure first */ p=(unsigned char *) &prg; for(i=0; i < 256; i++) p[i]='\0'; prg.c_0x61=0x61; /* size of image in sectors */ prg.c_0x35=0x35; /* don't know yet */ prg.c_0x03=0x03; /* don't know yet */ sp=256*sna.sph+sna.spl; addr=sp-0x4000; /* these are on the stack */ image[addr-1]=sna.a; image[addr-2]=sna.f; image[addr-3]=sna.r; image[addr-4]=sna.iff2; sp=sp-4; prg.name[0]='\0'; strncpy(prg.name,n,10); prg.name[10]='\0'; prg.b=sna.b; prg.c=sna.c; prg.d=sna.d; prg.e=sna.e; prg.h=sna.h; prg.l=sna.l; prg.fax=sna.fax; prg.aax=sna.aax; prg.bax=sna.bax; prg.cax=sna.cax; prg.dax=sna.dax; prg.eax=sna.eax; prg.hax=sna.hax; prg.lax=sna.lax; prg.ixh=sna.ixh; prg.ixl=sna.ixl; prg.iyh=sna.iyh; prg.iyl=sna.iyl; prg.i=sna.i; prg.iff2=sna.iff2; prg.sph=sp/256; prg.spl=sp%256; /* prg.border=sna.border; */ } void SNAC_sna_to_ach() { unsigned int addr; unsigned int sp; unsigned int pc; signed int i; unsigned char * p; /* clean header structure first */ p=(unsigned char *) &ach; for(i=0; i < 256; i++) p[i]='\0'; sp=256*sna.sph+sna.spl; addr=sp-0x4000; pc=image[addr]+256*image[addr+1]; sp=sp+2; ach.f=sna.f; ach.a=sna.a; ach.b=sna.b; ach.c=sna.c; ach.d=sna.d; ach.e=sna.e; ach.h=sna.h; ach.l=sna.l; ach.fax=sna.fax; ach.aax=sna.aax; ach.bax=sna.bax; ach.cax=sna.cax; ach.dax=sna.dax; ach.eax=sna.eax; ach.hax=sna.hax; ach.lax=sna.lax; ach.ixh=sna.ixh; ach.ixl=sna.ixl; ach.iyh=sna.iyh; ach.iyl=sna.iyl; ach.i=sna.i; ach.r=sna.r; ach.border=sna.border; if((sna.iff2 & 0x04) != 0) ach.iff2=0xff; else ach.iff2=0x00; ach.im=sna.im; ach.sph=sp/256; ach.spl=sp%256; ach.pch=pc/256; ach.pcl=pc%256; } void SNKG_sna_to_kgb() { unsigned int addr; unsigned int sp; unsigned int pc; signed int i; unsigned char * p; /* clean info structure first */ p = (unsigned char *) &kgb; for(i=0; i < 202; i++) p[i]='\0'; /* make some assumptions here */ kgb.is3_1 = 3; /* always 3, don't ask me why */ kgb.colourmode = 1; /* assume colour */ kgb.soundmode = 1; /* assume simple sound */ kgb.haltmode = 1; /* assume not in halt mode */ sp=256*sna.sph+sna.spl; addr=sp-0x4000; pc=image[addr]+256*image[addr+1]; sp=sp+2; kgb.f=sna.f; kgb.a=sna.a; kgb.b=sna.b; kgb.c=sna.c; kgb.d=sna.d; kgb.e=sna.e; kgb.h=sna.h; kgb.l=sna.l; kgb.fax=sna.fax; kgb.aax=sna.aax; kgb.bax=sna.bax; kgb.cax=sna.cax; kgb.dax=sna.dax; kgb.eax=sna.eax; kgb.hax=sna.hax; kgb.lax=sna.lax; kgb.ixh=sna.ixh; kgb.ixl=sna.ixl; kgb.iyh=sna.iyh; kgb.iyl=sna.iyl; kgb.i=sna.i; kgb.r=sna.r; /* kgb.border=sna.border; NOT IN KGB IMAGE! */ /* Interupt mode is stored in a word in the KGB format. */ /* Use byte accesses to be CPU independent */ switch (sna.im & 0x03) { case 0: kgb.i_mode_h = 0xff; kgb.i_mode_l = 0xff; break; case 2: kgb.i_mode_h = 0; kgb.i_mode_l = 1; break; default:kgb.i_mode_h = 0; kgb.i_mode_l = 0; break; } if((sna.iff2 & 0x04) != 0) kgb.interruptstatus=0x01; else kgb.interruptstatus=0x00; kgb.sph=sp/256; kgb.spl=sp%256; kgb.pch=pc/256; kgb.pcl=pc%256; } /* 16K PAGE READ FUNCTION FOR .Z80 FORMAT */ /* * Function returns: * 0: No more pages * 1: Page read */ signed int RDPG_z80_read_page(char * s, FILE * fd) { struct z80_page_s page_info; unsigned int len; unsigned int pos; signed long f_len; if(fread(&page_info,z80_pg_size,1,fd)!=1) { return 0; } len = (256 * page_info.blklen_h) + page_info.blklen_l; switch(page_info.page_num) { case 0: fprintf(stderr,"%s - memory page 0 - 48K rom ignored\n",s); pos=0x0ffff; break; case 1: fprintf(stderr,"%s - memory page 1 - Interface 1 rom ignored\n",s); pos=0x0ffff; break; case 2: fprintf(stderr,"%s - memory page 2 - basic samram rom ignored\n",s); pos=0x0ffff; break; case 3: fprintf(stderr,"%s - memory page 3 - monitor samram rom ignored\n",s); pos=0x0ffff; break; case 4: pos=0x04000; /* second 16K of RAM area */ break; case 5: pos=0x08000; /* third 16K of RAM area */ break; case 6: fprintf(stderr,"%s - memory page 6 - shadow rom 8000-BFFF ignored\n",s); pos=0x0ffff; break; case 7: fprintf(stderr,"%s - memory page 7 - shadow rom C000-FFFF ignored\n",s); pos=0x0ffff; break; case 8: pos=0; /* first 16K of RAM area */ break; case 9: fprintf(stderr,"%s - memory page 8 - 128K page 6 ignored\n",s); pos=0x0ffff; break; case 10:fprintf(stderr,"%s - memory page 10 - 128K page 7 ignored\n",s); pos=0x0ffff; break; case 11:fprintf(stderr,"%s - memory page 11 - Multiface rom ignored\n",s); pos=0x0ffff; break; default:fprintf(stderr,"%s - memory page %d - Unknown page number -ignored-\n",s,page_info.page_num); pos=0x0ffff; break; } if(pos == (unsigned int) 0x0ffff) { /* wrong page, seek over this page */ if(fseek(fd, (long) len, SEEK_CUR)!=0) RERR_read_error(s, fd); } else { /* Valid 48K page, read and decompress */ f_len = 0 - ftell(fd); Z80D_z80_decompress(fd, pos, 16384); f_len = f_len + ftell(fd); if((signed long) len != f_len) { fprintf(stderr,"Z80 image corrupted, can't convert\n"); fclose(fd); exit(EXIT_FILE_ERROR); } } return 1; } /* COMPRESSION/DECOMPRESSION for .Z80 FORMAT */ void Z80D_z80_decompress(FILE * fd, unsigned int start, unsigned int imsize) { signed int c,j,k; unsigned char l; unsigned char im; j=start; while(j<(start+imsize)) { c=getc(fd); if(c == -1) return; im = (unsigned char) c; if(im!=0xed) { image[j++]=im; } else { c=getc(fd); if(c == -1) return; im = (unsigned char) c; if(im!=0xed) { image[j++]=0xed; ungetc(im,fd); } else { /* fetch count */ k=getc(fd); if(k == -1) return; /* fetch character */ c=getc(fd); if(c == -1) return; l = (unsigned char) c; while(k!=0) { image[j++]=l; k--; } } } } if(j!=(start+imsize)) { fprintf(stderr,"Z80 image corrupted, can't decompress\n"); exit(EXIT_FILE_ERROR); } } int Z80C_z80_compress() { #ifdef __TURBOC__ unsigned char far * comp; #else unsigned char * comp; #endif unsigned int i,j; unsigned int num; unsigned char c,n; unsigned int ed; z80_size=(unsigned int) IMSIZE; /* * We need an intermediate buffer here, if the compressed image * is bigger than the uncompressed image than the image will * not be compressed to save space (!) */ #ifdef __TURBOC__ comp=(unsigned char far *) farmalloc((unsigned long)(IMSIZE+0x0100)); #else comp=(unsigned char *) malloc((size_t)(IMSIZE+0x0100)); #endif if(comp==NULL) { printf("Warning: Not enough memory to compress the image, using uncompressed image\n"); return NOTCOMPRESSED; } i=0; j=0; /* ensure 'ed' is not set */ ed=NO; while(i= (IMSIZE-4)) { /* compressed image bigger or same than original */ #ifdef __TURBOC__ farfree((void far *) comp); #else free((void *) comp); #endif return NOTCOMPRESSED; } } /* append "end of compressed area" mark */ comp[j]=0; j++; comp[j]=0xed; j++; comp[j]=0xed; j++; comp[j]=0; j++; z80_size = j; /* copy back */ i=0; j=0; while(i #include #include #include #define SPT_EXT "spt" const int SYNCC = 512; const int BUFSIZE = 1024; const int upth = 1; const int downth = -1; inline double sqr(double x) { return x * x; } class EdgeDetect { private: FILE *infile; signed char buf[BUFSIZE]; int sl, dl; int pos; int lastdpos; int lastdtype; int lastpos; int lastdist; int bufp; int bufoff; public: EdgeDetect(FILE *fp); int edge(int &dist, int &dist2, int &dir); void store_buffer(FILE *fp); }; EdgeDetect::EdgeDetect(FILE *fp) { int i; infile = fp; for(i = 0; i < BUFSIZE; i++) buf[i] = 0; bufp = 0; bufoff = 0; lastdtype = 0; lastdpos = 0; sl = 0; lastpos = 0; dl = 0; pos = 0; } int EdgeDetect::edge(int &dist, int &dist2, int &dir) { int c; int edge; int sn, dn; int minv, maxv; int thrs; int nowth; for(; (c = getc(stdin)) != EOF; pos++) { edge = 0; sn = c - 128; buf[bufp] = sn; dn = sn - sl; if(pos - lastdpos > 2) { if(lastdtype != 1 && dl < upth && dn >= upth) { edge = 1; lastdtype = 1; } if(lastdtype != -1 && dl > downth && dn <= downth) { edge = 1; lastdtype = -1; } } if(edge) { if(pos - lastdpos < BUFSIZE) { int bufb = (lastdpos - bufoff + BUFSIZE) % BUFSIZE; minv = buf[bufb]; maxv = buf[bufp]; thrs = (minv + maxv) / 2; for(nowth = lastdpos; nowth < pos; bufb = (bufb + 1) % BUFSIZE, nowth++) { if(lastdtype == 1 && buf[bufb] <= thrs) break; if(lastdtype == -1 && buf[bufb] >= thrs) break; } } else nowth = pos; dist = nowth - lastpos; lastpos = nowth; lastdpos = pos; dist2 = dist + lastdist; lastdist = dist; dir = -1 * lastdtype; return 1; } bufp++; if(bufp == BUFSIZE) { bufp = 0; bufoff += BUFSIZE; } sl = sn; dl = dn; } return 0; } void EdgeDetect::store_buffer(FILE *fp) { int i; for(i = (bufp + 1) % BUFSIZE; i != bufp; i = (i + 1) % BUFSIZE) putc((int) buf[i] + 128, fp); } const char *statename[] = { "NOTHING", "SCANNING", "SYNC", "START", "DATA" }; class SegmentRead : private EdgeDetect { public: SegmentRead(FILE *fp); int n_bytes(int n, unsigned char *buf, int &flag, int& bytenum); }; SegmentRead::SegmentRead(FILE *fp) : EdgeDetect(fp) { } int SegmentRead::n_bytes(int n, unsigned char *buf, int &flags, int &bytenum) { int dist, dist2, dir; int state; int laststate; int synccount; int syncdir; int bitnum; int databyte; int bitval; int parity; int firstbyte; int retval = -4; state = 0; laststate = -1; bytenum = -1; int syncsum; double syncvar; int b1sum, b0sum; double b1var, b0var; int b1ctr, b0ctr; b0sum = b1sum = 0; b0var = b1var = 0; b0ctr = b1ctr = 0; const int MINSYNC = 25; const int MAXSYNC = 50; const int STARTMAX = 14; const int STARTMIN = 2; while(edge(dist, dist2, dir)) { if(state == 0) { if(dist2 >= MINSYNC && dist2 <= MAXSYNC) { state = 1; synccount = 0; syncsum = 0; syncvar = 0; } } else if(state == 1) { if(dist2 >= MINSYNC && dist2 <= MAXSYNC) { synccount++; syncsum += dist2; syncvar += sqr((double) dist2 - ((double) syncsum / (double) synccount)); if(synccount >= SYNCC) state = 2; } else state = 0; } else if(state == 2) { if(dist > STARTMIN && dist < STARTMAX) { fprintf(stderr, "syncave: %.2f\n", (double) syncsum / (double) synccount); state = 3; } else if(dist2 < MINSYNC || dist2 > MAXSYNC) { fprintf(stderr, "FALSE SYNC, dist: %i, dist2: %i\n", dist, dist2); state = 0; } else { synccount++; syncsum += dist2; syncvar += sqr((double) dist2 - ((double) syncsum / (double) synccount)); } } else if(state == 3) { fprintf(stderr, "startdists: %i, %i\n", dist2 - dist, dist); if(dist > STARTMIN && dist < STARTMAX) { state = 4; bitnum = 0; bytenum = -1; parity = 0; firstbyte = 1; databyte = 0; syncdir = dir; b0sum = b1sum = 0; b0var = b1var = 0; b0ctr = b1ctr = 0; } else { fprintf(stderr, "FALSE START\n"); state = 2; } } else if(state == 4) { if(dir == syncdir) { if(dist2 > 5 && dist2 < 45) { databyte <<= 1; if(dist2 > 22) { bitval = 1; b1ctr++; b1sum+=dist2; b1var+=sqr((double) dist2 - ((double) b1sum / (double) b1ctr)); } else { bitval = 0; b0ctr++; b0sum+=dist2; b0var+=sqr((double) dist2 - ((double) b0sum / (double) b0ctr)); } databyte += bitval; bitnum++; if(bitnum == 8) { bitnum = 0; parity ^= databyte; if(firstbyte) { if(flags >= 0 && flags != databyte) { state = 0; fprintf(stderr, "searching flag: %i, found flag: %i\n", flags, databyte); continue; } if(flags == -2 && databyte == 0 && n < 0) n = 17; flags = databyte; fprintf(stderr, "found flag: %i\n", flags); firstbyte = 0; bytenum = 0; } else if(bytenum < n || n < 0) { buf[bytenum] = databyte; bytenum++; if(bytenum % 100 == 0) fprintf(stderr, "pos: %5i b1ave: %4.1f b0ave: %4.1f \r", bytenum, b1ctr ? (double) b1sum / (double) b1ctr : 0.0, b0ctr ? (double) b0sum / (double) b0ctr : 0.0); } else { if(parity == 0) retval = 0; else retval = -1; break; } databyte = 0; } } else { if(n >= 0 || parity != 0) { fprintf(stderr, "SIGNAL LOST: dist: %i, dist2: %i, bytenum: %i, bitnum: %i\n", dist, dist2, bytenum, bitnum); FILE *fp = fopen("bufstor", "w"); if(fp != NULL) store_buffer(fp); fclose(fp); } if(n < 0) { if(parity == 0) { bytenum--; retval = 1; } else retval = -3; } else retval = -2; break; } } } if(state != laststate) { if(state >= 2) fprintf(stderr, "state: %s\n", statename[state]); laststate = state; } } fprintf(stderr, "pos: %5i b1ave: %4.1f b0ave: %4.1f \r", bytenum, b1ctr ? (double) b1sum / (double) b1ctr : 0.0, b0ctr ? (double) b0sum / (double) b0ctr : 0.0); return retval; } const char *sperror(int status) { switch(status) { case 1: return "end found, parity OK"; case 0: return "parity OK"; case -1: return "parity error"; case -2: return "synchronisation lost"; case -3: return "end found, parity error"; case -4: return "end of tape"; } return "unknown error"; } int main(int argc, char *argv[]) { SegmentRead sr(stdin); unsigned char buf[65536]; int flags = -1; int nextflags; int status; int numbytes; int num = -1; int isheader; char filename[11]; filename[10] = 0; int filetype; int filesize; int segc = 0; FILE *tapefile; FILE *datfile; char datfilename[256]; char *tapefilename; if(argc < 2) tapefile = NULL; else { tapefilename = argv[1]; sprintf(datfilename, "%s.%s", tapefilename, SPT_EXT); tapefile = fopen(datfilename, "w"); if(tapefile == NULL) { fprintf(stderr, "Could not open tape directory file %s\n", datfilename); exit(1); } } while(1) { status = sr.n_bytes(num, buf, flags, numbytes); if(status < 0) fprintf(stderr, "\nError reading file segment: %s\n", sperror(status)); else fprintf(stderr, "\nStatus: %s\n", sperror(status)); if(status == -4) break; fprintf(stderr, "flags: %i, numbytes: %i\n", flags, numbytes); if(flags == 0 /*&& numbytes == 17*/) { isheader = 1; fprintf(stderr, " HEADER\n"); filetype = buf[0]; fprintf(stderr, "file type: %i\n", filetype); strncpy(filename, (char *) &buf[1], 10); fprintf(stderr, "file name: `%s'\n", filename); filesize = buf[11] + ((buf[12]) << 8); // num = filesize; // nextflags = 255; num = -1; nextflags = -1; fprintf(stderr, "file size: %i bytes\n", filesize); fprintf(stderr, "misc info: %02X %02X %02X %02X\n", buf[13], buf[14], buf[15], buf[16]); } else { isheader = 0; num = -1; nextflags = -1; } fprintf(stderr, "\n"); if(tapefile != NULL) { fprintf(tapefile, "%03i %02X %5i %3s", segc, flags, numbytes, status < 0 ? "ERR" : "OK "); if(isheader) fprintf(tapefile, " %10s %5i %02X", filename, filesize, filetype); fprintf(tapefile, "\n"); fflush(tapefile); sprintf(datfilename, "%s.%03i", tapefilename, segc); datfile = fopen(datfilename, "w"); if(datfile == NULL) { fprintf(stderr, "Could not open data file %s\n", datfilename); exit(1); } fwrite(buf, 1, numbytes, datfile); fclose(datfile); segc++; } flags = nextflags; } fclose(tapefile); fprintf(stderr, "\n"); return 0; } spectemu-0.94/utils/spt2tap.c0100644000175000017500000000437106316240444016447 0ustar cjwatsoncjwatson#include #include #include #include #define MAXLEN 256 typedef unsigned char byte; static int read_tape_line(FILE *tapefp, int line, int max, byte *flag) { static char buf[MAXLEN]; int iflag; int res; int i; do { if(fgets(buf, MAXLEN, tapefp) == NULL) return -1; res = sscanf(buf, "%d %x", &i, &iflag); if(max >= 0 && res == 2 && i > max) return -2; } while(res < 2 || i < line); *flag = (byte) iflag; fprintf(stderr, "%s", buf); return i; } int main(int argc, char *argv[]) { char filename[MAXLEN]; FILE *tap, *spt, *blk; int len, n, c; int from, to; int line; byte flag; byte parity; if(argc < 2) { fprintf(stderr, "usage: %s sptfile [tapfile [from to]]\n", argv[0]); exit(1); } strcpy(filename, argv[1]); strcat(filename, ".spt"); spt = fopen(filename, "rt"); if(spt == NULL) { fprintf(stderr, "Could not open file %s. %s\n", filename, strerror(errno)); exit(1); } if(argc < 3) strcpy(filename, argv[1]); else strcpy(filename, argv[2]); strcat(filename, ".tap"); tap = fopen(filename, "wb"); if(tap == NULL) { fprintf(stderr, "Could not open file %s. %s\n", filename, strerror(errno)); exit(1); } if(argc < 4) from = 0; else from = atoi(argv[3]); if(argc < 5) to = -1; else to = atoi(argv[4]); line = from; for(;;) { line = read_tape_line(spt, line, to, &flag); if(line == -1) { fprintf(stderr, "End of tapefile\n"); break; } if(line == -2) break; sprintf(filename, "%s.%03i", argv[1], line); blk = fopen(filename, "rb"); if(blk == NULL) { fprintf(stderr, "Could not open file %s. %s\n", filename, strerror(errno)); exit(1); } fseek(blk, 0, SEEK_END); len = ftell(blk) + 2; if(len > 0xFFFF) len = 0xFFFFF; rewind(blk); putc(len & 0xFF, tap); putc(len >> 8, tap); putc(flag, tap); parity = flag; for(n = 0; n < len - 2; n++) { c = getc(blk); if(c == EOF) { fprintf(stderr, "Warning: %s EOF too early\n", filename); c = 0; } parity = parity ^ (byte) c; putc(c, tap); } putc(parity, tap); fclose(blk); } fclose(spt); fclose(tap); return 0; } spectemu-0.94/utils/tap2spt.c0100644000175000017500000000244406314330725016446 0ustar cjwatsoncjwatson#include #include #include #include #define MAXLEN 256 int main(int argc, char *argv[]) { char filename[MAXLEN]; FILE *tap, *spt, *blk; int i, len, n, c; if(argc < 2) { fprintf(stderr, "usage: %s basename\n", argv[0]); exit(1); } strcpy(filename, argv[1]); strcat(filename, ".tap"); tap = fopen(filename, "rb"); if(tap == NULL) { fprintf(stderr, "Could not open file %s. %s\n", filename, strerror(errno)); exit(1); } strcpy(filename, argv[1]); strcat(filename, ".spt"); spt = fopen(filename, "wt"); if(spt == NULL) { fprintf(stderr, "Could not open file %s. %s\n", filename, strerror(errno)); exit(1); } for(i = 0;; i++) { c = getc(tap); if(c == EOF) break; len = c + (getc(tap) << 8); sprintf(filename, "%s.%03i", argv[1], i); blk = fopen(filename, "wb"); if(blk == NULL) { fprintf(stderr, "Could not open file %s. %s\n", filename, strerror(errno)); exit(1); } fprintf(spt, "%03i %02X %5i OK Generated by tap2spt\n", i, getc(tap), len - 2); for(n = 0; n < len - 2; n++) { putc(getc(tap), blk); } getc(tap); fclose(blk); } fclose(tap); fclose(spt); return 0; } spectemu-0.94/utils/taplist.c0100644000175000017500000000240506316235371016531 0ustar cjwatsoncjwatson#include #include #include typedef unsigned char byte; int main(int argc, char *argv[]) { int c; int len; int parity; int end; byte header[18]; char filename[11]; int filesize; int filetype; int ctr; int i; filename[10] = '\0'; if(argc > 1) { fprintf(stderr, "usage: %s < tapfile\n", argv[0]); exit(1); } end = 0; ctr = 0; while(!end) { c = getchar(); if(c == EOF) { end = 1; continue; } len = c; c = getchar(); if(c == EOF) { end = -1; continue; } len += (c << 8); parity = 0; for(i = 0; i < len; i++) { c = getchar(); if(c == EOF) { end = -1; break; } parity = parity ^ c; if(i < 18) header[i] = c; } printf("%03d", ctr); if(i >= 1) { printf(" %02X %5d %3s", header[0], len-2, parity == 0 ? "OK" : "ERR"); if(header[0] == 0 && len - 2 >= 17) { filetype = header[1]; strncpy(filename, header+2, 10); filesize = header[12] + (header[13] << 8); printf(" %02X %10s %5i", filetype, filename, filesize); } } printf("\n"); ctr++; } if(end < 0) { fprintf(stderr, "Error: Incomplete segment in tape file\n"); return 1; } return 0; } spectemu-0.94/utils/tzxlist.c0100644000175000017500000000126606507001333016565 0ustar cjwatsoncjwatson#include "tapefile.h" #include "tapef_p.h" #include #include int main(int argc, char *argv[]) { char *tapename; byte *head; int i; tapename = argv[1]; if(!open_tapefile(tapename, TAP_TZX)) { fprintf(stderr, "%s\n", seg_desc); return 1; } printf("TZX Version %i.%02i\n", tf_tpi.tzxmajver, tf_tpi.tzxminver); for(i = 0; (head = tf_get_block(i)) != NULL; i++) { if(head != NULL) printf("%4i (%05lX): %02X l:%5li p:%5i n:%5i u:%i %s\n", i, tf_segoffs, head[0], tf_cseg.len, tf_cseg.pause, tf_cseg.num, tf_cseg.bused, seg_desc); } while(head != NULL); if(head == NULL) printf("%s\n", seg_desc); return 0; } spectemu-0.94/utils/tapefile.c0120777000175000017500000000000007432615531021010 2../tapefile.custar cjwatsoncjwatsonspectemu-0.94/utils/tapefile.h0120777000175000017500000000000007432615531021022 2../tapefile.hustar cjwatsoncjwatsonspectemu-0.94/utils/tapef_p.h0120777000175000017500000000000007432615531020474 2../tapef_p.hustar cjwatsoncjwatsonspectemu-0.94/bin_to_c.c0100644000175000017500000000523006515667113015470 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #define FIELDS_PER_LINE 10 #define EXTENSION ".c" static char *progname; static void bin_to_c(FILE* ifp, FILE *ofp, char *name, char *iname, char *oname) { int i; int c; int first; unsigned long ctr; fprintf(ofp, "/* %s */\n\n", oname); fprintf(ofp, "/*\n" " This file was generated by %s from binary image\n" " file `%s'\n" " */\n\n", progname, iname); fprintf(ofp, "unsigned char %s[] = {", name); i = 0; first = 1; ctr = 0; while((c = getc(ifp)) != EOF) { ctr++; if(!first) fprintf(ofp, ", "); else first = 0; if(!i) fprintf(ofp, "\n "); fprintf(ofp, "0x%02X", (int) ((unsigned char) c)); i = (i + 1) % FIELDS_PER_LINE; } fprintf(ofp, "\n};\n\n"); fprintf(ofp, "const unsigned long %s_size = %lu;\n\n", name, ctr); fprintf(ofp, "/* End of %s */\n", oname); } int main(int argc, char *argv[]) { char *inputfile, *outputfile, *outprefix; FILE *ifp, *ofp; progname = argv[0]; if(argc != 3) { fprintf(stderr, "usage: %s inputfile output_prefix\n", progname); return 1; } inputfile = argv[1]; outprefix = argv[2]; outputfile = malloc(strlen(outprefix) + strlen(EXTENSION) + 1); if(outputfile == NULL) { fprintf(stderr, "Could not allocate memory\n"); return 1; } strcpy(outputfile, outprefix); strcat(outputfile, EXTENSION); ifp = fopen(inputfile, "rb"); if(ifp == NULL) { fprintf(stderr, "Could not open input file `%s': %s\n", inputfile, strerror(errno)); return 1; } ofp = fopen(outputfile, "wt"); if(ofp == NULL) { fprintf(stderr, "Could not open output file `%s': %s\n", outputfile, strerror(errno)); return 1; } bin_to_c(ifp, ofp, outprefix, inputfile, outputfile); free(outputfile); fclose(ofp); fclose(ifp); return 0; } spectemu-0.94/spectkey.srl0100644000175000017500000003701706515706652016133 0ustar cjwatsoncjwatsonяrяrяrюrз wюrЧ §эr Ч §ьr З ·ьr · Зыr · Зъr § Чъr — а— а— а— а‡ б‡ б‡ б‡ бw вw вw вg гg гg гg гW дW дW дW гxфrGЏG дxфr7€уrG€уrG€уrG€уr7ЁтrGЁтrGЁтrGЁтr7ёсrGёсrGёсr7ИрrGИрrGИрrGИрr7ШяbGШяbGШяbGШюbGаЏж д~юbGаЏж г~эbGбЏЦ д~у2 ч0GбЏ1 у џsг~(у › ђађ№ ™ ђ©ц0GвЏ1 © ђђЩ ђ© ђ№ц0GвЏR± Бя p p§ч  :°ЈГ 0Г >°ўІВ *ь ` j jя ЂИАЌ Ђ Ћрљ  ђ© ђЙшЂ ђ© ђ© ђђЙц07гЏRАу  p|b30:А3:°0>ђ*  ,А"/±j `foсЉАЊАЉ Ћрљ  ђ °љ ьЂ › ђЙ ђђЙЩх0GгЏRАу  p| R000:А< : >Ђ,  ,А /±l `jя ЂЊАЊ ЂЉп  ђљ ›  џИ© ђђЙАђЙ џSд~8х А ·§ zх  00Ј : : >Ђ ў * *ыР¦jр Ђ ЉАЊ ЂЉп  ђЙ›  ©ъЂ ђ© ђ© ђђ™ џSд~8х   2pzАzх  0Г 0<3 : >Ђ* ,А /±nj ``oЉАЊАЉп  ђ °љ ьЂ › њ ђ™ ™ ђ©х07дЏRАу pАpц  0: 0< : :и  ,А*ы j j oЉАЊАЉп  ђ °љ ьЂ2 ф0GдЏR±БЎБя pЗ r: 0 0Г : :й * В /Б¦°j `jс  И ЂИЁ ЂЏЃђђ  ђ© љ џ€у џCд~HъbGдЏ¦ г~XщbGеЏ– д~Xщb7жЏRЙ љ ђЙя ›  № № ќ љ ђ  ќ ђ№љ љ  ђ© љ ђ ћ©  ђљ °љ ђ© Й©л џ#№ф0 џs™ю ђ ›  №љ ђ љ ћ0© Й АЙ ђЙс0GжЏRњ љ °џљ ђђ  ђћњ  ђљ ћ љ  ђљ а  ђ ђ њ  ћђ ђ  ›  ђ ђ њ  ћЂ™ т0 џ#™™х0 џІљ  ђ љ  ђ љ з ђ Ањ а  џSд~hх Аљ › р Аљ  ђћњ  ђњ г  љ  ђћљ ђ  ђњ  ћђ  ›  ђ љ Аљ ж љ ь џ™Р™э   ™щ Аљ  ђљ  ђ њ з  ђњ Аћљ х0Gе‚х љ  ђ °џњ  ђ№ ©°њ  ђњ ћ@љ ђ  ђ©Аљ ђ  ђ© љ а ђђђљ °љ ђ  ђ© љ д ћ@џ’№№э ђ џТћ@™ч ђ№љ ђ ђ ќ ћ@љ љ А©Аљ џ3г~h/Rњ  ђ °џњ ђћ љ Аљ Ађћ0љ  љ б  ђ  ђњ  ћђ ™ђќ  ђ  ђњ  ћ`™ аџ’™Р™р0 џаљ џ’љ  Й Аљ ђ в г  ђњ Аћљ ф0Gж‚х Ађ  › р  ђљ в  њ  ђљ ћ љ ђ  ђћђљ ђ њ  ћђ  ђ ™ђљ ђ њ  ћЂ™ с0 ђ џ#ђ ц0 џІљ ђ  ђњ  ђ љ Аћ0ђ њ Аћљ ф0Gж‚х ђ© © џ©љ А№°Й© ©љ б  љ ©ЙАљ ђ© Й©а ђљ  љ љ  © љ ђ ћ°™у0 џC№ц0 џв№  ђљ Аљ ђ ђ ћ@© Й ђЙ љ џд~X"чb7ж‚/f д~h"цbGеЉ/Rц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц _Вг~hўх bNђц TйbNђц TйbNђц TйbNђц TйbNђц Tъ GжЉ/Rц TйbNђц TйbNђц TйbNђц TйbNђц TйbOўд~hўх ЃбќTйЃбќTйЃбќTйЃбќTйЃбќTйЃбќTйЃбќTйЃбќTйbNђц Tъ Gе‹/Rш[љYХNђшYҐ№ХNђшYХќTйЃбќTйЃ№ҐќTйЃљ[ќTйЃќYХNђш^ХNђц TйbOўг~hІх ™з[љYХNђХЙжYҐ№ХNђХЙжYХќTй%™ж^ХNђЕЩж[љYХNђХЙжYҐ№ХNђµаћeќYХNђЕЙз^ХNђЕЙьTй \џБO’д~hІх ©з[љYХNђЕ™Ґ™еYҐ№ХNђЕ™Ґ™еYХќTй©ж^ХNђЕ™к[љYХNђЕ™Ґ™еYҐ№ХNђµ™Ґ™жYХќTй YљYћeбќTй YљYџ±Nђµ™Ґ™ыTщ Gж‹/RХ№з^ХNђгYћUбќTй5™е^ХNђа[ћe№ҐќTй YћҐ№ҐќTй YћҐ№ҐќTй%™ж[љYХNђµ™Ґ™ж^ХNђµ™Ґ™ыTй Y•Zџ±O’д~XВх ™з^ХNђгYћUбќTй5™е^ХNђа[ћe№ҐќTй \ћu№ҐќTй YћҐ№ҐќTй™з[љYХNђµ™Ґ™ж^ХNђµ™Ґ™ыTй Y•Zџ±O’г~hВх ™з^ХNђгYћUбќTй№ж^ХNђХ™Yћe№ҐќTй%™ж[љYХNђЕЩж[љYХNђбYћu№ҐќTй \ћuбќTй YљYџ±Nђµ™YYџ±O‚д~hВх ™з^ХNђвYћeбќTй5™е^ХNђХ™YћeбќTй5™е^ХNђЕ™Ґ™е^ХNђаYћ…бќTй YљYћeбќTй ]џ±Nђµ™YYџ±O‚д~XТх ™ьTй™ьTй5™ъTй Y•Yџ±NђгYџЎNђЕ™Ґ™ъTй™эTй YљYџ±NђвYџ±Nђµ©U™ыTш 7жЌ/RбYџБNђаYџСNђгYџЎNђЕаџЎNђгYџЎNђЕ™Ґ™ъTй YџбNђµ™Ґ™ыTй%™ыTй Z•Yџ±Orд~hТх ™ьTй YџбNђЕ™Ґ™ъTй%™ыTй Y•Yџ±NђЕ™Ґ™ъTй YџбNђµ™Ґ™ыTй YљYџ±Nђµ™Ґ™ыTч GжЌ/RХЩдWзTй ^ жZ~5NђХЙжWWдTй%™жWжTй [ћEwU~UNђХЙгWйTй YћU~ҐNђЕЙеWиTй \ћe~uNђЕЙьTч GеЋх q~uNђшWҐ~%NђшWWдTйq·дTйеwWжTйХu~…NђнWкTйе~•NђшWжTйbOrг~hа/RчWзTйЃu§вTйqЗгTйхu~eNђшWжTйе~•NђмWлTйе~•NђшWжTйbObд~hа/RчWзTйЃuu~%NђшWWдTйq§еTйq~uNђнWWWжTйbNђоWйTйЃ~eNђц Tц GеЋх q~uNђшWZ~%Nђч\~5NђшWWдTйх~…NђнWU~uNђц Tйе~•NђшWжTйbObд~Xб/Rц TйЃ~eNђшWWдTйх·еTйхuwеTйХuWзTйbNђоWйTйЃ~eNђм^7вTц 7жЋх q~uNђщZ~5NђшWWдTйЃ~eNђоWUwеTйеwWжTйbNђпWиTйq~uNђц Tх GжЋх bNђц TйbNђц TйbNђц TйbNђц TйbNђц Tх GеЋ"х bNђц TйbNђц TйbNђц TйbNђц TйbNђц Tх 7жЋ"х bNђц TйbNђц TйbNђц TйbNђц TйbNђц Tф GжЋ"ц bкbкbкbкbкbкbкbкbкbф GжЋ"яRGеЋ2яR7жЋ2х z pЗ°З qЗ В| pz 2§·З }ш pР§ · }к p p pЗр p·°{ pЗъ z p pz С§°z bЗ§·z z rд~hг/Rp|бАwq|pь Рppц  pzАw}ч p| p|гкpw pzф АzppАбz pwzю p°‚| pzpwp{щ GеЋBх  p|бАppq|ь Рpц  pzАpp| ~р|АzА~ Зй pzф Аz p|ю pzp б| zш Аz ppppz ’д~Xд/Rz z } zч zь Рp Bz p zРpq|Аz§§бк pz "§ ·z§§ь p pppzюАz ‚§ z p zш GжЋBх  p|бАpq|wь Рpwц  p|Аp| ~р|АzАp~ Зй pzppф Аpz |юАzpw б| zш Аz z zш GжЋBх pА~| q| В}zц  p|АzРpqzАzАp~0p~ z pB|p |юАzp zю pz ‚| ppz zш GеЋRх z p~| q| ВЗ pz 2§| pzРpЃ§З§·ЗРp~ z§°z З pz p Ў} p pz с§z ‚} p pz zш 7жЋRьRGжЋRьRGеЋbьRGеЋbьR7жЋbыRGжЋRµ д~Xж!ыR7жЋbҐ д~hж!ъRGжЋRъRGеЋbъR7жЋbщRGжЋRЎс@ ў /’ў ў Іх * *ч * /‚І* /’І Ібя   Ібя * * /ІВ *р * ІъGеЋbЎр@Р  ш   *ы °  ш "*ъ   " ч а *РІь  * - /Б*  /B*А,/2+*щGеЋbЎр@Р ш А*ы  *ш  *ъ   *ц а *А /б,  *А /б,  *ф   ,А /B*  *щ7жЋbЎс@ * /‚,  /‚*  /‚  /ўІ *ч + Іа /С, Іа /С,  * /"Іў ў "х  * /‘д~hе+D  /‚, ,ч  В"ш  *ъ    *ъ  *вьА*вьА*  /B,А,ф  В /Ѓд~Xж+D *ш   *А/r*  *ш * /ў */І*  РІэ  *- /С*  /B,А,/2*  *ш7жЋb±р@ *щ * /‚*  *ч * /ў*  ўш + *ая   *ая * * /, В /"*  ІшGжЋRБчRGжЋRБчRGеЋbБчR7жЋbБр@bкbкbкbкbкbкbкbкbкbGжЋRСр@bNђц TйbNђц TйbNђц TйbNђц TйbNђц Tд~hе-ц TйbNђц TйbNђц TйbNђц TйbNђц TйbNGеЋbСр@ \ћE~…NђЕ™Ґ™еWWдTй ^ Х~ЕNђµЩиWеTй ]ћ5~…NђХ™U™бWҐzWZ|Tй YљYћe§U·ЕNђХЩеWҐЗЕNђХЙыTй ]џ±N7жЋbСр@ YљYћ%~•NђЕ™Ґ™дWҐ~5NђЕ™еWлTй YљYћe~eNђбYћe~uNђХ™U™аWWUwUuuWµNђµ™Ґ™еWҐuzWµNђбYћeu{WаTй YљYћ…wвTй YљYџЎN7жЋRаЕ™Ґ™бWҐЗвTй Y••™гWЕ~%NђЕ™жWUЗгTй YљYћU~uNђбYћu~eNђХ™U™ХzWWWWWҐzTй YљYћUzWWҐ{Tй™еWҐzWаTй YљYћ…wвTй YљYџЎN7еЋbаЕ™Ґ™аWлTй Y••™вWаWбTй Yћu~•Nђµ™Ґ™дWиTй™иWеTй Y•YќWҐuuuuzWҐNђµ™Ґ™еWҐu·ЕNђбYћUzWҐ~NђЕ™Ґ™ъTй YљYћҐu}Tв~hж.р@ YљYћ~ҐNђЕ™YYћ5|WвTй \ћ5~ҐNђµЩжWзTй™зWжTй№а\uuWuzWҐNђµ™Ґ™еWҐuu}Tй™е\zWаTй YљYџЎNђЕЩлWWХN'жЋRбЕ™Ґ™вWUЗвTй ^ дWҐ~5NђЕ™еWҐЗгTй Y•™иWжTй™жWзTй™бWҐuzWWU{Tй YљYћUzWWU|Tй™еWҐzWаTй YљYћ…wвTй YџсN'жЋRбЕ™Ґ™гWиTй ^ еWWдTй YћE~ЕNђµ™U™иWеTй™еWиTй™бWҐuzWZ|Tй YљYћe§UzWµNђбYћUzWҐ~NђЕ™Ґ™йWвTй YџсN'еЋbбЕ№YџЎNђХЙыTй YџсNђµ™U™ьTй™ьTй™ьTй YљYџ±NђбYџБNђЕ™Ґ™иWгTй YџсNжЋbбЕ™[џЎNђХ™Yџ±NђЕ™яTй YљYџ±NђбYџБNђбYџБNђµ™Ґ™ыTй™ьTй YљYџЎNђЕ™яTб~hе.!р@ \џ±NђХ™Yџ±NђЕаџЎNђµ™Ґ™ыTй™ьTй™ьTй \џБNђХЩъTй \џ±NђЕ™яTб~hе.!р@5™ъTйbNђц TйbNђц TйbNђц TйbNђц TйbNеЋbвц TйbNђц TйbNђц TйbNђц TйbNђц TйbNжЋbвг[•YХ©UЙЕNђвZљ[›YҐљYХNђй[•\•љYЕNђй[•YҐ•љYЕNђд[›YҐљYZќTй[•\•ЙYҐ•№UљYTй‘©\›Tй©YҐ•№UљY\›Tй5№Ґ©UљY\њTй%№U№U©YҐ•ЙUNжЋRггYҐ•њYҐљYаTй%•YUљYU••YҐќTй•љYYЕ™YњTй•љYYҐ•™UњTйEљYU••Y•YYUњTйYҐ•ћљYҐ•љYY•YTйЎ•YбTй•Y•YYҐ•љYҐќTй5љYYҐ••YUћ%NђвYҐ•љYU•Y•YҐ›Tа~Xж.1р@5љYYЕљYҐћNђвYҐ•љYYҐ•љYХNђйYҐ•њYYYЕNђйYҐ•љYYYYЕNђдYҐ•љYYYYYҐ›TйYҐ•ћљYҐ•љYYYYTйЎ•YбTй•YYYYҐ•љYҐќTй5љYYҐ••љYвTй%љYYҐ•YU••љYµM~hж.1р@5№UњYҐљYаTй%љY[•YҐ•љYХNђй[•ZљYYYЕNђй[•YҐ•••њTйE№UљYYYYYҐ›Tй[•ZњYҐљY[•YYYTйЎ•ZќTй•YYY[•YҐљYХNђг[•YҐ•™µ©аTй%№U№Ґ•YYYҐ›TЧжЋRдгYЕњYҐљYаTй%љYYYҐЙYYYХNђйYYҐњYҐњTй••љYҐ••YњTйE•љ\••Y•љYµNђU•љYаYҐљYYYҐ•Y•NђъYUћNђбYU•Y•њYҐљYХNђгYЕљYYYҐћ%NђвYЕ•›YU•YљYµM~hе.Aр@5њYЕљYҐћNђвYU•YU•YҐ•••ќTй••YUњYҐњTй••YUљYYҐњTйE•YUљYYҐ••YЕNђU•YUћљYҐ••YUљYTйЎ•YбTй•YҐ•њYҐљYХNђгYЕљYYU•YвTй%њYUљYUљYҐ›TЧеЋbдгYЕЙU©µћNђвZљYҐ•љYU•ћNђйYҐ•ЙYҐњTй•љYU©UљYЕNђдYҐ•љYYҐ•©ХNђUљY\љYµ©UљYYҐ•NђщZ•ћNђаZ•љYYХ©µќTй5ќZ•YҐ•ЙЕNђвYЕљYZ•љYҐ›TЗжЋbдц TйbNђц TйbNђц TйbNђц TйbNђц TйbL~hе.Qр@bNђц TйbNђц TйbNђц TйbNђц TйbNђц TЗеЋbд$ц N ц N ц N ц N ц N ц N ц N ц N ц N ц L~Xж.AсR7жЋRе д~hе.Qу@°· ‚{ z ‚z pzц  pЗ p pЗ ~рz p· §Зъ C§х0 pzю p pЗщ ‘д~Xж.Aу@|pч zы °zpц  p| p| ~рwp| pzюш0ц0wТz zъ °Ѓг~hж.Aт@ p|ц  p|ъ  z ppbzАzpАzпАzАбѓcpэ  pz ’ppпGжЋRе$z§ppbzР§ч  z ppbz z z§°§ч z p p§ьш0ц0ppТz zщ °~рд~hе.Aу@ |wц p~ bЗ zwч |°pаш p| zюш0ц0pТz zщ °~рд~Xж.Aу@ | bz |ц  z zч |z~ЃzАpzюш0ц0zэ  pz ’ppп7жЋbд4z p bz§·ч  z zш  З p§аш pЗ p pЗъ C§х0 pzю z {ъ °~рд~hе.Qх2 qд~Xж.AсRGеЋbд д~hе.QрRGжЋRе д~Xж.AсR7жЋbд д~hе.QрRGеЋbд д~Xж.AсR7жЋbд д~hе.QрRGеЋbд5ІВ * /"ІВІ .pўА* *у  /‚* * /rІўІч  * /ў, *ц   Іц07жЋbд5*Р /*А.*  *л*°+с А* ч *ъ А* /b* ъ А, ц   , /Cд~hе.QуP  ,  *р   ,а *  .°* * *р А,ц   *ъ А* /b*  /ў,А /b*А*ф0GеЋbдEІў * /Іў°ў°*  Іўй  * * /ў ўц   І ўш   Іч   *ъ Аў  /b*ўІх0GеЋbдE *АВ / *в *  *л  В * /B *"ц *А/ў /’ /ў,А /b*А /cг~hж.AфP А*/ . * * л  * *ф   *ц   *А/ў  ш *ъ А, /b*А ф0GжЋRеE* * /"* І°+   Вз * * *р * *ц   ІІч * *ш  * /bВ *ч  /3д~Xж.AсRGеЋbд г~hж.AрRGеЋbеUц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^ ц ^2дeц TйbNђц TйbNђц TйbNђц TйbNђц TйbN"дeц TйbNђц TйbNђц TйbNђц TйbNђц TйbNеeХ©Е·\uZu[zTй \ћzWU§UЗҐNђµЙХ·\uЗ[uTй ^ б\uZ~%Nђа[љ\uzW\uzWTй YљYћE~uNђвYџ±NђЕ™Ґ™ъTй YџбNђц Tб.AчP Y•™Ґ~zWҐuzWUNђµ™Ґ™аWuWWҐzWЕNђµ™U™µ~zWЕzWTй Yћ…zWҐ~NђХ™U™µzWҐu|WuWTй YљYћ5§жTй%™ыTй YљYћU~eNђХ™юTйbNдuЕ™YљWаWҐzWWҐuTй YћUuuuzWҐ|Tй YљYљWаWҐ|WҐuNђµ™иWҐzWбTй Yћ%zWҐu|WWWTй YљYћ%uu~UNђвYџ±NђЕ™U™жWжTй YћeЗеTйbNдuµ™Ґ™Ґ§µzWҐu·ҐNђµ™еWWWWҐzWЕNђµ™Ґ™µ§µzZz[uTй Yћ…zWҐ~NђЕ™вWҐЗZzWWWTй YљYћE~uNђвYћ%ЗжTй Y•™е\~ENђХ™юTйbNеuµ™Ґ™ХzWҐzWWХNђЕ©гWUwWҐzWЕNђµ™Ґ™аWҐzWЕ|Tй \ћUzWҐ~NђЕ™вWҐzWWЕuWuNђЕаћE~uNђвYџ±NђЕ№иWжTй YџбNђц Tа.AшP YљYќWҐzWҐu}Tй©бWҐuzWҐ|Tй YљYћzWҐ|WЕNђµ™иWҐzWбTй Y•Z›WҐzWWЕzWTй YљYћE~uNђвYџ±NђЕ№иWжTй YћeЗеTйbNд…µа•[{Wµ§U}Tй%™аWҐuZ{WЕNђµ™Ґ™Ґ·µz\u|Tй Yћ…{Z~%NђЕ™Ґ™µzWҐuЗWҐuNђЕ™Ґ™дWзTй%™ыTй Y•™ьTй YџбNђЕЙYҐ•Й\•№ЕNд…µ™Ґ™ыTй%™ыTй YљYџ±Nђµ™р Tй YљYџЎNђЕ™Ґ™дWзTй YљYџ±NђЕ™U™ыTй YџбNђЕњY•YҐљYЕљYµM.AщP YљYџ±Nђµ™Ґ™ыTй Y•YџБNђµ™р Tй Y•YџЎNђЕ™Ґ™ъTй YљYџ±NђЕ™Ґ™ъTй YџбNђЕњYYYҐљYЕљYµM.AщP YљYџ±NђЕЙьTй \џСNђµ™р TйЙъTй YљYџЎNђЕЙьTй YљYџЎNђХЩъTй ZљYYYҐљZљ[њTТд•ц TйbNђц TйbNђц TйbNђц TйbNђц Tй YЕ•YљYҐњYYХL.QщPbNђц TйbNђц TйbNђц TйbNђц TйbNђЕњYҐљYҐњYUњTВдҐзYҐ•ЙYҐћNђе[љYҐљY\›Tй•©Ґ©YҐћNђи\•Z•[ћNђеZљZ•\•ZњTй ZљZљ[•љY[ќTйEќZ›YҐ©ХNђгYЕ©U№\ћNђзYЕЙ\ћNђЕЙYҐљYҐЙYҐ›TВдҐзY•YYЕљYаTйEќYYUљYYбTй••YҐ•Y•™аTй…њYҐ•љYХNђдYҐ•љYҐљYҐ›Tй YҐ•љYYЕљYYҐњTйEњYҐ•YYU•YЕNђгYХ•YаYвTйuњYаYвTйbL.AъPu•••њYҐћNђдYЕљYYҐ•ћNђйYҐ•YU••ћNђиYЕљYYҐќTйEњYҐљYҐљYµNђµњYҐ•њYҐ•љYЕNђдYЕљYYҐ•љYµNђгYХ•YаYвTйuњYаYвTйbK.QъPu•••©ҐљYаTйU©UљYYҐ•©ХNђйYҐ•YU••ћNђиZљYҐ•№аTйE•©YҐљYҐљYµNђµ•©YҐ•Z•YҐ•№ХNђдYЕљYYҐ•љYµNђгYХљZ›YвTйuњZњYвTйbK.AыPu•Y•њYYYаTй…•ЙU••YбTй•љYU•YҐћNђиYЕљYYYбTйEљYYҐљYҐљYµNђµљYYҐњYYҐ•љYЕNђдYЕљY\•љYµNђгYХќYҐћ%NђзYЕћћ%Nђц TІдµзYҐ•њYYYаTй…•љYU••YбTй••YҐ•YҐћNђиYЕљYYUћNђдYҐ•љYҐљYҐ›Tй YҐ•љYЕ•љYYҐњTйEњYҐ•љYYUњTй5ќYХљYвTйuњYаYвTйbK.AыPuљY\•YYбTйE№UљYҐљ\›Tй•©Ґ©YҐћNђиYХ©UљYХNђе[•Z›Yµ©ЕNђЕ№U©U№Ґ©U№ХNђд\•Z•YҐ•©ХNђг\•©[›YвTйuЙ\љYвTйbJ.AьPbNђц TйbNђц TйbNђц TйbNђц TйbNђц TўдЕц TйbNђц TйbNђц TйbNђц TйbNђц TйbJ.AэPbкbкbкbкbкbкbкbкbкb"е д~Xж.AсRGеЋbдIc“3s§§ z pАЗп z ~@с·§·З pzаз З p·ц 7жЋbдеSssSSzp pzАЎzppг Б| pzА|pР·д°| zф GеЋbдеpp#ssSS}zА|ъ pzвюА| p|Аpp|е zАz Bд~Xж.Aс`у0ш0х0ч0ф0Рp pА| Ѓz p~0§ю pА·§ § pp} ~@z | ·х GеЋbдY“SSS}pzА|ыЗдр АpzА|wаг zАzц 7жЋRеY“SSSzpp p|ыzв pzpА| | ~@z | pф GеЋbдiЈS3s§§ p p pЗш z ~б· §z pЗ ~~Pz | zу GеЋbд г~hж.AрRGеЋbе д~Xж.AсRGеЋbд г~hе.QрRGеЋbд д~Xж.AсRGеЋbд д~hе.QрRGеЋbд д~Xж.AсR7жЋbдЧ, /ВВ  Іч АІІў  ВпА, Вь *ш *  В ..РІўрЂGеЋbдз, ь А* /b,  *   /Ѓ,Р аю  "/’   А*РІл  сЂGеЋbдз,ь Р  /b,  *  /Ѓ,Р аю   /’  , ,н  сЂGеЋbдз,ь , Іч АІІ   /Ѓ,Р* +ю * /’ + + .ўм *сЂ7жЋRез,"ь Р ъ А,° " /Ѓ,Р- /б* "щ   *авлР/д~Xж.QюpА*ь А*ъ А,** /Ѓ,Р- /б*  /’   ..ІмР/д~Xж.Aяp *ь *ъ ,  ў *ш В І°/бІў /‚ў  * *внАўяp7жЋbд д~Xж.QрRGеЋbд д~Xж.Aю0кbкbкbкbкbкbкbкbк$Сю0Nђц TйbNђц TйbNђц TйbNђц TйbNђт@TБю0Nђц TйbNђц TйbNђц TйbNђц TйbNђм[•[•\љYҐљYлT±я0%Йµ©µЩҐЙгTйbNђц Tйq§еTй‘~UNђц TйbNђц TйbNђмYҐ•љYYХ••YUћЕKубYљY•Y•™Ґ™Ґ™YљYћ%NђЕаћ%wиTй YљYћ%§иTй№дWҐ~ENђµ™Ґ™жWжTй ]ћ…~UNђХ™Ґ™щTй YљYџЎNђц TйЕљYYҐ•њYҐ••ћХKубYќYљY•YљY•™зTй%™гW~…Nђµ™Ґ™бWҐ~uNђХ™U™зWдTй YљYћe~eNђµ™Ґ™еWWWгTй Z•Yџ‘NђЕ™Ґ™ъTй [uzWWҐu·Ґ§U|TйЕ№U№U©ҐљYYћеKубYќYљY•]љ\ћ5NђвYџ±NђЕ™Yћ5~ҐNђЕ™лWеTй YљYћU~uNђµ™Ґ™жZ~ENђХ©U™щTй Z•©ъTйWЕzWWuwWҐuzWWЕNђмYҐ••љYЕЙYYнTЎр@™Ха•YћE™вTй™ьTй Y•™вZ~•NђЕ™кWжTй YљYћE~…Nђµ™Ґ™еWWWгTй [•™вW~uNђЕ©ZћUwеTйWЕzWWWWWҐuzWWЕNђмYҐ••YUњYҐ••YмTЎр@™Ґ™YљY•YќYљYћ%NђбYћEwиTй ZћE~ҐNђЕ™яTй Y•™еWиTй ]ћ…~UNђХ™YYћ5~uNђЕаћUwеTй ZzZuWWW[uWҐu|TйЕ№UљY\•љYYҐћµJв\•YљY•YћЙгTй™еW~…NђХ©гWлTй YћҐ~eNђЕ™YћE~•Nђµ™Ґ™ыTй Y•№вWиTй ^ ъTй WҐzWҐuzWWҐu|Tй$Aс0Tй™эTй Y•™в\~uNђЕ™яTй Y•™ьTй YљYџ±NђХ™U©щTй Y••™ъTй WҐzWҐuzWWҐu|Tй$Aс0Tй YџбNђЕ™YџБNђЕ™яTй Y•™ьTй YљYџ±NђХ™U©щTй Y••™ъTй[{WҐzW[zZu\uNђи\•]›Zњ[•^ жTс@NђХ™юTй YљYџ±NђХ™U™ъTй ZџСNђµ™Ґ™ыTй YљYџ‘NђЕ™YYџЎNђц Tйuа•аљZ›]•аћeAХЙU™Ґ™]•а•ЩаTй ^ ъTй YљYџ±Nђа[џ±NђХ©эTй ]џБNђХ™Ґ™щTй YљYџЎNђц Tйu™Ґ™YљY•Y•™U©U™YћµAт@ YљY•™Ґ™Ґ™Ґ™бYћ%Nђц TйbNђц TйbNђц TйbNђц TйbNђзYќYљY•Y•™U™Х™лT$Е™Х™Ґ™Ґ™Ґ™бYћ%NђеZљZ•[•YҐ›Tй Z•YЕЙҐљ[ќTй5©Ґ©UљY\ќTй…©Uќ[ћNђ[љZ•[•Zљ\•№ҐNђгYҐ•ЙYҐ•ЙЕNђХ№µљYҐ•[•ЙҐNђХ·WҐu§\uЗХNђз[›YљY•™Ґ™Yќ\ћ…Aт@ \•^ Ґ™ҐЙЕ™вTйEљYYҐ•љYYҐ›Tй YҐ•њYХ••YҐњTй%љYYҐ•™UљYбTйuљYYЕћENђYҐ•љYYҐ••YUњYҐ•Tй5™U•њYҐљYаTй YҐ•YYUљYYЕћNђЕ|WҐuWU~~Nђи\•^ YљY•™ХЙиTу@5™YљYљYљYћ™вTйEњYҐ•љYYҐ›Tй YЕњYЕљYYҐњTй%њYҐ•••љYбTйuњYЕћENђYҐ•љYYҐ•љYYЕљYUNђгYYYYХ•›YаTй YҐ•љYYҐ•њYаTй WЕzWUuWаWбT饹]•^ YќYћµO4Е™Ґ™YљYљYљYћ™вTйEњYҐ•№Ґ©ЕNђµњYЕ©ҐљY[ќTй%њYҐ•••љYбTйuњYХ©бTй№UљY[•YҐ•©Ґ№ҐNђгYYYZњYЕћNђХ№UљYYҐ•Z•ZњTй Zu\uWU§Е~NђмY•™Ха•™Х™лTу@ \•YљY•ЩYћ™вTйEњYҐ•ћќTй YЕњYЕЙYYаTй%њYҐ••YљYбTйuњYвYаTйљYYҐ••љYҐ•њYYµNђгYU™YХ•›YаTй YЕЙYҐњYYаTй%uzWUuWаWбTйu™Ґ™YќYљY•©U™YћµO4с0TйEљYYҐ•ћќTй YҐ•њYЕљYYUќTй%љYYҐ•љYҐћNђзYҐ•ћ%ћNђYҐ•љYYU•YU•YЕ•YҐNђгYҐ•њYҐљYаTй YЕљYYҐњYYаTй%uzWUuWаWбTйuа•™Х™Ґ™UЩ^ жTу@NђеZљZ•YаYХNђЕ©UЙ\•љYYҐњTй5©Ґ©UљYҐћNђиZ•\•№бT鹥©UљYZљ\•љYUNђгYҐ•ЙYҐљYаTй YЕљYU©U№UЙҐNђЕ·UzWZu~~Nђи\•YќYљYљ[•^ жTу@Nђц TйbNђц TйbNђц TйbNђц TйbNђт@Tу@Nђц TйbNђц TйbNђц TйbNђц TйbNђт@Tф@кbкbкbкbкbкbкbкbк$яBGеЋbд г~hе.QчЂ p pЗ § pzш { ·З ±За°· Ў··§§z q§z p·с pz pЗ z pЗшPGеЋbд€zА| pp’zpp p| Ў|РppАzъ pzp pz Ѓz p| pp p| p|ьPGеЋbд€zА| pъ  pz p| Ў|АzАzъ pzpАz Ѓz p| p p| p|ьP7жЋbд€·§ § ·т pppwы p p·§ ·ы zАz§Зъ p zp§ zш pz z "p p§ · §§щPGжЋRе€zА|х pppў| p|АpБ|АЗАpzъ pp{z zш p|у pp|аыPGеЋbдzА|х z’| p|АpыА| | Ўzzz zш p|"p p|}ыPGеЋbд·З pB§ pzш АzАЗ Ў| pz p Ў·z p pz ‘§°z pzр pz z pz p uг~hж.AрRGеЋbд д~Xж.AсRGеЋbд г~hе.QрRGеЋbд д~Xж.AсR7жЋbд д~Xж.QрRGеЋbд д~Xж.AсR7еЋbд д~Xж.AсRGеЋbд д~Xж.AрRGеЋbд д~Xж.AсRGеЋbд г~hе.QрRGеЋbд д~Xж.AсRGеЋbд г~Xж.AсRGеЋbд д~Xж.AсR7жЋbд д~Xж.AсRGеЋbд д~Xж.AсR7еЋbд д~Xж.AсRGеЋbд д~Xж.AсR7еЋbд д~Xж.AсRGеЋbд г~hж.AрRGеЋbд д~Xж.AсRGеЋbд г~Xж.AсRGеЋbд д~Xж.AсRGеЋbд г~Xж.AсRGеЋbд д~Xж.AсR7еЋbд д~Xж.AсRGеЋbд д~Xж.AрRGеЋbд д~Xж.Aс0 spectemu-0.94/run.xbm0100644000175000017500000000353006521363201015051 0ustar cjwatsoncjwatson#define run_width 48 #define run_height 48 static unsigned char run_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x7e, 0x00, 0x40, 0x00, 0x0c, 0x20, 0xc6, 0x00, 0x20, 0x00, 0x0c, 0x20, 0xc6, 0x00, 0x10, 0x00, 0x0c, 0x20, 0xc6, 0x00, 0x08, 0x00, 0x0c, 0x20, 0x7e, 0x00, 0x10, 0x00, 0x0c, 0x20, 0x36, 0x00, 0x20, 0x00, 0x0c, 0x20, 0x66, 0x00, 0x40, 0x00, 0x0c, 0x20, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x20, 0xc6, 0x00, 0x00, 0x00, 0x0c, 0x20, 0xc6, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0xe0, 0x89, 0x22, 0x0c, 0x20, 0x00, 0x20, 0x8a, 0x26, 0x0c, 0x20, 0x00, 0x20, 0x8a, 0x2a, 0x0c, 0x20, 0x00, 0xe0, 0x89, 0x2a, 0x0c, 0x20, 0x00, 0xa0, 0x88, 0x32, 0x0c, 0x20, 0x00, 0x20, 0x89, 0x22, 0x0c, 0x20, 0x00, 0x20, 0x72, 0x22, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; spectemu-0.94/mkinstalldirs0100755000175000017500000000133106515377701016355 0ustar cjwatsoncjwatson#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$? fi if test ! -d "$pathcomp"; then errstatus=$lasterr fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here spectemu-0.94/xdispkb.c0100644000175000017500000002767606526652271015403 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "xdispkb.h" #include "xkey.h" #include "xscr.h" #include "spkey_p.h" #include "ax.h" #include "interf.h" #include #include #include #include #include const int need_switch_mode = 0; extern const unsigned long spectkey_size; extern unsigned char spectkey[]; static GC shadow_gc; static GC empty_gc; static Atom delete_atom; void (*spkb_event_processor)(void); #define NUMROWS 4 #define NUMCOLS 10 #define MY_MIN(a,b) ((a) < (b) ? (a) : (b)) #define MY_MAX(a,b) ((a) > (b) ? (a) : (b)) static int rowsta[NUMROWS]; static int rowend[NUMROWS]; static int colsta[NUMROWS][NUMCOLS]; static int colend[NUMROWS][NUMCOLS]; static int pressed[NUMROWS][NUMCOLS]; #define KB_WIDTH 640 #define KB_HEIGHT 344 static int halfc_ch; static int halfc_numhalfs; static unsigned halfc_ctr; static Window kbwin; static Pixmap kbpix; static int kb_displayed = 0; static int kb_on_top = 0; static int kb_mapped = 1; static const char *kb_title = "Spectemu: Keyboard of ZX Spectrum"; static const char *kb_iconname = "Keyboard"; spkeyboard kb_mkey; static void kb_expose(XEvent *ev, void *ptr) { XExposeEvent *eev; eev = &((*ev).xexpose); XCopyArea(xsp_disp, kbpix, kbwin, empty_gc, eev->x, eev->y, (unsigned) eev->width, (unsigned) eev->height, eev->x, eev->y); } static void visibility_event(XEvent *ev, void *ptr) { ptr = ptr; if((*ev).xvisibility.state == VisibilityUnobscured) kb_on_top = 1; else kb_on_top = 0; } static void map_event(XEvent *ev, void *ptr) { ptr = ptr; if(ev->type == MapNotify) kb_mapped = 1; else { clear_keystates(); kb_mapped = 0; } } static void key_call_kb(XEvent *ev, void *ptr) { if(!kb_mapped) return; key_call(ev); } struct buttonstate { int pressed; int i; int j; }; #define NUMBUTTONS 6 static void kb_button(XEvent *ev, void *ptr) { XButtonEvent *bev; int prow, pcol; static struct buttonstate bstate[NUMBUTTONS]; static int inited = 0; int i, j; int but; if(!inited) { inited = 1; for(i = 0; i < NUMBUTTONS; i++) bstate[i].pressed = 0; } spkb_state_changed = 1; bev = &((*ev).xbutton); but = bev->button; if(but >= NUMBUTTONS) return; if(ev->type == ButtonPress) { if(bstate[but].pressed) return; for(i = 0; i < NUMROWS; i++) if(rowsta[i] <= bev->y && rowend[i] > bev->y) break; if(i == NUMROWS) return; prow = i; for(i = 0; i < NUMCOLS; i++) if(colsta[prow][i] <= bev->x && colend[prow][i] > bev->x) break; if(i == NUMCOLS) return; pcol = i; if(pcol < 5) { i = 3 - prow; j = pcol; } else { i = 4 + prow; j = 9 - pcol; } bstate[but].pressed = 1; bstate[but].i = i; bstate[but].j = j; kb_mkey[i] |= 1 << j; } else { if(!bstate[but].pressed) return; SP_SETEMPTY(kb_mkey); bstate[but].pressed = 0; for(i = 0; i < NUMBUTTONS; i++) if(bstate[i].pressed) kb_mkey[bstate[i].i] |= 1 << bstate[i].j; } } void kb_refresh(void) { int i, j; byte *km, *kmo; byte kmd; byte nkm; static int lastmapped = 0; static spkeyboard oldstate; int keychanged; if(!kb_displayed) return; if(!kb_mapped) { lastmapped = 0; return; } if(!lastmapped) { for(i = 0; i < 8; i++) oldstate[i] = 0xFF; lastmapped = 1; } km = spkey_state; kmo = oldstate; for(i = 8; i; i--) { nkm = *km; kmd = nkm ^ *kmo; if(kmd) { for(j = 5; j; kmd >>= 1, nkm >>= 1, j--) if(kmd & 1) { int row, col; int x, y; unsigned w, h; if(i > 4) { row = i - 5; col = 5 - j; } else { row = 4 - i; col = j + 4; } x = colsta[row][col]; y = rowsta[row]; w = colend[row][col] - x; h = rowend[row] - y; keychanged = 0; if(nkm & 1) { if(!pressed[row][col]) { pressed[row][col] = 1; keychanged = 1; XCopyArea(xsp_disp, kbpix, kbpix, empty_gc, x, y, w, h, x+1, y+1); XFillRectangle(xsp_disp, kbpix, empty_gc, x, y, 1, h); XFillRectangle(xsp_disp, kbpix, empty_gc, x, y, w, 1); } } else { if(pressed[row][col]) { pressed[row][col] = 0; keychanged = 1; XCopyArea(xsp_disp, kbpix, kbpix, empty_gc, x+1, y+1, w, h, x, y); XFillRectangle(xsp_disp, kbpix, shadow_gc, x+(int)w, y+1, 1, h); XFillRectangle(xsp_disp, kbpix, shadow_gc, x+1, y+(int)h, w, 1); } } if(keychanged) XCopyArea(xsp_disp, kbpix, kbwin, empty_gc, x, y, w+1, h+1, x, y); } *kmo = *km; } km++, kmo++; } } static void init_gethalfc(void) { halfc_numhalfs = 0; halfc_ctr = 0; } static int gethalfc(void) { if(!halfc_numhalfs) { halfc_numhalfs = 1; if(halfc_ctr == spectkey_size) return -1; halfc_ch = spectkey[halfc_ctr++]; return (halfc_ch >> 4); } else { halfc_numhalfs = 0; return (halfc_ch & 0x0F); } } #define GETHC hc = gethalfc(); if(hc < 0) break static unsigned long kb_coltab[10] = {0, 9, 4, 11, 7, 8, 5, 10, 14, 15}; static void misc_event(XEvent *ev, void *ptr) { ptr = ptr; if(ev->type == ClientMessage) { /* If we get a client message which has the value of the delete * atom, it means the window manager wants us to die. */ if ((*ev).xclient.data.l[0] == (unsigned char) delete_atom) { XUnmapWindow(xsp_disp, kbwin); } } } static void destroy_kb() { XFreePixmap(xsp_disp, kbpix); XFreeGC(xsp_disp, empty_gc); XFreeGC(xsp_disp, shadow_gc); XDestroyWindow(xsp_disp, kbwin); kb_displayed = 0; } static int init_image() { int i,j; XImage *kbimage; char *kbimage_data; XGCValues values; unsigned long valuemask; XSetWindowColormap(xsp_disp, kbwin, xsp_cmap); kbimage_data = (char *) malloc((unsigned) (xsp_bpp * KB_WIDTH * KB_HEIGHT / 8)); if(kbimage_data == NULL) { destroy_kb(); put_msg("Failed to allocate memory for keyboard image"); return 0; } kbimage = XCreateImage(xsp_disp, xsp_visual, xsp_depth, ZPixmap, 0, kbimage_data, KB_WIDTH, KB_HEIGHT, 32, 0); init_gethalfc(); i = 0; for(;;) { int hc; int numeq; GETHC; else if(hc <= 9) numeq = 1; else if(hc <= 13) { numeq = hc-7; GETHC; } else if(hc == 14) { GETHC; numeq = hc + 7; GETHC; } else { GETHC; numeq = hc; GETHC; numeq |= (hc << 4); GETHC; numeq |= (hc << 8); GETHC; } for(; numeq; numeq--) { XPutPixel(kbimage, i % KB_WIDTH, i / KB_WIDTH, xsp_colors[kb_coltab[hc]]); i++; } } valuemask = GCForeground; values.foreground = xsp_colors[7]; XChangeGC(xsp_disp, shadow_gc, valuemask, &values); values.foreground = xsp_colors[0]; XChangeGC(xsp_disp, empty_gc, valuemask, &values); XPutImage(xsp_disp, kbpix, empty_gc, kbimage, 0, 0, 0, 0, KB_WIDTH, KB_HEIGHT); XDestroyImage(kbimage); for(j = 0; j < NUMROWS; j++) for(i = 0; i < NUMCOLS; i++) pressed[j][i] = 0; return 1; } void kb_refresh_colormap(void) { if(kb_displayed) { init_image(); XCopyArea(xsp_disp, kbpix, kbwin, empty_gc, 0, 0, KB_WIDTH, KB_HEIGHT, 0, 0); } } int display_keyboard(void) { int i, j; int start; Atom proto_atom; unsigned long valuemask; XGCValues values; XWMHints *wm_hints; XTextProperty window_name, *wnp; XTextProperty icon_name, *inp; if(kb_displayed) { if(!kb_mapped /* || !kb_on_top */) XMapRaised(xsp_disp, kbwin); else XUnmapWindow(xsp_disp, kbwin); return 1; } kbwin = XCreateSimpleWindow(xsp_disp, RootWindow(xsp_disp, xsp_scr), 0,0, KB_WIDTH, KB_HEIGHT, 0, 0, BlackPixel(xsp_disp, xsp_scr)); wm_hints = XAllocWMHints(); if(wm_hints != NULL) { wm_hints->input = True; wm_hints->initial_state = NormalState; wm_hints->flags = InputHint | StateHint; } wnp = &window_name; if(!XStringListToTextProperty((char **) &kb_title, 1, wnp)) wnp = NULL; inp = &icon_name; if(!XStringListToTextProperty((char **) &kb_iconname, 1, inp)) inp = NULL; XSetWMProperties(xsp_disp, kbwin, wnp, inp, NULL, 0, NULL /* size_hints */, wm_hints, NULL /* class_hints */); if(wm_hints != NULL) XFree((void *) wm_hints); /* Delete-Window-Message black magic copied from xloadimage. */ proto_atom = XInternAtom(xsp_disp,"WM_PROTOCOLS", False); delete_atom = XInternAtom(xsp_disp,"WM_DELETE_WINDOW", False); if ((proto_atom != None) && (delete_atom != None)) { XChangeProperty(xsp_disp, kbwin, proto_atom, XA_ATOM, 32, PropModePrepend, (unsigned char*)&delete_atom, 1); } valuemask = GCGraphicsExposures; values.graphics_exposures = False; shadow_gc = XCreateGC(xsp_disp, kbwin, valuemask, &values); empty_gc = XCreateGC(xsp_disp, kbwin, valuemask, &values); kbpix = XCreatePixmap(xsp_disp, kbwin, KB_WIDTH, KB_HEIGHT, xsp_depth); if(!init_image()) return 0; start = 90; for(i = 0; i < NUMROWS; i++) { rowsta[i] = start; rowend[i] = start+24; start += 56; } for(j = 0; j < 3; j++) { switch(j) { case 0: start = 37; break; case 1: start = 64; break; case 2: start = 76; break; } for(i = 0; i < NUMCOLS; i++) { colsta[j][i] = start; colend[j][i] = start+38; start += 55; } } start = 37; colsta[3][0] = start; colend[3][0] = start+49; start += 66; for(i = 1; i < NUMCOLS - 1; i++) { colsta[3][i] = start; colend[3][i] = start+38; start += 55; } colsta[3][9] = start; colend[3][9] = start+66; aX_add_event_proc(xsp_disp, kbwin, Expose, kb_expose, ExposureMask, NULL); aX_add_event_proc(xsp_disp, kbwin, ButtonPress, kb_button, ButtonPressMask, NULL); aX_add_event_proc(xsp_disp, kbwin, ButtonRelease, kb_button, ButtonReleaseMask, NULL); aX_add_event_proc(xsp_disp, kbwin, ClientMessage, misc_event, 0, NULL); aX_add_event_proc(xsp_disp, kbwin, FocusIn, xkey_focus_change_call, FocusChangeMask, NULL); aX_add_event_proc(xsp_disp, kbwin, FocusOut, xkey_focus_change_call, FocusChangeMask, NULL); aX_add_event_proc(xsp_disp, kbwin, KeyPress, key_call_kb, KeyPressMask, NULL); aX_add_event_proc(xsp_disp, kbwin, KeyRelease, key_call_kb, KeyReleaseMask, NULL); aX_add_event_proc(xsp_disp, kbwin, VisibilityNotify, visibility_event, VisibilityChangeMask, NULL); aX_add_event_proc(xsp_disp, kbwin, ConfigureNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, CirculateNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, CreateNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, GravityNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, ReparentNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, DestroyNotify, misc_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, MapNotify, map_event, StructureNotifyMask, NULL); aX_add_event_proc(xsp_disp, kbwin, UnmapNotify, map_event, StructureNotifyMask, NULL); XMapWindow(xsp_disp, kbwin); kb_displayed = 1; return 1; } spectemu-0.94/spconf.c0100644000175000017500000004061306526331304015200 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "spconf_p.h" #include "spver.h" #include "misc.h" #include "interf.h" #include "spscr_p.h" #include "spkey.h" #include "snapshot.h" /* for SN_Z80 and SN_SNA */ #include "tapefile.h" /* for TAP_TAP and TAP_TZX */ #include #include #include #include #include extern const char *spcf_keynames_ascii[]; extern const char *spcf_keynames_misc[]; char *spcf_init_snapshot = NULL; int spcf_init_snapshot_type; char *spcf_init_tapefile = NULL; int spcf_init_tapefile_type; #define MAXLINELEN 512 static int linectr; static FILE *conffp; static const char *conffile; static void strip_spaces(char **sp) { char *s; s = *sp; while(isspace(*s)) s++; *sp = s; return; } int spcf_parse_conf_line(char *line, char **attrp, char **valp) { char *s; for(s = line; *s; s++) if(*s == '#') { *s = '\0'; break; } for(s--; s >= line && isspace(*s); s--) *s = '\0'; s = line; if(!*s) return 0; strip_spaces(&s); if(!isalpha(*s)) return -1; *attrp = s; for(; *s; s++) if(!isalnum(*s) && *s != '_' && *s != '-') break; if(!*s) return -1; if(isspace(*s)) { *s='\0'; s++; strip_spaces(&s); } if(*s != '=') return -1; *s='\0'; s++; strip_spaces(&s); if(!*s) return -1; *valp = s; return 1; } static int read_conf_line(char **attrp, char **valp) { char *res; int ret; static char line[MAXLINELEN]; do { linectr++; res = fgets(line, MAXLINELEN, conffp); if(res == NULL) return 0; if(line[0] && line[strlen(line)-1] != '\n') { int c; c = getc(conffp); if(c == EOF) fprintf(stderr, "%s: File does not end with a newline\n", conffile); else fprintf(stderr, "%s:%i: Line too long\n", conffile ,linectr); while(c != EOF && c != '\n') c = getc(conffp); ret = -1; } else { ret = spcf_parse_conf_line(line, attrp, valp); if(ret < 0) fprintf(stderr, "%s:%i: Parse error\n", conffile, linectr); } } while(ret <= 0); return 1; } static const char *vgamodes[] = { "320x240", "320x200", NULL }; static const char *keybtypes[] = { "extended", "spectrum", "compat", "custom", NULL }; static const char *curstypes[] = { "shifted", "raw", "joystick", NULL }; static const char *colrtypes[] = { "normal", "grayscale", "custom", NULL }; static const char *modifkeys[] = { "none", "shift", "lock", "control", "alt", "mod2", "mod3", "mod4", "mod5", NULL }; struct sp_options spcf_options[] = { {"frameSkip", SA_INT, &showframe, NULL, 1 }, {"rr", SA_INT, &showframe, NULL, 0 }, {"scale", SA_INT, &scrmul, NULL, 1 }, {"privateMap", SA_BOOL, &privatemap, NULL, 1 }, {"mitShm", SA_BOOL, &use_shm, NULL, 1 }, {"vgaMode", SA_ENUM, &small_screen, vgamodes, 1 }, {"sound", SA_BOOL, &sound_on, NULL, 1 }, {"soundDelay", SA_INT, &bufframes, NULL, 1 }, {"soundDevice", SA_STR, &sound_dev_name, NULL, 1 }, {"audioDev", SA_STR, &sound_dev_name, NULL, 0 }, {"soundSampleRate", SA_INT, &sound_sample_rate, NULL, 1 }, {"soundAutoclose", SA_BOOL, &sound_to_autoclose, NULL, 1 }, {"soundDspSetfrag", SA_BOOL, &sound_dsp_setfrag, NULL, 0 }, {"keyboardType", SA_ENUM, &keyboard_type, keybtypes, 1 }, {"cursorType", SA_ENUM, &cursor_type, curstypes, 1 }, {"allowAscii", SA_BOOL, &spkb_allow_ascii, NULL, 0 }, {"trueShift", SA_ENUM, &spkb_trueshift, modifkeys, 0 }, {"funcShift", SA_ENUM, &spkb_funcshift, modifkeys, 0 }, {"colorType", SA_ENUM, &color_type, colrtypes, 1 }, {"pauseOnIconify", SA_BOOL, &pause_on_iconify, NULL, 1 }, {"vgaPauseBg", SA_BOOL, &vga_pause_bg, NULL, 1 }, {"quickLoad", SA_BOOL, &sp_quick_load, NULL, 1 }, {"autoStop", SA_BOOL, &spt_auto_stop, NULL, 1 }, {"loadImmed", SA_BOOL, &load_immed, NULL, 1 }, {"pause", SA_BOOL, &sp_paused, NULL, 1 }, {NULL, 0, NULL, NULL, 0 } }; static int file_type = -1; static int file_subtype; struct ext_type { const char *ext; int type; int subtype; }; static struct ext_type extensions[] = { {"z80", FT_SNAPSHOT, SN_Z80}, {"sna", FT_SNAPSHOT, SN_SNA}, {"tzx", FT_TAPEFILE, TAP_TZX}, {"tap", FT_TAPEFILE, TAP_TAP}, {NULL, 0, 0} }; int spcf_find_file_type(char *filename, int *ftp, int *ftsubp) { int i; int found; if(*ftp >= 0 && *ftsubp >= 0) return 1; found = 0; for(i = 0; extensions[i].ext != NULL; i++) if((*ftp < 0 || *ftp == extensions[i].type) && (*ftsubp < 0 || *ftsubp == extensions[i].subtype) && check_ext(filename, extensions[i].ext)) { found = 1; *ftp = extensions[i].type; *ftsubp = extensions[i].subtype; break; } if(!found) for(i = 0; extensions[i].ext != NULL; i++) if((*ftp < 0 || *ftp == extensions[i].type) && (*ftsubp < 0 || *ftsubp == extensions[i].subtype) && try_extension(filename, extensions[i].ext)) { found = 1; *ftp = extensions[i].type; *ftsubp = extensions[i].subtype; break; } return found; } static int find_extension(const char *ext) { int i; for(i = 0; extensions[i].ext != NULL; i++) if(strcmp(extensions[i].ext, ext) == 0) return i; return -1; } static const char *spco[] = { "help", "version", NULL }; #define OPT_HELP 0 #define OPT_VERSION 1 static char *progname; static int atcol; #define MAXCOL 70 #define STTAB " " static void putopt(const char *opt) { if(atcol + strlen(opt) + 2 >= MAXCOL) { fprintf(stderr, "\n"); atcol = 0; } if(!atcol) fprintf(stderr, STTAB); fprintf(stderr, "%s, ", opt); atcol += strlen(opt) + 2; } static void makeopt(char *optstr, const char *instr) { *optstr++ = '-'; for(; *instr; instr++) { if(isupper(*instr)) { *optstr++ = '-'; *optstr++ = tolower(*instr); } else *optstr++ = *instr; } *optstr = '\0'; } static void usage(void) { char optionstr[128]; int i, j; fprintf(stderr, "usage: %s [options] [[filetype] filename]\n\n", progname); fprintf(stderr, "The following file types can be specified:\n"); atcol = 0; for(i = 0; extensions[i].ext != NULL; i++) { makeopt(optionstr, extensions[i].ext); putopt(optionstr); } fprintf(stderr, "\n\n"); fprintf(stderr, "The following options are available:\n"); atcol = 0; for(i = 0; spco[i] != NULL; i++) { makeopt(optionstr, spco[i]); putopt(optionstr); } for(i = 0; spcf_options[i].option != NULL; i++) if(spcf_options[i].disp) switch(spcf_options[i].argtype) { case SA_BOOL: /* makeopt(optionstr, spcf_options[i].option); putopt(optionstr); */ strcpy(optionstr, "[-no]"); makeopt(optionstr+5, spcf_options[i].option); putopt(optionstr); break; case SA_INT: makeopt(optionstr, spcf_options[i].option); strcat(optionstr, " NUM"); putopt(optionstr); break; case SA_ENUM: makeopt(optionstr, spcf_options[i].option); strcat(optionstr, " <"); for(j = 0; spcf_options[i].enums[j] != NULL; j++) { strcat(optionstr, spcf_options[i].enums[j]); strcat(optionstr, " "); } optionstr[strlen(optionstr)-1] = '>'; putopt(optionstr); break; case SA_STR: makeopt(optionstr, spcf_options[i].option); strcat(optionstr, " NAME"); putopt(optionstr); break; } fprintf(stderr, "\n"); } static void process_option(int ix, int pre) { pre = pre; switch(ix) { case OPT_HELP: usage(); exit(0); break; case OPT_VERSION: fprintf(stderr, "%s\n", SPECTEMU_VERSION); exit(0); break; } } #define MAXATTRLEN 32 static int match_attr(const char *attr, int onlybool) { int i; int nu; static char compa[MAXATTRLEN]; nu = 0; for(i = 0; *attr && i < MAXATTRLEN - 1; attr++) { if(*attr == '-') { if(nu) return -1; nu = 1; } else if(nu) nu = 0, compa[i++] = toupper(*attr); else compa[i++] = tolower(*attr); } if(nu) return -1; compa[i] = '\0'; for(i = 0; spcf_options[i].option != NULL; i++) if((!onlybool || spcf_options[i].argtype == SA_BOOL) && strcmp(spcf_options[i].option, compa) == 0) return i; return -1; } static int match_numbered(const char *attr, const char *beg, int maxnum) { size_t blen; int num; blen = strlen(beg); if(strncmp(attr, beg, blen) == 0) { const char *ns; int nd; ns = attr+blen; nd = 0; for(; *ns; nd++, ns++) if(!isdigit(*ns)) return -1; if(nd > 0 && nd < 6 && sscanf(attr+blen, "%d", &num) == 1 && num >= 0 && num <= maxnum) return num; } return -1; } int spcf_match_keydef(const char *attr, const char *beg) { size_t blen; blen = strlen(beg); if(strncmp(attr, beg, blen) == 0) { int i; const char *kn; kn = attr+blen; for(i = 32; i < 127; i++) if(strcmp(kn, spcf_keynames_ascii[i-32]) == 0) return i; for(i = 0; i < 256; i++) if(spcf_keynames_misc[i] != NULL && strcmp(kn, spcf_keynames_misc[i]) == 0) return i+0x100; } return -1; } static int match_option(const char *attr) { int i; for(i = 0; spco[i] != NULL; i++) if(strcmp(spco[i], attr) == 0) return i; return -1; } static int eqcstr(const char *s, const char *t) { for(; *s || *t; s++, t++) if(tolower(*s) != *t) return 0; return 1; } static int istrue(const char *s) { if(eqcstr(s, "true") || eqcstr(s, "yes") || eqcstr(s, "on") || eqcstr(s, "1")) return 1; return 0; } static int isfalse(const char *s) { if(eqcstr(s, "false") || eqcstr(s, "no") || eqcstr(s, "off") || eqcstr(s, "0")) return 1; return 0; } void spcf_set_val(int ix, const char *val, const char *name, int ctr, int fatal) { int res; long lv; int i; const char **es; int quiet; int *ip; char **cp; ip = (int *) spcf_options[ix].argvalp; cp = (char **) spcf_options[ix].argvalp; if(name == NULL) quiet = 1; else quiet = 0; switch(spcf_options[ix].argtype) { case SA_INT: res = sscanf(val, "%ld", &lv); if(res == 1) *ip = (int) lv; else if(!quiet) { fprintf(stderr, "%s:%i: Illegal value '%s', expected integer\n", name, ctr, val); if(fatal) exit(1); } break; case SA_BOOL: res = 0; if(istrue(val)) lv = 1, res = 1; else if(isfalse(val)) lv = 0, res = 1; else if(!quiet) { fprintf(stderr, "%s:%i: Illegal value '%s', expected " "'true' or 'false'\n", name, ctr, val); if(fatal) exit(1); } if(res) *ip = (int) lv; break; case SA_ENUM: res = 0; es = spcf_options[ix].enums; for(i = 0; es[i] != NULL; i++) if(strcmp(val, es[i]) == 0) { res = 1; break; } if(res) *ip = i; else if(!quiet) { fprintf(stderr, "%s:%i: Illegal value '%s', expected ", name, ctr, val); for(i = 0; es[i] != NULL;) { fprintf(stderr, "'%s'", es[i]); if(es[++i] != NULL) fprintf(stderr, " or "); } fprintf(stderr, "\n"); if(fatal) exit(1); } break; case SA_STR: *cp = make_string(*cp, val); break; } } void spcf_set_color(int ix, const char *val, const char *name, int ctr, int fatal) { int r, g, b; int res; int quiet; if(name == NULL) quiet = 1; else quiet = 0; res = sscanf(val, "%d %d %d", &r, &g, &b); if(res != 3 || r < 0 || r > 63 || g < 0 || g > 63 || b < 0 || b > 63) { if(!quiet) { fprintf(stderr, "%s:%i: Illegal rgb values: '%s'\n", name, ctr, val); if(fatal) exit(1); } } else { custom_colors[ix].r = r; custom_colors[ix].g = g; custom_colors[ix].b = b; } } #define MAXSPKEYNAME 32 void spcf_set_key(int ix, const char *val, const char *name, int ctr, int fatal) { int quiet; char spkeyname[MAXSPKEYNAME+1]; int len; if(name == NULL) quiet = 1; else quiet = 0; if(!spkey_new_custom(ix)) { if(!quiet) { fprintf(stderr, "%s:%i: Custom key table full\n", name, ctr); if(fatal) exit(1); } return; } while(*val) { for(len = 0; val[len] && !isspace(val[len]); len++); if(len > MAXSPKEYNAME) len = MAXSPKEYNAME; strncpy(spkeyname, val, (size_t) len); spkeyname[len] = '\0'; if(!spkey_add_custom(spkeyname)) { if(!quiet) { fprintf(stderr, "%s:%i: Illegal key name: '%s'\n", name, ctr, spkeyname); if(fatal) exit(1); } } val += len; while(isspace(*val)) val++; } } void spcf_pre_check_options(int argc, char *argv[]) { progname = get_base_name(argv[0]); if(argc > 1 && argv[1][0] == '-') { int ix; ix = match_option(argv[1]+1); if(ix >= 0) process_option(ix, 1); } } void spcf_read_command_line(int argc, char *argv[]) { int a; int ix; int bval; for(a = 1; a < argc; a++) { if(argv[a][0] == '-') { if(file_type >= 0) { fprintf(stderr, "File name expected after option '%s'\n", argv[a-1]); exit(1); } bval = 1; if(strncmp(argv[a]+1, "no-", 3) == 0) { bval = 0; ix = match_attr(argv[a]+4, 1); } else ix = match_attr(argv[a]+1, 0); if(ix >= 0) { if(spcf_options[ix].argtype == SA_BOOL) *((int *) spcf_options[ix].argvalp) = (int) bval; else { if(a+1 < argc) a++, spcf_set_val(ix, argv[a], "Command line", a, 1); else { fprintf(stderr, "Option '%s', argument expected\n", argv[a]); exit(1); } } } else { ix = match_option(argv[a]+1); if(ix >= 0) process_option(ix, 0); else { ix = find_extension(argv[a]+1); if(ix >= 0) { if(a + 1 == argc) { fprintf(stderr, "File name expected after option '%s'\n", argv[a]); exit(1); } file_type = extensions[ix].type; file_subtype = extensions[ix].subtype; } else { fprintf(stderr, "Option '%s' not recognized\n", argv[a]); fprintf(stderr, "Use '-help' to see valid options\n"); exit(1); } } } } else { /* Does not start with '-' */ strncpy(filenamebuf, argv[a], MAXFILENAME - 10); filenamebuf[MAXFILENAME-10] = '\0'; if(file_type < 0) file_subtype = -1; if(!spcf_find_file_type(filenamebuf, &file_type, &file_subtype)) { fprintf(stderr, "Can't determine file type of '%s'\n", filenamebuf); exit(1); } if(file_type == FT_SNAPSHOT) { spcf_init_snapshot = make_string(spcf_init_snapshot, filenamebuf); spcf_init_snapshot_type = file_subtype; } else if(file_type == FT_TAPEFILE) { spcf_init_tapefile = make_string(spcf_init_tapefile, filenamebuf); spcf_init_tapefile_type = file_subtype; } file_type = -1; } } } int spcf_read_conf_file(const char *filename) { int res; char *attr, *val; conffile = filename; conffp = fopen(conffile, "rt"); if(conffp == NULL) { fprintf(stderr, "Could not open file %s: %s\n", conffile, strerror(errno)); return -1; } linectr = 0; for(;;) { int ix; res = read_conf_line(&attr, &val); if(res <= 0) break; ix = match_attr(attr, 0); if(ix >= 0) spcf_set_val(ix, val, conffile, linectr, 0); else { ix = match_numbered(attr, "color", COLORNUM-1); if(ix >= 0) spcf_set_color(ix, val, conffile, linectr, 0); else { ix = spcf_match_keydef(attr, "Key_"); if(ix >= 0) spcf_set_key(ix, val, conffile, linectr, 0); else fprintf(stderr, "%s:%i: Unknown attribute '%s'\n", conffile, linectr, attr); } } } fclose(conffp); return res; } spectemu-0.94/xutils.c0100644000175000017500000001662306526532771015257 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* #define DEBUG_COLOR */ #include "xscr.h" #include "spscr.h" #include "spscr_p.h" #include "ax.h" #include "xdispkb.h" #include "spperif.h" #include "interf.h" #include "spconf_p.h" #include #include #include #include #include #include #include #define MAX_SEARCH_DEPTH 8 int privatemap = 0; static unsigned cdist(XColor *c1, XColor *c2) { int dr, dg, db; dr = (c1->red - c2->red) >> 8; dg = (c1->green - c2->green) >> 8; db = (c1->blue - c2->blue) >> 8; return dr * dr + dg * dg + db * db; } static int already_alloced(pixt *colors, int num, pixt pix) { int i; for(i = 0; i < num; i++) if(colors[i] == pix) return 1; return 0; } #define MYINF ((unsigned) -1) static int search_colors(Colormap cmap, unsigned dp) { int c; XColor xcolor, tmpcolor; pixt pix; XColor *scrcolors = NULL; unsigned ncolors = 0; unsigned dist, mindist; pixt minpix; int failed = 0, lfailed; int fails[COLORNUM]; if(dp < 4) failed = 1; if(!failed) { if(dp <= MAX_SEARCH_DEPTH) { ncolors = 1 << dp; scrcolors = malloc(sizeof(XColor) * ncolors); if(scrcolors != NULL) { for(pix = 0; pix < ncolors; pix++) scrcolors[pix].pixel = pix; XQueryColors(xsp_disp, cmap, scrcolors, (int) ncolors); } } for(c = 0; c < COLORNUM; c++) { xcolor.red = spscr_crgb[c].r << 10; xcolor.green = spscr_crgb[c].g << 10; xcolor.blue = spscr_crgb[c].b << 10; lfailed = 0; if(!XAllocColor(xsp_disp, cmap, &xcolor) || already_alloced(xsp_colors, c, xcolor.pixel)) { if(scrcolors != NULL) { #ifdef DEBUG_COLOR fprintf(stderr, "XAllocColor failed, searching all colors...\n"); #endif mindist = MYINF; for(pix = 0; pix < ncolors; pix++) { dist = cdist(&scrcolors[pix], &xcolor); if(dist < mindist) { tmpcolor.red = scrcolors[pix].red; tmpcolor.green = scrcolors[pix].green; tmpcolor.blue = scrcolors[pix].blue; if(XAllocColor(xsp_disp, cmap, &tmpcolor) && !already_alloced(xsp_colors, c, tmpcolor.pixel)) { if(mindist != MYINF) XFreeColors(xsp_disp, cmap, &minpix, 1, 0); mindist = dist; minpix = pix; } } } if(mindist == MYINF) { lfailed = 1; #ifdef DEBUG_COLOR fprintf(stderr, "Search failed\n"); #endif } else xsp_colors[c] = minpix; } else { #ifdef DEBUG_COLOR fprintf(stderr, "XAllocColor failed\n"); #endif lfailed = 1; } } else xsp_colors[c] = xcolor.pixel; if(lfailed) { fails[c] = 1; failed = 1; } else fails[c] = 0; #ifdef DEBUG_COLOR tmpcolor.pixel = xsp_colors[c]; XQueryColor(xsp_disp, cmap, &tmpcolor); fprintf(stderr, "Color %2i (%3i %3i %3i) -> Pixel %5lu (%3i %3i %3i)\n", c, spscr_crgb[c].r, spscr_crgb[c].g, spscr_crgb[c].b, xsp_colors[c], tmpcolor.red>>10, tmpcolor.green>>10, tmpcolor.blue>>10); #endif } if(failed) { for(c = 0; c < COLORNUM; c++) { if(!fails[c]) XFreeColors(xsp_disp, cmap, &xsp_colors[c], 1, 0); xsp_colors[c] = c; } } } if(scrcolors != NULL) free(scrcolors); if(failed) return 0; return 1; } static int firstalloced = 1; static int currprivate; int allocate_colors(void) { int color_res; Colormap defcmap; if(!firstalloced && !currprivate) XFreeColors(xsp_disp, xsp_cmap, xsp_colors, COLORNUM, 0); defcmap = DefaultColormap(xsp_disp, xsp_scr); color_res = search_colors(defcmap, xsp_depth); if((!color_res || privatemap) && (xsp_visual->class == PseudoColor || xsp_visual->class == GrayScale)) { XColor xcolor; int c; if(color_res) XFreeColors(xsp_disp, defcmap, xsp_colors, COLORNUM, 0); if(firstalloced || !currprivate) xsp_cmap = XCreateColormap(xsp_disp, xsp_win, xsp_visual, AllocAll); if(xsp_depth <= MAX_SEARCH_DEPTH) { /* Is this good? */ for(c = 0; c < (1 << xsp_depth); c++) { xcolor.pixel = c; XQueryColor(xsp_disp, defcmap, &xcolor); XStoreColor(xsp_disp, xsp_cmap, &xcolor); } } for(c = 0; c < COLORNUM; c++) { xcolor.pixel = xsp_colors[c]; xcolor.red = spscr_crgb[c].r << 10; xcolor.green = spscr_crgb[c].g << 10; xcolor.blue = spscr_crgb[c].b << 10; xcolor.flags = DoRed | DoGreen | DoBlue; XStoreColor(xsp_disp, xsp_cmap, &xcolor); } color_res = 1; currprivate = 1; } else { if(!firstalloced && currprivate) XFreeColormap(xsp_disp, xsp_cmap); xsp_cmap = defcmap; currprivate = 0; } firstalloced = 0; return color_res; } void spscr_refresh_colors(void) { if(!allocate_colors()) put_msg("Could not allocate colors"); kb_refresh_colormap(); XSetWindowColormap(xsp_disp, xsp_win, xsp_cmap); XSetWindowBackground(xsp_disp, xsp_win, xsp_colors[7]); XInstallColormap(xsp_disp, xsp_cmap); spxs_init_color(); sp_init_screen_mark(); } #define MAX_RES_NAME 64 #define MAXLINELEN 512 void spcf_read_xresources(void) { int i; char resname[MAX_RES_NAME], resclass[MAX_RES_NAME]; char line[MAXLINELEN+1]; char *val; resname[0] = '.'; resclass[0] = '.'; resname[MAX_RES_NAME-1] = '\0'; resclass[MAX_RES_NAME-1] = '\0'; for(i = 0; spcf_options[i].option != NULL; i++) { strncpy(resname+1, spcf_options[i].option, MAX_RES_NAME-2); strncpy(resclass+1, spcf_options[i].option, MAX_RES_NAME-2); resclass[1] = toupper(resclass[1]); val = aX_get_prog_res(resname, resclass); if(val != NULL) spcf_set_val(i, val, NULL, 0, 0); } strcpy(resname+1, "color"); strcpy(resclass+1, "Color"); for(i = 0; i < COLORNUM; i++) { sprintf(resname+6, "%i", i); sprintf(resclass+6, "%i", i); val = aX_get_prog_res(resname, resclass); if(val != NULL) spcf_set_color(i, val, NULL, 0, 0); } strcpy(resname+1, "keys"); strcpy(resclass+1, "Keys"); val = aX_get_prog_res(resname, resclass); if(val != NULL) { char *ival, *attr; int l; while(*val) { for(i = 0; val[i] && val[i] != ';'; i++); l = i; if(i > MAXLINELEN) i = MAXLINELEN; strncpy(line, val, (size_t) i); line[i] = '\0'; if(spcf_parse_conf_line(line, &attr, &ival)) { int ix; ix = spcf_match_keydef(attr, ""); if(ix >= 0) spcf_set_key(ix, ival, NULL, 0, 0); } if(!val[l]) break; val += (l+1); } } } spectemu-0.94/example.cfg0100644000175000017500000001035406526102044015654 0ustar cjwatsoncjwatson# This is an example configuration file for spectemu. # # The options shown here are the default values. If you want to change # an option to some other value, copy the option to either ~/.spectemurc, # or to spectemu.cfg. ## --------------------- ## Generic options ## --------------------- frame-skip = 2 pause = false ## --------------------- ## X options ## --------------------- scale = 2 private-map = false mit-shm = true pause-on-iconify = false ## --------------------- ## vga options ## --------------------- vga-mode = 320x240 # 320x200 is somewhat faster vga-pause-bg = false ## --------------------- ## tape options ## --------------------- quick-load = false load-immed = false # auto-stop = false ## --------------------- ## sound options ## --------------------- sound = true sound-delay = 4 sound-device = /dev/dsp sound-sample-rate = 15625 sound-autoclose = true sound-dsp-setfrag = true # Set this to false for PCSND ## --------------------- ## keyboard options ## --------------------- keyboard-type = extended # extended, spectrum, compat, custom cursor-type = shifted # shifted, normal, joystick allow-ascii = true true-shift = alt # none, shift, lock, control, alt, mod2, # mod3, mod4, mod5 func-shift = control # # Definition of the extended keyboard (excluding letters and numbers). # Of course you can specify more 'Key_'-s here (see spkey_p.h for # a complete list) Key_space = space Key_Return = enter Key_KP_Enter = enter Key_Shift_L = capsshift Key_Shift_R = symbolshift Key_BackSpace = capsshift 0 Key_Delete = capsshift 0 Key_Escape = capsshift 1 # Definition of spectrum keyboard type (in addition to the extended keyboard) # Key_comma = symbolshift # Key_period = space # Key_semicolon = enter # Definition of compat keyboard type (in addition to the extended keyboard) # Key_Shift_L = capsshift # Key_Shift_R = capsshift # Key_Alt_L = symbolshift # Key_Alt_R = symbolshift # Key_Meta_L = symbolshift # Key_Meta_R = symbolshift # # true-shift = none # Definition of shifted cursor keys: # Key_Left = capsshift 5 # Key_KP_Left = capsshift 5 # Key_Down = capsshift 6 # Key_KP_Down = capsshift 6 # Key_Up = capsshift 7 # Key_KP_Up = capsshift 7 # Key_Right = capsshift 8 # Key_KP_Right = capsshift 8 # Definition of raw cursor keys: # Key_Left = 5 # Key_KP_Left = 5 # Key_Down = 6 # Key_KP_Down = 6 # Key_Up = 7 # Key_KP_Up = 7 # Key_Right = 8 # Key_KP_Right = 8 # Definition of the joystick keys: # Key_Left = kempston_left # Key_KP_Left = kempston_left # Key_Down = kempston_down # Key_KP_Down = kempston_down # Key_Up = kempston_up # Key_KP_Up = kempston_up # Key_Right = kempston_right # Key_KP_Right = kempston_right # # Key_Insert = kempston_fire # Key_KP_Insert = kempston_fire # Key_KP_Delete = kempston_fire # # Key_Home = kempston_up kempston_left # Key_KP_Home = kempston_up kempston_left # Key_Page_Up = kempston_up kempston_right # Key_KP_Page_Up = kempston_up kempston_right # Key_End = kempston_down kempston_left # Key_KP_End = kempston_down kempston_left # Key_Page_Down = kempston_down kempston_right # Key_KP_Page_Down = kempston_down kempston_right ## --------------------- ## colour options ## --------------------- color-type = normal # normal, grayscale or custom # Custom colour definition (normal) color0 = 0 0 0 color1 = 4 4 52 color2 = 52 4 4 color3 = 52 4 52 color4 = 4 52 4 color5 = 4 52 52 color6 = 52 52 4 color7 = 52 52 52 color8 = 21 21 21 color9 = 8 8 63 color10 = 63 8 8 color11 = 63 8 63 color12 = 8 63 8 color13 = 8 63 63 color14 = 63 63 8 color15 = 63 63 63 # Custom colour definition (gray-scale) # # color0 = 0 0 0 # color1 = 20 20 20 # color2 = 26 26 26 # color3 = 32 32 32 # color4 = 38 38 38 # color5 = 44 44 44 # color6 = 50 50 50 # color7 = 56 56 56 # # color8 = 21 21 21 # color9 = 23 23 23 # color10 = 30 30 30 # color11 = 36 36 36 # color12 = 43 43 43 # color13 = 50 50 50 # color14 = 56 56 56 # color15 = 63 63 63 # # End of example.cfg # spectemu-0.94/spconf_p.h0100644000175000017500000000414606526063524015533 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPCONF_P_H #define SPCONF_P_H #include "spconf.h" struct sp_options { const char *option; int argtype; void *argvalp; const char **enums; int disp; }; extern struct sp_options spcf_options[]; #define SA_BOOL 1 #define SA_INT 2 #define SA_STR 3 #define SA_ENUM 4 extern int showframe; extern int scrmul; extern int privatemap; extern int use_shm; extern int small_screen; extern int sound_on; extern int bufframes; extern const char *sound_dev_name; extern int sound_sample_rate; extern int sound_to_autoclose; extern int sound_dsp_setfrag; extern int keyboard_type; extern int cursor_type; extern int color_type; extern int pause_on_iconify; extern int vga_pause_bg; extern int sp_quick_load; extern int sp_paused; extern int load_immed; extern int spt_auto_stop; extern int spkb_allow_ascii; extern int spkb_trueshift; extern int spkb_funcshift; extern void spcf_set_val(int ix, const char *val, const char *name, int ctr, int fatal); extern void spcf_set_color(int ix, const char *val, const char *name, int ctr, int fatal); extern void spcf_set_key(int ix, const char *val, const char *name, int ctr, int fatal); extern int spcf_match_keydef(const char *attr, const char *beg); extern int spcf_parse_conf_line(char *line, char **attrp, char **valp); #endif /* SPCONF_P_H */ spectemu-0.94/pause.xbm0100644000175000017500000000353606521363161015375 0ustar cjwatsoncjwatson#define pause_width 48 #define pause_height 48 static unsigned char pause_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x8c, 0x01, 0x00, 0x00, 0x0c, 0x20, 0x8c, 0x01, 0x00, 0x00, 0x0c, 0x20, 0xdc, 0x01, 0x00, 0x00, 0x0c, 0x20, 0xdc, 0x01, 0x60, 0x00, 0x0c, 0x20, 0xfc, 0x01, 0x60, 0x00, 0x0c, 0x20, 0xfc, 0x01, 0x00, 0x00, 0x0c, 0x20, 0xac, 0x01, 0x00, 0x00, 0x0c, 0x20, 0xac, 0x01, 0x00, 0x00, 0x0c, 0x20, 0xac, 0x01, 0x00, 0x00, 0x0c, 0x20, 0x8c, 0x01, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x78, 0x88, 0xc8, 0xfb, 0x0c, 0x20, 0x88, 0x94, 0x28, 0x08, 0x0c, 0x20, 0x88, 0xa2, 0x28, 0x08, 0x0c, 0x20, 0x78, 0xa2, 0xc8, 0x39, 0x0c, 0x20, 0x08, 0xbe, 0x08, 0x0a, 0x0c, 0x20, 0x08, 0xa2, 0x08, 0x0a, 0x0c, 0x20, 0x08, 0x22, 0xe7, 0xf9, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; spectemu-0.94/spectemu.cfg0100644000175000017500000000026206521371143016046 0ustar cjwatsoncjwatson# This is the global configuration file for Spectemu (xspect and vgaspect) # Put any options here, which you want all users to use # # See example.cfg for what can be put here # spectemu-0.94/loadim.z800100644000175000017500000000226406521613172015355 0ustar cjwatsoncjwatson@Л\YLя?W.!›6ј~:\в\aннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннння8ння8ння8888нняя # #нн нн<@яЊTянняюя8Л\¶\¶\Л\Р\К\М\П\П\С\у\у\’\нн“Xя![!@аP!!88нн"Wяяяф ЁKф ДSЃДRф ДPЂЂп"" Ђянн ЂннЂ О\ннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннянняннДу О гPО дPЬ О зPЬ Ч88 П\©\±3±3Ц\Р\]Ґqв\Л\v>>BB<DHpHDBнн@~BfZBBBBbRJFB> 5] |= 1 << ((addr) & 0x1F) #define PUTMEM(addr, ptr, val) \ { \ register byte addrhi; \ addrhi = (dbyte) (addr) >> 8; \ if(addrhi >= 0x5B) *(ptr) = (val); \ else if(addrhi & 0x40) { \ *(ptr) = (val); \ MARK_SCR((dbyte) (addr)); \ if(DANM(next_scri) >= 0 && DANM(tc) > 86) \ DANM(tc) -= 2; \ } \ } #define SOUNDPORT 0x10 /* TODO: attribute or pixel byte is present on unused ports? */ #define IN(porth, portl, dest) \ { \ if(!((portl) & DANM(inport_mask))) { \ dest = PORT(inports)[portl]; \ } \ else if(!((portl) & 1)) { \ if(DANM(imp_change) > DANM(tc)) { \ DANM(imp_change) = 0; \ DANM(ula_inport) ^= 0x40; \ } \ dest = SPECP(fe_inport_high)[porth] & DANM(ula_inport); \ DANM(tc) -= 1; \ } \ else { \ register int scri; \ scri = DANM(next_scri); \ dest = (scri < 0 || DANM(tc) <= 96) \ ? 0xFF : DANM(mem)[(scri<<5)+((224-DANM(tc))>>2)]; \ } \ } #define OUT(porth, portl, source) \ { \ if(!((portl) & 1)) { \ if((DANM(ula_outport) ^ (source)) & SOUNDPORT) { \ DANM(sound_change) = 1; \ if((source) & SOUNDPORT) DANM(sound_sam) += DANM(tc); \ else DANM(sound_sam) -= DANM(tc); \ } \ DANM(ula_outport) = (source); \ DANM(tc) -= 1; \ } \ PORT(outports)[portl] = (source); \ } #define DI_CHECK \ if(PC == LOAD_DI+1 && SPNM(quick_load)) \ SPNM(load_trapped) = 1, \ DANM(haltstate) = 1, \ DANM(tc) = 0; spectemu-0.94/README.Z800100644000175000017500000001202606526330037015003 0ustar cjwatsoncjwatsonThis file describes how to use the Z80 processor emulation as a standalone module (without the ZX Spectrum emulation). =========================================================================== You will need the following files: For the 'intel x86' assembly version: ------------------------------------- z80.c z80.h z80_type.h i386step.S i386def.S i386op1.S i386op1x.S i386op2.S i386op2x.S i386op3.S i386op3x.S i386op4.S i386op5.S i386op6.S sp_to_s.c For the 'C' version: -------------------- z80.c z80.h z80_type.h z80_step.c z80_def.h z80_ari.h z80optab.c z80optab.h z80_op1.c z80_op1x.c z80_op1.h z80_op2.c z80_op2x.c z80_op2.h z80_op3.c z80_op3x.c z80_op3.h z80_op4.c z80_op4x.c z80_op4.h z80_op5.c z80_op5.h z80_op6.c z80_op6.h =========================================================================== Makefile rules: For the 'intel x86' assembly version: ------------------------------------- CC = gcc AR = ar CPPFLAGS = CFLAGS = -Wall -O3 CPP = $(CC) -E z80_i386_objs = z80.o i386emul.o libz80.a: $(z80_i386_objs) $(AR) cr libz80.a $(z80_i386_objs) i386emul.o: i386emul.s $(CC) -c $(CFLAGS) i386emul.s i386emul.s: i386emul.sp sp_to_s ./sp_to_s < i386emul.sp > i386emul.s i386emul.sp: i386step.S $(CPP) $(CPPFLAGS) i386step.S > i386emul.sp sp_to_s: sp_to_s.o $(CC) -o sp_to_s $(LDFLAGS) sp_to_s.o .SUFFIXES: .SUFFIXES: .c .o .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $< For 'C' version: ---------------- CC = gcc AR = ar CPPFLAGS = -DZ80C CFLAGS = -Wall -O3 -fomit-frame-pointer -funroll-loops z80_c_objs = z80.o z80_step.o z80optab.o z80_op1.o z80_op2.o z80_op3.o \ z80_op4.o z80_op5.o z80_op6.o libz80.a: $(z80_c_objs) $(AR) cr libz80.a $(z80_c_objs) .SUFFIXES: .SUFFIXES: .c .o .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $< =========================================================================== The following functions are defined by libz80.a: void z80_init() --------------- This function initializes the processor emulation. This must be called only once at the beginning of the program. int z80_step(int ticknum) ------------------------- This function executes z80 instructions for 'ticknum' number of clock cycles. It returns the remaining number of ticks. NOTE: the remaining number of ticks is always zero or negative, meaning that exactly, or more than the given 'ticknum' clock cycles were executed. This is because WHOLE instructions are executed at a time. NOTE: HALT, LDDR, etc... do not count as one instruction, but as a series of instructions (e.g. HALT is a series of NOPs). void z80_reset() ---------------- This function resets the Z80 processor. This has the same effect as applying a pulse to the RESET input of the processor. NOTE: z80_init() does not reset the Z80, z80_reset() should be called after it. void z80_interrupt(int data) ----------------------------- Causes a Maskable Interrupt. Interrupt mode 1 and 2 are emulated correctly, in interrupt mode 2 'data' is used in the address calculation. In interrupt mode 0, it is assumed (as on the ZX Spectrum) that 0xFF is on the data bus, and always RST 38 is generated. NOTE: It is not emulated, that in the instruction after EI no interrupt can be generated. void z80_nmi() -------------- Causes a Non Maskable Interrupt. =========================================================================== Accessing the memory, the I/O ports and the Z80 processor's state (i.e. registers, etc...) To use the functions above and the variables below, include the "z80.h" include file. Memory ------ The memory is stored in the z80_proc.mem[] byte array, which has a size of 65536. By default it is all RAM. To make parts of it read only, you have to redefine the appropriate macros in i386step.S and/or z80_def.h. (These macros are sorounded by #ifdef SPECT_MEM, #else, #endif statements.) The memory is initialised to random data. You must fill it in before starting the emulation, but AFTER the call to z80_init(). I/O --- The input port values are stored in z80_inports[] array, which has a size of 256. The IN instruction will use the appropriate element of this array. This array is initialised to all zeroes. The output port values can be queried from the z80_outports[] array, which has also a size of 256. The OUT instruction will store the value in the element addressed by the instruction. If you need more complex behaviour of the I/O, you must redefine the appropriate macros in i386step.S and z80_def.h. Processor state --------------- You can access the processor's state with the following variables and macros defined in "z80.h". Registers: Double registers: normal: BC, DE, HL, AF, IR, IX, IY, PC, SP, aux: BCBK, DEBK, HLBK, AFBK Single registers: RB, RC, RD, RE, RH, RL, RA, RF, RI, RR, XH, XL, YH, YL, PCH, PCL, SPH, SPL Misc state: z80_proc.haltstate (1: processor is in halt mode, 0: processor is runnig) z80_proc.it_mode (interrupt mode 0, 1 or 2) z80_proc.iff1 (interrupt flip-flop 1) z80_proc.iff2 (interrupt flip-flop 2) You need not access the other parts of z80_proc, they are meaningless outside the z80_step() function. spectemu-0.94/README.DOS0100644000175000017500000000143106525576627015065 0ustar cjwatsoncjwatsonSpectemu is now basically usable under DOS. Still missing: 1) Sound 2) Decent GUI How to compile: --------------- - You will need DJGPP version 2, libkb, and the allegro game library. You can get these at: To get DJGPP, read: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/00README.TXT Libkb is at: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/libkb100.zip Allegro is at: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/allegro/alleg30.zip - Not all files are needed (no long named files are needed, you can try to get rid of them, but they cause no harm) - copy 'Makefile.dos' to 'Makefile', and 'config.dos' to 'config.h' - type 'make' It should compile without warnings. To start it, enter 'vgaspect'. See also README, for what can be done with the emulator. spectemu-0.94/sptiming.c0100644000175000017500000000541506526333346015553 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include "sptiming.h" #include "interf.h" #ifndef USE_ALLEGRO #include #include #else #include #endif #ifndef USE_ALLEGRO /* UNIX specific timer routines */ static void add_tv(long usec, struct timeval *tv) { long us1; us1 = tv->tv_usec + usec; tv->tv_sec += us1 / 1000000; tv->tv_usec = us1 % 1000000; } static long sub_tv(struct timeval *tv1, struct timeval *tv2) { return ((tv1->tv_sec - tv2->tv_sec) * 1000000 + (tv1->tv_usec - tv2->tv_usec)); } void spti_init(void) { } void spti_sleep(unsigned long usecs) { struct timeval waittv; waittv.tv_sec = 0; waittv.tv_usec = usecs; select(0, NULL, NULL, NULL, &waittv); } static struct timeval shouldbetv; void spti_reset(void) { gettimeofday(&shouldbetv, NULL); } void spti_wait(void) { long rem; struct timeval nowtv; add_tv(SKIPTIME, &shouldbetv); gettimeofday(&nowtv, NULL); rem = sub_tv(&shouldbetv, &nowtv); if(rem > 0) { if(rem > SKIPTIME) rem = SKIPTIME; spti_sleep((unsigned long) rem); } if(rem == SKIPTIME || rem < -10 * SKIPTIME) spti_reset(); } #else /* Allegro specific timer routines */ typedef unsigned long sptime; volatile sptime msecs; sptime shouldbems; static void timer_handler(void) { msecs++; } END_OF_FUNCTION(timer_handler); void spti_init(void) { if(install_timer() != NULL) { put_msg("Cloud not initialize timer in allegro\n"); exit(1); } LOCK_VARIABLE(msecs); LOCK_FUNCTION(timer_handler); install_int(timer_handler, 1); msecs = 0; } void spti_sleep(unsigned long usecs) { rest(usecs / 1000); } void spti_reset(void) { shouldbems = msecs; } void spti_wait(void) { long rem; shouldbems += (SKIPTIME / 1000); rem = ((long) (shouldbems - msecs)) * 1000; if(rem > 0) { if(rem > SKIPTIME) rem = SKIPTIME; spti_sleep(rem); } if(rem == SKIPTIME || rem < -10 * SKIPTIME) spti_reset(); } #endif /* USE_ALLEGRO */ spectemu-0.94/sptiming.h0100644000175000017500000000204006525576776015566 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef SPTIMING_H #define SPTIMING_H #define SKIPMS 20 #define SKIPTIME (SKIPMS * 1000) extern void spti_init(void); extern void spti_sleep(unsigned long usecs); extern void spti_reset(void); extern void spti_wait(void); #endif /* SPTIMING_H */ spectemu-0.94/keynames.c0100644000175000017500000001340706526035270015530 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include const char *spcf_keynames_ascii[95] = { "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "apostrophe", "parenleft", "parenright", "asterisk", "plus", "comma", "minus", "period", "slash", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde" }; const char *spcf_keynames_misc[256] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL, NULL, NULL, NULL, "Pause", "Scroll_Lock", "Sys_Req", NULL, NULL, NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL, "Multi_key", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Home", "Left", "Up", "Right", "Down", "Page_Up", "Page_Down", "End", "Begin", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Select", "Print", "Execute", "Insert", NULL, "Undo", "Redo", "Menu", "Find", "Cancel", "Help", "Break", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Mode_switch", "Num_Lock", "KP_Space", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "KP_Tab", NULL, NULL, NULL, NULL, "KP_Enter", NULL, NULL, NULL, "KP_F1", "KP_F2", "KP_F3", "KP_F4", "KP_Home", "KP_Left", "KP_Up", "KP_Right", "KP_Down", "KP_Page_Up", "KP_Page_Down", "KP_End", "KP_Begin", "KP_Insert", "KP_Delete", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "KP_Multiply", "KP_Add", "KP_Separator", "KP_Subtract", "KP_Decimal", "KP_Divide", "KP_0", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "KP_8", "KP_9", NULL, NULL, NULL, "KP_Equal", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", "F32", "F33", "F34", "F35", "Shift_L", "Shift_R", "Control_L", "Control_R", "Caps_Lock", "Shift_Lock", "Meta_L", "Meta_R", "Alt_L", "Alt_R", "Super_L", "Super_R", "Hyper_L", "Hyper_R", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Delete" }; spectemu-0.94/xdispkb.h0100644000175000017500000000165106526307652015371 0ustar cjwatsoncjwatson/* * Copyright (C) 1996-1998 Szeredi Miklos * Email: mszeredi@inf.bme.hu * * 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. See the file COPYING. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef XDISPKB_H #define XDISPKB_H extern void kb_refresh(void); extern void kb_refresh_colormap(void); #endif /* XDISPKB_H */