📄 tseng3.c
字号:
/*
** tseng3.c - get ET4000 graphics register values
** Copyright (C) 1993 Tommy Frandsen, Harm Hanemaayer, Hartmut Schirmer
**
** This program is free software;
**
** Permission is granted to any individual or institution to use, copy,
** or redistribute this executable so long as it is not modified and
** that it is not sold for profit.
**
** LIKE ANYTHING ELSE THAT'S FREE, TSENG3 IS PROVIDED AS IS AND
** COMEs WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED.
** IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
** RESULTING FROM THE USE OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <stdarg.h>
/* VGA index register ports */
#define CRT_I 0x3D4 /* CRT Controller Index (mono: 0x3B4) */
#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
#define GRA_I 0x3CE /* Graphics Controller Index */
#define SEQ_I 0x3C4 /* Sequencer Index */
#define PEL_IW 0x3C8 /* PEL Write Index */
/* VGA data register ports */
#define CRT_D 0x3D5 /* CRT Controller Data Register (mono: 0x3B5) */
#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
#define GRA_D 0x3CF /* Graphics Controller Data Register */
#define SEQ_D 0x3C5 /* Sequencer Data Register */
#define MIS_R 0x3CC /* Misc Output Read Register */
#define MIS_W 0x3C2 /* Misc Output Write Register */
#define IS1_R 0x3DA /* Input Status Register 1 (mono: 0x3BA) */
#define PEL_D 0x3C9 /* PEL Data Register */
/* VGA indexes max counts */
#define CRT_C 24 /* 24 CRT Controller Registers */
#define ATT_C 21 /* 21 Attribute Controller Registers */
#define GRA_C 9 /* 9 Graphics Controller Registers */
#define SEQ_C 5 /* 5 Sequencer Registers */
#define MIS_C 1 /* 1 Misc Output Register */
#define EXT_C 17 /* 11 SVGA Extended Registers */
/* VGA registers saving indexes */
#define CRT 0 /* CRT Controller Registers start */
#define ATT CRT+CRT_C /* Attribute Controller Registers start */
#define GRA ATT+ATT_C /* Graphics Controller Registers start */
#define SEQ GRA+GRA_C /* Sequencer Registers */
#define MIS SEQ+SEQ_C /* General Registers */
#define EXT MIS+MIS_C /* SVGA Extended Registers */
#define TOTAL EXT+EXT_C /* # or registers values */
unsigned char vga_regs[TOTAL];
static int do_all = 0;
FILE *output = NULL;
static int save_extregs;
void port_out(unsigned char value, unsigned short port)
{
asm mov dx,port
asm mov al,value
asm out dx,al
}
unsigned char port_in(unsigned short port)
{
asm mov dx,port
asm in al,dx
return (_AL);
}
int dactype(void)
{
union REGS cpu_regs;
cpu_regs.x.ax=0x10F1;
cpu_regs.x.bx=0x2EFF;
int86(0x10, &cpu_regs, &cpu_regs);
if (cpu_regs.x.ax != 0x0010)
return (-1);
else
return (cpu_regs.h.bl);
}
int read_dac(int addr)
{
inp(0x3c8);
inp(0x3c6);
inp(0x3c6);
inp(0x3c6);
inp(0x3c6);
while (addr)
--addr,inp(0x3c6);
addr = inp(0x3c6);
return addr;
}
int write_dac(int addr,int value)
{
inp(0x3c8);
inp(0x3c6);
inp(0x3c6);
inp(0x3c6);
inp(0x3c6);
while (addr)
--addr,inp(0x3c6);
outp(0x3c6,value);
return read_dac(addr);
}
int read_ext_dac(int addr)
{
write_dac(1,addr);
write_dac(2,0);
return read_dac(3);
}
void puts2(char *s) {
if (output != NULL)
fprintf(output, "%s\n", s);
while (*s != '\0') {
if (*s == '\n') putch('\r');
putch (*(s++));
}
putch('\r'); putch('\n');
}
int printf2(char *fmt, ...)
{
va_list argptr;
char str[140], *s;
int cnt;
va_start( argptr, fmt );
if (output != NULL)
vfprintf(output, fmt, argptr);
cnt = vsprintf( str, fmt, argptr );
s = str;
while (*s) {
switch (*s) {
case '\n' : putch('\r');
break;
case '\t' : cprintf("%*s", 8-((wherex()-1)&7), "");
++s;
continue;
}
putch(*(s++));
}
va_end( argptr );
return( cnt );
}
void get_dac(void)
{
int dac;
dac = dactype();
switch (dac)
{
case -1:
printf2 ("/* Dac detection BIOS call returned an error */\n");
break;
case 0:
printf2 ("/* Standard VGA dac detected */\n");
printf2 ("#define DAC_TYPE 0\n");
break;
case 1:
printf2 ("/* Sierra SC1148x HiColor dac detected */\n");
printf2 ("#define DAC_TYPE 1\n");
break;
case 2:
printf2 ("/* Diamond Speedstar 24 24bit dac or Sierra Mark2/Mark3 dac detected */\n");
break;
case 3:
printf2 ("/* AT&T ATT20c491/2 15/16/24 bit dac detected */\n");
printf2 ("#define DAC_TYPE 9\n");
break;
case 4:
printf2 ("/* AcuMos ADAC1 15/16/24 bit dac detected */\n");
break;
case 8:
printf2 ("/* Music 15/16/24 bit dac (AT&T compatible) detected */\n");
printf2 ("#define DAC_TYPE 9\n");
break;
default: { /* use alternate method */
int cmd = read_dac(0);
write_dac(0,cmd | 0x10);
if (read_ext_dac(0) == 0x44) {
printf2 ("/* SGS-Thomson STG170x 15/16/24 dac detected */\n");
save_extregs = 1;
}
else
printf2 ("/* Unknown HiColor dac (%d) detected */\n", dac);
break;
}
}
}
#define TickTime (1.0/1193182.0)
#define init_timer() do { \
asm mov al, 034h; \
asm out 043h, al; \
asm xor al, al; \
asm out 040h, al; \
asm out 040h, al; \
} while(0)
#define ReadTimer(dst) do { \
asm { mov al, 4; \
out 43h, al; \
in al, 40h; \
mov bl, al; \
in al, 40h; \
mov ah, al; \
mov al, bl; \
not ax } \
(dst) = _AX; \
} while (0);
#define _wait_(ID,VAL) \
w_##ID##1: \
asm in al, dx; \
asm test al, VAL; \
asm jne w_##ID##1; \
w_##ID##2: \
asm in al, dx; \
asm test al, VAL; \
asm je w_##ID##2
#define wait_horizontal(ID,port) do { _DX=(port); _wait_(ID##ch,8);} while(0)
#define wait_vertical(ID,port) do { _DX=(port); _wait_(ID##cv,1);} while(0)
#define __loop__(ID,port,loops,msk) do { \
register int cnt = (loops); \
_DX=(port); \
do { \
_wait_(ID,msk); \
} while (--cnt > 0); \
} while(0)
#define loop_vertical(ID,port,loops) __loop__(ID##cv,(port),(loops),1)
int interlaced(void) {
return (vga_regs[EXT+5] & 0x80) ? 1 : 0;
}
int calc_vtotal(void) {
int total;
total = (vga_regs[EXT+5]&2) ? 1024 : 0;
switch (vga_regs[CRT+7]&0x21) {
case 0x01 : total += 256; break;
case 0x20 : total += 512; break;
case 0x21 : total += 768; break;
}
total += vga_regs[CRT+6];
return total + 2;
}
double measure_horizontal(void)
{
short start, stop;
long diff;
disable();
init_timer();
wait_horizontal(mv0,0x3da);
wait_vertical(mv0,0x3da);
ReadTimer(start);
loop_vertical(mv, 0x3da, 200);
ReadTimer(stop);
enable();
diff = stop-start;
if (diff < 0) diff += 65536L;
return 200/(TickTime*((double)diff));
}
#define ASK_CONT 0
#define ASK_SKIP 1
#define ASK_ALL 2
int ask(char *expl)
{
int ch;
cprintf("\r\n\n"
"赏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯突\r\n"
"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -