PCem

view src/vid_et4000.c @ 133:24b744b9a632

ViRGE S3D triangle rendering now uses worker thread. Fixed clipping bug on ViRGE. Fixed status window crash.
author TomW
date Tue Jul 22 21:10:39 2014 +0100
parents f22b6152c221
children 6f30fb98b7f2
line source
1 /*ET4000 emulation*/
2 #include <stdlib.h>
3 #include "ibm.h"
4 #include "device.h"
5 #include "io.h"
6 #include "mem.h"
7 #include "rom.h"
8 #include "video.h"
9 #include "vid_svga.h"
10 #include "vid_unk_ramdac.h"
12 #include "vid_et4000.h"
14 typedef struct et4000_t
15 {
16 svga_t svga;
17 unk_ramdac_t ramdac;
19 rom_t bios_rom;
21 uint8_t banking;
22 } et4000_t;
24 void et4000_out(uint16_t addr, uint8_t val, void *p)
25 {
26 et4000_t *et4000 = (et4000_t *)p;
27 svga_t *svga = &et4000->svga;
29 uint8_t old;
31 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
32 addr ^= 0x60;
34 // pclog("ET4000 out %04X %02X\n", addr, val);
36 switch (addr)
37 {
38 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
39 unk_ramdac_out(addr, val, &et4000->ramdac, svga);
40 return;
42 case 0x3CD: /*Banking*/
43 svga->write_bank = (val & 0xf) * 0x10000;
44 svga->read_bank = ((val >> 4) & 0xf) * 0x10000;
45 et4000->banking = val;
46 // pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val);
47 return;
48 case 0x3D4:
49 svga->crtcreg = val & 0x3f;
50 return;
51 case 0x3D5:
52 if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
53 old = svga->crtc[svga->crtcreg];
54 svga->crtc[svga->crtcreg] = val;
55 if (old != val)
56 {
57 if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
58 {
59 svga->fullchange = changeframecount;
60 svga_recalctimings(svga);
61 }
62 }
63 break;
64 }
65 svga_out(addr, val, svga);
66 }
68 uint8_t et4000_in(uint16_t addr, void *p)
69 {
70 et4000_t *et4000 = (et4000_t *)p;
71 svga_t *svga = &et4000->svga;
73 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
74 addr ^= 0x60;
76 // if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr);
78 switch (addr)
79 {
80 case 0x3C5:
81 if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4;
82 break;
84 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
85 return unk_ramdac_in(addr, &et4000->ramdac, svga);
87 case 0x3CD: /*Banking*/
88 return et4000->banking;
89 case 0x3D4:
90 return svga->crtcreg;
91 case 0x3D5:
92 return svga->crtc[svga->crtcreg];
93 }
94 return svga_in(addr, svga);
95 }
97 void et4000_recalctimings(svga_t *svga)
98 {
99 et4000_t *et4000 = (et4000_t *)svga->p;
101 svga->ma_latch |= (svga->crtc[0x33]&3)<<16;
102 if (svga->crtc[0x35] & 2) svga->vtotal += 0x400;
103 if (svga->crtc[0x35] & 4) svga->dispend += 0x400;
104 if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400;
105 if (svga->crtc[0x35] & 0x10) svga->split += 0x400;
106 if (!svga->rowoffset) svga->rowoffset = 0x100;
107 if (svga->crtc[0x3f] & 1) svga->htotal += 256;
108 if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1;
110 // pclog("Rowoffset %i\n",svga_rowoffset);
112 switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4))
113 {
114 case 0: case 1: break;
115 case 3: svga->clock = cpuclock / 40000000.0; break;
116 case 5: svga->clock = cpuclock / 65000000.0; break;
117 default: svga->clock = cpuclock / 36000000.0; break;
118 }
120 switch (svga->bpp)
121 {
122 case 15: case 16:
123 svga->hdisp /= 2;
124 break;
125 case 24:
126 svga->hdisp /= 3;
127 break;
128 }
129 }
131 void *et4000_init()
132 {
133 et4000_t *et4000 = malloc(sizeof(et4000_t));
134 memset(et4000, 0, sizeof(et4000_t));
136 rom_init(&et4000->bios_rom, "roms/et4000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
138 io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
140 svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
141 et4000_recalctimings,
142 et4000_in, et4000_out,
143 NULL,
144 NULL);
146 return et4000;
147 }
149 static int et4000_available()
150 {
151 return rom_present("roms/et4000.bin");
152 }
154 void et4000_close(void *p)
155 {
156 et4000_t *et4000 = (et4000_t *)p;
158 svga_close(&et4000->svga);
160 free(et4000);
161 }
163 void et4000_speed_changed(void *p)
164 {
165 et4000_t *et4000 = (et4000_t *)p;
167 svga_recalctimings(&et4000->svga);
168 }
170 void et4000_force_redraw(void *p)
171 {
172 et4000_t *et4000 = (et4000_t *)p;
174 et4000->svga.fullchange = changeframecount;
175 }
177 void et4000_add_status_info(char *s, int max_len, void *p)
178 {
179 et4000_t *et4000 = (et4000_t *)p;
181 svga_add_status_info(s, max_len, &et4000->svga);
182 }
184 device_t et4000_device =
185 {
186 "Tseng Labs ET4000AX",
187 0,
188 et4000_init,
189 et4000_close,
190 NULL,
191 et4000_speed_changed,
192 et4000_force_redraw,
193 et4000_add_status_info
194 };