infinite hardware scrolling
[3sys] / sys1 / kern / src / vga.c
index 2967299..ae7c049 100644 (file)
@@ -28,25 +28,52 @@ void vga_setcursor(int x, int y)
        crtc_write(CRTC_CURPOS_L, loc);
 }
 
-void vga_setstart(int start)
+void vga_scroll(int s)
 {
-       yoffs = start;
-       crtc_write(CRTC_START_H, start >> 8);
-       crtc_write(CRTC_START_L, start);
+       yoffs = s % 25;
+       s = yoffs * 80;
+       crtc_write(CRTC_START_H, s >> 8);
+       crtc_write(CRTC_START_L, s);
 }
 
 void vga_reset(void)
 {
        vga_setcolor(VGA_WHITE, VGA_BLACK);
-       vga_setstart(0);
+       vga_scroll(0);
        vga_setcursor(0, 0);
        memset((void*)0xb8000, 0, 80 * 25 * 2);
 }
 
+void vga_clearline(int row)
+{
+       uint16_t *ptr;
+
+       row += yoffs;
+
+       ptr = (uint16_t*)0xb8000 + row * 80;
+       memset16(ptr, attr, 80);
+
+       if(row - 25 >= 0) {
+               /* write a copy to wrap-around future scrolling */
+               ptr -= 80 * 25;
+               memset16(ptr, attr, 80);
+       }
+}
+
 void vga_drawchar(int x, int y, int c)
 {
-       uint16_t *ptr = (uint16_t*)0xb8000 + (y + yoffs) * 80 + x;
-       *ptr = (c & 0xff) | attr;
+       uint16_t *ptr, val = (c & 0xff) | attr;
+
+       y += yoffs;
+
+       ptr = (uint16_t*)0xb8000 + y * 80 + x;
+       *ptr = val;
+
+       if(y - 25 >= 0) {
+               /* write a copy to wrap-around future scrolling */
+               ptr -= 80 * 25;
+               *ptr = val;
+       }
 }
 
 static void crtc_write(int reg, unsigned char val)