changed the scroll repeat window to a power of two (25 -> 32 lines)
[3sys] / sys1 / kern / src / vga.c
1 #include <string.h>
2 #include "vga.h"
3 #include "asmutil.h"
4
5 #define CRTC_ADDR_PORT  0x3d4
6 #define CRTC_DATA_PORT  0x3d5
7
8 /* CRTC registers */
9 #define CRTC_START_H    0x0c
10 #define CRTC_START_L    0x0d
11 #define CRTC_CURPOS_H   0x0e
12 #define CRTC_CURPOS_L   0x0f
13
14 static void crtc_write(int reg, unsigned char val);
15
16 static uint16_t attr = 0x0700;
17 static int yoffs;
18
19 void vga_setcolor(int fg, int bg)
20 {
21         attr = ((bg & 7) << 12) | ((fg & 0xf) << 8);
22 }
23
24 void vga_setcursor(int x, int y)
25 {
26         int loc = (y + yoffs) * 80 + x;
27         crtc_write(CRTC_CURPOS_H, loc >> 8);
28         crtc_write(CRTC_CURPOS_L, loc);
29 }
30
31 void vga_scroll(int s)
32 {
33         yoffs = s & 0x1f;
34         s = yoffs * 80;
35         crtc_write(CRTC_START_H, s >> 8);
36         crtc_write(CRTC_START_L, s);
37 }
38
39 void vga_reset(void)
40 {
41         vga_setcolor(VGA_WHITE, VGA_BLACK);
42         vga_scroll(0);
43         vga_setcursor(0, 0);
44         memset((void*)0xb8000, 0, 80 * 25 * 2);
45 }
46
47 void vga_clearline(int row)
48 {
49         uint16_t *ptr;
50
51         row += yoffs;
52
53         ptr = (uint16_t*)0xb8000 + row * 80;
54         memset16(ptr, attr, 80);
55
56         if(row - 32 >= 0) {
57                 /* write a copy to wrap-around future scrolling */
58                 ptr -= 80 * 32;
59                 memset16(ptr, attr, 80);
60         }
61 }
62
63 void vga_drawchar(int x, int y, int c)
64 {
65         uint16_t *ptr, val = (c & 0xff) | attr;
66
67         y += yoffs;
68
69         ptr = (uint16_t*)0xb8000 + y * 80 + x;
70         *ptr = val;
71
72         if(y - 32 >= 0) {
73                 /* write a copy to wrap-around future scrolling */
74                 ptr -= 80 * 32;
75                 *ptr = val;
76         }
77 }
78
79 static void crtc_write(int reg, unsigned char val)
80 {
81         outp(CRTC_ADDR_PORT, reg);
82         outp(CRTC_DATA_PORT, val);
83 }