2020-03-25 00:49:25 +01:00
/*
* TYPE 0x11 : ( Washington )
* Aztech MMPRO16AB ,
* Aztech Sound Galaxy Pro 16 AB
* Aztech Sound Galaxy Washington 16
* . . . and other OEM names
* FCC ID I38 - MMSN824 and others
*
* TYPE 0x0C : ( Clinton )
* Packard Bell FORTE16
* Aztech Sound Galaxy Nova 16 Extra
* Aztech Sound Galaxy Clinton 16
* . . . and other OEM names
*
* Also works more or less for drivers of other models with the same chipsets .
*
* Copyright ( c ) 2020 Eluan Costa Miranda < eluancm @ gmail . com > All rights reserved .
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2020-03-25 01:23:22 +01:00
* the Free Software Foundation , either version 2 of the License , or
2020-03-25 00:49:25 +01:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* The CS4248 DSP used is pin and software compatible with the AD1848 .
* I also have one of these cards with a CS4231 . The driver talks to the
* emulated card as if it was a CS4231 and I still don ' t know how to tell the
* drivers to see the CS4248 . The CS4231 more advanced features are NOT used ,
* just the new input / output channels . Apparently some drivers are hardcoded
* for one or the other , so there is an option for this .
*
* There is lots more to be learned form the Win95 drivers . The Linux driver is
* very straightforward and doesn ' t do much .
*
* Recording and voice modes in the windows mixer still do nothing in 86 Box , so
* this is missing .
*
* There is a jumper to load the startup configuration from an EEPROM . This is
* implemented , so any software - configured parameters will be saved .
*
* The CD - ROM interface commands are just ignored , along with gameport .
* The MPU401 is always enabled .
* The OPL3 is always active in some ( all ? ) drivers / cards , so there is no
* configuration for this .
*
* Tested with DOS ( driver installation , tools , diagnostics ) , Win3 .1 ( driver
* installation , tools ) , Win95 ( driver auto - detection ) , lots of games .
*
* I consider type 0x11 ( Washington ) to be very well tested . Type 0x0C ( Clinton )
* wasn ' t fully tested , but works well for WSS / Windows . BEWARE that there are
* * too many * driver types and OEM versions for each card . Maybe yours isn ' t
* emulated or you have the wrong driver . Some features of each card may work
* when using wrong drivers . CODEC selection is also important .
*
* Any updates to the WSS and SBPROV2 sound cards should be synced here when
* appropriate . The WSS was completely cloned here , while the SBPROV2 tends
* to call the original functions , except for initialization .
*
* TODO / Notes :
* - Some stuff still not understood on I / O addresses 0x624 and 0x530 - 0x533 .
* - Is the CS42xx dither mode used anywhere ? Implement .
* - What are the voice commands mode in Win95 mixer again ?
* - Configuration options not present on Aztech ' s CONFIG . EXE have been commented
* out or deleted . Other types of cards with this chipset may need them .
* - Sfademo on the Descent CD fails under Win95 , works under DOS , see if it
* happens on real hardware ( and OPL3 stops working after the failure )
* - There appears to be some differences in sound volumes bertween MIDI ,
* SBPROV2 , WSS and OPL3 ? Also check relationship between the SBPROV2 mixer and
* the WSS mixer ! Are they independent ? Current mode selects which mixer ? Are
* they entangled ?
* - Check real hardware to see if advanced , mic boost , etc appear in the mixer ?
* - CD - ROM driver shipped with the card ( SGIDECD . SYS ) checks for model strings .
* I have implemented mine ( Aztech CDA 468 - 02 I 4 x ) in PCem .
* - Descent 2 W95 version can ' t start cd music . Happens on real hardware .
* Explanation further below .
* - DOSQuake and Descent 2 DOS cd music do not work under Win95 . The mode
* selects get truncated and send all zeros for output channel selection and
* volume , Descent 2 also has excess zeros ! This is a PCem bug , happens on all
* sound cards . CD audio works in Winquake and Descent 2 DOS setup program .
* - DOSQuake CD audio works under DOS with VIDE - CDD . SYS and SGIDECD . SYS .
* Descent 2 DOS is still mute but volume selection appears to be working .
* Descent 2 fails to launch with SGIDECD . SYS with " Device failed to request
* command " . SGIDECD.SYS is the CD-ROM driver included with the sound card
* drivers . My real CD - ROM drive can ' t read anything so I can ' t check the
* real behavior of this driver .
* - Some cards just have regular IDE ports while other have proprietary ports .
* The regular IDE ports just have a option to enable an almost - generic CD - ROM
* driver in CONFIG . SYS / AUTOEXEC . BAT ( like SGIDECD . SYS ) and the onboard port
* is enabled / disabled by jumpers . The proprietary ones also have
* address / dma / irq settings . Since the configuration options are ignored here ,
* this behaves like a card with a regular interface disabled by jumper and
* the configuration just adds / removes the drivers ( which will see other IDE
* interfaces present ) from the boot process .
* - Continue reverse engineering to see if the AZT1605 shares the SB DMA with
* WSS or if it is set separately by the TSR loaded on boot . Currently it is
* only set by PCem config and then saved to EEPROM ( which would make it fixed
* if loading from EEPROM too ) .
* - Related to the previous note , part of the SBPROV2 emulation on the CLINTON
* family appears to be implemented with a TSR . It ' s better to remove the TSR
* for now . I need to investigate this . Mixer is also weird under DOS ( and
* wants to save to EEPROM ? I don ' t think the WASHINGTON does this ) .
* - Search for TODO in this file . : - )
*
* Misc things I use to test for regressions : Windows sounds , Descent under
* dos / windows , Descent 2 dos / windows ( + cd music option ) , Descent 2 W95 + cd
* music , Age of Empires ( CD + Midi ) , cd - audio under Windows + volume ,
* cd - audio under dos + volume , Aztech diagnose . exe , Aztech volset / M : 3 then
* volset / D , Aztech setmode , mixer ( volume + balance ) under dos and windows ,
* DOSQuake under dos and windows ( + cd music and volumes , + Winquake ) .
*
* Reason for Descent 2 Win95 CD - Audio not working :
* The game calls auxGetNumDevs ( ) to check if any of the AUX devices has
* caps . wTechnology = = AUXCAPS_CDAUDIO , but this fails because the Aztech
* Win95 driver only returns a " Line-In " device . I ' m not aware of any other
* game that does this and this is completely unnecessary . Other games that
* play cd audio correctly have the exact * same * initialization code , minus
* this check that only Descent 2 Win95 does . It would work if it just skipped
* this check and progressed with calling mciSendCommand ( ) with
* mciOpenParms . lpstrDeviceType = " cdaudio " , like other games do . There are
* some sound cards listed as incompatible in the game ' s README . TXT file that
* are probably due to this .
*/
# include <stdarg.h>
# include <stdio.h>
# include <stdint.h>
# include <string.h>
# include <stdlib.h>
# include <wchar.h>
# include <math.h>
# define HAVE_STDARG_H
2020-03-29 14:24:42 +02:00
# include <86box/86box.h>
# include <86box/io.h>
# include <86box/timer.h>
# include <86box/pic.h>
# include <86box/nvr.h>
# include <86box/device.h>
# include <86box/sound.h>
# include <86box/midi.h>
# include <86box/snd_ad1848.h>
# include <86box/snd_azt2316a.h>
# include <86box/snd_sb.h>
2020-03-25 00:49:25 +01:00
/*530, 11, 3 - 530=23*/
/*530, 11, 1 - 530=22*/
/*530, 11, 0 - 530=21*/
/*530, 10, 1 - 530=1a*/
/*530, 10, 0 - 530=19*/
/*530, 9, 1 - 530=12*/
/*530, 7, 1 - 530=0a*/
/*604, 11, 1 - 530=22*/
/*e80, 11, 1 - 530=22*/
/*f40, 11, 1 - 530=22*/
static int azt2316a_wss_dma [ 4 ] = { 0 , 0 , 1 , 3 } ;
static int azt2316a_wss_irq [ 8 ] = { 5 , 7 , 9 , 10 , 11 , 12 , 14 , 15 } ; /* W95 only uses 7-10, others may be wrong */
//static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40};
typedef struct azt2316a_t
{
int type ;
int wss_interrupt_after_config ;
uint8_t wss_config ;
uint16_t cur_addr , cur_wss_addr , cur_mpu401_addr ;
int cur_irq , cur_dma ;
int cur_wss_enabled , cur_wss_irq , cur_wss_dma ;
int cur_mpu401_irq ;
int cur_mpu401_enabled ;
uint32_t config_word ;
uint32_t config_word_unlocked ;
uint8_t cur_mode ;
ad1848_t ad1848 ;
mpu_t * mpu ;
sb_t * sb ;
} azt2316a_t ;
static uint8_t
azt2316a_wss_read ( uint16_t addr , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
uint8_t temp ;
/* TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to
0x530 makes reading from 0x533 return 0x44 , but writing 0x50
makes this return 0x04 . Why ? */
if ( addr & 1 )
temp = 4 | ( azt2316a - > wss_config & 0x40 ) ;
else
temp = 4 | ( azt2316a - > wss_config & 0xC0 ) ;
return temp ;
}
static void
azt2316a_wss_write ( uint16_t addr , uint8_t val , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
int interrupt = 0 ;
2020-03-31 00:53:03 +02:00
if ( azt2316a - > wss_interrupt_after_config ) {
if ( ( azt2316a - > wss_config & 0x40 ) & & ! ( val & 0x40 ) ) { // TODO: is this the right edge?
interrupt = 1 ;
}
}
2020-03-25 00:49:25 +01:00
azt2316a - > wss_config = val ;
azt2316a - > cur_wss_dma = azt2316a_wss_dma [ val & 3 ] ;
azt2316a - > cur_wss_irq = azt2316a_wss_irq [ ( val > > 3 ) & 7 ] ;
ad1848_setdma ( & azt2316a - > ad1848 , azt2316a_wss_dma [ val & 3 ] ) ;
ad1848_setirq ( & azt2316a - > ad1848 , azt2316a_wss_irq [ ( val > > 3 ) & 7 ] ) ;
if ( interrupt )
picint ( 1 < < azt2316a - > cur_wss_irq ) ;
}
/* generate a config word based on current settings */
static void
azt1605_create_config_word ( void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
uint32_t temp = 0 ;
/* not implemented / hardcoded */
uint8_t game_enable = 1 ;
uint8_t cd_type = 0 ; /* TODO: see if the cd-rom was originally connected there on the real machines emulated by 86Box (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) */
uint8_t cd_dma8 = - 1 ;
uint8_t cd_irq = 0 ;
switch ( azt2316a - > cur_addr ) {
case 0x220 :
/* do nothing
temp + = 0 < < 0 ; */
break ;
case 0x240 :
temp + = 1 < < 0 ;
break ;
/*
case 0x260 : // TODO: INVALID?
temp + = 2 < < 0 ;
break ;
case 0x280 : // TODO: INVALID?
temp + = 3 < < 0 ;
break ;
*/
}
switch ( azt2316a - > cur_irq ) {
2020-03-31 00:53:03 +02:00
case 9 :
2020-03-25 00:49:25 +01:00
temp + = 1 < < 8 ;
break ;
case 3 :
temp + = 1 < < 9 ;
break ;
case 5 :
temp + = 1 < < 10 ;
break ;
case 7 :
temp + = 1 < < 11 ;
break ;
}
switch ( azt2316a - > cur_wss_addr ) {
case 0x530 :
/* do nothing
temp + = 0 < < 16 ; */
break ;
case 0x604 :
temp + = 1 < < 16 ;
break ;
case 0xE80 :
temp + = 2 < < 16 ;
break ;
case 0xF40 :
temp + = 3 < < 16 ;
break ;
}
if ( azt2316a - > cur_wss_enabled )
temp + = 1 < < 18 ;
if ( game_enable )
temp + = 1 < < 4 ;
switch ( azt2316a - > cur_mpu401_addr ) {
case 0x300 :
/* do nothing
temp + = 0 < < 2 ; */
break ;
case 0x330 :
temp + = 1 < < 2 ;
break ;
}
if ( azt2316a - > cur_mpu401_enabled )
temp + = 1 < < 3 ;
switch ( cd_type ) {
case 0 : /* disabled
do nothing
temp + = 0 < < 5 ; */
break ;
case 1 : // panasonic
temp + = 1 < < 5 ;
break ;
case 2 : // mitsumi/sony/aztech
temp + = 2 < < 5 ;
break ;
case 3 : // all enabled
temp + = 3 < < 5 ;
break ;
case 4 : // unused
temp + = 4 < < 5 ;
break ;
case 5 : // unused
temp + = 5 < < 5 ;
break ;
case 6 : // unused
temp + = 6 < < 5 ;
break ;
case 7 : // unused
temp + = 7 < < 5 ;
break ;
}
switch ( cd_dma8 ) {
case 0xFF : /* -1
do nothing
temp + = 0 < < 22 ; */
break ;
case 0 :
temp + = 1 < < 22 ;
break ;
case 1 :
temp + = 2 < < 22 ;
break ;
case 3 :
temp + = 3 < < 22 ;
break ;
}
switch ( azt2316a - > cur_mpu401_irq ) {
2020-03-31 00:53:03 +02:00
case 9 :
2020-03-25 00:49:25 +01:00
temp + = 1 < < 12 ;
break ;
case 3 :
temp + = 1 < < 13 ;
break ;
case 5 :
temp + = 1 < < 14 ;
break ;
case 7 :
temp + = 1 < < 15 ;
break ;
}
switch ( cd_irq ) {
case 0 : // disabled
// do nothing
break ;
case 11 :
temp + = 1 < < 19 ;
break ;
case 12 :
temp + = 1 < < 20 ;
break ;
case 15 :
temp + = 1 < < 21 ;
break ;
}
azt2316a - > config_word = temp ;
}
static void
azt2316a_create_config_word ( void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
uint32_t temp = 0 ;
/* not implemented / hardcoded */
uint8_t game_enable = 1 ;
uint16_t cd_addr = 0x310 ;
uint8_t cd_type = 0 ; /* TODO: see if the cd-rom was originally connected there on the real machines emulated by 86Box (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) */
uint8_t cd_dma8 = - 1 ;
uint8_t cd_dma16 = - 1 ;
uint8_t cd_irq = 15 ;
if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT1605_0X0C ) {
azt1605_create_config_word ( p ) ;
return ;
}
switch ( azt2316a - > cur_addr ) {
case 0x220 :
/* do nothing
temp + = 0 < < 0 ; */
break ;
case 0x240 :
temp + = 1 < < 0 ;
break ;
/*
case 0x260 : // TODO: INVALID?
temp + = 2 < < 0 ;
break ;
case 0x280 : // TODO: INVALID?
temp + = 3 < < 0 ;
break ;
*/
}
switch ( azt2316a - > cur_irq ) {
2020-03-31 00:53:03 +02:00
case 9 :
2020-03-25 00:49:25 +01:00
temp + = 1 < < 2 ;
break ;
case 5 :
temp + = 1 < < 3 ;
break ;
case 7 :
temp + = 1 < < 4 ;
break ;
case 10 :
temp + = 1 < < 5 ;
break ;
}
switch ( azt2316a - > cur_dma ) {
/*
// TODO: INVALID?
case 0xFF : // -1
// do nothing
//temp += 0 << 6;
break ;
*/
case 0 :
temp + = 1 < < 6 ;
break ;
case 1 :
temp + = 2 < < 6 ;
break ;
case 3 :
temp + = 3 < < 6 ;
break ;
}
switch ( azt2316a - > cur_wss_addr )
{
case 0x530 :
// do nothing
//temp += 0 << 8;
break ;
case 0x604 :
temp + = 1 < < 8 ;
break ;
case 0xE80 :
temp + = 2 < < 8 ;
break ;
case 0xF40 :
temp + = 3 < < 8 ;
break ;
}
if ( azt2316a - > cur_wss_enabled )
temp + = 1 < < 10 ;
if ( game_enable )
temp + = 1 < < 11 ;
switch ( azt2316a - > cur_mpu401_addr )
{
case 0x300 :
// do nothing
//temp += 0 << 12;
break ;
case 0x330 :
temp + = 1 < < 12 ;
break ;
}
if ( azt2316a - > cur_mpu401_enabled )
temp + = 1 < < 13 ;
switch ( cd_addr ) {
case 0x310 :
// do nothing
//temp += 0 << 14;
break ;
case 0x320 :
temp + = 1 < < 14 ;
break ;
case 0x340 :
temp + = 2 < < 14 ;
break ;
case 0x350 :
temp + = 3 < < 14 ;
break ;
}
switch ( cd_type ) {
case 0 : /* disabled
do nothing
temp + = 0 < < 16 ; */
break ;
case 1 : /* panasonic */
temp + = 1 < < 16 ;
break ;
case 2 : /* sony */
temp + = 2 < < 16 ;
break ;
case 3 : /* mitsumi */
temp + = 3 < < 16 ;
break ;
case 4 : /* aztech */
temp + = 4 < < 16 ;
break ;
case 5 : /* unused */
temp + = 5 < < 16 ;
break ;
case 6 : /* unused */
temp + = 6 < < 16 ;
break ;
case 7 : /* unused */
temp + = 7 < < 16 ;
break ;
}
switch ( cd_dma8 ) {
case 0xFF : /* -1
do nothing
temp + = 0 < < 20 ; */
break ;
case 0 :
temp + = 1 < < 20 ;
break ;
/*
case 1 : // TODO: INVALID?
temp + = 2 < < 20 ;
break ;
*/
case 3 :
temp + = 3 < < 20 ;
break ;
}
switch ( cd_dma16 ) {
case 0xFF : /* -1
do nothing
temp + = 0 < < 22 ; */
break ;
case 5 :
temp + = 1 < < 22 ;
break ;
case 6 :
temp + = 2 < < 22 ;
break ;
case 7 :
temp + = 3 < < 22 ;
break ;
}
switch ( azt2316a - > cur_mpu401_irq ) {
2020-03-31 00:53:03 +02:00
case 9 :
2020-03-25 00:49:25 +01:00
temp + = 1 < < 24 ;
break ;
case 5 :
temp + = 1 < < 25 ;
break ;
case 7 :
temp + = 1 < < 26 ;
break ;
case 10 :
temp + = 1 < < 27 ;
break ;
}
switch ( cd_irq ) {
case 5 :
temp + = 1 < < 28 ;
break ;
case 11 :
temp + = 1 < < 29 ;
break ;
case 12 :
temp + = 1 < < 30 ;
break ;
case 15 :
temp + = 1 < < 31 ;
break ;
}
azt2316a - > config_word = temp ;
}
static uint8_t
azt2316a_config_read ( uint16_t addr , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
uint8_t temp = 0 ;
/* Some WSS config here + config change enable bit
( setting bit 7 and writing back ) */
if ( addr = = ( azt2316a - > cur_addr + 0x404 ) ) {
/* TODO: what is the real meaning of the read value?
I got a mention of bit 0x10 for WSS from disassembling the source
code of the driver , and when playing with the I / O ports on real
hardware after doing some configuration , but didn ' t dig into it .
Bit 0x08 seems to be a busy flag and generates a timeout
( continuous re - reading when initializing windows 98 ) */
temp = azt2316a - > cur_mode ? 0x07 : 0x0F ;
if ( azt2316a - > config_word_unlocked ) {
temp | = 0x80 ;
}
} else {
// Rest of config. These are documented in the Linux driver.
switch ( addr & 0x3 )
{
case 0 :
temp = azt2316a - > config_word & 0xFF ;
break ;
case 1 :
temp = ( azt2316a - > config_word > > 8 ) ;
break ;
case 2 :
temp = ( azt2316a - > config_word > > 16 ) ;
break ;
case 3 :
temp = ( azt2316a - > config_word > > 24 ) ;
break ;
}
}
return temp ;
}
static void
azt1605_config_write ( uint16_t addr , uint8_t val , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
uint8_t temp ;
if ( addr = = ( azt2316a - > cur_addr + 0x404 ) ) {
if ( val & 0x80 )
azt2316a - > config_word_unlocked = 1 ;
else
azt2316a - > config_word_unlocked = 0 ;
} else if ( azt2316a - > config_word_unlocked ) {
if ( val = = 0xFF ) { /* TODO: check if this still happens on eeprom.sys after having more complete emulation! */
return ;
}
switch ( addr & 3 ) {
case 0 :
azt2316a - > config_word = ( azt2316a - > config_word & 0xFFFFFF00 ) | val ;
temp = val & 3 ;
if ( temp = = 0 )
azt2316a - > cur_addr = 0x220 ;
else if ( temp = = 1 )
azt2316a - > cur_addr = 0x240 ;
/*
else if ( temp = = 2 )
azt2316a - > cur_addr = 0x260 ; // TODO: INVALID
else if ( temp = = 3 )
azt2316a - > cur_addr = 0x280 ; // TODO: INVALID
*/
if ( val & 0x4 )
azt2316a - > cur_mpu401_addr = 0x330 ;
else
azt2316a - > cur_mpu401_addr = 0x300 ;
if ( val & 0x8 )
azt2316a - > cur_mpu401_enabled = 1 ;
else
azt2316a - > cur_mpu401_enabled = 0 ;
break ;
case 1 :
azt2316a - > config_word = ( azt2316a - > config_word & 0xFFFF00FF ) | ( val < < 8 ) ;
if ( val & 0x1 )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( val & 0x2 )
azt2316a - > cur_irq = 3 ;
else if ( val & 0x4 )
azt2316a - > cur_irq = 5 ;
else if ( val & 0x8 )
azt2316a - > cur_irq = 7 ;
/* else undefined? */
if ( val & 0x10 )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_mpu401_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( val & 0x20 )
azt2316a - > cur_mpu401_irq = 3 ;
else if ( val & 0x40 )
azt2316a - > cur_mpu401_irq = 5 ;
else if ( val & 0x80 )
azt2316a - > cur_mpu401_irq = 7 ;
/* else undefined? */
break ;
case 2 :
azt2316a - > config_word = ( azt2316a - > config_word & 0xFF00FFFF ) | ( val < < 16 ) ;
io_removehandler ( azt2316a - > cur_wss_addr , 0x0004 , azt2316a_wss_read , NULL , NULL , azt2316a_wss_write , NULL , NULL , azt2316a ) ;
io_removehandler ( azt2316a - > cur_wss_addr + 0x0004 , 0x0004 , ad1848_read , NULL , NULL , ad1848_write , NULL , NULL , & azt2316a - > ad1848 ) ;
temp = val & 0x3 ;
if ( temp = = 0 )
azt2316a - > cur_wss_addr = 0x530 ;
else if ( temp = = 1 )
azt2316a - > cur_wss_addr = 0x604 ;
else if ( temp = = 2 )
azt2316a - > cur_wss_addr = 0xE80 ;
else if ( temp = = 3 )
azt2316a - > cur_wss_addr = 0xF40 ;
io_sethandler ( azt2316a - > cur_wss_addr , 0x0004 , azt2316a_wss_read , NULL , NULL , azt2316a_wss_write , NULL , NULL , azt2316a ) ;
io_sethandler ( azt2316a - > cur_wss_addr + 0x0004 , 0x0004 , ad1848_read , NULL , NULL , ad1848_write , NULL , NULL , & azt2316a - > ad1848 ) ;
/* no actual effect */
if ( val & 0x4 )
azt2316a - > cur_wss_enabled = 1 ;
else
azt2316a - > cur_wss_enabled = 0 ;
break ;
case 3 :
break ;
}
/* update sbprov2 configs */
sb_dsp_setaddr ( & azt2316a - > sb - > dsp , azt2316a - > cur_addr ) ;
sb_dsp_setirq ( & azt2316a - > sb - > dsp , azt2316a - > cur_irq ) ;
sb_dsp_setdma8 ( & azt2316a - > sb - > dsp , azt2316a - > cur_dma ) ;
mpu401_change_addr ( azt2316a - > mpu , azt2316a - > cur_mpu401_addr ) ;
mpu401_setirq ( azt2316a - > mpu , azt2316a - > cur_mpu401_irq ) ;
}
}
static void
azt2316a_config_write ( uint16_t addr , uint8_t val , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
uint8_t temp ;
if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT1605_0X0C ) {
azt1605_config_write ( addr , val , azt2316a ) ;
return ;
}
if ( addr = = ( azt2316a - > cur_addr + 0x404 ) ) {
if ( val & 0x80 )
azt2316a - > config_word_unlocked = 1 ;
else
azt2316a - > config_word_unlocked = 0 ;
} else if ( azt2316a - > config_word_unlocked ) {
if ( val = = 0xFF ) // TODO: check if this still happens on eeprom.sys after having more complete emulation!
return ;
switch ( addr & 3 ) {
case 0 :
azt2316a - > config_word = ( azt2316a - > config_word & 0xFFFFFF00 ) | val ;
temp = val & 3 ;
if ( temp = = 0 )
azt2316a - > cur_addr = 0x220 ;
else if ( temp = = 1 )
azt2316a - > cur_addr = 0x240 ;
if ( val & 0x4 )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( val & 0x8 )
azt2316a - > cur_irq = 5 ;
else if ( val & 0x10 )
azt2316a - > cur_irq = 7 ;
else if ( val & 0x20 )
azt2316a - > cur_irq = 10 ;
temp = ( val > > 6 ) & 3 ;
if ( temp = = 1 )
azt2316a - > cur_dma = 0 ;
else if ( temp = = 2 )
azt2316a - > cur_dma = 1 ;
else if ( temp = = 3 )
azt2316a - > cur_dma = 3 ;
break ;
case 1 :
azt2316a - > config_word = ( azt2316a - > config_word & 0xFFFF00FF ) | ( val < < 8 ) ;
io_removehandler ( azt2316a - > cur_wss_addr , 0x0004 , azt2316a_wss_read , NULL , NULL , azt2316a_wss_write , NULL , NULL , azt2316a ) ;
io_removehandler ( azt2316a - > cur_wss_addr + 0x0004 , 0x0004 , ad1848_read , NULL , NULL , ad1848_write , NULL , NULL , & azt2316a - > ad1848 ) ;
temp = val & 0x3 ;
if ( temp = = 0 )
azt2316a - > cur_wss_addr = 0x530 ;
else if ( temp = = 1 )
azt2316a - > cur_wss_addr = 0x604 ;
else if ( temp = = 2 )
azt2316a - > cur_wss_addr = 0xE80 ;
else if ( temp = = 3 )
azt2316a - > cur_wss_addr = 0xF40 ;
io_sethandler ( azt2316a - > cur_wss_addr , 0x0004 , azt2316a_wss_read , NULL , NULL , azt2316a_wss_write , NULL , NULL , azt2316a ) ;
io_sethandler ( azt2316a - > cur_wss_addr + 0x0004 , 0x0004 , ad1848_read , NULL , NULL , ad1848_write , NULL , NULL , & azt2316a - > ad1848 ) ;
/* no actual effect */
if ( val & 0x4 )
azt2316a - > cur_wss_enabled = 1 ;
else
azt2316a - > cur_wss_enabled = 0 ;
if ( val & 0x10 )
azt2316a - > cur_mpu401_addr = 0x330 ;
else
azt2316a - > cur_mpu401_addr = 0x300 ;
if ( val & 0x20 )
azt2316a - > cur_mpu401_enabled = 1 ;
else
azt2316a - > cur_mpu401_enabled = 0 ;
break ;
case 2 :
azt2316a - > config_word = ( azt2316a - > config_word & 0xFF00FFFF ) | ( val < < 16 ) ;
break ;
case 3 :
azt2316a - > config_word = ( azt2316a - > config_word & 0x00FFFFFF ) | ( val < < 24 ) ;
if ( val & 0x1 )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_mpu401_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( val & 0x2 )
azt2316a - > cur_mpu401_irq = 5 ;
else if ( val & 0x4 )
azt2316a - > cur_mpu401_irq = 7 ;
else if ( val & 0x8 )
azt2316a - > cur_mpu401_irq = 10 ;
/* else undefined? */
break ;
}
/* update sbprov2 configs */
sb_dsp_setaddr ( & azt2316a - > sb - > dsp , azt2316a - > cur_addr ) ;
sb_dsp_setirq ( & azt2316a - > sb - > dsp , azt2316a - > cur_irq ) ;
sb_dsp_setdma8 ( & azt2316a - > sb - > dsp , azt2316a - > cur_dma ) ;
mpu401_change_addr ( azt2316a - > mpu , azt2316a - > cur_mpu401_addr ) ;
mpu401_setirq ( azt2316a - > mpu , azt2316a - > cur_mpu401_irq ) ;
}
}
/* How it behaves when one or another is activated may affect games auto-detecting (and will also use more of the limited system resources!) */
void
azt2316a_enable_wss ( uint8_t enable , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
if ( enable )
azt2316a - > cur_mode = 1 ;
else
azt2316a - > cur_mode = 0 ;
}
static void
azt2316a_get_buffer ( int32_t * buffer , int len , void * p )
{
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
int c ;
/* wss part */
ad1848_update ( & azt2316a - > ad1848 ) ;
for ( c = 0 ; c < len * 2 ; c + + )
buffer [ c ] + = ( azt2316a - > ad1848 . buffer [ c ] / 2 ) ;
azt2316a - > ad1848 . pos = 0 ;
/* sbprov2 part */
sb_get_buffer_sbpro ( buffer , len , azt2316a - > sb ) ;
}
static void *
azt_init ( const device_t * info )
{
FILE * f ;
2021-03-14 20:35:01 +01:00
char * fn = NULL ;
2020-03-25 00:49:25 +01:00
int i ;
int loaded_from_eeprom = 0 ;
uint16_t addr_setting ;
uint8_t read_eeprom [ AZTECH_EEPROM_SIZE ] ;
azt2316a_t * azt2316a = malloc ( sizeof ( azt2316a_t ) ) ;
memset ( azt2316a , 0 , sizeof ( azt2316a_t ) ) ;
azt2316a - > type = info - > local ;
if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT1605_0X0C ) {
2021-03-14 20:35:01 +01:00
fn = " azt1605.nvr " ;
2020-03-25 00:49:25 +01:00
} else if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT2316A_0X11 ) {
2021-03-14 20:35:01 +01:00
fn = " azt2316a.nvr " ;
2020-03-25 00:49:25 +01:00
}
/* config */
2021-03-14 20:35:01 +01:00
f = nvr_fopen ( fn , " rb " ) ;
2020-03-25 00:49:25 +01:00
if ( f ) {
uint8_t checksum = 0x7f ;
uint8_t saved_checksum ;
size_t res ;
res = fread ( read_eeprom , AZTECH_EEPROM_SIZE , 1 , f ) ;
for ( i = 0 ; i < AZTECH_EEPROM_SIZE ; i + + )
checksum + = read_eeprom [ i ] ;
res = fread ( & saved_checksum , sizeof ( saved_checksum ) , 1 , f ) ;
( void ) res ;
fclose ( f ) ;
if ( checksum = = saved_checksum )
loaded_from_eeprom = 1 ;
}
if ( ! loaded_from_eeprom ) {
if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT2316A_0X11 ) {
read_eeprom [ 0 ] = 0x00 ;
read_eeprom [ 1 ] = 0x00 ;
read_eeprom [ 2 ] = 0x00 ;
read_eeprom [ 3 ] = 0x00 ;
read_eeprom [ 4 ] = 0x00 ;
read_eeprom [ 5 ] = 0x00 ;
read_eeprom [ 6 ] = 0x00 ;
read_eeprom [ 7 ] = 0x00 ;
read_eeprom [ 8 ] = 0x00 ;
read_eeprom [ 9 ] = 0x00 ;
read_eeprom [ 10 ] = 0x00 ;
read_eeprom [ 11 ] = 0x88 ;
read_eeprom [ 12 ] = 0xbc ;
read_eeprom [ 13 ] = 0x00 ;
read_eeprom [ 14 ] = 0x01 ;
read_eeprom [ 15 ] = 0x00 ;
} else if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT1605_0X0C ) {
read_eeprom [ 0 ] = 0x80 ;
read_eeprom [ 1 ] = 0x80 ;
read_eeprom [ 2 ] = 0x9F ;
read_eeprom [ 3 ] = 0x13 ;
read_eeprom [ 4 ] = 0x16 ;
read_eeprom [ 5 ] = 0x13 ;
read_eeprom [ 6 ] = 0x00 ;
read_eeprom [ 7 ] = 0x00 ;
read_eeprom [ 8 ] = 0x16 ;
read_eeprom [ 9 ] = 0x0B ;
read_eeprom [ 10 ] = 0x06 ;
read_eeprom [ 11 ] = 0x01 ;
read_eeprom [ 12 ] = 0x1C ;
read_eeprom [ 13 ] = 0x14 ;
read_eeprom [ 14 ] = 0x04 ;
read_eeprom [ 15 ] = 0x1C ;
}
}
if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT2316A_0X11 ) {
azt2316a - > config_word = read_eeprom [ 11 ] | ( read_eeprom [ 12 ] < < 8 ) | ( read_eeprom [ 13 ] < < 16 ) | ( read_eeprom [ 14 ] < < 24 ) ;
switch ( azt2316a - > config_word & ( 3 < < 0 ) ) {
case 0 :
azt2316a - > cur_addr = 0x220 ;
break ;
case 1 :
azt2316a - > cur_addr = 0x240 ;
break ;
default :
fatal ( " AZT2316A: invalid sb addr in config word %08X \n " , azt2316a - > config_word ) ;
}
if ( azt2316a - > config_word & ( 1 < < 2 ) )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( azt2316a - > config_word & ( 1 < < 3 ) )
azt2316a - > cur_irq = 5 ;
else if ( azt2316a - > config_word & ( 1 < < 4 ) )
azt2316a - > cur_irq = 7 ;
else if ( azt2316a - > config_word & ( 1 < < 5 ) )
azt2316a - > cur_irq = 10 ;
else
fatal ( " AZT2316A: invalid sb irq in config word %08X \n " , azt2316a - > config_word ) ;
switch ( azt2316a - > config_word & ( 3 < < 6 ) ) {
case 1 < < 6 :
azt2316a - > cur_dma = 0 ;
break ;
case 2 < < 6 :
azt2316a - > cur_dma = 1 ;
break ;
case 3 < < 6 :
azt2316a - > cur_dma = 3 ;
break ;
default :
fatal ( " AZT2316A: invalid sb dma in config word %08X \n " , azt2316a - > config_word ) ;
}
switch ( azt2316a - > config_word & ( 3 < < 8 ) ) {
case 0 :
azt2316a - > cur_wss_addr = 0x530 ;
break ;
case 1 < < 8 :
azt2316a - > cur_wss_addr = 0x604 ;
break ;
case 2 < < 8 :
azt2316a - > cur_wss_addr = 0xE80 ;
break ;
case 3 < < 8 :
azt2316a - > cur_wss_addr = 0xF40 ;
break ;
default :
fatal ( " AZT2316A: invalid wss addr in config word %08X \n " , azt2316a - > config_word ) ;
}
if ( azt2316a - > config_word & ( 1 < < 10 ) )
azt2316a - > cur_wss_enabled = 1 ;
else
azt2316a - > cur_wss_enabled = 0 ;
if ( azt2316a - > config_word & ( 1 < < 12 ) )
azt2316a - > cur_mpu401_addr = 0x330 ;
else
azt2316a - > cur_mpu401_addr = 0x300 ;
if ( azt2316a - > config_word & ( 1 < < 13 ) )
azt2316a - > cur_mpu401_enabled = 1 ;
else
azt2316a - > cur_mpu401_enabled = 0 ;
if ( azt2316a - > config_word & ( 1 < < 24 ) )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_mpu401_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( azt2316a - > config_word & ( 1 < < 25 ) )
azt2316a - > cur_mpu401_irq = 5 ;
else if ( azt2316a - > config_word & ( 1 < < 26 ) )
azt2316a - > cur_mpu401_irq = 7 ;
else if ( azt2316a - > config_word & ( 1 < < 27 ) )
azt2316a - > cur_mpu401_irq = 10 ;
else
fatal ( " AZT2316A: invalid mpu401 irq in config word %08X \n " , azt2316a - > config_word ) ;
/* these are not present on the EEPROM */
2020-03-31 00:53:03 +02:00
azt2316a - > cur_wss_irq = device_get_config_int ( " wss_irq " ) ;
azt2316a - > cur_wss_dma = device_get_config_int ( " wss_dma " ) ;
2020-03-25 00:49:25 +01:00
azt2316a - > cur_mode = 0 ;
} else if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT1605_0X0C ) {
azt2316a - > config_word = read_eeprom [ 12 ] + ( read_eeprom [ 13 ] < < 8 ) + ( read_eeprom [ 14 ] < < 16 ) ;
switch ( azt2316a - > config_word & ( 3 < < 0 ) ) {
case 0 :
azt2316a - > cur_addr = 0x220 ;
break ;
case 1 :
azt2316a - > cur_addr = 0x240 ;
break ;
default :
fatal ( " AZT1605: invalid sb addr in config word %08X \n " , azt2316a - > config_word ) ;
}
if ( azt2316a - > config_word & ( 1 < < 2 ) )
azt2316a - > cur_mpu401_addr = 0x330 ;
else
azt2316a - > cur_mpu401_addr = 0x300 ;
if ( azt2316a - > config_word & ( 1 < < 3 ) )
azt2316a - > cur_mpu401_enabled = 1 ;
else
azt2316a - > cur_mpu401_enabled = 0 ;
if ( azt2316a - > config_word & ( 1 < < 8 ) )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( azt2316a - > config_word & ( 1 < < 9 ) )
azt2316a - > cur_irq = 3 ;
else if ( azt2316a - > config_word & ( 1 < < 10 ) )
azt2316a - > cur_irq = 5 ;
else if ( azt2316a - > config_word & ( 1 < < 11 ) )
azt2316a - > cur_irq = 7 ;
else
fatal ( " AZT1605: invalid sb irq in config word %08X \n " , azt2316a - > config_word ) ;
if ( azt2316a - > config_word & ( 1 < < 12 ) )
2020-03-31 00:53:03 +02:00
azt2316a - > cur_mpu401_irq = 9 ;
2020-03-25 00:49:25 +01:00
else if ( azt2316a - > config_word & ( 1 < < 13 ) )
azt2316a - > cur_mpu401_irq = 3 ;
else if ( azt2316a - > config_word & ( 1 < < 14 ) )
azt2316a - > cur_mpu401_irq = 5 ;
else if ( azt2316a - > config_word & ( 1 < < 15 ) )
azt2316a - > cur_mpu401_irq = 7 ;
else
fatal ( " AZT1605: invalid mpu401 irq in config word %08X \n " , azt2316a - > config_word ) ;
switch ( azt2316a - > config_word & ( 3 < < 16 ) ) {
case 0 :
azt2316a - > cur_wss_addr = 0x530 ;
break ;
case 1 < < 16 :
azt2316a - > cur_wss_addr = 0x604 ;
break ;
case 2 < < 16 :
azt2316a - > cur_wss_addr = 0xE80 ;
break ;
case 3 < < 16 :
azt2316a - > cur_wss_addr = 0xF40 ;
break ;
default :
fatal ( " AZT1605: invalid wss addr in config word %08X \n " , azt2316a - > config_word ) ;
}
if ( azt2316a - > config_word & ( 1 < < 18 ) )
azt2316a - > cur_wss_enabled = 1 ;
else
azt2316a - > cur_wss_enabled = 0 ;
// these are not present on the EEPROM
azt2316a - > cur_dma = device_get_config_int ( " sb_dma8 " ) ; // TODO: investigate TSR to make this work with it - there is no software configurable DMA8?
2020-03-31 00:53:03 +02:00
azt2316a - > cur_wss_irq = device_get_config_int ( " wss_irq " ) ;
azt2316a - > cur_wss_dma = device_get_config_int ( " wss_dma " ) ;
2020-03-25 00:49:25 +01:00
azt2316a - > cur_mode = 0 ;
}
addr_setting = device_get_config_hex16 ( " addr " ) ;
if ( addr_setting )
azt2316a - > cur_addr = addr_setting ;
azt2316a - > wss_interrupt_after_config = device_get_config_int ( " wss_interrupt_after_config " ) ;
/* wss part */
ad1848_init ( & azt2316a - > ad1848 , device_get_config_int ( " codec " ) ) ;
ad1848_setirq ( & azt2316a - > ad1848 , azt2316a - > cur_wss_irq ) ;
ad1848_setdma ( & azt2316a - > ad1848 , azt2316a - > cur_wss_dma ) ;
io_sethandler ( azt2316a - > cur_addr + 0x0400 , 0x0040 , azt2316a_config_read , NULL , NULL , azt2316a_config_write , NULL , NULL , azt2316a ) ;
io_sethandler ( azt2316a - > cur_wss_addr , 0x0004 , azt2316a_wss_read , NULL , NULL , azt2316a_wss_write , NULL , NULL , azt2316a ) ;
io_sethandler ( azt2316a - > cur_wss_addr + 0x0004 , 0x0004 , ad1848_read , NULL , NULL , ad1848_write , NULL , NULL , & azt2316a - > ad1848 ) ;
/* sbprov2 part */
/*sbpro port mappings. 220h or 240h.
2 x0 to 2 x3 - > FM chip ( 18 voices )
2 x4 to 2 x5 - > Mixer interface
2 x6 , 2 xA , 2 xC , 2 xE - > DSP chip
2 x8 , 2 x9 , 388 and 389 FM chip ( 9 voices ) . */
azt2316a - > sb = malloc ( sizeof ( sb_t ) ) ;
memset ( azt2316a - > sb , 0 , sizeof ( sb_t ) ) ;
azt2316a - > sb - > opl_enabled = device_get_config_int ( " opl " ) ;
for ( i = 0 ; i < AZTECH_EEPROM_SIZE ; i + + )
azt2316a - > sb - > dsp . azt_eeprom [ i ] = read_eeprom [ i ] ;
if ( azt2316a - > sb - > opl_enabled )
opl3_init ( & azt2316a - > sb - > opl ) ;
sb_dsp_init ( & azt2316a - > sb - > dsp , SBPRO2 , azt2316a - > type , azt2316a ) ;
sb_dsp_setaddr ( & azt2316a - > sb - > dsp , azt2316a - > cur_addr ) ;
sb_dsp_setirq ( & azt2316a - > sb - > dsp , azt2316a - > cur_irq ) ;
sb_dsp_setdma8 ( & azt2316a - > sb - > dsp , azt2316a - > cur_dma ) ;
sb_ct1345_mixer_reset ( azt2316a - > sb ) ;
/* DSP I/O handler is activated in sb_dsp_setaddr */
if ( azt2316a - > sb - > opl_enabled ) {
io_sethandler ( azt2316a - > cur_addr + 0 , 0x0004 , opl3_read , NULL , NULL , opl3_write , NULL , NULL , & azt2316a - > sb - > opl ) ;
io_sethandler ( azt2316a - > cur_addr + 8 , 0x0002 , opl3_read , NULL , NULL , opl3_write , NULL , NULL , & azt2316a - > sb - > opl ) ;
io_sethandler ( 0x0388 , 0x0004 , opl3_read , NULL , NULL , opl3_write , NULL , NULL , & azt2316a - > sb - > opl ) ;
}
io_sethandler ( azt2316a - > cur_addr + 4 , 0x0002 , sb_ct1345_mixer_read , NULL , NULL , sb_ct1345_mixer_write , NULL , NULL , azt2316a - > sb ) ;
azt2316a_create_config_word ( azt2316a ) ;
sound_add_handler ( azt2316a_get_buffer , azt2316a ) ;
2020-10-21 02:46:50 +02:00
sound_set_cd_audio_filter ( sbpro_filter_cd_audio , azt2316a - > sb ) ;
2020-03-25 00:49:25 +01:00
if ( azt2316a - > cur_mpu401_enabled ) {
azt2316a - > mpu = ( mpu_t * ) malloc ( sizeof ( mpu_t ) ) ;
memset ( azt2316a - > mpu , 0 , sizeof ( mpu_t ) ) ;
mpu401_init ( azt2316a - > mpu , azt2316a - > cur_mpu401_addr , azt2316a - > cur_mpu401_irq , M_UART , device_get_config_int ( " receive_input401 " ) ) ;
} else
azt2316a - > mpu = NULL ;
if ( device_get_config_int ( " receive_input " ) )
midi_in_handler ( 1 , sb_dsp_input_msg , sb_dsp_input_sysex , & azt2316a - > sb - > dsp ) ;
return azt2316a ;
}
static void
azt_close ( void * p )
{
2020-03-31 00:53:03 +02:00
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
2021-03-14 20:35:01 +01:00
char * fn = NULL ;
2020-03-25 00:49:25 +01:00
FILE * f ;
2020-03-31 00:53:03 +02:00
uint8_t checksum = 0x7f ;
2020-03-25 00:49:25 +01:00
int i ;
if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT1605_0X0C ) {
2021-03-14 20:35:01 +01:00
fn = " azt1605.nvr " ;
2020-03-25 00:49:25 +01:00
} else if ( azt2316a - > type = = SB_SUBTYPE_CLONE_AZT2316A_0X11 ) {
2021-03-14 20:35:01 +01:00
fn = " azt2316a.nvr " ;
2020-03-25 00:49:25 +01:00
}
2020-03-31 00:53:03 +02:00
/* always save to eeprom (recover from bad values) */
2021-03-14 20:35:01 +01:00
f = nvr_fopen ( fn , " wb " ) ;
2020-03-31 00:53:03 +02:00
if ( f ) {
2020-03-25 00:49:25 +01:00
for ( i = 0 ; i < AZTECH_EEPROM_SIZE ; i + + )
checksum + = azt2316a - > sb - > dsp . azt_eeprom [ i ] ;
fwrite ( azt2316a - > sb - > dsp . azt_eeprom , AZTECH_EEPROM_SIZE , 1 , f ) ;
// TODO: confirm any models saving mixer settings to EEPROM and implement reading back
// TODO: should remember to save wss duplex setting if 86Box has voice recording implemented in the future? Also, default azt2316a->wss_config
// TODO: azt2316a->cur_mode is not saved to EEPROM?
fwrite ( & checksum , sizeof ( checksum ) , 1 , f ) ;
fclose ( f ) ;
2020-03-31 00:53:03 +02:00
}
2020-03-25 00:49:25 +01:00
2020-03-31 00:53:03 +02:00
sb_close ( azt2316a - > sb ) ;
2020-03-25 00:49:25 +01:00
2020-03-31 00:53:03 +02:00
free ( azt2316a ) ;
2020-03-25 00:49:25 +01:00
}
static void
azt_speed_changed ( void * p )
{
2020-03-31 00:53:03 +02:00
azt2316a_t * azt2316a = ( azt2316a_t * ) p ;
2020-03-25 00:49:25 +01:00
2020-03-31 00:53:03 +02:00
ad1848_speed_changed ( & azt2316a - > ad1848 ) ;
sb_speed_changed ( azt2316a - > sb ) ;
2020-03-25 00:49:25 +01:00
}
static const device_config_t azt1605_config [ ] =
{
{
. name = " codec " ,
. description = " CODEC " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " CS4248 " ,
. value = AD1848_TYPE_CS4248
} ,
{
. description = " CS4231 " ,
. value = AD1848_TYPE_CS4231
} ,
} ,
. default_int = AD1848_TYPE_CS4248
} ,
{
. name = " wss_interrupt_after_config " ,
. description = " Raise CODEC interrupt on CODEC setup (needed by some drivers) " ,
. type = CONFIG_BINARY ,
. default_int = 0
} ,
{
2020-11-16 00:01:21 +01:00
" addr " , " SB Address " , CONFIG_HEX16 , " " , 0 , " " , { 0 } ,
2020-03-25 00:49:25 +01:00
{
{
" 0x220 " , 0x220
} ,
{
" 0x240 " , 0x240
} ,
{
" Use EEPROM setting " , 0
} ,
{
" "
}
}
} ,
{
. name = " sb_dma8 " ,
. description = " SB low DMA " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " DMA 0 " ,
. value = 0
} ,
{
. description = " DMA 1 " ,
. value = 1
} ,
{
. description = " DMA 3 " ,
. value = 3
} ,
{
. description = " "
}
} ,
. default_int = 1
} ,
2020-03-31 00:53:03 +02:00
{
. name = " wss_irq " ,
. description = " WSS IRQ " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " IRQ 11 " ,
. value = 11
} ,
{
. description = " IRQ 10 " ,
. value = 10
} ,
{
. description = " IRQ 7 " ,
. value = 7
} ,
{
. description = " "
}
} ,
. default_int = 10
} ,
{
. name = " wss_dma " ,
. description = " WSS DMA " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " DMA 0 " ,
. value = 0
} ,
{
. description = " DMA 1 " ,
. value = 1
} ,
{
. description = " DMA 3 " ,
. value = 3
} ,
{
. description = " "
}
} ,
. default_int = 0
} ,
2020-03-25 00:49:25 +01:00
{
" opl " , " Enable OPL " , CONFIG_BINARY , " " , 1
} ,
{
" receive_input " , " Receive input (SB MIDI) " , CONFIG_BINARY , " " , 1
} ,
{
" receive_input401 " , " Receive input (MPU-401) " , CONFIG_BINARY , " " , 0
} ,
{
" " , " " , - 1
}
} ;
static const device_config_t azt2316a_config [ ] =
{
{
. name = " codec " ,
. description = " CODEC " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " CS4248 " ,
. value = AD1848_TYPE_CS4248
} ,
{
. description = " CS4231 " ,
. value = AD1848_TYPE_CS4231
} ,
} ,
. default_int = AD1848_TYPE_CS4248
} ,
{
. name = " wss_interrupt_after_config " ,
. description = " Raise CODEC interrupt on CODEC setup (needed by some drivers) " ,
. type = CONFIG_BINARY ,
. default_int = 0
} ,
{
2020-11-16 00:01:21 +01:00
" addr " , " SB Address " , CONFIG_HEX16 , " " , 0 , " " , { 0 } ,
2020-03-25 00:49:25 +01:00
{
{
" 0x220 " , 0x220
} ,
{
" 0x240 " , 0x240
} ,
{
" Use EEPROM setting " , 0
} ,
{
" "
}
}
} ,
2020-03-31 00:53:03 +02:00
{
. name = " wss_irq " ,
. description = " WSS IRQ " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " IRQ 11 " ,
. value = 11
} ,
{
. description = " IRQ 10 " ,
. value = 10
} ,
{
. description = " IRQ 7 " ,
. value = 7
} ,
{
. description = " "
}
} ,
. default_int = 10
} ,
{
. name = " wss_dma " ,
. description = " WSS DMA " ,
. type = CONFIG_SELECTION ,
. selection =
{
{
. description = " DMA 0 " ,
. value = 0
} ,
{
. description = " DMA 1 " ,
. value = 1
} ,
{
. description = " DMA 3 " ,
. value = 3
} ,
{
. description = " "
}
} ,
. default_int = 0
} ,
2020-03-25 00:49:25 +01:00
{
" opl " , " Enable OPL " , CONFIG_BINARY , " " , 1
} ,
{
" receive_input " , " Receive input (SB MIDI) " , CONFIG_BINARY , " " , 1
} ,
{
" receive_input401 " , " Receive input (MPU-401) " , CONFIG_BINARY , " " , 0
} ,
{
" " , " " , - 1
}
} ;
const device_t azt2316a_device =
{
" Aztech Sound Galaxy Pro 16 AB (Washington) " ,
DEVICE_ISA | DEVICE_AT ,
SB_SUBTYPE_CLONE_AZT2316A_0X11 ,
2020-11-16 00:01:21 +01:00
azt_init , azt_close , NULL , { NULL } ,
2020-03-25 00:49:25 +01:00
azt_speed_changed ,
NULL ,
azt2316a_config
} ;
const device_t azt1605_device =
{
" Aztech Sound Galaxy Nova 16 Extra (Clinton) " ,
DEVICE_ISA | DEVICE_AT ,
SB_SUBTYPE_CLONE_AZT1605_0X0C ,
2020-11-16 00:01:21 +01:00
azt_init , azt_close , NULL , { NULL } ,
2020-03-25 00:49:25 +01:00
azt_speed_changed ,
NULL ,
azt1605_config
} ;