PCem

view src/vid_ati_mach64.c @ 160:5bddbc972079

Mach64 now identifies correctly as PCI when used with a PCI system.
author TomW
date Sat Sep 20 17:24:23 2014 +0100
parents abd5259486c3
children
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"
15 //#define MACH64_DEBUG
17 typedef struct mach64_t
18 {
19 mem_mapping_t linear_mapping;
20 mem_mapping_t mmio_mapping;
21 mem_mapping_t mmio_linear_mapping;
23 ati68860_ramdac_t ramdac;
24 ati_eeprom_t eeprom;
25 ics2595_t ics2595;
26 svga_t svga;
28 rom_t bios_rom;
30 uint8_t regs[256];
31 int index;
33 uint8_t pci_regs[256];
35 int bank_r[2];
36 int bank_w[2];
38 uint32_t vram_size;
39 uint32_t vram_mask;
41 uint32_t config_cntl;
43 uint32_t context_load_cntl;
44 uint32_t context_mask;
46 uint32_t crtc_gen_cntl;
47 uint8_t crtc_int_cntl;
48 uint32_t crtc_h_total_disp;
49 uint32_t crtc_v_sync_strt_wid;
50 uint32_t crtc_v_total_disp;
51 uint32_t crtc_off_pitch;
53 uint32_t clock_cntl;
55 uint32_t clr_cmp_clr;
56 uint32_t clr_cmp_cntl;
57 uint32_t clr_cmp_mask;
59 uint32_t cur_horz_vert_off;
60 uint32_t cur_horz_vert_posn;
61 uint32_t cur_offset;
63 uint32_t dac_cntl;
65 uint32_t dp_bkgd_clr;
66 uint32_t dp_frgd_clr;
67 uint32_t dp_mix;
68 uint32_t dp_pix_width;
69 uint32_t dp_src;
71 uint32_t dst_bres_lnth;
72 uint32_t dst_bres_dec;
73 uint32_t dst_bres_err;
74 uint32_t dst_bres_inc;
76 uint32_t dst_cntl;
77 uint32_t dst_height_width;
78 uint32_t dst_off_pitch;
79 uint32_t dst_y_x;
81 uint32_t gen_test_cntl;
83 uint32_t gui_traj_cntl;
85 uint32_t mem_cntl;
87 uint32_t ovr_clr;
88 uint32_t ovr_wid_left_right;
89 uint32_t ovr_wid_top_bottom;
91 uint32_t pat_cntl;
92 uint32_t pat_reg0, pat_reg1;
94 uint32_t sc_left_right, sc_top_bottom;
96 uint32_t scratch_reg0, scratch_reg1;
98 uint32_t src_cntl;
99 uint32_t src_off_pitch;
100 uint32_t src_y_x;
101 uint32_t src_y_x_start;
102 uint32_t src_height1_width1, src_height2_width2;
105 uint32_t linear_base, old_linear_base;
107 struct
108 {
109 int op;
111 int dst_x, dst_y;
112 int dst_x_start, dst_y_start;
113 int src_x, src_y;
114 int src_x_start, src_y_start;
115 int xinc, yinc;
116 int x_count, y_count;
117 int src_x_count, src_y_count;
118 int src_width1, src_height1;
119 int src_width2, src_height2;
120 uint32_t src_offset, src_pitch;
121 uint32_t dst_offset, dst_pitch;
122 int mix_bg, mix_fg;
123 int source_bg, source_fg, source_mix;
124 int source_host;
125 int dst_width, dst_height;
126 int busy;
127 int pattern[8][8];
128 int sc_left, sc_right, sc_top, sc_bottom;
129 int dst_pix_width, src_pix_width, host_pix_width;
130 int dst_size, src_size;
132 uint32_t dp_bkgd_clr;
133 uint32_t dp_frgd_clr;
135 uint32_t clr_cmp_clr;
136 uint32_t clr_cmp_mask;
137 int clr_cmp_fn;
138 int clr_cmp_src;
140 int err;
141 } accel;
142 } mach64_t;
144 enum
145 {
146 SRC_BG = 0,
147 SRC_FG = 1,
148 SRC_HOST = 2,
149 SRC_BLITSRC = 3,
150 SRC_PAT = 4
151 };
153 enum
154 {
155 MONO_SRC_1 = 0,
156 MONO_SRC_PAT = 1,
157 MONO_SRC_HOST = 2,
158 MONO_SRC_BLITSRC = 3
159 };
161 enum
162 {
163 BPP_1 = 0,
164 BPP_4 = 1,
165 BPP_8 = 2,
166 BPP_15 = 3,
167 BPP_16 = 4,
168 BPP_32 = 5
169 };
171 enum
172 {
173 OP_RECT,
174 OP_LINE
175 };
177 enum
178 {
179 SRC_PATT_EN = 1,
180 SRC_PATT_ROT_EN = 2,
181 SRC_LINEAR_EN = 4
182 };
184 enum
185 {
186 DP_BYTE_PIX_ORDER = (1 << 24)
187 };
189 static int mach64_width[8] = {0, 0, 0, 1, 1, 2, 2, 0};
191 enum
192 {
193 DST_X_TILE = 0x08,
194 DST_Y_TILE = 0x10,
195 DST_24_ROT_EN = 0x80
196 };
198 void mach64_write(uint32_t addr, uint8_t val, void *priv);
199 uint8_t mach64_read(uint32_t addr, void *priv);
200 void mach64_updatemapping(mach64_t *mach64);
202 uint8_t mach64_ext_readb(uint32_t addr, void *priv);
203 uint16_t mach64_ext_readw(uint32_t addr, void *priv);
204 uint32_t mach64_ext_readl(uint32_t addr, void *priv);
205 void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv);
206 void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv);
207 void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv);
209 void mach64_out(uint16_t addr, uint8_t val, void *p)
210 {
211 mach64_t *mach64 = p;
212 svga_t *svga = &mach64->svga;
213 uint8_t old;
215 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
216 addr ^= 0x60;
218 // pclog("mach64 out %04X %02X\n", addr, val);
220 switch (addr)
221 {
222 case 0x1ce:
223 mach64->index = val;
224 break;
225 case 0x1cf:
226 mach64->regs[mach64->index] = val;
227 break;
229 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
230 ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga);
231 return;
233 case 0x3cf:
234 if (svga->gdcaddr == 6)
235 {
236 uint8_t old_val = svga->gdcreg[6];
237 svga->gdcreg[6] = val;
238 if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc))
239 mach64_updatemapping(mach64);
240 return;
241 }
242 break;
244 case 0x3D4:
245 svga->crtcreg = val & 0x1f;
246 return;
247 case 0x3D5:
248 if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
249 if (svga->crtcreg > 0x18)
250 return;
251 old = svga->crtc[svga->crtcreg];
252 svga->crtc[svga->crtcreg] = val;
254 if (old!=val)
255 {
256 if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
257 {
258 svga->fullchange = changeframecount;
259 svga_recalctimings(svga);
260 }
261 }
262 break;
263 }
264 svga_out(addr, val, svga);
265 }
267 uint8_t mach64_in(uint16_t addr, void *p)
268 {
269 mach64_t *mach64 = p;
270 svga_t *svga = &mach64->svga;
272 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1))
273 addr ^= 0x60;
275 // pclog("IN mach64 %04X\n", addr);
277 switch (addr)
278 {
279 case 0x1ce:
280 return mach64->index;
281 case 0x1cf:
282 return mach64->regs[mach64->index];
284 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
285 return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga);
287 case 0x3D4:
288 return svga->crtcreg;
289 case 0x3D5:
290 if (svga->crtcreg > 0x18)
291 return 0xff;
292 return svga->crtc[svga->crtcreg];
293 }
294 return svga_in(addr, svga);
295 }
297 void mach64_recalctimings(svga_t *svga)
298 {
299 mach64_t *mach64 = (mach64_t *)svga->p;
301 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
302 {
303 svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1;
304 svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1;
305 svga->htotal = (mach64->crtc_h_total_disp & 255) + 1;
306 svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1;
307 svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1;
308 svga->rowoffset = (mach64->crtc_off_pitch >> 22);
309 svga->clock = cpuclock / mach64->ics2595.output_clock;
310 svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2;
311 svga->linedbl = svga->rowcount = 0;
312 svga->split = 0xffffff;
313 svga->vblankstart = svga->dispend;
314 // svga_htotal <<= 1;
315 // svga_hdisp <<= 1;
316 svga->rowoffset <<= 1;
317 svga->render = mach64->ramdac.render;
318 switch ((mach64->crtc_gen_cntl >> 8) & 7)
319 {
320 case 1:
321 // svga->render = svga_render_4bpp_highres;
322 svga->hdisp *= 8;
323 break;
324 case 2:
325 // svga->render = svga_render_8bpp_highres;
326 svga->hdisp *= 8;
327 svga->rowoffset /= 2;
328 break;
329 case 3:
330 // svga->render = svga_render_15bpp_highres;
331 svga->hdisp *= 8;
332 //svga_rowoffset *= 2;
333 break;
334 case 4:
335 // svga->render = svga_render_16bpp_highres;
336 svga->hdisp *= 8;
337 //svga_rowoffset *= 2;
338 break;
339 case 5:
340 // svga->render = svga_render_24bpp_highres;
341 svga->hdisp *= 8;
342 svga->rowoffset = (svga->rowoffset * 3) / 2;
343 break;
344 case 6:
345 // svga->render = svga_render_32bpp_highres;
346 svga->hdisp *= 8;
347 svga->rowoffset *= 2;
348 break;
349 }
351 // 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);
352 }
353 }
355 void mach64_updatemapping(mach64_t *mach64)
356 {
357 svga_t *svga = &mach64->svga;
359 if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
360 {
361 pclog("Update mapping - PCI disabled\n");
362 mem_mapping_disable(&svga->mapping);
363 mem_mapping_disable(&mach64->linear_mapping);
364 mem_mapping_disable(&mach64->mmio_mapping);
365 mem_mapping_disable(&mach64->mmio_linear_mapping);
366 return;
367 }
369 mem_mapping_disable(&mach64->mmio_mapping);
370 // pclog("Write mapping %02X\n", val);
371 switch (svga->gdcreg[6] & 0xc)
372 {
373 case 0x0: /*128k at A0000*/
374 mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
375 mem_mapping_set_p(&mach64->svga.mapping, mach64);
376 mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
377 mem_mapping_enable(&mach64->mmio_mapping);
378 svga->banked_mask = 0xffff;
379 break;
380 case 0x4: /*64k at A0000*/
381 mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
382 mem_mapping_set_p(&mach64->svga.mapping, mach64);
383 mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
384 svga->banked_mask = 0xffff;
385 break;
386 case 0x8: /*32k at B0000*/
387 mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
388 mem_mapping_set_p(&mach64->svga.mapping, svga);
389 mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
390 svga->banked_mask = 0x7fff;
391 break;
392 case 0xC: /*32k at B8000*/
393 mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
394 mem_mapping_set_p(&mach64->svga.mapping, svga);
395 mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
396 svga->banked_mask = 0x7fff;
397 break;
398 }
399 if (mach64->linear_base)
400 {
401 if ((mach64->config_cntl & 3) == 2)
402 {
403 /*8 MB aperture*/
404 mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
405 mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
406 }
407 else
408 {
409 /*4 MB aperture*/
410 mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000);
411 mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000);
412 }
413 }
414 else
415 {
416 mem_mapping_disable(&mach64->linear_mapping);
417 mem_mapping_disable(&mach64->mmio_linear_mapping);
418 }
419 }
421 #define READ8(addr, var) switch ((addr) & 3) \
422 { \
423 case 0: ret = (var) & 0xff; break; \
424 case 1: ret = ((var) >> 8) & 0xff; break; \
425 case 2: ret = ((var) >> 16) & 0xff; break; \
426 case 3: ret = ((var) >> 24) & 0xff; break; \
427 }
429 #define WRITE8(addr, var, val) switch ((addr) & 3) \
430 { \
431 case 0: var = (var & 0xffffff00) | (val); break; \
432 case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \
433 case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \
434 case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \
435 }
437 void mach64_cursor_dump(mach64_t *mach64)
438 {
439 svga_t *svga = &mach64->svga;
440 /* pclog("Mach64 cursor :\n");
441 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);*/
442 }
444 void mach64_start_fill(mach64_t *mach64)
445 {
446 int x, y;
448 mach64->accel.dst_x = 0;
449 mach64->accel.dst_y = 0;
450 mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff;
451 mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff;
453 mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff;
454 mach64->accel.dst_height = mach64->dst_height_width & 0x1fff;
455 mach64->accel.x_count = mach64->accel.dst_width;
457 mach64->accel.src_x = 0;
458 mach64->accel.src_y = 0;
459 mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
460 mach64->accel.src_y_start = mach64->src_y_x & 0xfff;
461 if (mach64->src_cntl & SRC_LINEAR_EN)
462 mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/
463 else
464 mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff;
465 if (!(mach64->src_cntl & SRC_PATT_EN))
466 mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/
467 else
468 mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff;
470 mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff;
471 mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff;
472 mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff;
473 mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff;
475 #ifdef MACH64_DEBUG
476 pclog("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count,
477 mach64->accel.src_y_count,
478 mach64->accel.src_width1,
479 mach64->accel.src_height1,
480 mach64->src_height1_width1,
481 mach64->src_height2_width2);
482 #endif
484 mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8;
485 mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
487 mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8;
488 mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
490 mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
491 mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
493 mach64->accel.source_bg = mach64->dp_src & 7;
494 mach64->accel.source_fg = (mach64->dp_src >> 8) & 7;
495 mach64->accel.source_mix = (mach64->dp_src >> 16) & 7;
497 mach64->accel.dst_pix_width = mach64->dp_pix_width & 7;
498 mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7;
499 mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7;
501 mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width];
502 mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width];
504 /* mach64->accel.src_x *= mach64_inc[mach64->accel.src_pix_width];
505 mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
506 mach64->accel.dst_x *= mach64_inc[mach64->accel.dst_pix_width];
507 mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
509 mach64->accel.src_offset >>= mach64->accel.src_size;
510 mach64->accel.dst_offset >>= mach64->accel.dst_size;
512 /* if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC)
513 {*/
514 mach64->accel.xinc = (mach64->dst_cntl & 1) ? 1 : -1;
515 mach64->accel.yinc = (mach64->dst_cntl & 2) ? 1 : -1;
516 /* }
517 else
518 {
519 mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width];
520 mach64->accel.yinc = 1;
521 }*/
523 mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
526 // pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1);
527 for (y = 0; y < 8; y++)
528 {
529 for (x = 0; x < 8; x++)
530 {
531 uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
532 mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
533 // pclog("%i ", mach64->accel.pattern[y][x]);
534 }
535 // pclog("\n");
536 }
538 mach64->accel.sc_left = mach64->sc_left_right & 0x1fff;
539 mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff;
540 mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff;
541 mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff;
543 /* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width];
544 mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/
546 mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
547 mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;
549 mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask;
550 mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask;
551 mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7;
552 mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24);
554 mach64->accel.busy = 1;
555 #ifdef MACH64_DEBUG
556 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);
557 #endif
558 mach64->accel.op = OP_RECT;
559 }
561 void mach64_start_line(mach64_t *mach64)
562 {
563 int x, y;
565 mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff;
566 mach64->accel.dst_y = mach64->dst_y_x & 0xfff;
568 mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff;
569 mach64->accel.src_y = mach64->src_y_x & 0xfff;
571 mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8;
572 mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
574 mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8;
575 mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
577 mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
578 mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
580 mach64->accel.source_bg = mach64->dp_src & 7;
581 mach64->accel.source_fg = (mach64->dp_src >> 8) & 7;
582 mach64->accel.source_mix = (mach64->dp_src >> 16) & 7;
584 mach64->accel.dst_pix_width = mach64->dp_pix_width & 7;
585 mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7;
586 mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7;
588 mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width];
589 mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width];
591 mach64->accel.src_offset >>= mach64->accel.src_size;
592 mach64->accel.dst_offset >>= mach64->accel.dst_size;
594 /* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
595 mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
597 mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
599 for (y = 0; y < 8; y++)
600 {
601 for (x = 0; x < 8; x++)
602 {
603 uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
604 mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
605 }
606 }
608 mach64->accel.sc_left = mach64->sc_left_right & 0x1fff;
609 mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff;
610 mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff;
611 mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff;
613 mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
614 mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;
616 mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff;
617 mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0);
619 mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask;
620 mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask;
621 mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7;
622 mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24);
624 mach64->accel.busy = 1;
625 #ifdef MACH64_DEBUG
626 pclog("mach64_start_line\n");
627 #endif
628 mach64->accel.op = OP_LINE;
629 }
631 #define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \
632 else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \
633 else dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask];
635 #define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \
636 { \
637 case 0x0: dest_dat = ~dest_dat; break; \
638 case 0x1: dest_dat = 0; break; \
639 case 0x2: dest_dat = 0xffffffff; break; \
640 case 0x3: dest_dat = dest_dat; break; \
641 case 0x4: dest_dat = ~src_dat; break; \
642 case 0x5: dest_dat = src_dat ^ dest_dat; break; \
643 case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \
644 case 0x7: dest_dat = src_dat; break; \
645 case 0x8: dest_dat = ~(src_dat & dest_dat); break; \
646 case 0x9: dest_dat = ~src_dat | dest_dat; break; \
647 case 0xa: dest_dat = src_dat | ~dest_dat; break; \
648 case 0xb: dest_dat = src_dat | dest_dat; break; \
649 case 0xc: dest_dat = src_dat & dest_dat; break; \
650 case 0xd: dest_dat = src_dat & ~dest_dat; break; \
651 case 0xe: dest_dat = ~src_dat & dest_dat; break; \
652 case 0xf: dest_dat = ~(src_dat | dest_dat); break; \
653 }
655 #define WRITE(addr, width) if (width == 0) \
656 { \
657 svga->vram[(addr) & mach64->vram_mask] = dest_dat; \
658 svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \
659 } \
660 else if (width == 1) \
661 { \
662 *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \
663 svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \
664 } \
665 else \
666 { \
667 *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \
668 svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \
669 }
671 void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
672 {
673 svga_t *svga = &mach64->svga;
674 int cmp_clr = 0;
676 if (!mach64->accel.busy)
677 {
678 #ifdef MACH64_DEBUG
679 pclog("mach64_blit : return as not busy\n");
680 #endif
681 return;
682 }
683 switch (mach64->accel.op)
684 {
685 case OP_RECT:
686 while (count)
687 {
688 uint32_t src_dat, dest_dat;
689 uint32_t host_dat;
690 int mix;
691 int dst_x = mach64->accel.dst_x + mach64->accel.dst_x_start;
692 int dst_y = mach64->accel.dst_y + mach64->accel.dst_y_start;
694 if (mach64->accel.source_host)
695 {
696 host_dat = cpu_dat;
697 switch (mach64->accel.src_size)
698 {
699 case 0:
700 cpu_dat >>= 8;
701 count -= 8;
702 break;
703 case 1:
704 cpu_dat >>= 16;
705 count -= 16;
706 break;
707 case 2:
708 count -= 32;
709 break;
710 }
711 }
712 else
713 count--;
715 switch (mach64->accel.source_mix)
716 {
717 case MONO_SRC_HOST:
718 if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)
719 {
720 mix = cpu_dat & 1;
721 cpu_dat >>= 1;
722 }
723 else
724 {
725 mix = cpu_dat >> 31;
726 cpu_dat <<= 1;
727 }
728 break;
729 case MONO_SRC_PAT:
730 mix = mach64->accel.pattern[dst_y & 7][dst_x & 7];
731 break;
732 case MONO_SRC_1:
733 default:
734 mix = 1;
735 break;
736 }
738 if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right &&
739 dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom)
740 {
741 int src_x = mach64->accel.src_x + mach64->accel.src_x_start;
742 int src_y = mach64->accel.src_y + mach64->accel.src_y_start;
744 switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
745 {
746 case SRC_HOST:
747 src_dat = host_dat;
748 break;
749 case SRC_BLITSRC:
750 READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size);
751 break;
752 case SRC_FG:
753 src_dat = mach64->accel.dp_frgd_clr;
754 break;
755 case SRC_BG:
756 src_dat = mach64->accel.dp_bkgd_clr;
757 break;
758 default:
759 src_dat = 0;
760 break;
761 }
763 READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size);
765 switch (mach64->accel.clr_cmp_fn)
766 {
767 case 1: /*TRUE*/
768 cmp_clr = 1;
769 break;
770 case 4: /*DST_CLR != CLR_CMP_CLR*/
771 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr;
772 break;
773 case 5: /*DST_CLR == CLR_CMP_CLR*/
774 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr;
775 break;
776 }
778 if (!cmp_clr)
779 MIX
781 WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size);
782 }
784 if (mach64->dst_cntl & DST_24_ROT_EN)
785 {
786 mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16);
787 mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16);
788 }
790 mach64->accel.src_x += mach64->accel.xinc;
791 mach64->accel.dst_x += mach64->accel.xinc;
792 mach64->accel.src_x_count--;
793 if (mach64->accel.src_x_count <= 0)
794 {
795 mach64->accel.src_x = 0;
796 if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN))
797 {
798 mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff;
799 mach64->accel.src_x_count = mach64->accel.src_width2;
800 }
801 else
802 mach64->accel.src_x_count = mach64->accel.src_width1;
803 }
805 mach64->accel.x_count--;
807 if (mach64->accel.x_count <= 0)
808 {
809 mach64->accel.x_count = mach64->accel.dst_width;
810 mach64->accel.src_x = 0;
811 mach64->accel.dst_x = 0;
812 mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
813 mach64->accel.src_x_count = mach64->accel.src_width1;
815 mach64->accel.src_y += mach64->accel.yinc;
816 mach64->accel.dst_y += mach64->accel.yinc;
817 mach64->accel.src_y_count--;
818 if (mach64->accel.src_y_count <= 0)
819 {
820 mach64->accel.src_y = 0;
821 if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN))
822 {
823 mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff;
824 mach64->accel.src_y_count = mach64->accel.src_height2;
825 }
826 else
827 mach64->accel.src_y_count = mach64->accel.src_height1;
828 }
830 mach64->accel.dst_height--;
832 if (mach64->accel.dst_height <= 0)
833 {
834 /*Blit finished*/
835 #ifdef MACH64_DEBUG
836 pclog("mach64 blit finished\n");
837 #endif
838 mach64->accel.busy = 0;
839 if (mach64->dst_cntl & DST_X_TILE)
840 mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000);
841 if (mach64->dst_cntl & DST_Y_TILE)
842 mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + mach64->accel.dst_height) & 0xfff);
843 return;
844 }
845 if (mach64->accel.source_host)
846 return;
847 }
848 }
849 break;
851 case OP_LINE:
852 while (count)
853 {
854 uint32_t src_dat, dest_dat;
855 uint32_t host_dat;
856 int mix;
858 if (mach64->accel.source_host)
859 {
860 host_dat = cpu_dat;
861 switch (mach64->accel.src_size)
862 {
863 case 0:
864 cpu_dat >>= 8;
865 count -= 8;
866 break;
867 case 1:
868 cpu_dat >>= 16;
869 count -= 16;
870 break;
871 case 2:
872 count -= 32;
873 break;
874 }
875 }
876 else
877 count--;
879 switch (mach64->accel.source_mix)
880 {
881 case MONO_SRC_HOST:
882 mix = cpu_dat >> 31;
883 cpu_dat <<= 1;
884 break;
885 case MONO_SRC_PAT:
886 mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7];
887 break;
888 case MONO_SRC_1:
889 default:
890 mix = 1;
891 break;
892 }
894 if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right &&
895 mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom)
896 {
897 switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
898 {
899 case SRC_HOST:
900 src_dat = host_dat;
901 break;
902 case SRC_BLITSRC:
903 READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size);
904 break;
905 case SRC_FG:
906 src_dat = mach64->accel.dp_frgd_clr;
907 break;
908 case SRC_BG:
909 src_dat = mach64->accel.dp_bkgd_clr;
910 break;
911 default:
912 src_dat = 0;
913 break;
914 }
916 READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size);
918 // 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);
920 switch (mach64->accel.clr_cmp_fn)
921 {
922 case 1: /*TRUE*/
923 cmp_clr = 1;
924 break;
925 case 4: /*DST_CLR != CLR_CMP_CLR*/
926 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr;
927 break;
928 case 5: /*DST_CLR == CLR_CMP_CLR*/
929 cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr;
930 break;
931 }
933 if (!cmp_clr)
934 MIX
936 // pclog("%02X %i\n", dest_dat, mach64->accel.dst_height);
938 WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size);
939 }
941 mach64->accel.x_count--;
942 if (mach64->accel.x_count <= 0)
943 {
944 /*Blit finished*/
945 #ifdef MACH64_DEBUG
946 pclog("mach64 blit finished\n");
947 #endif
948 mach64->accel.busy = 0;
949 return;
950 }
952 switch (mach64->dst_cntl & 7)
953 {
954 case 0: case 2:
955 mach64->accel.src_x--;
956 mach64->accel.dst_x--;
957 break;
958 case 1: case 3:
959 mach64->accel.src_x++;
960 mach64->accel.dst_x++;
961 break;
962 case 4: case 5:
963 mach64->accel.src_y--;
964 mach64->accel.dst_y--;
965 break;
966 case 6: case 7:
967 mach64->accel.src_y++;
968 mach64->accel.dst_y++;
969 break;
970 }
971 #ifdef MACH64_DEBUG
972 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);
973 #endif
974 if (mach64->accel.err >= 0)
975 {
976 mach64->accel.err += mach64->dst_bres_dec;
978 switch (mach64->dst_cntl & 7)
979 {
980 case 0: case 1:
981 mach64->accel.src_y--;
982 mach64->accel.dst_y--;
983 break;
984 case 2: case 3:
985 mach64->accel.src_y++;
986 mach64->accel.dst_y++;
987 break;
988 case 4: case 6:
989 mach64->accel.src_x--;
990 mach64->accel.dst_x--;
991 break;
992 case 5: case 7:
993 mach64->accel.src_x++;
994 mach64->accel.dst_x++;
995 break;
996 }
997 }
998 else
999 mach64->accel.err += mach64->dst_bres_inc;
1001 break;
1005 void mach64_load_context(mach64_t *mach64)
1007 svga_t *svga = &mach64->svga;
1008 uint32_t addr;
1010 while (mach64->context_load_cntl & 0x30000)
1012 addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask;
1013 mach64->context_mask = *(uint32_t *)&svga->vram[addr];
1014 #ifdef MACH64_DEBUG
1015 pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask);
1016 #endif
1018 if (mach64->context_mask & (1 << 2))
1019 mach64_ext_writel(0x100, *(uint32_t *)&svga->vram[addr + 0x08], mach64);
1020 if (mach64->context_mask & (1 << 3))
1021 mach64_ext_writel(0x10c, *(uint32_t *)&svga->vram[addr + 0x0c], mach64);
1022 if (mach64->context_mask & (1 << 4))
1023 mach64_ext_writel(0x118, *(uint32_t *)&svga->vram[addr + 0x10], mach64);
1024 if (mach64->context_mask & (1 << 5))
1025 mach64_ext_writel(0x124, *(uint32_t *)&svga->vram[addr + 0x14], mach64);
1026 if (mach64->context_mask & (1 << 6))
1027 mach64_ext_writel(0x128, *(uint32_t *)&svga->vram[addr + 0x18], mach64);
1028 if (mach64->context_mask & (1 << 7))
1029 mach64_ext_writel(0x12c, *(uint32_t *)&svga->vram[addr + 0x1c], mach64);
1030 if (mach64->context_mask & (1 << 8))
1031 mach64_ext_writel(0x180, *(uint32_t *)&svga->vram[addr + 0x20], mach64);
1032 if (mach64->context_mask & (1 << 9))
1033 mach64_ext_writel(0x18c, *(uint32_t *)&svga->vram[addr + 0x24], mach64);
1034 if (mach64->context_mask & (1 << 10))
1035 mach64_ext_writel(0x198, *(uint32_t *)&svga->vram[addr + 0x28], mach64);
1036 if (mach64->context_mask & (1 << 11))
1037 mach64_ext_writel(0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c], mach64);
1038 if (mach64->context_mask & (1 << 12))
1039 mach64_ext_writel(0x1b0, *(uint32_t *)&svga->vram[addr + 0x30], mach64);
1040 if (mach64->context_mask & (1 << 13))
1041 mach64_ext_writel(0x280, *(uint32_t *)&svga->vram[addr + 0x34], mach64);
1042 if (mach64->context_mask & (1 << 14))
1043 mach64_ext_writel(0x284, *(uint32_t *)&svga->vram[addr + 0x38], mach64);
1044 if (mach64->context_mask & (1 << 15))
1045 mach64_ext_writel(0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c], mach64);
1046 if (mach64->context_mask & (1 << 16))
1047 mach64_ext_writel(0x2b4, *(uint32_t *)&svga->vram[addr + 0x40], mach64);
1048 if (mach64->context_mask & (1 << 17))
1049 mach64_ext_writel(0x2c0, *(uint32_t *)&svga->vram[addr + 0x44], mach64);
1050 if (mach64->context_mask & (1 << 18))
1051 mach64_ext_writel(0x2c4, *(uint32_t *)&svga->vram[addr + 0x48], mach64);
1052 if (mach64->context_mask & (1 << 19))
1053 mach64_ext_writel(0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c], mach64);
1054 if (mach64->context_mask & (1 << 20))
1055 mach64_ext_writel(0x2cc, *(uint32_t *)&svga->vram[addr + 0x50], mach64);
1056 if (mach64->context_mask & (1 << 21))
1057 mach64_ext_writel(0x2d0, *(uint32_t *)&svga->vram[addr + 0x54], mach64);
1058 if (mach64->context_mask & (1 << 22))
1059 mach64_ext_writel(0x2d4, *(uint32_t *)&svga->vram[addr + 0x58], mach64);
1060 if (mach64->context_mask & (1 << 23))
1061 mach64_ext_writel(0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c], mach64);
1062 if (mach64->context_mask & (1 << 24))
1063 mach64_ext_writel(0x300, *(uint32_t *)&svga->vram[addr + 0x60], mach64);
1064 if (mach64->context_mask & (1 << 25))
1065 mach64_ext_writel(0x304, *(uint32_t *)&svga->vram[addr + 0x64], mach64);
1066 if (mach64->context_mask & (1 << 26))
1067 mach64_ext_writel(0x308, *(uint32_t *)&svga->vram[addr + 0x68], mach64);
1068 if (mach64->context_mask & (1 << 27))
1069 mach64_ext_writel(0x330, *(uint32_t *)&svga->vram[addr + 0x6c], mach64);
1071 mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70];
1075 uint8_t mach64_ext_readb(uint32_t addr, void *p)
1077 mach64_t *mach64 = (mach64_t *)p;
1078 uint8_t ret;
1079 switch (addr & 0x3ff)
1081 case 0x00: case 0x01: case 0x02: case 0x03:
1082 READ8(addr, mach64->crtc_h_total_disp);
1083 break;
1084 case 0x08: case 0x09: case 0x0a: case 0x0b:
1085 READ8(addr, mach64->crtc_v_total_disp);
1086 break;
1087 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
1088 READ8(addr, mach64->crtc_v_sync_strt_wid);
1089 break;
1091 case 0x12: case 0x13:
1092 READ8(addr - 2, mach64->svga.vc);
1093 break;
1095 case 0x14: case 0x15: case 0x16: case 0x17:
1096 READ8(addr, mach64->crtc_off_pitch);
1097 break;
1099 case 0x18:
1100 ret = mach64->crtc_int_cntl & ~1;
1101 if (mach64->svga.cgastat & 8)
1102 ret |= 1;
1103 break;
1105 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
1106 READ8(addr, mach64->crtc_gen_cntl);
1107 break;
1109 case 0x40: case 0x41: case 0x42: case 0x43:
1110 READ8(addr, mach64->ovr_clr);
1111 break;
1112 case 0x44: case 0x45: case 0x46: case 0x47:
1113 READ8(addr, mach64->ovr_wid_left_right);
1114 break;
1115 case 0x48: case 0x49: case 0x4a: case 0x4b:
1116 READ8(addr, mach64->ovr_wid_top_bottom);
1117 break;
1119 case 0x68: case 0x69: case 0x6a: case 0x6b:
1120 READ8(addr, mach64->cur_offset);
1121 break;
1122 case 0x6c: case 0x6d: case 0x6e: case 0x6f:
1123 READ8(addr, mach64->cur_horz_vert_posn);
1124 break;
1125 case 0x70: case 0x71: case 0x72: case 0x73:
1126 READ8(addr, mach64->cur_horz_vert_off);
1127 break;
1129 case 0x80: case 0x81: case 0x82: case 0x83:
1130 READ8(addr, mach64->scratch_reg0);
1131 break;
1132 case 0x84: case 0x85: case 0x86: case 0x87:
1133 READ8(addr, mach64->scratch_reg1);
1134 break;
1136 case 0x90: case 0x91: case 0x92: case 0x93:
1137 READ8(addr, mach64->clock_cntl);
1138 break;
1140 case 0xb0: case 0xb1: case 0xb2: case 0xb3:
1141 READ8(addr, mach64->mem_cntl);
1142 break;
1144 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1145 ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga);
1146 break;
1147 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1148 READ8(addr, mach64->dac_cntl);
1149 break;
1151 case 0xd0: case 0xd1: case 0xd2: case 0xd3:
1152 READ8(addr, mach64->gen_test_cntl);
1153 break;
1155 case 0xe0: case 0xe1: case 0xe2: case 0xe3:
1156 READ8(addr, 0x020000d7); /*88800GX-2*/
1157 break;
1159 case 0x100: case 0x101: case 0x102: case 0x103:
1160 READ8(addr, mach64->dst_off_pitch);
1161 break;
1162 case 0x104: case 0x105:
1163 READ8(addr, mach64->dst_y_x);
1164 break;
1165 case 0x108: case 0x109: case 0x11c: case 0x11d:
1166 READ8(addr + 2, mach64->dst_y_x);
1167 break;
1168 case 0x10c: case 0x10d: case 0x10e: case 0x10f:
1169 READ8(addr, mach64->dst_y_x);
1170 break;
1171 case 0x110: case 0x111:
1172 addr += 2;
1173 case 0x114: case 0x115:
1174 case 0x118: case 0x119: case 0x11a: case 0x11b:
1175 case 0x11e: case 0x11f:
1176 READ8(addr, mach64->dst_height_width);
1177 break;
1179 case 0x120: case 0x121: case 0x122: case 0x123:
1180 READ8(addr, mach64->dst_bres_lnth);
1181 break;
1182 case 0x124: case 0x125: case 0x126: case 0x127:
1183 READ8(addr, mach64->dst_bres_err);
1184 break;
1185 case 0x128: case 0x129: case 0x12a: case 0x12b:
1186 READ8(addr, mach64->dst_bres_inc);
1187 break;
1188 case 0x12c: case 0x12d: case 0x12e: case 0x12f:
1189 READ8(addr, mach64->dst_bres_dec);
1190 break;
1192 case 0x130: case 0x131: case 0x132: case 0x133:
1193 READ8(addr, mach64->dst_cntl);
1194 break;
1196 case 0x180: case 0x181: case 0x182: case 0x183:
1197 READ8(addr, mach64->src_off_pitch);
1198 break;
1199 case 0x184: case 0x185:
1200 READ8(addr, mach64->src_y_x);
1201 break;
1202 case 0x188: case 0x189:
1203 READ8(addr + 2, mach64->src_y_x);
1204 break;
1205 case 0x18c: case 0x18d: case 0x18e: case 0x18f:
1206 READ8(addr, mach64->src_y_x);
1207 break;
1208 case 0x190: case 0x191:
1209 READ8(addr + 2, mach64->src_height1_width1);
1210 break;
1211 case 0x194: case 0x195:
1212 READ8(addr, mach64->src_height1_width1);
1213 break;
1214 case 0x198: case 0x199: case 0x19a: case 0x19b:
1215 READ8(addr, mach64->src_height1_width1);
1216 break;
1217 case 0x19c: case 0x19d:
1218 READ8(addr, mach64->src_y_x_start);
1219 break;
1220 case 0x1a0: case 0x1a1:
1221 READ8(addr + 2, mach64->src_y_x_start);
1222 break;
1223 case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7:
1224 READ8(addr, mach64->src_y_x_start);
1225 break;
1226 case 0x1a8: case 0x1a9:
1227 READ8(addr + 2, mach64->src_height2_width2);
1228 break;
1229 case 0x1ac: case 0x1ad:
1230 READ8(addr, mach64->src_height2_width2);
1231 break;
1232 case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3:
1233 READ8(addr, mach64->src_height2_width2);
1234 break;
1236 case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
1237 READ8(addr, mach64->src_cntl);
1238 break;
1240 case 0x280: case 0x281: case 0x282: case 0x283:
1241 READ8(addr, mach64->pat_reg0);
1242 break;
1243 case 0x284: case 0x285: case 0x286: case 0x287:
1244 READ8(addr, mach64->pat_reg1);
1245 break;
1247 case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
1248 READ8(addr, mach64->sc_left_right);
1249 break;
1250 case 0x2a4: case 0x2a5:
1251 addr += 2;
1252 case 0x2aa: case 0x2ab:
1253 READ8(addr, mach64->sc_left_right);
1254 break;
1256 case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
1257 READ8(addr, mach64->sc_top_bottom);
1258 break;
1259 case 0x2b0: case 0x2b1:
1260 addr += 2;
1261 case 0x2b6: case 0x2b7:
1262 READ8(addr, mach64->sc_top_bottom);
1263 break;
1265 case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
1266 READ8(addr, mach64->dp_bkgd_clr);
1267 break;
1268 case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
1269 READ8(addr, mach64->dp_frgd_clr);
1270 break;
1272 case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
1273 READ8(addr, mach64->dp_pix_width);
1274 break;
1275 case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
1276 READ8(addr, mach64->dp_mix);
1277 break;
1278 case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
1279 READ8(addr, mach64->dp_src);
1280 break;
1282 case 0x300: case 0x301: case 0x302: case 0x303:
1283 READ8(addr, mach64->clr_cmp_clr);
1284 break;
1285 case 0x304: case 0x305: case 0x306: case 0x307:
1286 READ8(addr, mach64->clr_cmp_mask);
1287 break;
1288 case 0x308: case 0x309: case 0x30a: case 0x30b:
1289 READ8(addr, mach64->clr_cmp_cntl);
1290 break;
1292 case 0x320: case 0x321: case 0x322: case 0x323:
1293 READ8(addr, mach64->context_mask);
1294 break;
1296 case 0x330: case 0x331:
1297 READ8(addr, mach64->dst_cntl);
1298 break;
1299 case 0x332:
1300 READ8(addr - 2, mach64->src_cntl);
1301 break;
1302 case 0x333:
1303 READ8(addr - 3, mach64->pat_cntl);
1304 break;
1306 default:
1307 ret = 0;
1308 break;
1310 #ifdef MACH64_DEBUG
1311 if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readb : addr %08X ret %02X\n", addr, ret);
1312 #endif
1313 return ret;
1315 uint16_t mach64_ext_readw(uint32_t addr, void *p)
1317 mach64_t *mach64 = (mach64_t *)p;
1318 uint16_t ret;
1319 switch (addr & 0x3ff)
1321 default:
1322 #ifdef MACH64_DEBUG
1323 pclog(" ");
1324 #endif
1325 ret = mach64_ext_readb(addr, p);
1326 #ifdef MACH64_DEBUG
1327 pclog(" ");
1328 #endif
1329 ret |= mach64_ext_readb(addr + 1, p) << 8;
1330 break;
1332 #ifdef MACH64_DEBUG
1333 if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readw : addr %08X ret %04X\n", addr, ret);
1334 #endif
1335 return ret;
1337 uint32_t mach64_ext_readl(uint32_t addr, void *p)
1339 mach64_t *mach64 = (mach64_t *)p;
1340 uint32_t ret;
1341 switch (addr & 0x3ff)
1343 case 0x18:
1344 ret = mach64->crtc_int_cntl & ~1;
1345 if (mach64->svga.cgastat & 8)
1346 ret |= 1;
1347 break;
1349 case 0xb4:
1350 ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16);
1351 break;
1352 case 0xb8:
1353 ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16);
1354 break;
1356 default:
1357 #ifdef MACH64_DEBUG
1358 pclog(" ");
1359 #endif
1360 ret = mach64_ext_readw(addr, p);
1361 #ifdef MACH64_DEBUG
1362 pclog(" ");
1363 #endif
1364 ret |= mach64_ext_readw(addr + 2, p) << 16;
1365 break;
1367 #ifdef MACH64_DEBUG
1368 if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readl : addr %08X ret %08X\n", addr, ret);
1369 #endif
1370 return ret;
1373 void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
1375 mach64_t *mach64 = (mach64_t *)p;
1376 svga_t *svga = &mach64->svga;
1377 #ifdef MACH64_DEBUG
1378 pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val);
1379 #endif
1380 switch (addr & 0x3ff)
1382 case 0x00: case 0x01: case 0x02: case 0x03:
1383 WRITE8(addr, mach64->crtc_h_total_disp, val);
1384 svga_recalctimings(&mach64->svga);
1385 break;
1386 case 0x08: case 0x09: case 0x0a: case 0x0b:
1387 WRITE8(addr, mach64->crtc_v_total_disp, val);
1388 svga_recalctimings(&mach64->svga);
1389 break;
1390 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
1391 WRITE8(addr, mach64->crtc_v_sync_strt_wid, val);
1392 svga_recalctimings(&mach64->svga);
1393 break;
1395 case 0x14: case 0x15: case 0x16: case 0x17:
1396 WRITE8(addr, mach64->crtc_off_pitch, val);
1397 svga_recalctimings(&mach64->svga);
1398 svga->fullchange = changeframecount;
1399 break;
1401 case 0x18:
1402 mach64->crtc_int_cntl = val;
1403 break;
1405 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
1406 WRITE8(addr, mach64->crtc_gen_cntl, val);
1407 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
1408 svga->fb_only = 1;
1409 else
1410 svga->fb_only = 0;
1411 svga_recalctimings(&mach64->svga);
1412 break;
1414 case 0x40: case 0x41: case 0x42: case 0x43:
1415 WRITE8(addr, mach64->ovr_clr, val);
1416 break;
1417 case 0x44: case 0x45: case 0x46: case 0x47:
1418 WRITE8(addr, mach64->ovr_wid_left_right, val);
1419 break;
1420 case 0x48: case 0x49: case 0x4a: case 0x4b:
1421 WRITE8(addr, mach64->ovr_wid_top_bottom, val);
1422 break;
1424 case 0x68: case 0x69: case 0x6a: case 0x6b:
1425 WRITE8(addr, mach64->cur_offset, val);
1426 svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8;
1427 mach64_cursor_dump(mach64);
1428 break;
1429 case 0x6c: case 0x6d: case 0x6e: case 0x6f:
1430 WRITE8(addr, mach64->cur_horz_vert_posn, val);
1431 svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
1432 svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
1433 mach64_cursor_dump(mach64);
1434 break;
1435 case 0x70: case 0x71: case 0x72: case 0x73:
1436 WRITE8(addr, mach64->cur_horz_vert_off, val);
1437 svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
1438 svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
1439 mach64_cursor_dump(mach64);
1440 break;
1442 case 0x80: case 0x81: case 0x82: case 0x83:
1443 WRITE8(addr, mach64->scratch_reg0, val);
1444 break;
1445 case 0x84: case 0x85: case 0x86: case 0x87:
1446 WRITE8(addr, mach64->scratch_reg1, val);
1447 break;
1449 case 0x90: case 0x91: case 0x92: case 0x93:
1450 WRITE8(addr, mach64->clock_cntl, val);
1451 ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf);
1452 svga_recalctimings(&mach64->svga);
1453 break;
1455 case 0xb0: case 0xb1: case 0xb2: case 0xb3:
1456 WRITE8(addr, mach64->mem_cntl, val);
1457 break;
1459 case 0xb4:
1460 mach64->bank_w[0] = val * 32768;
1461 #ifdef MACH64_DEBUG
1462 pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]);
1463 #endif
1464 break;
1465 case 0xb5: case 0xb6:
1466 mach64->bank_w[1] = val * 32768;
1467 #ifdef MACH64_DEBUG
1468 pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]);
1469 #endif
1470 break;
1471 case 0xb8:
1472 mach64->bank_r[0] = val * 32768;
1473 #ifdef MACH64_DEBUG
1474 pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]);
1475 #endif
1476 break;
1477 case 0xb9: case 0xba:
1478 mach64->bank_r[1] = val * 32768;
1479 #ifdef MACH64_DEBUG
1480 pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]);
1481 #endif
1482 break;
1484 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1485 ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga);
1486 break;
1487 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1488 WRITE8(addr, mach64->dac_cntl, val);
1489 break;
1491 case 0xd0: case 0xd1: case 0xd2: case 0xd3:
1492 WRITE8(addr, mach64->gen_test_cntl, val);
1493 // if (val == 2) output = 3;
1494 ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1);
1495 mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0);
1496 svga->hwcursor.ena = mach64->gen_test_cntl & 0x80;
1497 mach64_cursor_dump(mach64);
1498 break;
1500 case 0x100: case 0x101: case 0x102: case 0x103:
1501 WRITE8(addr, mach64->dst_off_pitch, val);
1502 break;
1503 case 0x104: case 0x105: case 0x11c: case 0x11d:
1504 WRITE8(addr + 2, mach64->dst_y_x, val);
1505 break;
1506 case 0x108: case 0x109:
1507 WRITE8(addr, mach64->dst_y_x, val);
1508 break;
1509 case 0x10c: case 0x10d: case 0x10e: case 0x10f:
1510 WRITE8(addr, mach64->dst_y_x, val);
1511 break;
1512 case 0x110: case 0x111:
1513 WRITE8(addr + 2, mach64->dst_height_width, val);
1514 break;
1515 case 0x114: case 0x115:
1516 case 0x118: case 0x119: case 0x11a: case 0x11b:
1517 case 0x11e: case 0x11f:
1518 WRITE8(addr, mach64->dst_height_width, val);
1519 case 0x113:
1520 if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f ||
1521 ((addr & 0x3ff) == 0x113) && !(val & 0x80))
1523 mach64_start_fill(mach64);
1524 #ifdef MACH64_DEBUG
1525 pclog("%i %i %i %i %i\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000),
1526 ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST),
1527 (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST));
1528 #endif
1529 if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) &&
1530 ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) &&
1531 (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST))
1532 mach64_blit(0, -1, mach64);
1534 break;
1536 case 0x120: case 0x121: case 0x122: case 0x123:
1537 WRITE8(addr, mach64->dst_bres_lnth, val);
1538 if ((addr & 0x3ff) == 0x123 && !(val & 0x80))
1540 mach64_start_line(mach64);
1542 if ((mach64->dst_bres_lnth & 0x7fff) &&
1543 ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) &&
1544 (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST))
1545 mach64_blit(0, -1, mach64);
1547 break;
1548 case 0x124: case 0x125: case 0x126: case 0x127:
1549 WRITE8(addr, mach64->dst_bres_err, val);
1550 break;
1551 case 0x128: case 0x129: case 0x12a: case 0x12b:
1552 WRITE8(addr, mach64->dst_bres_inc, val);
1553 break;
1554 case 0x12c: case 0x12d: case 0x12e: case 0x12f:
1555 WRITE8(addr, mach64->dst_bres_dec, val);
1556 break;
1558 case 0x130: case 0x131: case 0x132: case 0x133:
1559 WRITE8(addr, mach64->dst_cntl, val);
1560 break;
1562 case 0x180: case 0x181: case 0x182: case 0x183:
1563 WRITE8(addr, mach64->src_off_pitch, val);
1564 break;
1565 case 0x184: case 0x185:
1566 WRITE8(addr, mach64->src_y_x, val);
1567 break;
1568 case 0x188: case 0x189:
1569 WRITE8(addr + 2, mach64->src_y_x, val);
1570 break;
1571 case 0x18c: case 0x18d: case 0x18e: case 0x18f:
1572 WRITE8(addr, mach64->src_y_x, val);
1573 break;
1574 case 0x190: case 0x191:
1575 WRITE8(addr + 2, mach64->src_height1_width1, val);
1576 break;
1577 case 0x194: case 0x195:
1578 WRITE8(addr, mach64->src_height1_width1, val);
1579 break;
1580 case 0x198: case 0x199: case 0x19a: case 0x19b:
1581 WRITE8(addr, mach64->src_height1_width1, val);
1582 break;
1583 case 0x19c: case 0x19d:
1584 WRITE8(addr, mach64->src_y_x_start, val);
1585 break;
1586 case 0x1a0: case 0x1a1:
1587 WRITE8(addr + 2, mach64->src_y_x_start, val);
1588 break;
1589 case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7:
1590 WRITE8(addr, mach64->src_y_x_start, val);
1591 break;
1592 case 0x1a8: case 0x1a9:
1593 WRITE8(addr + 2, mach64->src_height2_width2, val);
1594 break;
1595 case 0x1ac: case 0x1ad:
1596 WRITE8(addr, mach64->src_height2_width2, val);
1597 break;
1598 case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3:
1599 WRITE8(addr, mach64->src_height2_width2, val);
1600 break;
1602 case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
1603 WRITE8(addr, mach64->src_cntl, val);
1604 break;
1606 case 0x200: case 0x201: case 0x202: case 0x203:
1607 case 0x204: case 0x205: case 0x206: case 0x207:
1608 case 0x208: case 0x209: case 0x20a: case 0x20b:
1609 case 0x20c: case 0x20d: case 0x20e: case 0x20f:
1610 case 0x210: case 0x211: case 0x212: case 0x213:
1611 case 0x214: case 0x215: case 0x216: case 0x217:
1612 case 0x218: case 0x219: case 0x21a: case 0x21b:
1613 case 0x21c: case 0x21d: case 0x21e: case 0x21f:
1614 case 0x220: case 0x221: case 0x222: case 0x223:
1615 case 0x224: case 0x225: case 0x226: case 0x227:
1616 case 0x228: case 0x229: case 0x22a: case 0x22b:
1617 case 0x22c: case 0x22d: case 0x22e: case 0x22f:
1618 case 0x230: case 0x231: case 0x232: case 0x233:
1619 case 0x234: case 0x235: case 0x236: case 0x237:
1620 case 0x238: case 0x239: case 0x23a: case 0x23b:
1621 case 0x23c: case 0x23d: case 0x23e: case 0x23f:
1622 mach64_blit(val, 8, mach64);
1623 break;
1625 case 0x280: case 0x281: case 0x282: case 0x283:
1626 WRITE8(addr, mach64->pat_reg0, val);
1627 break;
1628 case 0x284: case 0x285: case 0x286: case 0x287:
1629 WRITE8(addr, mach64->pat_reg1, val);
1630 break;
1632 case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
1633 WRITE8(addr, mach64->sc_left_right, val);
1634 break;
1635 case 0x2a4: case 0x2a5:
1636 addr += 2;
1637 case 0x2aa: case 0x2ab:
1638 WRITE8(addr, mach64->sc_left_right, val);
1639 break;
1641 case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
1642 WRITE8(addr, mach64->sc_top_bottom, val);
1643 break;
1644 case 0x2b0: case 0x2b1:
1645 addr += 2;
1646 case 0x2b6: case 0x2b7:
1647 WRITE8(addr, mach64->sc_top_bottom, val);
1648 break;
1650 case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
1651 WRITE8(addr, mach64->dp_bkgd_clr, val);
1652 break;
1653 case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
1654 WRITE8(addr, mach64->dp_frgd_clr, val);
1655 break;
1657 case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
1658 WRITE8(addr, mach64->dp_pix_width, val);
1659 break;
1660 case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
1661 WRITE8(addr, mach64->dp_mix, val);
1662 break;
1663 case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
1664 WRITE8(addr, mach64->dp_src, val);
1665 break;
1667 case 0x300: case 0x301: case 0x302: case 0x303:
1668 WRITE8(addr, mach64->clr_cmp_clr, val);
1669 break;
1670 case 0x304: case 0x305: case 0x306: case 0x307:
1671 WRITE8(addr, mach64->clr_cmp_mask, val);
1672 break;
1673 case 0x308: case 0x309: case 0x30a: case 0x30b:
1674 WRITE8(addr, mach64->clr_cmp_cntl, val);
1675 break;
1677 case 0x320: case 0x321: case 0x322: case 0x323:
1678 WRITE8(addr, mach64->context_mask, val);
1679 break;
1681 case 0x330: case 0x331:
1682 WRITE8(addr, mach64->dst_cntl, val);
1683 break;
1684 case 0x332:
1685 WRITE8(addr - 2, mach64->src_cntl, val);
1686 break;
1687 case 0x333:
1688 WRITE8(addr - 3, mach64->pat_cntl, val & 7);
1689 break;
1692 void mach64_ext_writew(uint32_t addr, uint16_t val, void *p)
1694 mach64_t *mach64 = (mach64_t *)p;
1695 #ifdef MACH64_DEBUG
1696 pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val);
1697 #endif
1698 switch (addr & 0x3fe)
1700 case 0x200: case 0x202: case 0x204: case 0x206:
1701 case 0x208: case 0x20a: case 0x20c: case 0x20e:
1702 case 0x210: case 0x212: case 0x214: case 0x216:
1703 case 0x218: case 0x21a: case 0x21c: case 0x21e:
1704 case 0x220: case 0x222: case 0x224: case 0x226:
1705 case 0x228: case 0x22a: case 0x22c: case 0x22e:
1706 case 0x230: case 0x232: case 0x234: case 0x236:
1707 case 0x238: case 0x23a: case 0x23c: case 0x23e:
1708 mach64_blit(val, 16, mach64);
1709 break;
1711 default:
1712 #ifdef MACH64_DEBUG
1713 pclog(" ");
1714 #endif
1715 mach64_ext_writeb(addr, val, p);
1716 #ifdef MACH64_DEBUG
1717 pclog(" ");
1718 #endif
1719 mach64_ext_writeb(addr + 1, val >> 8, p);
1720 break;
1723 void mach64_ext_writel(uint32_t addr, uint32_t val, void *p)
1725 mach64_t *mach64 = (mach64_t *)p;
1726 #ifdef MACH64_DEBUG
1727 if ((addr & 0x3c0) != 0x200)
1728 pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val);
1729 #endif
1730 switch (addr & 0x3fc)
1732 case 0x32c:
1733 mach64->context_load_cntl = val;
1734 if (val & 0x30000)
1735 mach64_load_context(mach64);
1736 break;
1738 case 0x200: case 0x204: case 0x208: case 0x20c:
1739 case 0x210: case 0x214: case 0x218: case 0x21c:
1740 case 0x220: case 0x224: case 0x228: case 0x22c:
1741 case 0x230: case 0x234: case 0x238: case 0x23c:
1742 if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER))
1743 mach64_blit(val, 32, mach64);
1744 else
1745 mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64);
1746 break;
1748 default:
1749 #ifdef MACH64_DEBUG
1750 pclog(" ");
1751 #endif
1752 mach64_ext_writew(addr, val, p);
1753 #ifdef MACH64_DEBUG
1754 pclog(" ");
1755 #endif
1756 mach64_ext_writew(addr + 2, val >> 16, p);
1757 break;
1761 uint8_t mach64_ext_inb(uint16_t port, void *p)
1763 mach64_t *mach64 = (mach64_t *)p;
1764 uint8_t ret;
1765 // if (CS == 0x2be7) output = 3;
1766 switch (port)
1768 case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
1769 case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
1770 ret = mach64_ext_readb(0x00 | (port & 3), p);
1771 break;
1772 case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
1773 ret = mach64_ext_readb(0x08 | (port & 3), p);
1774 break;
1775 case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
1776 ret = mach64_ext_readb(0x0c | (port & 3), p);
1777 break;
1779 case 0x12ec: case 0x12ed: case 0x12ee: case 0x12ef:
1780 ret = mach64_ext_readb(0x10 | (port & 3), p);
1781 break;
1783 case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
1784 ret = mach64_ext_readb(0x14 | (port & 3), p);
1785 break;
1787 case 0x1aec:
1788 ret = mach64_ext_readb(0x18, p);
1789 break;
1791 case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
1792 ret = mach64_ext_readb(0x1c | (port & 3), p);
1793 break;
1795 case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef:
1796 ret = mach64_ext_readb(0x40 | (port & 3), p);
1797 break;
1798 case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef:
1799 ret = mach64_ext_readb(0x44 | (port & 3), p);
1800 break;
1801 case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef:
1802 ret = mach64_ext_readb(0x48 | (port & 3), p);
1803 break;
1805 case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
1806 ret = mach64_ext_readb(0x68 | (port & 3), p);
1807 break;
1808 case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
1809 ret = mach64_ext_readb(0x6c | (port & 3), p);
1810 break;
1811 case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
1812 ret = mach64_ext_readb(0x70 | (port & 3), p);
1813 break;
1815 case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
1816 ret = mach64_ext_readb(0x80 | (port & 3), p);
1817 break;
1818 case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
1819 ret = mach64_ext_readb(0x84 | (port & 3), p);
1820 break;
1821 case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
1822 ret = mach64_ext_readb(0x90 | (port & 3), p);
1823 break;
1825 case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
1826 ret = mach64_ext_readb(0xb0 | (port & 3), p);
1827 break;
1829 case 0x56ec:
1830 ret = mach64_ext_readb(0xb4, p);
1831 break;
1832 case 0x56ed: case 0x56ee:
1833 ret = mach64_ext_readb(0xb5, p);
1834 break;
1835 case 0x5aec:
1836 ret = mach64_ext_readb(0xb8, p);
1837 break;
1838 case 0x5aed: case 0x5aee:
1839 ret = mach64_ext_readb(0xb9, p);
1840 break;
1842 case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
1843 ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga);
1844 break;
1846 case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
1847 ret = mach64_ext_readb(0xc4 | (port & 3), p);
1848 break;
1850 case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
1851 ret = mach64_ext_readb(0xd0 | (port & 3), p);
1852 break;
1854 case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
1855 mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4);
1856 READ8(port, mach64->config_cntl);
1857 break;
1859 case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef:
1860 ret = mach64_ext_readb(0xe0 | (port & 3), p);
1861 break;
1863 case 0x72ec:
1864 if (PCI)
1865 ret = 7 | (3 << 3); /*PCI, 256Kx16 DRAM*/
1866 else
1867 ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/
1868 break;
1870 default:
1871 ret = 0;
1872 break;
1874 #ifdef MACH64_DEBUG
1875 pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,pc);
1876 #endif
1877 return ret;
1879 uint16_t mach64_ext_inw(uint16_t port, void *p)
1881 mach64_t *mach64 = (mach64_t *)p;
1882 uint16_t ret;
1883 switch (port)
1885 default:
1886 #ifdef MACH64_DEBUG
1887 pclog(" ");
1888 #endif
1889 ret = mach64_ext_inb(port, p);
1890 #ifdef MACH64_DEBUG
1891 pclog(" ");
1892 #endif
1893 ret |= (mach64_ext_inb(port + 1, p) << 8);
1894 break;
1896 #ifdef MACH64_DEBUG
1897 pclog("mach64_ext_inw : port %04X ret %04X\n", port, ret);
1898 #endif
1899 return ret;
1901 uint32_t mach64_ext_inl(uint16_t port, void *p)
1903 mach64_t *mach64 = (mach64_t *)p;
1904 uint32_t ret;
1905 switch (port)
1907 case 0x56ec:
1908 ret = mach64_ext_readl(0xb4, p);
1909 break;
1910 case 0x5aec:
1911 ret = mach64_ext_readl(0xb8, p);
1912 break;
1914 default:
1915 #ifdef MACH64_DEBUG
1916 pclog(" ");
1917 #endif
1918 ret = mach64_ext_inw(port, p);
1919 #ifdef MACH64_DEBUG
1920 pclog(" ");
1921 #endif
1922 ret |= (mach64_ext_inw(port + 2, p) << 16);
1923 break;
1925 #ifdef MACH64_DEBUG
1926 pclog("mach64_ext_inl : port %04X ret %08X\n", port, ret);
1927 #endif
1928 return ret;
1931 void mach64_ext_outb(uint16_t port, uint8_t val, void *p)
1933 mach64_t *mach64 = (mach64_t *)p;
1934 #ifdef MACH64_DEBUG
1935 pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,pc);
1936 #endif
1937 switch (port)
1939 case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
1940 case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
1941 mach64_ext_writeb(0x00 | (port & 3), val, p);
1942 break;
1943 case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
1944 mach64_ext_writeb(0x08 | (port & 3), val, p);
1945 break;
1946 case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
1947 mach64_ext_writeb(0x0c | (port & 3), val, p);
1948 break;
1950 case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
1951 mach64_ext_writeb(0x14 | (port & 3), val, p);
1952 break;
1954 case 0x1aec:
1955 mach64_ext_writeb(0x18, val, p);
1956 break;
1958 case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
1959 mach64_ext_writeb(0x1c | (port & 3), val, p);
1960 break;
1962 case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef:
1963 mach64_ext_writeb(0x40 | (port & 3), val, p);
1964 break;
1965 case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef:
1966 mach64_ext_writeb(0x44 | (port & 3), val, p);
1967 break;
1968 case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef:
1969 mach64_ext_writeb(0x48 | (port & 3), val, p);
1970 break;
1972 case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
1973 mach64_ext_writeb(0x68 | (port & 3), val, p);
1974 break;
1975 case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
1976 mach64_ext_writeb(0x6c | (port & 3), val, p);
1977 break;
1978 case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
1979 mach64_ext_writeb(0x70 | (port & 3), val, p);
1980 break;
1982 case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
1983 mach64_ext_writeb(0x80 | (port & 3), val, p);
1984 break;
1985 case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
1986 mach64_ext_writeb(0x84 | (port & 3), val, p);
1987 break;
1988 case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
1989 mach64_ext_writeb(0x90 | (port & 3), val, p);
1990 break;
1992 case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
1993 mach64_ext_writeb(0xb0 | (port & 3), val, p);
1994 break;
1996 case 0x56ec:
1997 mach64_ext_writeb(0xb4, val, p);
1998 break;
1999 case 0x56ed: case 0x56ee:
2000 mach64_ext_writeb(0xb5, val, p);
2001 break;
2002 case 0x5aec:
2003 mach64_ext_writeb(0xb8, val, p);
2004 break;
2005 case 0x5aed: case 0x5aee:
2006 mach64_ext_writeb(0xb9, val, p);
2007 break;
2009 case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
2010 ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga);
2011 break;
2013 case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
2014 mach64_ext_writeb(0xc4 | (port & 3), val, p);
2015 break;
2017 case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
2018 mach64_ext_writeb(0xd0 | (port & 3), val, p);
2019 break;
2021 case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
2022 WRITE8(port, mach64->config_cntl, val);
2023 mach64_updatemapping(mach64);
2024 break;
2027 void mach64_ext_outw(uint16_t port, uint16_t val, void *p)
2029 mach64_t *mach64 = (mach64_t *)p;
2030 #ifdef MACH64_DEBUG
2031 pclog("mach64_ext_outw : port %04X val %04X\n", port, val);
2032 #endif
2033 switch (port)
2035 default:
2036 #ifdef MACH64_DEBUG
2037 pclog(" ");
2038 #endif
2039 mach64_ext_outb(port, val, p);
2040 #ifdef MACH64_DEBUG
2041 pclog(" ");
2042 #endif
2043 mach64_ext_outb(port + 1, val >> 8, p);
2044 break;
2047 void mach64_ext_outl(uint16_t port, uint32_t val, void *p)
2049 mach64_t *mach64 = (mach64_t *)p;
2050 pclog("mach64_ext_outl : port %04X val %08X\n", port, val);
2051 switch (port)
2053 default:
2054 #ifdef MACH64_DEBUG
2055 pclog(" ");
2056 #endif
2057 mach64_ext_outw(port, val, p);
2058 #ifdef MACH64_DEBUG
2059 pclog(" ");
2060 #endif
2061 mach64_ext_outw(port + 2, val >> 16, p);
2062 break;
2066 void mach64_write(uint32_t addr, uint8_t val, void *p)
2068 mach64_t *mach64 = (mach64_t *)p;
2069 svga_t *svga = &mach64->svga;
2070 // pclog("mach64_write : %05X %02X ", addr, val);
2071 addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1];
2072 // pclog("%08X\n", addr);
2073 svga_write_linear(addr, val, svga);
2076 uint8_t mach64_read(uint32_t addr, void *p)
2078 mach64_t *mach64 = (mach64_t *)p;
2079 svga_t *svga = &mach64->svga;
2080 uint8_t ret;
2081 // pclog("mach64_read : %05X ", addr);
2082 addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1];
2083 ret = svga_read_linear(addr, svga);
2084 // pclog("%08X %02X\n", addr, ret);
2085 return ret;
2088 void mach64_hwcursor_draw(svga_t *svga, int displine)
2090 int x, offset;
2091 uint8_t dat;
2092 offset = svga->hwcursor_latch.xoff;
2093 for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
2095 dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
2096 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0;
2097 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
2098 dat >>= 2;
2099 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0;
2100 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
2101 dat >>= 2;
2102 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0;
2103 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
2104 dat >>= 2;
2105 if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0;
2106 else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
2107 dat >>= 2;
2108 offset += 4;
2110 svga->hwcursor_latch.addr += 16;
2113 static void mach64_io_remove(mach64_t *mach64)
2115 int c;
2117 io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2119 for (c = 0; c < 8; c++)
2121 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);
2122 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);
2123 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);
2124 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);
2127 io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2130 static void mach64_io_set(mach64_t *mach64)
2132 int c;
2134 mach64_io_remove(mach64);
2136 io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2138 for (c = 0; c < 8; c++)
2140 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);
2141 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);
2142 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);
2143 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);
2146 io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
2149 uint8_t mach64_pci_read(int func, int addr, void *p)
2151 mach64_t *mach64 = (mach64_t *)p;
2152 svga_t *svga = &mach64->svga;
2154 // pclog("Mach64 PCI read %08X\n", addr);
2156 switch (addr)
2158 case 0x00: return 0x02; /*ATi*/
2159 case 0x01: return 0x10;
2161 case 0x02: return 'X'; /*88800GX*/
2162 case 0x03: return 'G';
2164 case PCI_REG_COMMAND:
2165 return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
2167 case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
2169 case 0x08: return 0; /*Revision ID*/
2170 case 0x09: return 0; /*Programming interface*/
2172 case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/
2173 case 0x0b: return 0x03;
2175 case 0x10: return 0x00; /*Linear frame buffer address*/
2176 case 0x11: return 0x00;
2177 case 0x12: return mach64->linear_base >> 16;
2178 case 0x13: return mach64->linear_base >> 24;
2180 case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/
2181 case 0x31: return 0x00;
2182 case 0x32: return mach64->pci_regs[0x32];
2183 case 0x33: return mach64->pci_regs[0x33];
2185 return 0;
2188 void mach64_pci_write(int func, int addr, uint8_t val, void *p)
2190 mach64_t *mach64 = (mach64_t *)p;
2192 // pclog("Mach64 PCI write %08X %02X\n", addr, val);
2194 switch (addr)
2196 case PCI_REG_COMMAND:
2197 mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27;
2198 if (val & PCI_COMMAND_IO)
2199 mach64_io_set(mach64);
2200 else
2201 mach64_io_remove(mach64);
2202 mach64_updatemapping(mach64);
2203 break;
2205 case 0x12:
2206 mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16);
2207 mach64_updatemapping(mach64);
2208 break;
2209 case 0x13:
2210 mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24);
2211 mach64_updatemapping(mach64);
2212 break;
2214 case 0x30: case 0x32: case 0x33:
2215 mach64->pci_regs[addr] = val;
2216 if (mach64->pci_regs[0x30] & 0x01)
2218 uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24);
2219 pclog("Mach64 bios_rom enabled at %08x\n", addr);
2220 mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000);
2222 else
2224 pclog("Mach64 bios_rom disabled\n");
2225 mem_mapping_disable(&mach64->bios_rom.mapping);
2227 return;
2231 void *mach64gx_init()
2233 int c;
2234 mach64_t *mach64 = malloc(sizeof(mach64_t));
2235 memset(mach64, 0, sizeof(mach64_t));
2237 mach64->vram_size = device_get_config_int("memory");
2238 mach64->vram_mask = (mach64->vram_size << 20) - 1;
2240 svga_init(&mach64->svga, mach64, mach64->vram_size << 20,
2241 mach64_recalctimings,
2242 mach64_in, mach64_out,
2243 mach64_hwcursor_draw,
2244 NULL);
2246 rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
2247 if (PCI)
2248 mem_mapping_disable(&mach64->bios_rom.mapping);
2250 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);
2251 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);
2252 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);
2253 mem_mapping_disable(&mach64->mmio_mapping);
2255 mach64_io_set(mach64);
2257 pci_add(mach64_pci_read, mach64_pci_write, mach64);
2259 mach64->pci_regs[PCI_REG_COMMAND] = 3;
2260 mach64->pci_regs[0x30] = 0x00;
2261 mach64->pci_regs[0x32] = 0x0c;
2262 mach64->pci_regs[0x33] = 0x00;
2264 ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1);
2266 ati68860_ramdac_init(&mach64->ramdac);
2268 mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/
2270 mach64->dst_cntl = 3;
2272 return mach64;
2275 int mach64gx_available()
2277 return rom_present("roms/mach64gx/bios.bin");
2280 void mach64_close(void *p)
2282 mach64_t *mach64 = (mach64_t *)p;
2284 svga_close(&mach64->svga);
2286 free(mach64);
2289 void mach64_speed_changed(void *p)
2291 mach64_t *mach64 = (mach64_t *)p;
2293 svga_recalctimings(&mach64->svga);
2296 void mach64_force_redraw(void *p)
2298 mach64_t *mach64 = (mach64_t *)p;
2300 mach64->svga.fullchange = changeframecount;
2303 void mach64_add_status_info(char *s, int max_len, void *p)
2305 mach64_t *mach64 = (mach64_t *)p;
2307 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
2309 svga_t *svga = &mach64->svga;
2310 char temps[128];
2311 int bpp = 4;
2313 strncat(s, "Mach64 in native mode\n", max_len);
2315 switch ((mach64->crtc_gen_cntl >> 8) & 7)
2317 case 1: bpp = 4; break;
2318 case 2: bpp = 8; break;
2319 case 3: bpp = 15; break;
2320 case 4: bpp = 16; break;
2321 case 5: bpp = 24; break;
2322 case 6: bpp = 32; break;
2325 sprintf(temps, "Mach64 colour depth : %i bpp\n", bpp);
2326 strncat(s, temps, max_len);
2328 sprintf(temps, "Mach64 resolution : %i x %i\n", svga->hdisp, svga->dispend);
2329 strncat(s, temps, max_len);
2331 sprintf(temps, "Mach64 refresh rate : %i Hz\n\n", svga->frames);
2332 svga->frames = 0;
2333 strncat(s, temps, max_len);
2335 else
2337 strncat(s, "Mach64 in SVGA mode\n", max_len);
2338 svga_add_status_info(s, max_len, &mach64->svga);
2342 static device_config_t mach64gx_config[] =
2345 .name = "memory",
2346 .description = "Memory size",
2347 .type = CONFIG_SELECTION,
2348 .selection =
2351 .description = "1 MB",
2352 .value = 1
2353 },
2355 .description = "2 MB",
2356 .value = 2
2357 },
2359 .description = "4 MB",
2360 .value = 4
2361 },
2363 .description = ""
2365 },
2366 .default_int = 4
2367 },
2369 .type = -1
2371 };
2373 device_t mach64gx_device =
2375 "ATI Mach64GX",
2376 0,
2377 mach64gx_init,
2378 mach64_close,
2379 mach64gx_available,
2380 mach64_speed_changed,
2381 mach64_force_redraw,
2382 mach64_add_status_info,
2383 mach64gx_config
2384 };