FreeBASIC  0.91.0
gfx_driver_vga.c
Go to the documentation of this file.
1 /* VGA gfx driver */
2 
3 #include "../fb_gfx.h"
4 #include "fb_gfx_dos.h"
5 #include <pc.h>
6 #include <go32.h>
7 
8 static int driver_init(char *title, int w, int h, int depth, int refresh_rate, int flags);
9 static void driver_update(void);
10 static void end_of_driver_update(void);
11 static int *driver_fetch_modes(int depth, int *size);
12 
14 {
15  "VGA", /* char *name; */
16  driver_init, /* int (*init)(char *title, int w, int h, int depth, int refresh_rate, int flags); */
17  fb_dos_exit, /* void (*exit)(void); */
18  fb_dos_lock, /* void (*lock)(void); */
19  fb_dos_unlock, /* void (*unlock)(void); */
20  fb_dos_set_palette, /* void (*set_palette)(int index, int r, int g, int b); */
21  fb_dos_vga_wait_vsync, /* void (*wait_vsync)(void); */
22  fb_dos_get_mouse, /* int (*get_mouse)(int *x, int *y, int *z, int *buttons, int *clip); */
23  fb_dos_set_mouse, /* void (*set_mouse)(int x, int y, int cursor, int clip); */
24  fb_dos_set_window_title, /* void (*set_window_title)(char *title); */
25  NULL, /* int (*set_window_pos)(int x, int y); */
26  driver_fetch_modes, /* int *(*fetch_modes)(int depth, int *size); */
27  NULL, /* void (*flip)(void); */
28  NULL /* void (*poll_events)(void); */
29 };
30 
31 static int modes[] = {
32  SCREENLIST(320, 200),
33  SCREENLIST(320, 100),
34  SCREENLIST(256, 256),
35  SCREENLIST(160, 120),
36  SCREENLIST(80, 80)
37 };
38 
39 static int driver_init(char *title, int w, int h, int depth_arg, int refresh_rate, int flags)
40 {
41  int depth = depth_arg;
42  int c;
43 
44  fb_dos_detect();
45 
46  if (flags & DRIVER_OPENGL)
47  return -1;
48 
49  if (depth != 8) return -1;
50 
51  fb_dos.regs.x.ax = 0x13;
52 
53  if ((w == 320) && (h == 200)) {
54  __dpmi_int(0x10, &fb_dos.regs);
55 
56  refresh_rate = 70;
57  } else if ((w == 320) && (h == 100)) {
58  __dpmi_int(0x10, &fb_dos.regs);
59 
60  outportb(0x3D4, 9);
61  outportb(0x3D5, inportb(0x3D5) | 0x80);
62 
63  refresh_rate = 70;
64  } else if ((w == 256) && (h == 256)) {
65  __dpmi_int(0x10, &fb_dos.regs);
66 
67  outportb(0x3D4, 0x11);
68  c = inportb(0x3D5) & 0x7F;
69  outportb(0x3D4, (c << 8) | 0x11);
70  outportb(0x3D5, c);
71 
72  outportb(0x3C2, 0xE3);
73  outportw(0x3D4, 0x5F00);
74  outportw(0x3D4, 0x3F01);
75  outportw(0x3D4, 0x4002);
76  outportw(0x3D4, 0x8203);
77  outportw(0x3D4, 0x4A04);
78  outportw(0x3D4, 0x9A05);
79  outportw(0x3D4, 0x2306);
80  outportw(0x3D4, 0xB207);
81  outportw(0x3D4, 0x0008);
82  outportw(0x3D4, 0x6109);
83  outportw(0x3D4, 0x0A10);
84  outportw(0x3D4, 0xAC11);
85  outportw(0x3D4, 0xFF12);
86  outportw(0x3D4, 0x2013);
87  outportw(0x3D4, 0x4014);
88  outportw(0x3D4, 0x0715);
89  outportw(0x3D4, 0x1A16);
90  outportw(0x3D4, 0xA317);
91  outportw(0x3C4, 0x0101);
92  outportw(0x3C4, 0x0E04);
93  outportw(0x3CE, 0x4005);
94  outportw(0x3CE, 0x0506);
95 
96  inportb(0x3DA);
97  outportb(0x3C0, 0x30);
98  outportb(0x3C0, 0x41);
99 
100  inportb(0x3DA);
101  outportb(0x3C0, 0x33);
102  outportb(0x3C0, 0x00);
103 
104  outportb(0x3C6, 0xFF);
105 
106  refresh_rate = 70;
107  } else if ((w == 160) && (h == 120)) {
108  fb_dos.regs.x.ax = 0x0D;
109  __dpmi_int(0x10, &fb_dos.regs);
110 
111  outportb(0x3D4, 0x11);
112  outportb(0x3D5, inportb(0x3D5)&0x7F);
113  outportb(0x3D4, 0x04);
114  outportb(0x3D5, inportb(0x3D5)+1);
115  outportb(0x3D4, 0x11);
116  outportb(0x3D5, inportb(0x3D5)|0x80);
117 
118  outportb(0x3C2, (inportb(0x3CC)&~0xC0)|0x80);
119 
120  outportb(0x3D4, 0x11);
121  outportb(0x3D5, inportb(0x3D5)&0x7F);
122 
123  outportb(0x3D4, 0x06);
124  outportb(0x3D5, 0x0B);
125 
126  outportb(0x3D4, 0x07);
127  outportb(0x3D5, 0x3E);
128 
129  outportb(0x3D4, 0x10);
130  outportb(0x3D5, 0xEA);
131 
132  outportb(0x3D4, 0x11);
133  outportb(0x3D5, 0x8C);
134 
135  outportb(0x3D4, 0x12);
136  outportb(0x3D5, 0xDF);
137 
138  outportb(0x3D4, 0x15);
139  outportb(0x3D5, 0xE7);
140 
141  outportb(0x3D4, 0x16);
142  outportb(0x3D5, 0x04);
143 
144  outportb(0x3D4, 0x11);
145  outportb(0x3D5, inportb(0x3D5)|0x80);
146 
147  outportb(0x3CE, 0x05);
148  outportb(0x3CF, (inportb(0x3CF)&0x60)|0x40);
149 
150  inportb(0x3DA);
151  outportb(0x3C0, 0x30);
152  outportb(0x3C0, inportb(0x3C1)|0x40);
153 
154  for (c=0; c<16; c++) {
155  outportb(0x3C0, c);
156  outportb(0x3C0, c);
157  }
158  outportb(0x3C0, 0x20);
159 
160  outportb(0x3C8, 0x00);
161 
162  outportb(0x3C4, 0x04);
163  outportb(0x3C5, (inportb(0x3C5)&0xF7)|8);
164  outportb(0x3D4, 0x14);
165  outportb(0x3D5, (inportb(0x3D5)&~0x40)|64);
166  outportb(0x3D4, 0x017);
167  outportb(0x3D5, (inportb(0x3D5)&~0x40)|64);
168 
169  outportb(0x3D4, 0x09);
170  outportb(0x3D5, (inportb(0x3D5)&0x60)|3);
171 
172  refresh_rate = 70;
173  } else if ((w == 80) && (h == 80)) {
174  __dpmi_int(0x10, &fb_dos.regs);
175 
176  outportw(0x3C4, 0x0604);
177  outportw(0x3C4, 0x0F02);
178 
179  outportw(0x3D4, 0x0014);
180  outportw(0x3D4, 0xE317);
181  outportw(0x3D4, 0xE317);
182  outportw(0x3D4, 0x0409);
183 
184  refresh_rate = 70;
185  } else {
186  return -1;
187  }
188 
190  fb_dos.update_len = (unsigned int)end_of_driver_update - (unsigned int)driver_update;
192 
193  return fb_dos_init(title, w, h, depth, refresh_rate, flags);
194 }
195 
196 static void driver_update(void)
197 {
198  int y;
199  unsigned int buffer = (unsigned int)__fb_gfx->framebuffer;
200  unsigned int screen = 0xA0000;
201 
202  for (y = 0; y < fb_dos.h; y++, buffer += fb_dos.w, screen += fb_dos.w) {
203  if (__fb_gfx->dirty[y]) {
204  movedata(_my_ds(), buffer, _dos_ds, screen, fb_dos.w);
205  }
206  }
207 }
208 static void end_of_driver_update(void) { /* do not remove */ }
209 
210 static int *driver_fetch_modes(int depth, int *size)
211 {
212  if (depth != 8) return NULL;
213 
214  *size = sizeof(modes) / sizeof(int);
215  return memcpy((void*)malloc(sizeof(modes)), modes, sizeof(modes));
216 }