# include "term.h" fixbios () { static char *p, **pp, *esctab, /* pointers to beginnings of regions */ *contab, *escvect, *convect, *ss; static short extra, *i, n, nesc, /* number of translateable sequences */ ncont, newsize, oldsize; static offset; static struct dca *d; static struct xlt *x, *next; static struct ctrans *ct; static struct mtab *mtab, *m; /* * first we calulate the offset between * actual addresses and address in the local memory image * of the BIOS in biosbuf */ i = biosbuf + 1; /* pointing at bytes 1 and 2 */ offset = (*i & HIBYTE) - BIOSSIZE; /* * now find the direct cursor addressing block */ i = biosbuf + DCAOFFSET; /* address of dca pointer */ d = biosbuf + *i - offset; /* set pointer to dca struct */ /* * range check the number */ if (biosbuf <= d && d < biosbuf + BIOSSIZE) { cpybuf (d, &terminal[term].dca, sizeof *d); /* dca patch */ } else { prs (" out of range DCA pointer\n"); } /* * change the strings to ff terminated strings */ ffterm (d->start); ffterm (d->mid); ffterm (d->end); /* * find the beginning of the linked list of tables */ i = biosbuf + 0x46; x = biosbuf + *i - offset; /* * now follow the chain until we find the one we're looking for */ for (;;) { if (x < biosbuf || biosbuf + BIOSSIZE < x) /* out of range */ { fatal ("\nWrong version of CP/M\n"); } if (x->code == TRANTAB || x->code == ENDTAB) break; x = (char *) x + x->length + sizeof (*x); } if (x->code == ENDTAB) fatal ("No char. translation table found\n"); next = (char *) x + x->length + sizeof (*x); if (next->code != ENDTAB) fatal ("Char tran table not last in list\n"); extra = next->length; oldsize = x->length; /* * we've found our translation table * It's the last table in the list * and free space follows. */ p = x + 1; /* p bpoints to the biginning of table space */ /* * patch in the pointer to the beginning of the esc char. table */ # define ESCTBL 0x48 i = biosbuf + ESCTBL; *i = p - biosbuf + offset; /* * here we lay in all the esc chars and then a ~0 for termination * count the escape characters on the way. */ ct = terminal[term].escape; nesc = 0; for (n = 0; n < NESCAPE; n++, ct++) if (ct->to) *p++ = ct->from, nesc++; *p++ = ~0; /* list termination */ /* * patch the pointer to the beginning of control char table */ # define CTRLTBL 0x4a i = biosbuf + CTRLTBL; *i = p - biosbuf + offset; /* * now lay down all the control characters * counting them as you go. */ ct = terminal[term].control; ncont = 0; for (n = 0; n < NCONTROL; n++, ct++) if (ct->to) *p++ = ct->from, ncont++; *p++ = ~0; /* terminate the list of cont. chars */ /* * find pointer to the beginning of string space */ ss = p + (nesc + ncont) * sizeof (char *); pp = p; /* prepare to lay down pointers */ /* * patch the escape vector pointer */ # define ESCVECT 0x4c i = biosbuf + ESCVECT; *i = (char *) pp - biosbuf + offset; ct = terminal[term].escape; for (n = 0; n < NESCAPE; n++, ct++) { if (ct->to) { char *new; *pp++ = ss + offset - biosbuf; /* save the pointer */ new = cpystr (ss, ct->to, NULL); /* copy in string */ ffterm (ss); ss = new + 1; } } /* * patch the control vector pointer */ # define CTVECT 0x4e i = biosbuf + CTVECT; *i = (char *) pp - biosbuf + offset; ct = terminal[term].control; for (n = 0; n < NCONTROL; n++, ct++) { if (ct->to) { char *new; *pp++ = ss + offset - biosbuf; /* save the pointer */ new = cpystr (ss, ct->to, NULL); /* copy in string */ ffterm (ss); ss = new + 1; /* leave space for the FF termination */ } } /* * now we patch up the linked list */ /* * make sure there's enough space */ newsize = ss - (char *) (x + 1); if (newsize > oldsize && newsize - oldsize > extra) fatal ("Out of string space\n"); next = ss; x->length = newsize; next->code = ENDTAB; next->length = extra - newsize + oldsize; /* * now patch the drive tables */ /* * find the tables */ i = biosbuf + 0x44; mtab = *i - offset + biosbuf; domtab (mtab); /* * patch the number of drives and the level of the terminal */ i = biosbuf + RAMDATY; p = biosbuf + *i - offset - 2; /* set pointer to dca struct */ *p++ = ndrives; *p = terminal[term].level; } /* * invert a null terminated string to one terminated by an all bits set char. * If an FF appears in a string, change it to a null. */ ffterm (a) char *a; { while (*a) { if (*a == ~0) *a = NULL; a++; } *a = ~0; /* final termination */ } # define MOTOR 7 /* 3 bit motor field */ # define PHYS 3 # define VIRT (1 << 7) # define EXT 3 # define MAXDRIVES 4