More work on the vgabios. Much of the changes are for unifying the mode lists shared between the various drivers. This series culminates with the Cirrus driver getting basic VBE support.
-Kevin
Kevin O'Connor (15): vgabios: Use vesa style memory model flags in stdvga code. vgabios: Use standard naming for cirrus memmodel. vgabios: Add char width to stdvga mode table. vgabios: Remove dummy 0xfe mode from list of cirrus modes. vgabios: Make struct vgamode_s more similar to bochs/cirrus mode tables. vgabios: Add memmodel field to bochsvga mode list. vgabios: Unify page size calculations; remove page size from vgamode_s. vgabios: Extract out common parts of struct vgamode_s. vgabios: Use vgamode_s in cirrus and bochsvga mode tables. vgabios: Unify code to generate the vbe mode list. vgabios: Make VBE code independent of bochsvga. vgabios: Unify cirrus and vbe vesa functions. vgabios: Make cirrus line lengths standard. vgabios: Hook up Cirrus extended bios functions. vgabios: Add cirrus linear framebuffer detection; enable VBE in cirrus.
Makefile | 2 +- vgasrc/bochsvga.c | 327 +++++++++++++--------------------- vgasrc/bochsvga.h | 11 +- vgasrc/clext.c | 499 ++++++++++++++++++---------------------------------- vgasrc/clext.h | 6 +- vgasrc/geodevga.c | 6 +- vgasrc/stdvga.c | 34 ++-- vgasrc/stdvga.h | 36 +--- vgasrc/vbe.c | 94 +++++----- vgasrc/vgabios.c | 85 +++++---- vgasrc/vgabios.h | 42 +++-- vgasrc/vgafb.c | 90 ++++------ vgasrc/vgahw.h | 17 ++ vgasrc/vgatables.c | 86 +++++---- 14 files changed, 564 insertions(+), 771 deletions(-)
Replace the custom flags with the flags defined in the VBE spec.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/stdvga.c | 7 +++---- vgasrc/stdvga.h | 18 ------------------ vgasrc/vgabios.c | 5 +++-- vgasrc/vgabios.h | 10 ++++++++++ vgasrc/vgafb.c | 48 +++++++++++++++++++++++------------------------- vgasrc/vgatables.c | 40 ++++++++++++++++++++-------------------- 6 files changed, 59 insertions(+), 69 deletions(-)
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index c7331e4..e90d48f 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -527,11 +527,10 @@ static void clear_screen(struct vgamode_s *vmode_g) { switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: + case MM_TEXT: memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); break; - case CGA: + case MM_CGA: memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); break; default: @@ -627,7 +626,7 @@ stdvga_set_mode(int mode, int flags)
// Write the fonts in memory u8 memmodel = GET_GLOBAL(vmode_g->memmodel); - if (memmodel & TEXT) + if (memmodel == MM_TEXT) stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
// Setup BDA variables diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 0685584..0a99d37 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -44,24 +44,6 @@ #define SEG_CTEXT 0xB800 #define SEG_MTEXT 0xB000
-/* - * Tables of default values for each mode - */ -#define TEXT 0x80 - -#define CTEXT (0x00 | TEXT) -#define MTEXT (0x01 | TEXT) -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR4 0x04 -#define LINEAR8 0x05 - -// for SVGA -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - struct vgamode_s { u8 svgamode; u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 063a2fd..7bed069 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -135,7 +135,7 @@ set_active_page(u8 page) struct cursorpos cp = get_cursor_pos(page);
u16 address; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { + if (GET_GLOBAL(vmode_g->memmodel) == MM_TEXT) { // Get the dimensions u16 nbcols = GET_BDA(video_cols); u16 nbrows = GET_BDA(video_rows) + 1; @@ -339,7 +339,8 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) SET_BDA(video_ctl, 0x60 | (flags & MF_NOCLEARMEM ? 0x80 : 0x00)); SET_BDA(video_switches, 0xF9); SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); - SET_BDA(cursor_type, GET_GLOBAL(vmode_g->memmodel) & TEXT ? 0x0607 : 0x0000); + SET_BDA(cursor_type + , GET_GLOBAL(vmode_g->memmodel) == MM_TEXT ? 0x0607 : 0x0000); int i; for (i=0; i<8; i++) SET_BDA(cursor_pos[i], 0x0000); diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 176f71c..7c5e8d3 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -33,6 +33,16 @@ struct saveBDAstate { #define MF_LINEARFB 0x4000 #define MF_NOCLEARMEM 0x8000
+// Memory model types +#define MM_TEXT 0x00 +#define MM_CGA 0x01 +#define MM_HERCULES 0x02 +#define MM_PLANAR 0x03 +#define MM_PACKED 0x04 +#define MM_NON_CHAIN_4_256 0x05 +#define MM_DIRECT 0x06 +#define MM_YUV 0x07 + // vgatables.c struct vgamode_s; struct vgamode_s *find_vga_entry(u8 mode); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 85e4ab3..0f33720 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -176,18 +176,17 @@ vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr)
// FIXME gfx mode not complete switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: + case MM_TEXT: scroll_text(vmode_g, nblines, attr, ul, lr); break; - case PLANAR4: - case PLANAR1: + case MM_PLANAR: scroll_pl4(vmode_g, nblines, attr, ul, lr); break; - case CGA: + case MM_CGA: scroll_cga(vmode_g, nblines, attr, ul, lr); break; - case LINEAR8: + case MM_DIRECT: + case MM_PACKED: scroll_lin(vmode_g, nblines, attr, ul, lr); break; } @@ -357,18 +356,17 @@ vgafb_write_char(struct cursorpos cp, struct carattr ca)
// FIXME gfx mode not complete switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: + case MM_TEXT: write_text_char(vmode_g, cp, ca); break; - case PLANAR4: - case PLANAR1: + case MM_PLANAR: write_gfx_char_pl4(vmode_g, cp, ca); break; - case CGA: + case MM_CGA: write_gfx_char_cga(vmode_g, cp, ca); break; - case LINEAR8: + case MM_DIRECT: + case MM_PACKED: write_gfx_char_lin(vmode_g, cp, ca); break; } @@ -382,7 +380,7 @@ vgafb_read_char(struct cursorpos cp) if (!vmode_g) goto fail;
- if (!(GET_GLOBAL(vmode_g->memmodel) & TEXT)) { + if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) { // FIXME gfx mode dprintf(1, "Read char in graphics mode\n"); goto fail; @@ -416,13 +414,10 @@ vgafb_write_pixel(u8 color, u16 x, u16 y) struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); if (!vmode_g) return; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - return;
u8 *addr_far, mask, attr, data; switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: + case MM_PLANAR: addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); mask = 0x80 >> (x & 0x07); stdvga_grdc_write(0x08, mask); @@ -435,7 +430,7 @@ vgafb_write_pixel(u8 color, u16 x, u16 y) stdvga_grdc_write(0x05, 0x00); stdvga_grdc_write(0x03, 0x00); break; - case CGA: + case MM_CGA: if (GET_GLOBAL(vmode_g->pixbits) == 2) addr_far = (void*)((x >> 2) + (y >> 1) * 80); else @@ -458,10 +453,13 @@ vgafb_write_pixel(u8 color, u16 x, u16 y) } SET_FARVAR(SEG_CTEXT, *addr_far, data); break; - case LINEAR8: + case MM_DIRECT: + case MM_PACKED: addr_far = (void*)(x + y * (GET_BDA(video_cols) * 8)); SET_FARVAR(SEG_GRAPH, *addr_far, color); break; + case MM_TEXT: + return; } }
@@ -472,13 +470,10 @@ vgafb_read_pixel(u16 x, u16 y) struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); if (!vmode_g) return 0; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - return 0;
u8 *addr_far, mask, attr=0, data, i; switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: + case MM_PLANAR: addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); mask = 0x80 >> (x & 0x07); attr = 0x00; @@ -489,7 +484,7 @@ vgafb_read_pixel(u16 x, u16 y) attr |= (0x01 << i); } break; - case CGA: + case MM_CGA: addr_far = (void*)((x >> 2) + (y >> 1) * 80); if (y & 1) addr_far += 0x2000; @@ -499,10 +494,13 @@ vgafb_read_pixel(u16 x, u16 y) else attr = (data >> (7 - (x & 0x07))) & 0x01; break; - case LINEAR8: + case MM_DIRECT: + case MM_PACKED: addr_far = (void*)(x + y * (GET_BDA(video_cols) * 8)); attr = GET_FARVAR(SEG_GRAPH, *addr_far); break; + case MM_TEXT: + return 0; } return attr; } diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index 0eda104..048e6c5 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -339,37 +339,37 @@ static u8 crtc_6A[] VAR16 = { static struct vgamode_s vga_modes[] VAR16 = { //mode model tx ty ch bits sstart slength // pelm dac sequ misc crtc actl grdc - {0x00, CTEXT, 40, 25, 16, 4, SEG_CTEXT, 0x0800 - , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01 }, - {0x01, CTEXT, 40, 25, 16, 4, SEG_CTEXT, 0x0800 - , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01 }, - {0x02, CTEXT, 80, 25, 16, 4, SEG_CTEXT, 0x1000 - , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01 }, - {0x03, CTEXT, 80, 25, 16, 4, SEG_CTEXT, 0x1000 - , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01 }, - {0x04, CGA, 40, 25, 8, 2, SEG_CTEXT, 0x0800 + {0x00, MM_TEXT, 40, 25, 16, 4, SEG_CTEXT, 0x0800 + , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, + {0x01, MM_TEXT, 40, 25, 16, 4, SEG_CTEXT, 0x0800 + , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, + {0x02, MM_TEXT, 80, 25, 16, 4, SEG_CTEXT, 0x1000 + , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, + {0x03, MM_TEXT, 80, 25, 16, 4, SEG_CTEXT, 0x1000 + , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, + {0x04, MM_CGA, 40, 25, 8, 2, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x05, CGA, 40, 25, 8, 2, SEG_CTEXT, 0x0800 + {0x05, MM_CGA, 40, 25, 8, 2, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x06, CGA, 80, 25, 8, 1, SEG_CTEXT, 0x1000 + {0x06, MM_CGA, 80, 25, 8, 1, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06}, - {0x07, MTEXT, 80, 25, 16, 4, SEG_MTEXT, 0x1000 + {0x07, MM_TEXT, 80, 25, 16, 4, SEG_MTEXT, 0x1000 , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07}, - {0x0D, PLANAR4, 40, 25, 8, 4, SEG_GRAPH, 0x2000 + {0x0D, MM_PLANAR, 40, 25, 8, 4, SEG_GRAPH, 0x2000 , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d}, - {0x0E, PLANAR4, 80, 25, 8, 4, SEG_GRAPH, 0x4000 + {0x0E, MM_PLANAR, 80, 25, 8, 4, SEG_GRAPH, 0x4000 , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d}, - {0x0F, PLANAR1, 80, 25, 14, 1, SEG_GRAPH, 0x8000 + {0x0F, MM_PLANAR, 80, 25, 14, 1, SEG_GRAPH, 0x8000 , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d}, - {0x10, PLANAR4, 80, 25, 14, 4, SEG_GRAPH, 0x8000 + {0x10, MM_PLANAR, 80, 25, 14, 4, SEG_GRAPH, 0x8000 , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d}, - {0x11, PLANAR1, 80, 30, 16, 1, SEG_GRAPH, 0x0000 + {0x11, MM_PLANAR, 80, 30, 16, 1, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d}, - {0x12, PLANAR4, 80, 30, 16, 4, SEG_GRAPH, 0x0000 + {0x12, MM_PLANAR, 80, 30, 16, 4, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d}, - {0x13, LINEAR8, 40, 25, 8, 8, SEG_GRAPH, 0x0000 + {0x13, MM_PACKED, 40, 25, 8, 8, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13}, - {0x6A, PLANAR4, 100, 37, 16, 4, SEG_GRAPH, 0x0000 + {0x6A, MM_PLANAR, 100, 37, 16, 4, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d}, };
The cirrus mode array stores memmodel as vesacolortype - rename it to 'memmodel' and use common field names.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 78 ++++++++++++++++++++++++++++---------------------------- 1 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index afab582..61bfe92 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -21,6 +21,7 @@ struct cirrus_mode_s { /* + 0 */ u16 mode; + u8 memmodel; u16 width; u16 height; u16 depth; @@ -31,7 +32,6 @@ struct cirrus_mode_s { u16 *crtc; /* 0x3d4 */ /* +16 */ u8 bitsperpixel; - u8 vesacolortype; u8 vesaredmask; u8 vesaredpos; u8 vesagreenmask; @@ -240,62 +240,62 @@ static u16 ccrtc_1600x1200x8[] VAR16 = { };
static struct cirrus_mode_s cirrus_modes[] VAR16 = { - {0x5f,640,480,8,0x00, + {0x5f,MM_PACKED,640,480,8,0x00, cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x64,640,480,16,0xe1, + 0,0,0,0,0,0,0,0}, + {0x64,MM_DIRECT,640,480,16,0xe1, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x66,640,480,15,0xf0, + 5,11,6,5,5,0,0,0}, + {0x66,MM_DIRECT,640,480,15,0xf0, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 6,5,10,5,5,5,0,1,15}, - {0x71,640,480,24,0xe5, + 5,10,5,5,5,0,1,15}, + {0x71,MM_DIRECT,640,480,24,0xe5, cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, - 6,8,16,8,8,8,0,0,0}, + 8,16,8,8,8,0,0,0},
- {0x5c,800,600,8,0x00, + {0x5c,MM_PACKED,800,600,8,0x00, cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x65,800,600,16,0xe1, + 0,0,0,0,0,0,0,0}, + {0x65,MM_DIRECT,800,600,16,0xe1, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x67,800,600,15,0xf0, + 5,11,6,5,5,0,0,0}, + {0x67,MM_DIRECT,800,600,15,0xf0, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 6,5,10,5,5,5,0,1,15}, + 5,10,5,5,5,0,1,15},
- {0x60,1024,768,8,0x00, + {0x60,MM_PACKED,1024,768,8,0x00, cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x74,1024,768,16,0xe1, + 0,0,0,0,0,0,0,0}, + {0x74,MM_DIRECT,1024,768,16,0xe1, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x68,1024,768,15,0xf0, + 5,11,6,5,5,0,0,0}, + {0x68,MM_DIRECT,1024,768,15,0xf0, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 6,5,10,5,5,5,0,1,15}, + 5,10,5,5,5,0,1,15},
- {0x78,800,600,24,0xe5, + {0x78,MM_DIRECT,800,600,24,0xe5, cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, - 6,8,16,8,8,8,0,0,0}, - {0x79,1024,768,24,0xe5, + 8,16,8,8,8,0,0,0}, + {0x79,MM_DIRECT,1024,768,24,0xe5, cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, - 6,8,16,8,8,8,0,0,0}, + 8,16,8,8,8,0,0,0},
- {0x6d,1280,1024,8,0x00, + {0x6d,MM_PACKED,1280,1024,8,0x00, cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x69,1280,1024,15,0xf0, + 0,0,0,0,0,0,0,0}, + {0x69,MM_DIRECT,1280,1024,15,0xf0, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 6,5,10,5,5,5,0,1,15}, - {0x75,1280,1024,16,0xe1, + 5,10,5,5,5,0,1,15}, + {0x75,MM_DIRECT,1280,1024,16,0xe1, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 6,5,11,6,5,5,0,0,0}, + 5,11,6,5,5,0,0,0},
- {0x7b,1600,1200,8,0x00, + {0x7b,MM_PACKED,1600,1200,8,0x00, cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, - 4,0,0,0,0,0,0,0,0}, + 0,0,0,0,0,0,0,0},
- {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, - 0xff,0,0,0,0,0,0,0,0}, + {0xfe,0xff,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, + 0,0,0,0,0,0,0,0}, };
@@ -345,11 +345,11 @@ cirrus_switch_mode(struct cirrus_mode_s *table) outb(GET_GLOBAL(table->hidden_dac), VGAREG_PEL_MASK); outb(0xff, VGAREG_PEL_MASK);
- u8 vesacolortype = GET_GLOBAL(table->vesacolortype); + u8 memmodel = GET_GLOBAL(table->memmodel); u8 v = stdvga_get_single_palette_reg(0x10) & 0xfe; - if (vesacolortype == 3) + if (memmodel == MM_PLANAR) v |= 0x41; - else if (vesacolortype) + else if (memmodel != MM_TEXT) v |= 0x01; stdvga_set_single_palette_reg(0x10, v); } @@ -752,7 +752,7 @@ cirrus_vesa_01h(struct bregs *regs) SET_FARVAR(seg, info->planes, 1); SET_FARVAR(seg, info->bits_per_pixel, GET_GLOBAL(table_g->depth)); SET_FARVAR(seg, info->banks, 1); - SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->vesacolortype)); + SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->memmodel)); SET_FARVAR(seg, info->bank_size, 0);
int pages = (cirrus_get_memsize() * 64 * 1024) / (height * linesize);
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/vgatables.c | 34 +++++++++++++++++----------------- 1 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index 048e6c5..fe860eb 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -337,39 +337,39 @@ static u8 crtc_6A[] VAR16 = { #define VPARAM(x) &video_param_table[x]
static struct vgamode_s vga_modes[] VAR16 = { - //mode model tx ty ch bits sstart slength + //mode model tx ty bpp cw ch sstart slength // pelm dac sequ misc crtc actl grdc - {0x00, MM_TEXT, 40, 25, 16, 4, SEG_CTEXT, 0x0800 + {0x00, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x01, MM_TEXT, 40, 25, 16, 4, SEG_CTEXT, 0x0800 + {0x01, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x02, MM_TEXT, 80, 25, 16, 4, SEG_CTEXT, 0x1000 + {0x02, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x03, MM_TEXT, 80, 25, 16, 4, SEG_CTEXT, 0x1000 + {0x03, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x04, MM_CGA, 40, 25, 8, 2, SEG_CTEXT, 0x0800 + {0x04, MM_CGA, 40, 25, 2, 8, 8, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x05, MM_CGA, 40, 25, 8, 2, SEG_CTEXT, 0x0800 + {0x05, MM_CGA, 40, 25, 2, 8, 8, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x06, MM_CGA, 80, 25, 8, 1, SEG_CTEXT, 0x1000 + {0x06, MM_CGA, 80, 25, 1, 8, 8, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06}, - {0x07, MM_TEXT, 80, 25, 16, 4, SEG_MTEXT, 0x1000 + {0x07, MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT, 0x1000 , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07}, - {0x0D, MM_PLANAR, 40, 25, 8, 4, SEG_GRAPH, 0x2000 + {0x0D, MM_PLANAR, 40, 25, 4, 8, 8, SEG_GRAPH, 0x2000 , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d}, - {0x0E, MM_PLANAR, 80, 25, 8, 4, SEG_GRAPH, 0x4000 + {0x0E, MM_PLANAR, 80, 25, 4, 8, 8, SEG_GRAPH, 0x4000 , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d}, - {0x0F, MM_PLANAR, 80, 25, 14, 1, SEG_GRAPH, 0x8000 + {0x0F, MM_PLANAR, 80, 25, 1, 8, 14, SEG_GRAPH, 0x8000 , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d}, - {0x10, MM_PLANAR, 80, 25, 14, 4, SEG_GRAPH, 0x8000 + {0x10, MM_PLANAR, 80, 25, 4, 8, 14, SEG_GRAPH, 0x8000 , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d}, - {0x11, MM_PLANAR, 80, 30, 16, 1, SEG_GRAPH, 0x0000 + {0x11, MM_PLANAR, 80, 30, 1, 8, 16, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d}, - {0x12, MM_PLANAR, 80, 30, 16, 4, SEG_GRAPH, 0x0000 + {0x12, MM_PLANAR, 80, 30, 4, 8, 16, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d}, - {0x13, MM_PACKED, 40, 25, 8, 8, SEG_GRAPH, 0x0000 + {0x13, MM_PACKED, 40, 25, 8, 8, 8, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13}, - {0x6A, MM_PLANAR, 100, 37, 16, 4, SEG_GRAPH, 0x0000 + {0x6A, MM_PLANAR, 100, 37, 4, 8, 16, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d}, };
The 0xfe mode isn't a real mode, it's a place holder for settings needed to switch back to non-cirrus modes. Handle it that way.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 61bfe92..ec0380f 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -293,10 +293,11 @@ static struct cirrus_mode_s cirrus_modes[] VAR16 = { {0x7b,MM_PACKED,1600,1200,8,0x00, cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, 0,0,0,0,0,0,0,0}, +};
+static struct cirrus_mode_s mode_switchback VAR16 = {0xfe,0xff,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, - 0,0,0,0,0,0,0,0}, -}; + 0,0,0,0,0,0,0,0};
/**************************************************************** @@ -405,8 +406,7 @@ clext_set_mode(int mode, int flags) SET_BDA(video_mode, mode); return 0; } - table_g = cirrus_get_modeentry(0xfe); - cirrus_switch_mode(table_g); + cirrus_switch_mode(&mode_switchback); dprintf(1, "cirrus mode switch regular\n"); return stdvga_set_mode(mode, flags); }
For graphics modes, store pixel width/height instead of text width/height. Add explicit char width field. Where needed, calculate text width/height from pixel width/height by dividing pixel count by character size.
Rename some fields and change field sizes to match cirrus/bochs definitions.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/stdvga.h | 11 +++++---- vgasrc/vgabios.c | 18 ++++++++++++---- vgasrc/vgafb.c | 10 ++++---- vgasrc/vgatables.c | 53 ++++++++++++++++++++++++++++++--------------------- 4 files changed, 55 insertions(+), 37 deletions(-)
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 0a99d37..735022c 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -45,12 +45,13 @@ #define SEG_MTEXT 0xB000
struct vgamode_s { - u8 svgamode; - u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - u8 twidth; - u8 theight; + u16 mode; + u8 memmodel; + u16 width; + u16 height; + u8 depth; + u8 cwidth; u8 cheight; - u8 pixbits; u16 sstart; u16 slength;
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 7bed069..31636cc 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -329,18 +329,26 @@ void modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) { // Set the BIOS mem - u16 cheight = GET_GLOBAL(vmode_g->cheight); + int width = GET_GLOBAL(vmode_g->width); + int height = GET_GLOBAL(vmode_g->height); + int cheight = GET_GLOBAL(vmode_g->cheight); SET_BDA(video_mode, mode); - SET_BDA(video_cols, GET_GLOBAL(vmode_g->twidth)); + if (GET_GLOBAL(vmode_g->memmodel) == MM_TEXT) { + SET_BDA(video_cols, width); + SET_BDA(video_rows, height-1); + SET_BDA(cursor_type, 0x0607); + } else { + int cwidth = GET_GLOBAL(vmode_g->cwidth); + SET_BDA(video_cols, width / cwidth); + SET_BDA(video_rows, (height / cheight) - 1); + SET_BDA(cursor_type, 0x0000); + } SET_BDA(video_pagesize, GET_GLOBAL(vmode_g->slength)); SET_BDA(crtc_address, stdvga_get_crtc()); - SET_BDA(video_rows, GET_GLOBAL(vmode_g->theight)-1); SET_BDA(char_height, cheight); SET_BDA(video_ctl, 0x60 | (flags & MF_NOCLEARMEM ? 0x80 : 0x00)); SET_BDA(video_switches, 0xF9); SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); - SET_BDA(cursor_type - , GET_GLOBAL(vmode_g->memmodel) == MM_TEXT ? 0x0607 : 0x0000); int i; for (i=0; i<8; i++) SET_BDA(cursor_pos[i], 0x0000); diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 0f33720..eb4ced8 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -75,7 +75,7 @@ scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { int cheight = GET_GLOBAL(vmode_g->cheight) / 2; - int cwidth = GET_GLOBAL(vmode_g->pixbits); + int cwidth = GET_GLOBAL(vmode_g->depth); int stride = GET_BDA(video_cols) * cwidth; void *src_far, *dest_far; if (nblines >= 0) { @@ -253,7 +253,7 @@ write_gfx_char_cga(struct vgamode_s *vmode_g return;
u8 *fdata_g = vgafont8; - u8 bpp = GET_GLOBAL(vmode_g->pixbits); + u8 bpp = GET_GLOBAL(vmode_g->depth); u16 addr = (cp.x * bpp) + cp.y * 320; u16 src = ca.car * 8; u8 i; @@ -431,14 +431,14 @@ vgafb_write_pixel(u8 color, u16 x, u16 y) stdvga_grdc_write(0x03, 0x00); break; case MM_CGA: - if (GET_GLOBAL(vmode_g->pixbits) == 2) + if (GET_GLOBAL(vmode_g->depth) == 2) addr_far = (void*)((x >> 2) + (y >> 1) * 80); else addr_far = (void*)((x >> 3) + (y >> 1) * 80); if (y & 1) addr_far += 0x2000; data = GET_FARVAR(SEG_CTEXT, *addr_far); - if (GET_GLOBAL(vmode_g->pixbits) == 2) { + if (GET_GLOBAL(vmode_g->depth) == 2) { attr = (color & 0x03) << ((3 - (x & 0x03)) * 2); mask = 0x03 << ((3 - (x & 0x03)) * 2); } else { @@ -489,7 +489,7 @@ vgafb_read_pixel(u16 x, u16 y) if (y & 1) addr_far += 0x2000; data = GET_FARVAR(SEG_CTEXT, *addr_far); - if (GET_GLOBAL(vmode_g->pixbits) == 2) + if (GET_GLOBAL(vmode_g->depth) == 2) attr = (data >> ((3 - (x & 0x03)) * 2)) & 0x03; else attr = (data >> (7 - (x & 0x07))) & 0x01; diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index fe860eb..314222e 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -54,16 +54,25 @@ build_video_param(void)
int i; for (i=0; i<ARRAY_SIZE(parammodes); i++) { - u8 mode = GET_GLOBAL(parammodes[i]); + int mode = GET_GLOBAL(parammodes[i]); if (! mode) continue; struct VideoParam_s *vparam_g = &video_param_table[i]; struct vgamode_s *vmode_g = find_vga_entry(mode); if (!vmode_g) continue; - SET_VGA(vparam_g->twidth, GET_GLOBAL(vmode_g->twidth)); - SET_VGA(vparam_g->theightm1, GET_GLOBAL(vmode_g->theight)-1); - SET_VGA(vparam_g->cheight, GET_GLOBAL(vmode_g->cheight)); + int width = GET_GLOBAL(vmode_g->width); + int height = GET_GLOBAL(vmode_g->height); + int cheight = GET_GLOBAL(vmode_g->cheight); + if (GET_GLOBAL(vmode_g->memmodel) == MM_TEXT) { + SET_VGA(vparam_g->twidth, width); + SET_VGA(vparam_g->theightm1, height-1); + } else { + int cwidth = GET_GLOBAL(vmode_g->cwidth); + SET_VGA(vparam_g->twidth, width / cwidth); + SET_VGA(vparam_g->theightm1, (height / cheight) - 1); + } + SET_VGA(vparam_g->cheight, cheight); SET_VGA(vparam_g->slength, GET_GLOBAL(vmode_g->slength)); memcpy_far(get_global_seg(), vparam_g->sequ_regs , get_global_seg(), GET_GLOBAL(vmode_g->sequ_regs) @@ -337,39 +346,39 @@ static u8 crtc_6A[] VAR16 = { #define VPARAM(x) &video_param_table[x]
static struct vgamode_s vga_modes[] VAR16 = { - //mode model tx ty bpp cw ch sstart slength + //mode model tx ty bpp cw ch sstart slength // pelm dac sequ misc crtc actl grdc - {0x00, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 + {0x00, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x01, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 + {0x01, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x02, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 + {0x02, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x03, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 + {0x03, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x04, MM_CGA, 40, 25, 2, 8, 8, SEG_CTEXT, 0x0800 + {0x04, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x05, MM_CGA, 40, 25, 2, 8, 8, SEG_CTEXT, 0x0800 + {0x05, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT, 0x0800 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x06, MM_CGA, 80, 25, 1, 8, 8, SEG_CTEXT, 0x1000 + {0x06, MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT, 0x1000 , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06}, - {0x07, MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT, 0x1000 + {0x07, MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT, 0x1000 , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07}, - {0x0D, MM_PLANAR, 40, 25, 4, 8, 8, SEG_GRAPH, 0x2000 + {0x0D, MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH, 0x2000 , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d}, - {0x0E, MM_PLANAR, 80, 25, 4, 8, 8, SEG_GRAPH, 0x4000 + {0x0E, MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH, 0x4000 , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d}, - {0x0F, MM_PLANAR, 80, 25, 1, 8, 14, SEG_GRAPH, 0x8000 + {0x0F, MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH, 0x8000 , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d}, - {0x10, MM_PLANAR, 80, 25, 4, 8, 14, SEG_GRAPH, 0x8000 + {0x10, MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH, 0x8000 , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d}, - {0x11, MM_PLANAR, 80, 30, 1, 8, 16, SEG_GRAPH, 0x0000 + {0x11, MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d}, - {0x12, MM_PLANAR, 80, 30, 4, 8, 16, SEG_GRAPH, 0x0000 + {0x12, MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d}, - {0x13, MM_PACKED, 40, 25, 8, 8, 8, SEG_GRAPH, 0x0000 + {0x13, MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13}, - {0x6A, MM_PLANAR, 100, 37, 4, 8, 16, SEG_GRAPH, 0x0000 + {0x6A, MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH, 0x0000 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d}, };
@@ -379,7 +388,7 @@ find_vga_entry(u8 mode) int i; for (i = 0; i < ARRAY_SIZE(vga_modes); i++) { struct vgamode_s *vmode_g = &vga_modes[i]; - if (GET_GLOBAL(vmode_g->svgamode) == mode) + if (GET_GLOBAL(vmode_g->mode) == mode) return vmode_g; } return NULL;
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 123 +++++++++++++++++++++++++++-------------------------- 1 files changed, 62 insertions(+), 61 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 70ac449..6652c2e 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -9,73 +9,74 @@ static struct mode { u16 mode; + u8 memmodel; u16 width; u16 height; u8 depth; } bochsvga_modes[] VAR16 = { /* standard modes */ - { 0x100, 640, 400, 8 }, - { 0x101, 640, 480, 8 }, - { 0x102, 800, 600, 4 }, - { 0x103, 800, 600, 8 }, - { 0x104, 1024, 768, 4 }, - { 0x105, 1024, 768, 8 }, - { 0x106, 1280, 1024, 4 }, - { 0x107, 1280, 1024, 8 }, - { 0x10D, 320, 200, 15 }, - { 0x10E, 320, 200, 16 }, - { 0x10F, 320, 200, 24 }, - { 0x110, 640, 480, 15 }, - { 0x111, 640, 480, 16 }, - { 0x112, 640, 480, 24 }, - { 0x113, 800, 600, 15 }, - { 0x114, 800, 600, 16 }, - { 0x115, 800, 600, 24 }, - { 0x116, 1024, 768, 15 }, - { 0x117, 1024, 768, 16 }, - { 0x118, 1024, 768, 24 }, - { 0x119, 1280, 1024, 15 }, - { 0x11A, 1280, 1024, 16 }, - { 0x11B, 1280, 1024, 24 }, - { 0x11C, 1600, 1200, 8 }, - { 0x11D, 1600, 1200, 15 }, - { 0x11E, 1600, 1200, 16 }, - { 0x11F, 1600, 1200, 24 }, + { 0x100, MM_PACKED, 640, 400, 8 }, + { 0x101, MM_PACKED, 640, 480, 8 }, + { 0x102, MM_PLANAR, 800, 600, 4 }, + { 0x103, MM_PACKED, 800, 600, 8 }, + { 0x104, MM_PLANAR, 1024, 768, 4 }, + { 0x105, MM_PACKED, 1024, 768, 8 }, + { 0x106, MM_PLANAR, 1280, 1024, 4 }, + { 0x107, MM_PACKED, 1280, 1024, 8 }, + { 0x10D, MM_DIRECT, 320, 200, 15 }, + { 0x10E, MM_DIRECT, 320, 200, 16 }, + { 0x10F, MM_DIRECT, 320, 200, 24 }, + { 0x110, MM_DIRECT, 640, 480, 15 }, + { 0x111, MM_DIRECT, 640, 480, 16 }, + { 0x112, MM_DIRECT, 640, 480, 24 }, + { 0x113, MM_DIRECT, 800, 600, 15 }, + { 0x114, MM_DIRECT, 800, 600, 16 }, + { 0x115, MM_DIRECT, 800, 600, 24 }, + { 0x116, MM_DIRECT, 1024, 768, 15 }, + { 0x117, MM_DIRECT, 1024, 768, 16 }, + { 0x118, MM_DIRECT, 1024, 768, 24 }, + { 0x119, MM_DIRECT, 1280, 1024, 15 }, + { 0x11A, MM_DIRECT, 1280, 1024, 16 }, + { 0x11B, MM_DIRECT, 1280, 1024, 24 }, + { 0x11C, MM_PACKED, 1600, 1200, 8 }, + { 0x11D, MM_DIRECT, 1600, 1200, 15 }, + { 0x11E, MM_DIRECT, 1600, 1200, 16 }, + { 0x11F, MM_DIRECT, 1600, 1200, 24 }, /* BOCHS modes */ - { 0x140, 320, 200, 32 }, - { 0x141, 640, 400, 32 }, - { 0x142, 640, 480, 32 }, - { 0x143, 800, 600, 32 }, - { 0x144, 1024, 768, 32 }, - { 0x145, 1280, 1024, 32 }, - { 0x146, 320, 200, 8 }, - { 0x147, 1600, 1200, 32 }, - { 0x148, 1152, 864, 8 }, - { 0x149, 1152, 864, 15 }, - { 0x14a, 1152, 864, 16 }, - { 0x14b, 1152, 864, 24 }, - { 0x14c, 1152, 864, 32 }, - { 0x178, 1280, 800, 16 }, - { 0x179, 1280, 800, 24 }, - { 0x17a, 1280, 800, 32 }, - { 0x17b, 1280, 960, 16 }, - { 0x17c, 1280, 960, 24 }, - { 0x17d, 1280, 960, 32 }, - { 0x17e, 1440, 900, 16 }, - { 0x17f, 1440, 900, 24 }, - { 0x180, 1440, 900, 32 }, - { 0x181, 1400, 1050, 16 }, - { 0x182, 1400, 1050, 24 }, - { 0x183, 1400, 1050, 32 }, - { 0x184, 1680, 1050, 16 }, - { 0x185, 1680, 1050, 24 }, - { 0x186, 1680, 1050, 32 }, - { 0x187, 1920, 1200, 16 }, - { 0x188, 1920, 1200, 24 }, - { 0x189, 1920, 1200, 32 }, - { 0x18a, 2560, 1600, 16 }, - { 0x18b, 2560, 1600, 24 }, - { 0x18c, 2560, 1600, 32 }, + { 0x140, MM_DIRECT, 320, 200, 32 }, + { 0x141, MM_DIRECT, 640, 400, 32 }, + { 0x142, MM_DIRECT, 640, 480, 32 }, + { 0x143, MM_DIRECT, 800, 600, 32 }, + { 0x144, MM_DIRECT, 1024, 768, 32 }, + { 0x145, MM_DIRECT, 1280, 1024, 32 }, + { 0x146, MM_PACKED, 320, 200, 8 }, + { 0x147, MM_DIRECT, 1600, 1200, 32 }, + { 0x148, MM_PACKED, 1152, 864, 8 }, + { 0x149, MM_DIRECT, 1152, 864, 15 }, + { 0x14a, MM_DIRECT, 1152, 864, 16 }, + { 0x14b, MM_DIRECT, 1152, 864, 24 }, + { 0x14c, MM_DIRECT, 1152, 864, 32 }, + { 0x178, MM_DIRECT, 1280, 800, 16 }, + { 0x179, MM_DIRECT, 1280, 800, 24 }, + { 0x17a, MM_DIRECT, 1280, 800, 32 }, + { 0x17b, MM_DIRECT, 1280, 960, 16 }, + { 0x17c, MM_DIRECT, 1280, 960, 24 }, + { 0x17d, MM_DIRECT, 1280, 960, 32 }, + { 0x17e, MM_DIRECT, 1440, 900, 16 }, + { 0x17f, MM_DIRECT, 1440, 900, 24 }, + { 0x180, MM_DIRECT, 1440, 900, 32 }, + { 0x181, MM_DIRECT, 1400, 1050, 16 }, + { 0x182, MM_DIRECT, 1400, 1050, 24 }, + { 0x183, MM_DIRECT, 1400, 1050, 32 }, + { 0x184, MM_DIRECT, 1680, 1050, 16 }, + { 0x185, MM_DIRECT, 1680, 1050, 24 }, + { 0x186, MM_DIRECT, 1680, 1050, 32 }, + { 0x187, MM_DIRECT, 1920, 1200, 16 }, + { 0x188, MM_DIRECT, 1920, 1200, 24 }, + { 0x189, MM_DIRECT, 1920, 1200, 32 }, + { 0x18a, MM_DIRECT, 2560, 1600, 16 }, + { 0x18b, MM_DIRECT, 2560, 1600, 24 }, + { 0x18c, MM_DIRECT, 2560, 1600, 32 }, { 0, }, };
The previous code could obtain the page size in different ways - from vmode_g->sslength, from SCREEN_MEM_START, or by manually multiplying cols and rows. Add a new func (calc_page_size) and use that in areas that need to calculate the page size.
Convert readers of the page size to read it from the "video_pagesize" entry in the BDA instead of recalculating it.
Remove the page size from struct vgamode_s (slength) as it is now calculated dynamically. The new calculated versions are different from the existing values exported in video_param_table. However, the existing values (for CGA) did not look correct - I compared the values to those exported by two other VGA BIOS manufacturers and used the values that look more standard.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/stdvga.h | 1 - vgasrc/vgabios.c | 53 +++++++++++++++++++++++++-------------------------- vgasrc/vgabios.h | 4 +-- vgasrc/vgafb.c | 20 +++++------------- vgasrc/vgatables.c | 39 +++++++++++++++++++------------------ 5 files changed, 53 insertions(+), 64 deletions(-)
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 735022c..2aabf1b 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -53,7 +53,6 @@ struct vgamode_s { u8 cwidth; u8 cheight; u16 sstart; - u16 slength;
u8 pelmask; u8 *dac; diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 31636cc..854ed38 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -48,6 +48,19 @@ struct pci_data rom_pci_data VAR16VISIBLE = { * Helper functions ****************************************************************/
+u16 +calc_page_size(u8 memmodel, u16 width, u16 height) +{ + switch (memmodel) { + case MM_TEXT: + return ALIGN(width * height * 2, 2*1024); + case MM_CGA: + return 16*1024; + default: + return ALIGN(width * height / 8, 8*1024); + } +} + static void set_cursor_shape(u8 start, u8 end) { @@ -93,15 +106,12 @@ set_cursor_pos(struct cursorpos cp) if (cp.page != current) return;
- // Get the dimensions + // Calculate the memory address u16 nbcols = GET_BDA(video_cols); - u16 nbrows = GET_BDA(video_rows) + 1; + u16 address = (GET_BDA(video_pagesize) * cp.page + + (cp.x + cp.y * nbcols) * 2);
- // Calculate the address knowing nbcols nbrows and page num - u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page) - + cp.x + cp.y * nbcols); - - stdvga_set_cursor_pos(address); + stdvga_set_cursor_pos(address / 2); }
static struct cursorpos @@ -134,25 +144,13 @@ set_active_page(u8 page) // Get pos curs pos for the right page struct cursorpos cp = get_cursor_pos(page);
- u16 address; - if (GET_GLOBAL(vmode_g->memmodel) == MM_TEXT) { - // 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_MEM_START(nbcols, nbrows, page); - SET_BDA(video_pagestart, address); - - // Start address - address = SCREEN_IO_START(nbcols, nbrows, page); - } else { - address = page * GET_GLOBAL(vmode_g->slength); - } - - stdvga_set_active_page(address); + // Calculate memory address of start of page + u8 memmodel = GET_GLOBAL(vmode_g->memmodel); + u16 address = GET_BDA(video_pagesize) * page; + stdvga_set_active_page(memmodel == MM_TEXT ? address / 2 : address);
// And change the BIOS page + SET_BDA(video_pagestart, address); SET_BDA(video_page, page);
dprintf(1, "Set active page %02x address %04x\n", page, address); @@ -174,7 +172,7 @@ set_scan_lines(u8 lines) u8 rows = vde / lines; SET_BDA(video_rows, rows - 1); u16 cols = GET_BDA(video_cols); - SET_BDA(video_pagesize, rows * cols * 2); + SET_BDA(video_pagesize, calc_page_size(MM_TEXT, cols, rows)); }
@@ -331,9 +329,10 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) // Set the BIOS mem int width = GET_GLOBAL(vmode_g->width); int height = GET_GLOBAL(vmode_g->height); + u8 memmodel = GET_GLOBAL(vmode_g->memmodel); int cheight = GET_GLOBAL(vmode_g->cheight); SET_BDA(video_mode, mode); - if (GET_GLOBAL(vmode_g->memmodel) == MM_TEXT) { + if (memmodel == MM_TEXT) { SET_BDA(video_cols, width); SET_BDA(video_rows, height-1); SET_BDA(cursor_type, 0x0607); @@ -343,7 +342,7 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g) SET_BDA(video_rows, (height / cheight) - 1); SET_BDA(cursor_type, 0x0000); } - SET_BDA(video_pagesize, GET_GLOBAL(vmode_g->slength)); + SET_BDA(video_pagesize, calc_page_size(memmodel, width, height)); SET_BDA(crtc_address, stdvga_get_crtc()); SET_BDA(char_height, cheight); SET_BDA(video_ctl, 0x60 | (flags & MF_NOCLEARMEM ? 0x80 : 0x00)); diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 7c5e8d3..8b806ff 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -4,9 +4,6 @@ #include "types.h" // u8 #include "farptr.h" // struct segoff_s
-#define SCREEN_IO_START(x,y,p) (((((x)*(y)) | 0x00ff) + 1) * (p)) -#define SCREEN_MEM_START(x,y,p) SCREEN_IO_START(((x)*2),(y),(p)) - struct saveBDAstate { u8 video_mode; u16 video_cols; @@ -66,6 +63,7 @@ struct carattr { struct cursorpos { u8 x, y, page; }; +u16 calc_page_size(u8 memmodel, u16 width, u16 height); void modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g);
// vgafb.c diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index eb4ced8..b933738 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -139,10 +139,8 @@ scroll_text(struct vgamode_s *vmode_g, int nblines, int attr { int cheight = 1; int cwidth = 2; - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - int stride = nbcols * cwidth; - void *src_far, *dest_far = (void*)SCREEN_MEM_START(nbcols, nbrows, ul.page); + int stride = GET_BDA(video_cols) * cwidth; + void *src_far, *dest_far = (void*)(GET_BDA(video_pagesize) * ul.page); if (nblines >= 0) { dest_far += ul.y * cheight * stride + ul.x * cwidth; src_far = dest_far + nblines * cheight * stride; @@ -330,12 +328,9 @@ static void write_text_char(struct vgamode_s *vmode_g , struct cursorpos cp, struct carattr ca) { - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - // Compute the address - void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page) + u16 nbcols = GET_BDA(video_cols); + void *address_far = (void*)(GET_BDA(video_pagesize) * cp.page + (cp.x + cp.y * nbcols) * 2);
if (ca.use_attr) { @@ -386,12 +381,9 @@ vgafb_read_char(struct cursorpos cp) goto fail; }
- // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - // Compute the address - u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page) + u16 nbcols = GET_BDA(video_cols); + u16 *address_far = (void*)(GET_BDA(video_pagesize) * cp.page + (cp.x + cp.y * nbcols) * 2); u16 v = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far); struct carattr ca = {v, v>>8, 0}; diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index 314222e..4fd9964 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -63,8 +63,9 @@ build_video_param(void) continue; int width = GET_GLOBAL(vmode_g->width); int height = GET_GLOBAL(vmode_g->height); + u8 memmodel = GET_GLOBAL(vmode_g->memmodel); int cheight = GET_GLOBAL(vmode_g->cheight); - if (GET_GLOBAL(vmode_g->memmodel) == MM_TEXT) { + if (memmodel == MM_TEXT) { SET_VGA(vparam_g->twidth, width); SET_VGA(vparam_g->theightm1, height-1); } else { @@ -73,7 +74,7 @@ build_video_param(void) SET_VGA(vparam_g->theightm1, (height / cheight) - 1); } SET_VGA(vparam_g->cheight, cheight); - SET_VGA(vparam_g->slength, GET_GLOBAL(vmode_g->slength)); + SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height)); memcpy_far(get_global_seg(), vparam_g->sequ_regs , get_global_seg(), GET_GLOBAL(vmode_g->sequ_regs) , ARRAY_SIZE(vparam_g->sequ_regs)); @@ -346,39 +347,39 @@ static u8 crtc_6A[] VAR16 = { #define VPARAM(x) &video_param_table[x]
static struct vgamode_s vga_modes[] VAR16 = { - //mode model tx ty bpp cw ch sstart slength + //mode model tx ty bpp cw ch sstart // pelm dac sequ misc crtc actl grdc - {0x00, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 + {0x00, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x01, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT, 0x0800 + {0x01, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x02, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 + {0x02, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x03, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT, 0x1000 + {0x03, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x04, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT, 0x0800 + {0x04, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x05, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT, 0x0800 + {0x05, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x06, MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT, 0x1000 + {0x06, MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06}, - {0x07, MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT, 0x1000 + {0x07, MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07}, - {0x0D, MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH, 0x2000 + {0x0D, MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d}, - {0x0E, MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH, 0x4000 + {0x0E, MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d}, - {0x0F, MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH, 0x8000 + {0x0F, MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d}, - {0x10, MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH, 0x8000 + {0x10, MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d}, - {0x11, MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH, 0x0000 + {0x11, MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d}, - {0x12, MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH, 0x0000 + {0x12, MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d}, - {0x13, MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH, 0x0000 + {0x13, MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13}, - {0x6A, MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH, 0x0000 + {0x6A, MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d}, };
Extract out the fields in 'struct vgamode_s' that are used in the main code. The remaining fields are specific to the standard vga hardware driver.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/geodevga.c | 6 +++- vgasrc/stdvga.c | 21 +++++++++--------- vgasrc/stdvga.h | 15 ++++++------- vgasrc/vgabios.c | 6 ++-- vgasrc/vgabios.h | 12 +++++++++- vgasrc/vgafb.c | 12 +++++----- vgasrc/vgahw.h | 4 +++ vgasrc/vgatables.c | 58 ++++++++++++++++++++++++++------------------------- 8 files changed, 75 insertions(+), 59 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 7735fdc..c1e4244 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -367,10 +367,12 @@ int geodevga_init(void) u8 *crtc = GET_GLOBAL(new_crtc[i]); if (!crtc) continue; - struct vgamode_s *vmode_g = find_vga_entry(i); + struct vgamode_s *vmode_g = stdvga_find_mode(i); if (!vmode_g) continue; - SET_VGA(vmode_g->crtc_regs, crtc); + struct stdvga_mode_s *stdmode_g = container_of( + vmode_g, struct stdvga_mode_s, info); + SET_VGA(stdmode_g->crtc_regs, crtc); }
ret |= vp_setup(); diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index e90d48f..70d018a 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -11,7 +11,6 @@ #include "biosvar.h" // GET_GLOBAL #include "util.h" // memcpy_far #include "vbe.h" // VBE_RETURN_STATUS_FAILED -#include "vgabios.h" // find_vga_entry
// TODO // * replace direct in/out calls with wrapper functions @@ -544,18 +543,20 @@ int stdvga_set_mode(int mode, int flags) { // find the entry in the video modes - struct vgamode_s *vmode_g = find_vga_entry(mode); + struct vgamode_s *vmode_g = stdvga_find_mode(mode); dprintf(1, "mode search %02x found %p\n", mode, vmode_g); if (!vmode_g) return VBE_RETURN_STATUS_FAILED; + struct stdvga_mode_s *stdmode_g = container_of( + vmode_g, struct stdvga_mode_s, info);
// if palette loading (bit 3 of modeset ctl = 0) if (!(flags & MF_NOPALETTE)) { // Set the PEL mask - stdvga_set_pel_mask(GET_GLOBAL(vmode_g->pelmask)); + stdvga_set_pel_mask(GET_GLOBAL(stdmode_g->pelmask));
// From which palette - u8 *palette_g = GET_GLOBAL(vmode_g->dac); - u16 palsize = GET_GLOBAL(vmode_g->dacsize) / 3; + u8 *palette_g = GET_GLOBAL(stdmode_g->dac); + u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3;
// Always 256*3 values stdvga_set_dac_regs(get_global_seg(), palette_g, 0, palsize); @@ -573,7 +574,7 @@ stdvga_set_mode(int mode, int flags) inb(VGAREG_ACTL_RESET);
// Set Attribute Ctl - u8 *regs = GET_GLOBAL(vmode_g->actl_regs); + u8 *regs = GET_GLOBAL(stdmode_g->actl_regs); u16 i; for (i = 0; i <= 0x13; i++) { outb(i, VGAREG_ACTL_ADDRESS); @@ -585,21 +586,21 @@ stdvga_set_mode(int mode, int flags) // Set Sequencer Ctl outb(0, VGAREG_SEQU_ADDRESS); outb(0x03, VGAREG_SEQU_DATA); - regs = GET_GLOBAL(vmode_g->sequ_regs); + regs = GET_GLOBAL(stdmode_g->sequ_regs); for (i = 1; i <= 4; i++) { outb(i, VGAREG_SEQU_ADDRESS); outb(GET_GLOBAL(regs[i - 1]), VGAREG_SEQU_DATA); }
// Set Grafx Ctl - regs = GET_GLOBAL(vmode_g->grdc_regs); + regs = GET_GLOBAL(stdmode_g->grdc_regs); for (i = 0; i <= 8; i++) { outb(i, VGAREG_GRDC_ADDRESS); outb(GET_GLOBAL(regs[i]), VGAREG_GRDC_DATA); }
// Set CRTC address VGA or MDA - u8 miscreg = GET_GLOBAL(vmode_g->miscreg); + u8 miscreg = GET_GLOBAL(stdmode_g->miscreg); u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; if (!(miscreg & 1)) crtc_addr = VGAREG_MDA_CRTC_ADDRESS; @@ -607,7 +608,7 @@ stdvga_set_mode(int mode, int flags) // Disable CRTC write protection outw(0x0011, crtc_addr); // Set CRTC regs - regs = GET_GLOBAL(vmode_g->crtc_regs); + regs = GET_GLOBAL(stdmode_g->crtc_regs); for (i = 0; i <= 0x18; i++) { outb(i, crtc_addr); outb(GET_GLOBAL(regs[i]), crtc_addr + 1); diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 2aabf1b..4cef89f 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -2,6 +2,7 @@ #define __STDVGA_H
#include "types.h" // u8 +#include "vgabios.h" // struct vgamode_s
// VGA registers #define VGAREG_ACTL_ADDRESS 0x3c0 @@ -44,15 +45,9 @@ #define SEG_CTEXT 0xB800 #define SEG_MTEXT 0xB000
-struct vgamode_s { +struct stdvga_mode_s { u16 mode; - u8 memmodel; - u16 width; - u16 height; - u8 depth; - u8 cwidth; - u8 cheight; - u16 sstart; + struct vgamode_s info;
u8 pelmask; u8 *dac; @@ -87,6 +82,10 @@ struct saveDACcolors { u8 color_select; };
+// vgatables.c +struct vgamode_s *stdvga_find_mode(int mode); + +// stdvga.c void stdvga_set_border_color(u8 color); void stdvga_set_overscan_border_color(u8 color); u8 stdvga_get_overscan_border_color(void); diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 854ed38..f351107 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -14,10 +14,10 @@ #include "bregs.h" // struct bregs #include "biosvar.h" // GET_BDA #include "util.h" // memset -#include "vgabios.h" // find_vga_entry +#include "vgabios.h" // calc_page_size #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* -#include "stdvga.h" // stdvga_set_mode +#include "stdvga.h" // stdvga_set_cursor_shape #include "geodevga.h" // geodevga_init #include "bochsvga.h" // bochsvga_init #include "clext.h" // clext_init @@ -137,7 +137,7 @@ set_active_page(u8 page) return;
// Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode)); if (!vmode_g) return;
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 8b806ff..3416b98 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -40,9 +40,17 @@ struct saveBDAstate { #define MM_DIRECT 0x06 #define MM_YUV 0x07
+struct vgamode_s { + u8 memmodel; + u16 width; + u16 height; + u8 depth; + u8 cwidth; + u8 cheight; + u16 sstart; +}; + // vgatables.c -struct vgamode_s; -struct vgamode_s *find_vga_entry(u8 mode); void build_video_param(void); extern struct VideoSavePointer_s video_save_pointer_table; extern u8 static_functionality[]; diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index b933738..b6daba6 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -7,7 +7,7 @@
#include "biosvar.h" // GET_BDA #include "util.h" // memset_far -#include "vgabios.h" // find_vga_entry +#include "vgahw.h" // vgahw_find_mode #include "stdvga.h" // stdvga_grdc_write
@@ -168,7 +168,7 @@ void vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr) { // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode)); if (!vmode_g) return;
@@ -345,7 +345,7 @@ void vgafb_write_char(struct cursorpos cp, struct carattr ca) { // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode)); if (!vmode_g) return;
@@ -371,7 +371,7 @@ struct carattr vgafb_read_char(struct cursorpos cp) { // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode)); if (!vmode_g) goto fail;
@@ -403,7 +403,7 @@ void vgafb_write_pixel(u8 color, u16 x, u16 y) { // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode)); if (!vmode_g) return;
@@ -459,7 +459,7 @@ u8 vgafb_read_pixel(u16 x, u16 y) { // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + struct vgamode_s *vmode_g = vgahw_find_mode(GET_BDA(video_mode)); if (!vmode_g) return 0;
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 23b4f13..55e3bc4 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -9,6 +9,10 @@ #include "stdvga.h" // stdvga_set_mode #include "geodevga.h" // geodevga_init
+static inline struct vgamode_s *vgahw_find_mode(int mode) { + return stdvga_find_mode(mode); +} + static inline int vgahw_set_mode(int mode, int flags) { if (CONFIG_VGA_CIRRUS) return clext_set_mode(mode, flags); diff --git a/vgasrc/vgatables.c b/vgasrc/vgatables.c index 4fd9964..e62b11e 100644 --- a/vgasrc/vgatables.c +++ b/vgasrc/vgatables.c @@ -58,7 +58,7 @@ build_video_param(void) if (! mode) continue; struct VideoParam_s *vparam_g = &video_param_table[i]; - struct vgamode_s *vmode_g = find_vga_entry(mode); + struct vgamode_s *vmode_g = stdvga_find_mode(mode); if (!vmode_g) continue; int width = GET_GLOBAL(vmode_g->width); @@ -75,18 +75,20 @@ build_video_param(void) } SET_VGA(vparam_g->cheight, cheight); SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height)); + struct stdvga_mode_s *stdmode_g = container_of( + vmode_g, struct stdvga_mode_s, info); memcpy_far(get_global_seg(), vparam_g->sequ_regs - , get_global_seg(), GET_GLOBAL(vmode_g->sequ_regs) + , get_global_seg(), GET_GLOBAL(stdmode_g->sequ_regs) , ARRAY_SIZE(vparam_g->sequ_regs)); - SET_VGA(vparam_g->miscreg, GET_GLOBAL(vmode_g->miscreg)); + SET_VGA(vparam_g->miscreg, GET_GLOBAL(stdmode_g->miscreg)); memcpy_far(get_global_seg(), vparam_g->crtc_regs - , get_global_seg(), GET_GLOBAL(vmode_g->crtc_regs) + , get_global_seg(), GET_GLOBAL(stdmode_g->crtc_regs) , ARRAY_SIZE(vparam_g->crtc_regs)); memcpy_far(get_global_seg(), vparam_g->actl_regs - , get_global_seg(), GET_GLOBAL(vmode_g->actl_regs) + , get_global_seg(), GET_GLOBAL(stdmode_g->actl_regs) , ARRAY_SIZE(vparam_g->actl_regs)); memcpy_far(get_global_seg(), vparam_g->grdc_regs - , get_global_seg(), GET_GLOBAL(vmode_g->grdc_regs) + , get_global_seg(), GET_GLOBAL(stdmode_g->grdc_regs) , ARRAY_SIZE(vparam_g->grdc_regs)); }
@@ -346,51 +348,51 @@ static u8 crtc_6A[] VAR16 = { #define PAL(x) x, sizeof(x) #define VPARAM(x) &video_param_table[x]
-static struct vgamode_s vga_modes[] VAR16 = { - //mode model tx ty bpp cw ch sstart +static struct stdvga_mode_s vga_modes[] VAR16 = { + //mode { model tx ty bpp cw ch sstart } // pelm dac sequ misc crtc actl grdc - {0x00, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT + {0x00, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT } , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x01, MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT + {0x01, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT } , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01}, - {0x02, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT + {0x02, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT } , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x03, MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT + {0x03, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT } , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01}, - {0x04, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT + {0x04, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT } , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x05, MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT + {0x05, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT } , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04}, - {0x06, MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT + {0x06, { MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT } , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06}, - {0x07, MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT + {0x07, { MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT } , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07}, - {0x0D, MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH + {0x0D, { MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH } , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d}, - {0x0E, MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH + {0x0E, { MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH } , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d}, - {0x0F, MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH + {0x0F, { MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH } , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d}, - {0x10, MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH + {0x10, { MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH } , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d}, - {0x11, MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH + {0x11, { MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH } , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d}, - {0x12, MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH + {0x12, { MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH } , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d}, - {0x13, MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH + {0x13, { MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH } , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13}, - {0x6A, MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH + {0x6A, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH } , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d}, };
struct vgamode_s * -find_vga_entry(u8 mode) +stdvga_find_mode(int mode) { int i; for (i = 0; i < ARRAY_SIZE(vga_modes); i++) { - struct vgamode_s *vmode_g = &vga_modes[i]; - if (GET_GLOBAL(vmode_g->mode) == mode) - return vmode_g; + struct stdvga_mode_s *stdmode_g = &vga_modes[i]; + if (GET_GLOBAL(stdmode_g->mode) == mode) + return &stdmode_g->info; } return NULL; }
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 171 +++++++++++++++++++++++++---------------------------- vgasrc/bochsvga.h | 1 + vgasrc/clext.c | 63 ++++++++++--------- vgasrc/clext.h | 1 + vgasrc/vgahw.h | 4 + 5 files changed, 120 insertions(+), 120 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 6652c2e..d1919ec 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -6,78 +6,74 @@ #include "biosvar.h" // SET_BDA #include "stdvga.h" // VGAREG_SEQU_ADDRESS
-static struct mode +static struct bochsvga_mode { u16 mode; - u8 memmodel; - u16 width; - u16 height; - u8 depth; + struct vgamode_s info; } bochsvga_modes[] VAR16 = { /* standard modes */ - { 0x100, MM_PACKED, 640, 400, 8 }, - { 0x101, MM_PACKED, 640, 480, 8 }, - { 0x102, MM_PLANAR, 800, 600, 4 }, - { 0x103, MM_PACKED, 800, 600, 8 }, - { 0x104, MM_PLANAR, 1024, 768, 4 }, - { 0x105, MM_PACKED, 1024, 768, 8 }, - { 0x106, MM_PLANAR, 1280, 1024, 4 }, - { 0x107, MM_PACKED, 1280, 1024, 8 }, - { 0x10D, MM_DIRECT, 320, 200, 15 }, - { 0x10E, MM_DIRECT, 320, 200, 16 }, - { 0x10F, MM_DIRECT, 320, 200, 24 }, - { 0x110, MM_DIRECT, 640, 480, 15 }, - { 0x111, MM_DIRECT, 640, 480, 16 }, - { 0x112, MM_DIRECT, 640, 480, 24 }, - { 0x113, MM_DIRECT, 800, 600, 15 }, - { 0x114, MM_DIRECT, 800, 600, 16 }, - { 0x115, MM_DIRECT, 800, 600, 24 }, - { 0x116, MM_DIRECT, 1024, 768, 15 }, - { 0x117, MM_DIRECT, 1024, 768, 16 }, - { 0x118, MM_DIRECT, 1024, 768, 24 }, - { 0x119, MM_DIRECT, 1280, 1024, 15 }, - { 0x11A, MM_DIRECT, 1280, 1024, 16 }, - { 0x11B, MM_DIRECT, 1280, 1024, 24 }, - { 0x11C, MM_PACKED, 1600, 1200, 8 }, - { 0x11D, MM_DIRECT, 1600, 1200, 15 }, - { 0x11E, MM_DIRECT, 1600, 1200, 16 }, - { 0x11F, MM_DIRECT, 1600, 1200, 24 }, + { 0x100, { MM_PACKED, 640, 400, 8 } }, + { 0x101, { MM_PACKED, 640, 480, 8 } }, + { 0x102, { MM_PLANAR, 800, 600, 4 } }, + { 0x103, { MM_PACKED, 800, 600, 8 } }, + { 0x104, { MM_PLANAR, 1024, 768, 4 } }, + { 0x105, { MM_PACKED, 1024, 768, 8 } }, + { 0x106, { MM_PLANAR, 1280, 1024, 4 } }, + { 0x107, { MM_PACKED, 1280, 1024, 8 } }, + { 0x10D, { MM_DIRECT, 320, 200, 15 } }, + { 0x10E, { MM_DIRECT, 320, 200, 16 } }, + { 0x10F, { MM_DIRECT, 320, 200, 24 } }, + { 0x110, { MM_DIRECT, 640, 480, 15 } }, + { 0x111, { MM_DIRECT, 640, 480, 16 } }, + { 0x112, { MM_DIRECT, 640, 480, 24 } }, + { 0x113, { MM_DIRECT, 800, 600, 15 } }, + { 0x114, { MM_DIRECT, 800, 600, 16 } }, + { 0x115, { MM_DIRECT, 800, 600, 24 } }, + { 0x116, { MM_DIRECT, 1024, 768, 15 } }, + { 0x117, { MM_DIRECT, 1024, 768, 16 } }, + { 0x118, { MM_DIRECT, 1024, 768, 24 } }, + { 0x119, { MM_DIRECT, 1280, 1024, 15 } }, + { 0x11A, { MM_DIRECT, 1280, 1024, 16 } }, + { 0x11B, { MM_DIRECT, 1280, 1024, 24 } }, + { 0x11C, { MM_PACKED, 1600, 1200, 8 } }, + { 0x11D, { MM_DIRECT, 1600, 1200, 15 } }, + { 0x11E, { MM_DIRECT, 1600, 1200, 16 } }, + { 0x11F, { MM_DIRECT, 1600, 1200, 24 } }, /* BOCHS modes */ - { 0x140, MM_DIRECT, 320, 200, 32 }, - { 0x141, MM_DIRECT, 640, 400, 32 }, - { 0x142, MM_DIRECT, 640, 480, 32 }, - { 0x143, MM_DIRECT, 800, 600, 32 }, - { 0x144, MM_DIRECT, 1024, 768, 32 }, - { 0x145, MM_DIRECT, 1280, 1024, 32 }, - { 0x146, MM_PACKED, 320, 200, 8 }, - { 0x147, MM_DIRECT, 1600, 1200, 32 }, - { 0x148, MM_PACKED, 1152, 864, 8 }, - { 0x149, MM_DIRECT, 1152, 864, 15 }, - { 0x14a, MM_DIRECT, 1152, 864, 16 }, - { 0x14b, MM_DIRECT, 1152, 864, 24 }, - { 0x14c, MM_DIRECT, 1152, 864, 32 }, - { 0x178, MM_DIRECT, 1280, 800, 16 }, - { 0x179, MM_DIRECT, 1280, 800, 24 }, - { 0x17a, MM_DIRECT, 1280, 800, 32 }, - { 0x17b, MM_DIRECT, 1280, 960, 16 }, - { 0x17c, MM_DIRECT, 1280, 960, 24 }, - { 0x17d, MM_DIRECT, 1280, 960, 32 }, - { 0x17e, MM_DIRECT, 1440, 900, 16 }, - { 0x17f, MM_DIRECT, 1440, 900, 24 }, - { 0x180, MM_DIRECT, 1440, 900, 32 }, - { 0x181, MM_DIRECT, 1400, 1050, 16 }, - { 0x182, MM_DIRECT, 1400, 1050, 24 }, - { 0x183, MM_DIRECT, 1400, 1050, 32 }, - { 0x184, MM_DIRECT, 1680, 1050, 16 }, - { 0x185, MM_DIRECT, 1680, 1050, 24 }, - { 0x186, MM_DIRECT, 1680, 1050, 32 }, - { 0x187, MM_DIRECT, 1920, 1200, 16 }, - { 0x188, MM_DIRECT, 1920, 1200, 24 }, - { 0x189, MM_DIRECT, 1920, 1200, 32 }, - { 0x18a, MM_DIRECT, 2560, 1600, 16 }, - { 0x18b, MM_DIRECT, 2560, 1600, 24 }, - { 0x18c, MM_DIRECT, 2560, 1600, 32 }, - { 0, }, + { 0x140, { MM_DIRECT, 320, 200, 32 } }, + { 0x141, { MM_DIRECT, 640, 400, 32 } }, + { 0x142, { MM_DIRECT, 640, 480, 32 } }, + { 0x143, { MM_DIRECT, 800, 600, 32 } }, + { 0x144, { MM_DIRECT, 1024, 768, 32 } }, + { 0x145, { MM_DIRECT, 1280, 1024, 32 } }, + { 0x146, { MM_PACKED, 320, 200, 8 } }, + { 0x147, { MM_DIRECT, 1600, 1200, 32 } }, + { 0x148, { MM_PACKED, 1152, 864, 8 } }, + { 0x149, { MM_DIRECT, 1152, 864, 15 } }, + { 0x14a, { MM_DIRECT, 1152, 864, 16 } }, + { 0x14b, { MM_DIRECT, 1152, 864, 24 } }, + { 0x14c, { MM_DIRECT, 1152, 864, 32 } }, + { 0x178, { MM_DIRECT, 1280, 800, 16 } }, + { 0x179, { MM_DIRECT, 1280, 800, 24 } }, + { 0x17a, { MM_DIRECT, 1280, 800, 32 } }, + { 0x17b, { MM_DIRECT, 1280, 960, 16 } }, + { 0x17c, { MM_DIRECT, 1280, 960, 24 } }, + { 0x17d, { MM_DIRECT, 1280, 960, 32 } }, + { 0x17e, { MM_DIRECT, 1440, 900, 16 } }, + { 0x17f, { MM_DIRECT, 1440, 900, 24 } }, + { 0x180, { MM_DIRECT, 1440, 900, 32 } }, + { 0x181, { MM_DIRECT, 1400, 1050, 16 } }, + { 0x182, { MM_DIRECT, 1400, 1050, 24 } }, + { 0x183, { MM_DIRECT, 1400, 1050, 32 } }, + { 0x184, { MM_DIRECT, 1680, 1050, 16 } }, + { 0x185, { MM_DIRECT, 1680, 1050, 24 } }, + { 0x186, { MM_DIRECT, 1680, 1050, 32 } }, + { 0x187, { MM_DIRECT, 1920, 1200, 16 } }, + { 0x188, { MM_DIRECT, 1920, 1200, 24 } }, + { 0x189, { MM_DIRECT, 1920, 1200, 32 } }, + { 0x18a, { MM_DIRECT, 2560, 1600, 16 } }, + { 0x18b, { MM_DIRECT, 2560, 1600, 24 } }, + { 0x18c, { MM_DIRECT, 2560, 1600, 32 } }, };
#define BYTES_PER_PIXEL(m) ((GET_GLOBAL((m)->depth) + 7) / 8) @@ -177,29 +173,26 @@ bochsvga_total_mem(void) return dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K); }
-static struct mode *find_mode_entry(u16 mode) +struct vgamode_s *bochsvga_find_mode(int mode) { - struct mode *m; - - for (m = bochsvga_modes; GET_GLOBAL(m->mode); m++) { + struct bochsvga_mode *m = bochsvga_modes; + for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++) if (GET_GLOBAL(m->mode) == mode) - return m; - } - - return NULL; + return &m->info; + return stdvga_find_mode(mode); }
-static int mode_valid(struct mode *m) +static int mode_valid(struct vgamode_s *vmode_g) { u16 max_xres = dispi_get_max_xres(); u16 max_bpp = dispi_get_max_bpp(); u32 max_mem = bochsvga_total_mem() * 64 * 1024;
- u32 mem = GET_GLOBAL(m->width) * GET_GLOBAL(m->height) * - BYTES_PER_PIXEL(m); + u32 mem = GET_GLOBAL(vmode_g->width) * GET_GLOBAL(vmode_g->height) * + BYTES_PER_PIXEL(vmode_g);
- if (GET_GLOBAL(m->width) > max_xres || - GET_GLOBAL(m->depth) > max_bpp || + if (GET_GLOBAL(vmode_g->width) > max_xres || + GET_GLOBAL(vmode_g->depth) > max_bpp || mem > max_mem) return 0;
@@ -211,10 +204,10 @@ bochsvga_list_modes(u16 seg, u16 ptr) { int count = 0; u16 *dest = (u16 *)(u32)ptr; - struct mode *m;
- for (m = bochsvga_modes; GET_GLOBAL(m->mode); m++) { - if (!mode_valid(m)) + struct bochsvga_mode *m = bochsvga_modes; + for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++) { + if (!mode_valid(&m->info)) continue;
dprintf(1, "VBE found mode %x valid.\n", GET_GLOBAL(m->mode)); @@ -231,15 +224,13 @@ bochsvga_list_modes(u16 seg, u16 ptr) int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info) { - struct mode *m; - - m = find_mode_entry(mode); - if (!m || !mode_valid(m)) + struct vgamode_s *vmode_g = bochsvga_find_mode(mode); + if (!vmode_g || !mode_valid(vmode_g)) return -1;
- info->width = GET_GLOBAL(m->width); - info->height = GET_GLOBAL(m->height); - info->depth = GET_GLOBAL(m->depth); + info->width = GET_GLOBAL(vmode_g->width); + info->height = GET_GLOBAL(vmode_g->height); + info->depth = GET_GLOBAL(vmode_g->depth);
info->linesize = info->width * ((info->depth + 7) / 8); info->phys_base = GET_GLOBAL(pci_lfb_addr); diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index 32554d5..963b0d3 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -59,6 +59,7 @@ int bochsvga_list_modes(u16 seg, u16 ptr); struct vbe_modeinfo; int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info); void bochsvga_hires_enable(int enable); +struct vgamode_s *bochsvga_find_mode(int mode); int bochsvga_set_mode(int mode, int flags); void bochsvga_clear_scr(void); int bochsvga_hires_enabled(void); diff --git a/vgasrc/clext.c b/vgasrc/clext.c index ec0380f..90d7924 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -19,18 +19,13 @@ ****************************************************************/
struct cirrus_mode_s { - /* + 0 */ u16 mode; - u8 memmodel; - u16 width; - u16 height; - u16 depth; - /* + 8 */ + struct vgamode_s info; + u16 hidden_dac; /* 0x3c6 */ u16 *seq; /* 0x3c4 */ u16 *graph; /* 0x3ce */ u16 *crtc; /* 0x3d4 */ - /* +16 */ u8 bitsperpixel; u8 vesaredmask; u8 vesaredpos; @@ -38,7 +33,6 @@ struct cirrus_mode_s { u8 vesagreenpos; u8 vesabluemask; u8 vesabluepos; - /* +24 */ u8 vesareservedmask; u8 vesareservedpos; }; @@ -240,63 +234,63 @@ static u16 ccrtc_1600x1200x8[] VAR16 = { };
static struct cirrus_mode_s cirrus_modes[] VAR16 = { - {0x5f,MM_PACKED,640,480,8,0x00, + {0x5f,{MM_PACKED,640,480,8},0x00, cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, 0,0,0,0,0,0,0,0}, - {0x64,MM_DIRECT,640,480,16,0xe1, + {0x64,{MM_DIRECT,640,480,16},0xe1, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 5,11,6,5,5,0,0,0}, - {0x66,MM_DIRECT,640,480,15,0xf0, + {0x66,{MM_DIRECT,640,480,15},0xf0, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 5,10,5,5,5,0,1,15}, - {0x71,MM_DIRECT,640,480,24,0xe5, + {0x71,{MM_DIRECT,640,480,24},0xe5, cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, 8,16,8,8,8,0,0,0},
- {0x5c,MM_PACKED,800,600,8,0x00, + {0x5c,{MM_PACKED,800,600,8},0x00, cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, 0,0,0,0,0,0,0,0}, - {0x65,MM_DIRECT,800,600,16,0xe1, + {0x65,{MM_DIRECT,800,600,16},0xe1, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 5,11,6,5,5,0,0,0}, - {0x67,MM_DIRECT,800,600,15,0xf0, + {0x67,{MM_DIRECT,800,600,15},0xf0, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 5,10,5,5,5,0,1,15},
- {0x60,MM_PACKED,1024,768,8,0x00, + {0x60,{MM_PACKED,1024,768,8},0x00, cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, 0,0,0,0,0,0,0,0}, - {0x74,MM_DIRECT,1024,768,16,0xe1, + {0x74,{MM_DIRECT,1024,768,16},0xe1, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 5,11,6,5,5,0,0,0}, - {0x68,MM_DIRECT,1024,768,15,0xf0, + {0x68,{MM_DIRECT,1024,768,15},0xf0, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 5,10,5,5,5,0,1,15},
- {0x78,MM_DIRECT,800,600,24,0xe5, + {0x78,{MM_DIRECT,800,600,24},0xe5, cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, 8,16,8,8,8,0,0,0}, - {0x79,MM_DIRECT,1024,768,24,0xe5, + {0x79,{MM_DIRECT,1024,768,24},0xe5, cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, 8,16,8,8,8,0,0,0},
- {0x6d,MM_PACKED,1280,1024,8,0x00, + {0x6d,{MM_PACKED,1280,1024,8},0x00, cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, 0,0,0,0,0,0,0,0}, - {0x69,MM_DIRECT,1280,1024,15,0xf0, + {0x69,{MM_DIRECT,1280,1024,15},0xf0, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 5,10,5,5,5,0,1,15}, - {0x75,MM_DIRECT,1280,1024,16,0xe1, + {0x75,{MM_DIRECT,1280,1024,16},0xe1, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 5,11,6,5,5,0,0,0},
- {0x7b,MM_PACKED,1600,1200,8,0x00, + {0x7b,{MM_PACKED,1600,1200,8},0x00, cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, 0,0,0,0,0,0,0,0}, };
static struct cirrus_mode_s mode_switchback VAR16 = - {0xfe,0xff,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, + {0xfe,{0xff,0,0,0},0,cseq_vga,cgraph_vga,ccrtc_vga,0, 0,0,0,0,0,0,0,0};
@@ -317,6 +311,15 @@ cirrus_get_modeentry(u8 mode) return NULL; }
+struct vgamode_s * +clext_find_mode(int mode) +{ + struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); + if (table_g) + return &table_g->info; + return stdvga_find_mode(mode); +} + static void cirrus_switch_mode_setregs(u16 *data, u16 port) { @@ -346,7 +349,7 @@ cirrus_switch_mode(struct cirrus_mode_s *table) outb(GET_GLOBAL(table->hidden_dac), VGAREG_PEL_MASK); outb(0xff, VGAREG_PEL_MASK);
- u8 memmodel = GET_GLOBAL(table->memmodel); + u8 memmodel = GET_GLOBAL(table->info.memmodel); u8 v = stdvga_get_single_palette_reg(0x10) & 0xfe; if (memmodel == MM_PLANAR) v |= 0x41; @@ -744,15 +747,15 @@ cirrus_vesa_01h(struct bregs *regs) SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); // XXX u16 linesize = cirrus_get_line_offset_entry(table_g); SET_FARVAR(seg, info->bytes_per_scanline, linesize); - SET_FARVAR(seg, info->xres, GET_GLOBAL(table_g->width)); - u16 height = GET_GLOBAL(table_g->height); + SET_FARVAR(seg, info->xres, GET_GLOBAL(table_g->info.width)); + u16 height = GET_GLOBAL(table_g->info.height); SET_FARVAR(seg, info->yres, height); SET_FARVAR(seg, info->xcharsize, 8); SET_FARVAR(seg, info->ycharsize, 16); SET_FARVAR(seg, info->planes, 1); - SET_FARVAR(seg, info->bits_per_pixel, GET_GLOBAL(table_g->depth)); + SET_FARVAR(seg, info->bits_per_pixel, GET_GLOBAL(table_g->info.depth)); SET_FARVAR(seg, info->banks, 1); - SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->memmodel)); + SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->info.memmodel)); SET_FARVAR(seg, info->bank_size, 0);
int pages = (cirrus_get_memsize() * 64 * 1024) / (height * linesize); diff --git a/vgasrc/clext.h b/vgasrc/clext.h index 6fd0a58..e344639 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -3,6 +3,7 @@
#include "types.h" // u8
+struct vgamode_s *clext_find_mode(int mode); int clext_set_mode(int mode, int flags); int clext_init(void);
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 55e3bc4..9d8a067 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -10,6 +10,10 @@ #include "geodevga.h" // geodevga_init
static inline struct vgamode_s *vgahw_find_mode(int mode) { + if (CONFIG_VGA_CIRRUS) + return clext_find_mode(mode); + if (CONFIG_VGA_BOCHS) + return bochsvga_find_mode(mode); return stdvga_find_mode(mode); }
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 18 ++++++------------ vgasrc/bochsvga.h | 2 +- vgasrc/clext.c | 18 +++++++++++++----- vgasrc/clext.h | 1 + vgasrc/stdvga.c | 6 ++++++ vgasrc/stdvga.h | 1 + vgasrc/vbe.c | 6 ++++-- vgasrc/vgahw.h | 9 +++++++++ 8 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index d1919ec..5ab1bc2 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -199,26 +199,20 @@ static int mode_valid(struct vgamode_s *vmode_g) return 1; }
-int -bochsvga_list_modes(u16 seg, u16 ptr) +void +bochsvga_list_modes(u16 seg, u16 *dest, u16 *last) { - int count = 0; - u16 *dest = (u16 *)(u32)ptr; - struct bochsvga_mode *m = bochsvga_modes; - for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++) { + for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)] && dest<last; m++) { if (!mode_valid(&m->info)) continue;
dprintf(1, "VBE found mode %x valid.\n", GET_GLOBAL(m->mode)); - SET_FARVAR(seg, dest[count], GET_GLOBAL(m->mode)); - - count++; + SET_FARVAR(seg, *dest, GET_GLOBAL(m->mode)); + dest++; }
- SET_FARVAR(seg, dest[count], 0xffff); /* End of list */ - - return count; + stdvga_list_modes(seg, dest, last); }
int diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index 963b0d3..c08f103 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -55,7 +55,7 @@ static inline void dispi_write(u16 reg, u16 val) int bochsvga_init(void); int bochsvga_enabled(void); u16 bochsvga_total_mem(void); -int bochsvga_list_modes(u16 seg, u16 ptr); +void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last); struct vbe_modeinfo; int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info); void bochsvga_hires_enable(int enable); diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 90d7924..90f37c8 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -566,6 +566,17 @@ static struct { { 0x11a, 0x75 }, };
+void +clext_list_modes(u16 seg, u16 *dest, u16 *last) +{ + int i; + for (i=0; i<ARRAY_SIZE(cirrus_vesa_modelist) && dest<last; i++) { + SET_FARVAR(seg, *dest, GET_GLOBAL(cirrus_vesa_modelist[i].vesamode)); + dest++; + } + stdvga_list_modes(seg, dest, last); +} + static u16 cirrus_vesamode_to_mode(u16 vesamode) { @@ -706,12 +717,9 @@ cirrus_vesa_00h(struct bregs *regs) SET_FARVAR(seg, info->total_memory, cirrus_get_memsize());
u16 *destmode = (void*)info->reserved; + u16 *last = (void*)&info->reserved[sizeof(info->reserved)]; SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode)); - int i; - for (i=0; i<ARRAY_SIZE(cirrus_vesa_modelist); i++) - SET_FARVAR(seg, destmode[i] - , GET_GLOBAL(cirrus_vesa_modelist[i].vesamode)); - SET_FARVAR(seg, destmode[i], 0xffff); + clext_list_modes(seg, destmode, last);
regs->ax = 0x004f; } diff --git a/vgasrc/clext.h b/vgasrc/clext.h index e344639..f337b65 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -5,6 +5,7 @@
struct vgamode_s *clext_find_mode(int mode); int clext_set_mode(int mode, int flags); +void clext_list_modes(u16 seg, u16 *dest, u16 *last); int clext_init(void);
#endif // clext.h diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index 70d018a..6998cd0 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -642,6 +642,12 @@ stdvga_set_mode(int mode, int flags) ****************************************************************/
void +stdvga_list_modes(u16 seg, u16 *dest, u16 *last) +{ + SET_FARVAR(seg, *dest, 0xffff); +} + +void stdvga_enable_video_addressing(u8 disable) { u8 v = (disable & 1) ? 0x00 : 0x02; diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 4cef89f..033a711 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -119,6 +119,7 @@ void stdvga_save_state(u16 seg, struct saveVideoHardware *info); void stdvga_restore_state(u16 seg, struct saveVideoHardware *info); int stdvga_set_mode(int mode, int flags); void stdvga_enable_video_addressing(u8 disable); +void stdvga_list_modes(u16 seg, u16 *dest, u16 *last); int stdvga_init(void);
#endif // stdvga.h diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 8256cae..daf8c51 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -39,7 +39,8 @@ vbe_104f00(struct bregs *regs) SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */
/* We generate our mode list in the reserved field of the info block */ - SET_FARVAR(seg, info->video_mode, SEGOFF(seg, regs->di + 34)); + u16 *destmode = (void*)info->reserved; + SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode));
/* Total memory (in 64 blocks) */ SET_FARVAR(seg, info->total_memory, bochsvga_total_mem()); @@ -52,7 +53,8 @@ vbe_104f00(struct bregs *regs) SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING));
/* Fill list of modes */ - bochsvga_list_modes(seg, regs->di + 32); + u16 *last = (void*)&info->reserved[sizeof(info->reserved)]; + vgahw_list_modes(seg, destmode, last - 1);
regs->al = regs->ah; /* 0x4F, Function supported */ regs->ah = 0x0; /* 0x0, Function call successful */ diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 9d8a067..1101e51 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -25,6 +25,15 @@ static inline int vgahw_set_mode(int mode, int flags) { return stdvga_set_mode(mode, flags); }
+static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) { + if (CONFIG_VGA_CIRRUS) + clext_list_modes(seg, dest, last); + else if (CONFIG_VGA_BOCHS) + bochsvga_list_modes(seg, dest, last); + else + stdvga_list_modes(seg, dest, last); +} + static inline int vgahw_init(void) { if (CONFIG_VGA_CIRRUS) return clext_init();
Introduce new global variables (VBE_enabled, VBE_total_memory, VBE_capabilities, VBE_framebuffer) to replace the need for function calls that were specific to bochsvga.
Replace info received from bochsvga_mode_info with info found in vgahw_find_mode.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/bochsvga.c | 137 ++++++++++++++++++---------------------------------- vgasrc/bochsvga.h | 8 --- vgasrc/vbe.c | 73 ++++++++++++++-------------- vgasrc/vgabios.h | 15 ++---- 4 files changed, 89 insertions(+), 144 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 5ab1bc2..d9858c2 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -76,10 +76,6 @@ static struct bochsvga_mode { 0x18c, { MM_DIRECT, 2560, 1600, 32 } }, };
-#define BYTES_PER_PIXEL(m) ((GET_GLOBAL((m)->depth) + 7) / 8) - -u32 pci_lfb_addr VAR16; - static inline u32 pci_config_readl(u16 bdf, u16 addr) { int status; @@ -101,7 +97,6 @@ static inline u32 pci_config_readl(u16 bdf, u16 addr) return val; }
- static u16 dispi_get_max_xres(void) { u16 en; @@ -145,7 +140,7 @@ bochsvga_init(void) return -1; }
- SET_BDA(vbe_flag, 0x1); + SET_VGA(VBE_enabled, 1); dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5);
u32 lfb_addr; @@ -154,51 +149,42 @@ bochsvga_init(void) else lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
- SET_FARVAR(get_global_seg(), pci_lfb_addr, lfb_addr); + SET_VGA(VBE_framebuffer, lfb_addr); + u16 totalmem = dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + SET_VGA(VBE_total_memory, totalmem * 64 * 1024); + SET_VGA(VBE_capabilities, VBE_CAPABILITY_8BIT_DAC);
- dprintf(1, "VBE DISPI detected. lfb_addr=%x\n", GET_GLOBAL(pci_lfb_addr)); + dprintf(1, "VBE DISPI detected. lfb_addr=%x\n", lfb_addr);
return 0; }
-int -bochsvga_enabled(void) +static int mode_valid(struct vgamode_s *vmode_g) { - return GET_BDA(vbe_flag); -} + u16 max_xres = dispi_get_max_xres(); + u16 max_bpp = dispi_get_max_bpp(); + u32 max_mem = GET_GLOBAL(VBE_total_memory);
-u16 -bochsvga_total_mem(void) -{ - return dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + u16 width = GET_GLOBAL(vmode_g->width); + u16 height = GET_GLOBAL(vmode_g->height); + u8 depth = GET_GLOBAL(vmode_g->depth); + u32 mem = width * height * DIV_ROUND_UP(depth, 8); + + return width <= max_xres && depth <= max_bpp && mem <= max_mem; }
struct vgamode_s *bochsvga_find_mode(int mode) { struct bochsvga_mode *m = bochsvga_modes; for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++) - if (GET_GLOBAL(m->mode) == mode) + if (GET_GLOBAL(m->mode) == mode) { + if (! mode_valid(&m->info)) + return NULL; return &m->info; + } return stdvga_find_mode(mode); }
-static int mode_valid(struct vgamode_s *vmode_g) -{ - u16 max_xres = dispi_get_max_xres(); - u16 max_bpp = dispi_get_max_bpp(); - u32 max_mem = bochsvga_total_mem() * 64 * 1024; - - u32 mem = GET_GLOBAL(vmode_g->width) * GET_GLOBAL(vmode_g->height) * - BYTES_PER_PIXEL(vmode_g); - - if (GET_GLOBAL(vmode_g->width) > max_xres || - GET_GLOBAL(vmode_g->depth) > max_bpp || - mem > max_mem) - return 0; - - return 1; -} - void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last) { @@ -215,25 +201,7 @@ bochsvga_list_modes(u16 seg, u16 *dest, u16 *last) stdvga_list_modes(seg, dest, last); }
-int -bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info) -{ - struct vgamode_s *vmode_g = bochsvga_find_mode(mode); - if (!vmode_g || !mode_valid(vmode_g)) - return -1; - - info->width = GET_GLOBAL(vmode_g->width); - info->height = GET_GLOBAL(vmode_g->height); - info->depth = GET_GLOBAL(vmode_g->depth); - - info->linesize = info->width * ((info->depth + 7) / 8); - info->phys_base = GET_GLOBAL(pci_lfb_addr); - info->vram_size = bochsvga_total_mem() * 64 * 1024; - - return 0; -} - -void +static void bochsvga_hires_enable(int enable) { u16 flags = enable ? @@ -244,43 +212,56 @@ bochsvga_hires_enable(int enable) dispi_write(VBE_DISPI_INDEX_ENABLE, flags); }
+static void +bochsvga_clear_scr(void) +{ + u16 en; + + en = dispi_read(VBE_DISPI_INDEX_ENABLE); + en &= ~VBE_DISPI_NOCLEARMEM; + dispi_write(VBE_DISPI_INDEX_ENABLE, en); +} + int bochsvga_set_mode(int mode, int flags) { if (!(mode & VBE_MODE_VESA_DEFINED)) { dprintf(1, "set VGA mode %x\n", mode);
+ SET_BDA(vbe_mode, 0); bochsvga_hires_enable(0); return stdvga_set_mode(mode, flags); }
- struct vbe_modeinfo modeinfo, *info = &modeinfo; - int ret = bochsvga_mode_info(mode, &modeinfo); - if (ret) { + struct vgamode_s *vmode_g = bochsvga_find_mode(mode); + if (!vmode_g) { dprintf(1, "VBE mode %x not found\n", mode); return VBE_RETURN_STATUS_FAILED; } bochsvga_hires_enable(1);
- if (info->depth == 4) + u8 depth = GET_GLOBAL(vmode_g->depth); + if (depth == 4) stdvga_set_mode(0x6a, 0); - if (info->depth == 8) + if (depth == 8) // XXX load_dac_palette(3); ;
- dispi_write(VBE_DISPI_INDEX_BPP, info->depth); - dispi_write(VBE_DISPI_INDEX_XRES, info->width); - dispi_write(VBE_DISPI_INDEX_YRES, info->height); + dispi_write(VBE_DISPI_INDEX_BPP, depth); + u16 width = GET_GLOBAL(vmode_g->width); + u16 height = GET_GLOBAL(vmode_g->height); + dispi_write(VBE_DISPI_INDEX_XRES, width); + dispi_write(VBE_DISPI_INDEX_YRES, height); dispi_write(VBE_DISPI_INDEX_BANK, 0);
/* VGA compat setup */ //XXX: This probably needs some reverse engineering u8 v; outw(0x0011, VGAREG_VGA_CRTC_ADDRESS); - outw(((info->width * 4 - 1) << 8) | 0x1, VGAREG_VGA_CRTC_ADDRESS); - dispi_write(VBE_DISPI_INDEX_VIRT_WIDTH, info->width); - outw(((info->height - 1) << 8) | 0x12, VGAREG_VGA_CRTC_ADDRESS); - outw(((info->height - 1) & 0xff00) | 0x7, VGAREG_VGA_CRTC_ADDRESS); + outw(((width * 4 - 1) << 8) | 0x1, VGAREG_VGA_CRTC_ADDRESS); + dispi_write(VBE_DISPI_INDEX_VIRT_WIDTH, width); + outw(((height - 1) << 8) | 0x12, VGAREG_VGA_CRTC_ADDRESS); + outw(((height - 1) & 0xff00) | 0x7, VGAREG_VGA_CRTC_ADDRESS); v = inb(VGAREG_VGA_CRTC_DATA) & 0xbd; if (v & 0x1) v |= 0x2; @@ -298,7 +279,7 @@ bochsvga_set_mode(int mode, int flags) outb(0x20, VGAREG_ACTL_ADDRESS); outw(0x0506, VGAREG_GRDC_ADDRESS); outw(0x0f02, VGAREG_SEQU_ADDRESS); - if (info->depth >= 8) { + if (depth >= 8) { outb(0x14, VGAREG_VGA_CRTC_ADDRESS); outb(inb(VGAREG_VGA_CRTC_DATA) | 0x40, VGAREG_VGA_CRTC_DATA); v = inb(VGAREG_ACTL_RESET); @@ -314,7 +295,7 @@ bochsvga_set_mode(int mode, int flags) outb(v | 0x40, VGAREG_GRDC_DATA); }
- SET_BDA(vbe_mode, mode); + SET_BDA(vbe_mode, mode | flags);
if (flags & MF_LINEARFB) { /* Linear frame buffer */ @@ -326,25 +307,3 @@ bochsvga_set_mode(int mode, int flags)
return 0; } - -void -bochsvga_clear_scr(void) -{ - u16 en; - - en = dispi_read(VBE_DISPI_INDEX_ENABLE); - en &= ~VBE_DISPI_NOCLEARMEM; - dispi_write(VBE_DISPI_INDEX_ENABLE, en); -} - -int -bochsvga_hires_enabled(void) -{ - return dispi_read(VBE_DISPI_INDEX_ENABLE) & VBE_DISPI_ENABLED; -} - -u16 -bochsvga_curr_mode(void) -{ - return GET_BDA(vbe_mode); -} diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index c08f103..a9cedbf 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -53,16 +53,8 @@ static inline void dispi_write(u16 reg, u16 val) }
int bochsvga_init(void); -int bochsvga_enabled(void); -u16 bochsvga_total_mem(void); void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last); -struct vbe_modeinfo; -int bochsvga_mode_info(u16 mode, struct vbe_modeinfo *info); -void bochsvga_hires_enable(int enable); struct vgamode_s *bochsvga_find_mode(int mode); int bochsvga_set_mode(int mode, int flags); -void bochsvga_clear_scr(void); -int bochsvga_hires_enabled(void); -u16 bochsvga_curr_mode(void);
#endif // bochsvga.h diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index daf8c51..d764a0c 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -11,9 +11,13 @@ #include "vbe.h" // struct vbe_info #include "util.h" // dprintf #include "biosvar.h" // get_global_set -#include "bochsvga.h" // bochsvga_hires_enabled #include "vgahw.h" // vgahw_set_mode
+int VBE_enabled VAR16; +u32 VBE_total_memory VAR16 = 256 * 1024; +u32 VBE_capabilities VAR16; +u32 VBE_framebuffer VAR16; + static void vbe_104f00(struct bregs *regs) { @@ -36,14 +40,15 @@ vbe_104f00(struct bregs *regs)
SET_FARVAR(seg, info->oem_string, SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); - SET_FARVAR(seg, info->capabilities, 0x1); /* 8BIT DAC */ + SET_FARVAR(seg, info->capabilities, GET_GLOBAL(VBE_capabilities));
/* We generate our mode list in the reserved field of the info block */ u16 *destmode = (void*)info->reserved; SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode));
/* Total memory (in 64 blocks) */ - SET_FARVAR(seg, info->total_memory, bochsvga_total_mem()); + SET_FARVAR(seg, info->total_memory + , GET_GLOBAL(VBE_total_memory) / (64*1024));
SET_FARVAR(seg, info->oem_vendor_string, SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); @@ -56,8 +61,7 @@ vbe_104f00(struct bregs *regs) u16 *last = (void*)&info->reserved[sizeof(info->reserved)]; vgahw_list_modes(seg, destmode, last - 1);
- regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ + regs->ax = 0x004f; }
static void @@ -66,15 +70,13 @@ vbe_104f01(struct bregs *regs) u16 seg = regs->es; struct vbe_mode_info *info = (void*)(regs->di+0); u16 mode = regs->cx; - struct vbe_modeinfo modeinfo; - int rc;
dprintf(1, "VBE mode info request: %x\n", mode);
- rc = bochsvga_mode_info(mode, &modeinfo); - if (rc) { + struct vgamode_s *vmode_g = vgahw_find_mode(mode); + if (! vmode_g) { dprintf(1, "VBE mode %x not found\n", mode); - regs->ax = 0x100; + regs->ax = 0x0100; return; }
@@ -82,7 +84,8 @@ vbe_104f01(struct bregs *regs) VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | VBE_MODE_ATTRIBUTE_COLOR_MODE | VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; - if (modeinfo.depth == 4) + int depth = GET_GLOBAL(vmode_g->depth); + if (depth == 4) mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; else mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; @@ -97,27 +100,29 @@ vbe_104f01(struct bregs *regs) SET_FARVAR(seg, info->winA_seg, 0xA000); SET_FARVAR(seg, info->winB_seg, 0x0); SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); - SET_FARVAR(seg, info->bytes_per_scanline, modeinfo.linesize); - SET_FARVAR(seg, info->xres, modeinfo.width); - SET_FARVAR(seg, info->yres, modeinfo.height); + int width = GET_GLOBAL(vmode_g->width); + int height = GET_GLOBAL(vmode_g->height); + int linesize = width * DIV_ROUND_UP(depth, 8); // XXX - not always true + SET_FARVAR(seg, info->bytes_per_scanline, linesize); + SET_FARVAR(seg, info->xres, width); + SET_FARVAR(seg, info->yres, height); SET_FARVAR(seg, info->xcharsize, 8); SET_FARVAR(seg, info->ycharsize, 16); - if (modeinfo.depth == 4) + if (depth == 4) SET_FARVAR(seg, info->planes, 4); else SET_FARVAR(seg, info->planes, 1); - SET_FARVAR(seg, info->bits_per_pixel, modeinfo.depth); - SET_FARVAR(seg, info->banks, - (modeinfo.linesize * modeinfo.height + 65535) / 65536); - if (modeinfo.depth == 4) + SET_FARVAR(seg, info->bits_per_pixel, depth); + SET_FARVAR(seg, info->banks, DIV_ROUND_UP(linesize * height, 64*1024)); + if (depth == 4) SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); - else if (modeinfo.depth == 8) + else if (depth == 8) SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); else SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); SET_FARVAR(seg, info->bank_size, 0); - u32 pages = modeinfo.vram_size / (modeinfo.height * modeinfo.linesize); - if (modeinfo.depth == 4) + u32 pages = GET_GLOBAL(VBE_total_memory) / (height * linesize); + if (depth == 4) SET_FARVAR(seg, info->pages, (pages / 4) - 1); else SET_FARVAR(seg, info->pages, pages - 1); @@ -125,7 +130,7 @@ vbe_104f01(struct bregs *regs)
u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos;
- switch (modeinfo.depth) { + switch (depth) { case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; @@ -147,20 +152,20 @@ vbe_104f01(struct bregs *regs) SET_FARVAR(seg, info->alpha_size, a_size); SET_FARVAR(seg, info->alpha_pos, a_pos);
- if (modeinfo.depth == 32) + if (depth == 32) SET_FARVAR(seg, info->directcolor_info, VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE); else SET_FARVAR(seg, info->directcolor_info, 0);
- if (modeinfo.depth > 4) - SET_FARVAR(seg, info->phys_base, modeinfo.phys_base); + if (depth > 4) + SET_FARVAR(seg, info->phys_base, GET_GLOBAL(VBE_framebuffer)); else SET_FARVAR(seg, info->phys_base, 0);
SET_FARVAR(seg, info->reserved1, 0); SET_FARVAR(seg, info->reserved2, 0); - SET_FARVAR(seg, info->linear_bytes_per_scanline, modeinfo.linesize); + SET_FARVAR(seg, info->linear_bytes_per_scanline, linesize); SET_FARVAR(seg, info->bank_pages, 0); SET_FARVAR(seg, info->linear_pages, 0); SET_FARVAR(seg, info->linear_red_size, r_size); @@ -173,8 +178,7 @@ vbe_104f01(struct bregs *regs) SET_FARVAR(seg, info->linear_alpha_pos, a_pos); SET_FARVAR(seg, info->pixclock_max, 0);
- regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ + regs->ax = 0x004f; }
static void @@ -193,16 +197,13 @@ vbe_104f02(struct bregs *regs) static void vbe_104f03(struct bregs *regs) { - if (!bochsvga_hires_enabled()) { + u16 mode = GET_BDA(vbe_mode); + if (!mode) regs->bx = GET_BDA(video_mode); - } else { - regs->bx = bochsvga_curr_mode(); - }
dprintf(1, "VBE current mode=%x\n", regs->bx);
- regs->al = regs->ah; /* 0x4F, Function supported */ - regs->ah = 0x0; /* 0x0, Function call successful */ + regs->ax = 0x004f; }
static void @@ -257,7 +258,7 @@ vbe_104fXX(struct bregs *regs) void handle_104f(struct bregs *regs) { - if (!bochsvga_enabled()) { + if (!GET_GLOBAL(VBE_enabled)) { vbe_104fXX(regs); return; } diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 3416b98..464100b 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -83,21 +83,14 @@ void vgafb_write_pixel(u8 color, u16 x, u16 y); u8 vgafb_read_pixel(u16 x, u16 y);
// vbe.c +int VBE_enabled; +u32 VBE_total_memory; +u32 VBE_capabilities; +u32 VBE_framebuffer; #define VBE_OEM_STRING "SeaBIOS VBE(C) 2011" #define VBE_VENDOR_STRING "SeaBIOS Developers" #define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter" #define VBE_REVISION_STRING "Rev. 1" - -struct vbe_modeinfo -{ - u16 width; - u16 height; - u8 depth; - u16 linesize; - u32 phys_base; - u32 vram_size; -}; - struct bregs; void handle_104f(struct bregs *regs);
Unify the code for the Cirrus and VBE vesa functions 00-03.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 328 ++++++++++++++---------------------------------------- vgasrc/vbe.c | 21 ++-- vgasrc/vgabios.h | 1 + 3 files changed, 96 insertions(+), 254 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 90f37c8..1736843 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -18,25 +18,6 @@ * tables ****************************************************************/
-struct cirrus_mode_s { - u16 mode; - struct vgamode_s info; - - u16 hidden_dac; /* 0x3c6 */ - u16 *seq; /* 0x3c4 */ - u16 *graph; /* 0x3ce */ - u16 *crtc; /* 0x3d4 */ - u8 bitsperpixel; - u8 vesaredmask; - u8 vesaredpos; - u8 vesagreenmask; - u8 vesagreenpos; - u8 vesabluemask; - u8 vesabluepos; - u8 vesareservedmask; - u8 vesareservedpos; -}; - /* VGA */ static u16 cseq_vga[] VAR16 = {0x0007,0xffff}; static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff}; @@ -233,74 +214,115 @@ static u16 ccrtc_1600x1200x8[] VAR16 = { 0xffff };
+struct cirrus_mode_s { + u16 mode; + struct vgamode_s info; + + u16 hidden_dac; /* 0x3c6 */ + u16 *seq; /* 0x3c4 */ + u16 *graph; /* 0x3ce */ + u16 *crtc; /* 0x3d4 */ +}; + static struct cirrus_mode_s cirrus_modes[] VAR16 = { {0x5f,{MM_PACKED,640,480,8},0x00, - cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, - 0,0,0,0,0,0,0,0}, + cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8}, {0x64,{MM_DIRECT,640,480,16},0xe1, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 5,11,6,5,5,0,0,0}, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16}, {0x66,{MM_DIRECT,640,480,15},0xf0, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 5,10,5,5,5,0,1,15}, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16}, {0x71,{MM_DIRECT,640,480,24},0xe5, - cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, - 8,16,8,8,8,0,0,0}, + cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24},
{0x5c,{MM_PACKED,800,600,8},0x00, - cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, - 0,0,0,0,0,0,0,0}, + cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8}, {0x65,{MM_DIRECT,800,600,16},0xe1, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 5,11,6,5,5,0,0,0}, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16}, {0x67,{MM_DIRECT,800,600,15},0xf0, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 5,10,5,5,5,0,1,15}, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16},
{0x60,{MM_PACKED,1024,768,8},0x00, - cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, - 0,0,0,0,0,0,0,0}, + cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8}, {0x74,{MM_DIRECT,1024,768,16},0xe1, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 5,11,6,5,5,0,0,0}, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16}, {0x68,{MM_DIRECT,1024,768,15},0xf0, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 5,10,5,5,5,0,1,15}, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16},
{0x78,{MM_DIRECT,800,600,24},0xe5, - cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, - 8,16,8,8,8,0,0,0}, + cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24}, {0x79,{MM_DIRECT,1024,768,24},0xe5, - cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, - 8,16,8,8,8,0,0,0}, + cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24},
{0x6d,{MM_PACKED,1280,1024,8},0x00, - cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, - 0,0,0,0,0,0,0,0}, + cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8}, {0x69,{MM_DIRECT,1280,1024,15},0xf0, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 5,10,5,5,5,0,1,15}, + cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16}, {0x75,{MM_DIRECT,1280,1024,16},0xe1, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 5,11,6,5,5,0,0,0}, + cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16},
{0x7b,{MM_PACKED,1600,1200,8},0x00, - cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, - 0,0,0,0,0,0,0,0}, + cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8}, };
static struct cirrus_mode_s mode_switchback VAR16 = - {0xfe,{0xff,0,0,0},0,cseq_vga,cgraph_vga,ccrtc_vga,0, - 0,0,0,0,0,0,0,0}; + {0xfe,{0xff},0,cseq_vga,cgraph_vga,ccrtc_vga}; + +static struct { + u16 vesamode, mode; +} cirrus_vesa_modelist[] VAR16 = { + // 640x480x8 + { 0x101, 0x5f }, + // 640x480x15 + { 0x110, 0x66 }, + // 640x480x16 + { 0x111, 0x64 }, + // 640x480x24 + { 0x112, 0x71 }, + // 800x600x8 + { 0x103, 0x5c }, + // 800x600x15 + { 0x113, 0x67 }, + // 800x600x16 + { 0x114, 0x65 }, + // 800x600x24 + { 0x115, 0x78 }, + // 1024x768x8 + { 0x105, 0x60 }, + // 1024x768x15 + { 0x116, 0x68 }, + // 1024x768x16 + { 0x117, 0x74 }, + // 1024x768x24 + { 0x118, 0x79 }, + // 1280x1024x8 + { 0x107, 0x6d }, + // 1280x1024x15 + { 0x119, 0x69 }, + // 1280x1024x16 + { 0x11a, 0x75 }, +};
/**************************************************************** * helper functions ****************************************************************/
+static u16 +cirrus_vesamode_to_mode(u16 vesamode) +{ + int i; + for (i=0; i<ARRAY_SIZE(cirrus_vesa_modelist); i++) + if (GET_GLOBAL(cirrus_vesa_modelist[i].vesamode) == vesamode) + return GET_GLOBAL(cirrus_vesa_modelist[i].mode); + return 0; +} + static struct cirrus_mode_s * -cirrus_get_modeentry(u8 mode) +cirrus_get_modeentry(int mode) { + int transmode = cirrus_vesamode_to_mode(mode); + if (transmode) + mode = transmode; struct cirrus_mode_s *table_g = cirrus_modes; while (table_g < &cirrus_modes[ARRAY_SIZE(cirrus_modes)]) { u16 tmode = GET_GLOBAL(table_g->mode); @@ -404,9 +426,12 @@ clext_set_mode(int mode, int flags) struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); if (table_g) { cirrus_switch_mode(table_g); + if (!(flags & MF_LINEARFB)) + cirrus_enable_16k_granularity(); if (!(flags & MF_NOCLEARMEM)) - cirrus_clear_vram(0xffff); + cirrus_clear_vram(0); SET_BDA(video_mode, mode); + SET_BDA(vbe_mode, mode | flags); return 0; } cirrus_switch_mode(&mode_switchback); @@ -531,41 +556,6 @@ cirrus_extbios(struct bregs *regs) * vesa calls ****************************************************************/
-static struct { - u16 vesamode, mode; -} cirrus_vesa_modelist[] VAR16 = { - // 640x480x8 - { 0x101, 0x5f }, - // 640x480x15 - { 0x110, 0x66 }, - // 640x480x16 - { 0x111, 0x64 }, - // 640x480x24 - { 0x112, 0x71 }, - // 800x600x8 - { 0x103, 0x5c }, - // 800x600x15 - { 0x113, 0x67 }, - // 800x600x16 - { 0x114, 0x65 }, - // 800x600x24 - { 0x115, 0x78 }, - // 1024x768x8 - { 0x105, 0x60 }, - // 1024x768x15 - { 0x116, 0x68 }, - // 1024x768x16 - { 0x117, 0x74 }, - // 1024x768x24 - { 0x118, 0x79 }, - // 1280x1024x8 - { 0x107, 0x6d }, - // 1280x1024x15 - { 0x119, 0x69 }, - // 1280x1024x16 - { 0x11a, 0x75 }, -}; - void clext_list_modes(u16 seg, u16 *dest, u16 *last) { @@ -577,16 +567,6 @@ clext_list_modes(u16 seg, u16 *dest, u16 *last) stdvga_list_modes(seg, dest, last); }
-static u16 -cirrus_vesamode_to_mode(u16 vesamode) -{ - int i; - for (i=0; i<ARRAY_SIZE(cirrus_vesa_modelist); i++) - if (GET_GLOBAL(cirrus_vesa_modelist[i].vesamode) == vesamode) - return GET_GLOBAL(cirrus_vesa_modelist[i].mode); - return 0; -} - static u8 cirrus_get_bpp_bytes(void) { @@ -624,7 +604,7 @@ cirrus_get_line_offset(void) return (((reg1b << 4) & 0x100) + reg13) * 8; }
-static u16 +u16 cirrus_get_line_offset_entry(struct cirrus_mode_s *table_g) { u16 *crtc = GET_GLOBAL(table_g->crtc); @@ -693,144 +673,6 @@ cirrus_get_start_addr(void) }
static void -cirrus_vesa_00h(struct bregs *regs) -{ - u16 seg = regs->es; - struct vbe_info *info = (void*)(regs->di+0); - - if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { - SET_FARVAR(seg, info->oem_revision, 0x0100); - SET_FARVAR(seg, info->oem_vendor_string, - SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); - SET_FARVAR(seg, info->oem_product_string, - SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); - SET_FARVAR(seg, info->oem_revision_string, - SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); - } - SET_FARVAR(seg, info->signature, VESA_SIGNATURE); - - SET_FARVAR(seg, info->version, 0x0200); - - SET_FARVAR(seg, info->oem_string - , SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); - SET_FARVAR(seg, info->capabilities, 0); - SET_FARVAR(seg, info->total_memory, cirrus_get_memsize()); - - u16 *destmode = (void*)info->reserved; - u16 *last = (void*)&info->reserved[sizeof(info->reserved)]; - SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode)); - clext_list_modes(seg, destmode, last); - - regs->ax = 0x004f; -} - -static u32 cirrus_lfb_addr VAR16; - -static void -cirrus_vesa_01h(struct bregs *regs) -{ - u16 mode = cirrus_vesamode_to_mode(regs->cx & 0x3fff); - if (!mode) { - regs->ax = 0x014f; - return; - } - struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); - u32 lfb = GET_GLOBAL(cirrus_lfb_addr); // XXX - if ((regs->cx & 0x4000) && !lfb) { - regs->ax = 0x014f; - return; - } - - u16 seg = regs->es; - struct vbe_mode_info *info = (void*)(regs->di+0); - memset_far(seg, info, 0, sizeof(*info)); - - SET_FARVAR(seg, info->mode_attributes, lfb ? 0xbb : 0x3b); - SET_FARVAR(seg, info->winA_attributes, 0x07); - SET_FARVAR(seg, info->winB_attributes, 0); - SET_FARVAR(seg, info->win_granularity, 16); - SET_FARVAR(seg, info->win_size, 64); - SET_FARVAR(seg, info->winA_seg, SEG_GRAPH); - SET_FARVAR(seg, info->winB_seg, 0x0); - SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); // XXX - u16 linesize = cirrus_get_line_offset_entry(table_g); - SET_FARVAR(seg, info->bytes_per_scanline, linesize); - SET_FARVAR(seg, info->xres, GET_GLOBAL(table_g->info.width)); - u16 height = GET_GLOBAL(table_g->info.height); - SET_FARVAR(seg, info->yres, height); - SET_FARVAR(seg, info->xcharsize, 8); - SET_FARVAR(seg, info->ycharsize, 16); - SET_FARVAR(seg, info->planes, 1); - SET_FARVAR(seg, info->bits_per_pixel, GET_GLOBAL(table_g->info.depth)); - SET_FARVAR(seg, info->banks, 1); - SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->info.memmodel)); - SET_FARVAR(seg, info->bank_size, 0); - - int pages = (cirrus_get_memsize() * 64 * 1024) / (height * linesize); - SET_FARVAR(seg, info->pages, pages - 1); - SET_FARVAR(seg, info->reserved0, 0); - - SET_FARVAR(seg, info->red_size, GET_GLOBAL(table_g->vesaredmask)); - SET_FARVAR(seg, info->red_pos, GET_GLOBAL(table_g->vesaredpos)); - SET_FARVAR(seg, info->green_size, GET_GLOBAL(table_g->vesagreenmask)); - SET_FARVAR(seg, info->green_pos, GET_GLOBAL(table_g->vesagreenpos)); - SET_FARVAR(seg, info->blue_size, GET_GLOBAL(table_g->vesabluemask)); - SET_FARVAR(seg, info->blue_pos, GET_GLOBAL(table_g->vesabluepos)); - SET_FARVAR(seg, info->alpha_size, GET_GLOBAL(table_g->vesareservedmask)); - SET_FARVAR(seg, info->alpha_pos, GET_GLOBAL(table_g->vesareservedpos)); - u8 directcolor_info = GET_GLOBAL(table_g->bitsperpixel) <= 8; - SET_FARVAR(seg, info->directcolor_info, directcolor_info); - - SET_FARVAR(seg, info->phys_base, lfb); - - regs->ax = 0x004f; -} - -static void -cirrus_vesa_02h(struct bregs *regs) -{ - if (regs->bx & 0x3e00) { - regs->ax = 0x014f; - return; - } - if ((regs->bx & 0x1ff) < 0x100) { - // XXX - call legacy mode switch - regs->ax = 0x004f; - return; - } - - u16 mode = cirrus_vesamode_to_mode(regs->cx & 0x3fff); - if (!mode) { - regs->ax = 0x014f; - return; - } - struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); - cirrus_switch_mode(table_g); - - if (!(regs->bx & 0x4000)) - cirrus_enable_16k_granularity(); - if (!(regs->bx & 0x8000)) - cirrus_clear_vram(0); - SET_BDA(video_mode, mode); - SET_BDA(vbe_mode, regs->bx); - - regs->ax = 0x004f; -} - -static void -cirrus_vesa_03h(struct bregs *regs) -{ - u16 mode = GET_BDA(vbe_mode); - if (!mode) - mode = GET_BDA(video_mode); - regs->bx = mode; - - regs->ax = 0x004f; -} - -// XXX - add cirrus_vesa_05h_farentry to vgaentry.S - -static void cirrus_vesa_05h(struct bregs *regs) { if (regs->bl > 1) @@ -926,10 +768,6 @@ void cirrus_vesa(struct bregs *regs) { switch (regs->al) { - case 0x00: cirrus_vesa_00h(regs); break; - case 0x01: cirrus_vesa_01h(regs); break; - case 0x02: cirrus_vesa_02h(regs); break; - case 0x03: cirrus_vesa_03h(regs); break; case 0x05: cirrus_vesa_05h(regs); break; case 0x06: cirrus_vesa_06h(regs); break; case 0x07: cirrus_vesa_07h(regs); break; @@ -955,6 +793,10 @@ clext_init(void) return -1; dprintf(1, "cirrus init 2\n");
+ u16 totalmem = cirrus_get_memsize(); + SET_VGA(VBE_total_memory, totalmem * 64 * 1024); + SET_VGA(VBE_win_granularity, 16); + // memory setup outb(0x0f, VGAREG_SEQU_ADDRESS); u8 v = inb(VGAREG_SEQU_DATA); diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index d764a0c..ee80e97 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -17,6 +17,7 @@ int VBE_enabled VAR16; u32 VBE_total_memory VAR16 = 256 * 1024; u32 VBE_capabilities VAR16; u32 VBE_framebuffer VAR16; +u16 VBE_win_granularity VAR16 = 64;
static void vbe_104f00(struct bregs *regs) @@ -80,14 +81,17 @@ vbe_104f01(struct bregs *regs) return; }
+ memset_far(seg, info, 0, sizeof(*info)); u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | VBE_MODE_ATTRIBUTE_COLOR_MODE | - VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; + VBE_MODE_ATTRIBUTE_GRAPHICS_MODE | + VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE; + u32 framebuffer = GET_GLOBAL(VBE_framebuffer); int depth = GET_GLOBAL(vmode_g->depth); if (depth == 4) mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; - else + else if (framebuffer) mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; SET_FARVAR(seg, info->mode_attributes, mode_attr); SET_FARVAR(seg, info->winA_attributes, @@ -95,9 +99,9 @@ vbe_104f01(struct bregs *regs) VBE_WINDOW_ATTRIBUTE_READABLE | VBE_WINDOW_ATTRIBUTE_WRITEABLE); SET_FARVAR(seg, info->winB_attributes, 0); - SET_FARVAR(seg, info->win_granularity, 64); /* Bank size 64K */ + SET_FARVAR(seg, info->win_granularity, GET_GLOBAL(VBE_win_granularity)); SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ - SET_FARVAR(seg, info->winA_seg, 0xA000); + SET_FARVAR(seg, info->winA_seg, SEG_GRAPH); SET_FARVAR(seg, info->winB_seg, 0x0); SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); int width = GET_GLOBAL(vmode_g->width); @@ -113,13 +117,8 @@ vbe_104f01(struct bregs *regs) else SET_FARVAR(seg, info->planes, 1); SET_FARVAR(seg, info->bits_per_pixel, depth); - SET_FARVAR(seg, info->banks, DIV_ROUND_UP(linesize * height, 64*1024)); - if (depth == 4) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); - else if (depth == 8) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); - else - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); + SET_FARVAR(seg, info->banks, 1); + SET_FARVAR(seg, info->mem_model, GET_GLOBAL(vmode_g->memmodel)); SET_FARVAR(seg, info->bank_size, 0); u32 pages = GET_GLOBAL(VBE_total_memory) / (height * linesize); if (depth == 4) diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 464100b..d0af248 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -87,6 +87,7 @@ int VBE_enabled; u32 VBE_total_memory; u32 VBE_capabilities; u32 VBE_framebuffer; +u16 VBE_win_granularity; #define VBE_OEM_STRING "SeaBIOS VBE(C) 2011" #define VBE_VENDOR_STRING "SeaBIOS Developers" #define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter"
Only two modes don't match their expected line length. One looks like a bug (it has a virtual line length of 1280 for a screen of 1600 bytes) and one looks like an optimization (2048 vs 1920). Change the mode line lengths to exactly match the expected line lengths so that the VBE code is correct.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 41 +++++++---------------------------------- vgasrc/vbe.c | 2 +- 2 files changed, 8 insertions(+), 35 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 1736843..835d809 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -73,8 +73,8 @@ static u16 ccrtc_640x480x24[] VAR16 = { 0x2c11, 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 0x4009,0x000c,0x000d, - 0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18, - 0x001a,0x321b,0x001d, + 0xea10,0xdf12,0xf013,0x4014,0xdf15,0x0b16,0xc317,0xff18, + 0x001a,0x221b,0x001d, 0xffff }; /* 800x600x8 */ @@ -209,7 +209,7 @@ static u16 cseq_1600x1200x8[] VAR16 = { static u16 ccrtc_1600x1200x8[] VAR16 = { 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 0x6009,0x000c,0x000d, - 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, + 0x0310,0xff12,0xc813,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; @@ -583,13 +583,14 @@ cirrus_get_bpp_bytes(void) static void cirrus_set_line_offset(u16 new_line_offset) { + new_line_offset /= 8; u16 crtc_addr = stdvga_get_crtc(); outb(0x13, crtc_addr); - outb(new_line_offset / 8, crtc_addr + 1); + outb(new_line_offset, crtc_addr + 1);
outb(0x1b, crtc_addr); u8 v = inb(crtc_addr + 1); - outb((((new_line_offset / 8) & 0x100) >> 4) | (v & 0xef), crtc_addr + 1); + outb(((new_line_offset & 0x100) >> 4) | (v & 0xef), crtc_addr + 1); }
static u16 @@ -601,35 +602,7 @@ cirrus_get_line_offset(void) outb(0x1b, crtc_addr); u8 reg1b = inb(crtc_addr + 1);
- return (((reg1b << 4) & 0x100) + reg13) * 8; -} - -u16 -cirrus_get_line_offset_entry(struct cirrus_mode_s *table_g) -{ - u16 *crtc = GET_GLOBAL(table_g->crtc); - - u16 *c = crtc; - u16 reg13; - for (;;) { - reg13 = GET_GLOBAL(*c); - if ((reg13 & 0xff) == 0x13) - break; - c++; - } - reg13 >>= 8; - - c = crtc; - u16 reg1b; - for (;;) { - reg1b = GET_GLOBAL(*c); - if ((reg1b & 0xff) == 0x1b) - break; - c++; - } - reg1b >>= 8; - - return (((reg1b << 4) & 0x100) + reg13) * 8; + return (((reg1b & 0x10) << 4) + reg13) * 8; }
static void diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index ee80e97..14efece 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -106,7 +106,7 @@ vbe_104f01(struct bregs *regs) SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); int width = GET_GLOBAL(vmode_g->width); int height = GET_GLOBAL(vmode_g->height); - int linesize = width * DIV_ROUND_UP(depth, 8); // XXX - not always true + int linesize = width * DIV_ROUND_UP(depth, 8); SET_FARVAR(seg, info->bytes_per_scanline, linesize); SET_FARVAR(seg, info->xres, width); SET_FARVAR(seg, info->yres, height);
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- vgasrc/clext.c | 47 ++++++++++++++++++++++++++--------------------- vgasrc/clext.h | 4 +++- vgasrc/vgabios.c | 11 ++++++----- 3 files changed, 35 insertions(+), 27 deletions(-)
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 835d809..9bd424e 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -452,7 +452,7 @@ cirrus_check(void) ****************************************************************/
static void -cirrus_extbios_80h(struct bregs *regs) +clext_101280(struct bregs *regs) { u16 crtc_addr = stdvga_get_crtc(); outb(0x27, crtc_addr); @@ -470,14 +470,14 @@ cirrus_extbios_80h(struct bregs *regs) }
static void -cirrus_extbios_81h(struct bregs *regs) +clext_101281(struct bregs *regs) { // XXX regs->ax = 0x0100; }
static void -cirrus_extbios_82h(struct bregs *regs) +clext_101282(struct bregs *regs) { u16 crtc_addr = stdvga_get_crtc(); outb(0x27, crtc_addr); @@ -486,13 +486,13 @@ cirrus_extbios_82h(struct bregs *regs) }
static void -cirrus_extbios_85h(struct bregs *regs) +clext_101285(struct bregs *regs) { regs->al = cirrus_get_memsize(); }
static void -cirrus_extbios_9Ah(struct bregs *regs) +clext_10129a(struct bregs *regs) { regs->ax = 0x4060; regs->cx = 0x1132; @@ -507,7 +507,7 @@ ASM16( "retf");
static void -cirrus_extbios_A0h(struct bregs *regs) +clext_1012a0(struct bregs *regs) { struct cirrus_mode_s *table_g = cirrus_get_modeentry(regs->al & 0x7f); regs->ah = (table_g ? 1 : 0); @@ -516,38 +516,43 @@ cirrus_extbios_A0h(struct bregs *regs) }
static void -cirrus_extbios_A1h(struct bregs *regs) +clext_1012a1(struct bregs *regs) { regs->bx = 0x0e00; // IBM 8512/8513, color }
static void -cirrus_extbios_A2h(struct bregs *regs) +clext_1012a2(struct bregs *regs) { regs->al = 0x07; // HSync 31.5 - 64.0 kHz }
static void -cirrus_extbios_AEh(struct bregs *regs) +clext_1012ae(struct bregs *regs) { regs->al = 0x01; // High Refresh 75Hz }
+static void +clext_1012XX(struct bregs *regs) +{ + debug_stub(regs); +} + void -cirrus_extbios(struct bregs *regs) +clext_1012(struct bregs *regs) { - // XXX - regs->bl < 0x80 or > 0xaf call regular handlers. switch (regs->bl) { - case 0x80: cirrus_extbios_80h(regs); break; - case 0x81: cirrus_extbios_81h(regs); break; - case 0x82: cirrus_extbios_82h(regs); break; - case 0x85: cirrus_extbios_85h(regs); break; - case 0x9a: cirrus_extbios_9Ah(regs); break; - case 0xa0: cirrus_extbios_A0h(regs); break; - case 0xa1: cirrus_extbios_A1h(regs); break; - case 0xa2: cirrus_extbios_A2h(regs); break; - case 0xae: cirrus_extbios_AEh(regs); break; - default: break; + case 0x80: clext_101280(regs); break; + case 0x81: clext_101281(regs); break; + case 0x82: clext_101282(regs); break; + case 0x85: clext_101285(regs); break; + case 0x9a: clext_10129a(regs); break; + case 0xa0: clext_1012a0(regs); break; + case 0xa1: clext_1012a1(regs); break; + case 0xa2: clext_1012a2(regs); break; + case 0xae: clext_1012ae(regs); break; + default: clext_1012XX(regs); break; } }
diff --git a/vgasrc/clext.h b/vgasrc/clext.h index f337b65..a14cf13 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -1,11 +1,13 @@ #ifndef __CLEXT_H #define __CLEXT_H
-#include "types.h" // u8 +#include "types.h" // u16
struct vgamode_s *clext_find_mode(int mode); int clext_set_mode(int mode, int flags); void clext_list_modes(u16 seg, u16 *dest, u16 *last); int clext_init(void); +struct bregs; +void clext_1012(struct bregs *regs);
#endif // clext.h diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index f351107..8ab5baa 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -18,9 +18,7 @@ #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* #include "stdvga.h" // stdvga_set_cursor_shape -#include "geodevga.h" // geodevga_init -#include "bochsvga.h" // bochsvga_init -#include "clext.h" // clext_init +#include "clext.h" // clext_1012 #include "vgahw.h" // vgahw_set_mode
// XXX @@ -942,6 +940,11 @@ handle_1012XX(struct bregs *regs) static void handle_1012(struct bregs *regs) { + if (CONFIG_VGA_CIRRUS && regs->bl >= 0x80) { + clext_1012(regs); + return; + } + switch (regs->bl) { case 0x10: handle_101210(regs); break; case 0x30: handle_101230(regs); break; @@ -953,8 +956,6 @@ handle_1012(struct bregs *regs) case 0x36: handle_101236(regs); break; default: handle_1012XX(regs); break; } - - // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae }
Extract Cirrus framebuffer address from PCI config space.
Enable VBE code for Cirrus cards.
Also, rework bochsvga code to use direct PCI accesses instead of calling into the BIOS.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- vgasrc/bochsvga.c | 26 ++++---------------------- vgasrc/clext.c | 10 +++++++++- 3 files changed, 14 insertions(+), 24 deletions(-)
diff --git a/Makefile b/Makefile index 79f9b54..c97ed8f 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,7 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py ################ VGA build rules
# VGA src files -SRCVGA=src/output.c src/util.c vgasrc/vgabios.c vgasrc/vgafb.c \ +SRCVGA=src/output.c src/util.c src/pci.c vgasrc/vgabios.c vgasrc/vgafb.c \ vgasrc/vgatables.c vgasrc/vgafonts.c vgasrc/vbe.c \ vgasrc/stdvga.c vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index d9858c2..b7b1b05 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -5,6 +5,8 @@ #include "config.h" // CONFIG_* #include "biosvar.h" // SET_BDA #include "stdvga.h" // VGAREG_SEQU_ADDRESS +#include "pci.h" // pci_config_readl +#include "pci_regs.h" // PCI_BASE_ADDRESS_0
static struct bochsvga_mode { @@ -76,27 +78,6 @@ static struct bochsvga_mode { 0x18c, { MM_DIRECT, 2560, 1600, 32 } }, };
-static inline u32 pci_config_readl(u16 bdf, u16 addr) -{ - int status; - u32 val; - - addr &= ~3; - - asm volatile( - "int $0x1a\n" - "cli\n" - "cld" - : "=a"(status), "=c"(val) - : "a"(0xb10a), "b"(bdf), "D"(addr) - : "cc", "memory"); - - if ((status >> 16)) - return (u32)-1; - - return val; -} - static u16 dispi_get_max_xres(void) { u16 en; @@ -145,7 +126,8 @@ bochsvga_init(void)
u32 lfb_addr; if (CONFIG_VGA_PCI) - lfb_addr = pci_config_readl(GET_GLOBAL(VgaBDF), 0x10) & ~0xf; + lfb_addr = (pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0) + & PCI_BASE_ADDRESS_MEM_MASK); else lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 9bd424e..413add5 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -12,6 +12,8 @@ #include "bregs.h" // struct bregs #include "vbe.h" // struct vbe_info #include "stdvga.h" // VGAREG_SEQU_ADDRESS +#include "pci.h" // pci_config_readl +#include "pci_regs.h" // PCI_BASE_ADDRESS_0
/**************************************************************** @@ -421,7 +423,7 @@ cirrus_clear_vram(u16 param) int clext_set_mode(int mode, int flags) { - dprintf(1, "cirrus mode %d\n", mode); + dprintf(1, "cirrus mode %x\n", mode); SET_BDA(vbe_mode, 0); struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); if (table_g) { @@ -771,6 +773,12 @@ clext_init(void) return -1; dprintf(1, "cirrus init 2\n");
+ SET_VGA(VBE_enabled, 1); + u32 lfb_addr = 0; + if (CONFIG_VGA_PCI) + lfb_addr = (pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0) + & PCI_BASE_ADDRESS_MEM_MASK); + SET_VGA(VBE_framebuffer, lfb_addr); u16 totalmem = cirrus_get_memsize(); SET_VGA(VBE_total_memory, totalmem * 64 * 1024); SET_VGA(VBE_win_granularity, 16);