leo@marco.UUCP (Matthias Pfaller) (03/13/90)
This is part 2 of zmachine, a interpreter for infocom interactive fiction games. leo@marco.uucp (Matthias Pfaller) echo x - code.c sed '/^X/s///' > code.c << '/' X/* X* @(#)code.c 2.24 X*/ X X#include "zmachine.h" X X/* X* decoding/encoding module X*/ X Xchar *codetab = X"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.,!?_#'\"/\\-:()\0"; X Xextern BYTE *short_cuts; X X/* X* decode the string at vaddress a X*/ X Xvoid decode(a) Xstruct address *a; X{ X UWORD op; X register UWORD d2; X register UWORD d4 = 0; X register UWORD d5 = 0; X register BYTE *p; X struct address vaddr; X UWORD f76 = 0; X BYTE b[3]; X X do X { X op = d2 = fetchw_data(a); X for (p = b; p - b < 3; p++) X { X *p = d2; X d2 >>= 5; X } X X while (p - b > 0) X { X d2 = *--p & 0x1f; X if (d4 & 0x8000) X { X waddr_to_vaddr(&vaddr, word_get(&short_cuts[(d2 + f76)*2])); X decode(&vaddr); X d4 = d5; X } X else X { X if (d4 == 3) X d4 = 0x4000 + d2; X else if (d4 > 3) X { X d4 &= 3; X d4 <<= 5; X d4 |= d2; X output_chr(d4); X d4 = d5; X } X else X { X if (d2 >= 6) X { X if (d4 == 2) X { X if (d2 < 7) X d4++; X else if (d2 == 7) X { X output_chr('\n'); X d4 = d5; X } X else X { X output_chr(codetab[d4 * 0x1a + d2 - 6]); X d4 = d5; X } X } X else X { X output_chr(codetab[d4 * 0x1a + d2 - 6]); X d4 = d5; X } X } X else X { X if (d2 == 0) X { X output_chr(' '); X d4 = d5; X } X else X { X if (d2 <= 3) X { X d4 |= ~0x7fff; X f76 = (d2 - 1) << 5; X } X else X { X d2 -= 3; X if (d4 == 0) X d4 = d2; X else X { X if (d4 != d2) X d4 = 0; X d5 = d4; X } X } X } X } X } X } X } X } X while (!(op & 0x8000)); X} X X X/* return the code group of c */ X XUWORD code_group(c) Xregister char c; X{ X if (!c) X return(3); X X if (c >= 'a' && c <= 'z') X return(0); X X if (c >= 'A' && c <= 'Z') X return(1); X X return(2); X} X X/* X* return the index X* of c in the codetab X*/ X XUWORD code_index(c) Xchar c; X{ X register char *p; X register UWORD i; X char *strchr(); X X p = strchr(codetab,c); X X if (p) X { X for (i = p - codetab + 6; i >= 0x20; i -= 0x1a) X ; X return(i); X } X else X return(0); X} X X X/* X* code a word of X* max 6 chars to dest X*/ X Xvoid encode(dst, src) Xregister UWORD *dst; char *src; X{ X register UWORD t, i; X register UWORD *tp; X UWORD b[12]; X char c; X X for(tp = b, i = 6; (c = *(src++)) && i; i--) X { X if (t = code_group(c)) X { X t += 3; X *(tp++) = t; X if (!--i) X break; X } X X if (!(t = code_index(c))) X { X *(tp++) = 6; X if (!--i) X break; X *(tp++) = c >> 5; X if (!--i) X break; X X t = c & 0x1f; X } X *(tp++) = t; X } X X for (; i; i--) X *(tp++) = 5; X X for (tp = b, i = 2; i; i--) X { X t = (*tp++ << 10) & (0x1f << 10); X t |= (*tp++ << 5) & (0x1f << 5); X t |= (*tp++) & (0x1f); X *dst++ = t; X } X dst[-1] |= 0x8000; X} / echo x - config.h sed '/^X/s///' > config.h << '/' X/* X* @(#)config.h 2.24 X*/ X X# define I_HIST_LEN 1024 /* len of input history */ Xtypedef char ZWORD[2]; /* zmachine word */ Xtypedef unsigned short UWORD; /* 16 bit unsigned */ X#ifndef OSK Xtypedef short WORD; /* 16 bit signed */ X#endif Xtypedef unsigned char BYTE; /* unsigned 8 bit */ / echo x - io.c sed '/^X/s///' > io.c << '/' X/* X* @(#)io.c 2.24 X*/ X X# ifdef OSK X# include <modes.h> X# endif X# include "zmachine.h" X# include "keys.h" X Xchar *iovers = "122400"; Xint pfile = -1; XFILE *fopen(); X Xchar *print_name = "protocol"; Xint printer_width = 80; X X/*****************************************************************************/ X Xstruct dev *init_dev(out, crlf, l, h, wrap) Xvoid (*out)(); void (*crlf)(); int l, h, wrap; X{ X register struct dev *d; X X if (d = (struct dev *)malloc(sizeof(struct dev) + l)) X { X d->buffer = d->bp = (char *)d + sizeof(struct dev); X d->width = l; X d->height = h; X d->count = 0; X d->out_f = out; X d->crlf_f = crlf; X d->wrap = wrap; X return(d); X } X else X no_mem_error(); X} X Xvoid putc_dev(c, d) Xchar c; register struct dev *d; X{ X register char *s, *p; X X if (c == '\n' || c == FLUSH) X { X (*d->out_f)(d->buffer, d->bp); X if (c != FLUSH && (d->count != d->width || !d->wrap)) X (*d->crlf_f)(); X X con_flush(); X X d->count = 0; X d->bp = d->buffer; X } X else X { X if (d->width < d->count+1) X { X if (c == ' ') X { X (*d->out_f)(d->buffer, d->bp); X if (d->count != d->width || !d->wrap) X (*d->crlf_f)(); X d->count = 0; X d->bp = d->buffer; X return; X } X else X { X for(s = d->bp; --s > d->buffer;) X if (*s == ' ') X break; X X if (s == d->buffer) X { X (*d->out_f)(d->buffer, d->bp); X d->count = 0; X d->bp = d->buffer; X } X else X { X (*d->out_f)(d->buffer, s); X (*d->crlf_f)(); X for (d->count = 0, p = d->buffer; X s < d->bp-1; X d->count++) X *p++ = *++s; X d->bp = p; X } X } X X } X *(d->bp++) = c; X d->count++; X } X} X Xvoid output_chr(c) Xchar c; X{ X extern int use_line, in_status; X extern char *line; X X if (c == FLUSH) X putc_dev(c, screen); X else if (use_line) X *line++ = c; X else X { X if (c == 9) X c = ' '; X X putc_dev(c, screen); X X if (!in_status && (word_get(main_h->reserved5) & 1)) X putc_dev(c, printer); X } X} X Xvoid output_str(p) Xregister char *p; X{ X while(*p) X output_chr(*p++); X} X Xvoid output_status(room, score) Xchar *room, *score; X{ X register char i; X register int t; X int x,y; X X storeXY(&x, &y); X cursorOFF(); X gotoXY(0,0); X reverseON(); X con_str1(room); X X t = screen->width - strlen(score); X for(i = strlen(room); i < t; i++) X con_chr(' '); X X con_str1(score); X reverseOFF(); X cursorON(); X gotoXY(x,y); X} X X/*****************************************************************************/ X Xvoid more_test() X{ X char getc_ne(); X extern int line_cnt, status_len; X X if ((screen->height - status_len) == ++line_cnt) X { X status(); X con_str1("[More]"); X con_flush(); X con_getc(); X con_str1("\r \r"); X line_cnt = 2; X } X} X Xvoid scr_write(a,b) Xchar *a, *b; X{ X extern int in_status; X X if (!in_status) X more_test(); X X if (b > a) X con_str2(a,b); X} X Xint prot_open() X{ X if (pfile == -1) X { X#ifdef OSK X if ((pfile = creat(print_name, S_IREAD|S_IWRITE)) < 0) X#else X if ((pfile = creat(print_name, 0666)) < 0) X#endif X { X con_crlf(); X con_str1("Can't open protokoll file"); X con_crlf(); X pfile = -2; X } X } X return(pfile >= 0); X} X Xvoid prot_write(a,b) Xchar *a, *b; X{ X if (prot_open() && (b > a)) X write(pfile, a, b-a); X} X Xvoid prot_crlf() X{ X if (prot_open()) X# if defined(unix) || defined(OSK) X write(pfile, "\n", 1); X# else X write(pfile, "\r\n", 2); X# endif X} X X/*****************************************************************************/ X Xchar fkeys[10][17]; X Xint save_keys() X{ X extern int save_len; X return(write_saveb(save_len + 1, 170, fkeys)); X} X Xint restore_keys() X{ X extern int save_len; X return(read_saveb(save_len + 1, 170, fkeys)); X} X Xchar *read_str(p, hist) Xchar *p; struct hist_buf *hist; X{ X extern int line_cnt; X register char *q, *src, *dst; X char *retype; X char *end; X register int c; X register int i, e; X int x, y; X X static char fbuf[18]; X static char fhmem[36]; X static struct hist_buf fhist = {36, fhmem, fhmem}; X static int imode=1; X static int init=1; X static int fprog = 0; X X if (init) X { X init = 0; X fhmem[0] = fhmem[1] = '\0'; X X for(i = F01; i < F10; i++) X fkeys[i][0] = '\0'; X } X X retype = NULL; X con_flush(); X X (*p)--; /* we need one char more (for '\0') */ X line_cnt = 1; X p[1] = '\0'; X end = p + p[0] + 1; X q = p + 1; X while ((c = con_getc()) != RETURN) X { X switch(c) X { X case 0x1b: X { X extern save_gf(); X save_gf("dump.z"); X } X break; X X case CUP: X case CDOWN: X if (c == CUP) X { X if (!retype) X retype = hist->undo; X else if (*(retype + strlen(retype) + 1)) X retype += strlen(retype) + 1; X else X break; X } X else X { X if (!retype) X retype = hist->undo; X else if (retype != hist->hb) X for (retype -= 1; X retype != hist->hb && X retype[-1]; retype--) X ; X else X break; X } X X case RETYPE: X if (!retype) X retype = hist->undo; X X /* go to start of input line */ X e = q - p - 1; X cursorOFF(); X for(i = 0; i < e; i++) X cursorLEFT(); X X /* delete to end of input line */ X storeXY(&x, &y); X e = strlen(p+1); X for (i = 0; i < e; i++) X con_chr(' '); X gotoXY(x, y); X X /* copy old input line and print it */ X strncpy(p + 1, retype, *p); X *(p + *p + 1) = '\0'; X con_str1(p + 1); X cursorON(); X q = p + 1 + strlen(p + 1); X break; X X case CLEFT: X if (q > p + 1) X { X q--; X cursorLEFT(); X } X break; X X case CRIGHT: X if (*q != '\0') X con_chr(*q++); X break; X X case START: X e = q - p - 1; X cursorOFF(); X for(i = 0; i < e; i++) X cursorLEFT(); X cursorON(); X q = p + 1; X break; X X case END: X cursorOFF(); X con_str1(q); X cursorON(); X q += strlen(q); X break; X X case BACKDEL: X if (q > p + 1) X { X cursorLEFT(); X storeXY(&x, &y); X strcpy(q-1, q); X q--; X cursorOFF(); X con_str1(q); X con_chr(' '); X gotoXY(x, y); X cursorON(); X } X break; X X case FORWDEL: X if (*q != '\0') X { X storeXY(&x, &y); X strcpy(q, q + 1); X cursorOFF(); X con_str1(q); X con_chr(' '); X gotoXY(x, y); X cursorON(); X } X break; X X case KILL: X if (*q != '\0') X { X storeXY(&x, &y); X cursorOFF(); X e = strlen(q); X for (i = 0; i < e; i++) X con_chr(' '); X *q = '\0'; X gotoXY(x, y); X cursorON(); X } X break; X X case INSERT: X imode = !imode; X break; X X case FPROG: X if(!fprog) X { X fprog = 1; X cursorOFF(); X storeXY(&x, &y); X gotoXY(0, 0); X reverseON(); X for (i = 0; i < screen->width; i++) X con_chr(' '); X gotoXY(0, 0); X con_str1("Press function key: "); X cursorON(); X con_flush(); X do X c = con_getc(); X while(c < FSTART); X cursorOFF(); X con_str1("\r \r"); X con_str1("Enter text: "); X fbuf[0] = 17; X cursorON(); X con_flush(); X read_str(fbuf, &fhist); X cursorOFF(); X status(); X gotoXY(x, y); X cursorON(); X strcpy(fkeys[c - FSTART], fbuf + 1); X fprog = 0; X } X break; X X default: X if (strlen(p + 1) < p[0] || (*q && !imode)) X { X if (c >= ' ' && c < 0x80) X { X if (imode) X { X for (src = q + strlen(q), X dst = q + strlen(q) + 1; X src >= q; X *dst-- = *src--) X ; X *q = c; X cursorOFF(); X con_str1(q++); X e = strlen(q); X for(i = 0; i < e; i++) X cursorLEFT(); X cursorON(); X } X else X { X if (!*q) X *(q+1) = '\0'; X *q++ = c; X con_chr(c); X } X } X else if (c >= FSTART) X { X if (!*q) X { X strncpy(q, fkeys[c - FSTART], end - q); X cursorOFF(); X con_str1(q); X cursorON(); X q += strlen(q); X } X else if (imode) X { X if (end - q - strlen(q) < strlen(fkeys[c - FSTART])) X dst = end + 1; X else X dst = q + strlen(fkeys[c - FSTART]) + strlen(q) + 1; X X cursorOFF(); X for (src = q + strlen(q) + 1; src >= q; *dst-- = *src--) X ; X X for(src = fkeys[c - FSTART]; q <= dst;) X con_chr(*q++ = *src++); X X con_str1(q); X e = strlen(q); X for(i = 0; i < e; i++) X cursorLEFT(); X cursorON(); X } X else X { X if(strlen(q) < strlen(fkeys[c - FSTART])) X { X strncpy(q, fkeys[c - FSTART], end - q); X dst = q + strlen(fkeys[c - FSTART]); X dst = (dst < end)?dst:end; X } X else X { X for(src = fkeys[c - FSTART], dst = q; *src && dst < end; *dst++ = *src++) X ; X } X cursorOFF(); X con_str2(q, dst); X cursorON(); X q = dst; X } X } X } X } X con_flush(); X } X X (*p)++; /* restore original maxlen */ X X if (!retype) X retype = hist->undo; X X if (strcmp(retype, p + 1) && strlen(p + 1)) X { X for (src = hist->hb + hist->len - strlen(p + 1) - 2, X dst = hist->hb + hist->len - 1; X src >= hist->hb; *dst-- = *src--) X ; X X strcpy(hist->hb, p + 1); X X hist->hb[hist->len - 2] = hist->hb[hist->len - 1] = '\0'; X hist->undo = hist->hb; X } X else X hist->undo = retype; X X cursorOFF(); X con_str1(q); X cursorON(); X putc_dev('\n', screen); X con_flush(); X return(p + strlen(p + 1) + 1); X} / echo x - zbios.c sed '/^X/s///' > zbios.c << '/' X/* X* @(#)zbios.c 2.24 X* Basic input/output System for ZMACHINE X* all machine dependent functions are collected X* in this file. X*/ X X#include <fcntl.h> X#include <ctype.h> X#ifdef OSK X#include <modes.h> X#endif X#include "zmachine.h" X#include "keys.h" X X#ifdef GEMDOS Xchar *sysname = "Atari ST"; X X#include <sys\osbind.h> X#endif X X#if defined(unix) || defined(OSK) X#ifdef unix Xchar *sysname = "u**x"; X X#include <sgtty.h> X#include <signal.h> X#include <sys/types.h> X Xstruct sgttyb otermio,ntermio; X#endif X#ifdef OSK Xchar *sysname = "OS9/68000"; X X#include <sgstat.h> X#define fputc(a,b) putc(a,b) X#define gtty(FD,ADR) getstat(0,FD,ADR) X#define stty(FD,ADR) setstat(0,FD,ADR) X#define CHRAW(X) chraw( & X) Xstruct sgbuf nstate, ostate; X X#define PC PC_ Xint ospeed = 0; X Xchraw(x) Xstruct sgbuf *x; X{ X x->sg_case = 0; X x->sg_backsp = 0; X x->sg_echo = 0; X x->sg_alf = 0; X x->sg_pause = 0; X x->sg_bspch = 0x80; X x->sg_dlnch = 0x80; X x->sg_eorch = 0x80; X x->sg_eofch = 0x80; X x->sg_rlnch = 0x80; X x->sg_dulnch = 0x80; X x->sg_psch = 0x80; X x->sg_kbich = 0x80; X x->sg_kbach = 0x80; X x->sg_bsech = 0x80; X x->sg_bellch = 0x80; X x->sg_tabcr = 0x80; X x->sg_xon = 0x11; X x->sg_xoff = 0x13; X} X#endif X Xchar tcapbuf[1024]; Xchar *CM = NULL, *CL = NULL, *BC = NULL, *UP = NULL, *DL = NULL, *TI = NULL, *TE = NULL, *SE = NULL, *SO = NULL, PC = '\0', *VS = NULL, *VE = NULL; Xchar *KS = NULL, *KE = NULL; X Xstruct fkencode X { X struct fkencode *nextchar; /* next char in string */ X struct fkencode *nextstring; /* next string */ X int fkc; /* current char X > 0x100 = return */ X } *fkroot = NULL; X Xstruct X { X char *name; X int code; X } keylist[] = { X { "kl", CLEFT }, X { "kr", CRIGHT }, X { "ku", CUP }, X { "kd", CDOWN }, X { "kb", BACKDEL }, X X { "k0", FSTART + F01 }, X { "k1", FSTART + F02 }, X { "k2", FSTART + F03 }, X { "k3", FSTART + F04 }, X { "k4", FSTART + F05 }, X { "k5", FSTART + F06 }, X { "k6", FSTART + F07 }, X { "k7", FSTART + F08 }, X { "k8", FSTART + F09 }, X { "k9", FSTART + F10 }, X { NULL, 0 } X }; X Xstruct fkencode *insertc(fk, c) Xstruct fkencode *fk; int c; X{ X if (!fk) X { X if (!(fk = (struct fkencode *)malloc(sizeof(struct fkencode)))) X no_mem_error(); X fk->nextchar = fk->nextstring = NULL; X fk->fkc = c; X return(fk); X } X else X { X if (fk->fkc == c) X return(fk); X else X { X if (!fk->nextstring) X { X fk->nextstring = insertc(NULL, c); X fk = fk->nextstring; X } X else X fk = insertc(fk->nextstring, c); X X return(fk); X } X } X} X Xstruct fkencode *insertkey(fk, s, c) Xstruct fkencode *fk; char *s; int c; X{ X struct fkencode *root; X X if (fk) X { X root = fk; X fk = insertc(fk, *s++); X } X else X root = fk = insertc(NULL, *s++); X X while(*s) X { X if (fk->nextchar) X fk = insertc(fk->nextchar, *s++); X else X { X fk->nextchar = insertc(NULL, *s++); X fk = fk->nextchar; X } X } X X fk->nextchar = insertc(NULL, c); X return(root); X} X X#endif X Xint story = -1; Xint save = -1; X Xstruct { X int x, y, lline, lchar; X } con; X Xstruct dev *screen; X Xvoid icon_str(); Xvoid icon_chr(); X/* X* long random() - return a random number (range 0 - min 0x7fff) X*/ X Xlong zrandom() X{ X#ifdef GEMDOS X return(Random()); X#endif X#if defined(unix) || defined(OSK) X extern void srand(); X extern long rand(); X extern long time(); X X static int init = 1; X X if (init) X { X init = 0; X srand((int)time(NULL)); X } X X return(rand()); X#endif X} X X/* X* con_flush() - flush the console output buffer X*/ X Xvoid con_flush() X{ X#if defined(unix) || defined(OSK) X fflush(stdout); X#endif X} X X/* X* con_chr(c) - output the single character c to X* char c; the console-device X*/ X Xvoid con_chr(c) Xchar c; X{ X int x,y; X if (c == '\r') X { X gotoXY(0, con.y); X return; X } X else if (con.x++ == con.lchar) X { X storeXY(&x, &y); X con_crlf(); X if (y == con.lline) X y--; X gotoXY(x, y); X#ifdef GEMDOS X Bconout(2,c); X#else X putchar(c); X#endif X gotoXY(0,y+1); X } X else X#ifdef GEMDOS X Bconout(2,c); X#else X putchar(c); X#endif X X} X X/* X* con_str1(p) - output a '\0' terminated string to X* char *p; the console-device X*/ X Xvoid con_str1(p) Xregister char *p; X{ while(*p) X con_chr(*p++); X} X X/* X* con_str2(p,q) - output the string p with the X* char *p, *q; endaddress q to the console-device X* X*/ X Xvoid con_str2(p,q) Xregister char *p,*q; X{ X while(p < q) X con_chr(*p++); X} X X/* X* con_crlf() - scroll all lines but first X* status_len lines (if possible). X* goto first column of next line. X*/ X Xvoid con_crlf() X{ X extern int status_len; X#if defined(unix) || defined(OSK) X int x,y; X#endif X X if (con.y == con.lline) X { X#ifdef GEMDOS X icon_str("\033j\033f\033Y"); X icon_chr(' ' + status_len); X icon_str(" \033M\033k\r\033e"); X#endif X#if defined(unix) || defined(OSK) X storeXY(&x,&y); X cursorOFF(); X if (DL) X { X gotoXY(0,status_len); X putpad(DL); X } X else X { X gotoXY(0, con.lline); X#ifdef OSK X icon_str("\012"); X#else X icon_str("\n"); X#endif X } X x = 0; X gotoXY(x,y); X cursorON(); X#endif X } X else X { X#ifdef OSK X icon_str("\015\012"); X#else X icon_str("\r\n"); X#endif X con.y++; X } X con.x = 0; X} X X/* X* reverseON() - turn reversemode on X* reverseOFF() - turn reversemode off X*/ X Xvoid reverseON() X{ X#ifdef GEMDOS X icon_str("\033p"); X#endif X#if defined(unix) || defined(OSK) X if (SO) X putpad(SO); X#endif X} X Xvoid reverseOFF() X{ X#ifdef GEMDOS X icon_str("\033q"); X#endif X#if defined(unix) || defined(OSK) X if (SE) X putpad(SE); X#endif X} X X/* X* cursorON() - turn cursor on X* cursorOFF() - turn cursor off X*/ X Xvoid cursorON() X{ X#ifdef GEMDOS X icon_str("\033e"); X#endif X} X Xvoid cursorOFF() X{ X#ifdef GEMDOS X icon_str("\033f"); X#endif X} X X/* X* cursorLEFT() - move cursor left (with wrap) X*/ X XcursorLEFT() X{ X if (con.x) X { X#ifdef GEMDOS X icon_chr(8); X#endif X#if defined(unix) || defined(OSK) X icon_str(BC); X#endif X con.x--; X } X else X gotoXY(con.lchar, con.y - 1); X} X X/* X* gotoXY(x,y) - goto screen position x,y X* int x,y; X*/ X Xvoid gotoXY(x,y) Xint x,y; X{ X#ifdef GEMDOS X icon_str("\033Y"); X icon_chr(' ' + y); X icon_chr(' ' + x); X#endif X#if defined(unix) || defined(OSK) X extern char *tgoto(); X putpad(tgoto(CM, x, y)); X#endif X con.x = x; X con.y = y; X} X X/* X* storeXY(x,y) - store current cursor position to X* int *x, *y; x and y X*/ X Xvoid storeXY(x,y) Xint *x, *y; X{ X *x = con.x; X *y = con.y; X} X X/* X* int con_getc() - get a character from the console X* handle special chars. X*/ X X#ifdef GEMDOS Xint con_getc() X{ X long c; X static int s = 16; X c = Bconin(2); X switch((int)(c >> s)) /* compiler error */ X { X case 0x004b: X return(CLEFT); X X case 0x004d: X return(CRIGHT); X X case 0x0050: X return(CDOWN); X X case 0x0048: X return(CUP); X X case 0x0061: X return(RETYPE); X X case 0x0052: X return(INSERT); X X case 0x0073: X return(START); X X case 0x0074: X return(END); X X default: X if ((c >> s) > 0x003a && (c >> s) < 0x0045) X return(FSTART + (c >> s) - 0x003b); X X switch((int)(c&0xff)) X { X case 0x01: X return(START); X X case 0x05: X return(END); X X case 0x19: X return(RETYPE); X X case 0x0b: X return(KILL); X X case 0x08: X return(BACKDEL); X X case 0x7f: X return(FORWDEL); X X case 0x04: X return(FORWDEL); X X case 0x02: X return(CLEFT); X X case 0x06: X return(CRIGHT); X X case 0x0e: X return(CDOWN); X X case 0x10: X return(CUP); X X case 0x09: X return(FPROG); X X case 0x0d: X return(RETURN); X X default: X return(c&0xff); X } X } X} X#else Xint con_getc() X{ X char c; X register struct fkencode *fk; XRETRY: X read(0, &c, 1); X c &= 0x7f; X for (fk = fkroot; fk;) X { X if (fk && c == fk->fkc) X { X fk = fk->nextchar; X if (fk && fk->fkc > 0x100) X return(fk->fkc); X else X { X read(0, &c, 1); X c &= 0x7f; X } X } X else X fk = fk->nextstring; X } X X switch((int)(c&0xff)) X { X case 0x18: X read(0, &c, 1); X c &= 0x0f; X if (c > 9) X goto RETRY; X return(c + FSTART); X X case 0x01: X return(START); X X case 0x05: X return(END); X X case 0x19: X return(RETYPE); X X case 0x0b: X return(KILL); X X case 0x7f: X return(BACKDEL); X X case 0x08: X return(FORWDEL); X X case 0x04: X return(FORWDEL); X X case 0x02: X return(CLEFT); X X case 0x06: X return(CRIGHT); X X case 0x0e: X return(CDOWN); X X case 0x10: X return(CUP); X X case 0x09: X return(FPROG); X X case '\n': X#ifndef OSK X case 0x0d: X#endif X return(RETURN); X X default: X return(c&0xff); X } X} X#endif X X/* X* init_con() - initialize console X* - clear screen X* - goto last line on screen X*/ X Xvoid init_con() X{ X int len; X int lines; X static int init=1; X#if defined(unix) || defined(OSK) X char *getenv(), *tgetstr(); X char *p, *t, *tv_stype; X int i; X void clean_up(); X char tcbuf[1024]; X#endif X X#ifdef GEMDOS X if (Getrez()) X len = 80; X else X len = 40; X lines = 25; X#endif X X#if defined(unix) || defined(OSK) X if (init) X { X#ifdef unix X ioctl(0, TIOCGETP, &otermio); X ntermio = otermio; X ntermio.sg_flags |= RAW; X ntermio.sg_flags &= ~(ECHO|CRMOD); X ioctl(0, TIOCSETP, &ntermio); X#endif X#ifdef OSK X gtty(0, &ostate); X gtty(0, &nstate); X CHRAW(nstate); X stty(0, &nstate); X#endif X if ((tv_stype = getenv("TERM")) == NULL) X fatal("Environment variable TERM not defined", NULL); X X if (tgetent(tcbuf, tv_stype) != 1) X fatal("Unknown terminal type", tv_stype); X X if ((lines = tgetnum("li")) == -1) X fatal("Termcap entry incomplete (lines)", tv_stype); X X if ((len = tgetnum("co")) == -1) X fatal("Termcap entry inclomplete (columns)", tv_stype); X X p = tcapbuf; X t = tgetstr("pc", &p); X if (t) X PC = *t; X X CM = tgetstr("cm", &p); /* cursor movement */ X X CL = tgetstr("cl", &p); /* clear screen */ X X UP = tgetstr("up", &p); /* cursor up */ X X SE = tgetstr("se", &p); /* exit reverse mode */ X X SO = tgetstr("so", &p); /* enter reverse mode */ X X BC = tgetstr("bc", &p); /* back space char */ X if (!BC) X BC = "\010"; X X DL = tgetstr("dl", &p); /* delete line */ X X TI = tgetstr("ti", &p); /* terminal init */ X X TE = tgetstr("te", &p); /* terminal reset */ X X VS = tgetstr("vs", &p); /* enter visual mode */ X X VE = tgetstr("ve", &p); /* exit visual mode */ X X KS = tgetstr("ks", &p); /* enter visual mode */ X X KE = tgetstr("ke", &p); /* enter visual mode */ X X if (!CM || !CL || !UP) X fatal("Termcap entry inclomplete", tv_stype); X X for (i = 0; keylist[i].name; i++) X if ( t = tgetstr(keylist[i].name, &p)) X fkroot = insertkey(fkroot, t, keylist[i].code); X X } X#endif X if (init) X { X con.lline = lines - 1; X con.lchar = len - 1; X } X#ifdef GEMDOS X icon_str("\033E\033w"); /* cursor on, wrap off */ X#endif X#if defined(unix) || defined(OSK) X if (init) X { X if (TI) X icon_str(TI); X X if (VS) X icon_str(VS); X X if (KS) X icon_str(KS); X } X icon_str(CL); X#endif X gotoXY(0, con.lline); X cursorON(); X if (init) X screen = init_dev(scr_write, con_crlf, len, lines, 1); X X screen->bp = screen->buffer; X screen->count = 0; X init = 0; X} X X/* X* open_story - open the storyfile specified by the X* global variable story_name X*/ X Xint open_story() X{ X return((story = open(story_name, O_RDONLY)) < 0); X} X X/* X* close_story - close the story file X*/ X Xint close_story() X{ X int st; X st = close(story); X story = -1; X return(st); X} X X/* X* read_story(p, n, bp) - read n pages (512 byte) from page no. p X* unsigned p, n; char *bp; to the address bp X*/ X Xvoid read_story(p, n, bp) Xunsigned p, n; BYTE *bp; X{ X if (read_pages(story, p, n, bp)) X fatal("story file read error", story_name); X} X Xvoid read_header(p) Xstruct header *p; X{ X if (read(story, p, sizeof(struct header)) != sizeof(struct header)) X fatal("can't read story header", story_name); X} X X/* X* open_save_w(name) - open the save file name for writing X* char *name; X*/ X Xint open_save_w(name) Xchar *name; X{ X#ifdef OSK X return((save = creat(name, S_IREAD|S_IWRITE)) < 0); X#else X return((save = creat(name, 0666)) < 0); X#endif X} X X/* X* open_save_r(name) - open the save file name for reading X* char *name; X*/ X Xint open_save_r(name) Xchar *name; X{ X return((save = open(name, O_RDONLY)) < 0); X} X X/* X* close_save() - close the save file X*/ X Xint close_save() X{ X int st; X st = close(save); X save = -1; X#ifdef OSK X return(0); X#else X return(st); X#endif X} X X/* X* read_save(p, n, bp) - read n pages (512 byte) from page no. p X* unsigned p, n; char *bp; to the address bp X*/ X Xint read_save(p, n, bp) Xunsigned p, n; BYTE *bp; X{ X return(read_pages(save, p, n, bp)); X} X X/* X* write_save(p, n, bp) - write n pages (512 byte) to page no. p X* unsigned p, n; char *bp; from the address bp X*/ X Xint write_save(p, n, bp) Xunsigned p, n; BYTE *bp; X{ X return(write_pages(save, p, n, bp)); X} X X/* X* write_saveb(p, n, bp) - write n bytes to page no. p from the X* unsigned p, n; BYTE *bp; address bp X*/ X Xint write_saveb(p, n, bp) Xunsigned p, n; BYTE *bp; X{ X long lseek(), lwrite(); X if (lseek(save, (long)p * 0x200L, 0) != (long)p * 0x200L) X return(1); X X return(lwrite(save, bp, (long)n) != (long)n); X} X X/* X* read_saveb(p, n, bp) - read n bytes from page no. p to the X* unsigned p, n; BYTE *bp; address bp X*/ X Xint read_saveb(p, n, bp) Xunsigned p, n; BYTE *bp; X{ X long lseek(), lread(); X if (lseek(save, (long)p * 0x200L, 0) != (long)p * 0x200L) X return(1); X X return(lread(save, bp, (long)n) < 0L); X} X X/* X* char *read_rname() - ask user for restore file X*/ X Xchar *read_rname() X{ X static char name[129]; X static struct hist_buf nam_hist = {256, NULL}; X X if (!nam_hist.hb) X { X if (!(nam_hist.undo = nam_hist.hb = malloc(nam_hist.len))) X no_mem_error(); X else X nam_hist.hb[0] = nam_hist.hb[1] = '\0'; X } X X name[0] = 128; X X con_str1("Default name is: "); X con_str1(nam_hist.undo); X con_crlf(); X con_str1("Enter file name: "); X read_str(name, &nam_hist); X X return(*nam_hist.undo?nam_hist.undo:NULL); X} X X/* X* char *read_sname() - ask user for save file X*/ X Xchar *read_sname() X{ X char *name; X char c; X if (name = read_rname()) X { X if (!access(name,0)) X { X con_str1("You are about to write over an existing file. Proceed? (Y/N) "); X con_flush(); X while ((c = toupper(con_getc())) != 'Y' && c != 'N') X ; X con_chr(c); X con_crlf(); X if (c == 'N') X return(NULL); X } X return(name); X } X else X return(NULL); X} X X/*****************************************************************************/ X/* utility functions */ X X#ifdef GEMDOS Xlong lread(fd, bp, n) Xint fd; BYTE *bp; long n; X{ X return(Fread(fd, n, bp)); X} X Xlong lwrite(fd, bp, n) Xint fd; BYTE *bp; long n; X{ X return(Fwrite(fd, n, bp)); X} X#endif X Xint write_pages(fd, p, n, bp) Xint fd; unsigned p, n; BYTE *bp; X{ X long lseek(); X if (lseek(fd, (long)p * 0x200L, 0) != (long)p * 0x200L) X return(1); X X return(lwrite(fd, bp, 0x200L * (long)n) != (0x200L * (long)n)); X} X Xint read_pages(fd, p, n, bp) Xint fd; unsigned p, n; BYTE *bp; X{ X if (lseek(fd, (long)p * 0x200L, 0) != (long)p * 0x200L) X return(1); X X return(lread(fd, bp, 0x200L * (long)n) < 0L); X} X Xvoid icon_str(p) Xregister char *p; X{ X while(*p) X#ifdef GEMDOS X Bconout(2,*p++); X#else X putchar(*p++); X#endif X} X Xvoid icon_chr(c) Xchar c; X{ X#ifdef GEMDOS X Bconout(2,c); X#else X putchar(c); X#endif X} X Xvoid fatal(s1, s2) Xchar *s1, *s2; X{ X write(2,"ERROR",5); X if (s2) { X write(2," [",2); X write(2,s2,strlen(s2)); X write(2,"]",1); X } X write(2,": ",2); X write(2,s1,strlen(s1)); X# ifdef GEMDOS X write(2,"\n\r",2); X# else X write(2,"\n",1); X# endif X clean_up(); X exit(userexit(1)); X} X Xvoid clean_up() X{ X if (story >= 0) X close_save(); X X if (save >= 0) X close_story(); X X if (pfile >= 0) X close(pfile); X X#if defined(unix) || defined(OSK) X if (TE) X icon_str(TE); X if (VE) X icon_str(VE); X X if (KE) X icon_str(KE); X X#ifdef unix X if (ntermio.sg_flags & RAW) X ioctl(0, TIOCSETP, &otermio); X#endif X#ifdef OSK X if (nstate.sg_tabcr == (char)(0x80)) X stty(0, &ostate); X#endif X icon_chr('\n'); X X#endif X} X Xint userexit(s) Xint s; X{ X char *getenv(); X X#ifdef GEMDOS X if (!getenv("ARGV")) X { X write(2, "\n\rStrike any key to exit ", 24); X con_getc(); X } X#endif X return(s); X} X X#if defined(unix) || defined(OSK) Xputpad(s) Xchar *s; X{ X tputs(s, 1, icon_chr); X} X X#if !defined(CADMUS) && !defined(minix) Xchar *lmalloc(n) Xlong n; X{ X return(malloc(n)); X} X#endif X X#if !defined(minix) Xlong lread(a,b,c) Xint a; char *b; int c; X{ X return (read(a,b,c)); X} X Xlong lwrite(a,b,c) Xint a; char *b; int c; X{ X return(write(a,b,c)); X} X#else Xlong lread(fd, bp, cnt) Xint fd; char *bp; long cnt; X{ X register int n, b; X register long bcnt; X bcnt = cnt; X while(bcnt) X { X n = read(fd, bp, (int)(b = bcnt>31744?31744:bcnt)); X if (n < 0) X return(n); X if (n < b) X return(bcnt - n); X bcnt -= n; X bp += n; X } X return(cnt); X} X Xlong lwrite(fd, bp, cnt) Xint fd; char *bp; long cnt; X{ X register int n, b; X register long bcnt; X bcnt = cnt; X while(bcnt) X { X n = write(fd, bp, (int)(b = bcnt>31744?31744:bcnt)); X if (n < 0) X return(n); X if (n < b) X return(bcnt - n); X bcnt -= n; X bp += n; X } X return(cnt); X} X X#endif / echo x - keys.h sed '/^X/s///' > keys.h << '/' X/* X* @(#)keys.h 2.24 X*/ X X#define CLEFT 0x180 X#define CRIGHT 0x181 X#define START 0x182 X#define END 0x183 X#define BACKDEL 0x184 X#define FORWDEL 0x185 X#define KILL 0x186 X#define INSERT 0x187 X#define RETURN 0x188 X#define RETYPE 0x189 X#define CDOWN 0x18a X#define CUP 0x18b X#define FPROG 0x18c X#define FSTART 0x200 X#define F01 0x01 X#define F02 0x02 X#define F03 0x03 X#define F04 0x04 X#define F05 0x05 X#define F06 0x06 X#define F07 0x07 X#define F08 0x08 X#define F09 0x09 X#define F10 0x0a /
leo@marco.UUCP (Matthias Pfaller) (03/14/90)
Sorry, but I have forgotten the makefiles; I received the pcminix-makefile from Robert R. Hall (hall@nosc.mil). I hope it will work. In the file zbios.c the last line got somehow lost. Please insert a '#endif' as the last line. leo@marco.UUCP (Matthias Pfaller) # -------------------- cut --------------------- echo x - stminix.mk sed '/^X/s///' > stminix.mk << '/' XOBJS = zmachine.o \ X io.o \ X mem.o \ X code.o \ X zbios.o X XBIN = $(HOME)/bin X XCFLAGS = -O -Dunix -Dminix X Xall: zmachine X Xzmachine: $(OBJS) X $(CC) -o zmachine $(OBJS) X X$(OBJS): zmachine.h config.h X Xio.o bios.o: keys.h X Xinstall: all X cp zmachine $(BIN)/zmachine X strip $(BIN)/zmachine / echo x - pcminix.mk sed '/^X/s///' > pcminix.mk << '/' XCFLAGS= -F -D_MINIX -D_POSIX_SOURCE -Dminix -Dunix XLDFLAGS =-i X XOBJS =code.s io.s mem.s zbios.s zmachine.s X Xzmachine: $(OBJS) X asld $(LDFLAGS) -o zmachine $(OBJS) X Xclean: X @rm $(OBJS) X /
leo@marco.UUCP (Matthias Pfaller) (03/16/90)
Sorry again, I have forgotten, that I have changed my stdio.h and my fcntl.h. You have to include sys/types.h in zbios.c before including fcntl.h. You have to insert a --- #undef NULL #define NULL ((char *)0) --- after including stdio.h in zmachine.h. leo@marco.UUCP (Matthias Pfaller)