correct window size in banked vbe, and added doublebuffered test
[vidsys] / drv_vga.c
1 #include <string.h>
2 #include <conio.h>
3 #include <i86.h>
4 #include "vidsys.h"
5 #include "drv.h"
6 #include "vga.h"
7
8 static int init(void);
9 static void cleanup(void);
10 static int setmode(int mode);
11 static int curmode(void);
12
13 static void setpal4(int idx, int count, const struct vid_color *col);
14 static void getpal4(int idx, int count, struct vid_color *col);
15 static void clear4(uint32_t color);
16 static void blitfb4(void *fb, int pitch);
17 static void fill4(int x, int y, int w, int h, uint32_t color);
18
19 static void clear8(uint32_t color);
20 static void blitfb8(void *fb, int pitch);
21 static void fill8(int x, int y, int w, int h, uint32_t color);
22
23
24 static struct vid_driver drv;
25 static struct vid_drvops drvops = {init, cleanup, setmode, curmode};
26 static struct vid_modeinfo modes[] = {
27         {3, 80, 25, 4},
28         {0x12, 640, 480, 4},
29         {0x13, 320, 200, 8}
30 };
31
32 static struct vid_gfxops gfxops_mode12h = {
33         0, 0, setpal4, getpal4, vid_vsync, clear4, blitfb4, 0, fill4 };
34 static struct vid_gfxops gfxops_mode13h = {
35         0, 0, vga_setpal, vga_getpal, vid_vsync, clear8, blitfb8, 0, fill8 };
36
37 void vid_register_vga(void)
38 {
39         int i;
40
41         drv.name = "vga";
42         drv.prio = 1;
43         drv.ops = &drvops;
44         drv.modes = modes;
45         drv.num_modes = sizeof modes / sizeof *modes;
46
47         for(i=0; i<drv.num_modes; i++) {
48                 modes[i].drv = &drv;
49                 modes[i].vmem_addr = 0xa0000;
50
51                 switch(modes[i].modeno) {
52                 case 0x3:
53                         modes[i].vmem_addr = 0xb8000;
54                         break;
55                                 
56                 case 0x13:
57                         modes[i].ops = gfxops_mode13h;
58                         break;
59
60                 case 0x12:
61                         modes[i].ops = gfxops_mode12h;
62                         break;
63                 }
64         }
65
66         vid_drvlist[vid_numdrv++] = &drv;
67 }
68
69 void vid_vsync(void)
70 {
71         while(inp(VGA_STAT1_PORT) & 8);
72         while((inp(VGA_STAT1_PORT) & 8) == 0);
73 }
74
75 void vga_setpal(int idx, int count, const struct vid_color *col)
76 {
77         int i;
78         outp(VGA_DAC_WADDR_PORT, idx);
79         for(i=0; i<count; i++) {
80                 outp(VGA_DAC_DATA_PORT, col->r >> 2);
81                 outp(VGA_DAC_DATA_PORT, col->g >> 2);
82                 outp(VGA_DAC_DATA_PORT, col->b >> 2);
83                 col++;
84         }
85 }
86
87 void vga_getpal(int idx, int count, struct vid_color *col)
88 {
89         int i;
90         outp(VGA_DAC_RADDR_PORT, idx);
91         for(i=0; i<count; i++) {
92                 col->r = inp(VGA_DAC_DATA_PORT) << 2;
93                 col->g = inp(VGA_DAC_DATA_PORT) << 2;
94                 col->b = inp(VGA_DAC_DATA_PORT) << 2;
95                 col++;
96         }
97 }
98
99
100 static int init(void)
101 {
102         return 0;
103 }
104
105 static void cleanup(void)
106 {
107 }
108
109 static int setmode(int mode)
110 {
111         union REGS regs = {0};
112         regs.w.ax = mode;
113         int386(0x10, &regs, &regs);
114         return 0;
115 }
116
117 static int curmode(void)
118 {
119         union REGS regs = {0};
120         regs.w.ax = 0xf00;
121         int386(0x10, &regs, &regs);
122         return regs.x.eax & 0xff;
123 }
124
125 static void setpal4(int idx, int count, const struct vid_color *col)
126 {
127 }
128
129 static void getpal4(int idx, int count, struct vid_color *col)
130 {
131 }
132
133 static void clear4(uint32_t color)
134 {
135 }
136
137 static void blitfb4(void *fb, int pitch)
138 {
139 }
140
141 static void fill4(int x, int y, int w, int h, uint32_t color)
142 {
143 }
144
145 static void clear8(uint32_t color)
146 {
147         memset((void*)0xa0000, color, 64000);
148 }
149
150 static void blitfb8(void *fb, int pitch)
151 {
152         int i;
153         unsigned char *src = fb;
154         unsigned char *dest = (unsigned char*)0xa0000;
155         for(i=0; i<200; i++) {
156                 memcpy(dest, src, 320);
157                 dest += 320;
158                 src += pitch;
159         }
160 }
161
162 static void fill8(int x, int y, int w, int h, uint32_t color)
163 {
164         int i;
165         unsigned char *fbptr = (unsigned char*)0xa0000;
166
167         fbptr += y * 320 + x;
168         for(i=0; i<h; i++) {
169                 memset(fbptr, color, w);
170                 fbptr += 320;
171         }
172 }