VGA: Make use of regs->ebp - now that it is present in 'struct bregs'.
[seabios.git] / vgasrc / vga.c
index e9deea03d1c0f5d0427ae59238b24eec9ba8dc9a..d7a5366da994be1d2d0e3b81c9776d33286e516f 100644 (file)
@@ -7,27 +7,18 @@
 
 
 // TODO:
-//  * commit to git
-//  * Send announcement emails
-//
 //  * introduce "struct vregs", or add ebp to struct bregs.
-//  * Integrate vga_modes/pallete?/line_to_vpti/dac_regs/video_param_table
 //  * define structs for save/restore state
 //  * review correctness of converted asm by comparing with RBIL
-//  * eliminate unimplemented() calls
-//  * eliminate DEBUG defs
-//  * more syntax cleanups
 //  * refactor redundant code into sub-functions
 //  * See if there is a method to the in/out stuff that can be encapsulated.
 //  * remove "biosfn" prefixes
-//  * don't hardcode 0xc000
-//  * add defs for 0xa000/0xb800
 //  * verify all funcs static
 //
+//  * convert vbe/clext code
+//
 //  * separate code into separate files
 //  * extract hw code from bios interfaces
-//
-//  * convert vbe/clext code
 
 #include "bregs.h" // struct bregs
 #include "biosvar.h" // GET_BDA
@@ -42,7 +33,7 @@
 #define DEBUG_VGA_POST 1
 #define DEBUG_VGA_10 3
 
-#define SET_VGA(var, val) SET_FARVAR(0xc000, (var), (val))
+#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val))
 
 
 // ===================================================================
 // ===================================================================
 
 // -------------------------------------------------------------------
-static u8
-find_vga_entry(u8 mode)
-{
-    u8 i;
-    for (i = 0; i <= MODE_MAX; i++)
-        if (GET_GLOBAL(vga_modes[i].svgamode) == mode)
-            return i;
-    return 0xFF;
-}
-
 inline void
 call16_vgaint(u32 eax, u32 ebx)
 {
@@ -92,34 +73,30 @@ memcpy16_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len)
 static void
 biosfn_perform_gray_scale_summing(u16 start, u16 count)
 {
-    u8 r, g, b;
-    u16 i;
-    u16 index;
-
     inb(VGAREG_ACTL_RESET);
     outb(0x00, VGAREG_ACTL_ADDRESS);
 
-    for (index = 0; index < count; index++) {
+    int i;
+    for (i = start; i < start+count; i++) {
         // set read address and switch to read mode
-        outb(start, VGAREG_DAC_READ_ADDRESS);
+        outb(i, VGAREG_DAC_READ_ADDRESS);
         // get 6-bit wide RGB data values
-        r = inb(VGAREG_DAC_DATA);
-        g = inb(VGAREG_DAC_DATA);
-        b = inb(VGAREG_DAC_DATA);
+        u8 r = inb(VGAREG_DAC_DATA);
+        u8 g = inb(VGAREG_DAC_DATA);
+        u8 b = inb(VGAREG_DAC_DATA);
 
         // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
-        i = ((77 * r + 151 * g + 28 * b) + 0x80) >> 8;
+        u16 intensity = ((77 * r + 151 * g + 28 * b) + 0x80) >> 8;
 
-        if (i > 0x3f)
-            i = 0x3f;
+        if (intensity > 0x3f)
+            intensity = 0x3f;
 
         // set write address and switch to write mode
-        outb(start, VGAREG_DAC_WRITE_ADDRESS);
+        outb(i, VGAREG_DAC_WRITE_ADDRESS);
         // write new intensity value
-        outb(i & 0xff, VGAREG_DAC_DATA);
-        outb(i & 0xff, VGAREG_DAC_DATA);
-        outb(i & 0xff, VGAREG_DAC_DATA);
-        start++;
+        outb(intensity & 0xff, VGAREG_DAC_DATA);
+        outb(intensity & 0xff, VGAREG_DAC_DATA);
+        outb(intensity & 0xff, VGAREG_DAC_DATA);
     }
     inb(VGAREG_ACTL_RESET);
     outb(0x20, VGAREG_ACTL_ADDRESS);
@@ -129,40 +106,42 @@ biosfn_perform_gray_scale_summing(u16 start, u16 count)
 static void
 biosfn_set_cursor_shape(u8 CH, u8 CL)
 {
-    u16 cheight, curs, crtc_addr;
-    u8 modeset_ctl;
-
     CH &= 0x3f;
     CL &= 0x1f;
 
-    curs = (CH << 8) + CL;
+    u16 curs = (CH << 8) + CL;
     SET_BDA(cursor_type, curs);
 
-    modeset_ctl = GET_BDA(modeset_ctl);
-    cheight = GET_BDA(char_height);
+    u8 modeset_ctl = GET_BDA(modeset_ctl);
+    u16 cheight = GET_BDA(char_height);
     if ((modeset_ctl & 0x01) && (cheight > 8) && (CL < 8) && (CH < 0x20)) {
-        if (CL != (CH + 1)) {
+        if (CL != (CH + 1))
             CH = ((CH + 1) * cheight / 8) - 1;
-        } else {
+        else
             CH = ((CL + 1) * cheight / 8) - 2;
-        }
         CL = ((CL + 1) * cheight / 8) - 1;
     }
     // CTRC regs 0x0a and 0x0b
-    crtc_addr = GET_BDA(crtc_address);
+    u16 crtc_addr = GET_BDA(crtc_address);
     outb(0x0a, crtc_addr);
     outb(CH, crtc_addr + 1);
     outb(0x0b, crtc_addr);
     outb(CL, crtc_addr + 1);
 }
 
+static u16
+biosfn_get_cursor_shape(u8 page)
+{
+    if (page > 7)
+        return 0;
+    // FIXME should handle VGA 14/16 lines
+    return GET_BDA(cursor_type);
+}
+
 // -------------------------------------------------------------------
 static void
 biosfn_set_cursor_pos(u8 page, u16 cursor)
 {
-    u8 xcurs, ycurs, current;
-    u16 nbcols, nbrows, address, crtc_addr;
-
     // Should not happen...
     if (page > 7)
         return;
@@ -171,67 +150,57 @@ biosfn_set_cursor_pos(u8 page, u16 cursor)
     SET_BDA(cursor_pos[page], cursor);
 
     // Set the hardware cursor
-    current = GET_BDA(video_page);
-    if (page == current) {
-        // Get the dimensions
-        nbcols = GET_BDA(video_cols);
-        nbrows = GET_BDA(video_rows) + 1;
+    u8 current = GET_BDA(video_page);
+    if (page != current)
+        return;
 
-        xcurs = cursor & 0x00ff;
-        ycurs = (cursor & 0xff00) >> 8;
+    // Get the dimensions
+    u16 nbcols = GET_BDA(video_cols);
+    u16 nbrows = GET_BDA(video_rows) + 1;
 
-        // Calculate the address knowing nbcols nbrows and page num
-        address =
-            SCREEN_IO_START(nbcols, nbrows, page) + xcurs + ycurs * nbcols;
-
-        // CRTC regs 0x0e and 0x0f
-        crtc_addr = GET_BDA(crtc_address);
-        outb(0x0e, crtc_addr);
-        outb((address & 0xff00) >> 8, crtc_addr + 1);
-        outb(0x0f, crtc_addr);
-        outb(address & 0x00ff, crtc_addr + 1);
-    }
+    u8 xcurs = cursor & 0x00ff;
+    u8 ycurs = (cursor & 0xff00) >> 8;
+
+    // Calculate the address knowing nbcols nbrows and page num
+    u16 address = SCREEN_IO_START(nbcols, nbrows, page) + xcurs + ycurs * nbcols;
+
+    // CRTC regs 0x0e and 0x0f
+    u16 crtc_addr = GET_BDA(crtc_address);
+    outb(0x0e, crtc_addr);
+    outb((address & 0xff00) >> 8, crtc_addr + 1);
+    outb(0x0f, crtc_addr);
+    outb(address & 0x00ff, crtc_addr + 1);
 }
 
-// -------------------------------------------------------------------
-static void
-biosfn_get_cursor_pos(u8 page, u16 *shape, u16 *pos)
+static u16
+biosfn_get_cursor_pos(u8 page)
 {
-    // Default
-    *shape = 0;
-    *pos = 0;
     if (page > 7)
-        return;
-
+        return 0;
     // FIXME should handle VGA 14/16 lines
-    *shape = GET_BDA(cursor_type);
-    *pos = GET_BDA(cursor_pos[page]);
+    return GET_BDA(cursor_pos[page]);
 }
 
 // -------------------------------------------------------------------
 static void
 biosfn_set_active_page(u8 page)
 {
-    u16 cursor, dummy, crtc_addr;
-    u16 nbcols, nbrows, address;
-    u8 mode, line;
-
     if (page > 7)
         return;
 
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
 
     // Get pos curs pos for the right page
-    biosfn_get_cursor_pos(page, &dummy, &cursor);
+    u16 cursor = biosfn_get_cursor_pos(page);
 
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+    u16 address;
+    if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Get the dimensions
-        nbcols = GET_BDA(video_cols);
-        nbrows = GET_BDA(video_rows) + 1;
+        u16 nbcols = GET_BDA(video_cols);
+        u16 nbrows = GET_BDA(video_rows) + 1;
 
         // Calculate the address knowing nbcols nbrows and page num
         address = SCREEN_MEM_START(nbcols, nbrows, page);
@@ -240,11 +209,12 @@ biosfn_set_active_page(u8 page)
         // Start address
         address = SCREEN_IO_START(nbcols, nbrows, page);
     } else {
-        address = page * GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].slength);
+        struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
+        address = page * GET_GLOBAL(vparam_g->slength);
     }
 
     // CRTC regs 0x0c and 0x0d
-    crtc_addr = GET_BDA(crtc_address);
+    u16 crtc_addr = GET_BDA(crtc_address);
     outb(0x0c, crtc_addr);
     outb((address & 0xff00) >> 8, crtc_addr + 1);
     outb(0x0d, crtc_addr);
@@ -253,9 +223,7 @@ biosfn_set_active_page(u8 page)
     // And change the BIOS page
     SET_BDA(video_page, page);
 
-#ifdef DEBUG
-    printf("Set active page %02x address %04x\n", page, address);
-#endif
+    dprintf(1, "Set active page %02x address %04x\n", page, address);
 
     // Display the cursor, now the page is active
     biosfn_set_cursor_pos(page, cursor);
@@ -264,79 +232,51 @@ biosfn_set_active_page(u8 page)
 static void
 biosfn_set_video_mode(u8 mode)
 {                               // mode: Bit 7 is 1 if no clear screen
-    // Should we clear the screen ?
-    u8 noclearmem = mode & 0x80;
-    u8 line, mmask, *palette, vpti;
-    u16 i, twidth, theightm1, cheight;
-    u8 modeset_ctl, video_ctl, vga_switches;
-
     if (CONFIG_CIRRUS)
         cirrus_set_video_mode(mode);
 
-#ifdef VBE
-    if (vbe_has_vbe_display())
-        dispi_set_enable(VBE_DISPI_DISABLED);
-#endif
+    if (CONFIG_VBE)
+        if (vbe_has_vbe_display())
+            dispi_set_enable(VBE_DISPI_DISABLED);
 
     // The real mode
+    u8 noclearmem = mode & 0x80;
     mode = mode & 0x7f;
 
     // find the entry in the video modes
-    line = find_vga_entry(mode);
-
-#ifdef DEBUG
-    printf("mode search %02x found line %02x\n", mode, line);
-#endif
-
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(mode);
+    dprintf(1, "mode search %02x found %p\n", mode, vmode_g);
+    if (!vmode_g)
         return;
 
-    vpti = GET_GLOBAL(line_to_vpti[line]);
-    twidth = GET_GLOBAL(video_param_table[vpti].twidth);
-    theightm1 = GET_GLOBAL(video_param_table[vpti].theightm1);
-    cheight = GET_GLOBAL(video_param_table[vpti].cheight);
-
-    // Read the bios vga control
-    video_ctl = GET_BDA(video_ctl);
-
-    // Read the bios vga switches
-    vga_switches = GET_BDA(video_switches);
+    struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
+    u16 twidth = GET_GLOBAL(vparam_g->twidth);
+    u16 theightm1 = GET_GLOBAL(vparam_g->theightm1);
+    u16 cheight = GET_GLOBAL(vparam_g->cheight);
 
     // Read the bios mode set control
-    modeset_ctl = GET_BDA(modeset_ctl);
+    u8 modeset_ctl = GET_BDA(modeset_ctl);
 
     // Then we know the number of lines
 // FIXME
 
     // if palette loading (bit 3 of modeset ctl = 0)
     if ((modeset_ctl & 0x08) == 0) {    // Set the PEL mask
-        outb(GET_GLOBAL(vga_modes[line].pelmask), VGAREG_PEL_MASK);
+        outb(GET_GLOBAL(vmode_g->pelmask), VGAREG_PEL_MASK);
 
         // Set the whole dac always, from 0
         outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
 
         // From which palette
-        switch (GET_GLOBAL(vga_modes[line].dacmodel)) {
-        default:
-        case 0:
-            palette = palette0;
-            break;
-        case 1:
-            palette = palette1;
-            break;
-        case 2:
-            palette = palette2;
-            break;
-        case 3:
-            palette = palette3;
-            break;
-        }
+        u8 *palette_g = GET_GLOBAL(vmode_g->dac);
+        u16 palsize = GET_GLOBAL(vmode_g->dacsize);
         // Always 256*3 values
+        u16 i;
         for (i = 0; i < 0x0100; i++) {
-            if (i <= GET_GLOBAL(dac_regs[GET_GLOBAL(vga_modes[line].dacmodel)])) {
-                outb(GET_GLOBAL(palette[(i * 3) + 0]), VGAREG_DAC_DATA);
-                outb(GET_GLOBAL(palette[(i * 3) + 1]), VGAREG_DAC_DATA);
-                outb(GET_GLOBAL(palette[(i * 3) + 2]), VGAREG_DAC_DATA);
+            if (i <= palsize) {
+                outb(GET_GLOBAL(palette_g[(i * 3) + 0]), VGAREG_DAC_DATA);
+                outb(GET_GLOBAL(palette_g[(i * 3) + 1]), VGAREG_DAC_DATA);
+                outb(GET_GLOBAL(palette_g[(i * 3) + 2]), VGAREG_DAC_DATA);
             } else {
                 outb(0, VGAREG_DAC_DATA);
                 outb(0, VGAREG_DAC_DATA);
@@ -350,10 +290,10 @@ biosfn_set_video_mode(u8 mode)
     inb(VGAREG_ACTL_RESET);
 
     // Set Attribute Ctl
+    u16 i;
     for (i = 0; i <= 0x13; i++) {
         outb(i, VGAREG_ACTL_ADDRESS);
-        outb(GET_GLOBAL(video_param_table[vpti].actl_regs[i])
-             , VGAREG_ACTL_WRITE_DATA);
+        outb(GET_GLOBAL(vparam_g->actl_regs[i]), VGAREG_ACTL_WRITE_DATA);
     }
     outb(0x14, VGAREG_ACTL_ADDRESS);
     outb(0x00, VGAREG_ACTL_WRITE_DATA);
@@ -363,20 +303,18 @@ biosfn_set_video_mode(u8 mode)
     outb(0x03, VGAREG_SEQU_DATA);
     for (i = 1; i <= 4; i++) {
         outb(i, VGAREG_SEQU_ADDRESS);
-        outb(GET_GLOBAL(video_param_table[vpti].sequ_regs[i - 1])
-             , VGAREG_SEQU_DATA);
+        outb(GET_GLOBAL(vparam_g->sequ_regs[i - 1]), VGAREG_SEQU_DATA);
     }
 
     // Set Grafx Ctl
     for (i = 0; i <= 8; i++) {
         outb(i, VGAREG_GRDC_ADDRESS);
-        outb(GET_GLOBAL(video_param_table[vpti].grdc_regs[i])
-             , VGAREG_GRDC_DATA);
+        outb(GET_GLOBAL(vparam_g->grdc_regs[i]), VGAREG_GRDC_DATA);
     }
 
     // Set CRTC address VGA or MDA
     u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
-    if (GET_GLOBAL(vga_modes[line].memmodel) == MTEXT)
+    if (GET_GLOBAL(vmode_g->memmodel) == MTEXT)
         crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
 
     // Disable CRTC write protection
@@ -384,30 +322,27 @@ biosfn_set_video_mode(u8 mode)
     // Set CRTC regs
     for (i = 0; i <= 0x18; i++) {
         outb(i, crtc_addr);
-        outb(GET_GLOBAL(video_param_table[vpti].crtc_regs[i]), crtc_addr + 1);
+        outb(GET_GLOBAL(vparam_g->crtc_regs[i]), crtc_addr + 1);
     }
 
     // Set the misc register
-    outb(GET_GLOBAL(video_param_table[vpti].miscreg), VGAREG_WRITE_MISC_OUTPUT);
+    outb(GET_GLOBAL(vparam_g->miscreg), VGAREG_WRITE_MISC_OUTPUT);
 
     // Enable video
     outb(0x20, VGAREG_ACTL_ADDRESS);
     inb(VGAREG_ACTL_RESET);
 
     if (noclearmem == 0x00) {
-        if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
-            memset16_far(GET_GLOBAL(vga_modes[line].sstart)
-                         , 0, 0x0720, 0x4000); // 32k
+        if (GET_GLOBAL(vmode_g->class) == TEXT) {
+            memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024);
         } else {
             if (mode < 0x0d) {
-                memset16_far(GET_GLOBAL(vga_modes[line].sstart)
-                             , 0, 0x0000, 0x4000);     // 32k
+                memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024);
             } else {
                 outb(0x02, VGAREG_SEQU_ADDRESS);
-                mmask = inb(VGAREG_SEQU_DATA);
+                u8 mmask = inb(VGAREG_SEQU_DATA);
                 outb(0x0f, VGAREG_SEQU_DATA);   // all planes
-                memset16_far(GET_GLOBAL(vga_modes[line].sstart)
-                             , 0, 0x0000, 0x8000);     // 64k
+                memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024);
                 outb(mmask, VGAREG_SEQU_DATA);
             }
         }
@@ -415,7 +350,7 @@ biosfn_set_video_mode(u8 mode)
     // Set the BIOS mem
     SET_BDA(video_mode, mode);
     SET_BDA(video_cols, twidth);
-    SET_BDA(video_pagesize, GET_GLOBAL(video_param_table[vpti].slength));
+    SET_BDA(video_pagesize, GET_GLOBAL(vparam_g->slength));
     SET_BDA(crtc_address, crtc_addr);
     SET_BDA(video_rows, theightm1);
     SET_BDA(char_height, cheight);
@@ -426,14 +361,14 @@ biosfn_set_video_mode(u8 mode)
     // FIXME We nearly have the good tables. to be reworked
     SET_BDA(dcc_index, 0x08);   // 8 is VGA should be ok for now
     SET_BDA(video_savetable_ptr, (u32)video_save_pointer_table);
-    SET_BDA(video_savetable_seg, 0xc000);
+    SET_BDA(video_savetable_seg, get_global_seg());
 
     // FIXME
     SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
     SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
 
     // Set cursor shape
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+    if (GET_GLOBAL(vmode_g->class) == TEXT)
         biosfn_set_cursor_shape(0x06, 0x07);
     // Set cursor pos for page 0..7
     for (i = 0; i < 8; i++)
@@ -443,22 +378,22 @@ biosfn_set_video_mode(u8 mode)
     biosfn_set_active_page(0x00);
 
     // Write the fonts in memory
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+    if (GET_GLOBAL(vmode_g->class) == TEXT) {
         call16_vgaint(0x1104, 0);
         call16_vgaint(0x1103, 0);
     }
     // Set the ints 0x1F and 0x43
-    SET_IVT(0x1f, 0xC000, (u32)&vgafont8[128 * 8]);
+    SET_IVT(0x1f, get_global_seg(), (u32)&vgafont8[128 * 8]);
 
     switch (cheight) {
     case 8:
-        SET_IVT(0x43, 0xC000, (u32)vgafont8);
+        SET_IVT(0x43, get_global_seg(), (u32)vgafont8);
         break;
     case 14:
-        SET_IVT(0x43, 0xC000, (u32)vgafont14);
+        SET_IVT(0x43, get_global_seg(), (u32)vgafont14);
         break;
     case 16:
-        SET_IVT(0x43, 0xC000, (u32)vgafont16);
+        SET_IVT(0x43, get_global_seg(), (u32)vgafont16);
         break;
     }
 }
@@ -473,8 +408,8 @@ vgamem_copy_pl4(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
     outw(0x0105, VGAREG_GRDC_ADDRESS);
     u8 i;
     for (i = 0; i < cheight; i++)
-        memcpy_far(0xa000, (void*)(dest + i * nbcols)
-                   , 0xa000, (void*)(src + i * nbcols), cols);
+        memcpy_far(SEG_GRAPH, (void*)(dest + i * nbcols)
+                   , SEG_GRAPH, (void*)(src + i * nbcols), cols);
     outw(0x0005, VGAREG_GRDC_ADDRESS);
 }
 
@@ -487,7 +422,7 @@ vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
     outw(0x0205, VGAREG_GRDC_ADDRESS);
     u8 i;
     for (i = 0; i < cheight; i++)
-        memset_far(0xa000, (void*)(dest + i * nbcols), attr, cols);
+        memset_far(SEG_GRAPH, (void*)(dest + i * nbcols), attr, cols);
     outw(0x0005, VGAREG_GRDC_ADDRESS);
 }
 
@@ -501,12 +436,12 @@ vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols,
     u8 i;
     for (i = 0; i < cheight; i++)
         if (i & 1)
-            memcpy_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
-                       , 0xb800, (void*)(0x2000 + src + (i >> 1) * nbcols)
+            memcpy_far(SEG_CTEXT, (void*)(0x2000 + dest + (i >> 1) * nbcols)
+                       , SEG_CTEXT, (void*)(0x2000 + src + (i >> 1) * nbcols)
                        , cols);
         else
-            memcpy_far(0xb800, (void*)(dest + (i >> 1) * nbcols)
-                       , 0xb800, (void*)(src + (i >> 1) * nbcols), cols);
+            memcpy_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols)
+                       , SEG_CTEXT, (void*)(src + (i >> 1) * nbcols), cols);
 }
 
 // -------------------------------------------------------------------
@@ -518,10 +453,10 @@ vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight,
     u8 i;
     for (i = 0; i < cheight; i++)
         if (i & 1)
-            memset_far(0xb800, (void*)(0x2000 + dest + (i >> 1) * nbcols)
+            memset_far(SEG_CTEXT, (void*)(0x2000 + dest + (i >> 1) * nbcols)
                        , attr, cols);
         else
-            memset_far(0xb800, (void*)(dest + (i >> 1) * nbcols), attr, cols);
+            memset_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols), attr, cols);
 }
 
 // -------------------------------------------------------------------
@@ -530,24 +465,19 @@ biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page,
               u8 dir)
 {
     // page == 0xFF if current
-
-    u8 mode, line, cheight, bpp, cols;
-    u16 nbcols, nbrows, i;
-
     if (rul > rlr)
         return;
     if (cul > clr)
         return;
 
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
 
     // Get the dimensions
-    nbrows = GET_BDA(video_rows) + 1;
-    nbcols = GET_BDA(video_cols);
+    u16 nbrows = GET_BDA(video_rows) + 1;
+    u16 nbcols = GET_BDA(video_cols);
 
     // Get the current page
     if (page == 0xFF)
@@ -559,129 +489,130 @@ biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page,
         clr = nbcols - 1;
     if (nblines > nbrows)
         nblines = 0;
-    cols = clr - cul + 1;
+    u8 cols = clr - cul + 1;
 
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+    if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page));
-#ifdef DEBUG
-        printf("Scroll, address %04x (%04x %04x %02x)\n", address, nbrows,
-               nbcols, page);
-#endif
+        void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page));
+        dprintf(3, "Scroll, address %p (%d %d %02x)\n"
+                , address_far, nbrows, nbcols, page);
 
         if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
             && clr == nbcols - 1) {
-            memset16_far(GET_GLOBAL(vga_modes[line].sstart), address
-                         , (u16)attr * 0x100 + ' ', nbrows * nbcols);
+            memset16_far(GET_GLOBAL(vmode_g->sstart), address_far
+                         , (u16)attr * 0x100 + ' ', nbrows * nbcols * 2);
         } else {                // if Scroll up
             if (dir == SCROLL_UP) {
-                for (i = rul; i <= rlr; i++) {
+                u16 i;
+                for (i = rul; i <= rlr; i++)
                     if ((i + nblines > rlr) || (nblines == 0))
-                        memset16_far(GET_GLOBAL(vga_modes[line].sstart)
-                                     , address + (i * nbcols + cul) * 2
-                                     , (u16)attr * 0x100 + ' ', cols);
+                        memset16_far(GET_GLOBAL(vmode_g->sstart)
+                                     , address_far + (i * nbcols + cul) * 2
+                                     , (u16)attr * 0x100 + ' ', cols * 2);
                     else
-                        memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
-                                     , address + (i * nbcols + cul) * 2
-                                     , GET_GLOBAL(vga_modes[line].sstart)
+                        memcpy16_far(GET_GLOBAL(vmode_g->sstart)
+                                     , address_far + (i * nbcols + cul) * 2
+                                     , GET_GLOBAL(vmode_g->sstart)
                                      , (void*)(((i + nblines) * nbcols + cul) * 2)
-                                     , cols);
-                }
+                                     , cols * 2);
             } else {
+                u16 i;
                 for (i = rlr; i >= rul; i--) {
                     if ((i < rul + nblines) || (nblines == 0))
-                        memset16_far(GET_GLOBAL(vga_modes[line].sstart)
-                                     , address + (i * nbcols + cul) * 2
-                                     , (u16)attr * 0x100 + ' ', cols);
+                        memset16_far(GET_GLOBAL(vmode_g->sstart)
+                                     , address_far + (i * nbcols + cul) * 2
+                                     , (u16)attr * 0x100 + ' ', cols * 2);
                     else
-                        memcpy16_far(GET_GLOBAL(vga_modes[line].sstart)
-                                     , address + (i * nbcols + cul) * 2
-                                     , GET_GLOBAL(vga_modes[line].sstart)
+                        memcpy16_far(GET_GLOBAL(vmode_g->sstart)
+                                     , address_far + (i * nbcols + cul) * 2
+                                     , GET_GLOBAL(vmode_g->sstart)
                                      , (void*)(((i - nblines) * nbcols + cul) * 2)
-                                     , cols);
+                                     , cols * 2);
                     if (i > rlr)
                         break;
                 }
             }
         }
-    } else {
-        // FIXME gfx mode not complete
-        cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
-        switch (GET_GLOBAL(vga_modes[line].memmodel)) {
-        case PLANAR4:
-        case PLANAR1:
-            if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
-                && clr == nbcols - 1) {
-                outw(0x0205, VGAREG_GRDC_ADDRESS);
-                memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
-                           nbrows * nbcols * cheight);
-                outw(0x0005, VGAREG_GRDC_ADDRESS);
-            } else {            // if Scroll up
-                if (dir == SCROLL_UP) {
-                    for (i = rul; i <= rlr; i++) {
-                        if ((i + nblines > rlr) || (nblines == 0))
-                            vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
-                                            attr);
-                        else
-                            vgamem_copy_pl4(cul, i + nblines, i, cols,
-                                            nbcols, cheight);
-                    }
-                } else {
-                    for (i = rlr; i >= rul; i--) {
-                        if ((i < rul + nblines) || (nblines == 0))
-                            vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
-                                            attr);
-                        else
-                            vgamem_copy_pl4(cul, i, i - nblines, cols,
-                                            nbcols, cheight);
-                        if (i > rlr)
-                            break;
-                    }
+        return;
+    }
+
+    // FIXME gfx mode not complete
+    struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
+    u8 cheight = GET_GLOBAL(vparam_g->cheight);
+    switch (GET_GLOBAL(vmode_g->memmodel)) {
+    case PLANAR4:
+    case PLANAR1:
+        if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
+            && clr == nbcols - 1) {
+            outw(0x0205, VGAREG_GRDC_ADDRESS);
+            memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr,
+                       nbrows * nbcols * cheight);
+            outw(0x0005, VGAREG_GRDC_ADDRESS);
+        } else {            // if Scroll up
+            if (dir == SCROLL_UP) {
+                u16 i;
+                for (i = rul; i <= rlr; i++)
+                    if ((i + nblines > rlr) || (nblines == 0))
+                        vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
+                                        attr);
+                    else
+                        vgamem_copy_pl4(cul, i + nblines, i, cols,
+                                        nbcols, cheight);
+            } else {
+                u16 i;
+                for (i = rlr; i >= rul; i--) {
+                    if ((i < rul + nblines) || (nblines == 0))
+                        vgamem_fill_pl4(cul, i, cols, nbcols, cheight,
+                                        attr);
+                    else
+                        vgamem_copy_pl4(cul, i, i - nblines, cols,
+                                        nbcols, cheight);
+                    if (i > rlr)
+                        break;
                 }
             }
-            break;
-        case CGA:
-            bpp = GET_GLOBAL(vga_modes[line].pixbits);
-            if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
-                && clr == nbcols - 1) {
-                memset_far(GET_GLOBAL(vga_modes[line].sstart), 0, attr,
-                           nbrows * nbcols * cheight * bpp);
+        }
+        break;
+    case CGA: {
+        u8 bpp = GET_GLOBAL(vmode_g->pixbits);
+        if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1
+            && clr == nbcols - 1) {
+            memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr,
+                       nbrows * nbcols * cheight * bpp);
+        } else {
+            if (bpp == 2) {
+                cul <<= 1;
+                cols <<= 1;
+                nbcols <<= 1;
+            }
+            // if Scroll up
+            if (dir == SCROLL_UP) {
+                u16 i;
+                for (i = rul; i <= rlr; i++)
+                    if ((i + nblines > rlr) || (nblines == 0))
+                        vgamem_fill_cga(cul, i, cols, nbcols, cheight,
+                                        attr);
+                    else
+                        vgamem_copy_cga(cul, i + nblines, i, cols,
+                                        nbcols, cheight);
             } else {
-                if (bpp == 2) {
-                    cul <<= 1;
-                    cols <<= 1;
-                    nbcols <<= 1;
-                }
-                // if Scroll up
-                if (dir == SCROLL_UP) {
-                    for (i = rul; i <= rlr; i++) {
-                        if ((i + nblines > rlr) || (nblines == 0))
-                            vgamem_fill_cga(cul, i, cols, nbcols, cheight,
-                                            attr);
-                        else
-                            vgamem_copy_cga(cul, i + nblines, i, cols,
-                                            nbcols, cheight);
-                    }
-                } else {
-                    for (i = rlr; i >= rul; i--) {
-                        if ((i < rul + nblines) || (nblines == 0))
-                            vgamem_fill_cga(cul, i, cols, nbcols, cheight,
-                                            attr);
-                        else
-                            vgamem_copy_cga(cul, i, i - nblines, cols,
-                                            nbcols, cheight);
-                        if (i > rlr)
-                            break;
-                    }
+                u16 i;
+                for (i = rlr; i >= rul; i--) {
+                    if ((i < rul + nblines) || (nblines == 0))
+                        vgamem_fill_cga(cul, i, cols, nbcols, cheight,
+                                        attr);
+                    else
+                        vgamem_copy_cga(cul, i, i - nblines, cols,
+                                        nbcols, cheight);
+                    if (i > rlr)
+                        break;
                 }
             }
-            break;
-#ifdef DEBUG
-        default:
-            printf("Scroll in graphics mode ");
-            unimplemented();
-#endif
         }
+        break;
+    }
+    default:
+        dprintf(1, "Scroll in graphics mode\n");
     }
 }
 
@@ -689,36 +620,29 @@ biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page,
 static void
 biosfn_read_char_attr(u8 page, u16 *car)
 {
-    u8 xcurs, ycurs, mode, line;
-    u16 nbcols, nbrows;
-    u16 cursor, dummy;
-
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
 
     // Get the cursor pos for the page
-    biosfn_get_cursor_pos(page, &dummy, &cursor);
-    xcurs = cursor & 0x00ff;
-    ycurs = (cursor & 0xff00) >> 8;
+    u16 cursor = biosfn_get_cursor_pos(page);
+    u8 xcurs = cursor & 0x00ff;
+    u8 ycurs = (cursor & 0xff00) >> 8;
 
     // Get the dimensions
-    nbrows = GET_BDA(video_rows) + 1;
-    nbcols = GET_BDA(video_cols);
+    u16 nbrows = GET_BDA(video_rows) + 1;
+    u16 nbcols = GET_BDA(video_cols);
 
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+    if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        u16 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                               + (xcurs + ycurs * nbcols) * 2);
+        u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                                   + (xcurs + ycurs * nbcols) * 2);
 
-        *car = GET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address);
+        *car = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far);
     } else {
         // FIXME gfx mode
-#ifdef DEBUG
-        unimplemented();
-#endif
+        dprintf(1, "Read char in graphics mode\n");
     }
 }
 
@@ -727,38 +651,37 @@ static void
 write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols,
                    u8 cheight)
 {
-    u8 i, j, mask;
-    u8 *fdata;
-    u16 addr, src;
-
+    u8 *fdata_g;
     switch (cheight) {
     case 14:
-        fdata = vgafont14;
+        fdata_g = vgafont14;
         break;
     case 16:
-        fdata = vgafont16;
+        fdata_g = vgafont16;
         break;
     default:
-        fdata = vgafont8;
+        fdata_g = vgafont8;
     }
-    addr = xcurs + ycurs * cheight * nbcols;
-    src = car * cheight;
+    u16 addr = xcurs + ycurs * cheight * nbcols;
+    u16 src = car * cheight;
     outw(0x0f02, VGAREG_SEQU_ADDRESS);
     outw(0x0205, VGAREG_GRDC_ADDRESS);
     if (attr & 0x80)
         outw(0x1803, VGAREG_GRDC_ADDRESS);
     else
         outw(0x0003, VGAREG_GRDC_ADDRESS);
+    u8 i;
     for (i = 0; i < cheight; i++) {
-        u8 *dest = (void*)(addr + i * nbcols);
+        u8 *dest_far = (void*)(addr + i * nbcols);
+        u8 j;
         for (j = 0; j < 8; j++) {
-            mask = 0x80 >> j;
+            u8 mask = 0x80 >> j;
             outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
-            GET_FARVAR(0xa000, *dest);
-            if (GET_GLOBAL(fdata[src + i]) & mask)
-                SET_FARVAR(0xa000, *dest, attr & 0x0f);
+            GET_FARVAR(SEG_GRAPH, *dest_far);
+            if (GET_GLOBAL(fdata_g[src + i]) & mask)
+                SET_FARVAR(SEG_GRAPH, *dest_far, attr & 0x0f);
             else
-                SET_FARVAR(0xa000, *dest, 0x00);
+                SET_FARVAR(SEG_GRAPH, *dest_far, 0x00);
         }
     }
     outw(0xff08, VGAREG_GRDC_ADDRESS);
@@ -770,22 +693,22 @@ write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols,
 static void
 write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
 {
-    u8 *fdata = vgafont8;
+    u8 *fdata_g = vgafont8;
     u16 addr = (xcurs * bpp) + ycurs * 320;
     u16 src = car * 8;
     u8 i;
     for (i = 0; i < 8; i++) {
-        u8 *dest = (void*)(addr + (i >> 1) * 80);
+        u8 *dest_far = (void*)(addr + (i >> 1) * 80);
         if (i & 1)
-            dest += 0x2000;
+            dest_far += 0x2000;
         u8 mask = 0x80;
         if (bpp == 1) {
             u8 data = 0;
             if (attr & 0x80)
-                data = GET_FARVAR(0xb800, *dest);
+                data = GET_FARVAR(SEG_CTEXT, *dest_far);
             u8 j;
             for (j = 0; j < 8; j++) {
-                if (GET_GLOBAL(fdata[src + i]) & mask) {
+                if (GET_GLOBAL(fdata_g[src + i]) & mask) {
                     if (attr & 0x80)
                         data ^= (attr & 0x01) << (7 - j);
                     else
@@ -793,15 +716,15 @@ write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
                 }
                 mask >>= 1;
             }
-            SET_FARVAR(0xb800, *dest, data);
+            SET_FARVAR(SEG_CTEXT, *dest_far, data);
         } else {
             while (mask > 0) {
                 u8 data = 0;
                 if (attr & 0x80)
-                    data = GET_FARVAR(0xb800, *dest);
+                    data = GET_FARVAR(SEG_CTEXT, *dest_far);
                 u8 j;
                 for (j = 0; j < 4; j++) {
-                    if (GET_GLOBAL(fdata[src + i]) & mask) {
+                    if (GET_GLOBAL(fdata_g[src + i]) & mask) {
                         if (attr & 0x80)
                             data ^= (attr & 0x03) << ((3 - j) * 2);
                         else
@@ -809,8 +732,8 @@ write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
                     }
                     mask >>= 1;
                 }
-                SET_FARVAR(0xb800, *dest, data);
-                dest += 1;
+                SET_FARVAR(SEG_CTEXT, *dest_far, data);
+                dest_far += 1;
             }
         }
     }
@@ -820,19 +743,19 @@ write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
 static void
 write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols)
 {
-    u8 *fdata = vgafont8;
+    u8 *fdata_g = vgafont8;
     u16 addr = xcurs * 8 + ycurs * nbcols * 64;
     u16 src = car * 8;
     u8 i;
     for (i = 0; i < 8; i++) {
-        u8 *dest = (void*)(addr + i * nbcols * 8);
+        u8 *dest_far = (void*)(addr + i * nbcols * 8);
         u8 mask = 0x80;
         u8 j;
         for (j = 0; j < 8; j++) {
             u8 data = 0x00;
-            if (GET_GLOBAL(fdata[src + i]) & mask)
+            if (GET_GLOBAL(fdata_g[src + i]) & mask)
                 data = attr;
-            SET_FARVAR(0xa000, dest[j], data);
+            SET_FARVAR(SEG_GRAPH, dest_far[j], data);
             mask >>= 1;
         }
     }
@@ -842,56 +765,48 @@ write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols)
 static void
 biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count)
 {
-    u8 cheight, xcurs, ycurs, mode, line, bpp;
-    u16 nbcols, nbrows;
-    u16 cursor, dummy;
-
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
 
     // Get the cursor pos for the page
-    biosfn_get_cursor_pos(page, &dummy, &cursor);
-    xcurs = cursor & 0x00ff;
-    ycurs = (cursor & 0xff00) >> 8;
+    u16 cursor = biosfn_get_cursor_pos(page);
+    u8 xcurs = cursor & 0x00ff;
+    u8 ycurs = (cursor & 0xff00) >> 8;
 
     // Get the dimensions
-    nbrows = GET_BDA(video_rows) + 1;
-    nbcols = GET_BDA(video_cols);
+    u16 nbrows = GET_BDA(video_rows) + 1;
+    u16 nbcols = GET_BDA(video_cols);
 
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+    if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        void *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                                + (xcurs + ycurs * nbcols) * 2);
+        void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                                    + (xcurs + ycurs * nbcols) * 2);
 
-        dummy = ((u16)attr << 8) + car;
-        memset16_far(GET_GLOBAL(vga_modes[line].sstart), address, dummy, count);
-    } else {
-        // FIXME gfx mode not complete
-        cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
-        bpp = GET_GLOBAL(vga_modes[line].pixbits);
-        while ((count-- > 0) && (xcurs < nbcols)) {
-            switch (GET_GLOBAL(vga_modes[line].memmodel)) {
-            case PLANAR4:
-            case PLANAR1:
-                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
-                                   cheight);
-                break;
-            case CGA:
-                write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
-                break;
-            case LINEAR8:
-                write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
-                break;
-#ifdef DEBUG
-            default:
-                unimplemented();
-#endif
-            }
-            xcurs++;
+        u16 dummy = ((u16)attr << 8) + car;
+        memset16_far(GET_GLOBAL(vmode_g->sstart), address_far, dummy, count * 2);
+        return;
+    }
+
+    // FIXME gfx mode not complete
+    struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
+    u8 cheight = GET_GLOBAL(vparam_g->cheight);
+    u8 bpp = GET_GLOBAL(vmode_g->pixbits);
+    while ((count-- > 0) && (xcurs < nbcols)) {
+        switch (GET_GLOBAL(vmode_g->memmodel)) {
+        case PLANAR4:
+        case PLANAR1:
+            write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight);
+            break;
+        case CGA:
+            write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+            break;
+        case LINEAR8:
+            write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+            break;
         }
+        xcurs++;
     }
 }
 
@@ -899,62 +814,52 @@ biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count)
 static void
 biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count)
 {
-    u8 cheight, xcurs, ycurs, mode, line, bpp;
-    u16 nbcols, nbrows;
-    u16 cursor, dummy;
-
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
 
     // Get the cursor pos for the page
-    biosfn_get_cursor_pos(page, &dummy, &cursor);
-    xcurs = cursor & 0x00ff;
-    ycurs = (cursor & 0xff00) >> 8;
+    u16 cursor = biosfn_get_cursor_pos(page);
+    u8 xcurs = cursor & 0x00ff;
+    u8 ycurs = (cursor & 0xff00) >> 8;
 
     // Get the dimensions
-    nbrows = GET_BDA(video_rows) + 1;
-    nbcols = GET_BDA(video_cols);
+    u16 nbrows = GET_BDA(video_rows) + 1;
+    u16 nbcols = GET_BDA(video_cols);
 
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+    if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                              + (xcurs + ycurs * nbcols) * 2);
+        u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                                  + (xcurs + ycurs * nbcols) * 2);
         while (count-- > 0) {
-            SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), *address, car);
-            address += 2;
+            SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far, car);
+            address_far += 2;
         }
-    } else {
-        // FIXME gfx mode not complete
-        cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
-        bpp = GET_GLOBAL(vga_modes[line].pixbits);
-        while ((count-- > 0) && (xcurs < nbcols)) {
-            switch (GET_GLOBAL(vga_modes[line].memmodel)) {
-            case PLANAR4:
-            case PLANAR1:
-                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
-                                   cheight);
-                break;
-            case CGA:
-                write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
-                break;
-            case LINEAR8:
-                write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
-                break;
-#ifdef DEBUG
-            default:
-                unimplemented();
-#endif
-            }
-            xcurs++;
+        return;
+    }
+
+    // FIXME gfx mode not complete
+    struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
+    u8 cheight = GET_GLOBAL(vparam_g->cheight);
+    u8 bpp = GET_GLOBAL(vmode_g->pixbits);
+    while ((count-- > 0) && (xcurs < nbcols)) {
+        switch (GET_GLOBAL(vmode_g->memmodel)) {
+        case PLANAR4:
+        case PLANAR1:
+            write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight);
+            break;
+        case CGA:
+            write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+            break;
+        case LINEAR8:
+            write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+            break;
         }
+        xcurs++;
     }
 }
 
-
-
 // -------------------------------------------------------------------
 static void
 biosfn_set_border_color(struct bregs *regs)
@@ -964,7 +869,7 @@ biosfn_set_border_color(struct bregs *regs)
     u8 al = regs->bl & 0x0f;
     if (al & 0x08)
         al += 0x08;
-    outb(al, VGAREG_ACTL_ADDRESS);
+    outb(al, VGAREG_ACTL_WRITE_DATA);
     u8 bl = regs->bl & 0x10;
 
     int i;
@@ -974,7 +879,7 @@ biosfn_set_border_color(struct bregs *regs)
         al = inb(VGAREG_ACTL_READ_DATA);
         al &= 0xef;
         al |= bl;
-        outb(al, VGAREG_ACTL_ADDRESS);
+        outb(al, VGAREG_ACTL_WRITE_DATA);
     }
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
@@ -991,7 +896,7 @@ biosfn_set_palette(struct bregs *regs)
         u8 al = inb(VGAREG_ACTL_READ_DATA);
         al &= 0xfe;
         al |= bl;
-        outb(al, VGAREG_ACTL_ADDRESS);
+        outb(al, VGAREG_ACTL_WRITE_DATA);
     }
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
@@ -1000,41 +905,38 @@ biosfn_set_palette(struct bregs *regs)
 static void
 biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX)
 {
-    u8 mask, attr, data;
-
     // Get the mode
-    u8 mode = GET_BDA(video_mode);
-    u8 line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+    if (GET_GLOBAL(vmode_g->class) == TEXT)
         return;
 
-    u8 *addr;
-    switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+    u8 *addr_far, mask, attr, data;
+    switch (GET_GLOBAL(vmode_g->memmodel)) {
     case PLANAR4:
     case PLANAR1:
-        addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
+        addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols));
         mask = 0x80 >> (CX & 0x07);
         outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
         outw(0x0205, VGAREG_GRDC_ADDRESS);
-        data = GET_FARVAR(0xa000, *addr);
+        data = GET_FARVAR(SEG_GRAPH, *addr_far);
         if (AL & 0x80)
             outw(0x1803, VGAREG_GRDC_ADDRESS);
-        SET_FARVAR(0xa000, *addr, AL);
+        SET_FARVAR(SEG_GRAPH, *addr_far, AL);
         outw(0xff08, VGAREG_GRDC_ADDRESS);
         outw(0x0005, VGAREG_GRDC_ADDRESS);
         outw(0x0003, VGAREG_GRDC_ADDRESS);
         break;
     case CGA:
-        if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
-            addr = (void*)((CX >> 2) + (DX >> 1) * 80);
+        if (GET_GLOBAL(vmode_g->pixbits) == 2)
+            addr_far = (void*)((CX >> 2) + (DX >> 1) * 80);
         else
-            addr = (void*)((CX >> 3) + (DX >> 1) * 80);
+            addr_far = (void*)((CX >> 3) + (DX >> 1) * 80);
         if (DX & 1)
-            addr += 0x2000;
-        data = GET_FARVAR(0xb800, *addr);
-        if (GET_GLOBAL(vga_modes[line].pixbits) == 2) {
+            addr_far += 0x2000;
+        data = GET_FARVAR(SEG_CTEXT, *addr_far);
+        if (GET_GLOBAL(vmode_g->pixbits) == 2) {
             attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
             mask = 0x03 << ((3 - (CX & 0x03)) * 2);
         } else {
@@ -1047,16 +949,12 @@ biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX)
             data &= ~mask;
             data |= attr;
         }
-        SET_FARVAR(0xb800, *addr, data);
+        SET_FARVAR(SEG_CTEXT, *addr_far, data);
         break;
     case LINEAR8:
-        addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
-        SET_FARVAR(0xa000, *addr, AL);
+        addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
+        SET_FARVAR(SEG_GRAPH, *addr_far, AL);
         break;
-#ifdef DEBUG
-    default:
-        unimplemented();
-#endif
     }
 }
 
@@ -1064,49 +962,41 @@ biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX)
 static void
 biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
 {
-    u8 mode, line, mask, attr, data, i;
-
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
-    if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+    if (GET_GLOBAL(vmode_g->class) == TEXT)
         return;
 
-    u8 *addr;
-    switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+    u8 *addr_far, mask, attr=0, data, i;
+    switch (GET_GLOBAL(vmode_g->memmodel)) {
     case PLANAR4:
     case PLANAR1:
-        addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
+        addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols));
         mask = 0x80 >> (CX & 0x07);
         attr = 0x00;
         for (i = 0; i < 4; i++) {
             outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS);
-            data = GET_FARVAR(0xa000, *addr) & mask;
+            data = GET_FARVAR(SEG_GRAPH, *addr_far) & mask;
             if (data > 0)
                 attr |= (0x01 << i);
         }
         break;
     case CGA:
-        addr = (void*)((CX >> 2) + (DX >> 1) * 80);
+        addr_far = (void*)((CX >> 2) + (DX >> 1) * 80);
         if (DX & 1)
-            addr += 0x2000;
-        data = GET_FARVAR(0xb800, *addr);
-        if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
+            addr_far += 0x2000;
+        data = GET_FARVAR(SEG_CTEXT, *addr_far);
+        if (GET_GLOBAL(vmode_g->pixbits) == 2)
             attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
         else
             attr = (data >> (7 - (CX & 0x07))) & 0x01;
         break;
     case LINEAR8:
-        addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
-        attr = GET_FARVAR(0xa000, *addr);
+        addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
+        attr = GET_FARVAR(SEG_GRAPH, *addr_far);
         break;
-    default:
-#ifdef DEBUG
-        unimplemented();
-#endif
-        attr = 0;
     }
     *AX = (*AX & 0xff00) | attr;
 }
@@ -1115,28 +1005,23 @@ biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
 static void
 biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
 {                               // flag = WITH_ATTR / NO_ATTR
-    u8 cheight, xcurs, ycurs, mode, line, bpp;
-    u16 nbcols, nbrows;
-    u16 cursor, dummy;
-
     // special case if page is 0xff, use current page
     if (page == 0xff)
         page = GET_BDA(video_page);
 
     // Get the mode
-    mode = GET_BDA(video_mode);
-    line = find_vga_entry(mode);
-    if (line == 0xFF)
+    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+    if (!vmode_g)
         return;
 
     // Get the cursor pos for the page
-    biosfn_get_cursor_pos(page, &dummy, &cursor);
-    xcurs = cursor & 0x00ff;
-    ycurs = (cursor & 0xff00) >> 8;
+    u16 cursor = biosfn_get_cursor_pos(page);
+    u8 xcurs = cursor & 0x00ff;
+    u8 ycurs = (cursor & 0xff00) >> 8;
 
     // Get the dimensions
-    nbrows = GET_BDA(video_rows) + 1;
-    nbcols = GET_BDA(video_cols);
+    u16 nbrows = GET_BDA(video_rows) + 1;
+    u16 nbcols = GET_BDA(video_cols);
 
     switch (car) {
     case 7:
@@ -1159,7 +1044,7 @@ biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
     case '\t':
         do {
             biosfn_write_teletype(' ', page, attr, flag);
-            biosfn_get_cursor_pos(page, &dummy, &cursor);
+            cursor = biosfn_get_cursor_pos(page);
             xcurs = cursor & 0x00ff;
             ycurs = (cursor & 0xff00) >> 8;
         } while (xcurs % 8 == 0);
@@ -1167,23 +1052,23 @@ biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
 
     default:
 
-        if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
+        if (GET_GLOBAL(vmode_g->class) == TEXT) {
             // Compute the address
-            u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                                  + (xcurs + ycurs * nbcols) * 2);
+            u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
+                                      + (xcurs + ycurs * nbcols) * 2);
             // Write the char
-            SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[0], car);
+            SET_FARVAR(GET_GLOBAL(vmode_g->sstart), address_far[0], car);
             if (flag == WITH_ATTR)
-                SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[1], attr);
+                SET_FARVAR(GET_GLOBAL(vmode_g->sstart), address_far[1], attr);
         } else {
             // FIXME gfx mode not complete
-            cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
-            bpp = GET_GLOBAL(vga_modes[line].pixbits);
-            switch (GET_GLOBAL(vga_modes[line].memmodel)) {
+            struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
+            u8 cheight = GET_GLOBAL(vparam_g->cheight);
+            u8 bpp = GET_GLOBAL(vmode_g->pixbits);
+            switch (GET_GLOBAL(vmode_g->memmodel)) {
             case PLANAR4:
             case PLANAR1:
-                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
-                                   cheight);
+                write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight);
                 break;
             case CGA:
                 write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
@@ -1191,10 +1076,6 @@ biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
             case LINEAR8:
                 write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
                 break;
-#ifdef DEBUG
-            default:
-                unimplemented();
-#endif
             }
         }
         xcurs++;
@@ -1207,7 +1088,7 @@ biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
     }
     // Do we need to scroll ?
     if (ycurs == nbrows) {
-        if (GET_GLOBAL(vga_modes[line].class) == TEXT)
+        if (GET_GLOBAL(vmode_g->class) == TEXT)
             biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
                           SCROLL_UP);
         else
@@ -1237,7 +1118,7 @@ biosfn_set_overscan_border_color(struct bregs *regs)
 {
     inb(VGAREG_ACTL_RESET);
     outb(0x11, VGAREG_ACTL_ADDRESS);
-    outb(regs->bh, VGAREG_ACTL_ADDRESS);
+    outb(regs->bh, VGAREG_ACTL_WRITE_DATA);
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
 
@@ -1247,16 +1128,16 @@ biosfn_set_all_palette_reg(struct bregs *regs)
 {
     inb(VGAREG_ACTL_RESET);
 
-    u8 *data = (u8*)(regs->dx + 0);
+    u8 *data_far = (u8*)(regs->dx + 0);
     int i;
     for (i = 0; i < 0x10; i++) {
         outb(i, VGAREG_ACTL_ADDRESS);
-        u8 val = GET_FARVAR(regs->es, *data);
-        outb(val, VGAREG_ACTL_ADDRESS);
-        data++;
+        u8 val = GET_FARVAR(regs->es, *data_far);
+        outb(val, VGAREG_ACTL_WRITE_DATA);
+        data_far++;
     }
     outb(0x11, VGAREG_ACTL_ADDRESS);
-    outb(GET_FARVAR(regs->es, *data), VGAREG_ACTL_ADDRESS);
+    outb(GET_FARVAR(regs->es, *data_far), VGAREG_ACTL_WRITE_DATA);
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
 
@@ -1267,7 +1148,7 @@ biosfn_toggle_intensity(struct bregs *regs)
     inb(VGAREG_ACTL_RESET);
     outb(0x10, VGAREG_ACTL_ADDRESS);
     u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3);
-    outb(val, VGAREG_ACTL_ADDRESS);
+    outb(val, VGAREG_ACTL_WRITE_DATA);
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
 
@@ -1277,7 +1158,7 @@ biosfn_set_single_palette_reg(u8 reg, u8 val)
 {
     inb(VGAREG_ACTL_RESET);
     outb(reg, VGAREG_ACTL_ADDRESS);
-    outb(val, VGAREG_ACTL_ADDRESS);
+    outb(val, VGAREG_ACTL_WRITE_DATA);
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
 
@@ -1308,17 +1189,17 @@ biosfn_read_overscan_border_color(struct bregs *regs)
 static void
 biosfn_get_all_palette_reg(struct bregs *regs)
 {
-    u8 *data = (u8*)(regs->dx + 0);
+    u8 *data_far = (u8*)(regs->dx + 0);
     int i;
     for (i = 0; i < 0x10; i++) {
         inb(VGAREG_ACTL_RESET);
         outb(i, VGAREG_ACTL_ADDRESS);
-        SET_FARVAR(regs->es, *data, inb(VGAREG_ACTL_READ_DATA));
-        data++;
+        SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA));
+        data_far++;
     }
     inb(VGAREG_ACTL_RESET);
     outb(0x11, VGAREG_ACTL_ADDRESS);
-    SET_FARVAR(regs->es, *data, inb(VGAREG_ACTL_READ_DATA));
+    SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA));
     inb(VGAREG_ACTL_RESET);
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
@@ -1338,15 +1219,15 @@ static void
 biosfn_set_all_dac_reg(struct bregs *regs)
 {
     outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
-    u8 *data = (u8*)(regs->dx + 0);
+    u8 *data_far = (u8*)(regs->dx + 0);
     int count = regs->cx;
     while (count) {
-        outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
-        data++;
-        outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
-        data++;
-        outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
-        data++;
+        outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
+        data_far++;
+        outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
+        data_far++;
+        outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
+        data_far++;
         count--;
     }
 }
@@ -1360,7 +1241,7 @@ biosfn_select_video_dac_color_page(struct bregs *regs)
     u8 val = inb(VGAREG_ACTL_READ_DATA);
     if (!(regs->bl & 0x01)) {
         val = (val & 0x7f) | (regs->bh << 7);
-        outb(val, VGAREG_ACTL_ADDRESS);
+        outb(val, VGAREG_ACTL_WRITE_DATA);
         outb(0x20, VGAREG_ACTL_ADDRESS);
         return;
     }
@@ -1370,7 +1251,7 @@ biosfn_select_video_dac_color_page(struct bregs *regs)
     if (!(val & 0x80))
         bh <<= 2;
     bh &= 0x0f;
-    outb(bh, VGAREG_ACTL_ADDRESS);
+    outb(bh, VGAREG_ACTL_WRITE_DATA);
     outb(0x20, VGAREG_ACTL_ADDRESS);
 }
 
@@ -1389,15 +1270,15 @@ static void
 biosfn_read_all_dac_reg(struct bregs *regs)
 {
     outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
-    u8 *data = (u8*)(regs->dx + 0);
+    u8 *data_far = (u8*)(regs->dx + 0);
     int count = regs->cx;
     while (count) {
-        SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
-        data++;
-        SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
-        data++;
-        SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
-        data++;
+        SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
+        data_far++;
+        SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
+        data_far++;
+        SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
+        data_far++;
         count--;
     }
 }
@@ -1467,12 +1348,9 @@ release_font_access()
 static void
 set_scan_lines(u8 lines)
 {
-    u16 crtc_addr, cols, vde;
-    u8 crtc_r9, ovl, rows;
-
-    crtc_addr = GET_BDA(crtc_address);
+    u16 crtc_addr = GET_BDA(crtc_address);
     outb(0x09, crtc_addr);
-    crtc_r9 = inb(crtc_addr + 1);
+    u8 crtc_r9 = inb(crtc_addr + 1);
     crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
     outb(crtc_r9, crtc_addr + 1);
     if (lines == 8)
@@ -1481,13 +1359,13 @@ set_scan_lines(u8 lines)
         biosfn_set_cursor_shape(lines - 4, lines - 3);
     SET_BDA(char_height, lines);
     outb(0x12, crtc_addr);
-    vde = inb(crtc_addr + 1);
+    u16 vde = inb(crtc_addr + 1);
     outb(0x07, crtc_addr);
-    ovl = inb(crtc_addr + 1);
+    u8 ovl = inb(crtc_addr + 1);
     vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
-    rows = vde / lines;
+    u8 rows = vde / lines;
     SET_BDA(video_rows, rows - 1);
-    cols = GET_BDA(video_cols);
+    u16 cols = GET_BDA(video_cols);
     SET_BDA(video_pagesize, rows * cols * 2);
 }
 
@@ -1499,9 +1377,9 @@ biosfn_load_text_user_pat(u8 AL, u16 ES, u16 BP, u16 CX, u16 DX, u8 BL,
     u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
     u16 i;
     for (i = 0; i < CX; i++) {
-        void *src = (void*)(BP + i * BH);
-        void *dest = (void*)(blockaddr + (DX + i) * 32);
-        memcpy_far(0xA000, dest, ES, src, BH);
+        void *src_far = (void*)(BP + i * BH);
+        void *dest_far = (void*)(blockaddr + (DX + i) * 32);
+        memcpy_far(SEG_GRAPH, dest_far, ES, src_far, BH);
     }
     release_font_access();
     if (AL >= 0x10)
@@ -1516,8 +1394,8 @@ biosfn_load_text_8_14_pat(u8 AL, u8 BL)
     u16 i;
     for (i = 0; i < 0x100; i++) {
         u16 src = i * 14;
-        void *dest = (void*)(blockaddr + i * 32);
-        memcpy_far(0xA000, dest, 0xC000, &vgafont14[src], 14);
+        void *dest_far = (void*)(blockaddr + i * 32);
+        memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont14[src], 14);
     }
     release_font_access();
     if (AL >= 0x10)
@@ -1532,8 +1410,8 @@ biosfn_load_text_8_8_pat(u8 AL, u8 BL)
     u16 i;
     for (i = 0; i < 0x100; i++) {
         u16 src = i * 8;
-        void *dest = (void*)(blockaddr + i * 32);
-        memcpy_far(0xA000, dest, 0xC000, &vgafont8[src], 8);
+        void *dest_far = (void*)(blockaddr + i * 32);
+        memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont8[src], 8);
     }
     release_font_access();
     if (AL >= 0x10)
@@ -1556,8 +1434,8 @@ biosfn_load_text_8_16_pat(u8 AL, u8 BL)
     u16 i;
     for (i = 0; i < 0x100; i++) {
         u16 src = i * 16;
-        void *dest = (void*)(blockaddr + i * 32);
-        memcpy_far(0xA000, dest, 0xC000, &vgafont16[src], 16);
+        void *dest_far = (void*)(blockaddr + i * 32);
+        memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont16[src], 16);
     }
     release_font_access();
     if (AL >= 0x10)
@@ -1582,33 +1460,31 @@ biosfn_get_font_info(u8 BH, u16 *ES, u16 *BP, u16 *CX, u16 *DX)
         break;
     }
     case 0x02:
-        *ES = 0xC000;
+        *ES = get_global_seg();
         *BP = (u32)vgafont14;
         break;
     case 0x03:
-        *ES = 0xC000;
+        *ES = get_global_seg();
         *BP = (u32)vgafont8;
         break;
     case 0x04:
-        *ES = 0xC000;
+        *ES = get_global_seg();
         *BP = (u32)vgafont8 + 128 * 8;
         break;
     case 0x05:
-        *ES = 0xC000;
+        *ES = get_global_seg();
         *BP = (u32)vgafont14alt;
         break;
     case 0x06:
-        *ES = 0xC000;
+        *ES = get_global_seg();
         *BP = (u32)vgafont16;
         break;
     case 0x07:
-        *ES = 0xC000;
+        *ES = get_global_seg();
         *BP = (u32)vgafont16alt;
         break;
     default:
-#ifdef DEBUG
-        printf("Get font info BH(%02x) was discarded\n", BH);
-#endif
+        dprintf(1, "Get font info BH(%02x) was discarded\n", BH);
         return;
     }
     // Set byte/char of on screen font
@@ -1654,9 +1530,7 @@ biosfn_select_vert_res(struct bregs *regs)
         vswt = (vswt & ~0x0f) | 0x09;
         break;
     default:
-#ifdef DEBUG
-        printf("Select vert res (%02x) was discarded\n");
-#endif
+        dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
         break;
     }
     SET_BDA(modeset_ctl, mctl);
@@ -1704,13 +1578,10 @@ biosfn_enable_cursor_emulation(struct bregs *regs)
 // -------------------------------------------------------------------
 static void
 biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
-                    u16 seg, u8 *offset)
+                    u16 seg, u8 *offset_far)
 {
-    u16 newcurs, oldcurs, dummy;
-    u8 car;
-
     // Read curs info for the page
-    biosfn_get_cursor_pos(page, &dummy, &oldcurs);
+    u16 oldcurs = biosfn_get_cursor_pos(page);
 
     // if row=0xff special case : use current cursor position
     if (row == 0xff) {
@@ -1718,17 +1589,17 @@ biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
         row = (oldcurs & 0xff00) >> 8;
     }
 
-    newcurs = row;
+    u16 newcurs = row;
     newcurs <<= 8;
     newcurs += col;
     biosfn_set_cursor_pos(page, newcurs);
 
     while (count-- != 0) {
-        car = GET_FARVAR(seg, *offset);
-        offset++;
+        u8 car = GET_FARVAR(seg, *offset_far);
+        offset_far++;
         if ((flag & 0x02) != 0) {
-            attr = GET_FARVAR(seg, *offset);
-            offset++;
+            attr = GET_FARVAR(seg, *offset_far);
+            offset_far++;
         }
 
         biosfn_write_teletype(car, page, attr, WITH_ATTR);
@@ -1751,9 +1622,7 @@ static void
 biosfn_set_display_code(struct bregs *regs)
 {
     SET_BDA(dcc_index, regs->bl);
-#ifdef DEBUG
-    printf("Alternate Display code (%02x) was discarded", regs->bh);
-#endif
+    dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
     regs->al = 0x1a;
 }
 
@@ -1763,7 +1632,7 @@ biosfn_read_state_info(u16 BX, u16 ES, u16 DI)
 {
     // Address of static functionality table
     SET_FARVAR(ES, *(u16*)(DI + 0x00), (u32)static_functionality);
-    SET_FARVAR(ES, *(u16*)(DI + 0x02), 0xC000);
+    SET_FARVAR(ES, *(u16*)(DI + 0x02), get_global_seg());
 
     // Hard coded copy from BIOS area. Should it be cleaner ?
     memcpy_far(ES, (void*)(DI + 0x04), SEG_BDA, (void*)0x49, 30);
@@ -1801,9 +1670,7 @@ biosfn_read_video_state_size(u16 CX)
 static u16
 biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
 {
-    u16 i, crtc_addr, ar_index;
-
-    crtc_addr = GET_BDA(crtc_address);
+    u16 crtc_addr = GET_BDA(crtc_address);
     if (CX & 1) {
         SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_ADDRESS));
         BX++;
@@ -1812,12 +1679,13 @@ biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
         SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_GRDC_ADDRESS));
         BX++;
         inb(VGAREG_ACTL_RESET);
-        ar_index = inb(VGAREG_ACTL_ADDRESS);
+        u16 ar_index = inb(VGAREG_ACTL_ADDRESS);
         SET_FARVAR(ES, *(u8*)(BX+0), ar_index);
         BX++;
         SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_READ_FEATURE_CTL));
         BX++;
 
+        u16 i;
         for (i = 1; i <= 4; i++) {
             outb(i, VGAREG_SEQU_ADDRESS);
             SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_SEQU_DATA));
@@ -1881,6 +1749,7 @@ biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
         BX++;
         SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_type));
         BX += 2;
+        u16 i;
         for (i = 0; i < 8; i++) {
             SET_FARVAR(ES, *(u16*)(BX+0), GET_BDA(cursor_pos[i]));
             BX += 2;
@@ -1890,14 +1759,10 @@ biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
         SET_FARVAR(ES, *(u8*)(BX+0), GET_BDA(video_page));
         BX++;
         /* current font */
-        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4)));
-        BX += 2;
-        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x1f * 4 + 2)));
-        BX += 2;
-        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4)));
-        BX += 2;
-        SET_FARVAR(ES, *(u16*)(BX+0), GET_FARVAR(0, *(u16*)(0x43 * 4 + 2)));
-        BX += 2;
+        SET_FARVAR(ES, *(u32*)(BX+0), GET_IVT(0x1f).segoff);
+        BX += 4;
+        SET_FARVAR(ES, *(u32*)(BX+0), GET_IVT(0x43).segoff);
+        BX += 4;
     }
     if (CX & 4) {
         /* XXX: check this */
@@ -1909,6 +1774,7 @@ biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
         BX++;
         // Set the whole dac always, from 0
         outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
+        u16 i;
         for (i = 0; i < 256 * 3; i++) {
             SET_FARVAR(ES, *(u8*)(BX+0), inb(VGAREG_DAC_DATA));
             BX++;
@@ -1922,16 +1788,15 @@ biosfn_save_video_state(u16 CX, u16 ES, u16 BX)
 static u16
 biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
 {
-    u16 i, crtc_addr, v, addr1, ar_index;
-
     if (CX & 1) {
         // Reset Attribute Ctl flip-flop
         inb(VGAREG_ACTL_RESET);
 
-        crtc_addr = GET_FARVAR(ES, *(u16*)(BX + 0x40));
-        addr1 = BX;
+        u16 crtc_addr = GET_FARVAR(ES, *(u16*)(BX + 0x40));
+        u16 addr1 = BX;
         BX += 5;
 
+        u16 i;
         for (i = 1; i <= 4; i++) {
             outb(i, VGAREG_SEQU_ADDRESS);
             outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_SEQU_DATA);
@@ -1952,8 +1817,8 @@ biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
             BX++;
         }
         // select crtc base address
-        v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
-        if (crtc_addr == 0x3d4)
+        u16 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
+        if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS)
             v |= 0x01;
         outb(v, VGAREG_WRITE_MISC_OUTPUT);
 
@@ -1962,7 +1827,7 @@ biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
         outb(GET_FARVAR(ES, *(u8*)(BX - 0x18 + 0x11)), crtc_addr + 1);
 
         // Set Attribute Ctl
-        ar_index = GET_FARVAR(ES, *(u8*)(addr1 + 0x03));
+        u16 ar_index = GET_FARVAR(ES, *(u8*)(addr1 + 0x03));
         inb(VGAREG_ACTL_RESET);
         for (i = 0; i <= 0x13; i++) {
             outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
@@ -2011,6 +1876,7 @@ biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
         BX++;
         SET_BDA(cursor_type, GET_FARVAR(ES, *(u16*)(BX+0)));
         BX += 2;
+        u16 i;
         for (i = 0; i < 8; i++) {
             SET_BDA(cursor_pos[i], GET_FARVAR(ES, *(u16*)(BX+0)));
             BX += 2;
@@ -2027,12 +1893,13 @@ biosfn_restore_video_state(u16 CX, u16 ES, u16 BX)
     }
     if (CX & 4) {
         BX++;
-        v = GET_FARVAR(ES, *(u8*)(BX+0));
+        u16 v = GET_FARVAR(ES, *(u8*)(BX+0));
         BX++;
         outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_PEL_MASK);
         BX++;
         // Set the whole dac always, from 0
         outb(0x00, VGAREG_DAC_WRITE_ADDRESS);
+        u16 i;
         for (i = 0; i < 256 * 3; i++) {
             outb(GET_FARVAR(ES, *(u8*)(BX+0)), VGAREG_DAC_DATA);
             BX++;
@@ -2086,7 +1953,8 @@ handle_1002(struct bregs *regs)
 static void
 handle_1003(struct bregs *regs)
 {
-    biosfn_get_cursor_pos(regs->bh, &regs->cx, &regs->dx);
+    regs->cx = biosfn_get_cursor_shape(regs->bh);
+    regs->dx = biosfn_get_cursor_pos(regs->bh);
 }
 
 // Read light pen pos (unimplemented)
@@ -2348,7 +2216,7 @@ static void
 handle_101100(struct bregs *regs)
 {
     // XXX - inline
-    biosfn_load_text_user_pat(regs->al, regs->es, 0 // XXX - regs->bp
+    biosfn_load_text_user_pat(regs->al, regs->es, regs->bp
                               , regs->cx, regs->dx, regs->bl, regs->bh);
 }
 
@@ -2408,7 +2276,7 @@ static void
 handle_101130(struct bregs *regs)
 {
     // XXX - inline
-    biosfn_get_font_info(regs->bh, &regs->es, 0 // &regs->bp
+    biosfn_get_font_info(regs->bh, &regs->es, &regs->bp
                          , &regs->cx, &regs->dx);
 }
 
@@ -2523,7 +2391,7 @@ handle_1013(struct bregs *regs)
 {
     // XXX - inline
     biosfn_write_string(regs->al, regs->bh, regs->bl, regs->cx
-                        , regs->dh, regs->dl, regs->es, 0); // regs->bp);
+                        , regs->dh, regs->dl, regs->es, (void*)(regs->bp + 0));
 }
 
 
@@ -2683,13 +2551,11 @@ handle_104fXX(struct bregs *regs)
 static void
 handle_104f(struct bregs *regs)
 {
-    if (! CONFIG_VBE) {
+    if (! CONFIG_VBE || !vbe_has_vbe_display()) {
         handle_104fXX(regs);
         return;
     }
 
-    // XXX - check vbe_has_vbe_display()?
-
     switch (regs->al) {
     case 0x00: handle_104f00(regs); break;
     case 0x01: handle_104f01(regs); break;
@@ -2796,10 +2662,11 @@ vga_post(struct bregs *regs)
 
     init_bios_area();
 
-    // vbe_init();
+    if (CONFIG_VBE)
+        vbe_init();
 
     extern void entry_10(void);
-    SET_IVT(0x10, 0xC000, (u32)entry_10);
+    SET_IVT(0x10, get_global_seg(), (u32)entry_10);
 
     if (CONFIG_CIRRUS)
         cirrus_init();
@@ -2808,11 +2675,11 @@ vga_post(struct bregs *regs)
 
     // XXX: fill it
     SET_VGA(video_save_pointer_table[0], (u32)video_param_table);
-    SET_VGA(video_save_pointer_table[1], 0xC000);
+    SET_VGA(video_save_pointer_table[1], get_global_seg());
 
     // Fixup checksum
     extern u8 _rom_header_size, _rom_header_checksum;
     SET_VGA(_rom_header_checksum, 0);
-    u8 sum = -checksum_far(0xC000, 0, _rom_header_size * 512);
+    u8 sum = -checksum_far(get_global_seg(), 0, _rom_header_size * 512);
     SET_VGA(_rom_header_checksum, sum);
 }