mirror of
https://github.com/alsa-project/alsa-tools.git
synced 2025-11-25 06:59:53 -05:00
Add ld10k1 tool
Added ld10k1 tool by Peter Zubaj.
This commit is contained in:
parent
37104ebf62
commit
2df1aa7c20
98 changed files with 19970 additions and 1 deletions
541
ld10k1/src/ld10k1_driver.c
Normal file
541
ld10k1/src/ld10k1_driver.c
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
* EMU10k1 loader
|
||||
*
|
||||
* Copyright (c) 2003,2004 by Peter Zubaj
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <alsa/sound/emu10k1.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "bitops.h"
|
||||
#include "ld10k1.h"
|
||||
#include "ld10k1_driver.h"
|
||||
#include "ld10k1_error.h"
|
||||
#include "ld10k1_fnc.h"
|
||||
#include "ld10k1_fnc_int.h"
|
||||
|
||||
//#define DEBUG_DRIVER 1
|
||||
|
||||
extern snd_hwdep_t *handle;
|
||||
|
||||
void ld10k1_syntetize_instr(int audigy, int op, int arg1, int arg2, int arg3, int arg4, unsigned int *out)
|
||||
{
|
||||
if (audigy) {
|
||||
*out = ((arg3 & 0x7ff) << 12) | (arg4 & 0x7ff);
|
||||
*(out + 1) = ((op & 0x0f) << 24) | ((arg1 & 0x7ff) << 12) | (arg2 & 0x7ff);
|
||||
} else {
|
||||
*out = ((arg3 & 0x3ff) << 10) | (arg4 & 0x3ff);
|
||||
*(out + 1) = ((op & 0x0f) << 20) | ((arg1 & 0x3ff) << 10) | (arg2 & 0x3ff);
|
||||
}
|
||||
}
|
||||
|
||||
void ld10k1_init_must_init_output(ld10k1_dsp_mgr_t *dsp_mgr);
|
||||
void ld10k1_set_must_init_output(ld10k1_dsp_mgr_t *dsp_mgr, int reg);
|
||||
void ld10k1_check_must_init_output(ld10k1_dsp_mgr_t *dsp_mgr, emu10k1_fx8010_code_t *code);
|
||||
|
||||
/* outputs what must be initialized on audigy */
|
||||
static int audigy_must_init_output[] = {
|
||||
0x68, 0,
|
||||
0x69, 0,
|
||||
0x6a, 0,
|
||||
0x6b, 0,
|
||||
0x6e, 0,
|
||||
0x6f, 0,
|
||||
-1};
|
||||
|
||||
#define LD10K1_SIGNATURE "LD10K1 ver. " VERSION " managed DSP code"
|
||||
|
||||
void ld10k1_free_code_struct(emu10k1_fx8010_code_t *code)
|
||||
{
|
||||
if (code->gpr_map)
|
||||
free(code->gpr_map);
|
||||
if (code->tram_data_map)
|
||||
free(code->tram_data_map);
|
||||
if (code->tram_addr_map)
|
||||
free(code->tram_addr_map);
|
||||
if (code->code)
|
||||
free(code->code);
|
||||
}
|
||||
|
||||
int ld10k1_alloc_code_struct(emu10k1_fx8010_code_t *code)
|
||||
{
|
||||
/* alloc code structure */
|
||||
code->gpr_map = NULL;
|
||||
code->tram_data_map = NULL;
|
||||
code->tram_addr_map = NULL;
|
||||
code->code = NULL;
|
||||
|
||||
code->gpr_map = (uint32_t *)malloc(sizeof(uint32_t) * 0x200);
|
||||
if (!code->gpr_map)
|
||||
goto err;
|
||||
memset(code->gpr_map, 0, sizeof(uint32_t) * 0x200);
|
||||
|
||||
code->tram_data_map = (uint32_t *)malloc(sizeof(uint32_t) * 0x100);
|
||||
if (!code->tram_data_map)
|
||||
goto err;
|
||||
memset(code->tram_data_map, 0, sizeof(uint32_t) * 0x100);
|
||||
|
||||
code->tram_addr_map = (uint32_t *)malloc(sizeof(uint32_t) * 0x100);
|
||||
if (!code->tram_addr_map)
|
||||
goto err;
|
||||
memset(code->tram_addr_map, 0, sizeof(uint32_t) * 0x100);
|
||||
|
||||
code->code = (uint32_t *)malloc(sizeof(uint32_t) * 1024 * 2);
|
||||
if (!code->code)
|
||||
goto err;
|
||||
memset(code->code, 0, sizeof(uint32_t) * 1024 * 2);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
ld10k1_free_code_struct(code);
|
||||
return LD10K1_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
int ld10k1_update_driver(ld10k1_dsp_mgr_t *dsp_mgr)
|
||||
{
|
||||
emu10k1_fx8010_code_t code;
|
||||
emu10k1_fx8010_control_gpr_t *add_ctrl;
|
||||
emu10k1_ctl_elem_id_t *del_ids;
|
||||
|
||||
ld10k1_ctl_list_item_t *item;
|
||||
unsigned int i, j;
|
||||
int max;
|
||||
int modified;
|
||||
unsigned int addr;
|
||||
unsigned int vaddr;
|
||||
unsigned int op;
|
||||
unsigned int idx_offset;
|
||||
unsigned int *iptr;
|
||||
ld10k1_ctl_t gctl;
|
||||
|
||||
int err;
|
||||
|
||||
if ((err = ld10k1_alloc_code_struct(&code)) < 0)
|
||||
return err;
|
||||
|
||||
/* new name */
|
||||
strcpy(code.name, LD10K1_SIGNATURE);
|
||||
|
||||
for (i = 0; i < sizeof(code.gpr_valid) / sizeof(unsigned long); i++)
|
||||
code.gpr_valid[i] = 0;
|
||||
for (i = 0; i < sizeof(code.tram_valid) / sizeof(unsigned long); i++)
|
||||
code.tram_valid[i] = 0;
|
||||
for (i = 0; i < sizeof(code.code_valid) / sizeof(unsigned long); i++)
|
||||
code.code_valid[i] = 0;
|
||||
|
||||
/* registers */
|
||||
for (i = 0; i < dsp_mgr->regs_max_count; i++)
|
||||
if (dsp_mgr->regs[i].modified) {
|
||||
set_bit(i, code.gpr_valid);
|
||||
code.gpr_map[i] = dsp_mgr->regs[i].val;
|
||||
}
|
||||
|
||||
/* tram addr + data */
|
||||
for (j = 0; j < 2; j++) {
|
||||
max = (j == 0 ? dsp_mgr->max_itram_hwacc : dsp_mgr->max_etram_hwacc);
|
||||
for (i = 0; i < max; i++) {
|
||||
modified = (j == 0 ? dsp_mgr->itram_hwacc[i].modified : dsp_mgr->etram_hwacc[i].modified);
|
||||
if (modified) {
|
||||
addr = (j == 0 ? dsp_mgr->itram_hwacc[i].addr_val : dsp_mgr->etram_hwacc[i].addr_val);
|
||||
vaddr = addr & 0xFFFFF;
|
||||
idx_offset = (j == 0 ? 0 : dsp_mgr->max_itram_hwacc);
|
||||
op = (j == 0 ? dsp_mgr->itram_hwacc[i].op : dsp_mgr->etram_hwacc[i].op);
|
||||
|
||||
set_bit(i + idx_offset, code.tram_valid);
|
||||
switch(op) {
|
||||
case TRAM_OP_READ:
|
||||
if (dsp_mgr->audigy)
|
||||
vaddr = vaddr | 0x2 << 20;
|
||||
else
|
||||
vaddr = vaddr | TANKMEMADDRREG_READ | TANKMEMADDRREG_ALIGN;
|
||||
break;
|
||||
case TRAM_OP_WRITE:
|
||||
if (dsp_mgr->audigy)
|
||||
vaddr = vaddr | 0x6 << 20;
|
||||
else
|
||||
vaddr = vaddr | TANKMEMADDRREG_WRITE | TANKMEMADDRREG_ALIGN;
|
||||
break;
|
||||
case TRAM_OP_NULL:
|
||||
default:
|
||||
vaddr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
code.tram_addr_map[i + idx_offset] = vaddr;
|
||||
code.tram_data_map[i + idx_offset] = (j == 0 ? dsp_mgr->itram_hwacc[i].data_val : dsp_mgr->etram_hwacc[i].data_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* controls to add */
|
||||
if (dsp_mgr->add_list_count > 0) {
|
||||
add_ctrl = (emu10k1_fx8010_control_gpr_t *)malloc(sizeof(emu10k1_fx8010_control_gpr_t) * dsp_mgr->add_list_count);
|
||||
memset(add_ctrl, 0, sizeof(emu10k1_fx8010_control_gpr_t) * dsp_mgr->add_list_count);
|
||||
for (i = 0, item = dsp_mgr->add_ctl_list; item != NULL; item = item->next, i++) {
|
||||
strcpy(add_ctrl[i].id.name, item->ctl.name);
|
||||
add_ctrl[i].id.iface = EMU10K1_CTL_ELEM_IFACE_MIXER;
|
||||
add_ctrl[i].id.index = item->ctl.index;
|
||||
add_ctrl[i].vcount = item->ctl.vcount;
|
||||
add_ctrl[i].count = item->ctl.count;
|
||||
for (j = 0; j < 32; j++) {
|
||||
add_ctrl[i].gpr[j] = item->ctl.gpr_idx[j];
|
||||
add_ctrl[i].value[j] = item->ctl.value[j];
|
||||
}
|
||||
add_ctrl[i].min = item->ctl.min;
|
||||
add_ctrl[i].max = item->ctl.max;
|
||||
add_ctrl[i].translation = item->ctl.translation;
|
||||
}
|
||||
} else
|
||||
add_ctrl = NULL;
|
||||
|
||||
code.gpr_add_control_count = dsp_mgr->add_list_count;
|
||||
code.gpr_add_controls = add_ctrl;
|
||||
|
||||
/* controls to del */
|
||||
if (dsp_mgr->del_list_count > 0) {
|
||||
del_ids = (emu10k1_ctl_elem_id_t *)malloc(sizeof(emu10k1_ctl_elem_id_t) * dsp_mgr->del_list_count);
|
||||
memset(del_ids, 0, sizeof(emu10k1_ctl_elem_id_t) * dsp_mgr->del_list_count);
|
||||
for (i = 0, item = dsp_mgr->del_ctl_list; item != NULL; item = item->next, i++) {
|
||||
strcpy(del_ids[i].name, item->ctl.name);
|
||||
del_ids[i].iface = EMU10K1_CTL_ELEM_IFACE_MIXER;
|
||||
del_ids[i].index = item->ctl.index;
|
||||
}
|
||||
} else
|
||||
del_ids = NULL;
|
||||
|
||||
code.gpr_del_control_count = dsp_mgr->del_list_count;
|
||||
code.gpr_del_controls = del_ids;
|
||||
|
||||
code.gpr_list_control_count = 0;
|
||||
|
||||
for (iptr = code.code, i = 0; i < dsp_mgr->instr_count; i++, iptr += 2) {
|
||||
if (dsp_mgr->instr[i].modified) {
|
||||
set_bit(i, code.code_valid);
|
||||
if (dsp_mgr->instr[i].used) {
|
||||
if (dsp_mgr->audigy) {
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
dsp_mgr->instr[i].op_code,
|
||||
dsp_mgr->instr[i].arg[0], dsp_mgr->instr[i].arg[1], dsp_mgr->instr[i].arg[2], dsp_mgr->instr[i].arg[3], iptr);
|
||||
} else {
|
||||
if (i < 0x200) {
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
dsp_mgr->instr[i].op_code,
|
||||
dsp_mgr->instr[i].arg[0], dsp_mgr->instr[i].arg[1], dsp_mgr->instr[i].arg[2], dsp_mgr->instr[i].arg[3], iptr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dsp_mgr->audigy) {
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
0x0f,
|
||||
0xc0, 0xc0, 0xcf, 0xc0, iptr);
|
||||
} else {
|
||||
if (i < 0x200) {
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
0x06,
|
||||
0x40, 0x40, 0x40, 0x40, iptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check initialization of i2s outputs on audigy */
|
||||
if (dsp_mgr->audigy)
|
||||
ld10k1_check_must_init_output(dsp_mgr, &code);
|
||||
|
||||
|
||||
#ifndef DEBUG_DRIVER
|
||||
if (snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_CODE_POKE, &code) < 0) {
|
||||
error("unable to poke code");
|
||||
ld10k1_free_code_struct(&code);
|
||||
if (add_ctrl)
|
||||
free(add_ctrl);
|
||||
if (del_ids)
|
||||
free(del_ids);
|
||||
return LD10K1_ERR_DRIVER_CODE_POKE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update state */
|
||||
for (item = dsp_mgr->del_ctl_list; item != NULL; item = item->next) {
|
||||
strcpy(gctl.name, item->ctl.name);
|
||||
ld10k1_del_control_from_list(&(dsp_mgr->ctl_list), &(dsp_mgr->ctl_list_count), &gctl);
|
||||
}
|
||||
|
||||
ld10k1_del_all_controls_from_list(&(dsp_mgr->del_ctl_list), &dsp_mgr->del_list_count);
|
||||
|
||||
for (item = dsp_mgr->add_ctl_list; item != NULL; item = item->next)
|
||||
ld10k1_add_control_to_list(&(dsp_mgr->ctl_list), &(dsp_mgr->ctl_list_count), &(item->ctl));
|
||||
|
||||
ld10k1_del_all_controls_from_list(&(dsp_mgr->add_ctl_list), &dsp_mgr->add_list_count);
|
||||
|
||||
for (i = 0; i < dsp_mgr->regs_max_count; i++)
|
||||
dsp_mgr->regs[i].modified = 0;
|
||||
|
||||
for (i = 0; i < dsp_mgr->instr_count; i++)
|
||||
dsp_mgr->instr[i].modified = 0;
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
max = (j == 0 ? dsp_mgr->max_itram_hwacc : dsp_mgr->max_etram_hwacc);
|
||||
for (i = 0; i < max; i++) {
|
||||
if (j == 0)
|
||||
dsp_mgr->itram_hwacc[i].modified = 0;
|
||||
else
|
||||
dsp_mgr->etram_hwacc[i].modified = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ld10k1_free_code_struct(&code);
|
||||
|
||||
if (add_ctrl)
|
||||
free(add_ctrl);
|
||||
if (del_ids)
|
||||
free(del_ids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ld10k1_init_driver(ld10k1_dsp_mgr_t *dsp_mgr, int tram_size)
|
||||
{
|
||||
emu10k1_fx8010_info_t info;
|
||||
int i;
|
||||
emu10k1_fx8010_code_t code;
|
||||
emu10k1_fx8010_control_gpr_t *ctrl;
|
||||
emu10k1_ctl_elem_id_t *ids;
|
||||
emu10k1_fx8010_pcm_t ipcm;
|
||||
|
||||
unsigned int *iptr;
|
||||
|
||||
int err;
|
||||
|
||||
if ((err = ld10k1_alloc_code_struct(&code)) < 0)
|
||||
return err;
|
||||
|
||||
/* setup tram size */
|
||||
if (tram_size >= 0 && snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_TRAM_SETUP, &tram_size) < 0) {
|
||||
error("unable to setup tram");
|
||||
if (dsp_mgr->audigy)
|
||||
error("You are probably user of audigy, audigy 2 and you not aplyed patch to enable tram");
|
||||
/* this is not fatal, but do not use tram */
|
||||
dsp_mgr->i_tram.size = 0;
|
||||
dsp_mgr->e_tram.size = 0;
|
||||
} else {
|
||||
if (snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_INFO, &info) < 0) {
|
||||
error("unable to get info ");
|
||||
ld10k1_free_code_struct(&code);
|
||||
return LD10K1_ERR_DRIVER_INFO;
|
||||
}
|
||||
|
||||
dsp_mgr->i_tram.size = info.internal_tram_size;
|
||||
dsp_mgr->e_tram.size = info.external_tram_size;
|
||||
}
|
||||
|
||||
/* get count of controls */
|
||||
code.gpr_list_control_count = 0;
|
||||
if (snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_CODE_PEEK, &code) < 0) {
|
||||
error("unable to peek code");
|
||||
ld10k1_free_code_struct(&code);
|
||||
return LD10K1_ERR_DRIVER_CODE_PEEK;
|
||||
}
|
||||
|
||||
ctrl = (emu10k1_fx8010_control_gpr_t *)malloc(sizeof(emu10k1_fx8010_control_gpr_t) * code.gpr_list_control_total);
|
||||
if (!ctrl) {
|
||||
ld10k1_free_code_struct(&code);
|
||||
return LD10K1_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
code.gpr_list_control_count = code.gpr_list_control_total;
|
||||
code.gpr_list_controls = ctrl;
|
||||
|
||||
for (i = 0; i < sizeof(code.gpr_valid) / sizeof(unsigned long); i++)
|
||||
code.gpr_valid[i] = 0x0;
|
||||
for (i = 0; i < sizeof(code.tram_valid) / sizeof(unsigned long); i++)
|
||||
code.tram_valid[i] = 0x0;
|
||||
for (i = 0; i < sizeof(code.code_valid) / sizeof(unsigned long); i++)
|
||||
code.code_valid[i] = 0x0;;
|
||||
|
||||
if (snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_CODE_PEEK, &code) < 0) {
|
||||
error("unable to peek code");
|
||||
ld10k1_free_code_struct(&code);
|
||||
free(ctrl);
|
||||
return LD10K1_ERR_DRIVER_CODE_PEEK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* new name */
|
||||
strcpy(code.name, LD10K1_SIGNATURE);
|
||||
for (i = 0; i < sizeof(code.gpr_valid) / sizeof(unsigned long); i++)
|
||||
code.gpr_valid[i] = ~0;
|
||||
|
||||
for (i = 0; i < sizeof(code.gpr_valid) * 8; i++) {
|
||||
code.gpr_map[i] = 0;
|
||||
}
|
||||
|
||||
ids = (emu10k1_ctl_elem_id_t *)malloc(sizeof(emu10k1_ctl_elem_id_t) * code.gpr_list_control_total);
|
||||
if (!ids) {
|
||||
ld10k1_free_code_struct(&code);
|
||||
free(ctrl);
|
||||
return LD10K1_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
code.gpr_del_control_count = code.gpr_list_control_total;
|
||||
if (code.gpr_del_control_count) {
|
||||
for (i = 0; i < code.gpr_del_control_count; i++) {
|
||||
memcpy(&(ids[i]), &(ctrl[i].id), sizeof(emu10k1_ctl_elem_id_t));
|
||||
}
|
||||
}
|
||||
|
||||
free(ctrl);
|
||||
|
||||
code.gpr_del_controls = ids;
|
||||
code.gpr_list_control_count = 0;
|
||||
code.gpr_add_control_count = 0;
|
||||
code.gpr_list_control_count = 0;
|
||||
|
||||
for (i = 0; i < sizeof(code.tram_valid) / sizeof(unsigned long); i++)
|
||||
code.tram_valid[i] = ~0;
|
||||
for (i = 0; i < sizeof(code.code_valid) / sizeof(unsigned long); i++)
|
||||
code.code_valid[i] = ~0;
|
||||
|
||||
for (i = 0; i < sizeof(code.tram_valid) * 8; i++) {
|
||||
code.tram_addr_map[i] = 0;
|
||||
code.tram_data_map[i] = 0;
|
||||
}
|
||||
|
||||
for (iptr = code.code, i = 0; i < sizeof(code.code_valid) * 8; i++, iptr += 2)
|
||||
if (dsp_mgr->audigy) {
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
0x0f,
|
||||
0xc0, 0xc0, 0xcf, 0xc0, iptr);
|
||||
} else {
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
0x06,
|
||||
0x40, 0x40, 0x40, 0x40, iptr);
|
||||
}
|
||||
|
||||
/* initialize i2s outputs on audigy */
|
||||
if (dsp_mgr->audigy) {
|
||||
for (iptr = code.code, i = 0; audigy_must_init_output[i] > 0; i += 2, iptr += 2)
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy, 0x00,
|
||||
audigy_must_init_output[i], 0xc0, 0xc0, 0xc0, iptr);
|
||||
}
|
||||
|
||||
#ifndef DEBUG_DRIVER
|
||||
if (snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_CODE_POKE, &code) < 0) {
|
||||
error("unable to poke code");
|
||||
ld10k1_free_code_struct(&code);
|
||||
free(ids);
|
||||
return LD10K1_ERR_DRIVER_CODE_POKE;
|
||||
}
|
||||
#endif
|
||||
|
||||
free(ids);
|
||||
|
||||
/* delete tram pcm dsp part */
|
||||
if (!dsp_mgr->audigy) {
|
||||
for (i = 0; i < EMU10K1_FX8010_PCM_COUNT; i++) {
|
||||
ipcm.substream = i;
|
||||
ipcm.channels = 0;
|
||||
#ifndef DEBUG_DRIVER
|
||||
if (snd_hwdep_ioctl(handle, SNDRV_EMU10K1_IOCTL_PCM_POKE, &ipcm) < 0) {
|
||||
error("unable to poke code");
|
||||
ld10k1_free_code_struct(&code);
|
||||
return LD10K1_ERR_DRIVER_PCM_POKE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ld10k1_free_code_struct(&code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ld10k1_init_must_init_output(ld10k1_dsp_mgr_t *dsp_mgr)
|
||||
{
|
||||
int i;
|
||||
if (dsp_mgr->audigy) {
|
||||
for (i = 0; audigy_must_init_output[i] > 0; i += 2)
|
||||
audigy_must_init_output[i + 1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ld10k1_set_must_init_output(ld10k1_dsp_mgr_t *dsp_mgr, int reg)
|
||||
{
|
||||
int i ;
|
||||
if (dsp_mgr->audigy) {
|
||||
for (i = 0; audigy_must_init_output[i] > 0; i += 2) {
|
||||
if (audigy_must_init_output[i] == reg) {
|
||||
audigy_must_init_output[i + 1] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ld10k1_check_must_init_output(ld10k1_dsp_mgr_t *dsp_mgr, emu10k1_fx8010_code_t *code)
|
||||
{
|
||||
int j;
|
||||
|
||||
ld10k1_init_must_init_output(dsp_mgr);
|
||||
for (j = 0; j < dsp_mgr->instr_count; j++) {
|
||||
if (dsp_mgr->instr[j].used)
|
||||
ld10k1_set_must_init_output(dsp_mgr, dsp_mgr->instr[j].arg[0]);
|
||||
}
|
||||
|
||||
int i;
|
||||
int l;
|
||||
int ioffset = dsp_mgr->instr_count - 1;
|
||||
if (dsp_mgr->audigy) {
|
||||
for (i = 0; audigy_must_init_output[i] > 0; i += 2) {
|
||||
if (audigy_must_init_output[i + 1]) {
|
||||
/* find free instruction slot */
|
||||
for (;ioffset >= 0; ioffset--) {
|
||||
if (!dsp_mgr->instr[ioffset].used) {
|
||||
ld10k1_instr_t *instr = &(dsp_mgr->instr[ioffset]);
|
||||
ld10k1_syntetize_instr(dsp_mgr->audigy,
|
||||
0x0,
|
||||
audigy_must_init_output[i], 0xc0, 0xc0, 0xc0,
|
||||
code->code + ioffset * 2);
|
||||
instr->op_code = 0;
|
||||
instr->arg[0] = audigy_must_init_output[i];
|
||||
for (l = 1; l < 4; l++)
|
||||
instr->arg[l] = 0xc0;
|
||||
set_bit(ioffset, code->code_valid);
|
||||
dsp_mgr->instr[ioffset].used = 1;
|
||||
ioffset--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ioffset < 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue