mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 09:35:32 -07:00
Merge remote-tracking branch 'upstream/master' into feature/ich2
This commit is contained in:
10
.ci/build.sh
10
.ci/build.sh
@@ -24,8 +24,8 @@
|
||||
# - For Windows (MSYS MinGW) builds:
|
||||
# - Packaging requires 7-Zip on Program Files
|
||||
# - Packaging the Ghostscript DLL requires 32-bit and/or 64-bit Ghostscript on Program Files
|
||||
# - Packaging the FluidSynth DLL requires it to be at /home/86Box/dll32/libfluidsynth.dll
|
||||
# and/or /home/86Box/dll64/libfluidsynth64.dll (for 32-bit and 64-bit builds respectively)
|
||||
# - Packaging the XAudio2 DLL for FAudio requires it to be at /home/86Box/dll32/xaudio2*.dll
|
||||
# and/or /home/86Box/dll64/xaudio2*.dll (for 32-bit and 64-bit builds respectively)
|
||||
# - For Linux builds:
|
||||
# - Only Debian and derivatives are supported
|
||||
# - dpkg and apt-get are called through sudo to manage dependencies; make sure those
|
||||
@@ -595,7 +595,7 @@ else
|
||||
# ...and the ones we do want listed. Non-dev packages fill missing spots on the list.
|
||||
libpkgs=""
|
||||
longest_libpkg=0
|
||||
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev
|
||||
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev
|
||||
do
|
||||
libpkgs="$libpkgs $pkg:$arch_deb"
|
||||
length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c)
|
||||
@@ -810,8 +810,8 @@ then
|
||||
"$sevenzip" e -y -o"archive_tmp" "$discord_zip" "lib/$arch_discord/discord_game_sdk.dll"
|
||||
[ ! -e "archive_tmp/discord_game_sdk.dll" ] && echo [!] No Discord Game SDK for architecture [$arch_discord]
|
||||
|
||||
# Archive other DLLs from local directory.
|
||||
cp -p "/home/$project/dll$arch/"* archive_tmp/
|
||||
# Archive XAudio2 DLL if required.
|
||||
grep -q "OPENAL:BOOL=ON" build/CMakeCache.txt || cp -p "/home/$project/dll$arch/xaudio2"* archive_tmp/
|
||||
|
||||
# Archive executable, while also stripping it if requested.
|
||||
if [ $strip -ne 0 ]
|
||||
|
||||
@@ -121,10 +121,13 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO: This is actually Fast A20 disable. */
|
||||
#if 0
|
||||
case 0xee:
|
||||
if (mem_a20_alt)
|
||||
outb(0x92, inb(0x92) & ~2);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -146,10 +149,13 @@ vl82c480_read(uint16_t addr, void *priv)
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
|
||||
/* TODO: This is actually Fast A20 enable. */
|
||||
#if 0
|
||||
case 0xee:
|
||||
if (!mem_a20_alt)
|
||||
outb(0x92, inb(0x92) | 2);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0xef:
|
||||
softresetx86();
|
||||
|
||||
912
src/cpu/808x.c
912
src/cpu/808x.c
File diff suppressed because it is too large
Load Diff
@@ -91,13 +91,30 @@ enum {
|
||||
|
||||
typedef union {
|
||||
uint32_t addr;
|
||||
uint8_t addr_regs[4];
|
||||
uint8_t addr_regs[4];
|
||||
} bar_t;
|
||||
|
||||
|
||||
#define PCI_IO_ON 0x01
|
||||
#define PCI_IO_DEV0 0x02
|
||||
|
||||
|
||||
extern int pci_burst_time;
|
||||
extern int agp_burst_time;
|
||||
extern int pci_nonburst_time;
|
||||
extern int agp_nonburst_time;
|
||||
extern int pci_take_over_io;
|
||||
|
||||
extern uint32_t pci_base;
|
||||
extern uint32_t pci_size;
|
||||
|
||||
|
||||
extern void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern void pci_type2_writew(uint16_t port, uint16_t val, void *priv);
|
||||
extern void pci_type2_writel(uint16_t port, uint32_t val, void *priv);
|
||||
extern uint8_t pci_type2_read(uint16_t port, void *priv);
|
||||
extern uint16_t pci_type2_readw(uint16_t port, void *priv);
|
||||
extern uint32_t pci_type2_readl(uint16_t port, void *priv);
|
||||
|
||||
extern void pci_set_irq_routing(int pci_int, int irq);
|
||||
extern void pci_set_irq_level(int pci_int, int level);
|
||||
|
||||
313
src/io.c
313
src/io.c
@@ -29,6 +29,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/m_amstrad.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
#define NPORTS 65536 /* PC/AT supports 64K ports */
|
||||
|
||||
@@ -287,15 +288,25 @@ inb(uint16_t port)
|
||||
int found = 0;
|
||||
int qfound = 0;
|
||||
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inb) {
|
||||
ret &= p->inb(port, p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_type2_read(port, NULL);
|
||||
found = 1;
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_type2_read(port, NULL);
|
||||
found = 1;
|
||||
qfound = 1;
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inb) {
|
||||
ret &= p->inb(port, p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (amstrad_latch & 0x80000000) {
|
||||
@@ -329,15 +340,25 @@ outb(uint16_t port, uint8_t val)
|
||||
int found = 0;
|
||||
int qfound = 0;
|
||||
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outb) {
|
||||
p->outb(port, val, p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_type2_write(port, val, NULL);
|
||||
found = 1;
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_type2_write(port, val, NULL);
|
||||
found = 1;
|
||||
qfound = 1;
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outb) {
|
||||
p->outb(port, val, p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
@@ -363,32 +384,42 @@ inw(uint16_t port)
|
||||
int qfound = 0;
|
||||
uint8_t ret8[2];
|
||||
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inw) {
|
||||
ret &= p->inw(port, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
ret8[0] = ret & 0xff;
|
||||
ret8[1] = (ret >> 8) & 0xff;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_type2_readw(port, NULL);
|
||||
found = 2;
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_type2_readw(port, NULL);
|
||||
found = 2;
|
||||
qfound = 1;
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inb && !p->inw) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
found |= 1;
|
||||
if (p->inw) {
|
||||
ret &= p->inw(port, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
ret8[0] = ret & 0xff;
|
||||
ret8[1] = (ret >> 8) & 0xff;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inb && !p->inw) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
ret = (ret8[1] << 8) | ret8[0];
|
||||
}
|
||||
ret = (ret8[1] << 8) | ret8[0];
|
||||
|
||||
if (amstrad_latch & 0x80000000) {
|
||||
if (port & 0x80)
|
||||
@@ -415,28 +446,38 @@ outw(uint16_t port, uint16_t val)
|
||||
int found = 0;
|
||||
int qfound = 0;
|
||||
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outw) {
|
||||
p->outw(port, val, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_type2_writew(port, val, NULL);
|
||||
found = 2;
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_type2_writew(port, val, NULL);
|
||||
found = 2;
|
||||
qfound = 1;
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outb && !p->outw) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
found |= 1;
|
||||
if (p->outw) {
|
||||
p->outw(port, val, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outb && !p->outw) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
@@ -463,59 +504,69 @@ inl(uint16_t port)
|
||||
int found = 0;
|
||||
int qfound = 0;
|
||||
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inl) {
|
||||
ret &= p->inl(port, p->priv);
|
||||
found |= 4;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
ret16[0] = ret & 0xffff;
|
||||
ret16[1] = (ret >> 16) & 0xffff;
|
||||
p = io[port & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[0] &= p->inw(port, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
p = io[(port + 2) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[1] &= p->inw(port + 2, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
ret = (ret16[1] << 16) | ret16[0];
|
||||
|
||||
ret8[0] = ret & 0xff;
|
||||
ret8[1] = (ret >> 8) & 0xff;
|
||||
ret8[2] = (ret >> 16) & 0xff;
|
||||
ret8[3] = (ret >> 24) & 0xff;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_type2_readl(port, NULL);
|
||||
found = 4;
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_type2_readl(port, NULL);
|
||||
found = 4;
|
||||
qfound = 1;
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inb && !p->inw && !p->inl) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
found |= 1;
|
||||
if (p->inl) {
|
||||
ret &= p->inl(port, p->priv);
|
||||
found |= 4;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
ret16[0] = ret & 0xffff;
|
||||
ret16[1] = (ret >> 16) & 0xffff;
|
||||
p = io[port & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[0] &= p->inw(port, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
p = io[(port + 2) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[1] &= p->inw(port + 2, p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
ret = (ret16[1] << 16) | ret16[0];
|
||||
|
||||
ret8[0] = ret & 0xff;
|
||||
ret8[1] = (ret >> 8) & 0xff;
|
||||
ret8[2] = (ret >> 16) & 0xff;
|
||||
ret8[3] = (ret >> 24) & 0xff;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->inb && !p->inw && !p->inl) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0];
|
||||
}
|
||||
ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0];
|
||||
|
||||
if (amstrad_latch & 0x80000000) {
|
||||
if (port & 0x80)
|
||||
@@ -543,42 +594,52 @@ outl(uint16_t port, uint32_t val)
|
||||
int qfound = 0;
|
||||
int i = 0;
|
||||
|
||||
p = io[port];
|
||||
if (p) {
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outl) {
|
||||
p->outl(port, val, p->priv);
|
||||
found |= 4;
|
||||
qfound++;
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_type2_writel(port, val, NULL);
|
||||
found = 4;
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_type2_writel(port, val, NULL);
|
||||
found = 4;
|
||||
qfound = 1;
|
||||
} else {
|
||||
p = io[port];
|
||||
if (p) {
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outl) {
|
||||
p->outl(port, val, p->priv);
|
||||
found |= 4;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i += 2) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outw && !p->outl) {
|
||||
p->outw(port + i, val >> (i << 3), p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
for (i = 0; i < 4; i += 2) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outw && !p->outl) {
|
||||
p->outw(port + i, val >> (i << 3), p->priv);
|
||||
found |= 2;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outb && !p->outw && !p->outl) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p = io[(port + i) & 0xffff];
|
||||
while (p) {
|
||||
q = p->next;
|
||||
if (p->outb && !p->outw && !p->outl) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
found |= 1;
|
||||
qfound++;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/isamem.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
int bios_only = 0;
|
||||
int machine;
|
||||
@@ -103,6 +104,8 @@ machine_init_ex(int m)
|
||||
|
||||
/* Reset the fast off stuff. */
|
||||
cpu_fast_off_reset();
|
||||
|
||||
pci_take_over_io = 0x00000000;
|
||||
}
|
||||
|
||||
/* All good, boot the machine! */
|
||||
|
||||
255
src/pci.c
255
src/pci.c
@@ -56,6 +56,10 @@ int pci_burst_time;
|
||||
int agp_burst_time;
|
||||
int pci_nonburst_time;
|
||||
int agp_nonburst_time;
|
||||
int pci_take_over_io;
|
||||
|
||||
uint32_t pci_base = 0xc000;
|
||||
uint32_t pci_size = 0x1000;
|
||||
|
||||
static pci_card_t pci_cards[32];
|
||||
static uint8_t pci_pmc = 0;
|
||||
@@ -77,8 +81,6 @@ static int pci_bus;
|
||||
static int pci_enable;
|
||||
static int pci_key;
|
||||
static int trc_reg = 0;
|
||||
static uint32_t pci_base = 0xc000;
|
||||
static uint32_t pci_size = 0x1000;
|
||||
|
||||
static void pci_reset_regs(void);
|
||||
|
||||
@@ -413,9 +415,6 @@ pci_readl(uint16_t port, UNUSED(void *priv))
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||
static uint8_t pci_type2_read(uint16_t port, void *priv);
|
||||
|
||||
void
|
||||
pci_set_pmc(uint8_t pmc)
|
||||
{
|
||||
@@ -425,9 +424,8 @@ pci_set_pmc(uint8_t pmc)
|
||||
#endif
|
||||
|
||||
if (!pci_pmc && (pmc & 0x01)) {
|
||||
io_removehandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
pci_log("PMC: Dellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
pci_take_over_io &= ~PCI_IO_ON;
|
||||
|
||||
io_removehandler(0x0cf8, 1,
|
||||
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
|
||||
@@ -440,13 +438,11 @@ pci_set_pmc(uint8_t pmc)
|
||||
io_sethandler(0x0cfc, 4,
|
||||
pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL);
|
||||
} else if (pci_pmc && !(pmc & 0x01)) {
|
||||
io_removehandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
pci_log("PMC: Redellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
pci_take_over_io &= ~PCI_IO_ON;
|
||||
if (pci_key) {
|
||||
io_sethandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
pci_log("PMC: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
pci_take_over_io |= PCI_IO_ON;
|
||||
}
|
||||
|
||||
io_removehandler(0x0cf8, 1,
|
||||
@@ -465,67 +461,97 @@ pci_set_pmc(uint8_t pmc)
|
||||
}
|
||||
|
||||
static void
|
||||
pci_type2_write(uint16_t port, uint8_t val, UNUSED(void *priv))
|
||||
pci_type2_write_reg(uint16_t port, uint8_t val)
|
||||
{
|
||||
uint8_t slot = 0;
|
||||
|
||||
if (port == 0xcf8) {
|
||||
pci_func = (val >> 1) & 7;
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
if (!pci_key && (val & 0xf0)) {
|
||||
io_removehandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
io_sethandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
} else if (pci_key && !(val & 0xf0))
|
||||
io_removehandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
|
||||
pci_key = val & 0xf0;
|
||||
} else if (port == 0xcfa) {
|
||||
pci_bus = val;
|
||||
|
||||
pci_log("Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
|
||||
/* Evidently, writing here, we should also enable the
|
||||
configuration space. */
|
||||
io_removehandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
io_sethandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
|
||||
/* Mark as enabled. */
|
||||
pci_key |= 0x100;
|
||||
} else if (port == 0xcfb) {
|
||||
pci_log("Write %02X to port 0CFB\n", val);
|
||||
pci_set_pmc(val);
|
||||
} else {
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card];
|
||||
if (slot != 0xff) {
|
||||
if (pci_cards[slot].write)
|
||||
pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv);
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
else
|
||||
pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
|
||||
#endif
|
||||
}
|
||||
slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card];
|
||||
if (slot != 0xff) {
|
||||
if (pci_cards[slot].write)
|
||||
pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv);
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
else
|
||||
pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
|
||||
pci_log("Writing to empty PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index);
|
||||
#endif
|
||||
}
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
else
|
||||
pci_log("Writing to unassigned PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
pci_type2_write(uint16_t port, uint8_t val, UNUSED(void *priv))
|
||||
{
|
||||
switch (port) {
|
||||
case 0xcf8:
|
||||
pci_func = (val >> 1) & 7;
|
||||
|
||||
if (val & 0xf0) {
|
||||
pci_log("CF8: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
pci_take_over_io |= PCI_IO_ON;
|
||||
} else {
|
||||
pci_log("CF8: Dellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
pci_take_over_io &= ~PCI_IO_ON;
|
||||
}
|
||||
|
||||
pci_key = val & 0xf0;
|
||||
break;
|
||||
case 0xcfa:
|
||||
pci_bus = val;
|
||||
|
||||
pci_log("CFA: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
|
||||
|
||||
/* Evidently, writing here, we should also enable the
|
||||
configuration space. */
|
||||
pci_take_over_io |= PCI_IO_ON;
|
||||
|
||||
/* Mark as enabled. */
|
||||
pci_key |= 0x100;
|
||||
break;
|
||||
case 0xcfb:
|
||||
pci_log("Write %02X to port 0CFB\n", val);
|
||||
pci_set_pmc(val);
|
||||
break;
|
||||
|
||||
case 0xc000 ... 0xc0ff:
|
||||
if (pci_take_over_io == 0x00000000)
|
||||
break;
|
||||
|
||||
pci_type2_write_reg(port, val);
|
||||
break;
|
||||
|
||||
case 0xc100 ... 0xcfff:
|
||||
if (!(pci_take_over_io & PCI_IO_ON))
|
||||
break;
|
||||
|
||||
pci_type2_write_reg(port, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
pci_type2_writew(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
pci_type2_write(port, val & 0xff, priv);
|
||||
pci_type2_write(port + 1, val >> 8, priv);
|
||||
}
|
||||
|
||||
void
|
||||
pci_type2_writel(uint16_t port, uint32_t val, void *priv)
|
||||
{
|
||||
pci_type2_writew(port, val & 0xffff, priv);
|
||||
pci_type2_writew(port + 2, val >> 16, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_type2_cfb_writel(uint16_t port, uint32_t val, void *priv)
|
||||
{
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
/* Make sure to have the DWORD write not pass through to PMC if mechanism 1 is in use,
|
||||
@@ -536,41 +562,88 @@ pci_type2_writel(uint16_t port, uint32_t val, void *priv)
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pci_type2_read(uint16_t port, UNUSED(void *priv))
|
||||
pci_type2_read_reg(uint16_t port)
|
||||
{
|
||||
uint8_t slot = 0;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port == 0xcf8)
|
||||
ret = pci_key | (pci_func << 1);
|
||||
else if (port == 0xcfa)
|
||||
ret = pci_bus;
|
||||
else if (port == 0xcfb)
|
||||
ret = pci_pmc;
|
||||
else {
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card];
|
||||
if (slot != 0xff) {
|
||||
if (pci_cards[slot].read)
|
||||
ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv);
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
else
|
||||
pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
|
||||
#endif
|
||||
}
|
||||
slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card];
|
||||
if (slot != 0xff) {
|
||||
if (pci_cards[slot].read)
|
||||
ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv);
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
else
|
||||
pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
|
||||
pci_log("Reading from empty PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index);
|
||||
#endif
|
||||
}
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
else
|
||||
pci_log("Reading from unasisgned PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index);
|
||||
#endif
|
||||
|
||||
pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func);
|
||||
pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
pci_type2_read(uint16_t port, UNUSED(void *priv))
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0xcf8:
|
||||
ret = pci_key | (pci_func << 1);
|
||||
break;
|
||||
case 0xcfa:
|
||||
ret = pci_bus;
|
||||
break;
|
||||
case 0xcfb:
|
||||
ret = pci_pmc;
|
||||
break;
|
||||
|
||||
case 0xc000 ... 0xc0ff:
|
||||
if (pci_take_over_io == 0x00000000)
|
||||
break;
|
||||
|
||||
ret = pci_type2_read_reg(port);
|
||||
break;
|
||||
|
||||
case 0xc100 ... 0xcfff:
|
||||
if (!(pci_take_over_io & PCI_IO_ON))
|
||||
break;
|
||||
|
||||
ret = pci_type2_read_reg(port);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
pci_type2_readw(uint16_t port, void *priv)
|
||||
{
|
||||
uint16_t ret = pci_type2_read(port, priv);
|
||||
ret |= ((uint16_t) pci_type2_read(port + 1, priv)) << 8;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pci_type2_readl(uint16_t port, void *priv)
|
||||
{
|
||||
uint32_t ret = pci_type2_readw(port, priv);
|
||||
ret |= ((uint32_t) pci_type2_readw(port + 2, priv)) << 16;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
pci_set_irq_routing(int pci_int, int irq)
|
||||
{
|
||||
@@ -852,9 +925,7 @@ pci_reset_regs(void)
|
||||
{
|
||||
pci_index = pci_card = pci_func = pci_bus = pci_key = 0;
|
||||
|
||||
io_removehandler(pci_base, pci_size,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
pci_take_over_io &= ~PCI_IO_ON;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1021,7 +1092,7 @@ pci_init(int type)
|
||||
pci_pmc = 0x00;
|
||||
|
||||
io_sethandler(0x0cfb, 1,
|
||||
pci_type2_read, NULL, NULL, pci_type2_write, NULL, pci_type2_writel, NULL);
|
||||
pci_type2_read, NULL, NULL, pci_type2_write, NULL, pci_type2_cfb_writel, NULL);
|
||||
}
|
||||
|
||||
if (type & PCI_NO_IRQ_STEERING) {
|
||||
@@ -1032,6 +1103,8 @@ pci_init(int type)
|
||||
pic_elcr_set_enabled(1);
|
||||
}
|
||||
|
||||
pci_take_over_io = 0x00000000;
|
||||
|
||||
if ((type & PCI_CONFIG_TYPE_MASK) == PCI_CONFIG_TYPE_1) {
|
||||
pci_log("PCI: Configuration mechanism #1\n");
|
||||
io_sethandler(0x0cf8, 1,
|
||||
@@ -1052,9 +1125,7 @@ pci_init(int type)
|
||||
pci_base = 0xc100;
|
||||
pci_size = 0x0f00;
|
||||
|
||||
io_sethandler(0xc000, 0x0100,
|
||||
pci_type2_read, NULL, NULL,
|
||||
pci_type2_write, NULL, NULL, NULL);
|
||||
pci_take_over_io |= PCI_IO_DEV0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,12 +85,13 @@ if(RTMIDI)
|
||||
endif()
|
||||
|
||||
if(FLUIDSYNTH)
|
||||
if(APPLE)
|
||||
find_library(FLUIDSYNTH_LIB fluidsynth)
|
||||
if (NOT FLUIDSYNTH_LIB)
|
||||
message(WARNING "Could not find fluid synth. The library will not be bundled and any related features will not work.")
|
||||
endif()
|
||||
endif ()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(FLUIDSYNTH REQUIRED IMPORTED_TARGET fluidsynth)
|
||||
target_link_libraries(86Box PkgConfig::FLUIDSYNTH)
|
||||
if(STATIC_BUILD)
|
||||
target_link_libraries(86Box -static ${FLUIDSYNTH_STATIC_LIBRARIES} -fopenmp)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH)
|
||||
target_sources(snd PRIVATE midi_fluidsynth.c)
|
||||
endif()
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
# ifdef __unix__
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
# define FLUIDSYNTH_NOT_A_DLL
|
||||
# include <fluidsynth.h>
|
||||
|
||||
# include <86box/86box.h>
|
||||
# include <86box/config.h>
|
||||
@@ -28,79 +30,9 @@
|
||||
# define RENDER_RATE 100
|
||||
# define BUFFER_SEGMENTS 10
|
||||
|
||||
enum fluid_chorus_mod {
|
||||
FLUID_CHORUS_MOD_SINE = 0,
|
||||
FLUID_CHORUS_MOD_TRIANGLE = 1
|
||||
};
|
||||
|
||||
enum fluid_interp {
|
||||
FLUID_INTERP_NONE = 0,
|
||||
FLUID_INTERP_LINEAR = 1,
|
||||
FLUID_INTERP_DEFAULT = 4,
|
||||
FLUID_INTERP_4THORDER = 4,
|
||||
FLUID_INTERP_7THORDER = 7,
|
||||
FLUID_INTERP_HIGHEST = 7
|
||||
};
|
||||
|
||||
extern void givealbuffer_midi(void *buf, uint32_t size);
|
||||
extern void al_set_midi(int freq, int buf_size);
|
||||
|
||||
static void *fluidsynth_handle; /* handle to FluidSynth DLL */
|
||||
|
||||
/* Pointers to the real functions. */
|
||||
// clang-format off
|
||||
static void *(*f_new_fluid_settings)(void);
|
||||
static void (*f_delete_fluid_settings)(void *settings);
|
||||
static int (*f_fluid_settings_setnum)(void *settings, const char *name, double val);
|
||||
static int (*f_fluid_settings_getnum)(void *settings, const char *name, double *val);
|
||||
static void *(*f_new_fluid_synth)(void *settings);
|
||||
static int (*f_delete_fluid_synth)(void *synth);
|
||||
static int (*f_fluid_synth_noteon)(void *synth, int chan, int key, int vel);
|
||||
static int (*f_fluid_synth_noteoff)(void *synth, int chan, int key);
|
||||
static int (*f_fluid_synth_cc)(void *synth, int chan, int ctrl, int val);
|
||||
static int (*f_fluid_synth_channel_pressure)(void *synth, int chan, int val);
|
||||
static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun);
|
||||
static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val);
|
||||
static int (*f_fluid_synth_program_change)(void *synth, int chan, int program);
|
||||
static int (*f_fluid_synth_sfload)(void *synth, const char *filename, int reset_presets);
|
||||
static int (*f_fluid_synth_set_interp_method)(void *synth, int chan, int interp_method);
|
||||
static void (*f_fluid_synth_set_reverb)(void *synth, double roomsize, double damping, double width, double level);
|
||||
static void (*f_fluid_synth_set_reverb_on)(void *synth, int on);
|
||||
static void (*f_fluid_synth_set_chorus)(void *synth, int nr, double level, double speed, double depth_ms, int type);
|
||||
static void (*f_fluid_synth_set_chorus_on)(void *synth, int on);
|
||||
static int (*f_fluid_synth_write_s16)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr);
|
||||
static int (*f_fluid_synth_write_float)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr);
|
||||
static char *(*f_fluid_version_str)(void);
|
||||
// clang-format on
|
||||
|
||||
static dllimp_t fluidsynth_imports[] = {
|
||||
// clang-format off
|
||||
{ "new_fluid_settings", &f_new_fluid_settings },
|
||||
{ "delete_fluid_settings", &f_delete_fluid_settings },
|
||||
{ "fluid_settings_setnum", &f_fluid_settings_setnum },
|
||||
{ "fluid_settings_getnum", &f_fluid_settings_getnum },
|
||||
{ "new_fluid_synth", &f_new_fluid_synth },
|
||||
{ "delete_fluid_synth", &f_delete_fluid_synth },
|
||||
{ "fluid_synth_noteon", &f_fluid_synth_noteon },
|
||||
{ "fluid_synth_noteoff", &f_fluid_synth_noteoff },
|
||||
{ "fluid_synth_cc", &f_fluid_synth_cc },
|
||||
{ "fluid_synth_channel_pressure", &f_fluid_synth_channel_pressure },
|
||||
{ "fluid_synth_sysex", &f_fluid_synth_sysex },
|
||||
{ "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend },
|
||||
{ "fluid_synth_program_change", &f_fluid_synth_program_change },
|
||||
{ "fluid_synth_sfload", &f_fluid_synth_sfload },
|
||||
{ "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method },
|
||||
{ "fluid_synth_set_reverb", &f_fluid_synth_set_reverb },
|
||||
{ "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on },
|
||||
{ "fluid_synth_set_chorus", &f_fluid_synth_set_chorus },
|
||||
{ "fluid_synth_set_chorus_on", &f_fluid_synth_set_chorus_on },
|
||||
{ "fluid_synth_write_s16", &f_fluid_synth_write_s16 },
|
||||
{ "fluid_synth_write_float", &f_fluid_synth_write_float },
|
||||
{ "fluid_version_str", &f_fluid_version_str },
|
||||
{ NULL, NULL },
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
typedef struct fluidsynth {
|
||||
void *settings;
|
||||
void *synth;
|
||||
@@ -153,7 +85,7 @@ fluidsynth_thread(void *param)
|
||||
float *buf = (float *) ((uint8_t *) data->buffer + buf_pos);
|
||||
memset(buf, 0, buf_size);
|
||||
if (data->synth)
|
||||
f_fluid_synth_write_float(data->synth, buf_size / (2 * sizeof(float)), buf, 0, 2, buf, 1, 2);
|
||||
fluid_synth_write_float(data->synth, buf_size / (2 * sizeof(float)), buf, 0, 2, buf, 1, 2);
|
||||
buf_pos += buf_size;
|
||||
if (buf_pos >= data->buf_size) {
|
||||
givealbuffer_midi(data->buffer, data->buf_size / sizeof(float));
|
||||
@@ -163,7 +95,7 @@ fluidsynth_thread(void *param)
|
||||
int16_t *buf = (int16_t *) ((uint8_t *) data->buffer_int16 + buf_pos);
|
||||
memset(buf, 0, buf_size);
|
||||
if (data->synth)
|
||||
f_fluid_synth_write_s16(data->synth, buf_size / (2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2);
|
||||
fluid_synth_write_s16(data->synth, buf_size / (2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2);
|
||||
buf_pos += buf_size;
|
||||
if (buf_pos >= data->buf_size) {
|
||||
givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t));
|
||||
@@ -187,24 +119,24 @@ fluidsynth_msg(uint8_t *msg)
|
||||
|
||||
switch (cmd) {
|
||||
case 0x80: /* Note Off */
|
||||
f_fluid_synth_noteoff(data->synth, chan, param1);
|
||||
fluid_synth_noteoff(data->synth, chan, param1);
|
||||
break;
|
||||
case 0x90: /* Note On */
|
||||
f_fluid_synth_noteon(data->synth, chan, param1, param2);
|
||||
fluid_synth_noteon(data->synth, chan, param1, param2);
|
||||
break;
|
||||
case 0xA0: /* Aftertouch */
|
||||
break;
|
||||
case 0xB0: /* Control Change */
|
||||
f_fluid_synth_cc(data->synth, chan, param1, param2);
|
||||
fluid_synth_cc(data->synth, chan, param1, param2);
|
||||
break;
|
||||
case 0xC0: /* Program Change */
|
||||
f_fluid_synth_program_change(data->synth, chan, param1);
|
||||
fluid_synth_program_change(data->synth, chan, param1);
|
||||
break;
|
||||
case 0xD0: /* Channel Pressure */
|
||||
f_fluid_synth_channel_pressure(data->synth, chan, param1);
|
||||
fluid_synth_channel_pressure(data->synth, chan, param1);
|
||||
break;
|
||||
case 0xE0: /* Pitch Bend */
|
||||
f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1);
|
||||
fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1);
|
||||
break;
|
||||
case 0xF0: /* SysEx */
|
||||
break;
|
||||
@@ -218,7 +150,7 @@ fluidsynth_sysex(uint8_t *data, unsigned int len)
|
||||
{
|
||||
fluidsynth_t *d = &fsdev;
|
||||
|
||||
f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0);
|
||||
fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -229,31 +161,12 @@ fluidsynth_init(const device_t *info)
|
||||
|
||||
memset(data, 0, sizeof(fluidsynth_t));
|
||||
|
||||
/* Try loading the DLL. */
|
||||
# ifdef _WIN32
|
||||
# if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
fluidsynth_handle = dynld_module("libfluidsynth.dll", fluidsynth_imports);
|
||||
# else
|
||||
fluidsynth_handle = dynld_module("libfluidsynth64.dll", fluidsynth_imports);
|
||||
# endif
|
||||
# elif defined __APPLE__
|
||||
fluidsynth_handle = dynld_module("libfluidsynth.dylib", fluidsynth_imports);
|
||||
# else
|
||||
fluidsynth_handle = dynld_module("libfluidsynth.so.3", fluidsynth_imports);
|
||||
if (fluidsynth_handle == NULL)
|
||||
fluidsynth_handle = dynld_module("libfluidsynth.so.2", fluidsynth_imports);
|
||||
# endif
|
||||
if (fluidsynth_handle == NULL) {
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2134);
|
||||
return NULL;
|
||||
}
|
||||
data->settings = new_fluid_settings();
|
||||
|
||||
data->settings = f_new_fluid_settings();
|
||||
fluid_settings_setnum(data->settings, "synth.sample-rate", 44100);
|
||||
fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain") / 100.0f);
|
||||
|
||||
f_fluid_settings_setnum(data->settings, "synth.sample-rate", 44100);
|
||||
f_fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain") / 100.0f);
|
||||
|
||||
data->synth = f_new_fluid_synth(data->settings);
|
||||
data->synth = new_fluid_synth(data->settings);
|
||||
|
||||
const char *sound_font = (char *) device_get_config_string("sound_font");
|
||||
# ifdef __unix__
|
||||
@@ -261,10 +174,10 @@ fluidsynth_init(const device_t *info)
|
||||
sound_font = (access("/usr/share/sounds/sf2/FluidR3_GM.sf2", F_OK) == 0 ? "/usr/share/sounds/sf2/FluidR3_GM.sf2" :
|
||||
(access("/usr/share/soundfonts/default.sf2", F_OK) == 0 ? "/usr/share/soundfonts/default.sf2" : ""));
|
||||
# endif
|
||||
data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1);
|
||||
data->sound_font = fluid_synth_sfload(data->synth, sound_font, 1);
|
||||
|
||||
if (device_get_config_int("chorus")) {
|
||||
f_fluid_synth_set_chorus_on(data->synth, 1);
|
||||
fluid_synth_set_chorus_on(data->synth, 1);
|
||||
|
||||
int chorus_voices = device_get_config_int("chorus_voices");
|
||||
double chorus_level = device_get_config_int("chorus_level") / 100.0;
|
||||
@@ -277,21 +190,21 @@ fluidsynth_init(const device_t *info)
|
||||
else
|
||||
chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE;
|
||||
|
||||
f_fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform);
|
||||
fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform);
|
||||
} else
|
||||
f_fluid_synth_set_chorus_on(data->synth, 0);
|
||||
fluid_synth_set_chorus_on(data->synth, 0);
|
||||
|
||||
if (device_get_config_int("reverb")) {
|
||||
f_fluid_synth_set_reverb_on(data->synth, 1);
|
||||
fluid_synth_set_reverb_on(data->synth, 1);
|
||||
|
||||
double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0;
|
||||
double reverb_damping = device_get_config_int("reverb_damping") / 100.0;
|
||||
int reverb_width = device_get_config_int("reverb_width");
|
||||
double reverb_level = device_get_config_int("reverb_level") / 100.0;
|
||||
|
||||
f_fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level);
|
||||
fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level);
|
||||
} else
|
||||
f_fluid_synth_set_reverb_on(data->synth, 0);
|
||||
fluid_synth_set_reverb_on(data->synth, 0);
|
||||
|
||||
int interpolation = device_get_config_int("interpolation");
|
||||
int fs_interpolation = FLUID_INTERP_4THORDER;
|
||||
@@ -305,10 +218,10 @@ fluidsynth_init(const device_t *info)
|
||||
else if (interpolation == 3)
|
||||
fs_interpolation = FLUID_INTERP_7THORDER;
|
||||
|
||||
f_fluid_synth_set_interp_method(data->synth, -1, fs_interpolation);
|
||||
fluid_synth_set_interp_method(data->synth, -1, fs_interpolation);
|
||||
|
||||
double samplerate;
|
||||
f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate);
|
||||
fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate);
|
||||
data->samplerate = (int) samplerate;
|
||||
if (sound_is_float) {
|
||||
data->buf_size = (data->samplerate / RENDER_RATE) * 2 * sizeof(float) * BUFFER_SEGMENTS;
|
||||
@@ -357,12 +270,12 @@ fluidsynth_close(void *p)
|
||||
thread_wait(data->thread_h);
|
||||
|
||||
if (data->synth) {
|
||||
f_delete_fluid_synth(data->synth);
|
||||
delete_fluid_synth(data->synth);
|
||||
data->synth = NULL;
|
||||
}
|
||||
|
||||
if (data->settings) {
|
||||
f_delete_fluid_settings(data->settings);
|
||||
delete_fluid_settings(data->settings);
|
||||
data->settings = NULL;
|
||||
}
|
||||
|
||||
@@ -375,12 +288,6 @@ fluidsynth_close(void *p)
|
||||
free(data->buffer_int16);
|
||||
data->buffer_int16 = NULL;
|
||||
}
|
||||
|
||||
/* Unload the DLL if possible. */
|
||||
if (fluidsynth_handle != NULL) {
|
||||
dynld_close(fluidsynth_handle);
|
||||
fluidsynth_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const device_config_t fluidsynth_config[] = {
|
||||
|
||||
@@ -77,7 +77,7 @@ cga_out(uint16_t addr, uint8_t val, void *p)
|
||||
cga->cgamode = val;
|
||||
|
||||
if (old ^ val) {
|
||||
if ((old ^ val) & 0x05)
|
||||
if ((old ^ val) & 0x07)
|
||||
update_cga16_color(val);
|
||||
|
||||
cga_recalctimings(cga);
|
||||
@@ -352,10 +352,7 @@ cga_poll(void *p)
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
|
||||
if (cga->composite) {
|
||||
if (cga->cgamode & 0x10)
|
||||
border = 0x00;
|
||||
else
|
||||
border = cga->cgacol & 0x0f;
|
||||
border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15);
|
||||
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine << 1]);
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]);
|
||||
@@ -536,6 +533,7 @@ cga_standalone_init(const device_t *info)
|
||||
cga->rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (cga->rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
update_cga16_color(cga->cgamode);
|
||||
|
||||
return cga;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user