Merge branch 'master' into pc98x1

This commit is contained in:
TC1995
2024-08-30 13:50:37 +02:00
8 changed files with 93 additions and 54 deletions

View File

@@ -1016,9 +1016,14 @@ smram_restore_state_p6(uint32_t *saved_state)
cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_gs);
mem_a20_alt = 0x00;
mem_a20_key = saved_state[SMRAM_FIELD_P6_A20M] ? 0x00 : 0x02;
mem_a20_recalc();
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
if (is6117)
rammask |= 0x3000000;
if (saved_state[SMRAM_FIELD_P6_A20M] & 0x01)
rammask &= ~0xffefffff;
flushmmucache();
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET];

View File

@@ -23,6 +23,7 @@
typedef struct ogc_t {
cga_t cga;
uint16_t ctrl_addr;
/* unused in OGC, required for M19 video card structure idiom */
uint8_t ctrl_3dd;
uint8_t ctrl_3de;

View File

@@ -341,6 +341,7 @@ enum {
LFB_FORMAT_RGB565 = 0,
LFB_FORMAT_RGB555 = 1,
LFB_FORMAT_ARGB1555 = 2,
LFB_FORMAT_XRGB8888 = 4,
LFB_FORMAT_ARGB8888 = 5,
LFB_FORMAT_DEPTH = 15,
LFB_FORMAT_MASK = 15

View File

@@ -2038,6 +2038,8 @@ m19_vid_init(m19_vid_t *vid)
vid->ogc.mono_display = 0;
else
vid->ogc.mono_display = 1;
vid->ogc.ctrl_addr = 0x3db;
/* OGC emulation part end */
/* Plantronics emulation part begin*/

View File

@@ -1182,7 +1182,7 @@ scsi_cdrom_cmd_error(scsi_cdrom_t *dev)
{
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->tf->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
if (dev->unit_attention > 2)
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
@@ -1199,7 +1199,7 @@ scsi_cdrom_unit_attention(scsi_cdrom_t *dev)
{
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
if (dev->unit_attention > 2)
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
@@ -1546,12 +1546,40 @@ scsi_cdrom_insert(void *priv)
if (!dev)
return;
dev->unit_attention = 0x11;
dev->unit_attention = 1;
/* Turn off the medium changed status. */
dev->drv->cd_status &= ~CD_STATUS_MEDIUM_CHANGED;
scsi_cdrom_log("CD-ROM %i: Media insert\n", dev->id);
}
static int
scsi_command_check_ready(scsi_cdrom_t *dev, uint8_t *cdb)
{
int ret = 0;
if (scsi_cdrom_command_flags[cdb[0]] & CHECK_READY) {
/*Note by TC1995: Some vendor commands from X vendor don't really check for ready status
but they do on Y vendor. Quite confusing I know.*/
if (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY) switch (dev->drv->type) {
default:
ret = 1;
break;
case CDROM_TYPE_DEC_RRD45_0436:
case CDROM_TYPE_SONY_CDU541_10i:
case CDROM_TYPE_SONY_CDU561_18k:
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100:
if (cdb[0] == 0xC0)
break;
ret = 1;
break;
} else
ret = 1;
}
return ret;
}
static int
scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb)
{
@@ -1598,23 +1626,24 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb)
ready = (dev->drv->cd_status != CD_STATUS_EMPTY) || (ext_medium_changed == -1);
/* Transition, pretend we're not ready for one check so that
Windows XP can recognize a medium change. */
if ((dev->unit_attention & 0xf0) == 0x10) {
ready = 0;
goto skip_ua_check;
}
skip_ready_check:
/* If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present, as we only use it to mark
disc changes. */
if (!ready && dev->unit_attention)
if (!ready && (dev->unit_attention > 2))
dev->unit_attention = 0;
/* If the UNIT ATTENTION condition is set and the command does not allow
execution under it, error out and report the condition. */
if (dev->unit_attention == 1) {
if ((dev->unit_attention > 0) && (dev->unit_attention < 3)) {
dev->media_status = MEC_MEDIA_REMOVAL;
if (scsi_command_check_ready(dev, cdb)) {
dev->unit_attention++;
scsi_cdrom_log("CD-ROM %i: Simulated not ready phase (%02X)\n", dev->id, cdb[0]);
scsi_cdrom_not_ready(dev);
return 0;
}
} else if (dev->unit_attention == 3) {
/* Only increment the unit attention phase if the command can not pass through it. */
if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) {
/* scsi_cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); */
@@ -1624,53 +1653,31 @@ skip_ready_check:
scsi_cdrom_unit_attention(dev);
return 0;
}
} else if (dev->unit_attention == 2) {
} else if (dev->unit_attention == 4) {
if (cdb[0] != GPCMD_REQUEST_SENSE) {
/* scsi_cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); */
dev->unit_attention = 0;
}
}
skip_ua_check:
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT*
the UNIT ATTENTION condition if it's set. */
if (cdb[0] != GPCMD_REQUEST_SENSE)
scsi_cdrom_sense_clear(dev, cdb[0]);
/* Next it's time for NOT READY. */
if (!ready)
if (!ready || ((dev->unit_attention > 0) && (dev->unit_attention < 3)))
dev->media_status = MEC_MEDIA_REMOVAL;
else
dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE;
dev->media_status = (dev->unit_attention > 2) ? MEC_NEW_MEDIA : MEC_NO_CHANGE;
if ((scsi_cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) {
if (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY) { /*Note by TC1995: Some vendor commands from X vendor don't really check for ready status
but they do on Y vendor. Quite confusing I know.*/
switch (dev->drv->type) {
case CDROM_TYPE_DEC_RRD45_0436:
case CDROM_TYPE_SONY_CDU541_10i:
case CDROM_TYPE_SONY_CDU561_18k:
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100:
if (cdb[0] == 0xC0)
break;
scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]);
scsi_cdrom_not_ready(dev);
return 0;
default:
scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]);
scsi_cdrom_not_ready(dev);
return 0;
}
} else {
scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]);
scsi_cdrom_not_ready(dev);
return 0;
}
if (!ready && scsi_command_check_ready(dev, cdb)) {
scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]);
scsi_cdrom_not_ready(dev);
return 0;
}
scsi_cdrom_log("CD-ROM %i: Continuing with command %02X\n", dev->id, cdb[0]);
return 1;
}
@@ -1719,7 +1726,7 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt
buffer[2] = SENSE_ILLEGAL_REQUEST;
buffer[12] = ASC_AUDIO_PLAY_OPERATION;
buffer[13] = (dev->drv->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
} else if (dev->unit_attention && ((dev->unit_attention & 0xf0) != 0x10) &&
} else if ((dev->unit_attention > 2) &&
((scsi_cdrom_sense_key == 0) || (scsi_cdrom_sense_key == 2))) {
buffer[2] = SENSE_UNIT_ATTENTION;
buffer[12] = ASC_MEDIUM_MAY_HAVE_CHANGED;
@@ -1728,9 +1735,6 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt
scsi_cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]);
if ((dev->unit_attention & 0xf0) == 0x10)
dev->unit_attention &= 0x0f;
if (buffer[2] == SENSE_UNIT_ATTENTION) {
/* If the last remaining sense is unit attention, clear
that condition. */
@@ -1746,7 +1750,7 @@ scsi_cdrom_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t al
if (dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED)
scsi_cdrom_insert((void *) dev);
if ((dev->drv->cd_status == CD_STATUS_EMPTY) && dev->unit_attention) {
if ((dev->drv->cd_status == CD_STATUS_EMPTY) && (dev->unit_attention > 2)) {
/* If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present, as we only use it to mark
disc changes. */

View File

@@ -97,11 +97,14 @@ ogc_out(uint16_t addr, uint8_t val, void *priv)
cga_out(addr, val, &ogc->cga);
break;
case 0x3db:
case 0x3de:
/* set control register */
ogc->ctrl_3de = val;
/* select 1st or 2nd 16k vram block to be used */
ogc->base = (val & 0x08) ? 0x4000 : 0;
if (addr == ogc->ctrl_addr) {
/* set control register */
ogc->ctrl_3de = val;
/* select 1st or 2nd 16k vram block to be used */
ogc->base = (val & 0x08) ? 0x4000 : 0;
}
break;
default:
@@ -622,6 +625,8 @@ ogc_init(UNUSED(const device_t *info))
else
ogc->mono_display = 1;
ogc->ctrl_addr = 0x3de;
return ogc;
}

View File

@@ -9441,12 +9441,18 @@ s3_disable_handlers(s3_t *s3)
{
s3_io_remove(s3);
mem_mapping_set_addr(&s3->linear_mapping, 0, 0);
mem_mapping_disable(&s3->linear_mapping);
mem_mapping_set_addr(&s3->mmio_mapping, 0, 0);
mem_mapping_disable(&s3->mmio_mapping);
mem_mapping_set_addr(&s3->new_mmio_mapping, 0, 0);
mem_mapping_disable(&s3->new_mmio_mapping);
mem_mapping_set_addr(&s3->svga.mapping, 0xa0000, 0x20000);
mem_mapping_disable(&s3->svga.mapping);
if (s3->pci)
if (s3->pci) {
mem_mapping_set_addr(&s3->bios_rom.mapping, 0xc0000, 0x8000);
mem_mapping_disable(&s3->bios_rom.mapping);
}
/* Save all the mappings and the timers because they are part of linked lists. */
reset_state->linear_mapping = s3->linear_mapping;
@@ -9457,6 +9463,11 @@ s3_disable_handlers(s3_t *s3)
reset_state->svga.timer = s3->svga.timer;
reset_state->svga.timer8514 = s3->svga.timer8514;
memset(s3->svga.vram, 0x00, s3->svga.vram_max + 8);
memset(s3->svga.changedvram, 0x00, (s3->svga.vram_max >> 12) + 1);
pci_clear_irq(s3->pci_slot, PCI_INTA, &s3->irq_state);
}
static void
@@ -9471,6 +9482,7 @@ s3_reset(void *priv)
reset_state->pci_slot = s3->pci_slot;
*s3 = *reset_state;
s3_io_set(s3);
}
}

View File

@@ -364,6 +364,15 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv)
addr >>= 1;
break;
case LFB_FORMAT_XRGB8888:
colour_data[0].b = val & 0xff;
colour_data[0].g = (val >> 8) & 0xff;
colour_data[0].r = (val >> 16) & 0xff;
alpha_data[0] = 0xff;
write_mask = LFB_WRITE_COLOUR;
addr >>= 1;
break;
case LFB_FORMAT_DEPTH:
depth_data[0] = val;
depth_data[1] = val >> 16;