202 lines
4.7 KiB
C
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");
|
|
}
|