Video and other misc. routines for in-line Assembly. These are especially
handy because you can just cut-and-paste them between languages on the PC;
I developed/rounded up many of these when I was programming in Pascal, and
when I turned to C, they were easily ported.
To use the virtual screens, declare global pointers like this:
unsigned char far *VS1 = NULL; // pointer to virtual screen.
Then from main(), allocate the memory for them like this:
VS1 = new far unsigned char[64000];
You can then access it like an array, and use Buffer_Paste(VS1) to paste it
to the screen and Buffer_Clear(VS1) to clear it.
Sorry about putpixel() and getpixel() - they're extremely sloppily-written -
but I never use them anymore, and if you need speed, don't look to making
function calls anyway!
//These macros will be needed for the palette functions.
#define COLOR_MASK 0x3C6 // the bit mask register
#define COLOR_REGISTER_RD 0x3C7 // set read index at this I/O
#define COLOR_REGISTER_WR 0x3C8 // set write index at this I/O
#define COLOR_DATA 0x3C9 // the R/W data is here
void set13()
{
asm
{
mov ax, 0013h; // set video mode
int 10h; // to 320x200x256
}
}
void settext()
{
asm
{
mov ax, 0003h;
int 10h;
}
}
void wait_refresh() // (...this one I stole from the web)
{
asm
{
mov dx,3dah //wait for vertical retrace
NoVrt:
in al,dx
test al,8 //Test 3rd bit again
jz NoVrt //Wait until Verticle Retrace ends
}
}
void putpixel(int x, int y, unsigned char c)
{
asm
{
mov bx, 40960
mov ax, 320
mul y
add ax, x
mov di, ax
mov es, bx
mov al, c
stosb // moves al to es:di
}
}
unsigned char getpixel(int x, int y)
{
unsigned char c;
asm
{
push ds
mov cx, y
mov ax, 40960
mov bx, cx
mov ds, ax
shl bx, 2
add bx, cx
shl bx, 6
add bx, x
mov si, bx
lodsb // moves [ds:si] to al
mov c, al
pop ds
}
return c;
}
unsigned char getsubpixel(unsigned char far *buffer, float x, float y)
{
int x2, y2;
static float dx, dy, dx_invert, dy_invert, e;
unsigned char a, b, c, d;
x2 = x;
y2 = y;
dx = x - (float)x2; // 0..1
dy = y - (float)y2; // 0..1
dx_invert = 1-dx;
dy_invert = 1-dy;
asm
{
push ds
lds si, buffer
mov ax, 320
mul y2
add ax, x2
mov si, ax
add si, 4 ;// crackhead patch alert!
lodsb // moves [ds:si] to al (1 byte) & inc. si
mov a, al
lodsb // moves [ds:si] to al
mov b, al
add si, 318
lodsb // moves [ds:si] to al
mov c, al
lodsb // moves [ds:si] to al
mov d, al
pop ds
}
e = a*dx_invert*dy_invert;
e += c*dx_invert*dy;
e += b*dy_invert*dx;
e += d*dx*dy;
return (unsigned char)e;
}
void setRGB(unsigned char co,unsigned char r,unsigned char g,unsigned char b)
{
asm
{
mov al, co
mov dx, COLOR_REGISTER_WR
cli // disable interrupts
out dx, al
mov dx, COLOR_DATA
mov al, r
out dx, al
mov al, g
out dx, al
mov al, b
out dx, al
sti // re-enable interrupts
}
//outp(COLOR_REGISTER_WR, co);
//outp(COLOR_DATA, r);
//outp(COLOR_DATA, g);
//outp(COLOR_DATA, b);
}
void getRGB(unsigned char co,unsigned char *r,unsigned char *g,unsigned char *b)
{
asm
{
mov al, co
mov dx, COLOR_REGISTER_RD
cli
out dx, al
mov dx, COLOR_DATA
in al, dx
mov bx, r
mov [bx], al // if this won't compile use BYTE PTR [bx].
in al, dx
mov bx, g
mov [bx], al
in al, dx
mov bx, b
mov [bx], al
sti
}
//outp(COLOR_REGISTER_RD, co);
//outp(COLOR_DATA, *r);
//outp(COLOR_DATA, *g);
//outp(COLOR_DATA, *b);
}
void Buffer_Paste(unsigned char far *buffer)
{
asm // "rep movsd" moves ecx dwords from ds:si to es:di
{
push ds;
mov ax, 40960;
mov di, 0; // es:di is the dest of memory to move to
mov ecx, 16000; // size of buffer in DWORDS (# of reps)
mov es, ax;
lds si, buffer; // ds:si is the source
rep movsd; // move 16000 dwords (64000 bytes)
pop ds;
}
}
void Buffer_Clear(unsigned char far *buffer)
{
asm // "rep movsd" moves ecx dwords from ds:si to es:di
{
push ds;
mov ecx, 16000; // size of buffer in DWORDS (# of reps)
mov eax, 0;
les di, buffer; // es:di is the dest
rep stosd; // move 16000 dwords (64000 bytes)
pop ds;
}
}
void Buffer_Copy(unsigned char far *buffer1, unsigned char far *buffer2)
{ // copies second buffer to first buffer.
asm // "rep movsd" moves ecx dwords from ds:si to es:di
{
push ds;
mov ecx, 16000; // size of buffer in DWORDS (# of reps)
les di, buffer1; // es:di is the dest
lds si, buffer2; // ds:si is the source
rep movsd; // move 16000 dwords (64000 bytes)
pop ds;
}
}
void waitkey()
{
asm
{
mov ah, 1 //DOS: get a character (puts it in AL)
int 21h
}
}
This document copyright (c)1998+ Ryan M. Geiss.
Return to FAQ page