mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 02:17:36 +08:00
PC-98 86PCM Support
This commit is contained in:
@@ -147,10 +147,6 @@ static inline void FillMemory(void *p,size_t l,unsigned char c) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void pcm86io_bind(void) {
|
||||
/* dummy */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@@ -18,7 +18,7 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler
|
||||
snd_pc98/common/parts.c snd_pc98/generic/keydisp.c snd_pc98/sound/adpcmc.c snd_pc98/sound/adpcmg.c \
|
||||
snd_pc98/sound/rhythmc.c snd_pc98/sound/sound.c snd_pc98/sound/getsnd/getwave.c snd_pc98/sound/getsnd/getsmix.c \
|
||||
snd_pc98/sound/getsnd/getsnd.c snd_pc98/x11/dosio.c snd_pc98/sound/fmboard.c snd_pc98/sound/soundrom.c \
|
||||
snd_pc98/cbus/board86.c snd_pc98/sound/fmtimer.c snd_pc98/cbus/board26k.c 8255.cpp opl2board/opl2board.cpp opl3duoboard/opl3duoboard.cpp \
|
||||
snd_pc98/cbus/board86.c snd_pc98/cbus/pcm86io.c snd_pc98/sound/fmtimer.c snd_pc98/cbus/board26k.c 8255.cpp opl2board/opl2board.cpp opl3duoboard/opl3duoboard.cpp \
|
||||
RetroWaveLib/Board/OPL3.c \
|
||||
RetroWaveLib/Platform/Win32_SerialPort.c \
|
||||
RetroWaveLib/Platform/POSIX_SerialPort.c \
|
||||
|
@@ -42,8 +42,7 @@ MixerChannel *pc98_mixer = NULL;
|
||||
|
||||
NP2CFG pccore;
|
||||
|
||||
static Bitu pcm86_ia460(Bitu port, Bitu iolen);
|
||||
static unsigned int baseio;
|
||||
extern "C" void pcm86io_setid(unsigned int baseio);
|
||||
|
||||
extern unsigned char pc98_mem_msw_m[8];
|
||||
bool pc98_soundbios_rom_load = true;
|
||||
@@ -140,43 +139,6 @@ Bitu pc98_fm86_read(Bitu port,Bitu iolen) {
|
||||
return ~0ul;
|
||||
}
|
||||
|
||||
static Bitu pcm86_ia460(Bitu port, Bitu iolen) {
|
||||
(void)port;
|
||||
(void)iolen;
|
||||
return (baseio == 0x288 ? 0x53 : 0x43); // Hack return Sound ID
|
||||
/* Sound ID baseio 0x188: 4 0x288: 5 */
|
||||
}
|
||||
#if 0
|
||||
static Bitu pcm86_ia466(Bitu port, Bitu /*iolen*/) {
|
||||
// Port 0xa466 Read: FIFO status
|
||||
LOG_MSG("read port a466h: Always return 0x80 (FIFO Full)");
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
static Bitu pcm86_ia468(Bitu port, Bitu /*iolen*/) {
|
||||
// Port 0xa468 Read: FIFO control
|
||||
LOG_MSG("read port a468h: Always return 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Bitu pcm86_ia46a(Bitu port, Bitu /*iolen*/) {
|
||||
// Port 0xa46a Read: D/A converter control
|
||||
LOG_MSG("read port a468h: Always return 0xB2");
|
||||
return 0xB2;
|
||||
}
|
||||
|
||||
static Bitu pcm86_ia46c(Bitu port, Bitu /*iolen*/) {
|
||||
// Port 0xa46c Read: Read FIFO
|
||||
LOG_MSG("read port a46ch: Always return 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Bitu pcm86_ia66e(Bitu port, Bitu /*iolen*/) {
|
||||
// Port 0xa66e Read: Mute control
|
||||
LOG_MSG("read port a66eh: Always return 0");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
// four I/O ports, 2 ports apart
|
||||
void cbuscore_attachsndex(UINT port, const IOOUT *out, const IOINP *inp) {
|
||||
LOG_MSG("cbuscore_attachsndex(port=0x%x)",port);
|
||||
@@ -190,7 +152,6 @@ void cbuscore_attachsndex(UINT port, const IOOUT *out, const IOINP *inp) {
|
||||
IO_RegisterWriteHandler(port+(i*2),pc98_fm86_write,IO_MB);
|
||||
cbusm.out = out[i];
|
||||
}
|
||||
IO_RegisterReadHandler(0xa460, pcm86_ia460, IO_MB);
|
||||
}
|
||||
|
||||
void pic_setirq(REG8 irq) {
|
||||
@@ -425,7 +386,7 @@ void PC98_FM_OnEnterPC98(Section *sec) {
|
||||
|
||||
if (!pc98fm_init) {
|
||||
unsigned char fmirqidx;
|
||||
//unsigned int baseio;
|
||||
unsigned int baseio;
|
||||
std::string board;
|
||||
int irq;
|
||||
|
||||
@@ -568,7 +529,8 @@ void PC98_FM_OnEnterPC98(Section *sec) {
|
||||
}
|
||||
|
||||
fmboard_bind();
|
||||
fmboard_extenable(true);
|
||||
// Set sound ID
|
||||
pcm86io_setid(baseio);
|
||||
|
||||
// WARNING: Some parts of the borrowed code assume 44100, 22050, or 11025 and
|
||||
// will misrender if given any other sample rate (especially the OPNA synth).
|
||||
@@ -580,7 +542,6 @@ void PC98_FM_OnEnterPC98(Section *sec) {
|
||||
if (was_pc98fm_init) {
|
||||
fmboard_on_reset();
|
||||
fmboard_bind(); // FIXME: Re-binds I/O ports as well
|
||||
fmboard_extenable(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,4 @@
|
||||
#include "compiler.h"
|
||||
#include "cpucore.h"
|
||||
#include "pccore.h"
|
||||
#include "iocore.h"
|
||||
#include "np2glue.h"
|
||||
#include "pcm86io.h"
|
||||
#include "sound.h"
|
||||
#include "fmboard.h"
|
||||
@@ -16,11 +13,10 @@ static const SINT32 pcm86rescue[] = {PCM86_RESCUE * 32, PCM86_RESCUE * 24,
|
||||
PCM86_RESCUE * 8, PCM86_RESCUE * 6,
|
||||
PCM86_RESCUE * 4, PCM86_RESCUE * 3};
|
||||
|
||||
|
||||
static void IOOUTCALL pcm86_oa460(UINT port, REG8 val) {
|
||||
|
||||
// TRACEOUT(("86pcm out %.4x %.2x", port, val));
|
||||
pcm86.extfunc = val;
|
||||
pcm86.soundflags = (pcm86.soundflags & 0xfe) | (val & 1);
|
||||
fmboard_extenable((REG8)(val & 1));
|
||||
(void)port;
|
||||
}
|
||||
@@ -43,33 +39,33 @@ static void IOOUTCALL pcm86_oa468(UINT port, REG8 val) {
|
||||
// TRACEOUT(("86pcm out %.4x %.2x", port, val));
|
||||
sound_sync();
|
||||
xchgbit = pcm86.fifo ^ val;
|
||||
// <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD>
|
||||
// バッファリセット判定
|
||||
if ((xchgbit & 8) && (val & 8)) {
|
||||
pcm86.readpos = 0; // <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||||
pcm86.readpos = 0; // バッファリセット
|
||||
pcm86.wrtpos = 0;
|
||||
pcm86.realbuf = 0;
|
||||
pcm86.virbuf = 0;
|
||||
pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
|
||||
pcm86.lastclock <<= 6;
|
||||
//pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
|
||||
//pcm86.lastclock <<= 6;
|
||||
}
|
||||
if ((xchgbit & 0x10) && (!(val & 0x10))) {
|
||||
pcm86.irqflag = 0;
|
||||
// pcm86.write = 0;
|
||||
// pcm86.reqirq = 0;
|
||||
}
|
||||
// <EFBFBD>T<EFBFBD><EFBFBD><EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O<EFBFBD><EFBFBD><EFBFBD>[<5B>g<EFBFBD>ύX
|
||||
// サンプリングレート変更
|
||||
if (xchgbit & 7) {
|
||||
pcm86.rescue = pcm86rescue[val & 7] << pcm86.stepbit;
|
||||
pcm86_setpcmrate(val);
|
||||
}
|
||||
#if 1 // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>d<EFBFBD><EFBFBD><EFBFBD>ȃo<EFBFBD>O....
|
||||
#if 1 // これ重大なバグ....
|
||||
pcm86.fifo = val;
|
||||
#else
|
||||
pcm86.fifo = val & (~0x10);
|
||||
#endif
|
||||
if ((xchgbit & 0x80) && (val & 0x80)) {
|
||||
pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
|
||||
pcm86.lastclock <<= 6;
|
||||
//pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
|
||||
//pcm86.lastclock <<= 6;
|
||||
}
|
||||
pcm86_setnextintr();
|
||||
(void)port;
|
||||
@@ -114,13 +110,13 @@ static void IOOUTCALL pcm86_oa46c(UINT port, REG8 val) {
|
||||
pcm86.buffer[pcm86.wrtpos] = val;
|
||||
pcm86.wrtpos = (pcm86.wrtpos + 1) & PCM86_BUFMSK;
|
||||
pcm86.realbuf++;
|
||||
// <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>I<EFBFBD>[<5B>o<EFBFBD>[<5B>t<EFBFBD><74><EFBFBD>[<5B>̊Ď<CC8A>
|
||||
// バッファオーバーフローの監視
|
||||
if (pcm86.realbuf >= PCM86_REALBUFSIZE) {
|
||||
#if 1
|
||||
pcm86.realbuf -= 4;
|
||||
pcm86.readpos = (pcm86.readpos + 4) & PCM86_BUFMSK;
|
||||
#else
|
||||
pcm86.realbuf &= 3; // align4<EFBFBD><EFBFBD><EFBFBD>߃E<EFBFBD>`
|
||||
pcm86.realbuf &= 3; // align4決めウチ
|
||||
pcm86.realbuf += PCM86_REALBUFSIZE - 4;
|
||||
#endif
|
||||
}
|
||||
@@ -132,9 +128,9 @@ static void IOOUTCALL pcm86_oa46c(UINT port, REG8 val) {
|
||||
pcm86.buffer[pcm86.wrtpos] = val;
|
||||
pcm86.wrtpos = (pcm86.wrtpos + 1) & PCM86_BUFMSK;
|
||||
pcm86.realbuf++;
|
||||
// <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>I<EFBFBD>[<5B>o<EFBFBD>[<5B>t<EFBFBD><74><EFBFBD>[<5B>̊Ď<CC8A>
|
||||
// バッファオーバーフローの監視
|
||||
if (pcm86.realbuf >= PCM86_REALBUFSIZE) {
|
||||
pcm86.realbuf &= 3; // align4<EFBFBD><EFBFBD><EFBFBD>߃E<EFBFBD>`
|
||||
pcm86.realbuf &= 3; // align4決めウチ
|
||||
pcm86.realbuf += PCM86_REALBUFSIZE - 4;
|
||||
}
|
||||
// pcm86.write = 1;
|
||||
@@ -146,17 +142,23 @@ static void IOOUTCALL pcm86_oa46c(UINT port, REG8 val) {
|
||||
|
||||
static REG8 IOINPCALL pcm86_ia460(UINT port) {
|
||||
|
||||
(void)port;
|
||||
return(0x40 | (pcm86.extfunc & 1));
|
||||
(void)port;
|
||||
return pcm86.soundflags;
|
||||
}
|
||||
|
||||
// Bit0 flips syncronizing with the sampling rate set by port A468h.
|
||||
// but I could not think of a good way to implement it.
|
||||
// NEC Windows 3.1 sound driver freeze if bit0 does not change,
|
||||
// so I have added a process to switch it on each call.
|
||||
static uint8_t lrclock;
|
||||
|
||||
static REG8 IOINPCALL pcm86_ia466(UINT port) {
|
||||
|
||||
UINT32 past;
|
||||
UINT32 cnt;
|
||||
UINT32 stepclock;
|
||||
// UINT32 past;
|
||||
// UINT32 cnt;
|
||||
// UINT32 stepclock;
|
||||
REG8 ret;
|
||||
|
||||
#if 0
|
||||
past = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
|
||||
past <<= 6;
|
||||
past -= pcm86.lastclock;
|
||||
@@ -171,11 +173,14 @@ static REG8 IOINPCALL pcm86_ia466(UINT port) {
|
||||
}
|
||||
}
|
||||
ret = ((past << 1) >= stepclock)?1:0;
|
||||
if (pcm86.virbuf >= PCM86_LOGICALBUF) { // <20>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>t<EFBFBD><74>
|
||||
#endif
|
||||
lrclock ^= 1;
|
||||
ret = lrclock & 1;
|
||||
if (pcm86.realbuf >= PCM86_REALBUFSIZE) { // バッファフル
|
||||
ret |= 0x80;
|
||||
}
|
||||
else if (!pcm86.virbuf) { // <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>O
|
||||
ret |= 0x40; // <EFBFBD><EFBFBD><EFBFBD>ƕρc
|
||||
else if (!pcm86.realbuf) { // バッファ0
|
||||
ret |= 0x40; // ちと変…
|
||||
}
|
||||
(void)port;
|
||||
// TRACEOUT(("86pcm in %.4x %.2x", port, ret));
|
||||
@@ -191,7 +196,7 @@ static REG8 IOINPCALL pcm86_ia468(UINT port) {
|
||||
if (pcm86gen_intrq()) {
|
||||
ret |= 0x10;
|
||||
}
|
||||
#elif 1 // <EFBFBD>ނ<EFBFBD><EFBFBD>낱<EFBFBD><EFBFBD><EFBFBD>H
|
||||
#elif 1 // むしろこう?
|
||||
if (pcm86.fifo & 0x20) {
|
||||
sound_sync();
|
||||
if (pcm86.virbuf <= pcm86.fifosize) {
|
||||
@@ -231,26 +236,33 @@ static REG8 IOINPCALL pcm86_inpdummy(UINT port) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
static const IOOUT pcm86_o1[4] = {
|
||||
pcm86_oa460, NULL, NULL, NULL };
|
||||
|
||||
// ----
|
||||
static const IOINP pcm86_i1[4] = {
|
||||
pcm86_ia460, NULL, NULL, NULL};
|
||||
|
||||
static const IOOUT pcm86_o2[4] = {
|
||||
pcm86_oa466, pcm86_oa468, pcm86_oa46a, pcm86_oa46c };
|
||||
|
||||
static const IOINP pcm86_i2[4] = {
|
||||
pcm86_ia466, pcm86_ia468, pcm86_ia46a, pcm86_inpdummy};
|
||||
|
||||
void pcm86io_bind(void) {
|
||||
|
||||
sound_streamregist(&pcm86, (SOUNDCB)pcm86gen_getpcm);
|
||||
|
||||
iocore_attachout(0xa460, pcm86_oa460);
|
||||
iocore_attachout(0xa466, pcm86_oa466);
|
||||
iocore_attachout(0xa468, pcm86_oa468);
|
||||
iocore_attachout(0xa46a, pcm86_oa46a);
|
||||
iocore_attachout(0xa46c, pcm86_oa46c);
|
||||
|
||||
iocore_attachinp(0xa460, pcm86_ia460);
|
||||
iocore_attachinp(0xa462, pcm86_inpdummy);
|
||||
iocore_attachinp(0xa464, pcm86_inpdummy);
|
||||
iocore_attachinp(0xa466, pcm86_ia466);
|
||||
iocore_attachinp(0xa468, pcm86_ia468);
|
||||
iocore_attachinp(0xa46a, pcm86_ia46a);
|
||||
iocore_attachinp(0xa46c, pcm86_inpdummy);
|
||||
iocore_attachinp(0xa46e, pcm86_inpdummy);
|
||||
//sound_streamregist(&pcm86, (SOUNDCB)pcm86gen_getpcm);
|
||||
cbuscore_attachsndex(0xa460, pcm86_o1, pcm86_i1);
|
||||
cbuscore_attachsndex(0xa466, pcm86_o2, pcm86_i2);
|
||||
}
|
||||
|
||||
void pcm86io_setid(unsigned int baseio)
|
||||
{
|
||||
if(baseio == 0x288) {
|
||||
// PC-9801-86 port=028xh
|
||||
pcm86.soundflags = 0x50;
|
||||
} else {
|
||||
// PC-9801-86 port=018xh
|
||||
pcm86.soundflags = 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -46,7 +46,7 @@ typedef struct {
|
||||
UINT stepmask;
|
||||
|
||||
UINT8 fifo;
|
||||
UINT8 extfunc;
|
||||
UINT8 soundflags; /*!< <20>T<EFBFBD>E<EFBFBD><45><EFBFBD>h <20>t<EFBFBD><74><EFBFBD>O (A460) */
|
||||
UINT8 dactrl;
|
||||
UINT8 _write;
|
||||
UINT8 stepbit;
|
||||
|
@@ -120,6 +120,11 @@ void pcm86_setnextintr(void) {
|
||||
}
|
||||
|
||||
void SOUNDCALL pcm86gen_checkbuf(void) {
|
||||
if (pcm86.realbuf <= pcm86.fifosize) {
|
||||
pcm86.reqirq = 0;
|
||||
pcm86.irqflag = 1;
|
||||
pic_setirq(fmtimer.irq);
|
||||
}
|
||||
#if 0
|
||||
long bufs;
|
||||
UINT32 past;
|
||||
@@ -165,7 +170,7 @@ BOOL pcm86gen_intrq(void) {
|
||||
}
|
||||
if (pcm86.fifo & 0x20) {
|
||||
sound_sync();
|
||||
if ((pcm86.reqirq) && (pcm86.virbuf <= pcm86.fifosize)) {
|
||||
if ((pcm86.reqirq) && (pcm86.realbuf <= pcm86.fifosize)) {
|
||||
pcm86.reqirq = 0;
|
||||
pcm86.irqflag = 1;
|
||||
return(TRUE);
|
||||
|
@@ -1167,6 +1167,7 @@ for /d %%i in ($(SolutionDir)\..\contrib\translations\*) do copy %%i\*.lng "$(Ou
|
||||
<ClCompile Include="..\src\hardware\serialport\serialfile.cpp" />
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board26k.c" />
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board86.c" />
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\cbus\pcm86io.c" />
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\common\parts.c" />
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\generic\keydisp.c" />
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\sound\adpcmc.c" />
|
||||
@@ -1807,6 +1808,7 @@ for /d %%i in ($(SolutionDir)\..\contrib\translations\*) do copy %%i\*.lng "$(Ou
|
||||
<ClInclude Include="..\src\hardware\serialport\softmodem.h" />
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\cbus\board26k.h" />
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\cbus\board86.h" />
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\cbus\pcm86io.h" />
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\common\parts.h" />
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\common\profile.h" />
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\common\wavefile.h" />
|
||||
|
@@ -1596,6 +1596,9 @@
|
||||
<ClCompile Include="..\src\misc\mkdir_p.cpp">
|
||||
<Filter>Sources\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\hardware\snd_pc98\cbus\pcm86io.c">
|
||||
<Filter>Sources\hardware\snd_pc98\cbus</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\aviwriter\avi.h">
|
||||
@@ -2531,6 +2534,9 @@
|
||||
<ClInclude Include="..\src\libs\mt32\Display.h">
|
||||
<Filter>Sources\libs\mt32</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\hardware\snd_pc98\cbus\pcm86io.h">
|
||||
<Filter>Sources\hardware\snd_pc98\cbus</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\src\winres.rc">
|
||||
|
Reference in New Issue
Block a user