PCem

view src/vid_ati_mach64.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 614f796ff7ed
children abd5259486c3
line source
1 /*ATI Mach64 emulation*/
2 #include <stdlib.h>
3 #include "ibm.h"
4 #include "device.h"
5 #include "io.h"
6 #include "mem.h"
7 #include "pci.h"
8 #include "rom.h"
9 #include "video.h"
10 #include "vid_svga.h"
11 #include "vid_ati68860_ramdac.h"
12 #include "vid_ati_eeprom.h"
13 #include "vid_ics2595.h"
14 #include "vid_svga_render.h"
16 //#define MACH64_DEBUG
18 typedef struct mach64_t
19 {
20 mem_mapping_t linear_mapping;
21 mem_mapping_t mmio_mapping;
22 mem_mapping_t mmio_linear_mapping;
24 ati68860_ramdac_t ramdac;
25 ati_eeprom_t eeprom;
26 ics2595_t ics2595;
27 svga_t svga;
29 rom_t bios_rom;
31 uint8_t regs[256];
32 int index;
34 uint8_t pci_regs[256];
36 int bank_r[2];
37 int bank_w[2];
39 uint32_t vram_size;
40 uint32_t vram_mask;
42 uint32_t config_cntl;
44 uint32_t context_load_cntl;
45 uint32_t context_mask;
47 uint32_t crtc_gen_cntl;
48 uint8_t crtc_int_cntl;
49 uint32_t crtc_h_total_disp;
50 uint32_t crtc_v_sync_strt_wid;
51 uint32_t crtc_v_total_disp;
52 uint32_t crtc_off_pitch;
54 uint32_t clock_cntl;
56 uint32_t clr_cmp_clr;
57 uint32_t clr_cmp_cntl;
58 uint32_t clr_cmp_mask;
60 uint32_t cur_horz_vert_off;
61 uint32_t cur_horz_vert_posn;
62 uint32_t cur_offset;
64 uint32_t dac_cntl;
66 uint32_t dp_bkgd_clr;
67 uint32_t dp_frgd_clr;
68 uint32_t dp_mix;
69 uint32_t dp_pix_width;
70 uint32_t dp_src;
72 uint32_t dst_bres_lnth;
73 uint32_t dst_bres_dec;
74 uint32_t dst_bres_err;
75 uint32_t dst_bres_inc;
77 uint32_t dst_cntl;
78 uint32_t dst_height_width;
79 uint32_t dst_off_pitch;
80 uint32_t dst_y_x;
82 uint32_t gen_test_cntl;
84 uint32_t gui_traj_cntl;
86 uint32_t mem_cntl;
88 uint32_t ovr_clr;
89 uint32_t ovr_wid_left_right;
90 uint32_t ovr_wid_top_bottom;
92 uint32_t pat_cntl;
93 uint32_t pat_reg0, pat_reg1;
95 uint32_t sc_left_right, sc_top_bottom;
97 uint32_t scratch_reg0, scratch_reg1;
99 uint32_t src_cntl;
100 uint32_t src_off_pitch;
101 uint32_t src_y_x;
102 uint32_t src_y_x_start;
103 uint32_t src_height1_width1, src_height2_width2;
106 uint32_t linear_base, old_linear_base;
108 struct
109 {
110 int op;
112 int dst_x, dst_y;
113 int dst_x_start, dst_y_start;
114 int src_x, src_y;
115 int src_x_start, src_y_start;
116 int xinc, yinc;
117 int x_count, y_count;
118 int src_x_count, src_y_count;
119 int src_width1, src_height1;
120 int src_width2, src_height2;
121 uint32_t src_offset, src_pitch;
122 uint32_t dst_offset, dst_pitch;
123 int mix_bg, mix_fg;
124 int source_bg, source_fg, source_mix;
125 int source_host;
126 int dst_width, dst_height;
127 int busy;
128 int pattern[8][8];
129 int sc_left, sc_right, sc_top, sc_bottom;
130 int dst_pix_width, src_pix_width, host_pix_width;
131 int dst_size, src_size;
133 uint32_t dp_bkgd_clr;
134 uint32_t dp_frgd_clr;
136 uint32_t clr_cmp_clr;
137 uint32_t clr_cmp_mask;
138 int clr_cmp_fn;
139 int clr_cmp_src;
141 int err;
142 } accel;
143 } mach64_t;
145 enum
146 {
147 SRC_BG = 0,
148 SRC_FG = 1,
149 SRC_HOST = 2,
150 SRC_BLITSRC = 3,
151 SRC_PAT = 4
152 };
154 enum
155 {
156 MONO_SRC_1 = 0,
157 MONO_SRC_PAT = 1,
158 MONO_SRC_HOST = 2,
159 MONO_SRC_BLITSRC = 3
160 };
162 enum
163 {
164 BPP_1 = 0,
165 BPP_4 = 1,
166 BPP_8 = 2,
167 BPP_15 = 3,
168 BPP_16 = 4,
169 BPP_32 = 5
170 };
172 enum
173 {
174 OP_RECT,
175 OP_LINE
176 };
178 enum
179 {
180 SRC_PATT_EN = 1,
181 SRC_PATT_ROT_EN = 2,
182 SRC_LINEAR_EN = 4
183 };
185 static int mach64_width[8] = {0, 0, 0, 1, 1, 2, 2, 0};
187 enum
188 {
189 DST_X_TILE = 0x08,
190 DST_Y_TILE = 0x10,
191 DST_24_ROT_EN = 0x80
192 };
194 void mach64_write(uint32_t addr, uint8_t val, void *priv);
195 uint8_t mach64_read(uint32_t addr, void *priv);
196 void mach64_updatemapping(mach64_t *mach64);
198 uint8_t mach64_ext_readb(uint32_t addr, void *priv);
199 uint16_t mach64_ext_readw(uint32_t addr, void *priv);
200 uint32_t mach64_ext_readl(uint32_t addr, void *priv);
201 void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv);
202 void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv);
203 void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv);
205 void mach64_out(uint16_t addr, uint8_t val, void *p)
206 {
207 mach64_t *mach64 = p;
208 svga_t *svga = &mach64->svga;
209 uint8_t old;
211 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
212 addr ^= 0x60;
214 // pclog("mach64 out %04X %02X\n", addr, val);
216 switch (addr)
217 {
218 case 0x1ce:
219 mach64->index = val;
220 break;
221 case 0x1cf:
222 mach64->regs[mach64->index] = val;
223 break;
225 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
226 ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga);
227 return;
229 case 0x3cf:
230 if (svga->gdcaddr == 6)
231 {
232 uint8_t old_val = svga->gdcreg[6];
233 svga->gdcreg[6] = val;
234 if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc))
235 mach64_updatemapping(mach64);
236 return;
237 }
238 break;
240 case 0x3D4:
241 svga->crtcreg = val & 0x3f;
242 return;
243 case 0x3D5:
244 if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
245 old = svga->crtc[svga->crtcreg];
246 svga->crtc[svga->crtcreg] = val;
248 if (old!=val)
249 {
250 if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
251 {
252 svga->fullchange = changeframecount;
253 svga_recalctimings(svga);
254 }
255 }
256 break;
257 }
258 svga_out(addr, val, svga);
259 }
261 uint8_t mach64_in(uint16_t addr, void *p)
262 {
263 mach64_t *mach64 = p;
264 svga_t *svga = &mach64->svga;
266 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1))
267 addr ^= 0x60;
269 // pclog("IN mach64 %04X\n", addr);
271 switch (addr)
272 {
273 case 0x1ce:
274 return mach64->index;
275 case 0x1cf:
276 return mach64->regs[mach64->index];
278 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
279 return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga);
281 case 0x3D4:
282 return svga->crtcreg;
283 case 0x3D5:
284 return svga->crtc[svga->crtcreg];
285 }
286 return svga_in(addr, svga);
287 }
289 void mach64_recalctimings(svga_t *svga)
290 {
291 mach64_t *mach64 = (mach64_t *)svga->p;
293 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
294 {
295 svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1;
296 svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1;
297 svga->htotal = (mach64->crtc_h_total_disp & 255) + 1;
298 svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1;
299 svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1;
300 svga->rowoffset = (mach64->crtc_off_pitch >> 22);
301 svga->clock = cpuclock / mach64->ics2595.output_clock;
302 svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2;
303 svga->linedbl = svga->rowcount = 0;
304 svga->split = 0xffffff;
305 svga->vblankstart = svga->dispend;
306 // svga_htotal <<= 1;
307 // svga_hdisp <<= 1;
308 svga->rowoffset <<= 1;
309 switch ((mach64->crtc_gen_cntl >> 8) & 7)
310 {
311 case 1:
312 svga->render = svga_render_4bpp_highres;
313 svga->hdisp *= 8;
314 break;
315 case 2:
316 svga->render = svga_render_8bpp_highres;
317 svga->hdisp *= 8;
318 svga->rowoffset /= 2;
319 break;
320 case 3:
321 svga->render = svga_render_15bpp_highres;
322 svga->hdisp *= 8;
323 //svga_rowoffset *= 2;
324 break;
325 case 4:
326 svga->render = svga_render_16bpp_highres;
327 svga->hdisp *= 8;
328 //svga_rowoffset *= 2;
329 break;
330 case 5:
331 svga->render = svga_render_24bpp_highres;
332 svga->hdisp *= 8;
333 svga->rowoffset = (svga->rowoffset * 3) / 2;
334 break;
335 case 6:
336 svga->render = svga_render_32bpp_highres;
337 svga->hdisp *= 8;
338 svga->rowoffset *= 2;
339 break;
340 }
342 // pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, svga->rowoffset, svga->clock, svga->ma);
343 }
344 }
346 void mach64_updatemapping(mach64_t *mach64)
347 {
348 svga_t *svga = &mach64->svga;
350 if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
351 {
352 pclog("Update mapping - PCI disabled\n");
353 mem_mapping_disable(&svga->mapping);
354 mem_mapping_disable(&mach64->linear_mapping);
355 mem_mapping_disable(&mach64->mmio_mapping);
356 mem_mapping_disable(&mach64->mmio_linear_mapping);
357 return;
358 }
360 mem_mapping_disable(&mach64->mmio_mapping);
361 // pclog("Write mapping %02X\n", val);
362 switch (svga->gdcreg[6] & 0xc)
363 {
364 case 0x0: /*128k at A0000*/
365 mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
366 mem_mapping_set_p(&mach64->svga.mapping, mach64);
367 mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
368 mem_mapping_enable(&mach64->mmio_mapping);
369 svga->banked_mask = 0xffff;
370 break;
371 case 0x4: /*64k at A0000*/
372 mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
373 mem_mapping_set_p(&mach64->svga.mapping, mach64);
374 mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
375 svga->banked_mask = 0xffff;
376 break;
377 case 0x8: /*32k at B0000*/
378 mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
379 mem_mapping_set_p(&mach64->svga.mapping, svga);
380 mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
381 svga->banked_mask = 0x7fff;
382 break;
383 case 0xC: /*32k at B8000*/
384 mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
385 mem_mapping_set_p(&mach64->svga.mapping, svga);
386 mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
387 svga->banked_mask = 0x7fff;
388 break;
389 }
390 if (mach64->linear_base)
391 {
392 if ((mach64->config_cntl & 3) == 2)
393 {
394 /*8 MB aperture*/
395 mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
396 mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
397 }
398 else
399 {
400 /*4 MB aperture*/
401 mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000);
402 mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000);
403 }
404 }
405 else
406 {
407 mem_mapping_disable(&mach64->linear_mapping);
408 mem_mapping_disable(&mach64->mmio_linear_mapping);
409 }
410 }
412 #define READ8(addr, var) switch ((addr) & 3) \
413 { \
414 case 0: ret = (var) & 0xff; break; \
415 case 1: ret = ((var) >> 8) & 0xff; break; \
416 case 2: ret = ((var) >> 16) & 0xff; break; \
417 case 3: ret = ((var) >> 24) & 0xff; break; \
418 }
420 #define WRITE8(addr, var, val) switch ((addr) & 3) \
421 { \
422 case 0: var = (var & 0xffffff00) | (val); break; \
423 case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \
424 case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \
425 case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \
426 }
428 void mach64_cursor_dump(mach64_t *mach64)
429 {
430 svga_t *svga = &mach64->svga;
431 /* pclog("Mach64 cursor :\n");
432 pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff);*/
433 }
435 void mach64_start_fill(mach64_t *mach64)
436 {
437 int x, y;
439 mach64->accel.dst_x = 0;
440 mach64->accel.dst_y = 0;
441 mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff;
442 mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff;
444 mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff;
445 mach64->accel.dst_height = mach64->dst_height_width & 0x1fff;
446 mach64->accel.x_count = mach64->accel.dst_width;
448 mach64->accel.src_x = 0;
449 mach64->accel.src_y = 0;
450 mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
451 mach64->accel.src_y_start = mach64->src_y_x & 0xfff;
452 if (mach64->src_cntl & SRC_LINEAR_EN)
453 mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/
454 else
455 mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff;
456 if (!(mach64->src_cntl & SRC_PATT_EN))
457 mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/
458 else
459 mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff;
461 mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff;
462 mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff;
463 mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff;
464 mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff;
466 #ifdef MACH64_DEBUG
467 pclog("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count,
468 mach64->accel.src_y_count,
469 mach64->accel.src_width1,
470 mach64->accel.src_height1,
471 mach64->src_height1_width1,
472 mach64->src_height2_width2);
473 #endif
475 mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8;
476 mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
478 mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8;
479 mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
481 mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
482 mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
484 mach64->accel.source_bg = mach64->dp_src & 7;
485 mach64->accel.source_fg = (mach64->dp_src >> 8) & 7;
486 mach64->accel.source_mix = (mach64->dp_src >> 16) & 7;
488 mach64->accel.dst_pix_width = mach64->dp_pix_width & 7;
489 mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7;
490 mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7;
492 mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width];
493 mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width];
495 /* mach64->accel.src_x *= mach64_inc[mach64->accel.src_pix_width];
496 mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
497 mach64->accel.dst_x *= mach64_inc[mach64->accel.dst_pix_width];
498 mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
500 mach64->accel.src_offset >>= mach64->accel.src_size;
501 mach64->accel.dst_offset >>= mach64->accel.dst_size;
503 /* if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC)
504 {*/
505 mach64->accel.xinc = (mach64->dst_cntl & 1) ? 1 : -1;
506 mach64->accel.yinc = (mach64->dst_cntl & 2) ? 1 : -1;
507 /* }
508 else
509 {
510 mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width];
511 mach64->accel.yinc = 1;
512 }*/
514 mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
517 // pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1);
518 for (y = 0; y < 8; y++)
519 {
520 for (x = 0; x < 8; x++)
521 {
522 uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
523 mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
524 // pclog("%i ", mach64->accel.pattern[y][x]);
525 }
526 // pclog("\n");
527 }
529 mach64->accel.sc_left = mach64->sc_left_right & 0x1fff;
530 mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff;
531 mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff;
532 mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff;
534 /* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width];
535 mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/
537 mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
538 mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;
540 mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask;
541 mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask;
542 mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7;
543 mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24);
545 mach64->accel.busy = 1;
546 #ifdef MACH64_DEBUG
547 pclog("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i mix %02X %02X\n", mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg);
548 #endif
549 mach64->accel.op = OP_RECT;
550 }
552 void mach64_start_line(mach64_t *mach64)
553 {
554 int x, y;
556 mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff;
557 mach64->accel.dst_y = mach64->dst_y_x & 0xfff;
559 mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff;
560 mach64->accel.src_y = mach64->src_y_x & 0xfff;
562 mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8;
563 mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
565 mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8;
566 mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
568 mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
569 mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
571 mach64->accel.source_bg = mach64->dp_src & 7;
572 mach64->accel.source_fg = (mach64->dp_src >> 8) & 7;
573 mach64->accel.source_mix = (mach64->dp_src >> 16) & 7;
575 mach64->accel.dst_pix_width = mach64->dp_pix_width & 7;
576 mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7;
577 mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7;
579 mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width];
580 mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width];
582 mach64->accel.src_offset >>= mach64->accel.src_size;
583 mach64->accel.dst_offset >>= mach64->accel.dst_size;
585 /* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
586 mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
588 mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
590 for (y = 0; y < 8; y++)
591 {
592 for (x = 0; x < 8; x++)
593 {
594 uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
595 mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
596 }
597 }
599 mach64->accel.sc_left = mach64->sc_left_right & 0x1fff;
600 mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff;
601 mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff;
602 mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff;
604 mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
605 mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;
607 mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff;
608 mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0);
610 mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask;
611 mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask;
612 mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7;
613 mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24);
615 mach64->accel.busy = 1;
616 #ifdef MACH64_DEBUG
617 pclog("mach64_start_line\n");
618 #endif
619 mach64->accel.op = OP_LINE;
620 }
622 #define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \
623 else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \
624 else dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask];
626 #define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \
627 { \
628 case 0x0: dest_dat = ~dest_dat; break; \
629 case 0x1: dest_dat = 0; break; \
630 case 0x2: dest_dat = 0xffffffff; break; \
631 case 0x3: dest_dat = dest_dat; break; \
632 case 0x4: dest_dat = ~src_dat; break; \
633 case 0x5: dest_dat = src_dat ^ dest_dat; break; \
634 case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \
635 case 0x7: dest_dat = src_dat; break; \
636 case 0x8: dest_dat = ~(src_dat & dest_dat); break; \
637 case 0x9: dest_dat = ~src_dat | dest_dat; break; \
638 case 0xa: dest_dat = src_dat | ~dest_dat; break; \
639 case 0xb: dest_dat = src_dat | dest_dat; break; \
640 case 0xc: dest_dat = src_dat & dest_dat; break; \
641 case 0xd: dest_dat = src_dat & ~dest_dat; break; \
642 case 0xe: dest_dat = ~src_dat & dest_dat; break; \
643 case 0xf: dest_dat = ~(src_dat | dest_dat); break; \
644 }
646 #define WRITE(addr, width) if (width == 0) \
647 { \
648 svga->vram[(addr) & mach64->vram_mask] = dest_dat; \
649 svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \
650 } \
651 else if (width == 1) \
652 { \
653 *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \
654 svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \
655 } \
656 else \
657 { \
658 *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \
659 svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \
660 }
662 void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
663 {
664 svga_t *svga = &mach64->svga;
665 int cmp_clr = 0;
667 if (!mach64->accel.busy)
668 {
669 #ifdef MACH64_DEBUG
670 pclog("mach64_blit : return as not busy\n");
671 #endif
672 return;
673 }
674 switch (mach64->accel.op)
675 {
676 case OP_RECT:
677 while (count)
678 {
679 uint32_t src_dat, dest_dat;
680 uint32_t host_dat;
681 int mix;
682 int dst_x = mach64->accel.dst_x + mach64->accel.dst_x_start;
683 int dst_y = mach64->accel.dst_y + mach64->accel.dst_y_start;
685 if (mach64->accel.source_host)
686 {
687 host_dat = cpu_dat;
688 switch (mach64->accel.src_size)
689 {
690 case 0:
691 cpu_dat >>= 8;
692 count -= 8;
693 break;
694 case 1:
695 cpu_dat >>= 16;
696 count -= 16;
697 break;
698 case 2:
699 count -= 32;
700 break;
701 }
702 }
703 else
704 count--;
706 switch (mach64->accel.source_mix)
707 {
708 case MONO_SRC_HOST:
709 mix = cpu_dat >> 31;
710 cpu_dat <<= 1;
711 break;
712 case MONO_SRC_PAT:
713 mix = mach64->accel.pattern[dst_y & 7][dst_x & 7];
714 break;
715 case MONO_SRC_1:
716 default:
717 mix = 1;
718 break;
719 }
721 if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right &&
722 dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom)
723 {
724 int src_x = mach64->accel.src_x + mach64->accel.src_x_start;
725 int src_y = mach64->accel.src_y + mach64->accel.src_y_start;
727 switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
728 {
729 case SRC_HOST:
730 src_dat = host_dat;
731 break;
732 case SRC_BLITSRC:
733 READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size);
734 break;
735 case SRC_FG:
736 src_dat = mach64->accel.dp_frgd_clr;
737 break;
738 case SRC_BG:
739 src_dat = mach64->accel.dp_bkgd_clr;
740 break;
741 default:
742 src_dat = 0;
743 break;
744 }
746 READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size);
748 switch (mach64->accel.clr_cmp_fn)
749 {
750 case 1: /*TRUE*/
751 cmp_clr = 1;
752 break;
753 case 4: /*DST_CLR != CLR_CMP_CLR*/
754 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr;
755 break;
756 case 5: /*DST_CLR == CLR_CMP_CLR*/
757 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr;
758 break;
759 }
761 if (!cmp_clr)
762 MIX
764 WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size);
765 }
767 if (mach64->dst_cntl & DST_24_ROT_EN)
768 {
769 mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16);
770 mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16);
771 }
773 mach64->accel.src_x += mach64->accel.xinc;
774 mach64->accel.dst_x += mach64->accel.xinc;
775 mach64->accel.src_x_count--;
776 if (mach64->accel.src_x_count <= 0)
777 {
778 mach64->accel.src_x = 0;
779 if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN))
780 {
781 mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff;
782 mach64->accel.src_x_count = mach64->accel.src_width2;
783 }
784 else
785 mach64->accel.src_x_count = mach64->accel.src_width1;
786 }
788 mach64->accel.x_count--;
790 if (mach64->accel.x_count <= 0)
791 {
792 mach64->accel.x_count = mach64->accel.dst_width;
793 mach64->accel.src_x = 0;
794 mach64->accel.dst_x = 0;
795 mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
796 mach64->accel.src_x_count = mach64->accel.src_width1;
798 mach64->accel.src_y += mach64->accel.yinc;
799 mach64->accel.dst_y += mach64->accel.yinc;
800 mach64->accel.src_y_count--;
801 if (mach64->accel.src_y_count <= 0)
802 {
803 mach64->accel.src_y = 0;
804 if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN))
805 {
806 mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff;
807 mach64->accel.src_y_count = mach64->accel.src_height2;
808 }
809 else
810 mach64->accel.src_y_count = mach64->accel.src_height1;
811 }
813 mach64->accel.dst_height--;
815 if (mach64->accel.dst_height <= 0)
816 {
817 /*Blit finished*/
818 #ifdef MACH64_DEBUG
819 pclog("mach64 blit finished\n");
820 #endif
821 mach64->accel.busy = 0;
822 if (mach64->dst_cntl & DST_X_TILE)
823 mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000);
824 if (mach64->dst_cntl & DST_Y_TILE)
825 mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + mach64->accel.dst_height) & 0xfff);
826 return;
827 }
828 if (mach64->accel.source_host)
829 return;
830 }
831 }
832 break;
834 case OP_LINE:
835 while (count)
836 {
837 uint32_t src_dat, dest_dat;
838 uint32_t host_dat;
839 int mix;
841 if (mach64->accel.source_host)
842 {
843 host_dat = cpu_dat;
844 switch (mach64->accel.src_size)
845 {
846 case 0:
847 cpu_dat >>= 8;
848 count -= 8;
849 break;
850 case 1:
851 cpu_dat >>= 16;
852 count -= 16;
853 break;
854 case 2:
855 count -= 32;
856 break;
857 }
858 }
859 else
860 count--;
862 switch (mach64->accel.source_mix)
863 {
864 case MONO_SRC_HOST:
865 mix = cpu_dat >> 31;
866 cpu_dat <<= 1;
867 break;
868 case MONO_SRC_PAT:
869 mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7];
870 break;
871 case MONO_SRC_1:
872 default:
873 mix = 1;
874 break;
875 }
877 if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right &&
878 mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom)
879 {
880 switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
881 {
882 case SRC_HOST:
883 src_dat = host_dat;
884 break;
885 case SRC_BLITSRC:
886 READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size);
887 break;
888 case SRC_FG:
889 src_dat = mach64->accel.dp_frgd_clr;
890 break;
891 case SRC_BG:
892 src_dat = mach64->accel.dp_bkgd_clr;
893 break;
894 default:
895 src_dat = 0;
896 break;
897 }
899 READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size);
901 // pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, mach64->accel.dst_y, (mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix);
903 switch (mach64->accel.clr_cmp_fn)
904 {
905 case 1: /*TRUE*/
906 cmp_clr = 1;
907 break;
908 case 4: /*DST_CLR != CLR_CMP_CLR*/
909 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr;
910 break;
911 case 5: /*DST_CLR == CLR_CMP_CLR*/
912 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr;
913 break;
914 }
916 if (!cmp_clr)
917 MIX
919 // pclog("%02X %i\n", dest_dat, mach64->accel.dst_height);
921 WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size);
922 }
924 mach64->accel.x_count--;
925 if (mach64->accel.x_count <= 0)
926 {
927 /*Blit finished*/
928 #ifdef MACH64_DEBUG
929 pclog("mach64 blit finished\n");
930 #endif
931 mach64->accel.busy = 0;
932 return;
933 }
935 switch (mach64->dst_cntl & 7)
936 {
937 case 0: case 2:
938 mach64->accel.src_x--;
939 mach64->accel.dst_x--;
940 break;
941 case 1: case 3:
942 mach64->accel.src_x++;
943 mach64->accel.dst_x++;
944 break;
945 case 4: case 5:
946 mach64->accel.src_y--;
947 mach64->accel.dst_y--;
948 break;
949 case 6: case 7:
950 mach64->accel.src_y++;
951 mach64->accel.dst_y++;
952 break;
953 }
954 #ifdef MACH64_DEBUG
955 pclog("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec);
956 #endif
957 if (mach64->accel.err >= 0)
958 {
959 mach64->accel.err += mach64->dst_bres_dec;
961 switch (mach64->dst_cntl & 7)
962 {
963 case 0: case 1:
964 mach64->accel.src_y--;
965 mach64->accel.dst_y--;
966 break;
967 case 2: case 3:
968 mach64->accel.src_y++;
969 mach64->accel.dst_y++;
970 break;
971 case 4: case 6:
972 mach64->accel.src_x--;
973 mach64->accel.dst_x--;
974 break;
975 case 5: case 7:
976 mach64->accel.src_x++;
977 mach64->accel.dst_x++;
978 break;
979 }
980 }
981 else
982 mach64->accel.err += mach64->dst_bres_inc;
983 }
984 break;
985 }
986 }
988 void mach64_load_context(mach64_t *mach64)
989 {
990 svga_t *svga = &mach64->svga;
991 uint32_t addr;
993 while (mach64->context_load_cntl & 0x30000)
994 {
995 addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask;
996 mach64->context_mask = *(uint32_t *)&svga->vram[addr];
997 #ifdef MACH64_DEBUG
998 pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask);
999 #endif
1001 if (mach64->context_mask & (1 << 2))
1002 mach64_ext_writel(0x100, *(uint32_t *)&svga->vram[addr + 0x08], mach64);
1003 if (mach64->context_mask & (1 << 3))
1004 mach64_ext_writel(0x10c, *(uint32_t *)&svga->vram[addr + 0x0c], mach64);
1005 if (mach64->context_mask & (1 << 4))
1006 mach64_ext_writel(0x118, *(uint32_t *)&svga->vram[addr + 0x10], mach64);
1007 if (mach64->context_mask & (1 << 5))
1008 mach64_ext_writel(0x124, *(uint32_t *)&svga->vram[addr + 0x14], mach64);
1009 if (mach64->context_mask & (1 << 6))
1010 mach64_ext_writel(0x128, *(uint32_t *)&svga->vram[addr + 0x18], mach64);
1011 if (mach64->context_mask & (1 << 7))
1012 mach64_ext_writel(0x12c, *(uint32_t *)&svga->vram[addr + 0x1c], mach64);
1013 if (mach64->context_mask & (1 << 8))
1014 mach64_ext_writel(0x180, *(uint32_t *)&svga->vram[addr + 0x20], mach64);
1015 if (mach64->context_mask & (1 << 9))
1016 mach64_ext_writel(0x18c, *(uint32_t *)&svga->vram[addr + 0x24], mach64);
1017 if (mach64->context_mask & (1 << 10))
1018 mach64_ext_writel(0x198, *(uint32_t *)&svga->vram[addr + 0x28], mach64);
1019 if (mach64->context_mask & (1 << 11))
1020 mach64_ext_writel(0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c], mach64);
1021 if (mach64->context_mask & (1 << 12))
1022 mach64_ext_writel(0x1b0, *(uint32_t *)&svga->vram[addr + 0x30], mach64);
1023 if (mach64->context_mask & (1 << 13))
1024 mach64_ext_writel(0x280, *(uint32_t *)&svga->vram[addr + 0x34], mach64);
1025 if (mach64->context_mask & (1 << 14))
1026 mach64_ext_writel(0x284, *(uint32_t *)&svga->vram[addr + 0x38], mach64);
1027 if (mach64->context_mask & (1 << 15))
1028 mach64_ext_writel(0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c], mach64);
1029 if (mach64->context_mask & (1 << 16))
1030 mach64_ext_writel(0x2b4, *(uint32_t *)&svga->vram[addr + 0x40], mach64);
1031 if (mach64->context_mask & (1 << 17))
1032 mach64_ext_writel(0x2c0, *(uint32_t *)&svga->vram[addr + 0x44], mach64);
1033 if (mach64->context_mask & (1 << 18))
1034 mach64_ext_writel(0x2c4, *(uint32_t *)&svga->vram[addr + 0x48], mach64);
1035 if (mach64->context_mask & (1 << 19))
1036 mach64_ext_writel(0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c], mach64);
1037 if (mach64->context_mask & (1 << 20))
1038 mach64_ext_writel(0x2cc, *(uint32_t *)&svga->vram[addr + 0x50], mach64);
1039 if (mach64->context_mask & (1 << 21))
1040 mach64_ext_writel(0x2d0, *(uint32_t *)&svga->vram[addr + 0x54], mach64);
1041 if (mach64->context_mask & (1 << 22))
1042 mach64_ext_writel(0x2d4, *(uint32_t *)&svga->vram[addr + 0x58], mach64);
1043 if (mach64->context_mask & (1 << 23))
1044 mach64_ext_writel(0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c], mach64);
1045 if (mach64->context_mask & (1 << 24))
1046 mach64_ext_writel(0x300, *(uint32_t *)&svga->vram[addr + 0x60], mach64);
1047 if (mach64->context_mask & (1 << 25))
1048 mach64_ext_writel(0x304, *(uint32_t *)&svga->vram[addr + 0x64], mach64);
1049 if (mach64->context_mask & (1 << 26))
1050 mach64_ext_writel(0x308, *(uint32_t *)&svga->vram[addr + 0x68], mach64);
1051 if (mach64->context_mask & (1 << 27))
1052 mach64_ext_writel(0x330, *(uint32_t *)&svga->vram[addr + 0x6c], mach64);
1054 mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70];
1058 uint8_t mach64_ext_readb(uint32_t addr, void *p)
1060 mach64_t *mach64 = (mach64_t *)p;
1061 uint8_t ret;
1062 switch (addr & 0x3ff)
1064 case 0x00: case 0x01: case 0x02: case 0x03:
1065 READ8(addr, mach64->crtc_h_total_disp);
1066 break;
1067 case 0x08: case 0x09: case 0x0a: case 0x0b:
1068 READ8(addr, mach64->crtc_v_total_disp);
1069 break;
1070 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
1071 READ8(addr, mach64->crtc_v_sync_strt_wid);
1072 break;
1074 case 0x12: case 0x13:
1075 READ8(addr - 2, mach64->svga.vc);
1076 break;
1078 case 0x14: case 0x15: case 0x16: case 0x17:
1079 READ8(addr, mach64->crtc_off_pitch);
1080 break;
1082 case 0x18:
1083 ret = mach64->crtc_int_cntl & ~1;
1084 if (mach64->svga.cgastat & 8)
1085 ret |= 1;
1086 break;
1088 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
1089 READ8(addr, mach64->crtc_gen_cntl);
1090 break;
1092 case 0x40: case 0x41: case 0x42: case 0x43:
1093 READ8(addr, mach64->ovr_clr);
1094 break;
1095 case 0x44: case 0x45: case 0x46: case 0x47:
1096 READ8(addr, mach64->ovr_wid_left_right);
1097 break;
1098 case 0x48: case 0x49: case 0x4a: case 0x4b:
1099 READ8(addr, mach64->ovr_wid_top_bottom);
1100 break;
1102 case 0x68: case 0x69: case 0x6a: case 0x6b:
1103 READ8(addr, mach64->cur_offset);
1104 break;
1105 case 0x6c: case 0x6d: case 0x6e: case 0x6f:
1106 READ8(addr, mach64->cur_horz_vert_posn);
1107 break;
1108 case 0x70: case 0x71: case 0x72: case 0x73:
1109 READ8(addr, mach64->cur_horz_vert_off);
1110 break;
1112 case 0x80: case 0x81: case 0x82: case 0x83:
1113 READ8(addr, mach64->scratch_reg0);
1114 break;
1115 case 0x84: case 0x85: case 0x86: case 0x87:
1116 READ8(addr, mach64->scratch_reg1);
1117 break;
1119 case 0x90: case 0x91: case 0x92: case 0x93:
1120 READ8(addr, mach64->clock_cntl);
1121 break;
1123 case 0xb0: case 0xb1: case 0xb2: case 0xb3:
1124 READ8(addr, mach64->mem_cntl);
1125 break;
1127 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1128 ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga);
1129 break;
1130 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1131 READ8(addr, mach64->dac_cntl);
1132 break;
1134 case 0xd0: case 0xd1: case 0xd2: case 0xd3:
1135 READ8(addr, mach64->gen_test_cntl);
1136 break;
1138 case 0xe0: case 0xe1: case 0xe2: case 0xe3:
1139 READ8(addr, 0x020000d7); /*88800GX-2*/
1140 break;
1142 case 0x100: case 0x101: case 0x102: case 0x103:
1143 READ8(addr, mach64->dst_off_pitch);
1144 break;
1145 case 0x104: case 0x105:
1146 READ8(addr, mach64->dst_y_x);
1147 break;
1148 case 0x108: case 0x109: case 0x11c: case 0x11d:
1149 READ8(addr + 2, mach64->dst_y_x);
1150 break;
1151 case 0x10c: case 0x10d: case 0x10e: case 0x10f:
1152 READ8(addr, mach64->dst_y_x);
1153 break;
1154 case 0x110: case 0x111:
1155 addr += 2;
1156 case 0x114: case 0x115:
1157 case 0x118: case 0x119: case 0x11a: case 0x11b:
1158 case 0x11e: case 0x11f:
1159 READ8(addr, mach64->dst_height_width);
1160 break;
1162 case 0x120: case 0x121: case 0x122: case 0x123:
1163 READ8(addr, mach64->dst_bres_lnth);
1164 break;
1165 case 0x124: case 0x125: case 0x126: case 0x127:
1166 READ8(addr, mach64->dst_bres_err);
1167 break;
1168 case 0x128: case 0x129: case 0x12a: case 0x12b:
1169 READ8(addr, mach64->dst_bres_inc);
1170 break;
1171 case 0x12c: case 0x12d: case 0x12e: case 0x12f:
1172 READ8(addr, mach64->dst_bres_dec);
1173 break;
1175 case 0x130: case 0x131: case 0x132: case 0x133:
1176 READ8(addr, mach64->dst_cntl);
1177 break;
1179 case 0x180: case 0x181: case 0x182: case 0x183:
1180 READ8(addr, mach64->src_off_pitch);
1181 break;
1182 case 0x184: case 0x185:
1183 READ8(addr, mach64->src_y_x);
1184 break;
1185 case 0x188: case 0x189:
1186 READ8(addr + 2, mach64->src_y_x);
1187 break;
1188 case 0x18c: case 0x18d: case 0x18e: case 0x18f:
1189 READ8(addr, mach64->src_y_x);
1190 break;
1191 case 0x190: case 0x191:
1192 READ8(addr + 2, mach64->src_height1_width1);
1193 break;
1194 case 0x194: case 0x195:
1195 READ8(addr, mach64->src_height1_width1);
1196 break;
1197 case 0x198: case 0x199: case 0x19a: case 0x19b:
1198 READ8(addr, mach64->src_height1_width1);
1199 break;
1200 case 0x19c: case 0x19d:
1201 READ8(addr, mach64->src_y_x_start);
1202 break;
1203 case 0x1a0: case 0x1a1:
1204 READ8(addr + 2, mach64->src_y_x_start);
1205 break;
1206 case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7:
1207 READ8(addr, mach64->src_y_x_start);
1208 break;
1209 case 0x1a8: case 0x1a9:
1210 READ8(addr + 2, mach64->src_height2_width2);
1211 break;
1212 case 0x1ac: case 0x1ad:
1213 READ8(addr, mach64->src_height2_width2);
1214 break;
1215 case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3:
1216 READ8(addr, mach64->src_height2_width2);
1217 break;
1219 case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
1220 READ8(addr, mach64->src_cntl);
1221 break;
1223 case 0x280: case 0x281: case 0x282: case 0x283:
1224 READ8(addr, mach64->pat_reg0);
1225 break;
1226 case 0x284: case 0x285: case 0x286: case 0x287:
1227 READ8(addr, mach64->pat_reg1);
1228 break;
1230 case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
1231 READ8(addr, mach64->sc_left_right);
1232 break;
1233 case 0x2a4: case 0x2a5:
1234 addr += 2;
1235 case 0x2aa: case 0x2ab:
1236 READ8(addr, mach64->sc_left_right);
1237 break;
1239 case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
1240 READ8(addr, mach64->sc_top_bottom);
1241 break;
1242 case 0x2b0: case 0x2b1:
1243 addr += 2;
1244 case 0x2b6: case 0x2b7:
1245 READ8(addr, mach64->sc_top_bottom);
1246 break;
1248 case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
1249 READ8(addr, mach64->dp_bkgd_clr);
1250 break;
1251 case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
1252 READ8(addr, mach64->dp_frgd_clr);
1253 break;
1255 case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
1256 READ8(addr, mach64->dp_pix_width);
1257 break;
1258 case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
1259 READ8(addr, mach64->dp_mix);
1260 break;
1261 case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
1262 READ8(addr, mach64->dp_src);
1263 break;
1265 case 0x300: case 0x301: case 0x302: case 0x303:
1266 READ8(addr, mach64->clr_cmp_clr);
1267 break;
1268 case 0x304: case 0x305: case 0x306: case 0x307:
1269 READ8(addr, mach64->clr_cmp_mask);
1270 break;
1271 case 0x308: case 0x309: case 0x30a: case 0x30b:
1272 READ8(addr, mach64->clr_cmp_cntl);
1273 break;
1275 case 0x320: case 0x321: case 0x322: case 0x323:
1276 READ8(addr, mach64->context_mask);
1277 break;
1279 case 0x330: case 0x331:
1280 READ8(addr, mach64->dst_cntl);
1281 break;
1282 case 0x332:
1283 READ8(addr - 2, mach64->src_cntl);
1284 break;
1285 case 0x333:
1286 READ8(addr - 3, mach64->pat_cntl);
1287 break;
1289 default:
1290 ret = 0;
1291 break;
1293 #ifdef MACH64_DEBUG
1294 if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readb : addr %08X ret %02X\n", addr, ret);
1295 #endif
1296 return ret;
1298 uint16_t mach64_ext_readw(uint32_t addr, void *p)
1300 mach64_t *mach64 = (mach64_t *)p;
1301 uint16_t ret;
1302 switch (addr & 0x3ff)
1304 default:
1305 #ifdef MACH64_DEBUG
1306 pclog(" ");
1307 #endif
1308 ret = mach64_ext_readb(addr, p);
1309 #ifdef MACH64_DEBUG
1310 pclog(" ");
1311 #endif
1312 ret |= mach64_ext_readb(addr + 1, p) << 8;
1313 break;
1315 #ifdef MACH64_DEBUG
1316 if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readw : addr %08X ret %04X\n", addr, ret);
1317 #endif
1318 return ret;
1320 uint32_t mach64_ext_readl(uint32_t addr, void *p)
1322 mach64_t *mach64 = (mach64_t *)p;
1323 uint32_t ret;
1324 switch (addr & 0x3ff)
1326 case 0x18:
1327 ret = mach64->crtc_int_cntl & ~1;
1328 if (mach64->svga.cgastat & 8)
1329 ret |= 1;
1330 break;
1332 case 0xb4:
1333 ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16);
1334 break;
1335 case 0xb8:
1336 ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16);
1337 break;
1339 default:
1340 #ifdef MACH64_DEBUG
1341 pclog(" ");
1342 #endif
1343 ret = mach64_ext_readw(addr, p);
1344 #ifdef MACH64_DEBUG
1345 pclog(" ");
1346 #endif
1347 ret |= mach64_ext_readw(addr + 2, p) << 16;
1348 break;
1350 #ifdef MACH64_DEBUG
1351 if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readl : addr %08X ret %08X\n", addr, ret);
1352 #endif
1353 return ret;
1356 void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
1358 mach64_t *mach64 = (mach64_t *)p;
1359 svga_t *svga = &mach64->svga;
1360 #ifdef MACH64_DEBUG
1361 pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val);
1362 #endif
1363 switch (addr & 0x3ff)
1365 case 0x00: case 0x01: case 0x02: case 0x03:
1366 WRITE8(addr, mach64->crtc_h_total_disp, val);
1367 svga_recalctimings(&mach64->svga);
1368 break;
1369 case 0x08: case 0x09: case 0x0a: case 0x0b:
1370 WRITE8(addr, mach64->crtc_v_total_disp, val);
1371 svga_recalctimings(&mach64->svga);
1372 break;
1373 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
1374 WRITE8(addr, mach64->crtc_v_sync_strt_wid, val);
1375 svga_recalctimings(&mach64->svga);
1376 break;
1378 case 0x14: case 0x15: case 0x16: case 0x17:
1379 WRITE8(addr, mach64->crtc_off_pitch, val);
1380 svga_recalctimings(&mach64->svga);
1381 svga->fullchange = changeframecount;
1382 break;
1384 case 0x18:
1385 mach64->crtc_int_cntl = val;
1386 break;
1388 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
1389 WRITE8(addr, mach64->crtc_gen_cntl, val);
1390 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
1391 svga->fb_only = 1;
1392 else
1393 svga->fb_only = 0;
1394 svga_recalctimings(&mach64->svga);
1395 break;
1397 case 0x40: case 0x41: case 0x42: case 0x43:
1398 WRITE8(addr, mach64->ovr_clr, val);
1399 break;
1400 case 0x44: case 0x45: case 0x46: case 0x47:
1401 WRITE8(addr, mach64->ovr_wid_left_right, val);
1402 break;
1403 case 0x48: case 0x49: case 0x4a: case 0x4b:
1404 WRITE8(addr, mach64->ovr_wid_top_bottom, val);
1405 break;
1407 case 0x68: case 0x69: case 0x6a: case 0x6b:
1408 WRITE8(addr, mach64->cur_offset, val);
1409 svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8;
1410 mach64_cursor_dump(mach64);
1411 break;
1412 case 0x6c: case 0x6d: case 0x6e: case 0x6f:
1413 WRITE8(addr, mach64->cur_horz_vert_posn, val);
1414 svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
1415 svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
1416 mach64_cursor_dump(mach64);
1417 break;
1418 case 0x70: case 0x71: case 0x72: case 0x73:
1419 WRITE8(addr, mach64->cur_horz_vert_off, val);
1420 svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
1421 svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
1422 mach64_cursor_dump(mach64);
1423 break;
1425 case 0x80: case 0x81: case 0x82: case 0x83:
1426 WRITE8(addr, mach64->scratch_reg0, val);
1427 break;
1428 case 0x84: case 0x85: case 0x86: case 0x87:
1429 WRITE8(addr, mach64->scratch_reg1, val);
1430 break;
1432 case 0x90: case 0x91: case 0x92: case 0x93:
1433 WRITE8(addr, mach64->clock_cntl, val);
1434 ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf);
1435 svga_recalctimings(&mach64->svga);
1436 break;
1438 case 0xb0: case 0xb1: case 0xb2: case 0xb3:
1439 WRITE8(addr, mach64->mem_cntl, val);
1440 break;
1442 case 0xb4:
1443 mach64->bank_w[0] = val * 32768;
1444 #ifdef MACH64_DEBUG
1445 pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]);
1446 #endif
1447 break;
1448 case 0xb5: case 0xb6:
1449 mach64->bank_w[1] = val * 32768;
1450 #ifdef MACH64_DEBUG
1451 pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]);
1452 #endif
1453 break;
1454 case 0xb8:
1455 mach64->bank_r[0] = val * 32768;
1456 #ifdef MACH64_DEBUG
1457 pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]);
1458 #endif
1459 break;
1460 case 0xb9: case 0xba:
1461 mach64->bank_r[1] = val * 32768;
1462 #ifdef MACH64_DEBUG
1463 pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]);
1464 #endif
1465 break;
1467 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1468 ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga);
1469 break;
1470 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1471 WRITE8(addr, mach64->dac_cntl, val);
1472 break;
1474 case 0xd0: case 0xd1: case 0xd2: case 0xd3:
1475 WRITE8(addr, mach64->gen_test_cntl, val);
1476 // if (val == 2) output = 3;
1477 ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1);
1478 mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0);
1479 svga->hwcursor.ena = mach64->gen_test_cntl & 0x80;
1480 mach64_cursor_dump(mach64);
1481 break;
1483 case 0x100: case 0x101: case 0x102: case 0x103:
1484 WRITE8(addr, mach64->dst_off_pitch, val);
1485 break;
1486 case 0x104: case 0x105: case 0x11c: case 0x11d:
1487 WRITE8(addr + 2, mach64->dst_y_x, val);
1488 break;
1489 case 0x108: case 0x109:
1490 WRITE8(addr, mach64->dst_y_x, val);
1491 break;
1492 case 0x10c: case 0x10d: case 0x10e: case 0x10f:
1493 WRITE8(addr, mach64->dst_y_x, val);
1494 break;
1495 case 0x110: case 0x111:
1496 WRITE8(addr + 2, mach64->dst_height_width, val);
1497 break;
1498 case 0x114: case 0x115:
1499 case 0x118: case 0x119: case 0x11a: case 0x11b:
1500 case 0x11e: case 0x11f:
1501 WRITE8(addr, mach64->dst_height_width, val);
1502 case 0x113:
1503 if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f ||
1504 ((addr & 0x3ff) == 0x113) && !(val & 0x80))
1506 mach64_start_fill(mach64);
1507 #ifdef MACH64_DEBUG
1508 pclog("%i %i %i %i %i\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000),
1509 ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST),
1510 (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST));
1511 #endif
1512 if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) &&
1513 ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) &&
1514 (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST))
1515 mach64_blit(0, -1, mach64);
1517 break;
1519 case 0x120: case 0x121: case 0x122: case 0x123:
1520 WRITE8(addr, mach64->dst_bres_lnth, val);
1521 if ((addr & 0x3ff) == 0x123 && !(val & 0x80))
1523 mach64_start_line(mach64);
1525 if ((mach64->dst_bres_lnth & 0x7fff) &&
1526 ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) &&
1527 (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST))
1528 mach64_blit(0, -1, mach64);
1530 break;
1531 case 0x124: case 0x125: case 0x126: case 0x127:
1532 WRITE8(addr, mach64->dst_bres_err, val);
1533 break;
1534 case 0x128: case 0x129: case 0x12a: case 0x12b:
1535 WRITE8(addr, mach64->dst_bres_inc, val);
1536 break;
1537 case 0x12c: case 0x12d: case 0x12e: case 0x12f:
1538 WRITE8(addr, mach64->dst_bres_dec, val);
1539 break;
1541 case 0x130: case 0x131: case 0x132: case 0x133:
1542 WRITE8(addr, mach64->dst_cntl, val);
1543 break;
1545 case 0x180: case 0x181: case 0x182: case 0x183:
1546 WRITE8(addr, mach64->src_off_pitch, val);
1547 break;
1548 case 0x184: case 0x185:
1549 WRITE8(addr, mach64->src_y_x, val);
1550 break;
1551 case 0x188: case 0x189:
1552 WRITE8(addr + 2, mach64->src_y_x, val);
1553 break;
1554 case 0x18c: case 0x18d: case 0x18e: case 0x18f:
1555 WRITE8(addr, mach64->src_y_x, val);
1556 break;
1557 case 0x190: case 0x191:
1558 WRITE8(addr + 2, mach64->src_height1_width1, val);
1559 break;
1560 case 0x194: case 0x195:
1561 WRITE8(addr, mach64->src_height1_width1, val);
1562 break;
1563 case 0x198: case 0x199: case 0x19a: case 0x19b:
1564 WRITE8(addr, mach64->src_height1_width1, val);
1565 break;
1566 case 0x19c: case 0x19d:
1567 WRITE8(addr, mach64->src_y_x_start, val);
1568 break;
1569 case 0x1a0: case 0x1a1:
1570 WRITE8(addr + 2, mach64->src_y_x_start, val);
1571 break;
1572 case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7:
1573 WRITE8(addr, mach64->src_y_x_start, val);
1574 break;
1575 case 0x1a8: case 0x1a9:
1576 WRITE8(addr + 2, mach64->src_height2_width2, val);
1577 break;
1578 case 0x1ac: case 0x1ad:
1579 WRITE8(addr, mach64->src_height2_width2, val);
1580 break;
1581 case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3:
1582 WRITE8(addr, mach64->src_height2_width2, val);
1583 break;
1585 case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
1586 WRITE8(addr, mach64->src_cntl, val);
1587 break;
1589 case 0x200: case 0x201: case 0x202: case 0x203:
1590 case 0x204: case 0x205: case 0x206: case 0x207:
1591 case 0x208: case 0x209: case 0x20a: case 0x20b:
1592 case 0x20c: case 0x20d: case 0x20e: case 0x20f:
1593 case 0x210: case 0x211: case 0x212: case 0x213:
1594 case 0x214: case 0x215: case 0x216: case 0x217:
1595 case 0x218: case 0x219: case 0x21a: case 0x21b:
1596 case 0x21c: case 0x21d: case 0x21e: case 0x21f:
1597 case 0x220: case 0x221: case 0x222: case 0x223:
1598 case 0x224: case 0x225: case 0x226: case 0x227:
1599 case 0x228: case 0x229: case 0x22a: case 0x22b:
1600 case 0x22c: case 0x22d: case 0x22e: case 0x22f:
1601 case 0x230: case 0x231: case 0x232: case 0x233:
1602 case 0x234: case 0x235: case 0x236: case 0x237:
1603 case 0x238: case 0x239: case 0x23a: case 0x23b:
1604 case 0x23c: case 0x23d: case 0x23e: case 0x23f:
1605 mach64_blit(val, 8, mach64);
1606 break;
1608 case 0x280: case 0x281: case 0x282: case 0x283:
1609 WRITE8(addr, mach64->pat_reg0, val);
1610 break;
1611 case 0x284: case 0x285: case 0x286: case 0x287:
1612 WRITE8(addr, mach64->pat_reg1, val);
1613 break;
1615 case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
1616 WRITE8(addr, mach64->sc_left_right, val);
1617 break;
1618 case 0x2a4: case 0x2a5:
1619 addr += 2;
1620 case 0x2aa: case 0x2ab:
1621 WRITE8(addr, mach64->sc_left_right, val);
1622 break;
1624 case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
1625 WRITE8(addr, mach64->sc_top_bottom, val);
1626 break;
1627 case 0x2b0: case 0x2b1:
1628 addr += 2;
1629 case 0x2b6: case 0x2b7:
1630 WRITE8(addr, mach64->sc_top_bottom, val);
1631 break;
1633 case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
1634 WRITE8(addr, mach64->dp_bkgd_clr, val);
1635 break;
1636 case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
1637 WRITE8(addr, mach64->dp_frgd_clr, val);
1638 break;
1640 case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
1641 WRITE8(addr, mach64->dp_pix_width, val);
1642 break;
1643 case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
1644 WRITE8(addr, mach64->dp_mix, val);
1645 break;
1646 case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
1647 WRITE8(addr, mach64->dp_src, val);
1648 break;
1650 case 0x300: case 0x301: case 0x302: case 0x303:
1651 WRITE8(addr, mach64->clr_cmp_clr, val);
1652 break;
1653 case 0x304: case 0x305: case 0x306: case 0x307:
1654 WRITE8(addr, mach64->clr_cmp_mask, val);
1655 break;
1656 case 0x308: case 0x309: case 0x30a: case 0x30b:
1657 WRITE8(addr, mach64->clr_cmp_cntl, val);
1658 break;
1660 case 0x320: case 0x321: case 0x322: case 0x323:
1661 WRITE8(addr, mach64->context_mask, val);
1662 break;
1664 case 0x330: case 0x331:
1665 WRITE8(addr, mach64->dst_cntl, val);
1666 break;
1667 case 0x332:
1668 WRITE8(addr - 2, mach64->src_cntl, val);
1669 break;
1670 case 0x333:
1671 WRITE8(addr - 3, mach64->pat_cntl, val & 7);
1672 break;
1675 void mach64_ext_writew(uint32_t addr, uint16_t val, void *p)
1677 mach64_t *mach64 = (mach64_t *)p;
1678 #ifdef MACH64_DEBUG
1679 pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val);
1680 #endif
1681 switch (addr & 0x3fe)
1683 case 0x200: case 0x202: case 0x204: case 0x206:
1684 case 0x208: case 0x20a: case 0x20c: case 0x20e:
1685 case 0x210: case 0x212: case 0x214: case 0x216:
1686 case 0x218: case 0x21a: case 0x21c: case 0x21e:
1687 case 0x220: case 0x222: case 0x224: case 0x226:
1688 case 0x228: case 0x22a: case 0x22c: case 0x22e:
1689 case 0x230: case 0x232: case 0x234: case 0x236:
1690 case 0x238: case 0x23a: case 0x23c: case 0x23e:
1691 mach64_blit(val, 16, mach64);
1692 break;
1694 default:
1695 #ifdef MACH64_DEBUG
1696 pclog(" ");
1697 #endif
1698 mach64_ext_writeb(addr, val, p);
1699 #ifdef MACH64_DEBUG
1700 pclog(" ");
1701 #endif
1702 mach64_ext_writeb(addr + 1, val >> 8, p);
1703 break;
1706 void mach64_ext_writel(uint32_t addr, uint32_t val, void *p)
1708 mach64_t *mach64 = (mach64_t *)p;
1709 #ifdef MACH64_DEBUG
1710 if ((addr & 0x3c0) != 0x200)
1711 pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val);
1712 #endif
1713 switch (addr & 0x3fc)
1715 case 0x32c:
1716 mach64->context_load_cntl = val;
1717 if (val & 0x30000)
1718 mach64_load_context(mach64);
1719 break;
1721 case 0x200: case 0x204: case 0x208: case 0x20c:
1722 case 0x210: case 0x214: case 0x218: case 0x21c:
1723 case 0x220: case 0x224: case 0x228: case 0x22c:
1724 case 0x230: case 0x234: case 0x238: case 0x23c:
1725 if (mach64->accel.source_host)
1726 mach64_blit(val, 32, mach64);
1727 else
1728 mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64);
1729 break;
1731 default:
1732 #ifdef MACH64_DEBUG
1733 pclog(" ");
1734 #endif
1735 mach64_ext_writew(addr, val, p);
1736 #ifdef MACH64_DEBUG
1737 pclog(" ");
1738 #endif
1739 mach64_ext_writew(addr + 2, val >> 16, p);
1740 break;
1744 uint8_t mach64_ext_inb(uint16_t port, void *p)
1746 mach64_t *mach64 = (mach64_t *)p;
1747 uint8_t ret;
1748 // if (CS == 0x2be7) output = 3;
1749 switch (port)
1751 case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
1752 case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
1753 ret = mach64_ext_readb(0x00 | (port & 3), p);
1754 break;
1755 case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
1756 ret = mach64_ext_readb(0x08 | (port & 3), p);
1757 break;
1758 case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
1759 ret = mach64_ext_readb(0x0c | (port & 3), p);
1760 break;
1762 case 0x12ec: case 0x12ed: case 0x12ee: case 0x12ef:
1763 ret = mach64_ext_readb(0x10 | (port & 3), p);
1764 break;
1766 case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
1767 ret = mach64_ext_readb(0x14 | (port & 3), p);
1768 break;
1770 case 0x1aec:
1771 ret = mach64_ext_readb(0x18, p);
1772 break;
1774 case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
1775 ret = mach64_ext_readb(0x1c | (port & 3), p);
1776 break;
1778 case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef:
1779 ret = mach64_ext_readb(0x40 | (port & 3), p);
1780 break;
1781 case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef:
1782 ret = mach64_ext_readb(0x44 | (port & 3), p);
1783 break;
1784 case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef:
1785 ret = mach64_ext_readb(0x48 | (port & 3), p);
1786 break;
1788 case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
1789 ret = mach64_ext_readb(0x68 | (port & 3), p);
1790 break;
1791 case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
1792 ret = mach64_ext_readb(0x6c | (port & 3), p);
1793 break;
1794 case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
1795 ret = mach64_ext_readb(0x70 | (port & 3), p);
1796 break;
1798 case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
1799 ret = mach64_ext_readb(0x80 | (port & 3), p);
1800 break;
1801 case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
1802 ret = mach64_ext_readb(0x84 | (port & 3), p);
1803 break;
1804 case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
1805 ret = mach64_ext_readb(0x90 | (port & 3), p);
1806 break;
1808 case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
1809 ret = mach64_ext_readb(0xb0 | (port & 3), p);
1810 break;
1812 case 0x56ec:
1813 ret = mach64_ext_readb(0xb4, p);
1814 break;
1815 case 0x56ed: case 0x56ee:
1816 ret = mach64_ext_readb(0xb5, p);
1817 break;
1818 case 0x5aec:
1819 ret = mach64_ext_readb(0xb8, p);
1820 break;
1821 case 0x5aed: case 0x5aee:
1822 ret = mach64_ext_readb(0xb9, p);
1823 break;
1825 case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
1826 ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga);
1827 break;
1829 case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
1830 ret = mach64_ext_readb(0xc4 | (port & 3), p);
1831 break;
1833 case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
1834 ret = mach64_ext_readb(0xd0 | (port & 3), p);
1835 break;
1837 case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
1838 mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4);
1839 READ8(port, mach64->config_cntl);
1840 break;
1842 case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef:
1843 ret = mach64_ext_readb(0xe0 | (port & 3), p);
1844 break;
1846 case 0x72ec:
1847 ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/
1848 break;
1850 default:
1851 ret = 0;
1852 break;
1854 #ifdef MACH64_DEBUG
1855 pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,pc);
1856 #endif
1857 return ret;
1859 uint16_t mach64_ext_inw(uint16_t port, void *p)
1861 mach64_t *mach64 = (mach64_t *)p;
1862 uint16_t ret;
1863 switch (port)
1865 default:
1866 #ifdef MACH64_DEBUG
1867 pclog(" ");
1868 #endif
1869 ret = mach64_ext_inb(port, p);
1870 #ifdef MACH64_DEBUG
1871 pclog(" ");
1872 #endif
1873 ret |= (mach64_ext_inb(port + 1, p) << 8);
1874 break;
1876 #ifdef MACH64_DEBUG
1877 pclog("mach64_ext_inw : port %04X ret %04X\n", port, ret);
1878 #endif
1879 return ret;
1881 uint32_t mach64_ext_inl(uint16_t port, void *p)
1883 mach64_t *mach64 = (mach64_t *)p;
1884 uint32_t ret;
1885 switch (port)
1887 case 0x56ec:
1888 ret = mach64_ext_readl(0xb4, p);
1889 break;
1890 case 0x5aec:
1891 ret = mach64_ext_readl(0xb8, p);
1892 break;
1894 default:
1895 #ifdef MACH64_DEBUG
1896 pclog(" ");
1897 #endif
1898 ret = mach64_ext_inw(port, p);
1899 #ifdef MACH64_DEBUG
1900 pclog(" ");
1901 #endif
1902 ret |= (mach64_ext_inw(port + 2, p) << 16);
1903 break;
1905 #ifdef MACH64_DEBUG
1906 pclog("mach64_ext_inl : port %04X ret %08X\n", port, ret);
1907 #endif
1908 return ret;
1911 void mach64_ext_outb(uint16_t port, uint8_t val, void *p)
1913 mach64_t *mach64 = (mach64_t *)p;
1914 #ifdef MACH64_DEBUG
1915 pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,pc);
1916 #endif
1917 switch (port)
1919 case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
1920 case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
1921 mach64_ext_writeb(0x00 | (port & 3), val, p);
1922 break;
1923 case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
1924 mach64_ext_writeb(0x08 | (port & 3), val, p);
1925 break;
1926 case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
1927 mach64_ext_writeb(0x0c | (port & 3), val, p);
1928 break;
1930 case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
1931 mach64_ext_writeb(0x14 | (port & 3), val, p);
1932 break;
1934 case 0x1aec:
1935 mach64_ext_writeb(0x18, val, p);
1936 break;
1938 case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
1939 mach64_ext_writeb(0x1c | (port & 3), val, p);
1940 break;
1942 case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef:
1943 mach64_ext_writeb(0x40 | (port & 3), val, p);
1944 break;
1945 case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef:
1946 mach64_ext_writeb(0x44 | (port & 3), val, p);
1947 break;
1948 case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef:
1949 mach64_ext_writeb(0x48 | (port & 3), val, p);
1950 break;
1952 case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
1953 mach64_ext_writeb(0x68 | (port & 3), val, p);
1954 break;
1955 case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
1956 mach64_ext_writeb(0x6c | (port & 3), val, p);
1957 break;
1958 case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
1959 mach64_ext_writeb(0x70 | (port & 3), val, p);
1960 break;
1962 case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
1963 mach64_ext_writeb(0x80 | (port & 3), val, p);
1964 break;
1965 case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
1966 mach64_ext_writeb(0x84 | (port & 3), val, p);
1967 break;
1968 case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
1969 mach64_ext_writeb(0x90 | (port & 3), val, p);
1970 break;
1972 case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
1973 mach64_ext_writeb(0xb0 | (port & 3), val, p);
1974 break;
1976 case 0x56ec:
1977 mach64_ext_writeb(0xb4, val, p);
1978 break;
1979 case 0x56ed: case 0x56ee:
1980 mach64_ext_writeb(0xb5, val, p);
1981 break;
1982 case 0x5aec:
1983 mach64_ext_writeb(0xb8, val, p);
1984 break;
1985 case 0x5aed: case 0x5aee:
1986 mach64_ext_writeb(0xb9, val, p);
1987 break;
1989 case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
1990 ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga);
1991 break;
1993 case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
1994 mach64_ext_writeb(0xc4 | (port & 3), val, p);
1995 break;
1997 case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
1998 mach64_ext_writeb(0xd0 | (port & 3), val, p);
1999 break;
2001 case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
2002 WRITE8(port, mach64->config_cntl, val);
2003 mach64_updatemapping(mach64);
2004 break;
2007 void mach64_ext_outw(uint16_t port, uint16_t val, void *p)
2009 mach64_t *mach64 = (mach64_t *)p;
2010 #ifdef MACH64_DEBUG
2011 pclog("mach64_ext_outw : port %04X val %04X\n", port, val);
2012 #endif
2013 switch (port)
2015 default:
2016 #ifdef MACH64_DEBUG
2017 pclog(" ");
2018 #endif
2019 mach64_ext_outb(port, val, p);
2020 #ifdef MACH64_DEBUG
2021 pclog(" ");
2022 #endif
2023 mach64_ext_outb(port + 1, val >> 8, p);
2024 break;
2027 void mach64_ext_outl(uint16_t port, uint32_t val, void *p)
2029 mach64_t *mach64 = (mach64_t *)p;
2030 pclog("mach64_ext_outl : port %04X val %08X\n", port, val);
2031 switch (port)
2033 default:
2034 #ifdef MACH64_DEBUG
2035 pclog(" ");
2036 #endif
2037 mach64_ext_outw(port, val, p);
2038 #ifdef MACH64_DEBUG
2039 pclog(" ");
2040 #endif
2041 mach64_ext_outw(port + 2, val >> 16, p);
2042 break;
2046 void mach64_write(uint32_t addr, uint8_t val, void *p)
2048 mach64_t *mach64 = (mach64_t *)p;
2049 svga_t *svga = &mach64->svga;
2050 // pclog("mach64_write : %05X %02X ", addr, val);
2051 addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1];
2052 // pclog("%08X\n", addr);
2053 svga_write_linear(addr, val, svga);
2056 uint8_t mach64_read(uint32_t addr, void *p)
2058 mach64_t *mach64 = (mach64_t *)p;
2059 svga_t *svga = &mach64->svga;
2060 uint8_t ret;
2061 // pclog("mach64_read : %05X ", addr);
2062 addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1];
2063 ret = svga_read_linear(addr, svga);
2064 // pclog("%08X %02X\n", addr, ret);
2065 return ret;
2068 void mach64_hwcursor_draw(svga_t *svga, int displine)
2070 int x, offset;
2071 uint8_t dat;
2072 offset = svga->hwcursor_latch.xoff;
2073 for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
2075 dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
2076 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0;
2077 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
2078 dat >>= 2;
2079 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0;
2080 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
2081 dat >>= 2;
2082 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0;
2083 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
2084 dat >>= 2;
2085 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0;
2086 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
2087 dat >>= 2;
2088 offset += 4;
2090 svga->hwcursor_latch.addr += 16;
2093 static void mach64_io_remove(mach64_t *mach64)
2095 int c;
2097 io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2099 for (c = 0; c < 8; c++)
2101 io_removehandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2102 io_removehandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2103 io_removehandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2104 io_removehandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2107 io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2110 static void mach64_io_set(mach64_t *mach64)
2112 int c;
2114 mach64_io_remove(mach64);
2116 io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2118 for (c = 0; c < 8; c++)
2120 io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2121 io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2122 io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2123 io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
2126 io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2129 uint8_t mach64_pci_read(int func, int addr, void *p)
2131 mach64_t *mach64 = (mach64_t *)p;
2132 svga_t *svga = &mach64->svga;
2134 // pclog("Mach64 PCI read %08X\n", addr);
2136 switch (addr)
2138 case 0x00: return 0x02; /*ATi*/
2139 case 0x01: return 0x10;
2141 case 0x02: return 'X'; /*88800GX*/
2142 case 0x03: return 'G';
2144 case PCI_REG_COMMAND:
2145 return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
2147 case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
2149 case 0x08: return 0; /*Revision ID*/
2150 case 0x09: return 0; /*Programming interface*/
2152 case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/
2153 case 0x0b: return 0x03;
2155 case 0x10: return 0x00; /*Linear frame buffer address*/
2156 case 0x11: return 0x00;
2157 case 0x12: return mach64->linear_base >> 16;
2158 case 0x13: return mach64->linear_base >> 24;
2160 case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/
2161 case 0x31: return 0x00;
2162 case 0x32: return mach64->pci_regs[0x32];
2163 case 0x33: return mach64->pci_regs[0x33];
2165 return 0;
2168 void mach64_pci_write(int func, int addr, uint8_t val, void *p)
2170 mach64_t *mach64 = (mach64_t *)p;
2172 // pclog("Mach64 PCI write %08X %02X\n", addr, val);
2174 switch (addr)
2176 case PCI_REG_COMMAND:
2177 mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27;
2178 if (val & PCI_COMMAND_IO)
2179 mach64_io_set(mach64);
2180 else
2181 mach64_io_remove(mach64);
2182 mach64_updatemapping(mach64);
2183 break;
2185 case 0x12:
2186 mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16);
2187 mach64_updatemapping(mach64);
2188 break;
2189 case 0x13:
2190 mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24);
2191 mach64_updatemapping(mach64);
2192 break;
2194 case 0x30: case 0x32: case 0x33:
2195 mach64->pci_regs[addr] = val;
2196 if (mach64->pci_regs[0x30] & 0x01)
2198 uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24);
2199 pclog("Mach64 bios_rom enabled at %08x\n", addr);
2200 mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000);
2202 else
2204 pclog("Mach64 bios_rom disabled\n");
2205 mem_mapping_disable(&mach64->bios_rom.mapping);
2207 return;
2211 void *mach64gx_init()
2213 int c;
2214 mach64_t *mach64 = malloc(sizeof(mach64_t));
2215 memset(mach64, 0, sizeof(mach64_t));
2217 mach64->vram_size = device_get_config_int("memory");
2218 mach64->vram_mask = (mach64->vram_size << 20) - 1;
2220 svga_init(&mach64->svga, mach64, mach64->vram_size << 20,
2221 mach64_recalctimings,
2222 mach64_in, mach64_out,
2223 mach64_hwcursor_draw,
2224 NULL);
2226 rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
2227 if (PCI)
2228 mem_mapping_disable(&mach64->bios_rom.mapping);
2230 mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga);
2231 mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64);
2232 mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64);
2233 mem_mapping_disable(&mach64->mmio_mapping);
2235 mach64_io_set(mach64);
2237 pci_add(mach64_pci_read, mach64_pci_write, mach64);
2239 mach64->pci_regs[PCI_REG_COMMAND] = 3;
2240 mach64->pci_regs[0x30] = 0x00;
2241 mach64->pci_regs[0x32] = 0x0c;
2242 mach64->pci_regs[0x33] = 0x00;
2244 ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1);
2246 mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/
2248 mach64->dst_cntl = 3;
2250 return mach64;
2253 int mach64gx_available()
2255 return rom_present("roms/mach64gx/bios.bin");
2258 void mach64_close(void *p)
2260 mach64_t *mach64 = (mach64_t *)p;
2262 svga_close(&mach64->svga);
2264 free(mach64);
2267 void mach64_speed_changed(void *p)
2269 mach64_t *mach64 = (mach64_t *)p;
2271 svga_recalctimings(&mach64->svga);
2274 void mach64_force_redraw(void *p)
2276 mach64_t *mach64 = (mach64_t *)p;
2278 mach64->svga.fullchange = changeframecount;
2281 void mach64_add_status_info(char *s, int max_len, void *p)
2283 mach64_t *mach64 = (mach64_t *)p;
2285 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
2287 svga_t *svga = &mach64->svga;
2288 char temps[128];
2289 int bpp = 4;
2291 strncat(s, "Mach64 in native mode\n", max_len);
2293 switch ((mach64->crtc_gen_cntl >> 8) & 7)
2295 case 1: bpp = 4; break;
2296 case 2: bpp = 8; break;
2297 case 3: bpp = 15; break;
2298 case 4: bpp = 16; break;
2299 case 5: bpp = 24; break;
2300 case 6: bpp = 32; break;
2303 sprintf(temps, "Mach64 colour depth : %i bpp\n", bpp);
2304 strncat(s, temps, max_len);
2306 sprintf(temps, "Mach64 resolution : %i x %i\n", svga->hdisp, svga->dispend);
2307 strncat(s, temps, max_len);
2309 sprintf(temps, "Mach64 refresh rate : %i Hz\n\n", svga->frames);
2310 svga->frames = 0;
2311 strncat(s, temps, max_len);
2313 else
2315 strncat(s, "Mach64 in SVGA mode\n", max_len);
2316 svga_add_status_info(s, max_len, &mach64->svga);
2320 static device_config_t mach64gx_config[] =
2323 .name = "memory",
2324 .description = "Memory size",
2325 .type = CONFIG_SELECTION,
2326 .selection =
2329 .description = "1 MB",
2330 .value = 1
2331 },
2333 .description = "2 MB",
2334 .value = 2
2335 },
2337 .description = "4 MB",
2338 .value = 4
2339 },
2341 .description = ""
2343 },
2344 .default_int = 4
2345 },
2347 .type = -1
2349 };
2351 device_t mach64gx_device =
2353 "ATI Mach64GX",
2354 0,
2355 mach64gx_init,
2356 mach64_close,
2357 mach64gx_available,
2358 mach64_speed_changed,
2359 mach64_force_redraw,
2360 mach64_add_status_info,
2361 mach64gx_config
2362 };