FreeBE/tgui/vga.h

202 lines
4.7 KiB
C

/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/* (I don't take care about mono by now) */
/* VGA Atttibute controller */
#define ATTindex 0x3C0
#define ATTdataW 0x3C0
#define ATTdataR 0x3C1
#define ATTdir 0x3DA
/* Miscellaneous Output Register */
#define MORdataW 0x3C2
#define MORdataR 0x3CC
/* VGA Sequencer Registers */
#define Sequencer 0x3C4
#define SequencerIndex 0x3C4
#define SequencerData 0x3C5
/* VGA Palette Registers */
#define ReadDataAddress 0x3C7
#define WriteDataAddress 0x3C8
#define PaletteDataRegister 0x3C9
/* VGA Graphics Controller Registers */
#define GraphicsController 0x3CE
#define GraphicsControllerIndex 0x3CE
#define GraphicsControllerData 0x3CF
/* VGA CRT Controller Register */
#define CRTController 0x3D4
#define CRTControllerIndex 0x3D4
#define CRTControllerData 0x3D5
/* VGA Input Status Register 1 */
#define InputStatusRegister1 0x3DA
/* Trident's DAC/Clock */
#define EDACindex 0x83C8
#define EDACdata 0x83C6
//#define SAFE_IO
#ifdef SAFE_IO
/* C approach, safier than my assembler ;-) */
extern inline uchar ReadCRT(uchar index) {
outportb(CRTControllerIndex, index);
return inportb(CRTControllerData);
}
extern inline uchar ReadGRA(uchar index) {
outportb(GraphicsControllerIndex, index);
return inportb(GraphicsControllerData);
}
extern inline uchar ReadSEQ(uchar index) {
outportb(SequencerIndex, index);
return inportb(SequencerData);
}
extern inline void WriteCRT(uchar index, uchar value) {
outportb(CRTControllerIndex, index);
outportb(CRTControllerData, value);
}
extern inline void WriteGRA(uchar index, uchar value) {
outportb(GraphicsControllerIndex, index);
outportb(GraphicsControllerData, value);
}
extern inline void WriteSEQ(uchar index, uchar value) {
outportb(SequencerIndex, index);
outportb(SequencerData, value);
}
extern inline void WaitVRT( ) {
while (inportb(InputStatusRegister1) & 8)
;
while (!(inportb(InputStatusRegister1) & 8))
;
}
#else
/*
Assembler stuff: It is normally more compact and in some cases faster. As
the functions are inline I think size is important.
They save 524 bytes in the driver (1.89%).
*/
extern inline uchar ReadCRT(uchar index) {
uchar a asm("%eax");
a = index;
asm volatile ("
outb %%al,%%dx
incl %%edx
inb %%dx,%%al
" : "a=" (a) : "a" (a), "d" (CRTController) : "%edx");
return a;
}
extern inline uchar ReadGRA(uchar index) {
uchar a asm("%eax");
a = index;
asm volatile ("
outb %%al,%%dx
incl %%edx
inb %%dx,%%al
" : "a=" (a) : "a" (a), "d" (GraphicsController) : "%edx");
return a;
}
extern inline uchar ReadSEQ(uchar index) {
uchar a asm("%eax");
a = index;
asm volatile ("
outb %%al,%%dx
incl %%edx
inb %%dx,%%al
" : "a=" (a) : "a" (a), "d" (Sequencer) : "%edx");
return a;
}
extern inline void WriteCRT(uchar index, uchar value) {
asm volatile ("
movb %0,%%ah
outw %%ax,%%dx
" : : "qi" (value), "a" (index), "d" (CRTController) : "%eax");
}
extern inline void WriteGRA(uchar index, uchar value) {
asm volatile ("
movb %0,%%ah
outw %%ax,%%dx
" : : "qi" (value), "a" (index), "d" (GraphicsController) : "%eax");
}
extern inline void WriteSEQ(uchar index, uchar value) {
asm volatile ("
movb %0,%%ah
outw %%ax,%%dx
" : : "qi" (value), "a" (index), "d" (Sequencer) : "%eax");
}
extern inline void WaitVRT( ) {
asm("
1:
inb %%dx,%%al
testb $8,%%al
jne 1b
.align 2,0x90
2:
inb %%dx,%%al
testb $8,%%al
je 2b
" : : "d" (InputStatusRegister1) : "%eax" );
}
#endif
extern inline uchar ReadATT(int index) {
/* Ensure we will write to the index */
inportb(ATTdir);
/* Set the index and disable the screen or we will read nothing */
outportb(ATTindex, index);
return inportb(ATTdataR);
}
extern inline void ATTEndReads(void) {
/* Ensure we will write to the index */
inportb(ATTdir);
/* Enable the screen */
outportb(ATTindex, 0x20);
}
extern inline void WriteATT(int index, int val) {
outportb(ATTindex, index);
outportb(ATTdataW, val);
}
extern inline uchar ReadMOR(void) {
return inportb(MORdataR);
}
extern inline void WriteMOR(int val) {
outportb(MORdataW, val);
}
extern inline uchar ReadEDAC(int index) {
outportb(EDACindex, index);
return inportb(EDACdata);
}
extern inline void WriteEDAC(int index, int val) {
outportb(EDACindex, index);
outportb(EDACdata, val);
}
extern inline void RPF_SetPalRange(unsigned char *_pal_ptr, int color,
int cant) {
__asm__("
outb %
% al,
% % dx incl % % edx cli rep outsb sti "
:
: "c"(cant * 3), "S"(_pal_ptr), "a"(color), "d"(0x3C8)
: "%eax", "%ecx", "%edx", "%esi");
}