Merge branch '86Box:master' into machine_23
This commit is contained in:
15
.ci/build.sh
15
.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 ]
|
||||
@@ -1003,6 +1003,11 @@ else
|
||||
ln -s "$relroot/usr/lib/libvulkan.so.1" "archive_tmp/usr/lib/libvulkan.so"
|
||||
ln -s "$relroot/usr/lib/$libdir/libvulkan.so.1" "archive_tmp/usr/lib/$libdir/libvulkan.so"
|
||||
|
||||
# The FluidSynth packaged by Debian bullseye is ABI incompatible with
|
||||
# the newer version we compile, despite sharing a major version. Since we
|
||||
# don't run into the one breaking ABI change they made, just symlink it.
|
||||
ln -s "$(readlink "archive_tmp/usr/lib/libfluidsynth.so.3")" "archive_tmp/usr/lib/libfluidsynth.so.2"
|
||||
|
||||
# Archive Discord Game SDK library.
|
||||
7z e -y -o"archive_tmp/usr/lib" "$discord_zip" "lib/$arch_discord/discord_game_sdk.so"
|
||||
[ ! -e "archive_tmp/usr/lib/discord_game_sdk.so" ] && echo [!] No Discord Game SDK for architecture [$arch_discord]
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
#ifndef USE_DRB_HACK
|
||||
#include <86box/row.h>
|
||||
#endif
|
||||
|
||||
#define MEM_STATE_SHADOW_R 0x01
|
||||
#define MEM_STATE_SHADOW_W 0x02
|
||||
@@ -158,6 +161,26 @@ i420ex_smram_handler_phase1(i420ex_t *dev)
|
||||
(regs[0x70] & 0x70) == 0x40, !(regs[0x70] & 0x20));
|
||||
}
|
||||
|
||||
#ifndef USE_DRB_HACK
|
||||
static void
|
||||
i420ex_drb_recalc(i420ex_t *dev)
|
||||
{
|
||||
int i;
|
||||
uint32_t boundary;
|
||||
|
||||
for (i = 4; i >= 0; i--)
|
||||
row_disable(i);
|
||||
|
||||
for (i = 0; i <= 4; i++) {
|
||||
boundary = ((uint32_t) dev->regs[0x60 + i]) & 0xff;
|
||||
row_set_boundary(i, boundary);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
i420ex_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -289,7 +312,12 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
#ifdef USE_DRB_HACK
|
||||
spd_write_drbs(dev->regs, 0x60, 0x64, 1);
|
||||
#else
|
||||
dev->regs[addr] = val;
|
||||
i420ex_drb_recalc(dev);
|
||||
#endif
|
||||
break;
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
@@ -452,7 +480,7 @@ i420ex_reset(void *priv)
|
||||
i420ex_write(0, 0x59 + i, 0x00, priv);
|
||||
|
||||
for (uint8_t i = 0; i <= 4; i++)
|
||||
i420ex_write(0, 0x60 + i, 0x01, priv);
|
||||
dev->regs[0x60 + i] = 0x01;
|
||||
|
||||
dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */
|
||||
dev->smram_locked = 0;
|
||||
@@ -530,6 +558,11 @@ i420ex_init(const device_t *info)
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
#ifndef USE_DRB_HACK
|
||||
row_device.local = 4 | (1 << 8) | (0x01 << 16) | (8 << 24);
|
||||
device_add((const device_t *) &row_device);
|
||||
#endif
|
||||
|
||||
i420ex_reset_hard(dev);
|
||||
|
||||
return dev;
|
||||
|
||||
@@ -1537,7 +1537,12 @@ i4x0_reset(void *priv)
|
||||
i4x0_write(0, 0x5a + i, 0x00, priv);
|
||||
|
||||
for (uint8_t i = 0; i <= dev->max_drb; i++)
|
||||
i4x0_write(0, 0x60 + i, dev->drb_default, priv);
|
||||
dev->regs[0x60 + i] = dev->drb_default;
|
||||
|
||||
if (dev->type >= INTEL_430NX) {
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
dev->regs[0x68 + i] = 0x00;
|
||||
}
|
||||
|
||||
if (dev->type >= INTEL_430FX) {
|
||||
dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */
|
||||
@@ -1621,7 +1626,7 @@ i4x0_init(const device_t *info)
|
||||
regs[0x59] = 0x0f;
|
||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02;
|
||||
dev->max_drb = 3;
|
||||
dev->drb_unit = 4;
|
||||
dev->drb_unit = 1;
|
||||
dev->drb_default = 0x02;
|
||||
break;
|
||||
case INTEL_430LX:
|
||||
|
||||
@@ -38,10 +38,17 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
#ifndef USE_DRB_HACK
|
||||
#include <86box/row.h>
|
||||
#endif
|
||||
|
||||
typedef struct sis_85c496_t {
|
||||
uint8_t cur_reg;
|
||||
uint8_t rmsmiblk_count;
|
||||
#ifndef USE_DRB_HACK
|
||||
uint8_t drb_default;
|
||||
uint8_t drb_bits;
|
||||
#endif
|
||||
uint8_t regs[127];
|
||||
uint8_t pci_conf[256];
|
||||
smram_t *smram;
|
||||
@@ -184,6 +191,26 @@ sis_85c496_ide_handler(sis_85c496_t *dev)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_DRB_HACK
|
||||
static void
|
||||
sis_85c496_drb_recalc(sis_85c496_t *dev)
|
||||
{
|
||||
int i;
|
||||
uint32_t boundary;
|
||||
|
||||
for (i = 7; i >= 0; i--)
|
||||
row_disable(i);
|
||||
|
||||
for (i = 0; i <= 7; i++) {
|
||||
boundary = ((uint32_t) dev->pci_conf[0x48 + i]);
|
||||
row_set_boundary(i, boundary);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */
|
||||
static void
|
||||
sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
@@ -259,10 +286,12 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
#if 0
|
||||
dev->pci_conf[addr] = val;
|
||||
#endif
|
||||
#ifdef USE_DRB_HACK
|
||||
spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1);
|
||||
#else
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_85c496_drb_recalc(dev);
|
||||
#endif
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x51: /* Exclusive Area 0 Setup */
|
||||
@@ -552,7 +581,7 @@ sis_85c496_reset(void *priv)
|
||||
// sis_85c49x_pci_write(0, 0x5a, 0x06, dev);
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev);
|
||||
dev->pci_conf[0x48 + i] = 0x02;
|
||||
|
||||
sis_85c49x_pci_write(0, 0x80, 0x00, dev);
|
||||
sis_85c49x_pci_write(0, 0x81, 0x00, dev);
|
||||
@@ -643,6 +672,11 @@ static void
|
||||
|
||||
timer_add(&dev->rmsmiblk_timer, sis_85c496_rmsmiblk_count, dev, 0);
|
||||
|
||||
#ifndef USE_DRB_HACK
|
||||
row_device.local = 7 | (1 << 8) | (0x02 << 16) | (7 << 24);
|
||||
device_add((const device_t *) &row_device);
|
||||
#endif
|
||||
|
||||
sis_85c496_reset(dev);
|
||||
|
||||
return dev;
|
||||
|
||||
46
src/include/86box/row.h
Normal file
46
src/include/86box/row.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Definitions for the SMRAM interface.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef EMU_ROW_H
|
||||
# define EMU_ROW_H
|
||||
|
||||
typedef struct _row_
|
||||
{
|
||||
struct _smram_ *prev;
|
||||
struct _smram_ *next;
|
||||
|
||||
uint8_t *buf;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
|
||||
uint32_t host_base;
|
||||
uint32_t host_size;
|
||||
uint32_t ram_base;
|
||||
uint32_t ram_size;
|
||||
uint32_t ram_mask;
|
||||
uint32_t boundary;
|
||||
} row_t;
|
||||
|
||||
|
||||
extern void row_disable(uint8_t row_id);
|
||||
extern void row_set_boundary(uint8_t row_id, uint32_t boundary);
|
||||
|
||||
|
||||
extern device_t row_device;
|
||||
|
||||
|
||||
#endif /*EMU_ROW_H*/
|
||||
@@ -14,4 +14,4 @@
|
||||
#
|
||||
|
||||
add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c
|
||||
smram.c spd.c sst_flash.c)
|
||||
row.c smram.c spd.c sst_flash.c)
|
||||
|
||||
343
src/mem/row.c
Normal file
343
src/mem/row.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* DRAM row handling.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86.h"
|
||||
#include <86box/config.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/row.h>
|
||||
|
||||
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
static uint8_t rows_num, rows_default,
|
||||
rows_bits;
|
||||
static uint32_t row_unit;
|
||||
static uint8_t drb_defaults[16];
|
||||
static row_t *rows;
|
||||
|
||||
|
||||
static uint8_t
|
||||
row_read(uint32_t addr, void *priv)
|
||||
{
|
||||
row_t *dev = (row_t *) priv;
|
||||
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
|
||||
|
||||
addreadlookup(mem_logical_addr, new_addr);
|
||||
|
||||
return dev->buf[new_addr];
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
row_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
row_t *dev = (row_t *) priv;
|
||||
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
|
||||
|
||||
addreadlookup(mem_logical_addr, new_addr);
|
||||
|
||||
return *(uint16_t *) &(dev->buf[new_addr]);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
row_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
row_t *dev = (row_t *) priv;
|
||||
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
|
||||
|
||||
addreadlookup(mem_logical_addr, new_addr);
|
||||
|
||||
return *(uint32_t *) &(dev->buf[new_addr]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
row_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
row_t *dev = (row_t *) priv;
|
||||
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
|
||||
|
||||
addwritelookup(mem_logical_addr, new_addr);
|
||||
mem_write_ramb_page(new_addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
row_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
row_t *dev = (row_t *) priv;
|
||||
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
|
||||
|
||||
addwritelookup(mem_logical_addr, new_addr);
|
||||
mem_write_ramw_page(new_addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
row_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
row_t *dev = (row_t *) priv;
|
||||
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
|
||||
|
||||
addwritelookup(mem_logical_addr, new_addr);
|
||||
mem_write_raml_page(new_addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
row_allocate(uint8_t row_id, uint8_t set)
|
||||
{
|
||||
uint32_t c, offset;
|
||||
|
||||
/* Do nothing if size is either zero or invalid. */
|
||||
if ((rows[row_id].host_size == 0x00000000) || (rows[row_id].host_size == 0xffffffff))
|
||||
return;
|
||||
|
||||
if (rows[row_id].ram_size == 0x00000000)
|
||||
return;
|
||||
|
||||
for (c = (rows[row_id].host_base >> 12); c < ((rows[row_id].host_base + rows[row_id].host_size) >> 12); c++) {
|
||||
offset = c - (rows[row_id].host_base >> 12);
|
||||
|
||||
pages[c].mem = set ? (rows[row_id].buf + rows[row_id].ram_base + ((offset << 12) & rows[row_id].ram_mask)) : page_ff;
|
||||
pages[c].write_b = set ? mem_write_ramb_page : NULL;
|
||||
pages[c].write_w = set ? mem_write_ramw_page : NULL;
|
||||
pages[c].write_l = set ? mem_write_raml_page : NULL;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
pages[c].evict_prev = EVICT_NOT_IN_LIST;
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rows[row_id].host_base >= 0x00100000) {
|
||||
mem_set_mem_state_both(rows[row_id].host_base, rows[row_id].host_base + rows[row_id].host_size,
|
||||
set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
|
||||
} else {
|
||||
if (0x000a0000 > rows[row_id].host_base) {
|
||||
mem_set_mem_state_both(rows[row_id].host_base, 0x000a0000 - rows[row_id].host_base,
|
||||
set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
|
||||
}
|
||||
if ((rows[row_id].host_base + rows[row_id].host_size) > 0x00100000) {
|
||||
mem_set_mem_state_both(0x00100000, (rows[row_id].host_base + rows[row_id].host_size) - 0x00100000,
|
||||
set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
|
||||
}
|
||||
}
|
||||
|
||||
if (set) {
|
||||
mem_mapping_set_addr(&rows[row_id].mapping, rows[row_id].host_base, rows[row_id].host_size);
|
||||
mem_mapping_set_exec(&rows[row_id].mapping, rows[row_id].buf + rows[row_id].ram_base);
|
||||
mem_mapping_set_mask(&rows[row_id].mapping, rows[row_id].ram_mask);
|
||||
if ((rows[row_id].host_base == rows[row_id].ram_base) && (rows[row_id].host_size == rows[row_id].ram_size)) {
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml,
|
||||
mem_write_ram,mem_write_ramw,mem_write_raml);
|
||||
#else
|
||||
if (rows[row_id].buf == ram2) {
|
||||
mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl,
|
||||
mem_write_ram,mem_write_ramw,mem_write_raml);
|
||||
} else {
|
||||
mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml,
|
||||
mem_write_ram,mem_write_ramw,mem_write_raml);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
mem_mapping_set_handler(&rows[row_id].mapping, row_read, row_readw, row_readl,
|
||||
row_write, row_writew, row_writel);
|
||||
}
|
||||
} else
|
||||
mem_mapping_disable(&rows[row_id].mapping);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
row_disable(uint8_t row_id)
|
||||
{
|
||||
row_allocate(row_id, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
row_set_boundary(uint8_t row_id, uint32_t boundary)
|
||||
{
|
||||
if (row_id >= rows_num)
|
||||
return;
|
||||
|
||||
boundary &= ((1 << rows_bits) - 1);
|
||||
|
||||
rows[row_id].host_size = boundary * row_unit;
|
||||
if (row_id == 0)
|
||||
rows[row_id].host_base = 0x00000000;
|
||||
else {
|
||||
rows[row_id].host_base = rows[row_id - 1].boundary * row_unit;
|
||||
if (rows[row_id - 1].boundary > boundary)
|
||||
rows[row_id].host_size = 0x00000000;
|
||||
else
|
||||
rows[row_id].host_size -= rows[row_id].host_base;
|
||||
}
|
||||
|
||||
rows[row_id].boundary = boundary;
|
||||
|
||||
row_allocate(row_id, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
row_reset(void *priv)
|
||||
{
|
||||
int i;
|
||||
uint32_t boundary, shift;
|
||||
|
||||
for (i = (rows_num - 1); i >= 0; i--)
|
||||
row_disable(i);
|
||||
|
||||
for (i = 0; i < rows_num; i++) {
|
||||
shift = (i & 1) << 2;
|
||||
boundary = ((uint32_t) drb_defaults[i]) + (((((uint32_t) drb_defaults[(i >> 1) + 8]) >> shift) & 0xf) << 8);
|
||||
row_set_boundary(i, boundary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
row_close(void *priv)
|
||||
{
|
||||
free(rows);
|
||||
rows = NULL;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
row_init(const device_t *info)
|
||||
{
|
||||
uint32_t cur_drb = 0, cur_drbe = 0;
|
||||
uint32_t last_drb = 0, last_drbe = 0;
|
||||
uint8_t phys_drbs[16];
|
||||
int i, max = info->local & 0xff;
|
||||
int c;
|
||||
uint32_t shift, drb;
|
||||
uint32_t boundary, mask;
|
||||
row_t *new_rows = NULL;
|
||||
|
||||
rows_bits = ((info->local >> 24) & 0xff);
|
||||
mask = (1 << rows_bits) - 1;
|
||||
row_unit = ((info->local >> 8) & 0xff);
|
||||
memset(phys_drbs, 0x00, 16);
|
||||
spd_write_drbs(phys_drbs, 0x00, max, row_unit);
|
||||
row_unit <<= 20;
|
||||
rows_default = (info->local >> 16) & 0xff;
|
||||
memset(drb_defaults, 0x00, 16);
|
||||
for (i = 0; i < 8; i++)
|
||||
drb_defaults[i] = rows_default;
|
||||
|
||||
new_rows = calloc(max + 1, sizeof(row_t));
|
||||
rows_num = max + 1;
|
||||
|
||||
rows = new_rows;
|
||||
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (mem_size > 1048576)
|
||||
mem_mapping_disable(&ram_2gb_mapping);
|
||||
#endif
|
||||
|
||||
for (c = 0; c < pages_sz; c++) {
|
||||
pages[c].mem = page_ff;
|
||||
pages[c].write_b = NULL;
|
||||
pages[c].write_w = NULL;
|
||||
pages[c].write_l = NULL;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
pages[c].evict_prev = EVICT_NOT_IN_LIST;
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64];
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set all memory space above the default allocated area to external. */
|
||||
boundary = ((uint32_t) rows_default) * row_unit;
|
||||
mem_set_mem_state_both(boundary, (mem_size << 10) - boundary, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
|
||||
for (i = 0; i <= max; i++) {
|
||||
cur_drb = phys_drbs[i];
|
||||
cur_drbe = phys_drbs[(i >> 1) + 8];
|
||||
|
||||
shift = (i & 1) << 2;
|
||||
drb = (cur_drb & mask) + (((cur_drbe >> shift) & 0x03) << 8);
|
||||
rows[i].ram_size = drb * row_unit;
|
||||
|
||||
shift = ((i - 1) & 1) << 2;
|
||||
drb = (last_drb & mask) + (((last_drbe >> shift) & 0x03) << 8);
|
||||
rows[i].ram_base = drb * row_unit;
|
||||
rows[i].ram_size -= rows[i].ram_base;
|
||||
|
||||
rows[i].buf = ram;
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (rows[i].ram_base >= (1 << 30)) {
|
||||
rows[i].ram_base -= (1 << 30);
|
||||
rows[i].buf = ram2;
|
||||
}
|
||||
#endif
|
||||
|
||||
rows[i].ram_mask = rows[i].ram_size - 1;
|
||||
|
||||
mem_mapping_add(&rows[i].mapping, rows[i].ram_base, rows[i].ram_size,
|
||||
row_read, row_readw, row_readl,
|
||||
row_write, row_writew, row_writel,
|
||||
rows[i].buf + rows[i].ram_base, MEM_MAPPING_INTERNAL, &(rows[i]));
|
||||
mem_mapping_disable(&rows[i].mapping);
|
||||
|
||||
shift = (i & 1) << 2;
|
||||
boundary = ((uint32_t) drb_defaults[i]) + ((((uint32_t) drb_defaults[(i >> 1) + 8]) >> shift) << 8);
|
||||
row_set_boundary(i, boundary);
|
||||
|
||||
last_drb = cur_drb;
|
||||
last_drbe = cur_drbe;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
|
||||
return new_rows;
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: NOT const, so that we can patch it at init. */
|
||||
device_t row_device = {
|
||||
.name = "DRAM Rows",
|
||||
.internal_name = "dram_rows",
|
||||
.flags = DEVICE_AT,
|
||||
.local = 0x0000,
|
||||
.init = row_init,
|
||||
.close = row_close,
|
||||
.reset = row_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -401,7 +401,7 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit
|
||||
}
|
||||
}
|
||||
|
||||
/* Needed for 430LX. */
|
||||
/* Needed for 430NX. */
|
||||
void
|
||||
spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
|
||||
{
|
||||
@@ -447,8 +447,9 @@ spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t
|
||||
row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
|
||||
regs[drb] = row_val & 0xff;
|
||||
drb = reg_min + 8 + (row >> 1);
|
||||
shift = (row & 0x01) << 3;
|
||||
regs[drb] = (((row_val & 0xfff) >> 8) << shift);
|
||||
shift = (row & 0x01) << 2;
|
||||
/* Limit to 1 GB space, per the 430NX datasheet. */
|
||||
regs[drb] = (regs[drb] & ~(0xf << shift)) | (((row_val >> 8) & 3) << shift);
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,12 @@ FileField::FileField(QWidget *parent)
|
||||
fileName_ = ui->label->text();
|
||||
emit fileSelected(ui->label->text(), true);
|
||||
});
|
||||
|
||||
connect(ui->label, &QLineEdit::textChanged, this, [this]() {
|
||||
fileName_ = ui->label->text();
|
||||
emit fileTextEntered(ui->label->text(), true);
|
||||
});
|
||||
|
||||
this->setFixedWidth(this->sizeHint().width() + ui->pushButton->sizeHint().width());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,14 @@ public:
|
||||
|
||||
void setFilter(const QString &filter) { filter_ = filter; }
|
||||
QString selectedFilter() const { return selectedFilter_; }
|
||||
void setselectedFilter(const QString &selectedFilter) { selectedFilter_ = selectedFilter; }
|
||||
|
||||
void setCreateFile(bool createFile) { createFile_ = createFile; }
|
||||
bool createFile() { return createFile_; }
|
||||
|
||||
signals:
|
||||
void fileSelected(const QString &fileName, bool precheck = false);
|
||||
void fileTextEntered(const QString &fileName, bool precheck = false);
|
||||
|
||||
private slots:
|
||||
void on_pushButton_clicked();
|
||||
|
||||
@@ -84,6 +84,13 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent)
|
||||
ui->lineEditSize->setValidator(new QIntValidator());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
|
||||
filters = QStringList({ tr("Raw image") % util::DlgFilter({ "img" }, true),
|
||||
tr("HDI image") % util::DlgFilter({ "hdi" }, true),
|
||||
tr("HDX image") % util::DlgFilter({ "hdx" }, true),
|
||||
tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true),
|
||||
tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true),
|
||||
tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) });
|
||||
|
||||
if (existing) {
|
||||
ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?", "im?", "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true));
|
||||
|
||||
@@ -99,24 +106,26 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent)
|
||||
|
||||
connect(ui->fileField, &FileField::fileSelected, this, &HarddiskDialog::onExistingFileSelected);
|
||||
} else {
|
||||
QStringList filters({ tr("Raw image") % util::DlgFilter({ "img" }, true),
|
||||
tr("HDI image") % util::DlgFilter({ "hdi" }, true),
|
||||
tr("HDX image") % util::DlgFilter({ "hdx" }, true),
|
||||
tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true),
|
||||
tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true),
|
||||
tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) });
|
||||
|
||||
ui->fileField->setFilter(filters.join(";;"));
|
||||
|
||||
setWindowTitle(tr("Add New Hard Disk"));
|
||||
ui->fileField->setCreateFile(true);
|
||||
|
||||
connect(ui->fileField, &FileField::fileSelected, this, [this, filters] {
|
||||
// Enable the OK button as long as the filename length is non-zero
|
||||
connect(ui->fileField, &FileField::fileTextEntered, this, [this] {
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled((this->fileName().length() > 0));
|
||||
});
|
||||
|
||||
connect(ui->fileField, &FileField::fileSelected, this, [this] {
|
||||
int filter = filters.indexOf(ui->fileField->selectedFilter());
|
||||
if (filter > -1)
|
||||
ui->comboBoxFormat->setCurrentIndex(filter);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
});
|
||||
// Set the default format to Dynamic-size VHD. Do it last after everything is set up
|
||||
// so the currentIndexChanged signal can do what is needed
|
||||
ui->comboBoxFormat->setCurrentIndex(DEFAULT_DISK_FORMAT);
|
||||
ui->fileField->setselectedFilter(filters.value(DEFAULT_DISK_FORMAT));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +188,7 @@ HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index)
|
||||
ui->comboBoxBlockSize->show();
|
||||
ui->labelBlockSize->show();
|
||||
}
|
||||
ui->fileField->setselectedFilter(filters.value(index));
|
||||
}
|
||||
|
||||
/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry,
|
||||
|
||||
@@ -52,6 +52,11 @@ private:
|
||||
|
||||
bool disallowSizeModifications = false;
|
||||
|
||||
QStringList filters;
|
||||
// "Dynamic-size VHD" is number 4 in the `filters` list and the
|
||||
// comboBoxFormat model
|
||||
const uint8_t DEFAULT_DISK_FORMAT = 4;
|
||||
|
||||
bool checkAndAdjustCylinders();
|
||||
bool checkAndAdjustHeads();
|
||||
bool checkAndAdjustSectors();
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
Reference in New Issue
Block a user