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)