home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 1
/
FREEWARE.BIN
/
dmycon
/
consim.c
< prev
next >
Wrap
Text File
|
1989-10-17
|
29KB
|
1,314 lines
/****************************************************
FM-TOWNS FM16/FMR50 Console Sim Program
89.9.16 make v1.00 by Ken
89.9.18 bug fix & speed up by Ken
89.9.20 Consol BIOS apend by Ken
****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <process.h>
#define TRUE 1
#define FALSE 0
#define ERR (-1)
#define UCHAR unsigned char
#define SHORT short int
#define UNSIG unsigned int
#define OFFSET(p,n) *((unsigned int *)(&(p)))=n
#define SEGSET(p,n) *((unsigned int *)(&(p))+1)=n
#define LOW(p) ((unsigned char *)(&(p)))
#define HIGH(p) ((unsigned char *)(&(p))+1)
#define CVRAM 0xC800
#define KVRAM 0xCA00
#define SCR_X 80
#define MAX_X 80
#define MAX_Y 25
#define DMYKAN 0xFE
#define CRCHR 0x1F
#define TABCHR 0x09
#define NULCHR 0x20
#define TAB 8
#define CONTRL FALSE
#define DEFCOL COLOR
SHORT CUR_X=0,CUR_Y=0;
static SHORT CUR_DSP_FLG=0;
static SHORT Con_mode=0xCE;
static SHORT SCR_Y=MAX_Y;
static SHORT BAK_X,BAK_Y;
static SHORT COLOR=7,BAKCOL=0;
static SHORT KANMOD=TRUE;
static UCHAR BAKCH1=0;
static UCHAR KANCOD=0;
static SHORT EXTFLG=FALSE;
static void (*EXTPRO)();
static SHORT ESCCNT=0;
static UCHAR ESCPRM[12];
static UCHAR dmy_ram[MAX_X*MAX_Y*2];
struct {
SHORT r_es;
SHORT r_ds;
SHORT r_di;
SHORT r_si;
SHORT r_bp;
SHORT r_sp;
SHORT r_bx;
SHORT r_dx;
SHORT r_cx;
SHORT r_ax;
SHORT r_ip;
SHORT r_cs;
SHORT r_cf;
} ureg;
extern UCHAR ankfont[];
/***************************************************
<<< Compile to "BIOS.ASM" >>>
static void colset(vp,cl,cnt)
UNSIG vp;
int cl,cnt;
{
UCHAR far *p;
SEGSET(p,CVRAM);
OFFSET(p,vp);
while ( cnt > 0 ) {
*(p++) = 0; *(p++) = cl;
cnt-=2;
}
}
static void vramcpy(d,s,n)
UNSIG d,s;
int n;
{
movedata(CVRAM,s,CVRAM,d,n);
movedata(KVRAM,s,KVRAM,d,n);
}
void Wrt_Ank(ch,x,y,cl)
UCHAR ch;
int x,y,cl;
{
int i,at,bk;
UCHAR *fp;
UCHAR far *vp;
UCHAR far *bp;
fp = ankfont + ch * 16;
*((unsigned int *)(&vp)+1) = 0xC000;
*((unsigned int *)(&vp)) = x + (MAX_X * 16) * y;
at = cl & 0x07;
if ( (cl & 0x20) != 0 ) at |= 0x08;
if ( (cl & 0x18) != 0 ) bk = 0xFF; else bk = 0;
outp(0xFF81,0x0F);
for ( bp = vp,i = 0 ; i < 16 ; i++ ) {
*bp = 0;
bp += MAX_X;
}
outp(0xFF81,at);
for ( i = 0 ; i < 16 ; i++ ) {
*vp = *(fp++) ^ bk;
vp += MAX_X;
}
}
void Wrt_Kan(ch,x,y,cl)
int ch;
int x,y,cl;
{
int i,at,bk;
UCHAR far *vp;
UCHAR far *bp;
*((unsigned int *)(&vp)+1) = 0xC000;
*((unsigned int *)(&vp)) = x + (MAX_X * 16) * y;
outp(0xFF94,ch >> 8);
outp(0xFF95,ch & 0xFF);
at = cl & 0x07;
if ( (cl & 0x20) != 0 ) at |= 0x08;
if ( (cl & 0x18) != 0 ) bk = 0xFF; else bk = 0;
outp(0xFF81,0x0F);
for ( bp = vp,i = 0 ; i < 16 ; i++ ) {
*bp = *(bp+1) = 0;
bp += MAX_X;
}
outp(0xFF81,at);
for ( i = 0 ; i < 16 ; i++ ) {
*vp = inp(0xFF96) ^ bk;
*(vp+1) = inp(0xFF97) ^ bk;
vp += MAX_X;
}
}
void locate(x,y)
int x,y;
{
int i;
UCHAR far *vp;
*((unsigned int *)(&vp)+1) = 0xC000;
*((unsigned int *)(&vp)) = x + (MAX_X * 16) * y + (MAX_X * 14);
outp(0xFF81,0x0F);
for ( vp = vp,i = 0 ; i < 2 ; i++ ) {
*vp = 0xFF;
vp += MAX_X;
}
}
int sjisto(cd)
int cd;
{
int hi,lo;
hi=(cd >> 8)&0xff;
lo=cd & 0xff;
hi -= ( hi <= 0x9f) ? 0x71 : 0xb1;
hi = hi * 2 +1;
if ( lo > 0x7f )
lo--;
if ( lo >= 0x9e ) {
lo -= 0x7d;
hi++;
}
else
lo -= 0x1f;
return (hi << 8 | lo);
}
static void Beep()
{
int i;
for ( i = 0 ; i < 5000 ; i++ )
inp(0xFF98);
outp(0xFF98,0);
}
**************************************************************/
static void NextChr(sub)
void (*sub)();
{
EXTFLG = TRUE;
EXTPRO = sub;
}
static void Scrool()
{
vramcpy(0,(MAX_X * 2),(MAX_X * 2) * (SCR_Y - 1));
colset((MAX_X * 2) * (SCR_Y - 1),COLOR,(MAX_X * 2));
}
static void PutBS()
{
if ( --CUR_X < 0 ) {
CUR_X = SCR_X - 1;
if ( --CUR_Y < 0 )
CUR_Y = 0;
}
}
static void PutTAB()
{
int i;
extern void PutChr();
if ( (Con_mode & 0x02) == 0 )
i = 1;
else
i = ((CUR_X + TAB) / TAB) * TAB - CUR_X;
while ( i-- > 0 )
PutChr(COLOR|0xC0,NULCHR);
}
static void PutLF()
{
if ( ++CUR_Y >= SCR_Y ) {
CUR_Y = (SCR_Y - 1);
Scrool();
}
if ( (Con_mode & 0x01) != 0 )
CUR_X = 0;
}
static void PutHOME()
{
CUR_X = CUR_Y = 0;
}
static void PutCLS()
{
colset(0,COLOR,(MAX_X * 2) * SCR_Y);
CUR_X = CUR_Y = 0;
}
static void PutCR()
{
CUR_X = 0;
if ( (Con_mode & 0x01) != 0 )
PutLF();
}
static void CurRit()
{
if ( ++CUR_X >= SCR_X )
CUR_X = 0;
}
static void CurLft()
{
if ( --CUR_X < 0 )
CUR_X = SCR_X - 1;
}
static void CurUp()
{
if ( --CUR_Y < 0 )
CUR_Y = SCR_Y - 1;
}
static void CurDwn()
{
if ( ++CUR_Y >= SCR_Y )
CUR_Y = 0;
}
void SVidAt(ch)
int ch;
{
COLOR = ch & 0x3F;
}
void SetDC2_s(ch)
int ch;
{
CUR_X = BAKCH1;
CUR_Y = ch;
if ( CUR_X < 0 ) CUR_X = 0;
if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
if ( CUR_Y < 0 ) CUR_Y = 0;
if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
}
void SetDC2(ch)
int ch;
{
extern void SetDC2_s();
BAKCH1 = ch;
NextChr(SetDC2_s);
}
void SetDC3_s(ch)
int ch;
{
extern void PutChr();
while ( BAKCH1-- > 0 )
PutChr(0xC0|COLOR,ch);
}
void SetDC3(ch)
int ch;
{
extern void SetDC3_s();
BAKCH1 = ch;
NextChr(SetDC3_s);
}
static void EraLin()
{
colset((CUR_X * 2) + (MAX_X * 2) * CUR_Y,COLOR,(MAX_X - CUR_X) * 2);
}
static void EraScr()
{
colset((CUR_X * 2) + (MAX_X * 2) * CUR_Y,COLOR,
(MAX_X * 2) * SCR_Y - (CUR_X * 2) + (MAX_X * 2) * CUR_Y);
}
static void InsLin()
{
int i;
UNSIG p;
p = (MAX_X * 2) * (SCR_Y - 1);
for ( i = SCR_Y - 1 ; i > CUR_Y ; i-- ) {
vramcpy(p,p-(MAX_X * 2),(MAX_X * 2));
p -= (MAX_X * 2);
}
colset((MAX_X * 2) * CUR_Y,COLOR,MAX_X * 2);
}
static void DelLin()
{
int i;
UNSIG p;
p = (MAX_X * 2) * CUR_Y;
for ( i = CUR_Y ; i < (SCR_Y - 1) ; i ++ ) {
vramcpy(p,p+(MAX_X * 2),(MAX_X * 2));
p += (MAX_X * 2);
}
colset((MAX_X * 2) * (SCR_Y - 1),COLOR,MAX_X * 2);
}
void SCurPs_s(ch)
int ch;
{
CUR_Y = BAKCH1 - ' ';
CUR_X = ch - ' ';
if ( CUR_X < 0 ) CUR_X = 0;
if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
if ( CUR_Y < 0 ) CUR_Y = 0;
if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
}
void SCurPs(ch)
int ch;
{
extern void SCurPs_s();
BAKCH1 = ch;
NextChr(SCurPs_s);
}
void CurAtt_s()
{
}
void CurAtt(ch)
int ch;
{
extern void CurAtt_s();
NextChr(CurAtt_s);
}
static void AnsiH()
{
if ( ESCPRM[0] > 0 ) ESCPRM[0]--;
if ( ESCPRM[1] > 0 ) ESCPRM[1]--;
CUR_Y = ESCPRM[0];
CUR_X = ESCPRM[1];
if ( CUR_X < 0 ) CUR_X = 0;
if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
if ( CUR_Y < 0 ) CUR_Y = 0;
if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
}
static void AnsiA()
{
if ( (CUR_Y -= ESCPRM[0]) < 0 )
CUR_Y = 0;
}
static void AnsiB()
{
if ( (CUR_Y += ESCPRM[0]) >= SCR_Y )
CUR_Y = SCR_Y - 1;
}
static void AnsiC()
{
if ( (CUR_X += ESCPRM[0]) >= SCR_X )
CUR_X = SCR_X - 1;
}
static void AnsiD()
{
if ( (CUR_X -= ESCPRM[0]) < 0 )
CUR_X = 0;
}
static void Ansis()
{
BAK_X = CUR_X;
BAK_Y = CUR_Y;
}
static void Ansiu()
{
CUR_X = BAK_X;
CUR_Y = BAK_Y;
}
static void AnsiJ()
{
switch(ESCPRM[0]) {
case 0: EraScr(); break;
case 1: colset(0,COLOR,(CUR_X * 2) + (MAX_X * 2) * CUR_Y); break;
case 2: PutCLS(); break;
}
}
static void AnsiK()
{
switch(ESCPRM[0]) {
case 0: EraLin(); break;
case 1:
if ( CUR_X > 0 )
colset((MAX_X * 2) * CUR_Y,COLOR,CUR_X * 2);
break;
case 2: colset((MAX_X * 2) * CUR_Y,COLOR,MAX_X * 2); break;
}
}
static void AnsiM()
{
while ( ESCPRM[0]-- > 0 )
DelLin();
CUR_X = 0;
}
static void AnsiL()
{
while ( ESCPRM[0]-- > 0 )
InsLin();
CUR_X = 0;
}
static void Ansiv()
{
CUR_DSP_FLG = ESCPRM[0];
}
static void Ansim()
{
int c;
int i,n;
static char ansiatt[]={ 0x00,0x20,0x00,0x00,0x00,0x10,0x00,0x08,0x00 };
static char ansicol[]={ 0,2,4,6,1,3,5,7 };
for ( n = 0,c = 0x07 ; n < ESCCNT ; n++ ) {
if ( (i = ESCPRM[n]) > 0 && i <= 8 ) {
c |= ansiatt[i];
} else if ( i == 0 ) {
c &= 0x07;
} else if ( i >= 30 && i <= 38 ) {
c &= 0xF8;
c |= ansicol[i-30];
} else if ( i >= 40 && i <= 47 ) {
BAKCOL = ansicol[i-40]; /* 現在未サポ-ト */
}
}
COLOR = c;
}
void AnsiCom(ch)
int ch;
{
if ( ch == ';' && ESCCNT < 8 )
ESCCNT++;
else if ( ch >= '0' && ch <= '9' )
ESCPRM[ESCCNT] = ESCPRM[ESCCNT] * 10 + (ch - '0');
else if ( ch != ' ' ) {
ESCCNT++;
switch(ch) {
case 'H': AnsiH(); break;
case 'f': AnsiH(); break;
case 'A': AnsiA(); break;
case 'B': AnsiB(); break;
case 'C': AnsiC(); break;
case 'D': AnsiD(); break;
case 's': Ansis(); break;
case 'u': Ansiu(); break;
case 'J': AnsiJ(); break;
case 'K': AnsiK(); break;
case 'm': Ansim(); break;
case 'M': AnsiM(); break;
case 'L': AnsiL(); break;
case 'v': Ansiv(); break;
}
return;
}
NextChr(AnsiCom);
}
static void AnsiESC()
{
extern void AnsiCom();
memset(ESCPRM,0,8);
ESCCNT = 0;
NextChr(AnsiCom);
}
void EscCom(ch)
int ch;
{
extern void SCurPs(),SVidAt(),CurAtt();
switch(ch) {
case '*': PutCLS(); break;
case 'T': EraLin(); break;
case 'Y': EraScr(); break;
case 'E': InsLin(); break;
case 'R': DelLin(); break;
case '=': NextChr(SCurPs); break;
case 'G': NextChr(SVidAt); break;
case 'K': KANMOD = TRUE; break;
case 'C': KANMOD = FALSE; break;
case '.': NextChr(CurAtt); break;
case '[': AnsiESC(); break;
case '1': case '2': case '3': break; /* TAB Set/UnSet */
default: PutChr(0xC0|COLOR,ch); break;
}
}
static void PutCnt(ch)
int ch;
{
extern void SVidAt(),SetDC2(),SetDC3(),EscCom();
switch(ch) {
case 0x00: break;
case 0x07: Beep(); break;
case 0x08: PutBS(); break;
case 0x09: PutTAB(); break;
case 0x0A: PutLF(); break;
case 0x0B: PutHOME(); break;
case 0x0C: PutCLS(); break;
case 0x0D: PutCR(); break;
case 0x12: NextChr(SetDC2); break;
case 0x13: NextChr(SetDC3); break;
case 0x15: PutCLS(); break;
case 0x16: PutCLS(); break;
case 0x1B: NextChr(EscCom); break;
case 0x1C: CurRit(); break;
case 0x1D: CurLft(); break;
case 0x1E: CurUp(); break;
case 0x1F: CurDwn(); break;
default: PutChr(0xC0|COLOR,ch); break;
}
}
void PutChr(att,ch)
int att,ch;
{
UCHAR far *p;
if ( (att & 0xC0) == 0xC0 )
att &= 0x3F;
else if ( ch < ' ' || ch == 0x7f ) {
if ( (att & 0x40) == 0 && (Con_mode & 0x80) != 0 ) {
PutCnt(ch);
return;
}
}
SEGSET(p,CVRAM);
OFFSET(p,(CUR_X * 2 + (MAX_X * 2) * CUR_Y));
*p = ch; *(p+1) = att;
if ( (att & 0x40) != 0 ) {
*p = DMYKAN;
SEGSET(p,KVRAM);
*p = ch >> 8;
*(p+1) = ch;
}
if ( ++CUR_X >= SCR_X ) {
CUR_X = 0;
if ( ++CUR_Y >= SCR_Y ) {
CUR_Y = SCR_Y - 1;
Scrool();
}
}
}
void Chr_out(ch)
int ch;
{
ch &= 0xff;
if ( EXTFLG != FALSE ) {
EXTFLG = FALSE;
(*EXTPRO)(ch);
return;
}
if ( KANMOD != FALSE ) {
if ( KANCOD != '\0' ) {
if ( iskanji2(ch) != FALSE ) {
if ( CUR_X == (SCR_X - 1) ) {
PutChr(COLOR,DMYKAN);
PutChr(COLOR,DMYKAN);
} else {
ch = sjisto((int)((KANCOD << 8) | ch));
PutChr(0x40|COLOR,ch);
PutChr(0xC0|COLOR,DMYKAN);
}
} else {
PutChr(COLOR,KANCOD);
PutChr(COLOR,ch);
}
KANCOD = '\0';
return;
} else if ( iskanji(ch) != FALSE ) {
KANCOD = ch;
return;
}
}
PutChr(COLOR,ch);
}
/**************************************************************
CONSOL BIOS (int 91h)
***************************************************************/
void VDB_00() /* 初期化 */
{
SCR_Y = MAX_Y - 1;
CUR_DSP_FLG = 0;
Con_mode = 0xCE;
CUR_X = CUR_Y = 0;
COLOR = 7;
colset(0,COLOR,(MAX_X * 2) * MAX_Y);
}
void VDB_01(){} /* 画面の表示制御 */
void VDB_02() /* 全画面消去 */
{
colset(0,DEFCOL,(MAX_X * 2) * MAX_Y);
CUR_X = CUR_Y = 0;
}
void VDB_03() /* 表示画面サイズの設定 */
{
/* SCR_X = x; */
if ( (SCR_Y = *HIGH(ureg.r_dx)) > MAX_Y )
SCR_Y = MAX_Y;
if ( (Con_mode & 0x40) != 0 )
SCR_Y - 1;
}
void VDB_04() /* 表示画面サイズの読み取り */
{
*LOW(ureg.r_dx) = SCR_X;
*HIGH(ureg.r_dx) = SCR_Y;
}
void VDB_05() /* 表示画面サイズレパ-トリの読み取り */
{
char far *p;
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
if ( *(p++) < 4 )
return;
*(p++) = 1;
*(p++) = 80;
*(p++) = 25;
}
void VDB_06() /* アトリビュート機能範囲の読み取り */
{
char far *p;
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
*(p++) = 0x03; /* 漢字識別可能 */
*(p++) = 0x38; /* リバ-ス & 強調 */
*(p++) = 0x07; /* 最大色数 */
*p = 0;
}
void VDB_07() /* フォントパタ-ンの取り出し */
{
int i;
char *fp;
char far *p;
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
if ( *HIGH(ureg.r_bx) == 0 ) { /* ANK 8x8 or 8x16 */
if ( *HIGH(ureg.r_dx) != 8 )
goto ERROR;
else if ( *LOW(ureg.r_dx) == 8 ) {
fp = ankfont + *LOW(ureg.r_bx) * 16;
for ( i = 0 ; i < 8 ; i++ )
*(p++) = *(fp++) | *(fp++);
return;
} else if ( *LOW(ureg.r_dx) == 16 ) {
fp = ankfont + *LOW(ureg.r_bx) * 16;
for ( i = 0 ; i < 16 ; i++ )
*(p++) = *(fp++);
return;
} else
goto ERROR;
} else if ( ureg.r_dx == 0x1010 ) { /* Kanji 16x16 */
outp(0xFF94,*LOW(ureg.r_bx));
outp(0xFF95,*HIGH(ureg.r_bx));
for ( i = 0 ; i < 16 ; i++ ) {
*(p++) = inp(0xFF96);
*(p++) = inp(0xFF97);
}
return;
}
ERROR:
*HIGH(ureg.r_ax) = 0x02;
ureg.r_cf |= 0x0001;
}
void VDB_08(){} /* 外字パタ-ンの登録 */
void VDB_09(){} /* カ-ソル形状の設定 */
void VDB_0A(){} /* カ-ソル形状の読み取り */
void VDB_0B() /* カ-ソル表示状態の設定 */
{
CUR_DSP_FLG = *LOW(ureg.r_ax);
}
void VDB_0C() /* カ-ソル表示状態の読み取り */
{
*LOW(ureg.r_ax) = CUR_DSP_FLG;
}
void VDB_0D() /* カーソル位置の指定 */
{
CUR_X = *LOW(ureg.r_dx) - 1;
CUR_Y = *HIGH(ureg.r_dx) - 1;
if ( CUR_X < 0 ) CUR_X = 0;
if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
if ( CUR_Y < 0 ) CUR_Y = 0;
if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
}
void VDB_0E() /* カーソル位置の読み取り */
{
*LOW(ureg.r_dx) = CUR_X + 1;
*HIGH(ureg.r_dx) = CUR_Y + 1;
}
void VDB_0F() /* アトリビュートの設定 */
{
int at,x,y;
char far *p;
UCHAR far *vp;
x = *LOW(ureg.r_dx) - 1;
y = *HIGH(ureg.r_dx) - 1;
SEGSET(vp,CVRAM);
OFFSET(vp,(x * 2 + (MAX_X * 2) * y + 1));
SEGSET(p,ureg.r_ds);
OFFSET(p,(ureg.r_di + 1));
at = *vp & 0xC0;
*vp = at | (*p & 0x38) | (*(p+1) & 0x07);
}
void VDB_10() /* アトリビュートの読み取り */
{
int at,x,y;
char far *p;
UCHAR far *vp;
x = *LOW(ureg.r_dx) - 1;
y = *HIGH(ureg.r_dx) - 1;
SEGSET(vp,CVRAM);
OFFSET(vp,(x * 2 + (MAX_X * 2) * y + 1));
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
if ( (*vp & 0x40) != 0 )
*p = 0x01;
else if ( x > 0 && (*(vp-2) & 0x40) != 0 ) {
*p = 0x03;
vp -= 2;
} else
*p = 0x00;
*(++p) = *vp & 0x38;
*(++p) = *vp & 0x07;
}
void VDB_11() /* デフォルトアトリビュ-トの設定 */
{
char far *p;
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
DEFCOL = (*(++p) & 0x38);
DEFCOL |= (*(++p) & 0x07);
}
void VDB_12() /* デフォルトアトリビュ-トの読み取り */
{
char far *p;
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
*(++p) = DEFCOL & 0x38;
*(++p) = DEFCOL & 0x07;
}
void VDB_13() /* 文字設定 */
{
int ch,x,y;
UCHAR far *vp;
x = *LOW(ureg.r_dx) - 1;
y = *HIGH(ureg.r_dx) - 1;
ch = *LOW(ureg.r_bx);
SEGSET(vp,CVRAM);
OFFSET(vp,(x * 2 + (MAX_X * 2) * y));
*(vp++) = ch;
if ( *LOW(ureg.r_ax) != 1 )
*vp = DEFCOL;
else
*vp &= 0x3F;
if ( *HIGH(ureg.r_bx) == 0x01 )
*vp |= 0x40;
else if ( *HIGH(ureg.r_bx) == 0x03 ) {
ch |= (*(vp-3) << 8);
*(vp-1) = *(vp-3) = DMYKAN;
SEGSET(vp,KVRAM);
*(vp-3) = ch >> 8;
*(vp-2) = ch;
}
}
void VDB_14() /* 文字読み取り */
{
int at,x,y;
UCHAR far *vp;
x = *LOW(ureg.r_dx) - 1;
y = *HIGH(ureg.r_dx) - 1;
SEGSET(vp,CVRAM);
OFFSET(vp,(x * 2 + (MAX_X * 2) * y));
if ( (*(vp+1) & 0x40) != 0 ) {
*HIGH(ureg.r_bx) = 0x01;
SEGSET(vp,KVRAM);
*LOW(ureg.r_bx) = *vp;
} else if ( x > 0 && (*(vp-1) & 0x40) != 0 ) {
*HIGH(ureg.r_bx) = 0x03;
SEGSET(vp,KVRAM);
*LOW(ureg.r_bx) = *(vp-1);
} else {
*HIGH(ureg.r_bx) = 0x00;
*LOW(ureg.r_bx) = *vp;
}
}
void VDB_15() /* 矩形域設定 */
{
int cx,ch;
int x1,y1,x2,y2;
int x,y,sx,sy;
UNSIG far *p;
UCHAR far *cp;
UCHAR far *ap;
UCHAR far *sp;
UCHAR far *vp;
if ( (x1 = *LOW(ureg.r_dx)-1) >= MAX_X || x1 < 0)
goto ERROR;
if ( (y1 = *HIGH(ureg.r_dx)-1) >= SCR_Y || y1 < 0 )
goto ERROR;
if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
goto ERROR;
if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
goto ERROR;
sx = x2 - x1; sy = y2 - y1;
if ( sx <= 0 || sy <= 0 )
goto ERROR;
SEGSET(sp,CVRAM);
OFFSET(sp,(x1 * 2 + (MAX_X * 2) * y1));
OFFSET(p,ureg.r_di);
SEGSET(p,ureg.r_ds);
OFFSET(cp,*(p++));
SEGSET(cp,*(p++));
OFFSET(ap,*(p++));
SEGSET(ap,*(p++));
for ( y = 0 ; y < sy ; y++ ) {
for ( x = 0,vp = sp ; x < sx ; x++ ) {
*(vp++) = *(cp++);
if ( *(ap++) == 0x03 ) {
*(vp-2) |= 0x40;
ch = *(vp-3) << 8 | *(vp-1);
SEGSET(vp,KVRAM);
*(vp-3) = ch >> 8;
*(vp-2) = ch;
SEGSET(vp,CVRAM);
} else
*vp &= 0x3F;
if ( *LOW(ureg.r_ax) == 1 ) {
*vp = *(ap++) & 0x38;
*vp |= *(ap++) & 0x07; ap++;
}
vp++;
}
sp += (MAX_X * 2);
}
return;
ERROR:
*HIGH(ureg.r_ax) = 0x02;
ureg.r_cf |= 0x0001;
}
void VDB_16() /* 矩形域読み取り */
{
int i;
int x1,y1,x2,y2;
int x,y,sx,sy;
UNSIG far *p;
UCHAR far *cp;
UCHAR far *ap;
UCHAR far *sp;
UCHAR far *vp;
if ( (x1 = *LOW(ureg.r_dx)-1) >= MAX_X || x1 < 0)
goto ERROR;
if ( (y1 = *HIGH(ureg.r_dx)-1) >= SCR_Y || y1 < 0 )
goto ERROR;
if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
goto ERROR;
if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
goto ERROR;
sx = x2 - x1; sy = y2 - y1;
if ( sx <= 0 || sy <= 0 )
goto ERROR;
SEGSET(sp,CVRAM);
OFFSET(sp,(x1 * 2 + (MAX_X * 2) * y1));
OFFSET(p,ureg.r_di);
SEGSET(p,ureg.r_ds);
OFFSET(cp,*(p++));
SEGSET(cp,*(p++));
OFFSET(ap,*(p++));
SEGSET(ap,*(p++));
for ( y = 0 ; y < sy ; y++ ) {
for ( x = 0,vp = sp ; x < sx ; x++ ) {
*(cp++) = *(vp++);
if ( (*vp & 0x40) != 0 ) {
*(ap++) = 0x01;
SEGSET(vp,KVRAM);
*(cp-1) = *(vp-1);
SEGSET(vp,CVRAM);
} else if ( x > 0 && (*(vp-2) & 0x40) != 0 ) {
*(ap++) = 0x03;
SEGSET(vp,KVRAM);
*(cp-1) = *(vp-2);
SEGSET(vp,CVRAM);
} else
*(ap++) = 0x00;
if ( *LOW(ureg.r_ax) == 1 ) {
*(ap++) = *vp & 0x38;
*(ap++) = *vp & 0x07; ap++;
}
vp++;
}
sp += (MAX_X * 2);
}
return;
ERROR:
*HIGH(ureg.r_ax) = 0x02;
ureg.r_cf |= 0x0001;
}
void VDB_17() /* 矩形域複写 */
{
int i;
int x1,y1,x2,y2,x3,y3;
int sx,sy;
UNSIG sp;
UNSIG dp;
if ( (x1 = *LOW(ureg.r_dx) - 1) >= MAX_X || x1 < 0 )
goto ERROR;
if ( (y1 = *HIGH(ureg.r_dx) - 1) >= SCR_Y || y1 < 0 )
goto ERROR;
if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
goto ERROR;
if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
goto ERROR;
if ( (x3 = *LOW(ureg.r_cx) - 1) >= MAX_X || x3 < 0 )
goto ERROR;
if ( (y3 = *HIGH(ureg.r_cx) - 1) >= SCR_Y || y3 < 0 )
goto ERROR;
sx = x2 - x1; sy = y2 - y1;
if ( sx <= 0 || sy <= 0 )
goto ERROR;
if ( (x3 + sx) > MAX_X || (y3 + sy) > SCR_Y )
goto ERROR;
if ( sp < dp ) {
sp = (x2 - 1) * 2 + (MAX_X * 2) * (y2 - 1);
dp = (x3 + sx - 1) * 2 + (MAX_X * 2) * (y3 + sy - 1);
for ( i = 0 ; i < sy ; i++ ) {
vramrcpy(dp,sp,sx * 2);
sp -= (MAX_X * 2);
dp -= (MAX_X * 2);
}
} else {
sp = x1 * 2 + (MAX_X * 2) * y1;
dp = x3 * 2 + (MAX_X * 2) * y3;
for ( i = 0 ; i < sy ; i++ ) {
vramcpy(dp,sp,sx * 2);
sp += (MAX_X * 2);
dp += (MAX_X * 2);
}
}
return;
ERROR:
*HIGH(ureg.r_ax) = 0x02;
ureg.r_cf |= 0x0001;
}
void VDB_18() /* 矩形域消去 */
{
int i;
int x1,y1,x2,y2;
int sx,sy;
UNSIG sp;
if ( (x1 = *LOW(ureg.r_dx) - 1) >= MAX_X || x1 < 0 )
goto ERROR;
if ( (y1 = *HIGH(ureg.r_dx) - 1) >= SCR_Y || y1 < 0 )
goto ERROR;
if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
goto ERROR;
if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
goto ERROR;
sx = x2 - x1; sy = y2 - y1;
if ( sx <= 0 || sy <= 0 )
goto ERROR;
sp = (x1 * 2 + (MAX_X * 2) * y1);
for ( i = 0 ; i < sy ; i++ ) {
colset(sp,DEFCOL,sx * 2);
sp += (MAX_X * 2);
}
return;
ERROR:
*HIGH(ureg.r_ax) = 0x02;
ureg.r_cf |= 0x0001;
}
void VDB_19() /* 全画面スクロ-ル */
{
int cx,i;
UNSIG vp;
if ( (cx = ureg.r_cx) == 0 || cx > SCR_Y )
cx = SCR_Y;
for ( ; cx > 0 ; cx-- ) {
switch(*LOW(ureg.r_ax)) {
case 1: /* 下方向 */
i = (MAX_X * 2) * (SCR_Y - 1);
vramrcpy(i + (MAX_X * 2 - 2),i - 2,i);
colset(0,DEFCOL,(MAX_X * 2));
break;
case 2: /* 右方向 */
i = (MAX_X * 2) * SCR_Y - 2;
vramrcpy(i,i - 2,i);
vp = 0;
for ( i = 0 ; i < SCR_Y ; i++ ) {
colset(vp,DEFCOL,2);
vp += (MAX_X * 2);
}
break;
case 3: /* 左方向 */
vramcpy(0,2,(MAX_X * 2) * SCR_Y - 2);
vp = (MAX_X * 2) - 2;
for ( i = 0 ; i < SCR_Y ; i++ ) {
colset(vp,DEFCOL,2);
vp += (MAX_X * 2);
}
break;
default: /* case 0 上方向 */
vramcpy(0,(MAX_X * 2),(MAX_X * 2) * (SCR_Y - 1));
colset((MAX_X * 2) * (SCR_Y - 1),DEFCOL,(MAX_X * 2));
break;
}
}
}
void VDB_1A() /* 部分スクロ-ル */
{
int cx,i;
int x1,y1,x2,y2;
int sx,sy;
UNSIG sp;
UNSIG vp;
if ( (x1 = *LOW(ureg.r_dx) - 1) >= MAX_X || x1 < 0 )
goto ERROR;
if ( (y1 = *HIGH(ureg.r_dx) - 1) >= SCR_Y || y1 < 0 )
goto ERROR;
if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
goto ERROR;
if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
goto ERROR;
sx = x2 - x1; sy = y2 - y1;
if ( sx <= 0 || sy <= 0 )
goto ERROR;
sp = (x1 * 2 + (MAX_X * 2) * y1);
if ( (cx = ureg.r_cx) == 0 || cx > sy )
cx = sy;
for ( ; cx > 0 ; cx-- ) {
switch(*LOW(ureg.r_ax)) {
case 1: /* 下方向 */
vp = sp + (MAX_X * 2) * (sy - 1);
for ( i = 0 ; i < (sy-1) ; i++ ) {
vramcpy(vp,vp - (MAX_X * 2),sx * 2);
vp -= (MAX_X * 2);
}
colset(sp,DEFCOL,sx * 2);
break;
case 2: /* 右方向 */
vp = sp + (sx * 2) - 2;
for ( i = 0 ; i < sy ; i++ ) {
vramrcpy(vp,vp - 2,sx * 2 - 2);
vp += (MAX_X * 2);
}
vp = sp;
for ( i = 0 ; i < sy ; i++ ) {
colset(vp,DEFCOL,2);
vp += (MAX_X * 2);
}
break;
case 3: /* 左方向 */
vp = sp;
for ( i = 0 ; i < sy ; i++ ) {
vramcpy(vp,vp + 2,sx * 2 - 2);
vp += (MAX_X * 2);
}
vp = sp + (sx * 2) - 2;
for ( i = 0 ; i < sy ; i++ ) {
colset(vp,DEFCOL,2);
vp += (MAX_X * 2);
}
break;
default: /* case 0 上方向 */
for ( vp = sp,i = 0 ; i < (sy-1) ; i++ ) {
vramcpy(vp,vp + (MAX_X * 2),sx * 2);
vp += (MAX_X * 2);
}
colset(vp,DEFCOL,sx * 2);
break;
}
}
return;
ERROR:
*HIGH(ureg.r_ax) = 0x02;
ureg.r_cf |= 0x0001;
}
void VDB_1B() /* コンソ-ル機能の設定 */
{
int i;
i = Con_mode;
Con_mode = (*LOW(ureg.r_ax) & 0xC7) | 0x08;
if ( (i & 0x40) != (Con_mode & 0x40) ) {
if ( (Con_mode & 0x40) != 0 )
SCR_Y--;
else
SCR_Y++;
}
}
void VDB_1C() /* コンソ-ル機能の読み取り */
{
*LOW(ureg.r_ax) = Con_mode;
}
void VDB_1D() /* 文字の出力 */
{
Chr_out(*LOW(ureg.r_ax));
}
void VDB_1E() /* 文字列の出力 */
{
int i;
UCHAR far *p;
SEGSET(p,ureg.r_ds);
OFFSET(p,ureg.r_di);
for ( i = ureg.r_cx ; i > 0 ; i-- )
Chr_out(*(p++));
}
void VDB_1F() /* システム行書き込み */
{
int ch,cx,at,md;
UNSIG far *p;
UCHAR far *cp;
UCHAR far *ap;
UCHAR far *vp;
if ( (Con_mode & 0x40) == 0 )
return;
OFFSET(p,ureg.r_di);
SEGSET(p,ureg.r_ds);
OFFSET(cp,*(p++));
SEGSET(cp,*(p++));
OFFSET(ap,*(p++));
SEGSET(ap,*(p++));
cx = ureg.r_cx;
OFFSET(vp,CVRAM);
SEGSET(vp,*LOW(ureg.r_dx) * 2 + (MAX_X * 2) * SCR_Y);
for ( ; cx > 0 ; cx-- ) {
*(vp++) = *(cp++);
if ( *LOW(ureg.r_ax) != 1 ) {
at = DEFCOL;
md = *(ap++);
} else {
md = *(ap++);
at = *(ap++) & 0x38;
at |= (*(ap++) & 0x07); ap++;
}
*(vp++) = at;
if ( md == 0x03 ) {
ch = (*(vp-4) << 8) | *(vp-2);
*(vp-4) = *(vp-2) = DMYKAN;
*(vp-3) |= 0x40;
SEGSET(vp,KVRAM);
*(vp-4) = ch >> 8;
*(vp-3) = ch;
SEGSET(vp,CVRAM);
}
}
}
void VDB_20() /* 背景色の読み取り */
{
ureg.r_dx = BAKCOL;
}
void BIOS_91()
{
int cm;
static void (*VDB_table[])()={
VDB_00, VDB_01, VDB_02, VDB_03, VDB_04, VDB_05, VDB_06, VDB_07,
VDB_08, VDB_09, VDB_0A, VDB_0B, VDB_0C, VDB_0D, VDB_0E, VDB_0F,
VDB_10, VDB_11, VDB_12, VDB_13, VDB_14, VDB_15, VDB_16, VDB_17,
VDB_18, VDB_19, VDB_1A, VDB_1B, VDB_1C, VDB_1D, VDB_1E, VDB_1F,
VDB_20 };
if ( (cm = *HIGH(ureg.r_ax)) <= 0x20 ) {
*HIGH(ureg.r_ax) = 0;
ureg.r_cf &= 0xFFFE;
(*VDB_table[cm])();
} else {
*HIGH(ureg.r_ax) = 0x01;
ureg.r_cf |= 0x0001;
}
}
void cflush()
{
int ch,x,y;
register UCHAR *dp;
UCHAR far *cp;
SHORT far *kp;
SEGSET(cp,CVRAM);
OFFSET(cp,0);
SEGSET(kp,KVRAM);
OFFSET(kp,0);
dp = dmy_ram;
for ( y = 0 ; y < MAX_Y ; y++ ) {
for ( x = 0 ; x < MAX_X ; x++,dp+=2,cp+=2,kp++ ) {
if ( (*(cp+1) & 0x40) != 0 ) {
ch = *dp << 8 | *(dp+2);
if ( *(dp+1) != *(cp+1) || ch != *kp ) {
*dp = *kp >> 8;
*(dp+1) = *(cp+1);
*(dp+2) = *kp;
*(dp+3) = *(cp+1) & 0x3F;
Wrt_Kan(*(dp+2) << 8 | *(dp),x,y,*(cp+1));
}
x++; dp+=2; cp+=2; kp++;
continue;
} else if ( *dp != *cp || *(dp+1) != *(cp+1) ) {
*dp = *cp;
*(dp+1) = *(cp+1);
Wrt_Ank(*dp,x,y,*(dp+1));
}
}
}
if ( CUR_DSP_FLG == 0 ) {
dp = dmy_ram + CUR_X * 2 + (MAX_X * 2) * CUR_Y + 1;
*dp ^= 0x10;
locate(CUR_X,CUR_Y);
}
}
void main(argc,argv)
int argc;
char *argv[];
{
int i;
char *arg[10];
for ( i = 0 ; i < 10 ; i++ ) {
if ( --argc <= 0 )
break;
arg[i] = argv[i+1];
}
arg[i] = NULL;
VDB_00();
setbios();
spawnvp(P_WAIT,arg[0],arg);
resetbios();
}