home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 21
/
CD_ASCQ_21_040595.iso
/
dos
/
prg
/
c
/
soundss3
/
usmod.asm
< prev
next >
Wrap
Assembly Source File
|
1995-02-10
|
70KB
|
3,249 lines
;
; ╔═════════════════════════════╗
; ║ ║
TITLE ║ GRAVIS ULTRASOUND MODPLAYER ║
; ║ ║
; ╚═════════════════════════════╝
;
; THIS MODULE PLAYER WAS CODED IN EARLY 1994
;
; BY SILVIO TURELLO (FRONTMAN/CREW242)
;
; IT IS A COMPLETELY REVISED VERSION OF GUSPLAY 1.5
;
; BY ROBERT ADOLFSSON (CASCADA)
;
; FEATURES: 4/6/8-CHANNEL-MODS (M.K./FLT4/FLT8/OCTA/8CHN/6CHN)
;
; 16-FX-CHANNELS, FULL MOD-FX SUPPORT, FULL 8/16-BIT DMA SUPPORT
;
; 1 MB GUS SUPPORT, PANNING COMMAND E8x, OF COURSE VERY FAST
;
; MEMORY: 13K CODE, 0-64K TRACKBUF
;
.ALPHA
.MODEL MEDIUM
COM_OR_OBJ = 0
STACKLENGTH = 0100H
UGROUP4 GROUP CODE_SEG4, DATA_SEG4
ASSUME CS:UGROUP4, DS:UGROUP4, SS:UGROUP4
;=============================================================================
IRQ1 = 20H
IRQ2 = 21H
IRQ3 =0A0H
IRQ4 =0A1H
TIMER0 = 40H
PIT1 = 43H
UHR_INDEX = 70H
UHR_PORT = 71H
UHR_STATA = 0AH
UHR_STATB = 0BH
UHR_STATC = 0CH
;-----------------------------------------------------------------------------
NumVoices = 25 ; Number of voices to use
StatusPort = 6h ; UltraSound Ports
TimerCtrlPort = 8h
TimerDataPort = 9h
DMASetPort = 0Bh
MidiCtrlPort = 100h
MidiDataPort = 101h
ActiveVoicePort = 102h
CommandPort = 103h
DataLowPort = 104h
DataHighPort = 105h
DRAMIOPort = 107h
GUS_VERSION = 506h
ICMIX_SEL = 506h
ICMIX_DATA = 106h
CODEC_BASE = 10Ch
WriteVoiceMode = 00h ; UltraSound Commands
SetVoiceFreq = 01h ; Value=Freq/Divisor
LoopStartLo = 02h
LoopStartHi = 03h
SampleEndLo = 04h
SampleEndHi = 05h
VolRampRate = 06h
VolRampStart = 07h
VolRampEnd = 08h
SetVolume = 09h
SampleStartLo = 0Ah
SampleStartHi = 0Bh
VoiceBalance = 0Ch
VolumeCtrl = 0Dh
VoicesActive = 0Eh
DMACtrl = 41h
DMAAddr = 42h
DRAMAddrLo = 43h
DRAMAddrHi = 44h
Initialize = 4Ch
ReadVolume = 89h
VoicePosLo = 8Ah
VoicePosHi = 8Bh
ReadVolCtrl = 8Dh
Voices14 = 4300 ; Divisors
Voices15 = 4000
Voices16 = 3700
Voices17 = 3500
Voices18 = 3300
Voices19 = 3100
Voices20 = 3030
Voices21 = 2800
Voices22 = 2700
Voices23 = 2600
Voices24 = 2500
Voices25 = 2400
Voices26 = 2300
Voices27 = 2200
Voices28 = 2100
Voices29 = 2000
Voices30 = 2000
Voices31 = 1900
Voices32 = 1800
;-----------------------------------------------------------------------------
CHAN_SIZE = 52
CHAN_INFO STRUC
SAMP_OFF DD 0
FREQ_VAL DW 0
VOL DW 0
OLD_VOL DW 0
FINE DW 0
REPEAT DW 0
REPLEN DW 0
LEN DW 0
AMIGA DW 0
EFFECT DW 0
VIBRATO_POINT DW 0
OLD_VIBRATO DW 0
PORT_TO DW 0
OLD_PORT_TO DW 0
EFFECT_TIME DW 0
CURR_SAMP DW 0
OLD_SAMP DW 0
ARP DW 0,0,0
ARP_COUNTER DW 0
INST_SET DB 0
BALANCE DB 0
LOOP_ONOFF DW 0
OFFSET_ADD DW 0
TRACK_OFF DW 0
CHAN_INFO ENDS
;=============================================================================
DATA_SEG4 SEGMENT WORD USE16
;=============================================================================
PROG_START_SEG DW 0
PROG_END_SEG DW 0
IF COM_OR_OBJ
VAR_BUFSEG DW 0
ELSE
VAR_BUFSEG DW 8000H
ENDIF
GDDLENGTH DD 0
GDDREST DW 0
GDDHANDLE DW 0
GDDSEG DW 0
BUFSEG DW 0
GDDZEIG DB 0
SAM_CH DB 8
MOD_STAT DB 0
US_MODUS DB 0 ;0=MUSIC&FX, 1=MUSIC, 2=FX, 3=OFF
CD_MIXER DB 0 ;0=MODULES ONLY, 1=CD MIXED
LOADMOD_FLAG DB 0
SYSTEM DB 0
IRQCOUNT DB 56
COMP_SPEED2 DW 0106H
COMP_SPEED3 DW 4006H
COMP_SPEED4 DW 0
COMP_SPEED5 DW 1165
HOLD70 LABEL DWORD
DW OFFSET CONTROL_CHANNELS, 0
PAN_REGS DB 3,12,12,3,3,12,12,3
DB 2,13,2,13,2,13,2,13
DB 2,13,2,13,2,13,2,13
DB 2,13,2,13,2,13,2,13
PAN_FX DB 0
SONG_START DB 0
MOD_NAME DB 88 DUP(0)
;-----------------------------------------------------------------------------
ERROR1_TEXT DB "MOD ERROR",13,10,"$"
ERROR2_TEXT DB "FX ERROR",13,10,"$"
OUT_TEXT DB "+/- VOLUME",13,10
DB "1 PLAY SAMPLE",13,10
DB "9 INIT REPEAT",13,10
DB "0 MUSIC MODE",13,10,"$"
SAMPLE_NAME DB "SAMPLE1.SAM",0
CONFIG_NAME DB "SS3.CFG",0
CFG_TEXT2 DB "DEFAULT MUSIC MODE = ",0
CFG_TEXT3 DB "SOUNDCARD BASE PORT = ",0
CFG_TEXT5 DB "SOUNDCARD DMA NUMBER = ",0
CFG_TEXT7 DB "SYSTEM COMPATIBILITY = ",0
DMA_ADR DB 0,2,4,6,0C0H,0C4H,0C8H,0CCH
DMA_CNT DB 1,3,5,7,0C2H,0C6H,0CAH,0CEH
DMA_PAGE DB 87H,83H,81H,82H,8FH,8BH,89H,8AH
DMA_STAT DB 08H,08H,08H,08H,0D0H,0D0H,0D0H,0D0H
DMA_BITS DB 1,2,4,8,1,2,4,8
DMA_MASK DB 0AH,0AH,0AH,0AH,0D4H,0D4H,0D4H,0D4H
DMA_MOD DB 0BH,0BH,0BH,0BH,0D6H,0D6H,0D6H,0D6H
DMA_FLIP DB 0CH,0CH,0CH,0CH,0D8H,0D8H,0D8H,0D8H
DMA_RESET DB 0DH,0DH,0DH,0DH,0DAH,0DAH,0DAH,0DAH
DMA_SET_DATA DB 0,1,0,2,0,3,4,5
;-----------------------------------------------------------------------------
; PROTRACKER VARIABLEN
;-----------------------------------------------------------------------------
ALIGN 2
ULTRA16 DW 0
CODEC_PORT DW 32CH
BASE_PORT DW 220H
DMA_CHANNEL DW 1 ;DMA 0 IS NO DMA BYTE-PUSHING
MASTER_VOLUME DW 255
MUSIC_VOLUME DW 255
FX_VOLUME DW 255
MUSIC_VOL DW 255
FX_VOL DW 255
BPM_RATE DW 1024
BPM_VALUE DW 125
BPM_COUNT DD 0
BPM_SPEED DD 0
COUNTER DW 0
CH_NUMB DW 4
PATT_SPEED DW 0
PATT_COUNT DW 0
PATT_ROW DW 0
PATT_CURRENT DW 0
PATT_BREAK DW 0
;-----------------------------------------------------------------------------
; MTM - TRACKSTRUKTUR
;-----------------------------------------------------------------------------
ALIGN 2
TRACK_NUMBER DW 0
TRACK_INFO DB 8 DUP(0)
TRACK_SEG DW 0
TRACKS_OFFSET DW OFFSET TRACK1_DATA, OFFSET TRACK2_DATA, OFFSET TRACK3_DATA
DW OFFSET TRACK4_DATA, OFFSET TRACK5_DATA, OFFSET TRACK6_DATA
DW OFFSET TRACK7_DATA, OFFSET TRACK8_DATA
TRACK1_DATA DB 128 DUP(0)
TRACK2_DATA DB 128 DUP(0)
TRACK3_DATA DB 128 DUP(0)
TRACK4_DATA DB 128 DUP(0)
TRACK5_DATA DB 128 DUP(0)
TRACK6_DATA DB 128 DUP(0)
TRACK7_DATA DB 128 DUP(0)
TRACK8_DATA DB 128 DUP(0)
;-----------------------------------------------------------------------------
; MOD - DATEISTRUKTUR
;-----------------------------------------------------------------------------
ALIGN 2
PATTERN_SIZE DW 0
PATTERN_SEG DW 0
PATTERN_NUMBER DW 0
IOFFSET DD 31 DUP(0)
ISIZE DW 31 DUP(0)
IVOLUME DW 31 DUP(0)
IFINETUNE DW 31 DUP(0)
ILOOP_START DW 31 DUP(0)
ILOOP_SIZE DW 31 DUP(0)
SONG_SIZE DB 0
SONG_LOOP DB 0
;-----------------------------------------------------------------------------
; PLAYER - KONTROLLSTRUKTUREN
;-----------------------------------------------------------------------------
ALIGN 2
SONG_DATA LABEL BYTE
FREQ_TABLE DW 780 DUP(0) ;908
QUEUE_BUFFER DW 128 DUP(0)
SAMP_CHANS CHAN_INFO 8 DUP(<>)
SAMPLE_CHAN CHAN_INFO <>
;-----------------------------------------------------------------------------
; SINGLE SAMPLE VARIABLES
;-----------------------------------------------------------------------------
GUS_MEM DD 0
SAMPLE_ZEIG DW 0
SAMPLE_MEM DD 64 DUP(0)
SAMPLE_BIG DW 64 DUP(0)
SAM_COUNT DW 32 DUP(0)
;-----------------------------------------------------------------------------
ALIGN 2
PattJumps DW OFFSET ARPeggioFix ; 0
DW OFFSET NoPattEFFECT ; 1
DW OFFSET NoPattEFFECT ; 2
DW OFFSET PORT_TOFix ; 3
DW OFFSET VibratoFix ; 4
DW OFFSET NoPattEFFECT ; 5
DW OFFSET NoPattEFFECT ; 6
DW OFFSET NoPattEFFECT ; 7
DW OFFSET NoPattEFFECT ; 8
DW OFFSET SampleOff ; 9
DW OFFSET NoPattEFFECT ; A
DW OFFSET PosJump ; B
DW OFFSET VOLume ; C
DW OFFSET BreakPatt ; D
DW OFFSET NoPattEFFECT ; E
DW OFFSET SpeedSet ; F
EPattJumps DW OFFSET NoPattEFFECT ; 0
DW OFFSET FINEPortUp ; 1
DW OFFSET FINEPortDown ; 2
DW OFFSET NoPattEFFECT ; 3
DW OFFSET NoPattEFFECT ; 4
DW OFFSET NoPattEFFECT ; 5
DW OFFSET NoPattEFFECT ; 6
DW OFFSET NoPattEFFECT ; 7
DW OFFSET PANNING ; 8
DW OFFSET NoPattEFFECT ; 9
DW OFFSET FINEVOLUP ; A
DW OFFSET FINEVOLDown ; B
DW OFFSET NoPattEFFECT ; C
DW OFFSET NoPattEFFECT ; D
DW OFFSET NoPattEFFECT ; E
DW OFFSET NoPattEFFECT ; F
EFFECTJumps DW OFFSET ARPeggio ; 0
DW OFFSET PortUp ; 1
DW OFFSET PortDown ; 2
DW OFFSET PORT_TOTone ; 3
DW OFFSET Vibrato ; 4
DW OFFSET PORT_TOVSlide ; 5
DW OFFSET VibratoVSlide ; 6
DW OFFSET NoEFFECT ; 7
DW OFFSET NoEFFECT ; 8
DW OFFSET NoEFFECT ; 9
DW OFFSET VOLSlide ; A
DW OFFSET NoEFFECT ; B
DW OFFSET NoEFFECT ; C
DW OFFSET NoEFFECT ; D
DW OFFSET NoEFFECT ; E
DW OFFSET NoEFFECT ; F
EEFFECTJumps DW OFFSET NoEFFECT ; 0
DW OFFSET NoEFFECT ; 1
DW OFFSET NoEFFECT ; 2
DW OFFSET NoEFFECT ; 3
DW OFFSET NoEFFECT ; 4
DW OFFSET NoEFFECT ; 5
DW OFFSET NoEFFECT ; 6
DW OFFSET NoEFFECT ; 7
DW OFFSET NoEFFECT ; 8
DW OFFSET RetrigNote ; 9
DW OFFSET NoEFFECT ; A
DW OFFSET NoEFFECT ; B
DW OFFSET CutNote ; C
DW OFFSET DelayNote ; D
DW OFFSET NoEFFECT ; E
DW OFFSET NoEFFECT ; F
SIN_TAB DB 0,25,50,74,98,120,142,162,180,197,212,225,236
DB 244,250,254,255,254,250,244,236,225,212,197,180
DB 162,142,120,98,74,50,25
PERIOD_TABLE LABEL WORD
DW 856,808,762,720,678,640,604,570,538,508,480,453 ;C-1 to H-1 Finetune +0.
DW 428,404,381,360,339,320,302,285,269,254,240,226 ;C-2 to H-2 Finetune +0.
DW 214,202,190,180,170,160,151,143,135,127,120,113 ;C-3 to H-3 Finetune +0.
DW 107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56 ;C-4 to H-4 Finetune +0.
DW 850,802,757,715,674,637,601,567,535,505,477,450 ;C-1 to H-1 Finetune +1.
DW 425,401,379,357,337,318,300,284,268,253,239,225 ;C-2 to H-2 Finetune +1.
DW 213,201,189,179,169,159,150,142,134,126,119,113 ;C-3 to H-3 Finetune +1.
DW 106,100, 94, 89, 84, 79, 75, 71, 67, 83, 59, 56 ;C-4 to H-4 Finetune +1.
DW 844,796,752,709,670,632,597,563,532,502,474,447 ;C-1 to H-1 Finetune +2.
DW 422,398,376,355,335,316,298,282,266,251,237,224 ;C-2 to H-2 Finetune +2.
DW 211,199,188,177,167,158,149,141,133,125,118,112 ;C-3 to H-3 Finetune +2.
DW 105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59, 56 ;C-4 to H-4 Finetune +2.
DW 838,791,746,704,665,628,592,559,528,498,470,444 ;C-1 to H-1 Finetune +3.
DW 419,395,373,352,332,314,296,280,264,249,235,222 ;C-2 to H-2 Finetune +3.
DW 209,198,187,176,166,157,148,140,132,125,118,111 ;C-3 to H-3 Finetune +3.
DW 104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59, 55 ;C-4 to H-4 Finetune +3.
DW 832,785,741,699,660,623,588,555,524,495,467,441 ;C-1 to H-1 Finetune +4.
DW 416,392,370,350,330,312,294,278,262,247,233,220 ;C-2 to H-2 Finetune +4.
DW 208,196,185,175,165,156,147,139,131,124,117,110 ;C-3 to H-3 Finetune +4.
DW 104, 98, 92, 87, 82, 78, 73, 69, 65, 62, 58, 55 ;C-4 to H-4 Finetune +4.
DW 826,779,736,694,655,619,584,551,520,491,463,437 ;C-1 to H-1 Finetune +5.
DW 413,390,368,347,328,309,292,276,260,245,232,219 ;C-2 to H-2 Finetune +5.
DW 206,195,184,174,164,155,146,138,130,123,116,109 ;C-3 to H-3 Finetune +5.
DW 103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58, 54 ;C-4 to H-4 Finetune +5.
DW 820,774,730,689,651,614,580,547,516,487,460,434 ;C-1 to H-1 Finetune +6.
DW 410,387,365,345,325,307,290,274,258,244,230,217 ;C-2 to H-2 Finetune +6.
DW 205,193,183,172,163,154,145,137,129,122,115,109 ;C-3 to H-3 Finetune +6.
DW 102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57, 54 ;C-4 to H-4 Finetune +6.
DW 814,768,725,684,646,610,575,543,513,484,457,431 ;C-1 to H-1 Finetune +7.
DW 407,384,363,342,323,305,288,272,256,242,228,216 ;C-2 to H-2 Finetune +7.
DW 204,192,181,171,161,152,144,136,128,121,114,108 ;C-3 to H-3 Finetune +7.
DW 102, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57, 54 ;C-4 to H-4 Finetune +7.
DW 907,856,808,762,720,678,640,604,570,538,504,480 ;C-1 to H-1 Finetune -8.
DW 453,428,404,381,360,339,320,302,285,269,254,240 ;C-2 to H-2 Finetune -8.
DW 226,214,202,190,180,170,160,151,143,135,127,120 ;C-3 to H-3 Finetune -8.
DW 113,107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60 ;C-4 to H-4 Finetune -8.
DW 900,850,802,757,715,675,636,601,567,535,505,477 ;C-1 to H-1 Finetune -7.
DW 450,425,401,379,357,337,318,300,284,268,253,238 ;C-2 to H-2 Finetune -7.
DW 225,212,200,189,179,169,159,150,142,134,126,119 ;C-3 to H-3 Finetune -7.
DW 112,106,100, 94, 89, 84, 79, 75, 71, 67, 63, 59 ;C-4 to H-4 Finetune -7.
DW 894,844,796,752,709,670,632,597,563,532,502,474 ;C-1 to H-1 Finetune -6.
DW 447,422,398,376,355,335,316,298,282,266,251,237 ;C-2 to H-2 Finetune -6.
DW 223,211,199,188,177,167,158,149,141,133,125,118 ;C-3 to H-3 Finetune -6.
DW 111,105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -6.
DW 887,838,791,746,704,665,628,592,559,528,498,470 ;C-1 to H-1 Finetune -5.
DW 444,419,395,373,352,332,314,296,280,264,249,235 ;C-2 to H-2 Finetune -5.
DW 222,209,198,187,176,166,157,148,140,132,125,118 ;C-3 to H-3 Finetune -5.
DW 111,104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -5.
DW 881,832,785,741,699,660,623,588,555,524,494,467 ;C-1 to H-1 Finetune -4.
DW 441,416,392,370,350,330,312,294,278,262,247,233 ;C-2 to H-2 Finetune -4.
DW 220,208,196,185,175,165,156,147,139,131,123,117 ;C-3 to H-3 Finetune -4.
DW 110,104, 98, 92, 87, 82, 78, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -4.
DW 875,826,779,736,694,655,619,584,551,520,491,463 ;C-1 to H-1 Finetune -3.
DW 437,413,390,368,347,338,309,292,276,260,245,232 ;C-2 to H-2 Finetune -3.
DW 219,206,195,184,174,164,155,146,138,130,123,116 ;C-3 to H-3 Finetune -3.
DW 109,103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -3.
DW 868,820,774,730,689,651,614,580,547,516,487,460 ;C-1 to H-1 Finetune -2.
DW 434,410,387,365,345,325,307,290,274,258,244,230 ;C-2 to H-2 Finetune -2.
DW 217,205,193,183,172,163,154,145,137,129,122,115 ;C-3 to H-3 Finetune -2.
DW 108,102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57 ;C-4 to H-4 Finetune -2.
DW 862,814,768,725,684,646,610,575,543,513,484,457 ;C-1 to H-1 Finetune -1.
DW 431,407,384,363,342,323,305,288,272,256,242,228 ;C-2 to H-2 Finetune -1.
DW 216,203,192,181,171,161,152,144,136,128,121,114 ;C-3 to H-3 Finetune -1.
DW 108,101, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57 ;C-4 to H-4 Finetune -1.
GUS_VOL DW 01000H,08FF0H,09FF0H,0A800H,0AFF0H,0B400H,0B800H,0BC00H
DW 0BFF0H,0C200H,0C400H,0C600H,0C800H,0CA00H,0CC00H,0CE00H
DW 0CFF0H,0D100H,0D200H,0D300H,0D400H,0D500H,0D600H,0D700H
DW 0D800H,0D900H,0DA00H,0DB00H,0DC00H,0DD00H,0DE00H,0DF00H
DW 0DFF0H,0E080H,0E100H,0E180H,0E200H,0E280H,0E300H,0E380H
DW 0E400H,0E480H,0E500H,0E580H,0E600H,0E680H,0E700H,0E780H
DW 0E800H,0E880H,0E900H,0E980H,0EA00H,0EA80H,0EB00H,0EB80H
DW 0EC00H,0EC80H,0ED00H,0ED80H,0EE00H,0EE80H,0EF00H,0EF80H
DW 0F800H ;SINGLE SAMPLE MAX VOL > SONG MAX VOL
;-----------------------------------------------------------------------------
PROG_END LABEL BYTE ;MUSS LETZE ZEILE IM DATENSEGMENT SEIN!
;-----------------------------------------------------------------------------
DATA_SEG4 ENDS
.386
CODE_SEG4 SEGMENT PAGE USE16
ORG 100H
;=============================================================================
PUBLIC _MAIN4
_MAIN4 PROC FAR
JMP MAIN_CONT ;0100
RETF
CALL CONFIG_INIT ;0104
RETF
CALL LOAD_MOD ;0108
RETF
CALL PLAY_MUSIC ;010C
RETF
CALL STOP_MUSIC ;0110
RETF
CALL END_MUSIC ;0114
RETF
CALL LOAD_SAMPLE ;0118
RETF
CALL PLAY_SAMPLE ;011C
RETF
CALL END_SAMPLE ;0120
RETF
JMP NOFUNC ;0124
NOFUNC: RETF
CALL GET_VOLUME ;0128
RETF
CALL SET_VOLUME ;012C
RETF
CALL SET_SONGLOOP ;0130
RETF
CALL GET_SONGPOSITION ;0134
RETF
CALL SET_SONGPOSITION ;0138
RETF
CALL GET_SONGMOD ;013C
RETF
CALL SET_SONGMOD ;0140
RETF
CALL US_OFF ;0144
RETF
CALL INIT_DEVICE ;0148
RETF
_MAIN4 ENDP
;=============================================================================
;=============================================================================
ALIGN 2
CONTROL_CHANNELS PROC NEAR
PUSH EAX EBX ECX EDX ESI EDI EBP
PUSH DS ES CS
POP DS
CMP SYSTEM,0
JNE SHORT WT6
MOV AL,UHR_STATC
OUT UHR_INDEX,AL
JMP SHORT WT1
WT1: JMP SHORT WT2
WT2: IN AL,UHR_PORT
WT6: MOV AL,20H
OUT IRQ3,AL
OUT IRQ1,AL
STI
CMP LOADMOD_FLAG,0
JNE EndPattern
INC COUNTER
MOV AX,WORD PTR [BPM_SPEED+2]
ADD WORD PTR [BPM_COUNT+2],AX
MOV AX,WORD PTR [BPM_SPEED]
ADC WORD PTR [BPM_COUNT],AX
JC JumpPattern
CMP BPM_RATE,512
JB EndPattern
CMP COUNTER,3
JE SHORT ClearNotes
CMP COUNTER,6
JE SetNotes
JMP EndPattern
;-----------------------------------------------------------------------------
ClearNotes:
CMP MOD_STAT,0
JE SHORT NOT_FINISHED
MOV PATT_CURRENT,0
MOV DI,OFFSET SAMP_CHANS
MOV CX,CH_NUMB
FINISH: MOV [DI.OLD_VOL],0
MOV [DI.VOL],0
MOV [DI.AMIGA],0
MOV [DI.FREQ_VAL],0
ADD DI,CHAN_SIZE
LOOP FINISH
NOT_FINISHED:
MOV DI,OFFSET SAMP_CHANS
MOV CX,CH_NUMB
MOV DX,BASE_PORT
ADD DX,CommandPort
StopVoices:
DEC DX
MOV AL,BYTE PTR CH_NUMB
SUB AL,CL
OUT DX,AL
INC DX
CMP [DI.INST_SET],2
JE SHORT VoiceOff1
CMP [DI.INST_SET],1
JE SHORT VoiceOff2
CMP [DI.OFFSET_ADD],0
JNE SHORT VoiceOff1
JMP SHORT NoVoiceOff
VoiceOff2:
MOV AX,[DI.CURR_SAMP]
CMP AX,[DI.OLD_SAMP]
JNE SHORT VoiceOff1
JMP SHORT NoVoiceOff
VoiceOff1:
MOV AX,[DI.OLD_VOL]
MOV [DI.OLD_VOL],0
MOV BP,GUS_VOL
MOV BX,MUSIC_VOL
MUL BL
MOVZX BX,AH
SHL BX,1
MOV BX,[GUS_VOL+BX]
TEST US_MODUS,2
JZ SHORT WITH_SOUND1
MOV BX,1000H
MOV BP,BX
WITH_SOUND1:
CALL SEND_RAMP
NoVoiceOff:
ADD DI,CHAN_SIZE
LOOP StopVoices
CMP BPM_RATE,512
JAE EndPattern
;-----------------------------------------------------------------------------
SetNotes:
MOV COUNTER,1
MOV DI,OFFSET SAMP_CHANS
MOV CX,CH_NUMB
MOV DX,BASE_PORT
ADD DX,CommandPort
ChangeSamps:
DEC DX
MOV AL,BYTE PTR CH_NUMB
SUB AL,CL
OUT DX,AL
INC DX
MOV AL,[DI.BALANCE] ;PANNING
MOV AH,AL
SHR AL,4
AND AH,0FH
CMP AL,AH
JE SHORT NO_PANNING
MOV AL,AH
SHL AL,4
OR AL,AH
MOV [DI.BALANCE],AL
MOV AL,VoiceBalance
OUT DX,AL
ADD DX,2
MOV AL,AH
OUT DX,AL
SUB DX,2
NO_PANNING:
CMP [DI.INST_SET],2
JE SHORT SampChange1
CMP [DI.INST_SET],1
JE SHORT SampChange2
CMP [DI.OFFSET_ADD],0
JNE SHORT ChangeOffset
JMP SHORT NoChangeSamp
ChangeOffset:
CALL SEND_SAMPLE_START
JMP SHORT NoChangeSamp
SampChange1:
MOV AH,3
CALL SEND_WRITE_VOICE
CALL WAIT_PORT
CALL SEND_SAMPLE_START
MOV AX,[DI.OLD_SAMP]
CMP AX,[DI.CURR_SAMP]
JE SHORT NoChangeSamp
CALL SEND_SAMPLE_END
CALL SEND_SAMPLE_LOOP
MOV AH,3
CALL SEND_WRITE_VOICE
JMP SHORT NoChangeSamp
SampChange2:
MOV AX,[DI.OLD_SAMP]
CMP AX,[DI.CURR_SAMP]
JE SHORT NoChangeSamp
MOV AL,VoicePosLo
OUT DX,AL
INC DX
IN AX,DX
MOV BX,AX
DEC DX
MOV AL,VoicePosHi
OUT DX,AL
INC DX
IN AX,DX
DEC DX
XCHG AX,BX
SHL AX,7
SHR BX,9
AND BX,7FH
OR AX,BX
MOV BX,[DI.OLD_SAMP]
DEC BX
SHL BX,2
SUB AX,WORD PTR [IOFFSET+BX]
MOV BX,AX
CMP BX,[DI.LEN]
JB SHORT NoFixStart
MOV BX,[DI.LEN]
DEC BX
NoFixStart:
CMP [DI.OFFSET_ADD],0
JNE SHORT NoOffsetEff
MOV [DI.OFFSET_ADD],BX
NoOffsetEff:
CALL SEND_SAMPLE_START
CALL SEND_SAMPLE_END
CALL SEND_SAMPLE_LOOP
MOV AH,BYTE PTR [DI.LOOP_ONOFF]
CALL SEND_WRITE_VOICE
CALL WAIT_PORT
NoChangeSamp:
MOV AX,[DI.OLD_VOL]
MOV BX,MUSIC_VOL
MUL BL
MOVZX BX,AH
SHL BX,1
MOV BX,[GUS_VOL+BX]
MOV AX,[DI.VOL]
MOV BP,MUSIC_VOL
MUL BP
MOVZX BP,AH
SHL BP,1
MOV BP,CS:[GUS_VOL+BP]
TEST US_MODUS,2
JZ SHORT WITH_SOUND2
MOV BX,1000H
MOV BP,BX
WITH_SOUND2:
MOV DX,BP
MOV DL,BH
CMP DL,DH
JNE SHORT SetVOL
MOV DX,BASE_PORT
ADD DX,CommandPort
MOV AL,VOLumeCtrl
OUT DX,AL
ADD DX,2
MOV AL,3
OUT DX,AL
SUB DX,2
MOV AL,SetVOLume
OUT DX,AL
MOV AX,BP
INC DX
OUT DX,AX
DEC DX
JMP SHORT NoSetVOL
SetVOL: CALL SEND_RAMP
NoSetVOL:
MOV AL,SetVoiceFreq
OUT DX,AL
INC DX
MOV AX,[DI.FREQ_VAL]
OUT DX,AX
DEC DX
SHL COUNTER,1
ADD DI,CHAN_SIZE
DEC CX
JNZ ChangeSamps
MOV DI,OFFSET SAMP_CHANS
MOV CX,CH_NUMB
StartVoices:
DEC DX
MOV AL,BYTE PTR CH_NUMB
SUB AL,CL
OUT DX,AL
INC DX
CMP [DI.INST_SET],2
JNE SHORT NoVoiceStart
MOV AH,BYTE PTR [DI.LOOP_ONOFF]
CALL SEND_WRITE_VOICE
CALL WAIT_PORT
NoVoiceStart:
MOV [DI.INST_SET],0
MOV [DI.OFFSET_ADD],0
ADD DI,CHAN_SIZE
LOOP StartVoices
JMP EndPattern
;-----------------------------------------------------------------------------
JumpPattern:
MOV COUNTER,0
DEC PATT_COUNT
JZ DoPattern
MOV DI,OFFSET SAMP_CHANS
MOV CX,CH_NUMB
EFFECTLoop:
MOV AX,[DI.VOL]
MOV [DI.OLD_VOL],AX
INC [DI.EFFECT_TIME]
ADD [DI.ARP_COUNTER],2
CMP [DI.ARP_COUNTER],6
JB SHORT NoWrapARP
MOV [DI.ARP_COUNTER],0
NoWrapARP:
MOV AX,[DI.EFFECT]
OR AX,AX
JZ NoEFFECT
MOVZX BX,AL
CMP BL,0EH
JE SHORT DoEEFFECTs
SHL BX,1
JMP [EFFECTJumps+BX]
DoEEFFECTs:
MOV BL,AH
AND AH,0FH
SHR BL,4
SHL BX,1
JMP [EEFFECTJumps+BX]
ARPeggio:
MOV BX,[DI.ARP_COUNTER]
MOV BX,[DI.ARP+BX]
SHL BX,1
MOV AX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],AX
JMP NoEFFECT
PortUp: XCHG AL,AH
XOR AH,AH
MOV SI,[DI.FINE]
MOV BP,[PERIOD_TABLE+47*2+SI] ;35
MOV BX,[DI.AMIGA]
SUB BX,AX
JNC SHORT NoFix1
MOV BX,BP
NoFix1: CMP BX,BP
JAE SHORT NotSmall1
MOV BX,BP
NotSmall1:
MOV [DI.AMIGA],BX
SHL BX,1
MOV AX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],AX
JMP NoEFFECT
PortDown:
XCHG AL,AH
XOR AH,AH
MOV SI,[DI.FINE]
MOV BP,[PERIOD_TABLE+SI]
MOV BX,[DI.AMIGA]
ADD BX,AX
CMP BX,BP
JBE SHORT NotBig1
MOV BX,BP
NotBig1:
MOV [DI.AMIGA],BX
SHL BX,1
MOV AX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],AX
JMP NoEFFECT
PORT_TOTone:
XCHG AL,AH
XOR AH,AH
GOTO_PORT_TO:
MOV DX,[DI.PORT_TO]
MOV BX,[DI.AMIGA]
CMP BX,DX
JAE SHORT NoPORT_TOUp
ADD BX,AX
CMP BX,DX
JBE SHORT NoPORT_TOUp
MOV [DI.AMIGA],DX
NoPORT_TOUp:
CMP BX,DX
JBE SHORT NoPORT_TODown
SUB BX,AX
JNC SHORT NoPORT_TOError
MOV BX,DX
NoPORT_TOError:
CMP BX,DX
JAE SHORT NoPORT_TODown
MOV BX,DX
NoPORT_TODown:
MOV [DI.AMIGA],BX
SHL BX,1
MOV AX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],AX
JMP NoEFFECT
Vibrato:
MOV SI,[DI.FINE]
MOV BP,[PERIOD_TABLE+47*2+SI] ;35
MOV SI,[PERIOD_TABLE+SI]
MOV DL,AH
AND AH,0F0H
SHR AH,2
AND DL,0FH
MOV BL,BYTE PTR [DI.VIBRATO_POINT]
ADD BL,AH
MOV BYTE PTR [DI.VIBRATO_POINT],BL
SHR BL,2
AND BX,1Fh
MOV AL,[SIN_TAB+BX]
MUL DL
ROL AX,1
XCHG AL,AH
AND AH,1
TEST BYTE PTR [DI.VIBRATO_POINT],80H
JNE SHORT VibUp1
NEG AX
VibUp1: ADD AX,[DI.AMIGA]
CMP AX,BP
JAE SHORT NoHighVibrato1
MOV AX,BP
NoHighVibrato1:
CMP AX,SI
JBE SHORT NoLowVibrato1
MOV AX,SI
NoLowVibrato1:
SHL AX,1
MOV BX,AX
MOV AX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],AX
JMP NoEFFECT
PORT_TOVSlide:
MOV AL,AH
AND AH,0FH
SHR AL,4
SUB AH,AL
MOV AL,BYTE PTR [DI.VOL]
SUB AL,AH
JNS SHORT NoSlideLow2
XOR AL,AL
NoSlideLow2:
CMP AL,40H
JBE SHORT NoSlideHigh2
MOV AL,40H
NoSlideHigh2:
MOV BYTE PTR [DI.VOL],AL
MOV AX,[DI.OLD_PORT_TO]
JMP GOTO_PORT_TO
VibratoVSlide:
MOV AL,AH
AND AH,0FH
SHR AL,4
SUB AH,AL
MOV AL,BYTE PTR [DI.VOL]
SUB AL,AH
JNS SHORT NoSlideLow3
XOR AL,AL
NoSlideLow3:
CMP AL,40H
JBE SHORT NoSlideHigh3
MOV AL,40H
NoSlideHigh3:
MOV BYTE PTR [DI.VOL],AL
JMP Vibrato
VOLSlide:
MOV AL,AH
AND AH,0FH
SHR AL,4
OR AL,AL
JZ SHORT NoVOLSlideUp
NEG AL
MOV AH,AL
NoVOLSlideUp:
MOV AL,BYTE PTR [DI.VOL]
SUB AL,AH
JNS SHORT NoSlideLow1
XOR AL,AL
NoSlideLow1:
CMP AL,40H
JBE SHORT NoSlideHigh1
MOV AL,40H
NoSlideHigh1:
MOV BYTE PTR [DI.VOL],AL
JMP SHORT NoEFFECT
RetrigNote:
CMP AH,BYTE PTR [DI.EFFECT_TIME]
JNE SHORT NoRetrig
MOV [DI.EFFECT_TIME],0
MOV [DI.INST_SET],2
NoRetrig:
JMP SHORT NoEFFECT
CutNote:
CMP AH,BYTE PTR [DI.EFFECT_TIME]
JNE SHORT NoCutNote
MOV [DI.AMIGA],0
MOV [DI.FREQ_VAL],0
NoCutNote:
JMP SHORT NoEFFECT
DelayNote:
CMP AH,BYTE PTR [DI.EFFECT_TIME]
JNE SHORT NoDelayNote
MOV [DI.INST_SET],2
MOV [DI.VIBRATO_POINT],0
MOV BX,[DI.PORT_TO]
MOV [DI.AMIGA],BX
SHL BX,1
MOV BX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],BX
NoDelayNote:
JMP SHORT NoEFFECT
NoEFFECT:
ADD DI,CHAN_SIZE
DEC CX
JNZ EFFECTLoop
JMP EndPattern2
;-----------------------------------------------------------------------------
DoPattern:
MOV AX,PATT_SPEED
MOV PATT_COUNT,AX
CMP PATT_ROW,64
JB SHORT NoPatternWrap
MOV AX,PATT_CURRENT
CMP AL,SONG_SIZE
JB SHORT NoTrackWrap
MOV AL,SONG_LOOP
CMP AL,SONG_SIZE
JB SHORT NoRestart
MOV MOD_STAT,3
XOR AL,AL
NoRestart:
MOV PATT_CURRENT,AX
MOV PATT_SPEED,6
MOV PATT_COUNT,1
MOV AL,125
CALL GO_SETBPM
MOV BPM_COUNT,0
NoTrackWrap:
MOV BX,PATT_CURRENT
INC PATT_CURRENT
MOV DI,OFFSET SAMP_CHANS
XOR SI,SI
NewTracks:
PUSH SI
SHL SI,1
MOV SI,[TRACKS_OFFSET+SI]
MOV AX,PATT_BREAK
MOV PATT_ROW,AX
SHL AX,2
ADD AH,[SI+BX]
MOV [DI.TRACK_OFF],AX
POP SI
ADD DI,CHAN_SIZE
INC SI
CMP SI,CH_NUMB
JB NewTracks
MOV PATT_BREAK,0
NoPatternWrap:
MOV ES,TRACK_SEG
MOV DI,OFFSET SAMP_CHANS
MOV CX,CH_NUMB
PattLoop:
MOV SI,[DI.TRACK_OFF]
MOV AX,[DI.VOL]
MOV [DI.OLD_VOL],AX
MOV BH,ES:[SI] ; New Sample
MOV BL,ES:[SI+2]
AND BH,0F0H
SHR BL,4
ADD BL,BH
JZ SHORT NoNewSample
MOV BH,BYTE PTR [DI.CURR_SAMP]
MOV BYTE PTR [DI.OLD_SAMP],BH
MOV BYTE PTR [DI.CURR_SAMP],BL
XOR BH,BH
DEC BX
SHL BX,1
MOV AX,[IVOLUME+BX]
MOV [DI.VOL],AX
MOV [DI.INST_SET],1
SHL BX,1
MOV EAX,[IOFFSET+BX]
MOV [DI.SAMP_OFF],EAX
SHR BX,1
MOV AX,[IFINETUNE+BX]
SHL AX,5
MOV [DI.FINE],AX
SHL AX,1
ADD [DI.FINE],AX
MOV [DI.LOOP_ONOFF],0
MOV AX,[ISIZE+BX]
MOV [DI.LEN],AX
MOV AX,[ILOOP_START+BX]
MOV [DI.REPEAT],AX
MOV AX,[ILOOP_SIZE+BX]
MOV [DI.REPLEN],AX
CMP AX,2
JBE SHORT NoNewSample
MOV [DI.LOOP_ONOFF],8
MOV AX,[DI.REPEAT]
ADD AX,[DI.REPLEN]
CMP AX,[DI.LEN]
JA SHORT NoNewSample
MOV [DI.LEN],AX
NoNewSample:
MOV BX,ES:[SI]
XCHG BL,BH
AND BX,0FFFH
JZ SHORT NoNewNote
CALL GET_PERIOD_INDEX
ADD BX,[DI.FINE]
MOV BX,[PERIOD_TABLE+BX]
MOV [DI.PORT_TO],BX
MOV AX,ES:[SI+2]
AND AL,0FH
AND AH,0F0H
CMP AL,3
JE SHORT NoNewNote
CMP AL,5
JE SHORT NoNewNote
CMP AX,0D00EH
JNE SHORT NewNote
MOV AL,ES:[SI+2]
OR AL,AL
JZ SHORT NewNote
MOV [DI.INST_SET],0
JMP SHORT NoNewNote
NewNote:
MOV [DI.INST_SET],2
MOV [DI.VIBRATO_POINT],0
MOV [DI.AMIGA],BX
SHL BX,1
MOV BX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],BX
NoNewNote:
MOV [DI.ARP_COUNTER],0
MOV AX,ES:[SI+2]
AND AL,0FH
MOV [DI.EFFECT],AX
CMP AL,7
JB SHORT NoSetOldFreq
MOV BX,AX
AND BH,0F0H
CMP BX,0C00EH
JE SHORT NoSetOldFreq
CMP BX,0D00EH
JE SHORT NoSetOldFreq
MOV BX,[DI.AMIGA]
SHL BX,1
MOV BX,[FREQ_TABLE+BX]
MOV [DI.FREQ_VAL],BX
NoSetOldFreq:
MOVZX BX,AL
CMP BL,0EH
JE SHORT DoEPattEFFECTs
SHL BX,1
JMP [PattJumps+BX]
DoEPattEFFECTs:
MOV BL,AH
AND AH,0FH
SHR BL,4
SHL BX,1
JMP [EPattJumps+BX]
ARPeggioFix:
MOV BX,[DI.AMIGA]
CALL GET_PERIOD_INDEX
MOV BP,BX
ADD BX,[DI.FINE]
MOV DX,[PERIOD_TABLE+BX]
MOV [DI.ARP],DX
XCHG AL,AH
XOR AH,AH
MOV DX,AX
SHR DX,4
AND AX,0FH
SHL DX,1
SHL AX,1
MOV BX,BP
ADD BX,DX
CMP BX,94
JBE SHORT NoWrapARP1
MOV BX,94
NoWrapARP1:
ADD BX,[DI.FINE]
MOV DX,[PERIOD_TABLE+BX]
MOV [DI.ARP+2],DX
MOV BX,BP
ADD BX,AX
CMP BX,94
JBE SHORT NoWrapARP2
MOV BX,94
NoWrapARP2:
ADD BX,[DI.FINE]
MOV DX,[PERIOD_TABLE+BX]
MOV [DI.ARP+4],DX
JMP NoPattEFFECT
PORT_TOFix:
OR AH,AH
JNZ SHORT NoPortPekFix
MOV AH,BYTE PTR [DI.OLD_PORT_TO]
NoPortPekFix:
MOV BYTE PTR [DI.OLD_PORT_TO],AH
MOV BYTE PTR [DI.EFFECT+1],AH
JMP NoPattEFFECT
VibratoFix:
MOV AL,AH
AND AL,0FH
AND AH,0F0H
OR AL,AL
JNZ SHORT NoVibratoFix1
MOV AL,BYTE PTR [DI.OLD_VIBRATO]
NoVibratoFix1:
OR AH,AH
JNZ SHORT NoVibratoFix2
MOV AH,BYTE PTR [DI.OLD_VIBRATO+1]
NoVibratoFix2:
MOV BYTE PTR [DI.OLD_VIBRATO],AL
MOV BYTE PTR [DI.OLD_VIBRATO+1],AH
OR AL,AH
MOV BYTE PTR [DI.EFFECT+1],AL
JMP NoPattEFFECT
SampleOff:
XOR AL,AL
CMP AX,[DI.LEN]
JB SHORT NoFixOffset
MOV AX,[DI.LEN]
DEC AX
NoFixOffset:
MOV [DI.OFFSET_ADD],AX
JMP NoPattEFFECT
PosJump:
MOV [PATT_ROW],63
MOV BYTE PTR [PATT_CURRENT],AH
JMP NoPattEFFECT
VOLume:
CMP AH,40H
JBE SHORT NoFixVOL1
MOV AH,40H
NoFixVOL1:
MOV BYTE PTR [DI.VOL],AH
JMP NoPattEFFECT
BreakPatt:
MOV [PATT_ROW],63
CMP AH,64H
JB SHORT NoFixBreak
MOV AH,63H
NoFixBreak:
MOV AL,AH
AND AL,0FH
SHR AH,4
SHL AH,1
MOV BYTE PTR [PATT_BREAK],AL
ADD BYTE PTR [PATT_BREAK],AH
SHL AH,2
ADD BYTE PTR [PATT_BREAK],AH
JMP NoPattEFFECT
SpeedSet:
OR AH,AH
JZ NoPattEFFECT
CMP AH,1FH
JBE SHORT UsualSpeed
XCHG AL,AH
CALL GO_SETBPM
JMP SHORT NoPattEFFECT
UsualSpeed:
MOV BYTE PTR [PATT_SPEED],AH
MOV BYTE PTR [PATT_COUNT],AH
JMP SHORT NoPattEFFECT
FINEPortUp:
XCHG AL,AH
XOR AH,AH
SUB [DI.AMIGA],AX
MOV BX,[DI.FINE]
MOV BX,[PERIOD_TABLE+47*2+BX] ;35
CMP [DI.AMIGA],BX
JAE SHORT NoFixFINEUp
MOV [DI.AMIGA],BX
NoFixFINEUp:
JMP SHORT NoPattEFFECT
FINEPortDown:
XCHG AL,AH
XOR AH,AH
ADD [DI.AMIGA],AX
MOV BX,[DI.FINE]
MOV BX,[PERIOD_TABLE+BX]
CMP [DI.AMIGA],BX
JBE SHORT NoFixFINEDown
MOV [DI.AMIGA],BX
NoFixFINEDown:
JMP SHORT NoPattEFFECT
PANNING:
AND [DI.BALANCE],0F0H
OR [DI.BALANCE],AH
JMP SHORT NoPattEFFECT
FINEVOLUP:
ADD BYTE PTR [DI.VOL],AH
CMP BYTE PTR [DI.VOL],40H
JBE SHORT NoFixFINEVOLUp
MOV BYTE PTR [DI.VOL],40H
NoFixFINEVOLUp:
JMP SHORT NoPattEFFECT
FINEVOLDown:
SUB BYTE PTR [DI.VOL],AH
JNC SHORT NoFixFINEVOLDown
MOV BYTE PTR [DI.VOL],0
NoFixFINEVOLDown:
JMP SHORT NoPattEFFECT
NoPattEFFECT:
ADD [DI.TRACK_OFF],4
MOV [DI.EFFECT_TIME],0
ADD DI,CHAN_SIZE
DEC CX
JNZ PattLoop
INC PATT_ROW
EndPattern2:
CMP BPM_RATE,512
JB ClearNotes
EndPattern:
CALL CONTROL_SAMPLE
POP ES DS
POP EBP EDI ESI EDX ECX EBX EAX
CMP CS:VAR_BUFSEG,0
JNE SHORT WT8
CMP CS:SYSTEM,0
JE SHORT WT7
DEC CS:IRQCOUNT
JNZ SHORT WT7
MOV CS:IRQCOUNT,56
WT8: JMP DWORD PTR CS:[HOLD70]
WT7: IRET
CONTROL_CHANNELS ENDP
;-----------------------------------------------------------------------------
GET_PERIOD_INDEX PROC NEAR
MOV BP,BX
XOR BH,BH
MOV DX,6000H ;BINAERSUCHE
LGP1: MOV BL,DL
ADD BL,DH
SHR BL,1
AND BL,0FEH
JZ SHORT GGP2
CMP BL,94
JE SHORT GGP2
CMP BP,[PERIOD_TABLE+BX]
JAE SHORT GGP1
MOV DL,BL
JMP LGP1
GGP1: MOV DH,BL
CMP BP,[PERIOD_TABLE-2+BX]
JAE LGP1 ;GEFUNDEN
MOV DX,[PERIOD_TABLE-2+BX] ;GET NEAREST PERIOD
SUB DX,BP
SUB BP,[PERIOD_TABLE+BX]
CMP DX,BP
JAE SHORT GGP2
SUB BX,2
GGP2: RET
GET_PERIOD_INDEX ENDP
;-----------------------------------------------------------------------------
GO_SETBPM PROC NEAR
XOR AH,AH
MOV BPM_VALUE,AX
SHL AX,1
MOV BL,5 ; Denna bit är för att ställa
DIV BL ; EFFECTs till annat än 50Hz
MOV DL,AL ; Detta ger automatiskt en annan
XOR DH,DH ; PATT_SPEED.; Hz=2*BPM/5
XOR AX,AX
MOV BX,BPM_RATE
CMP BX,DX
JA SHORT GOSBPM
MOV BX,DX
INC BX
GOSBPM: DIV BX
MOV WORD PTR BPM_SPEED,AX
XOR AX,AX
DIV BX
MOV WORD PTR BPM_SPEED+2,AX
RET
GO_SETBPM ENDP
;-----------------------------------------------------------------------------
CONTROL_SAMPLE PROC NEAR
MOV CL,8
XOR SI,SI
LCS1: CMP [SAM_COUNT+SI],0
JE SHORT GCS1
JL SHORT GCS2
DEC [SAM_COUNT+SI]
JNZ SHORT GCS1
MOV [SAM_COUNT+SI],-256 ;RAMP DOWN SAMPLE
MOV DX,BASE_PORT
ADD DX,CommandPort
DEC DX
MOV AL,CL
OUT DX,AL
INC DX
MOV BP,GUS_VOL
MOV BX,FX_VOL
INC BX
SHR BX,2
CMP BL,40H
JBE SHORT FIXVOL
MOV BL,40H
FIXVOL: SHL BX,1
MOV BX,[GUS_VOL+BX]
CALL SEND_RAMP
JMP SHORT GCS1
GCS2: INC [SAM_COUNT+SI] ;STOP SAMPLE
JNZ SHORT GCS1
MOV DX,BASE_PORT
ADD DX,ActiveVoicePort
MOV AL,CL
OUT DX,AL
INC DX
MOV AL,WriteVoiceMode
OUT DX,AL
ADD DX,2
MOV AL,3 ;Voice Off
OUT DX,AL
SUB DX,2
MOV AL,VolumeCtrl
OUT DX,AL
ADD DX,2
MOV AL,3 ;Ramp Off
OUT DX,AL
SUB DX,3
GCS1: INC SI
INC SI
INC CL
CMP CL,NumVoices-1
JB LCS1
RET
CONTROL_SAMPLE ENDP
;=============================================================================
;=============================================================================
;
; ULTRASOUND INIT
;
;=============================================================================
INIT_DEVICE PROC NEAR
PUSH CS
POP DS
CLI
MOV BX,BASE_PORT ;Init the UltraSound
MOV CX,BX
ADD BX,CommandPort
ADD CX,DataHighPort
MOV DX,BX
MOV AL,Initialize
OUT DX,AL
MOV DX,CX
MOV AL,0
OUT DX,AL
MOV DX,BASE_PORT
MOV AH,10
LID1: IN AL,DX
DEC AH
JNZ LID1
MOV DX,BX
MOV AL,Initialize
OUT DX,AL
MOV DX,CX
MOV AL,1
OUT DX,AL
MOV DX,BASE_PORT
MOV AH,10
LID2: IN AL,DX
DEC AH
JNZ LID2
MOV DX,BX
MOV AL,DMACtrl
OUT DX,AL
MOV DX,CX
MOV AL,0
OUT DX,AL
MOV DX,BX
MOV AL,45H
OUT DX,AL
MOV DX,CX
MOV AL,0
OUT DX,AL
MOV DX,BX
MOV AL,49H
OUT DX,AL
MOV DX,CX
MOV AL,0
OUT DX,AL
MOV DX,BX
MOV AL,VoicesActive
OUT DX,AL
MOV DX,CX
MOV AL,NumVoices
DEC AL
OR AL,0C0H
OUT DX,AL
MOV DX,BASE_PORT ;Clear IRQs
ADD DX,StatusPort
IN AL,DX
MOV DX,BX
MOV AL,DMACtrl
OUT DX,AL
MOV DX,CX
IN AL,DX
MOV DX,BX
MOV AL,49H
OUT DX,AL
MOV DX,CX
IN AL,DX
MOV DX,BX
MOV AL,8FH
OUT DX,AL
MOV DX,CX
IN AL,DX
PUSH CX
MOV CX,32
VoiceClearLoop:
MOV DX,BASE_PORT
ADD DX,ActiveVoicePort
MOV AL,CL
DEC AL
OUT DX,AL
INC DX
MOV AL,0
OUT DX,AL
ADD DX,2
MOV AL,3 ;Voice Off
OUT DX,AL
SUB DX,2
MOV AL,0DH
OUT DX,AL
ADD DX,2
MOV AL,3 ;Ramp Off
OUT DX,AL
MOV DX,BASE_PORT
MOV AH,10
LID3: IN AL,DX
DEC AH
JNZ LID3
LOOP VoiceClearLoop
POP CX
CMP DMA_CHANNEL,0 ;NO DMA
JE SHORT LID5
MOV DX,BASE_PORT ;SETUP FOR DIGITAL ASIC
ADD DX,0FH
MOV AL,5
OUT DX,AL
SUB DX,0FH
MOV AL,3
OUT DX,AL
ADD DX,DMASetPort
MOV AL,0
OUT DX,AL
ADD DX,0FH-DMASetPort
OUT DX,AL
SUB DX,0FH
MOV AL,3 ;SET DMA CHANNEL
OUT DX,AL
ADD DX,DMASetPort
PUSH BX
MOV BX,DMA_CHANNEL
MOV AL,[DMA_SET_DATA+BX]
POP BX
OR AL,0C0H ;SET DMA
OUT DX,AL
SUB DX,DMASetPort
PUSH AX
MOV AL,43H
OUT DX,AL
ADD DX,DMASetPort
MOV AL,45H ;SET IRQ11
OUT DX,AL
SUB DX,DMASetPort
MOV AL,3
OUT DX,AL
ADD DX,DMASetPort
POP AX
AND AL,7FH ;SET DMA
OUT DX,AL
SUB DX,DMASetPort
MOV AL,43H
OUT DX,AL
ADD DX,DMASetPort
MOV AL,45H ;SET IRQ11
OUT DX,AL
ADD DX,ActiveVoicePort-DMASetPort
MOV AL,0
OUT DX,AL
SUB DX,ActiveVoicePort
MOV AL,8 ;SETUP DMA LATCH
OUT DX,AL
ADD DX,ActiveVoicePort
MOV AL,0
OUT DX,AL
LID5:
MOV DX,BX ;Clear IRQs
MOV AL,DMACtrl
OUT DX,AL
MOV DX,CX
IN AL,DX
MOV DX,BX
MOV AL,49H
OUT DX,AL
MOV DX,CX
IN AL,DX
MOV DX,BX
MOV AL,8FH
OUT DX,AL
MOV DX,CX
IN AL,DX
MOV DX,BX
MOV AL,Initialize
OUT DX,AL
MOV DX,CX
MOV AL,3
OUT DX,AL
MOV CX,NumVoices
SetRampRateLoop:
MOV DX,BASE_PORT
ADD DX,ActiveVoicePort
MOV AL,NumVoices
SUB AL,CL
OUT DX,AL
MOV DX,BASE_PORT
ADD DX,CommandPort
MOV AL,VOLRampRate
OUT DX,AL
MOV AL,00111111B
MOV DX,BASE_PORT
ADD DX,DataHighPort
OUT DX,AL
MOV DX,BASE_PORT
ADD DX,CommandPort
MOV AL,SetVOLume
OUT DX,AL
MOV AX,GUS_VOL
MOV DX,BASE_PORT
ADD DX,DataLowPort
OUT DX,AX
MOV DX,BASE_PORT
MOV AH,10
LID4: IN AL,DX
DEC AH
JNZ LID4
LOOP SetRampRateLoop
MOV DX,BASE_PORT ;DETECT GUS VERSION
ADD DX,GUS_VERSION
IN AL,DX
CMP ULTRA16,0 ;IST ULTRA16 BOARD ANGEGEBEN?
JNE SHORT LID9
CMP AL,5 ;GUS BEFORE 3.7 NO MIXER
JL SHORT LID6
CMP AL,10
JB SHORT LID7 ;NON GUS MAX
LID9: CMP AL,10
JB SHORT LID8
ADD DX,ICMIX_DATA-ICMIX_SEL ;ACTIVATE GUS MAX MIXER OUTPUT
MOV AX,CODEC_PORT
SHR AL,4
OR AL,40H
OUT DX,AL
LID8: MOV DX,CODEC_PORT ;CODEC MIXER ON GUS MAX 31-0
MOV AH,8 ;NO GAIN, KEINE VERSTAERKUNG
MOV AL,2 ;GF1 LEFT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
DEC DX
MOV AL,3 ;GF1 RIGHT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
DEC DX
XOR AH,AH
MOV AL,6 ;OUT LEFT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
DEC DX
MOV AL,7 ;OUT RIGHT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
LID7: MOV AH,BYTE PTR MUSIC_VOL
CALL SET_CDMIXER
LID6: STI
RET
INIT_DEVICE ENDP
;-----------------------------------------------------------------------------
SEND_SAMPLE_START PROC NEAR
MOV AL,SampleStartLo
OUT DX,AL
INC DX
MOV AX,WORD PTR [DI.SAMP_OFF]
MOV BP,WORD PTR [DI.SAMP_OFF+2]
ADD AX,[DI.OFFSET_ADD]
ADC BP,0
SHR AX,7
SHL BP,9
OR AX,BP
OUT DX,AX
DEC DX
MOV AL,SampleStartHi
OUT DX,AL
INC DX
MOV AX,WORD PTR [DI.SAMP_OFF]
ADD AX,[DI.OFFSET_ADD]
SHL AX,9
OUT DX,AX
DEC DX
SUB DX,CommandPort
Rept 6
IN AL,DX
EndM
ADD DX,CommandPort
RET
SEND_SAMPLE_START ENDP
;-----------------------------------------------------------------------------
SEND_SAMPLE_END PROC NEAR
MOV AL,SampleEndLo
OUT DX,AL
INC DX
MOV AX,WORD PTR [DI.SAMP_OFF]
MOV BP,WORD PTR [DI.SAMP_OFF+2]
ADD AX,[DI.LEN]
ADC BP,0
SHR AX,7
SHL BP,9
OR AX,BP
OUT DX,AX
DEC DX
MOV AL,SampleEndHi
OUT DX,AL
INC DX
MOV AX,WORD PTR [DI.SAMP_OFF]
ADD AX,[DI.LEN]
SHL AX,9
OUT DX,AX
DEC DX
RET
SEND_SAMPLE_END ENDP
;-----------------------------------------------------------------------------
SEND_SAMPLE_LOOP PROC NEAR
MOV AL,LoopStartLo
OUT DX,AL
INC DX
MOV AX,WORD PTR [DI.SAMP_OFF]
MOV BP,WORD PTR [DI.SAMP_OFF+2]
ADD AX,[DI.REPEAT]
ADC BP,0
SHR AX,7
SHL BP,9
OR AX,BP
OUT DX,AX
DEC DX
MOV AL,LoopStartHi
OUT DX,AL
INC DX
MOV AX,WORD PTR [DI.SAMP_OFF]
ADD AX,[DI.REPEAT]
SHL AX,9
OUT DX,AX
DEC DX
RET
SEND_SAMPLE_LOOP ENDP
;-----------------------------------------------------------------------------
SEND_WRITE_VOICE PROC NEAR
MOV AL,WriteVoiceMode
OUT DX,AL
ADD DX,2
MOV AL,AH
OUT DX,AL
SUB DX,2
RET
SEND_WRITE_VOICE ENDP
;-----------------------------------------------------------------------------
WAIT_PORT PROC NEAR
SUB DX,CommandPort
Rept 6
IN AL,DX
EndM
ADD DX,CommandPort
RET
WAIT_PORT ENDP
;-----------------------------------------------------------------------------
SEND_RAMP PROC NEAR
MOV DX,BASE_PORT
ADD DX,CommandPort
MOV AL,VOLumeCtrl
OUT DX,AL
ADD DX,2
MOV AL,3
OUT DX,AL
SUB DX,2
MOV AH,0
CMP BX,BP
JB SHORT NoFixVOLDir
MOV AH,01000000B
XCHG BX,BP
NoFixVOLDir:
MOV AL,VOLRampStart
OUT DX,AL
XCHG AX,BX
INC DX
OUT DX,AX
DEC DX
MOV AL,VOLRampEnd
OUT DX,AL
MOV AX,BP
INC DX
OUT DX,AX
DEC DX
MOV AL,VOLumeCtrl
OUT DX,AL
MOV AL,BH
ADD DX,2
OUT DX,AL
SUB DX,2
RET
SEND_RAMP ENDP
;-----------------------------------------------------------------------------
; CX= ANZAHL WORDS, EDI= GUSMEM ZEIGER, BX= 0000H AMIGA, 8080H PC SAMPLE
; DS:SI= ZEIGER AUF SAMPLE-DATEN
;-----------------------------------------------------------------------------
SEND_SAMPLE_DATA PROC NEAR
CMP CS:DMA_CHANNEL,0
JNE DMA_INIT
MOV DX,CS:BASE_PORT
ADD DX,CommandPort
LHP1: LODSW
CLI
XOR AX,BX
MOV BP,AX
MOV AL,DRAMAddrLo
OUT DX,AL
INC DX
MOV AX,DI
OUT DX,AX
DEC DX
MOV AL,DRAMAddrHi
OUT DX,AL
ADD DX,2
MOV EAX,EDI
SHR EAX,16
OUT DX,AL
ADD DX,2
MOV AX,BP
OUT DX,AL
SUB DX,4
INC EDI
MOV AL,DRAMAddrLo
OUT DX,AL
INC DX
MOV AX,DI
OUT DX,AX
DEC DX
MOV AL,DRAMAddrHi
OUT DX,AL
ADD DX,2
MOV EAX,EDI
SHR EAX,16
OUT DX,AL
ADD DX,2
MOV AX,BP
MOV AL,AH
OUT DX,AL
SUB DX,4
INC EDI
STI
LOOP LHP1
CLI
MOV AL,DRAMAddrLo ;SAMPLE UM EIN WORD VERLÄNGERN
OUT DX,AL
INC DX
MOV AX,DI
OUT DX,AX
DEC DX
MOV AL,DRAMAddrHi
OUT DX,AL
ADD DX,2
MOV EAX,EDI
SHR EAX,16
OUT DX,AL
ADD DX,2
MOV AX,BP
MOV AL,AH
OUT DX,AL
SUB DX,4
INC EDI
MOV CS:GUS_MEM,EDI
STI
RET
SEND_SAMPLE_DATA ENDP
;-----------------------------------------------------------------------------
; SET DMA READY FOR TRANSFER WITH AUTOINIT
; IN: DS:SI= BLOCKPOINTER, CX= SIZE IN WORDS, EDI, BX WIE OBEN
;-----------------------------------------------------------------------------
DMA_INIT PROC NEAR
MOV DX,CS:BASE_PORT ;STOP GUS DMA & CLEAR ALL PENDING IRQs
ADD DX,CommandPort
MOV AL,DMACtrl
OUT DX,AL
INC DX
INC DX
IN AL,DX ;CLEAR IRQ, BUT MASTER IRQ IS DISABLED
MOV DX,CS:BASE_PORT ;THERE HAPPENED NO IRQ
ADD DX,StatusPort
IN AL,DX
MOV BP,CS:DMA_CHANNEL
; MOVZX DX,CS:[DMA_RESET+BP] ;CASCADED DMA2 (MASTER) RESET
; OUT DX,AL ;RESET AUF MASTER DMA LOESCHT CASCADE
CMP BP,4
JAE SHORT NO_RESET1
MOVZX DX,CS:[DMA_RESET] ;DMA1 (SLAVE) MASTER CLEAR
OUT DX,AL
NO_RESET1:
MOV BP,BX
MOVZX EAX,CX ;CHECK 256K GUS DRAM BOUNDARY
SHL EAX,1 ;BECAUSE DMA IS NOT ABLE TO CROSS
INC EAX ;1 WORD LÄNGER-1 BYTE IST LETZTES BYTE
ADD EAX,EDI
SHR EAX,18
MOV EDX,EDI
SHR EDX,18
CMP EAX,EDX
JE SHORT DMA_NORMAL
PUSH SI CX
SHL EAX,18
SUB EAX,EDI
MOV CX,AX
SHR CX,1
PUSH CX
DEC CX
CALL DMA_PORTION ;FIRST PORTION
POP AX CX SI
SUB CX,AX
ADD SI,AX
ADD SI,AX ;REST: CORRECT OFFSET & SIZE
DMA_NORMAL:
MOV BX,CX ;SAMPLE UM EIN WORD VERLÄNGERN
SHL BX,1
DEC BX
MOV AL,[SI+BX]
MOV AH,AL
INC BX
MOV [SI+BX],AX
DMA_PORTION:
CLI
MOV BX,SI ;SETUP PC DMA CONTROLLER
MOV DX,DS
MOV AX,DX ;ADRESSE IN PAGE UND OFFSET UMRECHNEN
SHL DX,4
SHR AH,4 ;PAGE
ADD BX,DX ;OFFSET NEU
ADC AH,0
MOV AL,AH
MOV SI,CS:DMA_CHANNEL
CMP SI,4
JB SHORT GDMI1
SHRD BX,AX,1 ;ADRESSE FÜR 16-BIT DMA
JMP SHORT GDMI2
GDMI1: SHL CX,1 ;ZAEHLER FÜR 8-BIT DMA
INC CX ;SAMPLE ABSCHLUSS MIT EINEM WORD MEHR
GDMI2: MOVZX DX,CS:[DMA_MASK+SI]
MOV AL,BYTE PTR CS:DMA_CHANNEL
OR AL,4
OUT DX,AL ;DMA-KANAL MASKIEREN
MOVZX DX,CS:[DMA_MOD+SI]
AND AL,3
OR AL,01001000B
OUT DX,AL ;DMA-MODUS FÜR GUS
MOVZX DX,CS:[DMA_FLIP+SI]
OUT DX,AL ;FLIP-FLOP CLEAR
MOVZX DX,CS:[DMA_ADR+SI]
MOV AL,BL ;DMA CHANNEL 1-4
OUT DX,AL ;OFFSET LOW
MOV AL,BH
OUT DX,AL ;OFFSET HIGH
MOVZX DX,CS:[DMA_CNT+SI]
MOV AL,CL
OUT DX,AL ;SIZE LOW
MOV AL,CH
OUT DX,AL ;SIZE HIGH
MOVZX DX,CS:[DMA_PAGE+SI]
MOV AL,AH
OUT DX,AL ;PAGE
MOVZX DX,CS:[DMA_MASK+SI]
MOV AX,SI
AND AL,3
OUT DX,AL ;DMA-KANAL DEMASKIEREN
MOV DX,CS:BASE_PORT ;SETUP GUS FOR DMA TRANSFER
ADD DX,CommandPort
MOV AL,DMAAddr ;SET DMA ADDRESS
OUT DX,AL
MOV EAX,EDI
SHR EAX,4
CMP SI,4
JB SHORT GDMI3
MOV BX,AX ;CONVERT FOR 16-BIT TRANSFER
AND AX,03FFFH
SHR AX,1
AND BX,0C000H
OR AX,BX
GDMI3: INC DX
OUT DX,AX
DEC DX
MOV AL,DMACtrl
OUT DX,AL
INC DX
INC DX
MOV AX,SI
AND AL,4 ;SELECT 8/16-BIT CHANNEL
OR AX,BP ;SELECT AMIGA/PC
OR AL,00100001B ;START DMA TRANSFER
OUT DX,AL
STI
MOVZX DX,CS:[DMA_STAT+SI]
MOV AH,CS:[DMA_BITS+SI]
MOV EBX,800000H ;TIMEOUT
GDMI4: DEC EBX
JZ SHORT GDMI5
OR BL,BL
JNZ GDMI4
IN AL,DX ;WAIT FOR TRANSFER END
TEST AL,AH
JZ GDMI4
GDMI5: MOV DX,CS:BASE_PORT ;STOP GUS DMA
ADD DX,CommandPort
MOV AL,DMACtrl
OUT DX,AL
INC DX
INC DX
IN AL,DX ;CLEAR IRQ, BUT MASTER IRQ IS DISABLED
MOV DX,CS:BASE_PORT ;THERE HAPPENED NO IRQ
ADD DX,StatusPort
IN AL,DX
; MOVZX DX,CS:[DMA_RESET+SI] ;CASCADED DMA2 (MASTER) RESET
; OUT DX,AL ;RESET AUF MASTER DMA LOESCHT CASCADE
CMP SI,4
JAE SHORT NO_RESET2
MOVZX DX,CS:[DMA_RESET] ;DMA1 (SLAVE) MASTER CLEAR
OUT DX,AL
NO_RESET2:
AND ECX,0FFFFH ;INCREASE GUSMEM-POINTER
INC CX
CMP SI,4
JB SHORT GDMI6
SHL CX,1
GDMI6: ADD EDI,ECX
MOV CS:GUS_MEM,EDI
RET
DMA_INIT ENDP
;=============================================================================
;=============================================================================
PLAY_MUSIC PROC NEAR
PUSH CS
POP DS
CLI
MOV SI,54*2
MOV EBP,54
MOV CX,908-54+1
CountLoop:
XOR EDX,EDX
MOV EAX,369DE4H
DIV EBP
MOV EDX,100
MUL EDX
MOV EBX,Voices25
DIV EBX
SHR BX,1
ADC BX,0
CMP DX,BX
JB SHORT NoHigherFreq
INC AX
NoHigherFreq:
MOV [FREQ_TABLE+SI],AX
INC BP
ADD SI,2
LOOP CountLoop
MOV SAM_CH,8
MOV MOD_STAT,0
MOV PATT_ROW,64
MOVZX AX,SONG_START
MOV PATT_CURRENT,AX
MOV PATT_SPEED,6
MOV PATT_COUNT,1
MOV DI,OFFSET SAMP_CHANS
XOR BX,BX
MOV CX,CH_NUMB
ClearVarLoop:
MOV [DI.FREQ_VAL],0
MOV [DI.VOL],0
MOV AL,[PAN_REGS+BX]
SHL AL,4
OR AL,[PAN_REGS+BX]
MOV [DI.BALANCE],AL
INC BX
ADD DI,CHAN_SIZE
LOOP ClearVarLoop
XOR BX,BX ;Set Pan Regs!!
MOV CX,NumVoices
LLDM14: MOV DX,BASE_PORT
ADD DX,ActiveVoicePort
MOV AL,NumVoices
SUB AL,CL
OUT DX,AL
MOV DX,BASE_PORT
ADD DX,CommandPort
MOV AL,VoiceBalance
OUT DX,AL
MOV DX,BASE_PORT
ADD DX,DataHighPort
MOV AL,[PAN_REGS+BX]
OUT DX,AL
INC BX
LOOP LLDM14
MOV AL,125
CALL GO_SETBPM
MOV BPM_COUNT,0
MOV COUNTER,20
MOV DX,BASE_PORT ;Speaker On!!!
MOV AL,00000001B
OUT DX,AL
STI
CALL IRQ_INIT
RET
PLAY_MUSIC ENDP
;-----------------------------------------------------------------------------
STOP_MUSIC PROC NEAR
PUSH CS
POP DS
CALL IRQ_INIT
US_OFF: PUSH CS
POP DS
MOV DX,BASE_PORT ;Speaker Off!!!
MOV AL,00000011B
OUT DX,AL
MOV DX,BASE_PORT
ADD DX,ActiveVoicePort
MOV CX,NumVoices
VoiceClearL:
MOV AL,CL
DEC AL
OUT DX,AL
INC DX
MOV AL,WriteVoiceMode
OUT DX,AL
ADD DX,2
MOV AL,3 ;Voice Off
OUT DX,AL
SUB DX,2
MOV AL,VolumeCtrl
OUT DX,AL
ADD DX,2
MOV AL,3 ;Ramp Off
OUT DX,AL
SUB DX,3
LOOP VoiceClearL
RET
STOP_MUSIC ENDP
;-----------------------------------------------------------------------------
; SERVICE IRQ UMLEITUNG; USES THE REAL-TIME-CLOCK IRQ
;-----------------------------------------------------------------------------
IRQ_INIT PROC NEAR
CLI
XOR AX,AX
MOV ES,AX
CMP SYSTEM,0
JNE SHORT WU11
CMP VAR_BUFSEG,0
JNE SHORT WU13
MOV AX,COMP_SPEED2 ;XCHANGE INIT & STOP DATA FOR DOS
MOV DX,COMP_SPEED3
MOV COMP_SPEED2,DX
MOV COMP_SPEED3,AX
MOV AL,UHR_STATA ;UHR-IRQ-RATE EINSTELLEN (1024 HZ)
OUT UHR_INDEX,AL
JMP SHORT WU1
WU1: JMP SHORT WU2
WU2: XCHG AL,AH
IN AL,UHR_PORT
AND AL,0F0H
OR AL,DL
XCHG AL,AH
OUT UHR_INDEX,AL
JMP SHORT WU3
WU3: JMP SHORT WU4
WU4: XCHG AL,AH
OUT UHR_PORT,AL
JMP SHORT WU5
WU5: JMP SHORT WU6
WU6: MOV AL,UHR_STATB ;UHR-IRQ-MODUS EINSTELLEN
OUT UHR_INDEX,AL
JMP SHORT WU7
WU7: JMP SHORT WU8
WU8: XCHG AL,AH
IN AL,UHR_PORT
AND AL,08FH
MOV DL,DH
AND DL,40H
OR AL,DL
XCHG AL,AH
OUT UHR_INDEX,AL
JMP SHORT WU9
WU9: JMP SHORT WU10
WU10: XCHG AL,AH
OUT UHR_PORT,AL
IN AL,IRQ4 ;IRQ8 DE-/MASKIEREN
AND AL,0FEH
MOV DL,DH
AND DL,1
OR AL,DL
OUT IRQ4,AL
WU13: MOV BX,4*70H ;UHR-IRQ VERBIEGEN
MOV EAX,ES:[BX]
MOV EDX,HOLD70
MOV ES:[BX],EDX
MOV HOLD70,EAX
JMP SHORT WU12
WU11: CMP VAR_BUFSEG,0
JNE SHORT WU14
MOV AX,COMP_SPEED4 ;FOR WINDOWS
MOV DX,COMP_SPEED5
MOV COMP_SPEED4,DX
MOV COMP_SPEED5,AX
MOV AL,00110110B ;TIMER0 AUF 1.024 KHZ EINSTELLEN
OUT PIT1,AL ;TEILER=1193
MOV AL,DL
OUT TIMER0,AL
JMP SHORT OUT40
OUT40: MOV AL,DH
OUT TIMER0,AL
WU14: MOV BX,4*8H ;TIMEOUT-IRQ VERBIEGEN
MOV EAX,ES:[BX]
MOV EDX,HOLD70
MOV ES:[BX],EDX
MOV HOLD70,EAX
WU12: MOV AL,20H
OUT IRQ3,AL
OUT IRQ1,AL
STI
RET
IRQ_INIT ENDP
;-----------------------------------------------------------------------------
GET_SONGMOD PROC NEAR
MOV AL,CS:US_MODUS
RET
GET_SONGMOD ENDP
;-----------------------------------------------------------------------------
SET_SONGMOD PROC NEAR
AND AL,3
MOV CS:US_MODUS,AL
PUSH AX
XOR AH,AH
TEST AL,2
JNZ SHORT GSNG2
MOV AH,BYTE PTR CS:MUSIC_VOL
GSNG2: CALL SET_CDMIXER
POP AX
GSNG1: RET
SET_SONGMOD ENDP
;-----------------------------------------------------------------------------
GET_SONGPOSITION PROC NEAR
MOV AL,BYTE PTR CS:PATT_CURRENT
RET
GET_SONGPOSITION ENDP
;-----------------------------------------------------------------------------
SET_SONGPOSITION PROC NEAR
PUSH CX DI
AND AL,7FH
MOV BYTE PTR CS:PATT_CURRENT,AL
MOV CS:PATT_ROW,64
MOV DI,OFFSET SAMP_CHANS
MOV CX,CS:CH_NUMB
LSET1: MOV CS:[DI.VOL],0
MOV CS:[DI.INST_SET],0
ADD DI,CHAN_SIZE
LOOP LSET1
POP DI CX
RET
SET_SONGPOSITION ENDP
;-----------------------------------------------------------------------------
SET_SONGLOOP PROC NEAR
MOV CS:SONG_LOOP,AL
RET
SET_SONGLOOP ENDP
;-----------------------------------------------------------------------------
GET_VOLUME PROC NEAR
MOV AL,BYTE PTR CS:MASTER_VOLUME ;0= MIN VOLUME,255= MAX VOLUME
MOV BL,BYTE PTR CS:MUSIC_VOLUME ;0= MIN VOLUME,255= MAX VOLUME
MOV BH,BYTE PTR CS:FX_VOLUME ;0= MIN VOLUME,255= MAX VOLUME
RET
GET_VOLUME ENDP
;-----------------------------------------------------------------------------
SET_VOLUME PROC NEAR
MOV BYTE PTR CS:MASTER_VOLUME,AL ;0= MIN VOLUME,255= MAX VOLUME
MOV BYTE PTR CS:MUSIC_VOLUME,BL ;0= MIN VOLUME,255= MAX VOLUME
MOV BYTE PTR CS:FX_VOLUME,BH ;0= MIN VOLUME,255= MAX VOLUME
PUSH AX DX
MOVZX DX,AL
INC DX
PUSH DX
MOVZX AX,BL
MUL DX
MOV BYTE PTR CS:MUSIC_VOL,AH
CALL SET_CDMIXER
POP DX
MOVZX AX,BH
MUL DX
MOV BYTE PTR CS:FX_VOL,AH
POP DX AX
RET
SET_VOLUME ENDP
;-----------------------------------------------------------------------------
SET_CDMIXER PROC NEAR
CMP CS:CD_MIXER,0
JE GCD1
PUSH AX DX
MOV DX,CS:BASE_PORT ;DETECT GUS VERSION
ADD DX,GUS_VERSION ;GLEICH WIE ICMIX_SEL
IN AL,DX
CMP CS:ULTRA16,0 ;IST ULTRA16 ANGEGEBEN?
JNE SHORT GCD3
CMP AL,5 ;GUS BEFORE 3.7 NO MIXER
JL SHORT GCD2
CMP AL,10
JAE SHORT GCD3
SHR AH,1 ;ICS MIXER ON GUS 0-127
MOV AL,18 ;CD LINE LEFT CHANNEL
OUT DX,AL
ADD DX,ICMIX_DATA-ICMIX_SEL
MOV AL,AH
OUT DX,AL
ADD DX,ICMIX_SEL-ICMIX_DATA
MOV AL,19 ;CD LINE RIGHT CHANNEL
OUT DX,AL
ADD DX,ICMIX_DATA-ICMIX_SEL
MOV AL,AH
OUT DX,AL
ADD DX,ICMIX_SEL-ICMIX_DATA
MOV AL,10 ;LINE IN LEFT CHANNEL
OUT DX,AL
ADD DX,ICMIX_DATA-ICMIX_SEL
MOV AL,AH
OUT DX,AL
ADD DX,ICMIX_SEL-ICMIX_DATA
MOV AL,11 ;LINE IN RIGHT CHANNEL
OUT DX,AL
ADD DX,ICMIX_DATA-ICMIX_SEL
MOV AL,AH
OUT DX,AL
JMP SHORT GCD2
GCD3: MOV DX,CS:CODEC_PORT ;CODEC MIXER ON GUS MAX 31-0
SHR AH,3
JZ SHORT GCD4
XOR AH,80H
GCD4: XOR AH,9FH
MOV AL,4 ;CD LEFT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
DEC DX
MOV AL,5 ;CD RIGHT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
DEC DX
MOV AL,12H ;LINE IN LEFT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
DEC DX
MOV AL,13H ;LINE IN RIGHT CHANNEL
OUT DX,AL
INC DX
MOV AL,AH
OUT DX,AL
GCD2: POP DX AX
GCD1: RET
SET_CDMIXER ENDP
;-----------------------------------------------------------------------------
SET_LOADMOD_FLAG PROC NEAR
AND AL,1
MOV CS:LOADMOD_FLAG,AL ;0= NORMAL, 1= CD PLAYER MODUS
RET
SET_LOADMOD_FLAG ENDP
;-----------------------------------------------------------------------------
SET_IRQ_RATE PROC NEAR
PUSH CS
POP DS
MOV BPM_RATE,AX
MOV AX,BPM_VALUE
CALL Go_SetBPM
MOV CL,8
XOR SI,SI
SIR1: CMP BPM_RATE,512
JB SHORT SIR2
SHL [SAM_COUNT+SI],4
OR [SAM_COUNT+SI],8
JMP SHORT SIR3
SIR2: CMP [SAM_COUNT+SI],16
JB SHORT SIR3
SHR [SAM_COUNT+SI],4
SIR3: INC SI
INC SI
INC CL
CMP CL,NumVoices-1
JB SIR1
RET
SET_IRQ_RATE ENDP
;-----------------------------------------------------------------------------
; STARTET SAMPLE AUSGABE
; BX= SAMPLE-HANDLE, CX= FREQUENCE (HZ), AL= PANNING: 0= LEFT, 255=RIGHT
;-----------------------------------------------------------------------------
PLAY_SAMPLE PROC NEAR
PUSH CS
POP DS
TEST US_MODUS,1
JNZ GPSMP1
CLI
PUSH AX
MOV DI,OFFSET SAMPLE_CHAN
MOV [DI.OFFSET_ADD],0
MOV [DI.REPEAT],0
MOV AX,[SAMPLE_BIG+BX]
MOV [DI.LEN],AX
MOV DX,BPM_RATE
MUL DX
DIV CX
MOV DX,BPM_RATE
SHR DX,4
MOV BP,AX
SUB AX,DX
JNC SHORT LOW_COUNT
MOV AX,BP
LOW_COUNT:
CMP AX,DX
JAE SHORT LOW_COUNT2
MOV AX,BP
LOW_COUNT2:
MOVZX SI,SAM_CH
SUB SI,8
SHL SI,1
MOV [SAM_COUNT+SI],AX
MOV AX,100
MUL CX
MOV BP,Voices25
DIV BP
SHR BP,1
ADC BP,0
CMP DX,BP
JB SHORT NoHigherFreq2
INC AX
NoHigherFreq2:
MOV [DI.FREQ_VAL],AX
SHL BX,1
MOV EAX,[SAMPLE_MEM+BX]
MOV [DI.SAMP_OFF],EAX
MOV DX,BASE_PORT
ADD DX,CommandPort
DEC DX
MOV AL,SAM_CH
OUT DX,AL
INC DX
MOV AL,VoiceBalance
OUT DX,AL
INC DX
INC DX
POP AX
SHR AL,4
OUT DX,AL
DEC DX
DEC DX
MOV AH,3
CALL SEND_WRITE_VOICE
CALL WAIT_PORT
CALL SEND_SAMPLE_START
CALL SEND_SAMPLE_END
CALL SEND_SAMPLE_LOOP
MOV AH,3
CALL SEND_WRITE_VOICE
MOV BP,GUS_VOL ;SET VOLUME
MOV BX,FX_VOL
INC BX
SHR BX,2
CMP BL,40H
JBE SHORT FIXVL
MOV BL,40H
FIXVL: SHL BX,1
MOV BX,[GUS_VOL+BX]
XCHG BX,BP
CALL SEND_RAMP
MOV AL,SetVoiceFreq ;SET FREQUENCE
OUT DX,AL
INC DX
MOV AX,[DI.FREQ_VAL]
OUT DX,AX
DEC DX
DEC DX ;START VOICE
MOV AL,SAM_CH
OUT DX,AL
INC DX
MOV AH,0 ;NO LOOP
CALL SEND_WRITE_VOICE
CALL WAIT_PORT
STI
INC SAM_CH
CMP SAM_CH,NumVoices-1
JB SHORT GPSMP1
MOV SAM_CH,8
GPSMP1: RET
PLAY_SAMPLE ENDP
;-----------------------------------------------------------------------------
END_SAMPLE PROC NEAR
MOV CS:SAMPLE_ZEIG,0
RET
END_SAMPLE ENDP
;=============================================================================
;=============================================================================
; LOAD CONFIG DATA (PARSER)
; IN: CX=0C242H, DS:BX= POINTER TO PARAM-BLOCK
;
; PARAM-BLOCK: + 0 BASE PORT 210H-280H, 388H, ETC.
; + 2 DMA NUMBER 0-7
; + 3 IRQ NUMBER 0-15
; + 4 SAMPLE RATE 10000-44100
; + 6 INTERNAL TYPE 0,1,2,3,... (if necessary)
; + 7 INTERRUPT TYPE 0,1 (realtime clock, timer)
; + 8 STARTING POSITION 0-127
; + 9 LOOP POSITION 0-127,128
; +10 SONG MODUS 0-3
; +11 START MASTER VOLUME 0-255
; +12 START MUSIC VOLUME 0-255
; +13 START FX VOLUME 0-255
;-----------------------------------------------------------------------------
CONFIG_INIT PROC NEAR
MOV DX,DS
MOV AX,CS
MOV DS,AX
MOV WORD PTR HOLD70+2,AX
CMP CX,0C242H
JNE SHORT NORMAL_CONFIG
MOV ES,DX
MOV AX,ES:[BX]
MOV BASE_PORT,AX
ADD AX,CODEC_BASE
MOV CODEC_PORT,AX
MOV AL,ES:[BX+2]
AND AX,7
MOV DMA_CHANNEL,AX
MOV AL,ES:[BX+7]
AND AL,1
MOV SYSTEM,AL
MOV AL,ES:[BX+8]
AND AL,127
MOV SONG_START,AL
MOV AL,ES:[BX+9]
MOV SONG_LOOP,AL
MOV AL,ES:[BX+10]
AND AL,3
MOV US_MODUS,AL
MOV AL,ES:[BX+11]
MOV BX,ES:[BX+12]
CALL SET_VOLUME
JMP CONT_CONFIG
NORMAL_CONFIG:
MOV DX,OFFSET CONFIG_NAME
MOV AH,3DH
MOV AL,80H
INT 21H
JC GCFG1
MOV GDDHANDLE,AX
LCFG1: XOR SI,SI
MOV DX,OFFSET QUEUE_BUFFER
LCFG2: MOV AH,3FH
MOV BX,GDDHANDLE
MOV CX,1
INT 21H
JC SHORT GCFG2
OR AX,AX
JZ SHORT GCFG2
MOV DI,DX
CMP BYTE PTR [DI],0AH
JE SHORT GCFG6
INC DX
INC SI
CMP SI,256
JB LCFG2
GCFG6: MOV BX,OFFSET CFG_TEXT2
CALL SEEK_LINE
JNC SHORT GCFG4
LODSB
AND AL,1
MOV CD_MIXER,AL
LODSB
AND AL,3
MOV US_MODUS,AL
JMP LCFG1
GCFG4: MOV BX,OFFSET CFG_TEXT3
CALL SEEK_LINE
JNC SHORT GCFG5
INC SI
LODSB
DEC AL
AND AL,7
INC AL
SHL AL,4
MOV AH,2
MOV BASE_PORT,AX
ADD AX,CODEC_BASE
MOV CODEC_PORT,AX
JMP LCFG1
GCFG5: MOV BX,OFFSET CFG_TEXT5
CALL SEEK_LINE
JNC SHORT GCFG7
LODSB
AND AX,7
MOV DMA_CHANNEL,AX
JMP LCFG1
GCFG7: MOV BX,OFFSET CFG_TEXT7
CALL SEEK_LINE
JNC LCFG1
LODSB
AND AL,1
MOV SYSTEM,AL
JMP LCFG1
GCFG2: MOV BX,GDDHANDLE
MOV AH,3EH
INT 21H
CONT_CONFIG:
MOV AH,62H ;ULTRA16 ENVIRONMENT SUCHEN
INT 21H ;PSP VON AKTUELLEM EXE ODER COM HOLEN
MOV ES,BX
MOV BX,ES:[2CH] ;ENV SEG HOLEN
MOV ES,BX
XOR BX,BX
MOV ULTRA16,BX
LCFG3: CMP WORD PTR ES:[BX],0
JE SHORT GCFG11
CMP DWORD PTR ES:[BX],"61AR";CHECK ULTRA16 TEXT
JNE SHORT GCFG10
CMP DWORD PTR ES:[BX-3],"RTLU"
JNE SHORT GCFG10
ADD BX,4
LCFG4: INC BX
MOV AL,ES:[BX]
OR AL,AL
JZ SHORT GCFG11
CMP AL,"0"
JB LCFG4
CMP AL,"F"
JA LCFG4
CMP AL,"9"
JBE SHORT GCFG12
CMP AL,"A"
JB LCFG4
GCFG12: XOR DX,DX
LCFG5: MOV AL,ES:[BX]
CMP AL,"0"
JB SHORT GCFG13
CMP AL,"F"
JA SHORT GCFG13
CMP AL,"9"
JBE SHORT GCFG14
SUB AL,7
CMP AL,"A"-7
JB SHORT GCFG13
GCFG14: AND AL,0FH
SHL DX,4
OR DL,AL
INC BX
CMP BX,8000H
JB LCFG5
GCFG13: MOV CODEC_PORT,DX
MOV ULTRA16,1
JMP SHORT GCFG11
GCFG10: INC BX
CMP BX,8000H
JB LCFG3
GCFG11: CLC
GCFG1: RET
CONFIG_INIT ENDP
;-----------------------------------------------------------------------------
SEEK_LINE PROC NEAR
CLD
MOV SI,OFFSET QUEUE_BUFFER
LSKL1: PUSH BX
LSKL2: CMP BYTE PTR [BX],0
JE SHORT GSKL1
CMP SI,DX
JAE SHORT GSKL2
LODSB
CMP AL,[BX]
JNE SHORT GSKL3
INC BX
JMP LSKL2
GSKL3: POP BX
JMP LSKL1
GSKL2: POP BX
CLC
RET
GSKL1: POP BX
STC
RET
SEEK_LINE ENDP
;=============================================================================
;=============================================================================
;
; MOD LADEROUTINEN
;
;=============================================================================
; LÄDT EIN MODFILE
; DS:DX= FILENAME
;-----------------------------------------------------------------------------
LOAD_MOD PROC NEAR
MOV AX,3D00H ;OPEN MOD
INT 21H
JC GLDM1
PUSH CS
POP DS
MOV GDDHANDLE,AX
GLDM0: CALL SET_TMEM ;ALLOCATE TRACK-BUFFER
MOV BX,GDDHANDLE
MOV GDDZEIG,0
CMP LOADMOD_FLAG,0
JNE GLDM99
MOV CX,10 ;SONG-NAME HOLEN
LLDM1: CALL GET_QUEUE
JC GLDM2
LOOP LLDM1
XOR SI,SI ;31 INSTRUMENTS
LLDM2: MOV CX,11 ;INSTRUMENT NAME
LLDM3: CALL GET_QUEUE
JC GLDM2
LOOP LLDM3
XOR EAX,EAX
CALL GET_QUEUE ;INSTRUMENT SIZE
XCHG AL,AH
CMP AX,2
JAE SHORT GLDM20
XOR AX,AX
GLDM20: SHL AX,1
MOV [ISIZE+SI],AX ;HÖCHSTENS 64K
CALL GET_QUEUE ;IVOLUME & FINETUNE
PUSH AX
XOR AH,AH
MOV [IFINETUNE+SI],AX
POP AX
SHR AX,8
CMP AX,40H
JBE SHORT GLDM9
MOV AX,40H
GLDM9: MOV [IVOLUME+SI],AX
CALL GET_QUEUE ;ILOOP_START
XCHG AL,AH
SHL AX,1
MOV [ILOOP_START+SI],AX
CALL GET_QUEUE ;ILOOP_SIZE
XCHG AL,AH
SHL AX,1
MOV [ILOOP_SIZE+SI],AX
INC SI
INC SI
CMP SI,62
JB LLDM2
CALL GET_QUEUE ;SONG_SIZE & LOOP_BYTE OR NOTHING
JC GLDM2
MOV SONG_SIZE,AL
MOV SONG_LOOP,AH
XOR DX,DX
MOV CX,64 ;SONG_DATA
MOV DI,OFFSET SONG_DATA
LLDM4: CALL GET_QUEUE
JC GLDM2
MOV [DI],AX
CMP AL,DL ;FIND HIGHEST PATTERN NUMBER
JBE SHORT GLDM12
MOV DL,AL
GLDM12: CMP AH,DL
JBE SHORT GLDM13
MOV DL,AH
GLDM13: INC DI
INC DI
LOOP LLDM4
INC DL
CLD
MOV PATTERN_NUMBER,DX
CALL GET_QUEUE
PUSH AX
CALL GET_QUEUE
SHL EAX,16
POP AX
CMP EAX,"NHC8" ;8CHN-MOD
JE SHORT GLDM3
CMP EAX,"8TLF" ;FLT8-MOD
JE SHORT GLDM3
CMP EAX,"ATCO" ;OCTA-MOD
JE SHORT GLDM3
CMP EAX,"NHC6" ;6CHN-MOD
JE SHORT GLDM16
CMP EAX,".K.M" ;M.K.-MOD
JE SHORT GLDM10
CMP EAX,"4TLF" ;FLT4-MOD
JNE GLDM2
GLDM10: MOV CH_NUMB,4 ;4-CHANNEL-MOD
MOV PATTERN_SIZE,1024
MOV AH,0
MOV TRACK_INFO+4,AH
MOV TRACK_INFO+5,AH
MOV TRACK_INFO+6,AH
MOV TRACK_INFO+7,AH
JMP SHORT GLDM11
GLDM16: MOV CH_NUMB,6 ;6-CHANNEL-MOD
MOV PATTERN_SIZE,1536
MOV AH,0
MOV TRACK_INFO+6,AH
MOV TRACK_INFO+7,AH
JMP SHORT GLDM11
GLDM3: MOV CH_NUMB,8 ;8-CHANNEL-MOD: GET-PATTERNS
MOV PATTERN_SIZE,2048
GLDM11: MOV PATT_CURRENT,0
MOV TRACK_NUMBER,0
LLDM7: MOV ES,PATTERN_SEG
MOV BX,GDDHANDLE
XOR DI,DI
LLDM6: XOR SI,SI
LLDM5: CALL GET_QUEUE ;PATTERN HOLEN UND IN TRACKS AUFSPALTEN
JC GLDM2
MOV DX,AX
CALL GET_QUEUE
JC GLDM2
PUSH DI
ADD DI,SI
SHL EAX,16
MOV AX,DX
STOSD
POP DI
ADD SI,256
CMP SI,PATTERN_SIZE ;NEXT TRACK/CHANNEL
JB LLDM5
ADD DI,4 ;NEXT NOTE
CMP DI,256
JB LLDM6
MOV ES,TRACK_SEG ;TRACK1-8 INTEGRIEREN
MOV DX,TRACK_NUMBER
XCHG DL,DH
MOV DS,PATTERN_SEG
XOR SI,SI
XOR BX,BX
LLDM8: XOR DI,DI
LLDM9: CMP DX,DI
JBE SHORT GLDM4
PUSH SI DI
MOV CX,256/4
REPE CMPSD ;TRACK ALREADY EXISTS?
POP DI SI
PUSHF
ADD DI,256
POPF
JNE LLDM9
JMP SHORT GLDM5
GLDM4: INC DH ;NO, ADD TRACK TO BUFFER
PUSH SI
MOV CX,256/4
REP MOVSD
POP SI
GLDM5: MOV AX,DI ;YES
DEC AH
MOV CS:[TRACK_INFO+BX],AH
INC BX
ADD SI,256
CMP BX,CS:CH_NUMB
JB LLDM8
PUSH CS
POP DS
XCHG DL,DH
MOV TRACK_NUMBER,DX
XOR BX,BX ;TRACKLISTE NACHFÜHREN
MOV AX,PATT_CURRENT
LLDM10: CMP [SONG_DATA+BX],AL
JNE SHORT GLDM6
MOV AH,TRACK_INFO
MOV [TRACK1_DATA+BX],AH
MOV AH,TRACK_INFO+1
MOV [TRACK2_DATA+BX],AH
MOV AH,TRACK_INFO+2
MOV [TRACK3_DATA+BX],AH
MOV AH,TRACK_INFO+3
MOV [TRACK4_DATA+BX],AH
MOV AH,TRACK_INFO+4
MOV [TRACK5_DATA+BX],AH
MOV AH,TRACK_INFO+5
MOV [TRACK6_DATA+BX],AH
MOV AH,TRACK_INFO+6
MOV [TRACK7_DATA+BX],AH
MOV AH,TRACK_INFO+7
MOV [TRACK8_DATA+BX],AH
GLDM6: INC BX
CMP BL,128
JB LLDM10
INC PATT_CURRENT ;NÄCHSTES PATTERN HOLEN
MOV AX,PATT_CURRENT
CMP AX,PATTERN_NUMBER
JB LLDM7
JMP SHORT GLDM7
GLDM99: MOV ES,TRACK_SEG ;TRACK SEGMENT WIEDER LÖSCHEN
MOV AH,49H
INT 21H
MOV GUS_MEM,0
GLDM7: MOV ES,PATTERN_SEG ;PATTERN SEGMENT WIEDER LÖSCHEN
MOV AH,49H
INT 21H
MOV PATTERN_SEG,0
CALL INIT_DEVICE ;IS PROBABLY THE FIRST INIT
CMP LOADMOD_FLAG,0
JNE GLDM98
MOV BX,TRACK_NUMBER ;TRACK SEGMENT REDUZIEREN
SHL BX,4
MOV ES,TRACK_SEG
MOV AH,4AH
INT 21H
MOVZX AX,GDDZEIG ;FILEZEIGER KORRIGIEREN
OR AX,AX ;BUFFER ABHÄNGEN
JZ SHORT GLDM30
MOV DX,GDDREST
SUB DX,AX
JZ SHORT GLDM30
XOR CX,CX
MOV GDDZEIG,CL
MOV BX,GDDHANDLE
NEG DX
DEC CX
MOV AX,4201H ;DATEIZEIGER ZURÜCKBEWEGEN
INT 21H
GLDM30: MOV AH,48H ;SAMPLE BUFFER BEREIT
MOV BX,2000H ;128K WEGEN 64K DMA FENSTER
INT 21H
MOV GDDSEG,AX
TEST AX,0FFFH
JZ SHORT GLDM31
AND AX,0F000H
ADD AX,1000H
GLDM31: MOV BUFSEG,AX
XOR EDI,EDI ;SAMPLES LADEN
MOV GUS_MEM,EDI
XOR SI,SI
LLDM12: PUSH SI
MOV CX,[ISIZE+SI]
JCXZ SHORT GLDM8
SHL SI,1
TEST EDI,31
JZ SHORT GLDM32
AND EDI,-32 ;32 BYTE BOUND FOR DMA
ADD EDI,32
GLDM32: MOV [IOFFSET+SI],EDI
MOV BX,GDDHANDLE ;SAMPLE IN BUFFER LADEN
PUSH DS
XOR DX,DX
MOV SI,DX
MOV DS,BUFSEG
MOV AH,3FH
INT 21H
SHR CX,1
XOR BX,BX ;AMIGA-SAMPLE
CALL SEND_SAMPLE_DATA
POP DS
GLDM8: POP SI
INC SI
INC SI
CMP SI,62
JB LLDM12
MOV ES,GDDSEG ;SAMPLE BUFFER FREIGEBEN
MOV AH,49H
INT 21H
MOV GDDSEG,0
GLDM98: CLC
JMP SHORT GLDM15
GLDM2: STC
GLDM15: PUSHF
CMP VAR_BUFSEG,0
JNE SHORT GLDM97
MOV AH,3EH
MOV BX,GDDHANDLE
INT 21H
GLDM97: POPF
GLDM1: RET
LOAD_MOD ENDP
;-----------------------------------------------------------------------------
; HOLT EIN WORD AUS DEM BUFFER
; IN: AX= WORD, BX= HANDLE
;-----------------------------------------------------------------------------
GET_QUEUE PROC NEAR
CMP GDDZEIG,0
JNE SHORT GTQ1
PUSH CX DX
MOV DX,OFFSET QUEUE_BUFFER
MOV CX,256
MOV AH,3FH
INT 21H
MOV GDDREST,AX
POP DX CX
GTQ1: PUSH BX
MOV BL,GDDZEIG
XOR BH,BH
CMP BX,GDDREST
JAE SHORT GTQ2
MOV AX,[QUEUE_BUFFER+BX]
ADD GDDZEIG,2
POP BX
CLC
RET
GTQ2: POP BX
STC
RET
GET_QUEUE ENDP
;----------------------------------------------------------------------------
; RESERVIERT SPEICHER FÜR TRACKS, CARRY-FLAG 0=OK 1=ABBRUCH
;----------------------------------------------------------------------------
SET_TMEM PROC NEAR
MOV AH,48H
MOV BX,1000H ;64K TRACK BUFFER (WIRD RESIZED)
INT 21H
JC SHORT STCM1
MOV TRACK_SEG,AX
MOV AH,48H
MOV BX,80H ;2K PATTERN BUFFER
INT 21H
JC SHORT STCM1
MOV PATTERN_SEG,AX
STCM1: RET
SET_TMEM ENDP
;----------------------------------------------------------------------------
END_MUSIC PROC NEAR
CALL INIT_DEVICE
CMP LOADMOD_FLAG,0
JNE SHORT LEM3
MOV AH,49H
MOV ES,TRACK_SEG
INT 21H
CMP PATTERN_SEG,0
JE SHORT LEM3
MOV AH,49H
MOV ES,PATTERN_SEG
INT 21H
MOV PATTERN_SEG,0
LEM3: CMP GDDSEG,0
JE SHORT LEM4
MOV AH,49H
MOV ES,GDDSEG
INT 21H
MOV GDDSEG,0
LEM4: XOR EAX,EAX
MOV GDDLENGTH,EAX
MOV GDDREST,AX
MOV GDDHANDLE,AX
MOV GDDSEG,AX
MOV BUFSEG,AX
MOV GDDZEIG,AL ;RESET VARIABLES
MOV SAM_CH,8
MOV MOD_STAT,AL
XOR BX,BX
MOV CX,11
LEM1: MOV WORD PTR [BPM_COUNT+BX],AX
ADD BX,2
LOOP LEM1
MOV CH_NUMB,4
MOV TRACK_NUMBER,AX
MOV DWORD PTR TRACK_INFO,EAX
MOV DWORD PTR TRACK_INFO+4,EAX
MOV TRACK_SEG,AX
MOV BX,OFFSET TRACK1_DATA
LEM2: MOV [BX],AL
INC BX
CMP BX,OFFSET PATTJUMPS
JB LEM2
MOV IRQCOUNT,56
RET
END_MUSIC ENDP
;=============================================================================
; LÄDT EIN SAMPLE
; INPUT: DS:DX= FILENAME, CL= 00H AMIGA-SAMPLE, 80H PC-SAMPLE
; OUTPUT: AX= SAMPLE-HANDLE FOR PLAYING
;-----------------------------------------------------------------------------
LOAD_SAMPLE PROC NEAR
MOV AX,3D00H ;OPEN SAMPLE
INT 21H
JC GSMP1
PUSH CS
POP DS
MOV GDDHANDLE,AX
MOV BX,AX
PUSH CX
CALL GET_FILESIZE
POP CX
GSMP0: AND CL,80H
MOV CH,CL
PUSH DS CX
MOV GDDZEIG,0
MOV CX,AX
AND CX,0FFFEH
MOV AH,48H ;SAMPLE BUFFER BEREIT
MOV BX,2000H ;128K WEGEN 64K DMA FENSTER
INT 21H
MOV GDDSEG,AX
TEST AX,0FFFH
JZ SHORT GSMP2
AND AX,0F000H
ADD AX,1000H
GSMP2: MOV BUFSEG,AX
MOV EDI,GUS_MEM
TEST EDI,31
JZ SHORT GSMP3
AND EDI,-32 ;32 BYTE BOUND FOR DMA
ADD EDI,32
GSMP3: MOV SI,SAMPLE_ZEIG
MOV [SAMPLE_BIG+SI],CX
SHL SI,1
MOV [SAMPLE_MEM+SI],EDI
MOV BX,GDDHANDLE ;SAMPLE IN BUFFER LADEN
XOR DX,DX
MOV SI,DX
MOV DS,BUFSEG
MOV AH,3FH
INT 21H
SHR CX,1
POP BX
CLD
CALL SEND_SAMPLE_DATA
POP DS
MOV ES,GDDSEG ;SAMPLE BUFFER FREIGEBEN
MOV AH,49H
INT 21H
MOV GDDSEG,0
CMP VAR_BUFSEG,0
JNE SHORT GSMP5
MOV BX,GDDHANDLE
MOV AH,3EH
INT 21H
GSMP5: MOV AX,SAMPLE_ZEIG
ADD SAMPLE_ZEIG,2
CLC
GSMP1: RET
LOAD_SAMPLE ENDP
;-----------------------------------------------------------------------------
GET_FILESIZE PROC NEAR
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H
PUSH AX
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
POP AX
RET
GET_FILESIZE ENDP
;=============================================================================
IF COM_OR_OBJ
;=============================================================================
MAIN_CONT PROC NEAR
PUSH BP DS CS ES
POP DS
SHL DI,2
ADD DI,0100H
CALL DI ;FAR CALL
SETC DL
XOR DH,DH
POP DS BP ;BP IS ABSOLUTELY IMPORTANT FOR C
RETF
MAIN_CONT ENDP
;=============================================================================
ELSE
;=============================================================================
MAIN_CONT PROC NEAR
MOV AX,CS ;DS setzen
MOV DS,AX
MOV PROG_START_SEG,ES ;PROGRAMMANFANG
MOV AX,SS ;UND -ENDE MERKEN
MOV BX,OFFSET PROG_END
ADD BX,STACKLENGTH
MOV SP,BX
SHR BX,4
INC BX
ADD AX,BX
MOV PROG_END_SEG,AX
XOR BX,BX
GL1: MOV AL,ES:[82H+BX]
OR AL,AL
JZ SHORT GL2
CMP AL,20H
JE SHORT GL2
CMP AL,0DH
JE SHORT GL2
MOV [MOD_NAME+BX],AL
INC BX
CMP BX,40H
JB GL1
GL2: OR BX,BX
JZ GMEND
XOR AL,AL
MOV [MOD_NAME+BX],0
MOV BX,PROG_END_SEG ;SPEICHER FREI MACHEN
SUB BX,PROG_START_SEG
MOV ES,PROG_START_SEG
MOV AH,4AH ;SPEICHERBLOCKGRÖSSE ÄNDERN
INT 21H
MOV VAR_BUFSEG,0
;-----------------------------------------------------------------------------
; INITIALIZING & STARTING
; MOV AL,255 ;SET MAXIMUM VOLUME
; MOV BL,AL
; MOV BH,AL
; CALL SET_VOLUME
XOR CX,CX ;FD.CFG
CALL CONFIG_INIT ;GET CONFIG
; MOV LOADMOD_FLAG,1 ;CD TEST CONFIGURATION
; MOV CD_MIXER,1
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
CALL LOAD_SAMPLE
JNC SHORT GM2
MOV AH,9
MOV DX,OFFSET ERROR2_TEXT
INT 21H
GM2: CALL PLAY_MUSIC ;TRY STARTING
;-----------------------------------------------------------------------------
; THIS COULD BE THE MAIN ROUTINE
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
INC US_MODUS
MOV AL,US_MODUS
CALL SET_SONGMOD
JMP LM1
G4: CMP AL,"1"
JNE LM1
ADD PAN_FX,10H
MOV AL,PAN_FX ;PANNING
XOR BX,BX ;HANDLE
MOV CX,22222 ;FREQUENCE
CALL PLAY_SAMPLE
JMP LM1
;-----------------------------------------------------------------------------
; CUTTING OFF
GM5: CALL STOP_MUSIC ;STOP MUSIC
CALL END_SAMPLE ;UNLOAD SAMPLES
GM4: CALL END_MUSIC ;UNLOAD MUSIC
GMEND: MOV AX,4C00H ;BEENDEN NACH DOS
INT 21H
MAIN_CONT ENDP
;=============================================================================
ENDIF
CODE_SEG4 ENDS
END _MAIN4