
data segment    ; data things here

include \nxdos\src\tbx_data.inc
data ends

code   segment
       assume cs:code, ds:data, es:data, ss:_stack
        jmp     start
include \nxdos\src\tbx_code.inc
       
start:  mov  ax, data    ; Establish data and extra segment addressability 
        mov  ds, ax      ; aka  setup the stack n' data segments
        mov  es, ax
main:   ; main code go here!
        call cs:sbinfo
exit:   call dosexit
_dma_reset PROC  near
        mov  dx,DMA_Mask
        mov  ax,reset_cmd
        add  ax,cs:[Channel]
        out  dx,al
        mov  ax,0
        ret
DMA_Mask        EQU     0Ah     ;DMAC DMA_Mask (write-only)
Mode            EQU     0Bh     ;DMAC mode (read/write)
byte_ptr        EQU     00ch    ; byte pointer flip-flop
addr	       	EQU	000h	; per-channel base address
ddcount         EQU     001h    ; per-channel byte count
read_cmd        EQU     048h    ; read mode
write_cmd       EQU     044h    ; write mode
set_cmd         EQU     000h    ; DMA_Mask set
reset_cmd       EQU     004h    ; DMA_Mask reset
channel         dw 0
ENDP _dma_reset

_dma_done PROC
        mov  dx,cs:[Channel]
        shl  dx,1
        add  dx,ddcount
        cli
        in   al,dx
        mov  ah,al
        in   al,dx
        xchg al,ah
        ret
ENDP _dma_done

_dma_setup PROC

        mov  cs:[_dma_errno],0
        mov  bx,cs:[WORD PTR Buffer]
        mov  ax,cs:[WORD PTR Buffer+2]
	mov  cl,4
        rol  ax,cl
        mov  ch,al
        and  al,0F0h
        add  ax,bx
        adc  ch,0
        and  ch,0Fh
        mov  di,ax

        mov  bx,cs:[Channel]
        shl  bx,1

        cmp  cs:[WORD PTR Dir],0
         jnz SHORT @@Do_Read
        mov  al,write_cmd
         jmp SHORT @@Do_Mode
@@Do_Read:
  	mov  al,read_cmd
@@Do_Mode:
        push cx
        mov  cx,cs:[Channel]
  	add  al,cl
        xor ah,ah
        mov  si,ax
        mov  ax,set_cmd
        add  al,cl
        pop  cx
        mov  cl,al
        mov  ax,di              ;Let's check the address to see if we
        add  ax,cs:[Len]        ;span a page boundary with our length
        ;jnc @@BoundaryOk        ;Do we?
        ;mov  cs:[_dma_errno],2  ; y: Error #2
        ;mov  ax,-1              ;    Return -1
        ;jmp @@ExitPt            ;    See ya...
@@BoundaryOk:                   ; n: Continue with action
        cli                     ;Disable interrupts while mucking with DMA

        mov  dx,byte_ptr        ;Reset byte pointer Flip/flop
        out  dx,al              ;All we have to do is write to it

        mov  ax,di              ;ax=LSW of 20-bit address
        mov  dx,bx              ;dx=DMAC Base Address port
	out  dx,al              ;Store LSB
        mov  al,ah
        out  dx,al              ;Store next byte

        mov  al,ch              ;al=Page number
        mov  dx,cs:[bx + OFFSET page_table]        ;dx=Port is the "Page index"
        out  dx,al              ;Store the page

        mov  ax,cs:[Len]
        mov  dx,bx              ;dx=DMAC Base Adress port
        inc  dx                 ;dx=DMAC Count port (1 after Base address)
        out  dx,al              ;Write LSB of Length
        mov  al,ah
        out  dx,al              ;Write MSB

        mov  ax,si              ;Load pre-calculated mode
        mov  dx,Mode            ;dx=DMAC mode register
        out  dx,al              ;Write it to the DSP

        mov  dx,DMA_Mask        ;dx=DMAX DMA_Mask register
        mov  al,cl              ;al=pre-calulated DMA_Mask value
        out  dx,al              ;Write DMA_Mask
        mov  ax,0               ;Return with no error

@@ExitPt:                       ;Restore stack and return
        ret
;ARG Channel:WORD,Buffer:DWORD,Len:WORD,Dir:WORD
buffer          dw 0,0
len             dw 0
dir             dw 0
_dma_errno   DW 0
page_table     	DW	00087h	; channel 0
	       	DW	00083h	; channel 1
	       	DW	00081h	; channel 2
  	       	DW	00082h	; channel 3

ENDP _dma_setup                 

Sb_Init2  proc
    mov al,1
    mov dx,cs:[SbIOaddr]
    add dx,6
    out dx,al
    in	al,dx
    in	al,dx
    in	al,dx
    in	al,dx
    mov al,0
    out dx,al
    add dx,4
    mov cx,100
@@1:
    in al,dx
    cmp al,0AAh
    je @@2
    loop @@1
    mov  ax,1
    ret
@@2:
    mov ax,0
    ret
SbDMAchan dw      1
SbType    dw      2

Sb_Init2  endp

sb_samplerate   proc near
                JMP sloop1
sloop1:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE sloop1
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                MOV AL,040h
                OUT DX,AL
                JMP sloop2
sloop2:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE sloop2
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                MOV AL,cs:[srate2];B[BP-1]
                OUT DX,AL

                ret
srate           dw 0
srate2          db 0bfh;0a6h

sb_samplerate    endp

sb_voice        proc near
                JMP vloop1
vloop1:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE vloop1
                CMP cs:[voice],0
                JE vloop3
                MOV AL,0D1h
                JMP vloop2
vloop3:
                MOV AL,0D3h
vloop2:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                OUT DX,AL

                RET

voice           dw 0
sb_voice        endp

sb_haltdma      proc near
                JMP hloop1
hloop1:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE hloop1
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                MOV AL,0D0h
                OUT DX,AL
                RET
sb_haltdma      endp
startit         proc near
                MOV DX,cs:[sbioaddr]
                ADD DX,4
                MOV AL,0Eh
                OUT DX,AL
                MOV DX,cs:[sbioaddr]
                ADD DX,5
                MOV AL,013h
                OUT DX,AL
                JMP stloop1
stloop1:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE stloop1

                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                MOV AL,014h
                OUT DX,AL
                JMP stloop2
stloop2:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE stloop2

                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                MOV AL,byte ptr cs:[len];35h;cs:[len];B[BP+0A]
                AND AL,0FFh
                OUT DX,AL
                JMP stloop3
stloop3:
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                IN AL,DX
                MOV AH,0
                TEST AX,080h
                JNE stloop3

                MOV AX,cs:[len];035bah;W[BP+0A]
                sub ax,30
                MOV CL,8
                SHR AX,CL
                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
                OUT DX,AL

                ret
startit         endp
dovoc           proc near
                push cs
                pop ds
                push cs
                pop es

                ;call sb_init2

                call sb_samplerate
                mov cs:[voice],1
                call sb_voice
                mov cs:[channel],1
                call _dma_reset
                mov ax,cs:[plays]


                mov cs:[buffer+2],ax
                mov cs:[buffer],0

                ;mov cs:[len],10000

                mov cs:[dir],1
                call _dma_setup
                call startit
                ;call _dma_done
                ret
dovoc           endp

doload          proc near

                mov bx,2000h
                call grabmem
                jc dole
                mov cs:[holdmem],ax

                mov bx,ax
                and bx,0fffh
                or bx,bx
                jz memok
                and ax,0f000h
                add ax,01000h
memok:
                mov cs:[plays],ax

                mov ax,3d00h
                lea dx,input;msound1
                push cs
                pop ds
                int 21h
                jc dole
                mov cs:[handle1],ax

                mov ah,3fh
                mov bx,cs:[handle1]
                mov cx,-1
                mov ds,cs:[plays]
                xor dx,dx
                int 21h
                mov cs:[len],ax

                mov ah,3eh
                mov bx,cs:[handle1]
                int 21h

                call iswave

                call dovoc

                mov es,cs:[holdmem]
                mov ah,49h
                int 21h

                clc
                ret
dole:
                stc
                ret

handle1         dw 0
msound1         db 'missile.smp',0,'grenade.smp',0,'sheep.smp',0
plays           dw 0
holdmem         dw 0
pname           db 'c:\asm\f.exe',0
doload          endp

grabmem         proc near

                mov ah,48h
                mov cs:[gmem],bx
                int 21h
                jnc nogr1
nogr1:
                ret
gmem            dw 0
grabmem         endp
window1	 proc near
                add di,cs:[screenwidth]
		push di
		mov al,cs:[si]
		stosw
		mov al,cs:[si+1]
		xor ch,ch
		mov cl,dl
                sub cl,2
		rep stosw
		mov al,cs:[si+2]
		stosw
                cmp cs:[shadow],1
                jne win1a
                mov es:[di+1],byte ptr 07h
                mov es:[di+3],byte ptr 07h
win1a:
                add si,3
		pop di
		ret
window1         endp
window2         proc near
		push di
		call window1
		pop di
		xor ch,ch
		mov cl,dl
		shl cx,1
                add di,cs:[screenwidth]

                ret
window2         endp
windowb         proc near               ;dh -len
box1:                                   ;dl -height
                mov cs:[windsiz],dx
                push dx
                push ax
                mov ax,cs:[screenwidth]
                shr ax,1
                sub ax,2
                and dh,254
                sub al,dh
                add di,ax
                pop ax
                pop dx
                mov cs:[shadow],1
                jmp box1c
box1nc:
                mov cs:[shadow],0
box1c:
                mov cs:[windsiz],dx
                mov cs:[wpos1],di
                push si
windtype:       lea si,wind1
winbeg:
                mov es,cs:[video]
		push di
                push ax

                add dx,202h
		xchg dh,dl
		mov ah,ch
                sub di,cs:[screenwidth]
                push word ptr cs:[shadow]
                mov cs:[shadow],0
                call window1
                pop word ptr cs:[shadow]
win1:
                call window2
		sub si,3
		dec dh
		cmp dh,2
		jne win1
		add si,3
                call window2
                add di,cs:[screenwidth]
                add di,2

                cmp cs:[shadow],0
                je win22
                add di,3
		xor ch,ch
		mov cl,dl
win21:
                mov es:[di],byte ptr 7
                add di,2
                loop win21
win22:
                pop ax
		pop di
		pop si
		ret

wind1           db 'ÉÍ»º ºÈÍ¼'
wind2           db 'ÚÄ¿³ ³ÀÄÙ'
shadow          db 0
windsiz         dw 0
windpos         dw 0
wpos1           dw 0
windowb         endp
box2nc          proc near
                lea si,wind2
                lea bp,windtype
                inc bp
                mov cs:[bp],word ptr si
                call box1nc
                lea si,wind1
                mov cs:[bp],word ptr si

                ret
box2nc          endp
clear proc near
                push es
                mov es,cs:[video]

                or cx,cx
                jz nocl3a
                cmp cx,4000
                ja nocl3a
                push ax
                mov al,20h
                mov ah,cs:[col]
                or ah,ah
                jz nocols4
clear22:
                mov es:[di],ax
                add di,2
                loop clear22

allcols1:
                pop ax
nocl3a:
                pop es
                ret
nocols4:
                mov es:[di],al
                add di,2
                loop nocols4
                jmp allcols1

clear2:
                mov es:[di],ax
                add di,2
                loop clear2

                ret
clear           endp
hide proc near
                push ds
                push di
                push cx
                push dx

                mov ax,cs:[screenwidth]
                shr ax,1
                sub ax,2
                sub al,dh
                add di,ax
                jmp skiphide2
hide2:
                push ds
                push di
                push cx
                push dx
skiphide2:
                xor ah,ah
                mov al,dh
                shl ax,1
                add ax,4
                xor dh,dh
                add dx,4
                mul dx

                add ax,4
                mov cx,8
                div cx
                ;shr ax,3
                inc ax
                mov bx,ax
                mov ah,48h
                int 21h
                jnc bbp6

                mov ax,cs:[video]
                add ax,100h
bbp6:
                mov cs:[shide],ax

                pop dx
                push dx

                mov ds,ax
                xor si,si
                mov ds:[si],di
                mov ds:[si+2],dx
                mov cl,dh
                xor ch,ch
                shl cx,1
                add cx,4
                add dl,4
                add si,4
kil2:
                push di
                push cx
kil1:
                mov ax,es:[di]
                mov ds:[si],ax
                add si,2
                add di,2
                loop kil1
                pop cx
                pop di

                add di,cs:[screenwidth]
                dec dl
                or dl,dl
                jnz kil2
bbp1:
                pop dx
                pop cx
                pop di
                pop ds
                ret
shide           dw 0
hide            endp
show proc near
                push ds

                call waitretrace

                mov es,cs:[video]
                mov ds,cs:[shide]
                xor si,si
                mov di,ds:[si]
                mov dx,ds:[si+2]
                mov cl,dh
                xor ch,ch
                shl cx,1
                add cx,04h
                add dl,4
                add si,4
                push dx

                mov bh,dh
kol2:
                mov dh,bh
                push di
                push cx
kol1:
                mov ax,ds:[si]
                mov es:[di],ax
                add si,2
                add di,2
                loop kol1
                pop cx
                pop di
                add di,cs:[screenwidth]
                dec dl
                or dl,dl
                jnz kol2

bbp2:
                mov ax,cs:[shide]
                call fuckmem

                pop ax
                pop ds
                ret
show            endp
waitretrace	proc	near
                push ax
                push dx

                mov     dx,03dah
xvert:
		in	al,dx
		and	al,8
		jz	xvert
xvert1:
		in	al,dx
		and	al,8
		jnz	xvert1

                pop dx
                pop ax
		ret
waitretrace	endp

hex4            proc near
                push es
                mov es,cs:[video]
                jmp hex4a
hex4b:
                push es
hex4a:
                push ax

                push ax
                mov al,ah
                call hex2
                pop ax
                call hex2
                pop ax
                pop es
                ret
hex4            endp
hex2            proc near
                push ax
                and al,011110000b
                shr al,4
                call hex1
                pop ax
                push ax
                and al,01111b
                call hex1
                pop ax
                ret
hex2            endp
hex1            proc near
                push es
                mov es,cs:[video]
                mov ah,cs:[col]
                cmp al,10
                jb hnum1
                add al,'A'-10
                jmp hnum2
hnum1:
                add al,'0'
hnum2:
                mov es:[di],ax
                add di,2
                pop es
                ret
hex1            endp
waitkey         proc near

startkeychk:

                call iskey
                jc startkeychk

                cmp al,0
                je startkeychk

		ret
keyseg          dw 40h
keyflag         db 0
waitkey         endp
iskey           proc near
                push es
                push di

                xor ax,ax

                mov ah,1
                int 16h
                jz nokey1
                or ax,ax
                jz iskey3

		mov es,cs:[keyseg]
                mov di,es:[1ah]
                mov es:[1ch],di

                mov al,ah
                jmp nokey2
iskey3:
                in al,60h

                push es
		mov es,cs:[keyseg]
                mov di,es:[1ah]
                mov es:[1ch],di
                mov ah,es:[di]
                pop es

                cmp al,0
                je nokey1

                in al,60h
                clc
                jmp nokey2
nokey1:
		mov es,cs:[keyseg]
                mov di,es:[1ah]
                cmp di,es:[1ch]
                je nokey3

                mov ah,1
                int 16h
                jmp iskey3
nokey3:
                stc
nokey2:
                pop di
                pop es
                ret
iskey           endp
fuckmem         proc near
                or ax,ax
                jz gofmem

                push es
                mov es,ax
                mov ah,49h
                int 21h
                pop es
gofmem:
                ret
fuckmem         endp
numshow         proc near
                mov es,cs:[video]

                or cl,cl
                jz dputu6

                mov bl,4
                cmp cl,3
                jbe dputul2
                mov bl,cs:[ctemp]
dputul2:
                mov ah,cs:[col]
                or ah,ah
                jz nocols2
dputul1:
                mov al,cs:[si]
                mov es:[di],ax
                add di,2
                inc si

                dec cl
                or cl,cl
                jz dputu6

                or bl,bl
                jnz dputu5
                mov al,','
                mov es:[di],ax
                add di,2
                mov bl,3
dputu5:
                dec bl

                jmp dputul1
dputu6:

                ret
nocols2:
ncdputul1:
                mov al,cs:[si]
                mov es:[di],al
                add di,2
                inc si

                dec cl
                or cl,cl
                jz ncdputu6

                or bl,bl
                jnz ncdputu5
                mov es:[di],byte ptr ','
                add di,2
                mov bl,3
ncdputu5:
                dec bl

                jmp ncdputul1
ncdputu6:
                ret
numshow         endp

;
; Putul prints the value in DX:AX as an unsigned dword integer value.
;
sl_PutUL        proc    near
                lea si,numbspace
                push    ax
                push    bx
                ;push    cx
                push    dx
                call    PutI2

                mov cx,si
                lea si,numbspace
                sub cx,si

                pop     dx
                ;pop     cx
                pop     bx
                pop     ax
                ret
sl_PutUL        endp
;
; PutI2- Recursive routine to actually print the value in AX as an integer.
;
Puti2           proc    near
                call    Div10
                cmp     ax, dx          ;See if dx:ax=0
                jnz     NotDone
                or      ax, ax
		jz	Done
NotDone:	push	bx
		call	Puti2
		pop	bx
Done:
                add bl,'0'
                mov cs:[si],bl
                inc si
		ret
PutI2		endp
;
; Div10- Divides DX:AX by 10 leaving the remainder in BL and the quotient
;	 in DX:AX.
;
Div10		proc	near
		mov	cx, 10
		mov	bx, ax
		xchg	ax, dx
		xor	dx, dx
		div	cx
		xchg	bx, ax
		div	cx
		xchg	dx, bx
		ret
Div10		endp
DWRD            PROC near
                push ax
                push dx
                push bx
                push cx

                mov es,cs:[video]
                mov bx,dx

DNUMP:          mov     cx,10           ;divisor and flag
                push    cx              ;put flag on stack

;- divide & store digit loop
DNUM1:          xchg    ax,bx           ;make ax high word, bx low word
                sub     dx,dx           ;extend high word
                div     cx              ;dx = remainder, ax high quotient
                xchg    ax,bx           ;save high quotient, get low word
                div     cx              ;dx = digit (0-9), ax low quotient
                push    dx              ;save digit (remainder) on stack
                mov     dx,bx           ;copy so not destroyed below
                or      dx,ax           ;is full quotient zero?
                jnz     DNUM1           ;no, continue

                pop     dx              ;get most significant digit

;- display loop
DNUM2:          or      dl,30h          ;convert to ASCII digit
                mov dh,cs:[col]
                mov es:[di],dx
                add di,2
                pop     dx              ;get next digit or flag
                cmp     dx,cx           ;is it a digit (less than 10)?
                jc      DNUM2           ;yes, continue display
                ;retn                    ;no, flag met (stack normal)

                pop cx
                pop bx
                pop dx
                pop ax
                RET
numbspace       db 16 dup(0),0
video           dw 0b800h
col             db 0
DWRD            ENDP
nDWRD        PROC NEAR
                push es
                mov es,cs:[video]

                PUSH AX
		PUSH BX
		PUSH CX
		PUSH DX
		push si

                call sl_putul

                xor ah,ah
                mov al,cl
                mov bl,3
                dec al
                div bl
                mov cs:[ctemp],ah

                call numshow

		pop si
		POP DX
		POP CX
		POP BX
		POP AX

                pop es
                RET
nDWRD           ENDP
cDWRD           PROC NEAR
                push es
                push si
                push ax
                push bx
                push dx

                mov cs:[clen],cx
                call sl_putul

                push cx

                xor ah,ah
                mov al,cl
                mov bl,3
                dec al
                div bl
                mov cs:[ctemp],ah
                xor ah,ah
                add ax,cx

                mov cx,cs:[clen]
                cmp cx,ax
                jbe putu9
                sub cx,ax
                call clear
putu9:
                pop cx
                call numshow
;putu6:
                pop dx
                pop bx
                pop ax
                pop si
                pop es
                ret
clen            dw 0
ctemp           db 0
cDWRD           ENDP
date            proc near

                push ax
                and ax,011111b
                call ldwrd
                pop ax
                mov cl,'-'
                mov ch,cs:[col]
                mov es:[di+4],cx

                add di,6
                push ax
                and ax,0111100000b
                shr ax,5
                call tdwrd
                pop ax
                mov cl,'-'
                mov ch,cs:[col]
                mov es:[di],cx

                add di,2
                push ax
                and ax,01111111000000000b
                shr ax,9
                add ax,80
                call ldwrd
                pop ax
                add di,4

                ret
date            endp
time proc near
                push ax
                and ax,01111100000000000b
                shr ax,11
                call ldwrd
                pop ax
                mov cl,':'
                mov ch,cs:[col]
                mov es:[di+4],cx

                add di,6
                and ax,011111100000b
                shr ax,5
                call tdwrd
                ret
time            endp

ldwrd           proc near
                mov cl,10
                div cl
                mov cl,cs:[col]

                or al,al
                jnz nold1
                mov al,32-'0'
nold1:
                add al,'0'
                mov es:[di],al
                mov es:[di+1],cl

                add ah,'0'
                mov es:[di+2],ah
                mov es:[di+3],cl
                ret
ldwrd           endp
tdwrd           proc near
                mov cl,10
                div cl
                mov cl,cs:[col]

                add al,'0'
                mov es:[di],al
                mov es:[di+1],cl
                add ah,'0'
                mov es:[di+2],ah
                mov es:[di+3],cl
                add di,4
                ret
tdwrd           endp

getsinfo        proc near

		MOV AX,1130H
		XOR BH,BH
		INT 10H
		DEC DL
                MOV CS:[screensize],Dl

                mov ah,0fh
                int 10h
                mov al,ah
                xor ah,ah
                shl ax,1
                mov cs:[screenwidth],ax

                mov ah,2
                mov dl,99
                mov dh,99
                mov bl,0
                int 10h

                ret
screenwidth     dw 0
screensize      db 0,0
getsinfo        endp
readindirs2     proc near
                mov ax,cs:[dirseg]
                call fuckmem
                mov cs:[dirseg],0

                mov bx,1000h
                call grabmem
                jc memerr56
                mov cs:[dirseg],ax

                mov cs:[filecount],0
                xor bp,bp

                push cs
                pop ds

                mov di,80h+15h
                mov es,cs:[dirseg]

                mov ah,4eh
                mov cx,0110111b
   ÿ            lea dx,allfiles
                int 21h
                jc nofiles
repeatread:
                mov cx,11
lop2:
                mov ax,cs:[di]
                mov es:[bp],ax
                add di,2
                add bp,2
                loop lop2

                mov ax,cs:[filecount]
                mov es:[bp],ax

                sub di,22
                add bp,2
                and es:[bp-1],byte ptr 127
                inc cs:[filecount]

                push cx
                push di
                xor dx,dx
                mov di,0;cs:[temp2]
                mov cx,4
                call ndwrd
                pop di
                pop cx

                mov ah,4fh
                int 21h
                jnc repeatread

                mov ax,cs:[filecount]
                mov cx,entrysze
                xor dx,dx
                mul cx
                shr ax,4
                add ax,10

                mov bx,ax
                mov ah,4ah
                mov es,cs:[dirseg]
                int 21h

                mov ds,cs:[dirseg]
                cmp ds:[9],byte ptr '.'
                jne noki
                cmp cs:[filecount],2
                jbe noki
                mov cs:[cursorpos],2
noki:
                ret
nofiles:
                mov ah,4ah
                mov bx,1
                mov es,cs:[dirseg]
                int 21h
memerr56:
                ret

allfiles        db '*.*',0
entrysze        equ 24
dirseg          dw 0
filecount       dw 0
cursorpos       db 0
toppos          dw 0

readindirs2     endp
showfiles       proc near
                mov es,cs:[video]
                mov di,0
                mov dh,40
                mov dl,cs:[screensize]
                mov ch,1bh
                call box1nc

                mov di,6
                mov ax,cs:[filecount]
                xor dx,dx
                call ndwrd
showfiles2:
                mov di,cs:[screenwidth]
                add di,4

                mov ax,cs:[toppos]
                xor dx,dx
                mov cx,entrysze
                mul cx
                add ax,9
                mov si,ax

                mov ds,cs:[dirseg]
                ;mov si,9
                mov ax,cs:[filecount]
                mov cx,word ptr cs:[screensize]

                cmp ax,cx
                ja sfa2
                mov cx,ax
sfa2:
                push di
                push cx
                push si

                mov cx,12
sfa1:
                mov ah,ds:[si]
                or ah,ah
                jz sfa3
                mov es:[di],ah
                add di,2
                inc si
                loop sfa1
                jmp sfa4
sfa3:
                mov es:[di],byte ptr 32
                add di,2
                loop sfa3
sfa4:
                pop si

                mov cs:[col],1fh
                ;mov al,ds:[si-9]
                ;add di,4
                ;call hex2

                mov ax,ds:[si-4]
                mov dx,ds:[si-2]
                add di,2
                mov cx,12
                call cdwrd
                add di,2
                mov ax,ds:[si-6]
                call date
                add di,4
                ;mov ax,ds:[si-6]
                ;call time

                pop cx

                pop di
                add si,entrysze
                add di,cs:[screenwidth]
                loop sfa2


                ret
showfiles       endp
cursor          proc near
                mov bh,0fh
                jmp clo0
ckill:
                mov bh,1fh
clo0:
                mov al,cs:[cursorpos]
                xor ah,ah
                inc ax
                mul cs:[screenwidth]
                inc ax
                mov di,ax
                mov cx,40
clo1:
                mov es:[di],bh
                add di,2
                loop clo1

                ret
cursor          endp

checkkey        proc near
                xor bp,bp
cko:
                mov ah,cs:thekeys[bp]
                cmp ah,al
                jne ck1

                shl bp,1

                mov ax,cs:[toppos]
                mov bl,cs:[cursorpos]
                xor bh,bh
                                  
                call cs:thelocs[bp]

                ret
ck1:
                inc bp
                or ah,ah
                jnz cko
                ret
thekeys         db 80,72,81,73,28,0
thelocs         dw doup,dodown,dopgdown,dopgup,playfile

checkkey        endp

doup            proc near
                inc bl
                cmp bl,cs:[screensize]
                je dop1
                call ckill
                inc cs:[cursorpos]
                call cursor
                ret
dop1:
                add ax,bx
                cmp ax,cs:[filecount]
                jae dop2
                inc cs:[toppos]

                call ckill
                call showfiles2
                call cursor
dop2:
                ret
doup            endp
dodown          proc near
                cmp bl,0
                je dod1

                call ckill
                dec cs:[cursorpos]
                call cursor
                ret
dod1:
                cmp ax,0
                je dod2
                dec cs:[toppos]
                call ckill
                call showfiles2
                call cursor
dod2:
                ret
dodown          endp
dopgdown        proc near
                inc bl

                cmp bl,cs:[screensize]
                jae don2

                call ckill
                mov bl,cs:[screensize]
                dec bl
                mov cs:[cursorpos],bl
                call cursor
                ret
don2:
                add ax,bx
                add ax,bx
                cmp ax,cs:[filecount]
                jbe don1
                mov ax,cs:[filecount]
don1:
                sub ax,bx
                mov cs:[toppos],ax
                call ckill
                call showfiles2
                call cursor
                ret
dopgdown        endp
dopgup          proc near
                cmp bl,0
                je dou1

                call ckill
                mov cs:[cursorpos],0
                call cursor

                ret
dou1:
                cmp ax,0
                je dou2

                cmp ax,word ptr cs:[screensize]
                ja dou3
                mov ax,0
                jmp dou4
dou3:
                sub ax,word ptr cs:[screensize]
dou4:
                mov cs:[toppos],ax
                call ckill
                call showfiles2
                call cursor
dou2:
                ret
dopgup          endp

getname         proc near
                mov al,cs:[cursorpos]
                xor ah,ah
                add ax,cs:[toppos]
                mov cx,entrysze
                xor dx,dx
                mul cx
                push ax
                add ax,9
                mov si,ax

                mov ds,cs:[dirseg]
                mov cx,12
                lea di,input
gna1:
                mov ah,ds:[si]
                mov cs:[di],ah
                inc di
                inc si
                loop gna1

                pop si
                mov ax,ds:[si+5]
                mov cs:[fsize],ax
                mov dx,ds:[si+7]
                mov cs:[fsize+2],dx

                ret
input           db 12 dup(0),0
fsize           dw 0,0


getname         endp

mess            proc
                push ax
                mov ah,cs:[col]
                or ah,ah
                jz gomessc
conmess:
                mov al,cs:[si]
                or al,al
                jz endmess
                mov es:[di],ax
                inc si
                add di,2
                jmp conmess
endmess:
                pop ax
                ret
gomessc:
                mov al,cs:[si]
                or al,al
                jz endmess
                mov es:[di],al
                inc si
                add di,2
                jmp gomessc
mess            endp

playfile        proc near
                push es
                push ds

                call getname;input

                test byte ptr ds:[si],16
                jz notdir1

                call cbox

                mov ah,3bh              ;its a dir
                push cs
                pop ds
                lea dx,input
                int 21h
                jc nodi1

                call show

                call ckill
                mov cs:[toppos],0
                mov cs:[cursorpos],0

                call readindirs2
                call showfiles
                call cursor
                jmp nodi3
nodi1:
                call show
nodi3:
                pop ds
                pop es
                ret
notdir1:
                call cbox

                push di
                ;mov di,20
                lea si,input
                mov cs:[col],4fh
                call mess
                pop di
                add di,cs:[screenwidth]

                push di
                mov ax,cs:[fsize]
                mov dx,cs:[fsize+2]
                call ndwrd
                pop di

                add di,cs:[screenwidth]

                push di

                call doload

                pop di

                mov es,cs:[video]

                mov cs:[col],3fh
                mov ax,cs:[plays]
                call hex4

                call waitkey

                call show
                pop ds
                pop es
                ret
playfile        endp
cbox            proc near
                mov ch,2fh
cbox2:
                xor dx,dx
                mov ax,5
                mul cs:[screenwidth]
                mov di,ax
                mov dx,3005h
                call hide

                call box1
                ;mov ax,1
                ;mov dx,1
                ;call dwrd
                add di,cs:[screenwidth]
                add di,4
                ret
cbox            endp
getaddr         proc near

ScanPort:       mov     bx,210h                 ; start scanning ports
                                                ; 210h, 220h, .. 260h
ResetDSP:       mov     dx,bx                   ; try to reset the DSP.
                add     dx,06h
                mov al, 1
                OUT dx, al
                in al, dx
                in al, dx
                in al, dx
                in al, dx
                xor     al,al
                OUT dx, al
                add     dx,08h
                mov cx, 100
WaitID:         in al, dx
                or      al,al
                js GetID
                loop    WaitID
                jmp NextPort
GetID:          sub     dx,04h
                in al, dx
                cmp     al,0AAh
                je Found
                add     dx,04h
                loop    WaitID

NextPort:       add     bx,10h                  ; if not response,
                cmp     bx,260h                 ; try the next port.
                jbe ResetDSP
                jmp Fail

Found:          mov cs:[SbioAddr],bx             ; SB Port Address Found!

                ret
SbIOaddr        dw      0
;sbaddr          dw 0
getaddr          endp
getirq          proc near

ScanIRQ:        cli

                in      al,21h                  ; save the IMR.
                mov bl, al
                mov     al,11111111b            ; disable all the IRQs.
                out     21h,al
                xor     ax,ax                   ; trap the IRQs 2,3,5,7.
                mov es, ax

SaveIrqs:       mov     ax,es:[28h]             ; irq2
                mov     dx,es:[2Ah]
                push ax
                push dx
                mov     ax,es:[2Ch]             ; irq3
                mov     dx,es:[2Eh]
                push ax
                push dx
                mov     ax,es:[34h]             ; irq5
                mov     dx,es:[36h]
                push ax
                push dx
                mov     ax,es:[3Ch]             ; irq7
                mov     dx,es:[3Eh]
                push ax
                push dx

SetIrqs:        mov     ax,offset TrapIrq2      ; irq2
                mov     es:[28h],ax
                mov     es:[2Ah],cs
                mov     ax,offset TrapIrq3      ; irq3
                mov     es:[2Ch],ax
                mov     es:[2Eh],cs
                mov     ax,offset TrapIrq5      ; irq5
                mov     es:[34h],ax
                mov     es:[36h],cs
                mov     ax,offset TrapIrq7      ; irq7
                mov     es:[3Ch],ax
                mov     es:[3Eh],cs

EnableIrqs:     mov     al,bl                   ; enable IRQs 2,3,5,7.
                and     al,01010011b
                out     21h,al
                sti
                mov     [SbIrq],0               ; clear the IRQ level.
                mov     dx,[SbioAddr]             ; tells to the SB to
                add     dx,0Ch                  ; generate a IRQ!
WaitSb:         in al, dx
                or      al,al
                js WaitSb
                mov     al,0F2h
                OUT dx, al
                xor     cx,cx                   ; wait until IRQ level
WaitIRQ:        cmp     [SbIrq],0               ; is changed or timeout.
                jne IrqOk
                loop    WaitIRQ

IrqOk:          mov     al,bl                   ; restore IMR.
                out     21h,al

RestoreIrqs:    cli                             ; restore IRQ vectors.
                xor     ax,ax
                mov es, ax
                pop     dx                      ; irq7
                pop ax
                mov     es:[3Ch],ax
                mov     es:[3Eh],dx
                pop     dx                      ; irq5
                pop ax
                mov     es:[34h],ax
                mov     es:[36h],dx
                pop     dx                      ; irq3
                pop ax
                mov     es:[2Ch],ax
                mov     es:[2Eh],dx
                pop     dx                      ; irq2
                pop ax
                mov     es:[28h],ax
                mov     es:[2Ah],dx
                cli
                cmp     [SbIrq],0               ; IRQ level was changed?
                je      Fail                    ; no, fail.

Success:        ;mov     dx,[SbioAddr]             ; Print Sucessful message.

fail:

                ret
SbIRQ           dw      0
getirq          endp
TrapIrq         Proc    Far

                push    dx                      ; General IRQ trapper
                push    ds                      ; used for IRQ autodetect.
                ;mov     dx,@Data
                ;mov ds, dx
                mov     [SbIrq],ax              ; save IRQ level.
                mov dx, cs:[SbioAddr]
                add     dx,0Eh
                in      al,dx                   ; SB acknowledge.
                mov     al,20h
                out     20h,al                  ; Hardware acknowledge.
                pop ds
                pop dx
                pop ax
                iret                            ; bye!

                IRP Level,<2,3,5,7>
TrapIrq&Level:  push    ax
                mov ax, Level
                jmp TrapIrq
                EndM

TrapIrq EndP

showsb          proc near
                mov di,48h+12
                mov dx,2408h
                mov ch,3fh
                call box1nc

                add di,cs:[screenwidth]
                add di,6

                push di

                mov cs:[col],3bh
                lea si,msb
                call mess

                MOV DX,cs:[sbioaddr]
                ADD DX,0Ch
sbl1:
                in al,dx
                and al,80h
                jnz sbl1

                mov al,0e1h
                out dx,al

                mov dx,cs:[sbioaddr]
                add dx,0eh
sbl2:
                in al,dx
                and al,80h
                jz sbl2

                sub dx,4

                in al,dx
                mov cs:[sbver],al
                xor ah,ah
                push ax
                add al,'0'
                mov cs:[mbrac+1],al
                in al,dx
                mov cs:[sbver+1],al
                pop ax
                dec al
                shl ax,2
                lea si,sbname
                add si,ax
                call mess
                lea si,mbrac
                call mess
                pop di

                add di,cs:[screenwidth]
                push di
                lea si,madd
                mov cs:[col],3eh
                call mess
                mov ax,cs:[sbioaddr]
                xor dx,dx
                call hex4

                pop di
                add di,cs:[screenwidth]
                push di

                mov es,cs:[video]

                lea si,mirq
                mov cs:[col],3bh
                call mess
                add di,8
                mov ax,cs:[sbirq]
                xor dx,dx
                call ndwrd
                pop di
                add di,cs:[screenwidth]

                call volume

                ret
madd            db 'Address ',0
mirq            db 'Irq ',0
mbrac           db '(0)',0
sbver           db 0,0

msb             db 'Sound Blaster ',0
sbname          db 'v 1',0
                db 'v 2',0
                db 'Pro',0
                db '16 ',0
                db 'Unk',0

showsb          endp
volume          proc near
                ;mov ah,8
                ;int 21h

                mov es,cs:[video]
                push di
                mov cs:[col],39h
                lea si,mmain
                call mess
                add di,4
                mov al,22h
                call sbshit
                pop di

                add di,cs:[screenwidth]

                push di
                mov cs:[col],3ch
                lea si,mvoice
                call mess
                add di,6
                mov al,4h
                call sbshit
                pop di

                add di,cs:[screenwidth]
                push di
                mov cs:[col],3eh
                lea si,fm
                call mess
                add di,8+4
                mov al,26h
                call sbshit
                pop di

                add di,cs:[screenwidth]
                push di
                lea si,line
                mov cs:[col],3ah
                call mess
                add di,8
                mov al,2eh
                call sbshit
                pop di

                ret

line            db 'line',0
mmain           db 'master',0
fm              db 'FM',0
mvoice          db 'voice',0

volume          endp

sbshit          proc near

                mov dx,224h
                out dx,al

                inc dx
                in al,dx

                call dispval

                ret
sbshit          endp
dispval         proc near
                xor ah,ah
                push ax
                and al,0fh
                xor dx,dx
                call dwrd
                pop ax
                shr al,4
                add di,20
                call dwrd
                ret
dispval         endp

iswave          proc near
                mov ds,cs:[plays]

                mov di,cs:[wpos1]
                add di,320*3
                mov si,0
                mov cx,200

isw1:
                mov ah,ds:[si]
                inc si
                mov es:[di],ah
                add di,2
                loop isw1

                mov di,cs:[wpos1]
                add di,480

                cmp ds:[0],'IR'
                jne notwave
                lea si,gotwave

                push di
                call mess
                add di,6
                mov ax,ds:[4]
                mov dx,ds:[6]
                call ndwrd
                pop di

                add di,cs:[screenwidth]
                mov ax,ds:[24]
                mov dx,ds:[26]
                mov cs:[col],2bh
                call ndwrd

                mov bx,ds:[24]
                jmp setsample

notwave:
                mov bx,22100

setsample:
                mov dx,15
                mov ax,16960
                div bx
                mov bx,256
                sub bx,ax
                mov cs:[srate2],bl

                ret
gotwave         db 'Wave File',0

iswave          endp

sbinfo proc far
; Autodetects setting for the soundblaster card, and allows you
; to play any soundfile on it. Works on most soundcards.
                lea sp,stk+200h
                MOV AH,4AH
                MOV BX,(OFFSET STK - OFFSET START + 30FH )/16
                INT 21H

                call getsinfo
                call getaddr
                call getirq
                call readindirs2
                call showfiles
                call showsb
                call cursor

                call sb_init2

mainloop:
                call waitkey
                cmp al,1
                je endloop1
                call checkkey
                jmp mainloop
endloop1:
                mov ax,cs:[dirseg]
                call fuckmem
                call _dma_done

                mov ax,2
                int 10h
       ret
sbinfo endp
code ends

_stack     segment word stack 'STACK'
           db      0100h DUP (05h)
_stack     ends

STK             EQU $
     end  start
