diff --git a/src/ibm.h b/src/ibm.h index b36c7b070..d4b119f17 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -222,7 +222,7 @@ extern int cpl_override; /*Timer*/ typedef struct PIT { - uint32_t l[3]; + uint64_t l[3]; int64_t c[3]; uint8_t m[3]; uint8_t ctrl,ctrls[3]; diff --git a/src/sound_ad1848.h b/src/sound_ad1848.h index b8d540aa7..1647409b7 100644 --- a/src/sound_ad1848.h +++ b/src/sound_ad1848.h @@ -22,7 +22,7 @@ typedef struct ad1848_t int freq; - int timer_count, timer_latch; + int64_t timer_count, timer_latch; int16_t buffer[SOUNDBUFLEN * 2]; int pos; diff --git a/src/sound_pas16.c b/src/sound_pas16.c index 911ace2a2..d9c6123e7 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -1,4 +1,4 @@ -/* Copyright holders: Sarah Walker +/* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ #include @@ -12,6 +12,7 @@ #include "pic.h" #include "pit.h" #include "sound.h" +#include "sound_mpu401_uart.h" #include "sound_opl.h" #include "sound_pas16.h" #include "sound_sb_dsp.h" @@ -121,7 +122,7 @@ typedef struct pas16_t struct { - uint32_t l[3]; + uint64_t l[3]; int64_t c[3]; uint8_t m[3]; uint8_t ctrl, ctrls[2]; @@ -134,6 +135,7 @@ typedef struct pas16_t } pit; opl_t opl; + mpu401_uart_t mpu; sb_dsp_t dsp; int16_t pcm_buffer[2][SOUNDBUFLEN]; @@ -145,8 +147,7 @@ static uint8_t pas16_pit_in(uint16_t port, void *priv); static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); static void pas16_update(pas16_t *pas16); -static int pas16_dmas[8] = {4, 1, 2, 3, 0, 5, 6, 7}; -static int pas16_irqs[16] = {0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0}; +static int pas16_dma = 0, pas16_irq = 0; static int pas16_sb_irqs[8] = {0, 2, 3, 5, 7, 10, 11, 12}; static int pas16_sb_dmas[8] = {0, 1, 2, 3}; @@ -177,12 +178,11 @@ static uint8_t pas16_in(uint16_t port, void *p) { pas16_t *pas16 = (pas16_t *)p; uint8_t temp; -/* if (CS == 0xCA53 && pc == 0x3AFC) - fatal("here");*/ - switch ((port - pas16->base) + 0x388) + + switch (port) { case 0x388: case 0x389: case 0x38a: case 0x38b: - temp = opl3_read((port - pas16->base) + 0x388, &pas16->opl); + temp = opl3_read(port, &pas16->opl); break; case 0xb88: @@ -210,7 +210,7 @@ static uint8_t pas16_in(uint16_t port, void *p) break; case 0x2789: /*Board revision*/ - temp = 0; + temp = 1; break; case 0x7f89: @@ -259,32 +259,23 @@ static uint8_t pas16_in(uint16_t port, void *p) break; case 0xff88: /*Board model*/ - temp = 4; /*PAS16*/ + temp = 3; /*PAS16*/ break; case 0xff8b: /*Master mode read*/ temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ break; } -/* if (port != 0x388 && port != 0x389 && port != 0xb8b) */pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS,cpu_state.pc); -/* if (CS == 0x1FF4 && pc == 0x0585) - { - if (output) - fatal("here"); - output = 3; - }*/ return temp; } static void pas16_out(uint16_t port, uint8_t val, void *p) { pas16_t *pas16 = (pas16_t *)p; -/* if (port != 0x388 && port != 0x389) */pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); -/* if (CS == 0x369 && pc == 0x2AC5) - fatal("here\n");*/ - switch ((port - pas16->base) + 0x388) + pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); + switch (port) { case 0x388: case 0x389: case 0x38a: case 0x38b: - opl3_write((port - pas16->base) + 0x388, val, &pas16->opl); + opl3_write(port, val, &pas16->opl); break; case 0xb88: @@ -292,8 +283,8 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) break; case 0xb89: + pas16_update(pas16); pas16->irq_stat &= ~val; -// pas16_update_irqs(); break; case 0xb8a: @@ -303,7 +294,6 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) case 0xb8b: pas16->irq_ena = val; -// pas16_update_irqs(); break; case 0xf88: @@ -315,8 +305,6 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); break; case 0xf8a: - if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ - pas16->stereo_lr = 0; pas16->pcm_ctrl = val; break; @@ -346,13 +334,11 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) break; case 0xf389: pas16->io_conf_2 = val; - pas16->dma = pas16_dmas[val & 0x7]; - pclog("pas16_out : set PAS DMA %i\n", pas16->dma); + pas16->dma = pas16_dma; break; case 0xf38a: pas16->io_conf_3 = val; - pas16->irq = pas16_irqs[val & 0xf]; - pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); + pas16->irq = pas16_irq; break; case 0xf38b: pas16->io_conf_4 = val; @@ -375,20 +361,18 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) pas16->sb_irqdma = val; sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pclog("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + pclog("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); break; + case 0x9a01: + pas16->base = val << 2; + pclog("pas16_out : PAS16 base now at %04X\n", pas16->base); + break; + default: pclog("pas16_out : unknown %04X\n", port); + break; } - if (cpu_state.pc == 0x80048CF3) - { - if (output) - fatal("here\n"); - output = 3; - } -/* if (CS == 0x1FF4 && pc == 0x0431) - output = 3;*/ } static void pas16_pit_out(uint16_t port, uint8_t val, void *p) @@ -496,7 +480,7 @@ static uint8_t pas16_pit_in(uint16_t port, void *p) pas16_t *pas16 = (pas16_t *)p; uint8_t temp; int t = port & 3; -// printf("Read PIT %04X ",addr); + printf("Read PIT %04X ",port); switch (port & 3) { case 0: case 1: case 2: /*Timers*/ @@ -639,54 +623,58 @@ static void pas16_pcm_poll(void *p) pclog("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); picint(1 << pas16->irq); } + else + picintc(1 << pas16->irq); } } } -static void pas16_out_base(uint16_t port, uint8_t val, void *p) +static void pas16_io_remove(pas16_t *pas16) { - pas16_t *pas16 = (pas16_t *)p; + io_removehandler(0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler(0x9a01, 0x0004, NULL, NULL, NULL, pas16_out, NULL, NULL, pas16); +} - io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - - pas16->base = val << 2; - pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); - - io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); +static void pas16_io_set(pas16_t *pas16) +{ + pas16_io_remove(pas16); + + io_sethandler(0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(0x9a01, 0x0004, NULL, NULL, NULL, pas16_out, NULL, NULL, pas16); } @@ -718,6 +706,7 @@ void pas16_get_buffer(int32_t *buffer, int len, void *p) opl3_update2(&pas16->opl); sb_dsp_update(&pas16->dsp); pas16_update(pas16); + for (c = 0; c < len * 2; c++) { buffer[c] += pas16->opl.buffer[c]; @@ -737,12 +726,16 @@ void *pas16_init() opl3_init(&pas16->opl); sb_dsp_init(&pas16->dsp, SB2); - - io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); + + pas16_irq = device_get_config_int("irq"); + pas16_dma = device_get_config_int("dma"); + + pas16_io_set(pas16); timer_add(pas16_pcm_poll, &pas16->pit.c[0], &pas16->pit.enable[0], pas16); sound_add_handler(pas16_get_buffer, pas16); + mpu401_uart_init(&pas16->mpu, 0x330); return pas16; } @@ -754,14 +747,94 @@ void pas16_close(void *p) free(pas16); } +static device_config_t pas16_config[] = +{ + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 5 + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { + .description = "DMA 5", + .value = 5 + }, + { + .description = "DMA 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 1 + }, + { + .type = -1 + } +}; + device_t pas16_device = { "Pro Audio Spectrum 16", - DEVICE_NOT_WORKING, + 0, pas16_init, pas16_close, NULL, NULL, NULL, - NULL + NULL, + pas16_config };