Merge branch '86Box:master' into main

This commit is contained in:
MaxwellS04
2024-08-09 15:15:37 +07:00
committed by GitHub
6 changed files with 59 additions and 28 deletions

View File

@@ -20,6 +20,9 @@ typedef struct sn76489_t {
int freqhi[4]; int freqhi[4];
int vol[4]; int vol[4];
uint32_t shift; uint32_t shift;
uint32_t white_noise_tap_1;
uint32_t white_noise_tap_2;
uint32_t feedback_mask;
uint8_t noise; uint8_t noise;
int lasttone; int lasttone;
uint8_t firstdat; 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); tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
vid_init(dev); vid_init(dev);
device_add_ex(&vid_device, dev); device_add_ex(&vid_device, dev);
device_add(&sn76489_device); device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device);
break; break;
case TYPE_TANDY1000HX: case TYPE_TANDY1000HX:

View File

@@ -396,7 +396,7 @@ dp8390_rx_common(void *priv, uint8_t *buf, int io_len)
} else { } else {
endbytes = (dev->page_stop - dev->curr_page) * 256; endbytes = (dev->page_stop - dev->curr_page) * 256;
memcpy(startptr + sizeof(pkthdr), buf, endbytes - sizeof(pkthdr)); memcpy(startptr + sizeof(pkthdr), buf, endbytes - sizeof(pkthdr));
startptr = &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap]; startptr = &dev->mem[((dev->page_start * 256) - dev->mem_start) & dev->mem_wrap];
memcpy(startptr, buf + endbytes - sizeof(pkthdr), io_len - endbytes + 8); memcpy(startptr, buf + endbytes - sizeof(pkthdr), io_len - endbytes + 8);
} }
dev->curr_page = nextpage; dev->curr_page = nextpage;

View File

@@ -21,7 +21,15 @@ static float volslog[16] = {
7.51785f, 9.46440f, 11.9194f, 15.0000f 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) sn76489_update(sn76489_t *sn76489)
{ {
for (; sn76489->pos < sound_pos_global; sn76489->pos++) { 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); result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2);
sn76489->count[0] -= (512 * sn76489->psgconst); 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); sn76489->count[0] += (sn76489->latch[0] * 4);
if (!(sn76489->noise & 4)) { if (!(sn76489->noise & 4)) {
if (sn76489->shift & 1) if ((sn76489->shift >> sn76489->white_noise_tap_1) & 1) {
sn76489->shift |= 0x8000; sn76489->shift >>= 1;
sn76489->shift >>= 1; sn76489->shift |= sn76489->feedback_mask;
} else
sn76489->shift >>= 1;
} else { } else {
if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) if (((sn76489->shift >> sn76489->white_noise_tap_1) & 1) ^ sn76489_check_tap_2(sn76489)) {
sn76489->shift |= 0x8000; sn76489->shift >>= 1;
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_get_buffer(int32_t *buffer, int len, void *priv)
{ {
sn76489_t *sn76489 = (sn76489_t *) priv; sn76489_t *sn76489 = (sn76489_t *) priv;
@@ -74,7 +86,7 @@ sn76489_get_buffer(int32_t *buffer, int len, void *priv)
sn76489->pos = 0; sn76489->pos = 0;
} }
void static void
sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv) sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv)
{ {
sn76489_t *sn76489 = (sn76489_t *) 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; sn76489->vol[1] = 0xf - data;
break; break;
case 0x60: case 0x60:
if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) if (((data & 4) != (sn76489->noise & 4)) || (sn76489->type == SN76496))
sn76489->shift = 0x4000; sn76489->shift = sn76489->feedback_mask;
sn76489->noise = data & 0xf; sn76489->noise = data & 0xf;
if ((data & 3) == 3) if ((data & 3) == 3)
sn76489->latch[0] = sn76489->latch[1]; sn76489->latch[0] = sn76489->latch[1];
else else
sn76489->latch[0] = 0x400 << (data & 3); sn76489->latch[0] = 0x400 << (data & 3);
if (!sn76489->extra_divide)
sn76489->latch[0] &= 0x3ff;
if (!sn76489->latch[0]) if (!sn76489->latch[0])
sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6;
break; break;
@@ -146,22 +156,24 @@ sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv)
break; break;
} }
} else { } 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 ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) {
if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) if (sn76489->type == SN76496)
sn76489->shift = 0x4000; sn76489->shift = sn76489->feedback_mask;
sn76489->noise = data & 0xf; sn76489->noise = data & 0xf;
if ((data & 3) == 3) if ((data & 3) == 3)
sn76489->latch[0] = sn76489->latch[1]; sn76489->latch[0] = sn76489->latch[1];
else else
sn76489->latch[0] = 0x400 << (data & 3); sn76489->latch[0] = 0x400 << (data & 3);
if (!sn76489->latch[0]) if (!sn76489->latch[0])
sn76489->latch[0] = 1024 << 6; sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6;
} else if ((sn76489->firstdat & 0x70) != 0x60) { } else if ((sn76489->firstdat & 0x70) != 0x60) {
if (sn76489->extra_divide) sn76489->freqhi[sn76489->lasttone] = data & 0x7F;
sn76489->freqhi[sn76489->lasttone] = data & 0x7F; freq = sn76489->freqlo[sn76489->lasttone] |
else (sn76489->freqhi[sn76489->lasttone] << 4);
sn76489->freqhi[sn76489->lasttone] = data & 0x3F;
freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4);
if (!sn76489->extra_divide) if (!sn76489->extra_divide)
freq &= 0x3ff; freq &= 0x3ff;
if (!freq) 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); 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->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6;
sn76489->vol[0] = 0; sn76489->vol[0] = 0;
sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8; 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[2] = (rand() & 0x3FF) << 6;
sn76489->count[3] = (rand() & 0x3FF) << 6; sn76489->count[3] = (rand() & 0x3FF) << 6;
sn76489->noise = 3; sn76489->noise = 3;
sn76489->shift = 0x4000; sn76489->shift = sn76489->feedback_mask;
sn76489->type = type; sn76489->type = type;
sn76489->psgconst = (((double) freq / 64.0) / (double) FREQ_48000); sn76489->psgconst = (((double) freq / 64.0) / (double) FREQ_48000);

View File

@@ -482,8 +482,11 @@ tgui_out(uint16_t addr, uint8_t val, void *priv)
svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff;
if ((tgui->accel.ger22 & 0xff) == 8) { if ((tgui->accel.ger22 & 0xff) == 8) {
if (svga->bpp != 24) if (svga->bpp != 24) {
svga->hwcursor.x <<= 1; svga->hwcursor.x <<= 1;
if ((tgui->type == TGUI_9440) && (svga->crtc[0x1e] & 4))
svga->hwcursor.x >>= 1;
}
} }
svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f;
@@ -788,6 +791,9 @@ tgui_recalctimings(svga_t *svga)
default: default:
break; break;
} }
} else {
if ((svga->hdisp == 1280) && (svga->dispend == (1020 >> 1)) && svga->interlace)
svga->dispend++;
} }
break; break;
case 15: case 15:

View File

@@ -513,7 +513,7 @@ banshee_render_16bpp_tiled(svga_t *svga)
if (addr >= svga->vram_max) if (addr >= svga->vram_max)
return; return;
for (int x = 0; x <= svga->hdisp; x += 64) { for (int x = 0; x < svga->hdisp; x += 64) {
if (svga->hwcursor_on || svga->overlay_on) if (svga->hwcursor_on || svga->overlay_on)
svga->changedvram[addr >> 12] = 2; svga->changedvram[addr >> 12] = 2;
if (svga->changedvram[addr >> 12] || svga->fullchange) { if (svga->changedvram[addr >> 12] || svga->fullchange) {