The vgabios uses storage in the BDA at offset 0xb9 for internal custom storage (the contents do not appear to be part of any bios standard). Move the description of this custom vgabios area from std/bda.h to vgasrc/vgabios.h. Add two new macros (GET_BDA_EXT and SET_BDA_EXT). This should make it more clear that the area is for custom internal storage.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/std/bda.h | 7 +------ vgasrc/vbe.c | 8 ++++---- vgasrc/vgabios.c | 8 ++++---- vgasrc/vgabios.h | 13 +++++++++++++ 4 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/src/std/bda.h b/src/std/bda.h index 948bdbf..c321266 100644 --- a/src/std/bda.h +++ b/src/std/bda.h @@ -95,12 +95,7 @@ struct bios_data_area_s { struct segoff_s video_savetable; u8 other_ac[4]; // 40:B0 - u8 other_b0[9]; - u8 vbe_flag; - u16 vbe_mode; - u8 other_bc[4]; - // 40:C0 - u8 other_c0[4*16]; + u8 other_b0[5*16]; } PACKED;
// BDA floppy_recalibration_status bitdefs diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 12bd981..06ec22e 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -217,7 +217,7 @@ vbe_104f02(struct bregs *regs) static void vbe_104f03(struct bregs *regs) { - regs->bx = GET_BDA(vbe_mode); + regs->bx = GET_BDA_EXT(vbe_mode); dprintf(1, "VBE current mode=%x\n", regs->bx); regs->ax = 0x004f; } @@ -247,7 +247,7 @@ vbe_104f05(struct bregs *regs) { if (regs->bh > 1 || regs->bl > 1) goto fail; - if (GET_BDA(vbe_mode) & MF_LINEARFB) { + if (GET_BDA_EXT(vbe_mode) & MF_LINEARFB) { regs->ah = VBE_RETURN_STATUS_INVALID; return; } @@ -382,10 +382,10 @@ vbe_104f10(struct bregs *regs) regs->bx = 0x0f30; break; case 0x01: - SET_BDA(vbe_flag, regs->bh); + SET_BDA_EXT(vbe_flag, regs->bh); break; case 0x02: - regs->bh = GET_BDA(vbe_flag); + regs->bh = GET_BDA_EXT(vbe_flag); break; default: regs->ax = 0x014f; diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index e87b7eb..d36b62a 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -252,7 +252,7 @@ bda_save_restore(int cmd, u16 seg, void *data) , sizeof(info->bda_0x49)); memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84 , sizeof(info->bda_0x84)); - SET_FARVAR(seg, info->vbe_mode, GET_BDA(vbe_mode)); + SET_FARVAR(seg, info->vbe_mode, GET_BDA_EXT(vbe_mode)); SET_FARVAR(seg, info->font0, GET_IVT(0x1f)); SET_FARVAR(seg, info->font1, GET_IVT(0x43)); } @@ -261,7 +261,7 @@ bda_save_restore(int cmd, u16 seg, void *data) , sizeof(info->bda_0x49)); memcpy_far(SEG_BDA, (void*)0x84, seg, info->bda_0x84 , sizeof(info->bda_0x84)); - SET_BDA(vbe_mode, GET_FARVAR(seg, info->vbe_mode)); + SET_BDA_EXT(vbe_mode, GET_FARVAR(seg, info->vbe_mode)); SET_IVT(0x1f, GET_FARVAR(seg, info->font0)); SET_IVT(0x43, GET_FARVAR(seg, info->font1)); } @@ -276,7 +276,7 @@ bda_save_restore(int cmd, u16 seg, void *data) struct vgamode_s * get_current_mode(void) { - return vgahw_find_mode(GET_BDA(vbe_mode) & ~MF_VBEFLAGS); + return vgahw_find_mode(GET_BDA_EXT(vbe_mode) & ~MF_VBEFLAGS); }
// Setup BDA after a mode switch. @@ -301,7 +301,7 @@ vga_set_mode(int mode, int flags) SET_BDA(video_mode, mode); else SET_BDA(video_mode, 0xff); - SET_BDA(vbe_mode, mode | (flags & MF_VBEFLAGS)); + SET_BDA_EXT(vbe_mode, mode | (flags & MF_VBEFLAGS)); if (memmodel == MM_TEXT) { SET_BDA(video_cols, width); SET_BDA(video_rows, height-1); diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 02cf3e3..70682c9 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -75,6 +75,19 @@ struct gfx_op { #define GO_MEMSET 3 #define GO_MEMMOVE 4
+// Custom internal storage in BDA +#define VGA_CUSTOM_BDA 0xb9 + +struct vga_bda_s { + u8 vbe_flag; + u16 vbe_mode; +} PACKED; + +#define GET_BDA_EXT(var) \ + GET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var) +#define SET_BDA_EXT(var, val) \ + SET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var, (val)) + // Debug settings #define DEBUG_VGA_POST 1 #define DEBUG_VGA_10 3
Cache a pointer to the current mode 'vgamode_s' struct in the BDA to avoid doing a linear scan of all available vga modes when the struct is needed.
This uses an additional two bytes in the BDA (at offset 0xbc). It's possible this could conflict with some other software, but that seams unlikely because that part of the BDA seems reserved for BIOS and VGABIOS uses. (And neither SeaBIOS nor Bochs BIOS currently make use of that area.)
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgabios.c | 8 ++++++-- vgasrc/vgabios.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index d36b62a..fcc5b34 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -261,7 +261,10 @@ bda_save_restore(int cmd, u16 seg, void *data) , sizeof(info->bda_0x49)); memcpy_far(SEG_BDA, (void*)0x84, seg, info->bda_0x84 , sizeof(info->bda_0x84)); - SET_BDA_EXT(vbe_mode, GET_FARVAR(seg, info->vbe_mode)); + u16 vbe_mode = GET_FARVAR(seg, info->vbe_mode); + SET_BDA_EXT(vbe_mode, vbe_mode); + struct vgamode_s *vmode_g = vgahw_find_mode(vbe_mode); + SET_BDA_EXT(vgamode_offset, (u32)vmode_g); SET_IVT(0x1f, GET_FARVAR(seg, info->font0)); SET_IVT(0x43, GET_FARVAR(seg, info->font1)); } @@ -276,7 +279,7 @@ bda_save_restore(int cmd, u16 seg, void *data) struct vgamode_s * get_current_mode(void) { - return vgahw_find_mode(GET_BDA_EXT(vbe_mode) & ~MF_VBEFLAGS); + return (void*)(GET_BDA_EXT(vgamode_offset)+0); }
// Setup BDA after a mode switch. @@ -302,6 +305,7 @@ vga_set_mode(int mode, int flags) else SET_BDA(video_mode, 0xff); SET_BDA_EXT(vbe_mode, mode | (flags & MF_VBEFLAGS)); + SET_BDA_EXT(vgamode_offset, (u32)vmode_g); if (memmodel == MM_TEXT) { SET_BDA(video_cols, width); SET_BDA(video_rows, height-1); diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 70682c9..d17b48f 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -81,6 +81,7 @@ struct gfx_op { struct vga_bda_s { u8 vbe_flag; u16 vbe_mode; + u16 vgamode_offset; } PACKED;
#define GET_BDA_EXT(var) \
Now that a pointer to the current video mode info struct is cached in memory, it's not necessary to pass the struct into the vgafb code. The vgafb code can lookup the struct itself.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgabios.c | 22 +++++++--------------- vgasrc/vgabios.h | 4 ++-- vgasrc/vgafb.c | 12 ++++++++++-- 3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index fcc5b34..8ec6aa6 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -212,19 +212,15 @@ write_teletype(struct cursorpos *pcp, struct carattr ca) if (pcp->y > nbrows) { pcp->y--;
- struct vgamode_s *vmode_g = get_current_mode(); - if (!vmode_g) - return; - struct cursorpos dest = {0, 0, pcp->page}; struct cursorpos src = {0, 1, pcp->page}; struct cursorpos size = {GET_BDA(video_cols), nbrows}; - vgafb_move_chars(vmode_g, dest, src, size); + vgafb_move_chars(dest, src, size);
struct cursorpos clr = {0, nbrows, pcp->page}; struct carattr attr = {' ', 0, 0}; struct cursorpos clrsize = {GET_BDA(video_cols), 1}; - vgafb_clear_chars(vmode_g, clr, attr, clrsize); + vgafb_clear_chars(clr, attr, clrsize); } }
@@ -430,10 +426,6 @@ verify_scroll(struct bregs *regs, int dir) if (wincols <= 0 || winrows <= 0) return;
- struct vgamode_s *vmode_g = get_current_mode(); - if (!vmode_g) - return; - u8 page = GET_BDA(video_page); int clearlines = regs->al, movelines = winrows - clearlines; if (!clearlines || movelines <= 0) { @@ -441,7 +433,7 @@ verify_scroll(struct bregs *regs, int dir) struct cursorpos clr = {ulx, uly, page}; struct carattr attr = {' ', regs->bh, 1}; struct cursorpos clrsize = {wincols, winrows}; - vgafb_clear_chars(vmode_g, clr, attr, clrsize); + vgafb_clear_chars(clr, attr, clrsize); return; }
@@ -450,23 +442,23 @@ verify_scroll(struct bregs *regs, int dir) struct cursorpos dest = {ulx, uly, page}; struct cursorpos src = {ulx, uly + clearlines, page}; struct cursorpos size = {wincols, movelines}; - vgafb_move_chars(vmode_g, dest, src, size); + vgafb_move_chars(dest, src, size);
struct cursorpos clr = {ulx, uly + movelines, page}; struct carattr attr = {' ', regs->bh, 1}; struct cursorpos clrsize = {wincols, clearlines}; - vgafb_clear_chars(vmode_g, clr, attr, clrsize); + vgafb_clear_chars(clr, attr, clrsize); } else { // Scroll down struct cursorpos dest = {ulx, uly + clearlines, page}; struct cursorpos src = {ulx, uly, page}; struct cursorpos size = {wincols, movelines}; - vgafb_move_chars(vmode_g, dest, src, size); + vgafb_move_chars(dest, src, size);
struct cursorpos clr = {ulx, uly, page}; struct carattr attr = {' ', regs->bh, 1}; struct cursorpos clrsize = {wincols, clearlines}; - vgafb_clear_chars(vmode_g, clr, attr, clrsize); + vgafb_clear_chars(clr, attr, clrsize); } }
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index d17b48f..fc8d45a 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -123,9 +123,9 @@ int vga_set_mode(int mode, int flags); void init_gfx_op(struct gfx_op *op, struct vgamode_s *vmode_g); void handle_gfx_op(struct gfx_op *op); void *text_address(struct cursorpos cp); -void vgafb_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest +void vgafb_move_chars(struct cursorpos dest , struct cursorpos src, struct cursorpos movesize); -void vgafb_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest +void vgafb_clear_chars(struct cursorpos dest , struct carattr ca, struct cursorpos movesize); void vgafb_write_char(struct cursorpos cp, struct carattr ca); struct carattr vgafb_read_char(struct cursorpos cp); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 74ddc53..9652683 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -512,9 +512,13 @@ text_address(struct cursorpos cp)
// Move characters on screen. void -vgafb_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest +vgafb_move_chars(struct cursorpos dest , struct cursorpos src, struct cursorpos movesize) { + struct vgamode_s *vmode_g = get_current_mode(); + if (!vmode_g) + return; + if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) { gfx_move_chars(vmode_g, dest, src, movesize); return; @@ -528,9 +532,13 @@ vgafb_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest
// Clear are of screen. void -vgafb_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest +vgafb_clear_chars(struct cursorpos dest , struct carattr ca, struct cursorpos clearsize) { + struct vgamode_s *vmode_g = get_current_mode(); + if (!vmode_g) + return; + if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) { gfx_clear_chars(vmode_g, dest, ca, clearsize); return;