Format of an XSD driver. An XSD driver is compiled as a single 32bit segment starting from offset ZERO and with the "XSD header" first. The init code will receive the "fixup" offset where the driver is loaded. Remember that any driver can access the "386Power internal vars" using the definitions contained into head32.inc When the XSD driver is loaded, 386Mixer has to "copy & convert to code32 relative offsets" all the offsets and values from the XSD device header to the "device table" (see XSD.TXT). Then it has to load the last configuration info (IRQ,BASE,DMA channel) into the device table. Then it has to "set" the current environment var value. At last it has to call _XSDInit to let the driver select the proper configuration. Then 386mixer has to check if _XSD_IRQ == 0 (timer driven sound system) and if this is true IT MUST HANDLE DIRECTLY the timer (using the 386timer module). So the "playback rate" has to be controlled directly by 386mixer by programming the timer. With "timer sound", the "sound interrupt" is actually a timer routine (_XSDTimed) called when the time count elapses. When _XSD_IRQ == 0 it is up to 386mixer to set up a "timer handler" and the appropriate timer rate to make sound (calling _XSDTimed when the timer interval elapses). If _XSD_IRQ is different from zero, it means it is up to _XSD_ON to set up an irq handler and "program" the appropriate playback rate. The reverse applies to _XSD_OFF (if _XSD_IRQ == 0 , it just has to "turn off" output, it will be up to the 386mixer to deinstall the timer handler). Offsets of "device entries" starting from the beginning of the driver data: __XSDSignature=0 there must be four bytes as follows: db 'XSD',0 This means XSD revision ZERO __XSDInit=4 ; driver-base relative pointer to the ; "hardware check" and system initialization code ; it will also initialize all data structures needed ; by the driver. ; IN: ebp=driver base offset (code32 relative) ; (use this to fix-up addresses) ; edi=XSD device table ; (code 32 relative offset ; of _XSDTable, from it you know ; where the other "XSD variables" are ; and where the sound channel descriptors are) ; OUT: ; If carry clear then OK ; else ; EAX=error code ; 0 = device not recognized ; 1 = not enough memory ; 2 = XSD device table contains ; wrong values ; N.B. ; Before calling this, the 386mixer module ; has to read the environment var ; with name pointed by _XSDEnvVar ; copy and convert it to code32 relative offset ; (the pointer name) into the XSD device table ; and then set the pointer to the "environment value" ; string. __XSDSetup=8 ; driver-base relative pointer to the ; sound system setup routine ; Simply set properly the values into the ; XSD device table (playback frequency, feed frequency ; active channels, types of emulation ; etc.etc.) ; and then call this. ; IN: none : OUT: XSD table set to the NEAREST supported values. ; all channels "preset" to silence. __XSDON=12 ; driver-base relative pointer to routine that ; turns on sound system (setting up IRQ handlers ; locking DMA channels, starting up transferts ; AND turning ON sound output). ; THIS ROUTINE will at least "set up" an IRQ handler ; to handle "end of DMA" from soundcard ; and calls to the _SOFTCHANNELIZER ; "mixer emulation" routine. __XSDOFF=16 ; driver-base relative pointer to routine that ; turns off sound system (turns off sound output ; disables DMA, unlocks DMA channel, restore IRQ handlers) ; the following entries may be not supported, it will be up to ; __XSDInit to set correctly the flags into _XSD_DRVTYPE (into XSD device table) ; to tell 386mixer what is supported and what's not __XSDMVol=20 ; driver-base relative pointer to ; MASTER VOLUME CONTROL routine ; this affects the output volume of all active channels ; ; actual_channel_volume = (chan_volume/255)*master_volume ; ; IN: al=channel volume (0..255) ; 0 = sound off ; 255 = maximum output ; ; The master volume can have a coarser granularity ; than sound channel volume ; (i.e. on a sound blaster Pro, master volume can range ; between 0..15 if you just use "output volume" ; but if you split master volume with ; the lower four bits controlling ; "voice volume" (0..15) ; and the higher four bits controlling ; "output volume" (0..15) ; you can get the "complete" 0..255 range. ; these entries are specific of "wavetable" soundcards ; (flag xsd_wavedriver set) __XSDPlay=24 ; driver-base relative pointer to routine that ; plays a sound sample ; IN: esi= ptr to the sound channel descriptor ; describing what to play and HOW to play it __XSDVol=28 ; driver-base relative pointer to routine that ; sets volume level/ramp only ; IN: esi= ptr to the sound channel descriptor ; describing what to play and HOW to play it __XSDPan=32 ; driver-base relative pointer to routine that ; sets panning level/ramp only ; IN: esi= ptr to the sound channel descriptor ; describing what to play and HOW to play it __XSDRate=36 ; driver-base relative pointer to routine that ; sets playback rate ratio (relative to playback freq) ; level/ramp only ; IN: esi= ptr to the sound channel descriptor ; describing what to play and HOW to play it __XSDEnvVar=40 ; driver-base relative pointer to ASCIIZ string ; with the name of the MS-DOS ENVIROMENT VAR ; to check for config info ;(for a sound blaster it is "BLASTER",0 ) __XSDMenu=44 ; driver-base relative pointer to ; User driven "driver setup" menu for custom configuration ; ("executing" this menu results in interactive calls to ; __XSDSetup subroutines) __XSDCardType=48 ; driver-base relative pointer to ASCIIZ string ; max. 30 character long ; (use this in the "choose driver" list) __XSDProgrammer=52 ; driver-base relative pointer to ASCIIZ string ; with multiple lines of text,max. 40 char each ; (use the LF char (code 10h) to mark newlines) ; (extended info on driver) __XSDNotes=56 ; driver-base relative pointer to ASCIIZ string ; with multiple lines of text,max. 40 char each ; (use the LF char (code 10h) to mark newlines) ; of notes about the driver usage and supperted display ; cards. (detailed info) __XSDWClear=60 ; driver-base relative pointer to routine that ; "resets" wavetable ram to "all free" __XSDWMark=64 ; driver-base relative pointer to routine that ; "marks" currently used wavetable ram ; OUT: eax= mark handle __XSDWRelease=68 ; driver-base relative pointer to routine that ; releases wavetable ram from the higher "currently in use" ; location down to the "marked" position ; IN: eax= mark handle that will be the new ; "currently in use" limit __XSDWUpLoad=72 ; driver-base relative pointer to routine that ; "loads" into wavetable ram a sound sample ; and returns info about it in "soundcard specific" ; units. ; IN: eax= sample size in dwords ; edx= sample data ptr ; OUT: ; IF carry clear THEN ; eax= "internal" sample size count ; edx= "internal" sample data ptr ; ELSE ; carry set, not enough wavetable ram ; END-IF __XSDTimed=76 ; driver-base relative pointer to routine ; called by 386timer to "emulate a sound irq" ; for sound hardware without irq support ; (i.e. the pc-speaker) ; such drivers set _XSD_IRQ to zero ; to tell the mixer it MUST call _XSDTimed ; to produce sound. Appendix: Some further explanations about the XSD interface: Into XGE you will never see XSD if you don't want to, the only thing you have to do is select the driver, the initialization code will load it and let it self-initialize, is you want to make a cool setup program you can include a "self configure" option (by checking the environment value or going diectly to hardware or bios) but ALWAYS include a "user driven configuration" option. If everything else fails, try to call me on the following internet addresses knight@maya.dei.unipd.it but keep in mind that for most of 1995 i will be in the army (mandatory militar service here in Italy) so i won't access frequently (AND IT MAY ALSO EXPIRE!!!) my internet account on the Engineering Department at Padova. My plain mail address is at the end of tech.txt. Ciao, Lorenzo Micheletto knight@maya.dei.unipd.it N.B. If you want to extend the capabilities of the XVD drivers (new functions, etc, etc) set up a portable interface (not a thing good for your graphic card only) and call it 'XSD1' and so on, but before doing this look into x2ftp.oulu.fi to see if someone else did it before you, check if the already published release is good enough, if not, publish yours with a successive number (i.e. XSD2, XSD3, etc. etc.).