static READ8_HANDLER(svision_r) { int data = svision_reg[offset]; switch (offset) { case 0x20: data = readinputport(0); break; case 0x21: data &= ~0xf; data |= svision_reg[0x22] & 0xf; if (svision_pet.on) { if (!svision_pet.clock) data &= ~4; if (!svision_pet.data) data &= ~8; } break; case 0x27: data &= ~3; if (svision.timer_shot) data|=1; if (svision_dma.finished) data|=2; break; case 0x24: svision.timer_shot = FALSE; svision_irq(); break; case 0x25: svision_dma.finished = FALSE; svision_irq(); break; default: logerror("%.6f svision read %04x %02x\n",timer_get_time(),offset,data); break; } return data; }
static WRITE8_HANDLER(svision_w) { int value; int delay; svision_reg[offset] = data; switch (offset) { case 2: case 3: break; case 0x26: /* bits 5,6 memory management for a000? */ logerror("%.6f svision write %04x %02x\n",timer_get_time(),offset,data); memory_set_bankptr(1, memory_region(REGION_USER1) + ((svision_reg[0x26] & 0xe0) << 9)); svision_irq(); break; case 0x23: /* delta hero irq routine write */ value = data; if (!data) value = 0x100; if (BANK & 0x10) delay = 16384; else delay = 256; timer_enable(svision.timer1, TRUE); timer_reset(svision.timer1, TIME_IN_CYCLES(value * delay, 0)); break; case 0x10: case 0x11: case 0x12: case 0x13: svision_soundport_w(svision_channel + 0, offset & 3, data); break; case 0x14: case 0x15: case 0x16: case 0x17: svision_soundport_w(svision_channel + 1, offset & 3, data); break; case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: svision_sounddma_w(offset - 0x18, data); break; case 0x28: case 0x29: case 0x2a: svision_noise_w(offset - 0x28, data); break; default: logerror("%.6f svision write %04x %02x\n", timer_get_time(), offset, data); break; } }
static STREAM_UPDATE( svision_update ) { svision_sound_state *state = get_safe_token(device); stream_sample_t *left=outputs[0], *right=outputs[1]; int i, j; SVISION_CHANNEL *channel; for (i = 0; i < samples; i++, left++, right++) { *left = 0; *right = 0; for (channel=state->channel, j=0; j<ARRAY_LENGTH(state->channel); j++, channel++) { if (channel->size != 0) { if (channel->on||channel->count) { int on = FALSE; switch (channel->waveform) { case 0: on = channel->pos <= (28 * channel->size) >> 5; break; case 1: on = channel->pos <= (24 * channel->size) >> 5; break; default: case 2: on = channel->pos <= channel->size / 2; break; case 3: on = channel->pos <= (9 * channel->size) >> 5; break; } { INT16 s = on ? channel->volume << 8 : 0; if (j == 0) *right += s; else *left += s; } } channel->pos++; if (channel->pos >= channel->size) channel->pos = 0; } } if (state->noise.on && (state->noise.play || state->noise.count)) { INT16 s = (state->noise.value ? 1 << 8: 0) * state->noise.volume; int b1, b2; if (state->noise.left) *left += s; if (state->noise.right) *right += s; state->noise.pos += state->noise.step; if (state->noise.pos >= 1.0) { switch (state->noise.type) { case SVISION_NOISE_Type7Bit: state->noise.value = state->noise.state & 0x40 ? 1 : 0; b1 = (state->noise.state & 0x40) != 0; b2 = (state->noise.state & 0x20) != 0; state->noise.state=(state->noise.state<<1)+(b1!=b2?1:0); break; case SVISION_NOISE_Type14Bit: default: state->noise.value = state->noise.state & 0x2000 ? 1 : 0; b1 = (state->noise.state & 0x2000) != 0; b2 = (state->noise.state & 0x1000) != 0; state->noise.state = (state->noise.state << 1) + (b1 != b2 ? 1 : 0); } state->noise.pos -= 1; } } if (state->dma.on) { UINT8 sample; INT16 s; UINT16 addr = state->dma.start + (unsigned) state->dma.pos / 2; if (addr >= 0x8000 && addr < 0xc000) { sample = device->machine().root_device().memregion("user1")->base()[(addr & 0x3fff) | state->dma.ca14to16]; } else { sample = device->machine().device("maincpu")->memory().space(AS_PROGRAM).read_byte(addr); } if (((unsigned)state->dma.pos) & 1) s = (sample & 0xf); else s = (sample & 0xf0) >> 4; s <<= 8; if (state->dma.left) *left += s; if (state->dma.right) *right += s; state->dma.pos += state->dma.step; if (state->dma.pos >= state->dma.size) { state->dma.finished = TRUE; state->dma.on = FALSE; svision_irq(device->machine()); } }
static void svision_update (void *param,stream_sample_t **inputs, stream_sample_t **_buffer,int length) { stream_sample_t *left=_buffer[0], *right=_buffer[1]; int i, j; SVISION_CHANNEL *channel; for (i = 0; i < length; i++, left++, right++) { *left = 0; *right = 0; for (channel=svision_channel, j=0; j<ARRAY_LENGTH(svision_channel); j++, channel++) { if (channel->size != 0) { if (channel->on||channel->count) { bool on = FALSE; switch (channel->waveform) { case 0: on = channel->pos <= (28 * channel->size) >> 5; break; case 1: on = channel->pos <= (24 * channel->size) >> 5; break; default: case 2: on = channel->pos <= channel->size / 2; break; case 3: on = channel->pos <= (9 * channel->size) >> 5; break; } { INT16 s = on ? channel->volume << 8 : 0; if (j == 0) *right += s; else *left += s; } } channel->pos++; if (channel->pos >= channel->size) channel->pos = 0; } } if (svision_noise.on && (svision_noise.play || svision_noise.count)) { INT16 s = (svision_noise.value ? 1 << 8: 0) * svision_noise.volume; bool b1, b2; if (svision_noise.left) *left += s; if (svision_noise.right) *right += s; svision_noise.pos += svision_noise.step; if (svision_noise.pos >= 1.0) { switch (svision_noise.type) { case SVISION_NOISE_Type7Bit: svision_noise.value = svision_noise.state & 0x40 ? 1 : 0; b1 = (svision_noise.state & 0x40) != 0; b2 = (svision_noise.state & 0x20) != 0; svision_noise.state=(svision_noise.state<<1)+(b1!=b2?1:0); break; case SVISION_NOISE_Type14Bit: default: svision_noise.value = svision_noise.state & 0x2000 ? 1 : 0; b1 = (svision_noise.state & 0x2000) != 0; b2 = (svision_noise.state & 0x1000) != 0; svision_noise.state = (svision_noise.state << 1) + (b1 != b2 ? 1 : 0); } svision_noise.pos -= 1; } } if (svision_dma.on) { UINT8 sample; INT16 s; UINT16 addr = svision_dma.start + (unsigned) svision_dma.pos / 2; if (addr >= 0x8000 && addr < 0xc000) { sample = memory_region(REGION_USER1)[(addr & 0x3fff) | svision_dma.ca14to16]; } else { sample = program_read_byte(addr); } if (((unsigned)svision_dma.pos) & 1) s = (sample & 0xf); else s = (sample & 0xf0) >> 4; s <<= 8; if (svision_dma.left) *left += s; if (svision_dma.right) *right += s; svision_dma.pos += svision_dma.step; if (svision_dma.pos >= svision_dma.size) { svision_dma.finished = TRUE; svision_dma.on = FALSE; svision_irq(); } }
static void svision_timer(int param) { svision.timer_shot = TRUE; timer_enable(svision.timer1, FALSE); svision_irq(); }