PCem

view src/vid_oti067.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
line source
1 /*Oak OTI067 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_oti067.h"
10 #include "vid_svga.h"
12 typedef struct oti067_t
13 {
14 svga_t svga;
16 rom_t bios_rom;
18 int index;
19 uint8_t regs[32];
21 uint32_t vram_size;
22 uint32_t vram_mask;
23 } oti067_t;
25 void oti067_out(uint16_t addr, uint8_t val, void *p)
26 {
27 oti067_t *oti067 = (oti067_t *)p;
28 svga_t *svga = &oti067->svga;
29 uint8_t old;
31 // pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins);
33 if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60;
35 switch (addr)
36 {
37 case 0x3D4:
38 svga->crtcreg = val & 31;
39 return;
40 case 0x3D5:
41 if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
42 old = svga->crtc[svga->crtcreg];
43 svga->crtc[svga->crtcreg] = val;
44 if (old != val)
45 {
46 if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
47 {
48 svga->fullchange = changeframecount;
49 svga_recalctimings(svga);
50 }
51 }
52 break;
54 case 0x3DE:
55 oti067->index = val & 0x1f;
56 return;
57 case 0x3DF:
58 oti067->regs[oti067->index] = val;
59 switch (oti067->index)
60 {
61 case 0xD:
62 svga->vrammask = (val & 0xc) ? oti067->vram_mask : 0x3ffff;
63 if ((val & 0x80) && oti067->vram_size == 256)
64 mem_mapping_disable(&svga->mapping);
65 else
66 mem_mapping_enable(&svga->mapping);
67 if (!(val & 0x80))
68 svga->vrammask = 0x3ffff;
69 break;
70 case 0x11:
71 svga->read_bank = (val & 0xf) * 65536;
72 svga->write_bank = (val >> 4) * 65536;
73 break;
74 }
75 return;
76 }
77 svga_out(addr, val, svga);
78 }
80 uint8_t oti067_in(uint16_t addr, void *p)
81 {
82 oti067_t *oti067 = (oti067_t *)p;
83 svga_t *svga = &oti067->svga;
84 uint8_t temp;
86 // if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr);
88 if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60;
90 switch (addr)
91 {
92 case 0x3D4:
93 temp = svga->crtcreg;
94 break;
95 case 0x3D5:
96 temp = svga->crtc[svga->crtcreg];
97 break;
99 case 0x3DE:
100 temp = oti067->index | (2 << 5);
101 break;
102 case 0x3DF:
103 if (oti067->index==0x10) temp = 0x18;
104 else temp = oti067->regs[oti067->index];
105 break;
107 default:
108 temp = svga_in(addr, svga);
109 break;
110 }
111 // if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc);
112 return temp;
113 }
115 void oti067_recalctimings(svga_t *svga)
116 {
117 oti067_t *oti067 = (oti067_t *)svga->p;
119 if (oti067->regs[0x14] & 0x08) svga->ma_latch |= 0x10000;
120 if (oti067->regs[0x0d] & 0x0c) svga->rowoffset <<= 1;
121 svga->interlace = oti067->regs[0x14] & 0x80;
122 }
124 void *oti067_common_init(char *bios_fn, int vram_size)
125 {
126 oti067_t *oti067 = malloc(sizeof(oti067_t));
127 memset(oti067, 0, sizeof(oti067_t));
129 rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
131 oti067->vram_size = vram_size;
132 oti067->vram_mask = (vram_size << 10) - 1;
134 svga_init(&oti067->svga, oti067, vram_size << 10,
135 oti067_recalctimings,
136 oti067_in, oti067_out,
137 NULL,
138 NULL);
140 io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067);
142 oti067->svga.miscout = 1;
143 return oti067;
144 }
146 void *oti067_init()
147 {
148 int vram_size = device_get_config_int("memory");
149 return oti067_common_init("roms/oti067/bios.bin", vram_size);
150 }
152 void *oti067_acer386_init()
153 {
154 oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512);
156 if (oti067)
157 oti067->bios_rom.rom[0x5d] = 0x74;
159 return oti067;
160 }
162 static int oti067_available()
163 {
164 return rom_present("roms/oti067/bios.bin");
165 }
167 void oti067_close(void *p)
168 {
169 oti067_t *oti067 = (oti067_t *)p;
171 svga_close(&oti067->svga);
173 free(oti067);
174 }
176 void oti067_speed_changed(void *p)
177 {
178 oti067_t *oti067 = (oti067_t *)p;
180 svga_recalctimings(&oti067->svga);
181 }
183 void oti067_force_redraw(void *p)
184 {
185 oti067_t *oti067 = (oti067_t *)p;
187 oti067->svga.fullchange = changeframecount;
188 }
190 void oti067_add_status_info(char *s, int max_len, void *p)
191 {
192 oti067_t *oti067 = (oti067_t *)p;
194 svga_add_status_info(s, max_len, &oti067->svga);
195 }
197 static device_config_t oti067_config[] =
198 {
199 {
200 .name = "memory",
201 .description = "Memory size",
202 .type = CONFIG_SELECTION,
203 .selection =
204 {
205 {
206 .description = "256 kB",
207 .value = 256
208 },
209 {
210 .description = "512 kB",
211 .value = 512
212 },
213 {
214 .description = ""
215 }
216 },
217 .default_int = 512
218 },
219 {
220 .type = -1
221 }
222 };
224 device_t oti067_device =
225 {
226 "Oak OTI-067",
227 0,
228 oti067_init,
229 oti067_close,
230 oti067_available,
231 oti067_speed_changed,
232 oti067_force_redraw,
233 oti067_add_status_info,
234 oti067_config
235 };
236 device_t oti067_acer386_device =
237 {
238 "Oak OTI-067 (Acermate 386SX/25N)",
239 0,
240 oti067_acer386_init,
241 oti067_close,
242 oti067_available,
243 oti067_speed_changed,
244 oti067_force_redraw,
245 oti067_add_status_info
246 };