Applied both mainline PCem commits;
Fixed the RTL8029AS again (one of my "fixes" broke it); RTL8029AS PCI register 4 is now written to; Added incomplete (and currently commented out) emulation of the AWE64 PCI; Replaced sector-based floppy emulation with more accurate code.
This commit is contained in:
249
src/sound_sb.c
249
src/sound_sb.c
@@ -1,6 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "pci.h"
|
||||
#include "sound_emu8k.h"
|
||||
#include "sound_mpu401_uart.h"
|
||||
#include "sound_opl.h"
|
||||
@@ -520,6 +522,175 @@ void *sb_awe32_init()
|
||||
return sb;
|
||||
}
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t word;
|
||||
uint8_t byte_regs[2];
|
||||
} word_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint32_t addr;
|
||||
uint8_t addr_regs[4];
|
||||
} bar_t;
|
||||
|
||||
uint8_t sb_awe64_pci_regs[256];
|
||||
|
||||
word_t sb_awe64_pci_words[6];
|
||||
|
||||
bar_t sb_awe64_pci_bar[6];
|
||||
|
||||
uint8_t sb_awe64_pci_read(int func, int addr, void *p)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0: case 1:
|
||||
return sb_awe64_pci_words[0].byte_regs[addr & 1];
|
||||
case 2: case 3:
|
||||
return sb_awe64_pci_words[1].byte_regs[addr & 1];
|
||||
case 8: case 9:
|
||||
return sb_awe64_pci_words[2].byte_regs[addr & 1];
|
||||
case 0xA: case 0xB:
|
||||
return sb_awe64_pci_words[3].byte_regs[addr & 1];
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
case 0x18: case 0x19: case 0x1A: case 0x1B:
|
||||
case 0x1C: case 0x1D: case 0x1E: case 0x1F:
|
||||
case 0x20: case 0x21: case 0x22: case 0x23:
|
||||
case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
return sb_awe64_pci_bar[(addr - 0x10) >> 2].addr_regs[addr & 3];
|
||||
case 0x2C: case 0x2D:
|
||||
return sb_awe64_pci_words[4].byte_regs[addr & 1];
|
||||
case 0x2E: case 0x2F:
|
||||
return sb_awe64_pci_words[5].byte_regs[addr & 1];
|
||||
default:
|
||||
return sb_awe64_pci_regs[addr];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sb_base_addr, old_base_addr;
|
||||
|
||||
void sb_awe64_io_remove(uint32_t base_addr, sb_t *sb)
|
||||
{
|
||||
io_removehandler(base_addr, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
io_removehandler(base_addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb);
|
||||
io_removehandler(base_addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
mpu401_uart_remove(&sb->mpu, base_addr + 8);
|
||||
}
|
||||
|
||||
void sb_awe64_io_set(uint32_t base_addr, sb_t *sb)
|
||||
{
|
||||
sb_dsp_setaddr(&sb->dsp, base_addr);
|
||||
|
||||
io_sethandler(base_addr, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(base_addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb);
|
||||
io_sethandler(base_addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
mpu401_uart_set(&sb->mpu, base_addr + 8);
|
||||
|
||||
old_base_addr = base_addr;
|
||||
}
|
||||
|
||||
void sb_awe64_pci_write(int func, int addr, uint8_t val, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *) p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 4:
|
||||
if (val & PCI_COMMAND_IO)
|
||||
{
|
||||
sb_awe64_io_remove(sb_base_addr, sb);
|
||||
sb_awe64_io_set(sb_base_addr, sb);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_awe64_io_remove(sb_base_addr, sb);
|
||||
}
|
||||
sb_awe64_pci_regs[addr] = val;
|
||||
return;
|
||||
case 0x10:
|
||||
val &= 0xfc;
|
||||
val |= 1;
|
||||
case 0x11: case 0x12: case 0x13:
|
||||
/* case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
case 0x18: case 0x19: case 0x1A: case 0x1B:
|
||||
case 0x1C: case 0x1D: case 0x1E: case 0x1F:
|
||||
case 0x20: case 0x21: case 0x22: case 0x23:
|
||||
case 0x24: case 0x25: case 0x26: case 0x27: */
|
||||
sb_awe64_pci_bar[(addr - 0x10) >> 2].addr_regs[addr & 3] = val;
|
||||
sb_awe64_pci_bar[(addr - 0x10) >> 2].addr &= 0xffc0;
|
||||
sb_awe64_pci_bar[(addr - 0x10) >> 2].addr |= 1;
|
||||
if ((addr & 0x14) == 0x10)
|
||||
{
|
||||
sb_awe64_io_remove(sb_base_addr, sb);
|
||||
sb_base_addr = sb_awe64_pci_bar[0].addr & 0xffc0;
|
||||
pclog("SB AWE64 PCI: New I/O base %i is %04X\n" , ((addr - 0x10) >> 2), sb_base_addr);
|
||||
}
|
||||
return;
|
||||
case 0x3C:
|
||||
sb_awe64_pci_regs[addr] = val;
|
||||
if (val != 0xFF)
|
||||
{
|
||||
pclog("SB AWE64 PCI IRQ now: %i\n", val);
|
||||
sb_dsp_setirq(&sb->dsp, val);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *sb_awe64pci_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t i = 0;
|
||||
int onboard_ram = device_get_config_int("onboard_ram");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl3_init(&sb->opl);
|
||||
sb_dsp_init(&sb->dsp, SB16 + 1);
|
||||
sb_dsp_setirq(&sb->dsp, 5);
|
||||
sb_dsp_setdma8(&sb->dsp, 1);
|
||||
mpu401_uart_init(&sb->mpu, 0x228);
|
||||
mpu401_uart_remove(&sb->mpu, 0x228);
|
||||
sb_awe64_io_set(0x220, sb);
|
||||
sb_mixer_init(&sb->mixer);
|
||||
io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
sound_add_handler(sb_get_buffer_emu8k, sb);
|
||||
emu8k_init(&sb->emu8k, onboard_ram);
|
||||
|
||||
sb->mixer.regs[0x30] = 31 << 3;
|
||||
sb->mixer.regs[0x31] = 31 << 3;
|
||||
sb->mixer.regs[0x32] = 31 << 3;
|
||||
sb->mixer.regs[0x33] = 31 << 3;
|
||||
sb->mixer.regs[0x34] = 31 << 3;
|
||||
sb->mixer.regs[0x35] = 31 << 3;
|
||||
sb->mixer.regs[0x44] = 8 << 4;
|
||||
sb->mixer.regs[0x45] = 8 << 4;
|
||||
sb->mixer.regs[0x46] = 8 << 4;
|
||||
sb->mixer.regs[0x47] = 8 << 4;
|
||||
sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4);
|
||||
sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4);
|
||||
sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4);
|
||||
|
||||
pci_add(sb_awe64_pci_read, sb_awe64_pci_write, sb);
|
||||
|
||||
sb_awe64_pci_words[0].word = 0x1102; /* Creative Labs */
|
||||
sb_awe64_pci_words[1].word = 0x0003; /* CT-8800-SAT chip (EMU8008) */
|
||||
sb_awe64_pci_words[3].word = 0x0401; /* Multimedia device, audio device */
|
||||
sb_awe64_pci_words[4].word = 0x1102; /* Creative Labs */
|
||||
sb_awe64_pci_words[5].word = device_get_config_int("revision"); /* Revision */
|
||||
sb_awe64_pci_bar[0].addr = 1;
|
||||
sb_awe64_pci_regs[0x3C] = 5;
|
||||
sb_awe64_pci_regs[0x3D] = 1;
|
||||
sb_awe64_pci_regs[0x3E] = 0x0c;
|
||||
sb_awe64_pci_regs[0x3F] = 0x80;
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void sb_close(void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
@@ -898,6 +1069,72 @@ static device_config_t sb_awe32_config[] =
|
||||
}
|
||||
};
|
||||
|
||||
static device_config_t sb_awe64pci_config[] =
|
||||
{
|
||||
{
|
||||
.name = "revision",
|
||||
.description = "Revision",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "CT4600",
|
||||
.value = 0x0010
|
||||
},
|
||||
{
|
||||
.description = "CT4650",
|
||||
.value = 0x0030
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 0x0010
|
||||
},
|
||||
{
|
||||
.name = "midi",
|
||||
.description = "MIDI out device",
|
||||
.type = CONFIG_MIDI,
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "onboard_ram",
|
||||
.description = "Onboard RAM",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "None",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = "512 KB",
|
||||
.value = 512
|
||||
},
|
||||
{
|
||||
.description = "2 MB",
|
||||
.value = 2048
|
||||
},
|
||||
{
|
||||
.description = "8 MB",
|
||||
.value = 8192
|
||||
},
|
||||
{
|
||||
.description = "28 MB",
|
||||
.value = 28*1024
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 512
|
||||
},
|
||||
{
|
||||
.type = -1
|
||||
}
|
||||
};
|
||||
|
||||
device_t sb_1_device =
|
||||
{
|
||||
"Sound Blaster v1.0",
|
||||
@@ -982,3 +1219,15 @@ device_t sb_awe32_device =
|
||||
sb_add_status_info,
|
||||
sb_awe32_config
|
||||
};
|
||||
device_t sb_awe64pci_device =
|
||||
{
|
||||
"Sound Blaster AWE64 PCI",
|
||||
0,
|
||||
sb_awe64pci_init,
|
||||
sb_close,
|
||||
sb_awe32_available,
|
||||
sb_speed_changed,
|
||||
NULL,
|
||||
sb_add_status_info,
|
||||
sb_awe64pci_config
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user