home *** CD-ROM | disk | FTP | other *** search
- /*
- * ibmpc.c: hterm CRT driver (IBM-PC or AX1/AX2 dependent)
- *
- * 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/07 Halca.Hirano use 98 compatible vram control procedures
- * (VRAM direct access)
- * 1.3 89/07/20 Halca.Hirano add screen saver
- * 1.4 89/07/30 Halca.Hirano add history editor related functions
- * remove BIOS call video access
- * ---- V2.3.-1 distribution ----
- * ---- V2.4.0 distribution ----
- * ---- V2.5.0 distribution ----
- * 1.5 89/11/29 Halca.Hirano visible/audible/both bell mode
- * 1.6 89/12/24 Halca.Hirano add nullFunction() to avoid optimizer bug
- * in bell() wait loop
- * 1.7 90/04/20 Halca.Hirano access VRAM thru addressing array
- * 1.8 90/06/19 Halca.Hirano
- * support soft font
- * 1.9 90/07/07 Halca.Hirano
- * fix hanging up of AX soft font
- *
- * $Header: ibmpc.cv 1.10 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"
-
-
- /*
- * 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])
-
- struct _videoInfo {
- char card[6];
- u_short address;
- } videoInfo[] =
- {{"JEGA", VRAM_EGA}, {"VGA", VRAM_VGA}, {"EGA", VRAM_EGA},
- {"CGA", VRAM_CGA}, {"MDA", VRAM_MDA}, {"MCGA", VRAM_MCGA}, {0, 0}};
-
- static short vramSegmentSave; /* text move VRAM segment */
- static u_char savedVideoMode; /* video mode at start up */
- static short backingStoreSeg; /* soft font backing store */
- static char FAR *backingStore; /* pointer to backing store */
-
- void reverseScreen(void );
-
- /*
- ** CRTInit(): initialize PC98 CRT
- *
- * called once just after hterm startup
- */
- void CRTInit()
- {
- register int i;
- register u_short *p;
- register struct _videoInfo *v;
-
- /*
- * build line number conversion table
- */
- p = (u_short *)0;
- for (i = 0; i < MAX_LINE_25_MODE; i++) {
- /* physical line no to VRAM address convertion table */
- ltopTab[i] = p;
- p += MAX_COLUMN;
- }
-
- #ifdef SOFT_FONT
- /*
- * allocate memory for VRAM backing store
- */
- backingStore = allocMem((long)MAX_CHAR*sizeof(short));
- if (backingStore == 0) {
- fprintf(stderr, msg_alloc, "backing store\n");
- exit(1);
- }
- backingStoreSeg = FP_SEG(backingStore);
- #endif
-
- /*
- * get VRAM address
- */
- #ifdef AX
- vramSegmentSave = vramSegment = VRAM_EGA;
- gvramSegment = GVRAMSEG;
- #else /* AX */
- vramSegmentSave = vramSegment = DEFAULT_VRAM_CARD; /* set default */
- gvramSegment = GVRAMSEG;
- for (v = videoInfo; *v->card; v++) {
- if (getenv(v->card)) {
- vramSegment = v->address;
- break;
- }
- }
- #endif /* AX */
- /*
- * get VIDEO mode (TEXT mode is assumed.)
- */
- rg.h.ah = 0x0f; /* get video mode command */
- int86(VIDEOBIOS, &rg, &rg);
- savedVideoMode = rg.h.al; /* save current mode */
- }
-
- /*
- ** 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();
- }
-
- /*
- ** setCRTMode()
- *
- * set CRT mode
- */
- void setCRTMode()
- {
- register int i;
- u_short FAR *p;
-
- /*
- * set CRT mode
- */
- #ifdef SOFT_FONT
- if (softFont) {
- /*
- * erase text cursor and text VRAM
- */
- softFont = NO;
- cursorOnOff(NO);
- clearCurrentPage();
- softFont = YES;
- /*
- * fake text VRAM dummy at vramBacking store
- */
- vramSegment = backingStoreSeg;
- /*
- * clear backing store
- */
- FP_SEG(p) = vramSegment;
- FP_OFF(p) = 0;
- for (i = MAX_CHAR; i > 0; --i)
- *p++ = (u_short)((eraseAttr<<8) | SPACE);
- /*
- * set GRAPHIC mode
- */
- rg.h.ah = 0; /* set video mode command */
- rg.h.al = 0x10; /* mono 640x350 */
- int86(VIDEOBIOS, &rg, &rg);
- } else
- #endif /* SOFT_FONT */
- {
- /*
- * set TEXT mode
- */
- rg.h.ah = 0; /* set video mode command */
- rg.h.al = savedVideoMode; /* restore mode */
- int86(VIDEOBIOS, &rg, &rg);
- vramSegment = vramSegmentSave;
- }
- }
-
- /*
- ** 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 */
- clearCurrentPage();
- cursorOnOff(YES);
- }
-
- /*
- ** locate(register int x, int y)
- *
- * set cursor on position (x,y)
- */
- void locate(x, y)
- register int x, y;
- {
- cursorX = x;
- cursorY = y;
- if (cursor) {
- #ifdef SOFT_FONT
- if (softFont) {
- softFontLocate(x, y);
- } else
- #endif
- {
- rg.h.ah = 2; /* set cursor position survice code */
- rg.h.bh = 0; /* page number */
- rg.h.dh = y; /* vertical coordinate */
- rg.h.dl = x; /* horizontal coordinate */
- int86(VIDEOBIOS, &rg, &rg); /* call rom bios */
- }
- }
- }
-
- /*
- ** 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(isSJIS1(*p & 0xff));
- }
-
- /*
- ** 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.ah = 1; /* set cursor type survice code */
- if (onOff == YES)
- if (blockCursor == YES) /* block cursor on */
- rg.x.cx = 0x0007;
- else /* underline cursor on */
- rg.x.cx = 0x0607;
- else
- rg.x.cx = 0x2000; /* cursor off */
- int86(0x10, &rg, &rg);
- }
- }
-
- /*
- ** putChar(register u_short c)
- *
- * put a charactor 'c' and attribute 'attrib' at (cursorX, cursorY)
- */
- void putChar(c)
- u_short c;
- {
- u_short FAR *p;
-
- FP_SEG(p) = vramSegment;
- FP_OFF(p) = (int)(ltop(cursorY) + cursorX);
- *p = (attrib << 8 | (u_char)c);
- }
-
- /*
- ** 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);
- }
-
- /*
- ** 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);
- }
-
- /*
- ** 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
- }
- }
-
- /*
- ** clearCurrentPage()
- *
- * clear current page
- */
- void clearCurrentPage()
- {
- clearLine(0, BOTTOM_LINE_25_MODE);
- }
-
- /*
- ** insertChar(register int at, int n)
- *
- * insert n blank charactors at 'at' on cursorY line
- */
- void insertChar(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)
- 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
- }
-
- /*
- ** 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
- }
-
- /*
- ** 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;
- {
- register u_short c;
- short FAR *from;
- register u_char l;
- register int i;
-
- FP_SEG(from) = vramSegment;
- FP_OFF(from) = (int)ltop(y);
-
- #ifdef KANJI
- for (i = 0; i < MAX_COLUMN; i++) {
- c = *from++;
- if (c & 0x80) { /* kanji */
- l = c;
- c = SJIStoJIS(l, *from++ & 0xff) | 0x8080;
- *buf++ = c >> 8;
- *buf++ = c;
- i++;
- } else
- *buf++ = c;
- }
- #else
- for (i = 0; i < MAX_COLUMN; i++) {
- *buf++ = (u_char)*from++;
- }
- #endif /* KANJI */
- }
-
- /*
- ** static void reverseScreen()
- *
- * reverse screen
- */
- static void reverseScreen()
- {
- short FAR *p;
- register u_short c;
- int i, j;
-
- #ifdef SOFT_FONT
- if (softFont)
- softFontReverseScreen();
- else
- #endif /* SOFT_FONT */
- {
- FP_SEG(p) = vramSegment;
- FP_OFF(p) = 0;
- for (i = MAX_COLUMN*MAX_LINE_25_MODE; i > 0; --i) {
- c = *p;
- *p++ = (c & 0x88ff) | (~c & 0x7700);
- }
- }
- }
-
- /*
- ** savePage(u_short buf[])
- *
- * save vram into save buffer 'buf' without code conversion
- */
- void savePage(buf)
- u_short *buf;
- {
- moveMemory(buf, getDSeg(), (u_short *)0, vramSegment, MAX_CHAR);
- }
-
- /*
- ** 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;
- int cursorXSave = cursorX;
- int cursorYSave = cursorY;
-
- moveMemory((u_short *)0, vramSegment, buf, getDSeg(), MAX_CHAR);
- #ifdef SOFT_FONT
- if (softFont) {
- softCursorOnOff(NO);
- p = buf; /* char pointer */
- for (cursorY = 0; cursorY <= realBottomLine; cursorY++) {
- for (cursorX = 0; cursorX < MAX_COLUMN; cursorX++) {
- c = *p++; /* get attribute and char */
- attrib = (c >> 8); /* attribute */
- c &= 0xff; /* strip attribute */
- if (c & 0x80) { /* kanji */
- l = c;
- c = SJIStoJIS(l, *p++ & 0xff);
- softFontPutChar(c);
- cursorX++;
- } else { /* ASCII */
- if (c < 0x20 || 0x7e < c) /* ignore kana */
- c = '?';
- softFontPutChar(c);
- }
- }
- }
- cursorX = cursorXSave;
- cursorY = cursorYSave;
- if (cursor)
- softCursorOnOff(YES);
- }
- #endif /* SOFT_FONT */
- }
-
- /*
- ** 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++ = (u_short)((eraseAttr<<8) | SPACE);
- }
-
- /*
- ** click()
- *
- * generate click 'pi' sound
- */
- void click()
- {
- int i;
- u_char status;
-
- status = inp(ADDR_BUZZAR); /* read current status */
- outp(ADDR_BUZZAR, status | 0x3); /* buzzar on */
- for (i = 0; i < CLICK_BEEP; i++)
- nullFunction(); /* short wait */
- outp(ADDR_BUZZAR, status); /* buzzar off */
- }
-
- /*
- ** bell()
- *
- * generate beep sound 'pii' with screen flush if required
- */
- void bell()
- {
- u_char status;
-
- if (visibleBell == AUDIBLE_BELL || visibleBell == BOTH_AV_BELL) {
- status = inp(ADDR_BUZZAR); /* read current status */
- outp(ADDR_BUZZAR, status | 0x3); /* 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(ADDR_BUZZAR, status); /* buzzar off */
- }
-
- /*
- ** textCRTOnOff(int onOff)
- *
- * display text CRT or hide it
- *
- * actually Off means Page 2 of TEXT VRAM, it MAY be cleared!
- */
- void textCRTOnOff(onOff)
- int onOff;
- {
- if (onOff == NO)
- clearCurrentPage();
- }
-
- void setBorder(col)
- int col;
- {
- /* not supported */
- }
-