diff --git a/src/ibm.h b/src/ibm.h index c507e1d5b..c29d71bba 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -396,6 +396,7 @@ enum GFX_WD90C11, /*Paradise WD90C11 Standalone*/ GFX_OTI077, /*Oak OTI-077*/ GFX_ET4000W32CS, /*Tseng ET4000/W32p (Cardex) (ICS RAMDAC) */ + GFX_VGAWONDERXL24, /*Compaq ATI VGA Wonder XL24 (28800-6)*/ GFX_MAX }; diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 42795ca11..f9d45df20 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -22,6 +22,8 @@ typedef struct ati28800_t int index; } ati28800_t; +void ati28800_svga_recalctimings(svga_t *svga); + void ati28800_out(uint16_t addr, uint8_t val, void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -42,6 +44,14 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) ati28800->regs[ati28800->index] = val; switch (ati28800->index) { + case 0xad: + if (gfxcard == GFX_VGAWONDERXL24) + { + svga->charseta = (svga->charseta & 0x3ffff) | ((((uint32_t) val) >> 4) << 18); + svga->charsetb = (svga->charsetb & 0x3ffff) | ((((uint32_t) val) >> 4) << 18); + } + break; + case 0xb2: case 0xbe: if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ @@ -75,7 +85,7 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; - svga_recalctimings(svga); + ati28800_svga_recalctimings(svga); } } break; @@ -101,6 +111,10 @@ uint8_t ati28800_in(uint16_t addr, void *p) case 0x1cf: switch (ati28800->index) { + case 0xaa: + temp = (gfxcard == GFX_VGAWONDERXL24) ? 6 : 5; + break; + case 0xb7: temp = ati28800->regs[ati28800->index] & ~8; if (ati_eeprom_read(&ati28800->eeprom)) @@ -135,6 +149,161 @@ uint8_t ati28800_in(uint16_t addr, void *p) return temp; } +void ati28800_svga_recalctimings(svga_t *svga) +{ + double crtcconst; + double _dispontime, _dispofftime, disptime; + int hdisp_old; + + svga->vtotal = svga->crtc[6]; + svga->dispend = svga->crtc[0x12]; + svga->vsyncstart = svga->crtc[0x10]; + svga->split = svga->crtc[0x18]; + svga->vblankstart = svga->crtc[0x15]; + + if (svga->crtc[7] & 1) svga->vtotal |= 0x100; + if (svga->crtc[7] & 32) svga->vtotal |= 0x200; + svga->vtotal += 2; + + if (svga->crtc[7] & 2) svga->dispend |= 0x100; + if (svga->crtc[7] & 64) svga->dispend |= 0x200; + svga->dispend++; + + if (svga->crtc[7] & 4) svga->vsyncstart |= 0x100; + if (svga->crtc[7] & 128) svga->vsyncstart |= 0x200; + svga->vsyncstart++; + + if (svga->crtc[7] & 0x10) svga->split|=0x100; + if (svga->crtc[9] & 0x40) svga->split|=0x200; + svga->split++; + + if (svga->crtc[7] & 0x08) svga->vblankstart |= 0x100; + if (svga->crtc[9] & 0x20) svga->vblankstart |= 0x200; + svga->vblankstart++; + + svga->hdisp = svga->crtc[1]; + svga->hdisp++; + + svga->htotal = svga->crtc[0]; + if ((ati28800->regs[0xad] & 8) && (gfxcard == GFX_VGAWONDERXL24)) svga->htotal |= (ati28800->regs[0xad] & 1) ? 0x100 | 0; + svga->htotal += 6; /*+6 is required for Tyrian*/ + + svga->rowoffset = svga->crtc[0x13]; + + svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1; + + svga->lowres = svga->attrregs[0x10] & 0x40; + + svga->interlace = 0; + + svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + + svga->hdisp_time = svga->hdisp; + svga->render = svga_render_blank; + if (!svga->scrblank && svga->attr_palette_enable) + { + if (!(svga->gdcreg[6] & 1)) /*Text mode*/ + { + if (svga->seqregs[1] & 8) /*40 column*/ + { + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + } + else + { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } + else + { + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; + + switch (svga->gdcreg[5] & 0x60) + { + case 0x00: /*16 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: case 0x60: /*256+ colours*/ + switch (svga->bpp) + { + case 8: + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 24: + if (svga->lowres) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + break; + } + break; + } + } + } + +// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); + + svga->linedbl = svga->crtc[9] & 0x80; + svga->rowcount = svga->crtc[9] & 31; + if (svga->recalctimings_ex) + svga->recalctimings_ex(svga); + + if (svga->vblankstart < svga->dispend) + svga->dispend = svga->vblankstart; + + crtcconst = (svga->seqregs[1] & 1) ? (svga->clock * 8.0) : (svga->clock * 9.0); + + disptime = svga->htotal; + _dispontime = svga->hdisp_time; + +// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); + if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } + _dispofftime = disptime - _dispontime; + _dispontime *= crtcconst; + _dispofftime *= crtcconst; + + svga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + svga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); + printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); + printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); + + pclog("svga->render %08X\n", svga->render);*/ +} + void ati28800_recalctimings(svga_t *svga) { ati28800_t *ati28800 = (ati28800_t *)svga->p; @@ -168,6 +337,13 @@ void *ati28800_init() "roms/XLODD.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); } + else if (gfxcard == GFX_VGAWONDERXL24) + { + rom_init_interleaved(&ati28800->bios_rom, + "roms/112-14318-102.bin", + "roms/112-14319-102.bin", + 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + } else rom_init(&ati28800->bios_rom, "roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -197,6 +373,11 @@ static int compaq_ati28800_available() return (rom_present("roms/XLEVEN.bin") && rom_present("roms/XLODD.bin")); } +static int ati28800_wonderxl24_available() +{ + return (rom_present("roms/112-14318-102.bin") && rom_present("roms/112-14319-102.bin")); +} + void ati28800_close(void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -210,7 +391,7 @@ void ati28800_speed_changed(void *p) { ati28800_t *ati28800 = (ati28800_t *)p; - svga_recalctimings(&ati28800->svga); + ati28800_svga_recalctimings(&ati28800->svga); } void ati28800_force_redraw(void *p) @@ -283,3 +464,16 @@ device_t compaq_ati28800_device = ati28800_add_status_info, ati28800_config }; + +device_t ati28800_wonderxl24_device = +{ + "ATI-28800 (VGA Wonder XL24)", + 0, + ati28800_init, + ati28800_close, + ati28800_wonderxl24_available, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800_add_status_info, + ati28800_config +}; diff --git a/src/vid_ati28800.h b/src/vid_ati28800.h index 68f488783..83b1769b7 100644 --- a/src/vid_ati28800.h +++ b/src/vid_ati28800.h @@ -1,2 +1,3 @@ extern device_t ati28800_device; extern device_t compaq_ati28800_device; +extern device_t ati28800_wonderxl24_device; diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index fa741356b..2f6ac5575 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -274,6 +274,12 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) break; case 0x1cf: mach64->regs[mach64->index & 0x3f] = val; + if ((mach64->index & 0x3f) == 0x2d) + { + svga->charseta = (svga->charseta & 0x3ffff) | ((((uint32_t) val) >> 4) << 18); + svga->charsetb = (svga->charsetb & 0x3ffff) | ((((uint32_t) val) >> 4) << 18); + break; + } if ((mach64->index & 0x3f) == 0x36) mach64_recalctimings(svga); break; @@ -360,11 +366,18 @@ void mach64_recalctimings(svga_t *svga) svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; + if (mach64->regs[0x2d] & 8) svga->htotal |= (mach64->regs[0x2d] & 1) ? 0x100 : 0; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); svga->clock = cpuclock / mach64->ics2595.output_clock; svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; + if (mach64->regs[0x2d] & 8) + { + svga->ma_latch |= (((uint32_t) (mach64->regs[0x30] & 0x40)) >> 6) << 16; + svga->ma_latch |= (((uint32_t) (mach64->regs[0x23] & 0x10)) >> 4) << 17; + svga->ma_latch |= (((uint32_t) (mach64->regs[0x2d] & 0xc)) >> 2) << 18; + } svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; svga->vblankstart = svga->dispend; diff --git a/src/video.c b/src/video.c index 8b3d99ca7..7d1339c08 100644 --- a/src/video.c +++ b/src/video.c @@ -50,7 +50,8 @@ typedef struct static VIDEO_CARD video_cards[] = { {"ATI Graphics Pro Turbo (Mach64 GX)", &mach64gx_device, GFX_MACH64GX}, - {"ATI VGA Charger (ATI-28800)", &ati28800_device, GFX_VGACHARGER}, + {"ATI VGA Charger (ATI-28800-5)", &ati28800_device, GFX_VGACHARGER}, + {"ATI VGA Wonder XL24 (ATI-28800-6)", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24}, {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16}, {"Cardex 1703-DDC (ET4000/W32P)", &et4000w32pc_device, GFX_ET4000W32C}, {"Cardex ICS5341 (ET4000/W32P)", &et4000w32pcs_device, GFX_ET4000W32CS}, @@ -60,7 +61,7 @@ static VIDEO_CARD video_cards[] = {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, {"EGA", &ega_device, GFX_EGA}, {"Chips & Technologies SuperEGA", &sega_device, GFX_SUPER_EGA}, - {"Compaq ATI VGA Wonder XL (ATI-28800)", &compaq_ati28800_device, GFX_VGAWONDERXL}, + {"Compaq ATI VGA Wonder XL (ATI-28800-5)", &compaq_ati28800_device, GFX_VGAWONDERXL}, {"Compaq EGA", &cpqega_device, GFX_COMPAQ_EGA}, {"Compaq/Paradise VGA", &cpqvga_device, GFX_COMPAQ_VGA}, {"Hercules", &hercules_device, GFX_HERCULES},