fix: gestion pilotes video, implantation mode texte, correction scrolling

This commit is contained in:
Nicolas Hordé 2018-10-13 05:35:08 +02:00
parent 1e77ba8c3f
commit 016b972d97
6 changed files with 174 additions and 43 deletions

View File

@ -7,6 +7,25 @@
#define TEXTSCREEN 0xB8000 /* debut de la memoire video texte*/
#define GRPHSCREEN 0xA0000 /* debut de la memoire video graphique*/
#define movsb(src,dst,count) \
asm volatile ("cld;rep movsb"::"S" (src), "D" (dst), "c" (count));
#define movsw(src,dst,count) \
asm volatile ("cld;rep movsw"::"S" (src), "D" (dst), "c" (count));
#define movsd(src,dst,count) \
asm volatile ("cld;rep movsd"::"S" (src), "D" (dst), "c" (count));
#define stosb(pattern,dst,count) \
asm volatile ("cld;rep stosb"::"c" (count), "D" (dst), "a" (pattern));
#define stosw(pattern,dst,count) \
asm volatile ("cld;rep stosw"::"a" (pattern), "c" (count), "D" (dst));
#define stosd(pattern,dst,count) \
asm volatile ("cld;rep stosd"::"a" (pattern), "c" (count), "D" (dst));
/* Registres VGAs */
#define SEQUENCER 0x3c4
@ -97,9 +116,9 @@ u8 VGA_setvideo_mode (u8 mode);
u8 *VGA_getvideo_drivername (void);
u8 *VGA_getvideo_capabilities (void);
videoinfos *VGA_getvideo_info (void);
u32 VGA_mem_to_video (void *src,u32 dst, u32 size, bool increment_src);
u32 VGA_video_to_mem (u32 src,void *dst, u32 size);
u32 VGA_video_to_video (u32 src,u32 dst, u32 size);
u32 VGA_mem_to_video (void *src,u32 dst, u32 size, u8 realsize, bool increment_src);
u32 VGA_video_to_mem (u32 src,void *dst, u32 size, u8 realsize);
u32 VGA_video_to_video (u32 src,u32 dst, u32 size, u8 realsize);
void VGA_wait_vretrace (void);
void VGA_wait_hretrace (void);
void VGA_page_set (u8 page);

View File

@ -77,6 +77,7 @@ typedef struct console {
u8 param2;
u8 param3;
u8 page;
bool scroll;
} console __attribute__ ((packed));
/* Fonctions de bas niveau */
@ -123,9 +124,9 @@ u8 (*setvideo_mode) (u8 mode);
u8 *(*getvideo_drivername) (void);
u8 *(*getvideo_capabilities) (void);
videoinfos *(*getvideo_info) (void);
u32 (*mem_to_video) (void *src,u32 dst, u32 size, bool increment_src);
u32 (*video_to_mem) (u32 src,void *dst, u32 size);
u32 (*video_to_video) (u32 src,u32 dst, u32 size);
u32 (*mem_to_video) (void *src,u32 dst, u32 size, u8 realsize, bool increment_src);
u32 (*video_to_mem) (u32 src,void *dst, u32 size, u8 realsize);
u32 (*video_to_video) (u32 src,u32 dst, u32 size, u8 realsize);
void (*wait_vretrace) (void);
void (*wait_hretrace) (void);
void (*page_set) (u8 page);

View File

@ -22,7 +22,7 @@ static vgamode modes[] = {
/*80*25 16 couleurs mode 0x00 */
{{0x67},
{0x03, 0x00, 0x03, 0x00, 0x02},
{0x03, 0x00, 0x03, 0x00, 0x06},
{0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00,
0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3, 0xFF},

115
lib/vga.c
View File

@ -25,10 +25,10 @@ u32 getbase(void)
{
u32 base;
/*outb(GRAPHICS, 6);
base = inb(GRAPHICS + 1);
base >>= 2;
base &= 3;*/
base = inb(GRAPHICS + 1);*/
base = modes[infos.currentmode].graphic.Miscellaneous_Graphics_Register;
base >>= 2;
base &= 3;
switch (base) {
case 0:
case 1:
@ -49,6 +49,8 @@ u32 getbase(void)
/* ERR 0 aucune
/* ERR 1 mode non existant */
static u8 realsize;
u8 VGA_setvideo_mode(u8 mode)
{
u32 index=0;
@ -78,23 +80,28 @@ u8 VGA_setvideo_mode(u8 mode)
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 */
if (modes[index].sequencer.Sequencer_Memory_Mode_Register == 0x0E) {
/* mode chainé (plus rapide mais limité en mémoire) */
infos.currentpitch = (infos.currentwidth << 3);
realsize=8;
} else {
/* mode non chainé */
infos.currentpitch = (infos.currentwidth << 1);
realsize=9;
}
break;
default:
@ -107,25 +114,26 @@ u8 VGA_setvideo_mode(u8 mode)
VGA_font_load(font8x16, 16, 0);
infos.currentpitch= infos.currentwidth * 2;
infos.pagesize=infos.currentheight * infos.currentpitch;
realsize=0;
}
infos.pagesnumber=(PLANESIZE / infos.currentpitch);
infos.pagesnumber=(PLANESIZE / infos.pagesize);
infos.baseaddress=(modes[index].ctrc.Cursor_Location_High_Register << 8) + modes[index].ctrc.Cursor_Location_Low_Register + getbase();
/* Initialise les registre "divers" */
outb(MISC_WRITE, modes[index].misc);
/* Initialise les registre d'etat */
outb(STATE, 0x00);
/* Initialise le séquenceur */
outreg(SEQUENCER, modes[index].sequencer, 5);
outreg(SEQUENCER, &modes[index].sequencer, 5);
/* Debloque le verouillage des registres controleur CRT */
outb(CCRT, 0x11);
outb(CCRT + 1, 0x0E);
/* Initialise le controleur CRT */
outreg(CCRT, modes[index].ctrc, 25);
outreg(CCRT, &modes[index].ctrc, 25);
/* Initialise le controleur graphique */
outreg(GRAPHICS, modes[index].graphic, 9);
outreg(GRAPHICS, &modes[index].graphic, 9);
inb(STATE);
/* Initialise le controleur d'attributs */
outregsame(ATTRIBS, modes[index].attribut, 21);
outregsame(ATTRIBS, &modes[index].attribut, 21);
inb(STATE);
outb(ATTRIBS, 0x20);
/* Initialise l'adresse des procedures de gestion graphique et les differentes
@ -154,19 +162,104 @@ videoinfos *VGA_getvideo_info (void) {
/*******************************************************************************/
/* Effecture un mouvement de la mémoire centrale vers la mémoire video (linéarisée) */
u32 VGA_mem_to_video (void *src,u32 dst, u32 size, bool increment_src) {
u32 VGA_mem_to_video (void *src,u32 dst, u32 size, u8 realsize, bool increment_src) {
u32 realdst=infos.baseaddress + infos.currentactivepage * infos.pagesize+dst;
switch (realsize)
{
case 0:
if (!increment_src)
{
u8 tmp=(u8) src;
stosb(tmp,realdst,size);
}
else
{
}
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);
stosb(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);
}
}
break;
case 9:
break;
}
}
/*******************************************************************************/
/* Effecture un mouvement de la mémoire video (linéarisée) vers la mémoire centrale*/
u32 VGA_video_to_mem (u32 src,void *dst, u32 size) {
u32 VGA_video_to_mem (u32 src,void *dst, u32 size, u8 realsize) {
}
/*******************************************************************************/
/* Effecture un mouvement de la mémoire video (linéarisé) vers la mémoire vidéo (linéarisée) */
u32 VGA_video_to_video (u32 src,u32 dst, u32 size) {
u32 VGA_video_to_video (u32 src,u32 dst, u32 size, u8 realsize)
{
u32 base=infos.baseaddress + infos.currentactivepage * infos.pagesize;
u32 realsrc=base+src;
u32 realdst=base+dst;
switch (realsize)
{
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 8:
break;
case 9:
break;
}
}

View File

@ -5,22 +5,22 @@
#include "video.h"
#include "stdarg.h"
drivers registred[maxdrivers];
static drivers registred[maxdrivers];
videoinfos *vinfo;
static videoinfos *vinfo;
console vc[8] = {
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} ,
{0x07, 0, 0, 0, 0, 0, 0, 0}
static console vc[8] = {
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x00, 0, 0, 0, 0, 0, 0, 0, true}
};
u8 usedvc = 0;
static u8 usedvc = 0;
/*******************************************************************************/
/* Fixe l'attribut courant */
@ -201,7 +201,7 @@ void changemode(u8 mode)
/* Efface la console en cours d'utilisation */
void clearscreen(void)
{
fill(0x00);
fill(vc[usedvc].attrib);
vc[usedvc].cursX=0;
vc[usedvc].cursY=0;
cursor_set(0,0);
@ -279,8 +279,7 @@ void putchar(u8 thechar)
break;
default:
if (thechar >= ' ') {
showchar(vc[usedvc].cursX, vc[usedvc].cursY, thechar,
vc[usedvc].attrib);
showchar(vc[usedvc].cursX, vc[usedvc].cursY, thechar, vc[usedvc].attrib);
vc[usedvc].cursX++;
}
break;
@ -894,7 +893,7 @@ void apply_driver(u8* name)
font2_set=registred[i].pointer->font2_set;
blink_enable=registred[i].pointer->blink_enable;
blink_disable=registred[i].pointer->blink_disable;
setvideo_mode(0x0);
changemode(0x0);
return;
}
i++;
@ -929,7 +928,7 @@ void apply_nextvideomode(void) {
if (cap[index].modenumber==0xFF)
apply_nextdriver();
else
setvideo_mode(cap[index].modenumber);
changemode(cap[index].modenumber);
return;
}
index++;
@ -943,33 +942,53 @@ void initvideo(void)
initdriver();
registerdriver(&fonctions);
apply_driver("VGA");
changemode(0x1);
}
/*******************************/
static u8 space=' ';
void fill(u8 attrib)
{
mem_to_video(space ,0,vinfo->pagesize, 0, false);
mem_to_video(attrib,1,vinfo->pagesize, 0, false);
}
void scroll (u8 lines, u8 attrib)
{
if (vc[usedvc].scroll) {
if (!vinfo->isgraphic)
{
u32 gain=vinfo->currentpitch*lines;
video_to_video(gain,0,vinfo->pagesize-gain, 0);
mem_to_video(space ,vinfo->pagesize-gain-2,gain, 0, false);
mem_to_video(attrib,vinfo->pagesize-gain-1,gain, 0, false);
}
}
else
{
clearscreen();
}
}
void scroll_enable(void)
{
vc[usedvc].scroll=true;
}
void scroll_disable(void)
{
vc[usedvc].scroll=false;
}
void showchar(u16 coordx, u16 coordy, u8 thechar, u8 attrib)
{
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
mem_to_video(thechar,addr , 1, 0, false);
mem_to_video(attrib, addr+1, 1, 0, false);
}
}
u8 getchar (u16 coordx, u16 coordy)

View File

@ -47,7 +47,6 @@ int main(u32 magic, u32 addr)
{
cli();
initvideo();
changemode(0x02);
/* Efface l'ecran */
print("\033[2J\000");