Merge pull request #4048 from 86Box/tc1995

ATI Mach8/32 mode changes and cleanup:
This commit is contained in:
Miran Grča
2024-01-15 21:46:34 +01:00
committed by GitHub
8 changed files with 1075 additions and 657 deletions

View File

@@ -33,6 +33,8 @@ typedef struct hwcursor8514_t {
} hwcursor8514_t;
typedef struct ibm8514_t {
rom_t bios_rom;
rom_t bios_rom2;
hwcursor8514_t hwcursor;
hwcursor8514_t hwcursor_latch;
uint8_t pos_regs[8];
@@ -60,12 +62,12 @@ typedef struct ibm8514_t {
int dac_b;
int internal_pitch;
int hwcursor_on;
int modechange;
struct {
uint16_t subsys_cntl;
uint16_t setup_md;
uint16_t advfunc_cntl;
uint8_t ext_advfunc_cntl;
uint16_t cur_y;
uint16_t cur_x;
int16_t destx;
@@ -142,14 +144,21 @@ typedef struct ibm8514_t {
uint16_t test;
int vendor_mode[2];
int h_blankstart;
int h_blank_end_val;
int hblankstart;
int hblank_end_val;
int hblankend;
int hblank_ext;
int hblank_sub;
int v_total;
int dispend;
int v_syncstart;
int split;
int h_disp;
int h_disp_old;
int h_total;
int h_sync_width;
int h_disp_time;
int rowoffset;
int dispon;
@@ -176,20 +185,17 @@ typedef struct ibm8514_t {
uint8_t data_available;
uint8_t data_available2;
uint8_t scanmodulos;
uint8_t rowcount;
int hsync_start;
int hsync_width;
int htotal;
int hdisp;
int vtadj;
int vdadj;
int vsadj;
int hdisped;
int sc;
int vtb;
int vdb;
int vsb;
int vsyncstart;
int vsyncwidth;
int vtotal;
int v_disp;
int vdisp;
int disp_cntl;
int interlace;
@@ -205,6 +211,7 @@ typedef struct ibm8514_t {
int pitch;
int ext_pitch;
int ext_crt_pitch;
int extensions;
} ibm8514_t;
#endif /*VIDEO_8514A_H*/

View File

@@ -0,0 +1,162 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the 8514/A-compatible Mach8 and Mach32 graphics
* chips from ATI for the ISA/VLB/MCA/PCI buses.
*
*
*
* Authors: TheCollector1995.
*
* Copyright 2022-2024 TheCollector1995.
*/
#ifndef VIDEO_ATI_MACH8_H
#define VIDEO_ATI_MACH8_H
typedef struct mach_t {
ati_eeprom_t eeprom;
svga_t svga;
rom_t bios_rom;
rom_t bios_rom2;
mem_mapping_t mmio_linear_mapping;
int mca_bus;
int pci_bus;
int vlb_bus;
int has_bios;
uint8_t regs[256];
uint8_t pci_regs[256];
uint8_t int_line;
uint8_t pci_slot;
uint8_t irq_state;
int index;
int ramdac_type;
int old_mode;
uint32_t memory;
uint16_t config1;
uint16_t config2;
uint8_t pos_regs[8];
uint8_t pci_cntl_reg;
uint8_t cursor_col_0;
uint8_t cursor_col_1;
uint8_t ext_cur_col_0_r;
uint8_t ext_cur_col_1_r;
uint8_t ext_cur_col_0_g;
uint8_t ext_cur_col_1_g;
uint16_t cursor_col_0_rg;
uint16_t cursor_col_1_rg;
uint16_t cursor_col_b;
uint16_t cursor_offset_lo;
uint16_t cursor_offset_lo_reg;
uint16_t cursor_offset_hi;
uint16_t cursor_offset_hi_reg;
uint16_t cursor_vh_offset;
uint16_t cursor_x;
uint16_t cursor_y;
uint16_t misc;
uint16_t memory_aperture;
uint16_t local_cntl;
uint32_t linear_base;
uint8_t ap_size;
uint8_t bank_w;
uint8_t bank_r;
uint16_t shadow_set;
uint16_t shadow_cntl;
int ext_on[2];
int compat_mode;
struct {
uint8_t line_idx;
int16_t line_array[6];
uint8_t patt_idx;
uint8_t patt_len;
uint8_t pix_trans[2];
uint8_t eeprom_control;
uint16_t dest_x_end;
uint16_t dest_x_start;
uint16_t dest_y_end;
uint16_t src_x_end;
uint16_t src_x_start;
uint16_t src_x;
uint16_t src_y;
int16_t bres_count;
uint16_t clock_sel;
uint16_t crt_pitch;
uint16_t ge_pitch;
uint16_t dest_cmp_fn;
uint16_t dp_config;
uint16_t ext_ge_config;
uint16_t ge_offset_lo;
uint16_t ge_offset_hi;
uint16_t linedraw_opt;
uint16_t max_waitstates;
uint8_t patt_data_idx;
uint8_t patt_data[0x18];
uint16_t scan_to_x;
uint16_t scratch0;
uint16_t scratch1;
uint16_t test;
uint16_t pattern;
uint16_t test2;
int src_y_dir;
int cmd_type;
int block_write_mono_pattern_enable;
int mono_pattern_enable;
int16_t cx_end_line;
int16_t cy_end_line;
int16_t cx;
int16_t cx_end;
int16_t cy_end;
int16_t dx;
int16_t dx_end;
int16_t dy;
int16_t dy_end;
int16_t dx_start;
int16_t dy_start;
int16_t cy;
int16_t sx_start;
int16_t sx_end;
int16_t sx;
int16_t x_count;
int16_t xx_count;
int16_t xxx_count;
int16_t sy;
int16_t y_count;
int16_t err;
int16_t width;
int16_t src_width;
int16_t height;
int16_t bleft, bright, btop, bbottom;
int poly_src;
int temp_cnt;
int stepx;
int stepy;
int src_stepx;
uint8_t color_pattern[16];
uint8_t color_pattern_full[32];
uint16_t color_pattern_word[8];
int mono_pattern[8][8];
uint32_t ge_offset;
uint32_t crt_offset;
uint32_t patt_len_reg;
int poly_fill;
uint16_t dst_clr_cmp_mask;
int clip_overrun;
int color_pattern_idx;
} accel;
atomic_int force_busy;
} mach_t;
#endif /*VIDEO_ATI_MACH8_H*/

View File

@@ -281,6 +281,7 @@ typedef struct svga_t {
uint32_t (*conv_16to32)(struct svga_t *svga, uint16_t color, uint8_t bpp);
void * dev8514;
void * ext8514;
void * xga;
} svga_t;
@@ -296,6 +297,13 @@ extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t
extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len);
extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len);
#ifdef ATI_8514_ULTRA
extern void ati8514_recalctimings(svga_t *svga);
extern uint8_t ati8514_mca_read(int port, void *priv);
extern void ati8514_mca_write(int port, uint8_t val, void *priv);
extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514);
#endif
extern void xga_poll(void *priv, svga_t *svga);
extern void xga_recalctimings(svga_t *svga);

View File

@@ -306,7 +306,7 @@ extern void xga_device_add(void);
/* IBM 8514/A and clones*/
extern void ibm8514_device_add(void);
extern const device_t mach8_isa_device;
extern const device_t mach8_vga_isa_device;
extern const device_t mach32_isa_device;
extern const device_t mach32_vlb_device;
extern const device_t mach32_mca_device;

View File

@@ -13,7 +13,7 @@
*
* Authors: TheCollector1995.
*
* Copyright 2022-2023 TheCollector1995.
* Copyright 2022-2024 TheCollector1995.
*/
#include <stdarg.h>
#include <stdint.h>
@@ -38,8 +38,14 @@
#include <86box/vid_xga.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/vid_ati_eeprom.h>
#include <86box/vid_ati_mach8.h>
#include "cpu.h"
#ifdef ATI_8514_ULTRA
#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN"
#endif
static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv);
static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv);
static uint8_t ibm8514_accel_inb(uint16_t port, void *priv);
@@ -63,6 +69,27 @@ ibm8514_log(const char *fmt, ...)
# define ibm8514_log(fmt, ...)
#endif
#define WRITE8(addr, var, val) \
switch ((addr) & 1) { \
case 0: \
var = (var & 0xff00) | (val); \
break; \
case 1: \
var = (var & 0x00ff) | ((val) << 8); \
break; \
}
#define READ8(addr, var) \
switch ((addr) & 1) { \
case 0: \
temp = (var) & 0xff; \
break; \
case 1: \
temp = ((var) >> 8) & 0xff; \
break; \
}
#define READ_PIXTRANS_WORD(cx, n) \
if ((cmd <= 1) || (cmd == 5)) { \
temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \
@@ -453,16 +480,15 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
switch (port) {
case 0x82e8:
case 0xc2e8:
if (len == 1) {
if (len == 1)
dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val;
} else
else
dev->accel.cur_y = val & 0x7ff;
break;
case 0x82e9:
case 0xc2e9:
if (len == 1) {
if (len == 1)
dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8);
}
break;
case 0x86e8:
@@ -474,9 +500,8 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
break;
case 0x86e9:
case 0xc6e9:
if (len == 1) {
if (len == 1)
dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8);
}
break;
case 0x8ae8:
@@ -742,16 +767,19 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
else {
dev->accel.multifunc_cntl = val;
dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff;
if ((dev->accel.multifunc_cntl >> 12) == 1) {
if ((dev->accel.multifunc_cntl >> 12) == 1)
dev->accel.clip_top = val & 0x7ff;
if (val & 0x400)
dev->accel.clip_top |= ~0x3ff;
}
if ((dev->accel.multifunc_cntl >> 12) == 2) {
if ((dev->accel.multifunc_cntl >> 12) == 2)
dev->accel.clip_left = val & 0x7ff;
if (val & 0x400)
dev->accel.clip_left |= ~0x3ff;
}
if ((dev->accel.multifunc_cntl >> 12) == 3)
dev->accel.multifunc[3] = val & 0x7ff;
if ((dev->accel.multifunc_cntl >> 12) == 4)
dev->accel.multifunc[4] = val & 0x7ff;
ibm8514_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch);
if (port == 0xfee8)
dev->accel.cmd_back = 1;
else
@@ -763,6 +791,12 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
if (len == 1) {
dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8);
dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff;
if ((dev->accel.multifunc_cntl >> 12) == 1)
dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff;
if ((dev->accel.multifunc_cntl >> 12) == 2)
dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff;
if (port == 0xfee9)
dev->accel.cmd_back = 1;
else
@@ -855,151 +889,118 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t old = 0;
if (port & 0x8000) {
if (port & 0x8000)
ibm8514_accel_out_fifo(svga, port, val, len);
} else {
else {
switch (port) {
case 0x2e8:
if (len == 1)
dev->htotal = (dev->htotal & 0xff00) | val;
else {
dev->htotal = val;
svga_recalctimings(svga);
}
break;
case 0x2e9:
if (len != 1) {
dev->htotal = (dev->htotal & 0xff) | (val << 8);
ibm8514_log("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1);
svga_recalctimings(svga);
}
WRITE8(port, dev->htotal, val);
break;
case 0x6e8:
dev->hdisp = val;
ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1);
svga_recalctimings(svga);
case 0x6e9:
if (!(port & 1)) {
dev->hdisped = val;
dev->hdisp = (dev->hdisped + 1) << 3;
}
ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4);
break;
case 0xae8:
case 0xae9:
if (!(port & 1)) {
dev->hsync_start = val;
dev->hblankstart = (dev->hsync_start & 0x07) + 1;
}
ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1);
svga_recalctimings(svga);
break;
case 0xee8:
case 0xee9:
if (!(port & 1)) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
}
ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
svga_recalctimings(svga);
break;
case 0x12e8:
if (len == 1)
dev->vtotal = (dev->vtotal & 0x1f00) | val;
else {
dev->vtotal = val & 0x1fff;
svga_recalctimings(svga);
}
break;
case 0x12e9:
if (len == 1) {
dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8);
ibm8514_log("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal);
svga_recalctimings(svga);
}
WRITE8(port, dev->vtotal, val);
dev->vtotal &= 0x1fff;
break;
case 0x16e8:
if (len == 1)
dev->vdisp = (dev->vdisp & 0x1f00) | val;
else {
dev->vdisp = val & 0x1fff;
svga_recalctimings(svga);
}
break;
case 0x16e9:
if (len == 1) {
dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8);
ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp);
svga_recalctimings(svga);
}
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
dev->vdisp = dev->v_disp;
dev->vdisp >>= 1;
dev->vdisp++;
ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp);
break;
case 0x1ae8:
if (len == 1)
dev->vsyncstart = (dev->vsyncstart & 0x1f00) | val;
else {
dev->vsyncstart = val & 0x1fff;
svga_recalctimings(svga);
}
break;
case 0x1ae9:
if (len == 1) {
dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8);
ibm8514_log("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart);
svga_recalctimings(svga);
}
WRITE8(port, dev->vsyncstart, val);
dev->vsyncstart &= 0x1fff;
break;
case 0x1ee8:
dev->vsyncwidth = val;
case 0x1ee9:
ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val);
svga_recalctimings(svga);
break;
case 0x22e8:
dev->disp_cntl = val & 0x7e;
dev->interlace = !!(val & 0x10);
ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos);
svga_recalctimings(svga);
ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace);
break;
case 0x42e8:
old = dev->subsys_stat;
if ((val & 0xff) & 1)
if (val & 1)
dev->subsys_stat &= ~1;
if ((val & 0xff) & 2)
if (val & 2)
dev->subsys_stat &= ~2;
if ((val & 0xff) & 4)
if (val & 4)
dev->subsys_stat &= ~4;
if ((val & 0xff) & 8)
if (val & 8)
dev->subsys_stat &= ~8;
if (len != 1) {
old = dev->subsys_cntl;
dev->subsys_cntl = (val >> 8);
if ((old ^ dev->subsys_cntl) & 1)
dev->subsys_stat |= 1;
if ((old ^ dev->subsys_cntl) & 2)
dev->subsys_stat |= 2;
if ((old ^ dev->subsys_cntl) & 4)
dev->subsys_stat |= 4;
if ((old ^ dev->subsys_cntl) & 8)
dev->subsys_stat |= 8;
}
break;
case 0x42e9:
if (len == 1) {
old = dev->subsys_cntl;
dev->subsys_cntl = val;
if ((old ^ val) & 1)
dev->subsys_stat |= 1;
if ((old ^ val) & 2)
dev->subsys_stat |= 2;
if ((old ^ val) & 4)
dev->subsys_stat |= 4;
if ((old ^ val) & 8)
dev->subsys_stat |= 8;
}
old = dev->subsys_cntl;
dev->subsys_cntl = val;
if ((old ^ val) & 1)
dev->subsys_stat |= 1;
if ((old ^ val) & 2)
dev->subsys_stat |= 2;
if ((old ^ val) & 4)
dev->subsys_stat |= 4;
if ((old ^ val) & 8)
dev->subsys_stat |= 8;
break;
case 0x4ae8:
if (!val)
break;
dev->accel.advfunc_cntl = val & 0x0f;
dev->on[0] = val & 0x01;
vga_on = !dev->on[0];
ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val);
case 0x4ae9:
WRITE8(port, dev->accel.advfunc_cntl, val);
dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01;
vga_on = !dev->on[port & 1];
dev->vendor_mode[port & 1] = 0;
if (dev->on[0] || dev->on[1]) {
if (!(dev->accel.advfunc_cntl & 4)) {
if (dev->disp_cntl & 0x60) {
dev->hdisp = 640;
dev->vdisp = 480;
}
}
}
ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4);
svga_recalctimings(svga);
break;
default:
break;
}
@@ -1036,16 +1037,16 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
vpos = dev->vc & 0x7ff;
if (vblankend > dev->v_total) {
vblankend -= dev->v_total;
if (vpos >= svga->vblankstart || vpos <= vblankend)
if ((vpos >= svga->vblankstart) || (vpos <= vblankend))
temp |= 2;
} else {
if (vpos >= svga->vblankstart && vpos <= vblankend)
if ((vpos >= svga->vblankstart) && (vpos <= vblankend))
temp |= 2;
}
break;
case 0x6e8:
temp = dev->hdisp;
temp = dev->hdisped;
break;
case 0x22e8:
@@ -1091,22 +1092,19 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
case 0x82e8:
case 0xc2e8:
if (len != 1) {
if (len != 1)
temp = dev->accel.cur_y;
}
break;
case 0x86e8:
case 0xc6e8:
if (len != 1) {
if (len != 1)
temp = dev->accel.cur_x;
}
break;
case 0x92e8:
if (len != 1) {
if (len != 1)
temp = dev->test;
}
break;
case 0x9ae8:
@@ -1200,12 +1198,6 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t
ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, svga, len);
}
#define CLAMP(x) \
do { \
if ((x) & ~0xff) \
x = ((x) < 0) ? 0 : 0xff; \
} while (0)
void
ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, UNUSED(int len))
{
@@ -3831,8 +3823,6 @@ bitblt:
}
}
#undef CLAMP
void
ibm8514_render_8bpp(svga_t *svga)
{
@@ -3840,9 +3830,8 @@ ibm8514_render_8bpp(svga_t *svga)
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0) {
if ((dev->displine + svga->y_add) < 0)
return;
}
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
@@ -4184,6 +4173,7 @@ ibm8514_poll(void *priv, svga_t *svga)
dev->maback += (dev->rowoffset << 3);
if (dev->interlace)
dev->maback += (dev->rowoffset << 3);
dev->maback &= dev->vram_mask;
dev->ma = dev->maback;
} else {
@@ -4260,65 +4250,66 @@ ibm8514_recalctimings(svga_t *svga)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
if (dev->on[0]) {
dev->h_disp = (dev->hdisp + 1) << 3;
dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640;
dev->h_total = (dev->htotal + 1);
dev->v_total = (dev->vtotal + 1);
dev->v_syncstart = (dev->vsyncstart + 1);
dev->rowcount = !!(dev->disp_cntl & 0x08);
dev->dispend = ((dev->vdisp >> 1) + 1);
if (dev->dispend == 766)
dev->dispend += 2;
#ifdef ATI_8514_ULTRA
if (dev->extensions) {
if (svga->ext8514 != NULL)
ati8514_recalctimings(svga);
} else
#endif
{
if (dev->on[0] || dev->on[1]) {
dev->h_disp = dev->hdisp;
dev->h_total = dev->htotal + 1;
dev->h_blankstart = dev->hblankstart;
dev->h_blank_end_val = dev->hblank_end_val;
dev->v_total = dev->vtotal + 1;
dev->v_syncstart = dev->vsyncstart + 1;
dev->rowcount = !!(dev->disp_cntl & 0x08);
dev->dispend = dev->vdisp;
if (dev->dispend == 598)
dev->dispend += 2;
if (dev->accel.advfunc_cntl & 4) {
if (dev->h_disp == 8) {
dev->h_disp = 1024;
dev->dispend = 768;
dev->v_total = 1536;
dev->v_syncstart = 1536;
}
if (dev->dispend == 766)
dev->dispend += 2;
if (dev->dispend == 598)
dev->dispend = 600;
dev->dispend += 2;
if (dev->interlace) {
dev->dispend >>= 1;
dev->v_syncstart >>= 2;
dev->v_total >>= 2;
if (dev->accel.advfunc_cntl & 4) {
dev->pitch = 1024;
if (!dev->h_disp) {
dev->h_disp = 1024;
dev->dispend = 768;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
dev->v_syncstart >>= 1;
dev->v_total >>= 1;
dev->pitch = 640;
if (!dev->h_disp) {
dev->h_disp = 640;
dev->dispend = 480;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
if (dev->interlace)
dev->dispend >>= 1;
dev->rowoffset = 0x80;
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
ibm8514_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace);
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
if (dev->h_disp == 1024) {
dev->h_disp = 640;
dev->dispend = 480;
dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val;
if (dev->hblankend <= dev->h_blankstart)
dev->hblankend += 0x40;
dev->hblankend += dev->hblank_ext;
dev->hblank_sub = 0;
if (dev->hblankend > dev->h_total) {
dev->hblankend &= 0x3f;
dev->hblank_sub = dev->hblankend + 1;
dev->h_disp -= dev->hblank_sub;
}
if (dev->interlace) {
dev->dispend >>= 1;
dev->v_syncstart >>= 2;
dev->v_total >>= 2;
} else {
dev->v_syncstart >>= 1;
dev->v_total >>= 1;
}
dev->rowoffset = 0x80;
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled);
}
svga->render8514 = ibm8514_render_8bpp;
ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, mode = %d, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->ibm_mode, dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled);
}
ibm8514_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split);
}
@@ -4355,6 +4346,19 @@ ibm8514_mca_feedb(void *priv)
return dev->pos_regs[2] & 1;
}
static void
ibm8514_mca_reset(void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
ibm8514_log("MCA reset.\n");
dev->on[0] = 0;
dev->on[1] = 0;
vga_on = 1;
ibm8514_mca_write(0x102, 0, svga);
}
static void *
ibm8514_init(const device_t *info)
{
@@ -4363,8 +4367,10 @@ ibm8514_init(const device_t *info)
svga_t *svga = svga_get_pri();
ibm8514_t *dev = (ibm8514_t *) calloc(1, sizeof(ibm8514_t));
mach_t *mach = NULL;
svga->dev8514 = dev;
svga->ext8514 = NULL;
dev->vram_size = 1024 << 10;
dev->vram = calloc(dev->vram_size, 1);
@@ -4376,13 +4382,56 @@ ibm8514_init(const device_t *info)
dev->type = info->flags;
dev->bpp = 0;
#ifdef ATI_8514_ULTRA
dev->extensions = device_get_config_int("extensions");
switch (dev->extensions) {
case 1:
if (rom_present(BIOS_MACH8_ROM_PATH)) {
mach = (mach_t *) calloc(1, sizeof(mach_t));
svga->ext8514 = mach;
ati8514_init(svga, svga->ext8514, svga->dev8514);
if (dev->type & DEVICE_MCA) {
rom_init(&dev->bios_rom,
BIOS_MACH8_ROM_PATH,
0xc6800, 0x1000, 0x0fff,
0x0800, MEM_MAPPING_EXTERNAL);
mem_mapping_disable(&dev->bios_rom.mapping);
dev->pos_regs[0] = 0x88;
dev->pos_regs[1] = 0x80;
mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga);
ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0);
} else {
rom_init(&dev->bios_rom,
BIOS_MACH8_ROM_PATH,
0xd0000, 0x1000, 0x0fff,
0x0800, MEM_MAPPING_EXTERNAL);
ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0);
}
break;
}
fallthrough;
default:
ibm8514_io_set(svga);
if (dev->type & DEVICE_MCA) {
dev->pos_regs[0] = 0x7f;
dev->pos_regs[1] = 0xef;
mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga);
}
break;
}
#else
ibm8514_io_set(svga);
if (dev->type & DEVICE_MCA) {
dev->pos_regs[0] = 0x7f;
dev->pos_regs[1] = 0xef;
mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, NULL, svga);
mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga);
}
#endif
return svga;
}
@@ -4392,6 +4441,10 @@ ibm8514_close(void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
mach_t *mach = (mach_t *) svga->ext8514;
if (mach)
free(mach);
if (dev) {
free(dev->vram);
@@ -4417,6 +4470,34 @@ ibm8514_force_redraw(void *priv)
svga->fullchange = changeframecount;
}
#ifdef ATI_8514_ULTRA
// clang-format off
static const device_config_t ext8514_config[] = {
{
.name = "extensions",
.description = "Vendor",
.type = CONFIG_SELECTION,
.default_int = 0,
.selection = {
{
.description = "IBM",
.value = 0
},
{
.description = "ATI",
.value = 1
},
{
.description = ""
}
}
},
{
.type = CONFIG_END
}
};
#endif
// clang-format off
const device_t gen8514_isa_device = {
.name = "Generic 8514/A clone (ISA)",

View File

@@ -44,6 +44,7 @@
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_8514a.h>

File diff suppressed because it is too large Load Diff

View File

@@ -80,7 +80,7 @@ video_cards[] = {
{ &vid_none_device },
{ &vid_internal_device },
{ &atiega800p_device },
{ &mach8_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach8_vga_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach32_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_isa_device },
{ &ati28800k_device },