diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2014-03-20 21:16:28 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2014-04-11 11:26:22 -0400 |
commit | 7fd2af64225098a7819743fbe66f413d51929a69 (patch) | |
tree | 49cab281968a013b1b3e537a5919e4e8c8d50810 /vgasrc/vgafb.c | |
parent | efbf4d69038d6d5de05b80e0fffc7759b9e022fe (diff) | |
download | seabios-7fd2af64225098a7819743fbe66f413d51929a69.tar.gz |
vgabios: Split vgafb_scroll() into separate move and clear functions.
Rewrite the low-level scroll code so that it is implemented using two
basic operations: move text and clear text. This simplifies the
low-level code as it no longer needs to handle up scrolling vs down
scrolling. Determining the direction of the scroll is now done in the
higher level (vgabios.c) code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'vgasrc/vgafb.c')
-rw-r--r-- | vgasrc/vgafb.c | 231 |
1 files changed, 122 insertions, 109 deletions
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 7c2570fc..5a2c4c8f 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -17,12 +17,16 @@ * Screen scrolling ****************************************************************/ -static inline void * -memcpy_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines) +static inline void +memmove_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines) { + if (src < dst) { + dst += stride * (lines - 1); + src += stride * (lines - 1); + stride = -stride; + } for (; lines; lines--, dst+=stride, src+=stride) memcpy_far(seg, dst, seg, src, copylen); - return dst; } static inline void @@ -40,163 +44,172 @@ memset16_stride(u16 seg, void *dst, u16 val, int setlen, int stride, int lines) } static void -scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) +planar_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct cursorpos src, struct cursorpos movesize) { if (!CONFIG_VGA_STDVGA_PORTS) return; int cheight = GET_BDA(char_height); int cwidth = 1; int stride = GET_BDA(video_cols) * cwidth; - void *src_far, *dest_far; - if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x * cwidth); - src_far = dest_far + nblines * cheight * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x * cwidth); - src_far = dest_far - nblines * cheight * stride; - stride = -stride; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + void *src_far = (void*)(src.y * cheight * stride + src.x * cwidth); + int i; + for (i=0; i<4; i++) { + stdvga_planar4_plane(i); + memmove_stride(SEG_GRAPH, dest_far, src_far + , movesize.x * cwidth, stride, movesize.y * cheight); } - if (attr < 0) - attr = 0; - int cols = lr.x - ul.x + 1; - int rows = lr.y - ul.y + 1; + stdvga_planar4_plane(-1); +} + +static void +planar_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct carattr ca, struct cursorpos clearsize) +{ + if (!CONFIG_VGA_STDVGA_PORTS) + return; + int cheight = GET_BDA(char_height); + int cwidth = 1; + int stride = GET_BDA(video_cols) * cwidth; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); int i; for (i=0; i<4; i++) { stdvga_planar4_plane(i); - void *dest = dest_far; - if (nblines < rows) - dest = memcpy_stride(SEG_GRAPH, dest, src_far, cols * cwidth - , stride, (rows - nblines) * cheight); - u8 pixels = (attr & (1<<i)) ? 0xff : 0x00; - memset_stride(SEG_GRAPH, dest, pixels, cols * cwidth - , stride, nblines * cheight); + u8 attr = (ca.attr & (1<<i)) ? 0xff : 0x00; + memset_stride(SEG_GRAPH, dest_far, attr + , clearsize.x * cwidth, stride, clearsize.y * cheight); } stdvga_planar4_plane(-1); } static void -scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) +cga_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct cursorpos src, struct cursorpos movesize) { int cheight = GET_BDA(char_height) / 2; int cwidth = GET_GLOBAL(vmode_g->depth); int stride = GET_BDA(video_cols) * cwidth; - void *src_far, *dest_far; - if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x * cwidth); - src_far = dest_far + nblines * cheight * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x * cwidth); - src_far = dest_far - nblines * cheight * stride; - stride = -stride; - } - if (attr < 0) - attr = 0; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + void *src_far = (void*)(src.y * cheight * stride + src.x * cwidth); + memmove_stride(SEG_CTEXT, dest_far, src_far + , movesize.x * cwidth, stride, movesize.y * cheight); + memmove_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000 + , movesize.x * cwidth, stride, movesize.y * cheight); +} + +static void +cga_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct carattr ca, struct cursorpos clearsize) +{ + int cheight = GET_BDA(char_height) / 2; + int cwidth = GET_GLOBAL(vmode_g->depth); + int stride = GET_BDA(video_cols) * cwidth; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + u8 attr = ca.attr; if (cwidth == 1) attr = (attr&1) | ((attr&1)<<1); attr &= 3; attr |= (attr<<2) | (attr<<4) | (attr<<6); - int cols = lr.x - ul.x + 1; - int rows = lr.y - ul.y + 1; - if (nblines < rows) { - memcpy_stride(SEG_CTEXT, dest_far+0x2000, src_far+0x2000, cols * cwidth - , stride, (rows - nblines) * cheight); - dest_far = memcpy_stride(SEG_CTEXT, dest_far, src_far, cols * cwidth - , stride, (rows - nblines) * cheight); - } - memset_stride(SEG_CTEXT, dest_far + 0x2000, attr, cols * cwidth - , stride, nblines * cheight); - memset_stride(SEG_CTEXT, dest_far, attr, cols * cwidth - , stride, nblines * cheight); + memset_stride(SEG_CTEXT, dest_far, attr + , clearsize.x * cwidth, stride, clearsize.y * cheight); + memset_stride(SEG_CTEXT, dest_far + 0x2000, attr + , clearsize.x * cwidth, stride, clearsize.y * cheight); } static void -scroll_lin(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) +packed_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct cursorpos src, struct cursorpos movesize) { int cheight = GET_BDA(char_height); int cwidth = 8; int stride = GET_BDA(video_cols) * cwidth; - void *src_far, *dest_far; - if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x * cwidth); - src_far = dest_far + nblines * cheight * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x * cwidth); - src_far = dest_far - nblines * cheight * stride; - stride = -stride; - } - if (attr < 0) - attr = 0; - int cols = lr.x - ul.x + 1; - int rows = lr.y - ul.y + 1; - if (nblines < rows) - dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols * cwidth - , stride, (rows - nblines) * cheight); - memset_stride(SEG_GRAPH, dest_far, attr, cols * cwidth - , stride, nblines * cheight); + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + void *src_far = (void*)(src.y * cheight * stride + src.x * cwidth); + memmove_stride(SEG_GRAPH, dest_far, src_far + , movesize.x * cwidth, stride, movesize.y * cheight); } static void -scroll_text(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) +packed_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct carattr ca, struct cursorpos clearsize) +{ + int cheight = GET_BDA(char_height); + int cwidth = 8; + int stride = GET_BDA(video_cols) * cwidth; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + memset_stride(SEG_GRAPH, dest_far, ca.attr + , clearsize.x * cwidth, stride, clearsize.y * cheight); +} + +static void +text_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct cursorpos src, struct cursorpos movesize) { int cheight = 1; int cwidth = 2; int stride = GET_BDA(video_cols) * cwidth; - void *src_far, *dest_far = (void*)(GET_BDA(video_pagesize) * ul.page); - if (nblines >= 0) { - dest_far += ul.y * cheight * stride + ul.x * cwidth; - src_far = dest_far + nblines * cheight * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far += lr.y * cheight * stride + ul.x * cwidth; - src_far = dest_far - nblines * cheight * stride; - stride = -stride; - } - if (attr < 0) - attr = 0x07; - attr = (attr << 8) | ' '; - int cols = lr.x - ul.x + 1; - int rows = lr.y - ul.y + 1; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + void *src_far = (void*)(src.y * cheight * stride + src.x * cwidth); + u32 pageoffset = GET_BDA(video_pagesize) * dest.page; + u16 seg = GET_GLOBAL(vmode_g->sstart); + memmove_stride(seg, dest_far + pageoffset, src_far + pageoffset + , movesize.x * cwidth, stride, movesize.y * cheight); +} + +static void +text_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct carattr ca, struct cursorpos clearsize) +{ + int cheight = 1; + int cwidth = 2; + int stride = GET_BDA(video_cols) * cwidth; + void *dest_far = (void*)(dest.y * cheight * stride + dest.x * cwidth); + u16 attr = ((ca.use_attr ? ca.attr : 0x07) << 8) | ca.car; + u32 pageoffset = GET_BDA(video_pagesize) * dest.page; u16 seg = GET_GLOBAL(vmode_g->sstart); - if (nblines < rows) - dest_far = memcpy_stride(seg, dest_far, src_far, cols * cwidth - , stride, (rows - nblines) * cheight); - memset16_stride(seg, dest_far, attr, cols * cwidth - , stride, nblines * cheight); + memset16_stride(seg, dest_far + pageoffset, attr + , clearsize.x * cwidth, stride, clearsize.y * cheight); } void -vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr) +vgafb_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct cursorpos src, struct cursorpos movesize) { - // Get the mode - struct vgamode_s *vmode_g = get_current_mode(); - if (!vmode_g) - return; + switch (GET_GLOBAL(vmode_g->memmodel)) { + case MM_TEXT: + text_move_chars(vmode_g, dest, src, movesize); + break; + case MM_PLANAR: + planar_move_chars(vmode_g, dest, src, movesize); + break; + case MM_CGA: + cga_move_chars(vmode_g, dest, src, movesize); + break; + case MM_PACKED: + packed_move_chars(vmode_g, dest, src, movesize); + break; + default: + break; + } +} - // FIXME gfx mode not complete +void +vgafb_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest + , struct carattr ca, struct cursorpos movesize) +{ switch (GET_GLOBAL(vmode_g->memmodel)) { case MM_TEXT: - scroll_text(vmode_g, nblines, attr, ul, lr); + text_clear_chars(vmode_g, dest, ca, movesize); break; case MM_PLANAR: - scroll_pl4(vmode_g, nblines, attr, ul, lr); + planar_clear_chars(vmode_g, dest, ca, movesize); break; case MM_CGA: - scroll_cga(vmode_g, nblines, attr, ul, lr); + cga_clear_chars(vmode_g, dest, ca, movesize); break; - case MM_DIRECT: case MM_PACKED: - scroll_lin(vmode_g, nblines, attr, ul, lr); + packed_clear_chars(vmode_g, dest, ca, movesize); break; default: break; |