-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Yamaha YMF724/YMF744/YMF754 (DS-XG) driver with hardware FM/MPU-401 port remapping #81
Changes from all commits
10f84fd
521b55d
c2c42d6
561422d
b83d5fd
3f2959c
3f543fb
5d48cc0
a0c3ce1
41d5abd
744876d
0ced005
cd1ca34
8af01e6
a464267
0af4b6b
64c3a64
2090648
255b478
107d18e
ab69650
e1bf818
19f29bd
bb78cee
95d63f6
835718e
233e984
f8d6705
be5aedf
0d2aa03
54c87df
3278b3e
9487d7d
5af070f
9c67330
6c03f98
62b5234
6d1daae
b224a10
dbfd272
62cf0c1
1e34fe0
e05ad3a
9e5e4b6
e85e207
dff737f
d831094
6dcd31e
5267146
268bc96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,21 +69,61 @@ static const char MAIN_ISR_DOSID_String[] = "Crazii SBEMU Sound Blaster emula | |
static void MAIN_TSR_InstallationCheck(); | ||
static void MAIN_TSR_Interrupt(); | ||
|
||
uint16_t main_hw_fmport = 0; | ||
#define hw_fm_outb(reg,data) outp(main_hw_fmport+reg,data) | ||
#define hw_fm_inb(reg) inp(main_hw_fmport+reg) | ||
|
||
uint16_t main_hw_mpuport = 0; | ||
#define hw_mpu_outb(reg,data) outp(main_hw_mpuport+reg,data) | ||
#define hw_mpu_inb(reg) inp(main_hw_mpuport+reg) | ||
|
||
static uint32_t MAIN_OPL3_388(uint32_t port, uint32_t val, uint32_t out) | ||
{ | ||
return out ? OPL3EMU_PrimaryWriteIndex(val) : OPL3EMU_PrimaryRead(val); | ||
if (main_hw_fmport) { | ||
if (out) { | ||
hw_fm_outb(0, val & 0xff); | ||
return val; | ||
} else { | ||
return hw_fm_inb(0); | ||
} | ||
} | ||
return out ? OPL3EMU_PrimaryWriteIndex(val) : OPL3EMU_PrimaryRead(val); | ||
} | ||
static uint32_t MAIN_OPL3_389(uint32_t port, uint32_t val, uint32_t out) | ||
{ | ||
return out ? OPL3EMU_PrimaryWriteData(val) : OPL3EMU_PrimaryRead(val); | ||
if (main_hw_fmport) { | ||
if (out) { | ||
hw_fm_outb(1, val & 0xff); | ||
return val; | ||
} else { | ||
return hw_fm_inb(1); | ||
} | ||
} | ||
return out ? OPL3EMU_PrimaryWriteData(val) : OPL3EMU_PrimaryRead(val); | ||
} | ||
static uint32_t MAIN_OPL3_38A(uint32_t port, uint32_t val, uint32_t out) | ||
{ | ||
return out ? OPL3EMU_SecondaryWriteIndex(val) : OPL3EMU_SecondaryRead(val); | ||
if (main_hw_fmport) { | ||
if (out) { | ||
hw_fm_outb(2, val & 0xff); | ||
return val; | ||
} else { | ||
return hw_fm_inb(2); | ||
} | ||
} | ||
return out ? OPL3EMU_SecondaryWriteIndex(val) : OPL3EMU_SecondaryRead(val); | ||
} | ||
static uint32_t MAIN_OPL3_38B(uint32_t port, uint32_t val, uint32_t out) | ||
{ | ||
return out ? OPL3EMU_SecondaryWriteData(val) : OPL3EMU_SecondaryRead(val); | ||
if (main_hw_fmport) { | ||
if (out) { | ||
hw_fm_outb(3, val & 0xff); | ||
return val; | ||
} else { | ||
return hw_fm_inb(3); | ||
} | ||
} | ||
return out ? OPL3EMU_SecondaryWriteData(val) : OPL3EMU_SecondaryRead(val); | ||
} | ||
|
||
static uint32_t MAIN_DMA(uint32_t port, uint32_t val, uint32_t out) | ||
|
@@ -144,43 +184,57 @@ static uint32_t MAIN_MPU_330(uint32_t port, uint32_t val, uint32_t out) | |
c = '\n'; | ||
mpu_dbg_ctr = 0; | ||
} | ||
DBG_Log("%02x%c", val, c); | ||
DBG_Logi("%02x%c", val, c); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DBG_Log/DBG_Logi will output log for release builds. do your need a debug log but without the source file/line information? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, a hex dump of the raw MIDI data. I think it is a nice feature. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I understand. So it is NOT needed for release builds? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It IS intended for release builds. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, cool :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is OK to print to the screen if /MDBG is specified but /DBG is not. BTW, is there a good reason to have the LF to CRLF conversion and the baud rate set to 9600? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might depend on the terminal, for me it needs CRLF to properly turn to next line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably fine to have 115200 and LF only. As @jiyunomegami mentioned, it's up to the terminal on the other side to be configured properly. |
||
} | ||
} else { | ||
DBG_Log("r%x\n", mpu_state); | ||
DBG_Logi("r%x\n", mpu_state); | ||
} | ||
} | ||
#endif | ||
if (out) { | ||
if (main_hw_mpuport) { | ||
hw_mpu_outb(0, (unsigned char)(val & 0xff)); | ||
} | ||
ser_putbyte((int)(val & 0xff)); | ||
return 0; | ||
} else { | ||
uint8_t val, hwval; | ||
if (main_hw_mpuport) { | ||
hwval = hw_mpu_inb(0); | ||
} | ||
if (mpu_state == 1) { | ||
mpu_state = 0; | ||
return 0xfe; | ||
val = 0xfe; | ||
} else if (mpu_state == 2) { | ||
mpu_state = 4; | ||
return 0xfe; | ||
val = 0xfe; | ||
} else { | ||
return 0; | ||
val = 0; | ||
} | ||
if (main_hw_mpuport) { | ||
val = hwval; | ||
} | ||
return val; | ||
} | ||
} | ||
static uint32_t MAIN_MPU_331(uint32_t port, uint32_t val, uint32_t out) | ||
{ | ||
#if MPU_DEBUG | ||
if (mpu_debug) { | ||
if (out) { | ||
DBG_Log("s%x\n", val); | ||
DBG_Logi("s%x\n", val); | ||
} else { | ||
if (mpu_dbg_ctr < 10 && mpu_state <= 2) { | ||
DBG_Log("sr%x\n", mpu_state); | ||
DBG_Logi("sr%x\n", mpu_state); | ||
mpu_dbg_ctr++; | ||
} | ||
} | ||
} | ||
#endif | ||
if (out) { | ||
if (main_hw_mpuport) { | ||
hw_mpu_outb(1, (unsigned char)(val & 0xff)); | ||
} | ||
if (val == 0xff) { // Reset | ||
#if MPU_DEBUG | ||
mpu_dbg_ctr = 0; | ||
|
@@ -194,6 +248,10 @@ static uint32_t MAIN_MPU_331(uint32_t port, uint32_t val, uint32_t out) | |
} | ||
return 0; | ||
} | ||
if (main_hw_mpuport) { | ||
uint8_t hwval = hw_mpu_inb(1); | ||
return hwval; | ||
} | ||
if ((mpu_state & 3) == 0) { | ||
return 0x80; | ||
} else { | ||
|
@@ -335,7 +393,7 @@ struct MAIN_OPT | |
"/SC", "Select sound card index in list (/SCL)", 0, MAIN_SETCMD_HIDDEN, | ||
"/R", "Reset sound card driver", 0, MAIN_SETCMD_HIDDEN, | ||
"/P", "UART mode MPU-401 IO address (default 330) [*]", 0x330, 0, | ||
"/MCOM", "UART mode MPU-401 COM port (1=COM1, 2=COM2, 3=COM3, 4=COM4, otherwise base address)", 0, 0, | ||
"/MCOM", "UART mode MPU-401 COM port (1=COM1, 2=COM2, 3=COM3, 4=COM4, 9:HW MPU only, otherwise base address)", 0, 0, | ||
"/COML", "List installed COM ports", 0, MAIN_SETCMD_HIDDEN, | ||
#if MPU_DEBUG | ||
"/MDBG", "Enable MPU-401 debugging (0 to disable, 1 or 2 to enable)", 0, 0, | ||
|
@@ -744,7 +802,8 @@ int main(int argc, char* argv[]) | |
} | ||
|
||
//OPL3EMU_Init(aui.freq_card); | ||
printf("OPL3 emulation at port 388: "); | ||
char *emutype = (main_hw_fmport != 0) ? "hardware" : "emulation"; | ||
printf("OPL3 %s at port 388: ", emutype); | ||
MAIN_Print_Enabled_Newline(true); | ||
} | ||
|
||
|
@@ -762,8 +821,9 @@ int main(int argc, char* argv[]) | |
return 1; | ||
} | ||
|
||
printf("MPU-401 UART emulation at address %x: ", | ||
MAIN_Options[OPT_MPUADDR].value); | ||
char *emutype = (main_hw_mpuport != 0) ? "hardware" : "emulation"; | ||
printf("MPU-401 UART %s at address %x: ", | ||
emutype, MAIN_Options[OPT_MPUADDR].value); | ||
MAIN_Print_Enabled_Newline(true); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,8 @@ extern one_sndcard_info VIA82XX_sndcard_info; | |
extern one_sndcard_info SBLIVE_sndcard_info; | ||
extern one_sndcard_info CMI8X38_sndcard_info; | ||
extern one_sndcard_info EMU20KX_sndcard_info; | ||
extern one_sndcard_info YMF_sndcard_info; | ||
extern one_sndcard_info YMFSB_sndcard_info; | ||
#ifndef SBEMU | ||
extern one_sndcard_info ESS_sndcard_info; | ||
extern one_sndcard_info WSS_sndcard_info; | ||
|
@@ -71,14 +73,20 @@ extern one_sndcard_info WINDSOUND_sndcard_info; | |
extern one_sndcard_info WINWAVOUT_sndcard_info; | ||
#endif | ||
|
||
extern one_sndcard_info NON_sndcard_info; | ||
#ifndef SBEMU | ||
extern one_sndcard_info WAV_sndcard_info; | ||
extern one_sndcard_info NON_sndcard_info; | ||
extern one_sndcard_info TST_sndcard_info; | ||
extern one_sndcard_info NUL_sndcard_info; | ||
#endif | ||
|
||
static one_sndcard_info *all_sndcard_info[]={ | ||
#ifdef AU_CARDS_LINK_YMF | ||
&YMFSB_sndcard_info, | ||
#endif | ||
#ifdef AU_CARDS_LINK_YMF | ||
&YMF_sndcard_info, | ||
#endif | ||
#ifdef AU_CARDS_LINK_SB16 | ||
&SB16_sndcard_info, | ||
#endif | ||
|
@@ -149,6 +157,7 @@ unsigned int playcontrol,outmode = OUTMODE_TYPE_AUDIO; | |
unsigned int intsoundconfig=INTSOUND_NOINT08|INTSOUND_NOBUSYWAIT,intsoundcontrol; | ||
unsigned long allcpuusage,allcputime; | ||
unsigned int is_lfn_support,uselfn,iswin9x; | ||
unsigned char au_cards_fallback_to_null = 0; | ||
#endif | ||
|
||
static aucards_writedata_t aucards_writedata_func; | ||
|
@@ -341,8 +350,21 @@ void AU_init(struct mpxplay_audioout_info_s *aui) | |
goto err_out_auinit; | ||
} | ||
if(!aui->card_handler && !(aui->card_controlbits&AUINFOS_CARDCNTRLBIT_SILENT)){ | ||
pds_textdisplay_printf("No supported soundcard found!"); | ||
goto err_out_auinit; | ||
#ifdef SBEMU | ||
if (au_cards_fallback_to_null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's good to use SBEMU on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this commit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, thanks |
||
static one_sndcard_info *no_sndcard_info[]={&NON_sndcard_info}; | ||
asip=&no_sndcard_info[0]; | ||
aui->card_handler=*asip; | ||
aui->card_test_index = 1; | ||
carddetect(aui,0); | ||
pds_textdisplay_printf("Using NULL driver"); | ||
} else { | ||
#endif | ||
pds_textdisplay_printf("No supported soundcard found!"); | ||
goto err_out_auinit; | ||
#ifdef SBEMU | ||
} | ||
#endif | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can determine
main_hw_fmport
before initialization and install a totally different handler (i.e. MAIN_OPL3_388_HWREMAP() ) to avoid checkmain_hw_fmport
in runtime every time.Also it will be better if
main_hw_fmport
is put inmpxplay_audioout_info_s
struct, and the init routine will check it and use another trap handler (aka MAIN_OPL3_388_HWREMAP).In such a way we decouple main from YMF driver, YMF driver only depend on mpxplay/au_cards module, not an extern defined in main.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a problem for some slow machines if you check
main_hw_fmport
every time?I think it is OK to commit it as is now, and improve it later.
There needs to be a way to have two or more cards selected. For example YMF for FM/MIDI and NULL or HDA for sound effects.
You could have options like /SC for sound effects, /FC for FM, /MC for MIDI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it is not.
As previously mentioned, That is A MONIOR SUGGESTION, and is not required do modify it right now.
But I'll be much better if dependency of
main_hw_fmport
is removed from main.c. The idea is to treat mpxplay/au_cards as a standalone library, and it should be SELF CONTAINED, WITHOUT ANY INCLUDE/LINKAGE dependencies.Think about this: if anyone, by any chance, want to use mpxplay/au_cards, he need to define a variable name
main_hw_fmport
to make the linker pass, which he might no even care; Or he need to modify the source code to remove anything involvingmain_hw_fmport
. Either way it is not a good portable code.This is already encountered when porting mpxplay into SBEMU. you can find dummy variables in
au_base.c
line 30:and au_cards.c, line 146
It's understandable that the author of mpxplay didn't predict that his code will be used others, but we can avoid the same problem for SBEMU.
Also please be noted that still it is a minor suggestion and you don't have to change it now, or for yourself, but please confirm if you want change it now.
Yes for now it is. I will be glad if you wanna add this, or if not, I can do that later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Naturally I think you would add some routines card_fm_read, card_fm_write etc. to struct one_sndcard_info.
I can do this later, but I want to clean up the Linux drivers first.
It would be easier for me to merge to/from my fork if this YMF patch gets merged first.
Before this I didn't have any experience with DOS.
I thought since this is a TSR it needs to be fast/simple, and, looking at main.c, thought that a global variable (
main_hw_fmport
) was OK.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, we can leave it for later. I'm really sorry for keep you waiting so long, I was digging into the doom crash problem and now still be. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the problem with doom? With which card?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The onboard HDA that @hjnijlunsing has, it's a compatibility problem not quite related to the soundcard driver as opl3 works.
Discussed here #13 (comment)