Merge branch 'master' into pc98x1

This commit is contained in:
TC1995
2024-08-08 19:16:38 +02:00
5 changed files with 54 additions and 32 deletions

View File

@@ -20,6 +20,9 @@ typedef struct sn76489_t {
int freqhi[4];
int vol[4];
uint32_t shift;
uint32_t white_noise_tap_1;
uint32_t white_noise_tap_2;
uint32_t feedback_mask;
uint8_t noise;
int lasttone;
uint8_t firstdat;

View File

@@ -1763,7 +1763,7 @@ machine_tandy1k_init(const machine_t *model, int type)
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
vid_init(dev);
device_add_ex(&vid_device, dev);
device_add(&sn76489_device);
device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device);
break;
case TYPE_TANDY1000HX:

View File

@@ -1724,9 +1724,6 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt
that condition. */
dev->unit_attention = 0;
}
/* Clear the sense stuff as per the spec. */
scsi_cdrom_sense_clear(dev, GPCMD_REQUEST_SENSE);
}
void
@@ -1841,6 +1838,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
return;
begin:
if (cdb[0] != GPCMD_REQUEST_SENSE) {
/* Clear the sense stuff as per the spec. */
scsi_cdrom_sense_clear(dev, cdb[0]);
}
switch (cdb[0]) {
case GPCMD_TEST_UNIT_READY:
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);

View File

@@ -545,10 +545,6 @@ esp_do_command_phase(esp_t *dev)
esp_log("ESP SCSI Start reading/writing\n");
esp_do_dma(dev);
} else {
if (dev->mca && (buf[0] == 0x43) && (sd->phase == SCSI_PHASE_STATUS)) {
esp_set_phase(dev, STAT_DI);
scsi_device_command_phase1(sd);
}
esp_log("ESP SCSI Command with no length\n");
esp_command_complete(dev, sd->status);
}

View File

@@ -21,7 +21,15 @@ static float volslog[16] = {
7.51785f, 9.46440f, 11.9194f, 15.0000f
};
void
static int
sn76489_check_tap_2(sn76489_t *sn76489)
{
int ret = ((sn76489->shift >> sn76489->white_noise_tap_2) & 1);
return (sn76489->type == SN76496) ? ret : !ret;
}
static void
sn76489_update(sn76489_t *sn76489)
{
for (; sn76489->pos < sound_pos_global; sn76489->pos++) {
@@ -42,24 +50,28 @@ sn76489_update(sn76489_t *sn76489)
result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2);
sn76489->count[0] -= (512 * sn76489->psgconst);
while (sn76489->count[0] < 0 && sn76489->latch[0]) {
while ((sn76489->count[0] < 0) && sn76489->latch[0]) {
sn76489->count[0] += (sn76489->latch[0] * 4);
if (!(sn76489->noise & 4)) {
if (sn76489->shift & 1)
sn76489->shift |= 0x8000;
sn76489->shift >>= 1;
if ((sn76489->shift >> sn76489->white_noise_tap_1) & 1) {
sn76489->shift >>= 1;
sn76489->shift |= sn76489->feedback_mask;
} else
sn76489->shift >>= 1;
} else {
if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1))
sn76489->shift |= 0x8000;
sn76489->shift >>= 1;
if (((sn76489->shift >> sn76489->white_noise_tap_1) & 1) ^ sn76489_check_tap_2(sn76489)) {
sn76489->shift >>= 1;
sn76489->shift |= sn76489->feedback_mask;
} else
sn76489->shift >>= 1;
}
}
sn76489->buffer[sn76489->pos] = result;
sn76489->buffer[sn76489->pos] = (sn76489->type == NCR8496) ? -result : result;
}
}
void
static void
sn76489_get_buffer(int32_t *buffer, int len, void *priv)
{
sn76489_t *sn76489 = (sn76489_t *) priv;
@@ -74,7 +86,7 @@ sn76489_get_buffer(int32_t *buffer, int len, void *priv)
sn76489->pos = 0;
}
void
static void
sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv)
{
sn76489_t *sn76489 = (sn76489_t *) priv;
@@ -125,15 +137,13 @@ sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv)
sn76489->vol[1] = 0xf - data;
break;
case 0x60:
if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496)
sn76489->shift = 0x4000;
if (((data & 4) != (sn76489->noise & 4)) || (sn76489->type == SN76496))
sn76489->shift = sn76489->feedback_mask;
sn76489->noise = data & 0xf;
if ((data & 3) == 3)
sn76489->latch[0] = sn76489->latch[1];
else
sn76489->latch[0] = 0x400 << (data & 3);
if (!sn76489->extra_divide)
sn76489->latch[0] &= 0x3ff;
if (!sn76489->latch[0])
sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6;
break;
@@ -146,22 +156,24 @@ sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv)
break;
}
} else {
/* NCR8496 ignores writes to registers 1, 3, 5, 6 and 7 with bit 7 clear. */
if ((sn76489->type != SN76496) && ((sn76489->firstdat & 0x10) || ((sn76489->firstdat & 0x70) == 0x60)))
return;
if ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) {
if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496)
sn76489->shift = 0x4000;
if (sn76489->type == SN76496)
sn76489->shift = sn76489->feedback_mask;
sn76489->noise = data & 0xf;
if ((data & 3) == 3)
sn76489->latch[0] = sn76489->latch[1];
else
sn76489->latch[0] = 0x400 << (data & 3);
if (!sn76489->latch[0])
sn76489->latch[0] = 1024 << 6;
sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6;
} else if ((sn76489->firstdat & 0x70) != 0x60) {
if (sn76489->extra_divide)
sn76489->freqhi[sn76489->lasttone] = data & 0x7F;
else
sn76489->freqhi[sn76489->lasttone] = data & 0x3F;
freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4);
sn76489->freqhi[sn76489->lasttone] = data & 0x7F;
freq = sn76489->freqlo[sn76489->lasttone] |
(sn76489->freqhi[sn76489->lasttone] << 4);
if (!sn76489->extra_divide)
freq &= 0x3ff;
if (!freq)
@@ -190,6 +202,16 @@ sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int fre
{
sound_add_handler(sn76489_get_buffer, sn76489);
if (type == SN76496) {
sn76489->white_noise_tap_1 = 0;
sn76489->white_noise_tap_2 = 1;
sn76489->feedback_mask = 0x4000;
} else {
sn76489->white_noise_tap_1 = 1;
sn76489->white_noise_tap_2 = 5;
sn76489->feedback_mask = 0x8000;
}
sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6;
sn76489->vol[0] = 0;
sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8;
@@ -200,7 +222,7 @@ sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int fre
sn76489->count[2] = (rand() & 0x3FF) << 6;
sn76489->count[3] = (rand() & 0x3FF) << 6;
sn76489->noise = 3;
sn76489->shift = 0x4000;
sn76489->shift = sn76489->feedback_mask;
sn76489->type = type;
sn76489->psgconst = (((double) freq / 64.0) / (double) FREQ_48000);