void write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct ai_controller* ai = (struct ai_controller*)opaque; uint32_t reg = ai_reg(address); switch (reg) { case AI_LEN_REG: masked_write(&ai->regs[AI_LEN_REG], value, mask); if (ai->regs[AI_LEN_REG] != 0) { fifo_push(ai); } else { /* stop sound */ } return; case AI_STATUS_REG: clear_rcp_interrupt(ai->mi, MI_INTR_AI); return; case AI_BITRATE_REG: case AI_DACRATE_REG: /* lazy audio format setting */ if ((ai->regs[reg]) != (value & mask)) ai->samples_format_changed = 1; masked_write(&ai->regs[reg], value, mask); return; } masked_write(&ai->regs[reg], value, mask); }
int write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct ai_controller* ai = (struct ai_controller*)opaque; uint32_t reg = ai_reg(address); unsigned int freq,delay=0; switch (reg) { case AI_LEN_REG: masked_write(&ai->regs[AI_LEN_REG], value, mask); audio.aiLenChanged(); freq = ROM_PARAMS.aidacrate / (ai->regs[AI_DACRATE_REG]+1); if (freq) delay = (unsigned int) (((unsigned long long)ai->regs[AI_LEN_REG]*ai->vi->delay*ROM_PARAMS.vilimit)/(freq*4)); if (ai->regs[AI_STATUS_REG] & 0x40000000) // busy { ai->fifo[1].delay = delay; ai->fifo[1].length = ai->regs[AI_LEN_REG]; ai->regs[AI_STATUS_REG] |= 0x80000000; } else { ai->fifo[0].delay = delay; ai->fifo[0].length = ai->regs[AI_LEN_REG]; update_count(); add_interupt_event(AI_INT, delay); ai->regs[AI_STATUS_REG] |= 0x40000000; } return 0; case AI_STATUS_REG: clear_rcp_interrupt(ai->r4300, MI_INTR_AI); return 0; case AI_DACRATE_REG: if ((ai->regs[AI_DACRATE_REG] & mask) != (value & mask)) { masked_write(&ai->regs[AI_DACRATE_REG], value, mask); audio.aiDacrateChanged(ROM_PARAMS.systemtype); } return 0; } masked_write(&ai->regs[reg], value, mask); return 0; }
void read_ai_regs(void* opaque, uint32_t address, uint32_t* value) { struct ai_controller* ai = (struct ai_controller*)opaque; uint32_t reg = ai_reg(address); if (reg == AI_LEN_REG) { *value = get_remaining_dma_length(ai); if (*value < ai->last_read) { unsigned int diff = ai->fifo[0].length - ai->last_read; unsigned char *p = (unsigned char*)&ai->ri->rdram->dram[ai->fifo[0].address/4]; ai->iaout->push_samples(ai->aout, p + diff, ai->last_read - *value); ai->last_read = *value; } } else { *value = ai->regs[reg]; } }
int read_ai_regs(void* opaque, uint32_t address, uint32_t* value) { struct ai_controller* ai = (struct ai_controller*)opaque; uint32_t reg = ai_reg(address); if (reg == AI_LEN_REG) { update_count(); if (ai->fifo[0].delay != 0 && get_event(AI_INT) != 0 && (get_event(AI_INT)-g_cp0_regs[CP0_COUNT_REG]) < 0x80000000) *value = ((get_event(AI_INT)-g_cp0_regs[CP0_COUNT_REG])*(long long)ai->fifo[0].length)/ ai->fifo[0].delay; else *value = 0; } else { *value = ai->regs[reg]; } return 0; }