📄 tsr.c
字号:
// uncomment the line to run in PC test mode
//#define debug
#define MODEX_DELAY 5 // default modex delay..
#define SUPPORT_DBCS
#include <dos.h>
#include <stdlib.h>
#include "define.h"
#include "mode15k.h"
#include "drv15k.h"
#include "vesa.h"
#include "tsr.h"
#include "tsrsub.h"
/* Program vars/options structure */
PROGRAMtag PROGRAM;
#ifdef SUPPORT_DBCS
static void DBCS_get_vector(void);
BYTE dbcs_supported;
WORD dbcs_ds;
WORD dbcs_si;
#endif
/* Stack size */
extern unsigned _stklen=1024;
/* Function to call old interrupt 10h */
#define INT10 \
asm { push bp } \
(*old_int10)(); \
asm { pop bp }
/* Function to call old interrupt 8h */
#define INT8 \
asm { push bp } \
(*old_int8)(); \
asm { pop bp }
static WORD CalcBytesPerLine(int width, int depth)
{
return ((WORD)width * depth) / 8;
}
static WORD CalcPixelsPerLine(int offset, int depth)
{
return ((WORD)offset * 8) / depth;
}
static void VsyncVga(void)
{
while( (_inb(0x3da) & 0x08) != 0 );
while( (_inb(0x3da) & 0x08) == 0 );
}
static int ParseOption(char *option)
{
int temp;
int c;
char *opt;
opt = &option[1]; /* Pointer to actual option */
/* Force uppercase if a to z */
if(option[0]>=97 && option[0]<=122)
{
option[0]-=32;
}
switch ( option[0] )
{
case 'H':
case '?':
printf(usage);
return 0;
case 'L':
DisplayModes();
break;
case 'U':
PROGRAM.unload=1;
break;
case 'E':
PROGRAM.enabled=1-PROGRAM.enabled;
break;
case 'M':
temp=atoi(opt);
if(temp>48)
printf("Invalid -m option\n");
else
PROGRAM.vidmem=temp;
break;
case 'W':
temp=atoi(opt);
if(temp<0 || 255<temp)
printf("Invalid -w option\n");
else
PROGRAM.max_ticks=temp;
break;
case 'X':
temp=atoi(opt);
if(temp<-16 || temp>16)
printf("Invalid -x option\n");
else
PROGRAM.center_x=temp;
break;
case 'Y':
temp=atoi(opt);
if(temp<-8 || temp>8)
printf("Invalid -y option\n");
else
PROGRAM.center_y=temp;
break;
case '1':
temp=atoi(opt);
if(temp<0 || temp>3)
printf("Invalid -1 option\n");
else
PROGRAM.h_sync_delay=temp;
break;
case '2':
temp=atoi(opt);
if(temp<0 || temp>3)
printf("Invalid -2 option\n");
else
PROGRAM.h_disp_delay=temp;
break;
case 'P':
PROGRAM.use_pm_interface=1-PROGRAM.use_pm_interface;
if(own_pm_interface_supported() == 0){
PROGRAM.use_pm_interface = 0;
}
break;
#ifdef SUPPORT_DBCS
case 'D':
PROGRAM.use_dbcs = 1 - PROGRAM.use_dbcs;
break;
#endif
case 'V':
PROGRAM.vga_hook_enabled = 1 - PROGRAM.vga_hook_enabled;
break;
case 'O':
PROGRAM.use_original_1024x768 = 1 - PROGRAM.use_original_1024x768;
break;
case 'I':
DisplayModeX();
break;
default:
printf("Unknown option %c\n",option[0]);
return 0;
}
return 1;
}
static int ParseOptions(int optCount, char **options)
{
VIDEOMODE SingleMode;
int i;
i=0;
while (i<optCount)
{
/* `-' and `/' valid operator seperators */
if((options[i][0]=='-') || (options[i][0]=='/'))
{
if(strcmp("#",&options[i][1])==0)
{
memset(&SingleMode,0,sizeof(VIDEOMODE));
i++;
SingleMode.HTotal=atoi(&options[i][0]);
i++;
SingleMode.HDisp=atoi(&options[i][0]);
i++;
SingleMode.HBStart=atoi(&options[i][0]);
i++;
SingleMode.HSStart=atoi(&options[i][0]);
i++;
SingleMode.HSEnd=atoi(&options[i][0]);
i++;
SingleMode.HBEnd=atoi(&options[i][0]);
i++;
SingleMode.VTotal=atoi(&options[i][0]);
i++;
SingleMode.VDisp=atoi(&options[i][0]);
i++;
SingleMode.VBStart=atoi(&options[i][0]);
i++;
SingleMode.VSStart=atoi(&options[i][0]);
i++;
SingleMode.VSEnd=atoi(&options[i][0]);
i++;
SingleMode.VBEnd=atoi(&options[i][0]);
i++;
SingleMode.hpolarity=atoi(&options[i][0]);
i++;
SingleMode.vpolarity=atoi(&options[i][0]);
i++;
SingleMode.doublescan=atoi(&options[i][0]);
i++;
SingleMode.interlace=atoi(&options[i][0]);
i++;
SingleMode.interlaceratio=atoi(&options[i][0]);
i++;
SingleMode.dotclockHz=atol(&options[i][0]);
i++;
SingleMode.horzHz=atol(&options[i][0]);
i++;
SingleMode.vert001Hz=atol(&options[i][0]);
SingleMode.width = SingleMode.HDisp;
SingleMode.height = GetScreenHeight(
SingleMode.VDisp,
SingleMode.doublescan,
SingleMode.interlace);
/* Make a DoubleScan report as half its designed height */
//if(SingleMode.doublescan)
// SingleMode.VDisp>>=1;
/* Add Mode */
AddMode(&SingleMode);
}
else
{
if(ParseOption(&options[i][1])==0)
{
return 0; /* Help shown don't do anything */
}
}
i++;
}
else
{
printf("Invalid command line option\n");
return 0;
}
}
/* No amount specified, use Videocard amount */
if(PROGRAM.vidmem==0)
{
PROGRAM.vidmem=VESA.memory>>4;
}
/* Allow memory emulation */
VESA.memory=((int)PROGRAM.vidmem<<4);
PROGRAM.membytes=(unsigned long)(VESA.memory<<6)<<10;
return 1;
}
static void ShowOptions()
{
/* Activate to the arcade monitor/PC monitor depending on state */
_AX=3;
asm int 10h
/* Display current options */
printf("Status:-\n");
printf("\t enabled = %s\n", YesNo[PROGRAM.enabled]);
printf("\t VGA hook enabled = %s\n", YesNo[PROGRAM.vga_hook_enabled]);
printf("\t original VESA 1024x768 = %s\n", YesNo[PROGRAM.use_original_1024x768]);
printf("\t video memory = %d MB\n", PROGRAM.vidmem);
printf("\t ModeX wait time = %d\n", PROGRAM.max_ticks);
printf("\t center_x = %i\n", PROGRAM.center_x);
printf("\t center_y = %i\n", PROGRAM.center_y);
printf("\t horizontal sync delay = %i\n", PROGRAM.h_sync_delay);
printf("\t horizontal disp delay = %i\n", PROGRAM.h_disp_delay);
if(own_pm_interface_supported() != 0){
printf("\t own protected mode interface = %s\n", YesNo[PROGRAM.use_pm_interface]);
}
#ifdef SUPPORT_DBCS
printf("\t DBCS 640x480 text mode = %s\n", YesNo[PROGRAM.use_dbcs]);
#endif
}
void main(int argc, char *argv[])
{
unsigned int TSR_SEG;
#ifdef SUPPORT_DBCS
DBCS_get_vector();
#endif
if(DetectVESA()==0) /* No VESA support */
return;
if(Detect15KHz()==0) /* Add your video card check here */
{
printf("%s", NotFoundMessage());
return;
}
PROGRAM.use_original_1024x768 = 1;
Init_PROGRAM_VideoModes();
old_int10 = getvect(0x10);
/* Check to make sure not already loaded */
if (FP_OFF(old_int10)==FP_OFF(int10h_proc))
{
/* Get the tsr segment, add correct offest in segment for old interrupt vectors */
TSR_SEG=FP_SEG(old_int10);
memcpy(&PROGRAM,MK_FP(TSR_SEG+(FP_SEG(&PROGRAM)-FP_SEG(int10h_proc)),FP_OFF(&PROGRAM)),sizeof(PROGRAM));
/* Check to make sure we got the right memory location */
if (PROGRAM.loaded_flag==TSR_ID)
{
/* TSR already in Memory */
/* Override the options with any new ones! */
if(ParseOptions(argc-1, &argv[1])==0)
{
return; /* Help was shown don't do anything */
}
if(PROGRAM.unload==1) /* Unload TSR */
{
/* Copy old Interrupt addresses */
memcpy(&old_int10,MK_FP(TSR_SEG+(FP_SEG(&old_int10)-FP_SEG(int10h_proc)),FP_OFF(&old_int10)),4);
memcpy(&old_int8,MK_FP(TSR_SEG+(FP_SEG(&old_int8)-FP_SEG(int10h_proc)),FP_OFF(&old_int8)),4);
asm cli
if(old_int10!=NULL)
setvect(0x10,old_int10);
if(old_int8!=NULL)
setvect(0x8,old_int8);
asm sti
asm mov ax,3
asm int 10h
printf("Restored old Int 0x10 at (%p)\n",old_int10);
printf("Restored old Int 0x8 at (%p)\n",old_int8);
freetsr(PROGRAM.psp);
}
else /* Change options */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -