⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xms.cpp

📁 串口可交换程序
💻 CPP
字号:
#include <alloc.h>
#include <graphics.h>
#include <dos.h>
#include <dir.h>
#include "xms.h"

int XMS::OK=0;

static void far *XMSaddr;

int XMS::Init(void)
{
	static struct REGPACK rg;       //{unsigned r_ax,r_bx,r_cx,r_dx;
									//unsigned r_bp,r_si,r_di,r_es,r_flags;}
	rg.r_ax=0x4300;
	intr(0x2f,&rg); //改变软中断接口 intr(int IntNo,struct REGPACK *preg)
	if((rg.r_ax & 0x00ff) == 0x80){
		rg.r_ax=0x4310;
		intr(0x2f,&rg);
		XMSaddr=MK_FP(rg.r_es,rg.r_bx);   //set a far pointer
		OK=1;                             //seg and ofs
	}
	else
		OK=0;
	return OK;
}
unsigned XMS::FreeSize(void)  //AH=08H查询自由扩展内存块
{                             //返回参数AX!=0.成功.=0.失败
	if(0 == OK)               //AX中为最大自由扩展内存块的大小。
		return 0;             //DX中为自由扩展内存的总的大小。

	asm mov  ah,8
	asm call XMSaddr

	return _DX;
}
unsigned XMS::LargestBlock(void)
{
	if(0 == OK)
		return 0;

	asm mov  ah,8
	asm	call XMSaddr

	return _AX;
}

XMS::XMS(int size)            //AH=09H分配扩展内存块
{                             //DX=请求的扩展内存的大小
	if(0 ==OK)                //返回参数.AX=1.成功.DX=分配块的句柄
	{                         //         AX=0,分配失败,BL中为错误码
		handle=0;
		return;
	}

	asm mov  ah,9
	asm mov  dx,size
	asm call XMSaddr

	handle=_DX;
}

XMS::~XMS()                   //AH=0AH释放扩展内存块
{                             //调用参数:AH=0AH,DX=欲释放的扩展内存的句柄
	if(0 == handle)           //返回参数:AX=1,成功
		return;               //          AX=0,失败.BL中为错误码
	int hd=handle;

	asm mov  ah,0ah
	asm mov  dx,hd
	asm call XMSaddr
}

int XMS::ReAlloc(int size)    //AH=0FH重新分配扩展内存块
{                             //调用参数:AH=0FH,BX=扩展内存块的新长度
	if(0 == handle)           //          DX=EMB句柄
		return 0;             //返回参数:AX=1,成功BX=UMB段号
	int hd=handle;            //DX=已分配的节数.AX=0,失败.BL中为错误码

	asm mov  ah,0fh
	asm mov  bx,size
	asm mov  dx,hd
	asm call XMSaddr

	return _AX;
}

//AH=0BH:移动扩展内存块。
//本功能可在常规内存和扩展内存,扩展内存和扩展内存之间移动扩展内存块。
int XMS::Move(struct EMB *emb)
{                              //调用参数:AH=0BH
							   //DS:SI指向扩展内存块移动参数表
	char far *s=(char far *)emb;

	if(0 != handle)            //返回参数:AX=1,移动成功
	{                          // AX=0,失败,BL中为错误码
		asm mov ah,0bh
		asm push ds
		asm push ds
		asm pop es
		asm lds si,s
		asm call es:XMSaddr
		asm pop ds
		return _AX;
	}
	else
		return 0;
}
int XMS::Put(long dp,void *sp,long leng)
{
	struct EMB emb;

	if(leng & 1L)
		leng++;
	emb.Leng=leng;
	emb.SourceHandle=0;
	emb.SourceOfs=(long)sp;
	emb.DestinHandle=handle;
	emb.DestinOfs=dp;
	return Move(&emb);
}
int XMS::Get(void *dp,long sp,long leng)
{
	struct EMB emb;
	int v;

	if(leng & 1L)
	{
		char *p,*d;
		leng--;
		if(leng>0)
		{
			emb.Leng=leng;
			emb.SourceHandle=handle;
			emb.SourceOfs=sp;
			emb.DestinHandle=0;
			emb.DestinOfs=(long)dp;
			Move(&emb);
		}
		p=(char *)malloc(2);
		emb.Leng=2L;
		emb.SourceHandle=handle;
		emb.SourceOfs=sp+leng;
		emb.DestinHandle=0;
		emb.DestinOfs=(long)p;
		v=Move(&emb);

		d=(char *)dp;
		d[(unsigned)leng]=p[0];
		free(p);
	}
	else
	{
		emb.Leng=leng;
		emb.SourceHandle=handle;
		emb.SourceOfs=sp;
		emb.DestinHandle=0;
		emb.DestinOfs=(long)dp;
		v=Move(&emb);
	}
	return v;
}
int XMS::Transfer(long dp,long sp,long len)
{
	struct EMB emb;

	if(len & 1L)
		return 0;

	emb.Leng=len;
	emb.SourceHandle=handle;
	emb.SourceOfs=sp;
	emb.DestinHandle=handle;
	emb.DestinOfs=dp;

	return Move(&emb);
}
//----------------------------------------------------------------------
/////////////////
//MEMORY CLASS///
/////////////////

void MEMORY :: PutBuf(void *buf,long length)
{
	leng=length;

	if(buf==NULL)
	{
		where=inNONE;
		leng=0L;
		OK=0;
		return;
	}
	if(0 == XMS::OK)     //如果扩充内存没有初始化
		where=inHD;
	else
	{
		long l=0;
		l=(long)XMS::LargestBlock()-1L;
		l *= 1024L;
		if(leng >= l)    // 是否有足够的扩充内存
			where=inHD;
		else where=inXMS;
	}

	if(inXMS == where)   //将缓冲区的内容调入扩充内存
	{
		long ll;

		ll = (leng+1023L)/1024L;
		handle.xms = new XMS((int)ll);
		handle.xms->Put(0L,buf,leng);
	}
	else{
		where = inHD;
		handle.file = tmpfile();
		fwrite(buf,(size_t)leng,1,handle.file);
	}
	OK=1;

}
int MEMORY :: GetBuf(void *buf,long offset,int ll)
{
	if(OK == 0)return 0;

	long dl=leng-offset;

	if(offset >= leng)
		return 0;
	if(dl < (long)ll)
		ll=int(dl);

	if(inXMS == where)
		handle.xms->Get(buf,offset,ll);
	else if(inHD == where)
	{
		fseek(handle.file,offset,SEEK_SET);
		fread(buf,ll,1,handle.file);
	}
	return ll;
}

MEMORY :: ~MEMORY()
{
	if(inXMS == where)
		delete handle.xms;
	else if(inHD == where)
		fclose(handle.file);
}

//---------------------------------------------------------------------

FILETOXMS::FILETOXMS(char *name)
{
	FILE *fp;
	struct ffblk fblk;

	if(-1 == findfirst(name,&fblk,0))  //如果没有这个文件
//查找第一个匹配文件
	{
		where=inNONE;
		leng=0L;
		OK=0;
		return;
	}
	leng=fblk.ff_fsize;  //文件大小

	if(0 == XMS::OK)    //如果扩充内存没有初始化
		where=inHD;
	else{
		long l=0;
		l=(long)XMS::LargestBlock()-1L;
		l *= 1024L;
		if(leng >= l)  // 是否有足够的扩充内存
			where=inHD;
		else where=inXMS;
	}

	if(inXMS == where)  //将文件调如扩充内存
	{
		long sagl = 0x4000L;
		long left,offset,ll;
		int n,i;
		void *buf;

		ll = (leng+1023L)/1024L;
		handle.xms = new XMS((int)ll);
		buf = malloc((unsigned)sagl);
		n = (int)(leng/sagl);
		left = leng-sagl*(long)n;
		fp = fopen(name,"rb");
		offset = 0L;
		for(i=0;i<n;i++){
			fread(buf,(unsigned)sagl,1,fp);
			handle.xms->Put(offset,buf,sagl);
			offset += sagl;
		}
		fread(buf,(unsigned)left,1,fp);     //从流中读数据
		handle.xms->Put(offset,buf,left);
		free(buf);
		fclose(fp);
	}
	else{
		where = inHD;
		handle.file=fopen(name,"rb");
	}
	OK=1;

}

//-----------------------------------------------------------------
////////////////
//IMAGE CLASS///
////////////////
void IMAGE :: GetImageMEM()
{
	char far *cp;
	register int y;

	cp=(char far *)handle.mem;
	for(y=y1;y<=y2;y++)
	{
		GetScanLine(x1,y,xn,cp);
		cp += ssize;
	}
}

void IMAGE :: PutImageMEM(int xx1,int yy1)
{
	register int y;
	char far *cp;
	cp=(char far *)handle.mem;

	for(y=0;y<yn;y++){
		PutScanLine(xx1,yy1+y,xn,cp);
		cp += ssize;
	}
}

void IMAGE :: GetImageXMS()
{
	register int y;
	void *buf;
	long offset=0L;
	buf=malloc(ssize);

	for(y=y1;y<=y2;y++)
	{
		GetScanLine(x1,y,xn,(char far *)buf);
		handle.xms->Put(offset,buf,ssize);
		offset += ssize;
	}
	free(buf);
}

void IMAGE :: PutImageXMS(int xx1,int yy1)
{
	register int y;
	void *buf;
	long offset=0L;
	buf=malloc(ssize);

	for(y=0;y<yn;y++)
	{
		handle.xms->Get(buf,offset,ssize);
		PutScanLine(xx1,y+yy1,xn,(char far *)buf);
		offset += ssize;
	}
	free(buf);
}

void IMAGE :: GetImageHD()
{
	register int y;
	void *buf = malloc(ssize);

	fseek(handle.file,0L,SEEK_SET);
	for(y=y1;y<=y2;y++){
		GetScanLine(x1,y,xn,(char far *)buf);
		fwrite(buf,ssize,1,handle.file);
	}
	free(buf);
}

void IMAGE :: PutImageHD(int xx1,int yy1)
{
	register int y;
	void *buf = malloc(ssize);

	fseek(handle.file,0L,SEEK_SET);
	for(y=0;y<yn;y++){
		fread(buf,ssize,1,handle.file);
		PutScanLine(xx1,y+yy1,xn,(char far *)buf);
	}
	free(buf);
}

void IMAGE :: GetScanLine(int x1,int y,int n,char far *buf)
{
	unsigned byte1,byte2,x2;
	char pn=4;

	asm{
		mov ax,x1
		add ax,n
		dec ax
		mov x2,ax     	       // x2 = x1+n-1;

		mov ax,y
		mov bx,ax
		mov cl,6
		shl ax,cl
		mov cl,4
		shl bx,cl              //mul scanleng=80
		add ax,bx

		push ax
		mov bx,x1
		shr bx,1
		shr bx,1
		shr bx,1
		add ax,bx
		mov byte1,ax              // byte1 = y*80 + x1/8
		pop ax
		mov bx,x2
		shr bx,1
		shr bx,1
		shr bx,1
		add ax,bx
		mov byte2,ax              // byte2 = y*80 + x2/8
	}
JEMP2:
	asm{
		mov dx,0x3ce                // outportb(0x3ce,0x05);
		mov ax,0x0005               // outportb(0x3cf,0);
		out dx,ax
		mov al,0x04
		out dx,al                 // outportb(0x3ce,0x04);
		inc dx

		mov cx,x1
		and cx,7
		mov bl,cl
		mov bh,8
		sub bh,bl                 // bh = 8-(x1%8)

		push ds
		mov ax,0x0a000
		mov ds,ax
		les di,buf
		mov ax,byte2
		sub ax,byte1
		add ax,2                 // ax=byte2-byte1+2
		mov es:[di],al
		inc di
	}
LOOP1:
	asm{
		dec pn
		mov al,pn
		out dx,al                 // outportb(0x3cf,al);
		mov si,byte1
	}
LOOP2:
	asm{
		mov ah,ds:[si]
		inc si
		mov al,ah
		mov cl,bh
		shr ah,cl
		or es:[di],ah
		inc di
		mov cl,bl
		shl al,cl
		mov es:[di],al
		cmp byte2,si
		jae LOOP2                 // if(byte2 >= si)
		inc di
		cmp pn,0
		jne LOOP1                 // if(pn !=  0)
		pop ds
	}
}
void IMAGE :: PutScanLine(int x1,int y,int n,char far *buf)
{
	unsigned byte1,byte2,x2;
	unsigned char pn=4;
	unsigned char pbn;

	asm{
		mov ax,x1
		add ax,n
		dec ax
		mov x2,ax            // x2 = x1+n-1;

		mov ax,y
		mov bx,ax
		mov cl,6
		shl ax,cl
		mov cl,4
		shl bx,cl              //mul scanleng=80
		add ax,bx

		push ax
		mov bx,x1
		shr bx,1
		shr bx,1
		shr bx,1
		add ax,bx
		mov byte1,ax         // byte1 = y*80+x1/8;
		mov bx,x2
		shr bx,1
		shr bx,1
		shr bx,1
		pop ax
		add ax,bx
		mov byte2,ax         // byte2 = y*80+x2/8;
	}
JEMP2:
	asm{
		mov dx,0x3ce         // outportb(0x3ce,0x05);
		mov ax,0x0005        // outportb(0x3cf,0);
		out dx,ax            // 选择方式寄存器写方式0;

		mov ax,0x0001        // outportb(0x3ce,0x01);
		out dx,ax            // outpotrb(0x3cf,0);

		mov ax,0x0003        // outportb(0x3ce,0x03);
		out dx,ax            // outportb(0x3cf,0);

		push ds
		mov ax,0x0a000
		mov es,ax
		lds si,buf
		mov al,ds:[si]
		mov pbn,al

		mov cx,x1
		and cx,7
		mov bl,cl
		mov bh,8
		sub bh,bl
	}
LOOP1:
	asm{
		dec pn
		lds si,buf
		mov al,3
		sub al,pn
		mul pbn
		add ax,2
		add si,ax
		mov di,byte1

		mov dx,0x3c4
		mov al,2
		out dx,al            // outportb(0x3c4,2);
		inc dx
		mov cl,pn
		mov al,1
		shl al,cl
		out dx,al            // outportb(0x3c5,al);(al = 1,2,4,8);

		mov dx,0x3ce
		mov al,0x08
		out dx,al            // outportb(0x3ce,0x08);
		inc dx
		mov ax,byte1
		cmp ax,byte2
		je INONEBYTE
	}
	asm{
		mov al,0xff
		mov cl,bl
		shr al,cl
		out dx,al            // outportb(0x3cf,al);
		mov al,ds:[si]
		mov cl,bl
		shr al,cl
		mov ah,es:[di]
		mov es:[di],al
		mov al,0xff
		out dx,al
	}
MIDDLE_BYTE_LOOP:
	asm{
		inc di
		cmp di,byte2
		je WRITE_END_BYTE
		mov al,ds:[si]
		mov cl,bh
		shl al,cl
		inc si
		mov ah,ds:[si]
		mov cl,bl
		shr ah,cl
		or al,ah
		mov es:[di],al
		jmp MIDDLE_BYTE_LOOP
	}
WRITE_END_BYTE:
	asm{
		mov cx,x2
		not cx
		and cx,7
		mov al,0xff
		shl al,cl
		out dx,al
		mov al,ds:[si]
		mov cl,bh
		shl al,cl
		inc si
		mov ah,ds:[si]
		mov cl,bl
		shr ah,cl
		or al,ah
		mov ah,es:[di]
		mov es:[di],al
		jmp JEMP3
	}
INONEBYTE:
	asm{
		mov cx,x1
		and cx,7
		mov al,0xff
		shr al,cl
		mov cx,x2
		not cx
		and cx,7
		mov ah,0xff
		shl ah,cl
		and al,ah
		out dx,al
		mov al,ds:[si]
		mov cl,bl
		shr al,cl
		mov ah,es:[di]
		mov es:[di],al
	}
JEMP3:
	if(pn>0)
		goto LOOP1;
	asm pop ds
}

// class MenuImage
IMAGE :: IMAGE(int xx1,int yy1,int xx2,int yy2,int whe)
{
	where = whe;
	if( xx1 > xx2 )
		{ x1=xx2;x2=xx1; }
	else
		{ x1=xx1;x2=xx2; }
	if( yy1 > yy2 )
		{ y1=yy2;y2=yy1; }
	else
		{ y1=yy1;y2=yy2; }

	xn=x2-x1+1;
	yn=y2-y1+1;
	ssize = (((x2-x1)>>3)+3)*4+2;
	Isize=(long)ssize*yn;

	if(inMEM == where)
	{
		long left;
		left = coreleft();
		if(Isize>=left || Isize >= 4000L )
			where=inXMS;
		else
			handle.mem=malloc((unsigned)Isize);
	}
	if(inXMS == where)
	{
		if(0 == XMS::OK)
			where=inHD;
		else
		{
			long left=0;
			left = (long)XMS::LargestBlock()-1L;
			left *= 1024L;
			if(Isize >= left)
				where=inHD;
		}
	}

	if(inXMS == where)
	{
		int ksize = (int)((Isize+1023L)/1024L);
		handle.xms = new XMS(ksize);
	}
	else
	{
		where = inHD;
		handle.file = tmpfile();
	}
}

IMAGE :: ~IMAGE()
{
	if(inMEM == where)
		free(handle.mem);
	else if(inXMS == where)
		delete handle.xms;
	else fclose(handle.file);
}

void IMAGE :: GetImage()
{
	if(inMEM == where)
		GetImageMEM();
	else if(inXMS == where)
		GetImageXMS();
	else
		GetImageHD();

/*
if(where==inXMS) outtextxy(400,400,"Inxms");
else if(where==inMEM) outtextxy(400,400,"Inmen");
else outtextxy(400,400,"Inhd");
if (XMS::OK==0) outtextxy(400,430,"sucess");
else outtextxy(400,430,"fail");
*/
}

void IMAGE :: PutImage(int xx1,int yy1)
{
	if(inMEM == where)
			PutImageMEM(xx1,yy1);
	else if(inXMS == where)
			PutImageXMS(xx1,yy1);
	else if(inHD == where)
			PutImageHD(xx1,yy1);
	outport(0x3ce,0xff08);
	outport(0x3c4,0x0f02);
}

/* void IMAGE :: GetImage(int xx1,int yy1,int xx2,int yy2,int whe)
{
	where = whe;
	if( xx1 > xx2 )
		{ x1=xx2;x2=xx1; }
	else
		{ x1=xx1;x2=xx2; }
	if( yy1 > yy2 )
		{ y1=yy2;y2=yy1; }
	else
		{ y1=yy1;y2=yy2; }

	xn=x2-x1+1;
	yn=y2-y1+1;
	ssize = (((x2-x1)>>3)+3)*4+2;
	Isize=(long)ssize*yn;

	if(inMEM == where)
	{
		long left;
		left = coreleft();
		if(Isize>=left || Isize >= 4000L )
			where=inXMS;
		else
		{
			handle.mem=malloc((unsigned)Isize);
			GetImageMEM();
		}
	}
	if(inXMS == where)
	{
		if(0 == XMS::OK)
			where=inHD;
		else
		{
			long left=0;
			left = (long)XMS::LargestBlock()-1L;
			left *= 1024L;
			if(Isize >= left)
				where=inHD;
		}
	}

	if(inXMS == where)
	{
		int ksize = (int)((Isize+1023L)/1024L);
		handle.xms = new XMS(ksize);
		GetImageXMS();
	}
	else
	{
		where = inHD;
		handle.file = tmpfile();
		GetImageHD();
	}
}

void IMAGE :: PutImage(int xx1,int yy1)
{
	if(inMEM == where)
		{
			PutImageMEM(xx1,yy1);
			free(handle.mem);
		}
	else if(inXMS == where)
		{
			PutImageXMS(xx1,yy1);
			delete handle.xms;
		}
	else if(inHD == where)
		{
			PutImageHD(xx1,yy1);
			fclose(handle.file);
		}
	outport(0x3ce,0xff08);
	outport(0x3c4,0x0f02);
}
*/

/*---------------END-----------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -