mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
360 lines
9.7 KiB
C
360 lines
9.7 KiB
C
#ifdef RLI
|
|
#include "diverge.h"
|
|
#endif
|
|
|
|
/********************************************************
|
|
* *
|
|
* CP/M-68K BDOS Character I/O Routines *
|
|
* *
|
|
* This module does BDOS functions 1 thru 11 *
|
|
* *
|
|
* It contains the following functions which *
|
|
* are called from the BDOS main routine: *
|
|
* constat(); *
|
|
* conin(); *
|
|
* tabout(); *
|
|
* rawconio(); *
|
|
* prt_line(); *
|
|
* readline(); *
|
|
* *
|
|
* Copyright (c) 1982 Digital Research, Inc. *
|
|
* *
|
|
* Modified 2/5/84 sw Allow typeahead *
|
|
* ^C warmboot modifications *
|
|
* Again 3/17/84 sw Chain hack *
|
|
* *
|
|
********************************************************/
|
|
|
|
#include "bdosinc.h"
|
|
|
|
#include "bdosdef.h"
|
|
|
|
#include "biosdef.h"
|
|
|
|
|
|
#define ctrlc 0x03
|
|
#define ctrle 0x05
|
|
#define ctrlp 0x10
|
|
#define ctrlq 0x11
|
|
#define ctrlr 0x12
|
|
#define ctrls 0x13
|
|
#define ctrlu 0x15
|
|
#define ctrlx 0x18
|
|
|
|
#define cr 0x0d
|
|
#define lf 0x0a
|
|
#define tab 0x09
|
|
#define rub 0x7f
|
|
#define bs 0x08
|
|
#define space 0x20
|
|
|
|
|
|
EXTERN warmboot(); /* External function definition */
|
|
|
|
|
|
/******************/
|
|
/* console status */
|
|
/******************/
|
|
|
|
BOOLEAN constat()
|
|
{
|
|
BSETUP
|
|
|
|
return( GBL.kbchar ? TRUE : bconstat() );
|
|
}
|
|
|
|
/********************/
|
|
/* check for ctrl/s */
|
|
/* used internally */
|
|
/********************/
|
|
conbrk()
|
|
{
|
|
REG UBYTE ch;
|
|
REG BOOLEAN stop;
|
|
BSETUP
|
|
|
|
stop = FALSE;
|
|
if ( bconstat() ) do
|
|
{
|
|
if ( (ch = bconin()) == ctrlc ) warmboot(2); /*sw from (1) */
|
|
if ( ch == ctrls ) stop = TRUE;
|
|
else if (ch == ctrlq) stop = FALSE;
|
|
else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
|
|
/*sw What Follows is new... */
|
|
else /* Insert character in ring buffer */
|
|
{ /* */
|
|
if(GBL.kbchar < TBUFSIZ) /* Room? */
|
|
{ /************************************/
|
|
*GBL.insptr++ = ch; /* Yes, insert the character in buff*/
|
|
GBL.kbchar++; /* Up count */
|
|
} /************************************/
|
|
} /* Note if no room, character is */
|
|
/* Ignomiously discarded (!) */
|
|
/*sw End of new stuff */
|
|
/************************************/
|
|
} while (stop);
|
|
}
|
|
|
|
|
|
/******************/
|
|
/* console output */
|
|
/* used internally*/
|
|
/******************/
|
|
|
|
conout(ch)
|
|
REG UBYTE ch;
|
|
{
|
|
BSETUP
|
|
|
|
conbrk(); /* check for control-s break */
|
|
bconout(ch); /* output character to console */
|
|
if (GBL.lstecho) blstout(ch); /* if ctrl-p on, echo to list dev */
|
|
if ((UWORD)ch >= (UWORD)' ')
|
|
GBL.column++; /* keep track of screen column */
|
|
else if (ch == cr) GBL.column = 0;
|
|
else if (ch == bs) GBL.column--;
|
|
}
|
|
|
|
|
|
/*************************************/
|
|
/* console output with tab expansion */
|
|
/*************************************/
|
|
|
|
tabout(ch)
|
|
REG UBYTE ch; /* character to output to console */
|
|
{
|
|
BSETUP
|
|
|
|
if (ch == tab) do
|
|
conout(' ');
|
|
while (GBL.column & 7);
|
|
else conout(ch);
|
|
}
|
|
|
|
/*******************************/
|
|
/* console output with tab and */
|
|
/* control character expansion */
|
|
/*******************************/
|
|
|
|
cookdout(ch)
|
|
REG UBYTE ch; /* character to output to console */
|
|
{
|
|
if (ch == tab) tabout(ch); /* if tab, expand it */
|
|
else
|
|
{
|
|
if ( (UWORD)ch < (UWORD)' ' )
|
|
{
|
|
conout( '^' );
|
|
ch |= 0x40;
|
|
}
|
|
conout(ch); /* output the character */
|
|
}
|
|
}
|
|
|
|
|
|
/*****************/
|
|
/* console input */
|
|
/*****************/
|
|
|
|
UBYTE getch() /* Get char from buffer or bios */
|
|
/* For internal use only */
|
|
{
|
|
REG UBYTE temp;
|
|
BSETUP
|
|
|
|
if(GBL.kbchar)
|
|
{
|
|
temp = *GBL.remptr++; /* Fetch the character */
|
|
GBL.kbchar--; /* Decrement the count */
|
|
if(!GBL.kbchar) /* Gone to zero? */
|
|
GBL.remptr = GBL.insptr = &(GBL.t_buff[0]);
|
|
return(temp);
|
|
}
|
|
return( bconin() ); /* else get char from bios */
|
|
}
|
|
|
|
UBYTE conin() /* BDOS console input function */
|
|
{
|
|
REG UBYTE ch;
|
|
BSETUP
|
|
|
|
conout( ch = getch() );
|
|
if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
|
|
return(ch);
|
|
}
|
|
|
|
/******************
|
|
* raw console i/o *
|
|
******************/
|
|
|
|
UBYTE rawconio(parm) /* BDOS raw console I/O function */
|
|
|
|
REG UWORD parm;
|
|
{
|
|
BSETUP
|
|
|
|
if (parm == 0xff) return(getch());
|
|
else if (parm == 0xfe) return(constat());
|
|
else bconout(parm & 0xff);
|
|
}
|
|
|
|
|
|
/****************************************************/
|
|
/* print line up to delimiter($) with tab expansion */
|
|
/****************************************************/
|
|
|
|
prt_line(p)
|
|
REG UBYTE *p;
|
|
{
|
|
BSETUP
|
|
|
|
while( *p != GBL.delim ) tabout( *p++ );
|
|
}
|
|
|
|
|
|
/**********************************************/
|
|
/* read line with editing and bounds checking */
|
|
/**********************************************/
|
|
|
|
/* Two subroutines first */
|
|
|
|
newline(startcol)
|
|
REG UWORD startcol;
|
|
{
|
|
BSETUP
|
|
|
|
conout(cr); /* go to new line */
|
|
conout(lf);
|
|
while(startcol)
|
|
{
|
|
conout(' ');
|
|
startcol -= 1; /* start output at starting column */
|
|
}
|
|
}
|
|
|
|
|
|
backsp(bufp, col)
|
|
/* backspace one character position */
|
|
REG struct conbuf *bufp; /* pointer to console buffer */
|
|
REG WORD col; /* starting console column */
|
|
{
|
|
REG UBYTE ch; /* current character */
|
|
REG WORD i;
|
|
REG UBYTE *p; /* character pointer */
|
|
BSETUP
|
|
|
|
if (bufp->retlen) --(bufp->retlen);
|
|
/* if buffer non-empty, decrease it by 1 */
|
|
i = UBWORD(bufp->retlen); /* get new character count */
|
|
p = &(bufp->cbuf[0]); /* point to character buffer */
|
|
while (i--) /* calculate column position */
|
|
{ /* across entire char buffer */
|
|
ch = *p++; /* get next char */
|
|
if ( ch == tab )
|
|
{
|
|
col += 8;
|
|
col &= ~7; /* for tab, go to multiple of 8 */
|
|
}
|
|
else if ( (UWORD)ch < (UWORD)' ' ) col += 2;
|
|
/* control chars put out 2 printable chars */
|
|
else col += 1;
|
|
}
|
|
while (GBL.column > col)
|
|
{
|
|
conout(bs); /* backspace until we get to proper column */
|
|
conout(' ');
|
|
conout(bs);
|
|
}
|
|
}
|
|
|
|
|
|
readline(p) /* BDOS function 10 */
|
|
REG struct conbuf *p;
|
|
|
|
{
|
|
REG UBYTE ch;
|
|
REG UWORD i;
|
|
REG UWORD j;
|
|
REG UBYTE *q;
|
|
UWORD stcol;
|
|
|
|
BSETUP
|
|
|
|
stcol = GBL.column; /* set up starting column */
|
|
|
|
#ifdef NFG /*sw This didn't work for SUBMIT files...*/
|
|
if (GBL.chainp != NULL) /* chain to program code */
|
|
{
|
|
i = UBWORD(*(GBL.chainp++));
|
|
j = UBWORD(p->maxlen);
|
|
if (j < i) i = j; /* don't overflow console buffer! */
|
|
p->retlen = (UBYTE)i;
|
|
q = p->cbuf;
|
|
while (i)
|
|
{
|
|
cookdout( *q++ = *(GBL.chainp++) );
|
|
i -= 1;
|
|
}
|
|
GBL.chainp = NULL;
|
|
return;
|
|
}
|
|
#endif /*sw NFG chain code */
|
|
|
|
p->retlen = 0; /* start out with empty buffer */
|
|
while ( UBWORD(p->retlen) < UBWORD(p->maxlen) )
|
|
{ /* main loop for read console buffer */
|
|
|
|
if ( ((ch=getch()) == ctrlc) && !(p->retlen) )
|
|
{
|
|
cookdout(ctrlc);
|
|
warmboot(2); /*sw From warmboot(1) */
|
|
}
|
|
|
|
else if ( (ch == cr) || (ch == lf) )
|
|
{ /* if cr or lf, exit */
|
|
conout(cr);
|
|
break;
|
|
}
|
|
|
|
else if (ch == bs) backsp(p, stcol); /* backspace */
|
|
|
|
else if (ch == rub) /* delete character */
|
|
{
|
|
if (GBL.echodel)
|
|
{
|
|
if (p->retlen)
|
|
{
|
|
i = UBWORD(--(p->retlen));
|
|
conout( p->cbuf[i] );
|
|
}
|
|
}
|
|
else backsp(p, stcol);
|
|
}
|
|
|
|
else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
|
|
/* control-p */
|
|
else if (ch == ctrlx) /* control-x */
|
|
do backsp(p,stcol); while (p->retlen);
|
|
|
|
else if (ch == ctrle) newline(stcol); /* control-e */
|
|
|
|
else if (ch == ctrlu) /* control-u */
|
|
{
|
|
conout('#');
|
|
newline(stcol);
|
|
p->retlen = 0;
|
|
}
|
|
|
|
else if (ch == ctrlr) /* control-r */
|
|
{
|
|
conout('#');
|
|
newline(stcol);
|
|
for (i=0; i < UBWORD(p->retlen); i++)
|
|
cookdout( p->cbuf[i] );
|
|
}
|
|
|
|
else /* normal character */
|
|
cookdout( p->cbuf[UBWORD((p->retlen)++)] = ch );
|
|
}
|
|
}
|