Merge branch '86Box:master' into feature/socket6

This commit is contained in:
cartifanwlr
2024-02-07 18:22:47 +03:00
committed by GitHub
27 changed files with 642 additions and 544 deletions

View File

@@ -442,7 +442,7 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
{
int ret = 1;
if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING)) {
if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) {
cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id);
if (dev->cd_status == CD_STATUS_PLAYING)
dev->seek_pos += (len >> 11);
@@ -557,6 +557,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
len += pos;
}
dev->audio_muted_soft = 0;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
@@ -578,6 +579,7 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
int m = 0;
int s = 0;
int f = 0;
uint32_t pos2 = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
@@ -614,14 +616,21 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
break;
}
pos2 = pos - 1;
if (pos2 == 0xffffffff)
pos2 = pos + 1;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
cdrom_stop(dev);
return 0;
}
if (!(dev->ops->track_type(dev, pos2) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: Track Search: LBA %08X not on an audio track\n", dev->id, pos);
dev->audio_muted_soft = 1;
if (dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)
dev->audio_muted_soft = 0;
} else
dev->audio_muted_soft = 0;
cdrom_log("Track Search Toshiba: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos);
dev->cd_buflen = 0;
dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED;
return 1;
@@ -647,6 +656,7 @@ cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit)
dev->seek_pos = pos;
dev->audio_muted_soft = 0;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
@@ -676,6 +686,7 @@ cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos)
pos = MSFtoLBA(m, s, f) - 150;
dev->cd_end = pos;
dev->audio_muted_soft = 0;
dev->cd_buflen = 0;
dev->cd_status = CD_STATUS_PLAYING;
return 1;
@@ -717,16 +728,7 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
break;
}
cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status);
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
cdrom_stop(dev);
return 0;
}
cdrom_log("Toshiba Play Audio: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos);
dev->cd_buflen = 0;
dev->cd_status = CD_STATUS_PLAYING;
return 1;
@@ -770,6 +772,7 @@ cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type)
break;
}
dev->audio_muted_soft = 0;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
@@ -1007,6 +1010,11 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
else
ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op;
/*If a valid audio track is detected with audio on, unmute it.*/
if (dev->ops->track_type(dev, dev->seek_pos) & CD_TRACK_AUDIO)
dev->audio_muted_soft = 0;
cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", dev->seek_pos, dev->cd_end, dev->audio_muted_soft);
b[0] = subc.attr;
b[1] = bin2bcd(subc.track);
b[2] = bin2bcd(subc.index);

View File

@@ -123,7 +123,7 @@ sis_85c497_isa_read(uint16_t port, void *priv)
const sis_85c496_t *dev = (sis_85c496_t *) priv;
uint8_t ret = 0xff;
if (port == 0x23)
if ((port == 0x23) && (dev->cur_reg < 0xc0))
ret = dev->regs[dev->cur_reg];
else if (port == 0x33)
ret = 0x3c /*random_generate()*/;

View File

@@ -641,7 +641,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -656,14 +656,14 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -678,14 +678,14 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -700,14 +700,14 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -722,7 +722,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

View File

@@ -367,6 +367,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
switch (rmdat & 0x38) {
case 0x00: /*SGDT*/
ILLEGAL_ON(cpu_mod == 3);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(gdt.limit);
@@ -389,6 +390,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
break;
case 0x10: /*LGDT*/
ILLEGAL_ON(cpu_mod == 3);
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
x86gpf(NULL, 0);
break;

View File

@@ -244,6 +244,7 @@ typedef struct cdrom {
int prev_host_drive;
int cd_buflen;
int audio_op;
int audio_muted_soft;
int sony_msf;
const cdrom_ops_t *ops;

View File

@@ -64,6 +64,9 @@ typedef struct ibm8514_t {
int hwcursor_on;
int modechange;
uint64_t dispontime;
uint64_t dispofftime;
struct {
uint16_t subsys_cntl;
uint16_t setup_md;

View File

@@ -118,16 +118,16 @@ typedef struct svga_t {
int vram_display_mask;
int vidclock;
int dots_per_clock;
int hblank_ext;
int hwcursor_on;
int dac_hwcursor_on;
int overlay_on;
int set_override;
int hblankstart;
int hblankend;
int hblank_sub;
int hblank_end_val;
int hblank_end_len;
int hblank_end_mask;
int hblank_sub;
int packed_4bpp;
int ati_4color;
@@ -166,8 +166,10 @@ typedef struct svga_t {
latch_t latch;
pc_timer_t timer;
pc_timer_t timer8514;
double clock;
double clock8514;
hwcursor_t hwcursor;
hwcursor_t hwcursor_latch;
@@ -287,7 +289,7 @@ typedef struct svga_t {
extern int vga_on;
extern void ibm8514_poll(void *priv, svga_t *svga);
extern void ibm8514_poll(void *priv);
extern void ibm8514_recalctimings(svga_t *svga);
extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv);
extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv);

View File

@@ -53,7 +53,7 @@ extern void svga_render_4bpp_lowres(svga_t *svga);
extern void svga_render_4bpp_highres(svga_t *svga);
extern void svga_render_8bpp_lowres(svga_t *svga);
extern void svga_render_8bpp_highres(svga_t *svga);
extern void svga_render_8bpp_incompatible_highres(svga_t *svga);
extern void svga_render_8bpp_clone_highres(svga_t *svga);
extern void svga_render_8bpp_tseng_lowres(svga_t *svga);
extern void svga_render_8bpp_tseng_highres(svga_t *svga);
extern void svga_render_8bpp_gs_lowres(svga_t *svga);
@@ -75,6 +75,7 @@ extern void svga_render_ABGR8888_highres(svga_t *svga);
extern void svga_render_RGBA8888_lowres(svga_t *svga);
extern void svga_render_RGBA8888_highres(svga_t *svga);
extern void ibm8514_render_blank(svga_t *svga);
extern void ibm8514_render_8bpp(svga_t *svga);
extern void ibm8514_render_15bpp(svga_t *svga);
extern void ibm8514_render_16bpp(svga_t *svga);

View File

@@ -7793,7 +7793,7 @@ const machine_t machines[] = {
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET3,
.block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX, CPU_Cx486S, CPU_Cx486DX, CPU_Cx5x86),
.block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX),
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,

View File

@@ -3613,6 +3613,14 @@ atapi_out:
dev->sony_vendor = 1;
len = (cdb[7] << 8) | cdb[8];
if (!len) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_log("CD-ROM %i: PlayBack Control Sony All done - callback set\n", dev->id);
dev->packet_status = PHASE_COMPLETE;
dev->callback = 20.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
break;
}
scsi_cdrom_buf_alloc(dev, 65536);
scsi_cdrom_set_buf_len(dev, BufLen, &len);

View File

@@ -607,12 +607,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
ncr->dma_mode = DMA_IDLE;
}
} else {
/*Don't stop the timer until it finishes the transfer*/
if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA)) {
ncr_log("Continuing DMA mode\n");
timer_on_auto(&ncr_dev->timer, 40.0);
}
/*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/
if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) {
ncr_log("No DMA mode\n");
@@ -648,12 +642,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
ncr_dev->t128.block_loaded = 1;
}
} else {
if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) {
memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length));
ncr_log("DMA send timer on\n");
timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0);
}
}
break;
@@ -674,12 +662,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
ncr_dev->t128.block_loaded = 1;
timer_on_auto(&ncr_dev->timer, 0.02);
}
} else {
if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) {
memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length));
ncr_log("DMA initiator receive timer on\n");
timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0);
}
}
break;
@@ -842,8 +824,9 @@ memio_read(uint32_t addr, void *priv)
break;
case 0x3900:
if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) {
if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr_dev->status_ctrl & CTRL_DATA_DIR))) {
ret = 0xff;
ncr_log("No Read.\n");
} else {
ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++];
ncr_log("Read host pos = %i, ret = %02x\n", ncr_dev->buffer_host_pos, ret);
@@ -948,7 +931,7 @@ memio_write(uint32_t addr, uint8_t val, void *priv)
break;
case 0x3981: /* block counter register */
ncr_log("Write block counter register: val=%d, dma mode = %i, period = %lf\n", val, ncr->dma_mode, ncr_dev->period);
ncr_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr_dev->period);
ncr_dev->block_count = val;
ncr_dev->block_count_loaded = 1;
@@ -959,6 +942,11 @@ memio_write(uint32_t addr, uint8_t val, void *priv)
ncr_dev->buffer_host_pos = 0;
ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
}
if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) {
memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length));
ncr_log("DMA timer on\n");
timer_on_auto(&ncr_dev->timer, ncr_dev->period);
}
break;
default:
@@ -1080,9 +1068,9 @@ ncr_callback(void *priv)
ncr5380_t *ncr_dev = (ncr5380_t *) priv;
ncr_t *ncr = &ncr_dev->ncr;
scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
int tx = 0;
int bytes_transferred = 0;
int bus;
int bytes_tx = 0;
int limit = 100;
uint8_t temp;
if (ncr_dev->type != 3) {
@@ -1127,16 +1115,13 @@ ncr_callback(void *priv)
if (!ncr_dev->block_count_loaded)
break;
while (bytes_transferred < 50) {
for (tx = 0; tx < 10; tx++) {
while (bytes_tx < limit) {
for (uint8_t c = 0; c < 10; c++) {
ncr_bus_read(ncr_dev);
if (ncr->cur_bus & BUS_REQ)
break;
}
if (tx == 10)
break;
/* Data ready. */
temp = ncr_dev->buffer[ncr_dev->buffer_pos];
@@ -1147,13 +1132,14 @@ ncr_callback(void *priv)
ncr_bus_update(ncr_dev, bus & ~BUS_ACK);
ncr_dev->buffer_pos++;
bytes_transferred++;
bytes_tx++;
ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos);
if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) {
bytes_tx = 0;
ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
ncr_dev->buffer_pos = 0;
ncr_dev->buffer_host_pos = 0;
ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
ncr_dev->ncr_busy = 0;
ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff;
ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count);
@@ -1208,6 +1194,7 @@ write_again:
ncr_dev->t128.pos = 0;
ncr_dev->t128.host_pos = 0;
ncr_dev->t128.status &= ~0x02;
ncr_dev->ncr_busy = 0;
ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff;
ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count);
if (!ncr_dev->t128.block_count) {
@@ -1242,16 +1229,13 @@ write_again:
if (!ncr_dev->block_count_loaded)
break;
while (bytes_transferred < 50) {
for (tx = 0; tx < 10; tx++) {
while (bytes_tx < limit) {
for (uint8_t c = 0; c < 10; c++) {
ncr_bus_read(ncr_dev);
if (ncr->cur_bus & BUS_REQ)
break;
}
if (tx == 10)
break;
/* Data ready. */
ncr_bus_read(ncr_dev);
temp = BUS_GETDATA(ncr->cur_bus);
@@ -1263,12 +1247,13 @@ write_again:
ncr_dev->buffer[ncr_dev->buffer_pos++] = temp;
ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos);
bytes_transferred++;
bytes_tx++;
if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) {
bytes_tx = 0;
ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
ncr_dev->buffer_pos = 0;
ncr_dev->buffer_host_pos = 0;
ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff;
ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count);
if (!ncr_dev->block_count) {

View File

@@ -925,7 +925,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
if (!(port & 1)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f;
}
}
ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
@@ -3831,6 +3831,25 @@ bitblt:
}
}
void
ibm8514_render_blank(svga_t *svga)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
if ((dev->displine + svga->y_add) < 0)
return;
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
uint32_t *line_ptr = &svga->monitor->target_buffer->line[dev->displine + svga->y_add][svga->x_add];
uint32_t line_width = (uint32_t)(dev->h_disp) * sizeof(uint32_t);
if (dev->h_disp > 0)
memset(line_ptr, 0, line_width);
}
void
ibm8514_render_8bpp(svga_t *svga)
{
@@ -4106,148 +4125,153 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga)
}
void
ibm8514_poll(void *priv, svga_t *svga)
ibm8514_poll(void *priv)
{
ibm8514_t *dev = (ibm8514_t *) priv;
svga_t *svga = (svga_t *)priv;
ibm8514_t *dev = (ibm8514_t *)svga->dev8514;
uint32_t x;
int wx;
int wy;
if (!dev->linepos) {
if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff;
dev->hwcursor_oddeven = 0;
}
if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1);
dev->hwcursor_oddeven = 1;
}
timer_advance_u64(&svga->timer, svga->dispofftime);
svga->cgastat |= 1;
dev->linepos = 1;
if (dev->dispon) {
dev->hdisp_on = 1;
dev->ma &= dev->vram_mask;
if (dev->firstline == 2000) {
dev->firstline = dev->displine;
video_wait_for_buffer_monitor(svga->monitor_index);
ibm8514_log("IBM 8514/A poll.\n");
if (dev->on[0] || dev->on[1]) {
ibm8514_log("ON!\n");
if (!dev->linepos) {
if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff;
dev->hwcursor_oddeven = 0;
}
if (dev->hwcursor_on)
dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2;
if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1);
dev->hwcursor_oddeven = 1;
}
svga->render8514(svga);
timer_advance_u64(&svga->timer8514, dev->dispofftime);
svga->cgastat |= 1;
dev->linepos = 1;
svga->x_add = (overscan_x >> 1);
ibm8514_render_overscan_left(dev, svga);
ibm8514_render_overscan_right(dev, svga);
svga->x_add = (overscan_x >> 1);
if (dev->dispon) {
dev->hdisp_on = 1;
if (dev->hwcursor_on) {
if (svga->hwcursor_draw)
svga->hwcursor_draw(svga, dev->displine + svga->y_add);
dev->hwcursor_on--;
if (dev->hwcursor_on && dev->interlace)
dev->ma &= dev->vram_mask;
if (dev->firstline == 2000) {
dev->firstline = dev->displine;
video_wait_for_buffer_monitor(svga->monitor_index);
}
if (dev->hwcursor_on)
dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2;
svga->render8514(svga);
svga->x_add = (overscan_x >> 1);
ibm8514_render_overscan_left(dev, svga);
ibm8514_render_overscan_right(dev, svga);
svga->x_add = (overscan_x >> 1);
if (dev->hwcursor_on) {
if (svga->hwcursor_draw)
svga->hwcursor_draw(svga, dev->displine + svga->y_add);
dev->hwcursor_on--;
if (dev->hwcursor_on && dev->interlace)
dev->hwcursor_on--;
}
if (dev->lastline < dev->displine)
dev->lastline = dev->displine;
}
if (dev->lastline < dev->displine)
dev->lastline = dev->displine;
}
dev->displine++;
if (dev->interlace)
dev->displine++;
if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines)
svga->cgastat &= ~8;
svga->vslines++;
if (dev->displine > 1500)
dev->displine = 0;
} else {
timer_advance_u64(&svga->timer, svga->dispontime);
if (dev->dispon)
svga->cgastat &= ~1;
dev->hdisp_on = 0;
if (dev->interlace)
dev->displine++;
if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines)
svga->cgastat &= ~8;
svga->vslines++;
if (dev->displine > 1500)
dev->displine = 0;
} else {
timer_advance_u64(&svga->timer8514, dev->dispontime);
if (dev->dispon)
svga->cgastat &= ~1;
dev->hdisp_on = 0;
dev->linepos = 0;
if (dev->dispon) {
if (dev->sc == dev->rowcount) {
dev->sc = 0;
dev->maback += (dev->rowoffset << 3);
if (dev->interlace)
dev->linepos = 0;
if (dev->dispon) {
if (dev->sc == dev->rowcount) {
dev->sc = 0;
dev->maback += (dev->rowoffset << 3);
if (dev->interlace)
dev->maback += (dev->rowoffset << 3);
dev->maback &= dev->vram_mask;
dev->ma = dev->maback;
} else {
dev->sc++;
dev->sc &= 0x1f;
dev->ma = dev->maback;
}
}
dev->vc++;
dev->vc &= 0x7ff;
if (dev->vc == dev->dispend) {
dev->dispon = 0;
for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) {
if (dev->changedvram[x])
dev->changedvram[x]--;
dev->maback &= dev->vram_mask;
dev->ma = dev->maback;
} else {
dev->sc++;
dev->sc &= 0x1f;
dev->ma = dev->maback;
}
}
if (svga->fullchange)
svga->fullchange--;
}
if (dev->vc == dev->v_syncstart) {
dev->dispon = 0;
svga->cgastat |= 8;
x = dev->h_disp;
dev->vc++;
dev->vc &= 0x7ff;
if (dev->interlace && !dev->oddeven)
dev->lastline++;
if (dev->interlace && dev->oddeven)
dev->firstline--;
if (dev->vc == dev->dispend) {
dev->dispon = 0;
wx = x;
wy = dev->lastline - dev->firstline;
svga_doblit(wx, wy, svga);
for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) {
if (dev->changedvram[x])
dev->changedvram[x]--;
}
dev->firstline = 2000;
dev->lastline = 0;
if (svga->fullchange)
svga->fullchange--;
}
if (dev->vc == dev->v_syncstart) {
dev->dispon = 0;
svga->cgastat |= 8;
x = dev->h_disp;
dev->firstline_draw = 2000;
dev->lastline_draw = 0;
if (dev->interlace && !dev->oddeven)
dev->lastline++;
if (dev->interlace && dev->oddeven)
dev->firstline--;
dev->oddeven ^= 1;
wx = x;
wy = dev->lastline - dev->firstline;
svga_doblit(wx, wy, svga);
svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2;
svga->vslines = 0;
dev->firstline = 2000;
dev->lastline = 0;
if (dev->interlace && dev->oddeven)
dev->ma = dev->maback = (dev->rowoffset << 1);
else
dev->ma = dev->maback = 0;
dev->firstline_draw = 2000;
dev->lastline_draw = 0;
dev->ma = (dev->ma << 2);
dev->maback = (dev->maback << 2);
}
if (dev->vc == dev->v_total) {
dev->vc = 0;
dev->sc = 0;
dev->dispon = 1;
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
dev->oddeven ^= 1;
svga->x_add = (overscan_x >> 1);
svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2;
svga->vslines = 0;
dev->hwcursor_on = 0;
dev->hwcursor_latch = dev->hwcursor;
if (dev->interlace && dev->oddeven)
dev->ma = dev->maback = (dev->rowoffset << 1);
else
dev->ma = dev->maback = 0;
dev->ma = (dev->ma << 2);
dev->maback = (dev->maback << 2);
}
if (dev->vc == dev->v_total) {
dev->vc = 0;
dev->sc = 0;
dev->dispon = 1;
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
svga->x_add = (overscan_x >> 1);
dev->hwcursor_on = 0;
dev->hwcursor_latch = dev->hwcursor;
}
}
}
}
@@ -4257,6 +4281,7 @@ ibm8514_recalctimings(svga_t *svga)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
svga->render8514 = ibm8514_render_blank;
#ifdef ATI_8514_ULTRA
if (dev->extensions) {
if (svga->ext8514 != NULL)
@@ -4283,14 +4308,14 @@ ibm8514_recalctimings(svga_t *svga)
dev->h_disp = 1024;
dev->dispend = 768;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
dev->pitch = 640;
if (!dev->h_disp) {
dev->h_disp = 640;
dev->dispend = 480;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
if (dev->interlace) {
@@ -4429,6 +4454,8 @@ ibm8514_init(const device_t *info)
}
#endif
timer_add(&svga->timer8514, ibm8514_poll, svga, 0);
return svga;
}

View File

@@ -429,8 +429,7 @@ ati28800_recalctimings(svga_t *svga)
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->rowoffset <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
svga->gdcreg[5] &= ~0x40;
}
@@ -446,8 +445,7 @@ ati28800_recalctimings(svga_t *svga)
if ((ati28800->regs[0xb6] & 0x18) == 8) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
svga->ati_4color = 1;
} else
svga->ati_4color = 0;

View File

@@ -130,7 +130,8 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
ramdac->render = svga_render_4bpp_highres;
break;
case 0x83:
ramdac->render = svga_render_8bpp_highres;
/*FIXME*/
ramdac->render = svga_render_8bpp_clone_highres;
break;
case 0xa0:
case 0xb0:
@@ -155,7 +156,8 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
ramdac->render = svga_render_RGBA8888_highres;
break;
default:
ramdac->render = svga_render_8bpp_highres;
/*FIXME*/
ramdac->render = svga_render_8bpp_clone_highres;
break;
}
break;
@@ -235,7 +237,8 @@ ati68860_ramdac_init(UNUSED(const device_t *info))
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) malloc(sizeof(ati68860_ramdac_t));
memset(ramdac, 0, sizeof(ati68860_ramdac_t));
ramdac->render = svga_render_8bpp_highres;
/*FIXME*/
ramdac->render = svga_render_8bpp_clone_highres;
return ramdac;
}

View File

@@ -2527,20 +2527,6 @@ ati8514_recalctimings(svga_t *svga)
mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3);
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
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;
}
} else {
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 8) { /*40 column*/
@@ -2582,8 +2568,7 @@ mach_recalctimings(svga_t *svga)
if ((mach->regs[0xb6] & 0x18) >= 0x10) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
svga->rowoffset <<= 1;
svga->gdcreg[5] &= ~0x40;
}
@@ -2601,12 +2586,13 @@ mach_recalctimings(svga_t *svga)
if ((mach->regs[0xb6] & 0x18) == 8) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
svga->ati_4color = 1;
} else
svga->ati_4color = 0;
}
svga->render8514 = ibm8514_render_blank;
mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]);
if (dev->on[0] || dev->on[1]) {
mach_log("8514/A ON.\n");
@@ -2631,14 +2617,14 @@ mach_recalctimings(svga_t *svga)
if ((dev->local & 0xff) >= 0x02) {
if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
if (dev->interlace) {
@@ -2698,13 +2684,13 @@ mach_recalctimings(svga_t *svga)
}
switch (mach->regs[0xb8] & 0xc0) {
case 0x40:
svga->clock *= 2;
svga->clock8514 *= 2;
break;
case 0x80:
svga->clock *= 3;
svga->clock8514 *= 3;
break;
case 0xc0:
svga->clock *= 4;
svga->clock8514 *= 4;
break;
default:
@@ -2713,21 +2699,20 @@ mach_recalctimings(svga_t *svga)
} else {
if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/
if (!(mach->accel.clock_sel & 0x01)) {
dev->h_disp = 640;
dev->dispend = 480;
}
dev->interlace = 0;
}
}
@@ -2746,7 +2731,7 @@ mach_recalctimings(svga_t *svga)
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
if (mach->regs[0xb8] & 0x40)
svga->clock *= 2;
svga->clock8514 *= 2;
}
}
@@ -3662,7 +3647,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
if (!(port & 1)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f;
}
}
mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
@@ -6072,6 +6057,8 @@ mach8_init(const device_t *info)
} else
ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr");
timer_add(&svga->timer8514, ibm8514_poll, svga, 0);
return mach;
}

View File

@@ -809,13 +809,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv)
svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256));
break;
case 0x07:
svga->packed_chain4 = svga->seqregs[7] & 1;
svga->packed_chain4 = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA;
if (gd54xx_is_5422(svga))
gd543x_recalc_mapping(gd54xx);
else
svga->seqregs[svga->seqaddr] &= 0x0f;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
svga->set_reset_disabled = svga->seqregs[7] & 1;
svga->set_reset_disabled = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA;
gd54xx_recalc_banking(gd54xx);
gd54xx_set_svga_fast(gd54xx);
svga_recalctimings(svga);
break;
@@ -1661,7 +1662,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
gd54xx->mmio_vram_overlap = 0;
if (!gd54xx_is_5422(svga) || !(svga->seqregs[7] & 0xf0) || !(svga->seqregs[0x07] & 0x01)) {
if (!gd54xx_is_5422(svga) || !(svga->seqregs[0x07] & 0xf0) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) {
mem_mapping_disable(&gd54xx->linear_mapping);
mem_mapping_disable(&gd54xx->aperture2_mapping);
switch (svga->gdcreg[6] & 0x0c) {
@@ -1687,7 +1688,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
break;
}
if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) {
if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) {
if (gd54xx->mmio_vram_overlap) {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000);
@@ -1698,10 +1699,10 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
} else {
if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) {
if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) {
base = (svga->seqregs[7] & 0xf0) << 16;
base = (svga->seqregs[0x07] & 0xf0) << 16;
size = 1 * 1024 * 1024;
} else {
base = (svga->seqregs[7] & 0xe0) << 16;
base = (svga->seqregs[0x07] & 0xe0) << 16;
size = 2 * 1024 * 1024;
}
} else if (gd54xx->pci) {
@@ -1761,6 +1762,8 @@ gd54xx_recalctimings(svga_t *svga)
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) |
(((svga->crtc[0x1a] >> 4) & 3) << 6);
svga->hblank_end_mask = 0x0000007f;
if (svga->crtc[0x1b] & 0x20) {
svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1;
svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3);
@@ -1769,9 +1772,6 @@ gd54xx_recalctimings(svga_t *svga)
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
/* No overscan in this mode. */
svga->hblank_overscan = 0;
svga->monitor->mon_overscan_y = 0;
svga->monitor->mon_overscan_x = 0;
@@ -1789,15 +1789,14 @@ gd54xx_recalctimings(svga_t *svga)
}
svga->map8 = svga->pallook;
if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) {
if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) {
if (linedbl)
svga->render = svga_render_8bpp_lowres;
else {
svga->render = svga_render_8bpp_highres;
if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) {
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
}
}
} else if (svga->gdcreg[5] & 0x40)
@@ -1839,7 +1838,7 @@ gd54xx_recalctimings(svga_t *svga)
break;
case 5:
if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) {
if (gd54xx_is_5434(svga) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_32)) {
svga->bpp = 32;
if (linedbl)
svga->render = svga_render_32bpp_lowres;
@@ -1876,7 +1875,7 @@ gd54xx_recalctimings(svga_t *svga)
break;
case 0xf:
switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) {
switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) {
case CIRRUS_SR7_BPP_32:
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) {
svga->bpp = 32;
@@ -1956,7 +1955,7 @@ gd54xx_recalctimings(svga_t *svga)
uint8_t m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1;
float freq = (14318184.0F * ((float) n / ((float) d * m)));
if (gd54xx_is_5422(svga)) {
switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) {
switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) {
case 2:
freq /= 2.0F;
break;
@@ -2005,11 +2004,11 @@ gd54xx_hwcursor_draw(svga_t *svga, int displine)
svga->hwcursor_latch.addr += pitch;
for (int x = 0; x < svga->hwcursor.cur_xsize; x += 8) {
dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask];
dat[0] = svga->vram[svga->hwcursor_latch.addr & gd54xx->vram_mask];
if (svga->hwcursor.cur_xsize == 64)
dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & svga->vram_display_mask];
dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & gd54xx->vram_mask];
else
dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask];
dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & gd54xx->vram_mask];
for (uint8_t xx = 0; xx < 8; xx++) {
b0 = (dat[0] >> (7 - xx)) & 1;
b1 = (dat[1] >> (7 - xx)) & 1;
@@ -2193,7 +2192,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv)
return;
}
if ((svga->seqregs[0x07] & 0x01) == 0) {
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) {
svga_write(addr, val, svga);
return;
}
@@ -2215,7 +2214,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv)
return;
}
if ((svga->seqregs[0x07] & 0x01) == 0) {
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) {
svga_writew(addr, val, svga);
return;
}
@@ -2346,7 +2345,7 @@ gd54xx_readb_linear(uint32_t addr, void *priv)
uint8_t ap = gd54xx_get_aperture(addr);
addr &= 0x003fffff; /* 4 MB mask */
if ((svga->seqregs[0x07] & 0x01) == 0)
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA))
return svga_read_linear(addr, svga);
if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) {
@@ -2389,7 +2388,7 @@ gd54xx_readw_linear(uint32_t addr, void *priv)
addr &= 0x003fffff; /* 4 MB mask */
if ((svga->seqregs[0x07] & 0x01) == 0)
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA))
return svga_readw_linear(addr, svga);
if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) {
@@ -2439,7 +2438,7 @@ gd54xx_readl_linear(uint32_t addr, void *priv)
addr &= 0x003fffff; /* 4 MB mask */
if ((svga->seqregs[0x07] & 0x01) == 0)
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA))
return svga_readl_linear(addr, svga);
if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) {
@@ -2579,7 +2578,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv)
uint8_t ap = gd54xx_get_aperture(addr);
if ((svga->seqregs[0x07] & 0x01) == 0) {
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) {
svga_write_linear(addr, val, svga);
return;
}
@@ -2626,7 +2625,7 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv)
uint32_t old_addr = addr;
uint8_t ap = gd54xx_get_aperture(addr);
if ((svga->seqregs[0x07] & 0x01) == 0) {
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) {
svga_writew_linear(addr, val, svga);
return;
}
@@ -2693,7 +2692,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv)
uint32_t old_addr = addr;
uint8_t ap = gd54xx_get_aperture(addr);
if ((svga->seqregs[0x07] & 0x01) == 0) {
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) {
svga_writel_linear(addr, val, svga);
return;
}
@@ -2770,7 +2769,7 @@ gd54xx_read(uint32_t addr, void *priv)
gd54xx_t *gd54xx = (gd54xx_t *) priv;
svga_t *svga = &gd54xx->svga;
if ((svga->seqregs[0x07] & 0x01) == 0)
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40))
return svga_read(addr, svga);
if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED))
@@ -2787,7 +2786,7 @@ gd54xx_readw(uint32_t addr, void *priv)
svga_t *svga = &gd54xx->svga;
uint16_t ret;
if ((svga->seqregs[0x07] & 0x01) == 0)
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40))
return svga_readw(addr, svga);
if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) {
@@ -2807,7 +2806,7 @@ gd54xx_readl(uint32_t addr, void *priv)
svga_t *svga = &gd54xx->svga;
uint32_t ret;
if ((svga->seqregs[0x07] & 0x01) == 0)
if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40))
return svga_readl(addr, svga);
if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) {
@@ -3445,7 +3444,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx)
if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)
pattern_pitch = 1;
dsta = gd54xx->blt.dst_addr & svga->vram_mask;
dsta = gd54xx->blt.dst_addr & gd54xx->vram_mask;
/* The vertical offset is in the three low-order bits of the Source Address register. */
pattern_y = gd54xx->blt.src_addr & 0x07;
@@ -3459,7 +3458,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx)
*/
/* The boundary has to be equal to the size of the pattern. */
srca = (gd54xx->blt.src_addr & ~0x07) & svga->vram_mask;
srca = (gd54xx->blt.src_addr & ~0x07) & gd54xx->vram_mask;
for (uint16_t y = 0; y <= gd54xx->blt.height; y++) {
/* Go to the correct pattern line. */
@@ -3470,16 +3469,16 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx)
if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL)
bitmask = 1;
else
bitmask = svga->vram[srca2 & svga->vram_mask] & (0x80 >> pixel);
bitmask = svga->vram[srca2 & gd54xx->vram_mask] & (0x80 >> pixel);
}
for (int xx = 0; xx < gd54xx->blt.pixel_width; xx++) {
if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)
src = gd54xx_color_expand(gd54xx, bitmask, xx);
else {
src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & svga->vram_mask];
src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & gd54xx->vram_mask];
bitmask = gd54xx_transparent_comp(gd54xx, xx, src);
}
dst = &(svga->vram[(dsta + x + xx) & svga->vram_mask]);
dst = &(svga->vram[(dsta + x + xx) & gd54xx->vram_mask]);
target = *dst;
gd54xx_rop(gd54xx, &target, &target, &src);
if (gd54xx->blt.pixel_width == 3)
@@ -3488,7 +3487,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx)
gd54xx_blit(gd54xx, bitmask, dst, target, (x < gd54xx->blt.pattern_x));
}
pixel = (pixel + 1) & 7;
svga->changedvram[((dsta + x) & svga->vram_mask) >> 12] = changeframecount;
svga->changedvram[((dsta + x) & gd54xx->vram_mask) >> 12] = changeframecount;
}
pattern_y = (pattern_y + 1) & 7;
dsta += gd54xx->blt.dst_pitch;
@@ -3549,7 +3548,7 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count)
bitmask = gd54xx_transparent_comp(gd54xx, gd54xx->blt.xx_count, exp);
}
dst = &(svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]);
dst = &(svga->vram[gd54xx->blt.dst_addr_backup & gd54xx->vram_mask]);
target = *dst;
gd54xx_rop(gd54xx, &target, &target, &exp);
if ((gd54xx->blt.pixel_width == 3) && (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND))
@@ -3562,7 +3561,7 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count)
if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)
gd54xx->blt.xx_count = (gd54xx->blt.xx_count + 1) % gd54xx->blt.pixel_width;
svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount;
svga->changedvram[(gd54xx->blt.dst_addr_backup & gd54xx->vram_mask) >> 12] = changeframecount;
if (!gd54xx->blt.xx_count) {
/* 1 mask bit = 1 blitted pixel */
@@ -3619,18 +3618,18 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga)
mask = 0;
if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) {
mask = svga->vram[src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width));
mask = svga->vram[src_addr & gd54xx->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width));
shift = (gd54xx->blt.x_count % gd54xx->blt.pixel_width);
src = gd54xx_color_expand(gd54xx, mask, shift);
} else {
src = svga->vram[src_addr & svga->vram_mask];
src = svga->vram[src_addr & gd54xx->vram_mask];
src_addr += gd54xx->blt.dir;
mask = 1;
}
count--;
dst = svga->vram[dst_addr & svga->vram_mask];
svga->changedvram[(dst_addr & svga->vram_mask) >> 12] = changeframecount;
dst = svga->vram[dst_addr & gd54xx->vram_mask];
svga->changedvram[(dst_addr & gd54xx->vram_mask) >> 12] = changeframecount;
gd54xx_rop(gd54xx, &dst, &dst, (const uint8_t *) &src);
@@ -3642,7 +3641,7 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga)
mask = 0;
if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) {
svga->vram[dst_addr & svga->vram_mask] = dst;
svga->vram[dst_addr & gd54xx->vram_mask] = dst;
}
dst_addr += gd54xx->blt.dir;
@@ -3666,10 +3665,10 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga)
} else
src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + (gd54xx->blt.src_pitch * gd54xx->blt.dir);
dst_addr &= svga->vram_mask;
gd54xx->blt.dst_addr_backup &= svga->vram_mask;
src_addr &= svga->vram_mask;
gd54xx->blt.src_addr_backup &= svga->vram_mask;
dst_addr &= gd54xx->vram_mask;
gd54xx->blt.dst_addr_backup &= gd54xx->vram_mask;
src_addr &= gd54xx->vram_mask;
gd54xx->blt.src_addr_backup &= gd54xx->vram_mask;
gd54xx->blt.x_count = 0;
@@ -3710,7 +3709,7 @@ gd54xx_mem_sys_dest(uint32_t count, gd54xx_t *gd54xx, svga_t *svga)
gd54xx->blt.msd_buf_pos = 0;
while (gd54xx->blt.msd_buf_pos < 32) {
gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & svga->vram_mask];
gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & gd54xx->vram_mask];
gd54xx->blt.src_addr_backup += gd54xx->blt.dir;
gd54xx->blt.msd_buf_pos++;

View File

@@ -668,8 +668,7 @@ et4000_recalctimings(svga_t *svga)
svga->htotal += 256;
if (svga->attrregs[0x16] & 0x20) {
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
}
switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) {

View File

@@ -450,8 +450,7 @@ et4000w32p_recalctimings(svga_t *svga)
svga->htotal += 256;
if (svga->attrregs[0x16] & 0x20) {
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen);
@@ -502,8 +501,7 @@ et4000w32p_recalctimings(svga_t *svga)
case 16:
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
}
if (et4000->type <= ET4000W32P_REVC) {
if (et4000->type == ET4000W32P_REVC) {
@@ -515,8 +513,7 @@ et4000w32p_recalctimings(svga_t *svga)
break;
case 24:
svga->hdisp /= 3;
svga->hblankstart /= 3;
svga->hblank_end_val /= 3;
svga->dots_per_clock /= 3;
if (et4000->type <= ET4000W32P_REVC)
et4000->adjust_cursor = 2;
if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) {

View File

@@ -454,14 +454,10 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
break;
case 0x46e8:
if ((ht216->id == 0x7152) && ht216->isabus)
io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&ht216->linear_mapping);
if (val & 8) {
if ((ht216->id == 0x7152) && ht216->isabus)
io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
mem_mapping_enable(&svga->mapping);
ht216_remap(ht216);

View File

@@ -976,11 +976,10 @@ mystique_recalctimings(svga_t *svga)
svga->hdisp_time = svga->hdisp;
svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4);
svga->dots_per_clock = 8;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((mystique->crtcext_regs[1] & 0x40) >> 6) << 6);
svga->hblank_overscan = 0;
svga->dots_per_clock = 8;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((mystique->crtcext_regs[1] & 0x40) >> 6) << 6);
svga->hblank_end_mask = 0x0000007f;
if (mystique->type != MGA_2164W && mystique->type != MGA_2064W)
svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS);

View File

@@ -51,7 +51,7 @@ typedef struct paradise_t {
uint32_t read_bank[4], write_bank[4];
int interlace;
int check, check2;
int check;
struct {
uint8_t reg_block_ptr;
@@ -79,6 +79,7 @@ paradise_in(uint16_t addr, void *priv)
{
paradise_t *paradise = (paradise_t *) priv;
svga_t *svga = &paradise->svga;
uint8_t temp = 0;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
@@ -109,13 +110,14 @@ paradise_in(uint16_t addr, void *priv)
}
switch (svga->gdcaddr) {
case 0x0b:
temp = svga->gdcreg[0x0b];
if (paradise->type == WD90C30) {
if (paradise->vram_mask == ((512 << 10) - 1)) {
svga->gdcreg[0x0b] |= 0xc0;
svga->gdcreg[0x0b] &= ~0x40;
temp &= ~0x40;
temp |= 0xc0;
}
}
return svga->gdcreg[0x0b];
return temp;
case 0x0f:
return (svga->gdcreg[0x0f] & 0x17) | 0x80;
@@ -184,9 +186,10 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
return;
}
old = svga->gdcreg[svga->gdcaddr];
switch (svga->gdcaddr) {
case 6:
if ((svga->gdcreg[6] & 0x0c) != (val & 0x0c)) {
if (old ^ (val & 0x0c)) {
switch (val & 0x0c) {
case 0x00: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
@@ -208,9 +211,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
default:
break;
}
svga->gdcreg[6] = val;
paradise_remap(paradise);
}
svga->gdcreg[6] = val;
paradise_remap(paradise);
return;
case 9:
@@ -222,6 +225,10 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
svga->gdcreg[0x0b] = val;
paradise_remap(paradise);
return;
case 0x0e:
svga->gdcreg[0x0e] = val;
svga_recalctimings(svga);
return;
default:
break;
@@ -258,15 +265,6 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0x46e8:
io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
mem_mapping_disable(&paradise->svga.mapping);
if (val & 8) {
io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
mem_mapping_enable(&paradise->svga.mapping);
}
break;
default:
break;
}
@@ -277,7 +275,7 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
void
paradise_remap(paradise_t *paradise)
{
const svga_t *svga = &paradise->svga;
svga_t *svga = &paradise->svga;
paradise->check = 0;
@@ -319,8 +317,6 @@ paradise_recalctimings(svga_t *svga)
{
const paradise_t *paradise = (paradise_t *) svga->priv;
svga->lowres = !(svga->gdcreg[0x0e] & 0x01);
if (paradise->type == WD90C30) {
if (svga->crtc[0x3e] & 0x01)
svga->vtotal |= 0x400;
@@ -335,50 +331,42 @@ paradise_recalctimings(svga_t *svga)
svga->interlace = !!(svga->crtc[0x2d] & 0x20);
if (!svga->interlace && svga->lowres && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to
if (!svga->interlace && !(svga->gdcreg[0x0e] & 0x01) && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to
a windowed DOS box in Win3.x*/
svga->interlace = 1;
}
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
svga->interlace = 0;
}
if (paradise->type < WD90C30) {
if ((svga->bpp >= 8) && !svga->lowres) {
svga->render = svga_render_8bpp_highres;
}
} else {
if ((svga->bpp >= 8) && !svga->lowres) {
if (svga->bpp == 16) {
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if ((svga->bpp >= 8) && (svga->gdcreg[0x0e] & 0x01)) {
svga->render = svga_render_8bpp_highres;
}
}
} else {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if ((svga->bpp >= 8) && (svga->gdcreg[0x0e] & 0x01)) {
if (svga->bpp == 16) {
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else {
svga->render = svga_render_8bpp_highres;
}
}
}
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->hdisp == 360)
svga->hdisp <<= 1;
if (svga->seqregs[1] & 8) {
svga->render = svga_render_text_40;
} else
svga->render = svga_render_text_80;
}
svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask;
}
static void
@@ -389,10 +377,15 @@ paradise_write(uint32_t addr, uint8_t val, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->gdcreg[5] & 0x40)) {
svga_write(addr, val, svga);
return;
}
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
if (!svga->lowres) {
if (svga->gdcreg[0x0e] & 0x01) {
if (paradise->check) {
prev_addr = addr & 3;
prev_addr2 = addr & 0xfffc;
@@ -427,7 +420,6 @@ paradise_write(uint32_t addr, uint8_t val, void *priv)
}
}
}
svga_write_linear(addr, val, svga);
}
static void
@@ -438,10 +430,15 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->gdcreg[5] & 0x40)) {
svga_writew(addr, val, svga);
return;
}
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
if (!svga->lowres) {
if (svga->gdcreg[0x0e] & 0x01) {
if (paradise->check) {
prev_addr = addr & 3;
prev_addr2 = addr & 0xfffc;
@@ -476,7 +473,6 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv)
}
}
}
svga_writew_linear(addr, val, svga);
}
@@ -488,10 +484,14 @@ paradise_read(uint32_t addr, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->gdcreg[5] & 0x40)) {
return svga_read(addr, svga);
}
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
if (!svga->lowres) {
if (svga->gdcreg[0x0e] & 0x01) {
if (paradise->check) {
prev_addr = addr & 3;
prev_addr2 = addr & 0xfffc;
@@ -526,7 +526,6 @@ paradise_read(uint32_t addr, void *priv)
}
}
}
return svga_read_linear(addr, svga);
}
static uint16_t
@@ -537,10 +536,14 @@ paradise_readw(uint32_t addr, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->gdcreg[5] & 0x40)) {
return svga_readw(addr, svga);
}
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
if (!svga->lowres) {
if (svga->gdcreg[0x0e] & 0x01) {
if (paradise->check) {
prev_addr = addr & 3;
prev_addr2 = addr & 0xfffc;
@@ -575,7 +578,6 @@ paradise_readw(uint32_t addr, void *priv)
}
}
}
return svga_readw_linear(addr, svga);
}
@@ -641,7 +643,6 @@ paradise_init(const device_t *info, uint32_t memsize)
case WD90C11:
svga->crtc[0x36] = '1';
svga->crtc[0x37] = '1';
io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
break;
case WD90C30:
svga->crtc[0x36] = '3';

View File

@@ -3153,6 +3153,17 @@ s3_recalctimings(svga_t *svga)
int clk_sel = (svga->miscout >> 2) & 3;
uint8_t mask = 0xc0;
if (svga->crtc[0x33] & 0x20) {
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
} else {
if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
}
}
svga->hdisp = svga->hdisp_old;
svga->ma_latch |= (s3->ma_ext << 16);
@@ -3255,24 +3266,15 @@ s3_recalctimings(svga_t *svga)
((svga->crtc[3] >> 5) & 3) + 1;
svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3);
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
/* No overscan in this mode. */
svga->hblank_overscan = 0;
svga->monitor->mon_overscan_y = 0;
svga->monitor->mon_overscan_x = 0;
/* Also make sure vertical blanking starts on display end. */
svga->vblankstart = svga->dispend;
} else if (s3->chip >= S3_86C801) {
if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
}
if (s3->chip >= S3_VISION964)
svga->hblank_end_mask = 0x7f;
} else if (s3->chip >= S3_86C801) {
svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1;
if (s3->chip >= S3_VISION964) {
@@ -3280,8 +3282,9 @@ s3_recalctimings(svga_t *svga)
The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6,
and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868,
and Vision968. */
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x5d] & 0x08) >> 3) << 6);
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x5d] & 0x08) >> 3) << 6);
svga->hblank_end_mask = 0x7f;
}
}
@@ -3329,20 +3332,17 @@ s3_recalctimings(svga_t *svga)
switch (s3->width) {
case 1280:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
case 2048: /*Account for the 1280x1024 resolution*/
switch (svga->hdisp) {
case 320:
svga->hdisp <<= 2;
svga->hblankstart <<= 2;
svga->hblank_end_val <<= 2;
svga->dots_per_clock <<= 2;
break;
case 640:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -3363,8 +3363,7 @@ s3_recalctimings(svga_t *svga)
switch (s3->width) {
case 640:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
@@ -3382,8 +3381,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
default:
break;
}
@@ -3398,29 +3396,16 @@ s3_recalctimings(svga_t *svga)
case S3_PHOENIX_VISION968:
case S3_NUMBER9_9FX_771:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
if (svga->hdisp == 832)
svga->hdisp -= 32;
break;
case S3_SPEA_MERCURY_P64V:
case S3_ELSAWIN2KPROX:
switch (s3->width) {
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
default:
break;
}
break;
case S3_MIROVIDEO40SV_ERGO_968:
switch (s3->width) {
case 1152:
case 1280:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
break;
svga->dots_per_clock <<= 1;
default:
break;
}
@@ -3464,16 +3449,14 @@ s3_recalctimings(svga_t *svga)
case S3_86C911:
case S3_86C924:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_86C801:
switch (s3->card_type) {
case S3_PHOENIX_86C801:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
@@ -3487,22 +3470,19 @@ s3_recalctimings(svga_t *svga)
case S3_PHOENIX_86C805:
case S3_86C805_ONBOARD:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_SPEA_MIRAGE_86C805:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
switch (s3->width) {
case 800:
case 1024:
if (svga->hdisp == 400) {
/*SPEA specific drivers + its VBE RAM BIOS...*/
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
}
break;
default:
@@ -3519,8 +3499,7 @@ s3_recalctimings(svga_t *svga)
case S3_METHEUS_86C928:
if (!s3->color_16bit) {
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
}
switch (svga->hdisp) { /*This might be a driver issue*/
case 800:
@@ -3544,8 +3523,7 @@ s3_recalctimings(svga_t *svga)
switch (s3->width) {
case 640:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
@@ -3558,8 +3536,7 @@ s3_recalctimings(svga_t *svga)
break;
case S3_VISION864:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_VISION964:
switch (s3->card_type) {
@@ -3568,8 +3545,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -3585,8 +3561,7 @@ s3_recalctimings(svga_t *svga)
case S3_PHOENIX_VISION868:
case S3_NUMBER9_9FX_531:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
@@ -3598,8 +3573,7 @@ s3_recalctimings(svga_t *svga)
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
/* TODO: Is this still needed? */
if (svga->hdisp == 832)
svga->hdisp -= 32;
@@ -3610,8 +3584,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -3625,8 +3598,7 @@ s3_recalctimings(svga_t *svga)
case S3_TRIO64:
case S3_TRIO32:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
@@ -3662,16 +3634,14 @@ s3_recalctimings(svga_t *svga)
case S3_86C911:
case S3_86C924:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_86C801:
switch (s3->card_type) {
case S3_PHOENIX_86C801:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
@@ -3685,8 +3655,7 @@ s3_recalctimings(svga_t *svga)
case S3_PHOENIX_86C805:
case S3_86C805_ONBOARD:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_SPEA_MIRAGE_86C805:
@@ -3697,8 +3666,7 @@ s3_recalctimings(svga_t *svga)
if (svga->hdisp == 400) {
/*SPEA specific drivers + its VBE RAM BIOS...*/
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
}
break;
default:
@@ -3714,8 +3682,7 @@ s3_recalctimings(svga_t *svga)
switch (s3->card_type) {
case S3_METHEUS_86C928:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
switch (svga->hdisp) { /*This might be a driver issue*/
case 800:
s3->width = 1024;
@@ -3738,8 +3705,7 @@ s3_recalctimings(svga_t *svga)
switch (s3->width) {
case 640:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
@@ -3752,16 +3718,14 @@ s3_recalctimings(svga_t *svga)
break;
case S3_VISION864:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_VISION868:
switch (s3->card_type) {
case S3_PHOENIX_VISION868:
case S3_NUMBER9_9FX_531:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
@@ -3775,8 +3739,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -3792,8 +3755,7 @@ s3_recalctimings(svga_t *svga)
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
/* TODO: Is this still needed? */
if (svga->hdisp == 832)
svga->hdisp -= 32;
@@ -3804,8 +3766,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -3819,8 +3780,7 @@ s3_recalctimings(svga_t *svga)
case S3_TRIO64:
case S3_TRIO32:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
@@ -3863,8 +3823,7 @@ s3_recalctimings(svga_t *svga)
switch (s3->card_type) {
case S3_AMI_86C924:
svga->hdisp = (svga->hdisp << 1) / 3;
svga->hblankstart = (svga->hblankstart << 1) / 3;
svga->hblank_end_val = (svga->hblank_end_val << 1) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
/* TODO: Is this still needed? */
if (svga->hdisp == 645)
svga->hdisp -= 5;
@@ -3878,8 +3837,7 @@ s3_recalctimings(svga_t *svga)
case S3_PHOENIX_86C801:
case S3_SPEA_MIRAGE_86C801:
svga->hdisp = (svga->hdisp << 1) / 3;
svga->hblankstart = (svga->hblankstart << 1) / 3;
svga->hblank_end_val = (svga->hblank_end_val << 1) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
break;
default:
break;
@@ -3893,8 +3851,7 @@ s3_recalctimings(svga_t *svga)
case S3_SPEA_MIRAGE_86C805:
case S3_86C805_ONBOARD:
svga->hdisp = (svga->hdisp << 1) / 3;
svga->hblankstart = (svga->hblankstart << 1) / 3;
svga->hblank_end_val = (svga->hblank_end_val << 1) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
break;
default:
break;
@@ -3904,8 +3861,7 @@ s3_recalctimings(svga_t *svga)
switch (s3->card_type) {
case S3_SPEA_MERCURY_LITE_PCI:
svga->hdisp = (svga->hdisp << 1) / 3;
svga->hblankstart = (svga->hblankstart << 1) / 3;
svga->hblank_end_val = (svga->hblank_end_val << 1) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
break;
default:
break;
@@ -3913,34 +3869,13 @@ s3_recalctimings(svga_t *svga)
break;
case S3_VISION864:
svga->hdisp = (svga->hdisp << 1) / 3;
svga->hblankstart = (svga->hblankstart << 1) / 3;
svga->hblank_end_val = (svga->hblank_end_val << 1) / 3;
break;
case S3_VISION968:
switch (s3->card_type) {
case S3_MIROVIDEO40SV_ERGO_968:
case S3_SPEA_MERCURY_P64V:
switch (s3->width) {
case 1280:
svga->hdisp = ((svga->hdisp << 1) / 3) << 1;
svga->hblankstart = (svga->hblankstart << 1) / 3;
svga->hblank_end_val = ((svga->hblank_end_val << 1) / 3) << 1;
break;
default:
break;
}
break;
default:
break;
}
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
break;
case S3_TRIO64:
case S3_TRIO32:
svga->hdisp /= 3;
svga->hblankstart /= 3;
svga->hblank_end_val /= 3;
svga->dots_per_clock /= 3;
break;
default:
@@ -3969,7 +3904,8 @@ s3_recalctimings(svga_t *svga)
svga->hdisp = 640;
}
} else {
if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V)
if ((s3->card_type == S3_MIROVIDEO40SV_ERGO_968) ||
(s3->card_type == S3_PHOENIX_VISION968) || (s3->card_type == S3_SPEA_MERCURY_P64V))
svga->hdisp = s3->width;
}
#endif
@@ -3982,8 +3918,7 @@ s3_recalctimings(svga_t *svga)
case S3_PHOENIX_VISION868:
case S3_NUMBER9_9FX_531:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
@@ -3996,8 +3931,7 @@ s3_recalctimings(svga_t *svga)
case 800:
case 1024:
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
@@ -4008,8 +3942,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -4024,8 +3957,7 @@ s3_recalctimings(svga_t *svga)
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
/* TODO: Is this still needed? */
if (svga->hdisp == 832)
svga->hdisp -= 32;
@@ -4036,8 +3968,7 @@ s3_recalctimings(svga_t *svga)
case 1280:
case 1600:
svga->hdisp <<= 1;
svga->hblankstart <<= 1;
svga->hblank_end_val <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -4105,7 +4036,8 @@ s3_recalctimings(svga_t *svga)
if (svga->crtc[0x31] & 0x08) {
svga->vram_display_mask = s3->vram_mask;
if (svga->bpp == 8) {
svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/
/*Enhanced 4bpp mode, just like the 8bpp mode per the spec. */
svga->render = svga_render_8bpp_highres;
svga->rowoffset <<= 1;
}
}
@@ -4125,6 +4057,12 @@ s3_trio64v_recalctimings(svga_t *svga)
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
}
if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) {
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
}
svga->hdisp = svga->hdisp_old;
if (svga->crtc[0x5d] & 0x01)
svga->htotal |= 0x100;
@@ -4176,13 +4114,6 @@ s3_trio64v_recalctimings(svga_t *svga)
((svga->crtc[3] >> 5) & 3) + 1;
svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3);
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
/* No overscan in this mode. */
svga->hblank_overscan = 0;
svga->monitor->mon_overscan_y = 0;
svga->monitor->mon_overscan_x = 0;
@@ -4197,6 +4128,7 @@ s3_trio64v_recalctimings(svga_t *svga)
and Vision968. */
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x5d] & 0x08) >> 3) << 6);
svga->hblank_end_mask = 0x7f;
}
if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/
@@ -4220,20 +4152,17 @@ s3_trio64v_recalctimings(svga_t *svga)
case 15:
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case 16:
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
svga->hblankstart >>= 1;
svga->hblank_end_val >>= 1;
svga->dots_per_clock >>= 1;
break;
case 24:
svga->render = svga_render_24bpp_highres;
svga->hdisp /= 3;
svga->hblankstart >>= 1;
svga->hblank_end_val /= 3;
svga->dots_per_clock /= 3;
break;
case 32:
svga->render = svga_render_32bpp_highres;

View File

@@ -783,6 +783,12 @@ s3_virge_recalctimings(svga_t *svga)
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
}
if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) {
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
}
if (svga->crtc[0x5d] & 0x01)
svga->htotal += 0x100;
if (svga->crtc[0x5d] & 0x02) {
@@ -824,13 +830,6 @@ s3_virge_recalctimings(svga_t *svga)
((svga->crtc[3] >> 5) & 3) + 1;
svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3);
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
/* No overscan in this mode. */
svga->hblank_overscan = 0;
svga->monitor->mon_overscan_y = 0;
svga->monitor->mon_overscan_x = 0;
@@ -839,8 +838,9 @@ s3_virge_recalctimings(svga_t *svga)
} else {
svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x5d] & 0x08) >> 3) << 6);
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x5d] & 0x08) >> 3) << 6);
svga->hblank_end_mask = 0x7f;
}
if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/

View File

@@ -222,6 +222,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
svga_log("3C3: VGA ON = %d.\n", val & 0x01);
vga_on = val & 0x01;
svga_recalctimings(svga);
break;
case 0x3c4:
svga->seqaddr = val;
@@ -567,11 +568,15 @@ svga_set_ramdac_type(svga_t *svga, int type)
void
svga_recalctimings(svga_t *svga)
{
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
double crtcconst;
double _dispontime;
double _dispofftime;
double disptime;
double crtcconst8514;
double _dispontime8514;
double _dispofftime8514;
double disptime8514;
#ifdef ENABLE_SVGA_LOG
int vsyncend;
int vblankend;
@@ -641,10 +646,17 @@ svga_recalctimings(svga_t *svga)
svga->render = svga_render_blank;
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
if (svga->seqregs[1] & 8)
svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
else
svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) {
if (svga->seqregs[1] & 8)
svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
else
svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
} else {
if (svga->seqregs[1] & 8)
svga->hdisp *= 16;
else
svga->hdisp *= 8;
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 8) { /*40 column*/
@@ -740,19 +752,24 @@ svga_recalctimings(svga_t *svga)
svga->hblankstart = svga->crtc[2] + 1;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00);
svga->hblank_end_mask = 0x0000003f;
svga_log("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n",
svga->htotal, svga->hblankstart, svga->hblank_end_val);
svga->hblank_end_len = 0x00000040;
svga->hblank_overscan = 1;
if (!svga->scrblank && svga->attr_palette_enable) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
if (svga->seqregs[1] & 8)
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
else
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) {
if (svga->seqregs[1] & 8)
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
else
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9);
} else {
if (svga->seqregs[1] & 8)
svga->dots_per_clock = 16;
else
svga->dots_per_clock = 8;
}
} else
svga->dots_per_clock = 1;
@@ -768,17 +785,55 @@ svga_recalctimings(svga_t *svga)
xga_recalctimings(svga);
if (!svga->hoverride) {
svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val;
if (svga->hblankend <= svga->hblankstart)
svga->hblankend += svga->hblank_end_len;
svga->hblankend += svga->hblank_ext;
uint32_t dot = svga->hblankstart;
uint32_t adj_dot = svga->hblankstart;
/* Verified with both the Voodoo 3 and the S3 cards: compare 7 bits if bit 7 is set,
otherwise compare 6 bits. */
uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f;
svga->hblank_sub = 0;
if (svga->hblankend > svga->htotal) {
svga->hblankend &= (svga->hblank_end_len - 1);
svga->hblank_sub = svga->hblankend + svga->hblank_overscan;
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
svga_log("Blank: %04i-%04i, Total: %04i, Mask: %02X\n", svga->hblankstart, svga->hblank_end_val,
svga->htotal, eff_mask);
while (1) {
if (dot == svga->htotal)
dot = 0;
if (adj_dot >= svga->htotal)
svga->hblank_sub++;
if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask))
break;
dot++;
adj_dot++;
}
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
uint32_t dot8514 = dev->h_blankstart;
uint32_t adj_dot8514 = dev->h_blankstart;
uint32_t eff_mask8514 = 0x0000003f;
dev->hblank_sub = 0;
while (1) {
if (dot8514 == dev->h_total)
dot = 0;
if (adj_dot8514 >= dev->h_total)
dev->hblank_sub++;
if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514))
break;
dot8514++;
adj_dot8514++;
}
dev->h_disp -= dev->hblank_sub;
}
}
}
@@ -792,6 +847,10 @@ svga_recalctimings(svga_t *svga)
svga->dispend = svga->vblankstart;
crtcconst = svga->clock * svga->char_width;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1])
crtcconst8514 = svga->clock8514;
}
#ifdef ENABLE_SVGA_LOG
vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f);
@@ -833,6 +892,13 @@ svga_recalctimings(svga_t *svga)
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
disptime8514 = dev->htotal;
_dispontime8514 = dev->hdisped;
}
}
if (svga->seqregs[1] & 8) {
disptime *= 2;
_dispontime *= 2;
@@ -849,6 +915,27 @@ svga_recalctimings(svga_t *svga)
if (svga->dispofftime < TIMER_USEC)
svga->dispofftime = TIMER_USEC;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
_dispofftime8514 = disptime8514 - _dispontime8514;
_dispontime8514 *= crtcconst8514;
_dispofftime8514 *= crtcconst8514;
dev->dispontime = (uint64_t) (_dispontime8514);
dev->dispofftime = (uint64_t) (_dispofftime8514);
if (dev->dispontime < TIMER_USEC)
dev->dispontime = TIMER_USEC;
if (dev->dispofftime < TIMER_USEC)
dev->dispofftime = TIMER_USEC;
timer_disable(&svga->timer);
timer_enable(&svga->timer8514);
} else {
timer_disable(&svga->timer8514);
timer_enable(&svga->timer);
}
}
if (!svga->force_old_addr)
svga_recalc_remap_func(svga);
@@ -921,10 +1008,6 @@ svga_poll(void *priv)
int old_ma;
if (!svga->override) {
if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) {
ibm8514_poll(dev, svga);
return;
}
if (xga_active && xga && xga->on) {
if ((xga->disp_cntl_2 & 7) >= 2) {
xga_poll(xga, svga);
@@ -1278,7 +1361,6 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
svga->ramdac_type = RAMDAC_6BIT;
svga->map8 = svga->pallook;
svga->hblank_overscan = 1; /* Do at least 1 character of overscan after horizontal blanking. */
return 0;
}
@@ -1323,9 +1405,10 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write)
}
if (memory_map_mode <= 1) {
if (svga->adv_flags & FLAG_EXTRA_BANKS)
addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1];
else {
if (svga->adv_flags & FLAG_EXTRA_BANKS) {
if ((svga->gdcreg[5] & 0x40) || svga->packed_chain4)
addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1];
} else {
if (write)
addr += svga->write_bank;
else

View File

@@ -717,7 +717,7 @@ void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false
void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); }
void
svga_render_8bpp_incompatible_highres(svga_t *svga)
svga_render_8bpp_clone_highres(svga_t *svga)
{
int x;
uint32_t *p;

View File

@@ -517,6 +517,65 @@ tvp3026_recalctimings(void *priv, svga_t *svga)
svga->interlace = (ramdac->ccr & 0x40);
/* TODO: Figure out gamma correction for 15/16 bpp color. */
svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00);
switch (ramdac->mcr) {
case 0x41:
case 0x4a:
case 0x61:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
case 0x42:
case 0x4b:
case 0x62:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 0x43:
case 0x4c:
case 0x63:
svga->hdisp <<= 3;
svga->dots_per_clock <<= 3;
break;
case 0x44:
case 0x64:
svga->hdisp <<= 4;
svga->dots_per_clock <<= 4;
break;
case 0x5b:
switch (ramdac->true_color) {
case 0x16:
case 0x17:
svga->hdisp = (svga->hdisp << 2) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 2) / 3;
break;
case 0x1e:
case 0x1f:
svga->hdisp = (svga->hdisp * 5) >> 2;
svga->dots_per_clock = (svga->dots_per_clock * 5) >> 2;
break;
}
break;
case 0x5c:
switch (ramdac->true_color) {
case 0x06:
case 0x07:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
case 0x16:
case 0x17:
svga->hdisp = (svga->hdisp << 3) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 3) / 3;
break;
case 0x1e:
case 0x1f:
svga->hdisp = (svga->hdisp * 5) >> 1;
svga->dots_per_clock = (svga->dots_per_clock * 5) >> 1;
break;
}
break;
}
}
uint32_t

View File

@@ -556,17 +556,20 @@ banshee_recalctimings(svga_t *svga)
if (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE) {
/* Video processing mode - assume timings akin to Cirrus' special blanking mode,
that is, no overscan and relying on display end to blank. */
svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) +
(((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1;
if (banshee->vgaInit0 & 0x40) {
svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) +
(((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1;
svga->hblank_end_mask = 0x0000007f;
} else {
svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1;
svga->hblank_end_mask = 0x0000003f;
}
svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3);
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
/* No overscan in this mode. */
svga->hblank_overscan = 0;
svga->monitor->mon_overscan_y = 0;
svga->monitor->mon_overscan_x = 0;
@@ -575,9 +578,16 @@ banshee_recalctimings(svga_t *svga)
svga->linedbl = 0;
} else {
svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x1a] & 0x20) >> 5) << 6);
if (banshee->vgaInit0 & 0x40) {
svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) |
(((svga->crtc[0x1a] & 0x20) >> 5) << 6);
svga->hblank_end_mask = 0x0000007f;
} else {
svga->hblankstart = svga->crtc[2] + 1;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5);
svga->hblank_end_mask = 0x0000003f;
}
}
/*6 R/W Vertical Retrace Start bit 10 0x10
@@ -642,9 +652,10 @@ banshee_recalctimings(svga_t *svga)
if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) {
svga->hdisp *= 2;
svga->htotal *= 2;
svga->hblankstart *= 2;
svga->hblank_end_val *= 2;
// svga->htotal *= 2;
// svga->hblankstart *= 2;
// svga->hblank_end_val *= 2;
svga->dots_per_clock *= 2;
}
svga->interlace = !!(banshee->vidProcCfg & VIDPROCCFG_INTERLACE);