PCem
view src/video.c @ 113:f749363ad763
Added per-device configuration.
Reworked configuration parser a bit.
Added configuration for S3 ViRGE and 8-bit Sound Blasters.
IRQ 2 routed to IRQ 9 on AT machines.
| author | TomW |
|---|---|
| date | Mon Jun 30 21:31:28 2014 +0100 |
| parents | 354491040ce1 |
| children | 47132154ffe7 |
line source
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4 #include "ibm.h"
5 #include "device.h"
6 #include "mem.h"
7 #include "video.h"
8 #include "vid_svga.h"
9 #include "io.h"
10 #include "cpu.h"
11 #include "rom.h"
12 #include "timer.h"
14 #include "vid_ati18800.h"
15 #include "vid_ati28800.h"
16 #include "vid_ati_mach64.h"
17 #include "vid_cga.h"
18 #include "vid_cl5429.h"
19 #include "vid_ega.h"
20 #include "vid_et4000.h"
21 #include "vid_et4000w32.h"
22 #include "vid_hercules.h"
23 #include "vid_mda.h"
24 #include "vid_olivetti_m24.h"
25 #include "vid_oti067.h"
26 #include "vid_paradise.h"
27 #include "vid_pc1512.h"
28 #include "vid_pc1640.h"
29 #include "vid_pc200.h"
30 #include "vid_pcjr.h"
31 #include "vid_s3.h"
32 #include "vid_s3_virge.h"
33 #include "vid_tandy.h"
34 #include "vid_tgui9440.h"
35 #include "vid_tvga.h"
36 #include "vid_vga.h"
38 typedef struct
39 {
40 char name[64];
41 device_t *device;
42 int legacy_id;
43 } VIDEO_CARD;
45 static VIDEO_CARD video_cards[] =
46 {
47 {"CGA", &cga_device, GFX_CGA},
48 {"MDA", &mda_device, GFX_MDA},
49 {"Hercules", &hercules_device, GFX_HERCULES},
50 {"EGA", &ega_device, GFX_EGA},
51 {"Trident TVGA8900D", &tvga8900d_device, GFX_TVGA},
52 {"Tseng ET4000AX", &et4000_device, GFX_ET4000},
53 {"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32},
54 {"Paradise Bahamas 64 (S3 Vision864)", &s3_bahamas64_device, GFX_BAHAMAS64},
55 {"Number Nine 9FX (S3 Trio64)", &s3_9fx_device, GFX_N9_9FX},
56 {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE},
57 {"S3 ViRGE/DX", &s3_virge_375_device, GFX_VIRGEDX},
58 {"Trident TGUI9440", &tgui9440_device, GFX_TGUI9440},
59 {"VGA", &vga_device, GFX_VGA},
60 {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16},
61 {"ATI VGA Charger", &ati28800_device, GFX_VGACHARGER},
62 {"OAK OTI-067", &oti067_device, GFX_OTI067},
63 {"ATI Graphics Pro Turbo (Mach64 GX)", &mach64gx_device, GFX_MACH64GX},
64 {"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429},
65 {"", NULL, 0}
66 };
68 int video_card_available(int card)
69 {
70 if (video_cards[card].device)
71 return device_available(video_cards[card].device);
73 return 1;
74 }
76 char *video_card_getname(int card)
77 {
78 return video_cards[card].name;
79 }
81 device_t *video_card_getdevice(int card)
82 {
83 return video_cards[card].device;
84 }
86 int video_card_has_config(int card)
87 {
88 return video_cards[card].device->config ? 1 : 0;
89 }
91 int video_card_getid(char *s)
92 {
93 int c = 0;
95 while (video_cards[c].device)
96 {
97 if (!strcmp(video_cards[c].name, s))
98 return c;
99 c++;
100 }
102 return 0;
103 }
105 int video_old_to_new(int card)
106 {
107 int c = 0;
109 while (video_cards[c].device)
110 {
111 if (video_cards[c].legacy_id == card)
112 return c;
113 c++;
114 }
116 return 0;
117 }
119 int video_new_to_old(int card)
120 {
121 return video_cards[card].legacy_id;
122 }
124 int video_fullscreen = 0, video_fullscreen_scale, video_fullscreen_first;
125 uint32_t *video_15to32, *video_16to32;
127 int egareads=0,egawrites=0;
128 int changeframecount=2;
130 uint8_t rotatevga[8][256];
132 int frames = 0;
134 int fullchange;
136 uint8_t edatlookup[4][4];
138 /*Video timing settings -
140 8-bit - 1mb/sec
141 B = 8 ISA clocks
142 W = 16 ISA clocks
143 L = 32 ISA clocks
145 Slow 16-bit - 2mb/sec
146 B = 6 ISA clocks
147 W = 8 ISA clocks
148 L = 16 ISA clocks
150 Fast 16-bit - 4mb/sec
151 B = 3 ISA clocks
152 W = 3 ISA clocks
153 L = 6 ISA clocks
155 Slow VLB/PCI - 8mb/sec (ish)
156 B = 4 bus clocks
157 W = 8 bus clocks
158 L = 16 bus clocks
160 Mid VLB/PCI -
161 B = 4 bus clocks
162 W = 5 bus clocks
163 L = 10 bus clocks
165 Fast VLB/PCI -
166 B = 3 bus clocks
167 W = 3 bus clocks
168 L = 4 bus clocks
169 */
171 enum
172 {
173 VIDEO_ISA = 0,
174 VIDEO_BUS
175 };
177 int video_speed = 0;
178 int video_timing[6][4] =
179 {
180 {VIDEO_ISA, 8, 16, 32},
181 {VIDEO_ISA, 6, 8, 16},
182 {VIDEO_ISA, 3, 3, 6},
183 {VIDEO_BUS, 4, 8, 16},
184 {VIDEO_BUS, 4, 5, 10},
185 {VIDEO_BUS, 3, 3, 4}
186 };
188 void video_updatetiming()
189 {
190 if (video_timing[video_speed][0] == VIDEO_ISA)
191 {
192 video_timing_b = (int)(isa_timing * video_timing[video_speed][1]);
193 video_timing_w = (int)(isa_timing * video_timing[video_speed][2]);
194 video_timing_l = (int)(isa_timing * video_timing[video_speed][3]);
195 }
196 else
197 {
198 video_timing_b = (int)(bus_timing * video_timing[video_speed][1]);
199 video_timing_w = (int)(bus_timing * video_timing[video_speed][2]);
200 video_timing_l = (int)(bus_timing * video_timing[video_speed][3]);
201 }
202 if (cpu_16bitbus)
203 video_timing_l = video_timing_w * 2;
204 }
206 int video_timing_b, video_timing_w, video_timing_l;
208 int video_res_x, video_res_y, video_bpp;
210 void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h);
211 void (*video_blit_memtoscreen_8)(int x, int y, int w, int h);
213 void video_init()
214 {
215 pclog("Video_init %i %i\n",romset,gfxcard);
217 switch (romset)
218 {
219 case ROM_IBMPCJR:
220 device_add(&pcjr_video_device);
221 return;
223 case ROM_TANDY:
224 device_add(&tandy_device);
225 return;
227 case ROM_PC1512:
228 device_add(&pc1512_device);
229 return;
231 case ROM_PC1640:
232 device_add(&pc1640_device);
233 return;
235 case ROM_PC200:
236 device_add(&pc200_device);
237 return;
239 case ROM_OLIM24:
240 device_add(&m24_device);
241 return;
243 case ROM_PC2086:
244 device_add(¶dise_pvga1a_pc2086_device);
245 return;
247 case ROM_PC3086:
248 device_add(¶dise_pvga1a_pc3086_device);
249 return;
251 case ROM_MEGAPC:
252 device_add(¶dise_wd90c11_megapc_device);
253 return;
255 case ROM_ACER386:
256 device_add(&oti067_device);
257 return;
258 }
259 device_add(video_cards[video_old_to_new(gfxcard)].device);
260 }
263 BITMAP *buffer, *buffer32;
265 uint8_t fontdat[256][8];
266 uint8_t fontdatm[256][16];
268 int xsize=1,ysize=1;
270 PALETTE cgapal;
272 void loadfont(char *s, int format)
273 {
274 FILE *f=romfopen(s,"rb");
275 int c,d;
276 if (!f)
277 return;
279 if (!format)
280 {
281 for (c=0;c<256;c++)
282 {
283 for (d=0;d<8;d++)
284 {
285 fontdatm[c][d]=getc(f);
286 }
287 }
288 for (c=0;c<256;c++)
289 {
290 for (d=0;d<8;d++)
291 {
292 fontdatm[c][d+8]=getc(f);
293 }
294 }
295 fseek(f,4096+2048,SEEK_SET);
296 for (c=0;c<256;c++)
297 {
298 for (d=0;d<8;d++)
299 {
300 fontdat[c][d]=getc(f);
301 }
302 }
303 }
304 else if (format == 1)
305 {
306 for (c=0;c<256;c++)
307 {
308 for (d=0;d<8;d++)
309 {
310 fontdatm[c][d]=getc(f);
311 }
312 }
313 for (c=0;c<256;c++)
314 {
315 for (d=0;d<8;d++)
316 {
317 fontdatm[c][d+8]=getc(f);
318 }
319 }
320 fseek(f, 4096, SEEK_SET);
321 for (c=0;c<256;c++)
322 {
323 for (d=0;d<8;d++)
324 {
325 fontdat[c][d]=getc(f);
326 }
327 for (d=0;d<8;d++) getc(f);
328 }
329 }
330 else
331 {
332 for (c=0;c<256;c++)
333 {
334 for (d=0;d<8;d++)
335 {
336 fontdat[c][d]=getc(f);
337 }
338 }
339 }
340 fclose(f);
341 }
344 void initvideo()
345 {
346 int c, d, e;
348 buffer32 = create_bitmap(2048, 2048);
350 buffer = create_bitmap(2048, 2048);
352 for (c = 0; c < 64; c++)
353 {
354 cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
355 cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
356 cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
357 if ((c & 0x17) == 6)
358 cgapal[c + 64].g >>= 1;
359 }
360 for (c = 0; c < 64; c++)
361 {
362 cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21;
363 cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
364 cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21;
365 }
367 for (c = 0; c < 256; c++)
368 {
369 e = c;
370 for (d = 0; d < 8; d++)
371 {
372 rotatevga[d][c] = e;
373 e = (e >> 1) | ((e & 1) ? 0x80 : 0);
374 }
375 }
376 for (c = 0; c < 4; c++)
377 {
378 for (d = 0; d < 4; d++)
379 {
380 edatlookup[c][d] = 0;
381 if (c & 1) edatlookup[c][d] |= 1;
382 if (d & 1) edatlookup[c][d] |= 2;
383 if (c & 2) edatlookup[c][d] |= 0x10;
384 if (d & 2) edatlookup[c][d] |= 0x20;
385 // printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
386 }
387 }
389 video_15to32 = malloc(4 * 65536);
390 for (c = 0; c < 65536; c++)
391 video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19);
393 video_16to32 = malloc(4 * 65536);
394 for (c = 0; c < 65536; c++)
395 video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19);
397 }
399 void closevideo()
400 {
401 free(video_15to32);
402 free(video_16to32);
403 destroy_bitmap(buffer);
404 destroy_bitmap(buffer32);
405 }
