2007-04-02 15:20:55 +02:00
|
|
|
|
#include "vga.h"
|
|
|
|
|
#include "memory.h"
|
|
|
|
|
#include "asm.h"
|
2007-04-02 15:43:32 +02:00
|
|
|
|
#include "types.h"
|
2018-08-17 16:46:56 +02:00
|
|
|
|
#include "VGA/modes.c"
|
|
|
|
|
#include "VGA/8x8fnt.c"
|
|
|
|
|
#include "VGA/8x16fnt.c"
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
|
|
|
|
/* Registres VGAs */
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2007-04-02 15:20:55 +02:00
|
|
|
|
#define sequencer 0x3c4
|
|
|
|
|
#define misc 0x3c2
|
|
|
|
|
#define ccrt 0x3D4
|
|
|
|
|
#define attribs 0x3c0
|
|
|
|
|
#define graphics 0x3ce
|
|
|
|
|
#define state 0x3da
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Taille d'un plan de bit */
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2007-04-02 15:20:55 +02:00
|
|
|
|
#define planesize 0x10000
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
static u16 resX, resY, color, splitY; /* resolution x,y en caract<63>res et profondeur */
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
static u8 pages, activepage, showedpage; /* nombre de pages disponibles N<> de la page active */
|
|
|
|
|
static u32 linesize, pagesize; /* Taille d'une ligne et d'une page */
|
|
|
|
|
static u8 vmode = 0xFF; /* mode en cours d'utilisation */
|
|
|
|
|
static u32 basemem; /* Adresse de la m<>moire vid<69>o */
|
|
|
|
|
static bool scrolling, graphic, blink; /* Activation du d<>filement, Flag du mode graphique */
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Donne la resolution max horizontale */
|
|
|
|
|
|
|
|
|
|
u16 getxres()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
return resX;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Donne la profondeur en bit */
|
|
|
|
|
|
|
|
|
|
u8 getdepth()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
return color;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Donne la resolution max verticale */
|
|
|
|
|
|
|
|
|
|
u16 getyres()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
return resY - splitY;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Donne le nombre max de page ecran dispo */
|
|
|
|
|
|
|
|
|
|
u16 getnbpages()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
return pages;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Fixe la page ecran de travail */
|
|
|
|
|
|
|
|
|
|
void setpage(u8 page)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (page < pages)
|
|
|
|
|
activepage = page;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Recupere la page ecran de travail */
|
|
|
|
|
|
|
|
|
|
u8 getpage()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
return activepage;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Affiche la page ecran specifi<66> */
|
|
|
|
|
|
|
|
|
|
void showpage(u8 page)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (page < pages) {
|
|
|
|
|
u16 addr;
|
|
|
|
|
addr = page * pagesize / 2;
|
|
|
|
|
outb(ccrt, 0x0C);
|
|
|
|
|
outb(ccrt + 1, (addr >> 8));
|
|
|
|
|
outb(ccrt, 0x0D);
|
|
|
|
|
outb(ccrt + 1, (addr & 0xFF));
|
|
|
|
|
showedpage = page;
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
2018-08-17 16:46:56 +02:00
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* S<>pare l'<27>cran en 2 a partir de la ligne Y */
|
|
|
|
|
|
|
|
|
|
void split(u16 y)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u16 addr;
|
|
|
|
|
if (graphic == 0)
|
|
|
|
|
addr = (y << 3);
|
|
|
|
|
else
|
|
|
|
|
addr = y;
|
|
|
|
|
/* line compare pour ligne atteinte */
|
|
|
|
|
outb(ccrt, 0x18);
|
|
|
|
|
outb(ccrt + 1, (addr & 0xFF));
|
|
|
|
|
/* overflow pour le bit 8 */
|
|
|
|
|
|
|
|
|
|
outb(ccrt, 0x07);
|
|
|
|
|
outb(ccrt + 1, (inb(ccrt + 1) & ~16) | ((addr >> 4) & 16));
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Maximum Scan Line pour le bit 9 */
|
|
|
|
|
|
|
|
|
|
outb(ccrt, 0x09);
|
|
|
|
|
outb(ccrt + 1, (inb(ccrt + 1) & ~64) | ((addr >> 3) & 64));
|
|
|
|
|
splitY = y;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
2018-08-17 16:46:56 +02:00
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* S<>pare l'<27>cran en 2 a partir de la ligne Y */
|
|
|
|
|
|
|
|
|
|
void unsplit()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* line compare pour ligne atteinte */
|
|
|
|
|
outb(ccrt, 0x18);
|
|
|
|
|
outb(ccrt + 1, 0);
|
|
|
|
|
/* overflow pour le bit 8 */
|
|
|
|
|
|
|
|
|
|
outb(ccrt, 0x07);
|
|
|
|
|
outb(ccrt + 1, inb(ccrt + 1) & ~16);
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Maximum Scan Line pour le bit 9 */
|
|
|
|
|
|
|
|
|
|
outb(ccrt, 0x09);
|
|
|
|
|
outb(ccrt + 1, inb(ccrt + 1) & ~64);
|
|
|
|
|
splitY = 0;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Attend la retrace verticale */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void waitvretrace(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
while ((inb(state) & 8) == 0) ;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Attend la retrace horizontale */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void waithretrace(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
while ((inb(state) & 1) == 0) ;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Active l'affichage du curseur de texte */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void enablecursor(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
|
|
|
|
u8 curs;
|
|
|
|
|
/* active le curseur hardware */
|
|
|
|
|
outb(ccrt, 10);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
curs = inb(ccrt + 1) & ~32;
|
|
|
|
|
outb(ccrt + 1, curs);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Desactive l'affichage du curseur de texte */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void disablecursor(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
|
|
|
|
u8 curs;
|
2007-04-02 15:43:32 +02:00
|
|
|
|
/* Desactive le curseur hardware */
|
2007-04-02 15:20:55 +02:00
|
|
|
|
outb(ccrt, 10);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
curs = inb(ccrt + 1) | 32;
|
|
|
|
|
outb(ccrt + 1, curs);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Active le scrolling en cas de d<>bordement d'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void enablescroll(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
scrolling = true;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Desactive le scrolling en cas de d<>bordement d'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void disablescroll(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
scrolling = false;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Utilise le plan de bit sp<73>cifi<66> */
|
|
|
|
|
|
|
|
|
|
void useplane(u8 plan)
|
|
|
|
|
{
|
|
|
|
|
u8 mask;
|
|
|
|
|
plan &= 3;
|
|
|
|
|
mask = 1 << plan;
|
|
|
|
|
/* choisi le plan de lecture */
|
|
|
|
|
outb(graphics, 4);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(graphics + 1, plan);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* choisi le plan d'ecriture */
|
|
|
|
|
outb(sequencer, 2);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(sequencer + 1, mask);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Renvoie l'adresse du segment video */
|
|
|
|
|
|
|
|
|
|
u32 getbase(void)
|
|
|
|
|
{
|
|
|
|
|
u32 base;
|
|
|
|
|
outb(graphics, 6);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
base = inb(graphics + 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
base >>= 2;
|
|
|
|
|
base &= 3;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
switch (base) {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
base = 0xA0000;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
base = 0xB0000;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
base = 0xB8000;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* efface l'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void (*fill) (u8 attrib);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void fill_text(u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize), ' ', pagesize / 2, 2);
|
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize + 1), attrib,
|
|
|
|
|
pagesize / 2, 2);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void fill_chain(u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize), attrib & 0x0F,
|
|
|
|
|
pagesize, 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void fill_unchain(u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
|
|
|
|
int i;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
for (i = 0; i < 4; i++) {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
useplane(i);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize), attrib & 0x0F,
|
|
|
|
|
pagesize, 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* fixe la position du curseur texte */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void gotoscr(u16 x, u16 y)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
|
|
|
|
u16 pos;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (splitY == 0)
|
|
|
|
|
pos = (showedpage * pagesize / 2 + x + y * resX);
|
|
|
|
|
else
|
|
|
|
|
pos = (x + y * resX);
|
|
|
|
|
outb(ccrt, 0x0F);
|
|
|
|
|
outb(ccrt + 1, (u8) (pos & 0x00FF));
|
|
|
|
|
outb(ccrt, 0x0E);
|
|
|
|
|
outb(ccrt + 1, (u8) ((pos & 0xFF00) >> 8));
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Fait defiler l'ecran de n lignes vers le haut */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void (*scroll) (u8 lines, u8 attrib);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void scroll_unchain(u8 lines, u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (scrolling) {
|
|
|
|
|
u8 i;
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
|
useplane(i);
|
|
|
|
|
memcpy((u8 *) (basemem + activepage * pagesize +
|
|
|
|
|
linesize * 8 * lines), (u8 *) basemem,
|
|
|
|
|
pagesize - linesize * 8 * lines, 1);
|
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize +
|
|
|
|
|
pagesize - linesize * 8 * lines),
|
|
|
|
|
attrib & 0x0F, linesize * 8 * lines, 1);
|
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void scroll_chain(u8 lines, u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (scrolling) {
|
|
|
|
|
memcpy((u8 *) basemem + activepage * pagesize +
|
|
|
|
|
linesize * 8 * lines,
|
|
|
|
|
(u8 *) basemem + activepage * pagesize,
|
|
|
|
|
pagesize - linesize * 8 * lines, 1);
|
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize + pagesize -
|
|
|
|
|
linesize * 8 * lines), attrib & 0x0F,
|
|
|
|
|
linesize * 8 * lines, 1);
|
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void scroll_text(u8 lines, u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (scrolling) {
|
|
|
|
|
memcpy((u8 *) basemem + activepage * pagesize +
|
|
|
|
|
linesize * lines, (u8 *) basemem + activepage * pagesize,
|
|
|
|
|
pagesize - linesize * lines, 1);
|
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize + pagesize -
|
|
|
|
|
linesize * lines - 2), ' ',
|
|
|
|
|
(linesize * lines) / 2, 2);
|
|
|
|
|
memset((u8 *) (basemem + activepage * pagesize + pagesize -
|
|
|
|
|
linesize * lines - 1), attrib,
|
|
|
|
|
(linesize * lines) / 2, 2);
|
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Affiche le caract<63>re a l'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void (*showchar) (u16 coordx, u16 coordy, u8 thechar, u8 attrib);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void showchar_graphic(u16 coordx, u16 coordy, u8 thechar, u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 x, y, pattern, set;
|
|
|
|
|
for (y = 0; y < 8; y++) {
|
|
|
|
|
pattern = font8x8[thechar * 8 + y];
|
|
|
|
|
for (x = 0; x < 8; x++) {
|
|
|
|
|
set = ((pattern >> (7 - x)) & 0x1); /* mettre un ROL import<72> depuis asm */
|
|
|
|
|
if (set == 0)
|
|
|
|
|
writepxl(coordx * 8 + x, coordy * 8 + y,
|
|
|
|
|
((attrib & 0xF0) >> 8) * set);
|
2007-04-02 15:43:32 +02:00
|
|
|
|
else
|
2018-08-17 16:46:56 +02:00
|
|
|
|
writepxl(coordx * 8 + x, coordy * 8 + y,
|
|
|
|
|
(attrib & 0x0F) * set);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void showchar_text(u16 coordx, u16 coordy, u8 thechar, u8 attrib)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *screen;
|
|
|
|
|
screen =
|
|
|
|
|
(u8 *) basemem + activepage * pagesize + 2 * (coordx +
|
|
|
|
|
coordy * resX);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
*screen = thechar;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
*(++screen) = attrib;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Recupere le caract<63>re a l'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8(*getchar) (u16 coordx, u16 coordy);
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 getchar_text(u16 coordx, u16 coordy)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *screen;
|
|
|
|
|
screen =
|
|
|
|
|
(u8 *) basemem + activepage * pagesize + 2 * (coordx +
|
|
|
|
|
coordy * resX);
|
2007-04-02 16:12:33 +02:00
|
|
|
|
return *screen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Recupere les attributs a l'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8(*getattrib) (u16 coordx, u16 coordy);
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 getattrib_text(u16 coordx, u16 coordy)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *screen;
|
|
|
|
|
screen =
|
|
|
|
|
(u8 *) basemem + activepage * pagesize + 2 * (coordx +
|
|
|
|
|
coordy * resX) + 1;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
return *screen;
|
|
|
|
|
}
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Ecrit un pixel a l'<27>cran */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
void (*writepxl) (u16 x, u16 y, u32 c);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
|
|
|
|
void writepxl_1bit(u16 x, u16 y, u32 c)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *off;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
u8 mask;
|
|
|
|
|
c = (c & 1) * 0xFF;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
off = (u8 *) (basemem + activepage * pagesize + linesize * y + x / 8);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
x = (x & 7) * 1;
|
|
|
|
|
mask = 0x80 >> x;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
*off = ((*off) & ~mask) | (c & mask);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void writepxl_2bits(u16 x, u16 y, u32 c)
|
|
|
|
|
{
|
|
|
|
|
u8 *off;
|
|
|
|
|
u8 mask;
|
|
|
|
|
c = (c & 3) * 0x55;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
off = (u8 *) (basemem + activepage * pagesize + linesize * y + x / 4);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
x = (x & 3) * 2;
|
|
|
|
|
mask = 0xC0 >> x;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
*off = ((*off) & ~mask) | (c & mask);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void writepxl_4bits(u16 x, u16 y, u32 c)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *off;
|
|
|
|
|
u8 mask, p, pmask;
|
|
|
|
|
off = (u8 *) (basemem + activepage * pagesize + linesize * y + x / 8);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
x = (x & 7) * 1;
|
|
|
|
|
mask = 0x80 >> x;
|
|
|
|
|
pmask = 1;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
for (p = 0; p < 4; p++) {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
useplane(p);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (pmask & c)
|
|
|
|
|
*off = ((*off) | mask);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
else
|
2018-08-17 16:46:56 +02:00
|
|
|
|
*off = ((*off) & ~mask);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
pmask <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void writepxl_8bits(u16 x, u16 y, u32 c)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *off;
|
|
|
|
|
off = (u8 *) (basemem + activepage * pagesize + linesize * y + x);
|
|
|
|
|
*off = c;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void writepxl_8bitsunchain(u16 x, u16 y, u32 c)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *off;
|
|
|
|
|
off = (u8 *) (basemem + activepage * pagesize + linesize * y + x / 4);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
useplane(x & 3);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
*off = c;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Change le mode video courant */
|
|
|
|
|
|
|
|
|
|
u32 setvmode(u8 mode)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 *def, gmode;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* R<>cupere la definition des registres VGA en fonction du mode
|
2018-08-17 16:46:56 +02:00
|
|
|
|
graphique : >0x80
|
|
|
|
|
text : 0x00 - 0x7F
|
|
|
|
|
*/
|
|
|
|
|
if (mode >= 0x80) {
|
|
|
|
|
gmode = mode - 0x80;
|
|
|
|
|
if (gmode > maxgraphmode)
|
|
|
|
|
return 1; /* mode inexistant */
|
|
|
|
|
def = graphmodes[gmode];
|
|
|
|
|
graphic = true;
|
|
|
|
|
} else {
|
|
|
|
|
if (mode > maxtextmode)
|
|
|
|
|
return 1; /* mode inexistant */
|
|
|
|
|
def = textmodes[mode];
|
|
|
|
|
graphic = false;
|
|
|
|
|
loadfont(font8x8, 8, 1);
|
|
|
|
|
loadfont(font8x16, 16, 0);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
/* Initialise les registre "divers" */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(misc, def[0]);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Initialise les registre d'etat */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(state, 0x00);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Initialise le s<>quenceur */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outreg(sequencer, &def[1], 5);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Debloque le verouillage des registres controleur CRT */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(ccrt, 0x11);
|
|
|
|
|
outb(ccrt + 1, 0x0E);
|
|
|
|
|
/* Initialise le controleur CRT */
|
|
|
|
|
outreg(ccrt, &def[6], 25);
|
|
|
|
|
/* Initialise le controleur graphique */
|
|
|
|
|
outreg(graphics, &def[31], 9);
|
|
|
|
|
inb(state);
|
|
|
|
|
/* Initialise le controleur d'attributs */
|
|
|
|
|
outregsame(attribs, &def[40], 21);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
inb(state);
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(attribs, 0x20);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* R<>cupere depuis la table de d<>finition des mode la r<>solution et la
|
2018-08-17 16:46:56 +02:00
|
|
|
|
profondeur (en bits) */
|
|
|
|
|
resX = def[61];
|
|
|
|
|
resY = def[62];
|
|
|
|
|
color = def[63];
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Initialise l'adresse des procedures de gestion graphique et les differentes
|
2018-08-17 16:46:56 +02:00
|
|
|
|
variables en fonction de la profondeur et du mode */
|
|
|
|
|
if (!graphic) {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* mode texte */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
linesize = resX * 2;
|
|
|
|
|
writepxl = NULL; /* pas d'affichage de pixels */
|
|
|
|
|
showchar = showchar_text;
|
|
|
|
|
scroll = scroll_text;
|
|
|
|
|
fill = fill_text;
|
|
|
|
|
pagesize = resY * linesize;
|
|
|
|
|
getchar = getchar_text;
|
|
|
|
|
getattrib = getattrib_text;
|
|
|
|
|
} else {
|
|
|
|
|
switch (color) {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
case 1:
|
|
|
|
|
/* mode N&B */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
linesize = resX;
|
|
|
|
|
writepxl = writepxl_1bit;
|
|
|
|
|
fill = fill_chain;
|
|
|
|
|
scroll = scroll_chain;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
/* mode 4 couleurs */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
linesize = (resX << 1);
|
|
|
|
|
writepxl = writepxl_2bits;
|
|
|
|
|
fill = fill_chain;
|
|
|
|
|
scroll = scroll_chain;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
/* mode 16 couleurs */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
linesize = resX;
|
|
|
|
|
writepxl = writepxl_4bits;
|
|
|
|
|
fill = fill_unchain;
|
|
|
|
|
scroll = scroll_unchain;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
/* mode 256 couleurs */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (def[5] == 0x0E) {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* mode chain<69> (plus rapide mais limit<69> en m<>moire) */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
linesize = (resX << 3);
|
|
|
|
|
writepxl = writepxl_8bits;
|
|
|
|
|
scroll = scroll_chain;
|
|
|
|
|
fill = fill_chain;
|
|
|
|
|
} else {
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* mode non chain<69> */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
linesize = (resX << 1);
|
|
|
|
|
writepxl = writepxl_8bitsunchain;
|
|
|
|
|
scroll = scroll_unchain;
|
|
|
|
|
fill = fill_unchain;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-08-17 16:46:56 +02:00
|
|
|
|
showchar = showchar_graphic;
|
|
|
|
|
pagesize = ((resY * linesize) << 3);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
/* calcul des variables d'<27>tat video */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
activepage = 0;
|
|
|
|
|
showedpage = 0;
|
|
|
|
|
splitY = 0;
|
|
|
|
|
vmode = mode;
|
|
|
|
|
scrolling = 1;
|
|
|
|
|
pages = (planesize / pagesize);
|
|
|
|
|
basemem = (def[20] << 8) + def[21] + getbase();
|
2007-04-02 15:20:55 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* R<>cup<75>re le mode vid<69>o en cours */
|
|
|
|
|
|
|
|
|
|
u8 getvmode(void)
|
|
|
|
|
{
|
|
|
|
|
return vmode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Charge une nouvelle police de caract<63>re */
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u32 loadfont(u8 * def, u8 size, u8 font)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (graphics == 1)
|
|
|
|
|
return 1;
|
|
|
|
|
u8 oldregs[5] = { 0, 0, 0, 0, 0 };
|
|
|
|
|
u8 *base;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
u16 i;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
if (font > 7)
|
|
|
|
|
return 1;
|
|
|
|
|
if (font < 4)
|
|
|
|
|
base = (u8 *) (getbase() + (font << 14));
|
2007-04-02 15:20:55 +02:00
|
|
|
|
else
|
2018-08-17 16:46:56 +02:00
|
|
|
|
base = (u8 *) (getbase() + ((((font - 4) << 1) + 1) << 13));
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* sauve les anciens registres */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(sequencer, 2);
|
|
|
|
|
oldregs[0] = inb(sequencer + 1);
|
|
|
|
|
outb(sequencer, 4);
|
|
|
|
|
oldregs[1] = inb(sequencer + 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Adressage paire/impair desactiv<69> (lineaire) */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(sequencer + 1, oldregs[1] | 0x04);
|
|
|
|
|
outb(graphics, 4);
|
|
|
|
|
oldregs[2] = inb(graphics + 1);
|
|
|
|
|
outb(graphics, 5);
|
|
|
|
|
oldregs[3] = inb(graphics + 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Adressage paire/impair desactiv<69> (lineaire) */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(graphics + 1, oldregs[3] & ~0x10);
|
|
|
|
|
outb(graphics, 6);
|
|
|
|
|
oldregs[4] = inb(graphics + 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* Adressage paire/impair desactiv<69> (lineaire) */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(graphics + 1, oldregs[4] & ~0x02);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* utilisation du plan N<>2 */
|
2018-08-17 16:46:56 +02:00
|
|
|
|
useplane(2);
|
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
|
memcpy(def, base + i * 32, size, 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
def += size;
|
|
|
|
|
}
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(sequencer, 2);
|
|
|
|
|
outb(sequencer + 1, oldregs[0]);
|
|
|
|
|
outb(sequencer, 4);
|
|
|
|
|
outb(sequencer + 1, oldregs[1]);
|
|
|
|
|
outb(graphics, 4);
|
|
|
|
|
outb(graphics + 1, oldregs[2]);
|
|
|
|
|
outb(graphics, 5);
|
|
|
|
|
outb(graphics + 1, oldregs[3]);
|
|
|
|
|
outb(graphics, 6);
|
|
|
|
|
outb(graphics + 1, oldregs[4]);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* R<>cupere le N<> de la police de caract<63>re en cours d'utilisation */
|
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
u8 getfont()
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 num, tmp;
|
|
|
|
|
outb(sequencer, 3);
|
|
|
|
|
tmp = inb(sequencer + 1);
|
|
|
|
|
num = (tmp & 0x03) | ((tmp & 0x10) >> 2);
|
|
|
|
|
return num;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* R<>cupere le N<> de la police de caract<63>re en cours d'utilisation */
|
|
|
|
|
|
|
|
|
|
u8 getfont2()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
u8 num, tmp;
|
|
|
|
|
outb(sequencer, 3);
|
|
|
|
|
tmp = inb(sequencer + 1);
|
|
|
|
|
num = ((tmp & 0x0C) >> 2) | ((tmp & 0x20) >> 3);
|
|
|
|
|
return num;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Fixe le N<> de la police de caract<63>re a utiliser */
|
|
|
|
|
|
|
|
|
|
void setfont(u8 num)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
num &= 0x07;
|
|
|
|
|
outb(sequencer, 3);
|
|
|
|
|
outb(sequencer + 1,
|
|
|
|
|
(inb(sequencer + 1) & 0xEC) | ((num & 0x03) +
|
|
|
|
|
((num & 0x04) << 2)));
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Fixe le N<> de la police de caract<63>re a utiliser */
|
|
|
|
|
|
|
|
|
|
void setfont2(u8 num)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
num &= 0x07;
|
|
|
|
|
outb(sequencer, 3);
|
|
|
|
|
outb(sequencer + 1,
|
|
|
|
|
(inb(sequencer + 1) & 0xD3) | (((num & 0x03) << 2) +
|
|
|
|
|
((num & 0x04) << 3)));
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Autorise le clignotement */
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
|
|
|
|
void enableblink()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(ccrt, 0x10);
|
|
|
|
|
outb(ccrt + 1, (inb(sequencer + 1) | 0x04));
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Annule le clignotement */
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
void disableblink()
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
outb(ccrt, 0x10);
|
|
|
|
|
outb(ccrt + 1, (inb(sequencer + 1) & ~0x04));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Envoie une s<>rie d'octet a destination d'une portion de m<>moire
|
|
|
|
|
vers le registre sp<EFBFBD>cifi<EFBFBD> */
|
|
|
|
|
|
|
|
|
|
void outreg(u16 port, u8 * src, u16 num)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
outb(port, i);
|
|
|
|
|
outb(port + 1, *src++);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Envoie une s<>rie d'octet a destination d'une portion de m<>moire
|
|
|
|
|
vers le registre sp<EFBFBD>cifi<EFBFBD> (acc<EFBFBD>s data et index confondu) */
|
|
|
|
|
|
|
|
|
|
void outregsame(u16 port, u8 * src, u16 num)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
inb(port);
|
|
|
|
|
outb(port, i);
|
|
|
|
|
outb(port, *src++);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* R<>cup<75>re une s<>rie d'octet en provenance d'un registre sp<73>cifi<66>
|
|
|
|
|
vers portion de m<EFBFBD>moire */
|
|
|
|
|
|
|
|
|
|
void inreg(u16 port, u8 * src, u16 num)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
outb(port, i);
|
|
|
|
|
*src++ = inb(port + 1);
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
/*******************************************************************************/
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* R<>cup<75>re une s<>rie d'octet en provenance d'un registre sp<73>cifi<66>
|
|
|
|
|
vers portion de m<EFBFBD>moire (acc<EFBFBD>s data et index confondu) */
|
|
|
|
|
|
|
|
|
|
void inregsame(u16 port, u8 * src, u16 num)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
inb(port);
|
|
|
|
|
outb(port, i);
|
|
|
|
|
*src++ = inb(port);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|