1、XMS.C
/*
扩展内存接口 by WXZ 1995,8
bcc -mc xms
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <dos.h>
#include <bios.h>
// interface
void PutError(char *s)
{
printf("%s\n",s);
while(bioskey(1))
bioskey(0);
bioskey(0);
exit(1);
}
typedef struct {
long size; // 必须是偶数
unsigned hSourceHandle;
unsigned long offsetOfSource;
unsigned hDestHandle;
unsigned long offsetOfDest;
} EMM;
typedef unsigned HND;
typedef enum {
false=0,true=1,False=0,True=1,FALSE=0,TRUE=1
} BOOL;
BOOL GetXMS(void);
int GetXMSMemSize(void); // 返回最大的内存块
HND AllocXMSMem(unsigned k_size);
void FreeXMSMem(HND hXMSHandle);
unsigned long LockXMS(HND h);
void UnlockXMS(HND h);
BOOL MoveXMS(EMM *pEMM);
void MoveFromXMS(HND h,unsigned long l,char far *s);
// local function
void CallXMS(union REGS *rIn,union REGS *rOut);
#ifndef NDEBUG
void ReportXMSStatus(void);
#else
#endif
void far (*XMSFunc)();
BOOL GetXMS(void)
{
union REGS r;
struct SREGS sr;
r.x.ax=0x4300; // Is there have XMS
int86(0x2f,&r,&r);
if(r.h.al!=0x80)
return False;
r.x.ax=0x4310; // Get far call pointer
segread(&sr);
int86x(0x2f,&r,&r,&sr);
XMSFunc=MK_FP(sr.es,r.x.bx);
return True;
}
int GetXMSMemSize(void) // 返回最大的一块内存
{
union REGS r;
r.h.ah=8;
CallXMS(&r,&r);
return(r.x.ax);
}
HND AllocXMSMem(unsigned k_size)
{
union REGS r;
r.x.dx=k_size;
r.h.ah=9;
CallXMS(&r,&r);
return r.x.dx;
}
void FreeXMSMem(HND hXMSHandle)
{
union REGS r;
r.x.dx=hXMSHandle;
r.h.ah=0xa;
CallXMS(&r,&r);
}
// Cation
// XMSFunc is DS data
// so not load DS new seg
BOOL MoveXMS(EMM *pEMM)
{
static EMM Emm;
Emm=*pEMM;
_DS=FP_SEG(&Emm);
_SI=FP_OFF(&Emm);
_AH=0xb;
(*XMSFunc)();
return _AX;
}
void MoveFromXMS(HND h,unsigned long l,char far *s)
{
EMM Emm;
Emm.size=32;
Emm.hSourceHandle=h;
Emm.hDestHandle=0;
Emm.offsetOfSource=l;
Emm.offsetOfDest=(unsigned long)s;
if(!MoveXMS(&Emm))
PutError("Can't Read From XMS");
}
unsigned long LockXMS(HND h)
{
union REGS r;
r.x.dx=h;
r.h.ah=0xc;
CallXMS(&r,&r);
return(((unsigned long)r.x.dx<<16)+r.x.bx);
}
void UnlockXMS(HND h)
{
union REGS r;
r.x.dx=h;
r.h.ah=0xd;
CallXMS(&r,&r);
}
void CallXMS(union REGS *rIn,union REGS *rOut)
{
_DX=rIn->x.dx;
_AH=rIn->h.ah;
XMSFunc();
rOut->x.ax=_AX;
rOut->x.bx=_BX;
rOut->x.dx=_DX;
}
// Test XMS mode
/*
void ReportXMSStatus(void)
{
union REGS r;
printf("\n Input AH DX : ");
scanf("%x %x",&r.h.ah,&r.x.dx);
CallXMS(&r,&r);
printf("\n\n\nReturn Code:\n");
printf("AX: %x\nBX: %x\nDX: %x\n",r.x.ax,r.x.bx,r.x.dx);
getch();
}
main()
{
if(!GetXMS())
return;
ReportXMSStatus();
}
*/
2、HZ.C
/*
汉字处理总接口 by WXZ 1995,8
bcc -mc HZ
*/
#define XMS
unsigned DataHandle,CodeHandle;
extern stklen=8192;
// memory size K bytes
int Data_k_size=264;
int Code_k_size=192;
#include "XMS.C"
#include "MAIN.C"
// interface
void LoadHZToXMS(void);
void WhenExit(void);
// local function
void GetMem(void);
void MoveToXMS(void);
void LockHZ(void);
void UnlockHZ(void);
// test function
void PrintHZ(void);
// handle
void LoadHZToXMS(void)
{
OpenHZ();
GetMem();
MoveToXMS();
}
void MoveToXMS(void)
{
EMM Emm;
Emm.size=1024*(unsigned long)HZ_k_size;
Emm.hSourceHandle=0;
Emm.hDestHandle=DataHandle;
Emm.offsetOfSource=((unsigned long)HZseg<<16);
Emm.offsetOfDest=0;
if(!MoveXMS(&Emm))
{
FreeXMSMem(DataHandle);
FreeXMSMem(CodeHandle);
PutError("Something Wrong In LoadToXMSMem");
}
}
void GetMem(void)
{
if(!GetXMS())
PutError("No XMS In Use");
Data_k_size=HZ_k_size;
if(GetXMSMemSize()<(Data_k_size+Code_k_size))
PutError("No Enough XMS Memory");
DataHandle=AllocXMSMem(Data_k_size);
CodeHandle=AllocXMSMem(Code_k_size);
if(!DataHandle||!CodeHandle)
{
FreeXMSMem(DataHandle);
FreeXMSMem(CodeHandle);
PutError("Something Wrong In AllocXMSMem");
}
}
void PrintHZ(void)
{
int i;
int color;
SetGraphMode();
PutHZ(0,0,RED,BLUE,"王");
PutHZ(18,0,RED,BLACK,"晓");
i=0;
while(i<256)
{
color++;
PutHZ(36+i,0,color,color+1,"智");
i+=18;
}
PutHZ(0,18,RED,BLACK,"『");
getch();
SetTextMode();
}
/*
void WhenExit()
{
UnlockHZ();
FreeXMSMem(DataHandle);
FreeXMSMem(CodeHandle);
poke(0,0x4f8,0);
poke(0,0x04fa,0);
}
*/
unsigned long Data32Address;
unsigned long Code32Address;
void LockHZ(void)
{
Data32Address=LockXMS(DataHandle);
Code32Address=LockXMS(CodeHandle);
}
void UnlockHZ(void)
{
UnlockXMS(DataHandle);
UnlockXMS(CodeHandle);
}
main()
{
unsigned long far *p=MK_FP(0,0x4f0);
unsigned int far *q=MK_FP(0,0x4f8);
LoadHZToXMS();
LockHZ();
*q=DataHandle; //04f8h
*(q+1)=CodeHandle; //04fah
*p=Data32Address; //04f0h
*(p+1)=Code32Address; //04f4h
PrintHZ();
printf("\n\n\n");
printf("HANDLE: %x\n",DataHandle);
printf("HZAddress: %lx\n",Data32Address);
printf("CodeAddress: %lx\n",Code32Address);
printf("FAR XMSFunc: %x:%x\n",FP_SEG(XMSFunc),FP_OFF(XMSFunc));
printf("PutHZ(int x,int y,int color,int bkcolor,char *p)\n");
printf("Address: %x:%x\n",FP_SEG(PutHZ),FP_OFF(PutHZ));
// system("");
// WhenExit();
return 0;
}
3、MAIN.C
/*
汉字装入及显示接口 by WXZ 1995,8
bcc -mc main
*/
#include <fcntl.h>
#include <io.h>
#include <dos.h>
#include <mem.h>
#include <bios.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
extern int directvideo=0;
// interface
void OpenHZ(void);
void far PutHZ(int x,int y,int color,int bkcolor,unsigned char *p);
void SetGraphMode(void);
void SetTextMode(void);
int HZ_k_size=262;
// local function
void PutPixel(int x,int y,int color);
int GetBit(unsigned char c,int n);
void ReadHZ(unsigned seg);
unsigned GetMemory(void);
long GetHZOffset(char *p);
void ClrLine(int x,int y,int bkcolor,int len);
int nHandle; // HZK16 file hanele
unsigned HZseg;
char far *pHZAddress; // a address in real mode
// in protected mode, it's 32bits abs address
void OpenHZ(void)
{
nHandle=open("HZK16",O_RDONLY|O_BINARY);
if(nHandle==-1)
PutError("Error On Open HZK16");
HZseg=GetMemory();
pHZAddress=MK_FP(HZseg,0);
ReadHZ(HZseg);
close(nHandle);
freemem(HZseg);
/*
Warning!
汉字内存已经释放,在汉字未送入扩展内存前,禁止
内存申请
*/
}
unsigned GetMemory(void)
{
unsigned seg;
if(allocmem(1024/16*(HZ_k_size+2),&seg)!=-1)
PutError("No DOS Memory");
return(seg);
}
void ReadHZ(unsigned seg)
{
int i;
char huge *p;
p=MK_FP(seg,0);
for(i=0;i<HZ_k_size;i++)
{
read(nHandle,(char far *)p,1024);
p+=1024;
}
}
// 参数需要两个字符 *p,*(++p) 来表示一个汉字
// 返回汉字点阵起始地址
long GetHZOffset(char *p)
{
unsigned char c1,c2;
long l;
c1=(*p-0xal)&0x07f;
c2=(*(++p)-0xal)&0x07f;
l=((long)((c1-23)*94+c2-23))*32;
return l;
}
void far PutHZ(int x,int y,int color,int bkcolor,unsigned char *p)
{
int i1,i2,i3;
long l;
unsigned char sHZBuf[32];
char far *s;
l=GetHZOffset(p);
// 由于偏移量超过64k,因此要将地址规范化相加
#ifndef XMS
s=MK_FP(HZseg+(unsigned)(l/16),(unsigned)(l%16));
movmem(s,sHZBuf,32);
#else
MoveFromXMS(DataHandle,l,sHZBuf);
#endif
// 将每一个点阵画到屏幕上,共256次(还需要优化)
ClrLine(x,y,bkcolor,18);
for(i1=0;i1<16;i1++)
{
PutPixel(x,y+i1+1,bkcolor);
for(i2=0;i2<2;i2++)
{
for(i3=0;i3<8;i3++)
{
if(GetBit(sHZBuf[i1*2+i2],7-i3))
PutPixel(x+i2*8+i3+1,y+i1+1,color);
else
PutPixel(x+i2*8+i3+1,y+i1+1,bkcolor);
}
}
PutPixel(x+17,y+i1+1,bkcolor);
}
ClrLine(x,y+17,bkcolor,18);
}
void ClrLine(int x,int y,int bkcolor,int len)
{
while(len--)
PutPixel(x+len,y,bkcolor);
}
// 判定字符的指定位是否为1
int GetBit(unsigned char c,int n)
{
return((c>>n)&1);
}
void SetGraphMode(void)
{
union REGS r;
r.h.ah=0;
r.h.al=0x12;
int86(0x10,&r,&r);
}
void SetTextMode(void)
{
union REGS r;
r.h.ah=0;
r.h.al=3; // not allowed mode 2
int86(0x10,&r,&r);
}
void PutPixel(int x,int y,int color)
{
unsigned offset; // 此点在内存中的偏移量
int bits; // 屏蔽位
unsigned char far *p;
bits=0x80>>(x%8);
y*=80;
x/=8;
offset=y+x;
p=MK_FP(0xa000,offset);
outportb(0x3ce,5); // 写方式 0
outportb(0x3cf,0);
outportb(0x3ce,0); // setup set/reset register
outportb(0x3cf,color);
outportb(0x3ce,1); // setup enable set/reset register
outportb(0x3cf,0xf);
outportb(0x3ce,8); // setup bit mask register
outportb(0x3cf,bits);
*p|=bits; // update the pixel
outportb(0x3ce,0); // default set/reset value
outportb(0x3cf,0);
outportb(0x3ce,1); // default enable set/reset value
outportb(0x3cf,0);
outportb(0x3ce,8); // default bit mask value
outportb(0x3cf,0xff);
}
// 此为测试程序
/*
void main(void)
{
int color,ch,i,j;
OpenHZ();
SetGraphMode();
PutHZ(1,12,RED,BLUE,"王");
PutHZ(17,12,RED,BLACK,"晓");
i=0,ch=0;
while(i<256)
{
color=ch++;
PutHZ(33+i,12,color,color+1,"智");
i+=16;
}
getch();
SetTextMode();
}
*/
4、FREE.C
#include <dos.h>
void main(void)
{
unsigned seg;
printf("\n\nInput PSP(MCB seg +1): ");
scanf("%x",&seg);
_BX=seg;
_ES=_BX;
_AH=0x49;
geninterrupt(0x21);
}
5、BIGMEM.C
// BigMem.c
// by wxz 1995.8 for HZDOS's software
//
//
//
// BCC -mc -f- -k- -y- -G- -v- BigMem.c
#include <mem.h>
#include <dos.h>
#include <process.h>
typedef enum {
FALSE=0,TRUE=1,False=0,True=1,false=0,true=1
} BOOL;
typedef unsigned char BYTE;
typedef unsigned WORD;
void main(void);
void SetBigMem(void);
void RestoreMem(void);
typedef struct {
BYTE type; // 5a:last 4d:normal
WORD psp;
WORD size;
} MCB;
MCB MCBSave;
MCB far *pMCB,*qMCB;
void SetBigMem(void)
{
_AH='W';
_AL='X';
geninterrupt(0x2f);
pMCB=MK_FP(_psp-1,0);
qMCB=MK_FP(pMCB->psp+pMCB->size,0);
if((qMCB->type!=0x5a)||(qMCB->psp!=0)||((qMCB->psp+qMCB->size)>0xa000))
{
exit(1);
}
movmem(qMCB,&MCBSave,16);
qMCB->size+=(0xb800-0xa000-1);
}
void RestoreMem(void)
{
_AH='W';
_AL='Z';
geninterrupt(0x2f);
movmem(&MCBSave,qMCB,16);
}
void main(void)
{
SetBigMem();
system("");
RestoreMem();
}