📄 ibmmsdos.c
字号:
/* IbmMsdos.c
This file is part of the VGB-DOS project
Copyright (C) Marcel de Kogel (m.dekogel@student.utwente.nl), 1996
You may not use this file for commercial purposes
Please notify me if you make any changes to this file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crt0.h>
#include <go32.h>
#include <dpmi.h>
#include <dos.h>
#include <pc.h>
#include <conio.h>
#include "GB.h"
#include "IbmMsDos.h"
/* Define if you've installed ANSI.SYS on your terminal */
/* #define USE_ANSI */
extern char szGifFile[];
int _crt0_startup_flags = _CRT0_FLAG_NONMOVE_SBRK |
_CRT0_FLAG_LOCK_MEMORY |
_CRT0_FLAG_DROP_EXE_SUFFIX;
struct _SB_Info SB_Info;
int swapbuttons=0;
int videomode=0;
int soundmode=1;
int IntSync=1;
static int OldTimer,NewTimer,ReadTimerMin;
int brightness=0;
int spritebrightness=1000,windowbrightness=1000,backgroundbrightness=1000;
unsigned short cs_alias;
static int KEY_LEFT,KEY_RIGHT,KEY_UP,KEY_DOWN,
KEY_BUTTONA,KEY_BUTTONB,KEY_START,KEY_SELECT;
char *szKeys="CBCDC8D0381D2A2C";
#ifdef DEBUG
int nDebugKey=0;
static int showwindow=1;
#else
#define showwindow 1
#endif
#define NUM_STACKS 16
#define STACK_SIZE 8192
#ifdef DEBUG
/* Called when one of the keys 1-9 is pressed */
static void ParseDebugKey (void)
{
const char *szRegNames[16] = {
"LCDCONT", "LCDSTAT", "SCROLLY", "SCROLLX",
"CURLINE", "CMPLINE", " ", "BGRDPAL",
"SPR0PAL", "SPR1PAL", "WNDPOSX", "WNDPOSY",
" ", " ", " ", " " };
int i;
switch (nDebugKey)
{
case 1:
Trace=!Trace;
break;
case 2:
#ifdef USE_ANSI
fprintf(stdout,"\033[H\033[2J");
#endif
fprintf(stdout,"*** REGISTERS: ***\n");
for(i=0xFF40;i<0xFF50;i++)
fprintf(stdout,"%s (%04Xh) = %02Xh\n",szRegNames[i-0xFF40],i,RAM[i]);
fprintf(stdout,"ISWITCH = %02Xh\n",ISWITCH);
fflush(stdout);
break;
case 3:
#ifdef USE_ANSI
fprintf(stdout,"\033[H\033[2J");
#endif
fprintf(stdout,"*** SPRITES: ***\n");
for(i=0xFE9C;i<0xFE9C+4*40;i+=4)
fprintf (stdout,"SPRITE %d: %d,%d Pat %d Attr %d\n",
(i-0xFE9C)/4,RAM[i+1],RAM[i],RAM[i+2],RAM[i+3]);
fflush(stdout);
break;
case 4:
showwindow=!showwindow;
break;
}
nDebugKey=0;
}
#endif
/* Parse the BLASTER environment variable */
static void GetSBInfo (void)
{
char *blaster=getenv ("BLASTER");
memset (&SB_Info,0,sizeof(SB_Info));
if (blaster)
{
strupr (blaster);
while (*blaster)
{
while (*blaster==' ' || *blaster=='\t')
++blaster;
switch (*blaster++)
{
case 'A': SB_Info.baseport=(word)strtol(blaster,NULL,16);
break;
case 'I': SB_Info.irq=(byte)strtol(blaster,NULL,10);
break;
case 'D': SB_Info.dma_low=(byte)strtol(blaster,NULL,10);
break;
case 'H': SB_Info.dma_high=(byte)strtol(blaster,NULL,10);
break;
case 'T': SB_Info.type=(byte)strtol(blaster,NULL,10);
break;
case 'E': SB_Info.emu_baseport=(word)strtol(blaster,NULL,16);
break;
case 'P': SB_Info.mpu_baseport=(word)strtol(blaster,NULL,16);
break;
}
while (*blaster && *blaster!=' ' && *blaster!='\t')
++blaster;
}
}
}
/** Various variables and short functions ********************/
#define WIDTH 176
#define HEIGHT 160
int DosSelector; /* Used by the assembly routines */
byte *XBuf,XPal[16]; /* Screen buffer and palette */
static void VGA_SetPalette (byte *pal,int start,int numcolors)
{
int i;
disable ();
while ((inportb(0x3DA)&0x08)!=0); /* Wait until vertical retrace is off */
while ((inportb(0x3DA)&0x08)==0); /* Now wait until it is on */
outportb (0x3C8,start);
for (i=0;i<numcolors*3;++i)
outportb(0x3C9,pal[i]/4);
enable ();
}
static int nOldVideoMode;
void VGA_Reset (void) /* Reset old video mode */
{
__dpmi_regs r;
r.x.ax=(short)nOldVideoMode;
__dpmi_int (0x10, &r);
}
/* For a 360x144 mode */
static unsigned char crtc_regs[24]=
{
0x6B,0x59,0x5A,0x8E,
0x5E,0x8A,0x5F,0x1F,
0x00,0x41,0x00,0x00,
0x00,0x00,0x00,0x00,
0x3C,0x2E,0x2F,0x2D,
0x40,0x36,0x59,0xA3
};
/* 256x200 */
static unsigned char crtc_regs_256[24]=
{
0x4F,0x3F,0x40,0x92,
0x44,0x10,0xBF,0x1F,
0x00,0x41,0x00,0x00,
0x00,0x08,0x00,0x00,
0x9C,0x8E,0x8F,0x28,
0x40,0x96,0xB9,0xA3
};
static void VGA_SetFullScreenMode (void)
{
int i;
disable ();
while (inportb(0x3DA)&8);
while ((inportb(0x3DA)&8)==0);
outportw (0x3C4,0x100); /* sequencer reset */
outportb (0x3C2,0x27); /* misc. output reg */
outportw (0x3C4,0x300); /* clear sequencer reset */
outportw (0x3D4,((crtc_regs[0x11]&0x7F)<<8)+0x11); /* deprotect regs 0-7 */
for (i=0;i<24;++i)
outportw (0x3D4,(crtc_regs[i]<<8)+i);
enable ();
}
static void VGA_Set256x200 (void)
{
int i;
disable ();
while (inportb(0x3DA)&8);
while ((inportb(0x3DA)&8)==0);
outportw (0x3C4,0x100);
outportb (0x3C2,0x63);
outportw (0x3C4,0x300);
outportw (0x3D4,((crtc_regs_256[0x11]&0x7F)<<8)+0x11);
for (i=0;i<24;++i)
outportw (0x3D4,(crtc_regs_256[i]<<8)+i);
enable ();
}
char *ColorNames[16];
struct ColorName_struct
{
char *name;
int color;
};
typedef struct ColorName_struct ColorName_t;
static ColorName_t ColorName[]=
{
{ "black" ,0x000000 },
{ "blue" ,0x0000FF },
{ "green" ,0x00FF00 },
{ "cyan" ,0x55FFFF },
{ "red" ,0xFF0000 },
{ "magenta" ,0xFF55FF },
{ "brown" ,0xAA5500 },
{ "orange" ,0xFF7711 },
{ "pink" ,0xFFAAAA },
{ "gray" ,0xAAAAAA },
{ "yellow" ,0xFFFF00 },
{ "white" ,0xFFFFFF },
{ "dkgray" ,0x555555 },
{ "dkblue" ,0x0000AA },
{ "dkgreen" ,0x00AA00 },
{ "dkcyan" ,0x00AAAA },
{ "dkred" ,0xAA0000 },
{ "dkmagenta" ,0xAA00AA },
{ NULL,-1 }
};
int ColorNameToColor (char *colorname)
{
int tmp;
char *pTmp;
int j;
tmp=-1;
if (colorname)
{
if (colorname[0]=='#')
tmp=strtoul (colorname+1,&pTmp,16);
else
for (j=0;ColorName[j].name;++j)
if (!strcmp(colorname,ColorName[j].name))
tmp=ColorName[j].color;
}
return tmp;
}
static void ParseColorNames (char *pal)
{
int i,tmp;
for (i=0;i<16;++i)
{
tmp=ColorNameToColor (ColorNames[i]);
if (tmp>=0)
{
*pal++=(tmp>>16)&0xFF;
*pal++=(tmp>>8)&0xFF;
*pal++=tmp&0xFF;
}
else
pal+=3;
}
}
static void _brightness (byte *pal,int brightness)
{
int tmp;
tmp=(int)(unsigned)*pal;
tmp=tmp*(brightness+200)/200;
if (tmp>255)
tmp=255;
*pal=(byte)tmp;
}
/* Set mode and palette, put decoded GIF on screen */
static int VGA_Init (char *pGifPalette,char *pGifBytes)
{
static byte fspal[256*3];
static byte pal[64*3]={ 0,0,0, /* Overscan colour */
0xFF,0xFF,0xFF, /* Background colours */
0xB0,0xB0,0xB0,
0x60,0x60,0x60,
0x00,0x00,0x00,
0xFF,0xFF,0xFF, /* Sprite colours */
0xB0,0xB0,0xB0,
0x60,0x60,0x60,
0x00,0x00,0x00,
0xFF,0xFF,0xFF, /* Window colours */
0xB0,0xB0,0xB0,
0x60,0x60,0x60,
0x00,0x00,0x00 };
int a,b;
__dpmi_regs r;
r.x.ax=0x0F00;
__dpmi_int (0x10,&r);
nOldVideoMode=(int)(r.h.al & 0x7F);
r.x.ax=0x0013;
__dpmi_int (0x10,&r);
if (videomode==2 || videomode==3)
{
VGA_SetFullScreenMode ();
}
else
{
if (videomode==4 || videomode==5)
{
VGA_Set256x200 ();
videomode-=4;
}
if (videomode!=1)
{
if (pGifBytes)
{
VGA_SetPalette (pGifPalette,0,256);
dosmemput (pGifBytes,64000,0xA0000);
}
}
videomode=0;
}
ParseColorNames (pal+3);
if (brightness<-100 || brightness>100)
brightness=0;
if (backgroundbrightness>100)
backgroundbrightness=brightness;
if (backgroundbrightness<-100 || backgroundbrightness>100)
backgroundbrightness=0;
for (a=1;a<5;++a)
{
_brightness (&pal[a*3+0],backgroundbrightness);
_brightness (&pal[a*3+1],backgroundbrightness);
_brightness (&pal[a*3+2],backgroundbrightness);
}
if (spritebrightness>100)
spritebrightness=brightness;
if (spritebrightness<-100 || spritebrightness>100)
spritebrightness=0;
for (a=5;a<9;++a)
{
_brightness (&pal[a*3+0],spritebrightness);
_brightness (&pal[a*3+1],spritebrightness);
_brightness (&pal[a*3+2],spritebrightness);
}
if (windowbrightness>100)
windowbrightness=brightness;
if (windowbrightness<-100 || windowbrightness>100)
windowbrightness=0;
for (a=9;a<13;++a)
{
_brightness (&pal[a*3+0],windowbrightness);
_brightness (&pal[a*3+1],windowbrightness);
_brightness (&pal[a*3+2],windowbrightness);
}
if (videomode==2 || videomode==3)
{
for (a=0;a<15;++a)
for (b=0;b<15;++b)
if (b==0 || videomode==3)
{
fspal[a*3+b*16*3+0]=pal[a*3+0];
fspal[a*3+b*16*3+1]=pal[a*3+1];
fspal[a*3+b*16*3+2]=pal[a*3+2];
}
else
{
fspal[a*3+b*16*3+0]=pal[a*3+0]/2+pal[b*3+0]/2;
fspal[a*3+b*16*3+1]=pal[a*3+1]/2+pal[b*3+1]/2;
fspal[a*3+b*16*3+2]=pal[a*3+2]/2+pal[b*3+2]/2;
}
VGA_SetPalette (fspal,0,256);
}
else
{
/* Handy for debugging */
for (a=0,b=16;a<16;++a,++b)
{
pal[b*3+0]=pal[a*3+0];
pal[b*3+1]=255;
pal[b*3+2]=pal[a*3+2];
}
for (a=0,b=32;a<32;++a,++b)
{
pal[b*3+0]=255;
pal[b*3+1]=pal[a*3+1];
pal[b*3+2]=pal[a*3+2];
}
VGA_SetPalette (pal,0,64);
}
return 1;
}
static __volatile__ int PausePressed=0;
static __volatile__ byte keybstatus[256]; /* 1 if key is pressed */
static _go32_dpmi_seginfo newirqkeyb,oldirqkeyb;
void keyb_interrupt (void)
{
unsigned code;
static int extkey;
code=inportb (0x60); /* get scancode */
if (code<0xE0) /* ignore codes >0xE0 */
{
if (code & 0x80) /* key is released */
{
code&=0x7F;
if (extkey)
keybstatus[code+128]=0;
else
keybstatus[code]=0;
}
else /* key is pressed */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -