mirror of
https://github.com/libretro/NP2kai.git
synced 2024-10-07 06:43:29 +00:00
Merge NP21/W rev.36
This commit is contained in:
parent
8875c9c80d
commit
896fd5a93b
13
README.md
13
README.md
@ -1,6 +1,6 @@
|
||||
Neko Project II 0.86 kai rev.13
|
||||
Neko Project II 0.86 kai rev.14
|
||||
===
|
||||
Oct 2, 2017
|
||||
Oct 21, 2017
|
||||
|
||||
Build SDL2 port
|
||||
---
|
||||
@ -300,6 +300,14 @@ I/O:0x00D0
|
||||
|
||||
Release
|
||||
---
|
||||
* Oct 21, 2017 (rev.14)
|
||||
- Merge NP21/w rev.36
|
||||
* Mate-X PCM
|
||||
* Sound Blaster 16
|
||||
* OPL3 (MAME codes is GPL licence)
|
||||
* Auto IDE BIOS
|
||||
* Oct 16, 2017 (rev.13)
|
||||
- Refix BEEP PCM
|
||||
* Oct 2, 2017 (rev.13)
|
||||
- remove CDDA mod
|
||||
* Sep 20, 2017
|
||||
@ -316,7 +324,6 @@ Release
|
||||
- [libretro] state save/load
|
||||
* Aug 23, 2017 (rev.10)
|
||||
- Merge NP21/w rev.35 beta1
|
||||
* SB16
|
||||
* Aug 22, 2017
|
||||
- Merge 私家
|
||||
Merged
|
||||
|
14
bios/bios.c
14
bios/bios.c
@ -27,6 +27,7 @@
|
||||
#if defined(SUPPORT_HRTIMER)
|
||||
#include "timemng.h"
|
||||
#endif
|
||||
#include "fmboard.h"
|
||||
|
||||
#define BIOS_SIMULATE
|
||||
|
||||
@ -97,8 +98,8 @@ static void bios_reinitbyswitch(void) {
|
||||
UINT8 biosflag;
|
||||
UINT8 extmem; // LARGE_MEM //UINT16 extmem;
|
||||
UINT8 boot;
|
||||
FILEH fh;
|
||||
OEMCHAR path[MAX_PATH];
|
||||
//FILEH fh;
|
||||
//OEMCHAR path[MAX_PATH];
|
||||
|
||||
if (!(pccore.dipsw[2] & 0x80)) {
|
||||
#if defined(CPUCORE_IA32)
|
||||
@ -483,8 +484,13 @@ UINT MEMCALL biosfunc(UINT32 adrs) {
|
||||
bios_screeninit();
|
||||
if (((pccore.model & PCMODELMASK) >= PCMODEL_VX) &&
|
||||
(pccore.sound & 0x7e)) {
|
||||
iocore_out8(0x188, 0x27);
|
||||
iocore_out8(0x18a, 0x3f);
|
||||
if(g_nSoundID == SOUNDID_MATE_X_PCM || g_nSoundID == SOUNDID_PC_9801_118 || g_nSoundID == SOUNDID_PC_9801_86_WSS){
|
||||
iocore_out8(0x188, 0x27);
|
||||
iocore_out8(0x18a, 0x30);
|
||||
}else{
|
||||
iocore_out8(0x188, 0x27);
|
||||
iocore_out8(0x18a, 0x3f);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
341
cbus/board118.c
341
cbus/board118.c
@ -12,9 +12,81 @@
|
||||
#include "sound/fmboard.h"
|
||||
#include "sound/sound.h"
|
||||
#include "sound/soundrom.h"
|
||||
#include "mpu98ii.h"
|
||||
|
||||
|
||||
static int opna_idx = 0;
|
||||
|
||||
/* for OPL */
|
||||
|
||||
#ifdef USE_MAME
|
||||
static void *opl3;
|
||||
static int samplerate;
|
||||
void *YMF262Init(INT clock, INT rate);
|
||||
void YMF262ResetChip(void *chip);
|
||||
void YMF262Shutdown(void *chip);
|
||||
INT YMF262Write(void *chip, INT a, INT v);
|
||||
UINT8 YMF262Read(void *chip, INT a);
|
||||
void YMF262UpdateOne(void *chip, INT16 **buffer, INT length);
|
||||
|
||||
static void IOOUTCALL sb16_o20d2(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.addr = dat;
|
||||
g_opl3.s.addrl = dat; // Key Display用
|
||||
YMF262Write(opl3, 0, dat);
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o21d2(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.reg[g_opl.addr] = dat;
|
||||
//S98_put(NORMAL2608, g_opl.addr, dat);
|
||||
opl3_writeRegister(&g_opl3, g_opl3.s.addrl, dat); // Key Display用
|
||||
YMF262Write(opl3, 1, dat);
|
||||
}
|
||||
static void IOOUTCALL sb16_o22d2(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.addr2 = dat;
|
||||
g_opl3.s.addrh = dat; // Key Display用
|
||||
YMF262Write(opl3, 2, dat);
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o23d2(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.reg[g_opl.addr2 + 0x100] = dat;
|
||||
opl3_writeExtendedRegister(&g_opl3, g_opl3.s.addrh, dat); // Key Display用
|
||||
//S98_put(EXTEND2608, opl.addr2, dat);
|
||||
YMF262Write(opl3, 3, dat);
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o28d2(UINT port, REG8 dat) {
|
||||
/**
|
||||
* いわゆるPC/ATで言うところのAdlib互換ポート
|
||||
* UltimaUnderWorldではこちらを叩く
|
||||
*/
|
||||
port = dat;
|
||||
YMF262Write(opl3, 0, dat);
|
||||
}
|
||||
static void IOOUTCALL sb16_o29d2(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
YMF262Write(opl3, 1, dat);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i20d2(UINT port) {
|
||||
(void)port;
|
||||
return YMF262Read(opl3, 0);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i22d2(UINT port) {
|
||||
(void)port;
|
||||
return YMF262Read(opl3, 1);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i28d2(UINT port) {
|
||||
(void)port;
|
||||
return YMF262Read(opl3, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void IOOUTCALL ymf_o188(UINT port, REG8 dat)
|
||||
{
|
||||
g_opna[opna_idx].s.addrl = dat;
|
||||
@ -41,6 +113,7 @@ static void IOOUTCALL ymf_o18a(UINT port, REG8 dat)
|
||||
(void)port;
|
||||
}
|
||||
|
||||
|
||||
static void IOOUTCALL ymf_o18c(UINT port, REG8 dat)
|
||||
{
|
||||
if (g_opna[opna_idx].s.extend)
|
||||
@ -142,7 +215,18 @@ static REG8 IOINPCALL ymf_ia460(UINT port)
|
||||
return (0x80 | (cs4231.extfunc & 1));
|
||||
}
|
||||
}
|
||||
char srnf;
|
||||
static void IOOUTCALL srnf_oa460(UINT port, REG8 dat)
|
||||
{
|
||||
srnf = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL srnf_ia460(UINT port)
|
||||
{
|
||||
(void)port;
|
||||
return (srnf);
|
||||
}
|
||||
|
||||
|
||||
static REG8 IOINPCALL wss_i881e(UINT port)
|
||||
@ -179,33 +263,16 @@ static REG8 IOINPCALL wss_i548f(UINT port)
|
||||
else return 0;// from PC-9821Nr166
|
||||
}
|
||||
|
||||
/*static REG8 IOINPCALL wss_ff(UINT port)
|
||||
{
|
||||
(void)port;
|
||||
return (0xFF);
|
||||
}*/
|
||||
|
||||
static REG8 IOINPCALL wss_i148c(UINT port)
|
||||
{
|
||||
return (0xFE);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL wss_i148d(UINT port)
|
||||
{
|
||||
|
||||
return (0x80);
|
||||
}
|
||||
|
||||
|
||||
static void IOOUTCALL ym_o1488(UINT port, REG8 dat) //FM Music Register Address Port
|
||||
{
|
||||
g_opl3.s.addrl = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
REG8 opl_data;
|
||||
static void IOOUTCALL ym_o1489(UINT port, REG8 dat) //FM Music Data Port
|
||||
{
|
||||
opl3_writeRegister(&g_opl3, g_opl3.s.addrl, dat);
|
||||
opl_data = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
@ -223,46 +290,72 @@ static void IOOUTCALL ym_o148b(UINT port, REG8 dat) //Advanced FM Music Data Por
|
||||
|
||||
static REG8 IOINPCALL ym_i1488(UINT port) //FM Music Status Port
|
||||
{
|
||||
TRACEOUT(("%x read",port));
|
||||
// if (opl_data == 0x80) return 0xe0;
|
||||
if (opl_data == 0x21) return 0xc0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL ym_i1489(UINT port) // ???
|
||||
{
|
||||
TRACEOUT(("%x read",port));
|
||||
return opl3_readRegister(&g_opl3, g_opl3.s.addrl);
|
||||
}
|
||||
static REG8 IOINPCALL ym_i148a(UINT port) //Advanced FM Music Status Port
|
||||
{
|
||||
TRACEOUT(("%x read",port));
|
||||
return opl3_readStatus(&g_opl3);
|
||||
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL ym_i148b(UINT port) // ???
|
||||
{
|
||||
TRACEOUT(("%x read",port));
|
||||
return opl3_readExtendedRegister(&g_opl3, g_opl3.s.addrh);
|
||||
}
|
||||
|
||||
REG8 sound118;
|
||||
static void IOOUTCALL csctrl_o148e(UINT port, REG8 dat) {
|
||||
TRACEOUT(("write %x %x",port,dat));
|
||||
sound118 = dat;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL csctrl_i148e(UINT port) {
|
||||
return(sound118);
|
||||
TRACEOUT(("%x read",port));
|
||||
}
|
||||
REG8 control118;
|
||||
static REG8 IOINPCALL csctrl_i148f(UINT port) {
|
||||
|
||||
TRACEOUT(("%x read",port));
|
||||
(void)port;
|
||||
if(sound118 == 0) return(0x03);
|
||||
if(sound118 == 0x05) {
|
||||
if(control118 == 0x04)return (0x04);
|
||||
else if(control118 == 0) return 0;}
|
||||
if(sound118 == 0) return(0x3);//PC-9801-118は3だけどYMFは0xff 2000はこれだけじゃまだダメ
|
||||
if(sound118 == 0x05){
|
||||
if(control118==4)return 4;
|
||||
if(control118==0x0c) return 4;
|
||||
if(control118==0)return 0;
|
||||
}
|
||||
if(sound118 == 0x04) return (0x00);
|
||||
if(sound118 == 0x21) return (0x00);
|
||||
if(sound118 == 0xff) return (0x00);
|
||||
if(sound118 == 0x21) switch(0x00/*mpu98.irqnum2*/){//MIDI割り込み 00:IRQ10 01:IRQ6 02:IRQ5 03:IRQ3
|
||||
case 10:return 0;
|
||||
case 6: return 1;
|
||||
case 5: return 2;
|
||||
case 3: return 3;
|
||||
default: return 0;
|
||||
}
|
||||
if(sound118 == 0xff) return (0x05);//bit0 MIDI割り込みあり bit1:Cb Na7 bit2:Mate-X bit3:A-Mate Ce2
|
||||
else
|
||||
return(0xff);
|
||||
}
|
||||
|
||||
static void IOOUTCALL csctrl_o148f(UINT port, REG8 dat) {
|
||||
TRACEOUT(("write %x %x",port,dat));
|
||||
|
||||
//if (sound118 == 0x21) switch(dat){
|
||||
// case 0:mpu98.irqnum2 = 10;break;
|
||||
// case 1:mpu98.irqnum2 = 6;break;
|
||||
// case 2:mpu98.irqnum2 = 5;break;
|
||||
// case 3:mpu98.irqnum2 = 3;break;
|
||||
// default: break;
|
||||
//}
|
||||
control118 = dat;
|
||||
}
|
||||
/*
|
||||
@ -317,15 +410,62 @@ static REG8 IOINPCALL csctrl_i486(UINT port) {
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb98_i2ad2(UINT port) {
|
||||
TRACEOUT(("%x read",port));
|
||||
return(0xaa);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb98_i2ed2(UINT port) {
|
||||
TRACEOUT(("%x read",port));
|
||||
return(0xff);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb98_i81d2(UINT port) {
|
||||
// TRACEOUT(("%x read",port));
|
||||
return(0xbf);
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
|
||||
#ifdef USE_MAME
|
||||
static SINT32 oplfm_softvolume_L = 0;
|
||||
static SINT32 oplfm_softvolume_R = 0;
|
||||
static SINT32 oplfm_softvolumereg_L = 0xff;
|
||||
static SINT32 oplfm_softvolumereg_R = 0xff;
|
||||
void SOUNDCALL opl3gen_getpcm2(void* opl3, SINT32 *pcm, UINT count) {
|
||||
UINT i;
|
||||
INT16 *buf[4];
|
||||
INT16 s1l,s1r,s2l,s2r;
|
||||
SINT32 oplfm_volume;
|
||||
SINT32 *outbuf = pcm;
|
||||
buf[0] = &s1l;
|
||||
buf[1] = &s1r;
|
||||
buf[2] = &s2l;
|
||||
buf[3] = &s2r;
|
||||
oplfm_volume = np2cfg.vol_fm;
|
||||
if(oplfm_softvolumereg_L != cs4231.devvolume[0x30]){
|
||||
oplfm_softvolumereg_L = cs4231.devvolume[0x30];
|
||||
if(oplfm_softvolumereg_L & 0x80){ // FM L Mute
|
||||
oplfm_softvolume_L = 0;
|
||||
}else{
|
||||
oplfm_softvolume_L = ((~oplfm_softvolumereg_L) & 0x1f); // FM L Volume
|
||||
}
|
||||
}
|
||||
if(oplfm_softvolumereg_R != cs4231.devvolume[0x31]){
|
||||
oplfm_softvolumereg_R = cs4231.devvolume[0x31];
|
||||
if(oplfm_softvolumereg_R & 0x80){ // FM R Mute
|
||||
oplfm_softvolume_R = 0;
|
||||
}else{
|
||||
oplfm_softvolume_R = ((~oplfm_softvolumereg_R) & 0x1f); // FM R Volume
|
||||
}
|
||||
}
|
||||
for (i=0; i < count; i++) {
|
||||
s1l = s1r = s2l = s2r = 0;
|
||||
YMF262UpdateOne(opl3, buf, 1);
|
||||
outbuf[0] += (SINT32)(((s1l << 1) * oplfm_volume * oplfm_softvolume_L) >> 10);
|
||||
outbuf[1] += (SINT32)(((s1r << 1) * oplfm_volume * oplfm_softvolume_R) >> 10);
|
||||
outbuf += 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static const IOOUT ymf_o[4] = {
|
||||
ymf_o188, ymf_o18a, ymf_o18c, ymf_o18e};
|
||||
|
||||
@ -356,6 +496,25 @@ void board118_reset(const NP2CFG *pConfig)
|
||||
cs4231io_reset();
|
||||
soundrom_load(0xcc000, OEMTEXT("118"));
|
||||
fmboard_extreg(extendchannel);
|
||||
#ifdef SUPPORT_SOUND_SB16
|
||||
#ifdef USE_MAME
|
||||
if (opl3) {
|
||||
if (samplerate != pConfig->samplingrate) {
|
||||
YMF262Shutdown(opl3);
|
||||
opl3 = YMF262Init(14400000, pConfig->samplingrate);
|
||||
samplerate = pConfig->samplingrate;
|
||||
} else {
|
||||
YMF262ResetChip(opl3);
|
||||
}
|
||||
}
|
||||
ZeroMemory(&g_sb16, sizeof(g_sb16));
|
||||
ZeroMemory(&g_opl, sizeof(g_opl));
|
||||
// ボードデフォルト IO:D2 DMA:3 INT:5
|
||||
g_sb16.base = 0xd2;
|
||||
g_sb16.dmach = 0x3;
|
||||
g_sb16.dmairq = 0x5;
|
||||
#endif
|
||||
#endif
|
||||
(void)pConfig;
|
||||
}
|
||||
|
||||
@ -364,96 +523,62 @@ void board118_reset(const NP2CFG *pConfig)
|
||||
*/
|
||||
void board118_bind(void)
|
||||
{
|
||||
cs4231io_bind();
|
||||
if(g_nSoundID==SOUNDID_PC_9801_86_WSS){
|
||||
opna_idx = 1;
|
||||
}else{
|
||||
opna_idx = 0;
|
||||
}
|
||||
if(g_nSoundID==SOUNDID_PC_9801_86_WSS){
|
||||
opna_bind(&g_opna[opna_idx]);
|
||||
cs4231io_bind();
|
||||
//cbuscore_attachsndex(0x188, ymf_o, ymf_i);
|
||||
|
||||
iocore_attachout(0xb460, ymf_oa460);
|
||||
iocore_attachinp(0xb460, ymf_ia460);
|
||||
|
||||
//iocore_attachout(0x1488, ym_o1488);
|
||||
//iocore_attachinp(0x1488, ym_i1488);
|
||||
//iocore_attachout(0x1489, ym_o1489);
|
||||
//iocore_attachout(0x148a, ym_o148a);
|
||||
//iocore_attachout(0x148b, ym_o148b);
|
||||
opl3_bind(&g_opl3);
|
||||
|
||||
//iocore_attachout(0x148e,csctrl_o148e);
|
||||
//iocore_attachinp(0x148e,csctrl_i148e);
|
||||
//iocore_attachout(0x148f,csctrl_o148f);
|
||||
//iocore_attachinp(0x148f,csctrl_i148f);
|
||||
//iocore_attachout(0x548e, wss_o548e);// YMF-701
|
||||
//iocore_attachinp(0x548e, wss_i548e);// YMF-701
|
||||
//iocore_attachinp(0x548f, wss_i548f);// YMF-701
|
||||
|
||||
//iocore_attachinp(0x486,csctrl_i486);
|
||||
//iocore_attachinp(0x1480, ymf_ia460);
|
||||
//iocore_attachinp(0x1481, ymf_ia460);
|
||||
//
|
||||
////偽SB-16 mode
|
||||
// iocore_attachout(0x20d2, ym_o1488);//sb16 opl
|
||||
// iocore_attachinp(0x20d2, ym_i1488);//sb16 opl
|
||||
// iocore_attachout(0x21d2, ym_o1489);//sb16 opl
|
||||
// iocore_attachout(0x22d2, ym_o148a);//sb16 opl3
|
||||
// iocore_attachout(0x23d2, ym_o148b);//sb16 opl3
|
||||
// iocore_attachout(0x28d2, ym_o1488);//sb16 opl?
|
||||
// iocore_attachinp(0x28d2, ym_i1488);//sb16 opl
|
||||
// iocore_attachout(0x29d2, ym_o1489);//sb16 opl?
|
||||
// iocore_attachinp(0x81d2, csctrl_i486);// sb16 midi port
|
||||
// iocore_attachinp(0x2ad2, sb98_i2ad2);// DSP Read Data Port
|
||||
// iocore_attachinp(0x2ed2, sb98_i2ed2);// DSP Read Buffer Status (Bit 7)
|
||||
|
||||
//iocore_attachinp(0x881e, wss_i881e);
|
||||
//iocore_attachinp(0x148c, wss_i148c);
|
||||
//iocore_attachinp(0x148d, wss_i148d);
|
||||
if(g_nSoundID==SOUNDID_PC_9801_86_WSS || g_nSoundID==SOUNDID_MATE_X_PCM){
|
||||
iocore_attachout(cs4231.port[1], ymf_oa460);
|
||||
iocore_attachinp(cs4231.port[1], ymf_ia460);
|
||||
iocore_attachinp(0x881e, wss_i881e);
|
||||
}else{
|
||||
opna_bind(&g_opna[opna_idx]);
|
||||
cs4231io_bind();
|
||||
cbuscore_attachsndex(0x188, ymf_o, ymf_i);
|
||||
cbuscore_attachsndex(cs4231.port[4],ymf_o, ymf_i);
|
||||
|
||||
#ifdef USE_MAME
|
||||
iocore_attachout(cs4231.port[9], sb16_o20d2);
|
||||
iocore_attachinp(cs4231.port[9], sb16_i20d2);
|
||||
iocore_attachout(cs4231.port[9]+1, sb16_o21d2);
|
||||
iocore_attachout(cs4231.port[9]+2, sb16_o22d2);
|
||||
iocore_attachout(cs4231.port[9]+3, sb16_o23d2);
|
||||
|
||||
iocore_attachout(0x1488, ym_o1488);
|
||||
iocore_attachinp(0x1488, ym_i1488);
|
||||
iocore_attachout(0x1489, ym_o1489);
|
||||
iocore_attachout(0x148a, ym_o148a);
|
||||
iocore_attachout(0x148b, ym_o148b);
|
||||
opl3_bind(&g_opl3);
|
||||
if (!opl3) {
|
||||
opl3 = YMF262Init(14400000, np2cfg.samplingrate);
|
||||
samplerate = np2cfg.samplingrate;
|
||||
}
|
||||
sound_streamregist(opl3, (SOUNDCB)opl3gen_getpcm2);
|
||||
#else
|
||||
iocore_attachout(cs4231.port[9], ym_o1488);
|
||||
iocore_attachinp(cs4231.port[9], ym_i1488);
|
||||
iocore_attachout(cs4231.port[9]+1, ym_o1489);
|
||||
iocore_attachout(cs4231.port[9]+2, ym_o148a);
|
||||
iocore_attachout(cs4231.port[9]+3, ym_o148b);
|
||||
#endif
|
||||
opl3_bind(&g_opl3); // MAME使用の場合Key Display用
|
||||
|
||||
iocore_attachout(0xa460, ymf_oa460);
|
||||
iocore_attachinp(0xa460, ymf_ia460);
|
||||
iocore_attachout(cs4231.port[1], ymf_oa460);
|
||||
iocore_attachinp(cs4231.port[1], ymf_ia460);
|
||||
|
||||
iocore_attachout(0x148e,csctrl_o148e);
|
||||
iocore_attachinp(0x148e,csctrl_i148e);
|
||||
iocore_attachout(0x148f,csctrl_o148f);
|
||||
iocore_attachinp(0x148f,csctrl_i148f);
|
||||
iocore_attachout(0x548e, wss_o548e);// YMF-701
|
||||
iocore_attachinp(0x548e, wss_i548e);// YMF-701
|
||||
iocore_attachinp(0x548f, wss_i548f);// YMF-701
|
||||
|
||||
iocore_attachinp(0x486,csctrl_i486);
|
||||
iocore_attachinp(0x1480, ymf_ia460);
|
||||
iocore_attachinp(0x1481, ymf_ia460);
|
||||
|
||||
//偽SB-16 mode
|
||||
iocore_attachout(0x20d2, ym_o1488);//sb16 opl
|
||||
iocore_attachinp(0x20d2, ym_i1488);//sb16 opl
|
||||
iocore_attachout(0x21d2, ym_o1489);//sb16 opl
|
||||
iocore_attachout(0x22d2, ym_o148a);//sb16 opl3
|
||||
iocore_attachout(0x23d2, ym_o148b);//sb16 opl3
|
||||
iocore_attachout(0x28d2, ym_o1488);//sb16 opl?
|
||||
iocore_attachinp(0x28d2, ym_i1488);//sb16 opl
|
||||
iocore_attachout(0x29d2, ym_o1489);//sb16 opl?
|
||||
iocore_attachinp(0x81d2, csctrl_i486);// sb16 midi port
|
||||
iocore_attachinp(0x2ad2, sb98_i2ad2);// DSP Read Data Port
|
||||
iocore_attachinp(0x2ed2, sb98_i2ed2);// DSP Read Buffer Status (Bit 7)
|
||||
//iocore_attachout(cs4231.port[15],srnf_oa460);//SRN-Fは必要なときだけ使う
|
||||
//iocore_attachinp(cs4231.port[15],srnf_ia460);
|
||||
//srnf = 0x81;
|
||||
|
||||
iocore_attachout(cs4231.port[14],csctrl_o148e);
|
||||
iocore_attachinp(cs4231.port[14],csctrl_i148e);
|
||||
iocore_attachout(cs4231.port[14]+1,csctrl_o148f);
|
||||
iocore_attachinp(cs4231.port[14]+1,csctrl_i148f);
|
||||
iocore_attachout(cs4231.port[6], wss_o548e);// YMF-701
|
||||
iocore_attachinp(cs4231.port[6], wss_i548e);// YMF-701
|
||||
iocore_attachinp(cs4231.port[6]+1, wss_i548f);// YMF-701
|
||||
iocore_attachinp(cs4231.port[11]+6,csctrl_i486);
|
||||
iocore_attachinp(0x881e, wss_i881e);
|
||||
iocore_attachinp(0x148c, wss_i148c);
|
||||
iocore_attachinp(0x148d, wss_i148d);
|
||||
// iocore_attachout(cs4231.port[10], mpu98ii_o0);//MIDI PORT mpu98ii.c側で調整
|
||||
// iocore_attachinp(cs4231.port[10], mpu98ii_i0);
|
||||
// iocore_attachout(cs4231.port[10]+1, mpu98ii_o2);
|
||||
// iocore_attachinp(cs4231.port[10]+1, mpu98ii_i2);
|
||||
//mpu98.irqnum = mpu98.irqnum2;
|
||||
|
||||
}
|
||||
}
|
||||
|
447
cbus/boardsb16.c
447
cbus/boardsb16.c
@ -1,206 +1,243 @@
|
||||
#include "compiler.h"
|
||||
#include "pccore.h"
|
||||
#include "iocore.h"
|
||||
#include "cbuscore.h"
|
||||
#include "boardso.h"
|
||||
#include "sound.h"
|
||||
#include "ct1741io.h"
|
||||
#include "ct1745io.h"
|
||||
#include "fmboard.h"
|
||||
//#include "s98.h"
|
||||
|
||||
#ifdef SUPPORT_SOUND_SB16
|
||||
|
||||
/**
|
||||
* Creative Sound Blaster 16(98)
|
||||
* YMF262-M(OPL3) + CT1741(PCM) + CT1745(MIXER) + YM2203(OPN - option)
|
||||
*
|
||||
* 現状は以下の固定仕様で動く IO:D2 DMA:3 INT:5
|
||||
*/
|
||||
|
||||
static void *opl3;
|
||||
static const UINT8 sb16base[] = {0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde};
|
||||
static int samplerate;
|
||||
|
||||
void *YMF262Init(INT clock, INT rate);
|
||||
void YMF262ResetChip(void *chip);
|
||||
void YMF262Shutdown(void *chip);
|
||||
INT YMF262Write(void *chip, INT a, INT v);
|
||||
UINT8 YMF262Read(void *chip, INT a);
|
||||
void YMF262UpdateOne(void *chip, INT16 **buffer, INT length);
|
||||
|
||||
static void IOOUTCALL sb16_o0400(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o0500(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o0600(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o0700(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o8000(UINT port, REG8 dat) {
|
||||
/* MIDI Data Port */
|
||||
// TRACEOUT(("SB16-midi commands: %.2x", dat));
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o8100(UINT port, REG8 dat) {
|
||||
/* MIDI Stat Port */
|
||||
// TRACEOUT(("SB16-midi status: %.2x", dat));
|
||||
port = dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2000(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.addr = dat;
|
||||
YMF262Write(opl3, 0, dat);
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2100(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.reg[g_opl.addr] = dat;
|
||||
//S98_put(NORMAL2608, g_opl.addr, dat);
|
||||
YMF262Write(opl3, 1, dat);
|
||||
}
|
||||
static void IOOUTCALL sb16_o2200(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.addr2 = dat;
|
||||
YMF262Write(opl3, 2, dat);
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2300(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.reg[g_opl.addr2 + 0x100] = dat;
|
||||
//S98_put(EXTEND2608, opl.addr2, dat);
|
||||
YMF262Write(opl3, 3, dat);
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2800(UINT port, REG8 dat) {
|
||||
/**
|
||||
* いわゆるPC/ATで言うところのAdlib互換ポート
|
||||
* UltimaUnderWorldではこちらを叩く
|
||||
*/
|
||||
port = dat;
|
||||
YMF262Write(opl3, 0, dat);
|
||||
}
|
||||
static void IOOUTCALL sb16_o2900(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
YMF262Write(opl3, 1, dat);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i0400(UINT port) {
|
||||
return 0xff;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i0500(UINT port) {
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i0600(UINT port) {
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i0700(UINT port) {
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i8000(UINT port) {
|
||||
/* Midi Port */
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i8100(UINT port) {
|
||||
/* Midi Port */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static REG8 IOINPCALL sb16_i2000(UINT port) {
|
||||
(void)port;
|
||||
return YMF262Read(opl3, 0);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i2200(UINT port) {
|
||||
(void)port;
|
||||
return YMF262Read(opl3, 1);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i2800(UINT port) {
|
||||
(void)port;
|
||||
return YMF262Read(opl3, 0);
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
void SOUNDCALL opl3gen_getpcm(void* opl3, SINT32 *pcm, UINT count) {
|
||||
UINT i;
|
||||
INT16 *buf[4];
|
||||
INT16 s1l,s1r,s2l,s2r;
|
||||
SINT32 *outbuf = pcm;
|
||||
buf[0] = &s1l;
|
||||
buf[1] = &s1r;
|
||||
buf[2] = &s2l;
|
||||
buf[3] = &s2r;
|
||||
for (i=0; i < count; i++) {
|
||||
s1l = s1r = s2l = s2r = 0;
|
||||
YMF262UpdateOne(opl3, buf, 1);
|
||||
outbuf[0] += s1l << 1;
|
||||
outbuf[1] += s1r << 1;
|
||||
outbuf += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void boardsb16_reset(const NP2CFG *pConfig) {
|
||||
if (opl3) {
|
||||
if (samplerate != pConfig->samplingrate) {
|
||||
YMF262Shutdown(opl3);
|
||||
opl3 = YMF262Init(14400000, pConfig->samplingrate);
|
||||
samplerate = pConfig->samplingrate;
|
||||
} else {
|
||||
YMF262ResetChip(opl3);
|
||||
}
|
||||
}
|
||||
ZeroMemory(&g_sb16, sizeof(g_sb16));
|
||||
ZeroMemory(&g_opl, sizeof(g_opl));
|
||||
// ボードデフォルト IO:D2 DMA:3 INT:5
|
||||
g_sb16.base = 0xd2;
|
||||
g_sb16.dmach = 0x3;
|
||||
g_sb16.dmairq = 0x5;
|
||||
ct1745io_reset();
|
||||
ct1741io_reset();
|
||||
}
|
||||
|
||||
void boardsb16_bind(void) {
|
||||
ct1745io_bind();
|
||||
ct1741io_bind();
|
||||
|
||||
iocore_attachout(0x2000 + g_sb16.base, sb16_o2000); /* FM Music Register Address Port */
|
||||
iocore_attachout(0x2100 + g_sb16.base, sb16_o2100); /* FM Music Data Port */
|
||||
iocore_attachout(0x2200 + g_sb16.base, sb16_o2200); /* Advanced FM Music Register Address Port */
|
||||
iocore_attachout(0x2300 + g_sb16.base, sb16_o2300); /* Advanced FM Music Data Port */
|
||||
iocore_attachout(0x2800 + g_sb16.base, sb16_o2800); /* FM Music Register Port */
|
||||
iocore_attachout(0x2900 + g_sb16.base, sb16_o2900); /* FM Music Data Port */
|
||||
|
||||
iocore_attachinp(0x2000 + g_sb16.base, sb16_i2000); /* FM Music Status Port */
|
||||
iocore_attachinp(0x2200 + g_sb16.base, sb16_i2200); /* Advanced FM Music Status Port */
|
||||
iocore_attachinp(0x2800 + g_sb16.base, sb16_i2800); /* FM Music Status Port */
|
||||
|
||||
iocore_attachout(0x0400 + g_sb16.base, sb16_o0400); /* GAME Port */
|
||||
iocore_attachout(0x0500 + g_sb16.base, sb16_o0500); /* GAME Port */
|
||||
iocore_attachout(0x0600 + g_sb16.base, sb16_o0600); /* GAME Port */
|
||||
iocore_attachout(0x0700 + g_sb16.base, sb16_o0700); /* GAME Port */
|
||||
iocore_attachinp(0x0400 + g_sb16.base, sb16_i0400); /* GAME Port */
|
||||
iocore_attachinp(0x0500 + g_sb16.base, sb16_i0500); /* GAME Port */
|
||||
iocore_attachinp(0x0600 + g_sb16.base, sb16_i0600); /* GAME Port */
|
||||
iocore_attachinp(0x0700 + g_sb16.base, sb16_i0700); /* GAME Port */
|
||||
|
||||
iocore_attachout(0x8000 + g_sb16.base, sb16_o8000); /* MIDI Port */
|
||||
iocore_attachout(0x8100 + g_sb16.base, sb16_o8100); /* MIDI Port */
|
||||
iocore_attachinp(0x8000 + g_sb16.base, sb16_i8000); /* MIDI Port */
|
||||
iocore_attachinp(0x8100 + g_sb16.base, sb16_i8100); /* MIDI Port */
|
||||
|
||||
if (!opl3) {
|
||||
opl3 = YMF262Init(14400000, np2cfg.samplingrate);
|
||||
samplerate = np2cfg.samplingrate;
|
||||
}
|
||||
sound_streamregist(opl3, (SOUNDCB)opl3gen_getpcm);
|
||||
}
|
||||
|
||||
#include "compiler.h"
|
||||
#include "pccore.h"
|
||||
#include "iocore.h"
|
||||
#include "cbuscore.h"
|
||||
#include "boardso.h"
|
||||
#include "sound.h"
|
||||
#include "ct1741io.h"
|
||||
#include "ct1745io.h"
|
||||
#include "fmboard.h"
|
||||
//#include "s98.h"
|
||||
|
||||
#ifdef SUPPORT_SOUND_SB16
|
||||
|
||||
/**
|
||||
* Creative Sound Blaster 16(98)
|
||||
* YMF262-M(OPL3) + CT1741(PCM) + CT1745(MIXER) + YM2203(OPN - option)
|
||||
*
|
||||
* 現状は以下の固定仕様で動く IO:D2 DMA:3 INT:5
|
||||
*/
|
||||
|
||||
static void *opl3;
|
||||
static const UINT8 sb16base[] = {0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde};
|
||||
static int samplerate;
|
||||
|
||||
#ifdef USE_MAME
|
||||
void *YMF262Init(INT clock, INT rate);
|
||||
void YMF262ResetChip(void *chip);
|
||||
void YMF262Shutdown(void *chip);
|
||||
INT YMF262Write(void *chip, INT a, INT v);
|
||||
UINT8 YMF262Read(void *chip, INT a);
|
||||
void YMF262UpdateOne(void *chip, INT16 **buffer, INT length);
|
||||
#endif
|
||||
|
||||
static void IOOUTCALL sb16_o0400(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o0500(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o0600(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o0700(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o8000(UINT port, REG8 dat) {
|
||||
/* MIDI Data Port */
|
||||
// TRACEOUT(("SB16-midi commands: %.2x", dat));
|
||||
port = dat;
|
||||
}
|
||||
static void IOOUTCALL sb16_o8100(UINT port, REG8 dat) {
|
||||
/* MIDI Stat Port */
|
||||
// TRACEOUT(("SB16-midi status: %.2x", dat));
|
||||
port = dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2000(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.addr = dat;
|
||||
#ifdef USE_MAME
|
||||
YMF262Write(opl3, 0, dat);
|
||||
g_opl3.s.addrl = dat; // Key Display用
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2100(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.reg[g_opl.addr] = dat;
|
||||
//S98_put(NORMAL2608, g_opl.addr, dat);
|
||||
#ifdef USE_MAME
|
||||
YMF262Write(opl3, 1, dat);
|
||||
opl3_writeRegister(&g_opl3, g_opl3.s.addrl, dat); // Key Display用
|
||||
#endif
|
||||
}
|
||||
static void IOOUTCALL sb16_o2200(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.addr2 = dat;
|
||||
#ifdef USE_MAME
|
||||
YMF262Write(opl3, 2, dat);
|
||||
g_opl3.s.addrh = dat; // Key Display用
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2300(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
g_opl.reg[g_opl.addr2 + 0x100] = dat;
|
||||
//S98_put(EXTEND2608, opl.addr2, dat);
|
||||
#ifdef USE_MAME
|
||||
YMF262Write(opl3, 3, dat);
|
||||
opl3_writeExtendedRegister(&g_opl3, g_opl3.s.addrh, dat); // Key Display用
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IOOUTCALL sb16_o2800(UINT port, REG8 dat) {
|
||||
/**
|
||||
* いわゆるPC/ATで言うところのAdlib互換ポート
|
||||
* UltimaUnderWorldではこちらを叩く
|
||||
*/
|
||||
port = dat;
|
||||
#ifdef USE_MAME
|
||||
YMF262Write(opl3, 0, dat);
|
||||
#endif
|
||||
}
|
||||
static void IOOUTCALL sb16_o2900(UINT port, REG8 dat) {
|
||||
port = dat;
|
||||
#ifdef USE_MAME
|
||||
YMF262Write(opl3, 1, dat);
|
||||
#endif
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i0400(UINT port) {
|
||||
return 0xff;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i0500(UINT port) {
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i0600(UINT port) {
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i0700(UINT port) {
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i8000(UINT port) {
|
||||
/* Midi Port */
|
||||
return 0;
|
||||
}
|
||||
static REG8 IOINPCALL sb16_i8100(UINT port) {
|
||||
/* Midi Port */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static REG8 IOINPCALL sb16_i2000(UINT port) {
|
||||
(void)port;
|
||||
#ifdef USE_MAME
|
||||
return YMF262Read(opl3, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i2200(UINT port) {
|
||||
(void)port;
|
||||
#ifdef USE_MAME
|
||||
return YMF262Read(opl3, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL sb16_i2800(UINT port) {
|
||||
(void)port;
|
||||
#ifdef USE_MAME
|
||||
return YMF262Read(opl3, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
void SOUNDCALL opl3gen_getpcm(void* opl3, SINT32 *pcm, UINT count) {
|
||||
UINT i;
|
||||
INT16 *buf[4];
|
||||
INT16 s1l,s1r,s2l,s2r;
|
||||
SINT32 *outbuf = pcm;
|
||||
SINT32 oplfm_volume;
|
||||
oplfm_volume = np2cfg.vol_fm;
|
||||
buf[0] = &s1l;
|
||||
buf[1] = &s1r;
|
||||
buf[2] = &s2l;
|
||||
buf[3] = &s2r;
|
||||
for (i=0; i < count; i++) {
|
||||
s1l = s1r = s2l = s2r = 0;
|
||||
#ifdef USE_MAME
|
||||
YMF262UpdateOne(opl3, buf, 1);
|
||||
#endif
|
||||
outbuf[0] += (SINT32)(((s1l << 1) * oplfm_volume) >> 5);
|
||||
outbuf[1] += (SINT32)(((s1r << 1) * oplfm_volume) >> 5);
|
||||
outbuf += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void boardsb16_reset(const NP2CFG *pConfig) {
|
||||
if (opl3) {
|
||||
if (samplerate != pConfig->samplingrate) {
|
||||
#ifdef USE_MAME
|
||||
YMF262Shutdown(opl3);
|
||||
opl3 = YMF262Init(14400000, pConfig->samplingrate);
|
||||
#endif
|
||||
samplerate = pConfig->samplingrate;
|
||||
} else {
|
||||
#ifdef USE_MAME
|
||||
YMF262ResetChip(opl3);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
ZeroMemory(&g_sb16, sizeof(g_sb16));
|
||||
ZeroMemory(&g_opl, sizeof(g_opl));
|
||||
// ボードデフォルト IO:D2 DMA:3 INT:5
|
||||
g_sb16.base = 0xd2;
|
||||
g_sb16.dmach = 0x3;
|
||||
g_sb16.dmairq = 0x5;
|
||||
ct1745io_reset();
|
||||
ct1741io_reset();
|
||||
}
|
||||
|
||||
void boardsb16_bind(void) {
|
||||
opl3_reset(&g_opl3, OPL3_HAS_OPL3L|OPL3_HAS_OPL3);
|
||||
|
||||
ct1745io_bind();
|
||||
ct1741io_bind();
|
||||
|
||||
iocore_attachout(0x2000 + g_sb16.base, sb16_o2000); /* FM Music Register Address Port */
|
||||
iocore_attachout(0x2100 + g_sb16.base, sb16_o2100); /* FM Music Data Port */
|
||||
iocore_attachout(0x2200 + g_sb16.base, sb16_o2200); /* Advanced FM Music Register Address Port */
|
||||
iocore_attachout(0x2300 + g_sb16.base, sb16_o2300); /* Advanced FM Music Data Port */
|
||||
iocore_attachout(0x2800 + g_sb16.base, sb16_o2800); /* FM Music Register Port */
|
||||
iocore_attachout(0x2900 + g_sb16.base, sb16_o2900); /* FM Music Data Port */
|
||||
|
||||
iocore_attachinp(0x2000 + g_sb16.base, sb16_i2000); /* FM Music Status Port */
|
||||
iocore_attachinp(0x2200 + g_sb16.base, sb16_i2200); /* Advanced FM Music Status Port */
|
||||
iocore_attachinp(0x2800 + g_sb16.base, sb16_i2800); /* FM Music Status Port */
|
||||
|
||||
iocore_attachout(0x0400 + g_sb16.base, sb16_o0400); /* GAME Port */
|
||||
iocore_attachout(0x0500 + g_sb16.base, sb16_o0500); /* GAME Port */
|
||||
iocore_attachout(0x0600 + g_sb16.base, sb16_o0600); /* GAME Port */
|
||||
iocore_attachout(0x0700 + g_sb16.base, sb16_o0700); /* GAME Port */
|
||||
iocore_attachinp(0x0400 + g_sb16.base, sb16_i0400); /* GAME Port */
|
||||
iocore_attachinp(0x0500 + g_sb16.base, sb16_i0500); /* GAME Port */
|
||||
iocore_attachinp(0x0600 + g_sb16.base, sb16_i0600); /* GAME Port */
|
||||
iocore_attachinp(0x0700 + g_sb16.base, sb16_i0700); /* GAME Port */
|
||||
|
||||
iocore_attachout(0x8000 + g_sb16.base, sb16_o8000); /* MIDI Port */
|
||||
iocore_attachout(0x8100 + g_sb16.base, sb16_o8100); /* MIDI Port */
|
||||
iocore_attachinp(0x8000 + g_sb16.base, sb16_i8000); /* MIDI Port */
|
||||
iocore_attachinp(0x8100 + g_sb16.base, sb16_i8100); /* MIDI Port */
|
||||
|
||||
if (!opl3) {
|
||||
#ifdef USE_MAME
|
||||
opl3 = YMF262Init(14400000, np2cfg.samplingrate);
|
||||
#endif
|
||||
samplerate = np2cfg.samplingrate;
|
||||
}
|
||||
sound_streamregist(opl3, (SOUNDCB)opl3gen_getpcm);
|
||||
opl3_bind(&g_opl3); // MAME使用の場合Key Display用
|
||||
}
|
||||
|
||||
#endif
|
297
cbus/cs4231io.c
297
cbus/cs4231io.c
@ -8,7 +8,7 @@
|
||||
#include "fmboard.h"
|
||||
|
||||
|
||||
static const UINT8 cs4231dma[] = {0xff,0x00,0x01,0x03,0xff,0xff,0xff,0xff};
|
||||
static const UINT8 cs4231dma[] = {0xff,0x00,0x01,0x03,0xff,0x00,0x01,0x03};
|
||||
static const UINT8 cs4231irq[] = {0xff,0x03,0x06,0x0a,0x0c,0xff,0xff,0xff};
|
||||
|
||||
|
||||
@ -68,6 +68,8 @@ static REG8 IOINPCALL csctrl_ic2d(UINT port) {
|
||||
return((REG8)(cs4231.port[num] >> 8));
|
||||
}
|
||||
REG8 sa3_control;
|
||||
REG8 sa3_control;
|
||||
UINT8 sa3data[256];
|
||||
static void IOOUTCALL csctrl_o480(UINT port, REG8 dat) {
|
||||
|
||||
sa3_control = dat;
|
||||
@ -75,22 +77,47 @@ static void IOOUTCALL csctrl_o480(UINT port, REG8 dat) {
|
||||
|
||||
}
|
||||
static REG8 IOINPCALL csctrl_i480(UINT port) {
|
||||
|
||||
TRACEOUT(("read %x",port));
|
||||
return sa3_control;
|
||||
(void)port;
|
||||
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL csctrl_i481(UINT port) {
|
||||
|
||||
static void IOOUTCALL csctrl_o481(UINT port, REG8 dat) {
|
||||
sa3data[sa3_control] = dat;
|
||||
(void)port;
|
||||
if(sa3_control == 0x17) return 0;
|
||||
if(sa3_control == 0x18) return 0;
|
||||
else return 0;
|
||||
|
||||
}
|
||||
static REG8 IOINPCALL csctrl_i481(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return sa3data[sa3_control];
|
||||
}
|
||||
REG8 f4a_control;
|
||||
UINT8 f4bdata[256];
|
||||
static void IOOUTCALL csctrl_of4a(UINT port, REG8 dat) {
|
||||
f4a_control = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL csctrl_if4a(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
return f4a_control;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL csctrl_of4b(UINT port, REG8 dat) {
|
||||
f4bdata[f4a_control] = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL csctrl_if4b(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return f4bdata[f4a_control];
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL csctrl_iac6d(UINT port) {
|
||||
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return (0x54);
|
||||
}
|
||||
@ -101,43 +128,47 @@ static REG8 IOINPCALL csctrl_iac6e(UINT port) {
|
||||
(void)port;
|
||||
return 0;
|
||||
}
|
||||
static void IOOUTCALL csctrl_o51ee(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
}
|
||||
static void IOOUTCALL csctrl_o51ef(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
}
|
||||
static void IOOUTCALL csctrl_o56ef(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
}
|
||||
static void IOOUTCALL csctrl_o57ef(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
}
|
||||
static void IOOUTCALL csctrl_o5bef(UINT port, REG8 dat) {
|
||||
|
||||
static REG8 IOINPCALL srnf_i51ee(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return (0x02);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL csctrl_i51ee(UINT port) {
|
||||
static REG8 IOINPCALL srnf_i51ef(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return 0x1;//0b1;
|
||||
}
|
||||
static REG8 IOINPCALL csctrl_i51ef(UINT port) {
|
||||
(void)port;
|
||||
return (0xc2);
|
||||
}
|
||||
static REG8 IOINPCALL csctrl_i56ef(UINT port) {
|
||||
(void)port;
|
||||
return 0x10;//(0b00010000);
|
||||
}
|
||||
static REG8 IOINPCALL csctrl_i57ef(UINT port) {
|
||||
(void)port;
|
||||
return 0xc0;//(0b11000000);
|
||||
}
|
||||
static REG8 IOINPCALL csctrl_i5bef(UINT port) {
|
||||
(void)port;
|
||||
return 0x0a;//(0b00001010);
|
||||
return 0xc2;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL srnf_i56ef(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return (0x9f);
|
||||
}
|
||||
static REG8 IOINPCALL srnf_i57ef(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return (0xc0);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL srnf_i59ef(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return 0x3;
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL srnf_i5bef(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return (0x0e);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL ifab(UINT port) {
|
||||
TRACEOUT(("read %x",port));
|
||||
(void)port;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
// ----
|
||||
@ -145,14 +176,6 @@ static REG8 IOINPCALL csctrl_i5bef(UINT port) {
|
||||
void cs4231io_reset(void) {
|
||||
|
||||
cs4231.enable = 1;
|
||||
if(g_nSoundID==SOUNDID_PC_9801_86_WSS){
|
||||
cs4231.adrs = 0x0a;////0b00 001 010 INT0 DMA1
|
||||
}else{
|
||||
cs4231.adrs = 0x22;////0b00 100 010 INT5 DMA1
|
||||
}
|
||||
cs4231.dmairq = cs4231irq[(cs4231.adrs >> 3) & 7];
|
||||
cs4231.dmach = cs4231dma[cs4231.adrs & 7];
|
||||
|
||||
/* 7 未使用
|
||||
R/W 6 不明
|
||||
R/W 5-3 PCM音源割り込みアドレス
|
||||
@ -168,13 +191,16 @@ void cs4231io_reset(void) {
|
||||
011b= DMA #3
|
||||
100b~101b= 未定義
|
||||
111b= DMAを使用しない
|
||||
*/
|
||||
if ((cs4231.adrs & 7) == 0x1/*0b001*/) cs4231.dmach = 0x00;
|
||||
if ((cs4231.adrs & 7) == 0x2/*0b010*/) cs4231.dmach = 0x01;
|
||||
if ((cs4231.adrs & 7) == 0x3/*0b011*/) cs4231.dmach = 0x03;
|
||||
if ((cs4231.adrs & 7) == 0x6/*0b110*/) cs4231.dmach = 0x01;//YMF-701,715
|
||||
if ((cs4231.adrs & 7) == 0x0/*0b000*/) cs4231.dmach = 0x01;//YMF-701,715
|
||||
if ((cs4231.adrs & 7) == 0x7/*0b111*/) cs4231.dmach = 0xff;
|
||||
*/
|
||||
if(g_nSoundID==SOUNDID_PC_9801_86_WSS){
|
||||
cs4231.adrs = 0x0a;////0b00 001 010 INT0 DMA1
|
||||
}else if(g_nSoundID==SOUNDID_MATE_X_PCM){
|
||||
cs4231.adrs = 0x22;////0b00 100 010 INT0 DMA1
|
||||
}else{
|
||||
cs4231.adrs = 0x23;////0b00 100 011 INT5 DMA3
|
||||
}
|
||||
cs4231.dmairq = cs4231irq[(cs4231.adrs >> 3) & 7];
|
||||
cs4231.dmach = cs4231dma[cs4231.adrs & 7];
|
||||
if (cs4231.dmach != 0xff) {
|
||||
dmac_attach(DMADEV_CS4231, cs4231.dmach);
|
||||
}
|
||||
@ -186,38 +212,14 @@ void cs4231io_reset(void) {
|
||||
}
|
||||
cs4231.port[2] = 0x0f48; // WSS FIFO port
|
||||
cs4231.port[4] = 0x0188; // OPN port
|
||||
cs4231.port[5] = 0x0f4a; // canbe mixer i/o port?
|
||||
/*Port bit
|
||||
0F4Ah R/W 7-0 音量制御する周辺デバイスID
|
||||
PnP により移動可 00h: ?
|
||||
01h: OPNA ON/OFF???
|
||||
02h: 内蔵モデム(ステレオ)? 左音量
|
||||
03h: 内蔵モデム(ステレオ)? 右音量
|
||||
30h: FM音源 左音量
|
||||
31h: FM音源 右音量
|
||||
32h: CD-ROM 左音量
|
||||
33h: CD-ROM 右音量
|
||||
34h: TV 左音量
|
||||
35h: TV 右音量
|
||||
36h: 内蔵モデム(モノラル)?
|
||||
|
||||
0F4Bh R/W 7 ミュート設定
|
||||
PnP により移動可 0:ミュートしない
|
||||
1:ミュートする
|
||||
6-5 未使用
|
||||
4-0 音量設定
|
||||
00000b:最大
|
||||
(
|
||||
)
|
||||
11111b:最小
|
||||
*/
|
||||
cs4231.port[5] = 0x0f4a; // canbe mixer i/o port?
|
||||
cs4231.port[6] = 0x548e; // YMF-701/715?
|
||||
cs4231.port[8] = 0x1480; // Joystick
|
||||
cs4231.port[9] = 0x1488; // OPL3
|
||||
cs4231.port[10] = 0x148c; // MIDI
|
||||
cs4231.port[11] = 0x0480; //9801-118 control? OPLという情報もありだが…
|
||||
cs4231.port[11] = 0x0480; //9801-118 control?
|
||||
cs4231.port[14] = 0x148e; //9801-118 config
|
||||
cs4231.port[15] = 0xffff;
|
||||
cs4231.port[15] = 0xa460; //空いてるのでこっちを利用
|
||||
|
||||
TRACEOUT(("CS4231 - IRQ = %d", cs4231.dmairq));
|
||||
TRACEOUT(("CS4231 - DMA channel = %d", cs4231.dmach));
|
||||
@ -240,7 +242,16 @@ PnP
|
||||
cs4231.reg.monoinput=0xc0;//1a from PC-9821Nr166
|
||||
cs4231.reg.reserved3=0x80; //1b from PC-9821Nr166
|
||||
cs4231.reg.reserved4=0x80; //1d from PC-9821Nr166
|
||||
cs4231.intflag = 0x22;// 0x22??
|
||||
cs4231.intflag = 0xcc;
|
||||
|
||||
sa3data[7] = 7;
|
||||
sa3data[8] = 7;
|
||||
switch (cs4231.dmairq){
|
||||
case 0x0c:f4bdata[1] = 0;break;
|
||||
case 0x0a:f4bdata[1] = 0x02;break;
|
||||
case 0x03:f4bdata[1] = 0x03;break;
|
||||
case 0x05:f4bdata[1] = 0x08;break;
|
||||
}
|
||||
}
|
||||
|
||||
void cs4231io_bind(void) {
|
||||
@ -259,39 +270,37 @@ void cs4231io_bind(void) {
|
||||
iocore_attachinp(0xac6d, csctrl_iac6d);
|
||||
iocore_attachinp(0xac6e, csctrl_iac6e);
|
||||
|
||||
|
||||
/* 必要な時だけ有効にすべき
|
||||
//WSN-F???
|
||||
iocore_attachout(0x51ee, csctrl_o51ee);
|
||||
iocore_attachout(0x51ef, csctrl_o51ef);
|
||||
iocore_attachout(0x56ef, csctrl_o56ef);
|
||||
iocore_attachout(0x57ef, csctrl_o57ef);
|
||||
iocore_attachout(0x5bef, csctrl_o5bef);
|
||||
iocore_attachinp(0x51ee, csctrl_i51ee);
|
||||
iocore_attachinp(0x51ef, csctrl_i51ef);
|
||||
iocore_attachinp(0x56ef, csctrl_i56ef);
|
||||
iocore_attachinp(0x57ef, csctrl_i57ef);
|
||||
iocore_attachinp(0x5bef, csctrl_i5bef);
|
||||
iocore_attachinp(0x51ee, srnf_i51ee);//7番めに読まれる
|
||||
iocore_attachinp(0x51ef, srnf_i51ef);//1番最初にC2を返す
|
||||
// iocore_attachinp(0x52ef, srnf_i52ef);//f40等を読み書きしたあとここを読んでエラー
|
||||
iocore_attachinp(0x56ef, srnf_i56ef);//2番めに読まれて割り込み等の設定? 4番めに2回読まれ直す
|
||||
iocore_attachinp(0x57ef, srnf_i57ef);//5番めに読まれる
|
||||
iocore_attachinp(0x59ef, srnf_i59ef);//3番めに読まれて何か調査 3と4でとりあえず通る
|
||||
// iocore_attachinp(0x5aef, srnf_i5aef);//8番めに読まれて終わり
|
||||
iocore_attachinp(0x5bef, srnf_i5bef);//6番めに読まれる
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
int acicounter;
|
||||
void IOOUTCALL cs4231io0_w8(UINT port, REG8 value) {
|
||||
|
||||
switch(port - cs4231.port[0]) {
|
||||
case 0x00:
|
||||
cs4231.adrs = value;
|
||||
cs4231.adrs = value &= ~0x40;
|
||||
cs4231.dmairq = cs4231irq[(value >> 3) & 7];
|
||||
cs4231.dmach = cs4231dma[value & 7];
|
||||
if ((value & 7) == 0x1/*0b001*/) cs4231.dmach = 0x00;
|
||||
if ((value & 7) == 0x2/*0b010*/) cs4231.dmach = 0x01;
|
||||
if ((value & 7) == 0x3/*0b011*/) cs4231.dmach = 0x03;
|
||||
if ((value & 7) == 0x6/*0b110*/) cs4231.dmach = 0x01;// YMF-701,715
|
||||
if ((value & 7) == 0x0/*0b000*/) cs4231.dmach = 0x01;// YMF-701.715
|
||||
if ((value & 7) == 0x7/*0b111*/) cs4231.dmach = 0xff;
|
||||
dmac_detach(DMADEV_CS4231);
|
||||
if (cs4231.dmach != 0xff) {
|
||||
if ((cs4231.adrs >>2) & 1){
|
||||
if (cs4231.dmach == 0)dmac_attach(DMADEV_NONE, 1);
|
||||
else dmac_attach(DMADEV_NONE, 0);
|
||||
}
|
||||
dmac_attach(DMADEV_CS4231, cs4231.dmach);
|
||||
#if 0
|
||||
if (cs4231.sdc_enable) {
|
||||
if (cs4231.reg.iface & SDC) {
|
||||
dmac.dmach[cs4231.dmach].ready = 1;
|
||||
dmac_check();
|
||||
}
|
||||
@ -299,50 +308,58 @@ void IOOUTCALL cs4231io0_w8(UINT port, REG8 value) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
cs4231.index = value;
|
||||
TRACEOUT(("index %x", cs4231.index & 0x1f));
|
||||
case 0x04://Index Address
|
||||
if ( !(cs4231.index & MCE) && (value & MCE) && (cs4231.reg.iface & (CAL0|CAL1) ) ) acicounter = 1;
|
||||
if (!(cs4231.index & MCE)) cs4231.intflag |=(PRDY|CRDY);
|
||||
cs4231.index = value & ~(INIT|TRD);
|
||||
break;
|
||||
case 0x05:
|
||||
case 0x05://Index_Data
|
||||
cs4231_control(cs4231.index & 0x1f, value);
|
||||
TRACEOUT(("register %x", value ));
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
pic_resetirq(cs4231.dmairq);
|
||||
cs4231.intflag &= 0xfe;
|
||||
cs4231.reg.featurestatus &= 0x8f;
|
||||
//TRACEOUT(("status %x", value));
|
||||
case 0x06://Status
|
||||
if (cs4231.intflag & INt) {
|
||||
pic_resetirq(cs4231.dmairq);
|
||||
}
|
||||
cs4231.intflag &= ~INt;
|
||||
cs4231.reg.featurestatus &= ~(PI|TI|CI);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
cs4231_datasend(value);
|
||||
// TRACEOUT(("PCM %x", value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
REG8 IOINPCALL cs4231io0_r8(UINT port) {
|
||||
|
||||
REG8 ret;
|
||||
switch(port - cs4231.port[0]) {
|
||||
case 0x00:
|
||||
return(cs4231.adrs);
|
||||
case 0x03:
|
||||
return(0x04);
|
||||
// return(0x05);//PC-9821Nr
|
||||
case 0x04:
|
||||
TRACEOUT(("index r 0x%02x", cs4231.index & 0x7f));
|
||||
if (cs4231.reg.mode_id & 0x40) return (cs4231.index &= 0x0f);
|
||||
else return (cs4231.index &= 0x1f);
|
||||
// return(cs4231.index & 0x7f);
|
||||
case 0x05:
|
||||
if ((cs4231.index & 0x1f) == 0x0c) return (cs4231.reg.mode_id |= 0x8a); //why 8a???
|
||||
case 0x04://Index address
|
||||
return(cs4231.index & ~(INIT|TRD|MCE));
|
||||
case 0x05://Index Data
|
||||
switch (cs4231.index & 0x1f){
|
||||
case 0x0b://featurestatus
|
||||
if(acicounter){
|
||||
TRACEOUT(("acicounter"));
|
||||
acicounter -= 1;
|
||||
cs4231.reg.errorstatus |= ACI;
|
||||
}else cs4231.reg.errorstatus &= ~ACI;
|
||||
break;
|
||||
case 0x0d:return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return(*(((UINT8 *)(&cs4231.reg)) + (cs4231.index & 0x1f)));
|
||||
case 0x06:
|
||||
TRACEOUT(("status r 0x%02x", cs4231.intflag));
|
||||
pic_resetirq(cs4231.dmairq);
|
||||
return(cs4231.intflag);
|
||||
if (cs4231.reg.errorstatus & (1 << 6)) cs4231.intflag |= SER;
|
||||
return (cs4231.intflag);
|
||||
case 0x07:
|
||||
return (0x80);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@ -353,6 +370,22 @@ void IOOUTCALL cs4231io5_w8(UINT port, REG8 value) {
|
||||
case 0x00:
|
||||
cs4231.extindex = value;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
switch(cs4231.extindex){
|
||||
case 0x02: // MODEM L ?
|
||||
case 0x03: // MODEM R ?
|
||||
case 0x30: // FM音源 L
|
||||
case 0x31: // FM音源 R
|
||||
case 0x32: // CD-DA L
|
||||
case 0x33: // CD-DA R
|
||||
case 0x34: // TV L
|
||||
case 0x35: // TV R
|
||||
case 0x36: // MODEM mono ?
|
||||
// bit7:mute, bit6,5:reserved, bit4-0:volume(00000(MAX) - 11111(MIN))
|
||||
cs4231.devvolume[cs4231.extindex] = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,8 +396,20 @@ REG8 IOINPCALL cs4231io5_r8(UINT port) {
|
||||
return(cs4231.extindex);
|
||||
|
||||
case 0x01:
|
||||
if (cs4231.extindex == 1) {
|
||||
switch(cs4231.extindex){
|
||||
case 1:
|
||||
return(0); // means opna int5 ???
|
||||
case 0x02: // MODEM L ?
|
||||
case 0x03: // MODEM R ?
|
||||
case 0x30: // FM音源 L
|
||||
case 0x31: // FM音源 R
|
||||
case 0x32: // CD-DA L
|
||||
case 0x33: // CD-DA R
|
||||
case 0x34: // TV L
|
||||
case 0x35: // TV R
|
||||
case 0x36: // MODEM mono ?
|
||||
// bit7:mute, bit6,5:reserved, bit4-0:volume(00000(MAX) - 11111(MIN))
|
||||
return cs4231.devvolume[cs4231.extindex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -18,3 +18,42 @@ REG8 IOINPCALL cs4231io5_r8(UINT port);
|
||||
}
|
||||
#endif
|
||||
|
||||
//Index Address Register 0xf44
|
||||
#define TRD (1 << 5) //cs4231.index bit5 Transfer Request Disable
|
||||
#define MCE (1 << 6) //cs4231.index bit6 Mode Change Enable
|
||||
#define INIT (1 << 7)//cs4231.index bit7 Ititialization
|
||||
|
||||
//Status Register 0xf46
|
||||
#define INt (1 << 0) //cs4231.intflag bit0 Interrupt Status
|
||||
#define PRDY (1 << 1) //cs4231.intflag bit1 Playback Data Ready(PIO data)
|
||||
#define PLR (1 << 2) //cs4231.intflag bit2 Playback Left/Right Sample
|
||||
#define PULR (1 << 3) //cs4231.intflag bit3 Playback Upper/Lower Byte
|
||||
#define SER (1 << 4) //cs4231.intflag bit4 Sample Error
|
||||
#define CRDY (1 << 5) //cs4231.intflag bit5 Capture Data Ready(PIO)
|
||||
#define CLR (1 << 6) //cs4231.intflag bit6 Capture Left/Right Sample
|
||||
#define CUL (1 << 7) //cs4231.intglag bit7 Capture Upper/Lower Byte
|
||||
|
||||
//cs4231.reg.iface(9)
|
||||
#define PEN (1 << 0) //bit0 Playback Enable set and reset without MCE
|
||||
#define CEN (1 << 1) //bit1 Capture Enable
|
||||
#define SDC (1 << 2) //bit2 Single DMA Channel 0 Dual 1 Single 逆と思ってたので修正すべし
|
||||
#define CAL0 (1 << 3) //bit3 Calibration 0 No Calibration 1 Converter calibration
|
||||
#define CAL1 (1 << 4) //bit4 2 DAC calibration 3 Full Calibration
|
||||
#define PPIO (1 << 6) //bit6 Playback PIO Enable 0 DMA 1 PIO
|
||||
#define CPIO (1 << 7) //bit7 Capture PIO Enable 0 DMA 1 PIO
|
||||
|
||||
//cs4231.reg.errorstatus(10)
|
||||
#define ACI (1 << 5) //bit5 Auto-calibrate In-Progress
|
||||
|
||||
//cs4231.reg.pinctrl(11)
|
||||
#define IEN (1 << 1) //bit1 Interrupt Enable reflect cs4231.intflag bit0
|
||||
#define DEN (1 << 3) //bit3 Dither Enable only active in 8-bit unsigned mode
|
||||
|
||||
//cs4231.reg.modeid(12)
|
||||
#define MODE2 (1 << 6) //bit6
|
||||
|
||||
//cs4231.reg.featurestatus(24)
|
||||
#define PI (1 << 4) //bit4 Playback Interrupt pending from Playback DMA count registers
|
||||
#define CI (1 << 5) //bit5 Capture Interrupt pending from record DMA count registers when SDC=1 non-functional
|
||||
#define TI (1 << 6) //bit6 Timer Interrupt pending from timer count registers
|
||||
// PI,CI,TI bits are reset by writing a "0" to the particular interrupt bit or by writing any value to the Status register
|
||||
|
@ -13,36 +13,6 @@
|
||||
* Creative SoundBlaster16 mixer CT1745
|
||||
*/
|
||||
|
||||
enum {
|
||||
MIXER_RESET = 0x00,
|
||||
MIXER_VOL_START = 0x30,
|
||||
MIXER_VOL_END = 0x47,
|
||||
MIXER_MASTER_LEFT = 0x0,
|
||||
MIXER_MASTER_RIGHT,
|
||||
MIXER_VOC_LEFT,
|
||||
MIXER_VOC_RIGHT,
|
||||
MIXER_MIDI_LEFT,
|
||||
MIXER_MIDI_RIGHT,
|
||||
MIXER_CD_LEFT,
|
||||
MIXER_CD_RIGHT,
|
||||
MIXER_LINE_LEFT,
|
||||
MIXER_LINE_RIGHT,
|
||||
MIXER_MIC,
|
||||
MIXER_PCSPEAKER,
|
||||
MIXER_OUT_SW,
|
||||
MIXER_IN_SW_LEFT,
|
||||
MIXER_IN_SW_RIGHT,
|
||||
MIXER_IN_GAIN_LEFT,
|
||||
MIXER_IN_GAIN_RIGHT,
|
||||
MIXER_OUT_GAIN_LEFT,
|
||||
MIXER_OUT_GAIN_RIGHT,
|
||||
MIXER_AGC,
|
||||
MIXER_TREBLE_LEFT,
|
||||
MIXER_TREBLE_RIGHT,
|
||||
MIXER_BASS_LEFT,
|
||||
MIXER_BASS_RIGHT
|
||||
};
|
||||
|
||||
static void ct1745_mixer_reset() {
|
||||
ZeroMemory(g_sb16.mixreg, sizeof(g_sb16.mixreg));
|
||||
|
||||
@ -70,7 +40,7 @@ static void IOOUTCALL sb16_o2500(UINT port, REG8 dat) {
|
||||
|
||||
if (g_sb16.mixsel >= MIXER_VOL_START &&
|
||||
g_sb16.mixsel <= MIXER_VOL_END) {
|
||||
g_sb16.mixreg[g_sb16.mixsel - MIXER_VOL_START] = dat;
|
||||
g_sb16.mixreg[g_sb16.mixsel] = dat;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,36 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
MIXER_RESET = 0x00,
|
||||
MIXER_VOL_START = 0x30,
|
||||
MIXER_MASTER_LEFT = 0x30,
|
||||
MIXER_MASTER_RIGHT,
|
||||
MIXER_VOC_LEFT,
|
||||
MIXER_VOC_RIGHT,
|
||||
MIXER_MIDI_LEFT,
|
||||
MIXER_MIDI_RIGHT,
|
||||
MIXER_CD_LEFT,
|
||||
MIXER_CD_RIGHT,
|
||||
MIXER_LINE_LEFT,
|
||||
MIXER_LINE_RIGHT,
|
||||
MIXER_MIC,
|
||||
MIXER_PCSPEAKER,
|
||||
MIXER_OUT_SW,
|
||||
MIXER_IN_SW_LEFT,
|
||||
MIXER_IN_SW_RIGHT,
|
||||
MIXER_IN_GAIN_LEFT,
|
||||
MIXER_IN_GAIN_RIGHT,
|
||||
MIXER_OUT_GAIN_LEFT,
|
||||
MIXER_OUT_GAIN_RIGHT,
|
||||
MIXER_AGC,
|
||||
MIXER_TREBLE_LEFT,
|
||||
MIXER_TREBLE_RIGHT,
|
||||
MIXER_BASS_LEFT,
|
||||
MIXER_BASS_RIGHT,
|
||||
MIXER_VOL_END = 0x47
|
||||
};
|
||||
|
||||
void ct1745io_reset(void);
|
||||
void ct1745io_bind(void);
|
||||
|
266
cbus/ideio.c
266
cbus/ideio.c
@ -19,6 +19,8 @@
|
||||
#include "sound.h"
|
||||
#include "idebios.res"
|
||||
#include "bios/biosmem.h"
|
||||
#include "fmboard.h"
|
||||
#include "cs4231io.h"
|
||||
|
||||
|
||||
IDEIO ideio;
|
||||
@ -1205,6 +1207,10 @@ REG16 IOINPCALL ideio_r16(UINT port) {
|
||||
// ----
|
||||
|
||||
#if 1
|
||||
static SINT32 cdda_softvolume_L = 0;
|
||||
static SINT32 cdda_softvolume_R = 0;
|
||||
static SINT32 cdda_softvolumereg_L = 0xff;
|
||||
static SINT32 cdda_softvolumereg_R = 0xff;
|
||||
static BRESULT SOUNDCALL playdevaudio(IDEDRV drv, SINT32 *pcm, UINT count) {
|
||||
|
||||
SXSIDEV sxsi;
|
||||
@ -1212,11 +1218,44 @@ static BRESULT SOUNDCALL playdevaudio(IDEDRV drv, SINT32 *pcm, UINT count) {
|
||||
const UINT8 *ptr;
|
||||
SINT sampl;
|
||||
SINT sampr;
|
||||
double sampbias = soundcfg.rate / 44100.0;
|
||||
SINT samploop;
|
||||
double samploop2 = 0.0;
|
||||
SINT samploopcount;
|
||||
double sampcount2 = 0.0;
|
||||
SINT32 buf_l;
|
||||
SINT32 buf_r;
|
||||
SINT32 buf_count;
|
||||
SINT32 samplen_n;
|
||||
SINT32 samplen_d;
|
||||
static SINT32 sampcount2_n = 0;
|
||||
SINT32 sampcount2_d;
|
||||
|
||||
samplen_n = soundcfg.rate;
|
||||
samplen_d = 44100;
|
||||
//if(samplen_n > samplen_d){
|
||||
// // XXX: サンプリングレートが大きい場合のオーバーフロー対策・・・
|
||||
// samplen_n /= 100;
|
||||
// samplen_d /= 100;
|
||||
//}
|
||||
//if(g_nSoundID == SOUNDID_PC_9801_118 || g_nSoundID == SOUNDID_MATE_X_PCM || g_nSoundID == SOUNDID_PC_9801_86_WSS){
|
||||
// if(cdda_softvolumereg_L != cs4231.devvolume[0x32]){
|
||||
// cdda_softvolumereg_L = cs4231.devvolume[0x32];
|
||||
// if(cdda_softvolumereg_L & 0x80){ // FM L Mute
|
||||
// cdda_softvolume_L = 0;
|
||||
// }else{
|
||||
// cdda_softvolume_L = ((~cdda_softvolumereg_L) & 0x1f); // FM L Volume
|
||||
// }
|
||||
// }
|
||||
// if(cdda_softvolumereg_R != cs4231.devvolume[0x33]){
|
||||
// cdda_softvolumereg_R = cs4231.devvolume[0x33];
|
||||
// if(cdda_softvolumereg_R & 0x80){ // FM R Mute
|
||||
// cdda_softvolume_R = 0;
|
||||
// }else{
|
||||
// cdda_softvolume_R = ((~cdda_softvolumereg_R) & 0x1f); // FM R Volume
|
||||
// }
|
||||
// }
|
||||
//}else{
|
||||
cdda_softvolume_L = 0x1f;
|
||||
cdda_softvolume_R = 0x1f;
|
||||
cdda_softvolumereg_L = 0;
|
||||
cdda_softvolumereg_R = 0;
|
||||
//}
|
||||
|
||||
sxsi = sxsi_getptr(drv->sxsidrv);
|
||||
if ((sxsi == NULL) || (sxsi->devtype != SXSIDEV_CDROM) ||
|
||||
@ -1225,38 +1264,49 @@ const UINT8 *ptr;
|
||||
return(FAILURE);
|
||||
}
|
||||
while(count) {
|
||||
r = min(count, drv->dabufrem * sampbias);
|
||||
r = min(count, drv->dabufrem * samplen_n / samplen_d);
|
||||
if (r) {
|
||||
count -= r;
|
||||
ptr = drv->dabuf + 2352 - drv->dabufrem * 4;
|
||||
drv->dabufrem -= r / sampbias;
|
||||
if(sampbias >= 1.0) {
|
||||
sampcount2 = sampbias;
|
||||
ptr = drv->dabuf + 2352 - (drv->dabufrem * 4);
|
||||
drv->dabufrem -= r * samplen_d / samplen_n;
|
||||
if(samplen_n < samplen_d){
|
||||
//sampcount2_n = 0;
|
||||
sampcount2_d = samplen_d;
|
||||
buf_l = buf_r = buf_count = 0;
|
||||
do {
|
||||
sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
pcm[0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
pcm[1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
sampcount2 -= 1.0;
|
||||
if(sampcount2 < 1.0) {
|
||||
sampcount2 += sampbias;
|
||||
ptr += 4;
|
||||
sampcount2_n += samplen_n;
|
||||
buf_l += (SINT)((int)(sampl)*np2cfg.davolume*cdda_softvolume_L/255/31);
|
||||
buf_r += (SINT)((int)(sampr)*np2cfg.davolume*cdda_softvolume_R/255/31);
|
||||
buf_count++;
|
||||
if(sampcount2_n > sampcount2_d){
|
||||
pcm[0] += buf_l / buf_count;
|
||||
pcm[1] += buf_r / buf_count;
|
||||
//pcm[0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
//pcm[1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
pcm += 2 * (sampcount2_n / sampcount2_d);
|
||||
--r;
|
||||
sampcount2_n = sampcount2_n % sampcount2_d;
|
||||
buf_l = buf_r = buf_count = 0;
|
||||
}
|
||||
} while(r > 0);
|
||||
}else{
|
||||
sampcount2_n = samplen_n;
|
||||
sampcount2_d = samplen_d;
|
||||
do {
|
||||
sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
pcm[0] += (SINT)((int)(sampl)*np2cfg.davolume*cdda_softvolume_L/255/31);
|
||||
pcm[1] += (SINT)((int)(sampr)*np2cfg.davolume*cdda_softvolume_L/255/31);
|
||||
sampcount2_n -= sampcount2_d;
|
||||
if(sampcount2_n <= 0){
|
||||
sampcount2_n += samplen_n;
|
||||
ptr += 4;
|
||||
}
|
||||
pcm += 2;
|
||||
} while(--r);
|
||||
} else {
|
||||
do {
|
||||
sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
samploopcount = (sampbias + samploop2) < 1.0 ? 1 : (SINT)(sampbias + samploop2);
|
||||
for(samploop = 0; samploop < samploopcount; samploop++) {
|
||||
pcm[samploop * 2 + 0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
pcm[samploop * 2 + 1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
}
|
||||
ptr += 4 * (1.0 / sampbias < 1.0 ? 1 : (SINT)(1.0 / sampbias + samploop2));
|
||||
pcm += 2 * samploopcount;
|
||||
samploop2 = ((SINT)((sampbias + samploop2) * 1000) % 1000) / 1000.0;
|
||||
} while(--r);
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
@ -1276,6 +1326,149 @@ const UINT8 *ptr;
|
||||
}
|
||||
return(SUCCESS);
|
||||
}
|
||||
//static BRESULT SOUNDCALL playdevaudio(IDEDRV drv, SINT32 *pcm, UINT count) {
|
||||
//
|
||||
// SXSIDEV sxsi;
|
||||
// UINT r;
|
||||
//const UINT8 *ptr;
|
||||
// SINT sampl;
|
||||
// SINT sampr;
|
||||
// double samplen;
|
||||
// double sampcount2;
|
||||
//
|
||||
// samplen = (double)soundcfg.rate / 44100;
|
||||
//
|
||||
// sxsi = sxsi_getptr(drv->sxsidrv);
|
||||
// if ((sxsi == NULL) || (sxsi->devtype != SXSIDEV_CDROM) ||
|
||||
// (!(sxsi->flag & SXSIFLAG_READY))) {
|
||||
// drv->daflag = 0x14;
|
||||
// return(FAILURE);
|
||||
// }
|
||||
// while(count) {
|
||||
// r = min(count, drv->dabufrem * samplen);
|
||||
// if (r) {
|
||||
// count -= r;
|
||||
// ptr = drv->dabuf + 2352 - (drv->dabufrem * 4);
|
||||
// drv->dabufrem -= r / samplen;
|
||||
// if(samplen < 1.0){
|
||||
// sampcount2 = 0;
|
||||
// do {
|
||||
// sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
// sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
// ptr += 4;
|
||||
// sampcount2 += samplen;
|
||||
// if((int)(sampcount2) > 0){
|
||||
// pcm[0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
// pcm[1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
// pcm += 2 * (int)(sampcount2);
|
||||
// --r;
|
||||
// sampcount2 = sampcount2 - (int)sampcount2;
|
||||
// }
|
||||
// } while(r > 0);
|
||||
// }else{
|
||||
// sampcount2 = samplen;
|
||||
// do {
|
||||
// sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
// sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
// pcm[0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
// pcm[1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
// sampcount2 -= 1.0;
|
||||
// if(sampcount2 < 1.0){
|
||||
// sampcount2 += samplen;
|
||||
// ptr += 4;
|
||||
// }
|
||||
// pcm += 2;
|
||||
// } while(--r);
|
||||
// }
|
||||
// }
|
||||
// if (count == 0) {
|
||||
// break;
|
||||
// }
|
||||
// if (drv->dalength == 0) {
|
||||
// drv->daflag = 0x13;
|
||||
// return(FAILURE);
|
||||
// }
|
||||
// if (sxsicd_readraw(sxsi, drv->dacurpos, drv->dabuf) != SUCCESS) {
|
||||
// drv->daflag = 0x14;
|
||||
// return(FAILURE);
|
||||
// }
|
||||
// drv->dalength--;
|
||||
// drv->dacurpos++;
|
||||
// drv->dabufrem = sizeof(drv->dabuf) / 4;
|
||||
// }
|
||||
// return(SUCCESS);
|
||||
//}
|
||||
//static BRESULT SOUNDCALL playdevaudio(IDEDRV drv, SINT32 *pcm, UINT count) {
|
||||
//
|
||||
// SXSIDEV sxsi;
|
||||
// UINT r;
|
||||
//const UINT8 *ptr;
|
||||
// SINT sampl;
|
||||
// SINT sampr;
|
||||
// double sampbias = soundcfg.rate / 44100.0;
|
||||
// SINT samploop;
|
||||
// double samploop2 = 0.0;
|
||||
// SINT samploopcount;
|
||||
// double sampcount2 = 0.0;
|
||||
//
|
||||
// sxsi = sxsi_getptr(drv->sxsidrv);
|
||||
// if ((sxsi == NULL) || (sxsi->devtype != SXSIDEV_CDROM) ||
|
||||
// (!(sxsi->flag & SXSIFLAG_READY))) {
|
||||
// drv->daflag = 0x14;
|
||||
// return(FAILURE);
|
||||
// }
|
||||
// while(count) {
|
||||
// r = min(count, drv->dabufrem * sampbias);
|
||||
// if (r) {
|
||||
// count -= r;
|
||||
// ptr = drv->dabuf + 2352 - drv->dabufrem * 4;
|
||||
// drv->dabufrem -= r / sampbias;
|
||||
// if(sampbias >= 1.0) {
|
||||
// sampcount2 = sampbias;
|
||||
// do {
|
||||
// sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
// sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
// pcm[0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
// pcm[1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
// sampcount2 -= 1.0;
|
||||
// if(sampcount2 < 1.0) {
|
||||
// sampcount2 += sampbias;
|
||||
// ptr += 4;
|
||||
// }
|
||||
// pcm += 2;
|
||||
// } while(--r);
|
||||
// } else {
|
||||
// do {
|
||||
// sampl = ((SINT8)ptr[1] << 8) + ptr[0];
|
||||
// sampr = ((SINT8)ptr[3] << 8) + ptr[2];
|
||||
// samploopcount = (sampbias + samploop2) < 1.0 ? 1 : (SINT)(sampbias + samploop2);
|
||||
// for(samploop = 0; samploop < samploopcount; samploop++) {
|
||||
// pcm[samploop * 2 + 0] += (SINT)((int)(sampl)*np2cfg.davolume/255);
|
||||
// pcm[samploop * 2 + 1] += (SINT)((int)(sampr)*np2cfg.davolume/255);
|
||||
// }
|
||||
// ptr += 4 * (1.0 / sampbias < 1.0 ? 1 : (SINT)(1.0 / sampbias + samploop2));
|
||||
// pcm += 2 * samploopcount;
|
||||
// samploop2 = ((SINT)((sampbias + samploop2) * 1000) % 1000) / 1000.0;
|
||||
// } while(--r);
|
||||
// }
|
||||
// }
|
||||
// if (count == 0) {
|
||||
// break;
|
||||
// }
|
||||
// if (drv->dalength == 0) {
|
||||
// drv->daflag = 0x13;
|
||||
// return(FAILURE);
|
||||
// }
|
||||
// if (sxsicd_readraw(sxsi, drv->dacurpos, drv->dabuf) != SUCCESS) {
|
||||
// drv->daflag = 0x14;
|
||||
// return(FAILURE);
|
||||
// }
|
||||
// drv->dalength--;
|
||||
// drv->dacurpos++;
|
||||
// drv->dabufrem = sizeof(drv->dabuf) / 4;
|
||||
// }
|
||||
// return(SUCCESS);
|
||||
//}
|
||||
|
||||
static void SOUNDCALL playaudio(void *hdl, SINT32 *pcm, UINT count) {
|
||||
|
||||
@ -1343,6 +1536,7 @@ void ideio_reset(const NP2CFG *pConfig) {
|
||||
REG8 i;
|
||||
IDEDRV drv;
|
||||
OEMCHAR tmpbiosname[16];
|
||||
UINT8 useidebios;
|
||||
|
||||
ZeroMemory(&ideio, sizeof(ideio));
|
||||
for (i=0; i<4; i++) {
|
||||
@ -1354,7 +1548,21 @@ void ideio_reset(const NP2CFG *pConfig) {
|
||||
ideio.wwait = np2cfg.idewwait;
|
||||
ideio.bios = IDETC_NOBIOS;
|
||||
|
||||
if(np2cfg.idebios){
|
||||
useidebios = np2cfg.idebios;
|
||||
if(useidebios && np2cfg.autoidebios){
|
||||
SXSIDEV sxsi;
|
||||
for (i=0; i<4; i++) {
|
||||
sxsi = sxsi_getptr(i);
|
||||
if ((sxsi != NULL) && (np2cfg.idetype[i] == SXSIDEV_HDD) &&
|
||||
(sxsi->devtype == SXSIDEV_HDD) && (sxsi->flag & SXSIFLAG_READY)) {
|
||||
if(sxsi->surfaces != 8 || sxsi->sectors != 17){
|
||||
TRACEOUT(("Incompatible CHS parameter detected. IDE BIOS automatically disabled."));
|
||||
useidebios = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(useidebios){
|
||||
_tcscpy(tmpbiosname, OEMTEXT("ide.rom"));
|
||||
getbiospath(path, tmpbiosname, NELEMENTS(path));
|
||||
fh = file_open_rb(path);
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "iocore.h"
|
||||
#include "cbuscore.h"
|
||||
#include "mpu98ii.h"
|
||||
#include "fmboard.h"
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
@ -1098,6 +1100,13 @@ void mpu98ii_bind(void) {
|
||||
iocore_attachout(0x331, mpu98ii_o2);
|
||||
iocore_attachinp(0x331, mpu98ii_i2);
|
||||
}
|
||||
// PC-9801-118
|
||||
if(g_nSoundID == SOUNDID_PC_9801_118){
|
||||
iocore_attachout(cs4231.port[10], mpu98ii_o0);
|
||||
iocore_attachinp(cs4231.port[10], mpu98ii_i0);
|
||||
iocore_attachout(cs4231.port[10]+1, mpu98ii_o2);
|
||||
iocore_attachinp(cs4231.port[10]+1, mpu98ii_i2);
|
||||
}
|
||||
}
|
||||
|
||||
void mpu98ii_callback(void) {
|
||||
|
36
common.h
36
common.h
@ -18,14 +18,14 @@ enum {
|
||||
#endif
|
||||
|
||||
#ifndef LOADINTELDWORD
|
||||
#define LOADINTELDWORD(a) (((UINT32)(((UINT8*)a)[0])) | \
|
||||
((UINT32)(((UINT8*)a)[1]) << 8) | \
|
||||
((UINT32)(((UINT8*)a)[2]) << 16) | \
|
||||
((UINT32)(((UINT8*)a)[3]) << 24))
|
||||
#define LOADINTELDWORD(a) (((UINT32)(((UINT8*)(a))[0])) | \
|
||||
((UINT32)(((UINT8*)(a))[1]) << 8) | \
|
||||
((UINT32)(((UINT8*)(a))[2]) << 16) | \
|
||||
((UINT32)(((UINT8*)(a))[3]) << 24))
|
||||
#endif
|
||||
|
||||
#ifndef LOADINTELWORD
|
||||
#define LOADINTELWORD(a) (((UINT16)((UINT8*)a)[0]) | ((UINT16)(((UINT8*)a)[1]) << 8))
|
||||
#define LOADINTELWORD(a) (((UINT16)((UINT8*)(a))[0]) | ((UINT16)(((UINT8*)(a))[1]) << 8))
|
||||
#endif
|
||||
|
||||
#ifndef STOREINTELDWORD
|
||||
@ -43,25 +43,25 @@ enum {
|
||||
/* Big Ending */
|
||||
|
||||
#ifndef LOADMOTOROLAQWORD
|
||||
#define LOADMOTOROLAQWORD(a) (((UINT64)((UINT8*)a)[7]) | \
|
||||
((UINT64)(((UINT8*)a)[6]) << 8) | \
|
||||
((UINT64)(((UINT8*)a)[5]) << 16) | \
|
||||
((UINT64)(((UINT8*)a)[4]) << 24) | \
|
||||
((UINT64)(((UINT8*)a)[3]) << 32) | \
|
||||
((UINT64)(((UINT8*)a)[2]) << 40) | \
|
||||
((UINT64)(((UINT8*)a)[1]) << 48) | \
|
||||
((UINT64)(((UINT8*)a)[0]) << 56))
|
||||
#define LOADMOTOROLAQWORD(a) (((UINT64)((UINT8*)(a))[7]) | \
|
||||
((UINT64)(((UINT8*)(a))[6]) << 8) | \
|
||||
((UINT64)(((UINT8*)(a))[5]) << 16) | \
|
||||
((UINT64)(((UINT8*)(a))[4]) << 24) | \
|
||||
((UINT64)(((UINT8*)(a))[3]) << 32) | \
|
||||
((UINT64)(((UINT8*)(a))[2]) << 40) | \
|
||||
((UINT64)(((UINT8*)(a))[1]) << 48) | \
|
||||
((UINT64)(((UINT8*)(a))[0]) << 56))
|
||||
#endif
|
||||
|
||||
#ifndef LOADMOTOROLADWORD
|
||||
#define LOADMOTOROLADWORD(a) (((UINT32)((UINT8*)a)[3]) | \
|
||||
((UINT32)(((UINT8*)a)[2]) << 8) | \
|
||||
((UINT32)(((UINT8*)a)[1]) << 16) | \
|
||||
((UINT32)(((UINT8*)a)[0]) << 24))
|
||||
#define LOADMOTOROLADWORD(a) (((UINT32)((UINT8*)(a))[3]) | \
|
||||
((UINT32)(((UINT8*)(a))[2]) << 8) | \
|
||||
((UINT32)(((UINT8*)(a))[1]) << 16) | \
|
||||
((UINT32)(((UINT8*)(a))[0]) << 24))
|
||||
#endif
|
||||
|
||||
#ifndef LOADMOTOROLAWORD
|
||||
#define LOADMOTOROLAWORD(a) (((UINT16)((UINT8*)a)[1]) | ((UINT16)(((UINT8*)a)[0]) << 8))
|
||||
#define LOADMOTOROLAWORD(a) (((UINT16)((UINT8*)(a))[1]) | ((UINT16)(((UINT8*)(a))[0]) << 8))
|
||||
#endif
|
||||
|
||||
#ifndef STOREMOTOROLAQWORD
|
||||
|
@ -168,4 +168,4 @@ static BRESULT opencdm(SXSIDEV sxsi, const OEMCHAR *fname) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
@ -159,4 +159,4 @@ opencue_err2:
|
||||
return(FAILURE);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -77,4 +77,4 @@ openiso_err1:
|
||||
return(FAILURE);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -281,4 +281,4 @@ openmds_err2:
|
||||
return(FAILURE);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -346,4 +346,4 @@ opennrg_err2:
|
||||
return(FAILURE);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -724,4 +724,4 @@ sxsiope_err1:
|
||||
return(FAILURE);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -83,4 +83,4 @@ const _XDFINFO *xdf;
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -489,15 +489,16 @@ BRESULT fdd_readid_d88(FDDFILE fdd) {
|
||||
/* 170101 ST modified to work on Windows 9x/2000 form ... */
|
||||
if (++fdc.crcn >= sectors) {
|
||||
fdc.crcn = 0;
|
||||
if(fdc.mt) {
|
||||
fdc.hd ^= 1;
|
||||
if (fdc.hd == 0) {
|
||||
fdc.treg[fdc.us]++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fdc.treg[fdc.us]++;
|
||||
}
|
||||
/* np21w rev36 removed */
|
||||
//if(fdc.mt) {
|
||||
// fdc.hd ^= 1;
|
||||
// if (fdc.hd == 0) {
|
||||
// fdc.treg[fdc.us]++;
|
||||
// }
|
||||
//}
|
||||
//else {
|
||||
// fdc.treg[fdc.us]++;
|
||||
//}
|
||||
}
|
||||
fdc.C = fdc.treg[fdc.us];
|
||||
fdc.H = fdc.hd;
|
||||
|
@ -434,4 +434,4 @@ BRESULT fdd_write_dcp(FDDFILE fdd) {
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -941,4 +941,4 @@ BRESULT fdd_readid_nfd1(FDDFILE fdd) {
|
||||
}
|
||||
//
|
||||
|
||||
#endif
|
||||
#endif
|
@ -251,4 +251,4 @@ BRESULT fdd_readid_vfdd(FDDFILE fdd) {
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -832,4 +832,4 @@ BOOL fdd_isformating(void) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -276,4 +276,4 @@ BOOL fdd_isformating(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
802
io/dmac.c
802
io/dmac.c
@ -1,368 +1,434 @@
|
||||
/**
|
||||
* @file dmac.c
|
||||
* @brief Implementation of the DMA controller
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
#include "dmac.h"
|
||||
#include "cpucore.h"
|
||||
#include "iocore.h"
|
||||
#include "sound.h"
|
||||
#include "cs4231.h"
|
||||
#include "sasiio.h"
|
||||
|
||||
|
||||
void DMACCALL dma_dummyout(REG8 data) {
|
||||
|
||||
(void)data;
|
||||
}
|
||||
|
||||
REG8 DMACCALL dma_dummyin(void) {
|
||||
|
||||
return(0xff);
|
||||
}
|
||||
|
||||
REG8 DMACCALL dma_dummyproc(REG8 func) {
|
||||
|
||||
(void)func;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static const DMAPROC dmaproc[] = {
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // NONE
|
||||
{fdc_datawrite, fdc_dataread, fdc_dmafunc}, // 2HD
|
||||
{fdc_datawrite, fdc_dataread, fdc_dmafunc}, // 2DD
|
||||
#if defined(SUPPORT_SASI)
|
||||
{sasi_datawrite, sasi_dataread, sasi_dmafunc}, // SASI
|
||||
#else
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // SASI
|
||||
#endif
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // SCSI
|
||||
#if !defined(DISABLE_SOUND)
|
||||
{dma_dummyout, dma_dummyin, cs4231dmafunc}, // CS4231
|
||||
#else
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // SASI
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// ----
|
||||
|
||||
void dmac_check(void) {
|
||||
|
||||
BOOL workchg;
|
||||
DMACH ch;
|
||||
REG8 bit;
|
||||
|
||||
workchg = FALSE;
|
||||
ch = dmac.dmach;
|
||||
bit = 1;
|
||||
do {
|
||||
if ((!(dmac.mask & bit)) && (ch->ready)) {
|
||||
if (!(dmac.work & bit)) {
|
||||
dmac.work |= bit;
|
||||
if (ch->proc.extproc(DMAEXT_START)) {
|
||||
dmac.stat &= ~bit;
|
||||
dmac.working |= bit;
|
||||
workchg = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dmac.work & bit) {
|
||||
dmac.work &= ~bit;
|
||||
dmac.working &= ~bit;
|
||||
ch->proc.extproc(DMAEXT_BREAK);
|
||||
workchg = TRUE;
|
||||
}
|
||||
}
|
||||
bit <<= 1;
|
||||
ch++;
|
||||
} while(bit & 0x0f);
|
||||
if (workchg) {
|
||||
nevent_forceexit();
|
||||
}
|
||||
}
|
||||
|
||||
UINT dmac_getdatas(DMACH dmach, UINT8 *buf, UINT size) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 addr;
|
||||
UINT i;
|
||||
|
||||
leng = min(dmach->leng.w, size);
|
||||
if (leng) {
|
||||
addr = dmach->adrs.d; // + mask
|
||||
if (!(dmach->mode & 0x20)) { // dir +
|
||||
for (i=0; i<leng; i++) {
|
||||
buf[i] = MEMP_READ8(addr + i);
|
||||
}
|
||||
dmach->adrs.d += leng;
|
||||
}
|
||||
else { // dir -
|
||||
for (i=0; i<leng; i++) {
|
||||
buf[i] = MEMP_READ8(addr - i);
|
||||
}
|
||||
dmach->adrs.d -= leng;
|
||||
}
|
||||
dmach->leng.w -= leng;
|
||||
if (dmach->leng.w == 0) {
|
||||
dmach->proc.extproc(DMAEXT_END);
|
||||
}
|
||||
}
|
||||
return(leng);
|
||||
}
|
||||
|
||||
|
||||
// ---- I/O
|
||||
|
||||
static void IOOUTCALL dmac_o01(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 2) & 3);
|
||||
lh = dmac.lh;
|
||||
dmac.lh = (UINT8)(lh ^ 1);
|
||||
dmach->adrs.b[lh + DMA32_LOW] = dat;
|
||||
dmach->adrsorg.b[lh] = dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o03(UINT port, REG8 dat) {
|
||||
|
||||
int ch;
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
ch = (port >> 2) & 3;
|
||||
dmach = dmac.dmach + ch;
|
||||
lh = dmac.lh;
|
||||
dmac.lh = lh ^ 1;
|
||||
dmach->leng.b[lh] = dat;
|
||||
dmach->lengorg.b[lh] = dat;
|
||||
dmac.stat &= ~(1 << ch);
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o13(UINT port, REG8 dat) {
|
||||
|
||||
dmac.dmach[dat & 3].sreq = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o15(UINT port, REG8 dat) {
|
||||
|
||||
if (dat & 4) {
|
||||
dmac.mask |= (1 << (dat & 3));
|
||||
}
|
||||
else {
|
||||
dmac.mask &= ~(1 << (dat & 3));
|
||||
}
|
||||
dmac_check();
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o17(UINT port, REG8 dat) {
|
||||
|
||||
dmac.dmach[dat & 3].mode = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o19(UINT port, REG8 dat) {
|
||||
|
||||
dmac.lh = DMA16_LOW;
|
||||
(void)port;
|
||||
(void)dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o1b(UINT port, REG8 dat) {
|
||||
|
||||
dmac.mask = 0x0f;
|
||||
(void)port;
|
||||
(void)dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o1f(UINT port, REG8 dat) {
|
||||
|
||||
dmac.mask = dat;
|
||||
dmac_check();
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o21(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
|
||||
dmach = dmac.dmach + (((port >> 1) + 1) & 3);
|
||||
#if defined(CPUCORE_IA32)
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat;
|
||||
#else
|
||||
// IA16‚Å‚Í ver0.75‚Å–³Œø<EFBFBD>Aver0.76‚Å<EFBFBD>C<EFBFBD>³
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat & 0x0f;
|
||||
#endif
|
||||
/* 170101 ST modified to work on Windows 9x/2000 */
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_HIGH] = 0;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o29(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
|
||||
dmach = dmac.dmach + (dat & 3);
|
||||
dmach->bound = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
/* 170101 ST modified to work on Windows 9x/2000 form ... */
|
||||
static void IOOUTCALL dmac_oE01(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 1) & 0x07) - 2;
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_HIGH] = dat;
|
||||
}
|
||||
/* 170101 ST modified to work on Windows 9x/2000 ... to */
|
||||
|
||||
static REG8 IOINPCALL dmac_i01(UINT port) {
|
||||
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 2) & 3);
|
||||
lh = dmac.lh;
|
||||
dmac.lh = lh ^ 1;
|
||||
return(dmach->adrs.b[lh + DMA32_LOW]);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL dmac_i03(UINT port) {
|
||||
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 2) & 3);
|
||||
lh = dmac.lh;
|
||||
dmac.lh = lh ^ 1;
|
||||
return(dmach->leng.b[lh]);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL dmac_i11(UINT port) {
|
||||
|
||||
(void)port;
|
||||
return(dmac.stat); // ToDo!!
|
||||
}
|
||||
|
||||
|
||||
// ---- I/F
|
||||
|
||||
static const IOOUT dmaco00[16] = {
|
||||
dmac_o01, dmac_o03, dmac_o01, dmac_o03,
|
||||
dmac_o01, dmac_o03, dmac_o01, dmac_o03,
|
||||
NULL, dmac_o13, dmac_o15, dmac_o17,
|
||||
dmac_o19, dmac_o1b, NULL, dmac_o1f};
|
||||
|
||||
static const IOINP dmaci00[16] = {
|
||||
dmac_i01, dmac_i03, dmac_i01, dmac_i03,
|
||||
dmac_i01, dmac_i03, dmac_i01, dmac_i03,
|
||||
dmac_i11, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL};
|
||||
|
||||
static const IOOUT dmaco21[8] = {
|
||||
dmac_o21, dmac_o21, dmac_o21, dmac_o21,
|
||||
dmac_o29, NULL, NULL, NULL};
|
||||
|
||||
void dmac_reset(const NP2CFG *pConfig) {
|
||||
|
||||
ZeroMemory(&dmac, sizeof(dmac));
|
||||
dmac.lh = DMA16_LOW;
|
||||
dmac.mask = 0xf;
|
||||
dmac_procset();
|
||||
// TRACEOUT(("sizeof(_DMACH) = %d", sizeof(_DMACH)));
|
||||
|
||||
(void)pConfig;
|
||||
}
|
||||
|
||||
void dmac_bind(void) {
|
||||
|
||||
iocore_attachsysoutex(0x0001, 0x0ce1, dmaco00, 16);
|
||||
iocore_attachsysinpex(0x0001, 0x0ce1, dmaci00, 16);
|
||||
iocore_attachsysoutex(0x0021, 0x0cf1, dmaco21, 8);
|
||||
|
||||
/* 170101 ST modified to work on Windows 9x/2000 form ... */
|
||||
iocore_attachout(0x0e05, dmac_oE01);
|
||||
iocore_attachout(0x0e07, dmac_oE01);
|
||||
iocore_attachout(0x0e09, dmac_oE01);
|
||||
iocore_attachout(0x0e0b, dmac_oE01);
|
||||
/* 170101 ST modified to work on Windows 9x/2000 ... to */
|
||||
}
|
||||
|
||||
|
||||
// ----
|
||||
|
||||
static void dmacset(REG8 channel) {
|
||||
|
||||
DMADEV *dev;
|
||||
DMADEV *devterm;
|
||||
UINT dmadev;
|
||||
|
||||
dev = dmac.device;
|
||||
devterm = dev + dmac.devices;
|
||||
dmadev = DMADEV_NONE;
|
||||
while(dev < devterm) {
|
||||
if (dev->channel == channel) {
|
||||
dmadev = dev->device;
|
||||
}
|
||||
dev++;
|
||||
}
|
||||
if (dmadev >= NELEMENTS(dmaproc)) {
|
||||
dmadev = 0;
|
||||
}
|
||||
// TRACEOUT(("dmac set %d - %d", channel, dmadev));
|
||||
dmac.dmach[channel].proc = dmaproc[dmadev];
|
||||
}
|
||||
|
||||
void dmac_procset(void) {
|
||||
|
||||
REG8 i;
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
dmacset(i);
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_attach(REG8 device, REG8 channel) {
|
||||
|
||||
dmac_detach(device);
|
||||
|
||||
if (dmac.devices < NELEMENTS(dmac.device)) {
|
||||
dmac.device[dmac.devices].device = device;
|
||||
dmac.device[dmac.devices].channel = channel;
|
||||
dmac.devices++;
|
||||
dmacset(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_detach(REG8 device) {
|
||||
|
||||
DMADEV *dev;
|
||||
DMADEV *devterm;
|
||||
REG8 ch;
|
||||
|
||||
dev = dmac.device;
|
||||
devterm = dev + dmac.devices;
|
||||
while(dev < devterm) {
|
||||
if (dev->device == device) {
|
||||
break;
|
||||
}
|
||||
dev++;
|
||||
}
|
||||
if (dev < devterm) {
|
||||
ch = dev->channel;
|
||||
dev++;
|
||||
while(dev < devterm) {
|
||||
*(dev - 1) = *dev;
|
||||
dev++;
|
||||
}
|
||||
dmac.devices--;
|
||||
dmacset(ch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @file dmac.c
|
||||
* @brief Implementation of the DMA controller
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
#include "dmac.h"
|
||||
#include "cpucore.h"
|
||||
#include "iocore.h"
|
||||
#include "sound.h"
|
||||
#include "cs4231.h"
|
||||
#include "sasiio.h"
|
||||
|
||||
void DMACCALL dma_dummyout(REG8 data) {
|
||||
|
||||
TRACEOUT(("dma_dummyout"));
|
||||
(void)data;
|
||||
}
|
||||
|
||||
REG8 DMACCALL dma_dummyin(void) {
|
||||
TRACEOUT(("dma_dummyin"));
|
||||
return(0xff);
|
||||
}
|
||||
|
||||
REG8 DMACCALL dma_dummyproc(REG8 func) {
|
||||
|
||||
(void)func;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static const DMAPROC dmaproc[] = {
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // NONE
|
||||
{fdc_datawrite, fdc_dataread, fdc_dmafunc}, // 2HD
|
||||
{fdc_datawrite, fdc_dataread, fdc_dmafunc}, // 2DD
|
||||
#if defined(SUPPORT_SASI)
|
||||
{sasi_datawrite, sasi_dataread, sasi_dmafunc}, // SASI
|
||||
#else
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // SASI
|
||||
#endif
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // SCSI
|
||||
#if !defined(DISABLE_SOUND)
|
||||
{dma_dummyout, dma_dummyin, cs4231dmafunc}, // CS4231
|
||||
#else
|
||||
{dma_dummyout, dma_dummyin, dma_dummyproc}, // SASI
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// ----
|
||||
UINT8 bank;
|
||||
UINT8 bank2;
|
||||
void dmac_check(void) {
|
||||
|
||||
BOOL workchg;
|
||||
DMACH ch;
|
||||
REG8 bit;
|
||||
|
||||
workchg = FALSE;
|
||||
ch = dmac.dmach;
|
||||
bit = 1;
|
||||
do {
|
||||
if ((!(dmac.mask & bit)) && (ch->ready)) {
|
||||
if (!(dmac.work & bit)) {
|
||||
dmac.work |= bit;
|
||||
if (ch->proc.extproc(DMAEXT_START)) {
|
||||
dmac.stat &= ~bit;
|
||||
dmac.working |= bit;
|
||||
workchg = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dmac.work & bit) {
|
||||
dmac.work &= ~bit;
|
||||
dmac.working &= ~bit;
|
||||
ch->proc.extproc(DMAEXT_BREAK);
|
||||
workchg = TRUE;
|
||||
}
|
||||
}
|
||||
bit <<= 1;
|
||||
ch++;
|
||||
} while(bit & 0x0f);
|
||||
if (workchg) {
|
||||
nevent_forceexit();
|
||||
}
|
||||
}
|
||||
|
||||
UINT dmac_getdatas(DMACH dmach, UINT8 *buf, UINT size) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 addr;
|
||||
UINT i;
|
||||
|
||||
leng = min(dmach->leng.w, size);
|
||||
if (leng) {
|
||||
addr = dmach->adrs.d; // + mask
|
||||
if (!(dmach->mode & 0x20)) { // dir +
|
||||
for (i=0; i<leng; i++) {
|
||||
buf[i] = MEMP_READ8(addr + i);
|
||||
}
|
||||
dmach->adrs.d += leng;
|
||||
}
|
||||
else { // dir -
|
||||
for (i=0; i<leng; i++) {
|
||||
buf[i] = MEMP_READ8(addr - i);
|
||||
}
|
||||
dmach->adrs.d -= leng;
|
||||
}
|
||||
dmach->leng.w -= leng;
|
||||
if (dmach->leng.w == 0) {
|
||||
dmach->proc.extproc(DMAEXT_END);
|
||||
}
|
||||
}
|
||||
return(leng);
|
||||
}
|
||||
|
||||
// ---- I/O
|
||||
|
||||
static void IOOUTCALL dmac_o01(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 2) & 3);
|
||||
lh = dmac.lh;
|
||||
dmac.lh = (UINT8)(lh ^ 1);
|
||||
dmach->adrs.b[lh + DMA32_LOW] = dat;
|
||||
dmach->adrsorg.b[lh] = dat;
|
||||
dmach->startaddr = dmach->adrs.d;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o03(UINT port, REG8 dat) {
|
||||
|
||||
int ch;
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
ch = (port >> 2) & 3;
|
||||
dmach = dmac.dmach + ch;
|
||||
lh = dmac.lh;
|
||||
dmac.lh = lh ^ 1;
|
||||
dmach->leng.b[lh] = dat;
|
||||
dmach->lengorg.b[lh] = dat;
|
||||
dmac.stat &= ~(1 << ch);
|
||||
//dmach->startcount =dmach->leng.w;
|
||||
//dmach->lastaddr = dmach->startaddr + dmach->leng.w;
|
||||
dmach->startcount = dmach->leng.w;
|
||||
dmach->lastaddr = dmach->startaddr + dmach->leng.w;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o13_(UINT port, REG8 dat) {
|
||||
if (dat& 4)
|
||||
dmac.stat |= 1 << ((dat & 3) +4);
|
||||
else
|
||||
dmac.stat &= ~(1 << ((dat & 3) +4));
|
||||
dmac.stat &=~(1 << (dat & 3));
|
||||
dmac_check();
|
||||
(void)port;
|
||||
}
|
||||
|
||||
|
||||
static void IOOUTCALL dmac_o13(UINT port, REG8 dat) {
|
||||
dmac.dmach[dat & 3].sreq = dat;
|
||||
dmac_check();
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o15(UINT port, REG8 dat) {
|
||||
|
||||
if (dat & 4) {
|
||||
dmac.mask |= (1 << (dat & 3));
|
||||
}
|
||||
else {
|
||||
dmac.mask &= ~(1 << (dat & 3));
|
||||
}
|
||||
dmac_check();
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o17(UINT port, REG8 dat) {
|
||||
|
||||
dmac.dmach[dat & 3].mode = dat;
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o19(UINT port, REG8 dat) {
|
||||
|
||||
dmac.lh = DMA16_LOW;
|
||||
(void)port;
|
||||
(void)dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o1b(UINT port, REG8 dat) {
|
||||
|
||||
dmac.mask = 0x0f;
|
||||
dmac.dmach[0].adrs.d = 0;
|
||||
dmac.dmach[0].leng.w = 0;
|
||||
dmac.dmach[1].adrs.d = 0;
|
||||
dmac.dmach[1].leng.w = 0;
|
||||
dmac.dmach[2].adrs.d = 0;
|
||||
dmac.dmach[2].leng.w = 0;
|
||||
dmac.dmach[3].adrs.d = 0;
|
||||
dmac.dmach[3].leng.w = 0;
|
||||
(void)port;
|
||||
(void)dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o1d(UINT port, REG8 dat) {
|
||||
|
||||
dmac.mask = 0;
|
||||
dmac_check();
|
||||
(void)port;
|
||||
(void)dat;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o1f(UINT port, REG8 dat) {
|
||||
|
||||
dmac.mask = dat;
|
||||
dmac_check();
|
||||
(void)port;
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o21(UINT port, REG8 dat) {//バンク設定
|
||||
|
||||
DMACH dmach;
|
||||
dmach = dmac.dmach + (((port >> 1) + 1) & 3);
|
||||
#if defined(CPUCORE_IA32)
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat;
|
||||
#else
|
||||
// IA16では ver0.75で無効、ver0.76で修正
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat & 0x0f;//V30は20bitまで
|
||||
#endif
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_HIGH] = 0;//25bitより上はここでは転送できない→0E05
|
||||
bank = dat;
|
||||
if (dmach->bound != 3){
|
||||
dmach->startaddr = dmach->adrs.d;
|
||||
dmach->lastaddr = (bank <<16 | dmach->lastaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
dmach->startaddr = bank << 16 | dmach->adrs.d;
|
||||
dmach->lastaddr = (bank <<16 | dmach->lastaddr);
|
||||
TRACEOUT(("port =%x ch=%x bank = %x dma_address = %x\n",port,((port >> 1) + 1) & 3, dat, dmach->adrs.d));
|
||||
}
|
||||
}
|
||||
|
||||
static void IOOUTCALL dmac_o29(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
|
||||
dmach = dmac.dmach + (dat & 3);
|
||||
// dmach = dmac.dmach + (dat & 0xf);
|
||||
// TRACEOUT (("dmach %x",dat));// PC-98は4chしか持ってない
|
||||
dmach->bound = (dat >> 2) & 3;
|
||||
(void)port;
|
||||
TRACEOUT(("port =%x ch= %x dma bound =%x\n",port,dat & 03 ,dmach->bound));
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL dmac_i01(UINT port) {
|
||||
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 2) & 3);
|
||||
lh = dmac.lh;
|
||||
dmac.lh = lh ^ 1;
|
||||
return(dmach->adrs.b[lh + DMA32_LOW]);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL dmac_i03(UINT port) {
|
||||
|
||||
DMACH dmach;
|
||||
int lh;
|
||||
|
||||
dmach = dmac.dmach + ((port >> 2) & 3);
|
||||
lh = dmac.lh;
|
||||
dmac.lh = lh ^ 1;
|
||||
return(dmach->leng.b[lh]);
|
||||
}
|
||||
|
||||
static REG8 IOINPCALL dmac_i11(UINT port) {
|
||||
|
||||
(void)port;
|
||||
return(dmac.stat &= 0xf0); // ToDo!!
|
||||
}
|
||||
static void IOOUTCALL dmac_oe05(UINT port, REG8 dat) {
|
||||
|
||||
DMACH dmach;
|
||||
|
||||
// dmach = dmac.dmach + (((port >> 1) - 2) & 3);//qemu
|
||||
// dmach = dmac.dmach + ((port >> 1) & 0x07) - 2;//np21/w
|
||||
|
||||
char channel;
|
||||
//switch(port){//シフト計算は頭がおかしくなるのでswitchでごまかしました
|
||||
// case 0xe05:channel = 0;break;
|
||||
// case 0xe07:channel = 1;break;
|
||||
// case 0xe09:channel = 2;break;
|
||||
// case 0xe0b:channel = 3;
|
||||
//}
|
||||
channel = ((port - 0x05) & 0x07) >> 1;
|
||||
dmach = dmac.dmach + channel;
|
||||
dmach->adrs.b[DMA32_HIGH + DMA16_HIGH] = dat;
|
||||
bank2 = dat;
|
||||
dmach->startaddr = ((bank2 &0x7f) << 24) | dmach->adrs.d;
|
||||
dmach->lastaddr = ((bank2 &0x7f) << 24) | (dmach->lastaddr);
|
||||
TRACEOUT(("32bit DMA ch %x bank %x\n",channel, dmach->adrs.b[3]));
|
||||
}
|
||||
static void IOOUTCALL dmac_o2b(UINT port, REG8 dat) {
|
||||
(void)port;
|
||||
}
|
||||
|
||||
// ---- I/F
|
||||
|
||||
static const IOOUT dmaco00[16] = {
|
||||
dmac_o01, dmac_o03, dmac_o01, dmac_o03,
|
||||
dmac_o01, dmac_o03, dmac_o01, dmac_o03,
|
||||
NULL, dmac_o13, dmac_o15, dmac_o17,
|
||||
dmac_o19, dmac_o1b, dmac_o1d, dmac_o1f};
|
||||
|
||||
static const IOINP dmaci00[16] = {
|
||||
dmac_i01, dmac_i03, dmac_i01, dmac_i03,
|
||||
dmac_i01, dmac_i03, dmac_i01, dmac_i03,
|
||||
dmac_i11, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL};
|
||||
|
||||
static const IOOUT dmaco21[8] = {
|
||||
dmac_o21, dmac_o21, dmac_o21, dmac_o21,
|
||||
dmac_o29, NULL, NULL, NULL};
|
||||
|
||||
void dmac_reset(const NP2CFG *pConfig) {
|
||||
|
||||
ZeroMemory(&dmac, sizeof(dmac));
|
||||
dmac.lh = DMA16_LOW;
|
||||
dmac.mask = 0xf;
|
||||
dmac_procset();
|
||||
TRACEOUT(("sizeof(_DMACH) = %d", sizeof(_DMACH)));
|
||||
(void)pConfig;
|
||||
}
|
||||
|
||||
void dmac_bind(void) {
|
||||
|
||||
iocore_attachsysoutex(0x0001, 0x0ce1, dmaco00, 16);
|
||||
iocore_attachsysinpex(0x0001, 0x0ce1, dmaci00, 16);
|
||||
iocore_attachsysoutex(0x0021, 0x0cf1, dmaco21, 8);
|
||||
iocore_attachout(0x0e05, dmac_oe05); //DMA ch.0
|
||||
iocore_attachout(0x0e07, dmac_oe05); //DMA ch.1
|
||||
iocore_attachout(0x0e09, dmac_oe05); //DMA ch.2
|
||||
iocore_attachout(0x0e0b, dmac_oe05); //DMA ch.3
|
||||
//0x489はnecio.cで使ってる
|
||||
//PC-H98??? EMM386.exeを組み込むと現れる
|
||||
// iocore_attachout(0x2b,dmac_o11);
|
||||
// iocore_attachinp(0x2d,dmac_i11);//when 0x2b = c8???
|
||||
}
|
||||
|
||||
|
||||
// ----
|
||||
|
||||
static void dmacset(REG8 channel) {
|
||||
|
||||
DMADEV *dev;
|
||||
DMADEV *devterm;
|
||||
UINT dmadev;
|
||||
|
||||
dev = dmac.device;
|
||||
devterm = dev + dmac.devices;
|
||||
dmadev = DMADEV_NONE;
|
||||
while(dev < devterm) {
|
||||
if (dev->channel == channel) {
|
||||
dmadev = dev->device;
|
||||
}
|
||||
dev++;
|
||||
}
|
||||
if (dmadev >= NELEMENTS(dmaproc)) {
|
||||
dmadev = 0;
|
||||
}
|
||||
|
||||
switch(dmadev){
|
||||
case 0:TRACEOUT(("dmac set %d - dummy", channel));break;
|
||||
case 1:TRACEOUT(("dmac set %d - 2HD", channel));break;
|
||||
case 2:TRACEOUT(("dmac set %d - 2DD", channel));break;
|
||||
case 3:TRACEOUT(("dmac set %d - SASI", channel));break;
|
||||
case 4:TRACEOUT(("dmac set %d - SCSI", channel));break;
|
||||
case 5:TRACEOUT(("dmac set %d - cs4231p", channel));break;
|
||||
}
|
||||
dmac.dmach[channel].proc = dmaproc[dmadev];
|
||||
}
|
||||
|
||||
void dmac_procset(void) {
|
||||
|
||||
REG8 i;
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
dmacset(i);
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_attach(REG8 device, REG8 channel) {
|
||||
|
||||
dmac_detach(device);
|
||||
|
||||
if (dmac.devices < NELEMENTS(dmac.device)) {
|
||||
dmac.device[dmac.devices].device = device;
|
||||
dmac.device[dmac.devices].channel = channel;
|
||||
dmac.devices++;
|
||||
dmacset(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_detach(REG8 device) {
|
||||
|
||||
DMADEV *dev;
|
||||
DMADEV *devterm;
|
||||
REG8 ch;
|
||||
|
||||
dev = dmac.device;
|
||||
devterm = dev + dmac.devices;
|
||||
while(dev < devterm) {
|
||||
if (dev->device == device) {
|
||||
break;
|
||||
}
|
||||
dev++;
|
||||
}
|
||||
if (dev < devterm) {
|
||||
ch = dev->channel;
|
||||
dev++;
|
||||
while(dev < devterm) {
|
||||
*(dev - 1) = *dev;
|
||||
dev++;
|
||||
}
|
||||
dmac.devices--;
|
||||
//if (ch < 5)
|
||||
dmacset(ch);
|
||||
}
|
||||
}
|
240
io/dmac.h
240
io/dmac.h
@ -1,119 +1,121 @@
|
||||
/**
|
||||
* @file dmac.h
|
||||
* @brief Interface of the DMA controller
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pccore.h"
|
||||
|
||||
#ifndef DMACCALL
|
||||
#define DMACCALL
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
DMAEXT_START = 0,
|
||||
DMAEXT_END = 1,
|
||||
DMAEXT_BREAK = 2,
|
||||
|
||||
DMA_INITSIGNALONLY = 1,
|
||||
|
||||
DMADEV_NONE = 0,
|
||||
DMADEV_2HD = 1,
|
||||
DMADEV_2DD = 2,
|
||||
DMADEV_SASI = 3,
|
||||
DMADEV_SCSI = 4,
|
||||
DMADEV_CS4231 = 5,
|
||||
DMADEV_CT1741 = 6
|
||||
};
|
||||
|
||||
#if defined(BYTESEX_LITTLE)
|
||||
enum {
|
||||
DMA16_LOW = 0,
|
||||
DMA16_HIGH = 1,
|
||||
DMA32_LOW = 0,
|
||||
DMA32_HIGH = 2
|
||||
};
|
||||
#elif defined(BYTESEX_BIG)
|
||||
enum {
|
||||
DMA16_LOW = 1,
|
||||
DMA16_HIGH = 0,
|
||||
DMA32_LOW = 2,
|
||||
DMA32_HIGH = 0
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
void (DMACCALL * outproc)(REG8 data);
|
||||
REG8 (DMACCALL * inproc)(void);
|
||||
REG8 (DMACCALL * extproc)(REG8 action);
|
||||
} DMAPROC;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
UINT8 b[4];
|
||||
UINT16 w[2];
|
||||
UINT32 d;
|
||||
} adrs;
|
||||
union {
|
||||
UINT8 b[2];
|
||||
UINT16 w;
|
||||
} leng;
|
||||
union {
|
||||
UINT8 b[2];
|
||||
UINT16 w;
|
||||
} adrsorg;
|
||||
union {
|
||||
UINT8 b[2];
|
||||
UINT16 w;
|
||||
} lengorg;
|
||||
UINT8 bound;
|
||||
UINT8 action;
|
||||
DMAPROC proc;
|
||||
UINT8 mode;
|
||||
UINT8 sreq;
|
||||
UINT8 ready;
|
||||
UINT8 mask;
|
||||
} _DMACH, *DMACH;
|
||||
|
||||
typedef struct {
|
||||
UINT8 device;
|
||||
UINT8 channel;
|
||||
} DMADEV;
|
||||
|
||||
typedef struct {
|
||||
_DMACH dmach[4];
|
||||
int lh;
|
||||
UINT8 work;
|
||||
UINT8 working;
|
||||
UINT8 mask;
|
||||
UINT8 stat;
|
||||
UINT devices;
|
||||
DMADEV device[8];
|
||||
} _DMAC, *DMAC;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void DMACCALL dma_dummyout(REG8 data);
|
||||
REG8 DMACCALL dma_dummyin(void);
|
||||
REG8 DMACCALL dma_dummyproc(REG8 func);
|
||||
|
||||
void dmac_reset(const NP2CFG *pConfig);
|
||||
void dmac_bind(void);
|
||||
void dmac_extbind(void);
|
||||
|
||||
void dmac_check(void);
|
||||
UINT dmac_getdatas(DMACH dmach, UINT8 *buf, UINT size);
|
||||
|
||||
void dmac_procset(void);
|
||||
void dmac_attach(REG8 device, REG8 channel);
|
||||
void dmac_detach(REG8 device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file dmac.h
|
||||
* @brief Interface of the DMA controller
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pccore.h"
|
||||
|
||||
#ifndef DMACCALL
|
||||
#define DMACCALL
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
DMAEXT_START = 0,
|
||||
DMAEXT_END = 1,
|
||||
DMAEXT_BREAK = 2,
|
||||
|
||||
DMA_INITSIGNALONLY = 1,
|
||||
|
||||
DMADEV_NONE = 0,
|
||||
DMADEV_2HD = 1,
|
||||
DMADEV_2DD = 2,
|
||||
DMADEV_SASI = 3,
|
||||
DMADEV_SCSI = 4,
|
||||
DMADEV_CS4231 = 5,
|
||||
DMADEV_CT1741 = 6
|
||||
};
|
||||
|
||||
#if defined(BYTESEX_LITTLE)
|
||||
enum {
|
||||
DMA16_LOW = 0,
|
||||
DMA16_HIGH = 1,
|
||||
DMA32_LOW = 0,
|
||||
DMA32_HIGH = 2
|
||||
};
|
||||
#elif defined(BYTESEX_BIG)
|
||||
enum {
|
||||
DMA16_LOW = 1,
|
||||
DMA16_HIGH = 0,
|
||||
DMA32_LOW = 2,
|
||||
DMA32_HIGH = 0
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
void (DMACCALL * outproc)(REG8 data);
|
||||
REG8 (DMACCALL * inproc)(void);
|
||||
REG8 (DMACCALL * extproc)(REG8 action);
|
||||
} DMAPROC;
|
||||
|
||||
typedef struct {
|
||||
UINT32 startaddr;
|
||||
UINT32 lastaddr;
|
||||
UINT16 startcount;
|
||||
union {
|
||||
UINT8 b[4];
|
||||
UINT16 w[2];
|
||||
UINT32 d;
|
||||
} adrs;
|
||||
union {
|
||||
UINT8 b[2];
|
||||
UINT16 w;
|
||||
} leng;
|
||||
union {
|
||||
UINT8 b[2];
|
||||
UINT16 w;
|
||||
} adrsorg;
|
||||
union {
|
||||
UINT8 b[2];
|
||||
UINT16 w;
|
||||
} lengorg;
|
||||
UINT8 bound;
|
||||
UINT8 action;
|
||||
DMAPROC proc;
|
||||
UINT8 mode;
|
||||
UINT8 sreq;
|
||||
UINT8 ready;
|
||||
UINT8 mask;
|
||||
} _DMACH, *DMACH;
|
||||
|
||||
typedef struct {
|
||||
UINT8 device;
|
||||
UINT8 channel;
|
||||
} DMADEV;
|
||||
|
||||
typedef struct {
|
||||
_DMACH dmach[8];
|
||||
int lh;
|
||||
UINT8 work;
|
||||
UINT8 working;
|
||||
UINT8 mask;
|
||||
UINT8 stat;
|
||||
UINT devices;
|
||||
DMADEV device[8];
|
||||
} _DMAC, *DMAC;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void DMACCALL dma_dummyout(REG8 data);
|
||||
REG8 DMACCALL dma_dummyin(void);
|
||||
REG8 DMACCALL dma_dummyproc(REG8 func);
|
||||
|
||||
void dmac_reset(const NP2CFG *pConfig);
|
||||
void dmac_bind(void);
|
||||
void dmac_extbind(void);
|
||||
|
||||
void dmac_check(void);
|
||||
UINT dmac_getdatas(DMACH dmach, UINT8 *buf, UINT size);
|
||||
void dmac_procset(void);
|
||||
void dmac_attach(REG8 device, REG8 channel);
|
||||
void dmac_detach(REG8 device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -66,8 +66,8 @@ SOURCES_C += $(NP2_PATH)/sdl2/libretro/libretro-common/compat/compat_strcasestr
|
||||
$(NP2_PATH)/i386c/ia32/instructions/fpu/fpemul_dosbox.c
|
||||
|
||||
OBJECTS = $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
CXXFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CXXFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
CFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
LDFLAGS += -lm -lpthread $(fpic)
|
||||
ifeq ($(platform), unix)
|
||||
CXXFLAGS += -DSUPPORT_NET -DSUPPORT_LGY98
|
||||
|
2
np2ver.h
2
np2ver.h
@ -3,7 +3,7 @@
|
||||
* @brief The version
|
||||
*/
|
||||
|
||||
#define NP2VER_CORE "ver.0.86 kai rev.13"
|
||||
#define NP2VER_CORE "ver.0.86 kai rev.14"
|
||||
|
||||
// #define NP2VER_WIN9X
|
||||
// #define NP2VER_MACOSX
|
||||
|
4
pccore.c
4
pccore.c
@ -84,7 +84,7 @@ const OEMCHAR np2version[] = OEMTEXT(NP2VER_CORE);
|
||||
1, 0x000000, 0xffffff,
|
||||
44100, 250, 4, 0,
|
||||
{0, 0, 0}, 0xd1, 0x7f, 0xd1, 0, 0, 1,
|
||||
3, {0x0c, 0x0c, 0x08, 0x06, 0x03, 0x0c}, 64, 64, 64, 64, 64, 64,
|
||||
3, {0x0c, 0x0c, 0x08, 0x06, 0x03, 0x0c}, 64, 64, 64, 64, 64,
|
||||
1, 0x82, 0,
|
||||
0, {0x17, 0x04, 0x1f}, {0x0c, 0x0c, 0x02, 0x10, 0x3f, 0x3f},
|
||||
#if defined(SUPPORT_FMGEN)
|
||||
@ -97,7 +97,7 @@ const OEMCHAR np2version[] = OEMTEXT(NP2VER_CORE);
|
||||
{OEMTEXT(""), OEMTEXT(""), OEMTEXT(""), OEMTEXT("")},
|
||||
{SXSIDEV_HDD, SXSIDEV_HDD, SXSIDEV_CDROM, SXSIDEV_HDD},
|
||||
{OEMTEXT(""), OEMTEXT(""), OEMTEXT(""), OEMTEXT("")},
|
||||
1, 0, 0, 40000,
|
||||
1, 1, 0, 0, 0,
|
||||
#else
|
||||
{OEMTEXT(""), OEMTEXT("")},
|
||||
#endif
|
||||
|
3
pccore.h
3
pccore.h
@ -53,6 +53,7 @@ enum tagSoundId
|
||||
SOUNDID_SB16 = 0x41, /*!< Sound Blaster 16 */
|
||||
SOUNDID_MATE_X_PCM = 0x60, /*!< Mate-X PCM */
|
||||
SOUNDID_PC_9801_86_WSS = 0x64, /*!< PC-9801-86 + Mate-X PCM(B460) */
|
||||
SOUNDID_PC_9801_86_118 = 0x68, /*!< PC-9801-86 + PC-9801-118(B460) */
|
||||
SOUNDID_AMD98 = 0x80, /*!< AMD-98 */
|
||||
SOUNDID_SOUNDORCHESTRA = 0x32, /*!< SOUND ORCHESTRA */
|
||||
SOUNDID_SOUNDORCHESTRAV = 0x82, /*!< SOUND ORCHESTRA-V */
|
||||
@ -131,7 +132,6 @@ struct tagNP2Config
|
||||
UINT8 vol_adpcm;
|
||||
UINT8 vol_pcm;
|
||||
UINT8 vol_rhythm;
|
||||
UINT8 vol_cdda; // ’ljÁ(kaiE)
|
||||
|
||||
UINT8 mpuenable;
|
||||
UINT8 mpuopt;
|
||||
@ -160,6 +160,7 @@ struct tagNP2Config
|
||||
UINT8 idetype[4]; // ver0.86w
|
||||
OEMCHAR idecd[4][MAX_PATH]; // ver0.85w
|
||||
UINT8 idebios; // ver0.86w rev20
|
||||
UINT8 autoidebios; // ver0.86w rev36
|
||||
UINT32 iderwait; // IDE読み取りの割り込み遅延時間(clock)。 np21w ver0.86 rev19
|
||||
UINT32 idewwait; // IDE書き込みの割り込み遅延時間(clock)。 np21w ver0.86 rev18
|
||||
UINT32 idemwait; // IDE BIOSがある場合の割り込み遅延最小値 np21w ver0.86 rev26
|
||||
|
@ -17,6 +17,7 @@ INCFLAGS := -I$(NP2_PATH) \
|
||||
-I$(NP2_PATH)/mem \
|
||||
-I$(NP2_PATH)/sound \
|
||||
-I$(NP2_PATH)/sound/vermouth \
|
||||
-I$(NP2_PATH)/sound/mame \
|
||||
-I$(NP2_PATH)/sound/fmgen \
|
||||
-I$(NP2_PATH)/trap \
|
||||
-I$(NP2_PATH)/vram \
|
||||
@ -64,6 +65,7 @@ SOURCES_C := $(NP2_PATH)/calendar.c \
|
||||
$(NP2_PATH)/sdl2/trace.c \
|
||||
$(wildcard $(NP2_PATH)/sound/*.c) \
|
||||
$(wildcard $(NP2_PATH)/sound/getsnd/*.c) \
|
||||
$(wildcard $(NP2_PATH)/sound/mame/*.c) \
|
||||
$(wildcard $(NP2_PATH)/sound/vermouth/*.c) \
|
||||
$(wildcard $(NP2_PATH)/trap/*.c) \
|
||||
$(wildcard $(NP2_PATH)/vram/*.c) \
|
||||
|
@ -290,8 +290,8 @@ SOURCES_C += $(NP2_PATH)/sdl2/libretro/libretro-common/compat/compat_strcasestr
|
||||
$(NP2_PATH)/i386c/ia32/instructions/fpu/fpemul_dosbox.c
|
||||
|
||||
OBJECTS = $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
CXXFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CXXFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
CFLAGS += -D__LIBRETRO__ $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
LDFLAGS += -lm -lpthread $(fpic)
|
||||
|
||||
ifeq ($(platform), unix)
|
||||
|
@ -33,8 +33,8 @@ SOURCES_C += $(wildcard $(NP2_PATH)/i286c/*.c) \
|
||||
$(NP2_PATH)/sdl2/unix/main.c
|
||||
|
||||
OBJECTS = $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
LDFLAGS += -lm $(fpic) -lpthread $(SDL_LIBS) -lSDL2_ttf -lSDL2_mixer
|
||||
|
||||
ifeq ($(SUPPORT_NET), 1)
|
||||
|
@ -32,8 +32,8 @@ SOURCES_C += $(wildcard $(NP2_PATH)/i286c/*.c) \
|
||||
$(NP2_PATH)/sdl2/win32/main.c
|
||||
|
||||
OBJECTS = $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
LDFLAGS += -lm $(fpic) $(SDL_LIBS) -lSDL2_ttf -lSDL2_mixer
|
||||
|
||||
ifeq ($(SUPPORT_NET), 1)
|
||||
|
@ -39,8 +39,8 @@ SOURCES_C += $(wildcard $(NP2_PATH)/i386c/*.c) \
|
||||
$(NP2_PATH)/sdl2/unix/main.c
|
||||
|
||||
OBJECTS = $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
LDFLAGS += -lm $(fpic) -lpthread $(SDL_LIBS) -lSDL2_ttf -lSDL2_mixer
|
||||
|
||||
ifeq ($(SUPPORT_NET), 1)
|
||||
|
@ -38,8 +38,8 @@ SOURCES_C += $(wildcard $(NP2_PATH)/i386c/*.c) \
|
||||
$(NP2_PATH)/sdl2/win32/main.c
|
||||
|
||||
OBJECTS = $(SOURCES_CXX:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN
|
||||
CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) -DUSE_SDLAUDIO -DUSE_SDLMIXER -DCPUCORE_IA32 -DSUPPORT_PC9821 -DUSE_FPU -DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
LDFLAGS += -lm $(fpic) $(SDL_LIBS) -lSDL2_ttf -lSDL2_mixer
|
||||
|
||||
ifeq ($(SUPPORT_NET), 1)
|
||||
|
15
sdl2/ini.c
15
sdl2/ini.c
@ -547,6 +547,19 @@ static const INITBL iniitem[] = {
|
||||
{"SCSIHDD1", INITYPE_STR, np2cfg.scsihdd[1], MAX_PATH},
|
||||
{"SCSIHDD2", INITYPE_STR, np2cfg.scsihdd[2], MAX_PATH},
|
||||
{"SCSIHDD3", INITYPE_STR, np2cfg.scsihdd[3], MAX_PATH},
|
||||
#endif
|
||||
#if defined(SUPPORT_IDEIO)
|
||||
{"HDD3FILE", INIRO_STR, np2cfg.sasihdd[2], MAX_PATH},
|
||||
{"HDD4FILE", INIRO_STR, np2cfg.sasihdd[3], MAX_PATH},
|
||||
{"HDD1TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"HDD2TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"HDD3TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"HDD4TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"IDE_BIOS", INIRO_BOOL, &np2cfg.idebios, 0},
|
||||
{"AIDEBIOS", INIRO_BOOL, &np2cfg.autoidebios, 0},
|
||||
{"IDERWAIT", INITYPE_UINT32, &np2cfg.iderwait, 0},
|
||||
{"IDEWWAIT", INITYPE_UINT32, &np2cfg.idewwait, 0},
|
||||
{"IDEMWAIT", INITYPE_UINT32, &np2cfg.idemwait, 0},
|
||||
#endif
|
||||
{"SampleHz", INITYPE_UINT32, &np2cfg.samplingrate, 0},
|
||||
{"Latencys", INITYPE_UINT16, &np2cfg.delayms, 0},
|
||||
@ -569,7 +582,7 @@ static const INITBL iniitem[] = {
|
||||
{"volume_A", INIMAX_UINT8, &np2cfg.vol_adpcm, 128},
|
||||
{"volume_P", INIMAX_UINT8, &np2cfg.vol_pcm, 128},
|
||||
{"volume_R", INIMAX_UINT8, &np2cfg.vol_rhythm, 128},
|
||||
{"volume_C", INIMAX_UINT8, &np2cfg.vol_cdda, 128},
|
||||
{"DAVOLUME", INIMAX_UINT8, &np2cfg.davolume, 128},
|
||||
|
||||
{"usefmgen", INITYPE_BOOL, &np2cfg.usefmgen, 0},
|
||||
|
||||
|
@ -40,16 +40,20 @@
|
||||
#endif
|
||||
|
||||
typedef int32_t SINT;
|
||||
typedef int32_t INT;
|
||||
typedef uint32_t UINT;
|
||||
|
||||
typedef int8_t SINT8;
|
||||
typedef int8_t INT8;
|
||||
typedef uint8_t UINT8;
|
||||
typedef int16_t SINT16;
|
||||
typedef int16_t INT16;
|
||||
typedef uint16_t UINT16;
|
||||
typedef int32_t SINT32;
|
||||
typedef int32_t INT32;
|
||||
typedef uint32_t UINT32;
|
||||
typedef int64_t SINT64;
|
||||
typedef int64_t INT64;
|
||||
typedef uint64_t UINT64;
|
||||
|
||||
typedef int32_t* INTPTR;
|
||||
|
@ -880,7 +880,7 @@ void retro_set_environment(retro_environment_t cb)
|
||||
{ "np2_skipline" , "Skipline Revisions; Full 255 lines|ON|OFF" },
|
||||
{ "np2_realpal" , "Real Palettes; OFF|ON" },
|
||||
{ "np2_lcd" , "LCD; OFF|ON" },
|
||||
{ "np2_SNDboard" , "Sound Board (Restart); PC9801-86|PC9801-26K + 86|PC9801-86 + Chibi-oto|PC9801-118|Speak Board|Spark Board|Sound Orchestra|Sound Orchestra-V|AMD-98|Otomi-chanx2|Otomi-chanx2 + 86|None|PC9801-14|PC9801-26K" },
|
||||
{ "np2_SNDboard" , "Sound Board (Restart); PC9801-86|PC9801-26K + 86|PC9801-86 + Chibi-oto|PC9801-118|PC9801-86 + Mate-X PCM(B460)|Mate-X PCM(B460)|Chibi-oto|Speak Board|Spark Board|Sound Orchestra|Sound Orchestra-V|Sound Blaster 16|AMD-98|Otomi-chanx2|Otomi-chanx2 + 86|None|PC9801-14|PC9801-26K" },
|
||||
{ "np2_jast_snd" , "JastSound; OFF|ON" },
|
||||
{ "np2_usefmgen" , "Sound Generator; fmgen|Default" },
|
||||
{ "np2_volume_F" , "Volume FM; 64|68|72|76|80|84|88|92|96|100|104|108|112|116|120|124|128|0|4|8|12|16|20|24|28|32|36|40|44|48|52|56|60" },
|
||||
@ -888,6 +888,7 @@ void retro_set_environment(retro_environment_t cb)
|
||||
{ "np2_volume_A" , "Volume ADPCM; 64|68|72|76|80|84|88|92|96|100|104|108|112|116|120|124|128|0|4|8|12|16|20|24|28|32|36|40|44|48|52|56|60" },
|
||||
{ "np2_volume_P" , "Volume PCM; 64|68|72|76|80|84|88|92|96|100|104|108|112|116|120|124|128|0|4|8|12|16|20|24|28|32|36|40|44|48|52|56|60" },
|
||||
{ "np2_volume_R" , "Volume RHYTHM; 64|68|72|76|80|84|88|92|96|100|104|108|112|116|120|124|128|0|4|8|12|16|20|24|28|32|36|40|44|48|52|56|60" },
|
||||
{ "np2_volume_C" , "Volume CD-DA; 128|136|144|154|160|168|196|184|192|200|208|216|224|232|240|248|255|0|8|16|24|32|40|48|56|64|72|80|88|96|104|112|120" },
|
||||
{ "np2_Seek_Snd" , "Floppy Seek Sound; OFF|ON" },
|
||||
{ "np2_Seek_Vol" , "Volume Floppy Seek; 80|84|88|92|96|100|104|108|112|116|120|124|128|0|4|8|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76" },
|
||||
{ "np2_BEEP_vol" , "Volume Beep; 3|0|1|2" },
|
||||
@ -1008,6 +1009,10 @@ static void update_variables(void)
|
||||
np2cfg.SOUND_SW = 0x14;
|
||||
else if (strcmp(var.value, "PC9801-118") == 0)
|
||||
np2cfg.SOUND_SW = 0x08;
|
||||
else if (strcmp(var.value, "PC9801-86 + Mate-X PCM(B460)") == 0)
|
||||
np2cfg.SOUND_SW = 0x64;
|
||||
else if (strcmp(var.value, "Mate-X PCM(B460)") == 0)
|
||||
np2cfg.SOUND_SW = 0x60;
|
||||
else if (strcmp(var.value, "Speak Board") == 0)
|
||||
np2cfg.SOUND_SW = 0x20;
|
||||
else if (strcmp(var.value, "Spark Board") == 0)
|
||||
@ -1016,6 +1021,8 @@ static void update_variables(void)
|
||||
np2cfg.SOUND_SW = 0x32;
|
||||
else if (strcmp(var.value, "Sound Orchestra-V") == 0)
|
||||
np2cfg.SOUND_SW = 0x82;
|
||||
else if (strcmp(var.value, "Sound Blaster 16") == 0)
|
||||
np2cfg.SOUND_SW = 0x41;
|
||||
else if (strcmp(var.value, "AMD-98") == 0)
|
||||
np2cfg.SOUND_SW = 0x80;
|
||||
else if (strcmp(var.value, "Otomi-chanx2") == 0)
|
||||
@ -1114,6 +1121,15 @@ static void update_variables(void)
|
||||
#endif /* defined(SUPPORT_FMGEN) */
|
||||
}
|
||||
|
||||
var.key = "np2_volume_C";
|
||||
var.value = NULL;
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
np2cfg.davolume = atoi(var.value);
|
||||
rhythm_setvol(np2cfg.davolume);
|
||||
}
|
||||
|
||||
var.key = "np2_Seek_Snd";
|
||||
var.value = NULL;
|
||||
|
||||
|
@ -388,6 +388,16 @@ static void sys_cmd(MENUID id) {
|
||||
update |= SYS_UPDATECFG;
|
||||
break;
|
||||
|
||||
case MID_PC9801_86_MX:
|
||||
np2cfg.SOUND_SW = 0x64;
|
||||
update |= SYS_UPDATECFG;
|
||||
break;
|
||||
|
||||
case MID_PC9801_MX:
|
||||
np2cfg.SOUND_SW = 0x60;
|
||||
update |= SYS_UPDATECFG;
|
||||
break;
|
||||
|
||||
case MID_SPEAKBOARD:
|
||||
np2cfg.SOUND_SW = 0x20;
|
||||
update |= SYS_UPDATECFG;
|
||||
@ -408,6 +418,11 @@ static void sys_cmd(MENUID id) {
|
||||
update |= SYS_UPDATECFG;
|
||||
break;
|
||||
|
||||
case MID_SB16:
|
||||
np2cfg.SOUND_SW = 0x41;
|
||||
update |= SYS_UPDATECFG;
|
||||
break;
|
||||
|
||||
case MID_AMD98:
|
||||
np2cfg.SOUND_SW = 0x80;
|
||||
update |= SYS_UPDATECFG;
|
||||
|
@ -93,10 +93,13 @@ enum {
|
||||
MID_PC9801_26_86,
|
||||
MID_PC9801_86_CB,
|
||||
MID_PC9801_118,
|
||||
MID_PC9801_86_MX,
|
||||
MID_PC9801_MX,
|
||||
MID_SPEAKBOARD,
|
||||
MID_SPARKBOARD,
|
||||
MID_SOUNDORCHESTRA,
|
||||
MID_SOUNDORCHESTRAV,
|
||||
MID_SB16,
|
||||
MID_AMD98,
|
||||
#if defined(SUPPORT_PX)
|
||||
MID_PX1,
|
||||
|
@ -87,10 +87,13 @@ static const char str_pc980186[] = "PC-9801-86";
|
||||
static const char str_pc980126k86[] = "PC-9801-26K + 86";
|
||||
static const char str_pc980186cb[] = "PC-9801-86 + Chibi-oto";
|
||||
static const char str_pc9801118[] = "PC-9801-118";
|
||||
static const char str_pc980186mx[] = "PC-9801-86 + Mate-X PCM(B460)";
|
||||
static const char str_pc9801mx[] = "Mate-X PCM(B460)";
|
||||
static const char str_spreakboard[] = "Speak board";
|
||||
static const char str_sparkboard[] = "Spark board";
|
||||
static const char str_sndorchestra[] = "Sound Orchestra";
|
||||
static const char str_sndorchestrav[] = "Sound Orchestra-V";
|
||||
static const char str_sb16[] = "Sound Blaster 16";
|
||||
static const char str_amd98[] = "AMD-98";
|
||||
#if defined(SUPPORT_PX)
|
||||
static const char str_px1[] = "Otomi-chanx2";
|
||||
@ -325,10 +328,13 @@ static const MSYSITEM s_snd[] = {
|
||||
{str_pc980126k86, NULL, MID_PC9801_26_86, 0},
|
||||
{str_pc980186cb, NULL, MID_PC9801_86_CB, 0},
|
||||
{str_pc9801118, NULL, MID_PC9801_118, 0},
|
||||
{str_pc980186mx, NULL, MID_PC9801_86_MX, 0},
|
||||
{str_pc9801mx, NULL, MID_PC9801_MX, 0},
|
||||
{str_spreakboard, NULL, MID_SPEAKBOARD, 0},
|
||||
{str_sparkboard, NULL, MID_SPARKBOARD, 0},
|
||||
{str_sndorchestra, NULL, MID_SOUNDORCHESTRA, 0},
|
||||
{str_sndorchestrav, NULL, MID_SOUNDORCHESTRAV,0},
|
||||
{str_sndorchestrav, NULL, MID_SOUNDORCHESTRAV, 0},
|
||||
{str_sb16, NULL, MID_SB16, 0},
|
||||
{str_amd98, NULL, MID_AMD98, 0},
|
||||
#if defined(SUPPORT_PX)
|
||||
{str_px1, NULL, MID_PX1, 0},
|
||||
|
@ -40,18 +40,23 @@ typedef unsigned int UINT;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef signed char SINT8;
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed short SINT16;
|
||||
typedef signed short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed int SINT32;
|
||||
typedef signed int INT32;
|
||||
typedef unsigned int UINT32;
|
||||
#if __WORDSIZE == 64
|
||||
typedef signed long int SINT64;
|
||||
typedef signed long int INT64;
|
||||
typedef unsigned long int UINT64;
|
||||
#else
|
||||
__extension__
|
||||
typedef signed long long int SINT64;
|
||||
typedef signed long int SINT64;
|
||||
__extension__
|
||||
typedef signed long int INT64;
|
||||
__extension__
|
||||
typedef unsigned long long int UINT64;
|
||||
#endif
|
||||
|
@ -29,28 +29,36 @@
|
||||
#ifndef __GNUC__
|
||||
typedef signed int SINT;
|
||||
typedef signed char SINT8;
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed short SINT16;
|
||||
typedef signed short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed int SINT32;
|
||||
typedef signed int INT32;
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed long long SINT64;
|
||||
typedef unsigned long long SINT64;
|
||||
typedef signed long long INT64;
|
||||
typedef unsigned long long UINT64;
|
||||
typedef signed int SINT;
|
||||
typedef signed int INT;
|
||||
typedef unsigned int UINT;
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
typedef signed char SINT8;
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed short SINT16;
|
||||
typedef signed short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed int SINT32;
|
||||
typedef signed int INT32;
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed long long SINT64;
|
||||
typedef signed long long INT64;
|
||||
typedef unsigned long long UINT64;
|
||||
typedef signed int SINT;
|
||||
typedef signed int INT;
|
||||
typedef unsigned int UINT;
|
||||
#endif
|
||||
|
||||
|
236
sound/cs4231.h
236
sound/cs4231.h
@ -1,96 +1,140 @@
|
||||
/**
|
||||
sudo make - * @file cs4231.h
|
||||
* @brief Interface of the CS4231
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sound.h"
|
||||
#include "io/dmac.h"
|
||||
|
||||
enum {
|
||||
//
|
||||
CS4231_BUFFERS = (1 << 9),
|
||||
CS4231_BUFMASK = (CS4231_BUFFERS - 1)
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINT8 adc_l; // 0
|
||||
UINT8 adc_r; // 1
|
||||
UINT8 aux1_l; // 2
|
||||
UINT8 aux1_r; // 3
|
||||
UINT8 aux2_l; // 4
|
||||
UINT8 aux2_r; // 5
|
||||
UINT8 dac_l; // 6
|
||||
UINT8 dac_r; // 7
|
||||
UINT8 datafmt; // 8
|
||||
UINT8 iface; // 9
|
||||
UINT8 pinctrl; // a
|
||||
UINT8 errorstatus; //b
|
||||
UINT8 mode_id; //c
|
||||
UINT8 loopctrl; //d
|
||||
UINT8 playcount[2]; //e-f
|
||||
UINT8 featurefunc[2]; //10-11
|
||||
UINT8 line_l; //12
|
||||
UINT8 line_r; //13
|
||||
UINT8 timer[2]; //14-15
|
||||
UINT8 reserved1; //16
|
||||
UINT8 reserved2; //17
|
||||
UINT8 featurestatus; //18
|
||||
UINT8 chipid; //19
|
||||
UINT8 monoinput; //1a
|
||||
UINT8 reserved3; //1b
|
||||
UINT8 cap_datafmt; //1c
|
||||
UINT8 reserved4; //1d
|
||||
UINT8 cap_basecount[2]; //1e-1f
|
||||
} CS4231REG;
|
||||
|
||||
typedef struct {
|
||||
UINT bufsize;
|
||||
UINT bufdatas;
|
||||
UINT bufpos;
|
||||
UINT32 pos12;
|
||||
UINT32 step12;
|
||||
|
||||
UINT8 enable;
|
||||
UINT8 portctrl;
|
||||
UINT8 dmairq;
|
||||
UINT8 dmach;
|
||||
UINT32 port[16];
|
||||
UINT8 adrs;
|
||||
UINT8 index;
|
||||
UINT8 intflag;
|
||||
UINT8 outenable;
|
||||
UINT8 extfunc;
|
||||
UINT8 extindex;
|
||||
|
||||
CS4231REG reg;
|
||||
UINT8 buffer[CS4231_BUFFERS];
|
||||
} _CS4231, *CS4231;
|
||||
|
||||
typedef struct {
|
||||
UINT rate;
|
||||
} CS4231CFG;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void cs4231_dma(NEVENTITEM item);
|
||||
REG8 DMACCALL cs4231dmafunc(REG8 func);
|
||||
void cs4231_datasend(REG8 dat);
|
||||
|
||||
void cs4231_initialize(UINT rate);
|
||||
void cs4231_setvol(UINT vol);
|
||||
|
||||
void cs4231_reset(void);
|
||||
void cs4231_update(void);
|
||||
void cs4231_control(UINT index, REG8 dat);
|
||||
|
||||
void SOUNDCALL cs4231_getpcm(CS4231 cs, SINT32 *pcm, UINT count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
sudo make - * @file cs4231.h
|
||||
* @brief Interface of the CS4231
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sound.h"
|
||||
#include "io/dmac.h"
|
||||
|
||||
enum {
|
||||
CS4231_BUFFERS = (1 << 9),
|
||||
CS4231_BUFMASK = (CS4231_BUFFERS - 1)
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINT8 adc_l; // 0
|
||||
UINT8 adc_r; // 1
|
||||
UINT8 aux1_l; // 2
|
||||
UINT8 aux1_r; // 3
|
||||
UINT8 aux2_l; // 4
|
||||
UINT8 aux2_r; // 5
|
||||
UINT8 dac_l; // 6
|
||||
UINT8 dac_r; // 7
|
||||
UINT8 datafmt; // 8
|
||||
UINT8 iface; // 9
|
||||
UINT8 pinctrl; // a
|
||||
UINT8 errorstatus; //b
|
||||
UINT8 mode_id; //c
|
||||
UINT8 loopctrl; //d
|
||||
UINT8 playcount[2]; //e-f
|
||||
UINT8 featurefunc[2]; //10-11
|
||||
UINT8 line_l; //12
|
||||
UINT8 line_r; //13
|
||||
UINT8 timer[2]; //14-15
|
||||
UINT8 reserved1; //16
|
||||
UINT8 reserved2; //17
|
||||
UINT8 featurestatus; //18
|
||||
UINT8 chipid; //19
|
||||
UINT8 monoinput; //1a
|
||||
UINT8 reserved3; //1b
|
||||
UINT8 cap_datafmt; //1c
|
||||
UINT8 reserved4; //1d
|
||||
UINT8 cap_basecount[2]; //1e-1f
|
||||
} CS4231REG;
|
||||
|
||||
typedef struct {
|
||||
UINT bufsize; // サウンド再生用の循環バッファサイズ。データのread/writeは4byte単位(16bitステレオの1サンプル単位)で行うこと
|
||||
UINT bufdatas; // = (bufwpos-bufpos)&CS4231_BUFMASK
|
||||
UINT bufpos; // バッファの読み取り位置。bufwposと一致してもよいが追い越してはいけない
|
||||
UINT bufwpos; // バッファの書き込み位置。周回遅れのbufposに追いついてはいけない(一致も不可)
|
||||
UINT32 pos12;
|
||||
UINT32 step12;
|
||||
|
||||
UINT8 enable;
|
||||
UINT8 portctrl;
|
||||
UINT8 dmairq;
|
||||
UINT8 dmach;
|
||||
UINT16 port[16];
|
||||
UINT8 adrs;
|
||||
UINT8 index;
|
||||
UINT8 intflag;
|
||||
UINT8 outenable;
|
||||
UINT8 extfunc;
|
||||
UINT8 extindex;
|
||||
|
||||
UINT16 timer;
|
||||
SINT32 timercounter;
|
||||
|
||||
CS4231REG reg;
|
||||
UINT8 buffer[CS4231_BUFFERS];
|
||||
|
||||
UINT8 devvolume[0x100];
|
||||
} _CS4231, *CS4231;
|
||||
|
||||
typedef struct {
|
||||
UINT rate;
|
||||
} CS4231CFG;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//Index Address Register 0xf44
|
||||
#define TRD (1 << 5) //cs4231.index bit5 Transfer Request Disable
|
||||
#define MCE (1 << 6) //cs4231.index bit6 Mode Change Enable
|
||||
|
||||
//Status Register 0xf46
|
||||
#define INt (1 << 0) //cs4231.intflag bit0 Interrupt Status
|
||||
#define PRDY (1 << 1) //cs4231.intflag bit1 Playback Data Ready(PIO data)
|
||||
#define PLR (1 << 2) //cs4231.intflag bit2 Playback Left/Right Sample
|
||||
#define PULR (1 << 3) //cs4231.intflag bit3 Playback Upper/Lower Byte
|
||||
#define SER (1 << 4) //cs4231.intflag bit4 Sample Error
|
||||
#define CRDY (1 << 5) //cs4231.intflag bit5 Capture Data Ready
|
||||
#define CLR (1 << 6) //cs4231.intflag bit6 Capture Left/Right Sample
|
||||
#define CUL (1 << 7) //cs4231.intglag bit7 Capture Upper/Lower Byte
|
||||
|
||||
//cs4231.reg.iface(9)
|
||||
#define PEN (1 << 0) //bit0 Playback Enable set and reset without MCE
|
||||
#define CEN (1 << 1) //bit1 Capture Enable
|
||||
#define SDC (1 << 2) //bit2 Single DMA Channel 0 Dual 1 Single 逆と思ってたので修正すべし
|
||||
#define CAL0 (1 << 3) //bit3 Calibration 0 No Calibration 1 Converter calibration
|
||||
#define CAL1 (1 << 4) //bit4 2 DAC calibration 3 Full Calibration
|
||||
#define PPIO (1 << 6) //bit6 Playback PIO Enable 0 DMA 1 PIO
|
||||
#define CPIO (1 << 7) //bit7 Capture PIO Enable 0 DMA 1 PIO
|
||||
|
||||
//cs4231.reg.errorstatus(11)b
|
||||
#define ACI (1 << 5) //bit5 Auto-calibrate In-Progress
|
||||
|
||||
//cs4231.reg.pinctrl(10)a
|
||||
#define IEN (1 << 1) //bit1 Interrupt Enable reflect cs4231.intflag bit0
|
||||
#define DEN (1 << 3) //bit3 Dither Enable only active in 8-bit unsigned mode
|
||||
|
||||
//cs4231.reg.modeid(12)c
|
||||
#define MODE2 (1 << 6) //bit6
|
||||
|
||||
//cs4231.reg.featurestatus(24)0x18
|
||||
#define PI (1 << 4) //bit4 Playback Interrupt pending from Playback DMA count registers
|
||||
#define CI (1 << 5) //bit5 Capture Interrupt pending from record DMA count registers when SDC=1 non-functional
|
||||
#define TI (1 << 6) //bit6 Timer Interrupt pending from timer count registers
|
||||
// PI,CI,TI bits are reset by writing a "0" to the particular interrupt bit or by writing any value to the Status register
|
||||
|
||||
void cs4231_dma(NEVENTITEM item);
|
||||
REG8 DMACCALL cs4231dmafunc(REG8 func);
|
||||
void cs4231_datasend(REG8 dat);
|
||||
|
||||
void cs4231_initialize(UINT rate);
|
||||
void cs4231_setvol(UINT vol);
|
||||
|
||||
void cs4231_reset(void);
|
||||
void cs4231_update(void);
|
||||
void cs4231_control(UINT index, REG8 dat);
|
||||
|
||||
void SOUNDCALL cs4231_getpcm(CS4231 cs, SINT32 *pcm, UINT count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
647
sound/cs4231c.c
647
sound/cs4231c.c
@ -1,237 +1,410 @@
|
||||
/**
|
||||
* @file cs4231c.c
|
||||
* @brief Implementation of the CS4231
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
#include "cs4231.h"
|
||||
#include "iocore.h"
|
||||
#include "fmboard.h"
|
||||
|
||||
|
||||
CS4231CFG cs4231cfg;
|
||||
|
||||
enum {
|
||||
CS4231REG_LINPUT = 0x00,
|
||||
CS4231REG_RINPUT = 0x01,
|
||||
CS4231REG_AUX1L = 0x02,
|
||||
CS4231REG_AUX1R = 0x03,
|
||||
CS4231REG_AUX2L = 0x04,
|
||||
CS4231REG_AUX2R = 0x05,
|
||||
CS4231REG_LOUTPUT = 0x06,
|
||||
CS4231REG_ROUTPUT = 0x07,
|
||||
CS4231REG_PLAYFMT = 0x08,
|
||||
CS4231REG_INTERFACE = 0x09,
|
||||
CS4231REG_PINCTRL = 0x0a,
|
||||
CS4231REG_TESTINIT = 0x0b,
|
||||
CS4231REG_MISCINFO = 0x0c,
|
||||
CS4231REG_LOOPBACK = 0x0d,
|
||||
CS4231REG_PLAYCNTM = 0x0e,
|
||||
CS4231REG_PLAYCNTL = 0x0f,
|
||||
|
||||
CS4231REG_FEATURE1 = 0x10,
|
||||
CS4231REG_FEATURE2 = 0x11,
|
||||
CS4231REG_LLINEIN = 0x12,
|
||||
CS4231REG_RLINEIN = 0x13,
|
||||
CS4231REG_TIMERL = 0x14,
|
||||
CS4231REG_TIMERH = 0x15,
|
||||
CS4231REG_RESERVED1= 0x16,
|
||||
CS4231REG_RESERVED2= 0x17,
|
||||
CS4231REG_IRQSTAT = 0x18,
|
||||
CS4231REG_VERSION = 0x19,
|
||||
CS4231REG_MONOCTRL = 0x1a,
|
||||
CS4231REG_RECFMT = 0x1c,
|
||||
CS4231REG_PLAYFREQ = 0x1d,
|
||||
CS4231REG_RECCNTM = 0x1e,
|
||||
CS4231REG_RECCNTL = 0x1f
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const UINT32 cs4231xtal64[2] = {24576000/64, 16934400/64};
|
||||
|
||||
static const UINT8 cs4231cnt64[8] = {
|
||||
3072/64, // 8000/ 5510
|
||||
1536/64, // 16000/11025
|
||||
896/64, // 27420/18900
|
||||
768/64, // 32000/22050
|
||||
448/64, // 54840/37800
|
||||
384/64, // 64000/44100
|
||||
512/64, // 48000/33075
|
||||
2560/64}; // 9600/ 6620
|
||||
|
||||
// 640:441
|
||||
|
||||
|
||||
void cs4231_initialize(UINT rate) {
|
||||
|
||||
cs4231cfg.rate = rate;
|
||||
}
|
||||
|
||||
void cs4231_setvol(UINT vol) {
|
||||
|
||||
(void)vol;
|
||||
}
|
||||
|
||||
void cs4231_dma(NEVENTITEM item) {
|
||||
|
||||
DMACH dmach;
|
||||
UINT rem;
|
||||
UINT pos;
|
||||
UINT size;
|
||||
UINT r;
|
||||
SINT32 cnt;
|
||||
if (item->flag & NEVENT_SETEVENT) {
|
||||
if (cs4231.dmach != 0xff) {
|
||||
sound_sync();
|
||||
dmach = dmac.dmach + cs4231.dmach;
|
||||
if (cs4231.bufsize > cs4231.bufdatas) {
|
||||
rem = cs4231.bufsize - cs4231.bufdatas;
|
||||
pos = (cs4231.bufpos + cs4231.bufdatas) & CS4231_BUFMASK;
|
||||
size = min(rem, CS4231_BUFFERS - pos);
|
||||
r = dmac_getdatas(dmach, cs4231.buffer + pos, size);
|
||||
rem -= r;
|
||||
cs4231.bufdatas += r;
|
||||
if (r != size) {
|
||||
r = dmac_getdatas(dmach, cs4231.buffer, rem);
|
||||
cs4231.bufdatas += r;
|
||||
}
|
||||
}
|
||||
if ((dmach->leng.w) && (cs4231cfg.rate)) {
|
||||
cnt = pccore.realclock * 16 / cs4231cfg.rate;
|
||||
nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_RELATIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)item;
|
||||
}
|
||||
|
||||
void cs4231_datasend(REG8 dat) {
|
||||
UINT pos;
|
||||
if (cs4231.reg.iface & 0x40) { // PIO play enable
|
||||
if (cs4231.bufsize <= cs4231.bufdatas) {
|
||||
sound_sync();
|
||||
}
|
||||
if (cs4231.bufsize > cs4231.bufdatas) {
|
||||
pos = (cs4231.bufpos + cs4231.bufdatas) & CS4231_BUFMASK;
|
||||
cs4231.buffer[pos] = dat;
|
||||
cs4231.bufdatas++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REG8 DMACCALL cs4231dmafunc(REG8 func) {
|
||||
SINT32 cnt;
|
||||
TRACEOUT(("dmafunc %x",func));
|
||||
switch(func) {
|
||||
case DMAEXT_START:
|
||||
if (cs4231cfg.rate) {
|
||||
cnt = pccore.realclock * 16 / cs4231cfg.rate;
|
||||
nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_ABSOLUTE);
|
||||
}
|
||||
break;
|
||||
case DMAEXT_END:
|
||||
if ((cs4231.reg.pinctrl & 2) && (cs4231.dmairq != 0xff)) {
|
||||
cs4231.intflag |=1;
|
||||
cs4231.reg.featurestatus |= 0x10;
|
||||
pic_setirq(cs4231.dmairq);
|
||||
}
|
||||
break;
|
||||
|
||||
case DMAEXT_BREAK:
|
||||
nevent_reset(NEVENT_CS4231);
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void cs4231_reset(void) {
|
||||
|
||||
ZeroMemory(&cs4231, sizeof(cs4231));
|
||||
cs4231.bufsize = CS4231_BUFFERS;
|
||||
// cs4231.proc = cs4231_nodecode;
|
||||
cs4231.dmach = 0xff;
|
||||
cs4231.dmairq = 0xff;
|
||||
FillMemory(cs4231.port, sizeof(cs4231.port), 0xff);
|
||||
}
|
||||
|
||||
void cs4231_update(void) {
|
||||
}
|
||||
|
||||
|
||||
static void setdataalign(void) {
|
||||
|
||||
UINT step;
|
||||
|
||||
step = (0 - cs4231.bufpos) & 3;
|
||||
if (step) {
|
||||
cs4231.bufpos += step;
|
||||
cs4231.bufdatas -= min(step, cs4231.bufdatas);
|
||||
}
|
||||
cs4231.bufdatas &= ~3;
|
||||
}
|
||||
|
||||
void cs4231_control(UINT idx, REG8 dat) {
|
||||
UINT8 modify;
|
||||
DMACH dmach;
|
||||
|
||||
cs4231.index |= 0x40;
|
||||
|
||||
modify = ((UINT8 *)&cs4231.reg)[idx] ^ dat;
|
||||
((UINT8 *)&cs4231.reg)[idx] = dat;
|
||||
switch(idx) {
|
||||
case CS4231REG_MISCINFO:
|
||||
if (cs4231.reg.mode_id & 0x40) cs4231.index &= 0x0f;
|
||||
else cs4231.index &= 0x1f;
|
||||
break;
|
||||
}
|
||||
switch(idx) {
|
||||
case CS4231REG_PLAYFMT:
|
||||
TRACEOUT(("PLAYFMT= %x",dat));
|
||||
if (modify & 0xf0) {
|
||||
setdataalign();
|
||||
}
|
||||
if (modify & 0x0f) {
|
||||
if (cs4231cfg.rate) {
|
||||
UINT32 r;
|
||||
r = cs4231xtal64[dat & 1] / cs4231cnt64[(dat >> 1) & 7];
|
||||
TRACEOUT(("samprate = %d", r));
|
||||
r <<= 12;
|
||||
r /= cs4231cfg.rate;
|
||||
cs4231.step12 = r;
|
||||
TRACEOUT(("step12 = %d", r));
|
||||
}
|
||||
else {
|
||||
cs4231.step12 = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CS4231REG_INTERFACE:
|
||||
if (modify & 5) {
|
||||
if (cs4231.dmach != 0xff) {
|
||||
dmach = dmac.dmach + cs4231.dmach;
|
||||
if ((dat & 0x1) == 0x1) {
|
||||
dmach->ready = 1;
|
||||
}
|
||||
else {
|
||||
dmach->ready = 0;
|
||||
}
|
||||
dmac_check();
|
||||
}
|
||||
if (!(dat & 1)) { // stop!
|
||||
cs4231.pos12 = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CS4231REG_IRQSTAT:
|
||||
if (modify & 0x10) {
|
||||
pic_resetirq(cs4231.dmairq);
|
||||
cs4231.intflag &= 0xfe;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @file cs4231c.c
|
||||
* @brief Implementation of the CS4231
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
#include "cs4231.h"
|
||||
#include "iocore.h"
|
||||
#include "fmboard.h"
|
||||
#include "dmac.h"
|
||||
#include "cpucore.h"
|
||||
#ifndef CPU_STAT_PM
|
||||
#define CPU_STAT_PM 0
|
||||
#endif
|
||||
|
||||
CS4231CFG cs4231cfg;
|
||||
|
||||
static SINT32 cs4231_totalsample = 0;
|
||||
|
||||
enum {
|
||||
CS4231REG_LINPUT = 0x00,
|
||||
CS4231REG_RINPUT = 0x01,
|
||||
CS4231REG_AUX1L = 0x02,
|
||||
CS4231REG_AUX1R = 0x03,
|
||||
CS4231REG_AUX2L = 0x04,
|
||||
CS4231REG_AUX2R = 0x05,
|
||||
CS4231REG_LOUTPUT = 0x06,
|
||||
CS4231REG_ROUTPUT = 0x07,
|
||||
CS4231REG_PLAYFMT = 0x08,
|
||||
CS4231REG_INTERFACE = 0x09,
|
||||
CS4231REG_PINCTRL = 0x0a,
|
||||
CS4231REG_TESTINIT = 0x0b,
|
||||
CS4231REG_MISCINFO = 0x0c,
|
||||
CS4231REG_LOOPBACK = 0x0d,
|
||||
CS4231REG_PLAYCNTM = 0x0e,
|
||||
CS4231REG_PLAYCNTL = 0x0f,
|
||||
|
||||
CS4231REG_FEATURE1 = 0x10,
|
||||
CS4231REG_FEATURE2 = 0x11,
|
||||
CS4231REG_LLINEIN = 0x12,
|
||||
CS4231REG_RLINEIN = 0x13,
|
||||
CS4231REG_TIMERL = 0x14,
|
||||
CS4231REG_TIMERH = 0x15,
|
||||
CS4231REG_RESERVED1= 0x16,
|
||||
CS4231REG_RESERVED2= 0x17,
|
||||
CS4231REG_IRQSTAT = 0x18,
|
||||
CS4231REG_VERSION = 0x19,
|
||||
CS4231REG_MONOCTRL = 0x1a,
|
||||
CS4231REG_RECFMT = 0x1c,
|
||||
CS4231REG_PLAYFREQ = 0x1d,
|
||||
CS4231REG_RECCNTM = 0x1e,
|
||||
CS4231REG_RECCNTL = 0x1f
|
||||
};
|
||||
|
||||
|
||||
UINT dmac_getdata_(DMACH dmach, UINT8 *buf, UINT offset, UINT size);
|
||||
static const UINT32 cs4231xtal64[2] = {24576000/64, 16934400/64};
|
||||
|
||||
static const UINT8 cs4231cnt64[8] = {
|
||||
3072/64, // 8000/ 5510
|
||||
1536/64, // 16000/11025
|
||||
896/64, // 27420/18900
|
||||
768/64, // 32000/22050
|
||||
448/64, // 54840/37800
|
||||
384/64, // 64000/44100
|
||||
512/64, // 48000/33075
|
||||
2560/64}; // 9600/ 6620
|
||||
|
||||
// 640:441
|
||||
|
||||
void cs4231_initialize(UINT rate) {
|
||||
|
||||
cs4231cfg.rate = rate;
|
||||
}
|
||||
|
||||
void cs4231_setvol(UINT vol) {
|
||||
|
||||
(void)vol;
|
||||
}
|
||||
|
||||
// CS4231 DMA処理
|
||||
void cs4231_dma(NEVENTITEM item) {
|
||||
|
||||
DMACH dmach;
|
||||
UINT rem;
|
||||
UINT pos;
|
||||
UINT size;
|
||||
UINT r;
|
||||
SINT32 cnt;
|
||||
if (item->flag & NEVENT_SETEVENT) {
|
||||
if (cs4231.dmach != 0xff) {
|
||||
dmach = dmac.dmach + cs4231.dmach;
|
||||
|
||||
// サウンド再生用バッファに送る?(cs4231g.c)
|
||||
sound_sync();
|
||||
|
||||
// バッファに空きがあればデータを読み出す
|
||||
if (cs4231.bufsize-4 > cs4231.bufdatas) {
|
||||
rem = min(cs4231.bufsize - 4 - cs4231.bufdatas, 512); //読み取り単位は16bitステレオの1サンプル分(4byte)にしておかないと雑音化する
|
||||
pos = cs4231.bufwpos & CS4231_BUFMASK; // バッファ書き込み位置
|
||||
size = min(rem, dmach->startcount); // バッファ書き込みサイズ
|
||||
r = dmac_getdata_(dmach, cs4231.buffer, pos, size); // DMA読み取り実行
|
||||
cs4231.bufwpos = (cs4231.bufwpos + r) & CS4231_BUFMASK; // バッファ書き込み位置を更新
|
||||
cs4231.bufdatas += r; // バッファ内の有効なデータ数を更新 = (bufwpos-bufpos)&CS4231_BUFMASK
|
||||
}
|
||||
|
||||
// まだデータがありそうならNEVENTをセット
|
||||
if ((dmach->leng.w) && (cs4231cfg.rate)) {
|
||||
cnt = pccore.realclock * 4 / cs4231cfg.rate;
|
||||
nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_RELATIVE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
(void)item;
|
||||
}
|
||||
|
||||
// PIO再生用
|
||||
void cs4231_datasend(REG8 dat) {
|
||||
UINT pos;
|
||||
if (cs4231.reg.iface & PPIO) { // PIO play enable
|
||||
if (cs4231.bufsize <= cs4231.bufdatas) {
|
||||
sound_sync();
|
||||
}
|
||||
if (cs4231.bufsize > cs4231.bufdatas) {
|
||||
pos = (cs4231.bufwpos) & CS4231_BUFMASK;
|
||||
cs4231.buffer[pos] = dat;
|
||||
cs4231.bufdatas++;
|
||||
cs4231.bufwpos = (cs4231.bufwpos + 1) & CS4231_BUFMASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DMA再生開始・終了・中断時に呼ばれる(つもり)
|
||||
REG8 DMACCALL cs4231dmafunc(REG8 func) {
|
||||
SINT32 cnt;
|
||||
switch(func) {
|
||||
case DMAEXT_START:
|
||||
if (cs4231cfg.rate) {
|
||||
//DMACH dmach;
|
||||
//dmach = dmac.dmach + cs4231.dmach;
|
||||
//dmach->adrs.d = dmach->startaddr;
|
||||
//cs4231.bufpos = cs4231.bufwpos;
|
||||
//cs4231.bufdatas = 0;
|
||||
cs4231_totalsample = 0;
|
||||
cnt = pccore.realclock * 4 / cs4231cfg.rate;
|
||||
nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_ABSOLUTE);
|
||||
}
|
||||
break;
|
||||
case DMAEXT_END:
|
||||
// ここでの割り込みは要らない?
|
||||
//if ((cs4231.reg.pinctrl & IEN) && (cs4231.dmairq != 0xff)) {
|
||||
// cs4231.intflag |= INt;
|
||||
// cs4231.reg.featurestatus |= PI;
|
||||
// pic_setirq(cs4231.dmairq);
|
||||
//}
|
||||
break;
|
||||
|
||||
case DMAEXT_BREAK:
|
||||
//{
|
||||
// DMACH dmach;
|
||||
// dmach = dmac.dmach + cs4231.dmach;
|
||||
// dmach->adrs.d = dmach->startaddr;
|
||||
//}
|
||||
nevent_reset(NEVENT_CS4231);
|
||||
break;
|
||||
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void cs4231_reset(void) {
|
||||
|
||||
ZeroMemory(&cs4231, sizeof(cs4231));
|
||||
cs4231.bufsize = CS4231_BUFFERS;
|
||||
// cs4231.proc = cs4231_nodecode;
|
||||
cs4231.dmach = 0xff;
|
||||
cs4231.dmairq = 0xff;
|
||||
//cs4231.timer = 200; // XXX: 何も入れてくれないのでそれっぽいのを入れる・・・(10usec単位)
|
||||
cs4231_totalsample = 0;
|
||||
FillMemory(cs4231.port, sizeof(cs4231.port), 0xff);
|
||||
}
|
||||
|
||||
void cs4231_update(void) {
|
||||
}
|
||||
|
||||
// バッファ位置のズレ修正用(雑音化防止)
|
||||
static void setdataalign(void) {
|
||||
|
||||
UINT step;
|
||||
|
||||
// バッファ位置がズレていたら修正(4byte単位に)
|
||||
step = (0 - cs4231.bufpos) & 3;
|
||||
if (step) {
|
||||
cs4231.bufpos += step;
|
||||
cs4231.bufdatas -= min(step, cs4231.bufdatas);
|
||||
}
|
||||
cs4231.bufdatas &= ~3;
|
||||
step = (0 - cs4231.bufwpos) & 3;
|
||||
if (step) {
|
||||
cs4231.bufwpos += step;
|
||||
}
|
||||
}
|
||||
|
||||
// CS4231 Indexed Data registerの処理
|
||||
void cs4231_control(UINT idx, REG8 dat) {
|
||||
UINT8 modify;
|
||||
DMACH dmach;
|
||||
switch(idx){
|
||||
case 0xd:
|
||||
break;
|
||||
case 0xc:
|
||||
dat &= 0x40;
|
||||
dat |= 0x8a;
|
||||
break;
|
||||
case 0xb://ErrorStatus
|
||||
case 0x19://Version ID
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
dmach = dmac.dmach + cs4231.dmach;
|
||||
modify = ((UINT8 *)&cs4231.reg)[idx] ^ dat;
|
||||
((UINT8 *)&cs4231.reg)[idx] = dat;
|
||||
switch(idx) {
|
||||
case CS4231REG_PLAYFMT:
|
||||
// 再生フォーマット設定とか Fs and Playback Data Format (I8)
|
||||
if (modify & 0xf0) {
|
||||
//dmach->adrs.d = dmach->startaddr;
|
||||
cs4231.bufpos = cs4231.bufwpos;
|
||||
cs4231.bufdatas = 0;
|
||||
setdataalign();
|
||||
}
|
||||
if (cs4231cfg.rate) {
|
||||
UINT32 r;
|
||||
r = cs4231xtal64[dat & 1] / cs4231cnt64[(dat >> 1) & 7];
|
||||
TRACEOUT(("samprate = %d", r));
|
||||
r <<= 12;
|
||||
r /= cs4231cfg.rate;
|
||||
cs4231.step12 = r;
|
||||
TRACEOUT(("step12 = %d", r));
|
||||
}
|
||||
else {
|
||||
cs4231.step12 = 0;
|
||||
}
|
||||
break;
|
||||
case CS4231REG_INTERFACE:
|
||||
// 再生録音の有効無効とかDMAとかの設定 Interface Configuration (I9)
|
||||
if (modify & PEN ) {
|
||||
if (cs4231.dmach != 0xff) {
|
||||
dmach = dmac.dmach + cs4231.dmach;
|
||||
if ((dat & (PEN)) == (PEN)){
|
||||
dmach->ready = 1;
|
||||
}
|
||||
else {
|
||||
dmach->ready = 0;
|
||||
}
|
||||
dmac_check();
|
||||
}
|
||||
if (!(dat & PEN)) { // stop!
|
||||
cs4231.pos12 = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CS4231REG_IRQSTAT:
|
||||
// バッファオーバーラン・アンダーランや割り込みを検出するためのレジスタ? Alternate Feature Status (I24)
|
||||
if (modify & PI) {
|
||||
/* XXX: TI CI */
|
||||
pic_resetirq (cs4231.dmairq);
|
||||
cs4231.intflag &= ~INt;
|
||||
}
|
||||
break;
|
||||
case CS4231REG_PLAYCNTM:
|
||||
// Playback Upper Base (I14)
|
||||
// cs4231.reg.playcount[0]
|
||||
break;
|
||||
case CS4231REG_PLAYCNTL:
|
||||
// Playback Lower Base (I15)
|
||||
// cs4231.reg.playcount[1]
|
||||
break;
|
||||
//case CS4231REG_TIMERL:
|
||||
// // CS4231 割り込みタイマー設定(下位バイト)
|
||||
// cs4231.reg.timer[0]
|
||||
// break;
|
||||
//case CS4231REG_TIMERH:
|
||||
// // CS4231 割り込みタイマー設定(上位バイト)
|
||||
// cs4231.reg.timer[1]
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
// 各フォーマットの割り込み間隔テーブル(たぶん1サンプルあたりのバイト数)
|
||||
//static const SINT32 cs4231_irqsamples[16] = {
|
||||
// 1 , // 0: 8bit PCM
|
||||
// 1*2,
|
||||
// 1 , // 1: u-Law
|
||||
// 1 ,
|
||||
// 1*2, // 2: 16bit PCM(little endian)?
|
||||
// 1*4,
|
||||
// 1 , // 3: A-Law
|
||||
// 1 ,
|
||||
// 1 , // 4:
|
||||
// 1 ,
|
||||
// 1 , // 5: ADPCM
|
||||
// 1 ,
|
||||
// 1*2, // 6: 16bit PCM
|
||||
// 1*4,
|
||||
// 1 , // 7: ADPCM
|
||||
// 1 };
|
||||
|
||||
|
||||
static const SINT32 cs4231_playcountshift[16] = {
|
||||
1 , // 0: 8bit PCM
|
||||
1*2,
|
||||
1 , // 1: u-Law
|
||||
1 ,
|
||||
1*2, // 2: 16bit PCM(little endian)?
|
||||
1*4,
|
||||
1 , // 3: A-Law
|
||||
1 ,
|
||||
1 , // 4:
|
||||
1 ,
|
||||
1 , // 5: ADPCM
|
||||
1 ,
|
||||
1*2, // 6: 16bit PCM
|
||||
1*4,
|
||||
1 , // 7: ADPCM
|
||||
1 };
|
||||
|
||||
|
||||
// CS4231 DMAデータ読み取り
|
||||
UINT dmac_getdata_(DMACH dmach, UINT8 *buf, UINT offset, UINT size) {
|
||||
UINT leng; // 読み取り数
|
||||
UINT lengsum; // 合計読み取り数
|
||||
UINT32 addr;
|
||||
UINT i;
|
||||
SINT32 sampleirq = 0; // 割り込みまでに必要なデータ転送数(byte)
|
||||
|
||||
lengsum = 0;
|
||||
while(size > 0) {
|
||||
leng = min(dmach->leng.w, size);
|
||||
if (leng) {
|
||||
addr = dmach->adrs.d; // 現在のメモリ読み取り位置
|
||||
if (!(dmach->mode & 0x20)) { // dir +
|
||||
// +方向にDMA転送
|
||||
for (i=0; i<leng ; i++) {
|
||||
buf[offset] = MEMP_READ8(addr);
|
||||
addr++;
|
||||
if(addr > dmach->lastaddr){
|
||||
addr = dmach->startaddr;
|
||||
}
|
||||
offset = (offset+1) & CS4231_BUFMASK;
|
||||
}
|
||||
dmach->adrs.d = addr;
|
||||
}
|
||||
else { // dir -
|
||||
// -方向にDMA転送
|
||||
for (i=0; i<leng; i++) {
|
||||
buf[offset] = MEMP_READ8(addr);
|
||||
addr--;
|
||||
if(addr < dmach->startaddr){
|
||||
addr = dmach->lastaddr;
|
||||
}
|
||||
offset = (offset-1) & CS4231_BUFMASK;
|
||||
}
|
||||
dmach->adrs.d = addr;
|
||||
}
|
||||
dmach->leng.w -= leng;
|
||||
|
||||
if (dmach->leng.w <= 0) {
|
||||
dmach->leng.w = dmach->startcount; // 戻す
|
||||
dmach->proc.extproc(DMAEXT_END);
|
||||
}
|
||||
|
||||
// 読み取り数と残り数更新
|
||||
lengsum += leng;
|
||||
size -= leng;
|
||||
|
||||
// Playback Countだけデータを転送したら割り込みを発生させる
|
||||
if ((cs4231.reg.pinctrl & IEN) && (cs4231.dmairq != 0xff)) {
|
||||
int playcount = (cs4231.reg.playcount[1]|(cs4231.reg.playcount[0] << 8)) * cs4231_playcountshift[cs4231.reg.datafmt >> 4];
|
||||
// 読み取り数カウント
|
||||
cs4231_totalsample += leng;
|
||||
|
||||
if(cs4231_totalsample >= playcount){
|
||||
cs4231_totalsample -= playcount;
|
||||
cs4231.intflag |= INt;
|
||||
cs4231.reg.featurestatus |= PI;
|
||||
pic_setirq(cs4231.dmairq);
|
||||
}
|
||||
}
|
||||
//// XXX: 一定バイト数読む毎に割り込みする(あまり根拠のない実装・・・)
|
||||
//sampleirq = cs4231_irqsamples[cs4231.reg.datafmt >> 4] * ((cs4231.step12*cs4231cfg.rate)>>12) / 32; // * 1100/1000; //XXX: 割り込み間隔実験式
|
||||
//if(cs4231_totalsample >= sampleirq){
|
||||
// if ((cs4231.reg.pinctrl & 2) && (cs4231.dmairq != 0xff)) {
|
||||
// //cs4231.intflag |= INt;
|
||||
// //cs4231.reg.featurestatus |= PI;
|
||||
// //pic_setirq(cs4231.dmairq);
|
||||
// }
|
||||
// cs4231_totalsample -= sampleirq;
|
||||
//}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(lengsum);
|
||||
}
|
||||
|
||||
|
119
sound/cs4231g.c
119
sound/cs4231g.c
@ -5,15 +5,23 @@
|
||||
|
||||
#include "compiler.h"
|
||||
#include "cs4231.h"
|
||||
#include "iocore.h"
|
||||
#include "sound/fmboard.h"
|
||||
#include <math.h>
|
||||
|
||||
extern CS4231CFG cs4231cfg;
|
||||
|
||||
static SINT32 cs4231_DACvolume_L = 1024;
|
||||
static SINT32 cs4231_DACvolume_R = 1024;
|
||||
static UINT16 cs4231_DACvolumereg_L = 0xff;
|
||||
static UINT16 cs4231_DACvolumereg_R = 0xff;
|
||||
|
||||
static void SOUNDCALL pcm8m(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 leng;
|
||||
UINT32 pos12;
|
||||
SINT32 fract;
|
||||
UINT samppos;
|
||||
UINT32 samppos;
|
||||
const UINT8 *ptr1;
|
||||
const UINT8 *ptr2;
|
||||
SINT32 samp1;
|
||||
@ -37,24 +45,24 @@ const UINT8 *ptr2;
|
||||
samp1 = (ptr1[0] - 0x80) << 8;
|
||||
samp2 = (ptr2[0] - 0x80) << 8;
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[0] += samp1;
|
||||
pcm[1] += samp1;
|
||||
pcm[0] += (samp1 * cs4231_DACvolume_L * np2cfg.vol_pcm) >> 15;
|
||||
pcm[1] += (samp1 * cs4231_DACvolume_R * np2cfg.vol_pcm) >> 15;
|
||||
pcm += 2;
|
||||
pos12 += cs->step12;
|
||||
} while(--count);
|
||||
|
||||
leng = min(leng, (pos12 >> 12));
|
||||
cs->bufdatas -= (leng << 0);
|
||||
cs->bufpos += (leng << 0);
|
||||
cs->bufpos = (cs->bufpos + (leng << 0)) & CS4231_BUFMASK;
|
||||
cs->pos12 = pos12 & ((1 << 12) - 1);
|
||||
}
|
||||
|
||||
static void SOUNDCALL pcm8s(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 leng;
|
||||
UINT32 pos12;
|
||||
SINT32 fract;
|
||||
UINT samppos;
|
||||
UINT32 samppos;
|
||||
const UINT8 *ptr1;
|
||||
const UINT8 *ptr2;
|
||||
SINT32 samp1;
|
||||
@ -78,27 +86,27 @@ const UINT8 *ptr2;
|
||||
samp1 = (ptr1[0] - 0x80) << 8;
|
||||
samp2 = (ptr2[0] - 0x80) << 8;
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[0] += samp1;
|
||||
pcm[0] += (samp1 * cs4231_DACvolume_L * np2cfg.vol_pcm) >> 15;
|
||||
samp1 = (ptr1[1] - 0x80) << 8;
|
||||
samp2 = (ptr2[1] - 0x80) << 8;
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[1] += samp1;
|
||||
pcm[1] += (samp1 * cs4231_DACvolume_R * np2cfg.vol_pcm) >> 15;
|
||||
pcm += 2;
|
||||
pos12 += cs->step12;
|
||||
} while(--count);
|
||||
|
||||
leng = min(leng, (pos12 >> 12));
|
||||
cs->bufdatas -= (leng << 1);
|
||||
cs->bufpos += (leng << 1);
|
||||
cs->bufpos = (cs->bufpos + (leng << 1)) & CS4231_BUFMASK;
|
||||
cs->pos12 = pos12 & ((1 << 12) - 1);
|
||||
}
|
||||
|
||||
static void SOUNDCALL pcm16m(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 leng;
|
||||
UINT32 pos12;
|
||||
SINT32 fract;
|
||||
UINT samppos;
|
||||
UINT32 samppos;
|
||||
const UINT8 *ptr1;
|
||||
const UINT8 *ptr2;
|
||||
SINT32 samp1;
|
||||
@ -122,24 +130,24 @@ const UINT8 *ptr2;
|
||||
samp1 = (((SINT8)ptr1[0]) << 8) + ptr1[1];
|
||||
samp2 = (((SINT8)ptr2[0]) << 8) + ptr2[1];
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[0] += samp1;
|
||||
pcm[1] += samp1;
|
||||
pcm[0] += (samp1 * cs4231_DACvolume_L * np2cfg.vol_pcm) >> 15;
|
||||
pcm[1] += (samp1 * cs4231_DACvolume_R * np2cfg.vol_pcm) >> 15;
|
||||
pcm += 2;
|
||||
pos12 += cs->step12;
|
||||
} while(--count);
|
||||
|
||||
leng = min(leng, (pos12 >> 12));
|
||||
cs->bufdatas -= (leng << 1);
|
||||
cs->bufpos += (leng << 1);
|
||||
cs->bufpos = (cs->bufpos + (leng << 1)) & CS4231_BUFMASK;
|
||||
cs->pos12 = pos12 & ((1 << 12) - 1);
|
||||
}
|
||||
|
||||
static void SOUNDCALL pcm16s(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 leng;
|
||||
UINT32 pos12;
|
||||
SINT32 fract;
|
||||
UINT samppos;
|
||||
UINT32 samppos;
|
||||
const UINT8 *ptr1;
|
||||
const UINT8 *ptr2;
|
||||
SINT32 samp1;
|
||||
@ -163,37 +171,32 @@ const UINT8 *ptr2;
|
||||
samp1 = (((SINT8)ptr1[0]) << 8) + ptr1[1];
|
||||
samp2 = (((SINT8)ptr2[0]) << 8) + ptr2[1];
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[0] += samp1;
|
||||
pcm[0] += (samp1 * cs4231_DACvolume_L * np2cfg.vol_pcm) >> 15;
|
||||
samp1 = (((SINT8)ptr1[2]) << 8) + ptr1[3];
|
||||
samp2 = (((SINT8)ptr2[2]) << 8) + ptr2[3];
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[1] += samp1;
|
||||
pcm[1] += (samp1 * cs4231_DACvolume_R * np2cfg.vol_pcm) >> 15;
|
||||
pcm += 2;
|
||||
pos12 += cs->step12;
|
||||
} while(--count);
|
||||
|
||||
leng = min(leng, (pos12 >> 12));
|
||||
cs->bufdatas -= (leng << 2);
|
||||
cs->bufpos += (leng << 2);
|
||||
cs->bufpos = (cs->bufpos + (leng << 2)) & CS4231_BUFMASK;
|
||||
cs->pos12 = pos12 & ((1 << 12) - 1);
|
||||
}
|
||||
|
||||
static void SOUNDCALL pcm16m_ex(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 leng;
|
||||
UINT32 pos12;
|
||||
SINT32 fract;
|
||||
UINT samppos;
|
||||
UINT32 samppos;
|
||||
const UINT8 *ptr1;
|
||||
const UINT8 *ptr2;
|
||||
SINT32 samp1;
|
||||
SINT32 samp2;
|
||||
UINT8 oddflag = 0;
|
||||
|
||||
if(cs->bufdatas & 1){
|
||||
oddflag = 1;
|
||||
}
|
||||
|
||||
leng = cs->bufdatas >> 1;
|
||||
if (!leng) {
|
||||
return;
|
||||
@ -212,36 +215,29 @@ const UINT8 *ptr2;
|
||||
samp1 = (((SINT8)ptr1[1]) << 8) + ptr1[0];
|
||||
samp2 = (((SINT8)ptr2[1]) << 8) + ptr2[0];
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[0] += samp1;
|
||||
pcm[1] += samp1;
|
||||
pcm[0] += (samp1 * cs4231_DACvolume_L * np2cfg.vol_pcm) >> 15;
|
||||
pcm[1] += (samp1 * cs4231_DACvolume_R * np2cfg.vol_pcm) >> 15;
|
||||
pcm += 2;
|
||||
pos12 += cs->step12;
|
||||
} while(--count);
|
||||
|
||||
if(oddflag){
|
||||
cs->bufdatas--;
|
||||
}
|
||||
leng = min(leng, (pos12 >> 12));
|
||||
cs->bufdatas -= (leng << 1);
|
||||
cs->bufpos += (leng << 1);
|
||||
cs->bufpos = (cs->bufpos + (leng << 1)) & CS4231_BUFMASK;
|
||||
cs->pos12 = pos12 & ((1 << 12) - 1);
|
||||
}
|
||||
|
||||
static void SOUNDCALL pcm16s_ex(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
UINT leng;
|
||||
UINT32 leng;
|
||||
UINT32 pos12;
|
||||
SINT32 fract;
|
||||
UINT samppos;
|
||||
UINT32 samppos;
|
||||
const UINT8 *ptr1;
|
||||
const UINT8 *ptr2;
|
||||
SINT32 samp1;
|
||||
SINT32 samp2;
|
||||
UINT8 oddflag = 0;
|
||||
|
||||
if(cs->bufdatas & 1){
|
||||
oddflag = 1;
|
||||
}
|
||||
|
||||
leng = cs->bufdatas >> 2;
|
||||
if (!leng) {
|
||||
return;
|
||||
@ -260,21 +256,18 @@ const UINT8 *ptr2;
|
||||
samp1 = (((SINT8)ptr1[1]) << 8) + ptr1[0];
|
||||
samp2 = (((SINT8)ptr2[1]) << 8) + ptr2[0];
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[0] += samp1;
|
||||
pcm[0] += (samp1 * cs4231_DACvolume_L * np2cfg.vol_pcm) >> 15;
|
||||
samp1 = (((SINT8)ptr1[3]) << 8) + ptr1[2];
|
||||
samp2 = (((SINT8)ptr2[3]) << 8) + ptr2[2];
|
||||
samp1 += ((samp2 - samp1) * fract) >> 12;
|
||||
pcm[1] += samp1;
|
||||
pcm[1] += (samp1 * cs4231_DACvolume_R * np2cfg.vol_pcm) >> 15;
|
||||
pcm += 2;
|
||||
pos12 += cs->step12;
|
||||
} while(--count);
|
||||
|
||||
if(oddflag){
|
||||
cs->bufdatas--;
|
||||
}
|
||||
leng = min(leng, (pos12 >> 12));
|
||||
cs->bufdatas -= (leng << 2);
|
||||
cs->bufpos += (leng << 2);
|
||||
cs->bufpos = (cs->bufpos + (leng << 2)) & CS4231_BUFMASK;
|
||||
cs->pos12 = pos12 & ((1 << 12) - 1);
|
||||
}
|
||||
|
||||
@ -293,7 +286,7 @@ static const CS4231FN cs4231fn[16] = {
|
||||
pcm8s,
|
||||
nomake, // 1: u-Law
|
||||
nomake,
|
||||
pcm16m_ex, // 2:
|
||||
pcm16m_ex, // 2: 16bit PCM(little endian)?
|
||||
pcm16s_ex,
|
||||
nomake, // 3: A-Law
|
||||
nomake,
|
||||
@ -312,7 +305,39 @@ static const CS4231FN cs4231fn[16] = {
|
||||
void SOUNDCALL cs4231_getpcm(CS4231 cs, SINT32 *pcm, UINT count) {
|
||||
|
||||
if ((cs->reg.iface & 1) && (count)) {
|
||||
if(cs4231_DACvolumereg_L != cs->reg.dac_l){
|
||||
cs4231_DACvolumereg_L = cs->reg.dac_l;
|
||||
if(cs->reg.dac_l & 0x80){ // DAC L Mute
|
||||
cs4231_DACvolume_L = 0;
|
||||
}else{
|
||||
cs4231_DACvolume_L = (int)(pow(10, -1.5 * ((cs4231_DACvolumereg_L) & 0x3f) / 20.0) * 1024); // DAC L Volume (1bit毎に-1.5dB)
|
||||
}
|
||||
}
|
||||
if(cs4231_DACvolumereg_R != cs->reg.dac_r){
|
||||
cs4231_DACvolumereg_R = cs->reg.dac_r;
|
||||
if(cs->reg.dac_r & 0x80){ // DAC R Mute
|
||||
cs4231_DACvolume_R = 0;
|
||||
}else{
|
||||
cs4231_DACvolume_R = (int)(pow(10, -1.5 * ((cs4231_DACvolumereg_R) & 0x3f) / 20.0) * 1024); // DAC R Volume (1bit毎に-1.5dB)
|
||||
}
|
||||
}
|
||||
(*cs4231fn[cs->reg.datafmt >> 4])(cs, pcm, count);
|
||||
//// CS4231タイマー割り込み(手抜き)
|
||||
//if ((cs->reg.pinctrl & 2) && (cs->dmairq != 0xff) && (cs->timer)) {
|
||||
// static double timercount = 0;
|
||||
// int decval = 0;
|
||||
// timercount += (double)count/44100 * 1000 * 100; // 10usec timer
|
||||
// decval = (int)(timercount);
|
||||
// timercount -= (double)decval;
|
||||
// cs->timercounter -= decval;
|
||||
// if(cs->timercounter < 0){
|
||||
// cs->timercounter = 3000;//cs->timer;
|
||||
// cs->intflag |= INt;
|
||||
// cs->reg.featurestatus |= PI;
|
||||
// pic_setirq(cs->dmairq);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -182,6 +182,7 @@ void fmboard_reset(const NP2CFG *pConfig, SOUNDID nSoundID)
|
||||
break;
|
||||
|
||||
case SOUNDID_PC_9801_118:
|
||||
g_nSoundID = nSoundID; // XXX: 先に設定
|
||||
board118_reset(pConfig);
|
||||
break;
|
||||
|
||||
@ -218,6 +219,12 @@ void fmboard_reset(const NP2CFG *pConfig, SOUNDID nSoundID)
|
||||
case SOUNDID_SOUNDORCHESTRAV:
|
||||
boardso_reset(pConfig, TRUE);
|
||||
break;
|
||||
|
||||
#if defined(SUPPORT_SOUND_SB16)
|
||||
case SOUNDID_SB16:
|
||||
boardsb16_reset(pConfig);
|
||||
break;
|
||||
#endif // defined(SUPPORT_SOUND_SB16)
|
||||
|
||||
#if defined(SUPPORT_PX)
|
||||
case SOUNDID_PX1:
|
||||
@ -293,6 +300,12 @@ void fmboard_bind(void) {
|
||||
boardso_bind();
|
||||
break;
|
||||
|
||||
#if defined(SUPPORT_SOUND_SB16)
|
||||
case SOUNDID_SB16:
|
||||
boardsb16_bind();
|
||||
break;
|
||||
#endif // defined(SUPPORT_SOUND_SB16)
|
||||
|
||||
#if defined(SUPPORT_PX)
|
||||
case SOUNDID_PX1:
|
||||
boardpx1_bind();
|
||||
@ -303,11 +316,6 @@ void fmboard_bind(void) {
|
||||
break;
|
||||
#endif // defined(SUPPORT_PX)
|
||||
|
||||
#if defined(SUPPORT_SOUND_SB16)
|
||||
case SOUNDID_SB16:
|
||||
boardsb16_bind();
|
||||
break;
|
||||
#endif // defined(SUPPORT_SOUND_SB16)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ typedef struct {
|
||||
UINT8 dmach;
|
||||
UINT16 base;
|
||||
UINT8 mixsel;
|
||||
UINT8 mixreg[0x18];
|
||||
UINT8 mixreg[0x100];
|
||||
} SB16;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
27
sound/mame/driver.h
Normal file
27
sound/mame/driver.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __DRIVER_H__
|
||||
#define __DRIVER_H__
|
||||
|
||||
#define HAS_YM3812 1
|
||||
#define HAS_YM3526 0
|
||||
#define HAS_Y8950 1
|
||||
#define HAS_YMF262 1
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4244)
|
||||
#pragma warning(disable: 4245)
|
||||
#define INLINE __inline static
|
||||
#elif defined(__BORLANDC__)
|
||||
#define INLINE __inline
|
||||
#elif defined(__GNUC__)
|
||||
#define INLINE __inline__
|
||||
#else
|
||||
#define INLINE static
|
||||
#endif
|
||||
|
||||
#define logerror(x,y,z)
|
||||
//typedef signed int stream_sample_t;
|
||||
typedef signed short stream_sample_t;
|
||||
|
||||
#endif /* __DRIVER_H__ */
|
214
sound/mame/fm.h
Normal file
214
sound/mame/fm.h
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
File: fm.h -- header file for software emulation for FM sound generator
|
||||
|
||||
*/
|
||||
#ifndef _H_FM_FM_
|
||||
#define _H_FM_FM_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --- select emulation chips --- */
|
||||
#define BUILD_YM2203 (HAS_YM2203) /* build YM2203(OPN) emulator */
|
||||
#define BUILD_YM2608 (HAS_YM2608) /* build YM2608(OPNA) emulator */
|
||||
#define BUILD_YM2610 (HAS_YM2610) /* build YM2610(OPNB) emulator */
|
||||
#define BUILD_YM2610B (HAS_YM2610B) /* build YM2610B(OPNB?)emulator */
|
||||
#define BUILD_YM2612 (HAS_YM2612 || HAS_YM3438) /* build YM2612(OPN2) emulator */
|
||||
|
||||
/* select bit size of output : 8 or 16 */
|
||||
#define FM_SAMPLE_BITS 16
|
||||
|
||||
/* select timer system internal or external */
|
||||
#define FM_INTERNAL_TIMER 0
|
||||
|
||||
/* --- speedup optimize --- */
|
||||
/* busy flag enulation , The definition of FM_GET_TIME_NOW() is necessary. */
|
||||
#define FM_BUSY_FLAG_SUPPORT 0
|
||||
//#define FM_BUSY_FLAG_SUPPORT 1
|
||||
|
||||
/* --- external SSG(YM2149/AY-3-8910)emulator interface port */
|
||||
/* used by YM2203,YM2608,and YM2610 */
|
||||
struct ssg_callbacks
|
||||
{
|
||||
void (*set_clock)(void *param, int clock);
|
||||
void (*write)(void *param, int address, int data);
|
||||
int (*read)(void *param);
|
||||
void (*reset)(void *param);
|
||||
};
|
||||
|
||||
/* --- external callback funstions for realtime update --- */
|
||||
|
||||
/* for busy flag emulation , function FM_GET_TIME_NOW() should */
|
||||
/* return present time in seconds with "double" precision */
|
||||
/* in timer.c */
|
||||
#define FM_GET_TIME_NOW() timer_get_time()
|
||||
|
||||
#if BUILD_YM2203
|
||||
/* in 2203intf.c */
|
||||
void YM2203UpdateRequest(void *param);
|
||||
#define YM2203UpdateReq(chip) YM2203UpdateRequest(chip)
|
||||
#endif
|
||||
#if BUILD_YM2608
|
||||
/* in 2608intf.c */
|
||||
void YM2608UpdateRequest(void *param);
|
||||
#define YM2608UpdateReq(chip) YM2608UpdateRequest(chip);
|
||||
#endif
|
||||
#if BUILD_YM2610
|
||||
/* in 2610intf.c */
|
||||
void YM2610UpdateRequest(void *param);
|
||||
#define YM2610UpdateReq(chip) YM2610UpdateRequest(chip);
|
||||
#endif
|
||||
#if BUILD_YM2612
|
||||
/* in 2612intf.c */
|
||||
void YM2612UpdateRequest(void *param);
|
||||
#define YM2612UpdateReq(chip) YM2612UpdateRequest(chip);
|
||||
#endif
|
||||
|
||||
/* compiler dependence */
|
||||
#if 1
|
||||
#ifndef OSD_CPU_H
|
||||
#define OSD_CPU_H
|
||||
typedef unsigned char UINT8; /* unsigned 8bit */
|
||||
typedef unsigned short UINT16; /* unsigned 16bit */
|
||||
typedef unsigned int UINT32; /* unsigned 32bit */
|
||||
typedef signed char INT8; /* signed 8bit */
|
||||
typedef signed short INT16; /* signed 16bit */
|
||||
typedef signed int INT32; /* signed 32bit */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef INLINE
|
||||
#define INLINE static __inline__
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//typedef stream_sample_t FMSAMPLE;
|
||||
/*
|
||||
#if (FM_SAMPLE_BITS==16)
|
||||
typedef INT16 FMSAMPLE;
|
||||
#endif
|
||||
#if (FM_SAMPLE_BITS==8)
|
||||
typedef unsigned char FMSAMPLE;
|
||||
#endif
|
||||
*/
|
||||
|
||||
typedef void (*FM_TIMERHANDLER)(void *param,int c,int cnt,double stepTime);
|
||||
typedef void (*FM_IRQHANDLER)(void *param,int irq);
|
||||
/* FM_TIMERHANDLER : Stop or Start timer */
|
||||
/* int n = chip number */
|
||||
/* int c = Channel 0=TimerA,1=TimerB */
|
||||
/* int count = timer count (0=stop) */
|
||||
/* doube stepTime = step time of one count (sec.)*/
|
||||
|
||||
/* FM_IRQHHANDLER : IRQ level changing sense */
|
||||
/* int n = chip number */
|
||||
/* int irq = IRQ level 0=OFF,1=ON */
|
||||
|
||||
#if BUILD_YM2203
|
||||
/* -------------------- YM2203(OPN) Interface -------------------- */
|
||||
|
||||
/*
|
||||
** Initialize YM2203 emulator(s).
|
||||
**
|
||||
** 'num' is the number of virtual YM2203's to allocate
|
||||
** 'baseclock'
|
||||
** 'rate' is sampling rate
|
||||
** 'TimerHandler' timer callback handler when timer start and clear
|
||||
** 'IRQHandler' IRQ callback handler when changed IRQ level
|
||||
** return 0 = success
|
||||
*/
|
||||
void * YM2203Init(void *param, int index, int baseclock, int rate,
|
||||
FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const struct ssg_callbacks *ssg);
|
||||
|
||||
/*
|
||||
** shutdown the YM2203 emulators
|
||||
*/
|
||||
void YM2203Shutdown(void *chip);
|
||||
|
||||
/*
|
||||
** reset all chip registers for YM2203 number 'num'
|
||||
*/
|
||||
void YM2203ResetChip(void *chip);
|
||||
|
||||
/*
|
||||
** update one of chip
|
||||
*/
|
||||
void YM2203UpdateOne(void *chip, FMSAMPLE *buffer, int length);
|
||||
|
||||
/*
|
||||
** Write
|
||||
** return : InterruptLevel
|
||||
*/
|
||||
int YM2203Write(void *chip,int a,unsigned char v);
|
||||
|
||||
/*
|
||||
** Read
|
||||
** return : InterruptLevel
|
||||
*/
|
||||
unsigned char YM2203Read(void *chip,int a);
|
||||
|
||||
/*
|
||||
** Timer OverFlow
|
||||
*/
|
||||
int YM2203TimerOver(void *chip, int c);
|
||||
|
||||
/*
|
||||
** State Save
|
||||
*/
|
||||
void YM2203Postload(void *chip);
|
||||
#endif /* BUILD_YM2203 */
|
||||
|
||||
#if BUILD_YM2608
|
||||
/* -------------------- YM2608(OPNA) Interface -------------------- */
|
||||
void * YM2608Init(void *param, int index, int baseclock, int rate,
|
||||
void *pcmroma,int pcmsizea,
|
||||
FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const struct ssg_callbacks *ssg);
|
||||
void YM2608Shutdown(void *chip);
|
||||
void YM2608ResetChip(void *chip);
|
||||
void YM2608UpdateOne(void *chip, FMSAMPLE **buffer, int length);
|
||||
|
||||
int YM2608Write(void *chip, int a,unsigned char v);
|
||||
unsigned char YM2608Read(void *chip,int a);
|
||||
int YM2608TimerOver(void *chip, int c );
|
||||
void YM2608Postload(void *chip);
|
||||
#endif /* BUILD_YM2608 */
|
||||
|
||||
#if (BUILD_YM2610||BUILD_YM2610B)
|
||||
/* -------------------- YM2610(OPNB) Interface -------------------- */
|
||||
void * YM2610Init(void *param, int index, int baseclock, int rate,
|
||||
void *pcmroma,int pcmasize,void *pcmromb,int pcmbsize,
|
||||
FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const struct ssg_callbacks *ssg);
|
||||
void YM2610Shutdown(void *chip);
|
||||
void YM2610ResetChip(void *chip);
|
||||
void YM2610UpdateOne(void *chip, FMSAMPLE **buffer, int length);
|
||||
#if BUILD_YM2610B
|
||||
void YM2610BUpdateOne(void *chip, FMSAMPLE **buffer, int length);
|
||||
#endif
|
||||
|
||||
int YM2610Write(void *chip, int a,unsigned char v);
|
||||
unsigned char YM2610Read(void *chip,int a);
|
||||
int YM2610TimerOver(void *chip, int c );
|
||||
void YM2610Postload(void *chip);
|
||||
#endif /* BUILD_YM2610 */
|
||||
|
||||
#if BUILD_YM2612
|
||||
void * YM2612Init(void *param, int index, int baseclock, int rate,
|
||||
FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler);
|
||||
void YM2612Shutdown(void *chip);
|
||||
void YM2612ResetChip(void *chip);
|
||||
void YM2612UpdateOne(void *chip, FMSAMPLE **buffer, int length);
|
||||
|
||||
int YM2612Write(void *chip, int a,unsigned char v);
|
||||
unsigned char YM2612Read(void *chip,int a);
|
||||
int YM2612TimerOver(void *chip, int c );
|
||||
void YM2612Postload(void *chip);
|
||||
#endif /* BUILD_YM2612 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _H_FM_FM_ */
|
2480
sound/mame/fmopl.c
Normal file
2480
sound/mame/fmopl.c
Normal file
File diff suppressed because it is too large
Load Diff
111
sound/mame/fmopl.h
Normal file
111
sound/mame/fmopl.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef __FMOPL_H_
|
||||
#define __FMOPL_H_
|
||||
|
||||
/* --- select emulation chips --- */
|
||||
#define BUILD_YM3812 (HAS_YM3812)
|
||||
//#define BUILD_YM3526 (HAS_YM3526)
|
||||
#define BUILD_Y8950 (HAS_Y8950)
|
||||
|
||||
/* select output bits size of output : 8 or 16 */
|
||||
#define OPL_SAMPLE_BITS 16
|
||||
|
||||
/* compiler dependence */
|
||||
#ifndef OSD_CPU_H
|
||||
#define OSD_CPU_H
|
||||
typedef unsigned char UINT8; /* unsigned 8bit */
|
||||
typedef unsigned short UINT16; /* unsigned 16bit */
|
||||
typedef unsigned int UINT32; /* unsigned 32bit */
|
||||
typedef signed char INT8; /* signed 8bit */
|
||||
typedef signed short INT16; /* signed 16bit */
|
||||
typedef signed int INT32; /* signed 32bit */
|
||||
#endif
|
||||
|
||||
typedef stream_sample_t OPLSAMPLE;
|
||||
/*
|
||||
#if (OPL_SAMPLE_BITS==16)
|
||||
typedef INT16 OPLSAMPLE;
|
||||
#endif
|
||||
#if (OPL_SAMPLE_BITS==8)
|
||||
typedef INT8 OPLSAMPLE;
|
||||
#endif
|
||||
*/
|
||||
|
||||
typedef void (*OPL_TIMERHANDLER)(void *param,int timer,double interval_Sec);
|
||||
typedef void (*OPL_IRQHANDLER)(void *param,int irq);
|
||||
typedef void (*OPL_UPDATEHANDLER)(void *param,int min_interval_us);
|
||||
typedef void (*OPL_PORTHANDLER_W)(void *param,unsigned char data);
|
||||
typedef unsigned char (*OPL_PORTHANDLER_R)(void *param);
|
||||
|
||||
|
||||
#if BUILD_YM3812
|
||||
|
||||
void *YM3812Init(int clock, int rate);
|
||||
void YM3812Shutdown(void *chip);
|
||||
void YM3812ResetChip(void *chip);
|
||||
int YM3812Write(void *chip, int a, int v);
|
||||
unsigned char YM3812Read(void *chip, int a);
|
||||
int YM3812TimerOver(void *chip, int c);
|
||||
void YM3812UpdateOne(void *chip, OPLSAMPLE *buffer, int length);
|
||||
|
||||
void YM3812SetTimerHandler(void *chip, OPL_TIMERHANDLER TimerHandler, void *param);
|
||||
void YM3812SetIRQHandler(void *chip, OPL_IRQHANDLER IRQHandler, void *param);
|
||||
void YM3812SetUpdateHandler(void *chip, OPL_UPDATEHANDLER UpdateHandler, void *param);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if BUILD_YM3526
|
||||
|
||||
/*
|
||||
** Initialize YM3526 emulator(s).
|
||||
**
|
||||
** 'num' is the number of virtual YM3526's to allocate
|
||||
** 'clock' is the chip clock in Hz
|
||||
** 'rate' is sampling rate
|
||||
*/
|
||||
void *YM3526Init(int clock, int rate);
|
||||
/* shutdown the YM3526 emulators*/
|
||||
void YM3526Shutdown(void *chip);
|
||||
void YM3526ResetChip(void *chip);
|
||||
int YM3526Write(void *chip, int a, int v);
|
||||
unsigned char YM3526Read(void *chip, int a);
|
||||
int YM3526TimerOver(void *chip, int c);
|
||||
/*
|
||||
** Generate samples for one of the YM3526's
|
||||
**
|
||||
** 'which' is the virtual YM3526 number
|
||||
** '*buffer' is the output buffer pointer
|
||||
** 'length' is the number of samples that should be generated
|
||||
*/
|
||||
void YM3526UpdateOne(void *chip, OPLSAMPLE *buffer, int length);
|
||||
|
||||
void YM3526SetTimerHandler(void *chip, OPL_TIMERHANDLER TimerHandler, void *param);
|
||||
void YM3526SetIRQHandler(void *chip, OPL_IRQHANDLER IRQHandler, void *param);
|
||||
void YM3526SetUpdateHandler(void *chip, OPL_UPDATEHANDLER UpdateHandler, void *param);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if BUILD_Y8950
|
||||
|
||||
/* Y8950 port handlers */
|
||||
void Y8950SetPortHandler(void *chip, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, void *param);
|
||||
void Y8950SetKeyboardHandler(void *chip, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, void *param);
|
||||
void Y8950SetDeltaTMemory(void *chip, void * deltat_mem_ptr, int deltat_mem_size );
|
||||
|
||||
void * Y8950Init (int clock, int rate);
|
||||
void Y8950Shutdown (void *chip);
|
||||
void Y8950ResetChip (void *chip);
|
||||
int Y8950Write (void *chip, int a, int v);
|
||||
unsigned char Y8950Read (void *chip, int a);
|
||||
int Y8950TimerOver (void *chip, int c);
|
||||
void Y8950UpdateOne (void *chip, OPLSAMPLE *buffer, int length);
|
||||
|
||||
void Y8950SetTimerHandler (void *chip, OPL_TIMERHANDLER TimerHandler, void *param);
|
||||
void Y8950SetIRQHandler (void *chip, OPL_IRQHANDLER IRQHandler, void *param);
|
||||
void Y8950SetUpdateHandler (void *chip, OPL_UPDATEHANDLER UpdateHandler, void *param);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __FMOPL_H_ */
|
654
sound/mame/ymdeltat.c
Normal file
654
sound/mame/ymdeltat.c
Normal file
@ -0,0 +1,654 @@
|
||||
/*
|
||||
**
|
||||
** File: ymdeltat.c
|
||||
**
|
||||
** YAMAHA DELTA-T adpcm sound emulation subroutine
|
||||
** used by fmopl.c (Y8950) and fm.c (YM2608 and YM2610/B)
|
||||
**
|
||||
** Base program is YM2610 emulator by Hiromitsu Shioya.
|
||||
** Written by Tatsuyuki Satoh
|
||||
** Improvements by Jarek Burczynski (bujar at mame dot net)
|
||||
**
|
||||
**
|
||||
** History:
|
||||
**
|
||||
** 03-08-2003 Jarek Burczynski:
|
||||
** - fixed BRDY flag implementation.
|
||||
**
|
||||
** 24-07-2003 Jarek Burczynski, Frits Hilderink:
|
||||
** - fixed delault value for control2 in YM_DELTAT_ADPCM_Reset
|
||||
**
|
||||
** 22-07-2003 Jarek Burczynski, Frits Hilderink:
|
||||
** - fixed external memory support
|
||||
**
|
||||
** 15-06-2003 Jarek Burczynski:
|
||||
** - implemented CPU -> AUDIO ADPCM synthesis (via writes to the ADPCM data reg $08)
|
||||
** - implemented support for the Limit address register
|
||||
** - supported two bits from the control register 2 ($01): RAM TYPE (x1 bit/x8 bit), ROM/RAM
|
||||
** - implemented external memory access (read/write) via the ADPCM data reg reads/writes
|
||||
** Thanks go to Frits Hilderink for the example code.
|
||||
**
|
||||
** 14-06-2003 Jarek Burczynski:
|
||||
** - various fixes to enable proper support for status register flags: BSRDY, PCM BSY, ZERO
|
||||
** - modified EOS handling
|
||||
**
|
||||
** 05-04-2003 Jarek Burczynski:
|
||||
** - implemented partial support for external/processor memory on sample replay
|
||||
**
|
||||
** 01-12-2002 Jarek Burczynski:
|
||||
** - fixed first missing sound in gigandes thanks to previous fix (interpolator) by ElSemi
|
||||
** - renamed/removed some YM_DELTAT struct fields
|
||||
**
|
||||
** 28-12-2001 Acho A. Tang
|
||||
** - added EOS status report on ADPCM playback.
|
||||
**
|
||||
** 05-08-2001 Jarek Burczynski:
|
||||
** - now_step is initialized with 0 at the start of play.
|
||||
**
|
||||
** 12-06-2001 Jarek Burczynski:
|
||||
** - corrected end of sample bug in YM_DELTAT_ADPCM_CALC.
|
||||
** Checked on real YM2610 chip - address register is 24 bits wide.
|
||||
** Thanks go to Stefan Jokisch (stefan.jokisch@gmx.de) for tracking down the problem.
|
||||
**
|
||||
** TO DO:
|
||||
** Check size of the address register on the other chips....
|
||||
**
|
||||
** Version 0.72
|
||||
**
|
||||
** sound chips that have this unit:
|
||||
** YM2608 OPNA
|
||||
** YM2610/B OPNB
|
||||
** Y8950 MSX AUDIO
|
||||
**
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
//#include "state.h"
|
||||
#include "fm.h"
|
||||
#include "ymdeltat.h"
|
||||
|
||||
#define YM_DELTAT_DELTA_MAX (24576)
|
||||
#define YM_DELTAT_DELTA_MIN (127)
|
||||
#define YM_DELTAT_DELTA_DEF (127)
|
||||
|
||||
#define YM_DELTAT_DECODE_RANGE 32768
|
||||
#define YM_DELTAT_DECODE_MIN (-(YM_DELTAT_DECODE_RANGE))
|
||||
#define YM_DELTAT_DECODE_MAX ((YM_DELTAT_DECODE_RANGE)-1)
|
||||
|
||||
|
||||
/* Forecast to next Forecast (rate = *8) */
|
||||
/* 1/8 , 3/8 , 5/8 , 7/8 , 9/8 , 11/8 , 13/8 , 15/8 */
|
||||
const INT32 ym_deltat_decode_tableB1[16] = {
|
||||
1, 3, 5, 7, 9, 11, 13, 15,
|
||||
-1, -3, -5, -7, -9, -11, -13, -15,
|
||||
};
|
||||
/* delta to next delta (rate= *64) */
|
||||
/* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
|
||||
const INT32 ym_deltat_decode_tableB2[16] = {
|
||||
57, 57, 57, 57, 77, 102, 128, 153,
|
||||
57, 57, 57, 57, 77, 102, 128, 153
|
||||
};
|
||||
|
||||
#if 0
|
||||
void YM_DELTAT_BRDY_callback(YM_DELTAT *DELTAT)
|
||||
{
|
||||
logerror("BRDY_callback reached (flag set) !\n");
|
||||
|
||||
/* set BRDY bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT8 YM_DELTAT_ADPCM_Read(YM_DELTAT *DELTAT)
|
||||
{
|
||||
UINT8 v = 0;
|
||||
|
||||
/* external memory read */
|
||||
if ( (DELTAT->portstate & 0xe0)==0x20 )
|
||||
{
|
||||
/* two dummy reads */
|
||||
if (DELTAT->memread)
|
||||
{
|
||||
DELTAT->now_addr = DELTAT->start << 1;
|
||||
DELTAT->memread--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if ( DELTAT->now_addr != (DELTAT->end<<1) )
|
||||
{
|
||||
v = DELTAT->memory[DELTAT->now_addr>>1];
|
||||
|
||||
/*logerror("YM Delta-T memory read $%08x, v=$%02x\n", DELTAT->now_addr >> 1, v);*/
|
||||
|
||||
DELTAT->now_addr+=2; /* two nibbles at a time */
|
||||
|
||||
/* reset BRDY bit in status register, which means we are reading the memory now */
|
||||
if(DELTAT->status_reset_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_reset_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
|
||||
/* setup a timer that will callback us in 10 master clock cycles for Y8950
|
||||
* in the callback set the BRDY flag to 1 , which means we have another data ready.
|
||||
* For now, we don't really do this; we simply reset and set the flag in zero time, so that the IRQ will work.
|
||||
*/
|
||||
/* set BRDY bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set EOS bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_EOS_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/* 0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */
|
||||
static UINT8 dram_rightshift[4]={3,0,0,0};
|
||||
|
||||
/* DELTA-T ADPCM write register */
|
||||
void YM_DELTAT_ADPCM_Write(YM_DELTAT *DELTAT,int r,int v)
|
||||
{
|
||||
if(r>=0x10) return;
|
||||
DELTAT->reg[r] = v; /* stock data */
|
||||
|
||||
switch( r )
|
||||
{
|
||||
case 0x00:
|
||||
/*
|
||||
START:
|
||||
Accessing *external* memory is started when START bit (D7) is set to "1", so
|
||||
you must set all conditions needed for recording/playback before starting.
|
||||
If you access *CPU-managed* memory, recording/playback starts after
|
||||
read/write of ADPCM data register $08.
|
||||
|
||||
REC:
|
||||
0 = ADPCM synthesis (playback)
|
||||
1 = ADPCM analysis (record)
|
||||
|
||||
MEMDATA:
|
||||
0 = processor (*CPU-managed*) memory (means: using register $08)
|
||||
1 = external memory (using start/end/limit registers to access memory: RAM or ROM)
|
||||
|
||||
|
||||
SPOFF:
|
||||
controls output pin that should disable the speaker while ADPCM analysis
|
||||
|
||||
RESET and REPEAT only work with external memory.
|
||||
|
||||
|
||||
some examples:
|
||||
value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning:
|
||||
C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
|
||||
E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register
|
||||
80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
|
||||
a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register
|
||||
|
||||
60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08
|
||||
20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08
|
||||
|
||||
*/
|
||||
/* handle emulation mode */
|
||||
if(DELTAT->emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610)
|
||||
{
|
||||
v |= 0x20; /* YM2610 always uses external memory and doesn't even have memory flag bit. */
|
||||
}
|
||||
|
||||
DELTAT->portstate = v & (0x80|0x40|0x20|0x10|0x01); /* start, rec, memory mode, repeat flag copy, reset(bit0) */
|
||||
|
||||
if( DELTAT->portstate&0x80 )/* START,REC,MEMDATA,REPEAT,SPOFF,--,--,RESET */
|
||||
{
|
||||
/* set PCM BUSY bit */
|
||||
DELTAT->PCM_BSY = 1;
|
||||
|
||||
/* start ADPCM */
|
||||
DELTAT->now_step = 0;
|
||||
DELTAT->acc = 0;
|
||||
DELTAT->prev_acc = 0;
|
||||
DELTAT->adpcml = 0;
|
||||
DELTAT->adpcmd = YM_DELTAT_DELTA_DEF;
|
||||
DELTAT->now_data = 0;
|
||||
|
||||
}
|
||||
|
||||
if( DELTAT->portstate&0x20 ) /* do we access external memory? */
|
||||
{
|
||||
DELTAT->now_addr = DELTAT->start << 1;
|
||||
DELTAT->memread = 2; /* two dummy reads needed before accesing external memory via register $08*/
|
||||
|
||||
/* if yes, then let's check if ADPCM memory is mapped and big enough */
|
||||
if(DELTAT->memory == 0)
|
||||
{
|
||||
// logerror("YM Delta-T ADPCM rom not mapped\n");
|
||||
DELTAT->portstate = 0x00;
|
||||
DELTAT->PCM_BSY = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( DELTAT->end >= DELTAT->memory_size ) /* Check End in Range */
|
||||
{
|
||||
// logerror("YM Delta-T ADPCM end out of range: $%08x\n", DELTAT->end);
|
||||
DELTAT->end = DELTAT->memory_size - 1;
|
||||
}
|
||||
if( DELTAT->start >= DELTAT->memory_size ) /* Check Start in Range */
|
||||
{
|
||||
// logerror("YM Delta-T ADPCM start out of range: $%08x\n", DELTAT->start);
|
||||
DELTAT->portstate = 0x00;
|
||||
DELTAT->PCM_BSY = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* we access CPU memory (ADPCM data register $08) so we only reset now_addr here */
|
||||
{
|
||||
DELTAT->now_addr = 0;
|
||||
}
|
||||
|
||||
if( DELTAT->portstate&0x01 )
|
||||
{
|
||||
DELTAT->portstate = 0x00;
|
||||
|
||||
/* clear PCM BUSY bit (in status register) */
|
||||
DELTAT->PCM_BSY = 0;
|
||||
|
||||
/* set BRDY flag */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
}
|
||||
break;
|
||||
case 0x01: /* L,R,-,-,SAMPLE,DA/AD,RAMTYPE,ROM */
|
||||
/* handle emulation mode */
|
||||
if(DELTAT->emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610)
|
||||
{
|
||||
v |= 0x01; /* YM2610 always uses ROM as an external memory and doesn't tave ROM/RAM memory flag bit. */
|
||||
}
|
||||
|
||||
DELTAT->pan = &DELTAT->output_pointer[(v>>6)&0x03];
|
||||
if ((DELTAT->control2 & 3) != (v & 3))
|
||||
{
|
||||
/*0-DRAM x1, 1-ROM, 2-DRAM x8, 3-ROM (3 is bad setting - not allowed by the manual) */
|
||||
if (DELTAT->DRAMportshift != dram_rightshift[v&3])
|
||||
{
|
||||
DELTAT->DRAMportshift = dram_rightshift[v&3];
|
||||
|
||||
/* final shift value depends on chip type and memory type selected:
|
||||
8 for YM2610 (ROM only),
|
||||
5 for ROM for Y8950 and YM2608,
|
||||
5 for x8bit DRAMs for Y8950 and YM2608,
|
||||
2 for x1bit DRAMs for Y8950 and YM2608.
|
||||
*/
|
||||
|
||||
/* refresh addresses */
|
||||
DELTAT->start = (DELTAT->reg[0x3]*0x0100 | DELTAT->reg[0x2]) << (DELTAT->portshift - DELTAT->DRAMportshift);
|
||||
DELTAT->end = (DELTAT->reg[0x5]*0x0100 | DELTAT->reg[0x4]) << (DELTAT->portshift - DELTAT->DRAMportshift);
|
||||
DELTAT->end += (1 << (DELTAT->portshift-DELTAT->DRAMportshift) ) - 1;
|
||||
DELTAT->limit = (DELTAT->reg[0xd]*0x0100 | DELTAT->reg[0xc]) << (DELTAT->portshift - DELTAT->DRAMportshift);
|
||||
}
|
||||
}
|
||||
DELTAT->control2 = v;
|
||||
break;
|
||||
case 0x02: /* Start Address L */
|
||||
case 0x03: /* Start Address H */
|
||||
DELTAT->start = (DELTAT->reg[0x3]*0x0100 | DELTAT->reg[0x2]) << (DELTAT->portshift - DELTAT->DRAMportshift);
|
||||
/*logerror("DELTAT start: 02=%2x 03=%2x addr=%8x\n",DELTAT->reg[0x2], DELTAT->reg[0x3],DELTAT->start );*/
|
||||
break;
|
||||
case 0x04: /* Stop Address L */
|
||||
case 0x05: /* Stop Address H */
|
||||
DELTAT->end = (DELTAT->reg[0x5]*0x0100 | DELTAT->reg[0x4]) << (DELTAT->portshift - DELTAT->DRAMportshift);
|
||||
DELTAT->end += (1 << (DELTAT->portshift-DELTAT->DRAMportshift) ) - 1;
|
||||
/*logerror("DELTAT end : 04=%2x 05=%2x addr=%8x\n",DELTAT->reg[0x4], DELTAT->reg[0x5],DELTAT->end );*/
|
||||
break;
|
||||
case 0x06: /* Prescale L (ADPCM and Record frq) */
|
||||
case 0x07: /* Prescale H */
|
||||
break;
|
||||
case 0x08: /* ADPCM data */
|
||||
|
||||
/*
|
||||
some examples:
|
||||
value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning:
|
||||
C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
|
||||
E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register
|
||||
80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
|
||||
a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register
|
||||
|
||||
60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08
|
||||
20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08
|
||||
|
||||
*/
|
||||
|
||||
/* external memory write */
|
||||
if ( (DELTAT->portstate & 0xe0)==0x60 )
|
||||
{
|
||||
if (DELTAT->memread)
|
||||
{
|
||||
DELTAT->now_addr = DELTAT->start << 1;
|
||||
DELTAT->memread = 0;
|
||||
}
|
||||
|
||||
/*logerror("YM Delta-T memory write $%08x, v=$%02x\n", DELTAT->now_addr >> 1, v);*/
|
||||
|
||||
if ( DELTAT->now_addr != (DELTAT->end<<1) )
|
||||
{
|
||||
DELTAT->memory[DELTAT->now_addr>>1] = v;
|
||||
DELTAT->now_addr+=2; /* two nibbles at a time */
|
||||
|
||||
/* reset BRDY bit in status register, which means we are processing the write */
|
||||
if(DELTAT->status_reset_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_reset_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
|
||||
/* setup a timer that will callback us in 10 master clock cycles for Y8950
|
||||
* in the callback set the BRDY flag to 1 , which means we have written the data.
|
||||
* For now, we don't really do this; we simply reset and set the flag in zero time, so that the IRQ will work.
|
||||
*/
|
||||
/* set BRDY bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set EOS bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_EOS_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ADPCM synthesis from CPU */
|
||||
if ( (DELTAT->portstate & 0xe0)==0x80 )
|
||||
{
|
||||
DELTAT->CPU_data = v;
|
||||
|
||||
/* Reset BRDY bit in status register, which means we are full of data */
|
||||
if(DELTAT->status_reset_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_reset_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x09: /* DELTA-N L (ADPCM Playback Prescaler) */
|
||||
case 0x0a: /* DELTA-N H */
|
||||
DELTAT->delta = (DELTAT->reg[0xa]*0x0100 | DELTAT->reg[0x9]);
|
||||
DELTAT->step = (UINT32)( (double)(DELTAT->delta /* *(1<<(YM_DELTAT_SHIFT-16)) */ ) * (DELTAT->freqbase) );
|
||||
/*logerror("DELTAT deltan:09=%2x 0a=%2x\n",DELTAT->reg[0x9], DELTAT->reg[0xa]);*/
|
||||
break;
|
||||
case 0x0b: /* Output level control (volume, linear) */
|
||||
{
|
||||
INT32 oldvol = DELTAT->volume;
|
||||
DELTAT->volume = (v&0xff) * (DELTAT->output_range/256) / YM_DELTAT_DECODE_RANGE;
|
||||
/* v * ((1<<16)>>8) >> 15;
|
||||
* thus: v * (1<<8) >> 15;
|
||||
* thus: output_range must be (1 << (15+8)) at least
|
||||
* v * ((1<<23)>>8) >> 15;
|
||||
* v * (1<<15) >> 15;
|
||||
*/
|
||||
/*logerror("DELTAT vol = %2x\n",v&0xff);*/
|
||||
if( oldvol != 0 )
|
||||
{
|
||||
DELTAT->adpcml = (int)((double)DELTAT->adpcml / (double)oldvol * (double)DELTAT->volume);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0c: /* Limit Address L */
|
||||
case 0x0d: /* Limit Address H */
|
||||
DELTAT->limit = (DELTAT->reg[0xd]*0x0100 | DELTAT->reg[0xc]) << (DELTAT->portshift - DELTAT->DRAMportshift);
|
||||
/*logerror("DELTAT limit: 0c=%2x 0d=%2x addr=%8x\n",DELTAT->reg[0xc], DELTAT->reg[0xd],DELTAT->limit );*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void YM_DELTAT_ADPCM_Reset(YM_DELTAT *DELTAT,int pan,int emulation_mode)
|
||||
{
|
||||
DELTAT->now_addr = 0;
|
||||
DELTAT->now_step = 0;
|
||||
DELTAT->step = 0;
|
||||
DELTAT->start = 0;
|
||||
DELTAT->end = 0;
|
||||
DELTAT->limit = ~0; /* this way YM2610 and Y8950 (both of which don't have limit address reg) will still work */
|
||||
DELTAT->volume = 0;
|
||||
DELTAT->pan = &DELTAT->output_pointer[pan];
|
||||
DELTAT->acc = 0;
|
||||
DELTAT->prev_acc = 0;
|
||||
DELTAT->adpcmd = 127;
|
||||
DELTAT->adpcml = 0;
|
||||
DELTAT->emulation_mode = (UINT8)emulation_mode;
|
||||
DELTAT->portstate = (emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610) ? 0x20 : 0;
|
||||
DELTAT->control2 = (emulation_mode == YM_DELTAT_EMULATION_MODE_YM2610) ? 0x01 : 0; /* default setting depends on the emulation mode. MSX demo called "facdemo_4" doesn't setup control2 register at all and still works */
|
||||
DELTAT->DRAMportshift = dram_rightshift[DELTAT->control2 & 3];
|
||||
|
||||
/* The flag mask register disables the BRDY after the reset, however
|
||||
** as soon as the mask is enabled the flag needs to be set. */
|
||||
|
||||
/* set BRDY bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
}
|
||||
|
||||
void YM_DELTAT_postload(YM_DELTAT *DELTAT,UINT8 *regs)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* to keep adpcml */
|
||||
DELTAT->volume = 0;
|
||||
/* update */
|
||||
for(r=1;r<16;r++)
|
||||
YM_DELTAT_ADPCM_Write(DELTAT,r,regs[r]);
|
||||
DELTAT->reg[0] = regs[0];
|
||||
|
||||
/* current rom data */
|
||||
if (DELTAT->memory)
|
||||
DELTAT->now_data = *(DELTAT->memory + (DELTAT->now_addr>>1) );
|
||||
|
||||
}
|
||||
void YM_DELTAT_savestate(const char *statename,int num,YM_DELTAT *DELTAT)
|
||||
{
|
||||
#ifdef __STATE_H__
|
||||
state_save_register_UINT8 (statename, num, "DeltaT.portstate", &DELTAT->portstate, 1);
|
||||
state_save_register_UINT32(statename, num, "DeltaT.address" , &DELTAT->now_addr , 1);
|
||||
state_save_register_UINT32(statename, num, "DeltaT.step" , &DELTAT->now_step , 1);
|
||||
state_save_register_INT32 (statename, num, "DeltaT.acc" , &DELTAT->acc , 1);
|
||||
state_save_register_INT32 (statename, num, "DeltaT.prev_acc" , &DELTAT->prev_acc , 1);
|
||||
state_save_register_INT32 (statename, num, "DeltaT.adpcmd" , &DELTAT->adpcmd , 1);
|
||||
state_save_register_INT32 (statename, num, "DeltaT.adpcml" , &DELTAT->adpcml , 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define YM_DELTAT_Limit(val,max,min) \
|
||||
{ \
|
||||
if ( val > max ) val = max; \
|
||||
else if ( val < min ) val = min; \
|
||||
}
|
||||
|
||||
INLINE void YM_DELTAT_synthesis_from_external_memory(YM_DELTAT *DELTAT)
|
||||
{
|
||||
UINT32 step;
|
||||
int data;
|
||||
|
||||
DELTAT->now_step += DELTAT->step;
|
||||
if ( DELTAT->now_step >= (1<<YM_DELTAT_SHIFT) )
|
||||
{
|
||||
step = DELTAT->now_step >> YM_DELTAT_SHIFT;
|
||||
DELTAT->now_step &= (1<<YM_DELTAT_SHIFT)-1;
|
||||
do{
|
||||
|
||||
if ( DELTAT->now_addr == (DELTAT->limit<<1) )
|
||||
DELTAT->now_addr = 0;
|
||||
|
||||
if ( DELTAT->now_addr == (DELTAT->end<<1) ) { /* 12-06-2001 JB: corrected comparison. Was > instead of == */
|
||||
if( DELTAT->portstate&0x10 ){
|
||||
/* repeat start */
|
||||
DELTAT->now_addr = DELTAT->start<<1;
|
||||
DELTAT->acc = 0;
|
||||
DELTAT->adpcmd = YM_DELTAT_DELTA_DEF;
|
||||
DELTAT->prev_acc = 0;
|
||||
}else{
|
||||
/* set EOS bit in status register */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_EOS_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_EOS_bit);
|
||||
|
||||
/* clear PCM BUSY bit (reflected in status register) */
|
||||
DELTAT->PCM_BSY = 0;
|
||||
|
||||
DELTAT->portstate = 0;
|
||||
DELTAT->adpcml = 0;
|
||||
DELTAT->prev_acc = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( DELTAT->now_addr&1 ) data = DELTAT->now_data & 0x0f;
|
||||
else
|
||||
{
|
||||
DELTAT->now_data = *(DELTAT->memory + (DELTAT->now_addr>>1));
|
||||
data = DELTAT->now_data >> 4;
|
||||
}
|
||||
|
||||
DELTAT->now_addr++;
|
||||
/* 12-06-2001 JB: */
|
||||
/* YM2610 address register is 24 bits wide.*/
|
||||
/* The "+1" is there because we use 1 bit more for nibble calculations.*/
|
||||
/* WARNING: */
|
||||
/* Side effect: we should take the size of the mapped ROM into account */
|
||||
DELTAT->now_addr &= ( (1<<(24+1))-1);
|
||||
|
||||
/* store accumulator value */
|
||||
DELTAT->prev_acc = DELTAT->acc;
|
||||
|
||||
/* Forecast to next Forecast */
|
||||
DELTAT->acc += (ym_deltat_decode_tableB1[data] * DELTAT->adpcmd / 8);
|
||||
YM_DELTAT_Limit(DELTAT->acc,YM_DELTAT_DECODE_MAX, YM_DELTAT_DECODE_MIN);
|
||||
|
||||
/* delta to next delta */
|
||||
DELTAT->adpcmd = (DELTAT->adpcmd * ym_deltat_decode_tableB2[data] ) / 64;
|
||||
YM_DELTAT_Limit(DELTAT->adpcmd,YM_DELTAT_DELTA_MAX, YM_DELTAT_DELTA_MIN );
|
||||
|
||||
/* ElSemi: Fix interpolator. */
|
||||
/*DELTAT->prev_acc = prev_acc + ((DELTAT->acc - prev_acc) / 2 );*/
|
||||
|
||||
}while(--step);
|
||||
|
||||
}
|
||||
|
||||
/* ElSemi: Fix interpolator. */
|
||||
DELTAT->adpcml = DELTAT->prev_acc * (int)((1<<YM_DELTAT_SHIFT)-DELTAT->now_step);
|
||||
DELTAT->adpcml += (DELTAT->acc * (int)DELTAT->now_step);
|
||||
DELTAT->adpcml = (DELTAT->adpcml>>YM_DELTAT_SHIFT) * (int)DELTAT->volume;
|
||||
|
||||
/* output for work of output channels (outd[OPNxxxx])*/
|
||||
*(DELTAT->pan) += DELTAT->adpcml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INLINE void YM_DELTAT_synthesis_from_CPU_memory(YM_DELTAT *DELTAT)
|
||||
{
|
||||
UINT32 step;
|
||||
int data;
|
||||
|
||||
DELTAT->now_step += DELTAT->step;
|
||||
if ( DELTAT->now_step >= (1<<YM_DELTAT_SHIFT) )
|
||||
{
|
||||
step = DELTAT->now_step >> YM_DELTAT_SHIFT;
|
||||
DELTAT->now_step &= (1<<YM_DELTAT_SHIFT)-1;
|
||||
do{
|
||||
|
||||
if( DELTAT->now_addr&1 )
|
||||
{
|
||||
data = DELTAT->now_data & 0x0f;
|
||||
|
||||
DELTAT->now_data = DELTAT->CPU_data;
|
||||
|
||||
/* after we used CPU_data, we set BRDY bit in status register,
|
||||
* which means we are ready to accept another byte of data */
|
||||
if(DELTAT->status_set_handler)
|
||||
if(DELTAT->status_change_BRDY_bit)
|
||||
(DELTAT->status_set_handler)(DELTAT->status_change_which_chip, DELTAT->status_change_BRDY_bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = DELTAT->now_data >> 4;
|
||||
}
|
||||
|
||||
DELTAT->now_addr++;
|
||||
|
||||
/* store accumulator value */
|
||||
DELTAT->prev_acc = DELTAT->acc;
|
||||
|
||||
/* Forecast to next Forecast */
|
||||
DELTAT->acc += (ym_deltat_decode_tableB1[data] * DELTAT->adpcmd / 8);
|
||||
YM_DELTAT_Limit(DELTAT->acc,YM_DELTAT_DECODE_MAX, YM_DELTAT_DECODE_MIN);
|
||||
|
||||
/* delta to next delta */
|
||||
DELTAT->adpcmd = (DELTAT->adpcmd * ym_deltat_decode_tableB2[data] ) / 64;
|
||||
YM_DELTAT_Limit(DELTAT->adpcmd,YM_DELTAT_DELTA_MAX, YM_DELTAT_DELTA_MIN );
|
||||
|
||||
|
||||
}while(--step);
|
||||
|
||||
}
|
||||
|
||||
/* ElSemi: Fix interpolator. */
|
||||
DELTAT->adpcml = DELTAT->prev_acc * (int)((1<<YM_DELTAT_SHIFT)-DELTAT->now_step);
|
||||
DELTAT->adpcml += (DELTAT->acc * (int)DELTAT->now_step);
|
||||
DELTAT->adpcml = (DELTAT->adpcml>>YM_DELTAT_SHIFT) * (int)DELTAT->volume;
|
||||
|
||||
/* output for work of output channels (outd[OPNxxxx])*/
|
||||
*(DELTAT->pan) += DELTAT->adpcml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ADPCM B (Delta-T control type) */
|
||||
void YM_DELTAT_ADPCM_CALC(YM_DELTAT *DELTAT)
|
||||
{
|
||||
|
||||
/*
|
||||
some examples:
|
||||
value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning:
|
||||
80 1 0 0 0 0 0 0 0 Synthesis (playing) from CPU (from reg $08) to AUDIO,sample rate in DELTA-N register
|
||||
a0 1 0 1 0 0 0 0 0 Synthesis (playing) from EXT.MEMORY to AUDIO, sample rate in DELTA-N register
|
||||
C8 1 1 0 0 1 0 0 0 Analysis (recording) from AUDIO to CPU (to reg $08), sample rate in PRESCALER register
|
||||
E8 1 1 1 0 1 0 0 0 Analysis (recording) from AUDIO to EXT.MEMORY, sample rate in PRESCALER register
|
||||
|
||||
60 0 1 1 0 0 0 0 0 External memory write via ADPCM data register $08
|
||||
20 0 0 1 0 0 0 0 0 External memory read via ADPCM data register $08
|
||||
|
||||
*/
|
||||
|
||||
if ( (DELTAT->portstate & 0xe0)==0xa0 )
|
||||
{
|
||||
YM_DELTAT_synthesis_from_external_memory(DELTAT);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (DELTAT->portstate & 0xe0)==0x80 )
|
||||
{
|
||||
/* ADPCM synthesis from CPU-managed memory (from reg $08) */
|
||||
YM_DELTAT_synthesis_from_CPU_memory(DELTAT); /* change output based on data in ADPCM data reg ($08) */
|
||||
return;
|
||||
}
|
||||
|
||||
//todo: ADPCM analysis
|
||||
// if ( (DELTAT->portstate & 0xe0)==0xc0 )
|
||||
// if ( (DELTAT->portstate & 0xe0)==0xe0 )
|
||||
|
||||
return;
|
||||
}
|
||||
|
82
sound/mame/ymdeltat.h
Normal file
82
sound/mame/ymdeltat.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef __YMDELTAT_H_
|
||||
#define __YMDELTAT_H_
|
||||
|
||||
#define YM_DELTAT_SHIFT (16)
|
||||
|
||||
#define YM_DELTAT_EMULATION_MODE_NORMAL 0
|
||||
#define YM_DELTAT_EMULATION_MODE_YM2610 1
|
||||
|
||||
|
||||
typedef void (*STATUS_CHANGE_HANDLER)(void *chip, UINT8 status_bits);
|
||||
|
||||
|
||||
/* DELTA-T (adpcm type B) struct */
|
||||
typedef struct deltat_adpcm_state { /* AT: rearranged and tigntened structure */
|
||||
UINT8 *memory;
|
||||
INT32 *output_pointer;/* pointer of output pointers */
|
||||
INT32 *pan; /* pan : &output_pointer[pan] */
|
||||
double freqbase;
|
||||
#if 0
|
||||
double write_time; /* Y8950: 10 cycles of main clock; YM2608: 20 cycles of main clock */
|
||||
double read_time; /* Y8950: 8 cycles of main clock; YM2608: 18 cycles of main clock */
|
||||
#endif
|
||||
UINT32 memory_size;
|
||||
int output_range;
|
||||
UINT32 now_addr; /* current address */
|
||||
UINT32 now_step; /* currect step */
|
||||
UINT32 step; /* step */
|
||||
UINT32 start; /* start address */
|
||||
UINT32 limit; /* limit address */
|
||||
UINT32 end; /* end address */
|
||||
UINT32 delta; /* delta scale */
|
||||
INT32 volume; /* current volume */
|
||||
INT32 acc; /* shift Measurement value*/
|
||||
INT32 adpcmd; /* next Forecast */
|
||||
INT32 adpcml; /* current value */
|
||||
INT32 prev_acc; /* leveling value */
|
||||
UINT8 now_data; /* current rom data */
|
||||
UINT8 CPU_data; /* current data from reg 08 */
|
||||
UINT8 portstate; /* port status */
|
||||
UINT8 control2; /* control reg: SAMPLE, DA/AD, RAM TYPE (x8bit / x1bit), ROM/RAM */
|
||||
UINT8 portshift; /* address bits shift-left:
|
||||
** 8 for YM2610,
|
||||
** 5 for Y8950 and YM2608 */
|
||||
|
||||
UINT8 DRAMportshift; /* address bits shift-right:
|
||||
** 0 for ROM and x8bit DRAMs,
|
||||
** 3 for x1 DRAMs */
|
||||
|
||||
UINT8 memread; /* needed for reading/writing external memory */
|
||||
|
||||
/* handlers and parameters for the status flags support */
|
||||
STATUS_CHANGE_HANDLER status_set_handler;
|
||||
STATUS_CHANGE_HANDLER status_reset_handler;
|
||||
|
||||
/* note that different chips have these flags on different
|
||||
** bits of the status register
|
||||
*/
|
||||
void * status_change_which_chip; /* this chip id */
|
||||
UINT8 status_change_EOS_bit; /* 1 on End Of Sample (record/playback/cycle time of AD/DA converting has passed)*/
|
||||
UINT8 status_change_BRDY_bit; /* 1 after recording 2 datas (2x4bits) or after reading/writing 1 data */
|
||||
UINT8 status_change_ZERO_bit; /* 1 if silence lasts for more than 290 miliseconds on ADPCM recording */
|
||||
|
||||
/* neither Y8950 nor YM2608 can generate IRQ when PCMBSY bit changes, so instead of above,
|
||||
** the statusflag gets ORed with PCM_BSY (below) (on each read of statusflag of Y8950 and YM2608)
|
||||
*/
|
||||
UINT8 PCM_BSY; /* 1 when ADPCM is playing; Y8950/YM2608 only */
|
||||
|
||||
UINT8 reg[16]; /* adpcm registers */
|
||||
UINT8 emulation_mode; /* which chip we're emulating */
|
||||
}YM_DELTAT;
|
||||
|
||||
/*void YM_DELTAT_BRDY_callback(YM_DELTAT *DELTAT);*/
|
||||
|
||||
UINT8 YM_DELTAT_ADPCM_Read(YM_DELTAT *DELTAT);
|
||||
void YM_DELTAT_ADPCM_Write(YM_DELTAT *DELTAT,int r,int v);
|
||||
void YM_DELTAT_ADPCM_Reset(YM_DELTAT *DELTAT,int pan,int emulation_mode);
|
||||
void YM_DELTAT_ADPCM_CALC(YM_DELTAT *DELTAT);
|
||||
|
||||
void YM_DELTAT_postload(YM_DELTAT *DELTAT,UINT8 *regs);
|
||||
void YM_DELTAT_savestate(const char *statename,int num,YM_DELTAT *DELTAT);
|
||||
|
||||
#endif
|
2762
sound/mame/ymf262.c
Normal file
2762
sound/mame/ymf262.c
Normal file
File diff suppressed because it is too large
Load Diff
55
sound/mame/ymf262.h
Normal file
55
sound/mame/ymf262.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef YMF262_H
|
||||
#define YMF262_H
|
||||
|
||||
|
||||
#define BUILD_YMF262 (HAS_YMF262)
|
||||
|
||||
|
||||
/* select number of output bits: 8 or 16 */
|
||||
#define OPL3_SAMPLE_BITS 16
|
||||
|
||||
/* compiler dependence */
|
||||
#ifndef OSD_CPU_H
|
||||
#define OSD_CPU_H
|
||||
typedef unsigned char UINT8; /* unsigned 8bit */
|
||||
typedef unsigned short UINT16; /* unsigned 16bit */
|
||||
typedef unsigned int UINT32; /* unsigned 32bit */
|
||||
typedef signed char INT8; /* signed 8bit */
|
||||
typedef signed short INT16; /* signed 16bit */
|
||||
typedef signed int INT32; /* signed 32bit */
|
||||
#endif
|
||||
|
||||
typedef stream_sample_t OPL3SAMPLE;
|
||||
/*
|
||||
#if (OPL3_SAMPLE_BITS==16)
|
||||
typedef INT16 OPL3SAMPLE;
|
||||
#endif
|
||||
#if (OPL3_SAMPLE_BITS==8)
|
||||
typedef INT8 OPL3SAMPLE;
|
||||
#endif
|
||||
*/
|
||||
|
||||
typedef void (*OPL3_TIMERHANDLER)(void *param,int timer,double interval_Sec);
|
||||
typedef void (*OPL3_IRQHANDLER)(void *param,int irq);
|
||||
typedef void (*OPL3_UPDATEHANDLER)(void *param,int min_interval_us);
|
||||
|
||||
|
||||
|
||||
#if BUILD_YMF262
|
||||
|
||||
void *YMF262Init(int clock, int rate);
|
||||
void YMF262Shutdown(void *chip);
|
||||
void YMF262ResetChip(void *chip);
|
||||
int YMF262Write(void *chip, int a, int v);
|
||||
unsigned char YMF262Read(void *chip, int a);
|
||||
int YMF262TimerOver(void *chip, int c);
|
||||
void YMF262UpdateOne(void *chip, OPL3SAMPLE **buffers, int length);
|
||||
|
||||
void YMF262SetTimerHandler(void *chip, OPL3_TIMERHANDLER TimerHandler, void *param);
|
||||
void YMF262SetIRQHandler(void *chip, OPL3_IRQHANDLER IRQHandler, void *param);
|
||||
void YMF262SetUpdateHandler(void *chip, OPL3_UPDATEHANDLER UpdateHandler, void *param);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* YMF262_H */
|
@ -1,74 +1,78 @@
|
||||
/**
|
||||
* @file opngencfg.h
|
||||
* @brief Interface of the OPN generator
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
FMDIV_BITS = 10,
|
||||
FMDIV_ENT = (1 << FMDIV_BITS),
|
||||
FMVOL_SFTBIT = 4
|
||||
};
|
||||
|
||||
#if defined(OPNGENX86)
|
||||
|
||||
#define SIN_BITS 11
|
||||
#define EVC_BITS 10
|
||||
#define ENV_BITS 16
|
||||
#define FREQ_BITS 21
|
||||
#define ENVTBL_BIT 14
|
||||
#define SINTBL_BIT 14
|
||||
|
||||
#else
|
||||
|
||||
#define SIN_BITS 10
|
||||
#define EVC_BITS 10
|
||||
#define ENV_BITS 16
|
||||
#define FREQ_BITS 21
|
||||
#define ENVTBL_BIT 14
|
||||
#define SINTBL_BIT 15
|
||||
|
||||
#endif
|
||||
|
||||
#define TL_BITS (FREQ_BITS + 2)
|
||||
#define OPM_OUTSB (TL_BITS + 2 - 16) /* OPM output 16bit */
|
||||
|
||||
#define SIN_ENT (1L << SIN_BITS)
|
||||
#define EVC_ENT (1L << EVC_BITS)
|
||||
|
||||
#define EC_ATTACK 0 /* ATTACK start */
|
||||
#define EC_DECAY (EVC_ENT << ENV_BITS) /* DECAY start */
|
||||
#define EC_OFF ((2 * EVC_ENT) << ENV_BITS) /* OFF */
|
||||
|
||||
enum
|
||||
{
|
||||
/* slot number */
|
||||
OPNSLOT1 = 0,
|
||||
OPNSLOT2 = 1,
|
||||
OPNSLOT3 = 2,
|
||||
OPNSLOT4 = 3,
|
||||
|
||||
EM_ATTACK = 4,
|
||||
EM_DECAY1 = 3,
|
||||
EM_DECAY2 = 2,
|
||||
EM_RELEASE = 1,
|
||||
EM_OFF = 0
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SINT32 calc1024;
|
||||
SINT32 fmvol;
|
||||
UINT ratebit;
|
||||
UINT vr_en;
|
||||
SINT32 vr_l;
|
||||
SINT32 vr_r;
|
||||
|
||||
SINT32 sintable[SIN_ENT];
|
||||
SINT32 envtable[EVC_ENT];
|
||||
SINT32 envcurve[EVC_ENT*2 + 1];
|
||||
} OPNCFG;
|
||||
|
||||
extern OPNCFG opncfg;
|
||||
/**
|
||||
* @file opngencfg.h
|
||||
* @brief Interface of the OPN generator
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
FMDIV_BITS = 10,
|
||||
FMDIV_ENT = (1 << FMDIV_BITS),
|
||||
FMVOL_SFTBIT = 4
|
||||
};
|
||||
|
||||
#if defined(OPNGENX86)
|
||||
|
||||
#define SIN_BITS 11
|
||||
#define EVC_BITS 10
|
||||
#define ENV_BITS 16
|
||||
#define FREQ_BITS 21
|
||||
#define ENVTBL_BIT 14
|
||||
#define SINTBL_BIT 14
|
||||
|
||||
#else
|
||||
|
||||
#define SIN_BITS 10
|
||||
#define EVC_BITS 10
|
||||
#define ENV_BITS 16
|
||||
#define FREQ_BITS 21
|
||||
#define ENVTBL_BIT 14
|
||||
#define SINTBL_BIT 15
|
||||
|
||||
#endif
|
||||
|
||||
#define TL_BITS (FREQ_BITS + 2)
|
||||
#define OPM_OUTSB (TL_BITS + 2 - 16) /* OPM output 16bit */
|
||||
|
||||
#define SIN_ENT (1L << SIN_BITS)
|
||||
#define EVC_ENT (1L << EVC_BITS)
|
||||
|
||||
#define EC_ATTACK 0 /* ATTACK start */
|
||||
#define EC_DECAY (EVC_ENT << ENV_BITS) /* DECAY start */
|
||||
#define EC_OFF ((2 * EVC_ENT) << ENV_BITS) /* OFF */
|
||||
|
||||
enum
|
||||
{
|
||||
/* slot number */
|
||||
OPNSLOT1 = 0,
|
||||
OPNSLOT2 = 1,
|
||||
OPNSLOT3 = 2,
|
||||
OPNSLOT4 = 3,
|
||||
|
||||
EM_ATTACK = 4,
|
||||
EM_DECAY1 = 3,
|
||||
EM_DECAY2 = 2,
|
||||
EM_RELEASE = 1,
|
||||
EM_OFF = 0
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SINT32 calc1024;
|
||||
SINT32 fmvol;
|
||||
UINT ratebit;
|
||||
UINT vr_en;
|
||||
SINT32 vr_l;
|
||||
SINT32 vr_r;
|
||||
|
||||
SINT32 sintable[SIN_ENT];
|
||||
SINT32 envtable[EVC_ENT];
|
||||
SINT32 envcurve[EVC_ENT*2 + 1];
|
||||
|
||||
#if defined(SUPPORT_FMGEN)
|
||||
UINT8 usefmgen;
|
||||
#endif /* SUPPORT_FMGEN */
|
||||
} OPNCFG;
|
||||
|
||||
extern OPNCFG opncfg;
|
||||
|
@ -45,6 +45,7 @@ private:
|
||||
CComboData m_cmbsm; //!< セカンダリ マスタ
|
||||
CComboData m_cmbss; //!< セカンダリ スレーブ
|
||||
CWndProc m_chkidebios; //!< Use IDE BIOS
|
||||
CWndProc m_chkautoidebios; //!< Auto IDE BIOS
|
||||
CWndProc m_nudrwait; //!< 割り込み(書き込み)ディレイ
|
||||
CWndProc m_nudwwait; //!< 割り込み(書き込み)ディレイ
|
||||
};
|
||||
@ -100,12 +101,22 @@ BOOL CIdeDlg::OnInitDialog()
|
||||
_stprintf(numbuf, _T("%d"), np2cfg.idewwait);
|
||||
m_nudwwait.SetWindowTextW(numbuf);
|
||||
|
||||
m_chkautoidebios.SubclassDlgItem(IDC_AUTOIDEBIOS, this);
|
||||
if(np2cfg.autoidebios){
|
||||
m_chkautoidebios.SendMessage(BM_SETCHECK , BST_CHECKED , 0);
|
||||
}else{
|
||||
m_chkautoidebios.SendMessage(BM_SETCHECK , BST_UNCHECKED , 0);
|
||||
}
|
||||
|
||||
m_chkidebios.SubclassDlgItem(IDC_USEIDEBIOS, this);
|
||||
if(np2cfg.idebios)
|
||||
if(np2cfg.idebios){
|
||||
m_chkidebios.SendMessage(BM_SETCHECK , BST_CHECKED , 0);
|
||||
else
|
||||
m_chkautoidebios.EnableWindow(TRUE);
|
||||
}else{
|
||||
m_chkidebios.SendMessage(BM_SETCHECK , BST_UNCHECKED , 0);
|
||||
|
||||
m_chkautoidebios.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
m_cmbpm.SetFocus();
|
||||
|
||||
return FALSE;
|
||||
@ -163,6 +174,11 @@ void CIdeDlg::OnOK()
|
||||
np2cfg.idebios = (m_chkidebios.SendMessage(BM_GETCHECK , 0 , 0) ? 1 : 0);
|
||||
update |= SYS_UPDATECFG;
|
||||
}
|
||||
if (np2cfg.autoidebios != (m_chkautoidebios.SendMessage(BM_GETCHECK , 0 , 0) ? 1 : 0))
|
||||
{
|
||||
np2cfg.autoidebios = (m_chkautoidebios.SendMessage(BM_GETCHECK , 0 , 0) ? 1 : 0);
|
||||
update |= SYS_UPDATECFG;
|
||||
}
|
||||
|
||||
sysmng_update(update);
|
||||
|
||||
@ -184,6 +200,9 @@ BOOL CIdeDlg::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
case IDC_IDE3TYPE:
|
||||
case IDC_IDE4TYPE:
|
||||
return TRUE;
|
||||
case IDC_USEIDEBIOS:
|
||||
m_chkautoidebios.EnableWindow((m_chkidebios.SendMessage(BM_GETCHECK , 0 , 0) ? TRUE : FALSE));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -132,15 +132,19 @@ void opl3_bind(POPL3 opl3)
|
||||
pExt->Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
oplgen_reset(&opl3->oplgen, nBaseClock);
|
||||
{
|
||||
#ifndef USE_MAME
|
||||
oplgen_reset(&opl3->oplgen, nBaseClock);
|
||||
#endif
|
||||
}
|
||||
restore(opl3);
|
||||
|
||||
|
||||
#ifndef USE_MAME
|
||||
if (pExt == NULL)
|
||||
{
|
||||
sound_streamregist(&opl3->oplgen, (SOUNDCB)oplgen_getpcm);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
keydisp_bindopl3(opl3->s.reg, (cCaps & OPL3_HAS_OPL3) ? 18 : 9, nBaseClock);
|
||||
}
|
||||
@ -236,8 +240,10 @@ static void writeRegister(POPL3 opl3, UINT nAddress, REG8 cData)
|
||||
pExt->WriteRegister(nAddress, cData);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
#ifndef USE_MAME
|
||||
sound_sync();
|
||||
#endif
|
||||
oplgen_setreg(&opl3->oplgen, nAddress, cData);
|
||||
}
|
||||
}
|
||||
@ -317,8 +323,10 @@ static void writeExtendedRegister(POPL3 opl3, UINT nAddress, REG8 cData)
|
||||
}
|
||||
//#if 0
|
||||
else
|
||||
{
|
||||
{
|
||||
#ifndef USE_MAME
|
||||
sound_sync();
|
||||
#endif
|
||||
oplgen_setreg(&opl3->oplgen, nAddress + 0x100, cData);
|
||||
}
|
||||
//#endif
|
||||
|
@ -500,6 +500,7 @@ static const PFTBL s_IniItems[] =
|
||||
PFVAL("IDE3TYPE", PFTYPE_UINT8, &np2cfg.idetype[2]),
|
||||
PFVAL("IDE4TYPE", PFTYPE_UINT8, &np2cfg.idetype[3]),
|
||||
PFVAL("IDE_BIOS", PFTYPE_BOOL, &np2cfg.idebios), // ŽÀ‹@IDE BIOSŽg—p
|
||||
PFVAL("AIDEBIOS", PFTYPE_BOOL, &np2cfg.autoidebios), // 実機IDE BIOS使用を自動設定する
|
||||
PFVAL("IDERWAIT", PFTYPE_UINT32, &np2cfg.iderwait),
|
||||
PFVAL("IDEWWAIT", PFTYPE_UINT32, &np2cfg.idewwait),
|
||||
PFVAL("IDEMWAIT", PFTYPE_UINT32, &np2cfg.idemwait),
|
||||
@ -527,7 +528,6 @@ static const PFTBL s_IniItems[] =
|
||||
PFMAX("volume_A", PFTYPE_UINT8, &np2cfg.vol_adpcm, 128),
|
||||
PFMAX("volume_P", PFTYPE_UINT8, &np2cfg.vol_pcm, 128),
|
||||
PFMAX("volume_R", PFTYPE_UINT8, &np2cfg.vol_rhythm, 128),
|
||||
PFMAX("volume_C", PFTYPE_UINT8, &np2cfg.vol_cdda, 128), // CD-DA(kaiE)
|
||||
|
||||
PFVAL("Seek_Snd", PFTYPE_BOOL, &np2cfg.MOTOR),
|
||||
PFMAX("Seek_Vol", PFTYPE_UINT8, &np2cfg.MOTORVOL, 100),
|
||||
|
@ -367,6 +367,9 @@ void xmenu_update(HMENU hMenu)
|
||||
CheckMenuItem(hMenu, IDM_MATE_X_PCM, MF_BYCOMMAND | MFCHECK(SOUND_SW == SOUNDID_MATE_X_PCM));
|
||||
CheckMenuItem(hMenu, IDM_SPEAKBOARD, MF_BYCOMMAND | MFCHECK(SOUND_SW == 0x20));
|
||||
CheckMenuItem(hMenu, IDM_SPARKBOARD, MF_BYCOMMAND | MFCHECK(SOUND_SW == 0x40));
|
||||
#if defined(SUPPORT_SOUND_SB16)
|
||||
CheckMenuItem(hMenu, IDM_SB16, MF_BYCOMMAND | MFCHECK(SOUND_SW == SOUNDID_SB16));
|
||||
#endif // defined(SUPPORT_SOUND_SB16)
|
||||
#if defined(SUPPORT_PX)
|
||||
CheckMenuItem(hMenu, IDM_PX1, MF_BYCOMMAND | MFCHECK(SOUND_SW == 0x30));
|
||||
CheckMenuItem(hMenu, IDM_PX2, MF_BYCOMMAND | MFCHECK(SOUND_SW == 0x50));
|
||||
|
@ -835,6 +835,25 @@ static void OnCommand(HWND hWnd, WPARAM wParam)
|
||||
case IDM_SCSI3EJECT:
|
||||
diskdrv_setsxsi(0x23, NULL);
|
||||
break;
|
||||
|
||||
case IDM_SCSI0STATE:
|
||||
case IDM_SCSI1STATE:
|
||||
case IDM_SCSI2STATE:
|
||||
case IDM_SCSI3STATE:
|
||||
{
|
||||
const OEMCHAR *fname;
|
||||
fname = sxsi_getfilename(uID - IDM_SCSI0STATE + 0x20);
|
||||
if(!fname || !(*fname)){
|
||||
fname = diskdrv_getsxsi(uID - IDM_IDE0STATE + 0x20);
|
||||
}
|
||||
if(fname && *fname){
|
||||
TCHAR seltmp[500];
|
||||
_tcscpy(seltmp, OEMTEXT("/select,"));
|
||||
_tcscat(seltmp, fname);
|
||||
ShellExecute(NULL, NULL, OEMTEXT("explorer.exe"), seltmp, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case IDM_WINDOW:
|
||||
@ -1097,6 +1116,13 @@ static void OnCommand(HWND hWnd, WPARAM wParam)
|
||||
np2cfg.SOUND_SW = 0x40;
|
||||
update |= SYS_UPDATECFG | SYS_UPDATESBOARD;
|
||||
break;
|
||||
|
||||
#if defined(SUPPORT_SOUND_SB16)
|
||||
case IDM_SB16:
|
||||
np2cfg.SOUND_SW = SOUNDID_SB16;
|
||||
update |= SYS_UPDATECFG | SYS_UPDATESBOARD;
|
||||
break;
|
||||
#endif // defined(SUPPORT_SOUND_SB16)
|
||||
|
||||
#if defined(SUPPORT_PX)
|
||||
case IDM_PX1:
|
||||
@ -2444,7 +2470,7 @@ void unloadNP2INI(){
|
||||
//np2net_shutdown();
|
||||
#endif
|
||||
|
||||
pccore_term();
|
||||
//pccore_term();
|
||||
|
||||
CSoundMng::GetInstance()->Close();
|
||||
CSoundMng::Deinitialize();
|
||||
|
@ -280,6 +280,7 @@
|
||||
#define IDC_IDERWAIT 19106
|
||||
#define IDC_SPINIDERWAIT 19107
|
||||
#define IDC_USEIDEBIOS 19108
|
||||
#define IDC_AUTOIDEBIOS 19109
|
||||
#define IDS_APP_NAME2 30001
|
||||
#define IDS_APP_NAME21 30002
|
||||
#define IDS_FILENAME_HELP 30003
|
||||
@ -586,6 +587,7 @@
|
||||
#define IDM_SOUNDORCHESTRAV 40656
|
||||
#define IDM_PC9801_86_WSS 40657
|
||||
#define IDM_MATE_X_PCM 40658
|
||||
#define IDM_SB16 40659
|
||||
#define IDM_MEM640 40661
|
||||
#define IDM_MEM16 40662
|
||||
#define IDM_MEM36 40663
|
||||
|
@ -537,6 +537,7 @@ BEGIN
|
||||
LTEXT "Interrupt Delay(Write)",IDC_STATIC,8,100,70,8
|
||||
LTEXT "clock",IDC_STATIC,126,100,32,8
|
||||
CONTROL "Use IDE BIOS",IDC_USEIDEBIOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,120,200,10
|
||||
CONTROL "Auto IDE BIOS",IDC_AUTOIDEBIOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,134,80,10
|
||||
DEFPUSHBUTTON "&OK",IDOK,92,130,44,14,WS_GROUP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,140,130,44,14
|
||||
END
|
||||
@ -923,6 +924,7 @@ BEGIN
|
||||
MENUITEM "Sp&ark board", IDM_SPARKBOARD
|
||||
MENUITEM "Sound &Orchestra", IDM_SOUNDORCHESTRA
|
||||
MENUITEM "Sound Orchestra-&V", IDM_SOUNDORCHESTRAV
|
||||
MENUITEM "Sound &Blaster 16", IDM_SB16
|
||||
MENUITEM "&AMD-98", IDM_AMD98
|
||||
MENUITEM "&JastSound", IDM_JASTSOUND
|
||||
MENUITEM SEPARATOR
|
||||
@ -1111,24 +1113,32 @@ BEGIN
|
||||
MENUITEM "&Open...", IDM_SCSI0OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Remove", IDM_SCSI0EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI0STATE
|
||||
END
|
||||
POPUP "SCSI #1"
|
||||
BEGIN
|
||||
MENUITEM "&Open...", IDM_SCSI1OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Remove", IDM_SCSI1EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI1STATE
|
||||
END
|
||||
POPUP "SCSI #2"
|
||||
BEGIN
|
||||
MENUITEM "&Open...", IDM_SCSI2OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Remove", IDM_SCSI2EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI2STATE
|
||||
END
|
||||
POPUP "SCSI #3"
|
||||
BEGIN
|
||||
MENUITEM "&Open...", IDM_SCSI3OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Remove", IDM_SCSI3EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI3STATE
|
||||
END
|
||||
END
|
||||
|
||||
|
@ -530,6 +530,7 @@ BEGIN
|
||||
LTEXT "Interrupt Delay(Write)",IDC_STATIC,8,100,70,8
|
||||
LTEXT "clock",IDC_STATIC,126,100,32,8
|
||||
CONTROL "Use IDE BIOS",IDC_USEIDEBIOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,120,200,10
|
||||
CONTROL "Auto IDE BIOS",IDC_AUTOIDEBIOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,134,80,10
|
||||
DEFPUSHBUTTON "&OK",IDOK,92,130,44,14,WS_GROUP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,140,130,44,14
|
||||
END
|
||||
@ -916,6 +917,7 @@ BEGIN
|
||||
MENUITEM "Sp&ark board", IDM_SPARKBOARD
|
||||
MENUITEM "Sound &Orchestra", IDM_SOUNDORCHESTRA
|
||||
MENUITEM "Sound Orchestra-&V", IDM_SOUNDORCHESTRAV
|
||||
MENUITEM "Sound &Blaster 16", IDM_SB16
|
||||
MENUITEM "&AMD-98", IDM_AMD98
|
||||
MENUITEM "&JastSound", IDM_JASTSOUND
|
||||
MENUITEM SEPARATOR
|
||||
|
@ -25,8 +25,8 @@ IDR_MANIFEST IRT_MANIFEST MOVEABLE PURE "..\\np2.mnf"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,8,6,35
|
||||
PRODUCTVERSION 0,8,6,35
|
||||
FILEVERSION 0,8,6,36
|
||||
PRODUCTVERSION 0,8,6,36
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -42,10 +42,10 @@ BEGIN
|
||||
BLOCK "041103a4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileVersion", "0, 8, 6, 35\0"
|
||||
VALUE "FileVersion", "0, 8, 6, 36\0"
|
||||
VALUE "LegalCopyright", "ねこさん開発ちーむ\0"
|
||||
|
||||
VALUE "ProductVersion", "0, 8, 6, 35\0"
|
||||
VALUE "ProductVersion", "0, 8, 6, 36\0"
|
||||
#ifdef _USRDLL
|
||||
VALUE "FileDescription", "PC-98x1series emulator resource file\0"
|
||||
VALUE "ProductName", "Neko Project II resource file\0"
|
||||
|
@ -529,6 +529,7 @@ BEGIN
|
||||
LTEXT "割り込み遅延(WRITE)",IDC_STATIC,8,100,70,8
|
||||
LTEXT "clock",IDC_STATIC,126,100,32,8
|
||||
CONTROL "実機IDE BIOSを使用",IDC_USEIDEBIOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,120,200,10
|
||||
CONTROL "IDE BIOSŽ©“®ON/OFF",IDC_AUTOIDEBIOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,134,80,10
|
||||
DEFPUSHBUTTON "&OK",IDOK,92,130,44,14,WS_GROUP
|
||||
PUSHBUTTON "キャンセル",IDCANCEL,140,130,44,14
|
||||
END
|
||||
@ -915,6 +916,7 @@ BEGIN
|
||||
MENUITEM "Sp&ark board", IDM_SPARKBOARD
|
||||
MENUITEM "Sound &Orchestra", IDM_SOUNDORCHESTRA
|
||||
MENUITEM "Sound Orchestra-&V", IDM_SOUNDORCHESTRAV
|
||||
MENUITEM "Sound &Blaster 16", IDM_SB16
|
||||
MENUITEM "&AMD-98", IDM_AMD98
|
||||
MENUITEM "&JastSound", IDM_JASTSOUND
|
||||
MENUITEM SEPARATOR
|
||||
@ -1115,24 +1117,32 @@ BEGIN
|
||||
MENUITEM "開く(&O)...", IDM_SCSI0OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "取り外し(&R)...", IDM_SCSI0EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI0STATE
|
||||
END
|
||||
POPUP "SCSI #1"
|
||||
BEGIN
|
||||
MENUITEM "開く(&O)...", IDM_SCSI1OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "取り外し(&R)...", IDM_SCSI1EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI1STATE
|
||||
END
|
||||
POPUP "SCSI #2"
|
||||
BEGIN
|
||||
MENUITEM "開く(&O)...", IDM_SCSI2OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "取り外し(&R)...", IDM_SCSI2EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI2STATE
|
||||
END
|
||||
POPUP "SCSI #3"
|
||||
BEGIN
|
||||
MENUITEM "開く(&O)...", IDM_SCSI3OPEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "取り外し(&R)...", IDM_SCSI3EJECT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM " ", IDM_SCSI3STATE
|
||||
END
|
||||
END
|
||||
|
||||
|
@ -561,9 +561,9 @@ BRESULT scrnmng_create(UINT8 scrnmode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((r = DirectDrawCreate(&devguid, &ddraw.ddraw1, NULL)) != DD_OK) {
|
||||
if ((r = DirectDrawCreate(devlpguid, &ddraw.ddraw1, NULL)) != DD_OK) {
|
||||
// プライマリで再挑戦
|
||||
if (DirectDrawCreate(NULL, &ddraw.ddraw1, NULL) != DD_OK) {
|
||||
if (DirectDrawCreate(np2oscfg.emuddraw ? (LPGUID)DDCREATE_EMULATIONONLY : NULL, &ddraw.ddraw1, NULL) != DD_OK) {
|
||||
goto scre_err;
|
||||
}
|
||||
}
|
||||
@ -1350,4 +1350,4 @@ void scrnmng_bltwab() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -127,10 +127,13 @@ COMMON_SOURCES= $(real_topsrcdir)/x11/main.c \
|
||||
$(real_topsrcdir)/cbus/board26k.c \
|
||||
$(real_topsrcdir)/cbus/board86.c \
|
||||
$(real_topsrcdir)/cbus/boardpx.c \
|
||||
$(real_topsrcdir)/cbus/boardsb16.c \
|
||||
$(real_topsrcdir)/cbus/boardso.c \
|
||||
$(real_topsrcdir)/cbus/boardspb.c \
|
||||
$(real_topsrcdir)/cbus/boardx2.c \
|
||||
$(real_topsrcdir)/cbus/cs4231io.c \
|
||||
$(real_topsrcdir)/cbus/ct1741io.c \
|
||||
$(real_topsrcdir)/cbus/ct1745io.c \
|
||||
$(real_topsrcdir)/cbus/pcm86io.c \
|
||||
$(real_topsrcdir)/cbus/sasiio.c \
|
||||
$(real_topsrcdir)/cbus/scsiio.c \
|
||||
@ -250,6 +253,9 @@ COMMON_SOURCES= $(real_topsrcdir)/x11/main.c \
|
||||
$(real_topsrcdir)/sound/fmgen/fmgen_opm.cpp \
|
||||
$(real_topsrcdir)/sound/fmgen/fmgen_opna.cpp \
|
||||
$(real_topsrcdir)/sound/fmgen/fmgen_psg.cpp \
|
||||
$(real_topsrcdir)/sound/mame/fmopl.c \
|
||||
$(real_topsrcdir)/sound/mame/ymdeltat.c \
|
||||
$(real_topsrcdir)/sound/mame/ymf262.c \
|
||||
\
|
||||
$(real_topsrcdir)/vram/vram.c \
|
||||
$(real_topsrcdir)/vram/scrndraw.c \
|
||||
@ -298,7 +304,7 @@ AM_CPPFLAGS= -I$(real_topsrcdir) \
|
||||
-I$(real_topsrcdir)/vram \
|
||||
$(GTK_CFLAGS) $(SDL_CFLAGS) $(LIBUSB1_CFLAGS) \
|
||||
$(X11_CFLAGS) $(XEXT_CFLAGS) \
|
||||
-DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DSUPPORT_NET -DSUPPORT_LGY98
|
||||
-DSUPPORT_LARGE_HDD -DSUPPORT_VPCVHD -DSUPPORT_KAI_IMAGES -DHOOK_SYSKEY -DALLOW_MULTIRUN -DSUPPORT_NET -DSUPPORT_LGY98 -DUSE_MAME -DSUPPORT_SOUND_SB16
|
||||
if BUILD_ALL
|
||||
AM_CPPFLAGS+= -DX11_BUILD_ALL
|
||||
endif
|
||||
|
4
x11/compiler.h
Executable file → Normal file
4
x11/compiler.h
Executable file → Normal file
@ -86,13 +86,17 @@
|
||||
#include <glib.h>
|
||||
|
||||
typedef gint32 SINT;
|
||||
typedef gint32 INT;
|
||||
typedef guint32 UINT;
|
||||
|
||||
typedef gint8 SINT8;
|
||||
typedef gint8 INT8;
|
||||
typedef gint16 SINT16;
|
||||
typedef gint16 INT16;
|
||||
typedef gint32 SINT32;
|
||||
typedef gint32 INT32;
|
||||
typedef gint64 SINT64;
|
||||
typedef gint64 INT64;
|
||||
|
||||
typedef guint8 UINT8;
|
||||
typedef guint16 UINT16;
|
||||
|
@ -57,6 +57,7 @@ static const struct {
|
||||
{ "ADPCM", &np2cfg.vol_adpcm, 0.0, 128.0 },
|
||||
{ "PCM", &np2cfg.vol_pcm, 0.0, 128.0 },
|
||||
{ "Rhythm", &np2cfg.vol_rhythm, 0.0, 128.0 },
|
||||
{ "CD-DA", &np2cfg.davolume, 0.0, 255.0 },
|
||||
};
|
||||
|
||||
static GObject *mixer_adj[NELEMENTS(mixer_vol_tbl)];
|
||||
@ -625,9 +626,10 @@ mixer_default_button_clicked(GtkButton *b, gpointer d)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NELEMENTS(mixer_vol_tbl); i++) {
|
||||
for (i = 0; i < NELEMENTS(mixer_vol_tbl) - 1; i++) {
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[i]), 64.0);
|
||||
}
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[5]), 128.0);
|
||||
#if defined(SUPPORT_FMGEN)
|
||||
OPNA_SetVolumeFM(g_opna[0].fmgen, pow((double)np2cfg.vol_fm / 128, 0.12) * (20 + 192) - 192);
|
||||
OPNA_SetVolumePSG(g_opna[0].fmgen, pow((double)np2cfg.vol_ssg / 128, 0.12) * (20 + 192) - 192);
|
||||
|
@ -271,10 +271,13 @@ static GtkRadioActionEntry soundboard_entries[] = {
|
||||
{ "pc-9801-26k-86", NULL, "PC-9801-26_K + 86", NULL, NULL, 0x06 },
|
||||
{ "pc-9801-86-cb", NULL, "PC-9801-86 + _Chibi-oto", NULL, NULL, 0x14 },
|
||||
{ "pc-9801-118", NULL, "PC-9801-11_8", NULL, NULL, 0x08 },
|
||||
{ "pc-9801-86-mx", NULL, "PC-9801-86 + Mate-X PCM(B460)", NULL, NULL, 0x64 },
|
||||
{ "pc-9801-mx", NULL, "Mate-X PCM(B460)", NULL, NULL, 0x60 },
|
||||
{ "speakboard", NULL, "S_peak board", NULL, NULL, 0x20 },
|
||||
{ "sparkboard", NULL, "Sp_ark board", NULL, NULL, 0x40 },
|
||||
{ "sndorchestra", NULL, "Sound Orchestra", NULL, NULL, 0x32 },
|
||||
{ "sndorchestrav", NULL, "Sound Orchestra-V", NULL, NULL, 0x82 },
|
||||
{ "sb16", NULL, "Sound Blaster 16", NULL, NULL, 0x41 },
|
||||
{ "amd98", NULL, "_AMD98", NULL, NULL, 0x80 },
|
||||
#if defined(SUPPORT_PX)
|
||||
{ "px1", NULL, "Otomi-chanx2", NULL, NULL, 0x30 },
|
||||
@ -469,10 +472,13 @@ static const gchar *ui_info =
|
||||
" <menuitem action='pc-9801-26k-86'/>\n"
|
||||
" <menuitem action='pc-9801-86-cb'/>\n"
|
||||
" <menuitem action='pc-9801-118'/>\n"
|
||||
" <menuitem action='pc-9801-86-mx'/>\n"
|
||||
" <menuitem action='pc-9801-mx'/>\n"
|
||||
" <menuitem action='speakboard'/>\n"
|
||||
" <menuitem action='sparkboard'/>\n"
|
||||
" <menuitem action='sndorchestra'/>\n"
|
||||
" <menuitem action='sndorchestrav'/>\n"
|
||||
" <menuitem action='sb16'/>\n"
|
||||
" <menuitem action='amd98'/>\n"
|
||||
#if defined(SUPPORT_PX)
|
||||
" <menuitem action='px1'/>\n"
|
||||
|
15
x11/ini.c
15
x11/ini.c
@ -541,6 +541,19 @@ static INITBL iniitem[] = {
|
||||
|
||||
{"HDD1FILE", INITYPE_STR, np2cfg.sasihdd[0], MAX_PATH},
|
||||
{"HDD2FILE", INITYPE_STR, np2cfg.sasihdd[1], MAX_PATH},
|
||||
#if defined(SUPPORT_IDEIO)
|
||||
{"HDD3FILE", INIRO_STR, np2cfg.sasihdd[2], MAX_PATH},
|
||||
{"HDD4FILE", INIRO_STR, np2cfg.sasihdd[3], MAX_PATH},
|
||||
{"HDD1TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"HDD2TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"HDD3TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"HDD4TYPE", INIRO_UINT8, &np2cfg.idetype[2], 0},
|
||||
{"IDE_BIOS", INIRO_BOOL, &np2cfg.idebios, 0},
|
||||
{"AIDEBIOS", INIRO_BOOL, &np2cfg.autoidebios, 0},
|
||||
{"IDERWAIT", INITYPE_UINT32, &np2cfg.iderwait, 0},
|
||||
{"IDEWWAIT", INITYPE_UINT32, &np2cfg.idewwait, 0},
|
||||
{"IDEMWAIT", INITYPE_UINT32, &np2cfg.idemwait, 0},
|
||||
#endif
|
||||
|
||||
{"SampleHz", INITYPE_UINT32, &np2cfg.samplingrate, 0},
|
||||
{"Latencys", INITYPE_UINT16, &np2cfg.delayms, 0},
|
||||
@ -563,7 +576,7 @@ static INITBL iniitem[] = {
|
||||
{"volume_A", INIMAX_UINT8, &np2cfg.vol_adpcm, 128},
|
||||
{"volume_P", INIMAX_UINT8, &np2cfg.vol_pcm, 128},
|
||||
{"volume_R", INIMAX_UINT8, &np2cfg.vol_rhythm, 128},
|
||||
{"volume_C", INIMAX_UINT8, &np2cfg.vol_cdda, 128},
|
||||
{"DAVOLUME", INIMAX_UINT8, &np2cfg.davolume, 128},
|
||||
|
||||
{"usefmgen", INITYPE_BOOL, &np2cfg.usefmgen, 0},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user