Metropoli BBS
VIEWER: gusmod.asm MODE: TEXT (CP437)
;			      Gusmod v2.11
;	     By Joshua C. Jensen (CyberStrike of Renaissance)
;			 Copyright (C) 1992,1993
;═══════════════════════════════════════════════════════════════════════════════

ideal
P286
model	Huge
jumps

stack	1024

include "gusmod.inc"

Ins_Line	= 20
Vol_Column	= 24
Per_Column	= 74
Pan_Column	= 57
Name_Col	= 1
freek_Line      = 24
freek_Col	= 69
maxk_Line       = 24
maxk_Col        = 75
Seq_Row 	= 19

segment MyCode

		assume	cs:MyCode,ds:MyData

MMus            SMus    <>
P		PM	<>
MusBuf		dw	0
Chan            db      0
Music		dw	0,BlankMusicSeg
Mode		db	0		; 0 - Text
					; 1 - Graphics
PanPos		db	3,12,12,3
MaxVol		db	100
ChanVol 	db	100,100,100,100
PlayStat	db	0

GraphFile       db      'SCOPES.INF',0
ConfigFile	db	'GUSMOD.INF',0
GTSRConfigFile  db      'GTSR.INF',0
ScreenFile	db	'SCREEN.INF',0
GConfigFile	db	'GSETUP.CFG',0
TopOfMusic	dw	0

include 	"gmoddisp.asm"
include 	"modload.asm"

proc            WriteAltScrn1 near
		mov	ax,MyData
		mov	ds,ax
		call	WriteMemLeft

		call	GetInfo
		call	Ed_Sequence
                call    Ed_Percent
		call	Ed_Pan
		call	Ed_PlayStatus

		mov	[Word OldPos],0FFFFh
		ret
endp		WriteAltScrn1

proc            Ed_DoPat near
                push    si di cx
		push	cx
		cmp	[Byte Ed_DontDoPattern],0
		je	@@DrawNumbers
		mov	si,offset Ed_DashStr
		jmp	@@0A
@@DrawNumbers:	xchg	al,ah
		add	di,ax
		mov	al,[es:di]		; Sequence Channel number in AL
		push	es
		push	ds
		pop	es
		xor	ah,ah
		mov	di,offset Ed_Zeroes
		mov	cx,3
		call	MakeDec
		pop	es
		mov	si,offset Ed_Zeroes
@@0A:		pop	cx
		mov	ax,4
		mul	cx
		xor	dx,dx
		mov	di,(Seq_Row*80+18)*2-1
		add	di,ax
		add	di,ax
		mov	cx,3
		call	DirectWrite1
                pop     cx di si
                ret
endp		Ed_DoPat

proc            Ed_Sequence near
		push	ds
		mov	ax,MyData
		mov	ds,ax
		mov	es,ax
		mov	di,offset Ed_PatternStr+4
		mov	al,[cs:numpatterns]
                mov     cx,3
		call	MakeDec
		mov	di,offset Ed_PatternStr
		xor	ah,ah
		mov	al,[CurBlock]
		mov	cx,3
		call	MakeDec
		mov	di,(Seq_Row*80+1)*2-1
		mov	si,offset Ed_PatternStr
		mov	cx,7
		call	DirectWrite1

		mov	di,offset Ed_PatternStr
		xor	ah,ah
		mov	al,[cs:offset MMus+(offset (SMus).mt_SongPos)]
		mov	cx,3
		call	MakeDec
		mov	al,[cs:offset MMus+(offset (SMus).songlen)]
		dec	al
		mov	di,offset Ed_PatternStr+4
		xor	ah,ah
		mov	cx,3
		call	MakeDec
		mov	di,(Seq_Row*80+9)*2-1
		mov	si,offset Ed_PatternStr
		mov	cx,7
		call	DirectWrite1
		les	bx,[cs:offset MMus+(offset (SMus).HeaderLoc)]
		add	bx,(offset (HS).Sequences)
		mov	si,bx
		mov	di,bx
		sub	di,3
		mov	cx,0
@@2:		xor	ax,ax
		mov	ah,[cs:offset MMus+(offset (SMus).mt_SongPos)]
@@1:		add	ah,cl
		cmp	ah,3
		jge	@@2_1
@@2_0:		mov	[Byte Ed_DontDoPattern],01h
		jmp	@@3
@@2_1:		mov	bl,[cs:offset MMus+(offset (SMus).songlen)]
		add	bl,3
		cmp	ah,bl
		jge	@@2_0
@@3:		push	si
		call	Ed_DoPat
		pop	si
		mov	[Byte Ed_DontDoPattern],00h
		inc	cx
		cmp	cx,7
		jne	@@2
		pop	ds
                ret
endp		Ed_Sequence

TempStore	dw	0
Percent 	db	0
proc            Ed_Percent near
		push	ds es
		mov	ax,MyData
		mov	ds,ax
		mov	es,ax

		mov	di,offset Ed_Zeroes
                xor     ah,ah
                mov     al,[cs:offset MMus+(offset (SMus).MaxVolume)]
                mov     cl,101
                mul     cl
                mov     al,ah
		mov	[cs:Percent],al
		mov	cx,3
                call    MakeDec
		mov	di,(Seq_Row*80+63)*2-1
                mov     si,offset Ed_Zeroes
                mov     cx,3
                call    DirectWrite1

		mov	cx,0
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	[Word cs:TempStore],(Ins_Line*80+Per_Column)*2-1
@@ChannelLoop:	push	cx
		mov	di,offset Ed_Zeroes
		mov	al,[Byte cs:offset MMus+(offset (SMus).MaxVolume)]
		or	al,al
		je	@@SkipDiv
		xor	ah,ah
		mov	al,[es:bx+MS.MasterVolume]
		mov	cx,100
		mul	cx
		xor	dx,dx
		xor	ch,ch
		mov	cl,[cs:offset MMus+(offset (SMus).MaxVolume)]
		div	cx
@@SkipDiv:	push	es bx
		mov	cx,MyData
		mov	es,cx
		mov	cx,3
                call    MakeDec
		pop	bx es
		mov	di,[cs:TempStore]
		mov	si,offset Ed_Zeroes
		mov	cx,3
                call    DirectWrite1
		add	[Word cs:TempStore],160
		pop	cx
		add	bx,size MS
		inc	cx
		cmp	cx,4
		jne	@@ChannelLoop
		pop	es ds
		ret
endp            Ed_Percent

proc            Ed_Pan near
		push	ds es
		mov	ax,MyData
		mov	ds,ax
		mov	es,ax

		mov	cx,0
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	[Word cs:TempStore],(Ins_Line*80+Pan_Column)*2
@@ChannelLoop:	push	cx
		xor	dh,dh
		mov	dl,[es:bx+MS.sc_PanPosition]
		mov	di,[cs:TempStore]
		push	es
		mov	es,[cs:Screen]
		mov	cx,16
		mov	ax,0
		rep	stosw
		mov	di,[cs:TempStore]
		add	di,dx
		add	di,dx
                mov     ax,0FFEh
                stosw
		pop	es
		add	[Word cs:TempStore],160
		pop	cx
		add	bx,size MS
		inc	cx
		cmp	cx,4
		jne	@@ChannelLoop
		pop	es ds
		ret
endp		Ed_Pan

proc            FindNote near
                push    bx

		mov	al,[es:si]
		and	ax,00111111b
		mov	bx,ax
		shl	ax,1
		add	bx,ax
		add	bx,offset Notes
                mov     ax,[bx]                 ; Copy note string
                mov     [di],ax
                mov     al,[bx+02h]
                mov     [di+02h],al

		mov	al,[es:si+1]		; Get lo instrument number
                and     al,0f0h
                shr     al,4
                mov     ah,[es:si]              ; Get hi instrument number
		and	ah,11000000b
		shr	ah,2
                or      al,ah
                add     di,4

                push    es
                push    ds
                pop     es
                mov     cx,2
                call    MakeHex
                pop     es
                add     di,3

		mov	ax,[es:si+1]
                xchg    ah,al
                and     ax,0fffh
                push    ax
                mov     bx,ax
                cmp     bh,0
                jne     @@2_1
                cmp     al,0
                jne     @@2_1
                mov     ax,0
                jmp     @@2_2
@@2_1:          mov     ax,3
                inc     bh
                mul     bh
@@2_2:          add     ax,offset ARP
                mov     bx,ax
                mov     cx,3
@@3:            mov     ax,[bx]
                mov     [di],ax
                inc     bx
                inc     di
                loop    @@3
                pop     ax
                push    es
                push    ds
                pop     es
                mov     cx,2
                call    MakeHex
                pop     es
                add     di,2
		add	si,3
                pop     bx
                ret
endp            FindNote

proc            MakeOne near
                push    ds
                pop     es
		mov	di,offset PatternLine+1
		xor	dx,dx
		mov	ax,[TempPos]
		mov	bx,48
		div	bx
                mov     cx,3
                call    MakeDec

                mov     es,[CurLineSeg]
                mov     si,[TempPos]
		mov	di,offset PatternLine+5
                call    FindNote
		mov	di,offset PatternLine+19
                call    FindNote
		mov	di,offset PatternLine+33
                call    FindNote
		mov	di,offset PatternLine+47
                call    FindNote

                ret
endp            MakeOne

proc            GetEditSeg near
                push    es
                call    GetInfo
                xor     ax,ax
                mov     al,[cs:offset MMus+(offset (SMus).mt_SongPos)]
                les     di,[cs:offset MMus+(offset (SMus).HeaderLoc)]
                add     di,ax
		mov	al,[es:di+HS.Sequences]
                mov     [CurBlock],al
                mov     ax,[cs:offset MMus+(offset (SMus).EditSeg)]
                mov     di,[cs:offset MMus+(offset (SMus).EditOfs)]
		mov	es,ax
                mov     [CurLineSeg],es
                mov     [CurLineOfs],di
                pop     es
                ret
endp            GetEditSeg

proc            DisplayNine near
                push    ds

                mov     ax,MyData
                mov     ds,ax
                call    GetEditSeg
		mov	cx,13
		mov	di,959

                mov     bx,[CurLineOfs]
                mov     es,[CurLineSeg]
@@1:		sub	bx,7*48
                mov     [TempPos],bx
@@2:            mov     [CurCount],cx
                push    di

                mov     bx,[TempPos]
		add	bx,48
                mov     [TempPos],bx
                js      @@Signed
		cmp	bx,3072-48
                jg      @@Signed
                call    MakeOne

@@4:            pop     di
                mov     si,offset PatternLine
		mov	cx,60
                call    DirectWrite1
		add	di,40
                mov     cx,[CurCount]
                loop    @@2
                jmp     @@Done

@@Signed:       pop     di
                mov     si,offset BlankPatLine
		mov	cx,60
                call    DirectWrite1
		add	di,40
                mov     cx,[CurCount]
                loop    @@2

@@Done:         pop     ds
                ret
endp            DisplayNine

proc            ShowPatMode near
                mov     ax,MyData
                mov     ds,ax
                call    GetInfo
@@AAA:          mov     ax,[cs:offset MMus+(offset (SMus).mt_PatternPos)]
                cmp     [OldPos],ax
                jne     @@1
                ret
@@1:            mov     [OldPos],ax
                call    DisplayNine
                call    Ed_Sequence
                ret
endp            ShowPatMode

proc            GetInfo near
		mov	bx,9
		mov	cx,1
		mov	si,seg MMus
		mov	di,offset MMus
		call	[dword cs:Music]
		ret
endp		GetInfo

proc            SetInfo near
		mov	bx,0Ah
		mov	si,seg MMus
		mov	di,offset MMus
		call	[dword cs:Music]
                ret
endp		SetInfo

proc            FlipChannel near
		mov	al,[es:bx+MS.MasterVolume]
		or	al,al
		jne	@@TurnItOff
		mov	al,[cs:offset MMus+(offset (SMus).MaxVolume)]
		mov	[es:bx+MS.MasterVolume],al
		call	DisplayChannel
		ret
@@TurnItOff:
		mov	[Byte es:bx+MS.MasterVolume],0
		call	DisplayChannel
		ret
endp		FlipChannel

proc            DisplayChannel near
		push	es
		mov	di,(Seq_Row*80+49)*2-1
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		call	Channel_WriteIt
		add	di,4
		add	bx,size MS
		call	Channel_WriteIt
		add	di,4
		add	bx,size MS
		call	Channel_WriteIt
		add	di,4
		add	bx,size MS
		call	Channel_WriteIt
		add	di,4
		call	Ed_Percent
                pop     es
		ret
endp		DisplayChannel

proc            Channel_WriteIt near
		cmp	[es:bx+MS.MasterVolume],0
		je	CW1
		mov	al,0Fh
		jmp	CW2
CW1:		mov	al,01h
CW2:		push	es
		mov	cx,[cs:Screen]
		mov	es,cx
		mov	[es:di],al
		pop	es
		ret
endp		Channel_WriteIt

proc            WriteCh near
		push	es
		mov	es,[cs:Screen]
		mov	di,(Ins_Line*80+79)*2
		mov	cx,0
@@Looper:	mov	ax,0
		cmp	cl,[cs:Chan]
		jne	@@Store
		mov	ax,0A11h
@@Store:	mov	[es:di],ax
		add	di,160
		inc	cx
		cmp	cx,4
		jne	@@Looper
		pop	es
		ret
endp            WriteCh

proc            Ed_PlayStatus near
		push	es
		mov	es,[cs:Screen]
		mov	di,(24*80+1)*2
		mov	ax,0A0Fh
		cmp	[Byte cs:offset MMus+(offset (SMus).PlayStatus)],1
		je	@@Store
		mov	ax,0
@@Store:	stosw
		pop	es
		ret
endp		Ed_PlayStatus

proc            DoVolBar near
		push	ds es
		mov	di,(Ins_Line*80+Vol_Column)*2-1
		lds	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	cx,0
@@Looper:	push	cx di
		mov	ax,0EFEh
		xor	ch,ch
		mov	cl,[ds:bx+MS.DecVolume]
                shr     cx,1
		mov	dx,cx
                or      cx,cx
		je	@@DoEnd
		mov	al,254
		call	DirectWrite2
@@DoEnd:	mov	cx,32
		sub	cl,dl
		or	cx,cx
		je	@@EndOfChannel
		mov	al,0
		call	DirectWrite2
@@EndOfChannel: pop     di
		add	di,160
		add	bx,size MS
		pop	cx
		inc	cx
		cmp	cx,4
		jne	@@Looper
		pop	es ds
		ret
endp		DoVolBar

; CX - Instrument to write.
proc            WriteIns near
		push	ds bx
		mov	ax,cs
		mov	ds,ax
		mov	si,offset samples
;		 lds	 si,[cs:offset MMus+(offset (SMus).HeaderLoc)]
;		 add	 si,(offset (HS).Samples)
		mov	ax,size SampleRec
		mul	cx
		add	si,ax
		mov	cx,22
                mov     ah,0Fh
@@StoreLoop:	lodsb
                stosw
                loop    @@StoreLoop
		pop	bx ds
                ret
endp		WriteIns

proc            WriteAllIns near
		push	ds
                mov     es,[cs:Screen]
		mov	di,(Ins_Line*80+Name_Col)*2
		lds	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	cx,0
@@Looper:	push	cx di
		xor	ch,ch
		mov	cl,[ds:bx+MS.SampleNum]
		call	WriteIns
		pop	di
		add	di,160
		pop	cx
		add	bx,size MS
		inc	cx
		cmp	cx,4
		jne	@@Looper
		pop	ds
		ret
endp		WriteAllIns

include 	"sd.asm"
include 	"env.asm"
include 	"cmdline.asm"
include 	"config.asm"

proc            Terminate near
		mov	bx,5
		call	[dword ptr cs:Music]
		mov	bx,1		; Close down player.
		call	[dword ptr cs:Music]
		mov	ax,MyData
                mov     ds,ax
                mov     ah,0Eh
                mov     dl,[OldDrive]
                int     21h
                mov     ah,3Bh
                mov     dx,offset HomeDirectory - 1
                int     21h
                mov     ax,4C00h
                int     21h
endp            Terminate

proc            SetGrMode near
		mov	ax,13h
                int     10h
		mov	dx,3c8h
		mov	al,0
		out	dx,al
		inc	dl
		mov	cx,768
		mov	al,0
@@PutLoop:	out	dx,al
		loop	@@PutLoop
                ret
endp            SetGrMode

VoiceList	dw	20*320+16,20*320+174,123*320+174,123*320+16
CurOsc		dw	0
CurOscOfs	dw	0
OscData 	db	1040 dup (0)
proc            Osc near
		push	ds
		lds	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	dx,0a000h
                mov     es,dx
		mov	cx,0
		mov	[Word cs:CurOscOfs],0
@@PLoop:	push	cx		; Channels
		push	ds bx		; ChannelLoc Pointer
		mov	si,[cs:CurOsc]
;		 mov	 al,[ds:bx+MS.volume]
;		 mul	 [Byte ds:bx+MS.MasterVolume]
;		 mov	 al,ah
;		 push	 ax
		cmp	[ds:bx+MS.MasterVolume],0
		jnz	@@GetIt
		mov	al,0
		mov	bx,0
		jmp	@@Skip2
@@GetIt:	mov	al,[ds:bx+MS.sc_Voice]
		mov	bx,0Bh
		push	si		; Save CurOsc
		call	[dword cs:Music]
		mov	ax,si
		pop	si
@@Skip2:  ;	 pop	 bx
;		 imul	 bl
;		 mov	 al,ah
		xor	al,80h
		shr	al,2		; 0-63 range
		add	si,[cs:CurOscOfs]	; CurOscOfs+CurOsc
		xor	ah,ah		; Byte to screen
		inc	al
		mov	bx,cx		; Channel
		shl	bx,1		;  *2
		mov	cx,320		; Byte * 320
		mul	cx
		mov	di,ax		; Destination = Byte * 320
		add	di,[cs:bx+VoiceList]	; Destination + Screen Offset
		mov	cx,[cs:CurOsc]	; CurOsc / 2
		shr	cx,1
		add	di,cx		; Destination + CurOsc/2
		mov	dx,[Word cs:si+OscData]       ; Get Old VGA Loc
                cmp     di,dx           ; Are they the same?
		jz	@@SkipIt	; Yes.
		xchg	di,dx		; Kill the one.
                xor     [Byte es:di],00100000b
		xchg	di,dx		; Store the other.
                xor     [Byte es:di],00100000b
@@SkipIt:	mov	[Word cs:si+OscData],di       ; Save New dest.
		pop	bx ds		; Pop ChannelLoc Pointer
		pop	cx		; Pop Channels
		add	bx,size MS	; Next structure.
		add	[Word cs:CurOscOfs],260
		inc	cx
		cmp	cx,4
		jne	@@PLoop
		add	[Word cs:CurOsc],2
		cmp	[Word cs:CurOsc],130*2-1 ;Are we at end of the oscilloscope display?
		jb	@@Skip
		mov	[Word cs:CurOsc],0
@@Skip: 	pop	ds
		ret
endp		Osc

assume          ds:MyData

proc            Error near
                mov     ax,MyData
		mov	ds,ax
		call	RestoreMode
                mov     ah,9
                int     21h
		mov	ah,0
		int	16h
                call    Terminate
endp            Error

; si - Filename offset
proc            PutName
		push	ds es
		mov	ax,MyData
                mov     es,ax
		mov	di,[es:PutFilename]
		mov	ax,cs
                mov     ds,ax
                mov     cx,12
		rep	movsb
		mov	al,0
		stosb
		pop	es ds
		ret
endp            PutName

proc		DisplayTextScreen
		call	SetMode
		mov	si,offset ScreenFile
                call    PutName
		mov	dx,offset GDirectory
                mov     cx,seg GDirectory
                push    ds
                mov     ds,cx
                mov     ax,3D00h
                int     21h
                jb      @@NoFind
                pop     ds
                mov     bx,ax
                push    bx
                call    GetDecodeSizes
                pop     bx
		mov	ax,[cs:Screen]
                mov     es,ax
                mov     di,0
                push    bx
                call    Decode
                pop     bx
                mov     ah,3Eh
                int     21h
		call	WriteAltScrn1
		call	WriteCh
		ret
@@NoFind:	pop	ds
		ret
endp            DisplayTextScreen

proc		DisplayGraph
		mov	si,offset GraphFile
                call    PutName
		mov	dx,offset GDirectory
                mov     cx,seg GDirectory
                push    ds
                mov     ds,cx
                mov     ax,3D00h
                int     21h
                jb      @@NoFind
                pop     ds
                mov     bx,ax
                push    bx
                call    SetGrMode
                pop     bx
                push    bx
                call    GetDecodeSizes
                pop     bx
                mov     ax,0A000h
                mov     es,ax
                mov     di,0
                push    bx
                call    Decode
                pop     bx
                mov     ah,3Eh
                int     21h
                mov     dx,3c8h
                mov     al,0
                out     dx,al
                inc     dl
                mov     cx,768
                push    ds es
                mov     ax,0A000h
                mov     ds,ax
                mov     si,64000
@@PutLoop:      lodsb
                out     dx,al
                loop    @@PutLoop
                mov     ax,cs
                mov     es,ax
                mov     di,offset OscData
                mov     cx,130*4
                mov     ax,0
                rep     stosw
                pop     es ds
                mov     [Word cs:CurOsc],0
		ret
@@NoFind:	mov	[Byte cs:Mode],0
		call	DisplayTextScreen
		ret
endp            DisplayGraph

proc		DisplaySpectrum
;		 call	 SetGrMode
;		 call	 ClearAna
;		 mov	 ax,13h
;		 int	 10h
		ret
endp		DisplaySpectrum

AnaSave 	dw	44 dup (0)
;AnaOfs 	 dw	 0,320,640,960,1280,1600
;		 dw
;		 dw
;		 dw
;		 dw
		dw	000F0h

proc		ClearAna
		ret
		push	ds
		cli
		lds	si,[cs:offset MMus+(offset (SMus).AnalyzerLoc)]
                mov     bp,offset AnaSave
		mov	cx,22
cahloop:	mov	[Word si],0
		mov	[Word cs:bp],0
		add	si,2
		add	bp,2
		loop	cahloop
		sti
		pop	ds
                ret
endp            ClearAna

proc            DoSpectrum
		ret
		push	ds
		lds	si,[cs:offset MMus+(offset (SMus).AnalyzerLoc)]
		mov	bp,offset AnaSave
		mov	ax,0A000h
		mov	es,ax
		mov	di,(199-36)*320
		mov	cx,22
spanlab1:	push	cx
		push	di
		mov	bx,[si]
		add	si,2
		cmp	bx,36
		jb	spanskip2
		mov	bx,36
spanskip2:	mov	cx,[cs:bp]
		add	bp,2
		cmp	cx,bx
		jz	spanskip3
		jb	span_r2
		mov	ax,32
		sub	ax,cx
		mov	cx,ax
;                sub     cx,bx
		dec	cx
		mov	ax,320
		mul	bx
;		 add	 bx,bx
		add	di,ax
;                mov     di,[cs:bx+AnaOfs]
		mov	bx,cx
		or	bx,bx
		jz	spanskip3
		mov	ax,0E0Eh
spanloop:       mov     cx,3
		rep	stosw
		sub	di,320+6
		dec	bx
		jnz	spanloop
		jmp	spanskip3
span_r2:	sub	bx,cx
		dec	bx
;		 shl	 cx,1
		mov	ax,320
		mul	cx
                add     di,ax
;                mov     di,[cs:bx+AnaOfs]
		or	bx,bx
		jz	spanskip3
		mov	ax,0F0Fh
spanloop2:      mov     cx,3
		rep	stosw
		sub	di,320+6
		dec	bx
		jnz	spanloop2
spanskip3:	pop	di
		add	di,7
		pop	cx
		loop	spanlab1
		lds	si,[cs:offset MMus+(offset (SMus).AnalyzerLoc)]
                mov     bp,offset AnaSave
		mov	cx,22
spanloop3:	mov	bx,[si]
		mov	[cs:bp],bx
		add	bp,2
		or	bx,bx
		jz	spanskip4
		dec	bx
spanskip4:	mov	[si],bx
		add	si,2
		loop	spanloop3
		pop	ds
		ret


;@@DrawLarge:	 push	 cx
;		 push	 di
;		 mov	 bx,[si]
;		 xor	 bh,bh
;		 and	 bx,36
;		 mov	 dx,bx
;		 or	 bx,bx
;		 jz	 @@ClearUp
;		 mov	 ax,0F0Fh
;@@DrawUp:	 mov	 cx,3
;		 rep	 stosw
;		 sub	 di,320+6
;		 dec	 bx
;		 jnz	 @@DrawUp
;@@ClearUp:	 mov	 bx,36
;;		  sub	  bx,dx
;		 or	 bx,bx
;		 jz	 @@ClearDone
;		 mov	 ax,0000h
;@@DrawCUp:	 mov	 cx,3
;		 rep	 stosw
;		 sub	 di,320+320+6
;		 dec	 bx
;		 jnz	 @@DrawCUp
;@@ClearDone:	 sub	 [Word si],1
;		 add	 si,2
;		 pop	 di
;		 add	 di,7
;		 pop	 cx
;		 loop	 @@DrawLarge
;		 pop	 ds
;		 ret
endp            DoSpectrum

include 	"gmodfile.asm"

proc		LoadFile
                call    FileSelect
                jb      @@EndError
                mov     cx,cs
                mov     si,offset P
                mov     bx,5
                call    [dword ptr cs:Music]
		mov	cx,es
                call    MUS_LoadModule
                call    GetInfo
                mov     [Byte cs:offset MMus+(offset (SMus).mt_speed)],6
                mov     [Byte cs:offset MMus+(offset (SMus).mt_counter)],5
                mov     cx,0
                call    SetInfo
@@End:          clc
                ret
@@EndError:	call	RestoreMode
                call    Terminate
		stc
                ret
endp            LoadFile

proc            FileSelect
                mov     di,55
                mov     bx,0
                mov     ah,1Fh
                mov     al,1
                mov     cx,24
		mov	dx,25
                call    DrawBox
                call    DisplayAll
                mov     ax,MyData
                mov     ds,ax
@@TopLoop:      mov     ah,0
                int     16h
;──────────────────────────────────────────────────────────
@@Key_Up:       cmp     ah,72
                jne     @@Key_Down
                cmp     [Word CurFile],0
                jz      @@Beep
                dec     [Word CurFile]
                mov     bx,[CurFile]
                sub     bx,[TopFile]
                jns     @@PrintIt
                dec     [Word TopFile]
                jmp     @@PrintIt
;──────────────────────────────────────────────────────────
@@Key_Down:     cmp     ah,80
                jne     @@Key_Home
                mov     bx,[NumFiles]
                dec     bx
                cmp     [CurFile],bx
                jz      @@Beep
                inc     [Word CurFile]
                mov     bx,[CurFile]
                sub     bx,[TopFile]
		cmp	bx,23
                jl      @@PrintIt
                inc     [Word TopFile]
                jmp     @@PrintIt
;──────────────────────────────────────────────────────────
@@Key_Home:     cmp     ah,71
                jne     @@Key_End
                cmp     [Word CurFile],0
                jnz     @@SetTop
                cmp     [Word TopFile],0
                jz      @@Beep
@@SetTop:       mov     [Word CurFile],0
                mov     [Word TopFile],0
                jmp     @@PrintIt
;──────────────────────────────────────────────────────────
@@Key_End:      cmp     ah,79
                jne     @@Key_PgUp
                mov     bx,[NumFiles]
                dec     bx
                cmp     [CurFile],bx
                jnz     @@SetBottom
                sub     bx,[TopFile]
		cmp	bx,23
                jl      @@Beep
@@SetBottom:    mov     bx,[NumFiles]
                dec     bx
                mov     [CurFile],bx
		sub	bx,22
                js      @@FixBottom
                mov     [TopFile],bx
                jmp     @@PrintIt
@@FixBottom:    mov     [Word TopFile],0
                jmp     @@PrintIt
;──────────────────────────────────────────────────────────
@@Key_PgUp:     cmp     ah,73
                jne     @@Key_PgDn
                cmp     [Word CurFile],0
                jz      @@Beep
		sub	[Word CurFile],23
                js      @@FixPgUp
		sub	[Word TopFile],23
                js      @@FixPgUp2
                jmp     @@PrintIt
@@FixPgUp:      mov     [Word CurFile],0
@@FixPgUp2:     mov     [Word TopFile],0
                jmp     @@PrintIt
;──────────────────────────────────────────────────────────
@@Key_PgDn:     cmp     ah,81
                jne     @@Key_Enter
                mov     dx,[NumFiles]
                dec     dx
                cmp     [CurFile],dx
                jz      @@Beep
		add	[Word CurFile],23
                cmp     [CurFile],dx
                jg      @@FixPgDn
		add	[Word TopFile],23
                cmp     [Word TopFile],dx
                jg      @@FixPgDn2
                jmp     @@PrintIt
@@FixPgDn:      mov     [Word CurFile],dx
@@FixPgDn2:	sub	dx,22
                js      @@FixPgDn3
                mov     [TopFile],dx
                jmp     @@PrintIt
@@FixPgDn3:     mov     [Word TopFile],0
                jmp     @@PrintIt
;──────────────────────────────────────────────────────────
@@Key_Enter:    cmp     al,13
                jnz     @@Key_Esc
                call    SelectFile
                jnb     @@End
                clc
                ret
;──────────────────────────────────────────────────────────
@@Key_Esc:      cmp     ah,1
                jnz     @@End
                stc
                ret
;──────────────────────────────────────────────────────────
@@Beep:         clc
                jmp     @@End
;──────────────────────────────────────────────────────────
@@PrintIt:      call    DisplayAll
                clc
                jmp     @@End
;──────────────────────────────────────────────────────────
@@End:          jmp     @@TopLoop
endp            FileSelect

proc            SelectFile
                push    ds
                mov     ax,size FStruc
                mul     [CurFile]
                lds     di,[FileSeg]
                add     di,ax
                mov     dx,di
                cmp     [di+FStruc.TypeOfFile],F_Directory
                jnz     @@MustBeAModule
                mov     AH,3Bh
                int     21h             ;2-Change_Directory
                call    ReadFiles
                call    DisplayAll
                pop     ds
                clc
                ret
@@MustBeAModule:
                mov     ax,ds
                mov     es,ax
                pop     ds
                stc
                ret
endp            SelectFile

;                Mode    =  0    -->  Outline
;                           1    -->  Fill
; cx - SizeX
; dx - SizeY
; ah - Color
; al - Mode
; di - X
; bx - Y
proc            DrawBox
                push    es ax dx
                mov     ax,[cs:Screen]
                mov     es,ax
                add     di,di
                mov     ax,160
                mul     bx
                add     di,ax

                mov     bx,160
                sub     bx,cx
                sub     bx,cx

                cld
                pop     dx ax
                cmp     al,1
                jne     @@OutlineTop
                mov     al,' '
@@FillLoop:     push    cx
                rep     stosw
                add     di,bx
                pop     cx
                dec     dx
                jnz     @@FillLoop
                jmp     @@Done

@@OutlineTop:   push    cx
                rep     stosb
                add     di,bx
                pop     cx
@@OutlineSides: stosb
                add     di,cx
                sub     di,2
                stosb
                add     di,bx
                dec     dx
                cmp     dx,2
                jne     @@OutlineSides

@@OutlineBottom:pop     cx
                rep     stosb

@@Done:         pop     es
                ret
endp            DrawBox


ScreenF         db      'SCREEN.BIN',0

PspAddress      dw      ?
SizeOfProg      dw      ?
TopOfData	dw	?

proc		Main
Start:          mov     [cs:PspAddress],es
                mov     ax,zzzzzseg
                inc     ax
                mov     [cs:TopOfData],ax

		call	HowMuchMemory
		call	DetermineDisplay
		mov	ax,MyData
                mov     ds,ax
                mov     ah,47h
                mov     dl,0
                mov     si,offset HomeDirectory
                int     21h
                mov     ah,19h
                int     21h
                mov     [OldDrive],al

		; ──── write title
		mov	ax,MyData
		mov	ds,ax
		mov	ah,9
		mov	dx,offset GusmodTitle
		int	21h

		call	SetEnv
@@LoadDriver:   mov     si,offset SoundFile
		call	PutName
		mov	dx,offset GDirectory
		mov	cx,seg GDirectory
                call    LoadSoundDriver
		jnb	@@DriverLoaded
		mov	dx,offset NoDriverFound
                call    Error
@@DriverLoaded: call	ReadGConfig
		mov	ax,[cs:GUSIRQ]
                mov     bx,0
		mov	cx,[cs:GUSMIDI]
		mov	dx,[cs:GUSPort]
		mov	si,[cs:DMAIn]
		mov	di,[cs:DMAOut]
		call	[dword ptr cs:Music]
                jnb     @@FoundCard
		mov	dx,offset NoGUS
		call	Error
@@FoundCard:	mov	[cs:GUSIRQ],si
		mov	[cs:GUSPort],di
		call	LoadCommandLine

		cmp	[Byte cs:Interactive],0
		jz	@@LoadItFromLine
		mov	ax,MyData
                mov     ds,ax
                xor     dx,dx
                mov     ax,size FStruc
                mov     bx,[MaxFiles]
                mul     bx
                mov     bx,ax
                shr     bx,4
                add     bx,1
		mov	ax,[cs:TopOfData]
		mov	[Word FileSeg+2],ax
                mov     [Word FileSeg],0
		add	[Word cs:TopOfData],bx
		call	ReadFiles

                mov     ax,[cs:TopOfData]
		mov	[cs:MusBuf],ax
		add	[Word cs:TopOfData],4096/16
		mov	ax,[cs:TopOfData]
		mov	[cs:TopOfMusic],ax

@@InteractiveTop:
		call	LoadFile
		jb	@@nofile
		jmp	@@BeginPlay

@@LoadItFromLine:
		mov	ax,[cs:TopOfData]
		mov	[cs:MusBuf],ax
                add     [Word cs:TopOfData],4096/16
                ; Load the module.
		mov	cx,ds
		mov	dx,130
		call	MUS_LoadModule
		jb	@@nofile
		jmp	@@BeginPlay

@@noargv:	mov	dx,offset NoFileName
		call	Error
@@nofile:	mov	dx,offset NoFileFound
		call	Error
@@BeginPlay:	mov	si,offset ConfigFile
                call    ReadConfig

		mov	[Word cs:offset P+(offset (PM).MusBuf)],0
		mov	ax,[cs:MusBuf]
		mov	[Word cs:offset P+(offset (PM).MusBuf)+2],ax
                mov     [Word cs:offset P+(offset (PM).Header)],offset PS16Header
		mov	[Word cs:offset P+(offset (PM).Header)+2],cs
		mov	[Word cs:offset P+(offset (PM).PatternLoc)],offset PatternLoc
		mov	[Word cs:offset P+(offset (PM).PatternLoc)+2],cs
		mov	[Word cs:offset P+(offset (PM).InsLoc)],offset InsLoc
		mov	[Word cs:offset P+(offset (PM).InsLoc)+2],cs
		mov	[Word cs:offset P+(offset (PM).mt_speed)],6
		mov	[Word cs:offset P+(offset (PM).mt_counter)],5
		mov	[Word cs:offset P+(offset (PM).mt_PatternPos)],0
		mov	[Word cs:offset P+(offset (PM).mt_SongPos)],0
@@PlayStart:    mov     cx,cs
		mov	si,offset P
		mov	bx,4
		call	[dword cs:Music]
@@DisplayScr:	cmp	[cs:Mode],0
		jnz	@@GraphicDisp
		call	DisplayTextScreen
		jmp	@@PollLoop
@@GraphicDisp:	cmp	[cs:Mode],1
		jnz	@@GraphicSp
		call	DisplayGraph
		jmp	@@PollLoop
@@GraphicSp:	call	DisplaySpectrum
@@PollLoop:	mov	bx,0Ch
		call	[dword cs:Music]
		cmp	si,1
		jz	@@MusicDone
		cmp	[cs:Mode],0
		jne	@@DoOsc
		call	ShowPatMode
		call	WriteAllIns
		call	DoVolBar
		jmp	@@CheckKey
@@DoOsc:	cmp	[Byte cs:Mode],1
		jne	@@DoSpect
		call	Osc
		jmp	@@CheckKey
@@DoSpect:	call	DoSpectrum
@@CheckKey:	mov	ah,1
		int	16h
		je	@@PollLoop
                mov     ah,0
		int	16h
		call	GetInfo
@@Key_F1:       cmp     ah,3Bh
		jne	@@Key_F2
                mov     si,offset ConfigFile
                call    WriteConfig
                jmp     @@End
;──────────────────────────────────────────────────────────
@@Key_F2:	cmp	ah,3Ch
                jne     @@Key_F3
                mov     si,offset ConfigFile
                call    ReadConfig
		jmp	@@DisplayScr
;──────────────────────────────────────────────────────────
@@Key_F3:       cmp     ah,3Dh
                jne     @@Key_F4
                mov     si,offset GTSRConfigFile
		call	WriteConfig
                jmp     @@DisplayScr
;──────────────────────────────────────────────────────────
@@Key_F4:       cmp     ah,3Eh
                jne     @@Key_Tab
                mov     si,offset GTSRConfigFile
                call    ReadConfig
                jmp     @@DisplayScr
;──────────────────────────────────────────────────────────
@@Key_Tab:	cmp	al,9
		jne	@@Key_Space
		inc	[Byte cs:Mode]
		and	[Byte cs:Mode],1
		cmp	[Byte cs:Mode],1
		jz	@@GraphicScope
		cmp	[Byte cs:Mode],2
		jz	@@GraphicSpectrum
		cmp	[cs:Mode],0
		jne	@@GraphicScope
		call	DisplayTextScreen
		jmp	@@End
@@GraphicScope: call	DisplayGraph
		jmp	@@End
@@GraphicSpectrum:
		call	DisplaySpectrum
		jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_Space:	cmp	al,' '
		jne	@@Key_Plus
		call	GetInfo
		xor	[Byte cs:offset MMus+(offset (SMus).PlayStatus)],1
		call	Ed_PlayStatus
                mov     cx,00000010b
                call    SetInfo
		jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_Plus:     cmp     al,'='
		jne	@@Key_Minus
		call	GetInfo
		cmp	[Byte cs:offset MMus+(offset (SMus).MaxVolume)],255
		je	@@Key_Plus_1
		inc	[Byte cs:offset MMus+(offset (SMus).MaxVolume)]
		mov	cx,00000001b
                call    SetInfo
		call	Ed_Percent
@@Key_Plus_1:   jmp     @@End
;──────────────────────────────────────────────────────────
@@Key_Minus:    cmp     al,'-'
		jne	@@Key_Up
		call	GetInfo
		cmp	[Byte cs:offset MMus+(offset (SMus).MaxVolume)],0
		je	@@Key_Plus_1
		dec	[Byte cs:offset MMus+(offset (SMus).MaxVolume)]
		mov	cx,00000001b
                call    SetInfo
		call	Ed_Percent
@@Key_Minus_1:  jmp     @@End
;──────────────────────────────────────────────────────────
@@Key_Up:	cmp	ah,72
		jne	@@Key_Down
		cmp	[Byte cs:Chan],0
		je	@@Key_Up_1
		dec	[Byte cs:Chan]
		call	WriteCh
@@Key_Up_1:	jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_Down:	cmp	ah,80
		jne	@@Key_Left
		cmp	[Byte cs:Chan],3
		je	@@Key_Down_1
		inc	[Byte cs:Chan]
		call	WriteCh
@@Key_Down_1:	jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_Left:	cmp	ah,75
		jne	@@Key_Right
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	ax,size MS
		xor	ch,ch
		mov	cl,[cs:Chan]
		mul	cx
                add     bx,ax
                cmp     [es:bx+MS.sc_PanPosition],0
		je	@@Key_Left_1
		cli
		dec	[Byte es:bx+MS.sc_PanPosition]
		sti
		call	Ed_Pan
@@Key_Left_1:   jmp     @@End
;──────────────────────────────────────────────────────────
@@Key_Right:	cmp	ah,77
		jne	@@Key_LBrack
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	ax,size MS
		xor	ch,ch
		mov	cl,[cs:Chan]
		mul	cx
		add	bx,ax
		cmp	[es:bx+MS.sc_PanPosition],15
		je	@@Key_Right_1
		cli
		inc	[Byte es:bx+MS.sc_PanPosition]
		sti
		call	Ed_Pan
@@Key_Right_1:  jmp     @@End
;──────────────────────────────────────────────────────────
@@Key_LBrack:	cmp	al,'['
		jne	@@Key_RBrack
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	ax,size MS
		xor	ch,ch
		mov	cl,[cs:Chan]
		mul	cx
                add     bx,ax
		cmp	[es:bx+MS.MasterVolume],0
		je	@@Key_LBrack_1
		cli
		dec	[Byte es:bx+MS.MasterVolume]
		sti
		call	Ed_Percent
@@Key_LBrack_1: jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_RBrack:	cmp	al,']'
		jne	@@Key_Home
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		mov	ax,size MS
		xor	ch,ch
		mov	cl,[cs:Chan]
		mul	cx
		add	bx,ax
		mov	al,[cs:offset MMus+(offset (SMus).MaxVolume)]
		cmp	[es:bx+MS.MasterVolume],al
		je	@@Key_RBrack_1
		cli
		inc	[Byte es:bx+MS.MasterVolume]
		sti
		call	Ed_Percent
@@Key_RBrack_1: jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_Home:     cmp     ah,71
		jne	@@Key_End
		mov	[Word cs:offset MMus+(offset (SMus).mt_PatternPos)],0
		mov	cx,00000010b
                call    SetInfo
                call    DisplayNine
		jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_End:	cmp	ah,79
		jne	@@Key_PgUp
		mov	[Word cs:offset MMus+(offset (SMus).mt_PatternPos)],3F0h
		mov	cx,00000010b
                call    SetInfo
                call    DisplayNine
		jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_PgUp:	cmp	ah,73
		jne	@@Key_PgDn
		cmp	[Byte cs:MMus+(offset (SMus).mt_SongPos)],0
		je	@@Key_F7_1
		dec	[Byte cs:offset MMus+(offset (SMus).mt_SongPos)]
@@Key_F7_1:	mov	[Word cs:offset MMus+(offset (SMus).mt_PatternPos)],0
		mov	cx,00000010b
                call    SetInfo
                call    GetEditSeg
		call	DisplayNine
		call	Ed_Sequence
		jmp	@@End
;──────────────────────────────────────────────────────────
@@Key_PgDn:	cmp	ah,81
		jne	@@KeyChannel1
		mov	al,[cs:offset MMus+(offset (SMus).songlen)]
		dec	al
		cmp	[cs:offset MMus+(offset (SMus).mt_SongPos)],al
		je	@@Key_F8_1
		inc	[Byte cs:offset MMus+(offset (SMus).mt_SongPos)]
@@Key_F8_1:	mov	[Word cs:offset MMus+(offset (SMus).mt_PatternPos)],0
		mov	cx,00000010b
                call    SetInfo
		call	GetEditSeg
		call	DisplayNine
		call	Ed_Sequence
		jmp	@@End
;──────────────────────────────────────────────────────────
@@KeyChannel1:	cmp	al,'1'
		jne	@@KeyChannel2
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		call	FlipChannel
		jmp	@@End

;──────────────────────────────────────────────────────────
@@KeyChannel2:	cmp	al,'2'
		jne	@@KeyChannel3
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		add	bx,size MS
		call	FlipChannel
		jmp	@@End

;──────────────────────────────────────────────────────────
@@KeyChannel3:	cmp	al,'3'
		jne	@@KeyChannel4
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		add	bx,size MS*2
                call    FlipChannel
                jmp     @@End

;──────────────────────────────────────────────────────────
@@KeyChannel4:	cmp	al,'4'
		jne	@@NormalKeys
		call	GetInfo
		les	bx,[cs:offset MMus+(offset (SMus).ChannelLoc)]
		add	bx,size MS*3
                call    FlipChannel
                jmp     @@End

;──────────────────────────────────────────────────────────
@@NormalKeys:	cmp	ah,1
		je	@@Exit
@@End:		jmp	@@PollLoop
@@MusicDone:	cmp	[Byte cs:TerminateFlag],0
		jz	@@Exit
		mov	ah,0
                int     16h
		cmp	al,' '
		jz	@@PlayStart
		cmp	ah,1
		je	@@Exit
		jmp	@@MusicDone
@@Exit: 	cmp	[Byte cs:Interactive],0
		je	@@NoInteractive
		mov	ax,[cs:TopOfMusic]
		mov	[cs:TopOfData],ax
		jmp	@@InteractiveTop
@@NoInteractive:call    RestoreMode
		call	Terminate
endp            Main

ends            MyCode

segment 	BlankMusicSeg
		stc
		retf
ends		BlankMusicSeg

segment         MyData
GusmodTitle	db	'Gusmod 2.11 By Joshua C. Jensen (CyberStrike of Renaissance)',13,10,'$'
NoGUS           db      '1: Could not detect a Gravis Ultrasound card.',13,10,'$'
NoFileName	db	'2: Usage: GUSMOD filename<.mod>',13,10,'$'
NoFileFound	db	'3: Module not found.',13,10,'$'
NoDriverFound	db	'4: Sound driver not found.',13,10,'$'
NoEnvFound	db	'5: The environment variable GUSMOD was not found.',13,10,'$'
NoGCFound	db	'6: GSETUP.CFG not found.  Run SETUP.',13,10,'$'

GDirectory      db      120 dup (0)
GEnv		db	6,"GUSMOD"
PutFilename	dw	0

db  '\'
HomeDirectory   db      80 dup (0)
OldDrive        db      0

ARP             db      "   ArpPrPrTonVibT&SV&STrm??8So=VlsJmpVolBrk**ESpd"
Notes		db	'---C-0C#0D-0D#0E-0F-0F#0G-0G#0A-0A#0B-0'
		db	'C-1C#1D-1D#1E-1F-1F#1G-1G#1A-1A#1B-1'
		db	'C-2C#2D-2D#2E-2F-2F#2G-2G#2A-2A#2B-2'
		db	'C-3C#3D-3D#3E-3F-3F#3G-3G#3A-3A#3B-3'
		db	'C-4C#4D-4D#4E-4F-4F#4G-4G#4A-4A#4B-4'

CurLineSeg      dw      0
CurLineOfs      dw      0
BlankPatLine	db	'║   ║      │     ║║      │     ║║      │     ║║      │     ║',0
PatternLine	db	'║   ║      │     ║║      │     ║║      │     ║║      │     ║',0
CurBlock        db      0
TempPos         dw      0
CurCount        dw      0
OldPos          dw      0FFFFh

Ed_DashStr              db      "---",0
Ed_SpeedStr             db      "000/000",0
Ed_PatternStr           db      "000/000",0
Ed_Zeroes               db      "000",0
Ed_DontDoPattern        db      0
Ed_4Hex 		db	"0000",0
Ed_IRQ			db	"00",0

NewDTA		DTA	<>

MaxFiles        dw      500
NumFiles        dw      0
FileSeg         dd      0

WildDir         db      "*.*",0
WildMod         db      "*.MOD",0
DriveLetter     db      "-:\"
CurPath         db      65 dup (0)

DriveStr        db      "-:",0
DriveList       db      26 dup (0)

MKLine          db      9 dup (0)
Ext             db      4 dup (0)
ExtBlank        db      "~ ",0
DesBlank        db      "~ ",0

FileDigits      db      "0000",0

CurFile         dw      0
TopFile         dw      0

ends    MyData

segment zzzzzseg
	db	16 dup (?)
ends	zzzzzseg

        end     Start

[ RETURN TO DIRECTORY ]