ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º º Sound System Source for your own productions (games&demos) º º º º coded and provided in 1994 by the Frontman of Crew242 !!! º º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ This Sound System Source package includes: SOUNDSYS.DOC This file USMOD.COM Gravis UltraSound module player, eg. USMOD CYBRNOID.MOD USMOD.ASM Gravis UltraSound player source SBMOD.COM SoundBlaster (Pro) module player, eg. SBMOD COMPLICA.MOD SBMOD.ASM SoundBlaster (Pro) player source SS.CFG Configuration file ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ What does this Sound System ? For Gravis UltraSound: - 4/6/8 channels Protracker/Fasttracker module playing - 5 channels for stereo FX - Extended MOD effects support (Panning Effect E8) - Mixing rate always 44100 Hz - Always stereo - Full 8/16-bit DMA support for sample upload (optional without) - Max 1 MB GUS memory for samples - 100% Assembler for high perfomance -> takes almost no cpu time - Player needs only 12 KB and max 64 KB for Patterns For SoundBlaster (Pro/or any SB compatibles): - 4/8 channels Protracker/Fasttracker module playing - 1/2 channels on SB/SBPro for FX - Full Protracker 2.1A effects support - Mixing rates 10000 - 22222 Hz - SBPro/SB16 stereo support - 544 KB EMS Support for FX - 100% Assembler for high perfomance -> takes only 10%-15% cpu time - Player needs only 10 KB and 24 KB for DMA buffers ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ Where from, why, what for ? This Sound System has actually been developed for FUTURE DIMENSION of Crew242, a new, commercial, neckbreaking shootem up game of the new generation. I decided to spread the Sound System as freeware (yes! the source is freeware) because I dont like adlib neither midi sounds very much. Modules for everyone. Anyway, modules produce the best sound and UltraSound is the best card for it. Use it in any manner for your productions. For major assimilations it is necessary to change the source, eg. you need an object instead of a com-file, you dont want to have a configuration file, etc. This source is written for Borland Tasm 3.1 and its Tlink /t option for COMs. ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º º All I want is a short credit in your production for the Sound System like: º º º º "Sound System by Frontman of Crew242" or "Sound System by Silvio Turello" º º º º I will also do that for the pioneers of module sound. Thanks goes to: º º º º Lars "Zap" Hamre for inventing the protracker de facto standard º º (Amiga Freelancers) º º º º Joshua C. Jensen for porting it to pc º º (Form. Renaissance) º º º º Serge Huber for giving me a hint, how to make a SB-player º º (Numerus/Imphobia) º º º º Robert Adolfsson for showing me, how to make a GUSPLAY (-er) º º (Robban/Cascada) º º º º Give always the complete package away ! º º º º If you want to be nice and you are allowed to give away a copy of your º º º º production, I would really appreciate to get a copy of it just because º º º º I am always interested in good sounding soft. I will of course respect º º º º any requests not to spread the copy you send me. It will be exclusively º º º º for the Frontman of Crew242. Refer to the address below: º º º º Silvio Turello, Giebeleichstr. 58, 8152 Glattbrugg, Switzerland º º º º Tel.: ++/1/810 70 96 Fax: ++/1/810 85 63 º º º º Email address until 1998: sturello@iiic.ethz.ch º º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ How ? Now it is time to give some technical details about the routines. The COM-format is quite unusual, but it has some important advantages, eg. you always now, what is going on, because you can load it in your own segment (at offset 100h) without relocating. the start address is 100h with a jump table for its functions. the functions can be reached with a far call to seg:104h, seg:108h, etc. Here is an example, how the routines are handled in FUTURE DIMENSION: PLAYER HAS ALREADY BEEN LOADED TO A SEGMENT WITH OFFSET 100H. THE SEGMENT POINTER IS STORED IN MUSIC_SEG. ;----------------------------------------------------------------------------- CALL CONFIG_INIT ;GET CONFIG ; OPTIONAL SETTINGS MOV AX,22222 ;SET MAXIMUM SAMPLERATE CALL SET_SAMPLERATE MOV AL,255 ;SET MAXIMUM VOLUME MOV BL,AL MOV BH,AL CALL SET_VOLUME ;----------------------------------------------------------------------------- ; INITIALIZING & STARTING MOV DX,OFFSET MOD_NAME ;FIRST, TRY LOADING CALL LOAD_MOD JNC SHORT GM1 MOV AH,9 MOV DX,OFFSET ERROR1_TEXT INT 21H JMP SHORT GM4 GM1: MOV DX,OFFSET SAMPLE_NAME ;GET SAMPLE MOV CL,80H ;PC-SAMPLE (00= AMIGA) CALL LOAD_SAMPLE JNC SHORT GM2 MOV AH,9 MOV DX,OFFSET ERROR2_TEXT INT 21H GM2: CALL PLAY_MUSIC ;TRY STARTING JNC SHORT GM3 MOV AH,9 MOV DX,OFFSET ERROR3_TEXT INT 21H JMP SHORT GM4 ;----------------------------------------------------------------------------- ; THIS COULD BE THE MAIN ROUTINE GM3: MOV AH,9 MOV DX,OFFSET OUT_TEXT INT 21H LM1: XOR AH,AH INT 16H CMP AL,27 JE SHORT GM5 CMP AL,"+" JNE SHORT G1 CALL GET_VOLUME INC AL CALL SET_VOLUME JMP LM1 G1: CMP AL,"-" JNE SHORT G2 CALL GET_VOLUME DEC AL CALL SET_VOLUME JMP LM1 G2: CMP AL,"9" JNE SHORT G3 MOV AL,0 CALL SET_SONGLOOP JMP LM1 G3: CMP AL,"0" JNE SHORT G4 CALL GET_SONGMOD INC AL CALL SET_SONGMOD JMP LM1 G4: CMP AL,"1" JNE LM1 MOV BX,0 ;HANDLE MOV CX,22222 ;FREQUENCE CALL PLAY_SAMPLE JMP LM1 ;----------------------------------------------------------------------------- ; CUTTING OFF GM5: CALL STOP_MUSIC ;STOP MUSIC GM4: CALL END_SAMPLE ;UNLOAD SAMPLES CALL END_MUSIC ;UNLOAD MUSIC ;----------------------------------------------------------------------------- FUNCTION LIBRARY: MUSIC_CALL DW 0 MUSIC_SEG DW 0 ;----------------------------------------------------------------------------- CONFIG_INIT: MOV BP,104H JMP NEXT_STEP LOAD_MOD: MOV BP,108H JMP NEXT_STEP PLAY_MUSIC: MOV BP,10CH JMP NEXT_STEP STOP_MUSIC: MOV BP,110H JMP NEXT_STEP END_MUSIC: MOV BP,114H JMP NEXT_STEP LOAD_SAMPLE: MOV BP,118H JMP NEXT_STEP PLAY_SAMPLE: MOV BP,11CH JMP NEXT_STEP END_SAMPLE: MOV BP,120H JMP NEXT_STEP SET_SAMPLERATE: ;SB ONLY MOV BP,124H JMP NEXT_STEP GET_VOLUME: MOV BP,128H JMP NEXT_STEP SET_VOLUME: MOV BP,12CH JMP NEXT_STEP SET_SONGLOOP: MOV BP,130H JMP NEXT_STEP GET_SONGPOSITION: MOV BP,134H JMP NEXT_STEP SET_SONGPOSITION: MOV BP,138H JMP NEXT_STEP GET_SONGMOD: MOV BP,13CH JMP NEXT_STEP SET_SONGMOD: MOV BP,140H JMP NEXT_STEP DSP_OFF: MOV BP,144H JMP NEXT_STEP DSP_RESET: MOV BP,148H JMP NEXT_STEP NEXT_STEP: MOV MUSIC_CALL,BP PUSHA PUSH DS CALL DWORD PTR DS:[MUSIC_CALL] POP DS POPA RET ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ It is handier to combine some functions to a logical group as below: proc start_music(x,y,z...) is the player already in memory? if not then load player and CALL CONFIG_INIT IF CARRY RETURNED IS 1 THEN ERROR load module x CALL LOAD_MOD DS:DX IS FILENAME IF CARRY RETURNED IS 1 THEN ERROR load optional FX samples y,z,... CALL LOAD_SAMPLE DS:DX IS FILENAME CL=80H PC SAMPLE, 00H AMIGA SAMPLE AX RETURNS A HANDLE (0,2,4,6,..) IF CARRY RETURNED IS 1 THEN ERROR set optional volume, songloop, samplerate, soundmod CALL GET_VOLUME \ AL=MASETR_VOLUME CALL SET_VOLUME / BL=MUSIC_VOL, BH=FX_VOL CALL SET_SONGLOOP AL=PATTERN ORDER, >127 IS NO LOOP CALL SET_SAMPLERATE AX=RATE 10000-22222 CALL GET_SONGMOD \ AL=0 MUSIC & FX CALL SET_SONGMOD / =1 MUSIC, =2 FX, =3 NOTHING start playing CALL PLAY_MUSIC IF CARRY RETURNED IS 1 THEN ERROR get or set optional current songposition (only valid if music is playing) CALL GET_SONGPOSITION \ AL=0..127 CALL SET_SONGPOSITION / end start_music proc quit_music stop playing It is no problem to restart again CALL STOP_MUSIC unload FX samples I do not recommend to reload fx samples CALL END_SAMPLE before unloading module unload module data CALL END_MUSIC end quit music now it is very easy to use: call start_music start optional FX CALL PLAY_SAMPLE BX= HANDLE, CX= FREQUENCY call quit_music call start_music call quit_music etc. kill player Do not forget to remove player segment ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ The players use a 1024 Hz interrupt generated by the timer or by the realtime clock. If it is the timer, you can enable or disable chaining of the old irq. Most options can be set in the SSS.CFG configuration file. The SoundBlaster player uses in this version 544 KB EMS for FX and only conventional memory to hold the whole module. It should be no problem to use EMS for the module data too. Both players (SB/SBPro and GUS) are very stable. That means, that they wont crash because of a wrong baseport, irq, dma, etc. It may happen that DMA stops after use of Playfile or some other players. In this case start ultrinit before using usmod. If you encounter problems, remember that the interface does never recover any registers especially es, ds segment registers because it is speed and memory optimized code. The players dont use the MOD patterns as internal format because of too many repetitions in channels. The loader splits up the patterns into tracks for each channel and generates instead of the pattern order table a track order table for each channel. That means, if a channel plays always the same like a drum channel, it needs just the memory of one track. It is similar to the MTM format. The differences between MOD and MTM's memory requirements for the same song can range from 20 to over 100 KB. The SB/SBPro player precalculates most periods to notes. Refer to the actual SB/SBPro loader for more details about the internal format. If you have some experience with assembler, you can change following parts very easily: - proc config_init sets all config variables. You can exchange it with a selfdetecting routine, a menu or a set variable - proc load_mod change the first lines to assimilate to your proc load_sample own filesystem - loader you can implement loader for your own format - interfaces no problem to assimilate - additional functions, eg. peeks for volume bars implement some additional functions to allow access to internal variables while playing. ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ Happy coding... Frontman of Crew242 ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ