VGA: Combine x/y/page into one parameter.

These three values are frequently used together - put them in a struct
    and pass the struct around.
diff --git a/vgasrc/vga.c b/vgasrc/vga.c
index 2fa9687..74c5680 100644
--- a/vgasrc/vga.c
+++ b/vgasrc/vga.c
@@ -93,40 +93,45 @@
 }
 
 static void
-biosfn_set_cursor_pos(u8 page, u16 cursor)
+set_cursor_pos(struct cursorpos cp)
 {
     // Should not happen...
-    if (page > 7)
+    if (cp.page > 7)
         return;
 
     // Bios cursor pos
-    SET_BDA(cursor_pos[page], cursor);
+    SET_BDA(cursor_pos[cp.page], (cp.y << 8) | cp.x);
 
     // Set the hardware cursor
     u8 current = GET_BDA(video_page);
-    if (page != current)
+    if (cp.page != current)
         return;
 
     // Get the dimensions
     u16 nbcols = GET_BDA(video_cols);
     u16 nbrows = GET_BDA(video_rows) + 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;
+    u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page)
+                   + cp.x + cp.y * nbcols);
 
     vgahw_set_cursor_pos(address);
 }
 
-u16
-biosfn_get_cursor_pos(u8 page)
+struct cursorpos
+get_cursor_pos(u8 page)
 {
-    if (page > 7)
-        return 0;
+    if (page == 0xff)
+        // special case - use current page
+        page = GET_BDA(video_page);
+    if (page > 7) {
+        struct cursorpos cp = { 0, 0, 0xfe };
+        return cp;
+    }
     // FIXME should handle VGA 14/16 lines
-    return GET_BDA(cursor_pos[page]);
+    u16 xy = GET_BDA(cursor_pos[page]);
+    struct cursorpos cp = {xy, xy>>8, page};
+    return cp;
 }
 
 static void
@@ -141,7 +146,7 @@
         return;
 
     // Get pos curs pos for the right page
-    u16 cursor = biosfn_get_cursor_pos(page);
+    struct cursorpos cp = get_cursor_pos(page);
 
     u16 address;
     if (GET_GLOBAL(vmode_g->class) == TEXT) {
@@ -168,25 +173,19 @@
     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);
+    set_cursor_pos(cp);
 }
 
 static void
 biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
 {                               // flag = WITH_ATTR / NO_ATTR
-    // special case if page is 0xff, use current page
-    if (page == 0xff)
-        page = GET_BDA(video_page);
-
     // Get the mode
     struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
     if (!vmode_g)
         return;
 
     // Get the cursor pos for the page
-    u16 cursor = biosfn_get_cursor_pos(page);
-    u8 xcurs = cursor & 0x00ff;
-    u8 ycurs = (cursor & 0xff00) >> 8;
+    struct cursorpos cp = get_cursor_pos(page);
 
     // Get the dimensions
     u16 nbrows = GET_BDA(video_rows) + 1;
@@ -198,74 +197,64 @@
         break;
 
     case 8:
-        if (xcurs > 0)
-            xcurs--;
+        if (cp.x > 0)
+            cp.x--;
         break;
 
     case '\r':
-        xcurs = 0;
+        cp.x = 0;
         break;
 
     case '\n':
-        ycurs++;
+        cp.y++;
         break;
 
     case '\t':
         do {
             biosfn_write_teletype(' ', page, attr, flag);
-            cursor = biosfn_get_cursor_pos(page);
-            xcurs = cursor & 0x00ff;
-            ycurs = (cursor & 0xff00) >> 8;
-        } while (xcurs % 8 == 0);
+            cp = get_cursor_pos(page);
+        } while (cp.x % 8 == 0);
         break;
 
     default:
         if (flag == WITH_ATTR)
-            biosfn_write_char_attr(car, page, attr, 1);
+            biosfn_write_char_attr(car, cp.page, attr, 1);
         else
-            biosfn_write_char_only(car, page, attr, 1);
-        xcurs++;
+            biosfn_write_char_only(car, cp.page, attr, 1);
+        cp.x++;
     }
 
     // Do we need to wrap ?
-    if (xcurs == nbcols) {
-        xcurs = 0;
-        ycurs++;
+    if (cp.x == nbcols) {
+        cp.x = 0;
+        cp.y++;
     }
     // Do we need to scroll ?
-    if (ycurs == nbrows) {
+    if (cp.y == nbrows) {
         if (GET_GLOBAL(vmode_g->class) == TEXT)
             biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
                           SCROLL_UP);
         else
             biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, page,
                           SCROLL_UP);
-        ycurs -= 1;
+        cp.y--;
     }
     // Set the cursor for the page
-    cursor = ycurs;
-    cursor <<= 8;
-    cursor += xcurs;
-    biosfn_set_cursor_pos(page, cursor);
+    set_cursor_pos(cp);
 }
 
 static void
-biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
+biosfn_write_string(struct cursorpos cp, u8 flag, u8 attr, u16 count,
                     u16 seg, u8 *offset_far)
 {
     // Read curs info for the page
-    u16 oldcurs = biosfn_get_cursor_pos(page);
+    struct cursorpos oldcp = get_cursor_pos(cp.page);
 
     // if row=0xff special case : use current cursor position
-    if (row == 0xff) {
-        col = oldcurs & 0x00ff;
-        row = (oldcurs & 0xff00) >> 8;
-    }
+    if (cp.y == 0xff)
+        cp = oldcp;
 
-    u16 newcurs = row;
-    newcurs <<= 8;
-    newcurs += col;
-    biosfn_set_cursor_pos(page, newcurs);
+    set_cursor_pos(cp);
 
     while (count-- != 0) {
         u8 car = GET_FARVAR(seg, *offset_far);
@@ -275,12 +264,12 @@
             offset_far++;
         }
 
-        biosfn_write_teletype(car, page, attr, WITH_ATTR);
+        biosfn_write_teletype(car, cp.page, attr, WITH_ATTR);
     }
 
     // Set back curs pos
     if ((flag & 0x01) == 0)
-        biosfn_set_cursor_pos(page, oldcurs);
+        set_cursor_pos(oldcp);
 }
 
 static void
@@ -359,22 +348,13 @@
     u8 noclearmem = regs->al & 0x80;
     u8 mode = regs->al & 0x7f;
 
-    switch(mode) {
-    case 6:
-        regs->al = 0x3F;
-        break;
-    case 0:
-    case 1:
-    case 2:
-    case 3:
-    case 4:
-    case 5:
-    case 7:
-        regs->al = 0x30;
-        break;
-    default:
+    // Set regs->al
+    if (mode > 7)
         regs->al = 0x20;
-    }
+    else if (mode == 6)
+        regs->al = 0x3f;
+    else
+        regs->al = 0x30;
 
     if (CONFIG_CIRRUS)
         cirrus_set_video_mode(mode);
@@ -452,8 +432,10 @@
         biosfn_set_cursor_shape(0x06, 0x07);
     // Set cursor pos for page 0..7
     int i;
-    for (i = 0; i < 8; i++)
-        biosfn_set_cursor_pos(i, 0x0000);
+    for (i = 0; i < 8; i++) {
+        struct cursorpos cp = {0, 0, i};
+        set_cursor_pos(cp);
+    }
 
     // Set active page 0
     biosfn_set_active_page(0x00);
@@ -488,14 +470,17 @@
 static void
 handle_1002(struct bregs *regs)
 {
-    biosfn_set_cursor_pos(regs->bh, regs->dx);
+    struct cursorpos cp = {regs->dl, regs->dh, regs->bh};
+    set_cursor_pos(cp);
 }
 
 static void
 handle_1003(struct bregs *regs)
 {
     regs->cx = biosfn_get_cursor_shape(regs->bh);
-    regs->dx = biosfn_get_cursor_pos(regs->bh);
+    struct cursorpos cp = get_cursor_pos(regs->bh);
+    regs->dl = cp.x;
+    regs->dh = cp.y;
 }
 
 // Read light pen pos (unimplemented)
@@ -998,8 +983,9 @@
 handle_1013(struct bregs *regs)
 {
     // XXX - inline
-    biosfn_write_string(regs->al, regs->bh, regs->bl, regs->cx
-                        , regs->dh, regs->dl, regs->es, (void*)(regs->bp + 0));
+    struct cursorpos cp = {regs->dl, regs->dh, regs->bh};
+    biosfn_write_string(cp, regs->al, regs->bl, regs->cx
+                        , regs->es, (void*)(regs->bp + 0));
 }
 
 
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c
index 605a3b6..f6a416b 100644
--- a/vgasrc/vgafb.c
+++ b/vgasrc/vgafb.c
@@ -13,7 +13,6 @@
 //  * extract hw code from framebuffer code
 //  * use clear_screen() in scroll code
 //  * merge car/attr/with_attr into one param
-//  * merge page/x/y into one param
 //  * combine biosfn_write_char_attr/_only()
 //  * read/write_char should take a position; should not take count
 //  * remove vmode_g->class (integrate into vmode_g->memmodel)
@@ -268,7 +267,7 @@
  ****************************************************************/
 
 static void
-write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols,
+write_gfx_char_pl4(struct cursorpos cp, u8 car, u8 attr, u8 nbcols,
                    u8 cheight)
 {
     u8 *fdata_g;
@@ -282,7 +281,7 @@
     default:
         fdata_g = vgafont8;
     }
-    u16 addr = xcurs + ycurs * cheight * nbcols;
+    u16 addr = cp.x + cp.y * cheight * nbcols;
     u16 src = car * cheight;
     outw(0x0f02, VGAREG_SEQU_ADDRESS);
     outw(0x0205, VGAREG_GRDC_ADDRESS);
@@ -310,10 +309,10 @@
 }
 
 static void
-write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp)
+write_gfx_char_cga(struct cursorpos cp, u8 car, u8 attr, u8 nbcols, u8 bpp)
 {
     u8 *fdata_g = vgafont8;
-    u16 addr = (xcurs * bpp) + ycurs * 320;
+    u16 addr = (cp.x * bpp) + cp.y * 320;
     u16 src = car * 8;
     u8 i;
     for (i = 0; i < 8; i++) {
@@ -359,10 +358,10 @@
 }
 
 static void
-write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols)
+write_gfx_char_lin(struct cursorpos cp, u8 car, u8 attr, u8 nbcols)
 {
     u8 *fdata_g = vgafont8;
-    u16 addr = xcurs * 8 + ycurs * nbcols * 64;
+    u16 addr = cp.x * 8 + cp.y * nbcols * 64;
     u16 src = car * 8;
     u8 i;
     for (i = 0; i < 8; i++) {
@@ -388,9 +387,7 @@
         return;
 
     // Get the cursor pos for the page
-    u16 cursor = biosfn_get_cursor_pos(page);
-    u8 xcurs = cursor & 0x00ff;
-    u8 ycurs = (cursor & 0xff00) >> 8;
+    struct cursorpos cp = get_cursor_pos(page);
 
     // Get the dimensions
     u16 nbrows = GET_BDA(video_rows) + 1;
@@ -398,8 +395,8 @@
 
     if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                                    + (xcurs + ycurs * nbcols) * 2);
+        void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page)
+                                    + (cp.x + cp.y * nbcols) * 2);
 
         u16 dummy = ((u16)attr << 8) + car;
         memset16_far(GET_GLOBAL(vmode_g->sstart), address_far, dummy, count * 2);
@@ -410,20 +407,20 @@
     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)) {
+    while ((count-- > 0) && (cp.x < nbcols)) {
         switch (GET_GLOBAL(vmode_g->memmodel)) {
         case PLANAR4:
         case PLANAR1:
-            write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight);
+            write_gfx_char_pl4(cp, car, attr, nbcols, cheight);
             break;
         case CGA:
-            write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+            write_gfx_char_cga(cp, car, attr, nbcols, bpp);
             break;
         case LINEAR8:
-            write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+            write_gfx_char_lin(cp, car, attr, nbcols);
             break;
         }
-        xcurs++;
+        cp.x++;
     }
 }
 
@@ -436,9 +433,7 @@
         return;
 
     // Get the cursor pos for the page
-    u16 cursor = biosfn_get_cursor_pos(page);
-    u8 xcurs = cursor & 0x00ff;
-    u8 ycurs = (cursor & 0xff00) >> 8;
+    struct cursorpos cp = get_cursor_pos(page);
 
     // Get the dimensions
     u16 nbrows = GET_BDA(video_rows) + 1;
@@ -446,8 +441,8 @@
 
     if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                                  + (xcurs + ycurs * nbcols) * 2);
+        u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page)
+                                  + (cp.x + cp.y * nbcols) * 2);
         while (count-- > 0) {
             SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far, car);
             address_far += 2;
@@ -459,20 +454,20 @@
     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)) {
+    while ((count-- > 0) && (cp.x < nbcols)) {
         switch (GET_GLOBAL(vmode_g->memmodel)) {
         case PLANAR4:
         case PLANAR1:
-            write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight);
+            write_gfx_char_pl4(cp, car, attr, nbcols, cheight);
             break;
         case CGA:
-            write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
+            write_gfx_char_cga(cp, car, attr, nbcols, bpp);
             break;
         case LINEAR8:
-            write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
+            write_gfx_char_lin(cp, car, attr, nbcols);
             break;
         }
-        xcurs++;
+        cp.x++;
     }
 }
 
@@ -485,9 +480,7 @@
         return;
 
     // Get the cursor pos for the page
-    u16 cursor = biosfn_get_cursor_pos(page);
-    u8 xcurs = cursor & 0x00ff;
-    u8 ycurs = (cursor & 0xff00) >> 8;
+    struct cursorpos cp = get_cursor_pos(page);
 
     // Get the dimensions
     u16 nbrows = GET_BDA(video_rows) + 1;
@@ -495,8 +488,8 @@
 
     if (GET_GLOBAL(vmode_g->class) == TEXT) {
         // Compute the address
-        u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
-                                   + (xcurs + ycurs * nbcols) * 2);
+        u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page)
+                                   + (cp.x + cp.y * nbcols) * 2);
 
         *car = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far);
     } else {
diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h
index df09686..1e91661 100644
--- a/vgasrc/vgatables.h
+++ b/vgasrc/vgatables.h
@@ -161,7 +161,10 @@
 extern u8 vgafont16alt[];
 
 // vga.c
-u16 biosfn_get_cursor_pos(u8 page);
+struct cursorpos {
+    u8 x, y, page;
+};
+struct cursorpos get_cursor_pos(u8 page);
 
 // vgafb.c
 void clear_screen(struct vgamode_s *vmode_g);