CP/M paging program for netnews readers
utzoo!decvax!harpo!eagle!karn
utzoo!decvax!harpo!eagle!karn
Thu Jun 10 01:41:18 AEST 1982
/* The number of requests for my terminal paging program has been
* sufficient to warrant posting it on net.sources.
* This version is set up for the Heathkit H-19;
* three constants can be changed to configure it for other
* terminals.
* Note that no attempt is made to keep track of cursor movement by
* means other than printing characters, carriage return or line feed
* characters; hence, this program will get very confused if you try
* to run emacs, vi, etc., through it.
*
* Use BDS-C to compile, and clink with the cio terminal I/O
* package. Note that I make reference to the terminal and modem port
* definitions in bdscio.h.
*/
/*
* Modem buffering program. A large chunk of memory is used as a circular
* buffer for incoming modem data, which is sent out to the terminal
* a crt page at a time. High/low water marks are used to flow control
* the host when the buffer is filled.
*
* The program is NOT interrupt driven. Frequent polls are made on
* both the keyboard and modem ports to avoid losing characters.
* March 1982, Phil Karn
*/
#include <a:bdscio.h>
/* Terminal dependent parameters */
#define ROWS 24
#define COLS 80
#define ERASE "\033E"
#define BSIZE 32767
#define HIWATER 32000
#define LOWATER 31000
#define CTLS 19
#define CTLQ 17
char buffer[BSIZE];
char *in,*out;
int count;
int stopped;
main()
{
register char c;
int row,col; /* Cursor position */
stopped = count = col = row = 0;
in = out = buffer;
TTYMode(0); /* Really raw mode */
puts(ERASE); /* Erase screen */
loop: scanmod();
scankbd();
c = getb();
switch(c & 0x7f){
case '\n':
row++;
break;
case '\r':
col = 0;
break;
default:
/* Normal character; check for end of line wraparound */
col++;
if(col == COLS){
col = 0;
row++;
}
break;
}
/* Screen full. Wait for any character before proceeding */
while(row == ROWS){
while(!kbhit())
scanmod();
getchar();
col = row = 0;
puts(ERASE);
}
/* Don't waste the top line of the screen with the newline */
if(c != '\n' || row != 0 )
putchar(c);
goto loop;
}
scanmod()
{
/* Scan modem input for activity */
if(inp(MSTAT) & MIMASK){
*in++ = inp(MDATA);
count++;
if(in == &buffer[BSIZE])
in = buffer;
if(!stopped && count > HIWATER){
stopped = 1;
putmod(CTLS);
}
}
}
scankbd()
{
/* Do same for keyboard */
if(kbhit())
putmod(getchar());
}
/* Fetch char from modem input buffer */
char
getb()
{
char c;
while(count == 0){
scanmod();
scankbd();
}
c = *out++;
count--;
if(stopped && count < LOWATER){
stopped = 0;
putmod(CTLQ);
}
if(out == &buffer[BSIZE])
out = buffer;
return(c);
}
/* Send character to modem */
putmod(c)
char c;
{
while((inp(MSTAT) & MOMASK) == 0)
scanmod();
outp(MDATA,c);
}
More information about the Comp.sources.unix
mailing list