home *** CD-ROM | disk | FTP | other *** search
- /*
- ** pc98.c: hterm NEC PC98xx physical CRT driver and bell driver
- *
- * Author: HIRANO Satoshi
- * (C) 1989 Halca Computer Science Laboratory TM
- * University of Tokyo
- *
- * 1.1 89/06/15 Halca.Hirano creation
- * 1.2 89/07/20 Halca.Hirano add many features
- * use generic memory move functions to access VRAM
- * ---- V2.3.-1 distribution ----
- * ---- V2.4.0 distribution ----
- * ---- V2.5.0 distribution ----
- * 1.3 89/11/29 Halca.Hirano visible/audible/both bell mode
- * 1.4 89/12/24 Halca.Hirano add nullFunction() to avoid optimizer bug
- * in bell() wait loop
- * 1.5 90/04/20 Halca.Hirano access VRAM thru addressing array
- * remember function key display status at startup
- * 1.6 90/06/19 Halca.Hirano
- * support soft font
- * 1.7 90/07/07 Halca.Hirano
- * turn back light on/off when textCRTOn/Off for PC9801NS
- *
- * $Header: pc98.cv 1.11 90/07/05 08:37:26 hirano Exp $
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "hterm.h"
- #include "option.h"
- #include "default.h"
- #include "global.h"
-
-
- /*
- ** static variables
- */
-
- /*
- * physical line number VRAM address convertion table
- * index = physical line number
- * contents = VRAM address
- */
- static u_short *ltopTab[MAX_LINE_25_MODE];
- /*
- * logical line number to VRAM address conversion function
- */
- #define ltop(y) (ltopTab[y])
-
- static short backingStoreSeg; /* soft font backing store */
- static char FAR *backingStore; /* pointer to backing store */
- static void reverseScreen(void);
-
- /*
- ** void CRTInit(): initialize PC98 CRT
- *
- * called once just after hterm startup
- */
- void CRTInit()
- {
- register int i;
- register u_short *p;
- u_short FAR *v;
-
- vramSegment = VRAMSEG;
- gvramSegment = GVRAMSEG;
- #ifdef SOFT_FONT
- /*
- * allocate memory for VRAM backing store
- */
- backingStore = allocMem((long)(ATTR_OFFSET*2));
- if (backingStore == 0) {
- fprintf(stderr, msg_alloc, "backing store\n");
- exit(1);
- }
- backingStoreSeg = FP_SEG(backingStore);
- #endif
- /*
- * build line number conversion table
- */
- p = (u_short *)0;
- for (i = 0; i < MAX_LINE_25_MODE; i++) {
- /* physical line no to VRAM address conversion table */
- ltopTab[i] = p;
- p += MAX_COLUMN;
- }
- /*
- * remember function key is displayed or not
- * (it may not be so strict)
- */
- FP_SEG(v) = vramSegment;
- FP_OFF(v) = (int)ltop(BOTTOM_LINE_25_MODE);
- funKeyDisplayed = NO;
- for (i = 0; i < 20; i++, v++)
- if (*v != 0 && *v != 0x20) {
- funKeyDisplayed = YES;
- break;
- }
- printf("\x1b[>1h"); /* clear funktion key line */
- }
-
- /*
- ** void CRTEnd()
- */
- void CRTEnd()
- {
- upScrRegion = 0;
- lowScrRegion = BOTTOM_LINE_25_MODE;
- #ifdef SOFT_FONT
- freeMem(backingStore);
- if (softFont) { /* erase graphic screen */
- clearCurrentPage();
- cursorOnOff(NO);
- softFont = NO;
- }
- #endif /* SOFT_FONT */
- restoreCRTMode();
- }
-
- /*
- ** void setCRTMode()
- *
- * set CRT mode
- */
- void setCRTMode()
- {
- /*
- * set crt mode (25/20 lines)
- */
- setCRTLineMode(realMaxLine < 21 ? 0 : 1); /* 20 or 25 line mode */
- /*
- * set CRT mode
- */
- #ifdef SOFT_FONT
- if (softFont) {
- /*
- * make text CRT tranparent overlay
- * erase text cursor
- */
- softFont = NO;
- cursorOnOff(NO);
- clearCurrentPage();
- /*
- * fake text VRAM dummy at vramBacking store
- */
- vramSegment = backingStoreSeg;
- clearCurrentPage(); /* clear backing store */
- softFont = YES;
- #ifndef PC98XA
- /*
- * set graphic mode, color 640x400
- */
- rg.h.ah = 0x42;
- rg.h.ch = 0xc0 ; /* color, 640x400, use page 1 */
- int86(CRTBIOS, &rg, &rg);
- /*
- * set color palette; blue plane displays white color
- */
- outp(0xaa, 0x75);
- #endif
- } else
- #endif /* SOFT_FONT */
- {
- vramSegment = VRAMSEG;
- #ifndef PC98XA
- /*
- * set graphic mode
- */
- rg.h.ah = 0x42;
- rg.h.ch = 0xc0; /* color, 640x400, use page 1 */
- int86(CRTBIOS, &rg, &rg);
- /*
- * set color palette; blue plane displays blue color
- */
- outp(0xaa, 0x15);
- #endif
- }
- graphicCRTOnOff(YES);
- }
-
- /*
- ** void restoreCRTMode()
- *
- * restore CRT mode to startup condition
- */
- void restoreCRTMode()
- {
- eraseAttr = attrib = _NORMAL;
- softFont = NO;
- setCRTMode(); /* MSDOS CRT mode is same as hterm's TEXT mode */
- setCRTLineMode(1); /* 25 line mode */
- clearCurrentPage();
- cursorOnOff(YES);
- if (funKeyDisplayed)
- printf("\x1b[>1l");
- setBorder(0);
- }
-
- /*
- ** void locate(register int x, int y)
- *
- * set cursor on position (x,y)
- */
- void locate(x, y)
- register int x;
- int y;
- {
- register u_short *ad;
-
- cursorX = x;
- cursorY = y;
- if (cursor) {
- #ifdef SOFT_FONT
- if (softFont) {
- softFontLocate(x, y);
- } else
- #endif
- {
- ad = ltop(y) + x;
- rg.h.ah = 0x13; /* cursor position command */
- rg.x.dx = (int)ad;
- int86(CRTBIOS, &rg, &rg); /* call CRT BIOS */
- }
- }
- }
-
- /*
- ** int isKanjiOnVRAM(x, y)
- *
- * return non zero if the character is kanji at current cursor position
- */
- int isKanjiOnVRAM(x, y)
- int x;
- int y;
- {
- u_short FAR *p;
-
- FP_SEG(p) = vramSegment;
- FP_OFF(p) = (int)(ltop(y) + x);
- return((*p & 0xff00) && (*(p+1) & 0x8000));
- }
-
- /*
- ** void cursorOnOff(int onOff)
- *
- * set cursor form; on/off, blinking/static, underline/block
- */
- void cursorOnOff(onOff)
- int onOff;
- {
- #ifdef SOFT_FONT
- if (softFont) {
- softCursorOnOff(onOff);
- } else
- #endif
- {
- rg.h.al = (blinkCursor == YES ? 0 : 1);
- rg.h.ah = 0x10;
- int86(CRTBIOS, &rg, &rg);
- rg.h.ah = (onOff == YES ? 0x11 : 0x12);
- int86(CRTBIOS, &rg, &rg);
- }
- }
-
- /*
- ** void putChar(register u_short c)
- *
- * put a charactor 'c' and attribute 'attrib' at (cursorX, cursorY)
- */
- void putChar(c)
- register u_short c;
- {
- u_short FAR *p;
-
- FP_SEG(p) = vramSegment;
- FP_OFF(p) = (int)(ltop(cursorY) + cursorX);
- *p = c;
- FP_OFF(p) += ATTR_OFFSET;
- *p = attrib;
- }
-
- /*
- ** void insertLine(register u_short num)
- *
- * insert num lines at cursorY
- *
- * If cursorY is not in scroll region, ignore request
- * If num exceeds scroll region, strict num into scroll region
- *
- */
- void insertLine(num)
- register int num;
- {
- /*
- * if cursor is out of scroll region or zero request, ignore request
- */
- if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
- return; /* ignore */
- if (softFont && cursor)
- cursorOnOff(NO);
- /*
- * requested num must be in scroll region
- */
- if (lowScrRegion+1-cursorY < num)
- num = lowScrRegion+1-cursorY; /* out of scroll region */
- /* moveBackward(to, from, num, MOVE_ATTRIBUTE_TOO) */
- moveBackward(ltop(cursorY+num), ltop(cursorY),
- (lowScrRegion+1-cursorY-num) * MAX_COLUMN, YES);
- #ifdef SOFT_FONT
- if (softFont) {
- softFontInsertLine(num);
- if (cursor)
- cursorOnOff(YES);
- }
- #endif
- /*
- * clear created lines
- */
- clearLine(cursorY, cursorY+num-1);
- }
-
- /*
- ** void deleteLine(register u_short num)
- *
- * delete num lines at cursorY
- *
- * If cursorY is not in scroll region, ignore request
- * If num exceeds scroll region, strict num into scroll region
- *
- */
- void deleteLine(num)
- register int num;
- {
- /*
- * if cursor is out of scroll region or zero request, ignore request
- */
- if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
- return; /* ignore */
- if (softFont && cursor)
- cursorOnOff(NO);
- /*
- * requested num must be in scroll region
- */
- if (lowScrRegion+1-cursorY < num)
- num = lowScrRegion+1-cursorY; /* out of scroll region */
- /* moveForward(to, from, num, MOVE_ATTRIBUTE_TOO) */
- moveForward(ltop(cursorY), ltop(cursorY+num),
- (lowScrRegion+1-cursorY-num)*MAX_COLUMN, YES);
- #ifdef SOFT_FONT
- if (softFont) {
- softFontDeleteLine(num);
- if (cursor)
- cursorOnOff(YES);
- }
- #endif
- /*
- * clear created lines
- */
- clearLine(lowScrRegion-num+1, lowScrRegion);
- }
-
- /*
- ** void clearColumn(register u_shrot from, register u_short to)
- *
- * clear column 'from' to 'to'-1 on cursorY line,
- */
- void clearColumn(from, to)
- register u_short from, to;
- {
- if (to > from) {
- if (softFont && cursor)
- cursorOnOff(NO);
- fillVRAM(ltop(cursorY)+from, to-from, SPACE, eraseAttr);
- #ifdef SOFT_FONT
- if (softFont) {
- softFontClearColumn(from, to);
- if (cursor)
- cursorOnOff(YES);
- }
- #endif
- }
- }
-
- /*
- ** void clearCurrentPage()
- *
- * clear current page
- */
- void clearCurrentPage()
- {
- clearLine(0, BOTTOM_LINE_25_MODE);
- }
-
- /*
- ** void insertChar(register u_short at, u_short n)
- *
- * insert n blank charactors at 'at' on cursorY line
- */
- void insertChar(at, n)
- register int at;
- int n;
- {
- register u_short *src = ltop(cursorY)+at;
- register int moveNum = MAX_COLUMN-at-n;
-
- if (softFont && cursor)
- cursorOnOff(NO);
- if (moveNum > 0)
- moveBackward(src+n, src, moveNum, YES);
- else
- n = MAX_COLUMN-at;
- fillVRAM(src, n, SPACE, eraseAttr);
- #ifdef SOFT_FONT
- if (softFont) {
- softFontInsertChar(at, n);
- if (cursor)
- cursorOnOff(YES);
- }
- #endif
- }
-
- /*
- ** void deleteChar(register int at, register int n)
- *
- * delete 'n' characters at 'at' on cursorY line and make blank trailing 'n'
- * characters.
- */
- void deleteChar(at, n)
- register int at;
- register int n;
- {
- register u_short *src = ltop(cursorY) + at;
- register int moveNum = MAX_COLUMN-at-n;
-
- if (softFont && cursor)
- cursorOnOff(NO);
- if (moveNum > 0)
- moveForward(src, src+n, moveNum, YES);
- else {
- n = MAX_COLUMN-at;
- moveNum = 0;
- }
- fillVRAM(src+moveNum, n, SPACE, eraseAttr);
- #ifdef SOFT_FONT
- if (softFont) {
- softFontDeleteChar(at, n);
- if (cursor)
- cursorOnOff(YES);
- }
- #endif
- }
-
- /*
- ** void saveLine(int y, register u_char FAR *buf)
- *
- * copy line y in VRAM into buffer
- * Kanji code is EUC in buffer.
- */
- void saveLine(y, buf)
- int y;
- register u_char FAR *buf;
- {
- short FAR *from;
- register u_short c;
- register u_char l;
- register int i;
-
- FP_SEG(from) = vramSegment;
- FP_OFF(from) = (int)ltop(y);
-
- for (i = 0; i < MAX_COLUMN; i++) {
- c = *from++;
- if (c & 0xff00) { /* kanji */
- l = c;
- *buf++ = (l + 0x20) | 0x80;
- *buf++ = (c >> 8) | 0x80;
- from++;
- i++;
- } else { /* ASCII */
- if (c == 0xef || c == 0xfc) /* back slash */
- c = 0x5c;
- else if (c == 0xde) /* backquote */
- c = 0x60;
- else if (c < 0x20 || 0x7e < c) /* ignore kana */
- c = '?';
- *buf++ = c;
- }
- }
- }
-
- /*
- ** static void reverseScreen()
- *
- * reverse screen
- */
- static void reverseScreen()
- {
- short FAR *p;
- register u_short c, a;
- int i;
-
- #ifdef SOFT_FONT
- if (softFont)
- softFontReverseScreen();
- else
- #endif /* SOFT_FONT */
- {
- FP_SEG(p) = vramSegment;
- FP_OFF(p) = ATTR_OFFSET;
-
- a = 0x0004;
- for (i = MAX_COLUMN*MAX_LINE_25_MODE; i > 0; --i) {
- c = *p;
- *p++ = ((c & ~a) | (~c & a));
- }
- }
- }
-
- /*
- ** void savePage(u_short buf[])
- *
- * save vram into save buffer 'buf' without code conversion
- */
- void savePage(buf)
- u_short buf[];
- {
- /* charactor VARM */
- moveMemory(buf, getDSeg(), (u_short *)0, vramSegment, MAX_CHAR);
- /* attribute VRAM */
- moveMemory(&buf[MAX_CHAR], getDSeg(), (u_short *)ATTR_OFFSET, vramSegment, MAX_CHAR);
- }
-
- /*
- ** void restorePage(u_short buf[])
- *
- * restore saved page into vram
- */
- void restorePage(buf)
- u_short buf[];
- {
- register u_short c;
- register u_char l;
- u_short *p, *a;
-
- /* character VRAM */
- moveMemory((u_short *)0, vramSegment, buf, getDSeg(), MAX_CHAR);
- /* attribute VRAM */
- moveMemory((u_short *)ATTR_OFFSET, vramSegment, &buf[MAX_CHAR], getDSeg(), MAX_CHAR);
-
- #ifdef SOFT_FONT
- if (softFont) {
- int cursorXSave = cursorX;
- int cursorYSave = cursorY;
-
- softCursorOnOff(NO);
- p = buf; /* char pointer */
- a = &buf[MAX_CHAR]; /* attrib pointer */
- for (cursorY = 0; cursorY <= realBottomLine; cursorY++) {
- for (cursorX = 0; cursorX < MAX_COLUMN; cursorX++) {
- c = *p++;
- attrib = *a++;
- if (c & 0xff00) { /* kanji */
- l = c;
- softFontPutChar(((l+0x20) << 8) | (c >> 8));
- p++;
- a++;
- cursorX++;
- } else { /* ASCII */
- if (c == 0xef || c == 0xfc) /* back slash */
- c = 0x5c;
- else if (c == 0xde) /* backquote */
- c = 0x60;
- else if (c < 0x20 || 0x7e < c) /* ignore kana */
- c = '?';
- softFontPutChar(c);
- }
- }
- }
- cursorX = cursorXSave;
- cursorY = cursorYSave;
- if (cursor)
- softCursorOnOff(YES);
- }
- #endif /* SOFT_FONT */
- }
-
- /*
- ** void clearSavedPage(u_char buf[])
- *
- * clear saved page
- */
- void clearSavedPage(buf)
- u_short buf[];
- {
- register int i;
- register u_short *p;
-
- for (p = buf, i = MAX_CHAR; i > 0; --i)
- *p++ = SPACE;
- for (p = &buf[MAX_CHAR], i = MAX_CHAR; i > 0; --i)
- *p++ = eraseAttr;
- }
-
- /*
- ** void click()
- *
- * generate click 'pi' sound
- */
- void click()
- {
- int i;
-
- outp(PORT_C, 0x06); /* buzzar on */
- for (i = 0; i < CLICK_BEEP; i++)
- nullFunction(); /* short wait */
- outp(PORT_C, 0x07);
- }
-
- /*
- * void bell()
- *
- * generate beep sound 'pii' with screen flush if required
- */
- void bell()
- {
- if (visibleBell == AUDIBLE_BELL || visibleBell == BOTH_AV_BELL)
- outp(PORT_C, 0x06); /* buzzar on */
- timerValue = timerLoadValue;
- while (timerLoadValue - timerValue < BELL_BEEP) {
- nullFunction();
- if (visibleBell == VISIBLE_BELL || visibleBell == BOTH_AV_BELL) {
- reverseScreen();
- reverseScreen();
- }
- }
- if (visibleBell == AUDIBLE_BELL || visibleBell == BOTH_AV_BELL)
- outp(PORT_C, 0x07); /* buzzar off */
- }
-
- /*
- ** void textCRTOnOff(int onOff)
- *
- * display text CRT or hide it
- */
- void textCRTOnOff(onOff)
- int onOff;
- {
- rg.h.ah = (onOff ? 0x0c : 0x0d);
- int86(CRTBIOS, &rg, &rg);
- /*
- * PC9801NS back light control
- */
- if (onOff)
- outp(0xce8e, 0x80); /* turn back light on */
- else
- outp(0xce8e, 0x00); /* turn back light off */
- }
-
- /*
- ** void graphicCRTOnOff(int onOff)
- *
- * display graphic CRT or hide it
- */
- void graphicCRTOnOff(onOff)
- int onOff;
- {
- /*
- * show graphic page
- */
- rg.h.ah = onOff ? 0x40 : 0x41; /* 0x40 = ON, 0x41 = OFF */
- int86(CRTBIOS, &rg, &rg);
- }
-
- /*
- ** void setCRTLineMode(int mode25)
- *
- * switch 25 lines mode or 20 lines mode
- */
- void setCRTLineMode(mode25)
- int mode25; /* 1 = 25 lines mode, 0 = 20 lines mode */
- {
- #ifndef PC98XA
- /* PC98XA does not support 20 line mode */
- rg.h.ah = 0x0a;
- rg.h.al = (mode25 ? 0 : 1);
- int86(CRTBIOS, &rg, &rg);
- #endif
- }
-
- /*
- ** setBorder(int col)
- *
- * void set border coloer to col
- */
- void setBorder(col)
- int col;
- {
- static char ucw[2]; /* UCW */
-
- ucw[1] = col; /* color code */
- rg.h.ah = 0x44; /* set border color command */
- rg.x.bx = (int)ucw;
- int86(CRTBIOS, &rg, &rg);
- }
-
-