|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 8826 (0x227a)
Types: TextFile
Notes: UNIX file
Names: »hrterm3.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »hrtty/src/hrterm3.c«
#include <signal.h>
#include <errno.h>
#include "../h/rico.h"
#include "../h/machine.h"
#include "../h/display.h"
#include "../h/subr.h"
#include "../h/font.h"
extern unsigned short nulls[];
uint ascii[MAXLINE][MAXCOL];
uint line,
col,
iget,
iput,
inl;
state;
bool iesc;
/*
** Screen Initialization routine. Called by htload
*/
ricoload()
{
register unsigned short i,j;
unsigned short *sp;
for(i = 0; i <YSCROLL*WPERSL;i++)nulls[i] = 0xffff;
sp = SEG0;
for(i = 0; i<512; i++)
for(j = 0; j < 1024/16; j++)
*sp++ = 0xffff;
sp = SEG1;
for(i = 0; i< 800-512; i++)
for(j = 0; j < 1024/16; j++)
*sp++ = 0xffff;
state = 0;
col = 0;
line = MAXLINE-1;
for(i=0; i<MAXLINE; i++)
for(j=0; j<MAXCOL; j++)
ascii[i][j] = ' ';
cursor();
}
rico( c)
{
register li;
static uint
arg,
args[2];
switch (state) {
/*
* no ongoing escape sequence
*/
case 0:
switch (c) {
case '\33':
state = 1;
break;
case '\n':
++line;
if (line >= MAXLINE) {
uint i,j;
/*
j = (MAXLINE - 1)*YSCROLL;
for(i=0;i<YSCROLL;++i)
scompute(j+i);
*/
line = MAXLINE - 1;
for(i=1; i< MAXLINE; i++){
moveline(i, 1);
slcompute(i);
}
for(i=0; i<MAXCOL; i++)
ascii[MAXLINE-1][i] = ' ';
scroll( );
}
else{
/*
uint i,j;
if( line - 1){
j = (line -1)*YSCROLL;
for(i=0; i<YSCROLL; ++i)
scompute(j+i);
}
*/
}
col = 0;
break;
case '\r':
col = 0;
break;
case '\t':
col = tab( col);
break;
case '\b':
if (col)
--col;
break;
case ctrl( 'G'):
bell( );
break;
default:
plotc( c, col, line);
++col;
}
break;
/*
* ESC
*/
case 1:
switch (c) {
case '[':
arg = nel( args);
do {
args[--arg] = 0;
} while (arg);
state = 2;
break;
default:
state = 0;
rico( c);
break;
}
break;
/*
* ESC [
*/
case 2:
switch (c) {
default:
if ((isascii( c))
and (isdigit( c))
and (arg < nel( args))) {
args[arg] = args[arg]*10 + c - '0';
break;
}
state = 0;
rico( c);
break;
case ';':
++arg;
break;
case 'H': /* Cursor Home */
col = 0;
if (args[1])
col = args[1] - 1;
if (args[0])
--args[0];
if (args[0] < MAXLINE){
/*
if(~(texttab[line] & SCROLLABLE))
slcompute(line);
*/
line = args[0];
}
state = 0;
break;
case 'A': /* Cursor Up */
if (not args[0])
++args[0];
if (args[0] <= line){
/*
if(~(texttab[line] & SCROLLABLE))
slcompute(line);
*/
line -= args[0];
}
state = 0;
break;
case 'B': /* Cursor Down */
if (not args[0])
++args[0];
if (args[0] < MAXLINE-1){
/*
if(~(texttab[line] & SCROLLABLE))
slcompute(line);
*/
line += args[0];
}
state = 0;
break;
case 'D':
if (not args[0])
++args[0];
if (args[0] <= col)
col -= args[0];
state = 0;
break;
case 'C':
if (not args[0])
++col;
else
col += args[0];
state = 0;
break;
case 'J': /* Erase Screen */
for(line = 0; line < MAXLINE; line++)
{
uint j;
for(j=0; j<MAXCOL; j++)
ascii[line][j] = ' ';
/*
texttab[line] &= ERASED;
*/
linerase(line);
/*
slcompute(line);
*/
}
slecompute();
line = 0;
col = 0;
state = 0;
break;
case 'L':
scrolld( line);
col = 0;
state = 0;
break;
case 'M':
for(li=line; li< MAXLINE; li++)
if(li)
moveline(li, 1);
scrollu( line);
for(li=0; li<MAXCOL; li++)
ascii[MAXLINE][li] = ' ';
col = 0;
state = 0;
break;
case 'K':
eolerase( line, col);
state = 0;
break;
case '@':
cinsert( args[0]);
state = 0;
break;
case 'P':
cdelete( args[0]);
state = 0;
break;
}
}
}
isascii(c) char c;{ return((c >= 0x20)&&(c <= 0x7f));}
isdigit(c) char c;{ return((c >= '0')&&(c<='9'));}
scrolld( li)
int li;
{
uint y,
ybase,
o,
*p,
*q,
co;
int i;
int n;
for (n=MAXLINE-1; n>li; --n)
slcompute( n);
for (n=MAXLINE-1; n>li; --n)
{
i = n-1;
texttab[n] = texttab[i];
}
for (n=MAXLINE-2; n>=li; n--)
moveline(n, 0);
ybase = li * YSCROLL;
y = (MAXLINE-1) * YSCROLL;
while (y > ybase) {
--y;
if (y >= YSPLIT) {
p = (uint *)SEG1 + (y-YSPLIT)*WPERSL;
q = p + YSCROLL*WPERSL;
} else if (y+YSCROLL < YSPLIT) {
p = (uint *)SEG0 + y*WPERSL;
q = p + YSCROLL*WPERSL;
} else {
p = (uint *)SEG0 + y*WPERSL;
q = (uint *)SEG1 + (y+YSCROLL-YSPLIT)*WPERSL;
}
n = scantab[y+YSCROLL].sc_nword;
if (n) {
o = scantab[y+YSCROLL].sc_off;
p += o;
q += o;
aldir( q, p, n);
}
scantab[y+YSCROLL] = scantab[y];
}
eolerase( li, 0);
if (li+1 < MAXLINE)
texttab[li+1] &= ~SCROLLABLE;
}
eolerase( li, co)
uint li,
co;
{
if (texttab[li] & ERASED)
return;
if (not co) {
for(; co<MAXCOL; ++co)
ascii[li][co] = ' ';
linerase( li);
texttab[li] |= ERASED;
}
else{
for (; co<MAXCOL; ++co)
plotc( ' ', co, li);
}
texttab[li] &= ~SCROLLABLE;
if (li+1 < MAXLINE)
texttab[li+1] &= ~SCROLLABLE;
}
cinsert( n)
uint n;
{
register co;
if ( not n)
n = 1;
if (n <= MAXCOL)
for (co=MAXCOL-n; co>col; ) {
--co;
plotc(ascii[line][co], co+n, line);
}
for (co=col; co<col+n && co<MAXCOL; ++co){
plotc(' ', co, line);
}
slcompute(line);
/*
texttab[line] &= ~SCROLLABLE;
if (line+1 < MAXLINE)
texttab[line+1] &= ~SCROLLABLE;
*/
}
cdelete( n)
uint n;
{
register co;
if (not n)
n = 1;
for (co=col; co+n<MAXCOL; ++co)
plotc(ascii[line][co+n], co, line);
for (; co<MAXCOL; ++co)
plotc(' ', co, line);
texttab[line] &= ~SCROLLABLE;
if (line+1 < MAXLINE)
texttab[line+1] &= ~SCROLLABLE;
}
plotc( c, co, li)
uint co,
li;
{
register short *fp;
register char *p;
register uint y;
uint ylim;
char b,
segflag;
uint coladdr;
if (co >= MAXCOL)
return;
if((c > 0x7f) && (c < 0xa0)) return;
/*
if(c < 0x20) return;
*/
ascii[li][co] = c;
fp = font[c-' '];
if(c & 0x80) fp = font[c-0x40];
y = li * YSCROLL;
ylim = y + YSCROLL;
coladdr = ( co * 3) >> 1; /* co*12/8 */
segflag = 0;
p = (char *)SEG0+y*BPERSL + coladdr;
if (co&1) {
for(; y<ylim; y++) {
if(y >= YSPLIT){
if( not segflag){
p = (char *)SEG1+(y-YSPLIT)*BPERSL+
coladdr;
segflag = 1;
}
}
b = (char)((~(*fp>>12))&0xf);
*p = (*p&0xf0)|b;
*++p = ~((char)(*fp++>>4));
p--;
p += BPERSL;
}
}
else {
for (; y<ylim; y++) {
if (y >= YSPLIT){
if( not segflag){
p = (char *)SEG1 + (y-YSPLIT)*BPERSL+
coladdr;
segflag = 1;
}
}
*p++ = (char)(~((*fp)>>8));
*p = (*p&0xf) | (char)((~(*fp++))&0xf0);
p--;
p += BPERSL;
}
}
texttab[li] &= ~ (SCROLLABLE|ERASED);
if (line+1 < MAXLINE)
texttab[line+1] &= ~SCROLLABLE;
}
bell( )
{
uint i,
*p;
p = SEG0;
for (i=0; i<2*YSCROLL*WPERSL; ++i)
*p++ ^= ~0;
p = SEG0;
for (i=0; i<2*YSCROLL*WPERSL; ++i)
*p++ ^= ~0;
}
cursor( )
{
register uchar *p;
register uint y,
ylim;
register int coladdr;
char segflag;
if (col >= MAXCOL)
return;
y = line * YSCROLL;
ylim = y + YSCROLL;
coladdr = (col * 3) >> 1; /* col * 12 / 8 */
p = (char *)SEG0 + y*BPERSL + coladdr;
segflag = 0;
if(col&1) {
for (; y<ylim; ++y) {
if (y >= YSPLIT){
if( not segflag){
p = (char *)SEG1 + (y-YSPLIT)*BPERSL +
coladdr;
segflag = 1;
}
}
*p++ ^=0x0f;
*p ^= 0xff;
p--;
p += BPERSL;
}
}
else{
for(; y<ylim; ++y) {
if( y >= YSPLIT){
if( not segflag){
p = (char *)SEG1 + (y-YSPLIT)*BPERSL +
coladdr;
segflag = 1;
}
}
*p++ ^= 0xff;
*p ^= 0xf0;
p--;
p += BPERSL;
}
}
}
/* given dest, src col numbers will move 12 bits of a char in raster */
int tmove(dst, src, p)
register int dst; /* destination column */
register int src; /* source column */
uchar *p; /* raster address */
{
register tdst,
tsrc;
tdst = (dst * 3) >> 1; /* for 12 bits 12/8 */
tsrc = (src * 3) >> 1;
if( dst & 1){ /* odd dst */
if( src & 1){ /* odd src */
p[tdst] = (p[tsrc] & 0x0F) | (p[tdst] & 0xF0);
p[tdst+1] = p[tsrc+1];
}
else{ /* even src */
p[tdst] = (p[tdst] & 0xF0) | ((p[tsrc] >> 4) & 0x0F);
p[tdst + 1] = (p[tsrc] << 4) | (p[tsrc+1] >> 4);
}
}
else{ /* even dst */
if( src & 1){ /* odd src */
p[tdst] = (p[tsrc] << 4) | (p[tsrc+1] >> 4);
p[tdst+1] = (p[tdst+1] & 0x0F) | (p[tsrc+1] << 4);
}
else{ /* even src */
p[tdst] = p[tsrc];
p[tdst+1] = (p[tdst+1] & 0x0F) | (p[tsrc+1] & 0xF0);
}
}
}
int moveline(li, flag)
uint li;
uint flag;
{
uint *p,
*q;
/*
if(flag)
for(i=0; i< MAXCOL; i++)
ascii[li-1][i] = ascii[li][i];
else
for(i=0; i< MAXCOL; i++)
ascii[li+1][i] = ascii[li][i];
*/
p = ascii[li];
if( flag)
q = p - MAXCOL;
else
q = p + MAXCOL;
aldir( q, p, MAXCOL);
}