     1                                  ; ****************************************************************************
     2                                  ; wavplay.s (for TRDOS 386)
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; WAVPLAY.PRG ! VIA VT8237 .WAV PLAYER program by Erdogan TAN
     5                                  ;
     6                                  ; 17/03/2017
     7                                  ;
     8                                  ; [ Last Modification: 17/03/2017 ]
     9                                  ;
    10                                  ; Modified from PLAYWAV.PRG .wav player program by Erdogan Tan, 10/03/2017 
    11                                  ;
    12                                  ; Derived from source code of 'PLAYER.COM' ('PLAYER.ASM') by Erdogan Tan
    13                                  ;	      (18/02/2017) 
    14                                  ; Assembler: NASM version 2.11
    15                                  ;	     nasm wavplay.asm -l wavplay.txt -o WAVPLAY.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[000B0000]        <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[5C0C0000]            	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 00000029 E8C8010000              	call    DetectVT8233	; Detect the VT8233 Audio Device
   110                                  GetFileName:  
   111 0000002E 89E6                    	mov	esi, esp
   112 00000030 AD                      	lodsd
   113 00000031 83F802                  	cmp	eax, 2 ; two arguments 
   114                                  	       ; (program file name & mod file name)
   115 00000034 0F828C010000            	jb	pmsg_usage ; nothing to do
   116                                  
   117 0000003A AD                      	lodsd ; program file name address 
   118 0000003B AD                      	lodsd ; mod file name address (file to be read)
   119 0000003C 89C6                    	mov	esi, eax
   120 0000003E BF[910C0000]            	mov	edi, wav_file_name
   121                                  ScanName:       
   122 00000043 AC                      	lodsb
   123 00000044 84C0                    	test	al, al
   124 00000046 0F847A010000            	je	pmsg_usage
   125 0000004C 3C20                    	cmp	al, 20h
   126 0000004E 74F3                    	je	short ScanName	; scan start of name.
   127 00000050 AA                      	stosb
   128 00000051 B4FF                    	mov	ah, 0FFh
   129                                  a_0:	
   130 00000053 FEC4                    	inc	ah
   131                                  a_1:
   132 00000055 AC                      	lodsb
   133 00000056 AA                      	stosb
   134 00000057 3C2E                    	cmp	al, '.'
   135 00000059 74F8                    	je	short a_0	
   136 0000005B 20C0                    	and	al, al
   137 0000005D 75F6                    	jnz	short a_1
   138                                  
   139 0000005F 08E4                    	or	ah, ah		 ; if period NOT found,
   140 00000061 750B                    	jnz	short init_codec ; then add a .WAV extension.
   141                                  SetExt:
   142 00000063 4F                      	dec	edi
   143 00000064 C7072E574156            	mov	dword [edi], '.WAV'
   144 0000006A C6470400                	mov	byte [edi+4], 0
   145                                  
   146                                  init_codec:
   147                                  	; init AC97 codec
   148                                  
   149 0000006E B041                    	mov	al, VIA_ACLINK_CTRL  ; AC link interface control (41h)
   150 00000070 E84C030000              	call	pciRegRead8
   151                                  
   152 00000075 B040                    	mov	al, VIA_ACLINK_STAT  ; AC Link interface status (40h)
   153 00000077 E845030000              	call	pciRegRead8
   154                                  	
   155                                  	;movzx	eax, dl
   156                                  	;test	al, VIA_ACLINK_C00_READY  ; 1 ; primary codec ready ?
   157                                  	;jnz	short a_2
   158                                  
   159 0000007C E8EF040000              	call	reset_codec
   160 00000081 731B                    	jnc	short a_2 ; EAX = 1
   161                                  
   162                                  	;test	al, VIA_ACLINK_C00_READY 	
   163                                          ;jnz     short a_2
   164                                  
   165                                  _codec_err:
   166                                  	sys	_msg, CodecErrMsg, 255, 0Fh
   166                              <1> 
   166                              <1> 
   166                              <1> 
   166                              <1> 
   166                              <1>  %if %0 >= 2
   166 00000083 BB[CF0A0000]        <1>  mov ebx, %2
   166                              <1>  %if %0 >= 3
   166 00000088 B9FF000000          <1>  mov ecx, %3
   166                              <1>  %if %0 = 4
   166 0000008D BA0F000000          <1>  mov edx, %4
   166                              <1>  %endif
   166                              <1>  %endif
   166                              <1>  %endif
   166 00000092 B823000000          <1>  mov eax, %1
   166                              <1> 
   166 00000097 CD40                <1>  int 40h
   167 00000099 E91F010000                      jmp     Exit
   168                                  
   169                                  a_2:
   170                                  	; eax = 1
   171 0000009E E841050000              	call	codec_io_w16 ; w32
   172                                  	
   173                                  	;call	detect_codec
   174                                  
   175 000000A3 E80A060000              	call	channel_reset
   176                                  
   177 000000A8 E86A080000              	call	write_ac97_dev_info 
   178                                  
   179                                  ; setup the Codec (actually mixer registers) 
   180 000000AD E8E7030000                      call    codecConfig                     ; unmute codec, set rates.
   181 000000B2 7309                    	jnc	short a_3
   182                                  
   183 000000B4 0430                    	add	al, '0'
   184 000000B6 A2[DC0A0000]            	mov	[ErrNo], al
   185 000000BB EBC6                    	jmp	short _codec_err
   186                                  
   187                                  a_3:
   188                                  	; SETUP INTERRUPT CALLBACK SERVICE
   189                                  	; 05/03/2017
   190 000000BD 8A1D[630C0000]          	mov	bl, [ac97_int_ln_reg] ; IRQ number
   191 000000C3 B702                    	mov	bh, 2 ; Link IRQ to user for callback service
   192 000000C5 BA[24030000]            	mov	edx, ac97_int_handler
   193                                  	sys	_calbac
   193                              <1> 
   193                              <1> 
   193                              <1> 
   193                              <1> 
   193                              <1>  %if %0 >= 2
   193                              <1>  mov ebx, %2
   193                              <1>  %if %0 >= 3
   193                              <1>  mov ecx, %3
   193                              <1>  %if %0 = 4
   193                              <1>  mov edx, %4
   193                              <1>  %endif
   193                              <1>  %endif
   193                              <1>  %endif
   193 000000CA B82C000000          <1>  mov eax, %1
   193                              <1> 
   193 000000CF CD40                <1>  int 40h
   194 000000D1 0F8207010000            	jc	error_exit
   195                                  
   196                                  	; DIRECT CGA (TEXT MODE) MEMORY ACCESS
   197                                  	; bl = 0, bh = 4
   198                                  	; Direct access/map to CGA (Text) memory (0B8000h)
   199                                  
   200                                  	sys	_video, 0400h
   200                              <1> 
   200                              <1> 
   200                              <1> 
   200                              <1> 
   200                              <1>  %if %0 >= 2
   200 000000D7 BB00040000          <1>  mov ebx, %2
   200                              <1>  %if %0 >= 3
   200                              <1>  mov ecx, %3
   200                              <1>  %if %0 = 4
   200                              <1>  mov edx, %4
   200                              <1>  %endif
   200                              <1>  %endif
   200                              <1>  %endif
   200 000000DC B81F000000          <1>  mov eax, %1
   200                              <1> 
   200 000000E1 CD40                <1>  int 40h
   201 000000E3 3D00800B00              	cmp	eax, 0B8000h
   202 000000E8 0F85F0000000            	jne	error_exit
   203                                  
   204                                  ; open the file
   205                                          ; open existing file
   206 000000EE E8A3010000                      call    openFile ; no error? ok.
   207 000000F3 731B                            jnc     short _gsr
   208                                  
   209                                  ; file not found!
   210                                  	sys	_msg, noFileErrMsg, 255, 0Fh
   210                              <1> 
   210                              <1> 
   210                              <1> 
   210                              <1> 
   210                              <1>  %if %0 >= 2
   210 000000F5 BB[490B0000]        <1>  mov ebx, %2
   210                              <1>  %if %0 >= 3
   210 000000FA B9FF000000          <1>  mov ecx, %3
   210                              <1>  %if %0 = 4
   210 000000FF BA0F000000          <1>  mov edx, %4
   210                              <1>  %endif
   210                              <1>  %endif
   210                              <1>  %endif
   210 00000104 B823000000          <1>  mov eax, %1
   210                              <1> 
   210 00000109 CD40                <1>  int 40h
   211 0000010B E9AD000000                      jmp     Exit
   212                                  
   213                                  _gsr:  
   214 00000110 E8B1010000                     	call    getSampleRate		; read the sample rate
   215                                                                          ; pass it onto codec.
   216 00000115 0F82A2000000            	jc	Exit
   217                                  
   218 0000011B 66A3[8F0C0000]          	mov	[sample_rate], ax
   219 00000121 880D[5C0C0000]          	mov	[stmo], cl
   220 00000127 8815[5D0C0000]          	mov	[bps], dl
   221                                  	
   222                                  PlayNow: 
   223                                  	; DIRECT MEMORY ACCESS (for Audio Controller)
   224                                  	; ebx = BDL buffer address (virtual, user)
   225                                  	; ecx = buffer size (in bytes)
   226                                  	; edx = upper limit = 0 = no limit
   227                                  
   228                                  	sys	_alloc, BdlBuffer, 4096, 0 
   228                              <1> 
   228                              <1> 
   228                              <1> 
   228                              <1> 
   228                              <1>  %if %0 >= 2
   228 0000012D BB[00100000]        <1>  mov ebx, %2
   228                              <1>  %if %0 >= 3
   228 00000132 B900100000          <1>  mov ecx, %3
   228                              <1>  %if %0 = 4
   228 00000137 BA00000000          <1>  mov edx, %4
   228                              <1>  %endif
   228                              <1>  %endif
   228                              <1>  %endif
   228 0000013C B82A000000          <1>  mov eax, %1
   228                              <1> 
   228 00000141 CD40                <1>  int 40h
   229 00000143 0F8295000000            	jc	error_exit
   230                                  
   231 00000149 A3[A40C0000]            	mov	[BDL_phy_buff], eax	; physical address
   232                                  					; of the buffer
   233                                  					; (which is needed
   234                                  					; for Audio controller)
   235                                  
   236                                  	; DIRECT MEMORY ACCESS (for Audio Controller)
   237                                  	; ebx = DMA buffer address (virtual, user)
   238                                  	; ecx = buffer size (in bytes)
   239                                  	; edx = upper limit = 0 = no limit
   240                                  
   241                                  	sys	_alloc, DmaBuffer, 65536, 0 
   241                              <1> 
   241                              <1> 
   241                              <1> 
   241                              <1> 
   241                              <1>  %if %0 >= 2
   241 0000014E BB[00000100]        <1>  mov ebx, %2
   241                              <1>  %if %0 >= 3
   241 00000153 B900000100          <1>  mov ecx, %3
   241                              <1>  %if %0 = 4
   241 00000158 BA00000000          <1>  mov edx, %4
   241                              <1>  %endif
   241                              <1>  %endif
   241                              <1>  %endif
   241 0000015D B82A000000          <1>  mov eax, %1
   241                              <1> 
   241 00000162 CD40                <1>  int 40h
   242 00000164 7278                    	jc	short error_exit
   243                                  
   244 00000166 A3[A80C0000]            	mov	[DMA_phy_buff], eax	; physical address
   245                                  					; of the buffer
   246                                  					; (which is needed
   247                                  					; for Audio controller)
   248                                  ;
   249                                  ; position file pointer to start in actual wav data
   250                                  ; MUCH improvement should really be done here to check if sample size is
   251                                  ; supported, make sure there are 2 channels, etc.  
   252                                  ;
   253                                          ;mov     ah, 42h
   254                                          ;mov     al, 0	; from start of file
   255                                          ;mov     bx, [FileHandle]
   256                                          ;xor     cx, cx
   257                                          ;mov     dx, 44	; jump past .wav/riff header
   258                                          ;int     21h
   259                                  
   260                                  	sys	_seek, [FileHandle], 44, 0
   260                              <1> 
   260                              <1> 
   260                              <1> 
   260                              <1> 
   260                              <1>  %if %0 >= 2
   260 0000016B 8B1D[820B0000]      <1>  mov ebx, %2
   260                              <1>  %if %0 >= 3
   260 00000171 B92C000000          <1>  mov ecx, %3
   260                              <1>  %if %0 = 4
   260 00000176 BA00000000          <1>  mov edx, %4
   260                              <1>  %endif
   260                              <1>  %endif
   260                              <1>  %endif
   260 0000017B B813000000          <1>  mov eax, %1
   260                              <1> 
   260 00000180 CD40                <1>  int 40h
   261                                  
   262                                  ; play the .wav file.  Most of the good stuff is in here.
   263                                  
   264 00000182 E8B9050000                      call    PlayWav
   265                                  
   266                                  ; close the .wav file and exit.
   267                                  
   268 00000187 E823010000                      call    closeFile
   269                                  
   270                                  StopPlaying:
   271 0000018C 8A1D[630C0000]          	mov     bl, [ac97_int_ln_reg] ; Audio IRQ number
   272 00000192 28FF                    	sub	bh, bh ; 0 = Unlink IRQ from user
   273                                  	sys	_calbac 
   273                              <1> 
   273                              <1> 
   273                              <1> 
   273                              <1> 
   273                              <1>  %if %0 >= 2
   273                              <1>  mov ebx, %2
   273                              <1>  %if %0 >= 3
   273                              <1>  mov ecx, %3
   273                              <1>  %if %0 = 4
   273                              <1>  mov edx, %4
   273                              <1>  %endif
   273                              <1>  %endif
   273                              <1>  %endif
   273 00000194 B82C000000          <1>  mov eax, %1
   273                              <1> 
   273 00000199 CD40                <1>  int 40h
   274                                  
   275                                  	; Deallocate BDL buffer (not necessary just before exit!)
   276                                  	sys	_dalloc, BdlBuffer, 4096
   276                              <1> 
   276                              <1> 
   276                              <1> 
   276                              <1> 
   276                              <1>  %if %0 >= 2
   276 0000019B BB[00100000]        <1>  mov ebx, %2
   276                              <1>  %if %0 >= 3
   276 000001A0 B900100000          <1>  mov ecx, %3
   276                              <1>  %if %0 = 4
   276                              <1>  mov edx, %4
   276                              <1>  %endif
   276                              <1>  %endif
   276                              <1>  %endif
   276 000001A5 B82B000000          <1>  mov eax, %1
   276                              <1> 
   276 000001AA CD40                <1>  int 40h
   277                                  	; Deallocate DMA buffer (not necessary just before exit!)
   278                                  	sys	_dalloc, DmaBuffer, 65536  ; 14/03/2017
   278                              <1> 
   278                              <1> 
   278                              <1> 
   278                              <1> 
   278                              <1>  %if %0 >= 2
   278 000001AC BB[00000100]        <1>  mov ebx, %2
   278                              <1>  %if %0 >= 3
   278 000001B1 B900000100          <1>  mov ecx, %3
   278                              <1>  %if %0 = 4
   278                              <1>  mov edx, %4
   278                              <1>  %endif
   278                              <1>  %endif
   278                              <1>  %endif
   278 000001B6 B82B000000          <1>  mov eax, %1
   278                              <1> 
   278 000001BB CD40                <1>  int 40h
   279                                  Exit:           
   280                                  	sys	_exit	; Bye!
   280                              <1> 
   280                              <1> 
   280                              <1> 
   280                              <1> 
   280                              <1>  %if %0 >= 2
   280                              <1>  mov ebx, %2
   280                              <1>  %if %0 >= 3
   280                              <1>  mov ecx, %3
   280                              <1>  %if %0 = 4
   280                              <1>  mov edx, %4
   280                              <1>  %endif
   280                              <1>  %endif
   280                              <1>  %endif
   280 000001BD B801000000          <1>  mov eax, %1
   280                              <1> 
   280 000001C2 CD40                <1>  int 40h
   281                                  here:
   282 000001C4 EBFE                    	jmp	short here
   283                                  
   284                                  pmsg_usage:
   285                                  	sys	_msg, msg_usage, 255, 0Bh
   285                              <1> 
   285                              <1> 
   285                              <1> 
   285                              <1> 
   285                              <1>  %if %0 >= 2
   285 000001C6 BB[E20A0000]        <1>  mov ebx, %2
   285                              <1>  %if %0 >= 3
   285 000001CB B9FF000000          <1>  mov ecx, %3
   285                              <1>  %if %0 = 4
   285 000001D0 BA0B000000          <1>  mov edx, %4
   285                              <1>  %endif
   285                              <1>  %endif
   285                              <1>  %endif
   285 000001D5 B823000000          <1>  mov eax, %1
   285                              <1> 
   285 000001DA CD40                <1>  int 40h
   286 000001DC EBDF                    	jmp	short Exit
   287                                  
   288                                  error_exit:
   289                                  	sys	_msg, trdos386_err_msg, 255, 0Eh
   289                              <1> 
   289                              <1> 
   289                              <1> 
   289                              <1> 
   289                              <1>  %if %0 >= 2
   289 000001DE BB[620B0000]        <1>  mov ebx, %2
   289                              <1>  %if %0 >= 3
   289 000001E3 B9FF000000          <1>  mov ecx, %3
   289                              <1>  %if %0 = 4
   289 000001E8 BA0E000000          <1>  mov edx, %4
   289                              <1>  %endif
   289                              <1>  %endif
   289                              <1>  %endif
   289 000001ED B823000000          <1>  mov eax, %1
   289                              <1> 
   289 000001F2 CD40                <1>  int 40h
   290 000001F4 EBC7                    	jmp	short Exit
   291                                  
   292                                  DetectVT8233:
   293 000001F6 B806115930              	mov     eax, (VT8233_DID << 16) + VIA_VID
   294 000001FB E869020000                      call    pciFindDevice
   295 00000200 7318                            jnc     short _1
   296                                  
   297                                  ; couldn't find the audio device!
   298                                  	sys	_msg, noDevMsg, 255, 0Fh
   298                              <1> 
   298                              <1> 
   298                              <1> 
   298                              <1> 
   298                              <1>  %if %0 >= 2
   298 00000202 BB[980A0000]        <1>  mov ebx, %2
   298                              <1>  %if %0 >= 3
   298 00000207 B9FF000000          <1>  mov ecx, %3
   298                              <1>  %if %0 = 4
   298 0000020C BA0F000000          <1>  mov edx, %4
   298                              <1>  %endif
   298                              <1>  %endif
   298                              <1>  %endif
   298 00000211 B823000000          <1>  mov eax, %1
   298                              <1> 
   298 00000216 CD40                <1>  int 40h
   299 00000218 EBA3                            jmp     short Exit
   300                                  
   301                                  _1:
   302                                  	; 05/03/2017 (TRDOS 386)
   303                                  	; 12/11/2016
   304                                  	; Erdogan Tan - 8/11/2016
   305                                  	; References: Kolibrios - vt823x.asm (2016)
   306                                  	;	      VIA VT8235 V-Link South Bridge (VT8235-VIA.PDF)(2002)
   307                                  	;	      lowlevel.eu - AC97 (2016)
   308                                  	;	      .wav player for DOS by Jeff Leyda (2002) -this file-
   309                                  	;	      Linux kernel - via82xx.c (2016)
   310                                  
   311                                  	; eax = BUS/DEV/FN
   312                                  	;	00000000BBBBBBBBDDDDDFFF00000000
   313                                  	; edx = DEV/VENDOR
   314                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
   315                                  
   316 0000021A A3[650C0000]            	mov	[bus_dev_fn], eax
   317 0000021F 8915[690C0000]          	mov	[dev_vendor], edx
   318                                  
   319                                  	; init controller
   320 00000225 B004                    	mov	al, PCI_CMD_REG ; command register (04h)
   321 00000227 E8A8010000              	call	pciRegRead32
   322                                  
   323                                  	; eax = BUS/DEV/FN/REG
   324                                  	; edx = STATUS/COMMAND
   325                                  	; 	SSSSSSSSSSSSSSSSCCCCCCCCCCCCCCCC
   326 0000022C 8915[6D0C0000]          	mov	[stats_cmd], edx
   327                                  
   328 00000232 B010                    	mov	al, PCI_IO_BASE ; IO base address register (10h)
   329 00000234 E89B010000              	call	pciRegRead32
   330                                  
   331 00000239 6683E2C0                	and     dx, 0FFC0h	; IO_ADDR_MASK (0FFFE) ?
   332 0000023D 668915[710C0000]                mov     [ac97_io_base], dx
   333                                  
   334 00000244 B03C                    	mov	al, AC97_INT_LINE ; Interrupt line register (3Ch)
   335 00000246 E889010000              	call	pciRegRead32
   336                                  
   337 0000024B 81E2FF000000            	and 	edx, 0FFh
   338 00000251 8815[630C0000]            	mov     [ac97_int_ln_reg], dl
   339                                  
   340                                  	; 05/03/2017 (TRDOS 386, INT 34h, IOCTL Interrupt)
   341                                  	; (Note: Interrupts are already enabled by TRDOS 386 kernel!)
   342                                  	; 28/11/2016
   343                                  	;mov	cx, dx
   344                                  
   345                                  	;in	al, 0A1h ; irq 8-15
   346 00000257 B2A1                    	mov	dl, 0A1h
   347 00000259 28E4                    	sub	ah, ah ; 0 ; inb
   348 0000025B CD34                    	int	34h
   349                                  
   350                                  	;mov	ah, al
   351 0000025D 88C3                    	mov	bl, al
   352                                  
   353                                  	;in	al, 21h  ; irq 0-7 
   354 0000025F B221                    	mov	dl, 21h	
   355                                  	;mov	ah, 0 ; inb
   356 00000261 CD34                    	int	34h	
   357                                  
   358 00000263 88DC                    	mov	ah, bl
   359 00000265 660FB3C8                	btr	ax, cx	 ; unmask ; 17/03/2017
   360 00000269 88E3                    	mov	bl, ah
   361                                  
   362                                  	;out	21h, al  ; enable interrupt (if irq <= 7)
   363 0000026B B401                    	mov	ah, 1 ; outb
   364 0000026D CD34                    	int	34h
   365                                  
   366                                  	;mov	al, ah
   367 0000026F 88D8                    	mov	al, bl
   368                                  	;out	0A1h, al ; enable interrupt (if irq > 7)
   369 00000271 B2A1                    	mov	dl, 0A1h
   370                                  	;mov	ah, 1 ; outb
   371 00000273 CD34                    	int	34h		
   372                                  
   373 00000275 66BAD104                	mov	dx, 4D1h	; 8259 ELCR1
   374                                       	;in	al, dx
   375 00000279 FECC                    	dec	ah ; 0 ; inb
   376 0000027B CD34                    	int	34h
   377                                  
   378                                  	;mov	ah, al
   379 0000027D 88C3                    	mov	bl, al
   380                                  	
   381                                  	;mov	dx, 4D0h 
   382 0000027F FECA                    	dec	dl
   383                                  	;in	al, dx
   384                                  	;mov	ah, 0 ; inb
   385 00000281 CD34                    	int	34h
   386                                  
   387 00000283 88DC                    	mov	ah, bl
   388 00000285 660FABC8                	bts	ax, cx
   389 00000289 88E3                    	mov	bl, ah
   390                                  
   391                                  	;mov	dx, 4D0h
   392                                  	;out	dx, al		; set level-triggered mode
   393 0000028B B401                    	mov	ah, 1 ; outb	
   394 0000028D CD34                    	int	34h
   395                                  
   396                                  	;mov	al, ah
   397 0000028F 88D8                    	mov	al, bl
   398                                  	;mov	dx, 4D1h
   399 00000291 FEC2                    	inc	dl
   400                                  	;out	dx, al		; set level-triggered mode
   401                                  	;mov	ah, 1 ; outb	
   402 00000293 CD34                    	int	34h
   403                                  
   404 00000295 C3                      	retn
   405                                  
   406                                  ;open or create file
   407                                  ;
   408                                  ;input: ds:dx-->filename (asciiz)
   409                                  ;       al=file Mode (create or open)
   410                                  ;output: none  cs:[FileHandle] filled
   411                                  ;
   412                                  openFile:
   413                                  	;;push	eax
   414                                  	;;push	ecx
   415                                  	;mov	ah, 3Bh	; start with a mode
   416                                  	;add	ah, al	; add in create or open mode
   417                                  	;xor	cx, cx
   418                                  	;int	21h
   419                                  	;jc	short _of1
   420                                  	;;mov	[cs:FileHandle], ax
   421                                  
   422                                  	sys	_open, wav_file_name, 0
   422                              <1> 
   422                              <1> 
   422                              <1> 
   422                              <1> 
   422                              <1>  %if %0 >= 2
   422 00000296 BB[910C0000]        <1>  mov ebx, %2
   422                              <1>  %if %0 >= 3
   422 0000029B B900000000          <1>  mov ecx, %3
   422                              <1>  %if %0 = 4
   422                              <1>  mov edx, %4
   422                              <1>  %endif
   422                              <1>  %endif
   422                              <1>  %endif
   422 000002A0 B805000000          <1>  mov eax, %1
   422                              <1> 
   422 000002A5 CD40                <1>  int 40h
   423 000002A7 7205                    	jc	short _of1
   424                                  
   425 000002A9 A3[820B0000]            	mov	[FileHandle], eax
   426                                  _of1:
   427                                  	;;pop	ecx
   428                                  	;;pop	eax
   429 000002AE C3                      	retn
   430                                  
   431                                  ; close the currently open file
   432                                  ; input: none, uses cs:[FileHandle]
   433                                  closeFile:
   434                                  	;push	eax
   435                                  	;push	ebx
   436 000002AF 833D[820B0000]FF        	cmp	dword [FileHandle], -1
   437 000002B6 740D                    	je	short _cf1
   438                                  	;mov    bx, [FileHandle]  
   439                                  	;mov    ax, 3E00h
   440                                          ;int    21h              ;close file
   441                                  
   442                                  	sys	_close, [FileHandle]
   442                              <1> 
   442                              <1> 
   442                              <1> 
   442                              <1> 
   442                              <1>  %if %0 >= 2
   442 000002B8 8B1D[820B0000]      <1>  mov ebx, %2
   442                              <1>  %if %0 >= 3
   442                              <1>  mov ecx, %3
   442                              <1>  %if %0 = 4
   442                              <1>  mov edx, %4
   442                              <1>  %endif
   442                              <1>  %endif
   442                              <1>  %endif
   442 000002BE B806000000          <1>  mov eax, %1
   442                              <1> 
   442 000002C3 CD40                <1>  int 40h
   443                                  _cf1:
   444                                  	;pop	ebx
   445                                  	;pop	eax
   446 000002C5 C3                      	retn
   447                                  
   448                                  getSampleRate:
   449                                  	
   450                                  ; reads the sample rate from the .wav file.
   451                                  ; entry: none - assumes file is already open
   452                                  ; exit: ax = sample rate (11025, 22050, 44100, 48000)
   453                                  ;	cx = number of channels (mono=1, stereo=2)
   454                                  ;	dx = bits per sample (8, 16)
   455                                  
   456 000002C6 53                      	push    ebx
   457                                  
   458                                          ;mov	ah, 42h
   459                                          ;mov	al, 0	; from start of file
   460                                          ;mov	bx, [FileHandle]
   461                                          ;xor	cx, cx
   462                                          ;mov	dx, 08h	; "WAVE"
   463                                          ;int	21h
   464                                  	
   465                                  	sys	_seek, [FileHandle], 8, 0
   465                              <1> 
   465                              <1> 
   465                              <1> 
   465                              <1> 
   465                              <1>  %if %0 >= 2
   465 000002C7 8B1D[820B0000]      <1>  mov ebx, %2
   465                              <1>  %if %0 >= 3
   465 000002CD B908000000          <1>  mov ecx, %3
   465                              <1>  %if %0 = 4
   465 000002D2 BA00000000          <1>  mov edx, %4
   465                              <1>  %endif
   465                              <1>  %endif
   465                              <1>  %endif
   465 000002D7 B813000000          <1>  mov eax, %1
   465                              <1> 
   465 000002DC CD40                <1>  int 40h
   466                                  
   467                                          ;mov	dx, smpRBuff
   468                                          ;mov	cx, 28	; 28 bytes
   469                                  	;mov	ah, 3fh
   470                                          ;int	21h
   471                                  
   472                                  	sys	_read, [FileHandle], smpRBuff, 28
   472                              <1> 
   472                              <1> 
   472                              <1> 
   472                              <1> 
   472                              <1>  %if %0 >= 2
   472 000002DE 8B1D[820B0000]      <1>  mov ebx, %2
   472                              <1>  %if %0 >= 3
   472 000002E4 B9[730C0000]        <1>  mov ecx, %3
   472                              <1>  %if %0 = 4
   472 000002E9 BA1C000000          <1>  mov edx, %4
   472                              <1>  %endif
   472                              <1>  %endif
   472                              <1>  %endif
   472 000002EE B803000000          <1>  mov eax, %1
   472                              <1> 
   472 000002F3 CD40                <1>  int 40h
   473                                  
   474 000002F5 813D[730C0000]5741-     	cmp	dword [smpRBuff], 'WAVE'
   474 000002FD 5645               
   475 000002FF 7520                    	jne	short gsr_stc
   476                                  
   477 00000301 66833D[7F0C0000]01      	cmp	word [smpRBuff+12], 1	; Offset 20, must be 1 (= PCM)
   478 00000309 7516                    	jne	short gsr_stc
   479                                  
   480 0000030B 668B0D[810C0000]        	mov	cx, [smpRBuff+14]	; return num of channels in CX
   481 00000312 66A1[830C0000]                  mov     ax, [smpRBuff+16]	; return sample rate in AX
   482 00000318 668B15[8D0C0000]        	mov	dx, [smpRBuff+26]	; return bits per sample value in DX
   483                                  gsr_retn:
   484 0000031F 5B                              pop     ebx
   485 00000320 C3                              retn
   486                                  
   487                                  gsr_stc:
   488 00000321 F9                      	stc
   489 00000322 EBFB                    	jmp	short gsr_retn
   490                                  
   491                                  ac97_int_handler:
   492                                  	; 14/03/2017
   493                                  	; 06/03/2017 (Signal Response Byte Check)
   494                                  	; 05/03/2017 (Modified for TRDOS 386 IRQ callback method)
   495                                  
   496 00000324 803D[5F0C0000]01        	cmp	byte [uLVI], 1
   497 0000032B 7337                    	jnb	short _busy
   498                                  
   499 0000032D C605[5F0C0000]01        	mov	byte [uLVI], 1
   500                                  
   501 00000334 C605[5E0C0000]00        	mov	byte [irq_status], 0
   502                                  
   503 0000033B 66BA0000                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   504 0000033F E8D2020000                      call    ctrl_io_r8
   505                                  
   506 00000344 A880                    	test    al, VIA_REG_STAT_ACTIVE
   507 00000346 740E                            jz      short _callback_retn
   508                                  
   509 00000348 2407                            and     al, VIA_REG_STAT_EOL + VIA_REG_STAT_FLAG + VIA_REG_STAT_STOPPED
   510 0000034A A2[5E0C0000]            	mov	[irq_status], al
   511 0000034F 7405                            jz	short _callback_retn
   512                                  
   513                                  	; 28/11/2016 - Erdogan Tan
   514 00000351 E8E0040000              	call	tuneLoop
   515                                  _callback_retn:
   516 00000356 C605[5F0C0000]00        	mov	byte [uLVI], 0 ; 14/03/2017
   517                                  _callback_bsy_retn:
   518                                  	sys	_rele ; return from callback service
   518                              <1> 
   518                              <1> 
   518                              <1> 
   518                              <1> 
   518                              <1>  %if %0 >= 2
   518                              <1>  mov ebx, %2
   518                              <1>  %if %0 >= 3
   518                              <1>  mov ecx, %3
   518                              <1>  %if %0 = 4
   518                              <1>  mov edx, %4
   518                              <1>  %endif
   518                              <1>  %endif
   518                              <1>  %endif
   518 0000035D B827000000          <1>  mov eax, %1
   518                              <1> 
   518 00000362 CD40                <1>  int 40h
   519                                  _busy:
   520                                  	; 28/11/2016 - Erdogan Tan
   521 00000364 A0[5E0C0000]                    mov     al, [irq_status]   ;; ack ;;
   522 00000369 66BA0000                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   523 0000036D E898020000                      call    ctrl_io_w8
   524                                  
   525                                  	;jmp	short _callback_bsy_retn ; 14/03/2017
   526 00000372 EBE2                    	jmp	short _callback_retn ; 17/03/2017
   527                                  
   528                                  ;=============================================================================
   529                                  ;               PCI.ASM
   530                                  ;=============================================================================
   531                                  
   532                                  ; EQUATES
   533                                  
   534                                  ;constants of stuff that seem hard to remember at times.
   535                                  
   536                                  TRUE  EQU 1
   537                                  FALSE EQU 0
   538                                  
   539                                  ENABLED  EQU 1
   540                                  DISABLED EQU 0
   541                                  
   542                                  BIT0  EQU 1
   543                                  BIT1  EQU 2
   544                                  BIT2  EQU 4
   545                                  BIT3  EQU 8
   546                                  BIT4  EQU 10h
   547                                  BIT5  EQU 20h
   548                                  BIT6  EQU 40h
   549                                  BIT7  EQU 80h
   550                                  BIT8  EQU 100h
   551                                  BIT9  EQU 200h
   552                                  BIT10 EQU 400h
   553                                  BIT11 EQU 800h
   554                                  BIT12 EQU 1000h
   555                                  BIT13 EQU 2000h
   556                                  BIT14 EQU 4000h
   557                                  BIT15 EQU 8000h
   558                                  BIT16 EQU 10000h
   559                                  BIT17 EQU 20000h
   560                                  BIT18 EQU 40000h
   561                                  BIT19 EQU 80000h
   562                                  BIT20 EQU 100000h
   563                                  BIT21 EQU 200000h
   564                                  BIT22 EQU 400000h
   565                                  BIT23 EQU 800000h
   566                                  BIT24 EQU 1000000h
   567                                  BIT25 EQU 2000000h
   568                                  BIT26 EQU 4000000h
   569                                  BIT27 EQU 8000000h
   570                                  BIT28 EQU 10000000h
   571                                  BIT29 EQU 20000000h
   572                                  BIT30 EQU 40000000h
   573                                  BIT31 EQU 80000000h
   574                                  
   575                                  ;special characters
   576                                  NUL     EQU 0
   577                                  NULL    EQU 0
   578                                  BELL    EQU 07
   579                                  BS      EQU 08
   580                                  TAB     EQU 09
   581                                  LF      EQU 10
   582                                  CR      EQU 13
   583                                  ESCAPE  EQU 27           ;ESC is a reserved word....
   584                                  
   585                                  
   586                                  ;file stuff
   587                                  READONLY  EQU   BIT0
   588                                  HIDDEN    EQU   BIT1
   589                                  SYSTEM    EQU   BIT2
   590                                  VOLUME    EQU   BIT3         ;ignored for file access
   591                                  DIRECTORY EQU   BIT4         ;must be 0 for file access
   592                                  ARCHIVE   EQU   BIT5
   593                                  SHAREABLE EQU   BIT7         ;for novell networks
   594                                  OPEN	EQU	2	; open existing file
   595                                  CREATE	EQU	1	; create new file
   596                                  
   597                                  
   598                                  ; PCI equates
   599                                  ; PCI function address (PFA)
   600                                  ; bit 31 = 1
   601                                  ; bit 23:16 = bus number     (0-255)
   602                                  ; bit 15:11 = device number  (0-31)
   603                                  ; bit 10:8 = function number (0-7)
   604                                  ; bit 7:0 = register number  (0-255)
   605                                  
   606                                  IO_ADDR_MASK    EQU     0FFFEh          ; mask off bit 0 for reading BARs
   607                                  PCI_INDEX_PORT  EQU     0CF8h
   608                                  PCI_DATA_PORT   EQU     0CFCh
   609                                  PCI32           EQU     BIT31           ; bitflag to signal 32bit access
   610                                  PCI16           EQU     BIT30           ; bitflag for 16bit access
   611                                  
   612                                  PCI_FN0         EQU     0 << 8
   613                                  PCI_FN1         EQU     1 << 8
   614                                  PCI_FN2         EQU     2 << 8
   615                                  PCI_FN3         EQU     3 << 8
   616                                  PCI_FN4         EQU     4 << 8
   617                                  PCI_FN5         EQU     5 << 8
   618                                  PCI_FN6         EQU     6 << 8
   619                                  PCI_FN7         EQU     7 << 8
   620                                  
   621                                  PCI_CMD_REG	EQU	04h	; reg 04, command reg
   622                                   IO_ENA		EQU	BIT0	; i/o decode enable
   623                                   MEM_ENA	EQU	BIT1	; memory decode enable
   624                                   BM_ENA                 EQU     BIT2	; bus master enable
   625                                  
   626                                  ; CODE
   627                                  
   628                                  ; PCI device register reader/writers.
   629                                  
   630                                  ; 05/03/2017 (TRDOS 386, INT 34h, IOCTL interrupt modifications)
   631                                  ; NASM version: Erdogan Tan (29/11/2016)
   632                                  
   633                                  ;===============================================================
   634                                  ; 8/16/32bit PCI reader
   635                                  ;
   636                                  ; Entry: EAX=PCI Bus/Device/fn/register number
   637                                  ;           BIT30 set if 32 bit access requested
   638                                  ;           BIT29 set if 16 bit access requested
   639                                  ;           otherwise defaults to 8bit read
   640                                  ;
   641                                  ; Exit:  DL,DX,EDX register data depending on requested read size
   642                                  ;
   643                                  ; Note: this routine is meant to be called via pciRegRead8, pciRegread16,
   644                                  ;	or pciRegRead32, listed below.
   645                                  ;
   646                                  ; Note2: don't attempt to read 32bits of data from a non dword aligned reg
   647                                  ;	 number.  Likewise, don't do 16bit reads from non word aligned reg #
   648                                  ; 
   649                                  pciRegRead:
   650 00000374 53                      	push	ebx
   651 00000375 51                      	push	ecx
   652 00000376 89C3                            mov     ebx, eax		; save eax, dh
   653 00000378 88F1                            mov     cl, dh
   654                                  
   655 0000037A 25FFFFFFBF                      and     eax, (~PCI32)+PCI16	; clear out data size request
   656 0000037F 0D00000080                      or      eax, BIT31		; make a PCI access request
   657 00000384 24FC                            and     al, ~3 ; NOT 3		; force index to be dword
   658                                  
   659 00000386 66BAF80C                        mov     dx, PCI_INDEX_PORT
   660                                          ;out	dx, eax			; write PCI selector
   661 0000038A 53                      	push	ebx
   662 0000038B 89C3                    	mov	ebx, eax ; Data dword		
   663 0000038D B405                    	mov	ah, 5	; outd (32 bit write)
   664 0000038F CD34                    	int	34h	
   665 00000391 5B                      	pop	ebx
   666                                  
   667 00000392 66BAFC0C                        mov     dx, PCI_DATA_PORT
   668 00000396 88D8                            mov     al, bl
   669 00000398 2403                            and     al, 3			; figure out which port to
   670 0000039A 00C2                            add     dl, al			; read to
   671                                  
   672                                  	;in     eax, dx			; do 32bit read
   673 0000039C B404                            mov	ah, 4	; ind (32 bit read)
   674 0000039E CD34                    	int	34h
   675                                  
   676 000003A0 F7C300000080            	test    ebx, PCI32
   677 000003A6 7402                            jz      short _pregr1
   678                                  
   679 000003A8 89C2                            mov     edx, eax		; return 32bits of data
   680                                  _pregr1:
   681 000003AA 6689C2                  	mov     dx, ax			; return 16bits of data
   682 000003AD F7C3000000C0                    test    ebx, PCI32+PCI16
   683 000003B3 7502                            jnz     short _pregr2
   684 000003B5 88CE                            mov     dh, cl			; restore dh for 8 bit read
   685                                  _pregr2:
   686 000003B7 89D8                            mov     eax, ebx		; restore eax
   687 000003B9 25FFFFFFBF                      and     eax, (~PCI32)+PCI16	; clear out data size request
   688 000003BE 59                      	pop	ecx
   689 000003BF 5B                      	pop	ebx
   690 000003C0 C3                      	retn
   691                                  
   692                                  pciRegRead8:
   693 000003C1 25FFFFFF3F                      and     eax, (~PCI16)+PCI32	; set up 8 bit read size
   694 000003C6 EBAC                            jmp     short pciRegRead	; call generic PCI access
   695                                  
   696                                  pciRegRead16:
   697 000003C8 25FFFFFF3F                      and     eax, (~PCI16)+PCI32	; set up 16 bit read size
   698 000003CD 0D00000040                      or      eax, PCI16		; call generic PCI access
   699 000003D2 EBA0                            jmp     short pciRegRead
   700                                  
   701                                  pciRegRead32:
   702 000003D4 25FFFFFF3F                      and     eax, (~PCI16)+PCI32	; set up 32 bit read size
   703 000003D9 0D00000080                      or      eax, PCI32		; call generic PCI access
   704 000003DE EB94                            jmp     short pciRegRead
   705                                  
   706                                  ;===============================================================
   707                                  ; 8/16/32bit PCI writer
   708                                  ;
   709                                  ; Entry: EAX=PCI Bus/Device/fn/register number
   710                                  ;           BIT31 set if 32 bit access requested
   711                                  ;           BIT30 set if 16 bit access requested
   712                                  ;           otherwise defaults to 8bit read
   713                                  ;        DL/DX/EDX data to write depending on size
   714                                  ;
   715                                  ;
   716                                  ; note: this routine is meant to be called via pciRegWrite8, pciRegWrite16,
   717                                  ; 	or pciRegWrite32 as detailed below.
   718                                  ;
   719                                  ; Note2: don't attempt to write 32bits of data from a non dword aligned reg
   720                                  ;	 number.  Likewise, don't do 16bit writes from non word aligned reg #
   721                                  ;
   722                                  pciRegWrite:
   723 000003E0 53                      	push	ebx
   724 000003E1 51                      	push	ecx
   725 000003E2 89C3                            mov     ebx, eax		; save eax, dx
   726 000003E4 89D1                            mov     ecx, edx
   727 000003E6 0D00000080                      or      eax, BIT31		; make a PCI access request
   728 000003EB 25FFFFFFBF                      and     eax, ~PCI16 ; NOT PCI16	; clear out data size request
   729 000003F0 24FC                            and     al, ~3 ; NOT 3		; force index to be dword
   730                                  
   731 000003F2 66BAF80C                        mov     dx, PCI_INDEX_PORT
   732                                          ;out	dx, eax			; write PCI selector
   733 000003F6 53                      	push	ebx
   734 000003F7 89C3                    	mov	ebx, eax ; Data dword		
   735 000003F9 B405                    	mov	ah, 5	; outd (32 bit write)
   736 000003FB CD34                    	int	34h	
   737 000003FD 8B1C24                  	mov	ebx, [esp]
   738                                  
   739 00000400 66BAFC0C                        mov     dx, PCI_DATA_PORT
   740 00000404 88D8                            mov     al, bl
   741 00000406 2403                            and     al, 3			; figure out which port to
   742 00000408 00C2                            add     dl, al			; write to
   743                                  
   744                                  	; ? (05/03/2017)
   745 0000040A 89D0                            mov     eax, edx		; put data into eax 
   746 0000040C 6689C8                          mov     ax, cx
   747                                  
   748                                  	;out	dx, al
   749 0000040F 6689C3                  	mov	bx, ax
   750 00000412 B401                    	mov	ah, 1 ; outb (8 bit write)
   751 00000414 CD34                    	int	34h		
   752 00000416 6689D8                  	mov 	ax, bx
   753 00000419 5B                      	pop	ebx
   754                                  		
   755 0000041A F7C3000000C0                    test    ebx, PCI16+PCI32	; only 8bit access? bail
   756 00000420 7419                            jz      short _pregw1
   757                                  
   758                                  	;out	dx, ax			; write 16 bit value
   759 00000422 53                              push	ebx
   760 00000423 6689C3                  	mov	bx, ax
   761 00000426 B403                    	mov	ah, 3 ; outw (16 bit write)
   762 00000428 CD34                    	int	34h
   763 0000042A 5B                      	pop	ebx        
   764                                  
   765 0000042B F7C300000040            	test    ebx, PCI16		; 16bit requested?  bail
   766 00000431 7508                            jnz     short _pregw1
   767                                  
   768                                          ;out	dx, eax			; write full 32bit
   769 00000433 53                      	push	ebx
   770 00000434 89C3                    	mov	ebx, eax
   771 00000436 B405                    	mov	ah, 5 ; outd (32 bit write)
   772 00000438 CD34                    	int	34h
   773 0000043A 5B                      	pop	ebx      
   774                                  
   775                                  _pregw1:
   776 0000043B 89D8                            mov     eax, ebx		; restore eax
   777 0000043D 25FFFFFFBF                      and     eax, (~PCI32)+PCI16	; clear out data size request
   778 00000442 89CA                            mov     edx, ecx		; restore dx
   779 00000444 59                      	pop	ecx
   780 00000445 5B                      	pop	ebx
   781 00000446 C3                      	retn
   782                                  
   783                                  pciRegWrite8:
   784 00000447 25FFFFFF3F                      and     eax, (~PCI16)+PCI32	; set up 8 bit write size
   785 0000044C EB92                            jmp	short pciRegWrite	; call generic PCI access
   786                                  
   787                                  pciRegWrite16:
   788 0000044E 25FFFFFF3F                      and     eax, (~PCI16)+PCI32	; set up 16 bit write size
   789 00000453 0D00000040                      or      eax, PCI16		; call generic PCI access
   790 00000458 EB86                            jmp	short pciRegWrite
   791                                  
   792                                  pciRegWrite32:
   793 0000045A 25FFFFFF3F                      and     eax, (~PCI16)+PCI32	; set up 32 bit write size
   794 0000045F 0D00000080                      or      eax, PCI32		; call generic PCI access
   795 00000464 E977FFFFFF                      jmp	pciRegWrite
   796                                  
   797                                  ;===============================================================
   798                                  ; PCIFindDevice: scan through PCI space looking for a device+vendor ID
   799                                  ;
   800                                  ; Entry: EAX=Device+Vendor ID
   801                                  ;
   802                                  ;  Exit: EAX=PCI address if device found
   803                                  ;	 EDX=Device+Vendor ID
   804                                  ;        CY clear if found, set if not found. EAX invalid if CY set.
   805                                  ;
   806                                  ; [old stackless] Destroys: ebx, esi, edi, cl
   807                                  ;
   808                                  pciFindDevice:
   809                                  	;push	ecx
   810 00000469 50                      	push	eax
   811                                  	;push	esi
   812                                  	;push	edi
   813                                  
   814 0000046A 89C6                            mov     esi, eax                ; save off vend+device ID
   815 0000046C BF00FFFF7F                      mov     edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0
   816                                  
   817                                  nextPCIdevice:
   818 00000471 81C700010000                    add     edi, 100h
   819 00000477 81FF00F8FF80                    cmp     edi, 80FFF800h	; scanned all devices?
   820 0000047D F9                              stc
   821 0000047E 740C                            je      short PCIScanExit       ; not found
   822                                  
   823 00000480 89F8                            mov     eax, edi                ; read PCI registers
   824 00000482 E84DFFFFFF                      call    pciRegRead32
   825 00000487 39F2                            cmp     edx, esi                ; found device?
   826 00000489 75E6                            jne     short nextPCIdevice
   827 0000048B F8                              clc
   828                                  
   829                                  PCIScanExit:
   830 0000048C 9C                      	pushf
   831 0000048D B800000080              	mov	eax, BIT31
   832 00000492 F7D0                    	not	eax
   833 00000494 21F8                    	and	eax, edi	; return only bus/dev/fn #
   834 00000496 9D                      	popf
   835                                  
   836                                  	;pop	edi
   837                                  	;pop	esi
   838 00000497 5A                      	pop	edx
   839                                  	;pop	ecx
   840 00000498 C3                      	retn
   841                                  
   842                                  ;=============================================================================
   843                                  ;               CODEC.ASM
   844                                  ;=============================================================================
   845                                  
   846                                  ; EQUATES
   847                                  
   848                                  ;Codec registers.
   849                                  ;
   850                                  ;Not all codecs are created equal. Refer to the spec for your specific codec.
   851                                  ;
   852                                  ;All registers are 16bits wide.  Access to codec registers over the AC97 link
   853                                  ;is defined by the OEM.  
   854                                  ;
   855                                  ;Secondary codec's are accessed by ORing in BIT7 of all register accesses.
   856                                  ;
   857                                  
   858                                  ; each codec/mixer register is 16bits
   859                                  
   860                                  CODEC_RESET_REG                 equ     00      ; reset codec
   861                                  CODEC_MASTER_VOL_REG            equ     02      ; master volume
   862                                  CODEC_HP_VOL_REG                equ     04      ; headphone volume
   863                                  CODEC_MASTER_MONO_VOL_REG       equ     06      ; master mono volume
   864                                  CODEC_MASTER_TONE_REG           equ     08      ; master tone (R+L)
   865                                  CODEC_PCBEEP_VOL_REG            equ     0ah     ; PC beep volume
   866                                  CODEC_PHONE_VOL_REG             equ     0bh     ; phone volume
   867                                  CODEC_MIC_VOL_REG               equ     0eh     ; MIC volume
   868                                  CODEC_LINE_IN_VOL_REG           equ     10h     ; line input volume
   869                                  CODEC_CD_VOL_REG                equ     12h     ; CD volume
   870                                  CODEC_VID_VOL_REG               equ     14h     ; video volume
   871                                  CODEC_AUX_VOL_REG               equ     16h     ; aux volume
   872                                  CODEC_PCM_OUT_REG               equ     18h     ; PCM output volume
   873                                  CODEC_RECORD_SELECT_REG         equ     1ah     ; record select input
   874                                  CODEC_RECORD_VOL_REG            equ     1ch     ; record volume
   875                                  CODEC_RECORD_MIC_VOL_REG        equ     1eh     ; record mic volume
   876                                  CODEC_GP_REG                    equ     20h     ; general purpose
   877                                  CODEC_3D_CONTROL_REG            equ     22h     ; 3D control
   878                                  ; 24h is reserved
   879                                  CODEC_POWER_CTRL_REG            equ     26h     ; powerdown control
   880                                  CODEC_EXT_AUDIO_REG             equ     28h     ; extended audio
   881                                  CODEC_EXT_AUDIO_CTRL_REG        equ     2ah     ; extended audio control
   882                                  CODEC_PCM_FRONT_DACRATE_REG     equ     2ch     ; PCM out sample rate
   883                                  CODEC_PCM_SURND_DACRATE_REG     equ     2eh     ; surround sound sample rate
   884                                  CODEC_PCM_LFE_DACRATE_REG       equ     30h     ; LFE sample rate
   885                                  CODEC_LR_ADCRATE_REG            equ     32h     ; PCM in sample rate
   886                                  CODEC_MIC_ADCRATE_REG           equ     34h     ; mic in sample rate
   887                                  
   888                                  ; registers 36-7a are reserved on the ICH
   889                                  
   890                                  CODEC_VENDORID1_REG             equ     7ch     ; codec vendor ID 1
   891                                  CODEC_VENDORID2_REG             equ     7eh     ; codec vendor ID 2
   892                                  
   893                                  ; Mixer registers 0 through 51h reside in the ICH and are not forwarded over
   894                                  ; the AC97 link to the codec, which I think is a little weird.  Looks like
   895                                  ; the ICH makes it so you don't need a fully functional codec to play audio?
   896                                  ;
   897                                  ; whenever 2 codecs are present in the system, use BIT7 to access the 2nd
   898                                  ; set of registers, ie 80h-feh
   899                                  
   900                                  PRIMARY_CODEC		equ     0       ; 0-7F for primary codec
   901                                  SECONDARY_CODEC		equ     BIT7    ; 80-8f registers for 2ndary
   902                                  
   903                                  SAMPLE_RATE_441khz	equ     44100   ; 44.1Khz (cd quality) rate
   904                                  
   905                                  ; each buffer descriptor BAR holds a pointer which has entries to the buffer
   906                                  ; contents of the .WAV file we're going to play.  Each entry is 8 bytes long
   907                                  ; (more on that later) and can contain 32 entries total, so each BAR is
   908                                  ; 256 bytes in length, thus:
   909                                  
   910                                  BDL_SIZE                equ     32*8    ; Buffer Descriptor List size
   911                                  INDEX_MASK              equ     31      ; indexes must be 0-31
   912                                  
   913                                  ;
   914                                  ; Buffer Descriptors List
   915                                  ; As stated earlier, each buffer descriptor list is a set of (up to) 32 
   916                                  ; descriptors, each 8 bytes in length.  Bytes 0-3 of a descriptor entry point
   917                                  ; to a chunk of memory to either play from or record to.  Bytes 4-7 of an
   918                                  ; entry describe various control things detailed below.
   919                                  ; 
   920                                  ; Buffer pointers must always be aligned on a Dword boundry.
   921                                  ;
   922                                  ;
   923                                  
   924                                  IOC                     equ     BIT31   ; Fire an interrupt whenever this
   925                                                                          ; buffer is complete.
   926                                  
   927                                  BUP                     equ     BIT30   ; Buffer Underrun Policy.
   928                                                                          ; if this buffer is the last buffer
   929                                                                          ; in a playback, fill the remaining
   930                                                                          ; samples with 0 (silence) or not.
   931                                                                          ; It's a good idea to set this to 1
   932                                                                          ; for the last buffer in playback,
   933                                                                          ; otherwise you're likely to get a lot
   934                                                                          ; of noise at the end of the sound.
   935                                  
   936                                  ;
   937                                  ; Bits 15:0 contain the length of the buffer, in number of samples, which
   938                                  ; are 16 bits each, coupled in left and right pairs, or 32bits each.
   939                                  ; Luckily for us, that's the same format as .wav files.
   940                                  ;
   941                                  ; A value of FFFF is 65536 samples.  Running at 44.1Khz, that's just about
   942                                  ; 1.5 seconds of sample time.  FFFF * 32bits is 1FFFFh bytes or 128k of data.
   943                                  ;
   944                                  ; A value of 0 in these bits means play no samples.
   945                                  ;
   946                                  
   947                                  ;VIA VT8233 (VT8235) AC97 Codec equates 
   948                                  ;(edited by Erdogan Tan, 7/11/2016)
   949                                  
   950                                  ; PCI stuff
   951                                  
   952                                  VIA_VID		equ 1106h	; VIA's PCI vendor ID
   953                                  VT8233_DID      equ 3059h	; VT8233 (VT8235) device ID
   954                                  		
   955                                  PCI_IO_BASE          equ 10h
   956                                  AC97_INT_LINE        equ 3Ch
   957                                  VIA_ACLINK_CTRL      equ 41h
   958                                  VIA_ACLINK_STAT      equ 40h
   959                                  VIA_ACLINK_C00_READY equ 01h ; primary codec ready
   960                                  	
   961                                  VIA_REG_AC97	     equ 80h ; dword
   962                                  
   963                                  VIA_ACLINK_CTRL_ENABLE	equ   80h ; 0: disable, 1: enable
   964                                  VIA_ACLINK_CTRL_RESET	equ   40h ; 0: assert, 1: de-assert
   965                                  VIA_ACLINK_CTRL_SYNC	equ   20h ; 0: release SYNC, 1: force SYNC hi
   966                                  VIA_ACLINK_CTRL_VRA	equ   08h ; 0: disable VRA, 1: enable VRA
   967                                  VIA_ACLINK_CTRL_PCM	equ   04h ; 0: disable PCM, 1: enable PCM
   971                                  VIA_ACLINK_CTRL_INIT	equ  (VIA_ACLINK_CTRL_ENABLE +                               VIA_ACLINK_CTRL_RESET +                               VIA_ACLINK_CTRL_PCM +                               VIA_ACLINK_CTRL_VRA)
   972                                  
   973                                  CODEC_AUX_VOL		equ   04h
   974                                  VIA_REG_AC97_BUSY	equ   01000000h ;(1<<24) 
   975                                  VIA_REG_AC97_CMD_SHIFT	equ   10h ; 16
   976                                  VIA_REG_AC97_PRIMARY_VALID equ 02000000h ;(1<<25)
   977                                  VIA_REG_AC97_READ	equ   00800000h ;(1<<23)
   978                                  VIA_REG_AC97_CODEC_ID_SHIFT   equ  1Eh ; 30
   979                                  VIA_REG_AC97_CODEC_ID_PRIMARY equ  0
   980                                  VIA_REG_AC97_DATA_SHIFT equ   0
   981                                  VIADEV_PLAYBACK         equ   0
   982                                  VIA_REG_OFFSET_STATUS   equ   0    ;; byte - channel status
   983                                  VIA_REG_OFFSET_CONTROL  equ   01h  ;; byte - channel control
   984                                  VIA_REG_CTRL_START	equ   80h  ;; WO
   985                                  VIA_REG_CTRL_TERMINATE  equ   40h  ;; WO
   986                                  VIA_REG_CTRL_PAUSE      equ   08h  ;; RW
   987                                  VIA_REG_CTRL_RESET      equ   01h  ;; RW - probably reset? undocumented
   988                                  VIA_REG_OFFSET_STOP_IDX equ   08h  ;; dword - stop index, channel type, sample rate
   989                                  VIA8233_REG_TYPE_16BIT  equ   200000h ;; RW
   990                                  VIA8233_REG_TYPE_STEREO equ   100000h ;; RW
   991                                  VIA_REG_OFFSET_CURR_INDEX equ 0Fh ;; byte - channel current index (for via8233 only)
   992                                  VIA_REG_OFFSET_TABLE_PTR equ  04h  ;; dword - channel table pointer
   993                                  VIA_REG_OFFSET_CURR_PTR equ   04h  ;; dword - channel current pointer
   994                                  VIA_REG_OFS_PLAYBACK_VOLUME_L equ  02h ;; byte
   995                                  VIA_REG_OFS_PLAYBACK_VOLUME_R equ  03h ;; byte
   996                                  VIA_REG_CTRL_AUTOSTART	equ   20h
   997                                  VIA_REG_CTRL_INT_EOL	equ   02h
   998                                  VIA_REG_CTRL_INT_FLAG	equ   01h
  1001                                  VIA_REG_CTRL_INT	equ  (VIA_REG_CTRL_INT_FLAG +                               VIA_REG_CTRL_INT_EOL +                               VIA_REG_CTRL_AUTOSTART)
  1002                                  ; 24/11/2016
  1003                                  VIA_REG_STAT_STOPPED	equ   04h    ;; RWC
  1004                                  VIA_REG_STAT_EOL	equ   02h    ;; RWC
  1005                                  VIA_REG_STAT_FLAG	equ   01h    ;; RWC
  1006                                  VIA_REG_STAT_ACTIVE	equ   80h    ;; RO
  1007                                  ; 28/11/2016
  1008                                  VIA_REG_STAT_LAST	equ   40h    ;; RO
  1009                                  VIA_REG_STAT_TRIGGER_QUEUED equ 08h  ;; RO
  1010                                  VIA_REF_CTRL_INT_STOP	equ   04h  ; Interrupt on Current Index = Stop Index
  1011                                  		   ; and End of Block
  1012                                  
  1013                                  ; 14/03/2017
  1014                                  VIA_REG_OFFSET_CURR_COUNT equ 0Ch ;; dword - channel current count, index
  1015                                  
  1016                                  ; CODE
  1017                                  
  1018                                  ; codec configuration code.  Not much here really.
  1019                                  ; NASM version: Erdogan Tan (29/11/2016)
  1020                                  
  1021                                  ; enable codec, unmute stuff, set output rate to 44.1
  1022                                  ; entry: ax = desired sample rate
  1023                                  ;
  1024                                  codecConfig:
  1025                                  	; 15/11/2016
  1026                                  	; 14/11/2016
  1027                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, 'setup_codec', codec.inc)
  1028                                  
  1029                                  	; 14/11/2016 - Erdogan Tan	
  1030                                  	; (Ref: Mpxplay, PDSoft, Attila Padar, SC_VIA82.C)
  1031                                  ;;;	call	channel_reset
  1032                                  
  1033 00000499 C605[640C0000]00        	mov	byte [err_num], 0
  1034                                  
  1035 000004A0 B802020000              	mov     eax, 0202h
  1036 000004A5 BA02000000              	mov	edx, CODEC_MASTER_VOL_REG ; 02h ; Line Out
  1037 000004AA E8C8010000              	call	codec_write
  1038                                  	;jc	cconfig_error
  1039                                  
  1040 000004AF C605[640C0000]01        	mov	byte [err_num], 1
  1041                                  
  1042 000004B6 B802020000              	mov     eax, 0202h
  1043 000004BB BA18000000              	mov	edx, CODEC_PCM_OUT_REG ; 18h ; Wave Output (Stereo)
  1044 000004C0 E8B2010000              	call	codec_write
  1045                                  	;jc	cconfig_error
  1046                                        
  1047 000004C5 C605[640C0000]02        	mov	byte [err_num], 2
  1048                                  
  1049                                   	;xor    eax, eax
  1050 000004CC B802020000              	mov	eax, 0202h
  1051 000004D1 BA04000000              	mov	edx, CODEC_AUX_VOL ; 04h ; CODEC_HP_VOL_REG ; HeadPhone
  1052 000004D6 E89C010000              	call	codec_write
  1053                                  	;jc	cconfig_error
  1054                                  
  1055 000004DB C605[640C0000]03        	mov	byte [err_num], 3
  1056                                  
  1057 000004E2 66B80800                        mov     ax,  08h
  1058 000004E6 BA0C000000                      mov	edx, 0Ch  ; AC97_PHONE_VOL ; TAD Input (Mono)
  1059 000004EB E887010000              	call	codec_write
  1060                                  	;jc	short cconfig_error
  1061                                  
  1062 000004F0 C605[640C0000]04        	mov	byte [err_num], 4
  1063                                  
  1064 000004F7 66B80808                        mov     ax,  0808h
  1065 000004FB BA10000000                      mov	edx, CODEC_LINE_IN_VOL_REG ; 10h ; Line Input (Stereo)	
  1066 00000500 E872010000              	call	codec_write
  1067                                  	;jc	short cconfig_error
  1068                                  
  1069 00000505 C605[640C0000]05        	mov	byte [err_num], 5
  1070                                  
  1071 0000050C 66B80808                	mov     ax,  0808h
  1072 00000510 BA12000000                      mov	edx, CODEC_CD_VOL_REG ; 12h ; CR Input (Stereo)
  1073 00000515 E85D010000              	call	codec_write
  1074                                  	;jc	short cconfig_error
  1075                                  
  1076 0000051A C605[640C0000]06        	mov	byte [err_num], 6
  1077                                  
  1078 00000521 66B80808                	mov     ax,  0808h
  1079 00000525 BA16000000                      mov	edx, CODEC_AUX_VOL_REG ; 16h ; Aux Input (Stereo)
  1080 0000052A E848010000              	call	codec_write
  1081                                  	;jc	short cconfig_error
  1082                                  
  1083 0000052F C605[640C0000]07        	mov	byte [err_num], 7
  1084                                  
  1085                                  	; Extended Audio Status (2Ah)
  1086 00000536 B82A000000              	mov	eax, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah 
  1087 0000053B E8FE000000              	call	codec_read
  1088 00000540 25FDFF0000                      and     eax, 0FFFFh - 2 ; clear DRA (BIT1)
  1089                                          ;or     eax, 1		; set VRA (BIT0)
  1090 00000545 83C805                  	or	eax, 5  	; VRA (BIT0) & S/PDIF (BIT2) ; 14/11/2016
  1091 00000548 BA2A000000              	mov	edx, CODEC_EXT_AUDIO_CTRL_REG
  1092 0000054D E825010000              	call	codec_write
  1093                                  	;jc	short cconfig_error
  1094                                  
  1095 00000552 C605[640C0000]08        	mov	byte [err_num], 8
  1096                                  set_sample_rate:
  1097 00000559 0FB705[8F0C0000]                movzx	eax, word [sample_rate]
  1098 00000560 BA2C000000              	mov	edx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch ; PCM Front DAC Rate
  1099                                          ;call	codec_write
  1100                                          ;retn
  1101 00000565 E90D010000              	jmp	codec_write
  1102                                  	
  1103                                  cconfig_error:
  1104 0000056A A0[640C0000]            	mov	al, [err_num]
  1105 0000056F C3                              retn
  1106                                  
  1107                                  reset_codec:
  1108                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1109 00000570 A1[650C0000]            	mov	eax, [bus_dev_fn]
  1110 00000575 B041                     	mov	al, VIA_ACLINK_CTRL
  1111 00000577 B2E0                           	mov	dl, VIA_ACLINK_CTRL_ENABLE + VIA_ACLINK_CTRL_RESET + VIA_ACLINK_CTRL_SYNC
  1112                                  
  1113 00000579 E8C9FEFFFF              	call	pciRegWrite8
  1114                                  
  1115 0000057E E852000000              	call	delay_100ms 	; wait 100 ms
  1116                                  _rc_cold:
  1117 00000583 E80A000000                      call    cold_reset
  1118 00000588 7303                            jnc     short _reset_codec_ok
  1119                                  
  1120 0000058A 31C0                            xor     eax, eax         ; timeout error
  1121 0000058C C3                              retn
  1122                                  
  1123                                  _reset_codec_ok:
  1124 0000058D 31C0                            xor     eax, eax
  1125                                          ;mov	al, VIA_ACLINK_C00_READY ; 1
  1126 0000058F FEC0                            inc	al
  1127 00000591 C3                      	retn
  1128                                  
  1129                                  cold_reset:
  1130                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1131                                  	;mov	eax, [bus_dev_fn]
  1132                                  	;mov	al, VIA_ACLINK_CTRL
  1133 00000592 30D2                    	xor	dl, dl ; 0
  1134 00000594 E8AEFEFFFF              	call	pciRegWrite8
  1135                                  
  1136 00000599 E837000000              	call	delay_100ms 	; wait 100 ms
  1137                                  
  1138                                  	;; ACLink on, deassert ACLink reset, VSR, SGD data out
  1139                                          ;; note - FM data out has trouble with non VRA codecs !!
  1140                                          
  1141                                  	;mov	eax, [bus_dev_fn]
  1142                                  	;mov	al, VIA_ACLINK_CTRL
  1143                                  
  1144 0000059E B2CC                    	mov	dl, VIA_ACLINK_CTRL_INIT
  1145                                  
  1146 000005A0 E8A2FEFFFF              	call	pciRegWrite8
  1147                                  
  1148 000005A5 B910000000              	mov	ecx, 16	; total 2s
  1149                                  
  1150                                  _crst_wait:
  1151 000005AA 51                      	push	ecx
  1152                                  
  1153                                  	;mov	eax, [bus_dev_fn]
  1154 000005AB B040                    	mov	al, VIA_ACLINK_STAT
  1155 000005AD E80FFEFFFF              	call	pciRegRead8	
  1156                                  
  1157 000005B2 F6C201                          test    dl, VIA_ACLINK_C00_READY
  1158 000005B5 750B                            jnz     short _crst_ok
  1159                                  
  1160 000005B7 E819000000              	call	delay_100ms
  1161                                  
  1162 000005BC 59                      	pop	ecx
  1163                                  
  1164 000005BD 49                              dec     ecx
  1165 000005BE 75EA                            jnz     short _crst_wait
  1166                                  
  1167                                  _crst_fail:
  1168 000005C0 F9                              stc
  1169 000005C1 C3                              retn
  1170                                  
  1171                                  _crst_ok:
  1172 000005C2 59                      	pop	ecx
  1173                                  
  1174                                  	; are these necessary ? - 14/11/2016 - Erdogan Tan
  1175                                  
  1176                                  	;mov	eax, [bus_dev_fn]
  1177                                  	;mov	al, VIA_ACLINK_CTRL
  1178 000005C3 E8F9FDFFFF              	call	pciRegRead8
  1179                                  
  1180                                  	;mov	eax, [bus_dev_fn]
  1181                                  	;mov	al, VIA_ACLINK_STAT
  1182 000005C8 E8F4FDFFFF              	call	pciRegRead8
  1183                                  
  1184 000005CD 0FB6C2                  	movzx	eax, dl
  1185 000005D0 2401                    	and     al, VIA_ACLINK_C00_READY ; 1
  1186 000005D2 74EC                    	jz	short _crst_fail
  1187                                  
  1188 000005D4 C3                      	retn
  1189                                  
  1190                                  delay_100ms:
  1191                                  	; wait 100 ms
  1192 000005D5 B919000000              	mov	ecx, 25
  1193                                  _delay_x_ms:
  1194 000005DA 51                      	push	ecx
  1195 000005DB E810030000              	call	delay1_4ms
  1196 000005E0 59                      	pop	ecx
  1197 000005E1 E2F7                            loop	_delay_x_ms
  1198 000005E3 C3                      	retn
  1199                                  
  1200                                  codec_io_w16: ;w32
  1201 000005E4 668B15[710C0000]                mov	dx, [ac97_io_base]
  1202 000005EB 6681C28000                      add     dx, VIA_REG_AC97
  1203                                  	;out	dx, eax
  1204                                  	; 05/03/2017
  1205 000005F0 53                      	push	ebx
  1206 000005F1 89C3                    	mov	ebx, eax
  1207 000005F3 B405                    	mov	ah, 5 ; outd
  1208 000005F5 CD34                    	int	34h
  1209 000005F7 5B                      	pop	ebx
  1210 000005F8 C3                              retn
  1211                                  
  1212                                  codec_io_r16: ;r32
  1213 000005F9 668B15[710C0000]                mov     dx, [ac97_io_base]
  1214 00000600 6681C28000                      add     dx, VIA_REG_AC97
  1215                                          ;in	eax, dx
  1216                                  	; 05/03/2017
  1217 00000605 B404                    	mov	ah, 4 ; ind
  1218 00000607 CD34                    	int	34h
  1219 00000609 C3                              retn
  1220                                  
  1221                                  ctrl_io_w8:
  1222 0000060A 660315[710C0000]                add     dx, [ac97_io_base]
  1223                                          ;out	dx, al
  1224                                  	; 05/03/2017
  1225 00000611 B401                    	mov	ah, 1 ; outb
  1226 00000613 CD34                    	int	34h
  1227 00000615 C3                              retn
  1228                                  
  1229                                  ctrl_io_r8:
  1230 00000616 660315[710C0000]                add     dx, [ac97_io_base]
  1231                                          ;in	al, dx
  1232                                  	; 05/03/2017
  1233 0000061D B400                    	mov	ah, 0 ; inb
  1234 0000061F CD34                    	int	34h
  1235 00000621 C3                              retn
  1236                                  
  1237                                  ctrl_io_w32:
  1238 00000622 660315[710C0000]                add     dx, [ac97_io_base]
  1239                                          ;out	dx, eax
  1240                                  	; 05/03/2017
  1241 00000629 53                      	push	ebx
  1242 0000062A 89C3                    	mov	ebx, eax
  1243 0000062C B405                    	mov	ah, 5 ; outd
  1244 0000062E CD34                    	int	34h
  1245 00000630 5B                      	pop	ebx
  1246 00000631 C3                              retn
  1247                                  
  1248                                  ctrl_io_r32:
  1249 00000632 660315[710C0000]                add	dx, [ac97_io_base]
  1250                                  	;in	eax, dx
  1251                                  	; 05/03/2017
  1252 00000639 B404                    	mov	ah, 4 ; ind
  1253 0000063B CD34                    	int	34h
  1254 0000063D C3                              retn
  1255                                  
  1256                                  codec_read:
  1257                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1258                                          ; Use only primary codec.
  1259                                          ; eax = register
  1260 0000063E C1E010                          shl     eax, VIA_REG_AC97_CMD_SHIFT
  1261 00000641 0D00008002                      or      eax, VIA_REG_AC97_PRIMARY_VALID + VIA_REG_AC97_READ
  1262                                  
  1263 00000646 E899FFFFFF              	call    codec_io_w16
  1264                                  
  1265                                        	; codec_valid
  1266 0000064B E83E000000              	call	codec_check_ready
  1267 00000650 7301                            jnc	short _cr_ok
  1268                                  
  1269 00000652 C3                      	retn
  1270                                  
  1271                                  _cr_ok:
  1272                                  	; wait 25 ms
  1273 00000653 E898020000              	call	delay1_4ms
  1274 00000658 E893020000              	call	delay1_4ms
  1275 0000065D E88E020000              	call	delay1_4ms
  1276 00000662 E889020000              	call	delay1_4ms
  1277 00000667 E884020000              	call	delay1_4ms
  1278                                  
  1279 0000066C E888FFFFFF                      call    codec_io_r16
  1280 00000671 25FFFF0000                      and     eax, 0FFFFh
  1281 00000676 C3                              retn
  1282                                  
  1283                                  codec_write:
  1284                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1285                                          ; Use only primary codec.
  1286                                          
  1287                                  	; eax = data (volume)
  1288                                  	; edx = register (mixer register)
  1289                                  	
  1290 00000677 C1E210                  	shl     edx, VIA_REG_AC97_CMD_SHIFT
  1291                                  
  1292 0000067A C1E000                          shl     eax, VIA_REG_AC97_DATA_SHIFT ; shl eax, 0
  1293 0000067D 09C2                            or      edx, eax
  1294                                  
  1295 0000067F B800000000                      mov     eax, VIA_REG_AC97_CODEC_ID_PRIMARY
  1296 00000684 C1E01E                          shl     eax, VIA_REG_AC97_CODEC_ID_SHIFT
  1297 00000687 09D0                            or      eax, edx
  1298                                  
  1299 00000689 E856FFFFFF                      call    codec_io_w16
  1300                                          ;mov    [codec.regs+esi], ax
  1301                                  
  1302                                          ;call	codec_check_ready
  1303                                         	;retn
  1304                                  	;jmp	short _codec_check_ready	
  1305                                  
  1306                                  codec_check_ready:
  1307                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1308                                  
  1309                                  _codec_check_ready:
  1310 0000068E B914000000              	mov	ecx, 20	; total 2s
  1311                                  _ccr_wait:
  1312 00000693 51                      	push	ecx
  1313                                  
  1314 00000694 E860FFFFFF                      call    codec_io_r16
  1315 00000699 A900000001                      test    eax, VIA_REG_AC97_BUSY
  1316 0000069E 740B                            jz      short _ccr_ok
  1317                                  
  1318 000006A0 E830FFFFFF              	call	delay_100ms
  1319                                  
  1320 000006A5 59                      	pop	ecx
  1321                                  
  1322 000006A6 49                      	dec     ecx
  1323 000006A7 75EA                            jnz     short _ccr_wait
  1324                                  
  1325 000006A9 F9                              stc
  1326 000006AA C3                              retn
  1327                                  
  1328                                  _ccr_ok:
  1329 000006AB 59                      	pop	ecx
  1330 000006AC 25FFFF0000              	and     eax, 0FFFFh
  1331 000006B1 C3                              retn
  1332                                  
  1333                                  channel_reset:
  1334                                  	; 14/11/2016 - Erdogan Tan
  1335                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1336 000006B2 BA01000000                      mov	edx, VIA_REG_OFFSET_CONTROL
  1337 000006B7 B849000000                      mov     eax, VIA_REG_CTRL_PAUSE + VIA_REG_CTRL_TERMINATE + VIA_REG_CTRL_RESET
  1338 000006BC E849FFFFFF                      call    ctrl_io_w8
  1339                                  
  1340                                          ;mov	edx, VIA_REG_OFFSET_CONTROL
  1341                                          ;call   ctrl_io_r8
  1342                                  
  1343 000006C1 B90C000000              	mov	ecx, 12 ; 50 ms	
  1344                                  _ch_rst_wait:
  1345 000006C6 51                      	push	ecx
  1346 000006C7 E824020000              	call	delay1_4ms
  1347 000006CC 59                      	pop	ecx
  1348 000006CD 49                      	dec	ecx
  1349 000006CE 75F6                    	jnz	short _ch_rst_wait     
  1350                                  
  1351                                          ; disable interrupts
  1352 000006D0 BA01000000                      mov	edx, VIA_REG_OFFSET_CONTROL
  1353 000006D5 31C0                            xor     eax, eax
  1354 000006D7 E82EFFFFFF                      call    ctrl_io_w8
  1355                                  
  1356                                          ; clear interrupts
  1357 000006DC BA00000000                      mov	edx, VIA_REG_OFFSET_STATUS
  1358                                  	;mov	eax, 3
  1359 000006E1 B8FF000000                      mov     eax, 0FFh ; 14/11/2016 - SC_VIA82.C (Attila Padar)
  1360 000006E6 E81FFFFFFF                      call	ctrl_io_w8
  1361                                  
  1362                                  	; 14/11/2016 (Ref: Attila Padar, Mpxplay, SC_VIA82.C)
  1363 000006EB BA04000000              	mov	edx, VIA_REG_OFFSET_CURR_PTR
  1364 000006F0 31C0                    	xor	eax, eax
  1365 000006F2 E82BFFFFFF              	call	ctrl_io_w32
  1366                                  
  1367 000006F7 C3                              retn
  1368                                  
  1369                                  loadFromFile:
  1370                                  	; 17/03/2017
  1371                                  	; edi = buffer address
  1372                                  	; edx = buffer size
  1373                                  	; 10/03/2017
  1374                                          ;push	eax
  1375                                          ;push	ecx
  1376                                          ;push	edx
  1377                                  	;push	ebx
  1378 000006F8 F605[620C0000]01                test    byte [flags], ENDOFFILE	; have we already read the
  1379 000006FF F9                              stc			; last of the file?
  1380 00000700 7532                            jnz     short endLFF
  1381 00000702 F8                      	clc
  1382                                  	; load file into memory
  1383                                  	sys 	_read, [FileHandle], edi
  1383                              <1> 
  1383                              <1> 
  1383                              <1> 
  1383                              <1> 
  1383                              <1>  %if %0 >= 2
  1383 00000703 8B1D[820B0000]      <1>  mov ebx, %2
  1383                              <1>  %if %0 >= 3
  1383 00000709 89F9                <1>  mov ecx, %3
  1383                              <1>  %if %0 = 4
  1383                              <1>  mov edx, %4
  1383                              <1>  %endif
  1383                              <1>  %endif
  1383                              <1>  %endif
  1383 0000070B B803000000          <1>  mov eax, %1
  1383                              <1> 
  1383 00000710 CD40                <1>  int 40h
  1384 00000712 89D1                    	mov	ecx, edx
  1385 00000714 720A                    	jc	short padfill ; error !
  1386 00000716 21C0                    	and	eax, eax
  1387 00000718 7406                    	jz	short padfill
  1388 0000071A 29C1                    	sub	ecx, eax
  1389 0000071C 7416                    	jz	short endLFF
  1390 0000071E 01C7                    	add	edi, eax  
  1391                                  padfill:
  1392 00000720 803D[5D0C0000]10        	cmp 	byte [bps], 16
  1393 00000727 740C                    	je	short _7
  1394                                  	; Minimum Value = 0
  1395 00000729 30C0                            xor     al, al
  1396 0000072B F3AA                    	rep	stosb
  1397                                  _6:
  1398                                          ;clc			; don't exit with CY yet.
  1399 0000072D 800D[620C0000]01                or	byte [flags], ENDOFFILE	; end of file flag
  1400                                  endLFF:
  1401                                  	;pop	ebx
  1402                                  	;pop	edx
  1403                                          ;pop	ecx
  1404                                          ;pop	eax
  1405 00000734 C3                              retn
  1406                                  _7:
  1407                                  	; Minimum value = 8000h (-32768)
  1408 00000735 D1E9                    	shr	ecx, 1 
  1409 00000737 66B80080                	mov	ax, 8000h ; -32768
  1410 0000073B F366AB                  	rep	stosw
  1411 0000073E EBED                    	jmp	short _6
  1412                                  
  1413                                  ;=============================================================================
  1414                                  ;               VIA_WAV.ASM
  1415                                  ;=============================================================================
  1416                                  
  1417                                  ; DOS based .WAV player using AC'97 and codec interface.
  1418                                  ; ---------------------------------------------------------------
  1419                                  ; VIA VT8233 Modification & NASM version: Erdogan Tan (29/11/2016)
  1420                                  ; Last Update: 08/12/2016 (by Erdogan Tan)
  1421                                  
  1422                                  ; player internal variables and other equates.
  1423                                  BUFFERSIZE      equ     32768	; 32K half buffer size. ; 14/03/2017
  1424                                  ENDOFFILE       equ     BIT0	; flag for knowing end of file
  1425                                  
  1426                                  ;===========================================================================
  1427                                  ; entry: none.  File is already open and [filehandle] filled.
  1428                                  ; exit:  not until the song is finished or the user aborts.
  1429                                  ;
  1430                                  	; 17/03/2017
  1431                                  PlayWav:
  1432                                  	;cld
  1433                                  	; clear (half) buffer 2
  1434 00000740 BF[00000100]                   	mov     edi, DmaBuffer
  1435                                  	;add	edi, BUFFERSIZE
  1436 00000745 BA00800000              	mov	edx, BUFFERSIZE
  1437 0000074A 01D7                    	add	edi, edx
  1438 0000074C 6629C0                  	sub	ax, ax
  1439 0000074F B900400000              	mov	ecx, (BUFFERSIZE/2)
  1440 00000754 F366AB                  	rep	stosw
  1441                                  	
  1442                                         ; load 32768 bytes into half buffer 1
  1443                                  
  1444 00000757 BF[00000100]            	mov     edi, DmaBuffer
  1445                                  	;mov	edx, BUFFERSIZE
  1446 0000075C E897FFFFFF              	call	loadFromFile
  1447                                  
  1448                                         ; load 32768 bytes into half buffer 2
  1449                                  
  1450                                  	;mov	edi, Dma Buffer
  1451                                  	;mov	edx, BUFFERSIZE
  1452                                  	;add	edi, edx
  1453                                  	;call	loadFromFile
  1454                                  
  1455                                  ; write last valid index to 31 to start with.
  1456                                  ; The Last Valid Index register tells the DMA engine when to stop playing.
  1457                                  ; 
  1458                                  ; As we progress through the song we change the last valid index to always be
  1459                                  ; something other than the index we're currently playing.  
  1460                                  ;
  1461                                          ;;mov   al, 1
  1462                                          ;mov	al, 31
  1463                                  	;call   setLastValidIndex
  1464                                  
  1465                                  ; create Buffer Descriptor List
  1466                                  ;
  1467                                  ; A buffer descriptor list is a list of pointers and control bits that the
  1468                                  ; DMA engine uses to know where to get the .wav data and how to play it.
  1469                                  ;
  1470                                  ; I set it up to use only 2 buffers of .wav data, and whenever 1 buffer is
  1471                                  ; playing, I refresh the other one with good data.
  1472                                  ;
  1473                                  ;
  1474                                  ; For the control bits, you can specify that the DMA engine fire an interrupt
  1475                                  ; after a buffer has been processed, but I poll the current index register
  1476                                  ; to know when it's safe to update the other buffer.
  1477                                  ;
  1478                                  ; I set the BUP bit, which tells the DMA engine to just play 0's (silence)
  1479                                  ; if it ever runs out of data to play.  Good for safety.
  1480                                  ;
  1481                                  	; 05/03/2017 (32 bit buffer addresses)
  1482                                  
  1483                                  	; 14/02/2017
  1484 00000761 BF[00100000]                    mov     edi, BdlBuffer		; get BDL address
  1485 00000766 66B91000                        mov     cx, 32 / 2		; make 32 entries in BDL
  1486                                  _0:
  1487                                  
  1488                                  ; set buffer descriptor 0 to start of data file in memory
  1489                                  
  1490 0000076A A1[A80C0000]                    mov	eax, [DMA_phy_buff]	; Physical address of DMA buffer
  1491 0000076F AB                              stosd				; store dmabuffer1 address
  1492                                  
  1493 00000770 89C2                    	mov	edx, eax ; 05/03/2017
  1494                                  
  1495                                  ;
  1496                                  ; set length to 32k samples.  1 sample is 16bits or 2bytes.
  1497                                  ; Set control (bits 31:16) to BUP, bits 15:0=number of samples.
  1498                                  ; 
  1499                                  
  1500                                  ; VIA VT8235.PDF: (Page 110) (Erdogan Tan, 29/11/2016)
  1501                                  	;
  1502                                  	; 	Audio SGD Table Format
  1503                                  	;	-------------------------------
  1504                                  	;	63   62    61-56    55-32  31-0
  1505                                  	;	--   --   --------  -----  ----
  1506                                  	;	EOL FLAG -reserved- Base   Base
  1507                                  	;		    	    Count  Address
  1508                                  	;		            [23:0] [31:0]
  1509                                  	;	EOL: End Of Link. 
  1510                                  	;	     1 indicates this block is the last of the link.
  1511                                  	;	     If the channel Interrupt on EOL bit is set, then
  1512                                  	;	     an interrupt is generated at the end of the transfer.
  1513                                  	;
  1514                                  	;	FLAG: Block Flag. If set, transfer pauses at the end of this
  1515                                  	;	      block. If the channel Interrupt on FLAG bit is set,
  1516                                  	;	      then an interrupt is generated at the end of this block.
  1517                                  
  1518                                  	FLAG	EQU BIT30
  1519                                  	EOL	EQU BIT31
  1520                                  
  1521                                  	; 08/12/2016 - Erdogan Tan
  1522 00000772 B800800000              	mov	eax, BUFFERSIZE
  1523 00000777 01C2                    	add	edx, eax ; 05/03/2017
  1524 00000779 0D00000040              	or	eax, FLAG
  1525                                  	;or	eax, EOL
  1526 0000077E AB                      	stosd
  1527                                  
  1528                                  ; 2nd buffer:
  1529                                  
  1530 0000077F 89D0                            mov	eax, edx ; Physical address of the 2nd half of DMA buffer	
  1531 00000781 AB                      	stosd				; store dmabuffer2 address
  1532                                  
  1533                                  ; set length to 64k (32k of two 16 bit samples)
  1534                                  ; Set control (bits 31:16) to BUP, bits 15:0=number of samples
  1535                                  ; 
  1536                                  	; 08/12/2016 - Erdogan Tan
  1537 00000782 B800800000              	mov	eax, BUFFERSIZE
  1538 00000787 0D00000080              	or	eax, EOL
  1539                                  	;or	eax, FLAG
  1540 0000078C AB                      	stosd
  1541                                  
  1542 0000078D E2DB                            loop    _0
  1543                                  
  1544                                  ;
  1545                                  ; tell the DMA engine where to find our list of Buffer Descriptors.
  1546                                  ; this 32bit value is a flat mode memory offset (ie no segment:offset)
  1547                                  ;
  1548                                  ; write buffer descriptor list address
  1549                                  ;
  1550 0000078F A1[A40C0000]                    mov	eax, [BDL_phy_buff] ; Physical address of the BDL
  1551                                  	
  1552                                  	; 12/11/2016 - Erdogan Tan 
  1553                                  	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
  1554 00000794 BA04000000              	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_TABLE_PTR
  1555 00000799 E884FEFFFF                      call    ctrl_io_w32
  1556                                  
  1557 0000079E E8EBFEFFFF              	call	codec_check_ready
  1558                                  
  1559 000007A3 66BA0200                  	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_L
  1560 000007A7 B802000000                      mov     eax, 2   ;31
  1561 000007AC E859FEFFFF                      call    ctrl_io_w8
  1562                                  
  1563 000007B1 E8D8FEFFFF              	call	codec_check_ready
  1564                                  
  1565 000007B6 66BA0300                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_R
  1566 000007BA 66B80200                        mov     ax, 2   ;31
  1567 000007BE E847FEFFFF                      call    ctrl_io_w8
  1568                                  
  1569 000007C3 E8C6FEFFFF              	call	codec_check_ready
  1570                                  ;
  1571                                  ;
  1572                                  ; All set.  Let's play some music.
  1573                                  ;
  1574                                  ;
  1575                                         	;mov    dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
  1576                                          ;mov    ax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
  1577                                          ;call   ctrl_io_w32
  1578                                  
  1579                                  	;call	codec_check_ready
  1580                                  
  1581                                  	; 14/03/2017
  1582                                  	;mov	byte [stmo], 1 ; mono
  1583                                  	;mov	byte [bps], 8 ; 8 bit
  1584                                  
  1585                                  	; 08/12/2016
  1586                                  	; 07/10/2016
  1587                                          ;mov	al, 1
  1588 000007C8 B01F                            mov	al, 31
  1589 000007CA E8D9000000              	call    setLastValidIndex
  1590                                  
  1591 000007CF C605[600C0000]01        	mov	byte [tLoop], 1 ; 30/11/2016
  1592                                  
  1593 000007D6 B823000000                      mov	eax, VIA_REG_CTRL_INT ; 14/03/2017
  1594 000007DB 0D80000000                     	or	eax, VIA_REG_CTRL_START
  1595                                          ;mov	ax, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START
  1596                                  	; 28/11/2016
  1597                                  	;mov	ax, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START + VIA_REG_CTRL_INT_FLAG
  1598 000007E0 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1599 000007E4 E821FEFFFF                      call    ctrl_io_w8
  1600                                  
  1601 000007E9 E8A0FEFFFF              	call	codec_check_ready
  1602                                  
  1603                                  ; while DMA engine is running, examine current index and wait until it hits 1
  1604                                  ; as soon as it's 1, we need to refresh the data in wavbuffer1 with another
  1605                                  ; 64k.  Likewise when it's playing buffer 2, refresh buffer 1 and repeat.
  1606                                     
  1607                                  	; 05/03/2017 (TRDOS 386)
  1608                                  	; 14/02/2017
  1609                                  	; 13/02/2017
  1610                                  	; 08/12/2016
  1611                                  	; 28/11/2016
  1612                                  
  1613 000007EE BD[00000100]            	mov	ebp, DmaBuffer ; 14/02/2017
  1614                                  p_loop:
  1615 000007F3 B401                    	mov     ah, 1		; any key pressed?
  1616 000007F5 CD32                    	int     32h		; no, Loop.
  1617 000007F7 740C                    	jz	short q_loop
  1618                                  
  1619 000007F9 B400                    	mov     ah, 0		; flush key buffer...
  1620 000007FB CD32                    	int     32h
  1621                                  p_return:
  1622 000007FD C605[600C0000]00        	mov	byte [tLoop], 0	; 13/02/2017
  1623 00000804 C3                      	retn
  1624                                  q_loop:
  1625 00000805 6631C0                  	xor	ax, ax
  1626 00000808 8605[610C0000]          	xchg	al, [tBuff] ; AL = [tBuff], [tBuff] = 0
  1627 0000080E 3C01                    	cmp	al, 1
  1628 00000810 7709                    	ja	short r_loop
  1629 00000812 72DF                    	jb	short p_loop
  1630                                  	; 05/03/2017
  1631 00000814 BF[00000100]                 	mov	edi, DmaBuffer ; [tBuff]=1 (from tuneLoop)
  1632 00000819 EB0B                           	jmp	short s_loop 
  1633                                  r_loop:
  1634                                  	; 05/03/2017
  1635 0000081B BF[00000100]                    mov     edi, DmaBuffer ; [tBuff]=2 (from tuneLoop)
  1636 00000820 81C700800000            	add	edi, BUFFERSIZE
  1637                                  s_loop:
  1638                                  	; 05/03/2017
  1639 00000826 89FD                    	mov	ebp, edi ; save current buffer addres in bp register
  1640 00000828 BB00800000              	mov	ebx, BUFFERSIZE ; 32768 bytes ; 14/03/2017
  1641                                  	; 17/03/2017
  1642 0000082D E8C6FEFFFF              	call    loadFromFile
  1643 00000832 73D1                    	jnc	short q_loop
  1644                                  	;mov	byte [tLoop], 0
  1645 00000834 EB5B                    	jmp	short _exit_
  1646                                  
  1647                                  tuneLoop:
  1648                                  	; 17/03/2017
  1649                                  	; 14/03/2017
  1650                                  	; 05/03/2017 (TRDOS 386)
  1651                                  	; 08/12/2016
  1652                                  	; 28/11/2016 - Erdogan Tan
  1653                                  	
  1654 00000836 803D[600C0000]01        	cmp	byte [tLoop], 1
  1655 0000083D 7252                    	jb	short _exit_
  1656                                  
  1657 0000083F BE00800B00              	mov	esi, 0B8000h ; video display page address
  1658 00000844 B44E                    	mov	ah, 4Eh
  1659 00000846 B031                    	mov	al, '1'
  1660                                  
  1661 00000848 C605[610C0000]01        	mov	byte [tBuff], 1 ; Buffer 1
  1662                                  
  1663 0000084F F605[5E0C0000]02        	test	byte [irq_status], VIA_REG_STAT_EOL 
  1664 00000856 7408                    	jz	short _tlp1 ; FLAG
  1665                                  	
  1666                                  	; EOL
  1667 00000858 FE05[610C0000]          	inc	byte [tBuff] ; Buffer 2
  1668 0000085E FEC0                    	inc	al
  1669                                  _tlp1: 
  1670 00000860 668906                  	mov	[esi], ax ; show playing buffer (1, 2)
  1671                                  
  1672 00000863 F605[5E0C0000]01        	test	byte [irq_status], VIA_REG_STAT_FLAG 
  1673 0000086A 7416                    	jz	short _tlp2
  1674                                  
  1675 0000086C 66B82300                	mov	ax, VIA_REG_CTRL_INT
  1676 00000870 660D8000                	or	ax, VIA_REG_CTRL_START
  1677 00000874 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1678 00000878 E88DFDFFFF              	call    ctrl_io_w8
  1679                                  	
  1680 0000087D E80CFEFFFF              	call	codec_check_ready
  1681                                  _tlp2:	
  1682 00000882 A0[5E0C0000]                    mov     al, [irq_status]   ;; ack ;;
  1683 00000887 66BA0000                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
  1684 0000088B E87AFDFFFF                      call    ctrl_io_w8
  1685 00000890 C3                      	retn
  1686                                  _exit_:
  1687                                          ; finished with song, stop everything
  1688 00000891 66B82300                	mov     ax, VIA_REG_CTRL_INT
  1689 00000895 6683C840                        or      ax, VIA_REG_CTRL_TERMINATE
  1690 00000899 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1691 0000089D E868FDFFFF                      call    ctrl_io_w8
  1692                                  
  1693 000008A2 E80BFEFFFF                      call	channel_reset
  1694                                  _return:
  1695 000008A7 C3                      	retn
  1696                                  
  1697                                  ;input AL = index # to stop on
  1698                                  setLastValidIndex:
  1699                                  	; 05/03/2017 (TRDOS 386)
  1700                                  	; 19/11/2016
  1701                                  	; 14/11/2016 - Erdogan Tan (Ref: VIA VT8235.PDF, Page 110)
  1702                                  	; 12/11/2016 - Erdogan Tan
  1703                                  	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
  1704                                  	;push	edx
  1705 000008A8 50                      	push	eax
  1706                                  	;push	ecx
  1707 000008A9 0FB705[8F0C0000]        	movzx	eax, word [sample_rate] ; Hertz
  1708 000008B0 BA00001000              	mov	edx, 100000h ; 2^20 = 1048576
  1709 000008B5 F7E2                    	mul	edx
  1710 000008B7 B980BB0000              	mov	ecx, 48000	
  1711 000008BC F7F1                    	div	ecx
  1712                                  	;and	eax, 0FFFFFh
  1713                                  	;pop	ecx
  1714 000008BE 5A                      	pop	edx 
  1715 000008BF C1E218                  	shl	edx, 24  ; STOP Index Setting: Bit 24 to 31
  1716 000008C2 09D0                    	or	eax, edx
  1717                                  	; 19/11/2016
  1718 000008C4 803D[5D0C0000]10        	cmp	byte [bps], 16
  1719 000008CB 7505                    	jne	short sLVI_1
  1720 000008CD 0D00002000              	or	eax, VIA8233_REG_TYPE_16BIT
  1721                                  sLVI_1:
  1722 000008D2 803D[5C0C0000]02        	cmp	byte [stmo], 2
  1723 000008D9 7505                    	jne	short sLVI_2
  1724 000008DB 0D00001000              	or	eax, VIA8233_REG_TYPE_STEREO
  1725                                  sLVI_2:
  1726 000008E0 BA08000000              	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
  1727 000008E5 E838FDFFFF                      call    ctrl_io_w32
  1728 000008EA E89FFDFFFF              	call	codec_check_ready
  1729                                  	;pop	edx
  1730 000008EF C3                      	retn
  1731                                  
  1732                                  ;       delay1_4ms - Delay for 1/4 millisecond.
  1733                                  ;	    1mS = 1000us
  1734                                  ;       Entry:
  1735                                  ;         None
  1736                                  ;       Exit:
  1737                                  ;	  None
  1738                                  ;
  1739                                  ;       Modified:
  1740                                  ;         None
  1741                                  ;
  1742                                  PORTB		EQU	061h
  1743                                  REFRESH_STATUS	EQU	010h	; Refresh signal status
  1744                                  
  1745                                  	; 05/03/2017 (TRDOS 386)
  1746                                  delay1_4ms:
  1747 000008F0 50                              push    eax 
  1748 000008F1 51                              push    ecx
  1749                                          ;mov	cl, 16		; close enough.
  1750 000008F2 B10C                    	mov	cl, 12 ; + INT 34h delay	
  1751                                  
  1752                                  	;in	al, PORTB
  1753                                  	
  1754 000008F4 66BA6100                	mov	dx,  PORTB
  1755 000008F8 28E4                    	sub	ah, ah ; 0 ; inb
  1756 000008FA CD34                    	int	34h
  1757                                  	
  1758 000008FC 2410                    	and	al, REFRESH_STATUS
  1759 000008FE 88C5                    	mov	ch, al		; Start toggle state
  1760 00000900 08C9                    	or	cl, cl
  1761 00000902 7402                    	jz	short _d4ms1
  1762 00000904 FEC1                    	inc	cl		; Throwaway first toggle
  1763                                  _d4ms1:	
  1764                                  	;in	al, PORTB	; Read system control port
  1765                                  	
  1766                                  	;mov	ah, 0 ; inb
  1767                                  	;mov	dx, PORTB
  1768 00000906 CD34                    	int	34h
  1769                                  	
  1770 00000908 2410                    	and	al, REFRESH_STATUS ; Refresh toggles 15.085 microseconds
  1771 0000090A 38C5                    	cmp	ch, al
  1772 0000090C 74F8                    	je	short _d4ms1	; Wait for state change
  1773                                  
  1774 0000090E 88C5                    	mov	ch, al		; Update with new state
  1775 00000910 FEC9                    	dec	cl
  1776 00000912 75F2                    	jnz	short _d4ms1
  1777                                  
  1778 00000914 59                              pop     ecx
  1779 00000915 58                              pop     eax
  1780 00000916 C3                              retn
  1781                                  
  1782                                  	; 05/03/2017 (TRDOS 386)
  1783                                  	; 13/11/2016 - Erdogan Tan
  1784                                  write_ac97_dev_info:
  1785                                  	; BUS/DEV/FN
  1786                                  	;	00000000BBBBBBBBDDDDDFFF00000000
  1787                                  	; DEV/VENDOR
  1788                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
  1789                                  
  1790 00000917 8B35[690C0000]          	mov	esi, [dev_vendor]
  1791 0000091D 6689F0                  	mov	ax, si
  1792 00000920 0FB6D8                  	movzx	ebx, al
  1793 00000923 88DA                    	mov	dl, bl
  1794 00000925 80E30F                  	and	bl, 0Fh
  1795 00000928 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1796 0000092E A2[C90B0000]            	mov	[msgVendorId+3], al
  1797 00000933 88D3                    	mov	bl, dl
  1798 00000935 C0EB04                  	shr	bl, 4
  1799 00000938 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1800 0000093E A2[C80B0000]            	mov	[msgVendorId+2], al
  1801 00000943 88E3                    	mov	bl, ah
  1802 00000945 88DA                    	mov	dl, bl
  1803 00000947 80E30F                  	and	bl, 0Fh
  1804 0000094A 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1805 00000950 A2[C70B0000]            	mov	[msgVendorId+1], al
  1806 00000955 88D3                    	mov	bl, dl
  1807 00000957 C0EB04                  	shr	bl, 4
  1808 0000095A 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1809 00000960 A2[C60B0000]            	mov	[msgVendorId], al
  1810 00000965 C1EE10                  	shr	esi, 16
  1811 00000968 6689F0                  	mov	ax, si
  1812 0000096B 88C3                    	mov	bl, al
  1813 0000096D 88DA                    	mov	dl, bl
  1814 0000096F 80E30F                  	and	bl, 0Fh
  1815 00000972 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1816 00000978 A2[DA0B0000]            	mov	[msgDevId+3], al
  1817 0000097D 88D3                    	mov	bl, dl
  1818 0000097F C0EB04                  	shr	bl, 4
  1819 00000982 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1820 00000988 A2[D90B0000]            	mov	[msgDevId+2], al
  1821 0000098D 88E3                    	mov	bl, ah
  1822 0000098F 88DA                    	mov	dl, bl
  1823 00000991 80E30F                  	and	bl, 0Fh
  1824 00000994 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1825 0000099A A2[D80B0000]            	mov	[msgDevId+1], al
  1826 0000099F 88D3                    	mov	bl, dl
  1827 000009A1 C0EB04                  	shr	bl, 4
  1828 000009A4 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1829 000009AA A2[D70B0000]            	mov	[msgDevId], al
  1830                                  
  1831 000009AF 8B35[650C0000]          	mov	esi, [bus_dev_fn]
  1832 000009B5 C1EE08                  	shr	esi, 8
  1833 000009B8 6689F0                  	mov	ax, si
  1834 000009BB 88C3                    	mov	bl, al
  1835 000009BD 88DA                    	mov	dl, bl
  1836 000009BF 80E307                  	and	bl, 7 ; bit 0,1,2
  1837 000009C2 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1838 000009C8 A2[FE0B0000]            	mov	[msgFncNo+1], al
  1839 000009CD 88D3                    	mov	bl, dl
  1840 000009CF C0EB03                  	shr	bl, 3
  1841 000009D2 88DA                    	mov	dl, bl
  1842 000009D4 80E30F                  	and	bl, 0Fh
  1843 000009D7 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1844 000009DD A2[F00B0000]            	mov	[msgDevNo+1], al
  1845 000009E2 88D3                    	mov	bl, dl
  1846 000009E4 C0EB04                  	shr	bl, 4
  1847 000009E7 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1848 000009ED A2[EF0B0000]            	mov	[msgDevNo], al
  1849 000009F2 88E3                    	mov	bl, ah
  1850 000009F4 88DA                    	mov	dl, bl
  1851 000009F6 80E30F                  	and	bl, 0Fh
  1852 000009F9 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1853 000009FF A2[E40B0000]            	mov	[msgBusNo+1], al
  1854 00000A04 88D3                    	mov	bl, dl
  1855 00000A06 C0EB04                  	shr	bl, 4
  1856 00000A09 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1857 00000A0F A2[E30B0000]            	mov	[msgBusNo], al
  1858                                  
  1859 00000A14 66A1[710C0000]          	mov	ax, [ac97_io_base]
  1860 00000A1A 88C3                    	mov	bl, al
  1861 00000A1C 88DA                    	mov	dl, bl
  1862 00000A1E 80E30F                  	and	bl, 0Fh
  1863 00000A21 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1864 00000A27 A2[170C0000]            	mov	[msgIOBaseAddr+3], al
  1865 00000A2C 88D3                    	mov	bl, dl
  1866 00000A2E C0EB04                  	shr	bl, 4
  1867 00000A31 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1868 00000A37 A2[160C0000]            	mov	[msgIOBaseAddr+2], al
  1869 00000A3C 88E3                    	mov	bl, ah
  1870 00000A3E 88DA                    	mov	dl, bl
  1871 00000A40 80E30F                  	and	bl, 0Fh
  1872 00000A43 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1873 00000A49 A2[150C0000]            	mov	[msgIOBaseAddr+1], al
  1874 00000A4E 88D3                    	mov	bl, dl
  1875 00000A50 C0EB04                  	shr	bl, 4
  1876 00000A53 8A83[860B0000]          	mov	al, [ebx+hex_chars]
  1877 00000A59 A2[140C0000]            	mov	[msgIOBaseAddr], al
  1878                                  
  1879                                  	; 24/11/2016
  1880 00000A5E 30E4                    	xor	ah, ah
  1881 00000A60 A0[630C0000]            	mov	al, [ac97_int_ln_reg]
  1882 00000A65 B10A                    	mov	cl, 10
  1883 00000A67 F6F1                    	div	cl
  1884 00000A69 660105[1F0C0000]        	add	[msgIRQ], ax
  1885 00000A70 20C0                    	and	al, al
  1886 00000A72 750D                    	jnz	short _pmi
  1887 00000A74 A0[200C0000]            	mov	al, [msgIRQ+1]
  1888 00000A79 B420                    	mov	ah, ' '
  1889 00000A7B 66A3[1F0C0000]          	mov	[msgIRQ], ax
  1890                                  _pmi:
  1891                                  	; EBX = Message address
  1892                                  	; ECX = Max. message length (or stop on ZERO character)
  1893                                  	;	(1 to 255)
  1894                                  	; DL  = Message color (07h = light gray, 0Fh = white) 
  1895                                       	sys 	_msg, msgAC97Info, 255, 07h
  1895                              <1> 
  1895                              <1> 
  1895                              <1> 
  1895                              <1> 
  1895                              <1>  %if %0 >= 2
  1895 00000A81 BB[970B0000]        <1>  mov ebx, %2
  1895                              <1>  %if %0 >= 3
  1895 00000A86 B9FF000000          <1>  mov ecx, %3
  1895                              <1>  %if %0 = 4
  1895 00000A8B BA07000000          <1>  mov edx, %4
  1895                              <1>  %endif
  1895                              <1>  %endif
  1895                              <1>  %endif
  1895 00000A90 B823000000          <1>  mov eax, %1
  1895                              <1> 
  1895 00000A95 CD40                <1>  int 40h
  1896 00000A97 C3                              retn
  1897                                  
  1898                                  ;=============================================================================
  1899                                  ;               preinitialized data
  1900                                  ;=============================================================================
  1901                                  
  1902                                  noDevMsg:
  1903 00000A98 4572726F723A20556E-     	db "Error: Unable to find VIA VT8233 based audio device!",CR,LF,0
  1903 00000AA1 61626C6520746F2066-
  1903 00000AAA 696E64205649412056-
  1903 00000AB3 543832333320626173-
  1903 00000ABC 656420617564696F20-
  1903 00000AC5 646576696365210D0A-
  1903 00000ACE 00                 
  1904                                  
  1905                                  CodecErrMsg:
  1906 00000ACF 436F64656320457272-     	db	"Codec Error #"
  1906 00000AD8 6F722023           
  1907 00000ADC 3020210D0A00            ErrNo:	db 	"0 !", CR,LF,0
  1908                                  
  1909                                  msg_usage:
  1910 00000AE2 75736167653A207761-     	db	'usage: wavplay filename.wav',10,13,0
  1910 00000AEB 76706C61792066696C-
  1910 00000AF4 656E616D652E776176-
  1910 00000AFD 0A0D00             
  1911                                  Credits:
  1912 00000B00 54696E792057415620-     	db	'Tiny WAV Player for TRDOS 386 by Erdogan Tan. '
  1912 00000B09 506C6179657220666F-
  1912 00000B12 72205452444F532033-
  1912 00000B1B 383620627920457264-
  1912 00000B24 6F67616E2054616E2E-
  1912 00000B2D 20                 
  1913 00000B2E 4D6172636820323031-     	db	'March 2017.',10,13,0
  1913 00000B37 372E0A0D00         
  1914 00000B3C 31372F30332F323031-     	db	'17/03/2017', 10,13,0
  1914 00000B45 370A0D00           
  1915                                  noFileErrMsg:
  1916 00000B49 4572726F723A206669-     	db	'Error: file not found.',10,13,0
  1916 00000B52 6C65206E6F7420666F-
  1916 00000B5B 756E642E0A0D00     
  1917                                  
  1918                                  trdos386_err_msg:
  1919 00000B62 5452444F5320333836-     	db	'TRDOS 386 System call error !',10,13,0
  1919 00000B6B 2053797374656D2063-
  1919 00000B74 616C6C206572726F72-
  1919 00000B7D 20210A0D00         
  1920                                  
  1921                                  FileHandle:	
  1922 00000B82 FFFFFFFF                	dd	-1
  1923                                  
  1924                                  ; 13/11/2016
  1925 00000B86 303132333435363738-     hex_chars:	db "0123456789ABCDEF", 0
  1925 00000B8F 3941424344454600   
  1926 00000B97 414339372041756469-     msgAC97Info:	db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah 
  1926 00000BA0 6F20436F6E74726F6C-
  1926 00000BA9 6C6572202620436F64-
  1926 00000BB2 656320496E666F0D0A 
  1927 00000BBB 56656E646F72204944-     		db "Vendor ID: "
  1927 00000BC4 3A20               
  1928 00000BC6 303030306820446576-     msgVendorId:	db "0000h Device ID: "
  1928 00000BCF 6963652049443A20   
  1929 00000BD7 30303030680D0A          msgDevId:	db "0000h", 0Dh, 0Ah
  1930 00000BDE 4275733A20              		db "Bus: "
  1931 00000BE3 303068204465766963-     msgBusNo:	db "00h Device: "
  1931 00000BEC 653A20             
  1932 00000BEF 3030682046756E6374-     msgDevNo:	db "00h Function: "
  1932 00000BF8 696F6E3A20         
  1933 00000BFD 303068                  msgFncNo:	db "00h"
  1934 00000C00 0D0A                    		db 0Dh, 0Ah
  1935 00000C02 492F4F204261736520-     		db "I/O Base Address: "
  1935 00000C0B 416464726573733A20 
  1936 00000C14 303030306820495251-     msgIOBaseAddr:	db "0000h IRQ: "
  1936 00000C1D 3A20               
  1937 00000C1F 3030                    msgIRQ:		dw 3030h
  1938 00000C21 0D0A00                  		db 0Dh, 0Ah, 0
  1939 00000C24 53616D706C65205261-     msgSampleRate:	db "Sample Rate: "
  1939 00000C2D 74653A20           
  1940 00000C31 303030303020487A20-     msgHertz:	db "00000 Hz ", 0
  1940 00000C3A 00                 
  1941 00000C3B 3820626974732000        msg8Bits:	db "8 bits ", 0
  1942 00000C43 4D6F6E6F0D0A00          msgMono:	db "Mono", 0Dh, 0Ah, 0
  1943 00000C4A 313620626974732024      msg16Bits:	db "16 bits ", "$" 
  1944 00000C53 53746572656F0D0A00      msgStereo:	db "Stereo", 0Dh, 0Ah, 0
  1945                                  
  1946                                  ;; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
  1947                                  ;codec_id:	   dd 0
  1948                                  ;codec_chip_id:	   dd 0
  1949                                  ;codec_vendor_ids: dw 0
  1950                                  ;codec_chip_ids:   dw 0
  1951                                  
  1952                                  ;dword_str:	dd 30303030h, 30303030h
  1953                                  ;	 	db 'h', 0Dh, 0Ah, 0
  1954                                  
  1955                                  ;=============================================================================
  1956                                  ;        	uninitialized data
  1957                                  ;=============================================================================
  1958                                  
  1959                                  bss_start:
  1960                                  
  1961                                  ABSOLUTE bss_start
  1962                                  
  1963                                  alignb 4
  1964                                  
  1965 00000C5C <res 00000001>          stmo	resb	1 ; stereo or mono  
  1966 00000C5D <res 00000001>          bps	resb	1 ; bits per sample (16)
  1967                                  
  1968 00000C5E <res 00000001>          irq_status:	resb 	1
  1969                                  
  1970 00000C5F <res 00000001>          uLVI:	resb	1 
  1971 00000C60 <res 00000001>          tLoop:	resb 	1
  1972 00000C61 <res 00000001>          tBuff:	resb	1
  1973 00000C62 <res 00000001>          flags:	resb	1
  1974                                  
  1975                                  ; 12/11/2016 - Erdogan Tan
  1976                                  
  1977 00000C63 <res 00000001>          ac97_int_ln_reg: resb 1 
  1978 00000C64 <res 00000001>          err_num:	resb 1
  1979                                  ;s_r_b:		resb 1 ; 06/03/2017	
  1980                                  	
  1981 00000C65 <res 00000004>          bus_dev_fn:	resd 1
  1982 00000C69 <res 00000004>          dev_vendor:	resd 1
  1983 00000C6D <res 00000004>          stats_cmd:	resd 1
  1984 00000C71 <res 00000002>          ac97_io_base:	resw 1
  1985                                  
  1986 00000C73 <res 0000001C>          smpRBuff:	resw 14 
  1987                                  
  1988                                  sample_rate:
  1989 00000C8F <res 00000002>          		resw 1
  1990                                  
  1991                                  wav_file_name:
  1992 00000C91 <res 00000010>          		resb 16
  1993                                  
  1994 00000CA1 <res 00000003>          alignb 4
  1995                                  
  1996                                  ; 17/03/2017
  1997 00000CA4 <res 00000004>          BDL_phy_buff:	resd 1
  1998 00000CA8 <res 00000004>          DMA_phy_buff:	resd 1
  1999                                  
  2000 00000CAC <res 00000354>          alignb 4096
  2001                                  
  2002 00001000 <res 00001000>          BdlBuffer:	resb	4096 ; BDL_SIZE (round up to 1 page)
  2003                                  
  2004 00002000 <res 0000E000>          alignb 65536
  2005 00010000 <res 00010000>          DmaBuffer:	resb 65536 ; 2 * 32K half buffer (BUFFERSIZE)
  2006                                  EOF:
