     1                                  ; ****************************************************************************
     2                                  ; playwav.s (for TRDOS 386)
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; PLAYWAV.PRG ! Sound Blaster 16 .wav player program by Erdogan TAN
     5                                  ;
     6                                  ; 07/03/2017
     7                                  ;
     8                                  ; [ Last Modification: 24/04/2017 ]
     9                                  ;
    10                                  ; Modified from TINYPLAY.PRG .mod player program by Erdogan Tan, 04/03/2017 
    11                                  ;
    12                                  ; Derived from source code of 'PLAYWAV.COM' ('PLAYWAV.ASM') by Erdogan Tan
    13                                  ;	      (17/02/2017) 
    14                                  ; Assembler: NASM version 2.11
    15                                  ;	     nasm playwav.s -l playwav.txt -o PLAYWAV.PRG	
    16                                  ; ----------------------------------------------------------------------------
    17                                  ; Derived from '.wav file player for DOS' Jeff Leyda, Sep 02, 2002
    18                                  
    19                                  
    20                                  ; 01/03/2017
    21                                  ; 16/10/2016
    22                                  ; 29/04/2016
    23                                  ; TRDOS 386 system calls (temporary list!)
    24                                  _ver 	equ 0
    25                                  _exit 	equ 1
    26                                  _fork 	equ 2
    27                                  _read 	equ 3
    28                                  _write	equ 4
    29                                  _open	equ 5
    30                                  _close 	equ 6
    31                                  _wait 	equ 7
    32                                  _creat 	equ 8
    33                                  _link 	equ 9
    34                                  _unlink	equ 10
    35                                  _exec	equ 11
    36                                  _chdir	equ 12
    37                                  _time 	equ 13
    38                                  _mkdir 	equ 14
    39                                  _chmod	equ 15
    40                                  _chown	equ 16
    41                                  _break	equ 17
    42                                  _stat	equ 18
    43                                  _seek	equ 19
    44                                  _tell 	equ 20
    45                                  _mount	equ 21
    46                                  _umount	equ 22
    47                                  _setuid	equ 23
    48                                  _getuid	equ 24
    49                                  _stime	equ 25
    50                                  _quit	equ 26	
    51                                  _intr	equ 27
    52                                  _fstat	equ 28
    53                                  _emt 	equ 29
    54                                  _mdate 	equ 30
    55                                  _video 	equ 31
    56                                  _audio	equ 32
    57                                  _timer	equ 33
    58                                  _sleep	equ 34
    59                                  _msg    equ 35
    60                                  _geterr	equ 36
    61                                  _fpsave	equ 37
    62                                  _pri	equ 38
    63                                  _rele	equ 39
    64                                  _fff	equ 40
    65                                  _fnf	equ 41
    66                                  _alloc	equ 42
    67                                  _dalloc equ 43
    68                                  _calbac equ 44	
    69                                  
    70                                  %macro sys 1-4
    71                                      ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
    72                                      ; 03/09/2015	
    73                                      ; 13/04/2015
    74                                      ; Retro UNIX 386 v1 system call.	
    75                                      %if %0 >= 2   
    76                                          mov ebx, %2
    77                                          %if %0 >= 3    
    78                                              mov ecx, %3
    79                                              %if %0 = 4
    80                                                 mov edx, %4   
    81                                              %endif
    82                                          %endif
    83                                      %endif
    84                                      mov eax, %1
    85                                      ;int 30h
    86                                      int 40h ; TRDOS 386 (TRDOS v2.0)	   
    87                                  %endmacro
    88                                  
    89                                  ; TRDOS 386 (and Retro UNIX 386 v1) system call format:
    90                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    91                                  
    92                                  
    93                                  [BITS 32]
    94                                  
    95                                  [ORG 0] 
    96                                  
    97                                  _STARTUP:
    98                                  	; Prints the Credits Text.
    99                                  	sys	_msg, Credits, 255, 0Bh
    99                              <1> 
    99                              <1> 
    99                              <1> 
    99                              <1> 
    99                              <1>  %if %0 >= 2
    99 00000000 BB[FB060000]        <1>  mov ebx, %2
    99                              <1>  %if %0 >= 3
    99 00000005 B9FF000000          <1>  mov ecx, %3
    99                              <1>  %if %0 = 4
    99 0000000A BA0B000000          <1>  mov edx, %4
    99                              <1>  %endif
    99                              <1>  %endif
    99                              <1>  %endif
    99 0000000F B823000000          <1>  mov eax, %1
    99                              <1> 
    99 00000014 CD40                <1>  int 40h
   100                                  
   101                                  	; clear bss
   102 00000016 B9[00000200]            	mov	ecx, EOF
   103 0000001B BF[BC070000]            	mov	edi, bss_start
   104 00000020 29F9                    	sub	ecx, edi
   105 00000022 D1E9                    	shr	ecx, 1
   106 00000024 31C0                    	xor	eax, eax
   107 00000026 F366AB                  	rep	stosw
   108                                  
   109                                  GetFileName:  
   110 00000029 89E6                    	mov	esi, esp
   111 0000002B AD                      	lodsd
   112 0000002C 83F802                  	cmp	eax, 2 ; two arguments 
   113                                  	       ; (program file name & mod file name)
   114 0000002F 0F82EA000000            	jb	pmsg_usage ; nothing to do
   115                                  
   116 00000035 AD                      	lodsd ; program file name address 
   117 00000036 AD                      	lodsd ; mod file name address (file to be read)
   118 00000037 89C6                    	mov	esi, eax
   119 00000039 BF[E2070000]            	mov	edi, wav_file_name
   120                                  ScanName:       
   121 0000003E AC                      	lodsb
   122 0000003F 84C0                    	test	al, al
   123 00000041 0F84D8000000            	je	pmsg_usage
   124 00000047 3C20                    	cmp	al, 20h
   125 00000049 74F3                    	je	short ScanName	; scan start of name.
   126 0000004B AA                      	stosb
   127 0000004C B4FF                    	mov	ah, 0FFh
   128                                  a_0:	
   129 0000004E FEC4                    	inc	ah
   130                                  a_1:
   131 00000050 AC                      	lodsb
   132 00000051 AA                      	stosb
   133 00000052 3C2E                    	cmp	al, '.'
   134 00000054 74F8                    	je	short a_0	
   135 00000056 20C0                    	and	al, al
   136 00000058 75F6                    	jnz	short a_1
   137                                  
   138 0000005A 08E4                    	or	ah, ah		; if period NOT found,
   139 0000005C 750B                    	jnz	short a_2	; then add a .WAV extension.
   140                                  SetExt:
   141 0000005E 4F                      	dec	edi
   142 0000005F C7072E574156            	mov	dword [edi], '.WAV'
   143 00000065 C6470400                	mov	byte [edi+4], 0
   144                                  a_2:      
   145 00000069 E8E1000000              	call    DetectSb	; Detect the SB Addr, Irq.
   146                                  
   147                                  	; DIRECT CGA (TEXT MODE) MEMORY ACCESS
   148                                  	; bl = 0, bh = 4
   149                                  	; Direct access/map to CGA (Text) memory (0B8000h)
   150                                  
   151                                  	sys	_video, 0400h
   151                              <1> 
   151                              <1> 
   151                              <1> 
   151                              <1> 
   151                              <1>  %if %0 >= 2
   151 0000006E BB00040000          <1>  mov ebx, %2
   151                              <1>  %if %0 >= 3
   151                              <1>  mov ecx, %3
   151                              <1>  %if %0 = 4
   151                              <1>  mov edx, %4
   151                              <1>  %endif
   151                              <1>  %endif
   151                              <1>  %endif
   151 00000073 B81F000000          <1>  mov eax, %1
   151                              <1> 
   151 00000078 CD40                <1>  int 40h
   152 0000007A 3D00800B00              	cmp	eax, 0B8000h
   153 0000007F 0F85B2000000            	jne	error_exit
   154                                  
   155                                  ; open the file
   156                                          ; open existing file
   157 00000085 E86D020000                      call    openFile ; no error? ok.
   158 0000008A 7318                            jnc     short _gsr
   159                                  
   160                                  ; file not found!
   161                                  	sys	_msg, noFileErrMsg, 255, 0Fh
   161                              <1> 
   161                              <1> 
   161                              <1> 
   161                              <1> 
   161                              <1>  %if %0 >= 2
   161 0000008C BB[29070000]        <1>  mov ebx, %2
   161                              <1>  %if %0 >= 3
   161 00000091 B9FF000000          <1>  mov ecx, %3
   161                              <1>  %if %0 = 4
   161 00000096 BA0F000000          <1>  mov edx, %4
   161                              <1>  %endif
   161                              <1>  %endif
   161                              <1>  %endif
   161 0000009B B823000000          <1>  mov eax, %1
   161                              <1> 
   161 000000A0 CD40                <1>  int 40h
   162 000000A2 EB72                            jmp     Exit
   163                                  
   164                                  _gsr:  
   165 000000A4 E87E020000                     	call    getSampleRate		; read the sample rate
   166                                                                          ; pass it onto codec.
   167 000000A9 726B                    	jc	Exit
   168                                  
   169 000000AB 66A3[D8070000]          	mov	[sampling_rate], ax
   170 000000B1 880D[DA070000]          	mov	[stmo], cl
   171 000000B7 8815[DC070000]          	mov	[bps], dl
   172                                  	
   173                                  PlayNow: 
   174                                  	; DIRECT MEMORY ACCESS (for Audio DMA)
   175                                  	; ebx = DMA buffer address (virtual, user)
   176                                  	; ecx = buffer size (in bytes)
   177                                  	; edx = upper limit = 16MB
   178                                  
   179                                  	_16MB	equ 1024*1024*16	
   180                                  
   181                                  	sys	_alloc, DmaBuffer, DmaBufSize, _16MB 
   181                              <1> 
   181                              <1> 
   181                              <1> 
   181                              <1> 
   181                              <1>  %if %0 >= 2
   181 000000BD BB[00000100]        <1>  mov ebx, %2
   181                              <1>  %if %0 >= 3
   181 000000C2 B900000100          <1>  mov ecx, %3
   181                              <1>  %if %0 = 4
   181 000000C7 BA00000001          <1>  mov edx, %4
   181                              <1>  %endif
   181                              <1>  %endif
   181                              <1>  %endif
   181 000000CC B82A000000          <1>  mov eax, %1
   181                              <1> 
   181 000000D1 CD40                <1>  int 40h
   182 000000D3 7262                    	jc	short error_exit
   183                                  
   184 000000D5 A3[F2070000]            	mov	[DMA_phy_buff], eax	; physical address
   185                                  	     				; of the buffer
   186                                  					; (which is needed
   187                                  					; for DMA controller)
   188 000000DA E8A6020000              	call    SbInit
   189                                  ;
   190                                  ; position file pointer to start in actual wav data
   191                                  ; MUCH improvement should really be done here to check if sample size is
   192                                  ; supported, make sure there are 2 channels, etc.  
   193                                  ;
   194                                          ;mov     ah, 42h
   195                                          ;mov     al, 0	; from start of file
   196                                          ;mov     bx, [FileHandle]
   197                                          ;xor     cx, cx
   198                                          ;mov     dx, 44	; jump past .wav/riff header
   199                                          ;int     21h
   200                                  
   201                                  	sys	_seek, [FileHandle], 44, 0
   201                              <1> 
   201                              <1> 
   201                              <1> 
   201                              <1> 
   201                              <1>  %if %0 >= 2
   201 000000DF 8B1D[B8070000]      <1>  mov ebx, %2
   201                              <1>  %if %0 >= 3
   201 000000E5 B92C000000          <1>  mov ecx, %3
   201                              <1>  %if %0 = 4
   201 000000EA BA00000000          <1>  mov edx, %4
   201                              <1>  %endif
   201                              <1>  %endif
   201                              <1>  %endif
   201 000000EF B813000000          <1>  mov eax, %1
   201                              <1> 
   201 000000F4 CD40                <1>  int 40h
   202                                  
   203                                  ; play the .wav file.  Most of the good stuff is in here.
   204                                  
   205 000000F6 E888050000                      call    PlayWav
   206                                  
   207                                  ; close the .wav file and exit.
   208                                  
   209 000000FB E810020000                      call    closeFile
   210                                  
   211 00000100 E8FC040000              	call	SbDone
   212                                  
   213                                  	; Deallocate DMA buffer (not necessary just before exit!)
   214                                  	sys	_dalloc, DmaBuffer, DmaBufSize
   214                              <1> 
   214                              <1> 
   214                              <1> 
   214                              <1> 
   214                              <1>  %if %0 >= 2
   214 00000105 BB[00000100]        <1>  mov ebx, %2
   214                              <1>  %if %0 >= 3
   214 0000010A B900000100          <1>  mov ecx, %3
   214                              <1>  %if %0 = 4
   214                              <1>  mov edx, %4
   214                              <1>  %endif
   214                              <1>  %endif
   214                              <1>  %endif
   214 0000010F B82B000000          <1>  mov eax, %1
   214                              <1> 
   214 00000114 CD40                <1>  int 40h
   215                                  	;jc	error_exit
   216                                  Exit:           
   217                                  	sys	_exit	; Bye!
   217                              <1> 
   217                              <1> 
   217                              <1> 
   217                              <1> 
   217                              <1>  %if %0 >= 2
   217                              <1>  mov ebx, %2
   217                              <1>  %if %0 >= 3
   217                              <1>  mov ecx, %3
   217                              <1>  %if %0 = 4
   217                              <1>  mov edx, %4
   217                              <1>  %endif
   217                              <1>  %endif
   217                              <1>  %endif
   217 00000116 B801000000          <1>  mov eax, %1
   217                              <1> 
   217 0000011B CD40                <1>  int 40h
   218                                  
   219                                  here:
   220 0000011D EBFE                    	jmp	short here
   221                                  
   222                                  pmsg_usage:
   223                                  	sys	_msg, msg_usage, 255, 0Bh
   223                              <1> 
   223                              <1> 
   223                              <1> 
   223                              <1> 
   223                              <1>  %if %0 >= 2
   223 0000011F BB[D3060000]        <1>  mov ebx, %2
   223                              <1>  %if %0 >= 3
   223 00000124 B9FF000000          <1>  mov ecx, %3
   223                              <1>  %if %0 = 4
   223 00000129 BA0B000000          <1>  mov edx, %4
   223                              <1>  %endif
   223                              <1>  %endif
   223                              <1>  %endif
   223 0000012E B823000000          <1>  mov eax, %1
   223                              <1> 
   223 00000133 CD40                <1>  int 40h
   224 00000135 EBDF                    	jmp	short Exit
   225                                  
   226                                  error_exit:
   227                                  	sys	_msg, trdos386_err_msg, 255, 0Eh
   227                              <1> 
   227                              <1> 
   227                              <1> 
   227                              <1> 
   227                              <1>  %if %0 >= 2
   227 00000137 BB[98070000]        <1>  mov ebx, %2
   227                              <1>  %if %0 >= 3
   227 0000013C B9FF000000          <1>  mov ecx, %3
   227                              <1>  %if %0 = 4
   227 00000141 BA0E000000          <1>  mov edx, %4
   227                              <1>  %endif
   227                              <1>  %endif
   227                              <1>  %endif
   227 00000146 B823000000          <1>  mov eax, %1
   227                              <1> 
   227 0000014B CD40                <1>  int 40h
   228 0000014D EBC7                    	jmp	short Exit
   229                                  
   230                                  DetectSb:
   231 0000014F 60                      	pushad
   232                                  ScanPort:
   233 00000150 66BB1002                	mov     bx, 210h	; start scanning ports
   234                                  		; 210h, 220h, .. 260h
   235                                  ResetDSP:       
   236 00000154 6689DA                  	mov     dx, bx	; try to reset the DSP.
   237 00000157 6683C206                	add     dx, 06h
   238 0000015B B001                    	mov	al, 1
   239                                  	;out	dx, al
   240 0000015D B401                    	mov	ah, 1 ; outb
   241 0000015F CD34                    	int	34h
   242                                  
   243                                  	;in	al, dx
   244                                  	;in	al, dx
   245                                  	;in	al, dx
   246                                  	;in	al, dx
   247                                  
   248 00000161 B400                    	mov	ah, 0 ; inb
   249 00000163 CD34                    	int	34h
   250                                  	;mov	ah, 0 ; inb
   251 00000165 CD34                    	int	34h
   252                                  
   253 00000167 30C0                    	xor     al, al
   254                                  	;out	dx, al
   255 00000169 B401                    	mov	ah, 1 ; outb
   256 0000016B CD34                    	int	34h
   257                                  
   258 0000016D 6683C208                	add     dx, 08h
   259                                  	;mov	cx, 100
   260 00000171 66B92000                	mov	cx, 32
   261 00000175 28E4                    	sub	ah, ah ; 0
   262                                  WaitID:
   263                                  	;in	al, dx
   264 00000177 CD34                    	int	34h  ;ah = 0 ; inb
   265 00000179 08C0                    	or      al, al
   266 0000017B 7804                    	js      short GetID
   267 0000017D E2F8                    	loop    WaitID
   268 0000017F EB10                    	jmp     short NextPort
   269                                  GetID:          
   270 00000181 6683EA04                	sub     dx, 04h
   271                                  	;in	al, dx
   272 00000185 CD34                    	int	34h  ;ah = 0 ; inb
   273 00000187 3CAA                    	cmp     al, 0AAh
   274 00000189 7416                    	je      short Found
   275 0000018B 6683C204                	add     dx, 04h
   276 0000018F E2E6                    	loop    WaitID
   277                                  NextPort:
   278 00000191 6683C310                	add     bx, 10h	; if not response,
   279 00000195 6681FB6002              	cmp     bx, 260h	; try the next port.
   280 0000019A 76B8                    	jbe     short ResetDSP
   281 0000019C E934010000              	jmp     Fail
   282                                  Found:
   283 000001A1 66891D[CF060000]        	mov     [SbAddr], bx	; SB Port Address Found!
   284                                  ScanIRQ:
   285                                  SetIrqs:
   286                                  	; LINK SIGNAL RESPONSE/RETURN BYTE TO REQUESTED IRQ
   287                                  	sys	_calbac, 102h, 2, SbIrq ; IRQ 2
   287                              <1> 
   287                              <1> 
   287                              <1> 
   287                              <1> 
   287                              <1>  %if %0 >= 2
   287 000001A8 BB02010000          <1>  mov ebx, %2
   287                              <1>  %if %0 >= 3
   287 000001AD B902000000          <1>  mov ecx, %3
   287                              <1>  %if %0 = 4
   287 000001B2 BA[D1060000]        <1>  mov edx, %4
   287                              <1>  %endif
   287                              <1>  %endif
   287                              <1>  %endif
   287 000001B7 B82C000000          <1>  mov eax, %1
   287                              <1> 
   287 000001BC CD40                <1>  int 40h
   288                                  		; Signal Response Byte
   289                                  	;jc	short error_exit
   290                                  
   291                                  	sys	_calbac, 103h, 3, SbIrq ; IRQ 3
   291                              <1> 
   291                              <1> 
   291                              <1> 
   291                              <1> 
   291                              <1>  %if %0 >= 2
   291 000001BE BB03010000          <1>  mov ebx, %2
   291                              <1>  %if %0 >= 3
   291 000001C3 B903000000          <1>  mov ecx, %3
   291                              <1>  %if %0 = 4
   291 000001C8 BA[D1060000]        <1>  mov edx, %4
   291                              <1>  %endif
   291                              <1>  %endif
   291                              <1>  %endif
   291 000001CD B82C000000          <1>  mov eax, %1
   291                              <1> 
   291 000001D2 CD40                <1>  int 40h
   292                                  		; Signal Response Byte 
   293                                  	;jc	short error_exit
   294                                  
   295                                  	sys	_calbac, 104h, 4, SbIrq ; IRQ 4
   295                              <1> 
   295                              <1> 
   295                              <1> 
   295                              <1> 
   295                              <1>  %if %0 >= 2
   295 000001D4 BB04010000          <1>  mov ebx, %2
   295                              <1>  %if %0 >= 3
   295 000001D9 B904000000          <1>  mov ecx, %3
   295                              <1>  %if %0 = 4
   295 000001DE BA[D1060000]        <1>  mov edx, %4
   295                              <1>  %endif
   295                              <1>  %endif
   295                              <1>  %endif
   295 000001E3 B82C000000          <1>  mov eax, %1
   295                              <1> 
   295 000001E8 CD40                <1>  int 40h
   296                                  		; Signal Response Byte 
   297                                  	;jc	short error_exit
   298                                  
   299                                  	sys	_calbac, 105h, 5, SbIrq ; IRQ 5
   299                              <1> 
   299                              <1> 
   299                              <1> 
   299                              <1> 
   299                              <1>  %if %0 >= 2
   299 000001EA BB05010000          <1>  mov ebx, %2
   299                              <1>  %if %0 >= 3
   299 000001EF B905000000          <1>  mov ecx, %3
   299                              <1>  %if %0 = 4
   299 000001F4 BA[D1060000]        <1>  mov edx, %4
   299                              <1>  %endif
   299                              <1>  %endif
   299                              <1>  %endif
   299 000001F9 B82C000000          <1>  mov eax, %1
   299                              <1> 
   299 000001FE CD40                <1>  int 40h
   300                                  		; Signal Response Byte 
   301                                  	;jc	short error_exit
   302                                  
   303                                  	sys	_calbac, 107h, 7, SbIrq ; IRQ 7
   303                              <1> 
   303                              <1> 
   303                              <1> 
   303                              <1> 
   303                              <1>  %if %0 >= 2
   303 00000200 BB07010000          <1>  mov ebx, %2
   303                              <1>  %if %0 >= 3
   303 00000205 B907000000          <1>  mov ecx, %3
   303                              <1>  %if %0 = 4
   303 0000020A BA[D1060000]        <1>  mov edx, %4
   303                              <1>  %endif
   303                              <1>  %endif
   303                              <1>  %endif
   303 0000020F B82C000000          <1>  mov eax, %1
   303                              <1> 
   303 00000214 CD40                <1>  int 40h
   304                                  		; Signal Response Byte 
   305                                  	;jc	short error_exit
   306                                  
   307 00000216 C605[D1060000]00        	mov     byte [SbIrq], 0	; clear the IRQ level.
   308                                  
   309 0000021D 668B15[CF060000]        	mov     dx, [SbAddr]	; tells to the SB to
   310 00000224 6683C20C                	add     dx, 0Ch	; generate a IRQ!
   311                                  WaitSb:
   312                                  	;in	al, dx
   313 00000228 B400                    	mov	ah, 0 ; inb
   314 0000022A CD34                    	int	34h
   315 0000022C 08C0                    	or      al, al
   316 0000022E 78F8                    	js      short WaitSb
   317 00000230 B0F2                    	mov     al, 0F2h
   318                                  	;out	dx, al
   319 00000232 B401                    	mov	ah,1  ; outb
   320 00000234 CD34                    	int	34h	
   321                                  
   322 00000236 31C9                    	xor     ecx, ecx	; wait until IRQ level
   323                                  WaitIRQ:        
   324 00000238 803D[D1060000]00        	cmp     byte [SbIrq], 0	; is changed or timeout.
   325 0000023F 7506                    	jne     short IrqOk
   326 00000241 6649                    	dec 	cx
   327 00000243 75F3                    	jnz	short WaitIRQ
   328 00000245 EB0F                    	jmp	short RestoreIrqs
   329                                  IrqOk:
   330 00000247 668B15[CF060000]        	mov     dx, [SbAddr]
   331 0000024E 6683C20E                	add     dx, 0Eh
   332                                  	;in	al, dx	; SB acknowledge.
   333 00000252 B400                    	mov	ah, 0 ; inb
   334 00000254 CD34                    	int	34h
   335                                  	;mov	al, 20h
   336                                  	;;out	20h, al	; Hardware acknowledge.
   337                                  	;mov	ah,1  ; outb
   338                                  	;int	34h	
   339                                  
   340                                  RestoreIrqs:
   341                                  	; UNLINK SIGNAL RESPONSE/RETURN BYTE FROM REQUESTED IRQ
   342                                  	sys	_calbac, 2	; unlink IRQ 2
   342                              <1> 
   342                              <1> 
   342                              <1> 
   342                              <1> 
   342                              <1>  %if %0 >= 2
   342 00000256 BB02000000          <1>  mov ebx, %2
   342                              <1>  %if %0 >= 3
   342                              <1>  mov ecx, %3
   342                              <1>  %if %0 = 4
   342                              <1>  mov edx, %4
   342                              <1>  %endif
   342                              <1>  %endif
   342                              <1>  %endif
   342 0000025B B82C000000          <1>  mov eax, %1
   342                              <1> 
   342 00000260 CD40                <1>  int 40h
   343                                  		; Signal Response Byte
   344                                  	sys	_calbac, 3	; unlink IRQ 3
   344                              <1> 
   344                              <1> 
   344                              <1> 
   344                              <1> 
   344                              <1>  %if %0 >= 2
   344 00000262 BB03000000          <1>  mov ebx, %2
   344                              <1>  %if %0 >= 3
   344                              <1>  mov ecx, %3
   344                              <1>  %if %0 = 4
   344                              <1>  mov edx, %4
   344                              <1>  %endif
   344                              <1>  %endif
   344                              <1>  %endif
   344 00000267 B82C000000          <1>  mov eax, %1
   344                              <1> 
   344 0000026C CD40                <1>  int 40h
   345                                  		; Signal Response Byte 
   346                                  	sys	_calbac, 4	; unlink IRQ 4
   346                              <1> 
   346                              <1> 
   346                              <1> 
   346                              <1> 
   346                              <1>  %if %0 >= 2
   346 0000026E BB04000000          <1>  mov ebx, %2
   346                              <1>  %if %0 >= 3
   346                              <1>  mov ecx, %3
   346                              <1>  %if %0 = 4
   346                              <1>  mov edx, %4
   346                              <1>  %endif
   346                              <1>  %endif
   346                              <1>  %endif
   346 00000273 B82C000000          <1>  mov eax, %1
   346                              <1> 
   346 00000278 CD40                <1>  int 40h
   347                                  		; Signal Response Byte 
   348                                  	sys	_calbac, 5	; unlink IRQ 5
   348                              <1> 
   348                              <1> 
   348                              <1> 
   348                              <1> 
   348                              <1>  %if %0 >= 2
   348 0000027A BB05000000          <1>  mov ebx, %2
   348                              <1>  %if %0 >= 3
   348                              <1>  mov ecx, %3
   348                              <1>  %if %0 = 4
   348                              <1>  mov edx, %4
   348                              <1>  %endif
   348                              <1>  %endif
   348                              <1>  %endif
   348 0000027F B82C000000          <1>  mov eax, %1
   348                              <1> 
   348 00000284 CD40                <1>  int 40h
   349                                  		; Signal Response Byte
   350                                  	sys	_calbac, 7	; unlink IRQ 7
   350                              <1> 
   350                              <1> 
   350                              <1> 
   350                              <1> 
   350                              <1>  %if %0 >= 2
   350 00000286 BB07000000          <1>  mov ebx, %2
   350                              <1>  %if %0 >= 3
   350                              <1>  mov ecx, %3
   350                              <1>  %if %0 = 4
   350                              <1>  mov edx, %4
   350                              <1>  %endif
   350                              <1>  %endif
   350                              <1>  %endif
   350 0000028B B82C000000          <1>  mov eax, %1
   350                              <1> 
   350 00000290 CD40                <1>  int 40h
   351                                  		; Signal Response Byte 
   352                                  
   353 00000292 803D[D1060000]00        	cmp     byte [SbIrq], 0	; IRQ level was changed?
   354 00000299 743A                    	je      short Fail	; no, fail.
   355                                  Success:        
   356 0000029B 668B15[CF060000]        	mov     dx, [SbAddr]	; Print Sucessful message.
   357 000002A2 8A0D[D1060000]          	mov     cl, [SbIrq]
   358 000002A8 C0EA04                  	shr     dl, 4
   359 000002AB 80C230                  	add     dl, '0'
   360 000002AE 8815[8A070000]          	mov     [PortText], dl
   361 000002B4 80C130                  	add     cl, '0'
   362 000002B7 880D[93070000]          	mov     [IrqText], cl
   363                                  
   364                                  	sys	_msg, MsgFound, 255, 0Fh
   364                              <1> 
   364                              <1> 
   364                              <1> 
   364                              <1> 
   364                              <1>  %if %0 >= 2
   364 000002BD BB[6A070000]        <1>  mov ebx, %2
   364                              <1>  %if %0 >= 3
   364 000002C2 B9FF000000          <1>  mov ecx, %3
   364                              <1>  %if %0 = 4
   364 000002C7 BA0F000000          <1>  mov edx, %4
   364                              <1>  %endif
   364                              <1>  %endif
   364                              <1>  %endif
   364 000002CC B823000000          <1>  mov eax, %1
   364                              <1> 
   364 000002D1 CD40                <1>  int 40h
   365                                  
   366 000002D3 61                      	popad	; Return to caller.
   367 000002D4 C3                      	retn
   368                                  
   369                                  Fail:  
   370                                  	; Print Failed Message,
   371                                  	; and exit to MainProg.
   372                                  
   373                                  	sys	_msg, MsgNotFound, 255, 0Fh
   373                              <1> 
   373                              <1> 
   373                              <1> 
   373                              <1> 
   373                              <1>  %if %0 >= 2
   373 000002D5 BB[42070000]        <1>  mov ebx, %2
   373                              <1>  %if %0 >= 3
   373 000002DA B9FF000000          <1>  mov ecx, %3
   373                              <1>  %if %0 = 4
   373 000002DF BA0F000000          <1>  mov edx, %4
   373                              <1>  %endif
   373                              <1>  %endif
   373                              <1>  %endif
   373 000002E4 B823000000          <1>  mov eax, %1
   373                              <1> 
   373 000002E9 CD40                <1>  int 40h
   374                                  
   375                                  	sys 	_exit
   375                              <1> 
   375                              <1> 
   375                              <1> 
   375                              <1> 
   375                              <1>  %if %0 >= 2
   375                              <1>  mov ebx, %2
   375                              <1>  %if %0 >= 3
   375                              <1>  mov ecx, %3
   375                              <1>  %if %0 = 4
   375                              <1>  mov edx, %4
   375                              <1>  %endif
   375                              <1>  %endif
   375                              <1>  %endif
   375 000002EB B801000000          <1>  mov eax, %1
   375                              <1> 
   375 000002F0 CD40                <1>  int 40h
   376                                  
   377 000002F2 E926FEFFFF              	jmp	here
   378                                  
   379                                  ;open or create file
   380                                  ;
   381                                  ;input: ds:dx-->filename (asciiz)
   382                                  ;       al=file Mode (create or open)
   383                                  ;output: none  cs:[FileHandle] filled
   384                                  ;
   385                                  openFile:
   386                                  	;;push	eax
   387                                  	;;push	ecx
   388                                  	;mov	ah, 3Bh	; start with a mode
   389                                  	;add	ah, al	; add in create or open mode
   390                                  	;xor	cx, cx
   391                                  	;int	21h
   392                                  	;jc	short _of1
   393                                  	;;mov	[cs:FileHandle], ax
   394                                  
   395                                  	sys	_open, wav_file_name, 0
   395                              <1> 
   395                              <1> 
   395                              <1> 
   395                              <1> 
   395                              <1>  %if %0 >= 2
   395 000002F7 BB[E2070000]        <1>  mov ebx, %2
   395                              <1>  %if %0 >= 3
   395 000002FC B900000000          <1>  mov ecx, %3
   395                              <1>  %if %0 = 4
   395                              <1>  mov edx, %4
   395                              <1>  %endif
   395                              <1>  %endif
   395                              <1>  %endif
   395 00000301 B805000000          <1>  mov eax, %1
   395                              <1> 
   395 00000306 CD40                <1>  int 40h
   396 00000308 7205                    	jc	short _of1
   397                                  
   398 0000030A A3[B8070000]            	mov	[FileHandle], eax
   399                                  _of1:
   400                                  	;;pop	ecx
   401                                  	;;pop	eax
   402 0000030F C3                      	retn
   403                                  
   404                                  ; close the currently open file
   405                                  ; input: none, uses cs:[FileHandle]
   406                                  closeFile:
   407                                  	;push	eax
   408                                  	;push	ebx
   409 00000310 833D[B8070000]FF        	cmp	dword [FileHandle], -1
   410 00000317 740D                    	je	short _cf1
   411                                  	;mov    bx, [FileHandle]  
   412                                  	;mov    ax, 3E00h
   413                                          ;int    21h              ;close file
   414                                  
   415                                  	sys	_close, [FileHandle]
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1> 
   415                              <1>  %if %0 >= 2
   415 00000319 8B1D[B8070000]      <1>  mov ebx, %2
   415                              <1>  %if %0 >= 3
   415                              <1>  mov ecx, %3
   415                              <1>  %if %0 = 4
   415                              <1>  mov edx, %4
   415                              <1>  %endif
   415                              <1>  %endif
   415                              <1>  %endif
   415 0000031F B806000000          <1>  mov eax, %1
   415                              <1> 
   415 00000324 CD40                <1>  int 40h
   416                                  _cf1:
   417                                  	;pop	ebx
   418                                  	;pop	eax
   419 00000326 C3                      	retn
   420                                  
   421                                  getSampleRate:
   422                                  	
   423                                  ; reads the sample rate from the .wav file.
   424                                  ; entry: none - assumes file is already open
   425                                  ; exit: ax = sample rate (11025, 22050, 44100, 48000)
   426                                  ;	cx = number of channels (mono=1, stereo=2)
   427                                  ;	dx = bits per sample (8, 16)
   428                                  
   429 00000327 53                      	push    ebx
   430                                  
   431                                          ;mov	ah, 42h
   432                                          ;mov	al, 0	; from start of file
   433                                          ;mov	bx, [FileHandle]
   434                                          ;xor	cx, cx
   435                                          ;mov	dx, 08h	; "WAVE"
   436                                          ;int	21h
   437                                  	
   438                                  	sys	_seek, [FileHandle], 8, 0
   438                              <1> 
   438                              <1> 
   438                              <1> 
   438                              <1> 
   438                              <1>  %if %0 >= 2
   438 00000328 8B1D[B8070000]      <1>  mov ebx, %2
   438                              <1>  %if %0 >= 3
   438 0000032E B908000000          <1>  mov ecx, %3
   438                              <1>  %if %0 = 4
   438 00000333 BA00000000          <1>  mov edx, %4
   438                              <1>  %endif
   438                              <1>  %endif
   438                              <1>  %endif
   438 00000338 B813000000          <1>  mov eax, %1
   438                              <1> 
   438 0000033D CD40                <1>  int 40h
   439                                  
   440                                          ;mov	dx, smpRBuff
   441                                          ;mov	cx, 28	; 28 bytes
   442                                  	;mov	ah, 3fh
   443                                          ;int	21h
   444                                  
   445                                  	sys	_read, [FileHandle], smpRBuff, 28
   445                              <1> 
   445                              <1> 
   445                              <1> 
   445                              <1> 
   445                              <1>  %if %0 >= 2
   445 0000033F 8B1D[B8070000]      <1>  mov ebx, %2
   445                              <1>  %if %0 >= 3
   445 00000345 B9[BC070000]        <1>  mov ecx, %3
   445                              <1>  %if %0 = 4
   445 0000034A BA1C000000          <1>  mov edx, %4
   445                              <1>  %endif
   445                              <1>  %endif
   445                              <1>  %endif
   445 0000034F B803000000          <1>  mov eax, %1
   445                              <1> 
   445 00000354 CD40                <1>  int 40h
   446                                  
   447 00000356 813D[BC070000]5741-     	cmp	dword [smpRBuff], 'WAVE'
   447 0000035E 5645               
   448 00000360 7520                    	jne	short gsr_stc
   449                                  
   450 00000362 66833D[C8070000]01      	cmp	word [smpRBuff+12], 1	; Offset 20, must be 1 (= PCM)
   451 0000036A 7516                    	jne	short gsr_stc
   452                                  
   453 0000036C 668B0D[CA070000]        	mov	cx, [smpRBuff+14]	; return num of channels in CX
   454 00000373 66A1[CC070000]                  mov     ax, [smpRBuff+16]	; return sample rate in AX
   455 00000379 668B15[D6070000]        	mov	dx, [smpRBuff+26]	; return bits per sample value in DX
   456                                  gsr_retn:
   457 00000380 5B                              pop     ebx
   458 00000381 C3                              retn
   459                                  
   460                                  gsr_stc:
   461 00000382 F9                      	stc
   462 00000383 EBFB                    	jmp	short gsr_retn
   463                                  
   464                                  DmaBufSize	equ     65536		; 64K file buffer size.
   465                                  ENDOFFILE       equ     1		; flag for knowing end of file
   466                                  
   467                                  %macro	SbOut	1
   468                                  %%Wait:
   469                                  	;in	al, dx
   470                                  	mov	ah, 0
   471                                  	int	34h
   472                                  	or	al, al
   473                                  	js	short %%Wait
   474                                  	mov	al, %1
   475                                  	;out	dx, al
   476                                  	mov	ah, 1
   477                                  	int	34h
   478                                  %endmacro
   479                                  
   480                                  SbInit:
   481 00000385 60                      	pushad
   482                                  
   483                                  SetBuffer:
   484                                  	;mov	byte [DmaFlag], 0
   485                                  	; 10/03/2017
   486 00000386 8B1D[F2070000]          	mov	ebx, [DMA_phy_buff] ; physical addr of DMA buff
   487 0000038C B900000100              	mov     ecx, DmaBufSize
   488 00000391 49                      	dec     ecx
   489                                  
   490 00000392 803D[DC070000]10        	cmp	byte [bps], 16
   491 00000399 753B                    	jne	short _0 ; set 8 bit DMA buffer
   492                                  	
   493                                  	; 16 bit DMA buffer setting (DMA channel 5)
   494 0000039B B005                    	mov     al, 05h ; set mask bit for channel 5  (4+1)
   495                                  	;out	0D4h, al
   496 0000039D 66BAD400                	mov	dx, 0D4h ; DMA mask register
   497 000003A1 B401                    	mov	ah, 1  ;outb
   498 000003A3 CD34                    	int	34h
   499                                  
   500 000003A5 30C0                    	xor     al, al ; stops all DMA processes on selected channel
   501                                  	;out	0D8h, al
   502 000003A7 B2D8                    	mov	dl, 0D8h  ; clear selected channel register
   503                                  	;mov	ah, 1  ;outb
   504 000003A9 CD34                    	int	34h
   505                                  
   506 000003AB 88D8                    	mov     al, bl	; byte 0 of DMA buffer address (physical)   
   507                                  	;out	0C4, al
   508 000003AD B2C4                    	mov	dl, 0C4h ; DMA channel 5 port number
   509                                  	;mov	ah, 1  ;outb
   510 000003AF CD34                    	int	34h
   511                                  
   512 000003B1 88F8                    	mov     al, bh  ; byte 1 of DMA buffer address (physical)   
   513                                  	;out	0C4h, al
   514                                  	;mov	dl, 0C4h ; DMA channel 5 port number
   515                                  	;mov	ah, 1  ;outb
   516 000003B3 CD34                    	int	34h
   517                                  
   518 000003B5 C1EB10                  	shr	ebx, 16
   519                                  
   520 000003B8 88D8                    	mov     al, bl ; byte 2 of DMA buffer address (physical)   
   521                                  	;out	89h, al
   522 000003BA B289                    	mov	dl, 89h ; page register port addr for channel 5
   523                                  	;mov	ah, 1  ;outb
   524 000003BC CD34                    	int	34h
   525                                  
   526 000003BE 88C8                    	mov     al, cl ; low byte of DMA count - 1
   527                                  	;out	0C6h, al
   528 000003C0 B2C6                    	mov	dl, 0C6h ; count register port addr for channel 1
   529                                  	;mov	ah, 1  ;outb
   530 000003C2 CD34                    	int	34h
   531                                  
   532 000003C4 88E8                    	mov     al, ch ; high byte of DMA count - 1
   533                                  	;out	0C6h, al
   534                                  	;mov	dl, 0C6h ; count register port addr for channel 1
   535                                  	;mov	ah, 1  ;outb
   536 000003C6 CD34                    	int	34h
   537                                  
   538                                  	; channel 5, read, autoinitialized, single mode
   539 000003C8 B049                    	mov     al, 49h 
   540                                  	;out	0D6h, al
   541 000003CA B2D6                    	mov	dl, 0D6h ; DMA mode register port address
   542                                  	;mov	ah, 1  ;outb
   543 000003CC CD34                    	int	34h
   544                                  
   545 000003CE B001                    	mov     al, 01h ; clear mask bit for channel 1
   546                                  	;out	0D4h, al
   547 000003D0 B2D4                    	mov	dl, 0D4h ; DMA mask register port address
   548                                  	;mov	ah, 1  ;outb
   549 000003D2 CD34                    	int	34h
   550                                  
   551 000003D4 EB39                    	jmp	short ClearBuffer
   552                                  _0:    
   553                                  	; 8 bit DMA buffer setting (DMA channel 1)
   554 000003D6 B005                    	mov     al, 05h ; set mask bit for channel 1  (4+1)
   555                                  	;out	0Ah, al
   556 000003D8 66BA0A00                	mov	dx, 0Ah ; DMA mask register
   557 000003DC B401                    	mov	ah, 1  ;outb
   558 000003DE CD34                    	int	34h
   559                                  
   560 000003E0 30C0                    	xor     al, al ; stops all DMA processes on selected channel
   561                                  	;out	0Ch, al
   562 000003E2 B20C                    	mov	dl, 0Ch  ; clear selected channel register
   563                                  	;mov	ah, 1  ;outb
   564 000003E4 CD34                    	int	34h
   565                                  
   566 000003E6 88D8                    	mov     al, bl	; byte 0 of DMA buffer address (physical)   
   567                                  	;out	02h, al
   568 000003E8 B202                    	mov	dl, 02h	; DMA channel 1 port number
   569                                  	;mov	ah, 1  ;outb
   570 000003EA CD34                    	int	34h
   571                                  
   572 000003EC 88F8                    	mov     al, bh  ; byte 1 of DMA buffer address (physical)   
   573                                  	;out	02h, al
   574                                  	;mov	dl, 02h ; DMA channel 1 port number
   575                                  	;mov	ah, 1  ;outb
   576 000003EE CD34                    	int	34h
   577                                  
   578 000003F0 C1EB10                  	shr	ebx, 16
   579                                  
   580 000003F3 88D8                    	mov     al, bl ; byte 2 of DMA buffer address (physical)   
   581                                  	;out	83h, al
   582 000003F5 B283                    	mov	dl, 83h ; page register port addr for channel 1
   583                                  	;mov	ah, 1  ;outb
   584 000003F7 CD34                    	int	34h
   585                                  
   586 000003F9 88C8                    	mov     al, cl ; low byte of DMA count - 1
   587                                  	;out	03h, al
   588 000003FB B203                    	mov	dl, 03h ; count register port addr for channel 1
   589                                  	;mov	ah, 1  ;outb
   590 000003FD CD34                    	int	34h
   591                                  
   592 000003FF 88E8                    	mov     al, ch ; high byte of DMA count - 1
   593                                  	;out	03h, al
   594                                  	;mov	dl, 03h ; count register port addr for channel 1
   595                                  	;mov	ah, 1  ;outb
   596 00000401 CD34                    	int	34h
   597                                  
   598                                  	; channel 1, read, autoinitialized, single mode
   599 00000403 B049                    	mov     al, 49h 
   600                                  	;out	0Bh, al
   601 00000405 B20B                    	mov	dl, 0Bh ; DMA mode register port address
   602                                  	;mov	ah, 1  ;outb
   603 00000407 CD34                    	int	34h
   604                                  
   605 00000409 B001                    	mov     al, 01h ; clear mask bit for channel 1
   606                                  	;out	0Ah, al
   607 0000040B B20A                    	mov	dl, 0Ah ; DMA mask register port address
   608                                  	;mov	ah, 1  ;outb
   609 0000040D CD34                    	int	34h
   610                                  
   611                                  ClearBuffer:
   612 0000040F BF[00000100]            	mov     edi, DmaBuffer  ; virtual addr of DMA buff
   613                                  	;mov	ecx, DmaBufSize
   614 00000414 41                      	inc	ecx
   615 00000415 B080                    	mov     al, 80h
   616                                  	;cld
   617 00000417 F3AA                    	rep     stosb
   618                                  SetIrq:
   619                                  	; CALLBACK method
   620 00000419 8A1D[D1060000]          	mov	bl, [SbIrq] ; IRQ number
   621 0000041F B702                    	mov	bh, 2 ; Link IRQ to user for callback service
   622 00000421 BA[46050000]            	mov	edx, SbIrqHandler
   623                                  	sys	_calbac 
   623                              <1> 
   623                              <1> 
   623                              <1> 
   623                              <1> 
   623                              <1>  %if %0 >= 2
   623                              <1>  mov ebx, %2
   623                              <1>  %if %0 >= 3
   623                              <1>  mov ecx, %3
   623                              <1>  %if %0 = 4
   623                              <1>  mov edx, %4
   623                              <1>  %endif
   623                              <1>  %endif
   623                              <1>  %endif
   623 00000426 B82C000000          <1>  mov eax, %1
   623                              <1> 
   623 0000042B CD40                <1>  int 40h
   624                                  	; SIGNAL RESPONSE BYTE method ; 04/03/2017
   625                                  	;mov	bl, [SbIrq]
   626                                  	;mov	bh, 1 ; Signal Response Byte method
   627                                  	;movzx	ecx, bl ; S.R.B. value = IRQ Number 
   628                                  	;mov	edx, SbSrb ; S.R.B. address
   629                                  	;sys	_calbac
   630                                  ResetDsp:
   631 0000042D 668B15[CF060000]        	mov     dx, [SbAddr]
   632 00000434 6683C206                	add     dx, 06h
   633 00000438 B001                    	mov     al, 1
   634                                  	;out	dx, al
   635 0000043A B401                    	mov	ah, 1  ;outb
   636 0000043C CD34                    	int	34h
   637                                  
   638                                  	;in	al, dx
   639                                  	;in	al, dx
   640                                  	;in	al, dx
   641                                  	;in	al, dx
   642                                  
   643 0000043E FECC                    	dec	ah ; ah = 0 ; inb
   644 00000440 CD34                    	int	34h	
   645                                  	;mov	ah, 0
   646 00000442 CD34                    	int	34h
   647                                  
   648 00000444 30C0                    	xor     al, al
   649                                  	;out	dx, al
   650 00000446 FEC4                    	inc	ah ; ah = 1 ;outb
   651 00000448 CD34                    	int	34h
   652                                  
   653 0000044A 66B96400                	mov     cx, 100
   654 0000044E 28E4                    	sub	ah, ah ; 0
   655                                  WaitId:         
   656 00000450 668B15[CF060000]        	mov     dx, [SbAddr]
   657 00000457 6683C20E                	add     dx, 0Eh
   658                                  	;in	al, dx
   659                                  	;mov	ah, 0  ;inb
   660 0000045B CD34                    	int	34h
   661 0000045D 08C0                    	or      al, al
   662 0000045F 7807                    	js      short sb_GetId
   663 00000461 E2ED                    	loop    WaitId
   664 00000463 E9DC000000              	jmp     sb_Exit
   665                                  sb_GetId:
   666 00000468 668B15[CF060000]        	mov     dx, [SbAddr]
   667 0000046F 6683C20A                	add     dx, 0Ah
   668                                  	;in	al, dx
   669                                  	;mov	ah, 0  ;inb
   670 00000473 CD34                    	int	34h
   671 00000475 3CAA                    	cmp     al, 0AAh
   672 00000477 7407                    	je      short SbOk
   673 00000479 E2D5                    	loop    WaitId
   674 0000047B E9C4000000              	jmp	sb_Exit
   675                                  SbOk:
   676 00000480 668B15[CF060000]        	mov     dx, [SbAddr]
   677 00000487 6683C20C                	add     dx, 0Ch
   678                                  	SbOut   0D1h ; Turn on speaker
   678                              <1> %%Wait:
   678                              <1> 
   678 0000048B B400                <1>  mov ah, 0
   678 0000048D CD34                <1>  int 34h
   678 0000048F 08C0                <1>  or al, al
   678 00000491 78F8                <1>  js short %%Wait
   678 00000493 B0D1                <1>  mov al, %1
   678                              <1> 
   678 00000495 B401                <1>  mov ah, 1
   678 00000497 CD34                <1>  int 34h
   679                                  	; 10/03/2017
   680                                  	SbOut   41h ; 8 bit or 16 bit transfer
   680                              <1> %%Wait:
   680                              <1> 
   680 00000499 B400                <1>  mov ah, 0
   680 0000049B CD34                <1>  int 34h
   680 0000049D 08C0                <1>  or al, al
   680 0000049F 78F8                <1>  js short %%Wait
   680 000004A1 B041                <1>  mov al, %1
   680                              <1> 
   680 000004A3 B401                <1>  mov ah, 1
   680 000004A5 CD34                <1>  int 34h
   681 000004A7 668B1D[D8070000]        	mov	bx, [sampling_rate]
   682                                  	SbOut	bh ; sampling rate high byte
   682                              <1> %%Wait:
   682                              <1> 
   682 000004AE B400                <1>  mov ah, 0
   682 000004B0 CD34                <1>  int 34h
   682 000004B2 08C0                <1>  or al, al
   682 000004B4 78F8                <1>  js short %%Wait
   682 000004B6 88F8                <1>  mov al, %1
   682                              <1> 
   682 000004B8 B401                <1>  mov ah, 1
   682 000004BA CD34                <1>  int 34h
   683                                  	SbOut	bl ; sampling rate low byte
   683                              <1> %%Wait:
   683                              <1> 
   683 000004BC B400                <1>  mov ah, 0
   683 000004BE CD34                <1>  int 34h
   683 000004C0 08C0                <1>  or al, al
   683 000004C2 78F8                <1>  js short %%Wait
   683 000004C4 88D8                <1>  mov al, %1
   683                              <1> 
   683 000004C6 B401                <1>  mov ah, 1
   683 000004C8 CD34                <1>  int 34h
   684                                  	; 22/04/2017
   685                                  	;mov	ah, 1
   686                                  	;mov	dx, [SbAddr]
   687                                  	;add	dx, 4 ; Mixer chip address port
   688 000004CA 6683EA08                	sub	dx, 0Ch-04h
   689 000004CE B022                    	mov	al, 22h ; master volume
   690 000004D0 CD34                    	int	34h
   691 000004D2 6642                    	inc	dx
   692 000004D4 B0FF                    	mov	al, 0FFh ; maximum volume level
   693 000004D6 CD34                    	int	34h
   694 000004D8 6683C207                	add	dx, 0Ch-05h
   695                                  StartDma:  
   696                                  	; autoinitialized mode
   697 000004DC 803D[DC070000]10        	cmp	byte [bps], 16 ; 16 bit samples
   698 000004E3 7411                    	je	short _1
   699                                  	; 8 bit samples
   700 000004E5 66BBC600                	mov	bx, 0C6h ; 8 bit output (0C6h)
   701 000004E9 803D[DA070000]02        	cmp	byte [stmo], 2 ; 1 = mono, 2 = stereo
   702 000004F0 7214                    	jb	short _2
   703 000004F2 B720                    	mov	bh, 20h	; 8 bit stereo (20h)
   704 000004F4 EB10                    	jmp	short _2
   705                                  _1:
   706                                  	; 16 bit samples
   707 000004F6 66BBB610                	mov	bx, 10B6h ; 16 bit output (0B6h)
   708 000004FA 803D[DA070000]02        	cmp	byte [stmo], 2 ; 1 = mono, 2 = stereo
   709 00000501 7203                    	jb	short _2
   710 00000503 80C720                  	add	bh, 20h	; 16 bit stereo (30h)
   711                                  _2:     
   712                                  	; PCM output (8/16 bit mono autoinitialized transfer)
   713                                  	SbOut   bl ; bCommand
   713                              <1> %%Wait:
   713                              <1> 
   713 00000506 B400                <1>  mov ah, 0
   713 00000508 CD34                <1>  int 34h
   713 0000050A 08C0                <1>  or al, al
   713 0000050C 78F8                <1>  js short %%Wait
   713 0000050E 88D8                <1>  mov al, %1
   713                              <1> 
   713 00000510 B401                <1>  mov ah, 1
   713 00000512 CD34                <1>  int 34h
   714                                  	SbOut	bh ; bMode
   714                              <1> %%Wait:
   714                              <1> 
   714 00000514 B400                <1>  mov ah, 0
   714 00000516 CD34                <1>  int 34h
   714 00000518 08C0                <1>  or al, al
   714 0000051A 78F8                <1>  js short %%Wait
   714 0000051C 88F8                <1>  mov al, %1
   714                              <1> 
   714 0000051E B401                <1>  mov ah, 1
   714 00000520 CD34                <1>  int 34h
   715 00000522 66BB0080                	mov	bx, DmaBufSize / 2
   716 00000526 664B                    	dec	bx  ; wBlkSize is one less than the actual size 
   717                                  	SbOut   bl
   717                              <1> %%Wait:
   717                              <1> 
   717 00000528 B400                <1>  mov ah, 0
   717 0000052A CD34                <1>  int 34h
   717 0000052C 08C0                <1>  or al, al
   717 0000052E 78F8                <1>  js short %%Wait
   717 00000530 88D8                <1>  mov al, %1
   717                              <1> 
   717 00000532 B401                <1>  mov ah, 1
   717 00000534 CD34                <1>  int 34h
   718                                  	SbOut   bh
   718                              <1> %%Wait:
   718                              <1> 
   718 00000536 B400                <1>  mov ah, 0
   718 00000538 CD34                <1>  int 34h
   718 0000053A 08C0                <1>  or al, al
   718 0000053C 78F8                <1>  js short %%Wait
   718 0000053E 88F8                <1>  mov al, %1
   718                              <1> 
   718 00000540 B401                <1>  mov ah, 1
   718 00000542 CD34                <1>  int 34h
   719                                  
   720                                  	;; Set Voice and master volumes
   721                                  	;mov	dx, [SbAddr]
   722                                  	;add	dl, 4 ; Mixer chip Register Address Port
   723                                  	;SbOut	30h   ; select Master Volume Register (L)
   724                                  	;inc	dl    ; Mixer chip Register Data Port
   725                                  	;SbOut	0F8h  ; Max. volume value is 31 (31*8)
   726                                  	;dec	dl
   727                                  	;SbOut	31h   ; select Master Volume Register (R)
   728                                  	;inc	dl
   729                                  	;SbOut	0F8h  ; Max. volume value is 31 (31*8)
   730                                  	;dec	dl
   731                                  	;SbOut	32h   ; select Voice Volume Register (L)
   732                                  	;inc	dl
   733                                  	;SbOut	0F8h  ; Max. volume value is 31 (31*8)
   734                                  	;dec	dl
   735                                  	;SbOut	33h   ; select Voice Volume Register (R)
   736                                  	;inc	dl
   737                                  	;SbOut	0F8h  ; Max. volume value is 31 (31*8)	
   738                                  	;;
   739                                  	;dec	dl
   740                                  	;SbOut	44h   ; select Treble Register (L)
   741                                  	;inc	dl
   742                                  	;SbOut	0F0h  ; Max. Treble value is 15 (15*16)
   743                                  	;dec	dl
   744                                  	;SbOut	45h   ; select Treble Register (R)
   745                                  	;inc	dl
   746                                  	;SbOut	0F0h  ; Max. Treble value is 15 (15*16)
   747                                  	;dec	dl
   748                                  	;SbOut	46h   ; select Bass Register (L)
   749                                  	;inc	dl
   750                                  	;SbOut	0F0h  ; Max. Bass value is 15 (15*16)
   751                                  	;dec	dl
   752                                  	;SbOut	47h   ; select Bass Register (R)
   753                                  	;inc	dl
   754                                  	;SbOut	0F0h  ; Max. Bass value is 15 (15*16)	
   755                                  
   756                                  sb_Exit:           
   757 00000544 61                      	popad
   758 00000545 C3                      	retn
   759                                  
   760                                  SbIrqHandler:  ; SoundBlaster IRQ Callback service for TRDOS 386
   761                                  	; 10/03/2017
   762 00000546 668B15[CF060000]        	mov     dx, [SbAddr]
   763 0000054D 6683C20E                	add     dx, 0Eh
   764                                  	;in	al, dx
   765                                  	;mov	ah, 0
   766 00000551 28E4                    	sub	ah, ah
   767 00000553 CD34                    	int	34h
   768                                  
   769 00000555 F605[E0070000]01        	test	byte [flags], ENDOFFILE	; end of file flag
   770 0000055C 741F                    	jz	short _4
   771                                  
   772 0000055E 6683EA02                	sub     dx, 02h ; 0Ch
   773                                  
   774 00000562 B3D9                    	mov	bl, 0D9h ; exit auto-initialize 16 bit transfer
   775                                  	; auto initialized mode 
   776 00000564 803D[DC070000]10        	cmp	byte [bps], 16 ; 16 bit samples
   777 0000056B 7402                    	je	short _3
   778                                  	;mov	bl, 0DAh ; exit auto-initialize 8 bit transfer
   779 0000056D FEC3                    	inc	bl
   780                                  _3:
   781                                  	SbOut	bl ; exit auto-initialize transfer command
   781                              <1> %%Wait:
   781                              <1> 
   781 0000056F B400                <1>  mov ah, 0
   781 00000571 CD34                <1>  int 34h
   781 00000573 08C0                <1>  or al, al
   781 00000575 78F8                <1>  js short %%Wait
   781 00000577 88D8                <1>  mov al, %1
   781                              <1> 
   781 00000579 B401                <1>  mov ah, 1
   781 0000057B CD34                <1>  int 34h
   782                                  _4:
   783                                  	; 09/03/2017
   784 0000057D 30C0                    	xor	al, al ; 0
   785 0000057F A2[E1070000]            	mov	[iStatus], al ; 10/03/2017
   786 00000584 3805[DE070000]          	cmp 	[DmaFlag], al ; 0
   787 0000058A 7702                    	ja	short SbIrq_iret
   788 0000058C FEC0                    	inc	al
   789                                  SbIrq_iret:
   790 0000058E A2[DE070000]            	mov 	[DmaFlag], al ; 
   791                                  	sys	_rele ; return from callback service
   791                              <1> 
   791                              <1> 
   791                              <1> 
   791                              <1> 
   791                              <1>  %if %0 >= 2
   791                              <1>  mov ebx, %2
   791                              <1>  %if %0 >= 3
   791                              <1>  mov ecx, %3
   791                              <1>  %if %0 = 4
   791                              <1>  mov edx, %4
   791                              <1>  %endif
   791                              <1>  %endif
   791                              <1>  %endif
   791 00000593 B827000000          <1>  mov eax, %1
   791                              <1> 
   791 00000598 CD40                <1>  int 40h
   792                                  
   793                                  SbPoll:	;  Sound Blaster Polling.
   794 0000059A 60                      	pushad
   795                                  
   796                                  	; 10/03/2017
   797 0000059B 803D[E1070000]00        	cmp	byte [iStatus], 0
   798 000005A2 772C                    	ja	short Bye
   799                                  
   800 000005A4 C605[E1070000]01        	mov	byte [iStatus], 1 ; 1 = set before interrupt
   801                                  			     ; (for preventing data load
   802                                  			     ; without an interrupt)		
   803                                  
   804 000005AB F605[E0070000]01        	test	byte [flags], ENDOFFILE
   805 000005B2 751E                    	jnz	short sbPoll_stop
   806                                  	
   807 000005B4 B8[00000100]            	mov     eax, DmaBuffer
   808 000005B9 BA00800000              	mov     edx, DmaBufSize/2
   809                                  
   810 000005BE F605[DE070000]01        	test	byte [DmaFlag], 1
   811 000005C5 7402                    	jz     short FirstHalf
   812                                  SecondHalf: ; write to the second half    
   813 000005C7 01D0                    	add     eax, edx
   814                                  FirstHalf: ; write to the first half
   815 000005C9 E86C000000              	call    loadFromFile
   816 000005CE 7202                    	jc	short sbPoll_stop
   817                                  Bye:
   818 000005D0 61                      	popad
   819 000005D1 C3                      	retn
   820                                  
   821                                  sbPoll_stop:
   822                                  	; 24/04/2017
   823 000005D2 668B15[CF060000]        	mov     dx, [SbAddr]
   824 000005D9 6683C20C                	add     dx, 0Ch
   825                                  	;
   826 000005DD B3D9                    	mov	bl, 0D9h ; exit auto-initialize 16 bit transfer
   827                                  	; stop  autoinitialized DMA transfer mode 
   828 000005DF 803D[DC070000]10        	cmp	byte [bps], 16 ; 16 bit samples
   829 000005E6 7402                    	je	short _5
   830                                  	;mov	bl, 0DAh ; exit auto-initialize 8 bit transfer
   831 000005E8 FEC3                    	inc	bl
   832                                  _5:
   833                                  	SbOut	bl ; exit auto-initialize transfer command
   833                              <1> %%Wait:
   833                              <1> 
   833 000005EA B400                <1>  mov ah, 0
   833 000005EC CD34                <1>  int 34h
   833 000005EE 08C0                <1>  or al, al
   833 000005F0 78F8                <1>  js short %%Wait
   833 000005F2 88D8                <1>  mov al, %1
   833                              <1> 
   833 000005F4 B401                <1>  mov ah, 1
   833 000005F6 CD34                <1>  int 34h
   834                                  
   835 000005F8 C605[DF070000]00        	mov	byte [tLoop], 0
   836 000005FF EBCF                    	jmp	short Bye
   837                                  
   838                                  SbDone:
   839 00000601 60                      	pushad
   840                                  
   841 00000602 8A1D[D1060000]          	mov     bl, [SbIrq] ; IRQ number
   842 00000608 28FF                    	sub	bh, bh ; 0 = Unlink IRQ from user
   843                                  	sys	_calbac 
   843                              <1> 
   843                              <1> 
   843                              <1> 
   843                              <1> 
   843                              <1>  %if %0 >= 2
   843                              <1>  mov ebx, %2
   843                              <1>  %if %0 >= 3
   843                              <1>  mov ecx, %3
   843                              <1>  %if %0 = 4
   843                              <1>  mov edx, %4
   843                              <1>  %endif
   843                              <1>  %endif
   843                              <1>  %endif
   843 0000060A B82C000000          <1>  mov eax, %1
   843                              <1> 
   843 0000060F CD40                <1>  int 40h
   844                                  
   845 00000611 668B15[CF060000]        	mov     dx, [SbAddr]
   846 00000618 6683C20C                	add     dx, 0Ch
   847                                  	SbOut   0D0h
   847                              <1> %%Wait:
   847                              <1> 
   847 0000061C B400                <1>  mov ah, 0
   847 0000061E CD34                <1>  int 34h
   847 00000620 08C0                <1>  or al, al
   847 00000622 78F8                <1>  js short %%Wait
   847 00000624 B0D0                <1>  mov al, %1
   847                              <1> 
   847 00000626 B401                <1>  mov ah, 1
   847 00000628 CD34                <1>  int 34h
   848                                  	SbOut   0D3h
   848                              <1> %%Wait:
   848                              <1> 
   848 0000062A B400                <1>  mov ah, 0
   848 0000062C CD34                <1>  int 34h
   848 0000062E 08C0                <1>  or al, al
   848 00000630 78F8                <1>  js short %%Wait
   848 00000632 B0D3                <1>  mov al, %1
   848                              <1> 
   848 00000634 B401                <1>  mov ah, 1
   848 00000636 CD34                <1>  int 34h
   849                                  
   850 00000638 61                      	popad
   851 00000639 C3                      	retn
   852                                  
   853                                  loadFromFile:
   854                                  	; 10/03/2017
   855                                          ;push	eax
   856                                          ;push	ecx
   857                                          ;push	edx
   858                                  	;push	ebx
   859 0000063A F605[E0070000]01                test    byte [flags], ENDOFFILE	; have we already read the
   860 00000641 F9                              stc			; last of the file?
   861 00000642 7533                            jnz     short endLFF
   862 00000644 89C7                    	mov	edi, eax ; buffer address
   863                                  	;mov	edx, (DmaBufSize/2)
   864                                  	; load file into memory
   865                                  	sys 	_read, [FileHandle], edi
   865                              <1> 
   865                              <1> 
   865                              <1> 
   865                              <1> 
   865                              <1>  %if %0 >= 2
   865 00000646 8B1D[B8070000]      <1>  mov ebx, %2
   865                              <1>  %if %0 >= 3
   865 0000064C 89F9                <1>  mov ecx, %3
   865                              <1>  %if %0 = 4
   865                              <1>  mov edx, %4
   865                              <1>  %endif
   865                              <1>  %endif
   865                              <1>  %endif
   865 0000064E B803000000          <1>  mov eax, %1
   865                              <1> 
   865 00000653 CD40                <1>  int 40h
   866 00000655 89D1                    	mov	ecx, edx
   867 00000657 720A                    	jc	short padfill ; error !
   868 00000659 21C0                    	and	eax, eax
   869 0000065B 7406                    	jz	short padfill
   870 0000065D 29C1                    	sub	ecx, eax
   871 0000065F 7416                    	jz	short endLFF
   872 00000661 01C7                    	add	edi, eax  
   873                                  padfill:
   874 00000663 803D[DC070000]10        	cmp 	byte [bps], 16
   875 0000066A 740C                    	je	short _7
   876                                  	 ;Minmum Value = 0
   877 0000066C 30C0                            xor     al, al
   878 0000066E F3AA                    	rep	stosb
   879                                  _6:
   880                                          ;clc			; don't exit with CY yet.
   881 00000670 800D[E0070000]01                or	byte [flags], ENDOFFILE	; end of file flag
   882                                  endLFF:
   883                                  	;pop	ebx
   884                                  	;pop	edx
   885                                          ;pop	ecx
   886                                          ;pop	eax
   887 00000677 C3                              retn
   888                                  _7:
   889                                  	; Minimum value = 8000h (-32768)
   890 00000678 D1E9                    	shr	ecx, 1 
   891 0000067A 66B80080                	mov	ax, 8000h ; -32768
   892 0000067E F366AB                  	rep	stosw
   893 00000681 EBED                    	jmp	short _6
   894                                  
   895                                  PlayWav:
   896 00000683 C605[DF070000]01        	mov	byte [tLoop], 1
   897                                  tuneLoop:
   898 0000068A E80BFFFFFF              	call	SbPoll
   899                                  	
   900 0000068F 803D[DF070000]01        	cmp	byte [tLoop], 1
   901 00000696 721D                    	jb	short StopPlaying
   902                                  
   903 00000698 BE00800B00              	mov	esi, 0B8000h
   904 0000069D A0[DE070000]            	mov	al, [DmaFlag]
   905 000006A2 B44E                    	mov	ah, 4Eh
   906 000006A4 2401                    	and	al, 1
   907 000006A6 0431                    	add	al, '1'
   908 000006A8 668906                  	mov	[esi], ax ; show current play buffer (1, 2)
   909                                  	
   910 000006AB B401                    	mov     ah, 1			; any key pressed?
   911 000006AD CD32                    	int     32h			; no, Loop.
   912 000006AF 74D9                    	jz	short tuneLoop
   913                                  
   914 000006B1 B400                    	mov     ah, 0			; flush key buffer...
   915 000006B3 CD32                    	int     32h
   916                                  
   917                                  	;mov	byte [tLoop], 0
   918                                  
   919                                  StopPlaying:
   920                                  	; stop DMA process
   921 000006B5 30C0                    	xor     al, al
   922 000006B7 803D[DC070000]10        	cmp	byte [bps], 16
   923 000006BE 7406                    	je	short _8
   924                                  
   925                                  	; Stop 8 bit (autoinitialized) DMA process	
   926                                  	;out	0Ch, al
   927                                  	;retn
   928 000006C0 66BA0C00                	mov	dx, 0Ch
   929 000006C4 EB04                    	jmp	short _9
   930                                  _8:	
   931                                  	; Stop 16 bit (autoinitialized) DMA process
   932                                  	;out	0D8h, al
   933 000006C6 66BAD800                	mov	dx, 0D8h	
   934                                  _9:
   935 000006CA B401                    	mov	ah, 1 ;outb
   936 000006CC CD34                    	int	34h
   937                                  
   938 000006CE C3                      	retn
   939                                  
   940                                  _DATA:
   941                                  
   942                                  SbAddr:
   943 000006CF 2002                    	dw      220h
   944                                  SbIrq:
   945 000006D1 0700                    	dw      7
   946                                  
   947                                  msg_usage:
   948 000006D3 75736167653A20706C-     	db	'usage: playwav filename.wav',10,13,0
   948 000006DC 61797761762066696C-
   948 000006E5 656E616D652E776176-
   948 000006EE 0A0D00             
   949 000006F1 32322F30342F323031-     	db	'22/04/2017'
   949 000006FA 37                 
   950                                  
   951                                  Credits:
   952 000006FB 54696E792057415620-     	db	'Tiny WAV Player by Erdogan Tan. April 2017.'
   952 00000704 506C61796572206279-
   952 0000070D 204572646F67616E20-
   952 00000716 54616E2E2041707269-
   952 0000071F 6C20323031372E     
   953 00000726 0A0D00                  	db	10,13,0
   954                                  noFileErrMsg:
   955 00000729 4572726F723A206669-     	db	'Error: file not found.',10,13,0
   955 00000732 6C65206E6F7420666F-
   955 0000073B 756E642E0A0D00     
   956                                  MsgNotFound:
   957 00000742 536F756E6420426C61-     	db	'Sound Blaster not found or IRQ error.',10,13,0
   957 0000074B 73746572206E6F7420-
   957 00000754 666F756E64206F7220-
   957 0000075D 495251206572726F72-
   957 00000766 2E0A0D00           
   958                                  MsgFound:
   959 0000076A 536F756E6420426C61-     	db	'Sound Blaster found at Address 2'
   959 00000773 7374657220666F756E-
   959 0000077C 642061742041646472-
   959 00000785 6573732032         
   960                                  PortText:
   961 0000078A 7830682C2049525120      	db	'x0h, IRQ '
   962                                  IrqText:
   963 00000793 782E0A0D00              	db	'x.',10,13,0
   964                                  
   965                                  trdos386_err_msg:
   966 00000798 5452444F5320333836-     	db	'TRDOS 386 System call error !', 10, 13,0
   966 000007A1 2053797374656D2063-
   966 000007AA 616C6C206572726F72-
   966 000007B3 20210A0D00         
   967                                  
   968                                  FileHandle:	
   969 000007B8 FFFFFFFF                	dd	-1
   970                                  
   971                                  bss_start:
   972                                  
   973                                  ABSOLUTE bss_start
   974                                  
   975                                  alignb 4
   976                                  
   977                                  ; 28/11/2016
   978                                  
   979 000007BC <res 0000001C>          smpRBuff:	resw 14 
   980                                  
   981                                  sampling_rate:
   982 000007D8 <res 00000002>          		resw 1
   983                                  stmo:	
   984 000007DA <res 00000002>          		resw 1 
   985                                  bps:	
   986 000007DC <res 00000002>          		resw 1
   987                                  DmaFlag: 
   988 000007DE <res 00000001>          		resb 1
   989                                  tLoop:	
   990 000007DF <res 00000001>          		resb 1	
   991                                  flags:	
   992 000007E0 <res 00000001>          		resb 1
   993                                  iStatus:
   994 000007E1 <res 00000001>          		resb 1
   995                                  wav_file_name:
   996 000007E2 <res 00000010>          		resb 16
   997                                  
   998                                  DMA_phy_buff:
   999 000007F2 <res 00000004>          		resd 1
  1000 000007F6 <res 0000F80A>          alignb 65536
  1001 00010000 <res 00010000>          DmaBuffer:	resb 65536 ; 2 * 32K half buffer
  1002                                  EOF:
