📄 lsys1.cpp
字号:
//////////////////////////////////////////////////////////////////////////
#include <lsys.h>
#include <dos.h>
#include <stdio.h>
#include <mem.h>
#include <malloc.h>
#include <conio.h>
#include <time.h>
//////////////////////////////////////////////////////////////////////////
char *VideoBuf=(char *)0xa0000L, // Video Mem addr in graph mode
*VideoTextBuf=(char *)0xb8000L, // Video Mem addr in text mode
*DrawBuf; // Active Graph Mem addr
extern struct TGModeTable GModeTable[SVGA_MAX_MODE]=
{ { 0x03, SVGA_TYPE_TEXT, 80, 25 }, // Text mode
{ 0x13, SVGA_TYPE_256, 320, 200 }, // 320 * 200 *256 mode
{ 0x5d, SVGA_TYPE_256, 640, 480 },
{ 0x5e, SVGA_TYPE_256, 800, 600 },
{ 0x101,SVGA_TYPE_256, 640, 480 },
{ 0x103,SVGA_TYPE_256, 800, 600 },
{ 0x1f9,SVGA_TYPE_256, 320, 200 },
{ 0x1f8,SVGA_TYPE_256, 320, 240 },
{ 0x1f3,SVGA_TYPE_256, 512, 384 },
{ 0x00, SVGA_TYPE_X , 320, 240 },
{ 0x00, SVGA_TYPE_X , 400, 300 },
{ 0,0,0,0 }, { 0,0,0,0 }, { 0,0,0,0 }, // NULL
};
struct TGModeTable GModeData={ 0, 0, 0, 0 };
int LineBase[2000], *DrawLb=LineBase;
char lsys_message[200]="NO ERROR";
short DrawLen, DrawWid;
short VGApage=0;
////////////////////////////////////////////////////////////////////////////
short lCreateSurface(short len,short wid,LSURFACE *sface,char *shadow,int mode)
{ long size=wid, y; size*=len; int *index;
switch (mode)
{ case LSM_SCREEN: sface->memory=VideoBuf; break;
case LSM_MEMORY: sface->memory=new char[size]; break;
case LSM_SHADOW: sface->memory=shadow; break;
default: sface->memory=NULL; mode=LSM_MEMORY; break;
}
sface->mode=0;
if (mode==LSM_MEMORY&&sface->memory==NULL) {
sprintf(lsys_message,"error alloc memory for surface bitmap");
return FALSE;
}
if (mode==LSM_SCREEN&&(len!=GModeData.LEN||wid!=GModeData.WID)) {
sprintf(lsys_message,"error screen size");
return FALSE;
}
sface->len=len; sface->wid=wid;
index=new int[wid];
if (!index) {
lDeleteSurface(sface);
sprintf(lsys_message,"error make line indexs");
return FALSE;
}
for (y=0;y<wid;y++) index[y]=y*len;
sface->index=index; sface->mode=mode;
if (mode==LSM_MEMORY) memset(sface->memory,0,size);
sprintf(lsys_message,"created a %dx%d surface in %lxh",len,wid,sface);
return TRUE;
}
void lDeleteSurface(LSURFACE *sface)
{ if (sface->mode==0) return;
if (DrawBuf==sface->memory) lActiveSurface(NULL);
if (sface->memory&&sface->mode==LSM_MEMORY) delete sface->memory;
if (sface->index!=LineBase) delete sface->index;
sface->mode=0;
}
void lActiveSurface(LSURFACE *SFACE)
{ if (SFACE==NULL||SFACE->mode==LSM_SCREEN) // to screen
{ DrawLen=GModeData.LEN; DrawWid=GModeData.WID;
DrawBuf=VideoBuf; DrawLb=LineBase;
return;
}
if (SFACE->mode==NULL) return;
DrawBuf=SFACE->memory;
DrawLb =SFACE->index;
DrawLen=SFACE->len;
DrawWid=SFACE->wid;
return;
}
////////////////////////////////////////////////////////////////////////////
extern "C" void cdecl LVGApageX(short page);
extern "C" void cdecl LMemCpy2X(void *dest,void *source,unsigned long len);
static char lEnterModeX(short len,short wid);
////////////////////////////////////////////////////////////////////////////
short lInitGraph(short index)
{ int vgaMode, len, wid, vtype, ret = TRUE;
int i,j;
vgaMode=GModeTable[index].VGAMODE; // Load Data
vtype=GModeTable[index].GMTYPE;
len=GModeTable[index].LEN;
wid=GModeTable[index].WID;
if (vtype==SVGA_TYPE_X) ret = lEnterModeX(len,wid);
else ret = lEnterGraph(GModeTable[index].VGAMODE);
if (ret==FALSE) return FALSE;
GModeData.VGAMODE=vgaMode, // copy data
GModeData.GMTYPE =vtype,
GModeData.LEN =DrawLen=len,
GModeData.WID =DrawWid=wid;
DrawLb=LineBase; DrawBuf=VideoBuf;
for (j=0;j<wid;j++) LineBase[j] = j * len;
return TRUE;
}
void lCloseGraph()
{ lEnterGraph(GModeTable[SVGA_TEXT].VGAMODE);
GModeData.VGAMODE=0;
}
short lEnterGraph(short mode)
{ short i=TRUE, j;
union REGS r;
if (mode<0x100)
{ r.w.ax=mode;
int386(0x10,&r,&r);
r.h.ah=0xf;
int386(0x10,&r,&r);
if (r.h.al!=mode) i=FALSE;
}
else
{ r.w.ax=0x4f02;
r.w.bx=mode;
int386(0x10,&r,&r);
if (r.w.ax!=0x004f) i=FALSE;
}
return (i);
}
///// MODE X //////////////////////////////////
struct LVGA_REGISTER
{
unsigned short port;
unsigned char index;
unsigned char value;
};
static LVGA_REGISTER lin_mode_320x240[] =
{
{ 0x3C2, 0x0, 0xE3 }, { 0x3D4, 0x0, 0x5F }, { 0x3D4, 0x1, 0x4F },
{ 0x3D4, 0x2, 0x50 }, { 0x3D4, 0x3, 0x82 }, { 0x3D4, 0x4, 0x54 },
{ 0x3D4, 0x5, 0x80 }, { 0x3D4, 0x6, 0xD }, { 0x3D4, 0x7, 0x3E },
{ 0x3D4, 0x8, 0x0 }, { 0x3D4, 0x9, 0x41 }, { 0x3D4, 0x10, 0xEA },
{ 0x3D4, 0x11, 0xAC }, { 0x3D4, 0x12, 0xDF }, { 0x3D4, 0x14, 0x0 },
{ 0x3D4, 0x15, 0xE7 }, { 0x3D4, 0x16, 0x6 }, { 0x3D4, 0x17, 0xE3 },
{ 0x3C4, 0x1, 0x1 }, { 0x3CE, 0x5, 0x40 }, { 0x3CE, 0x6, 0x5 },
{ 0x3C0, 0x10, 0x41 }, { 0, 0, 0 }
};
static LVGA_REGISTER lin_mode_notweak[] =
{
{ 0, 0, 0 }
};
struct LTWEAKED_MODE
{
int len, wid;
LVGA_REGISTER *regs;
int parent;
int hrs;
int shift;
int repeat;
};
static LTWEAKED_MODE lin_xmodes[] =
{
{ 320, 240, lin_mode_320x240, 0x13, 0, 0, 0 },
{ 400, 300, lin_mode_notweak, 0x6A, 1, 1, 1 },
{ 0, 0, NULL, 0, 0, 0, 0 }
};
static char lEnterModeX(short len,short wid)
{ long c;
LVGA_REGISTER *reg;
LTWEAKED_MODE *mode = lin_xmodes;
for (;(mode->len!=len || mode->wid!=wid);mode++)
if (!mode->regs) {
sprintf(lsys_message,"Can not init %dx%d in Mode X",len,wid);
return FALSE;
}
if (!lEnterGraph(mode->parent)) {
sprintf(lsys_message,"Can not init the parent mode in Mode X");
return FALSE;
}
outpw(0x3C4, 0x0100); /* synchronous reset */
outp(0x3D4, 0x11); /* enable crtc regs 0-7 */
outp(0x3D5, inp(0x3D5) & 0x7F);
outpw(0x3C4, 0x0604); /* disable chain-4 */
for (reg=mode->regs; reg->port; reg++) { /* set the VGA registers */
if (reg->port == 0x3C0) {
inp(0x3DA);
outp(0x3C0, reg->index | 0x20);
outp(0x3C0, reg->value);
} else if (reg->port == 0x3C2) {
outp(reg->port, reg->value);
} else {
outp(reg->port, reg->index);
outp(reg->port+1, reg->value);
}
}
if (mode->hrs) {
outp(0x3D4, 0x11); outp(0x3D5, inp(0x3D5)&0x7F);
outp(0x3D4, 0x04); outp(0x3D5, inp(0x3D5)+mode->hrs);
outp(0x3D4, 0x11); outp(0x3D5, inp(0x3D5)|0x80);
}
if (mode->shift) {
outp(0x3CE, 0x05); outp(0x3CF,(inp(0x3CF)&0x60)|0x40);
inp(0x3DA); outp(0x3C0, 0x30);
outp(0x3C0, inp(0x3C1)|0x40);
for (c=0; c<16; c++) {
outp(0x3C0, c);
outp(0x3C0, c);
} outp(0x3C0, 0x20);
}
if (mode->repeat) {
outp(0x3D4, 0x09);
outp(0x3D5,(inp(0x3D5)&0x60)|mode->repeat);
}
outp(0x3D4, 0x13); /* set scanline length */
outp(0x3D5, len/8);
outpw(0x3C4, 0x0300); /* restart sequencer */
for (c=0;c<0x10000;c++) VideoBuf[c]=0;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -