2018-09-28 20:35:51 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hord<72> Nicolas */
|
|
|
|
|
/* */
|
2007-04-02 15:20:55 +02:00
|
|
|
|
#include "vga.h"
|
2018-10-12 20:37:26 +02:00
|
|
|
|
#include "video.h"
|
2007-04-02 15:20:55 +02:00
|
|
|
|
#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"
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
static videoinfos infos;
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2018-11-29 13:42:07 +01:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Deplace l'adresse virtuelle en mode paginee */
|
|
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
|
void VGA_remap_memory(u32 vaddr)
|
|
|
|
|
{
|
|
|
|
|
virtual_range_use_kernel(vaddr, GRPHSCREEN, ENDOFVMEM - GRPHSCREEN,
|
|
|
|
|
PAGE_NOFLAG);
|
2018-11-29 13:42:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Detecte si le hardware est disponible, return NULL ou pointeur sur le type de pilote */
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u8 *VGA_detect_hardware(void)
|
|
|
|
|
{
|
|
|
|
|
return "LEGACY";
|
2018-10-12 22:31:34 +02:00
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Renvoie l'adresse du segment video */
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
u32 getbase(void)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 base;
|
2018-10-19 10:13:29 +02:00
|
|
|
|
outb(GRAPHICS, 6);
|
|
|
|
|
base = inb(GRAPHICS + 1);
|
2018-10-13 05:35:08 +02:00
|
|
|
|
base >>= 2;
|
|
|
|
|
base &= 3;
|
2018-12-12 15:25:04 +01:00
|
|
|
|
switch (base)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
base = 0xA0000;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
base = 0xB0000;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
base = 0xB8000;
|
|
|
|
|
break;
|
2018-10-12 20:37:26 +02:00
|
|
|
|
}
|
|
|
|
|
return base;
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Change le mode video courant */
|
|
|
|
|
/* ERR 0 aucune
|
|
|
|
|
/* ERR 1 mode non existant */
|
|
|
|
|
|
2018-10-13 05:35:08 +02:00
|
|
|
|
static u8 realsize;
|
|
|
|
|
|
2018-10-12 22:31:34 +02:00
|
|
|
|
u8 VGA_setvideo_mode(u8 mode)
|
2018-10-12 20:37:26 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 index = 0;
|
|
|
|
|
while (vgacapabilities[index].modenumber != 0xFF)
|
|
|
|
|
{
|
|
|
|
|
if (vgacapabilities[index].modenumber == mode)
|
|
|
|
|
{
|
|
|
|
|
infos.currentmode =
|
|
|
|
|
vgacapabilities[index].modenumber;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
if (infos.currentmode != mode)
|
|
|
|
|
return 1;
|
|
|
|
|
infos.currentwidth = vgacapabilities[index].width;
|
|
|
|
|
infos.currentheight = vgacapabilities[index].height;
|
|
|
|
|
infos.currentdepth = vgacapabilities[index].depth;
|
|
|
|
|
infos.currentactivepage = 0;
|
|
|
|
|
infos.currentshowedpage = 0;
|
|
|
|
|
infos.currentcursorX = 0;
|
|
|
|
|
infos.currentcursorY = 0;
|
|
|
|
|
infos.currentfont1 = 0;
|
|
|
|
|
infos.currentfont2 = 0;
|
|
|
|
|
infos.isgraphic = vgacapabilities[index].graphic;
|
|
|
|
|
infos.isblinking = false;
|
|
|
|
|
infos.iscursorvisible = false;
|
|
|
|
|
if (infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
switch (infos.currentdepth)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
/* mode N&B */
|
|
|
|
|
infos.currentpitch = infos.currentwidth;
|
|
|
|
|
realsize = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
/* mode 4 couleurs */
|
|
|
|
|
infos.currentpitch =
|
|
|
|
|
(infos.currentwidth << 1);
|
|
|
|
|
realsize = 2;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
/* mode 16 couleurs */
|
|
|
|
|
infos.currentpitch = infos.currentwidth;
|
|
|
|
|
realsize = 4;
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
/* mode 256 couleurs */
|
2018-12-12 17:57:23 +01:00
|
|
|
|
if (modes[index].
|
|
|
|
|
sequencer.Sequencer_Memory_Mode_Register
|
|
|
|
|
== 0x0E)
|
2018-12-12 15:25:04 +01:00
|
|
|
|
{
|
|
|
|
|
/* mode chain<69> (plus rapide mais limit<69> en m<>moire) */
|
|
|
|
|
infos.currentpitch =
|
|
|
|
|
infos.currentwidth;
|
|
|
|
|
realsize = 8;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* mode non chain<69> */
|
|
|
|
|
infos.currentpitch =
|
|
|
|
|
infos.currentwidth >> 2;
|
|
|
|
|
realsize = 9;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-10-13 13:23:00 +02:00
|
|
|
|
infos.pagesize = infos.currentheight * infos.currentpitch;
|
2018-10-12 20:37:26 +02:00
|
|
|
|
}
|
2018-12-12 15:25:04 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
infos.currentpitch = infos.currentwidth * 2;
|
|
|
|
|
infos.pagesize = infos.currentheight * infos.currentpitch;
|
|
|
|
|
realsize = 0;
|
|
|
|
|
}
|
|
|
|
|
infos.pagesnumber = (PLANESIZE / infos.pagesize);
|
|
|
|
|
infos.baseaddress =
|
|
|
|
|
(modes[index].ctrc.Cursor_Location_High_Register << 8) +
|
|
|
|
|
modes[index].ctrc.Cursor_Location_Low_Register + getbase();
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise les registre "divers" */
|
2018-10-12 22:31:34 +02:00
|
|
|
|
outb(MISC_WRITE, modes[index].misc);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise les registre d'etat */
|
2018-10-12 22:31:34 +02:00
|
|
|
|
outb(STATE, 0x00);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise le s<>quenceur */
|
2018-10-13 05:35:08 +02:00
|
|
|
|
outreg(SEQUENCER, &modes[index].sequencer, 5);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Debloque le verouillage des registres controleur CRT */
|
2018-10-12 22:31:34 +02:00
|
|
|
|
outb(CCRT, 0x11);
|
|
|
|
|
outb(CCRT + 1, 0x0E);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise le controleur CRT */
|
2018-10-13 05:35:08 +02:00
|
|
|
|
outreg(CCRT, &modes[index].ctrc, 25);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise le controleur graphique */
|
2018-10-13 05:35:08 +02:00
|
|
|
|
outreg(GRAPHICS, &modes[index].graphic, 9);
|
2018-10-12 22:31:34 +02:00
|
|
|
|
inb(STATE);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise le controleur d'attributs */
|
2018-10-13 05:35:08 +02:00
|
|
|
|
outregsame(ATTRIBS, &modes[index].attribut, 21);
|
2018-10-12 22:31:34 +02:00
|
|
|
|
inb(STATE);
|
|
|
|
|
outb(ATTRIBS, 0x20);
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Initialise l'adresse des procedures de gestion graphique et les differentes
|
|
|
|
|
variables en fonction de la profondeur et du mode */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Renvoie le nom du driver */
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u8 *VGA_getvideo_drivername(void)
|
|
|
|
|
{
|
|
|
|
|
return "VGA";
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Renvoie un pointeur sur la structure des capacit<69>s graphiques */
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u8 *VGA_getvideo_capabilities(void)
|
|
|
|
|
{
|
|
|
|
|
return vgacapabilities;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Renvoie un pointeur sur l'<27>tat courant de la carte */
|
2018-12-12 15:25:04 +01:00
|
|
|
|
videoinfos *VGA_getvideo_info(void)
|
|
|
|
|
{
|
|
|
|
|
return &infos;
|
2018-10-12 20:37:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Effecture un mouvement de la m<>moire centrale vers la m<>moire video (lin<69>aris<69>e) */
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 VGA_mem_to_video(void *src, u32 dst, u32 size, bool increment_src)
|
|
|
|
|
{
|
|
|
|
|
u32 realdst =
|
|
|
|
|
infos.baseaddress +
|
|
|
|
|
infos.currentactivepage * infos.pagesize + dst;
|
|
|
|
|
switch (realsize)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
if (!increment_src)
|
|
|
|
|
{
|
|
|
|
|
u8 tmp = (u8) src;
|
|
|
|
|
memset(realdst, tmp, size, 2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memcpy(src, realdst, size, 2);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
if (!increment_src)
|
|
|
|
|
{
|
|
|
|
|
u8 tmp = (u8) (src);
|
|
|
|
|
if (size % 4 == 0)
|
|
|
|
|
{
|
|
|
|
|
u32 pattern =
|
|
|
|
|
tmp + (tmp << 8) +
|
|
|
|
|
(tmp << 16) + (tmp << 24);
|
|
|
|
|
stosd(pattern, realdst,
|
|
|
|
|
(size >> 2));
|
|
|
|
|
}
|
|
|
|
|
else if (size % 2 == 0)
|
|
|
|
|
{
|
|
|
|
|
u32 pattern = tmp + (tmp << 8);
|
|
|
|
|
stosw(pattern, realdst,
|
|
|
|
|
(size >> 1));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
u32 pattern = tmp;
|
|
|
|
|
stosb(pattern, realdst, size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (size % 4 == 0)
|
|
|
|
|
{
|
|
|
|
|
movsd(src, realdst, size >> 2);
|
|
|
|
|
}
|
|
|
|
|
else if (size % 2 == 0)
|
|
|
|
|
{
|
|
|
|
|
movsw(src, realdst, size >> 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
movsb(src, realdst, size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Effecture un mouvement de la m<>moire video (lin<69>aris<69>e) vers la m<>moire centrale*/
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 VGA_video_to_mem(u32 src, void *dst, u32 size)
|
2018-10-13 11:25:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 realsrc =
|
|
|
|
|
infos.baseaddress +
|
|
|
|
|
infos.currentactivepage * infos.pagesize + src;
|
|
|
|
|
switch (realsize)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
memcpy(realsrc, dst, size, 2);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Effecture un mouvement de la m<>moire video (lin<69>aris<69>) vers la m<>moire vid<69>o (lin<69>aris<69>e) */
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 VGA_video_to_video(u32 src, u32 dst, u32 size)
|
2018-10-13 05:35:08 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u32 base =
|
|
|
|
|
infos.baseaddress +
|
|
|
|
|
infos.currentactivepage * infos.pagesize;
|
|
|
|
|
u32 realsrc = base + src;
|
|
|
|
|
u32 realdst = base + dst;
|
|
|
|
|
switch (realsize)
|
|
|
|
|
{
|
|
|
|
|
case 8:
|
|
|
|
|
case 0:
|
|
|
|
|
if (size % 4 == 0)
|
|
|
|
|
{
|
|
|
|
|
movsd(realsrc, realdst, size >> 2);
|
|
|
|
|
}
|
|
|
|
|
else if (size % 2 == 0)
|
|
|
|
|
{
|
|
|
|
|
movsw(realsrc, realdst, size >> 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
movsb(realsrc, realdst, size);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* Fixe la page ecran de travail */
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_page_set(u8 page)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-10-12 20:37:26 +02:00
|
|
|
|
if (page < infos.pagesnumber)
|
|
|
|
|
infos.currentactivepage = page;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Affiche la page ecran specifi<66> */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_page_show(u8 page)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (page < infos.pagesnumber)
|
|
|
|
|
{
|
|
|
|
|
u16 addr;
|
2018-10-12 20:37:26 +02:00
|
|
|
|
addr = page * infos.pagesize / 2;
|
2018-10-12 22:31:34 +02:00
|
|
|
|
outb(CCRT, 0x0C);
|
|
|
|
|
outb(CCRT + 1, (addr >> 8));
|
|
|
|
|
outb(CCRT, 0x0D);
|
|
|
|
|
outb(CCRT + 1, (addr & 0xFF));
|
2018-10-12 20:37:26 +02:00
|
|
|
|
infos.currentshowedpage = page;
|
2018-08-17 16:46:56 +02:00
|
|
|
|
}
|
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 */
|
|
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
|
static splitY = 0;
|
2007-04-02 16:12:33 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_page_split(u16 y)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (y != 0)
|
|
|
|
|
{
|
|
|
|
|
u16 addr;
|
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
/* Maximum Scan Line pour le bit 9 */
|
|
|
|
|
|
|
|
|
|
outb(CCRT, 0x09);
|
|
|
|
|
outb(CCRT + 1, (inb(CCRT + 1) & ~64) | ((addr >> 3) & 64));
|
|
|
|
|
splitY = y;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
|
|
/* 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-10-12 20:37:26 +02:00
|
|
|
|
void VGA_wait_vretrace(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
while ((inb(STATE) & 8) == 0);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Attend la retrace horizontale */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_wait_hretrace(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
while ((inb(STATE) & 1) == 0);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Active l'affichage du curseur de texte */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_cursor_enable(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
u8 curs;
|
|
|
|
|
/* active le curseur hardware */
|
|
|
|
|
outb(CCRT, 10);
|
|
|
|
|
curs = inb(CCRT + 1) & ~32;
|
|
|
|
|
outb(CCRT + 1, curs);
|
|
|
|
|
infos.iscursorvisible = true;
|
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Desactive l'affichage du curseur de texte */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_cursor_disable(void)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
u8 curs;
|
|
|
|
|
/* Desactive le curseur hardware */
|
|
|
|
|
outb(CCRT, 10);
|
|
|
|
|
curs = inb(CCRT + 1) | 32;
|
|
|
|
|
outb(CCRT + 1, curs);
|
|
|
|
|
infos.iscursorvisible = false;
|
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Utilise le plan de bit sp<73>cifi<66> */
|
|
|
|
|
|
|
|
|
|
void useplane(u8 plan)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u8 mask;
|
2007-04-02 15:20:55 +02:00
|
|
|
|
plan &= 3;
|
|
|
|
|
mask = 1 << plan;
|
|
|
|
|
/* choisi le plan de lecture */
|
2018-10-12 22:31:34 +02:00
|
|
|
|
outb(GRAPHICS, 4);
|
|
|
|
|
outb(GRAPHICS + 1, plan);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* choisi le plan d'ecriture */
|
2018-10-12 22:31:34 +02:00
|
|
|
|
outb(SEQUENCER, 2);
|
|
|
|
|
outb(SEQUENCER + 1, mask);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* fixe la position du curseur texte */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_cursor_set(u16 x, u16 y)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
u16 pos;
|
|
|
|
|
if (splitY == 0)
|
|
|
|
|
pos = (infos.currentshowedpage * infos.pagesize /
|
|
|
|
|
2 + x + y * infos.currentwidth);
|
|
|
|
|
else
|
|
|
|
|
pos = (x + y * infos.currentwidth);
|
|
|
|
|
outb(CCRT, 0x0F);
|
|
|
|
|
outb(CCRT + 1, (u8) (pos & 0x00FF));
|
|
|
|
|
outb(CCRT, 0x0E);
|
|
|
|
|
outb(CCRT + 1, (u8) ((pos & 0xFF00) >> 8));
|
|
|
|
|
infos.currentcursorX = x;
|
|
|
|
|
infos.currentcursorY = y;
|
|
|
|
|
}
|
2007-04-02 15:20:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Charge une nouvelle police de caract<63>re */
|
2018-10-12 20:37:26 +02:00
|
|
|
|
/* ERR 1 mode graphique activ<69>*/
|
2007-04-02 15:20:55 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
u32 VGA_font_load(u8 * def, u8 size, u8 font)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-10-12 20:37:26 +02:00
|
|
|
|
if (infos.isgraphic)
|
2018-08-17 16:46:56 +02:00
|
|
|
|
return 1;
|
2018-12-12 15:25:04 +01:00
|
|
|
|
u8 oldregs[5] = { 0, 0, 0, 0, 0 };
|
|
|
|
|
u8 *base;
|
|
|
|
|
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-12-12 15:25:04 +01:00
|
|
|
|
base = (u8 *) (getbase() +
|
|
|
|
|
((((font - 4) << 1) + 1) << 13));
|
2007-04-02 15:20:55 +02:00
|
|
|
|
/* sauve les anciens registres */
|
2018-10-12 22:31:34 +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-10-12 22:31:34 +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-10-12 22:31:34 +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-10-12 22:31:34 +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);
|
2018-12-12 15:25:04 +01:00
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
memcpy(def, base + i * 32, size, 1);
|
2007-04-02 15:20:55 +02:00
|
|
|
|
def += size;
|
|
|
|
|
}
|
2018-10-12 22:31:34 +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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Fixe le N<> de la police de caract<63>re a utiliser */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_font1_set(u8 num)
|
2007-04-02 15:20:55 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
num &= 0x07;
|
|
|
|
|
outb(SEQUENCER, 3);
|
|
|
|
|
outb(SEQUENCER + 1,
|
|
|
|
|
(inb(SEQUENCER + 1) & 0xEC) | ((num & 0x03) +
|
|
|
|
|
((num & 0x04) << 2)));
|
|
|
|
|
infos.currentfont1 = num;
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Fixe le N<> de la police de caract<63>re a utiliser */
|
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_font2_set(u8 num)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
num &= 0x07;
|
|
|
|
|
outb(SEQUENCER, 3);
|
|
|
|
|
outb(SEQUENCER + 1,
|
|
|
|
|
(inb(SEQUENCER + 1) & 0xD3) | (((num & 0x03) << 2) +
|
|
|
|
|
((num & 0x04) << 3)));
|
|
|
|
|
infos.currentfont2 = num;
|
|
|
|
|
}
|
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
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_blink_enable(void)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
outb(CCRT, 0x10);
|
|
|
|
|
outb(CCRT + 1, (inb(SEQUENCER + 1) | 0x04));
|
|
|
|
|
infos.isblinking = true;
|
|
|
|
|
}
|
2007-04-02 16:12:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Annule le clignotement */
|
2007-04-02 15:43:32 +02:00
|
|
|
|
|
2018-10-12 20:37:26 +02:00
|
|
|
|
void VGA_blink_disable(void)
|
2007-04-02 16:12:33 +02:00
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
if (!infos.isgraphic)
|
|
|
|
|
{
|
|
|
|
|
outb(CCRT, 0x10);
|
|
|
|
|
outb(CCRT + 1, (inb(SEQUENCER + 1) & ~0x04));
|
|
|
|
|
infos.isblinking = false;
|
|
|
|
|
}
|
2018-08-17 16:46:56 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* 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)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
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)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
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)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
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
|
|
|
|
/*******************************************************************************/
|
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)
|
|
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
{
|
2018-08-17 16:46:56 +02:00
|
|
|
|
inb(port);
|
|
|
|
|
outb(port, i);
|
|
|
|
|
*src++ = inb(port);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|