home *** CD-ROM | disk | FTP | other *** search
- ********************************************************************************
- OS/2 device driver interface to the Gravis Ultrasound family of soundcards
- 24-8-1995
- Written by Sander van Leeuwen
- email: s509475@dutiws.twi.tudelft.nl
- ********************************************************************************
- This document is meant for programmers looking for an easy way to directly
- access the Gravis Ultrasound hardware, without developing their own device
- driver. MMPM/2 is good for writing multimedia applications, but it's not
- really suitable for writing modplayers or trackers (and probably some other
- software too) for wavetable soundcards.
-
- I've developed a device driver, that offers a subset of the routines
- available in the GUS SDK, to support my OS/2 modplayer UltiMOD.
- After UltiMOD was released to the public a few months ago, Robert Manley
- (the author of the GUS MMPM/2 drivers) and I joined forces to release one
- driver that provides both MMPM/2 support and a special MOD engine for my
- player.
- This driver (version 0.7a) was released about three months ago.
- I've added a few more routines in the driver so you should have enough to
- write (or port) your own player or tracker.
- The next section is a short introduction to programming the driver interface.
- I'm not going into too much detail, because the most calls were ported from
- the original GUS SDK. If you don't know what the calls do, just look them up
- in the docs that come with the Gravis SDK.
- There are a few extra calls, because OS/2 isn't quite like DOS. 8)
-
- ********************************************************************************
- Source Code
- ********************************************************************************
- This package contains:
- - struct.h typedefs of structures needed to communicate with the
- device driver
- - ultradev.h definitions of all the provided routines
- - ultradev.c source for communication with the driver
- - readme.doc this file
- This code compiles without errors using Watcom C/C++ v10. It will probably work
- with the other major OS/2 compilers (IBM CSet and Borland C++) as I see no
- reason why it shouldn't.
-
- IMPORTANT NOTE: To compile ultradev.c you should enable structure packing.
- (not for your entire app, just for ultradev.c)
- ********************************************************************************
- Opening and closing the MMPM/2 Driver.
- ********************************************************************************
- The code below is pretty clear. You need to call UltraGetAccess in order to
- prevent any other applications (OS/2, Windows or dos) to use the driver.
- This call return a value (> 0) when for some reason you didn't get exclusive
- access to the device driver.
-
- int InitDevice()
- {
- APIRET status;
- ULONG action;
-
- status = DosOpen( "ULTRA1$", &GUSHandle, &action, 0,
- FILE_NORMAL, FILE_OPEN,
- OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_WRITE_THROUGH,
- NULL );
- if(status) return(FALSE);
- if(UltraGetAccess()) {
- DosClose(GUSHandle);
- return(FALSE); //not only owner
- }
- }
- To check whether or not the user is running the right version of the driver
- use the following call:
- APIRET UltraGetDriverVersion(int *version)
- On return, the high word of version will contains the major version, the low
- word the minor version of the driver.
- This API is only implemented in v0.8 (and will be supported in future releases),
- so with older drivers, DosDevIOCTl will return 31 (ERR_GEN_FAILURE).
-
- To close the driver:
- UltraReleaseAccess(); //gives other programs access to the GUS
- DosClose(GUSHandle);
-
- ********************************************************************************
- Original Gravis SDK calls.
- ********************************************************************************
- The following procdures work exactly as described in Gravis' GUS SDK:
- The calls use different return values though:
- - 0 success
- - > 0 error (returned by DosDevIOCtl)
-
- - UltraSetNVoices
- - UltraEnableOutput
- - UltraDisableOutput
- - UltraMemInit
- - UltraMemAlloc
- - UltraMemFree
- - UltraSizeDram
- - UltraStartTimer
- - UltraStopTimer
- - UltraStartVoice
- - UltraStopVoice
- - UltraSetBalance
- - UltraSetFrequency
- - UltraVectorLinearVolume
- - UltraDownload
-
- The Peek/Poke calls aren't exactly the same as their SDK equivalents.
- There's no need to specify the Ultrasound's baseport.
- APIRET UltraPokeData(long, int);
- - UltraPokeData
-
- UltraPeekData expects (a pointer to) the address, from which you wish to
- read data, as a parameter. It returns this data in this parameter.
- APIRET UltraPeekData(int *);
- - UltraPeekData
-
- You don't need to call UltraMemInit when initializing the GUS. This call
- is just an easy way to release all reserved memory.
- ********************************************************************************
- Writing a multithreaded player
- ********************************************************************************
- When programming for OS/2 you should put time consuming task in a separate
- thread, so it's a good idea to do this for your plackback procedure(s).
- Use DosSetPriority to give the thread the highest priority. (to make sure the
- music will be played smoothly)
- OS/2 isn't a realtime system, so your thread might not always get a time slice
- in time. (especially when the system load is quite high)
-
- In OS/2 ring 3 applications cannot change the interrupt vector table, so you
- need the next solution:
- DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 31, 0);
-
- while(!Fatal) //StopPlaying changes Fatal to TRUE
- {
- UltraBlockTimerHandler1();
- DoYourStuff(); //proccess song data
- .....Update the voices (vol, freq, balance)
- } //while
- To start playing you start timer 1 (UltraStartTimer).
- UltraBlockTimerHandler1 blocks the thread until timer 1 on the GUS produces an
- interrupt. (UltraBlockTimerHandler2 does the same, but for timer 2)
-
- UltraUnBlockAll unblocks the blocked threads, so they can return to your code.
- You SHOULDN'T use DosKillThread to kill a thread that's blocked in the driver.
- This doesn't work and will cause your program to hang. Once it's hung, you
- can't kill it.
- If you application crashes, it can occur that the thread(s) will stay stuck in-
- side the driver.
- OS/2 should unblock threads blocked in a driver, when the application crashes,
- but most of the time this doesn't work. Don't ask me why.
- A solution for this is to set an exception handler that unblocks the play
- thread whenever something bad happens (div/0, protection violation etc)
- (this is very easy, just look it up in the online OS/2 API reference)
-
- UltraSetAll is a way to update the balance, frequency & volume settings for a
- voice in one DevIOCTL call. When you need to update these three settings for
- a voice, this call saves a lot of time.
-
- ********************************************************************************
- ********************************************************************************
- As you might have noticed I've removed a few of the DevIOCTL calls in
- ultradev.c.
- I use these in my modplayer to improve the efficiency. These routines are very
- dependant on my channel structures and overal program structure so they aren't
- usefull to you.
- You shouldn't call them though. At least two of them will crash you computer.
- (trap D in the driver) Don't tell me I didn't warn you.
-
- If you have any suggestions, bug reports or questions, feel free to mail me.
- I'd also appreciate mails from people using it, so I can decide whether it's
- useful to continue enhancing the interface.
-
- Enjoy your programming adventure in the world of REAL operating systems.
-
- Sander van Leeuwen
- email: s509475@dutiws.twi.tudelft.nl
-
- ********************************************************************************
- Standard Disclaimer
- ********************************************************************************
- This code is provided as is. The author (Sander van Leeuwen) isn't responsible
- for any damage that may result from using this code.
- So don't mail me with claims about damaged ears/stereo's or crashed computers.
- ********************************************************************************
- ********************************************************************************
-
-