From 016b972d972762bcce0401982f5bdd6aa920cfa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Sat, 13 Oct 2018 05:35:08 +0200 Subject: [PATCH] fix: gestion pilotes video, implantation mode texte, correction scrolling --- include/vga.h | 25 +++++++++-- include/video.h | 7 +-- lib/VGA/modes.c | 2 +- lib/vga.c | 117 +++++++++++++++++++++++++++++++++++++++++++----- lib/video.c | 65 +++++++++++++++++---------- system/system.c | 1 - 6 files changed, 174 insertions(+), 43 deletions(-) diff --git a/include/vga.h b/include/vga.h index 53b3f33..a594e68 100755 --- a/include/vga.h +++ b/include/vga.h @@ -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); diff --git a/include/video.h b/include/video.h index 73b85eb..442f65b 100755 --- a/include/video.h +++ b/include/video.h @@ -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); diff --git a/lib/VGA/modes.c b/lib/VGA/modes.c index dadd5c3..1040ff4 100755 --- a/lib/VGA/modes.c +++ b/lib/VGA/modes.c @@ -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}, diff --git a/lib/vga.c b/lib/vga.c index b7b1927..e032758 100755 --- a/lib/vga.c +++ b/lib/vga.c @@ -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,20 +162,105 @@ 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; + + } + } /*******************************************************************************/ diff --git a/lib/video.c b/lib/video.c index 8ac9a79..80f9fa1 100755 --- a/lib/video.c +++ b/lib/video.c @@ -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) +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) diff --git a/system/system.c b/system/system.c index ac3f864..61993cd 100755 --- a/system/system.c +++ b/system/system.c @@ -47,7 +47,6 @@ int main(u32 magic, u32 addr) { cli(); initvideo(); - changemode(0x02); /* Efface l'ecran */ print("\033[2J\000");