/* > c.buffer (c) D.R.McAuley 1987 */ #include "arthur.h" #include #include "tty.h" static reg_set rs; reg_set *regptr = &rs; #define interupts_off() swix(OS_IntOff, regptr) #define interupts_on() swix(OS_IntOn, regptr) #define ctrlS 19 #define ctrlQ 20 #define BUFFSIZE 0x4000 #define BUFFLWM 0x0400 #define BUFFHWM 0x3C00 /* #define OUTPUTTOO */ #define XONXOFF #ifdef OUTPUTTOO static char rsbufout[BUFFSIZE]; static char *headout = rsbufout; static char *tailout = rsbufout; static int countout = 0; #endif static char rsbufinn[BUFFSIZE]; static char *headinn = rsbufinn; static char *tailinn = rsbufinn; static int countinn = 0; static char kbbufinn[BUFFSIZE]; static char *kbheadinn = kbbufinn; static char *kbtailinn = kbbufinn; static int kbcountinn = 0; static struct { unsigned count:8; unsigned on:1; unsigned run:1; } x; void (*keypoller)(); /* code */ static f_ptr tmp; f_ptr define_keypoller(void (*proc)()) { tmp = keypoller; keypoller = proc; return tmp; } void set_xon_xoff(int state) { x.count = 0; x.on = state; x.run = state; } int rsgetcount (void) { return(0); } int kbgetcount (void) { return(0); } #ifdef OUTPUTTOO int _rsinsertout(char ch) { int wasdead = (countout == 0); if (countout == BUFFSIZE) return (1); if (ch != 0) { (countout)++; *headout = ch; if (++(headout) == (rsbufout + BUFFSIZE)) headout = rsbufout; } if (wasdead) inter(); return (0); } int _rsremoveout(int examine) { char ch; if (countout == 0) return(256); ch = *tailout; if (!examine) { countout--; if (++(tailout) == (rsbufout + BUFFSIZE)) tailout = rsbufout; } return (ch); } int _rscountnpout(int purge, int countt) { if (purge) { countout = 0; headout = tailout = rsbufout; return (0); } if (countt) return(BUFFSIZE-countout); else return(countout); } #endif int _rsinsertinn(char ch) { if (countinn == BUFFSIZE) return (1); if (ch != 0) { (countinn)++; *headinn = ch; if (++(headinn) == (rsbufinn + BUFFSIZE)) headinn = rsbufinn; } return (0); } int _rsremoveinn(int examine) { char ch; if (countinn == 0) return(256); ch = *tailinn; if (!examine) { countinn--; if (++(tailinn) == (rsbufinn + BUFFSIZE)) tailinn = rsbufinn; } return (ch); } int _rscountnpinn(int purge, int countt) { if (purge) { countinn = 0; headinn = tailinn = rsbufinn; return (0); } if (countt) return(BUFFSIZE-countinn); else return(countinn); } static int kbcalled = 0; int _kbinsertinn(char ch) { kbcalled++; if (kbcountinn == BUFFSIZE) return (1); if (ch != 0) { (kbcountinn)++; *kbheadinn = ch; if (++(kbheadinn) == (kbbufinn + BUFFSIZE)) kbheadinn = kbbufinn; } return (0); } int _kbremoveinn(int examine) { char ch; if (kbcountinn == 0) return(256); ch = *kbtailinn; if (!examine) { kbcountinn--; if (++(kbtailinn) == (kbbufinn + BUFFSIZE)) kbtailinn = kbbufinn; } return (ch); } int _kbcountnpinn(int purge, int countt) { if (purge) { kbcountinn = 0; kbheadinn = kbtailinn = kbbufinn; return (0); } if (countt) return(BUFFSIZE-kbcountinn); else return(kbcountinn); } void rsinsert(int ch, int b) { interupts_off(); if (b == 1) _rsinsertinn((char) ch); #ifdef OUTPUTTOO else _rsinsertout((char) ch); #endif interupts_on(); } int rsremove(int b) { int ch = 0; if (b == 1 ) { if (countinn != 0) { interupts_off(); ch = _rsremoveinn(FALSE); interupts_on(); } #ifdef OUTPUTTOO } else { if (countout != 0) { interupts_off(); ch = _rsremoveout(FALSE); interupts_on(); } #endif } return(ch); } void rspurge(int b) { interupts_off(); if (b == 1) _rscountnpinn(TRUE, 0); #ifdef OUTPUTTOO else _rscountnpout(TRUE, 0); #endif interupts_on(); } int rscount(int spaces, int b) { int cnt; interupts_off(); if (b ==1 ) cnt = _rscountnpinn(FALSE, spaces); #ifdef OUTPUTTOO else cnt = _rscountnpout(FALSE, spaces); #endif interupts_on(); return(cnt); } void kbinsert(int ch, int b) { interupts_off(); if (b == 0) _kbinsertinn((char) ch); interupts_on(); } int kbremove(int b) { int ch = 0; if (b == 0 ) { if (kbcountinn != 0) { interupts_off(); ch = _kbremoveinn(FALSE); interupts_on(); } } return(ch); } void kbpurge(int b) { interupts_off(); if (b == 0) _kbcountnpinn(TRUE, 0); interupts_on(); } int kbcount(int spaces, int b) { int cnt; interupts_off(); if (b == 0 ) cnt = _kbcountnpinn(FALSE, spaces); interupts_on(); return(cnt); } int rsgetch(void) { int ch; int loop = 0; x.count++; while (TRUE) { #ifdef XONXOFF if (x.count > 16) { if ((countinn >= BUFFHWM) && x.run && x.on) { sendchar(ctrlS); x.run = FALSE; } else if ((countinn <= BUFFLWM) && (!x.run) && x.on) { sendchar(ctrlQ); x.run = TRUE; } x.count = 0; (*keypoller)(); } #endif if ((ch = pollch()) != NOCHAR) return(ch); if (loop++ == 16) { loop = 0; (*keypoller)(); } } } int pollch(void) { return(rsremove(1) & 0x7F); } /* int pollch(void) { mosbyte2(145, 1); return(regs.r[2] & 0x7F); } */ #ifdef OUTPUTTOO void sendchar(int ch) { rsinsert(ch, 2); } #else void sendchar(int ch) { mosbyte3(138, 2, ch); } #endif void inter(void) { mosbyte3(156, 0x20, 0x9F); } /* Enable interupts poo */