diff options
Diffstat (limited to 'vgasrc')
-rw-r--r-- | vgasrc/vga.c | 994 | ||||
-rw-r--r-- | vgasrc/vgafb.c | 642 | ||||
-rw-r--r-- | vgasrc/vgaio.c | 312 | ||||
-rw-r--r-- | vgasrc/vgatables.h | 37 |
4 files changed, 1010 insertions, 975 deletions
diff --git a/vgasrc/vga.c b/vgasrc/vga.c index 6c4ec05..48fcdeb 100644 --- a/vgasrc/vga.c +++ b/vgasrc/vga.c @@ -22,7 +22,7 @@ #include "bregs.h" // struct bregs #include "biosvar.h" // GET_BDA #include "util.h" // memset -#include "vgatables.h" // vga_modes +#include "vgatables.h" // find_vga_entry // XXX #define CONFIG_VBE 0 @@ -54,13 +54,6 @@ call16_vgaint(u32 eax, u32 ebx) : "cc", "memory"); } -// XXX -inline void -memcpy16_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len) -{ - memcpy_far(d_seg, d_far, s_seg, s_far, len); -} - // =================================================================== // @@ -171,7 +164,7 @@ biosfn_set_cursor_pos(u8 page, u16 cursor) outb(address & 0x00ff, crtc_addr + 1); } -static u16 +u16 biosfn_get_cursor_pos(u8 page) { if (page > 7) @@ -399,609 +392,6 @@ biosfn_set_video_mode(u8 mode) // ------------------------------------------------------------------- static void -vgamem_copy_pl4(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols, - u8 cheight) -{ - u16 src = ysrc * cheight * nbcols + xstart; - u16 dest = ydest * cheight * nbcols + xstart; - outw(0x0105, VGAREG_GRDC_ADDRESS); - u8 i; - for (i = 0; i < cheight; i++) - memcpy_far(SEG_GRAPH, (void*)(dest + i * nbcols) - , SEG_GRAPH, (void*)(src + i * nbcols), cols); - outw(0x0005, VGAREG_GRDC_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, - u8 attr) -{ - u16 dest = ystart * cheight * nbcols + xstart; - outw(0x0205, VGAREG_GRDC_ADDRESS); - u8 i; - for (i = 0; i < cheight; i++) - memset_far(SEG_GRAPH, (void*)(dest + i * nbcols), attr, cols); - outw(0x0005, VGAREG_GRDC_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols, - u8 cheight) -{ - u16 src = ((ysrc * cheight * nbcols) >> 1) + xstart; - u16 dest = ((ydest * cheight * nbcols) >> 1) + xstart; - u8 i; - for (i = 0; i < cheight; i++) - if (i & 1) - memcpy_far(SEG_CTEXT, (void*)(0x2000 + dest + (i >> 1) * nbcols) - , SEG_CTEXT, (void*)(0x2000 + src + (i >> 1) * nbcols) - , cols); - else - memcpy_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols) - , SEG_CTEXT, (void*)(src + (i >> 1) * nbcols), cols); -} - -// ------------------------------------------------------------------- -static void -vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, - u8 attr) -{ - u16 dest = ((ystart * cheight * nbcols) >> 1) + xstart; - u8 i; - for (i = 0; i < cheight; i++) - if (i & 1) - memset_far(SEG_CTEXT, (void*)(0x2000 + dest + (i >> 1) * nbcols) - , attr, cols); - else - memset_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols), attr, cols); -} - -// ------------------------------------------------------------------- -static void -biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page, - u8 dir) -{ - // page == 0xFF if current - if (rul > rlr) - return; - if (cul > clr) - return; - - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - // Get the current page - if (page == 0xFF) - page = GET_BDA(video_page); - - if (rlr >= nbrows) - rlr = nbrows - 1; - if (clr >= nbcols) - clr = nbcols - 1; - if (nblines > nbrows) - nblines = 0; - u8 cols = clr - cul + 1; - - if (GET_GLOBAL(vmode_g->class) == TEXT) { - // Compute the address - void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)); - dprintf(3, "Scroll, address %p (%d %d %02x)\n" - , address_far, nbrows, nbcols, page); - - if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1 - && clr == nbcols - 1) { - memset16_far(GET_GLOBAL(vmode_g->sstart), address_far - , (u16)attr * 0x100 + ' ', nbrows * nbcols * 2); - } else { // if Scroll up - if (dir == SCROLL_UP) { - u16 i; - for (i = rul; i <= rlr; i++) - if ((i + nblines > rlr) || (nblines == 0)) - memset16_far(GET_GLOBAL(vmode_g->sstart) - , address_far + (i * nbcols + cul) * 2 - , (u16)attr * 0x100 + ' ', cols * 2); - else - memcpy16_far(GET_GLOBAL(vmode_g->sstart) - , address_far + (i * nbcols + cul) * 2 - , GET_GLOBAL(vmode_g->sstart) - , (void*)(((i + nblines) * nbcols + cul) * 2) - , cols * 2); - } else { - u16 i; - for (i = rlr; i >= rul; i--) { - if ((i < rul + nblines) || (nblines == 0)) - memset16_far(GET_GLOBAL(vmode_g->sstart) - , address_far + (i * nbcols + cul) * 2 - , (u16)attr * 0x100 + ' ', cols * 2); - else - memcpy16_far(GET_GLOBAL(vmode_g->sstart) - , address_far + (i * nbcols + cul) * 2 - , GET_GLOBAL(vmode_g->sstart) - , (void*)(((i - nblines) * nbcols + cul) * 2) - , cols * 2); - if (i > rlr) - break; - } - } - } - return; - } - - // FIXME gfx mode not complete - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1 - && clr == nbcols - 1) { - outw(0x0205, VGAREG_GRDC_ADDRESS); - memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr, - nbrows * nbcols * cheight); - outw(0x0005, VGAREG_GRDC_ADDRESS); - } else { // if Scroll up - if (dir == SCROLL_UP) { - u16 i; - for (i = rul; i <= rlr; i++) - if ((i + nblines > rlr) || (nblines == 0)) - vgamem_fill_pl4(cul, i, cols, nbcols, cheight, - attr); - else - vgamem_copy_pl4(cul, i + nblines, i, cols, - nbcols, cheight); - } else { - u16 i; - for (i = rlr; i >= rul; i--) { - if ((i < rul + nblines) || (nblines == 0)) - vgamem_fill_pl4(cul, i, cols, nbcols, cheight, - attr); - else - vgamem_copy_pl4(cul, i, i - nblines, cols, - nbcols, cheight); - if (i > rlr) - break; - } - } - } - break; - case CGA: { - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1 - && clr == nbcols - 1) { - memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr, - nbrows * nbcols * cheight * bpp); - } else { - if (bpp == 2) { - cul <<= 1; - cols <<= 1; - nbcols <<= 1; - } - // if Scroll up - if (dir == SCROLL_UP) { - u16 i; - for (i = rul; i <= rlr; i++) - if ((i + nblines > rlr) || (nblines == 0)) - vgamem_fill_cga(cul, i, cols, nbcols, cheight, - attr); - else - vgamem_copy_cga(cul, i + nblines, i, cols, - nbcols, cheight); - } else { - u16 i; - for (i = rlr; i >= rul; i--) { - if ((i < rul + nblines) || (nblines == 0)) - vgamem_fill_cga(cul, i, cols, nbcols, cheight, - attr); - else - vgamem_copy_cga(cul, i, i - nblines, cols, - nbcols, cheight); - if (i > rlr) - break; - } - } - } - break; - } - default: - dprintf(1, "Scroll in graphics mode\n"); - } -} - -// ------------------------------------------------------------------- -static void -biosfn_read_char_attr(u8 page, u16 *car) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // Get the cursor pos for the page - u16 cursor = biosfn_get_cursor_pos(page); - u8 xcurs = cursor & 0x00ff; - u8 ycurs = (cursor & 0xff00) >> 8; - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - if (GET_GLOBAL(vmode_g->class) == TEXT) { - // Compute the address - u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) - + (xcurs + ycurs * nbcols) * 2); - - *car = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far); - } else { - // FIXME gfx mode - dprintf(1, "Read char in graphics mode\n"); - } -} - -// ------------------------------------------------------------------- -static void -write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, - u8 cheight) -{ - u8 *fdata_g; - switch (cheight) { - case 14: - fdata_g = vgafont14; - break; - case 16: - fdata_g = vgafont16; - break; - default: - fdata_g = vgafont8; - } - u16 addr = xcurs + ycurs * cheight * nbcols; - u16 src = car * cheight; - outw(0x0f02, VGAREG_SEQU_ADDRESS); - outw(0x0205, VGAREG_GRDC_ADDRESS); - if (attr & 0x80) - outw(0x1803, VGAREG_GRDC_ADDRESS); - else - outw(0x0003, VGAREG_GRDC_ADDRESS); - u8 i; - for (i = 0; i < cheight; i++) { - u8 *dest_far = (void*)(addr + i * nbcols); - u8 j; - for (j = 0; j < 8; j++) { - u8 mask = 0x80 >> j; - outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS); - GET_FARVAR(SEG_GRAPH, *dest_far); - if (GET_GLOBAL(fdata_g[src + i]) & mask) - SET_FARVAR(SEG_GRAPH, *dest_far, attr & 0x0f); - else - SET_FARVAR(SEG_GRAPH, *dest_far, 0x00); - } - } - outw(0xff08, VGAREG_GRDC_ADDRESS); - outw(0x0005, VGAREG_GRDC_ADDRESS); - outw(0x0003, VGAREG_GRDC_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp) -{ - u8 *fdata_g = vgafont8; - u16 addr = (xcurs * bpp) + ycurs * 320; - u16 src = car * 8; - u8 i; - for (i = 0; i < 8; i++) { - u8 *dest_far = (void*)(addr + (i >> 1) * 80); - if (i & 1) - dest_far += 0x2000; - u8 mask = 0x80; - if (bpp == 1) { - u8 data = 0; - if (attr & 0x80) - data = GET_FARVAR(SEG_CTEXT, *dest_far); - u8 j; - for (j = 0; j < 8; j++) { - if (GET_GLOBAL(fdata_g[src + i]) & mask) { - if (attr & 0x80) - data ^= (attr & 0x01) << (7 - j); - else - data |= (attr & 0x01) << (7 - j); - } - mask >>= 1; - } - SET_FARVAR(SEG_CTEXT, *dest_far, data); - } else { - while (mask > 0) { - u8 data = 0; - if (attr & 0x80) - data = GET_FARVAR(SEG_CTEXT, *dest_far); - u8 j; - for (j = 0; j < 4; j++) { - if (GET_GLOBAL(fdata_g[src + i]) & mask) { - if (attr & 0x80) - data ^= (attr & 0x03) << ((3 - j) * 2); - else - data |= (attr & 0x03) << ((3 - j) * 2); - } - mask >>= 1; - } - SET_FARVAR(SEG_CTEXT, *dest_far, data); - dest_far += 1; - } - } - } -} - -// ------------------------------------------------------------------- -static void -write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols) -{ - u8 *fdata_g = vgafont8; - u16 addr = xcurs * 8 + ycurs * nbcols * 64; - u16 src = car * 8; - u8 i; - for (i = 0; i < 8; i++) { - u8 *dest_far = (void*)(addr + i * nbcols * 8); - u8 mask = 0x80; - u8 j; - for (j = 0; j < 8; j++) { - u8 data = 0x00; - if (GET_GLOBAL(fdata_g[src + i]) & mask) - data = attr; - SET_FARVAR(SEG_GRAPH, dest_far[j], data); - mask >>= 1; - } - } -} - -// ------------------------------------------------------------------- -static void -biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // Get the cursor pos for the page - u16 cursor = biosfn_get_cursor_pos(page); - u8 xcurs = cursor & 0x00ff; - u8 ycurs = (cursor & 0xff00) >> 8; - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - if (GET_GLOBAL(vmode_g->class) == TEXT) { - // Compute the address - void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) - + (xcurs + ycurs * nbcols) * 2); - - u16 dummy = ((u16)attr << 8) + car; - memset16_far(GET_GLOBAL(vmode_g->sstart), address_far, dummy, count * 2); - return; - } - - // FIXME gfx mode not complete - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - while ((count-- > 0) && (xcurs < nbcols)) { - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight); - break; - case CGA: - write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp); - break; - case LINEAR8: - write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols); - break; - } - xcurs++; - } -} - -// ------------------------------------------------------------------- -static void -biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // Get the cursor pos for the page - u16 cursor = biosfn_get_cursor_pos(page); - u8 xcurs = cursor & 0x00ff; - u8 ycurs = (cursor & 0xff00) >> 8; - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - if (GET_GLOBAL(vmode_g->class) == TEXT) { - // Compute the address - u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) - + (xcurs + ycurs * nbcols) * 2); - while (count-- > 0) { - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far, car); - address_far += 2; - } - return; - } - - // FIXME gfx mode not complete - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - while ((count-- > 0) && (xcurs < nbcols)) { - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight); - break; - case CGA: - write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp); - break; - case LINEAR8: - write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols); - break; - } - xcurs++; - } -} - -// ------------------------------------------------------------------- -static void -biosfn_set_border_color(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - outb(0x00, VGAREG_ACTL_ADDRESS); - u8 al = regs->bl & 0x0f; - if (al & 0x08) - al += 0x08; - outb(al, VGAREG_ACTL_WRITE_DATA); - u8 bl = regs->bl & 0x10; - - int i; - for (i = 1; i < 4; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - - al = inb(VGAREG_ACTL_READ_DATA); - al &= 0xef; - al |= bl; - outb(al, VGAREG_ACTL_WRITE_DATA); - } - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -static void -biosfn_set_palette(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - u8 bl = regs->bl & 0x01; - int i; - for (i = 1; i < 4; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - - u8 al = inb(VGAREG_ACTL_READ_DATA); - al &= 0xfe; - al |= bl; - outb(al, VGAREG_ACTL_WRITE_DATA); - } - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - if (GET_GLOBAL(vmode_g->class) == TEXT) - return; - - u8 *addr_far, mask, attr, data; - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols)); - mask = 0x80 >> (CX & 0x07); - outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS); - outw(0x0205, VGAREG_GRDC_ADDRESS); - data = GET_FARVAR(SEG_GRAPH, *addr_far); - if (AL & 0x80) - outw(0x1803, VGAREG_GRDC_ADDRESS); - SET_FARVAR(SEG_GRAPH, *addr_far, AL); - outw(0xff08, VGAREG_GRDC_ADDRESS); - outw(0x0005, VGAREG_GRDC_ADDRESS); - outw(0x0003, VGAREG_GRDC_ADDRESS); - break; - case CGA: - if (GET_GLOBAL(vmode_g->pixbits) == 2) - addr_far = (void*)((CX >> 2) + (DX >> 1) * 80); - else - addr_far = (void*)((CX >> 3) + (DX >> 1) * 80); - if (DX & 1) - addr_far += 0x2000; - data = GET_FARVAR(SEG_CTEXT, *addr_far); - if (GET_GLOBAL(vmode_g->pixbits) == 2) { - attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); - mask = 0x03 << ((3 - (CX & 0x03)) * 2); - } else { - attr = (AL & 0x01) << (7 - (CX & 0x07)); - mask = 0x01 << (7 - (CX & 0x07)); - } - if (AL & 0x80) { - data ^= attr; - } else { - data &= ~mask; - data |= attr; - } - SET_FARVAR(SEG_CTEXT, *addr_far, data); - break; - case LINEAR8: - addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8)); - SET_FARVAR(SEG_GRAPH, *addr_far, AL); - break; - } -} - -// ------------------------------------------------------------------- -static void -biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - if (GET_GLOBAL(vmode_g->class) == TEXT) - return; - - u8 *addr_far, mask, attr=0, data, i; - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols)); - mask = 0x80 >> (CX & 0x07); - attr = 0x00; - for (i = 0; i < 4; i++) { - outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS); - data = GET_FARVAR(SEG_GRAPH, *addr_far) & mask; - if (data > 0) - attr |= (0x01 << i); - } - break; - case CGA: - addr_far = (void*)((CX >> 2) + (DX >> 1) * 80); - if (DX & 1) - addr_far += 0x2000; - data = GET_FARVAR(SEG_CTEXT, *addr_far); - if (GET_GLOBAL(vmode_g->pixbits) == 2) - attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03; - else - attr = (data >> (7 - (CX & 0x07))) & 0x01; - break; - case LINEAR8: - addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8)); - attr = GET_FARVAR(SEG_GRAPH, *addr_far); - break; - } - *AX = (*AX & 0xff00) | attr; -} - -// ------------------------------------------------------------------- -static void biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag) { // flag = WITH_ATTR / NO_ATTR // special case if page is 0xff, use current page @@ -1050,33 +440,10 @@ biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag) break; default: - - if (GET_GLOBAL(vmode_g->class) == TEXT) { - // Compute the address - u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) - + (xcurs + ycurs * nbcols) * 2); - // Write the char - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), address_far[0], car); - if (flag == WITH_ATTR) - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), address_far[1], attr); - } else { - // FIXME gfx mode not complete - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight); - break; - case CGA: - write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp); - break; - case LINEAR8: - write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols); - break; - } - } + if (flag == WITH_ATTR) + biosfn_write_char_attr(car, page, attr, 1); + else + biosfn_write_char_only(car, page, attr, 1); xcurs++; } @@ -1111,238 +478,6 @@ biosfn_get_video_mode(struct bregs *regs) regs->ah = GET_BDA(video_cols); } -// ------------------------------------------------------------------- -static void -biosfn_set_overscan_border_color(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - outb(regs->bh, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_set_all_palette_reg(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - - u8 *data_far = (u8*)(regs->dx + 0); - int i; - for (i = 0; i < 0x10; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - u8 val = GET_FARVAR(regs->es, *data_far); - outb(val, VGAREG_ACTL_WRITE_DATA); - data_far++; - } - outb(0x11, VGAREG_ACTL_ADDRESS); - outb(GET_FARVAR(regs->es, *data_far), VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_toggle_intensity(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -void -biosfn_set_single_palette_reg(u8 reg, u8 val) -{ - inb(VGAREG_ACTL_RESET); - outb(reg, VGAREG_ACTL_ADDRESS); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -u8 -biosfn_get_single_palette_reg(u8 reg) -{ - inb(VGAREG_ACTL_RESET); - outb(reg, VGAREG_ACTL_ADDRESS); - u8 v = inb(VGAREG_ACTL_READ_DATA); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - return v; -} - -// ------------------------------------------------------------------- -static void -biosfn_read_overscan_border_color(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - regs->bh = inb(VGAREG_ACTL_READ_DATA); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_get_all_palette_reg(struct bregs *regs) -{ - u8 *data_far = (u8*)(regs->dx + 0); - int i; - for (i = 0; i < 0x10; i++) { - inb(VGAREG_ACTL_RESET); - outb(i, VGAREG_ACTL_ADDRESS); - SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA)); - data_far++; - } - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA)); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_set_single_dac_reg(struct bregs *regs) -{ - outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS); - outb(regs->dh, VGAREG_DAC_DATA); - outb(regs->ch, VGAREG_DAC_DATA); - outb(regs->cl, VGAREG_DAC_DATA); -} - -// ------------------------------------------------------------------- -static void -biosfn_set_all_dac_reg(struct bregs *regs) -{ - outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS); - u8 *data_far = (u8*)(regs->dx + 0); - int count = regs->cx; - while (count) { - outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA); - data_far++; - outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA); - data_far++; - outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA); - data_far++; - count--; - } -} - -// ------------------------------------------------------------------- -static void -biosfn_select_video_dac_color_page(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val = inb(VGAREG_ACTL_READ_DATA); - if (!(regs->bl & 0x01)) { - val = (val & 0x7f) | (regs->bh << 7); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); - return; - } - inb(VGAREG_ACTL_RESET); - outb(0x14, VGAREG_ACTL_ADDRESS); - u8 bh = regs->bh; - if (!(val & 0x80)) - bh <<= 2; - bh &= 0x0f; - outb(bh, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_read_single_dac_reg(struct bregs *regs) -{ - outb(regs->bl, VGAREG_DAC_READ_ADDRESS); - regs->dh = inb(VGAREG_DAC_DATA); - regs->ch = inb(VGAREG_DAC_DATA); - regs->cl = inb(VGAREG_DAC_DATA); -} - -// ------------------------------------------------------------------- -static void -biosfn_read_all_dac_reg(struct bregs *regs) -{ - outb(regs->bl, VGAREG_DAC_READ_ADDRESS); - u8 *data_far = (u8*)(regs->dx + 0); - int count = regs->cx; - while (count) { - SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - count--; - } -} - -// ------------------------------------------------------------------- -static void -biosfn_set_pel_mask(struct bregs *regs) -{ - outb(regs->bl, VGAREG_PEL_MASK); -} - -// ------------------------------------------------------------------- -static void -biosfn_read_pel_mask(struct bregs *regs) -{ - regs->bl = inb(VGAREG_PEL_MASK); -} - -// ------------------------------------------------------------------- -static void -biosfn_read_video_dac_state(struct bregs *regs) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7; - - inb(VGAREG_ACTL_RESET); - outb(0x14, VGAREG_ACTL_ADDRESS); - u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f; - if (!(val1 & 0x01)) - val2 >>= 2; - - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - - regs->bl = val1; - regs->bh = val2; -} - -// ------------------------------------------------------------------- -static void -get_font_access() -{ - outw(0x0100, VGAREG_SEQU_ADDRESS); - outw(0x0402, VGAREG_SEQU_ADDRESS); - outw(0x0704, VGAREG_SEQU_ADDRESS); - outw(0x0300, VGAREG_SEQU_ADDRESS); - outw(0x0204, VGAREG_GRDC_ADDRESS); - outw(0x0005, VGAREG_GRDC_ADDRESS); - outw(0x0406, VGAREG_GRDC_ADDRESS); -} - -static void -release_font_access() -{ - outw(0x0100, VGAREG_SEQU_ADDRESS); - outw(0x0302, VGAREG_SEQU_ADDRESS); - outw(0x0304, VGAREG_SEQU_ADDRESS); - outw(0x0300, VGAREG_SEQU_ADDRESS); - u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; - outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS); - outw(0x0004, VGAREG_GRDC_ADDRESS); - outw(0x1005, VGAREG_GRDC_ADDRESS); -} - static void set_scan_lines(u8 lines) { @@ -1367,79 +502,6 @@ set_scan_lines(u8 lines) SET_BDA(video_pagesize, rows * cols * 2); } -static void -biosfn_load_text_user_pat(u8 AL, u16 ES, u16 BP, u16 CX, u16 DX, u8 BL, - u8 BH) -{ - get_font_access(); - u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - u16 i; - for (i = 0; i < CX; i++) { - void *src_far = (void*)(BP + i * BH); - void *dest_far = (void*)(blockaddr + (DX + i) * 32); - memcpy_far(SEG_GRAPH, dest_far, ES, src_far, BH); - } - release_font_access(); - if (AL >= 0x10) - set_scan_lines(BH); -} - -static void -biosfn_load_text_8_14_pat(u8 AL, u8 BL) -{ - get_font_access(); - u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - u16 i; - for (i = 0; i < 0x100; i++) { - u16 src = i * 14; - void *dest_far = (void*)(blockaddr + i * 32); - memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont14[src], 14); - } - release_font_access(); - if (AL >= 0x10) - set_scan_lines(14); -} - -static void -biosfn_load_text_8_8_pat(u8 AL, u8 BL) -{ - get_font_access(); - u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - u16 i; - for (i = 0; i < 0x100; i++) { - u16 src = i * 8; - void *dest_far = (void*)(blockaddr + i * 32); - memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont8[src], 8); - } - release_font_access(); - if (AL >= 0x10) - set_scan_lines(8); -} - -// ------------------------------------------------------------------- -static void -biosfn_set_text_block_specifier(struct bregs *regs) -{ - outw((regs->bl << 8) | 0x03, VGAREG_SEQU_ADDRESS); -} - -// ------------------------------------------------------------------- -static void -biosfn_load_text_8_16_pat(u8 AL, u8 BL) -{ - get_font_access(); - u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - u16 i; - for (i = 0; i < 0x100; i++) { - u16 src = i * 16; - void *dest_far = (void*)(blockaddr + i * 32); - memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont16[src], 16); - } - release_font_access(); - if (AL >= 0x10) - set_scan_lines(16); -} - // ------------------------------------------------------------------- static void biosfn_get_font_info(u8 BH, u16 *ES, u16 *BP, u16 *CX, u16 *DX) @@ -1545,15 +607,6 @@ biosfn_enable_default_palette_loading(struct bregs *regs) regs->ax = 0x1212; } -static void -biosfn_enable_video_addressing(struct bregs *regs) -{ - u8 v = ((regs->al << 1) & 0x02) ^ 0x02; - u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02; - outb(v | v2, VGAREG_WRITE_MISC_OUTPUT); - regs->ax = 0x1212; -} - static void biosfn_enable_grayscale_summing(struct bregs *regs) @@ -2213,23 +1266,20 @@ handle_1010(struct bregs *regs) static void handle_101100(struct bregs *regs) { - // XXX - inline - biosfn_load_text_user_pat(regs->al, regs->es, regs->bp + biosfn_load_text_user_pat(regs->es, regs->bp , regs->cx, regs->dx, regs->bl, regs->bh); } static void handle_101101(struct bregs *regs) { - // XXX - inline - biosfn_load_text_8_14_pat(regs->al, regs->bl); + biosfn_load_text_8_14_pat(regs->bl); } static void handle_101102(struct bregs *regs) { - // XXX - inline - biosfn_load_text_8_8_pat(regs->al, regs->bl); + biosfn_load_text_8_8_pat(regs->bl); } static void @@ -2242,32 +1292,36 @@ handle_101103(struct bregs *regs) static void handle_101104(struct bregs *regs) { - // XXX - inline - biosfn_load_text_8_16_pat(regs->al, regs->bl); + biosfn_load_text_8_16_pat(regs->bl); } static void handle_101110(struct bregs *regs) { - handle_101100(regs); + biosfn_load_text_user_pat(regs->es, regs->bp + , regs->cx, regs->dx, regs->bl, regs->bh); + set_scan_lines(regs->bh); } static void handle_101111(struct bregs *regs) { - handle_101101(regs); + biosfn_load_text_8_14_pat(regs->bl); + set_scan_lines(14); } static void handle_101112(struct bregs *regs) { - handle_101102(regs); + biosfn_load_text_8_8_pat(regs->bl); + set_scan_lines(8); } static void handle_101114(struct bregs *regs) { - handle_101104(regs); + biosfn_load_text_8_16_pat(regs->bl); + set_scan_lines(16); } static void @@ -2641,16 +1695,6 @@ init_bios_area() SET_BDA(video_msr, 0x09); } -static void -init_vga_card() -{ - // switch to color mode and enable CPU access 480 lines - outb(0xc3, VGAREG_WRITE_MISC_OUTPUT); - // more than 64k 3C4/04 - outb(0x04, VGAREG_SEQU_ADDRESS); - outb(0x02, VGAREG_SEQU_DATA); -} - void VISIBLE16 vga_post(struct bregs *regs) { diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c new file mode 100644 index 0000000..a34b6c0 --- /dev/null +++ b/vgasrc/vgafb.c @@ -0,0 +1,642 @@ +// Code for manipulating VGA framebuffers. +// +// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net> +// Copyright (C) 2001-2008 the LGPL VGABios developers Team +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "biosvar.h" // GET_BDA +#include "util.h" // memset_far +#include "vgatables.h" // find_vga_entry + +// XXX +inline void +memcpy16_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len) +{ + memcpy_far(d_seg, d_far, s_seg, s_far, len); +} + + +/**************************************************************** + * Screen scrolling + ****************************************************************/ + +static void +vgamem_copy_pl4(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols, + u8 cheight) +{ + u16 src = ysrc * cheight * nbcols + xstart; + u16 dest = ydest * cheight * nbcols + xstart; + outw(0x0105, VGAREG_GRDC_ADDRESS); + u8 i; + for (i = 0; i < cheight; i++) + memcpy_far(SEG_GRAPH, (void*)(dest + i * nbcols) + , SEG_GRAPH, (void*)(src + i * nbcols), cols); + outw(0x0005, VGAREG_GRDC_ADDRESS); +} + +static void +vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, + u8 attr) +{ + u16 dest = ystart * cheight * nbcols + xstart; + outw(0x0205, VGAREG_GRDC_ADDRESS); + u8 i; + for (i = 0; i < cheight; i++) + memset_far(SEG_GRAPH, (void*)(dest + i * nbcols), attr, cols); + outw(0x0005, VGAREG_GRDC_ADDRESS); +} + +static void +vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols, + u8 cheight) +{ + u16 src = ((ysrc * cheight * nbcols) >> 1) + xstart; + u16 dest = ((ydest * cheight * nbcols) >> 1) + xstart; + u8 i; + for (i = 0; i < cheight; i++) + if (i & 1) + memcpy_far(SEG_CTEXT, (void*)(0x2000 + dest + (i >> 1) * nbcols) + , SEG_CTEXT, (void*)(0x2000 + src + (i >> 1) * nbcols) + , cols); + else + memcpy_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols) + , SEG_CTEXT, (void*)(src + (i >> 1) * nbcols), cols); +} + +static void +vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, + u8 attr) +{ + u16 dest = ((ystart * cheight * nbcols) >> 1) + xstart; + u8 i; + for (i = 0; i < cheight; i++) + if (i & 1) + memset_far(SEG_CTEXT, (void*)(0x2000 + dest + (i >> 1) * nbcols) + , attr, cols); + else + memset_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols), attr, cols); +} + +void +biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page, + u8 dir) +{ + // page == 0xFF if current + if (rul > rlr) + return; + if (cul > clr) + return; + + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + + // Get the current page + if (page == 0xFF) + page = GET_BDA(video_page); + + if (rlr >= nbrows) + rlr = nbrows - 1; + if (clr >= nbcols) + clr = nbcols - 1; + if (nblines > nbrows) + nblines = 0; + u8 cols = clr - cul + 1; + + if (GET_GLOBAL(vmode_g->class) == TEXT) { + // Compute the address + void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)); + dprintf(3, "Scroll, address %p (%d %d %02x)\n" + , address_far, nbrows, nbcols, page); + + if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1 + && clr == nbcols - 1) { + memset16_far(GET_GLOBAL(vmode_g->sstart), address_far + , (u16)attr * 0x100 + ' ', nbrows * nbcols * 2); + } else { // if Scroll up + if (dir == SCROLL_UP) { + u16 i; + for (i = rul; i <= rlr; i++) + if ((i + nblines > rlr) || (nblines == 0)) + memset16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + cul) * 2 + , (u16)attr * 0x100 + ' ', cols * 2); + else + memcpy16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + cul) * 2 + , GET_GLOBAL(vmode_g->sstart) + , (void*)(((i + nblines) * nbcols + cul) * 2) + , cols * 2); + } else { + u16 i; + for (i = rlr; i >= rul; i--) { + if ((i < rul + nblines) || (nblines == 0)) + memset16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + cul) * 2 + , (u16)attr * 0x100 + ' ', cols * 2); + else + memcpy16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + cul) * 2 + , GET_GLOBAL(vmode_g->sstart) + , (void*)(((i - nblines) * nbcols + cul) * 2) + , cols * 2); + if (i > rlr) + break; + } + } + } + return; + } + + // FIXME gfx mode not complete + struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); + u8 cheight = GET_GLOBAL(vparam_g->cheight); + switch (GET_GLOBAL(vmode_g->memmodel)) { + case PLANAR4: + case PLANAR1: + if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1 + && clr == nbcols - 1) { + outw(0x0205, VGAREG_GRDC_ADDRESS); + memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr, + nbrows * nbcols * cheight); + outw(0x0005, VGAREG_GRDC_ADDRESS); + } else { // if Scroll up + if (dir == SCROLL_UP) { + u16 i; + for (i = rul; i <= rlr; i++) + if ((i + nblines > rlr) || (nblines == 0)) + vgamem_fill_pl4(cul, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_pl4(cul, i + nblines, i, cols, + nbcols, cheight); + } else { + u16 i; + for (i = rlr; i >= rul; i--) { + if ((i < rul + nblines) || (nblines == 0)) + vgamem_fill_pl4(cul, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_pl4(cul, i, i - nblines, cols, + nbcols, cheight); + if (i > rlr) + break; + } + } + } + break; + case CGA: { + u8 bpp = GET_GLOBAL(vmode_g->pixbits); + if (nblines == 0 && rul == 0 && cul == 0 && rlr == nbrows - 1 + && clr == nbcols - 1) { + memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr, + nbrows * nbcols * cheight * bpp); + } else { + if (bpp == 2) { + cul <<= 1; + cols <<= 1; + nbcols <<= 1; + } + // if Scroll up + if (dir == SCROLL_UP) { + u16 i; + for (i = rul; i <= rlr; i++) + if ((i + nblines > rlr) || (nblines == 0)) + vgamem_fill_cga(cul, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_cga(cul, i + nblines, i, cols, + nbcols, cheight); + } else { + u16 i; + for (i = rlr; i >= rul; i--) { + if ((i < rul + nblines) || (nblines == 0)) + vgamem_fill_cga(cul, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_cga(cul, i, i - nblines, cols, + nbcols, cheight); + if (i > rlr) + break; + } + } + } + break; + } + default: + dprintf(1, "Scroll in graphics mode\n"); + } +} + + +/**************************************************************** + * Read/write characters to screen + ****************************************************************/ + +static void +write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, + u8 cheight) +{ + u8 *fdata_g; + switch (cheight) { + case 14: + fdata_g = vgafont14; + break; + case 16: + fdata_g = vgafont16; + break; + default: + fdata_g = vgafont8; + } + u16 addr = xcurs + ycurs * cheight * nbcols; + u16 src = car * cheight; + outw(0x0f02, VGAREG_SEQU_ADDRESS); + outw(0x0205, VGAREG_GRDC_ADDRESS); + if (attr & 0x80) + outw(0x1803, VGAREG_GRDC_ADDRESS); + else + outw(0x0003, VGAREG_GRDC_ADDRESS); + u8 i; + for (i = 0; i < cheight; i++) { + u8 *dest_far = (void*)(addr + i * nbcols); + u8 j; + for (j = 0; j < 8; j++) { + u8 mask = 0x80 >> j; + outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS); + GET_FARVAR(SEG_GRAPH, *dest_far); + if (GET_GLOBAL(fdata_g[src + i]) & mask) + SET_FARVAR(SEG_GRAPH, *dest_far, attr & 0x0f); + else + SET_FARVAR(SEG_GRAPH, *dest_far, 0x00); + } + } + outw(0xff08, VGAREG_GRDC_ADDRESS); + outw(0x0005, VGAREG_GRDC_ADDRESS); + outw(0x0003, VGAREG_GRDC_ADDRESS); +} + +static void +write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp) +{ + u8 *fdata_g = vgafont8; + u16 addr = (xcurs * bpp) + ycurs * 320; + u16 src = car * 8; + u8 i; + for (i = 0; i < 8; i++) { + u8 *dest_far = (void*)(addr + (i >> 1) * 80); + if (i & 1) + dest_far += 0x2000; + u8 mask = 0x80; + if (bpp == 1) { + u8 data = 0; + if (attr & 0x80) + data = GET_FARVAR(SEG_CTEXT, *dest_far); + u8 j; + for (j = 0; j < 8; j++) { + if (GET_GLOBAL(fdata_g[src + i]) & mask) { + if (attr & 0x80) + data ^= (attr & 0x01) << (7 - j); + else + data |= (attr & 0x01) << (7 - j); + } + mask >>= 1; + } + SET_FARVAR(SEG_CTEXT, *dest_far, data); + } else { + while (mask > 0) { + u8 data = 0; + if (attr & 0x80) + data = GET_FARVAR(SEG_CTEXT, *dest_far); + u8 j; + for (j = 0; j < 4; j++) { + if (GET_GLOBAL(fdata_g[src + i]) & mask) { + if (attr & 0x80) + data ^= (attr & 0x03) << ((3 - j) * 2); + else + data |= (attr & 0x03) << ((3 - j) * 2); + } + mask >>= 1; + } + SET_FARVAR(SEG_CTEXT, *dest_far, data); + dest_far += 1; + } + } + } +} + +static void +write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols) +{ + u8 *fdata_g = vgafont8; + u16 addr = xcurs * 8 + ycurs * nbcols * 64; + u16 src = car * 8; + u8 i; + for (i = 0; i < 8; i++) { + u8 *dest_far = (void*)(addr + i * nbcols * 8); + u8 mask = 0x80; + u8 j; + for (j = 0; j < 8; j++) { + u8 data = 0x00; + if (GET_GLOBAL(fdata_g[src + i]) & mask) + data = attr; + SET_FARVAR(SEG_GRAPH, dest_far[j], data); + mask >>= 1; + } + } +} + +void +biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count) +{ + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + + // Get the cursor pos for the page + u16 cursor = biosfn_get_cursor_pos(page); + u8 xcurs = cursor & 0x00ff; + u8 ycurs = (cursor & 0xff00) >> 8; + + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + + if (GET_GLOBAL(vmode_g->class) == TEXT) { + // Compute the address + void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) + + (xcurs + ycurs * nbcols) * 2); + + u16 dummy = ((u16)attr << 8) + car; + memset16_far(GET_GLOBAL(vmode_g->sstart), address_far, dummy, count * 2); + return; + } + + // FIXME gfx mode not complete + struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); + u8 cheight = GET_GLOBAL(vparam_g->cheight); + u8 bpp = GET_GLOBAL(vmode_g->pixbits); + while ((count-- > 0) && (xcurs < nbcols)) { + switch (GET_GLOBAL(vmode_g->memmodel)) { + case PLANAR4: + case PLANAR1: + write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight); + break; + case CGA: + write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp); + break; + case LINEAR8: + write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols); + break; + } + xcurs++; + } +} + +void +biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count) +{ + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + + // Get the cursor pos for the page + u16 cursor = biosfn_get_cursor_pos(page); + u8 xcurs = cursor & 0x00ff; + u8 ycurs = (cursor & 0xff00) >> 8; + + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + + if (GET_GLOBAL(vmode_g->class) == TEXT) { + // Compute the address + u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) + + (xcurs + ycurs * nbcols) * 2); + while (count-- > 0) { + SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far, car); + address_far += 2; + } + return; + } + + // FIXME gfx mode not complete + struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); + u8 cheight = GET_GLOBAL(vparam_g->cheight); + u8 bpp = GET_GLOBAL(vmode_g->pixbits); + while ((count-- > 0) && (xcurs < nbcols)) { + switch (GET_GLOBAL(vmode_g->memmodel)) { + case PLANAR4: + case PLANAR1: + write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols, cheight); + break; + case CGA: + write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp); + break; + case LINEAR8: + write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols); + break; + } + xcurs++; + } +} + +void +biosfn_read_char_attr(u8 page, u16 *car) +{ + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + + // Get the cursor pos for the page + u16 cursor = biosfn_get_cursor_pos(page); + u8 xcurs = cursor & 0x00ff; + u8 ycurs = (cursor & 0xff00) >> 8; + + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + + if (GET_GLOBAL(vmode_g->class) == TEXT) { + // Compute the address + u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page) + + (xcurs + ycurs * nbcols) * 2); + + *car = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far); + } else { + // FIXME gfx mode + dprintf(1, "Read char in graphics mode\n"); + } +} + + +/**************************************************************** + * Read/write pixels + ****************************************************************/ + +void +biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX) +{ + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + if (GET_GLOBAL(vmode_g->class) == TEXT) + return; + + u8 *addr_far, mask, attr, data; + switch (GET_GLOBAL(vmode_g->memmodel)) { + case PLANAR4: + case PLANAR1: + addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols)); + mask = 0x80 >> (CX & 0x07); + outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS); + outw(0x0205, VGAREG_GRDC_ADDRESS); + data = GET_FARVAR(SEG_GRAPH, *addr_far); + if (AL & 0x80) + outw(0x1803, VGAREG_GRDC_ADDRESS); + SET_FARVAR(SEG_GRAPH, *addr_far, AL); + outw(0xff08, VGAREG_GRDC_ADDRESS); + outw(0x0005, VGAREG_GRDC_ADDRESS); + outw(0x0003, VGAREG_GRDC_ADDRESS); + break; + case CGA: + if (GET_GLOBAL(vmode_g->pixbits) == 2) + addr_far = (void*)((CX >> 2) + (DX >> 1) * 80); + else + addr_far = (void*)((CX >> 3) + (DX >> 1) * 80); + if (DX & 1) + addr_far += 0x2000; + data = GET_FARVAR(SEG_CTEXT, *addr_far); + if (GET_GLOBAL(vmode_g->pixbits) == 2) { + attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); + mask = 0x03 << ((3 - (CX & 0x03)) * 2); + } else { + attr = (AL & 0x01) << (7 - (CX & 0x07)); + mask = 0x01 << (7 - (CX & 0x07)); + } + if (AL & 0x80) { + data ^= attr; + } else { + data &= ~mask; + data |= attr; + } + SET_FARVAR(SEG_CTEXT, *addr_far, data); + break; + case LINEAR8: + addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8)); + SET_FARVAR(SEG_GRAPH, *addr_far, AL); + break; + } +} + +void +biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX) +{ + // Get the mode + struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); + if (!vmode_g) + return; + if (GET_GLOBAL(vmode_g->class) == TEXT) + return; + + u8 *addr_far, mask, attr=0, data, i; + switch (GET_GLOBAL(vmode_g->memmodel)) { + case PLANAR4: + case PLANAR1: + addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols)); + mask = 0x80 >> (CX & 0x07); + attr = 0x00; + for (i = 0; i < 4; i++) { + outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS); + data = GET_FARVAR(SEG_GRAPH, *addr_far) & mask; + if (data > 0) + attr |= (0x01 << i); + } + break; + case CGA: + addr_far = (void*)((CX >> 2) + (DX >> 1) * 80); + if (DX & 1) + addr_far += 0x2000; + data = GET_FARVAR(SEG_CTEXT, *addr_far); + if (GET_GLOBAL(vmode_g->pixbits) == 2) + attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03; + else + attr = (data >> (7 - (CX & 0x07))) & 0x01; + break; + case LINEAR8: + addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8)); + attr = GET_FARVAR(SEG_GRAPH, *addr_far); + break; + } + *AX = (*AX & 0xff00) | attr; +} + + +/**************************************************************** + * Font loading + ****************************************************************/ + +void +biosfn_load_text_user_pat(u16 ES, u16 BP, u16 CX, u16 DX, u8 BL, u8 BH) +{ + get_font_access(); + u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + u16 i; + for (i = 0; i < CX; i++) { + void *src_far = (void*)(BP + i * BH); + void *dest_far = (void*)(blockaddr + (DX + i) * 32); + memcpy_far(SEG_GRAPH, dest_far, ES, src_far, BH); + } + release_font_access(); +} + +void +biosfn_load_text_8_14_pat(u8 BL) +{ + get_font_access(); + u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + u16 i; + for (i = 0; i < 0x100; i++) { + u16 src = i * 14; + void *dest_far = (void*)(blockaddr + i * 32); + memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont14[src], 14); + } + release_font_access(); +} + +void +biosfn_load_text_8_8_pat(u8 BL) +{ + get_font_access(); + u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + u16 i; + for (i = 0; i < 0x100; i++) { + u16 src = i * 8; + void *dest_far = (void*)(blockaddr + i * 32); + memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont8[src], 8); + } + release_font_access(); +} + +void +biosfn_load_text_8_16_pat(u8 BL) +{ + get_font_access(); + u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + u16 i; + for (i = 0; i < 0x100; i++) { + u16 src = i * 16; + void *dest_far = (void*)(blockaddr + i * 32); + memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont16[src], 16); + } + release_font_access(); +} diff --git a/vgasrc/vgaio.c b/vgasrc/vgaio.c new file mode 100644 index 0000000..88fd01e --- /dev/null +++ b/vgasrc/vgaio.c @@ -0,0 +1,312 @@ +// VGA io port access +// +// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net> +// Copyright (C) 2001-2008 the LGPL VGABios developers Team +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "ioport.h" // outb +#include "bregs.h" // struct bregs +#include "farptr.h" // SET_FARVAR +#include "vgatables.h" // VGAREG_* + + +/**************************************************************** + * Attribute control + ****************************************************************/ + +void +biosfn_set_border_color(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + outb(0x00, VGAREG_ACTL_ADDRESS); + u8 al = regs->bl & 0x0f; + if (al & 0x08) + al += 0x08; + outb(al, VGAREG_ACTL_WRITE_DATA); + u8 bl = regs->bl & 0x10; + + int i; + for (i = 1; i < 4; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + + al = inb(VGAREG_ACTL_READ_DATA); + al &= 0xef; + al |= bl; + outb(al, VGAREG_ACTL_WRITE_DATA); + } + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_set_overscan_border_color(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + outb(0x11, VGAREG_ACTL_ADDRESS); + outb(regs->bh, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_read_overscan_border_color(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + outb(0x11, VGAREG_ACTL_ADDRESS); + regs->bh = inb(VGAREG_ACTL_READ_DATA); + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_set_palette(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + u8 bl = regs->bl & 0x01; + int i; + for (i = 1; i < 4; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + + u8 al = inb(VGAREG_ACTL_READ_DATA); + al &= 0xfe; + al |= bl; + outb(al, VGAREG_ACTL_WRITE_DATA); + } + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_set_single_palette_reg(u8 reg, u8 val) +{ + inb(VGAREG_ACTL_RESET); + outb(reg, VGAREG_ACTL_ADDRESS); + outb(val, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +u8 +biosfn_get_single_palette_reg(u8 reg) +{ + inb(VGAREG_ACTL_RESET); + outb(reg, VGAREG_ACTL_ADDRESS); + u8 v = inb(VGAREG_ACTL_READ_DATA); + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); + return v; +} + +void +biosfn_set_all_palette_reg(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + + u8 *data_far = (u8*)(regs->dx + 0); + int i; + for (i = 0; i < 0x10; i++) { + outb(i, VGAREG_ACTL_ADDRESS); + u8 val = GET_FARVAR(regs->es, *data_far); + outb(val, VGAREG_ACTL_WRITE_DATA); + data_far++; + } + outb(0x11, VGAREG_ACTL_ADDRESS); + outb(GET_FARVAR(regs->es, *data_far), VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_get_all_palette_reg(struct bregs *regs) +{ + u8 *data_far = (u8*)(regs->dx + 0); + int i; + for (i = 0; i < 0x10; i++) { + inb(VGAREG_ACTL_RESET); + outb(i, VGAREG_ACTL_ADDRESS); + SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA)); + data_far++; + } + inb(VGAREG_ACTL_RESET); + outb(0x11, VGAREG_ACTL_ADDRESS); + SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA)); + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_toggle_intensity(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + outb(0x10, VGAREG_ACTL_ADDRESS); + u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3); + outb(val, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_select_video_dac_color_page(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + outb(0x10, VGAREG_ACTL_ADDRESS); + u8 val = inb(VGAREG_ACTL_READ_DATA); + if (!(regs->bl & 0x01)) { + val = (val & 0x7f) | (regs->bh << 7); + outb(val, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); + return; + } + inb(VGAREG_ACTL_RESET); + outb(0x14, VGAREG_ACTL_ADDRESS); + u8 bh = regs->bh; + if (!(val & 0x80)) + bh <<= 2; + bh &= 0x0f; + outb(bh, VGAREG_ACTL_WRITE_DATA); + outb(0x20, VGAREG_ACTL_ADDRESS); +} + +void +biosfn_read_video_dac_state(struct bregs *regs) +{ + inb(VGAREG_ACTL_RESET); + outb(0x10, VGAREG_ACTL_ADDRESS); + u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7; + + inb(VGAREG_ACTL_RESET); + outb(0x14, VGAREG_ACTL_ADDRESS); + u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f; + if (!(val1 & 0x01)) + val2 >>= 2; + + inb(VGAREG_ACTL_RESET); + outb(0x20, VGAREG_ACTL_ADDRESS); + + regs->bl = val1; + regs->bh = val2; +} + + +/**************************************************************** + * DAC control + ****************************************************************/ + +void +biosfn_set_single_dac_reg(struct bregs *regs) +{ + outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS); + outb(regs->dh, VGAREG_DAC_DATA); + outb(regs->ch, VGAREG_DAC_DATA); + outb(regs->cl, VGAREG_DAC_DATA); +} + +void +biosfn_read_single_dac_reg(struct bregs *regs) +{ + outb(regs->bl, VGAREG_DAC_READ_ADDRESS); + regs->dh = inb(VGAREG_DAC_DATA); + regs->ch = inb(VGAREG_DAC_DATA); + regs->cl = inb(VGAREG_DAC_DATA); +} + +void +biosfn_set_all_dac_reg(struct bregs *regs) +{ + outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS); + u8 *data_far = (u8*)(regs->dx + 0); + int count = regs->cx; + while (count) { + outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA); + data_far++; + outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA); + data_far++; + outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA); + data_far++; + count--; + } +} + +void +biosfn_read_all_dac_reg(struct bregs *regs) +{ + outb(regs->bl, VGAREG_DAC_READ_ADDRESS); + u8 *data_far = (u8*)(regs->dx + 0); + int count = regs->cx; + while (count) { + SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA)); + data_far++; + SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA)); + data_far++; + SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA)); + data_far++; + count--; + } +} + +void +biosfn_set_pel_mask(struct bregs *regs) +{ + outb(regs->bl, VGAREG_PEL_MASK); +} + +void +biosfn_read_pel_mask(struct bregs *regs) +{ + regs->bl = inb(VGAREG_PEL_MASK); +} + + +/**************************************************************** + * Memory control + ****************************************************************/ + +void +biosfn_set_text_block_specifier(struct bregs *regs) +{ + outw((regs->bl << 8) | 0x03, VGAREG_SEQU_ADDRESS); +} + +void +get_font_access() +{ + outw(0x0100, VGAREG_SEQU_ADDRESS); + outw(0x0402, VGAREG_SEQU_ADDRESS); + outw(0x0704, VGAREG_SEQU_ADDRESS); + outw(0x0300, VGAREG_SEQU_ADDRESS); + outw(0x0204, VGAREG_GRDC_ADDRESS); + outw(0x0005, VGAREG_GRDC_ADDRESS); + outw(0x0406, VGAREG_GRDC_ADDRESS); +} + +void +release_font_access() +{ + outw(0x0100, VGAREG_SEQU_ADDRESS); + outw(0x0302, VGAREG_SEQU_ADDRESS); + outw(0x0304, VGAREG_SEQU_ADDRESS); + outw(0x0300, VGAREG_SEQU_ADDRESS); + u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; + outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS); + outw(0x0004, VGAREG_GRDC_ADDRESS); + outw(0x1005, VGAREG_GRDC_ADDRESS); +} + + +/**************************************************************** + * Misc + ****************************************************************/ + +void +biosfn_enable_video_addressing(struct bregs *regs) +{ + u8 v = ((regs->al << 1) & 0x02) ^ 0x02; + u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02; + outb(v | v2, VGAREG_WRITE_MISC_OUTPUT); + regs->ax = 0x1212; +} + +void +init_vga_card() +{ + // switch to color mode and enable CPU access 480 lines + outb(0xc3, VGAREG_WRITE_MISC_OUTPUT); + // more than 64k 3C4/04 + outb(0x04, VGAREG_SEQU_ADDRESS); + outb(0x02, VGAREG_SEQU_DATA); +} diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h index 4fbfb90..2634c8b 100644 --- a/vgasrc/vgatables.h +++ b/vgasrc/vgatables.h @@ -117,8 +117,45 @@ extern u8 vgafont14alt[]; extern u8 vgafont16alt[]; // vga.c +u16 biosfn_get_cursor_pos(u8 page); + +// vgafb.c +void biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr + , u8 page, u8 dir); +void biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count); +void biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count); +void biosfn_read_char_attr(u8 page, u16 *car); +void biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX); +void biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX); +void biosfn_load_text_user_pat(u16 ES, u16 BP, u16 CX, u16 DX, u8 BL, u8 BH); +void biosfn_load_text_8_14_pat(u8 BL); +void biosfn_load_text_8_8_pat(u8 BL); +void biosfn_load_text_8_16_pat(u8 BL); + +// vgaio.c +struct bregs; +void biosfn_set_border_color(struct bregs *regs); +void biosfn_set_overscan_border_color(struct bregs *regs); +void biosfn_read_overscan_border_color(struct bregs *regs); +void biosfn_set_palette(struct bregs *regs); void biosfn_set_single_palette_reg(u8 reg, u8 val); u8 biosfn_get_single_palette_reg(u8 reg); +void biosfn_set_all_palette_reg(struct bregs *regs); +void biosfn_get_all_palette_reg(struct bregs *regs); +void biosfn_toggle_intensity(struct bregs *regs); +void biosfn_select_video_dac_color_page(struct bregs *regs); +void biosfn_read_video_dac_state(struct bregs *regs); +void biosfn_set_single_dac_reg(struct bregs *regs); +void biosfn_read_single_dac_reg(struct bregs *regs); +void biosfn_set_all_dac_reg(struct bregs *regs); +void biosfn_read_all_dac_reg(struct bregs *regs); +void biosfn_set_pel_mask(struct bregs *regs); +void biosfn_read_pel_mask(struct bregs *regs); +void biosfn_set_text_block_specifier(struct bregs *regs); +void get_font_access(); +void release_font_access(); +void biosfn_enable_video_addressing(struct bregs *regs); +void init_vga_card(); // clext.c void cirrus_set_video_mode(u8 mode); |