/* * Name: MicroEMACS * Amiga console device virtual terminal display * Version: 31 * Last Edit: 19-Apr-86 * Created: 19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic * * Drives the Amiga console device display. The code is a combination * of the Heath and ANSI terminal drivers. */ #include "def.h" #define BEL 0x07 /* BEL character. */ #define ESC 0x1B /* ESC character. */ extern int ttrow; extern int ttcol; extern int tttop; extern int ttbot; extern int tthue; int tceeol = 3; /* Costs, ANSI display. */ int tcinsl = 17; int tcdell = 16; /* * Initialize the terminal when the editor * gets started up. This is a no-op on the Amiga. */ ttinit() { } /* * Clean up the terminal, in anticipation of * a return to the command interpreter. This is a no-op * on the Amiga. */ tttidy() { } /* * Move the cursor to the specified * origin 0 row and column position. Try to * optimize out extra moves; redisplay may * have left the cursor in the right * location last time! */ ttmove(row, col) { if (ttrow!=row || ttcol!=col) { ttputc(ESC); ttputc('['); asciiparm(row+1); ttputc(';'); asciiparm(col+1); ttputc('H'); ttrow = row; ttcol = col; } } /* * Erase to end of line. */ tteeol() { ttputc(ESC); ttputc('['); ttputc('K'); } /* * Erase to end of page. */ tteeop() { ttputc(ESC); ttputc('['); ttputc('J'); } /* * Make a noise. */ ttbeep() { ttputc(BEL); ttflush(); } /* * Convert a number to decimal * ascii, and write it out. Used to * deal with numeric arguments. */ asciiparm(n) register int n; { register int q; q = n/10; if (q != 0) asciiparm(q); ttputc((n%10) + '0'); } /* * Insert a block of blank lines onto the * screen, using a scrolling region that starts at row * "row" and extends down to row "bot". Deal with the one * line case, which is a little bit special, with special * case code. * Since we don't really have a scrolling region, * delete the block of lines that would have been deleted if * we'd had one, then insert blank lines to move the rest * of the screen back to where it belongs. This idea from * the Heath driver. */ VOID ttinsl(row, bot, nchunk) { if (row == bot) { /* Funny case. */ if (nchunk != 1) abort(); ttmove(row, 0); tteeol(); return; } ttmove(1+bot-nchunk, 0); if (nchunk > 0) { /* Delete a chunk of lines */ ttputc(ESC); /* nchunk in size. Rest of */ ttputc('['); /* screen moves up. */ asciiparm(nchunk); ttputc('M'); } ttmove(row, 0); if (nchunk > 0) { /* Insert a chunk nchunk in size*/ ttputc(ESC); /* before current line, sliding */ ttputc('['); /* rest of screen down. */ asciiparm(nchunk); ttputc('L'); } ttrow = row; /* End up on current line */ ttcol = 0; } /* * Delete a block of lines, with the uppermost * line at row "row", in a screen slice that extends to * row "bot". The "nchunk" is the number of lines that have * to be deleted. This is done by deleting nchunk lines at the * appropriate spot, then inserting nchunk lines to make up for * the empty space at the bottom of the virtual scrolling region. */ VOID ttdell(row, bot, nchunk) { if (row == bot) { /* One line special case */ ttmove(row, 0); tteeol(); return; } if (nchunk > 0) { ttmove(row, 0); ttputc(ESC); ttputc('['); asciiparm(nchunk); ttputc('M'); } ttmove(1+bot-nchunk,0); if (nchunk > 0) { ttputc(ESC); /* For all lines in chunk */ ttputc('['); /* INS line before bottom */ asciiparm(nchunk); /* Bottom of window (and rest */ ttputc('L'); /* of screen) moves down */ } ttrow = HUGE; ttcol = HUGE; ttmove(bot-nchunk,0); } /* * No-op. */ ttwindow(top,bot) { } /* * No-op. */ ttnowindow() { } /* * Set the current writing color to the * specified color. Watch for color changes that are * not going to do anything (the color is already right) * and don't send anything to the display. */ ttcolor(color) register int color; { if (color != tthue) { if (color == CTEXT) { /* Normal video. */ ttputc(ESC); ttputc('['); ttputc('m'); } else if (color == CMODE) { /* Reverse video. */ ttputc(ESC); ttputc('['); ttputc('7'); ttputc('m'); } tthue = color; /* Save the color. */ } } /* * This routine is called by the * "refresh the screen" command to try and resize * the display. The new size, which must be deadstopped * to not exceed the NROW and NCOL limits, is stored * back into "nrow" and "ncol". Display can always deal * with a screen NROW by NCOL. Look in "window.c" to * see how the caller deals with a change. */ #define CSI 0x9B extern int ttsize(); /* Defined by "ttyio.c" */ ttresize() { int newnrow, newncol; ttsize(&newnrow,&newncol); /* ask tty how big it is */ if (newnrow < 1) /* check limits. */ newnrow = 1; else if (newnrow > NROW) newnrow = NROW; if (newncol < 1) newncol = 1; else if (newncol > NCOL) newncol = NCOL; nrow = newnrow; ncol = newncol; } /* * Read an unsigned parameter from the console */ static readparm(delim) char delim; { register int parm; register int c; parm = 0; while ((c=ttgetc()) >= '0' && c <= '9') parm = 10 * parm + c - '0'; return (c == delim) ? parm : -1; }