diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-05-31 00:46:47 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-05-31 00:46:47 -0400 |
commit | 217f2bc7d52267dd548655891651f87ed7942889 (patch) | |
tree | 999cae32c418f6efb7781c4eacf42fbc4c1dfc6f /vgasrc | |
parent | eaec3c2265306fa80b4d0ba94ed9f24e26324ca2 (diff) | |
download | seabios-217f2bc7d52267dd548655891651f87ed7942889.tar.gz |
VGA: Breakup biosfn_scroll.
Rename biosfn_scroll to vgafb_scroll.
Break function up into per-mode scroll function.
Pass row/col params in a 'struct cursorpos'.
Encode direction as sign in nblines.
Move parameter checking to callers.
Add enhancement to 'attr' for using mode specific default attribute.
Also, make get_cursor_pos local to vga.c.
Diffstat (limited to 'vgasrc')
-rw-r--r-- | vgasrc/vga.c | 45 | ||||
-rw-r--r-- | vgasrc/vgafb.c | 332 | ||||
-rw-r--r-- | vgasrc/vgatables.h | 5 |
3 files changed, 217 insertions, 165 deletions
diff --git a/vgasrc/vga.c b/vgasrc/vga.c index 06b3993d..180fc991 100644 --- a/vgasrc/vga.c +++ b/vgasrc/vga.c @@ -30,7 +30,7 @@ #define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val)) -inline void +static inline void call16_vgaint(u32 eax, u32 ebx) { asm volatile( @@ -117,7 +117,7 @@ set_cursor_pos(struct cursorpos cp) vgahw_set_cursor_pos(address); } -struct cursorpos +static struct cursorpos get_cursor_pos(u8 page) { if (page == 0xff) @@ -189,17 +189,9 @@ check_scroll(struct cursorpos cp) } // Do we need to scroll ? if (cp.y == nbrows) { - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return cp; - - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, cp.page, - SCROLL_UP); - else - biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, cp.page, - SCROLL_UP); + struct cursorpos ul = {0, 0, cp.page}; + struct cursorpos lr = {nbcols-1, nbrows-1, cp.page}; + vgafb_scroll(1, -1, ul, lr); cp.y--; } @@ -494,17 +486,36 @@ handle_1005(struct bregs *regs) } static void +verify_scroll(struct bregs *regs, int dir) +{ + u8 page = GET_BDA(video_page); + struct cursorpos ul = {regs->cl, regs->ch, page}; + struct cursorpos lr = {regs->dl, regs->dh, page}; + + if (ul.x > lr.x || ul.y > lr.y) + return; + + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + + if (lr.y >= nbrows) + lr.y = nbrows - 1; + if (lr.x >= nbcols) + lr.x = nbcols - 1; + + vgafb_scroll(dir * regs->al, regs->bh, ul, lr); +} + +static void handle_1006(struct bregs *regs) { - biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl - , 0xFF, SCROLL_UP); + verify_scroll(regs, 1); } static void handle_1007(struct bregs *regs) { - biosfn_scroll(regs->al, regs->bh, regs->ch, regs->cl, regs->dh, regs->dl - , 0xFF, SCROLL_DOWN); + verify_scroll(regs, -1); } static void diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index f1b46d49..6790570d 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -53,6 +53,58 @@ vgamem_fill_pl4(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, } static void +scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr + , struct cursorpos ul, struct cursorpos lr) +{ + if (attr < 0) + attr = 0; + u8 dir = SCROLL_UP; + if (nblines < 0) { + nblines = -nblines; + dir = SCROLL_DOWN; + } + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + if (nblines > nbrows) + nblines = 0; + u8 cols = lr.x - ul.x + 1; + + struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); + u8 cheight = GET_GLOBAL(vparam_g->cheight); + if (nblines == 0 && ul.y == 0 && ul.x == 0 && lr.y == nbrows - 1 + && lr.x == nbcols - 1) { + outw(0x0205, VGAREG_GRDC_ADDRESS); + memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr, + nbrows * nbcols * cheight); + outw(0x0005, VGAREG_GRDC_ADDRESS); + return; + } + if (dir == SCROLL_UP) { + u16 i; + for (i = ul.y; i <= lr.y; i++) + if ((i + nblines > lr.y) || (nblines == 0)) + vgamem_fill_pl4(ul.x, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_pl4(ul.x, i + nblines, i, cols, + nbcols, cheight); + return; + } + u16 i; + for (i = lr.y; i >= ul.y; i--) { + if ((i < ul.y + nblines) || (nblines == 0)) + vgamem_fill_pl4(ul.x, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_pl4(ul.x, i, i - nblines, cols, + nbcols, cheight); + if (i > lr.y) + break; + } +} + +static void vgamem_copy_cga(u8 xstart, u8 ysrc, u8 ydest, u8 cols, u8 nbcols, u8 cheight) { @@ -83,180 +135,170 @@ vgamem_fill_cga(u8 xstart, u8 ystart, u8 cols, u8 nbcols, u8 cheight, memset_far(SEG_CTEXT, (void*)(dest + (i >> 1) * nbcols), attr, cols); } -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->memmodel) & TEXT) { - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); + if (attr < 0) + attr = 0; + u8 dir = SCROLL_UP; + if (nblines < 0) { + nblines = -nblines; + dir = SCROLL_DOWN; + } + // Get the dimensions + u16 nbrows = GET_BDA(video_rows) + 1; + u16 nbcols = GET_BDA(video_cols); + if (nblines > nbrows) + nblines = 0; + u8 cols = lr.x - ul.x + 1; + + struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); + u8 cheight = GET_GLOBAL(vparam_g->cheight); + u8 bpp = GET_GLOBAL(vmode_g->pixbits); + if (nblines == 0 && ul.y == 0 && ul.x == 0 && lr.y == nbrows - 1 + && lr.x == nbcols - 1) { + memset_far(GET_GLOBAL(vmode_g->sstart), 0, attr, + nbrows * nbcols * cheight * bpp); return; } - if (GET_GLOBAL(vmode_g->svgamode) < 0x0d) { - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); + if (bpp == 2) { + ul.x <<= 1; + cols <<= 1; + nbcols <<= 1; + } + // if Scroll up + if (dir == SCROLL_UP) { + u16 i; + for (i = ul.y; i <= lr.y; i++) + if ((i + nblines > lr.y) || (nblines == 0)) + vgamem_fill_cga(ul.x, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_cga(ul.x, i + nblines, i, cols, + nbcols, cheight); return; } - 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); + u16 i; + for (i = lr.y; i >= ul.y; i--) { + if ((i < ul.y + nblines) || (nblines == 0)) + vgamem_fill_cga(ul.x, i, cols, nbcols, cheight, + attr); + else + vgamem_copy_cga(ul.x, i, i - nblines, cols, + nbcols, cheight); + if (i > lr.y) + break; + } } -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; - - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - + if (attr < 0) + attr = 0x07; + u8 dir = SCROLL_UP; + if (nblines < 0) { + nblines = -nblines; + dir = SCROLL_DOWN; + } // 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; + u8 cols = lr.x - ul.x + 1; - if (GET_GLOBAL(vmode_g->memmodel) & 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; - } - } - } + // Compute the address + void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, ul.page)); + dprintf(3, "Scroll, address %p (%d %d %02x)\n" + , address_far, nbrows, nbcols, ul.page); + + if (nblines == 0 && ul.y == 0 && ul.x == 0 && lr.y == nbrows - 1 + && lr.x == nbcols - 1) { + memset16_far(GET_GLOBAL(vmode_g->sstart), address_far + , (u16)attr * 0x100 + ' ', nbrows * nbcols * 2); return; } + if (dir == SCROLL_UP) { + u16 i; + for (i = ul.y; i <= lr.y; i++) + if ((i + nblines > lr.y) || (nblines == 0)) + memset16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + ul.x) * 2 + , (u16)attr * 0x100 + ' ', cols * 2); + else + memcpy16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + ul.x) * 2 + , GET_GLOBAL(vmode_g->sstart) + , (void*)(((i + nblines) * nbcols + ul.x) * 2) + , cols * 2); + return; + } + + u16 i; + for (i = lr.y; i >= ul.y; i--) { + if ((i < ul.y + nblines) || (nblines == 0)) + memset16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + ul.x) * 2 + , (u16)attr * 0x100 + ' ', cols * 2); + else + memcpy16_far(GET_GLOBAL(vmode_g->sstart) + , address_far + (i * nbcols + ul.x) * 2 + , GET_GLOBAL(vmode_g->sstart) + , (void*)(((i - nblines) * nbcols + ul.x) * 2) + , cols * 2); + if (i > lr.y) + break; + } +} + +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; // 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) +{ + if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); + return; + } + if (GET_GLOBAL(vmode_g->svgamode) < 0x0d) { + memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); + return; + } + 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); +} + /**************************************************************** * Read/write characters to screen diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h index 60794350..aa21108e 100644 --- a/vgasrc/vgatables.h +++ b/vgasrc/vgatables.h @@ -162,12 +162,11 @@ struct carattr { struct cursorpos { u8 x, y, page; }; -struct cursorpos get_cursor_pos(u8 page); // vgafb.c void clear_screen(struct vgamode_s *vmode_g); -void biosfn_scroll(u8 nblines, u8 attr, u8 rul, u8 cul, u8 rlr, u8 clr - , u8 page, u8 dir); +void vgafb_scroll(int nblines, int attr + , struct cursorpos ul, struct cursorpos lr); void vgafb_write_char(struct cursorpos cp, struct carattr ca); struct carattr vgafb_read_char(struct cursorpos cp); void biosfn_write_pixel(u8 BH, u8 AL, u16 CX, u16 DX); |