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 TEXTSCREEN 0xB8000 /* debut de la memoire video texte*/
#define GRPHSCREEN 0xA0000 /* debut de la memoire video graphique*/ #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 */ /* Registres VGAs */
#define SEQUENCER 0x3c4 #define SEQUENCER 0x3c4
@ -97,9 +116,9 @@ u8 VGA_setvideo_mode (u8 mode);
u8 *VGA_getvideo_drivername (void); u8 *VGA_getvideo_drivername (void);
u8 *VGA_getvideo_capabilities (void); u8 *VGA_getvideo_capabilities (void);
videoinfos *VGA_getvideo_info (void); videoinfos *VGA_getvideo_info (void);
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 VGA_video_to_mem (u32 src,void *dst, u32 size); u32 VGA_video_to_mem (u32 src,void *dst, u32 size, u8 realsize);
u32 VGA_video_to_video (u32 src,u32 dst, u32 size); u32 VGA_video_to_video (u32 src,u32 dst, u32 size, u8 realsize);
void VGA_wait_vretrace (void); void VGA_wait_vretrace (void);
void VGA_wait_hretrace (void); void VGA_wait_hretrace (void);
void VGA_page_set (u8 page); void VGA_page_set (u8 page);

View File

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

View File

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

117
lib/vga.c
View File

@ -25,10 +25,10 @@ u32 getbase(void)
{ {
u32 base; u32 base;
/*outb(GRAPHICS, 6); /*outb(GRAPHICS, 6);
base = inb(GRAPHICS + 1); base = inb(GRAPHICS + 1);*/
base >>= 2;
base &= 3;*/
base = modes[infos.currentmode].graphic.Miscellaneous_Graphics_Register; base = modes[infos.currentmode].graphic.Miscellaneous_Graphics_Register;
base >>= 2;
base &= 3;
switch (base) { switch (base) {
case 0: case 0:
case 1: case 1:
@ -49,6 +49,8 @@ u32 getbase(void)
/* ERR 0 aucune /* ERR 0 aucune
/* ERR 1 mode non existant */ /* ERR 1 mode non existant */
static u8 realsize;
u8 VGA_setvideo_mode(u8 mode) u8 VGA_setvideo_mode(u8 mode)
{ {
u32 index=0; u32 index=0;
@ -78,23 +80,28 @@ u8 VGA_setvideo_mode(u8 mode)
case 1: case 1:
/* mode N&B */ /* mode N&B */
infos.currentpitch = infos.currentwidth; infos.currentpitch = infos.currentwidth;
realsize=1;
break; break;
case 2: case 2:
/* mode 4 couleurs */ /* mode 4 couleurs */
infos.currentpitch = (infos.currentwidth << 1); infos.currentpitch = (infos.currentwidth << 1);
realsize=2;
break; break;
case 4: case 4:
/* mode 16 couleurs */ /* mode 16 couleurs */
infos.currentpitch = infos.currentwidth; infos.currentpitch = infos.currentwidth;
realsize=4;
break; break;
case 8: case 8:
/* mode 256 couleurs */ /* mode 256 couleurs */
if (modes[index].sequencer.Sequencer_Memory_Mode_Register == 0x0E) { if (modes[index].sequencer.Sequencer_Memory_Mode_Register == 0x0E) {
/* mode chainé (plus rapide mais limité en mémoire) */ /* mode chainé (plus rapide mais limité en mémoire) */
infos.currentpitch = (infos.currentwidth << 3); infos.currentpitch = (infos.currentwidth << 3);
realsize=8;
} else { } else {
/* mode non chainé */ /* mode non chainé */
infos.currentpitch = (infos.currentwidth << 1); infos.currentpitch = (infos.currentwidth << 1);
realsize=9;
} }
break; break;
default: default:
@ -107,25 +114,26 @@ u8 VGA_setvideo_mode(u8 mode)
VGA_font_load(font8x16, 16, 0); VGA_font_load(font8x16, 16, 0);
infos.currentpitch= infos.currentwidth * 2; infos.currentpitch= infos.currentwidth * 2;
infos.pagesize=infos.currentheight * infos.currentpitch; 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(); infos.baseaddress=(modes[index].ctrc.Cursor_Location_High_Register << 8) + modes[index].ctrc.Cursor_Location_Low_Register + getbase();
/* Initialise les registre "divers" */ /* Initialise les registre "divers" */
outb(MISC_WRITE, modes[index].misc); outb(MISC_WRITE, modes[index].misc);
/* Initialise les registre d'etat */ /* Initialise les registre d'etat */
outb(STATE, 0x00); outb(STATE, 0x00);
/* Initialise le séquenceur */ /* Initialise le séquenceur */
outreg(SEQUENCER, modes[index].sequencer, 5); outreg(SEQUENCER, &modes[index].sequencer, 5);
/* Debloque le verouillage des registres controleur CRT */ /* Debloque le verouillage des registres controleur CRT */
outb(CCRT, 0x11); outb(CCRT, 0x11);
outb(CCRT + 1, 0x0E); outb(CCRT + 1, 0x0E);
/* Initialise le controleur CRT */ /* Initialise le controleur CRT */
outreg(CCRT, modes[index].ctrc, 25); outreg(CCRT, &modes[index].ctrc, 25);
/* Initialise le controleur graphique */ /* Initialise le controleur graphique */
outreg(GRAPHICS, modes[index].graphic, 9); outreg(GRAPHICS, &modes[index].graphic, 9);
inb(STATE); inb(STATE);
/* Initialise le controleur d'attributs */ /* Initialise le controleur d'attributs */
outregsame(ATTRIBS, modes[index].attribut, 21); outregsame(ATTRIBS, &modes[index].attribut, 21);
inb(STATE); inb(STATE);
outb(ATTRIBS, 0x20); outb(ATTRIBS, 0x20);
/* Initialise l'adresse des procedures de gestion graphique et les differentes /* Initialise l'adresse des procedures de gestion graphique et les differentes
@ -154,20 +162,105 @@ videoinfos *VGA_getvideo_info (void) {
/*******************************************************************************/ /*******************************************************************************/
/* Effecture un mouvement de la mémoire centrale vers la mémoire video (linéarisée) */ /* 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*/ /* 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) */ /* 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 "video.h"
#include "stdarg.h" #include "stdarg.h"
drivers registred[maxdrivers]; static drivers registred[maxdrivers];
videoinfos *vinfo; static videoinfos *vinfo;
console vc[8] = { static console vc[8] = {
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} , {0x00, 0, 0, 0, 0, 0, 0, 0, true} ,
{0x07, 0, 0, 0, 0, 0, 0, 0} {0x00, 0, 0, 0, 0, 0, 0, 0, true}
}; };
u8 usedvc = 0; static u8 usedvc = 0;
/*******************************************************************************/ /*******************************************************************************/
/* Fixe l'attribut courant */ /* Fixe l'attribut courant */
@ -201,7 +201,7 @@ void changemode(u8 mode)
/* Efface la console en cours d'utilisation */ /* Efface la console en cours d'utilisation */
void clearscreen(void) void clearscreen(void)
{ {
fill(0x00); fill(vc[usedvc].attrib);
vc[usedvc].cursX=0; vc[usedvc].cursX=0;
vc[usedvc].cursY=0; vc[usedvc].cursY=0;
cursor_set(0,0); cursor_set(0,0);
@ -279,8 +279,7 @@ void putchar(u8 thechar)
break; break;
default: default:
if (thechar >= ' ') { if (thechar >= ' ') {
showchar(vc[usedvc].cursX, vc[usedvc].cursY, thechar, showchar(vc[usedvc].cursX, vc[usedvc].cursY, thechar, vc[usedvc].attrib);
vc[usedvc].attrib);
vc[usedvc].cursX++; vc[usedvc].cursX++;
} }
break; break;
@ -894,7 +893,7 @@ void apply_driver(u8* name)
font2_set=registred[i].pointer->font2_set; font2_set=registred[i].pointer->font2_set;
blink_enable=registred[i].pointer->blink_enable; blink_enable=registred[i].pointer->blink_enable;
blink_disable=registred[i].pointer->blink_disable; blink_disable=registred[i].pointer->blink_disable;
setvideo_mode(0x0); changemode(0x0);
return; return;
} }
i++; i++;
@ -929,7 +928,7 @@ void apply_nextvideomode(void) {
if (cap[index].modenumber==0xFF) if (cap[index].modenumber==0xFF)
apply_nextdriver(); apply_nextdriver();
else else
setvideo_mode(cap[index].modenumber); changemode(cap[index].modenumber);
return; return;
} }
index++; index++;
@ -943,33 +942,53 @@ void initvideo(void)
initdriver(); initdriver();
registerdriver(&fonctions); registerdriver(&fonctions);
apply_driver("VGA"); apply_driver("VGA");
changemode(0x1);
} }
/*******************************/ /*******************************/
static u8 space=' ';
void fill(u8 attrib) 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) 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) void scroll_enable(void)
{ {
vc[usedvc].scroll=true;
} }
void scroll_disable(void) void scroll_disable(void)
{ {
vc[usedvc].scroll=false;
} }
void showchar (u16 coordx, u16 coordy, u8 thechar, u8 attrib) 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) u8 getchar (u16 coordx, u16 coordy)

View File

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