Initial. Don't... just don't ask.

This commit is contained in:
Ryan McGrath 2011-02-24 00:22:00 -08:00
commit 00bae13bba
586 changed files with 129057 additions and 0 deletions

23
obsolete/support/0-README Normal file
View file

@ -0,0 +1,23 @@
This contains the source for a Borland C++ program that allows you to dump
the register contents for any BIOS video mode. 'vga.exe' should work with
any VGA/SVGA adapter. It takes a hexadecimal mode number as argument and
writes the (VGA) register contents to the console.
These printout can be used to write a new driver. Please read also 'man 7
svgalib.et4000' about the tseng3.exe program.
trap-out.asm / .com is a DOS program which traces all I/O calls made when a
given video mode is set by the BIOS. It was used for the TVGA driver and should
be useful for other drivers too, esp. if no documentation is available.
It spits out a long list of "T DX/I AX/L" strings where T is "I" for IN or
"O" for OUT, DX/I is the value of DX or the immediate given value for
ports <256, and AX/L is the value of AX or AL before the call to IN or OUT
(yeah, the value of AX is pretty worthless before a call to IN, but oh
well)
This output is very very easily parsed into a simple C routine that calls
port_in and port_out many many times, but will set the same mode the BIOS
did.
The trap-out program is courtesy of Ryan Rubley <rubleyr@river.it.gvsu.edu>

View file

@ -0,0 +1,344 @@
; TRAPOUT2.ASM v2.0 by ARK (ark@lhq.com, root@ark.dyn.ml.org) 11-28-97
; Traps IN and OUT instructions in INT 10h and displays DX and AX/AL values.
;
; In the header "T DX/I AX/L", T is the Type of instruction (I=IN, O=OUT),
; DX/I is the value of DX or the Immediate value if port<256, and AX/L
; is the value of AX or AL depending on if an 8 or 16 bit value is listed.
; AX/L is meaningless for IN's since it is the value if AX/L *before* the
; call to IN.
;
; This is very useful to find information about how your video card works.
; I wrote this to get register dumps for my Trident TVGA9440AGi card so
; that I could use it under Linux.
;
; NOTE: Pipe the output or you won't see anything!
; (ex: TRAP-OUT 4F02 0101 > 640x480.256)
;
; New in v2.0:
; * Traces into INT 10 calls that are called from inside INT 10!
; * Allows AX and BX values to be specified!
; * Command line accepts trailing spaces now.
; x Code to trap INT's also! (T column='N', DX/I=INT ##, AX/L=AX value)
; (Its commented out - but you can recompile with it if you want)
;
; How to assemble with Borland:
; tasm /ml /zd ncr.asm (case sensitive, line number debug info only)
; tlink /x /t ncr.obj (no map, make com file)
;
.model tiny ; Tiny memory model, all segments point to the same 64K
.286 ; This code will run on a 286... actually, it
.code ; Everything is in the code segment(cs) will probably
.startup ; Startup run on anything
jmp Start ; Go to beginning of progam
realINT1 dd 52411A3Eh ; Address of original INT 01h routine offset
realINT10 dd 3C1B214Bh ; Memory for [es:bx] of the real INT 10h
; (defaults are '>-ARK!-<' just for looks in the .COM)
; strings
no_command_line db 'Use: TRAPOUT2 [AX] [BX]',13,10
db ' Traces all IN/OUT calls inside INT 10h',13,10,36
tracing db 'Tracing INT 10h with AX:',36
bx_msg db ' BX:',36
header db 13,10,'T DX/I AX/L',13,10,36
INT1 proc ; Interrupt Service Routine for Single Step Debugging
push ax ; save registers
push dx
push es
push di
push bp
mov bp,sp ; set bp to the stack
push word ptr cs:[bp+12] ; put the real cs
pop es ; into es
push word ptr cs:[bp+10] ; put the real ip
pop di ; into di
mov al,byte ptr es:[di] ; set al to the next instruction that will
; be executed after this INT 01 is done.
; This code will trap INT's also...
; cmp al,0CDh ; If al is not CD (INT) keep going
; jne not_int ; If it is, display some stuff...
;; This will skip doing the INT's...
;; add word ptr cs:[bp+10],2 ; Add 2 to the real ip, to skip the INT
; mov dl,4Eh ; Display an N
; mov ah,02h ; The immediate value/DX is the INT ##
; int 21h ; that is called. AX is the value before
; mov dl,20h ; Display a space
; mov ah,02h ;
; int 21h ; Display the immediate value which is
; jmp is_imm ; reallly the interrupt number called.
not_int:
and al,0F4h ; If al is E4-E7 or EC-EF (all IN/OUT's)
cmp al,0E4h ; Then we display our stuff
jne not_io ; Otherwise, do nothing
; note: 1 more byte of code after this
; jmp will make it out of range...
mov al,byte ptr es:[di] ; Set al to next instruction
test al,02h ; If bit 1 is set then we have an OUT
jz is_in ; If bit 1 is 0, we have an IN
mov dl,4Fh ; Display an O
mov ah,02h
int 21h
jmp dx_or_imd
is_in: ; Display an I
mov dl,49h
mov ah,02h
int 21h
dx_or_imd: ; Display a space
mov dl,20h
mov ah,02h
int 21h
mov al,byte ptr es:[di] ; Set al to next instruction
test al,08h ; If bit 3 is set then we are using DX
jz is_imm ; If bit 3 is 0, we are using an immediate
mov ax,[bp+6] ; restore dx to ax
call ShowHex ; Display dx
call ShowHex
call ShowHex
call ShowHex
jmp ax_or_al
is_imm:
mov dl,20h ; Display 2 spaces
mov ah,02h
int 21h
mov dl,20h
mov ah,02h
int 21h
mov ah,byte ptr es:[di+1] ; Set ah to byte after the next instruction
call ShowHex ; Display the immediate value
call ShowHex
ax_or_al:
mov dl,2Ch ; Display a comma
mov ah,02h
int 21h
mov al,byte ptr es:[di] ; Set al to next instruction
test al,01h ; If bit 0 is set then we are using AX
jz is_al ; If bit 0 is 0, we are using AL
mov ax,[bp+8] ; Restore ax
call ShowHex ; Display ax
call ShowHex
call ShowHex
call ShowHex
jmp print_next_line
is_al:
mov ah,[bp+8] ; Restore al to ah
call ShowHex ; Display al
call ShowHex
print_next_line:
mov dl,0Dh ; print a newline
mov ah,02h
int 21h
mov dl,0Ah
mov ah,02h
int 21h
not_io:
pop bp ; restore registers
pop di
pop es
pop dx
pop ax
iret ; end interrupt
INT1 endp
; INT 10h that fakes the real INT 10 and sets the trap flag.
INT10 proc ; Interrupt Service Routine for Tracing INT 10h
push ax ; Save AX
pushf ; Put flags on the stack
pop ax ; Then into AX
or ax,0100h ; Set the trap flag
push ax ; Trap Flag calls INT 01h between every instruction
popf ; Stuff new flags back into the flags register
pop ax ; Restore AX
cli ; Fake INT call: clear interrupt flag, skip clearing
pushf ; trap flag, push flags, call to location.
call cs:[realINT10] ; This call to INT 10h is be trapped for
; IN/OUT/INT Normal INT calls would clear
; the trap flag and then INT 01h would never
; be called.
iret ; end interrupt
INT10 endp
; function that prints the highest 4 bits of ax as text {0-9,A-F} to stdout
; ax will be shifted left 4 bits on return.
ShowHex proc
push ax ; save registers
push dx
shr ax,0Ch ; move the highest 4 bits to the lowest 4
and al,0Fh ; limit to lowest 4 bits
or al,30h ; change range to 30h-3Fh {0-9:;<=>?}
cmp al,39h ; if it is 30h-39h
jbe is_0_thru_9 ; then its already set
add al,07h ; otherwise change :;<=>? to A-F
is_0_thru_9:
mov dl,al
mov ah,02h
int 21h
pop dx ; restore dx
pop ax ; restore ax
shl ax,4 ; set up ax for next call
ret ; return
ShowHex endp
Start: ; Program begins here
mov si,0080h ; CS:0080h is the command line
cmp byte ptr [si],10 ; I want it to be at least 10 bytes long
jae process_command_line ; if not, abort
mov dx,offset no_command_line ; ds is preset
mov ah,09h ; Dos function 09h
int 21h ; Display no command line string
ret ; Exit program
process_command_line:
inc si ; move si to start of actual string
mov ax,[si+1] ; copy first 2 chrs to ax, skipping the space
mov bx,[si+3] ; copy 2nd two characters to bx
sub al,30h ; subtract 30h so chrs 0-9 have value 0-9
cmp al,09h ; if its 0-9, its ok.
jbe al_is_ok ; if its not, its probably A-F or a-f
sub al,07h ; so subtract 7 more
and al,0Fh ; and limit to 0-F
al_is_ok:
sub ah,30h ; do the same to ah
cmp ah,09h
jbe ah_is_ok
sub ah,07h
and ah,0Fh
ah_is_ok:
sub bl,30h ; do the same to bl
cmp bl,09h
jbe bl_is_ok
sub bl,07h
and bl,0Fh
bl_is_ok:
sub bh,30h ; do the same to bh
cmp bh,09h
jbe bh_is_ok
sub bh,07h
and bh,0Fh
bh_is_ok:
shl al,04h ; Combine the values so that AL-AH-BL-BH
or ah,al ; Goes into --AH- --AL-
mov al,bl ; <----AX--->
shl al,04h
or al,bh
mov word ptr [si],ax ; store the value over the string
mov ax,[si+6] ; copy 3rd 2 chrs to ax, skip the 2nd space
mov bx,[si+8] ; copy 4th two characters to bx
sub al,30h ; subtract 30h so chrs 0-9 have value 0-9
cmp al,09h ; if its 0-9, its ok.
jbe al_is_ok2 ; if its not, its probably A-F or a-f
sub al,07h ; so subtract 7 more
and al,0Fh ; and limit to 0-F
al_is_ok2:
sub ah,30h ; do the same to ah
cmp ah,09h
jbe ah_is_ok2
sub ah,07h
and ah,0Fh
ah_is_ok2:
sub bl,30h ; do the same to bl
cmp bl,09h
jbe bl_is_ok2
sub bl,07h
and bl,0Fh
bl_is_ok2:
sub bh,30h ; do the same to bh
cmp bh,09h
jbe bh_is_ok2
sub bh,07h
and bh,0Fh
bh_is_ok2:
shl al,04h ; Combine the values so that AL-AH-BL-BH
or ah,al ; Goes into --AH- --AL-
mov al,bl ; <----AX--->
shl al,04h
or al,bh
mov word ptr [si+2],ax ; store the value over the string
; Now [si] contains the real values of AX and BX
mov dx,offset tracing ; ds is preset
mov ah,09h ; Dos function 09h
int 21h ; Display tracing string
mov ax,word ptr [si] ; Restore ax
call ShowHex ; Display command line
call ShowHex ; ax value back to user
call ShowHex ; by placing it in ax
call ShowHex ; and calling ShowHex
mov dx,offset bx_msg ; ds is preset
mov ah,09h ; Dos function 09h
int 21h ; Display bx message
mov ax,word ptr [si+2] ; Restore bx into ax
call ShowHex ; Display command line
call ShowHex ; bx value back to user
call ShowHex ; by placing it in ax
call ShowHex ; and calling ShowHex
mov dx,offset header ; ds is preset
mov ah,09h ; Dos function 09h
int 21h ; Display header to output
mov ax,3501h ; Dos function 35h, Get vector of INT 01h
int 21h ; Store it in es:bx
mov word ptr [realINT1],bx ; Store address of original INT 01h
mov word ptr [realINT1+2],es ; into realINT1
mov ax,3510h ; Dos function 35h, Get vector of INT 10h
int 21h ; Store it in es:bx
mov word ptr [realINT10],bx ; Store address of original INT 10h
mov word ptr [realINT10+2],es ; into realINT10 so we can fake an INT
mov ax,2501h ; Dos function 25h, Store DS:DX to INT 01h
mov dx,offset INT1 ; ds is preset, dx is the handler's offset
int 21h ; Set new Single Step handler
mov ax,2510h ; Dos function 25h, Store DS:DX to INT 10h
mov dx,offset INT10 ; ds is preset, dx is the handler's offset
int 21h ; Set new Video Interrupt
mov ax,word ptr [si] ; We will use the command line ax/bx
mov bx,word ptr [si+2] ; values for the fake int call
int 10h ; Call my int 10 which fakes the
; real int 10 and traps it.
mov ax,2501h ; Dos function 25h, Store DS:DX to INT 01h
mov dx,word ptr [realINT1] ; ds/dx are in realINT1
push ds ; Save old ds
push word ptr [realINT1+2] ; Put segment on stack
pop ds ; Set ds to the segment
int 21h ; Reset old Single Step handler
pop ds ; Restore old ds
mov ax,2510h ; Dos function 25h, Store DS:DX to INT 10h
mov dx,word ptr [realINT10] ; ds/dx are in realINT10
push ds ; Save old ds
push word ptr [realINT10+2] ; Put segment on stack
pop ds ; Set ds to the segment
int 21h ; Reset old Video Interrupt
pop ds ; Restore old ds
mov ax,0003h ; Set ax to 3
int 10h ; Set 80x25 Text mode
ret ; End of program
end ; End of file

Binary file not shown.

146
obsolete/support/vga.c Normal file
View file

@ -0,0 +1,146 @@
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
/* January 1995, Scott Heavner (sdh@po.cwru.edu)
* Changes to allow anyone to compile vga.c under the go32 Linux->dos cross compiler.
* It should also work with DJGPP (the gcc port to msdos). The cross compiler is
* available at ftp://sunsite.unc.edu/pub/Linux/devel/msdos/go32crs.tar.gz.
*
* I compiled it with:
*
* go32gcc vga.c -lpc
* cat /usr/local/go32/bin/go32.exe a.out > vga.exe
*/
#ifdef GO32
#include <pc.h>
#endif
/* 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 */
/* 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 END MIS+MIS_C /* last */
unsigned char vga_regs[60];
#ifdef GO32
#define port_out(v,p) outportb(p,v)
#define port_in(p) inportb(p)
#else
void port_out(unsigned char value, unsigned short port)
{
asm
{
mov dx, port
mov al, value
out dx, al
}
} unsigned char port_in(unsigned short port)
{
asm
{
mov dx, port
in al, dx
} return (_AL);
}
#endif
main(int argc, char *argv[])
{
union REGS cpu_regs;
int i;
unsigned char mode;
if (argc != 2) {
printf("Usage: getregs mode (mode must be hexadecimal)\n");
exit(-1);
}
if (!sscanf(argv[1], "%x", &mode)) {
printf("Usage: getregs mode (mode must be hexadecimal)\n");
exit(-1);
}
cpu_regs.h.ah = 0x00;
cpu_regs.h.al = mode;
int86(0x10, &cpu_regs, &cpu_regs);
/* get VGA register values */
for (i = 0; i < CRT_C; i++) {
port_out(i, CRT_I);
vga_regs[CRT + i] = port_in(CRT_D);
}
for (i = 0; i < ATT_C; i++) {
port_in(IS1_R);
port_out(i, ATT_IW);
vga_regs[ATT + i] = port_in(ATT_R);
}
for (i = 0; i < GRA_C; i++) {
port_out(i, GRA_I);
vga_regs[GRA + i] = port_in(GRA_D);
}
for (i = 0; i < SEQ_C; i++) {
port_out(i, SEQ_I);
vga_regs[SEQ + i] = port_in(SEQ_D);
}
vga_regs[MIS] = port_in(MIS_R);
cpu_regs.h.ah = 0x00;
cpu_regs.h.al = 0x03;
int86(0x10, &cpu_regs, &cpu_regs);
printf("/* BIOS mode 0x%02X */\n", mode);
printf("static char regs[60] = {\n ");
for (i = 0; i < 12; i++)
printf("0x%02X,", vga_regs[CRT + i]);
printf("\n ");
for (i = 12; i < CRT_C; i++)
printf("0x%02X,", vga_regs[CRT + i]);
printf("\n ");
for (i = 0; i < 12; i++)
printf("0x%02X,", vga_regs[ATT + i]);
printf("\n ");
for (i = 12; i < ATT_C; i++)
printf("0x%02X,", vga_regs[ATT + i]);
printf("\n ");
for (i = 0; i < GRA_C; i++)
printf("0x%02X,", vga_regs[GRA + i]);
printf("\n ");
for (i = 0; i < SEQ_C; i++)
printf("0x%02X,", vga_regs[SEQ + i]);
printf("\n ");
printf("0x%02X", vga_regs[MIS]);
printf("\n};\n");
}