Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -137,6 +137,7 @@ typedef struct mach_t {
|
|||||||
int16_t dx_end;
|
int16_t dx_end;
|
||||||
int16_t dy;
|
int16_t dy;
|
||||||
int16_t dy_end;
|
int16_t dy_end;
|
||||||
|
int16_t dx_first_row_start;
|
||||||
int16_t dx_start;
|
int16_t dx_start;
|
||||||
int16_t dy_start;
|
int16_t dy_start;
|
||||||
int16_t cy;
|
int16_t cy;
|
||||||
|
|||||||
@@ -61,42 +61,63 @@ typedef enum mda_crtc_registers_e
|
|||||||
typedef enum mda_mode_flags_e
|
typedef enum mda_mode_flags_e
|
||||||
{
|
{
|
||||||
MDA_MODE_HIGHRES = 1 << 0, // MUST be enabled for sane operation
|
MDA_MODE_HIGHRES = 1 << 0, // MUST be enabled for sane operation
|
||||||
MDA_MODE_BLACKANDWHITE = 1 << 1, // UNUSED in most cases. Not present on Hercules
|
MDA_MODE_BW = 1 << 1, // UNUSED in most cases. Not present on Hercules
|
||||||
MDA_MODE_VIDEO_ENABLE = 1 << 3,
|
MDA_MODE_VIDEO_ENABLE = 1 << 3,
|
||||||
MDA_MODE_BLINK = 1 << 5,
|
MDA_MODE_BLINK = 1 << 5,
|
||||||
} mda_mode_flags;
|
} mda_mode_flags;
|
||||||
|
|
||||||
|
typedef enum mda_colors_e
|
||||||
|
{
|
||||||
|
MDA_COLOR_BLACK = 0,
|
||||||
|
MDA_COLOR_BLUE = 1,
|
||||||
|
MDA_COLOR_GREEN = 2,
|
||||||
|
MDA_COLOR_CYAN = 3,
|
||||||
|
MDA_COLOR_RED = 4,
|
||||||
|
MDA_COLOR_MAGENTA = 5,
|
||||||
|
MDA_COLOR_BROWN = 6,
|
||||||
|
MDA_COLOR_WHITE = 7,
|
||||||
|
MDA_COLOR_GREY = 8,
|
||||||
|
MDA_COLOR_BRIGHT_BLUE = 9,
|
||||||
|
MDA_COLOR_BRIGHT_GREEN = 10,
|
||||||
|
MDA_COLOR_BRIGHT_CYAN = 11,
|
||||||
|
MDA_COLOR_BRIGHT_RED = 12,
|
||||||
|
MDA_COLOR_BRIGHT_MAGENTA = 13,
|
||||||
|
MDA_COLOR_BRIGHT_YELLOW = 14,
|
||||||
|
MDA_COLOR_BRIGHT_WHITE = 15,
|
||||||
|
} mda_colors;
|
||||||
|
|
||||||
typedef struct mda_t {
|
typedef struct mda_t {
|
||||||
mem_mapping_t mapping;
|
mem_mapping_t mapping;
|
||||||
|
|
||||||
uint8_t crtc[MDA_CRTC_NUM_REGISTERS];
|
uint8_t crtc[MDA_CRTC_NUM_REGISTERS];
|
||||||
int crtcreg;
|
int32_t crtcreg;
|
||||||
|
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
uint64_t dispontime;
|
uint64_t dispontime;
|
||||||
uint64_t dispofftime;
|
uint64_t dispofftime;
|
||||||
pc_timer_t timer;
|
pc_timer_t timer;
|
||||||
|
|
||||||
int firstline;
|
int32_t firstline;
|
||||||
int lastline;
|
int32_t lastline;
|
||||||
|
|
||||||
int fontbase;
|
int32_t fontbase;
|
||||||
int linepos;
|
int32_t linepos;
|
||||||
int displine;
|
int32_t displine;
|
||||||
int vc;
|
int32_t vc;
|
||||||
int scanline;
|
int32_t scanline;
|
||||||
uint16_t memaddr;
|
uint16_t memaddr;
|
||||||
uint16_t memaddr_backup;
|
uint16_t memaddr_backup;
|
||||||
int cursorvisible;
|
int32_t cursorvisible;
|
||||||
int cursoron;
|
int32_t cursoron;
|
||||||
int dispon;
|
int32_t dispon;
|
||||||
int blink;
|
int32_t blink;
|
||||||
int vsynctime;
|
int32_t vsynctime;
|
||||||
int vadj;
|
int32_t vadj;
|
||||||
int monitor_index;
|
int32_t monitor_index;
|
||||||
int prev_monitor_index;
|
int32_t prev_monitor_index;
|
||||||
|
int32_t monitor_type; // Used for MDA Colour support (REV0 u64)
|
||||||
|
|
||||||
uint8_t *vram;
|
uint8_t *vram;
|
||||||
} mda_t;
|
} mda_t;
|
||||||
|
|||||||
@@ -188,6 +188,10 @@ extern bitmap_t *buffer32;
|
|||||||
#define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y)
|
#define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y)
|
||||||
#define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x)
|
#define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x)
|
||||||
#define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y)
|
#define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y)
|
||||||
|
|
||||||
|
#define CGAPAL_CGA_START 16 // Where the 16-color cga text/composite starts
|
||||||
|
|
||||||
|
|
||||||
extern PALETTE cgapal;
|
extern PALETTE cgapal;
|
||||||
extern PALETTE cgapal_mono[6];
|
extern PALETTE cgapal_mono[6];
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -15,10 +15,39 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
add_library(vid OBJECT
|
add_library(vid OBJECT
|
||||||
|
|
||||||
|
# Video Core
|
||||||
agpgart.c
|
agpgart.c
|
||||||
video.c
|
video.c
|
||||||
vid_table.c
|
vid_table.c
|
||||||
# CGA
|
|
||||||
|
# RAMDAC (Should this be its own library?)
|
||||||
|
ramdac/vid_ramdac_ati68860.c
|
||||||
|
ramdac/vid_ramdac_ati68875.c
|
||||||
|
ramdac/vid_ramdac_att20c49x.c
|
||||||
|
ramdac/vid_ramdac_att2xc498.c
|
||||||
|
ramdac/vid_ramdac_bt48x.c
|
||||||
|
ramdac/vid_ramdac_bt481.c
|
||||||
|
ramdac/vid_ramdac_ibm_rgb528.c
|
||||||
|
ramdac/vid_ramdac_sc1148x.c
|
||||||
|
ramdac/vid_ramdac_sc1502x.c
|
||||||
|
ramdac/vid_ramdac_sdac.c
|
||||||
|
ramdac/vid_ramdac_stg1702.c
|
||||||
|
ramdac/vid_ramdac_tkd8001.c
|
||||||
|
ramdac/vid_ramdac_tvp3026.c
|
||||||
|
|
||||||
|
# Clock generator chips
|
||||||
|
clockgen/vid_clockgen_av9194.c
|
||||||
|
clockgen/vid_clockgen_icd2061.c
|
||||||
|
clockgen/vid_clockgen_ics2494.c
|
||||||
|
clockgen/vid_clockgen_ics2595.c
|
||||||
|
|
||||||
|
# DDC / monitor identification stuff
|
||||||
|
vid_ddc.c
|
||||||
|
|
||||||
|
# CARDS start here
|
||||||
|
|
||||||
|
# CGA / Super CGA
|
||||||
vid_cga.c
|
vid_cga.c
|
||||||
vid_cga_comp.c
|
vid_cga_comp.c
|
||||||
vid_cga_compaq.c
|
vid_cga_compaq.c
|
||||||
@@ -32,64 +61,84 @@ add_library(vid OBJECT
|
|||||||
# PCJr/Tandy
|
# PCJr/Tandy
|
||||||
vid_pcjr.c
|
vid_pcjr.c
|
||||||
vid_tandy.c
|
vid_tandy.c
|
||||||
|
|
||||||
vid_mda.c
|
vid_mda.c
|
||||||
|
|
||||||
|
# Hercules
|
||||||
vid_hercules.c
|
vid_hercules.c
|
||||||
vid_hercules_plus.c
|
vid_hercules_plus.c
|
||||||
vid_hercules_incolor.c
|
vid_hercules_incolor.c
|
||||||
|
|
||||||
|
# Other early CGA-era cards
|
||||||
vid_genius.c
|
vid_genius.c
|
||||||
|
vid_sigma.c
|
||||||
|
|
||||||
|
# PGC / IM1024 / WY700 high-resolution
|
||||||
vid_pgc.c
|
vid_pgc.c
|
||||||
vid_im1024.c
|
vid_im1024.c
|
||||||
vid_sigma.c
|
|
||||||
vid_wy700.c
|
vid_wy700.c
|
||||||
|
|
||||||
|
# EGA
|
||||||
vid_ega.c
|
vid_ega.c
|
||||||
vid_ega_render.c
|
vid_ega_render.c
|
||||||
vid_svga.c
|
vid_jega.c
|
||||||
vid_8514a.c
|
|
||||||
vid_svga_render.c
|
# (Real IBM) VGA
|
||||||
vid_ddc.c
|
|
||||||
vid_vga.c
|
vid_vga.c
|
||||||
|
|
||||||
|
# Super VGA core
|
||||||
|
vid_svga.c
|
||||||
|
vid_svga_render.c
|
||||||
|
|
||||||
|
# 8514/A, XGA and derivatives
|
||||||
|
vid_8514a.c
|
||||||
|
vid_xga.c
|
||||||
|
vid_ps55da2.c
|
||||||
|
|
||||||
|
# ATI Technologies
|
||||||
vid_ati_eeprom.c
|
vid_ati_eeprom.c
|
||||||
vid_ati18800.c
|
vid_ati18800.c
|
||||||
vid_ati28800.c
|
vid_ati28800.c
|
||||||
vid_ati_mach8.c
|
vid_ati_mach8.c
|
||||||
vid_ati_mach64.c
|
vid_ati_mach64.c
|
||||||
vid_ati68875_ramdac.c
|
|
||||||
vid_ati68860_ramdac.c
|
# Chips & Technologies
|
||||||
vid_bt481_ramdac.c
|
|
||||||
vid_bt48x_ramdac.c
|
|
||||||
vid_chips_69000.c
|
vid_chips_69000.c
|
||||||
vid_av9194.c
|
|
||||||
vid_icd2061.c
|
# Cirrus Logic
|
||||||
vid_ics2494.c
|
|
||||||
vid_ics2595.c
|
|
||||||
vid_cl54xx.c
|
vid_cl54xx.c
|
||||||
|
|
||||||
|
# Tseng Labs
|
||||||
vid_et3000.c
|
vid_et3000.c
|
||||||
vid_et4000.c
|
vid_et4000.c
|
||||||
vid_sc1148x_ramdac.c
|
|
||||||
vid_sc1502x_ramdac.c
|
|
||||||
vid_et4000w32.c
|
vid_et4000w32.c
|
||||||
vid_stg_ramdac.c
|
|
||||||
|
# Headland
|
||||||
vid_ht216.c
|
vid_ht216.c
|
||||||
vid_oak_oti.c
|
vid_oak_oti.c
|
||||||
|
|
||||||
|
# Paradise
|
||||||
vid_paradise.c
|
vid_paradise.c
|
||||||
vid_rtg310x.c
|
vid_rtg310x.c
|
||||||
vid_f82c425.c
|
vid_f82c425.c
|
||||||
vid_ti_cf62011.c
|
vid_ti_cf62011.c
|
||||||
vid_tvga.c vid_tgui9440.c
|
|
||||||
vid_tkd8001_ramdac.c
|
# Trident
|
||||||
vid_att20c49x_ramdac.c
|
vid_tvga.c
|
||||||
vid_s3.c vid_s3_virge.c
|
vid_tgui9440.c
|
||||||
vid_ibm_rgb528_ramdac.c
|
|
||||||
vid_sdac_ramdac.c
|
# S3 Graphics
|
||||||
|
vid_s3.c
|
||||||
|
vid_s3_virge.c
|
||||||
|
|
||||||
|
# Matrox
|
||||||
vid_mga.c
|
vid_mga.c
|
||||||
vid_tvp3026_ramdac.c
|
|
||||||
vid_att2xc498_ramdac.c
|
# NVidia (pending)
|
||||||
vid_xga.c
|
|
||||||
vid_bochs_vbe.c
|
|
||||||
vid_ps55da2.c
|
|
||||||
vid_jega.c
|
|
||||||
nv/nv_rivatimer.c
|
nv/nv_rivatimer.c
|
||||||
|
|
||||||
|
# Generic
|
||||||
|
vid_bochs_vbe.c
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if(G100)
|
if(G100)
|
||||||
@@ -100,6 +149,7 @@ if(XL24)
|
|||||||
target_compile_definitions(vid PRIVATE USE_XL24)
|
target_compile_definitions(vid PRIVATE USE_XL24)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# 3Dfx Voodoo
|
||||||
add_library(voodoo OBJECT
|
add_library(voodoo OBJECT
|
||||||
vid_voodoo.c
|
vid_voodoo.c
|
||||||
vid_voodoo_banshee.c
|
vid_voodoo_banshee.c
|
||||||
|
|||||||
@@ -261,38 +261,57 @@ void
|
|||||||
ati68860_hwcursor_draw(svga_t *svga, int displine)
|
ati68860_hwcursor_draw(svga_t *svga, int displine)
|
||||||
{
|
{
|
||||||
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
|
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
|
||||||
|
int comb;
|
||||||
int offset;
|
int offset;
|
||||||
uint8_t dat;
|
int x_pos;
|
||||||
|
int y_pos;
|
||||||
|
int shift = 0;
|
||||||
|
uint16_t dat;
|
||||||
uint32_t col0 = ramdac->pallook[0];
|
uint32_t col0 = ramdac->pallook[0];
|
||||||
uint32_t col1 = ramdac->pallook[1];
|
uint32_t col1 = ramdac->pallook[1];
|
||||||
|
uint32_t *p;
|
||||||
|
|
||||||
offset = svga->dac_hwcursor_latch.xoff;
|
offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff;
|
||||||
for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) {
|
if (svga->packed_4bpp)
|
||||||
dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)];
|
shift = 1;
|
||||||
if (!(dat & 2))
|
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0;
|
for (int x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += (8 >> shift)) {
|
||||||
else if ((dat & 3) == 3)
|
if (shift) {
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF;
|
dat = svga->vram[(svga->dac_hwcursor_latch.addr) & svga->vram_mask] & 0x0f;
|
||||||
dat >>= 2;
|
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 1) & svga->vram_mask] << 4);
|
||||||
if (!(dat & 2))
|
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 2) & svga->vram_mask] << 8);
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0;
|
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 3) & svga->vram_mask] << 12);
|
||||||
else if ((dat & 3) == 3)
|
} else {
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF;
|
dat = svga->vram[svga->dac_hwcursor_latch.addr & svga->vram_mask];
|
||||||
dat >>= 2;
|
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 1) & svga->vram_mask] << 8);
|
||||||
if (!(dat & 2))
|
}
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0;
|
for (int xx = 0; xx < (8 >> shift); xx++) {
|
||||||
else if ((dat & 3) == 3)
|
comb = (dat >> (xx << 1)) & 0x03;
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF;
|
|
||||||
dat >>= 2;
|
y_pos = displine;
|
||||||
if (!(dat & 2))
|
x_pos = offset + svga->x_add;
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0;
|
p = buffer32->line[y_pos];
|
||||||
else if ((dat & 3) == 3)
|
|
||||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF;
|
if (offset >= svga->dac_hwcursor_latch.x) {
|
||||||
dat >>= 2;
|
switch (comb) {
|
||||||
offset += 4;
|
case 0:
|
||||||
|
p[x_pos] = col0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
p[x_pos] = col1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
p[x_pos] ^= 0xffffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
svga->dac_hwcursor_latch.addr += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
svga->dac_hwcursor_latch.addr += 16;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -524,14 +524,18 @@ mach64_recalctimings(svga_t *svga)
|
|||||||
svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1;
|
svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1;
|
||||||
svga->rowoffset = (mach64->crtc_off_pitch >> 22);
|
svga->rowoffset = (mach64->crtc_off_pitch >> 22);
|
||||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen);
|
svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen);
|
||||||
svga->memaddr_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2;
|
svga->memaddr_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2;
|
||||||
svga->linedbl = svga->rowcount = 0;
|
svga->linedbl = svga->rowcount = 0;
|
||||||
svga->split = 0xffffff;
|
svga->split = 0xffffff;
|
||||||
svga->vblankstart = svga->dispend;
|
svga->vblankstart = svga->dispend;
|
||||||
svga->rowcount = mach64->crtc_gen_cntl & 1;
|
svga->rowcount = mach64->crtc_gen_cntl & 1;
|
||||||
svga->rowoffset <<= 1;
|
svga->rowoffset <<= 1;
|
||||||
|
|
||||||
if (mach64->type == MACH64_GX)
|
if (mach64->type == MACH64_GX)
|
||||||
ati68860_ramdac_set_render(svga->ramdac, svga);
|
ati68860_ramdac_set_render(svga->ramdac, svga);
|
||||||
|
|
||||||
|
svga->packed_4bpp = !!(((mach64->crtc_gen_cntl >> 8) & 7) == BPP_4);
|
||||||
|
|
||||||
switch ((mach64->crtc_gen_cntl >> 8) & 7) {
|
switch ((mach64->crtc_gen_cntl >> 8) & 7) {
|
||||||
case BPP_4:
|
case BPP_4:
|
||||||
if (mach64->type != MACH64_GX)
|
if (mach64->type != MACH64_GX)
|
||||||
@@ -572,8 +576,9 @@ mach64_recalctimings(svga_t *svga)
|
|||||||
}
|
}
|
||||||
|
|
||||||
svga->vram_display_mask = mach64->vram_mask;
|
svga->vram_display_mask = mach64->vram_mask;
|
||||||
} else
|
} else {
|
||||||
svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff;
|
svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2310,6 +2315,7 @@ uint8_t
|
|||||||
mach64_ext_readb(uint32_t addr, void *priv)
|
mach64_ext_readb(uint32_t addr, void *priv)
|
||||||
{
|
{
|
||||||
mach64_t *mach64 = (mach64_t *) priv;
|
mach64_t *mach64 = (mach64_t *) priv;
|
||||||
|
svga_t *svga = &mach64->svga;
|
||||||
|
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
if (!(addr & 0x400)) {
|
if (!(addr & 0x400)) {
|
||||||
@@ -2524,8 +2530,22 @@ mach64_ext_readb(uint32_t addr, void *priv)
|
|||||||
case 0xc3:
|
case 0xc3:
|
||||||
if (mach64->type == MACH64_GX)
|
if (mach64->type == MACH64_GX)
|
||||||
ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga);
|
ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga);
|
||||||
else
|
else {
|
||||||
ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga);
|
switch (addr & 3) {
|
||||||
|
case 0:
|
||||||
|
ret = svga_in(0x3c8, svga);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ret = svga_in(0x3c9, svga);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ret = svga_in(0x3c6, svga);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ret = svga_in(0x3c7, svga);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xc4:
|
case 0xc4:
|
||||||
case 0xc5:
|
case 0xc5:
|
||||||
@@ -2962,7 +2982,7 @@ mach64_ext_readl(uint32_t addr, void *priv)
|
|||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
|
|
||||||
if (!(addr & 0x400)) {
|
if (!(addr & 0x400)) {
|
||||||
mach64_log("nmach64_ext_readl: addr=%04x\n", addr);
|
mach64_log("mach64_ext_readl: addr=%04x\n", addr);
|
||||||
ret = 0xffffffff;
|
ret = 0xffffffff;
|
||||||
} else
|
} else
|
||||||
switch (addr & 0x3ff) {
|
switch (addr & 0x3ff) {
|
||||||
@@ -3101,6 +3121,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
|||||||
} else if (addr & 0x300) {
|
} else if (addr & 0x300) {
|
||||||
mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE);
|
mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE);
|
||||||
} else {
|
} else {
|
||||||
|
mach64_log("mach64_ext_writeb: addr=%04x val=%02x\n", addr & 0x3ff, val);
|
||||||
switch (addr & 0x3ff) {
|
switch (addr & 0x3ff) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
case 0x01:
|
case 0x01:
|
||||||
@@ -3189,39 +3210,48 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
|||||||
case 0x62:
|
case 0x62:
|
||||||
case 0x63:
|
case 0x63:
|
||||||
WRITE8(addr, mach64->cur_clr0, val);
|
WRITE8(addr, mach64->cur_clr0, val);
|
||||||
if (mach64->type == MACH64_VT2)
|
|
||||||
ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff));
|
|
||||||
break;
|
break;
|
||||||
case 0x64:
|
case 0x64:
|
||||||
case 0x65:
|
case 0x65:
|
||||||
case 0x66:
|
case 0x66:
|
||||||
case 0x67:
|
case 0x67:
|
||||||
WRITE8(addr, mach64->cur_clr1, val);
|
WRITE8(addr, mach64->cur_clr1, val);
|
||||||
if (mach64->type == MACH64_VT2)
|
|
||||||
ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff));
|
|
||||||
break;
|
break;
|
||||||
case 0x68:
|
case 0x68:
|
||||||
case 0x69:
|
case 0x69:
|
||||||
case 0x6a:
|
case 0x6a:
|
||||||
case 0x6b:
|
case 0x6b:
|
||||||
WRITE8(addr, mach64->cur_offset, val);
|
WRITE8(addr, mach64->cur_offset, val);
|
||||||
svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8;
|
if (mach64->type == MACH64_GX)
|
||||||
|
svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) << 3;
|
||||||
|
else
|
||||||
|
svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) << 3;
|
||||||
break;
|
break;
|
||||||
case 0x6c:
|
case 0x6c:
|
||||||
case 0x6d:
|
case 0x6d:
|
||||||
case 0x6e:
|
case 0x6e:
|
||||||
case 0x6f:
|
case 0x6f:
|
||||||
WRITE8(addr, mach64->cur_horz_vert_posn, val);
|
WRITE8(addr, mach64->cur_horz_vert_posn, val);
|
||||||
svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
|
if (mach64->type == MACH64_GX) {
|
||||||
svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
|
svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
|
||||||
|
svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
|
||||||
|
} else {
|
||||||
|
svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
|
||||||
|
svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x70:
|
case 0x70:
|
||||||
case 0x71:
|
case 0x71:
|
||||||
case 0x72:
|
case 0x72:
|
||||||
case 0x73:
|
case 0x73:
|
||||||
WRITE8(addr, mach64->cur_horz_vert_off, val);
|
WRITE8(addr, mach64->cur_horz_vert_off, val);
|
||||||
svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
|
if (mach64->type == MACH64_GX) {
|
||||||
svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
|
svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
|
||||||
|
svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
|
||||||
|
} else {
|
||||||
|
svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
|
||||||
|
svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x80:
|
case 0x80:
|
||||||
@@ -3283,8 +3313,22 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
|||||||
case 0xc3:
|
case 0xc3:
|
||||||
if (mach64->type == MACH64_GX)
|
if (mach64->type == MACH64_GX)
|
||||||
ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
|
ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
|
||||||
else
|
else {
|
||||||
ati68860_ramdac_out(addr & 3, val, svga->ramdac, svga);
|
switch (addr & 3) {
|
||||||
|
case 0:
|
||||||
|
svga_out(0x3c8, val, svga);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
svga_out(0x3c9, val, svga);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
svga_out(0x3c6, val, svga);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
svga_out(0x3c7, val, svga);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xc4:
|
case 0xc4:
|
||||||
case 0xc5:
|
case 0xc5:
|
||||||
@@ -3294,7 +3338,8 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
|||||||
mach64_log("Ext RAMDAC TYPE write=%x, bit set=%03x.\n", addr & 0x3ff, mach64->dac_cntl & 0x100);
|
mach64_log("Ext RAMDAC TYPE write=%x, bit set=%03x.\n", addr & 0x3ff, mach64->dac_cntl & 0x100);
|
||||||
if ((addr & 3) >= 1) {
|
if ((addr & 3) >= 1) {
|
||||||
svga_set_ramdac_type(svga, !!(mach64->dac_cntl & 0x100));
|
svga_set_ramdac_type(svga, !!(mach64->dac_cntl & 0x100));
|
||||||
ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100));
|
if (mach64->type == MACH64_GX)
|
||||||
|
ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100));
|
||||||
}
|
}
|
||||||
i2c_gpio_set(mach64->i2c, !(mach64->dac_cntl & 0x20000000) || (mach64->dac_cntl & 0x04000000), !(mach64->dac_cntl & 0x10000000) || (mach64->dac_cntl & 0x02000000));
|
i2c_gpio_set(mach64->i2c, !(mach64->dac_cntl & 0x20000000) || (mach64->dac_cntl & 0x04000000), !(mach64->dac_cntl & 0x10000000) || (mach64->dac_cntl & 0x02000000));
|
||||||
break;
|
break;
|
||||||
@@ -3306,7 +3351,10 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
|||||||
WRITE8(addr, mach64->gen_test_cntl, val);
|
WRITE8(addr, mach64->gen_test_cntl, val);
|
||||||
ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1);
|
ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1);
|
||||||
mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0);
|
mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0);
|
||||||
svga->dac_hwcursor.ena = mach64->gen_test_cntl & 0x80;
|
if (mach64->type == MACH64_GX)
|
||||||
|
svga->dac_hwcursor.ena = !!(mach64->gen_test_cntl & 0x80);
|
||||||
|
else
|
||||||
|
svga->hwcursor.ena = !!(mach64->gen_test_cntl & 0x80);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xdc:
|
case 0xdc:
|
||||||
@@ -3371,6 +3419,7 @@ uint8_t
|
|||||||
mach64_ext_inb(uint16_t port, void *priv)
|
mach64_ext_inb(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
mach64_t *mach64 = (mach64_t *) priv;
|
mach64_t *mach64 = (mach64_t *) priv;
|
||||||
|
svga_t *svga = &mach64->svga;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
@@ -3384,6 +3433,12 @@ mach64_ext_inb(uint16_t port, void *priv)
|
|||||||
case 0x7eef:
|
case 0x7eef:
|
||||||
ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), priv);
|
ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), priv);
|
||||||
break;
|
break;
|
||||||
|
case 0x06ec:
|
||||||
|
case 0x06ed:
|
||||||
|
case 0x06ee:
|
||||||
|
case 0x06ef:
|
||||||
|
ret = mach64_ext_readb(0x400 | 0x04 | (port & 3), priv);
|
||||||
|
break;
|
||||||
case 0x0aec:
|
case 0x0aec:
|
||||||
case 0x0aed:
|
case 0x0aed:
|
||||||
case 0x0aee:
|
case 0x0aee:
|
||||||
@@ -3519,8 +3574,22 @@ mach64_ext_inb(uint16_t port, void *priv)
|
|||||||
case 0x5eef:
|
case 0x5eef:
|
||||||
if (mach64->type == MACH64_GX)
|
if (mach64->type == MACH64_GX)
|
||||||
ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga);
|
ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga);
|
||||||
else
|
else {
|
||||||
ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga);
|
switch (port & 3) {
|
||||||
|
case 0:
|
||||||
|
ret = svga_in(0x3c8, svga);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ret = svga_in(0x3c9, svga);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ret = svga_in(0x3c6, svga);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ret = svga_in(0x3c7, svga);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x62ec:
|
case 0x62ec:
|
||||||
@@ -3617,6 +3686,12 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
|
|||||||
case 0x7eef:
|
case 0x7eef:
|
||||||
mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, priv);
|
mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, priv);
|
||||||
break;
|
break;
|
||||||
|
case 0x06ec:
|
||||||
|
case 0x06ed:
|
||||||
|
case 0x06ee:
|
||||||
|
case 0x06ef:
|
||||||
|
mach64_ext_writeb(0x400 | 0x04 | (port & 3), val, priv);
|
||||||
|
break;
|
||||||
case 0x0aec:
|
case 0x0aec:
|
||||||
case 0x0aed:
|
case 0x0aed:
|
||||||
case 0x0aee:
|
case 0x0aee:
|
||||||
@@ -3745,8 +3820,22 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
|
|||||||
case 0x5eef:
|
case 0x5eef:
|
||||||
if (mach64->type == MACH64_GX)
|
if (mach64->type == MACH64_GX)
|
||||||
ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
|
ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
|
||||||
else
|
else {
|
||||||
ati68860_ramdac_out(port & 3, val, svga->ramdac, svga);
|
switch (port & 3) {
|
||||||
|
case 0:
|
||||||
|
svga_out(0x3c8, val, svga);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
svga_out(0x3c9, val, svga);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
svga_out(0x3c6, val, svga);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
svga_out(0x3c7, val, svga);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x62ec:
|
case 0x62ec:
|
||||||
@@ -3905,6 +3994,63 @@ mach64_readl(uint32_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mach64_int_hwcursor_draw(svga_t *svga, int displine)
|
||||||
|
{
|
||||||
|
const mach64_t *mach64 = (mach64_t *) svga->priv;
|
||||||
|
int comb;
|
||||||
|
int offset;
|
||||||
|
int x_pos;
|
||||||
|
int y_pos;
|
||||||
|
int shift = 0;
|
||||||
|
uint16_t dat;
|
||||||
|
uint32_t col0 = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff);
|
||||||
|
uint32_t col1 = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff);
|
||||||
|
uint32_t *p;
|
||||||
|
|
||||||
|
offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||||
|
if (svga->packed_4bpp)
|
||||||
|
shift = 1;
|
||||||
|
|
||||||
|
for (int x = 0; x < svga->hwcursor_latch.cur_xsize; x += (8 >> shift)) {
|
||||||
|
if (shift) {
|
||||||
|
dat = svga->vram[(svga->hwcursor_latch.addr) & svga->vram_mask] & 0x0f;
|
||||||
|
dat |= (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 4);
|
||||||
|
dat |= (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_mask] << 8);
|
||||||
|
dat |= (svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_mask] << 12);
|
||||||
|
} else {
|
||||||
|
dat = svga->vram[svga->hwcursor_latch.addr & svga->vram_mask];
|
||||||
|
dat |= (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 8);
|
||||||
|
}
|
||||||
|
for (int xx = 0; xx < (8 >> shift); xx++) {
|
||||||
|
comb = (dat >> (xx << 1)) & 0x03;
|
||||||
|
|
||||||
|
y_pos = displine;
|
||||||
|
x_pos = offset + svga->x_add;
|
||||||
|
p = buffer32->line[y_pos];
|
||||||
|
|
||||||
|
if (offset >= svga->hwcursor_latch.x) {
|
||||||
|
switch (comb) {
|
||||||
|
case 0:
|
||||||
|
p[x_pos] = col0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
p[x_pos] = col1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
p[x_pos] ^= 0xffffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
svga->hwcursor_latch.addr += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define CLAMP(x) \
|
#define CLAMP(x) \
|
||||||
do { \
|
do { \
|
||||||
if ((x) & ~0xff) \
|
if ((x) & ~0xff) \
|
||||||
@@ -4550,15 +4696,22 @@ mach64_common_init(const device_t *info)
|
|||||||
|
|
||||||
svga = &mach64->svga;
|
svga = &mach64->svga;
|
||||||
|
|
||||||
|
mach64->type = info->local & 0xff;
|
||||||
mach64->vram_size = device_get_config_int("memory");
|
mach64->vram_size = device_get_config_int("memory");
|
||||||
mach64->vram_mask = (mach64->vram_size << 20) - 1;
|
mach64->vram_mask = (mach64->vram_size << 20) - 1;
|
||||||
|
|
||||||
svga_init(info, svga, mach64, mach64->vram_size << 20,
|
if (mach64->type > MACH64_GX)
|
||||||
mach64_recalctimings,
|
svga_init(info, svga, mach64, mach64->vram_size << 20,
|
||||||
mach64_in, mach64_out,
|
mach64_recalctimings,
|
||||||
NULL,
|
mach64_in, mach64_out,
|
||||||
mach64_overlay_draw);
|
mach64_int_hwcursor_draw,
|
||||||
svga->dac_hwcursor.cur_ysize = 64;
|
mach64_overlay_draw);
|
||||||
|
else
|
||||||
|
svga_init(info, svga, mach64, mach64->vram_size << 20,
|
||||||
|
mach64_recalctimings,
|
||||||
|
mach64_in, mach64_out,
|
||||||
|
NULL,
|
||||||
|
mach64_overlay_draw);
|
||||||
|
|
||||||
mem_mapping_add(&mach64->linear_mapping, 0, 0, mach64_read_linear, mach64_readw_linear, mach64_readl_linear, mach64_write_linear, mach64_writew_linear, mach64_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga);
|
mem_mapping_add(&mach64->linear_mapping, 0, 0, mach64_read_linear, mach64_readw_linear, mach64_readl_linear, mach64_write_linear, mach64_writew_linear, mach64_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga);
|
||||||
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, MEM_MAPPING_EXTERNAL, mach64);
|
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, MEM_MAPPING_EXTERNAL, mach64);
|
||||||
@@ -4576,9 +4729,6 @@ mach64_common_init(const device_t *info)
|
|||||||
mach64->pci_regs[0x32] = 0x0c;
|
mach64->pci_regs[0x32] = 0x0c;
|
||||||
mach64->pci_regs[0x33] = 0x00;
|
mach64->pci_regs[0x33] = 0x00;
|
||||||
|
|
||||||
svga->ramdac = device_add(&ati68860_ramdac_device);
|
|
||||||
svga->dac_hwcursor_draw = ati68860_hwcursor_draw;
|
|
||||||
|
|
||||||
svga->clock_gen = device_add(&ics2595_device);
|
svga->clock_gen = device_add(&ics2595_device);
|
||||||
|
|
||||||
mach64->dst_cntl = 3;
|
mach64->dst_cntl = 3;
|
||||||
@@ -4598,6 +4748,13 @@ static void *
|
|||||||
mach64gx_init(const device_t *info)
|
mach64gx_init(const device_t *info)
|
||||||
{
|
{
|
||||||
mach64_t *mach64 = mach64_common_init(info);
|
mach64_t *mach64 = mach64_common_init(info);
|
||||||
|
svga_t *svga = &mach64->svga;
|
||||||
|
|
||||||
|
svga->ramdac = device_add(&ati68860_ramdac_device);
|
||||||
|
svga->dac_hwcursor_draw = ati68860_hwcursor_draw;
|
||||||
|
|
||||||
|
svga->dac_hwcursor.cur_ysize = 64;
|
||||||
|
svga->dac_hwcursor.cur_xsize = 64;
|
||||||
|
|
||||||
if (info->flags & DEVICE_ISA16)
|
if (info->flags & DEVICE_ISA16)
|
||||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_isa);
|
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_isa);
|
||||||
@@ -4606,12 +4763,11 @@ mach64gx_init(const device_t *info)
|
|||||||
else
|
else
|
||||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb);
|
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb);
|
||||||
|
|
||||||
mach64->type = MACH64_GX;
|
|
||||||
mach64->pci = !!(info->flags & DEVICE_PCI);
|
mach64->pci = !!(info->flags & DEVICE_PCI);
|
||||||
mach64->pci_id = 'X' | ('G' << 8);
|
mach64->pci_id = 'X' | ('G' << 8);
|
||||||
mach64->config_chip_id = 0x000000d7;
|
mach64->config_chip_id = 0x000000d7;
|
||||||
mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/
|
mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/
|
||||||
mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/
|
mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI 68860, 256Kx16 DRAM*/
|
||||||
if (info->flags & DEVICE_PCI) {
|
if (info->flags & DEVICE_PCI) {
|
||||||
mach64->config_stat0 |= 7; /*PCI, 256Kx16 DRAM*/
|
mach64->config_stat0 |= 7; /*PCI, 256Kx16 DRAM*/
|
||||||
ati_eeprom_load(&mach64->eeprom, "mach64_pci.nvr", 1);
|
ati_eeprom_load(&mach64->eeprom, "mach64_pci.nvr", 1);
|
||||||
@@ -4635,9 +4791,13 @@ mach64vt2_init(const device_t *info)
|
|||||||
mach64_t *mach64 = mach64_common_init(info);
|
mach64_t *mach64 = mach64_common_init(info);
|
||||||
svga_t *svga = &mach64->svga;
|
svga_t *svga = &mach64->svga;
|
||||||
|
|
||||||
|
svga->dac_hwcursor_draw = NULL;
|
||||||
|
|
||||||
|
svga->hwcursor.cur_ysize = 64;
|
||||||
|
svga->hwcursor.cur_xsize = 64;
|
||||||
|
|
||||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci);
|
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci);
|
||||||
|
|
||||||
mach64->type = MACH64_VT2;
|
|
||||||
mach64->pci = 1;
|
mach64->pci = 1;
|
||||||
mach64->pci_id = 0x5654;
|
mach64->pci_id = 0x5654;
|
||||||
mach64->config_chip_id = 0x40005654;
|
mach64->config_chip_id = 0x40005654;
|
||||||
@@ -4757,7 +4917,7 @@ const device_t mach64gx_isa_device = {
|
|||||||
.name = "ATI Mach64GX ISA",
|
.name = "ATI Mach64GX ISA",
|
||||||
.internal_name = "mach64gx_isa",
|
.internal_name = "mach64gx_isa",
|
||||||
.flags = DEVICE_ISA16,
|
.flags = DEVICE_ISA16,
|
||||||
.local = 0,
|
.local = MACH64_GX,
|
||||||
.init = mach64gx_init,
|
.init = mach64gx_init,
|
||||||
.close = mach64_close,
|
.close = mach64_close,
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
@@ -4771,7 +4931,7 @@ const device_t mach64gx_vlb_device = {
|
|||||||
.name = "ATI Mach64GX VLB",
|
.name = "ATI Mach64GX VLB",
|
||||||
.internal_name = "mach64gx_vlb",
|
.internal_name = "mach64gx_vlb",
|
||||||
.flags = DEVICE_VLB,
|
.flags = DEVICE_VLB,
|
||||||
.local = 0,
|
.local = MACH64_GX,
|
||||||
.init = mach64gx_init,
|
.init = mach64gx_init,
|
||||||
.close = mach64_close,
|
.close = mach64_close,
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
@@ -4785,7 +4945,7 @@ const device_t mach64gx_pci_device = {
|
|||||||
.name = "ATI Mach64GX PCI",
|
.name = "ATI Mach64GX PCI",
|
||||||
.internal_name = "mach64gx_pci",
|
.internal_name = "mach64gx_pci",
|
||||||
.flags = DEVICE_PCI,
|
.flags = DEVICE_PCI,
|
||||||
.local = 0,
|
.local = MACH64_GX,
|
||||||
.init = mach64gx_init,
|
.init = mach64gx_init,
|
||||||
.close = mach64_close,
|
.close = mach64_close,
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
@@ -4799,7 +4959,7 @@ const device_t mach64vt2_device = {
|
|||||||
.name = "ATI Mach64VT2",
|
.name = "ATI Mach64VT2",
|
||||||
.internal_name = "mach64vt2",
|
.internal_name = "mach64vt2",
|
||||||
.flags = DEVICE_PCI,
|
.flags = DEVICE_PCI,
|
||||||
.local = 0,
|
.local = MACH64_VT2,
|
||||||
.init = mach64vt2_init,
|
.init = mach64vt2_init,
|
||||||
.close = mach64_close,
|
.close = mach64_close,
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
|
|||||||
@@ -817,6 +817,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
|||||||
dev->accel.dy |= ~0x5ff;
|
dev->accel.dy |= ~0x5ff;
|
||||||
|
|
||||||
/*Destination Width*/
|
/*Destination Width*/
|
||||||
|
mach->accel.dx_first_row_start = dev->accel.cur_x;
|
||||||
|
if (dev->accel.cur_x >= 0x600)
|
||||||
|
mach->accel.dx_first_row_start |= ~0x5ff;
|
||||||
|
|
||||||
mach->accel.dx_start = mach->accel.dest_x_start;
|
mach->accel.dx_start = mach->accel.dest_x_start;
|
||||||
if (mach->accel.dest_x_start >= 0x600)
|
if (mach->accel.dest_x_start >= 0x600)
|
||||||
mach->accel.dx_start |= ~0x5ff;
|
mach->accel.dx_start |= ~0x5ff;
|
||||||
@@ -831,16 +835,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
|||||||
} else if (mach->accel.dx_end < mach->accel.dx_start) {
|
} else if (mach->accel.dx_end < mach->accel.dx_start) {
|
||||||
mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end);
|
mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end);
|
||||||
mach->accel.stepx = -1;
|
mach->accel.stepx = -1;
|
||||||
if (dev->accel.dx > 0)
|
|
||||||
dev->accel.dx--;
|
|
||||||
mach_log("BitBLT: Dst Negative X, dxstart = %d, end = %d, width = %d, dx = %d, dpconfig = %04x.\n",
|
|
||||||
mach->accel.dest_x_start, mach->accel.dest_x_end, mach->accel.width, dev->accel.dx,
|
|
||||||
mach->accel.dp_config);
|
|
||||||
} else {
|
} else {
|
||||||
mach->accel.stepx = 1;
|
mach->accel.stepx = 1;
|
||||||
mach->accel.width = 0;
|
mach->accel.width = 0;
|
||||||
mach_log("BitBLT: Dst Indeterminate X, dpconfig = %04x, destxend = %d, destxstart = %d.\n",
|
|
||||||
mach->accel.dp_config, mach->accel.dest_x_end, mach->accel.dest_x_start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->accel.sx = 0;
|
dev->accel.sx = 0;
|
||||||
@@ -869,6 +866,24 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
|||||||
if (mach->accel.dp_config == 0x4011)
|
if (mach->accel.dp_config == 0x4011)
|
||||||
mach->accel.height++;
|
mach->accel.height++;
|
||||||
|
|
||||||
|
if (mach->accel.height == 1) {
|
||||||
|
if (mach->accel.dx_end > mach->accel.dx_first_row_start) {
|
||||||
|
mach->accel.width = (mach->accel.dx_end - mach->accel.dx_first_row_start);
|
||||||
|
mach->accel.stepx = 1;
|
||||||
|
} else if (mach->accel.dx_end < mach->accel.dx_first_row_start) {
|
||||||
|
mach->accel.width = (mach->accel.dx_first_row_start - mach->accel.dx_end);
|
||||||
|
mach->accel.stepx = -1;
|
||||||
|
} else {
|
||||||
|
mach->accel.stepx = 1;
|
||||||
|
mach->accel.width = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mach->accel.stepx == -1) {
|
||||||
|
if (dev->accel.dx > 0)
|
||||||
|
dev->accel.dx--;
|
||||||
|
}
|
||||||
|
|
||||||
dev->accel.sy = 0;
|
dev->accel.sy = 0;
|
||||||
dev->accel.dest = mach->accel.dst_ge_offset + (dev->accel.dy * mach->accel.dst_pitch);
|
dev->accel.dest = mach->accel.dst_ge_offset + (dev->accel.dy * mach->accel.dst_pitch);
|
||||||
|
|
||||||
@@ -6475,6 +6490,7 @@ ati8514_io_set(svga_t *svga)
|
|||||||
io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||||
io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||||
io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||||
|
io_sethandler(0xfaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||||
io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* This file is part of the 86Box distribution.
|
* This file is part of the 86Box distribution.
|
||||||
*
|
*
|
||||||
* MDA emulation.
|
* IBM Monochrome Display and Printer Adapter emulation.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
* Copyright 2016-2025 Miran Grca.
|
* Copyright 2016-2025 Miran Grca.
|
||||||
* Copyright 2025 starfrost / Connor Hyde
|
* Copyright 2025 starfrost / Connor Hyde
|
||||||
*/
|
*/
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -35,6 +36,16 @@
|
|||||||
#include <86box/vid_mda.h>
|
#include <86box/vid_mda.h>
|
||||||
#include <86box/plat_unused.h>
|
#include <86box/plat_unused.h>
|
||||||
|
|
||||||
|
// Enumerates MDA monitor types
|
||||||
|
enum mda_monitor_type_e {
|
||||||
|
MDA_MONITOR_TYPE_DEFAULT = 0, // Default MDA monitor type.
|
||||||
|
MDA_MONITOR_TYPE_GREEN = 1, // Green phosphor
|
||||||
|
MDA_MONITOR_TYPE_AMBER = 2, // Amber phosphor
|
||||||
|
MDA_MONITOR_TYPE_GRAY = 3, // Gray phosphor
|
||||||
|
MDA_MONITOR_TYPE_RGBI = 4, // RGBI colour monitor with modified rev1 or rev0 MDA card for colour support
|
||||||
|
} mda_monitor_type;
|
||||||
|
|
||||||
|
// [attr][blink][fg]
|
||||||
static int mda_attr_to_color_table[256][2][2];
|
static int mda_attr_to_color_table[256][2][2];
|
||||||
|
|
||||||
static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||||
@@ -46,12 +57,11 @@ mda_out(uint16_t addr, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
mda_t *mda = (mda_t *) priv;
|
mda_t *mda = (mda_t *) priv;
|
||||||
|
|
||||||
if (addr < MDA_REGISTER_START
|
if (addr < MDA_REGISTER_START
|
||||||
|| addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case
|
|| addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (addr)
|
switch (addr) {
|
||||||
{
|
|
||||||
case MDA_REGISTER_MODE_CONTROL:
|
case MDA_REGISTER_MODE_CONTROL:
|
||||||
mda->mode = val;
|
mda->mode = val;
|
||||||
return;
|
return;
|
||||||
@@ -61,20 +71,17 @@ mda_out(uint16_t addr, uint8_t val, void *priv)
|
|||||||
|
|
||||||
// addr & 1 == 1 = MDA_REGISTER_CRTC_DATA
|
// addr & 1 == 1 = MDA_REGISTER_CRTC_DATA
|
||||||
// otherwise MDA_REGISTER_CRTC_INDEX
|
// otherwise MDA_REGISTER_CRTC_INDEX
|
||||||
if (addr & 1)
|
if (addr & 1) {
|
||||||
{
|
|
||||||
mda->crtc[mda->crtcreg] = val;
|
mda->crtc[mda->crtcreg] = val;
|
||||||
if (mda->crtc[MDA_CRTC_CURSOR_START] == 6
|
if (mda->crtc[MDA_CRTC_CURSOR_START] == 6
|
||||||
&& mda->crtc[MDA_CRTC_CURSOR_END] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
&& mda->crtc[MDA_CRTC_CURSOR_END] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||||
{
|
{
|
||||||
mda->crtc[MDA_CRTC_CURSOR_START] = 0xb;
|
mda->crtc[MDA_CRTC_CURSOR_START] = 0xb;
|
||||||
mda->crtc[MDA_CRTC_CURSOR_END] = 0xc;
|
mda->crtc[MDA_CRTC_CURSOR_END] = 0xc;
|
||||||
}
|
}
|
||||||
mda_recalctimings(mda);
|
mda_recalctimings(mda);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
mda->crtcreg = val & 31;
|
mda->crtcreg = val & 31;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
@@ -82,19 +89,18 @@ mda_in(uint16_t addr, void *priv)
|
|||||||
{
|
{
|
||||||
const mda_t *mda = (mda_t *) priv;
|
const mda_t *mda = (mda_t *) priv;
|
||||||
|
|
||||||
switch (addr)
|
switch (addr) {
|
||||||
{
|
|
||||||
case MDA_REGISTER_CRT_STATUS:
|
case MDA_REGISTER_CRT_STATUS:
|
||||||
return mda->status | 0xF0;
|
return mda->status | 0xF0;
|
||||||
default:
|
default:
|
||||||
if (addr < MDA_REGISTER_START
|
if (addr < MDA_REGISTER_START
|
||||||
|| addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case
|
|| addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
|
||||||
// MDA_REGISTER_CRTC_DATA
|
// MDA_REGISTER_CRTC_DATA
|
||||||
if (addr & 1)
|
if (addr & 1)
|
||||||
return mda->crtc[mda->crtcreg];
|
return mda->crtc[mda->crtcreg];
|
||||||
else
|
else
|
||||||
return mda->crtcreg;
|
return mda->crtcreg;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -136,51 +142,133 @@ mda_recalctimings(mda_t *mda)
|
|||||||
void
|
void
|
||||||
mda_poll(void *priv)
|
mda_poll(void *priv)
|
||||||
{
|
{
|
||||||
mda_t *mda = (mda_t *) priv;
|
mda_t *mda = (mda_t *) priv;
|
||||||
uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||||
int drawcursor;
|
bool drawcursor;
|
||||||
int x;
|
int32_t oldvc;
|
||||||
int c;
|
|
||||||
int oldvc;
|
|
||||||
uint8_t chr;
|
uint8_t chr;
|
||||||
uint8_t attr;
|
uint8_t attr;
|
||||||
int scanline_old;
|
int32_t scanline_old;
|
||||||
int blink;
|
int32_t blink;
|
||||||
|
|
||||||
VIDEO_MONITOR_PROLOGUE()
|
VIDEO_MONITOR_PROLOGUE()
|
||||||
|
|
||||||
if (!mda->linepos) {
|
if (!mda->linepos) {
|
||||||
timer_advance_u64(&mda->timer, mda->dispofftime);
|
timer_advance_u64(&mda->timer, mda->dispofftime);
|
||||||
mda->status |= 1;
|
mda->status |= 1;
|
||||||
mda->linepos = 1;
|
mda->linepos = 1;
|
||||||
scanline_old = mda->scanline;
|
scanline_old = mda->scanline;
|
||||||
if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3)
|
if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3)
|
||||||
mda->scanline = (mda->scanline << 1) & 7;
|
mda->scanline = (mda->scanline << 1) & 7;
|
||||||
|
|
||||||
if (mda->dispon) {
|
if (mda->dispon) {
|
||||||
if (mda->displine < mda->firstline) {
|
if (mda->displine < mda->firstline) {
|
||||||
mda->firstline = mda->displine;
|
mda->firstline = mda->displine;
|
||||||
video_wait_for_buffer();
|
video_wait_for_buffer();
|
||||||
}
|
}
|
||||||
mda->lastline = mda->displine;
|
mda->lastline = mda->displine;
|
||||||
for (x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) {
|
|
||||||
|
for (uint32_t x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) {
|
||||||
chr = mda->vram[(mda->memaddr << 1) & 0xfff];
|
chr = mda->vram[(mda->memaddr << 1) & 0xfff];
|
||||||
attr = mda->vram[((mda->memaddr << 1) + 1) & 0xfff];
|
attr = mda->vram[((mda->memaddr << 1) + 1) & 0xfff];
|
||||||
drawcursor = ((mda->memaddr == cursoraddr) && mda->cursorvisible && mda->cursoron);
|
drawcursor = ((mda->memaddr == cursoraddr) && mda->cursorvisible && mda->cursoron);
|
||||||
blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor);
|
blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor);
|
||||||
if (mda->scanline == 12 && ((attr & 7) == 1)) {
|
|
||||||
for (c = 0; c < 9; c++)
|
// Colours that will be used
|
||||||
buffer32->line[mda->displine][(x * 9) + c] = mda_attr_to_color_table[attr][blink][1];
|
int32_t color_bg = 0, color_fg = 0;
|
||||||
} else {
|
|
||||||
for (c = 0; c < 8; c++)
|
// If we are using an RGBI monitor allow colour
|
||||||
buffer32->line[mda->displine][(x * 9) + c] = mda_attr_to_color_table[attr][blink][(fontdatm[chr + mda->fontbase][mda->scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||||
if ((chr & ~0x1f) == 0xc0)
|
&& !(mda->mode & MDA_MODE_BW)) {
|
||||||
buffer32->line[mda->displine][(x * 9) + 8] = mda_attr_to_color_table[attr][blink][fontdatm[chr + mda->fontbase][mda->scanline] & 1];
|
color_bg = (attr >> 4) & 0x0F;
|
||||||
else
|
color_fg = (attr & 0x0F);
|
||||||
buffer32->line[mda->displine][(x * 9) + 8] = mda_attr_to_color_table[attr][blink][0];
|
|
||||||
|
// turn off bright bg colours in blink mode
|
||||||
|
if ((mda->mode & MDA_MODE_BLINK)
|
||||||
|
&& (color_bg & 0x8))
|
||||||
|
color_bg & ~(0x8);
|
||||||
|
|
||||||
|
// black-on-non black or white colours forced to white
|
||||||
|
// grey-on-colours forced to bright white
|
||||||
|
|
||||||
|
bool special_treatment = (color_bg != 0 && color_bg != 7);
|
||||||
|
|
||||||
|
if (color_fg == MDA_COLOR_GREY
|
||||||
|
&& special_treatment)
|
||||||
|
color_fg = MDA_COLOR_BRIGHT_WHITE;
|
||||||
|
|
||||||
|
if (color_fg == 0
|
||||||
|
&& special_treatment)
|
||||||
|
color_fg = MDA_COLOR_GREY;
|
||||||
|
|
||||||
|
// gray is black
|
||||||
|
if (color_fg == MDA_COLOR_GREY
|
||||||
|
&& (color_bg == MDA_COLOR_GREY || color_bg == MDA_COLOR_BLACK))
|
||||||
|
color_fg = MDA_COLOR_BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mda->scanline == 12
|
||||||
|
&& ((attr & 7) == 1)) { // underline
|
||||||
|
for (uint32_t column = 0; column < 9; column++) {
|
||||||
|
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||||
|
&& !(mda->mode & MDA_MODE_BW)) {
|
||||||
|
buffer32->line[mda->displine][(x * 9) + column] = CGAPAL_CGA_START + color_fg;
|
||||||
|
} else
|
||||||
|
buffer32->line[mda->displine][(x * 9) + column] = mda_attr_to_color_table[attr][blink][1];
|
||||||
|
}
|
||||||
|
} else { // character
|
||||||
|
for (uint32_t column = 0; column < 8; column++) {
|
||||||
|
// bg=0, fg=1
|
||||||
|
bool is_fg = (fontdatm[chr + mda->fontbase][mda->scanline] & (1 << (column ^ 7))) ? 1 : 0;
|
||||||
|
|
||||||
|
uint32_t font_char = mda_attr_to_color_table[attr][blink][is_fg];
|
||||||
|
|
||||||
|
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||||
|
&& !(mda->mode & MDA_MODE_BW)) {
|
||||||
|
if (!is_fg)
|
||||||
|
font_char = CGAPAL_CGA_START + color_bg;
|
||||||
|
else
|
||||||
|
font_char = CGAPAL_CGA_START + color_fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer32->line[mda->displine][(x * 9) + column] = font_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
// these characters (C0-DF) have their background extended to their 9th column
|
||||||
|
if ((chr & ~0x1f) == 0xc0) {
|
||||||
|
bool is_fg = fontdatm[chr + mda->fontbase][mda->scanline] & 1;
|
||||||
|
uint32_t final_result = mda_attr_to_color_table[attr][blink][is_fg];
|
||||||
|
|
||||||
|
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||||
|
&& !(mda->mode & MDA_MODE_BW)) {
|
||||||
|
if (!is_fg)
|
||||||
|
final_result = CGAPAL_CGA_START + color_bg;
|
||||||
|
else
|
||||||
|
final_result = CGAPAL_CGA_START + color_fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer32->line[mda->displine][(x * 9) + 8] = final_result;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||||
|
&& !(mda->mode & MDA_MODE_BW)) {
|
||||||
|
buffer32->line[mda->displine][(x * 9) + 8] = CGAPAL_CGA_START + color_bg;
|
||||||
|
|
||||||
|
} else
|
||||||
|
buffer32->line[mda->displine][(x * 9) + 8] = mda_attr_to_color_table[attr][blink][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mda->memaddr++;
|
mda->memaddr++;
|
||||||
|
|
||||||
if (drawcursor) {
|
if (drawcursor) {
|
||||||
for (c = 0; c < 9; c++)
|
for (uint32_t column = 0; column < 9; column++) {
|
||||||
buffer32->line[mda->displine][(x * 9) + c] ^= mda_attr_to_color_table[attr][0][1];
|
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||||
|
&& !(mda->mode & MDA_MODE_BW)) {
|
||||||
|
buffer32->line[mda->displine][(x * 9) + column] ^= CGAPAL_CGA_START + color_fg;
|
||||||
|
} else
|
||||||
|
buffer32->line[mda->displine][(x * 9) + column] ^= mda_attr_to_color_table[attr][0][1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,33 +286,35 @@ mda_poll(void *priv)
|
|||||||
if (mda->dispon)
|
if (mda->dispon)
|
||||||
mda->status &= ~1;
|
mda->status &= ~1;
|
||||||
mda->linepos = 0;
|
mda->linepos = 0;
|
||||||
|
|
||||||
if (mda->vsynctime) {
|
if (mda->vsynctime) {
|
||||||
mda->vsynctime--;
|
mda->vsynctime--;
|
||||||
if (!mda->vsynctime) {
|
if (!mda->vsynctime) {
|
||||||
mda->status &= ~8;
|
mda->status &= ~8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31)
|
if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31)
|
||||||
|| ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3
|
|| ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3
|
||||||
&& mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) {
|
&& mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||||
mda->cursorvisible = 0;
|
mda->cursorvisible = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mda->vadj) {
|
if (mda->vadj) {
|
||||||
mda->scanline++;
|
mda->scanline++;
|
||||||
mda->scanline &= 31;
|
mda->scanline &= 31;
|
||||||
mda->memaddr = mda->memaddr_backup;
|
mda->memaddr = mda->memaddr_backup;
|
||||||
mda->vadj--;
|
mda->vadj--;
|
||||||
if (!mda->vadj) {
|
if (!mda->vadj) {
|
||||||
mda->dispon = 1;
|
mda->dispon = 1;
|
||||||
mda->memaddr = mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
mda->memaddr = mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||||
mda->scanline = 0;
|
mda->scanline = 0;
|
||||||
}
|
}
|
||||||
} else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR]
|
} else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR]
|
||||||
|| ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3
|
|| ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3
|
||||||
&& mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) {
|
&& mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) {
|
||||||
mda->memaddr_backup = mda->memaddr;
|
mda->memaddr_backup = mda->memaddr;
|
||||||
mda->scanline = 0;
|
mda->scanline = 0;
|
||||||
oldvc = mda->vc;
|
oldvc = mda->vc;
|
||||||
mda->vc++;
|
mda->vc++;
|
||||||
mda->vc &= 127;
|
mda->vc &= 127;
|
||||||
if (mda->vc == mda->crtc[MDA_CRTC_VDISP])
|
if (mda->vc == mda->crtc[MDA_CRTC_VDISP])
|
||||||
@@ -247,7 +337,7 @@ mda_poll(void *priv)
|
|||||||
mda->displine = 0;
|
mda->displine = 0;
|
||||||
mda->vsynctime = 16;
|
mda->vsynctime = 16;
|
||||||
if (mda->crtc[MDA_CRTC_VSYNC]) {
|
if (mda->crtc[MDA_CRTC_VSYNC]) {
|
||||||
x = mda->crtc[MDA_CRTC_HDISP] * 9;
|
uint32_t x = mda->crtc[MDA_CRTC_HDISP] * 9;
|
||||||
mda->lastline++;
|
mda->lastline++;
|
||||||
if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) {
|
if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) {
|
||||||
xsize = x;
|
xsize = x;
|
||||||
@@ -277,9 +367,9 @@ mda_poll(void *priv)
|
|||||||
mda->memaddr = mda->memaddr_backup;
|
mda->memaddr = mda->memaddr_backup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31)
|
if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31)
|
||||||
|| ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3
|
|| ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3
|
||||||
&& mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1))) {
|
&& mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1))) {
|
||||||
mda->cursorvisible = 1;
|
mda->cursorvisible = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,21 +379,22 @@ mda_poll(void *priv)
|
|||||||
void
|
void
|
||||||
mda_init(mda_t *mda)
|
mda_init(mda_t *mda)
|
||||||
{
|
{
|
||||||
for (uint16_t c = 0; c < 256; c++) {
|
|
||||||
mda_attr_to_color_table[c][0][0] = mda_attr_to_color_table[c][1][0] = mda_attr_to_color_table[c][1][1] = 16;
|
for (uint16_t attr = 0; attr < 256; attr++) {
|
||||||
if (c & 8)
|
mda_attr_to_color_table[attr][0][0] = mda_attr_to_color_table[attr][1][0] = mda_attr_to_color_table[attr][1][1] = 16;
|
||||||
mda_attr_to_color_table[c][0][1] = 15 + 16;
|
if (attr & 8)
|
||||||
|
mda_attr_to_color_table[attr][0][1] = 15 + 16;
|
||||||
else
|
else
|
||||||
mda_attr_to_color_table[c][0][1] = 7 + 16;
|
mda_attr_to_color_table[attr][0][1] = 7 + 16;
|
||||||
}
|
}
|
||||||
mda_attr_to_color_table[0x70][0][1] = 16;
|
mda_attr_to_color_table[0x70][0][1] = 16;
|
||||||
mda_attr_to_color_table[0x70][0][0] = mda_attr_to_color_table[0x70][1][0] = mda_attr_to_color_table[0x70][1][1] = 16 + 15;
|
mda_attr_to_color_table[0x70][0][0] = mda_attr_to_color_table[0x70][1][0] = mda_attr_to_color_table[0x70][1][1] = CGAPAL_CGA_START + 15;
|
||||||
mda_attr_to_color_table[0xF0][0][1] = 16;
|
mda_attr_to_color_table[0xF0][0][1] = 16;
|
||||||
mda_attr_to_color_table[0xF0][0][0] = mda_attr_to_color_table[0xF0][1][0] = mda_attr_to_color_table[0xF0][1][1] = 16 + 15;
|
mda_attr_to_color_table[0xF0][0][0] = mda_attr_to_color_table[0xF0][1][0] = mda_attr_to_color_table[0xF0][1][1] = CGAPAL_CGA_START + 15;
|
||||||
mda_attr_to_color_table[0x78][0][1] = 16 + 7;
|
mda_attr_to_color_table[0x78][0][1] = CGAPAL_CGA_START + 7;
|
||||||
mda_attr_to_color_table[0x78][0][0] = mda_attr_to_color_table[0x78][1][0] = mda_attr_to_color_table[0x78][1][1] = 16 + 15;
|
mda_attr_to_color_table[0x78][0][0] = mda_attr_to_color_table[0x78][1][0] = mda_attr_to_color_table[0x78][1][1] = CGAPAL_CGA_START + 15;
|
||||||
mda_attr_to_color_table[0xF8][0][1] = 16 + 7;
|
mda_attr_to_color_table[0xF8][0][1] = CGAPAL_CGA_START + 7;
|
||||||
mda_attr_to_color_table[0xF8][0][0] = mda_attr_to_color_table[0xF8][1][0] = mda_attr_to_color_table[0xF8][1][1] = 16 + 15;
|
mda_attr_to_color_table[0xF8][0][0] = mda_attr_to_color_table[0xF8][1][0] = mda_attr_to_color_table[0xF8][1][1] = CGAPAL_CGA_START + 15;
|
||||||
mda_attr_to_color_table[0x00][0][1] = mda_attr_to_color_table[0x00][1][1] = 16;
|
mda_attr_to_color_table[0x00][0][1] = mda_attr_to_color_table[0x00][1][1] = 16;
|
||||||
mda_attr_to_color_table[0x08][0][1] = mda_attr_to_color_table[0x08][1][1] = 16;
|
mda_attr_to_color_table[0x08][0][1] = mda_attr_to_color_table[0x08][1][1] = 16;
|
||||||
mda_attr_to_color_table[0x80][0][1] = mda_attr_to_color_table[0x80][1][1] = 16;
|
mda_attr_to_color_table[0x80][0][1] = mda_attr_to_color_table[0x80][1][1] = 16;
|
||||||
@@ -312,7 +403,8 @@ mda_init(mda_t *mda)
|
|||||||
overscan_x = overscan_y = 0;
|
overscan_x = overscan_y = 0;
|
||||||
mda->monitor_index = monitor_index_global;
|
mda->monitor_index = monitor_index_global;
|
||||||
|
|
||||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
mda->monitor_type = device_get_config_int("rgb_type");
|
||||||
|
cga_palette = mda->monitor_type << 1;
|
||||||
if (cga_palette > 6) {
|
if (cga_palette > 6) {
|
||||||
cga_palette = 0;
|
cga_palette = 0;
|
||||||
}
|
}
|
||||||
@@ -330,7 +422,7 @@ mda_standalone_init(UNUSED(const device_t *info))
|
|||||||
|
|
||||||
mda->vram = malloc(0x1000);
|
mda->vram = malloc(0x1000);
|
||||||
|
|
||||||
switch(device_get_config_int("font")) {
|
switch (device_get_config_int("font")) {
|
||||||
case 0:
|
case 0:
|
||||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||||
break;
|
break;
|
||||||
@@ -369,7 +461,7 @@ mda_standalone_init(UNUSED(const device_t *info))
|
|||||||
void
|
void
|
||||||
mda_setcol(int chr, int blink, int fg, uint8_t cga_ink)
|
mda_setcol(int chr, int blink, int fg, uint8_t cga_ink)
|
||||||
{
|
{
|
||||||
mda_attr_to_color_table[chr][blink][fg] = 16 + cga_ink;
|
mda_attr_to_color_table[chr][blink][fg] = CGAPAL_CGA_START + cga_ink;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -390,7 +482,7 @@ mda_speed_changed(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const device_config_t mda_config[] = {
|
static const device_config_t mda_config[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{
|
{
|
||||||
.name = "rgb_type",
|
.name = "rgb_type",
|
||||||
.description = "Display type",
|
.description = "Display type",
|
||||||
@@ -399,12 +491,14 @@ static const device_config_t mda_config[] = {
|
|||||||
.default_int = 0,
|
.default_int = 0,
|
||||||
.file_filter = NULL,
|
.file_filter = NULL,
|
||||||
.spinner = { 0 },
|
.spinner = { 0 },
|
||||||
.selection = {
|
.selection =
|
||||||
{ .description = "Default", .value = 0 },
|
{
|
||||||
{ .description = "Green", .value = 1 },
|
{ .description = "Default", .value = MDA_MONITOR_TYPE_DEFAULT },
|
||||||
{ .description = "Amber", .value = 2 },
|
{ .description = "Green", .value = MDA_MONITOR_TYPE_GREEN },
|
||||||
{ .description = "Gray", .value = 3 },
|
{ .description = "Amber", .value = MDA_MONITOR_TYPE_AMBER },
|
||||||
{ .description = "" }
|
{ .description = "Gray", .value = MDA_MONITOR_TYPE_GRAY },
|
||||||
|
{ .description = "Generic RGBI color monitor", .value = MDA_MONITOR_TYPE_RGBI },
|
||||||
|
{ .description = "" }
|
||||||
},
|
},
|
||||||
.bios = { { 0 } }
|
.bios = { { 0 } }
|
||||||
},
|
},
|
||||||
@@ -416,18 +510,19 @@ static const device_config_t mda_config[] = {
|
|||||||
.default_int = 0,
|
.default_int = 0,
|
||||||
.file_filter = NULL,
|
.file_filter = NULL,
|
||||||
.spinner = { 0 },
|
.spinner = { 0 },
|
||||||
.selection = {
|
.selection =
|
||||||
{ .description = "US (CP 437)", .value = 0 },
|
{
|
||||||
|
{ .description = "US (CP 437)", .value = 0 },
|
||||||
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
|
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
|
||||||
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
|
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
|
||||||
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
|
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
|
||||||
{ .description = "Tulip DGA", .value = 4 },
|
{ .description = "Tulip DGA", .value = 4 },
|
||||||
{ .description = "" }
|
{ .description = "" }
|
||||||
},
|
},
|
||||||
.bios = { { 0 } }
|
.bios = { { 0 } }
|
||||||
},
|
},
|
||||||
{ .name = "", .description = "", .type = CONFIG_END }
|
{ .name = "", .description = "", .type = CONFIG_END }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
const device_t mda_device = {
|
const device_t mda_device = {
|
||||||
@@ -443,3 +538,4 @@ const device_t mda_device = {
|
|||||||
.force_redraw = NULL,
|
.force_redraw = NULL,
|
||||||
.config = mda_config
|
.config = mda_config
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -917,7 +917,7 @@ svga_recalctimings(svga_t *svga)
|
|||||||
if (vblankend <= svga->vblankstart)
|
if (vblankend <= svga->vblankstart)
|
||||||
vblankend += 0x00000080;
|
vblankend += 0x00000080;
|
||||||
|
|
||||||
if (svga->hoverride) {
|
if (svga->hoverride || svga->override) {
|
||||||
if (svga->hdisp >= 2048)
|
if (svga->hdisp >= 2048)
|
||||||
svga->monitor->mon_overscan_x = 0;
|
svga->monitor->mon_overscan_x = 0;
|
||||||
|
|
||||||
@@ -958,14 +958,18 @@ svga_recalctimings(svga_t *svga)
|
|||||||
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
|
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
|
||||||
|
|
||||||
svga->left_overscan = svga->x_add = (svga->htotal - adj_dot - 1) * svga->dots_per_clock;
|
svga->left_overscan = svga->x_add = (svga->htotal - adj_dot - 1) * svga->dots_per_clock;
|
||||||
svga->monitor->mon_overscan_x = svga->x_add + (svga->hblankstart * svga->dots_per_clock) - hd;
|
svga->monitor->mon_overscan_x = svga->x_add + (svga->hblankstart * svga->dots_per_clock) - hd + svga->dots_per_clock;
|
||||||
|
/* Compensate for the HDISP code above. */
|
||||||
|
if (svga->crtc[1] & 1)
|
||||||
|
svga->monitor->mon_overscan_x++;
|
||||||
|
|
||||||
if ((svga->hdisp >= 2048) || (svga->left_overscan < 0)) {
|
if ((svga->hdisp >= 2048) || (svga->left_overscan < 0)) {
|
||||||
svga->left_overscan = svga->x_add = 0;
|
svga->left_overscan = svga->x_add = 0;
|
||||||
svga->monitor->mon_overscan_x = 0;
|
svga->monitor->mon_overscan_x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
svga->y_add = svga->vtotal - vblankend + 1;
|
/* - 1 because + 1 but also - 2 to compensate for the + 2 added to vtotal above. */
|
||||||
|
svga->y_add = svga->vtotal - vblankend - 1;
|
||||||
svga->monitor->mon_overscan_y = svga->y_add + abs(svga->vblankstart - svga->dispend);
|
svga->monitor->mon_overscan_y = svga->y_add + abs(svga->vblankstart - svga->dispend);
|
||||||
|
|
||||||
if ((svga->dispend >= 2048) || (svga->y_add < 0)) {
|
if ((svga->dispend >= 2048) || (svga->y_add < 0)) {
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ vid_poll(void *priv)
|
|||||||
vid->memaddr++;
|
vid->memaddr++;
|
||||||
if (vid->scanline & 8) {
|
if (vid->scanline & 8) {
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = cols[0];
|
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[0];
|
||||||
} else {
|
} else {
|
||||||
for (c = 0; c < 8; c++) {
|
for (c = 0; c < 8; c++) {
|
||||||
if (vid->scanline == 8) {
|
if (vid->scanline == 8) {
|
||||||
@@ -824,4 +824,4 @@ const device_t tandy_1000sl_video_device = {
|
|||||||
.speed_changed = tandy_vid_speed_changed,
|
.speed_changed = tandy_vid_speed_changed,
|
||||||
.force_redraw = NULL,
|
.force_redraw = NULL,
|
||||||
.config = NULL
|
.config = NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -530,6 +530,7 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv)
|
|||||||
voodoo_recalc(voodoo);
|
voodoo_recalc(voodoo);
|
||||||
voodoo->front_offset = voodoo->params.front_offset;
|
voodoo->front_offset = voodoo->params.front_offset;
|
||||||
}
|
}
|
||||||
|
svga_recalctimings(voodoo->svga);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SST_fbiInit1:
|
case SST_fbiInit1:
|
||||||
|
|||||||
Reference in New Issue
Block a user