Example #1
0
static void pssj_write(uint16_t port, uint8_t val, void *p)
{
        pssj_t *pssj = (pssj_t *)p;
        
        switch (port & 3)
        {
                case 0:
                pssj->ctrl = val;
                pssj->enable = (val & 4) && (pssj->ctrl & 3);
                sn74689_set_extra_divide(&pssj->sn76489, val & 0x40);
                if (!(val & 8))
                        pssj->irq = 0;
                pssj_update_irq(pssj);
                break;
                case 1:
                switch (pssj->ctrl & 3)
                {
                        case 1: /*Sound channel*/
                        pssj->wave = val;
                        pssj->pulse_width = val & 7;
                        break;
                        case 3: /*Direct DAC*/
                        pssj->dac_val = val;
                        break;
                }
                break;
                case 2:
                pssj->freq = (pssj->freq & 0xf00) | val;
                break;
                case 3:
                pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8);
                pssj->amplitude = val >> 4;
                break;
        }       
}
Example #2
0
static void pssj_callback(void *p)
{
        pssj_t *pssj = (pssj_t *)p;
        int data;
        
        pssj_update(pssj);
        if (pssj->ctrl & 2)
        {
                if ((pssj->ctrl & 3) == 3)
                {
                        data = dma_channel_read(1);

                        if (data != DMA_NODATA)
                        {
                                pssj->dac_val = data & 0xff;
//                                pclog("DAC_val=%02x\n", data);
                        }
                }
                else
                {
                        data = dma_channel_write(1, 0x80);
                }

                if ((data & DMA_OVER) && data != DMA_NODATA)
                {
//                        pclog("Check IRQ %i %02x\n", pssj->irq, pssj->ctrl);
                        if (pssj->ctrl & 0x08)
                        {
                                pssj->irq = 1;
                                pssj_update_irq(pssj);
                        }
                } 
        }
        else
        {
                switch (pssj->wave & 0xc0)
                {
                        case 0x00: /*Pulse*/
                        pssj->dac_val = (pssj->wave_pos > (pssj->pulse_width << 1)) ? 0xff : 0;
                        break;
                        case 0x40: /*Ramp*/
                        pssj->dac_val = pssj->wave_pos << 3;
                        break;
                        case 0x80: /*Triangle*/
                        if (pssj->wave_pos & 16)
                                pssj->dac_val = (pssj->wave_pos ^ 31) << 4;
                        else
                                pssj->dac_val = pssj->wave_pos << 4;
                        break;
                        case 0xc0:
                        pssj->dac_val = 0x80;
                        break;
                }
                pssj->wave_pos = (pssj->wave_pos + 1) & 31;
        }

        pssj->timer_count += (int)(TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400));
}