X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=vgasrc%2Fvgafb.c;h=1e1943dc2b6cb126b885a29c33d0f2ff1dbd5969;hb=87233e9ddac7f833d14031be5d7afc705aed5f25;hp=605a3b6918ebd01702fd376b63a16f5613262acc;hpb=deb9cb929d3db99839e4b65f48d41dea942d3e5a;p=seabios.git diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 605a3b6..1e1943d 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -9,268 +9,186 @@ #include "util.h" // memset_far #include "vgatables.h" // find_vga_entry -// TODO -// * extract hw code from framebuffer code -// * use clear_screen() in scroll code -// * merge car/attr/with_attr into one param -// * merge page/x/y into one param -// * combine biosfn_write_char_attr/_only() -// * read/write_char should take a position; should not take count -// * remove vmode_g->class (integrate into vmode_g->memmodel) -// * normalize params (don't use AX/BX/CX/etc.) - -// 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) +static inline void * +memcpy_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines) { - 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); + for (; lines; lines--, dst+=stride, src+=stride) + memcpy_far(seg, dst, seg, src, copylen); + return dst; } -static void -vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, - u8 attr) +static inline void +memset_stride(u16 seg, void *dst, u8 val, int setlen, int stride, int lines) { - 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); + for (; lines; lines--, dst+=stride) + memset_far(seg, dst, val, setlen); } -static void -vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols, - u8 cheight) +static inline void +memset16_stride(u16 seg, void *dst, u16 val, int setlen, int stride, int lines) { - 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); + for (; lines; lines--, dst+=stride) + memset16_far(seg, dst, val, setlen); } static void -vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, - u8 attr) +scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr + , struct cursorpos ul, struct cursorpos lr) { - 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); + u8 cheight = GET_GLOBAL(vmode_g->cheight); + int stride = GET_BDA(video_cols); + void *src_far, *dest_far; + if (nblines >= 0) { + dest_far = (void*)(ul.y * cheight * stride + ul.x); + src_far = dest_far + nblines * cheight * stride; + } else { + // Scroll down + nblines = -nblines; + dest_far = (void*)(lr.y * cheight * stride + ul.x); + src_far = dest_far - nblines * cheight * stride; + stride = -stride; + } + int cols = lr.x - ul.x + 1; + int rows = lr.y - ul.y + 1; + if (nblines < rows) { + vgahw_grdc_write(0x05, 0x01); + dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols, stride + , (rows - nblines) * cheight); + } + if (attr < 0) + attr = 0; + vgahw_grdc_write(0x05, 0x02); + memset_stride(SEG_GRAPH, dest_far, attr, cols, stride, nblines * cheight); + vgahw_grdc_write(0x05, 0x00); } -void -clear_screen(struct vgamode_s *vmode_g) +static void +scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr + , struct cursorpos ul, struct cursorpos lr) { - if (GET_GLOBAL(vmode_g->class) == TEXT) { - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); - return; + u8 cheight = GET_GLOBAL(vmode_g->cheight); + u8 bpp = GET_GLOBAL(vmode_g->pixbits); + int stride = GET_BDA(video_cols) * bpp; + void *src_far, *dest_far; + if (nblines >= 0) { + dest_far = (void*)(ul.y * cheight * stride + ul.x * bpp); + src_far = dest_far + nblines * cheight * stride; + } else { + // Scroll down + nblines = -nblines; + dest_far = (void*)(lr.y * cheight * stride + ul.x * bpp); + src_far = dest_far - nblines * cheight * stride; + stride = -stride; } - if (GET_GLOBAL(vmode_g->svgamode) < 0x0d) { - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); - return; + int cols = (lr.x - ul.x + 1) * bpp; + int rows = lr.y - ul.y + 1; + if (nblines < rows) { + memcpy_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000, cols + , stride, (rows - nblines) * cheight / 2); + dest_far = memcpy_stride(SEG_CTEXT, dest_far, src_far, cols + , stride, (rows - nblines) * cheight / 2); } - outb(0x02, VGAREG_SEQU_ADDRESS); - u8 mmask = inb(VGAREG_SEQU_DATA); - outb(0x0f, VGAREG_SEQU_DATA); // all planes - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024); - outb(mmask, VGAREG_SEQU_DATA); + if (attr < 0) + attr = 0; + memset_stride(SEG_CTEXT, dest_far + 0x2000, attr, cols + , stride, nblines * cheight / 2); + memset_stride(SEG_CTEXT, dest_far, attr, cols + , stride, nblines * cheight / 2); } -void -biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr, u8 page, - u8 dir) +static void +scroll_text(struct vgamode_s *vmode_g, int nblines, int attr + , struct cursorpos ul, struct cursorpos lr) { - // page == 0xFF if current - if (rul > rlr) - return; - if (cul > clr) - return; + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + void *src_far, *dest_far = (void*)SCREEN_MEM_START(nbcols, nbrows, ul.page); + int stride = nbcols * 2; + if (nblines >= 0) { + dest_far += ul.y * stride + ul.x * 2; + src_far = dest_far + nblines * stride; + } else { + // Scroll down + nblines = -nblines; + dest_far += lr.y * stride + ul.x * 2; + src_far = dest_far - nblines * stride; + stride = -stride; + } + int cols = (lr.x - ul.x + 1) * 2; + int rows = lr.y - ul.y + 1; + u16 seg = GET_GLOBAL(vmode_g->sstart); + if (nblines < rows) + dest_far = memcpy_stride(seg, dest_far, src_far, cols, stride + , (rows - nblines)); + if (attr < 0) + attr = 0x07; + attr = (attr << 8) | ' '; + memset16_stride(seg, dest_far, attr, cols, stride, nblines); +} +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)); 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 CTEXT: + case MTEXT: + scroll_text(vmode_g, nblines, attr, ul, lr); + break; 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; - } - } - } + scroll_pl4(vmode_g, nblines, attr, ul, lr); 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; - } - } - } + case CGA: + scroll_cga(vmode_g, nblines, attr, ul, lr); break; - } default: dprintf(1, "Scroll in graphics mode\n"); } } +void +clear_screen(struct vgamode_s *vmode_g) +{ + switch (GET_GLOBAL(vmode_g->memmodel)) { + case CTEXT: + case MTEXT: + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); + break; + case CGA: + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); + break; + default: + // XXX - old code gets/sets/restores sequ register 2 to 0xf - + // but it should always be 0xf anyway. + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024); + } +} + /**************************************************************** * Read/write characters to screen ****************************************************************/ static void -write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, - u8 cheight) +write_gfx_char_pl4(struct vgamode_s *vmode_g + , struct cursorpos cp, struct carattr ca) { + u16 nbcols = GET_BDA(video_cols); + if (cp.x >= nbcols) + return; + + u8 cheight = GET_GLOBAL(vmode_g->cheight); u8 *fdata_g; switch (cheight) { case 14: @@ -282,39 +200,45 @@ write_gfx_char_pl4(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, 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); + u16 addr = cp.x + cp.y * cheight * nbcols; + u16 src = ca.car * cheight; + vgahw_sequ_write(0x02, 0x0f); + vgahw_grdc_write(0x05, 0x02); + if (ca.attr & 0x80) + vgahw_grdc_write(0x03, 0x18); else - outw(0x0003, VGAREG_GRDC_ADDRESS); + vgahw_grdc_write(0x03, 0x00); 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); + vgahw_grdc_write(0x08, mask); GET_FARVAR(SEG_GRAPH, *dest_far); if (GET_GLOBAL(fdata_g[src + i]) & mask) - SET_FARVAR(SEG_GRAPH, *dest_far, attr & 0x0f); + SET_FARVAR(SEG_GRAPH, *dest_far, ca.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); + vgahw_grdc_write(0x08, 0xff); + vgahw_grdc_write(0x05, 0x00); + vgahw_grdc_write(0x03, 0x00); } static void -write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp) +write_gfx_char_cga(struct vgamode_s *vmode_g + , struct cursorpos cp, struct carattr ca) { + u16 nbcols = GET_BDA(video_cols); + if (cp.x >= nbcols) + return; + u8 *fdata_g = vgafont8; - u16 addr = (xcurs * bpp) + ycurs * 320; - u16 src = car * 8; + u8 bpp = GET_GLOBAL(vmode_g->pixbits); + u16 addr = (cp.x * bpp) + cp.y * 320; + u16 src = ca.car * 8; u8 i; for (i = 0; i < 8; i++) { u8 *dest_far = (void*)(addr + (i >> 1) * 80); @@ -323,15 +247,15 @@ write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp) u8 mask = 0x80; if (bpp == 1) { u8 data = 0; - if (attr & 0x80) + if (ca.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); + if (ca.attr & 0x80) + data ^= (ca.attr & 0x01) << (7 - j); else - data |= (attr & 0x01) << (7 - j); + data |= (ca.attr & 0x01) << (7 - j); } mask >>= 1; } @@ -339,15 +263,15 @@ write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp) } else { while (mask > 0) { u8 data = 0; - if (attr & 0x80) + if (ca.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); + if (ca.attr & 0x80) + data ^= (ca.attr & 0x03) << ((3 - j) * 2); else - data |= (attr & 0x03) << ((3 - j) * 2); + data |= (ca.attr & 0x03) << ((3 - j) * 2); } mask >>= 1; } @@ -359,11 +283,17 @@ write_gfx_char_cga(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols, u8 bpp) } static void -write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols) +write_gfx_char_lin(struct vgamode_s *vmode_g + , struct cursorpos cp, struct carattr ca) { + // Get the dimensions + u16 nbcols = GET_BDA(video_cols); + if (cp.x >= nbcols) + return; + u8 *fdata_g = vgafont8; - u16 addr = xcurs * 8 + ycurs * nbcols * 64; - u16 src = car * 8; + u16 addr = cp.x * 8 + cp.y * nbcols * 64; + u16 src = ca.car * 8; u8 i; for (i = 0; i < 8; i++) { u8 *dest_far = (void*)(addr + i * nbcols * 8); @@ -372,137 +302,88 @@ write_gfx_char_lin(u8 car, u8 attr, u8 xcurs, u8 ycurs, u8 nbcols) for (j = 0; j < 8; j++) { u8 data = 0x00; if (GET_GLOBAL(fdata_g[src + i]) & mask) - data = attr; + data = ca.attr; SET_FARVAR(SEG_GRAPH, dest_far[j], data); mask >>= 1; } } } -void -biosfn_write_char_attr(u8 car, u8 page, u8 attr, u16 count) +static void +write_text_char(struct vgamode_s *vmode_g + , struct cursorpos cp, struct carattr ca) { - // 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; - } + // Compute the address + void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page) + + (cp.x + cp.y * nbcols) * 2); - // 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++; + if (ca.use_attr) { + u16 dummy = (ca.attr << 8) | ca.car; + SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u16*)address_far, dummy); + } else { + SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)address_far, ca.car); } } void -biosfn_write_char_only(u8 car, u8 page, u8 attr, u16 count) +vgafb_write_char(struct cursorpos cp, struct carattr ca) { // 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++; + switch (GET_GLOBAL(vmode_g->memmodel)) { + case CTEXT: + case MTEXT: + write_text_char(vmode_g, cp, ca); + break; + case PLANAR4: + case PLANAR1: + write_gfx_char_pl4(vmode_g, cp, ca); + break; + case CGA: + write_gfx_char_cga(vmode_g, cp, ca); + break; + case LINEAR8: + write_gfx_char_lin(vmode_g, cp, ca); + break; } } -void -biosfn_read_char_attr(u8 page, u16 *car) +struct carattr +vgafb_read_char(struct cursorpos cp) { // Get the mode struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); if (!vmode_g) - return; + goto fail; - // Get the cursor pos for the page - u16 cursor = biosfn_get_cursor_pos(page); - u8 xcurs = cursor & 0x00ff; - u8 ycurs = (cursor & 0xff00) >> 8; + if (!(GET_GLOBAL(vmode_g->memmodel) & TEXT)) { + // FIXME gfx mode + dprintf(1, "Read char in graphics mode\n"); + goto fail; + } // 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); + // Compute the address + u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, 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}; + return ca; - *car = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far); - } else { - // FIXME gfx mode - dprintf(1, "Read char in graphics mode\n"); - } +fail: ; + struct carattr ca2 = {0, 0, 0}; + return ca2; } @@ -511,47 +392,47 @@ biosfn_read_char_attr(u8 page, u16 *car) ****************************************************************/ void -biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX) +vgafb_write_pixel(u8 color, u16 x, u16 y) { // 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) + if (GET_GLOBAL(vmode_g->memmodel) & 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); + addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); + mask = 0x80 >> (x & 0x07); + vgahw_grdc_write(0x08, mask); + vgahw_grdc_write(0x05, 0x02); 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); + if (color & 0x80) + vgahw_grdc_write(0x03, 0x18); + SET_FARVAR(SEG_GRAPH, *addr_far, color); + vgahw_grdc_write(0x08, 0xff); + vgahw_grdc_write(0x05, 0x00); + vgahw_grdc_write(0x03, 0x00); break; case CGA: if (GET_GLOBAL(vmode_g->pixbits) == 2) - addr_far = (void*)((CX >> 2) + (DX >> 1) * 80); + addr_far = (void*)((x >> 2) + (y >> 1) * 80); else - addr_far = (void*)((CX >> 3) + (DX >> 1) * 80); - if (DX & 1) + 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) { - attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); - mask = 0x03 << ((3 - (CX & 0x03)) * 2); + attr = (color & 0x03) << ((3 - (x & 0x03)) * 2); + mask = 0x03 << ((3 - (x & 0x03)) * 2); } else { - attr = (AL & 0x01) << (7 - (CX & 0x07)); - mask = 0x01 << (7 - (CX & 0x07)); + attr = (color & 0x01) << (7 - (x & 0x07)); + mask = 0x01 << (7 - (x & 0x07)); } - if (AL & 0x80) { + if (color & 0x80) { data ^= attr; } else { data &= ~mask; @@ -560,52 +441,52 @@ biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX) 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); + addr_far = (void*)(x + y * (GET_BDA(video_cols) * 8)); + SET_FARVAR(SEG_GRAPH, *addr_far, color); break; } } -void -biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX) +u8 +vgafb_read_pixel(u16 x, u16 y) { // 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; + 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: - addr_far = (void*)(CX / 8 + DX * GET_BDA(video_cols)); - mask = 0x80 >> (CX & 0x07); + addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); + mask = 0x80 >> (x & 0x07); attr = 0x00; for (i = 0; i < 4; i++) { - outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS); + vgahw_grdc_write(0x04, i); 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 = (void*)((x >> 2) + (y >> 1) * 80); + if (y & 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; + attr = (data >> ((3 - (x & 0x03)) * 2)) & 0x03; else - attr = (data >> (7 - (CX & 0x07))) & 0x01; + attr = (data >> (7 - (x & 0x07))) & 0x01; break; case LINEAR8: - addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8)); + addr_far = (void*)(x + y * (GET_BDA(video_cols) * 8)); attr = GET_FARVAR(SEG_GRAPH, *addr_far); break; } - *AX = (*AX & 0xff00) | attr; + return attr; }