⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sb16.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */            break;        case 0x48:            s->needed_bytes = 2;            break;        case 0x74:            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */            dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");            break;        case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */            s->needed_bytes = 2;            dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");            break;        case 0x76:              /* DMA DAC, 2.6-bit ADPCM */            s->needed_bytes = 2;            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");            break;        case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */            s->needed_bytes = 2;            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");            break;        case 0x7d:            dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");            dolog ("not implemented\n");            break;        case 0x7f:            dolog (                "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"                );            dolog ("not implemented\n");            break;        case 0x80:            s->needed_bytes = 2;            break;        case 0x90:        case 0x91:            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);            break;        case 0xd0:              /* halt DMA operation. 8bit */            control (s, 0);            break;        case 0xd1:              /* speaker on */            speaker (s, 1);            break;        case 0xd3:              /* speaker off */            speaker (s, 0);            break;        case 0xd4:              /* continue DMA operation. 8bit */            control (s, 1);            break;        case 0xd5:              /* halt DMA operation. 16bit */            control (s, 0);            break;        case 0xd6:              /* continue DMA operation. 16bit */            control (s, 1);            break;        case 0xd9:              /* exit auto-init DMA after this block. 16bit */            s->dma_auto = 0;            break;        case 0xda:              /* exit auto-init DMA after this block. 8bit */            s->dma_auto = 0;            break;        case 0xe0:              /* DSP identification */            s->needed_bytes = 1;            break;        case 0xe1:            dsp_out_data (s, s->ver & 0xff);            dsp_out_data (s, s->ver >> 8);            break;        case 0xe2:            s->needed_bytes = 1;            goto warn;        case 0xe3:            {                int i;                for (i = sizeof (e3) - 1; i >= 0; --i)                    dsp_out_data (s, e3[i]);            }            break;        case 0xe4:              /* write test reg */            s->needed_bytes = 1;            break;        case 0xe7:            dolog ("Attempt to probe for ESS (0xe7)?\n");            break;        case 0xe8:              /* read test reg */            dsp_out_data (s, s->test_reg);            break;        case 0xf2:        case 0xf3:            dsp_out_data (s, 0xaa);            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;            pic_set_irq (s->irq, 1);            break;        case 0xf9:            s->needed_bytes = 1;            goto warn;        case 0xfa:            dsp_out_data (s, 0);            goto warn;        case 0xfc:              /* FIXME */            dsp_out_data (s, 0);            goto warn;        default:            dolog ("Unrecognized command %#x\n", cmd);            break;        }    }    if (!s->needed_bytes) {        ldebug ("\n");    } exit:    if (!s->needed_bytes) {        s->cmd = -1;    }    else {        s->cmd = cmd;    }    return; warn:    dolog ("warning: command %#x,%d is not truly understood yet\n",           cmd, s->needed_bytes);    goto exit;}static uint16_t dsp_get_lohi (SB16State *s){    uint8_t hi = dsp_get_data (s);    uint8_t lo = dsp_get_data (s);    return (hi << 8) | lo;}static uint16_t dsp_get_hilo (SB16State *s){    uint8_t lo = dsp_get_data (s);    uint8_t hi = dsp_get_data (s);    return (hi << 8) | lo;}static void complete (SB16State *s){    int d0, d1, d2;    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",            s->cmd, s->in_index, s->needed_bytes);    if (s->cmd > 0xaf && s->cmd < 0xd0) {        d2 = dsp_get_data (s);        d1 = dsp_get_data (s);        d0 = dsp_get_data (s);        if (s->cmd & 8) {            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",                   s->cmd, d0, d1, d2);        }        else {            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",                    s->cmd, d0, d1, d2);            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));        }    }    else {        switch (s->cmd) {        case 0x04:            s->csp_mode = dsp_get_data (s);            s->csp_reg83r = 0;            s->csp_reg83w = 0;            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);            break;        case 0x05:            s->csp_param = dsp_get_data (s);            s->csp_value = dsp_get_data (s);            ldebug ("CSP command 0x05: param=%#x value=%#x\n",                    s->csp_param,                    s->csp_value);            break;        case 0x0e:            d0 = dsp_get_data (s);            d1 = dsp_get_data (s);            ldebug ("write CSP register %d <- %#x\n", d1, d0);            if (d1 == 0x83) {                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);                s->csp_reg83[s->csp_reg83r % 4] = d0;                s->csp_reg83r += 1;            }            else {                s->csp_regs[d1] = d0;            }            break;        case 0x0f:            d0 = dsp_get_data (s);            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",                    d0, s->csp_regs[d0], s->csp_mode);            if (d0 == 0x83) {                ldebug ("0x83[%d] -> %#x\n",                        s->csp_reg83w,                        s->csp_reg83[s->csp_reg83w % 4]);                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);                s->csp_reg83w += 1;            }            else {                dsp_out_data (s, s->csp_regs[d0]);            }            break;        case 0x10:            d0 = dsp_get_data (s);            dolog ("cmd 0x10 d0=%#x\n", d0);            break;        case 0x14:            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);            break;        case 0x40:            s->time_const = dsp_get_data (s);            ldebug ("set time const %d\n", s->time_const);            break;        case 0x42:              /* FT2 sets output freq with this, go figure */#if 0            dolog ("cmd 0x42 might not do what it think it should\n");#endif        case 0x41:            s->freq = dsp_get_hilo (s);            ldebug ("set freq %d\n", s->freq);            break;        case 0x48:            s->block_size = dsp_get_lohi (s) + 1;            ldebug ("set dma block len %d\n", s->block_size);            break;        case 0x74:        case 0x75:        case 0x76:        case 0x77:            /* ADPCM stuff, ignore */            break;        case 0x80:            {                int freq, samples, bytes;                int64_t ticks;                freq = s->freq > 0 ? s->freq : 11025;                samples = dsp_get_lohi (s) + 1;                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);                ticks = (bytes * ticks_per_sec) / freq;                if (ticks < ticks_per_sec / 1024) {                    pic_set_irq (s->irq, 1);                }                else {                    if (s->aux_ts) {                        qemu_mod_timer (                            s->aux_ts,                            qemu_get_clock (vm_clock) + ticks                            );                    }                }                ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);            }            break;        case 0xe0:            d0 = dsp_get_data (s);            s->out_data_len = 0;            ldebug ("E0 data = %#x\n", d0);            dsp_out_data (s, ~d0);            break;        case 0xe2:            d0 = dsp_get_data (s);            ldebug ("E2 = %#x\n", d0);            break;        case 0xe4:            s->test_reg = dsp_get_data (s);            break;        case 0xf9:            d0 = dsp_get_data (s);            ldebug ("command 0xf9 with %#x\n", d0);            switch (d0) {            case 0x0e:                dsp_out_data (s, 0xff);                break;            case 0x0f:                dsp_out_data (s, 0x07);                break;            case 0x37:                dsp_out_data (s, 0x38);                break;            default:                dsp_out_data (s, 0x00);                break;            }            break;        default:            dolog ("complete: unrecognized command %#x\n", s->cmd);            return;        }    }    ldebug ("\n");    s->cmd = -1;    return;}static void reset (SB16State *s){    pic_set_irq (s->irq, 0);    if (s->dma_auto) {        pic_set_irq (s->irq, 1);        pic_set_irq (s->irq, 0);    }    s->mixer_regs[0x82] = 0;    s->dma_auto = 0;    s->in_index = 0;    s->out_data_len = 0;    s->left_till_irq = 0;    s->needed_bytes = 0;    s->block_size = -1;    s->nzero = 0;    s->highspeed = 0;    s->v2x6 = 0;    s->cmd = -1;    dsp_out_data(s, 0xaa);    speaker (s, 0);    control (s, 0);}static IO_WRITE_PROTO (dsp_write){    SB16State *s = opaque;    int iport;    iport = nport - s->port;    ldebug ("write %#x <- %#x\n", nport, val);    switch (iport) {    case 0x06:        switch (val) {        case 0x00:            if (s->v2x6 == 1) {                if (0 && s->highspeed) {                    s->highspeed = 0;                    pic_set_irq (s->irq, 0);                    control (s, 0);                }                else {                    reset (s);                }            }            s->v2x6 = 0;            break;        case 0x01:        case 0x03:              /* FreeBSD kludge */            s->v2x6 = 1;            break;        case 0xc6:            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */            break;        case 0xb8:              /* Panic */            reset (s);            break;        case 0x39:            dsp_out_data (s, 0x38);            reset (s);            s->v2x6 = 0x39;            break;        default:            s->v2x6 = val;            break;        }        break;    case 0x0c:                  /* write data or command | write status *//*         if (s->highspeed) *//*             break; */        if (0 == s->needed_bytes) {            command (s, val);#if 0            if (0 == s->needed_bytes) {                log_dsp (s);            }#endif        }        else {            if (s->in_index == sizeof (s->in2_data)) {                dolog ("in data overrun\n");            }            else {                s->in2_data[s->in_index++] = val;                if (s->in_index == s->needed_bytes) {                    s->needed_bytes = 0;                    complete (s);#if 0                    log_dsp (s);#endif                }            }        }        break;    default:        ldebug ("(nport=%#x, val=%#x)\n", nport, val);        break;    }}static IO_READ_PROTO (dsp_read){    SB16State *s = opaque;    int iport, retval, ack = 0;    iport = nport - s->port;    switch (iport) {    case 0x06:                  /* reset */        retval = 0xff;        break;    case 0x0a:                  /* read data */        if (s->out_data_len) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -