     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: 21/04/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                                  ; 01/03/2017
    20                                  ; 16/10/2016
    21                                  ; 29/04/2016
    22                                  ; TRDOS 386 system calls (temporary list!)
    23                                  _ver 	equ 0
    24                                  _exit 	equ 1
    25                                  _fork 	equ 2
    26                                  _read 	equ 3
    27                                  _write	equ 4
    28                                  _open	equ 5
    29                                  _close 	equ 6
    30                                  _wait 	equ 7
    31                                  _creat 	equ 8
    32                                  _link 	equ 9
    33                                  _unlink	equ 10
    34                                  _exec	equ 11
    35                                  _chdir	equ 12
    36                                  _time 	equ 13
    37                                  _mkdir 	equ 14
    38                                  _chmod	equ 15
    39                                  _chown	equ 16
    40                                  _break	equ 17
    41                                  _stat	equ 18
    42                                  _seek	equ 19
    43                                  _tell 	equ 20
    44                                  _mount	equ 21
    45                                  _umount	equ 22
    46                                  _setuid	equ 23
    47                                  _getuid	equ 24
    48                                  _stime	equ 25
    49                                  _quit	equ 26	
    50                                  _intr	equ 27
    51                                  _fstat	equ 28
    52                                  _emt 	equ 29
    53                                  _mdate 	equ 30
    54                                  _video 	equ 31
    55                                  _audio	equ 32
    56                                  _timer	equ 33
    57                                  _sleep	equ 34
    58                                  _msg    equ 35
    59                                  _geterr	equ 36
    60                                  _fpsave	equ 37
    61                                  _pri	equ 38
    62                                  _rele	equ 39
    63                                  _fff	equ 40
    64                                  _fnf	equ 41
    65                                  _alloc	equ 42
    66                                  _dalloc equ 43
    67                                  _calbac equ 44
    68                                  
    69                                  %macro sys 1-4
    70                                      ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
    71                                      ; 03/09/2015	
    72                                      ; 13/04/2015
    73                                      ; Retro UNIX 386 v1 system call.	
    74                                      %if %0 >= 2   
    75                                          mov ebx, %2
    76                                          %if %0 >= 3    
    77                                              mov ecx, %3
    78                                              %if %0 = 4
    79                                                 mov edx, %4   
    80                                              %endif
    81                                          %endif
    82                                      %endif
    83                                      mov eax, %1
    84                                      ;int 30h
    85                                      int 40h ; TRDOS 386 (TRDOS v2.0)	   
    86                                  %endmacro
    87                                  
    88                                  ; TRDOS 386 (and Retro UNIX 386 v1) system call format:
    89                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    90                                  
    91                                  
    92                                  [BITS 32]
    93                                  
    94                                  [ORG 0] 
    95                                  
    96                                  _STARTUP:
    97                                  	; Prints the Credits Text.
    98                                  	sys	_msg, Credits, 255, 0Bh
    98                              <1> 
    98                              <1> 
    98                              <1> 
    98                              <1> 
    98                              <1>  %if %0 >= 2
    98 00000000 BB[EE0A0000]        <1>  mov ebx, %2
    98                              <1>  %if %0 >= 3
    98 00000005 B9FF000000          <1>  mov ecx, %3
    98                              <1>  %if %0 = 4
    98 0000000A BA0B000000          <1>  mov edx, %4
    98                              <1>  %endif
    98                              <1>  %endif
    98                              <1>  %endif
    98 0000000F B823000000          <1>  mov eax, %1
    98                              <1> 
    98 00000014 CD40                <1>  int 40h
    99                                  
   100                                  	; clear bss
   101 00000016 B9[00000200]            	mov	ecx, EOF
   102 0000001B BF[4A0C0000]            	mov	edi, bss_start
   103 00000020 29F9                    	sub	ecx, edi
   104 00000022 D1E9                    	shr	ecx, 1
   105 00000024 31C0                    	xor	eax, eax
   106 00000026 F366AB                  	rep	stosw
   107                                  
   108 00000029 E8BA010000              	call    DetectVT8233	; Detect the VT8233 Audio Device
   109                                  GetFileName:  
   110 0000002E 89E6                    	mov	esi, esp
   111 00000030 AD                      	lodsd
   112 00000031 83F802                  	cmp	eax, 2 ; two arguments 
   113                                  	       ; (program file name & mod file name)
   114 00000034 0F827E010000            	jb	pmsg_usage ; nothing to do
   115                                  
   116 0000003A AD                      	lodsd ; program file name address 
   117 0000003B AD                      	lodsd ; mod file name address (file to be read)
   118 0000003C 89C6                    	mov	esi, eax
   119 0000003E BF[810C0000]            	mov	edi, wav_file_name
   120                                  ScanName:       
   121 00000043 AC                      	lodsb
   122 00000044 84C0                    	test	al, al
   123 00000046 0F846C010000            	je	pmsg_usage
   124 0000004C 3C20                    	cmp	al, 20h
   125 0000004E 74F3                    	je	short ScanName	; scan start of name.
   126 00000050 AA                      	stosb
   127 00000051 B4FF                    	mov	ah, 0FFh
   128                                  a_0:	
   129 00000053 FEC4                    	inc	ah
   130                                  a_1:
   131 00000055 AC                      	lodsb
   132 00000056 AA                      	stosb
   133 00000057 3C2E                    	cmp	al, '.'
   134 00000059 74F8                    	je	short a_0	
   135 0000005B 20C0                    	and	al, al
   136 0000005D 75F6                    	jnz	short a_1
   137                                  
   138 0000005F 08E4                    	or	ah, ah		 ; if period NOT found,
   139 00000061 750B                    	jnz	short init_codec ; then add a .WAV extension.
   140                                  SetExt:
   141 00000063 4F                      	dec	edi
   142 00000064 C7072E574156            	mov	dword [edi], '.WAV'
   143 0000006A C6470400                	mov	byte [edi+4], 0
   144                                  
   145                                  init_codec:
   146                                  	; init AC97 codec
   147                                  
   148                                  	; 19/03/2017
   149                                  	;mov	eax, [bus_dev_fn]
   150                                  	;mov	al, VIA_ACLINK_CTRL  ; AC link interface control (41h)
   151                                  	;call	pciRegRead8
   152                                  
   153                                  	;;mov	eax, [bus_dev_fn]
   154                                  	;mov	al, VIA_ACLINK_STAT  ; AC Link interface status (40h)
   155                                  	;call	pciRegRead8
   156                                  	
   157                                  	;movzx	eax, dl
   158                                  	;test	al, VIA_ACLINK_C00_READY  ; 1 ; primary codec ready ?
   159                                  	;jnz	short a_2
   160                                  
   161 0000006E E81C050000              	call	reset_codec
   162 00000073 731B                    	jnc	short a_2 ; EAX = 1
   163                                  
   164                                  	;test	al, VIA_ACLINK_C00_READY 	
   165                                          ;jnz     short a_2
   166                                  
   167                                  _codec_err:
   168                                  	sys	_msg, CodecErrMsg, 255, 0Fh
   168                              <1> 
   168                              <1> 
   168                              <1> 
   168                              <1> 
   168                              <1>  %if %0 >= 2
   168 00000075 BB[BD0A0000]        <1>  mov ebx, %2
   168                              <1>  %if %0 >= 3
   168 0000007A B9FF000000          <1>  mov ecx, %3
   168                              <1>  %if %0 = 4
   168 0000007F BA0F000000          <1>  mov edx, %4
   168                              <1>  %endif
   168                              <1>  %endif
   168                              <1>  %endif
   168 00000084 B823000000          <1>  mov eax, %1
   168                              <1> 
   168 00000089 CD40                <1>  int 40h
   169 0000008B E91F010000                      jmp     Exit
   170                                  
   171                                  a_2:
   172                                  	; eax = 1
   173 00000090 E84C050000              	call	codec_io_w16 ; w32
   174                                  	
   175                                  	;call	detect_codec
   176                                  
   177 00000095 E815060000              	call	channel_reset
   178                                  
   179 0000009A E866080000              	call	write_ac97_dev_info 
   180                                  
   181                                  ; setup the Codec (actually mixer registers) 
   182 0000009F E810040000                      call    codecConfig                     ; unmute codec, set rates.
   183 000000A4 7309                    	jnc	short a_3
   184                                  
   185 000000A6 0430                    	add	al, '0'
   186 000000A8 A2[CA0A0000]            	mov	[ErrNo], al
   187 000000AD EBC6                    	jmp	short _codec_err
   188                                  
   189                                  a_3:
   190                                  	; SETUP INTERRUPT CALLBACK SERVICE
   191                                  	; 05/03/2017
   192 000000AF 8A1D[530C0000]          	mov	bl, [ac97_int_ln_reg] ; IRQ number
   193 000000B5 B702                    	mov	bh, 2 ; Link IRQ to user for callback service
   194 000000B7 BA[19030000]            	mov	edx, ac97_int_handler
   195                                  	sys	_calbac
   195                              <1> 
   195                              <1> 
   195                              <1> 
   195                              <1> 
   195                              <1>  %if %0 >= 2
   195                              <1>  mov ebx, %2
   195                              <1>  %if %0 >= 3
   195                              <1>  mov ecx, %3
   195                              <1>  %if %0 = 4
   195                              <1>  mov edx, %4
   195                              <1>  %endif
   195                              <1>  %endif
   195                              <1>  %endif
   195 000000BC B82C000000          <1>  mov eax, %1
   195                              <1> 
   195 000000C1 CD40                <1>  int 40h
   196 000000C3 0F8207010000            	jc	error_exit
   197                                  
   198                                  	; DIRECT CGA (TEXT MODE) MEMORY ACCESS
   199                                  	; bl = 0, bh = 4
   200                                  	; Direct access/map to CGA (Text) memory (0B8000h)
   201                                  
   202                                  	sys	_video, 0400h
   202                              <1> 
   202                              <1> 
   202                              <1> 
   202                              <1> 
   202                              <1>  %if %0 >= 2
   202 000000C9 BB00040000          <1>  mov ebx, %2
   202                              <1>  %if %0 >= 3
   202                              <1>  mov ecx, %3
   202                              <1>  %if %0 = 4
   202                              <1>  mov edx, %4
   202                              <1>  %endif
   202                              <1>  %endif
   202                              <1>  %endif
   202 000000CE B81F000000          <1>  mov eax, %1
   202                              <1> 
   202 000000D3 CD40                <1>  int 40h
   203 000000D5 3D00800B00              	cmp	eax, 0B8000h
   204 000000DA 0F85F0000000            	jne	error_exit
   205                                  
   206                                  ; open the file
   207                                          ; open existing file
   208 000000E0 E8A6010000                      call    openFile ; no error? ok.
   209 000000E5 731B                            jnc     short _gsr
   210                                  
   211                                  ; file not found!
   212                                  	sys	_msg, noFileErrMsg, 255, 0Fh
   212                              <1> 
   212                              <1> 
   212                              <1> 
   212                              <1> 
   212                              <1>  %if %0 >= 2
   212 000000E7 BB[370B0000]        <1>  mov ebx, %2
   212                              <1>  %if %0 >= 3
   212 000000EC B9FF000000          <1>  mov ecx, %3
   212                              <1>  %if %0 = 4
   212 000000F1 BA0F000000          <1>  mov edx, %4
   212                              <1>  %endif
   212                              <1>  %endif
   212                              <1>  %endif
   212 000000F6 B823000000          <1>  mov eax, %1
   212                              <1> 
   212 000000FB CD40                <1>  int 40h
   213 000000FD E9AD000000                      jmp     Exit
   214                                  
   215                                  _gsr:  
   216 00000102 E8B4010000                     	call    getSampleRate		; read the sample rate
   217                                                                          ; pass it onto codec.
   218 00000107 0F82A2000000            	jc	Exit
   219                                  
   220 0000010D 66A3[7F0C0000]          	mov	[sample_rate], ax
   221 00000113 880D[4C0C0000]          	mov	[stmo], cl
   222 00000119 8815[4D0C0000]          	mov	[bps], dl
   223                                  	
   224                                  PlayNow: 
   225                                  	; DIRECT MEMORY ACCESS (for Audio Controller)
   226                                  	; ebx = BDL buffer address (virtual, user)
   227                                  	; ecx = buffer size (in bytes)
   228                                  	; edx = upper limit = 0 = no limit
   229                                  
   230                                  	sys	_alloc, BdlBuffer, 4096, 0 
   230                              <1> 
   230                              <1> 
   230                              <1> 
   230                              <1> 
   230                              <1>  %if %0 >= 2
   230 0000011F BB[00100000]        <1>  mov ebx, %2
   230                              <1>  %if %0 >= 3
   230 00000124 B900100000          <1>  mov ecx, %3
   230                              <1>  %if %0 = 4
   230 00000129 BA00000000          <1>  mov edx, %4
   230                              <1>  %endif
   230                              <1>  %endif
   230                              <1>  %endif
   230 0000012E B82A000000          <1>  mov eax, %1
   230                              <1> 
   230 00000133 CD40                <1>  int 40h
   231 00000135 0F8295000000            	jc	error_exit
   232                                  
   233 0000013B A3[940C0000]            	mov	[BDL_phy_buff], eax	; physical address
   234                                  					; of the buffer
   235                                  					; (which is needed
   236                                  					; for Audio controller)
   237                                  
   238                                  	; DIRECT MEMORY ACCESS (for Audio Controller)
   239                                  	; ebx = DMA buffer address (virtual, user)
   240                                  	; ecx = buffer size (in bytes)
   241                                  	; edx = upper limit = 0 = no limit
   242                                  
   243                                  	sys	_alloc, DmaBuffer, 65536, 0 
   243                              <1> 
   243                              <1> 
   243                              <1> 
   243                              <1> 
   243                              <1>  %if %0 >= 2
   243 00000140 BB[00000100]        <1>  mov ebx, %2
   243                              <1>  %if %0 >= 3
   243 00000145 B900000100          <1>  mov ecx, %3
   243                              <1>  %if %0 = 4
   243 0000014A BA00000000          <1>  mov edx, %4
   243                              <1>  %endif
   243                              <1>  %endif
   243                              <1>  %endif
   243 0000014F B82A000000          <1>  mov eax, %1
   243                              <1> 
   243 00000154 CD40                <1>  int 40h
   244 00000156 7278                    	jc	short error_exit
   245                                  
   246 00000158 A3[980C0000]            	mov	[DMA_phy_buff], eax	; physical address
   247                                  					; of the buffer
   248                                  					; (which is needed
   249                                  					; for Audio controller)
   250                                  ;
   251                                  ; position file pointer to start in actual wav data
   252                                  ; MUCH improvement should really be done here to check if sample size is
   253                                  ; supported, make sure there are 2 channels, etc.  
   254                                  ;
   255                                          ;mov     ah, 42h
   256                                          ;mov     al, 0	; from start of file
   257                                          ;mov     bx, [FileHandle]
   258                                          ;xor     cx, cx
   259                                          ;mov     dx, 44	; jump past .wav/riff header
   260                                          ;int     21h
   261                                  
   262                                  	sys	_seek, [FileHandle], 44, 0
   262                              <1> 
   262                              <1> 
   262                              <1> 
   262                              <1> 
   262                              <1>  %if %0 >= 2
   262 0000015D 8B1D[700B0000]      <1>  mov ebx, %2
   262                              <1>  %if %0 >= 3
   262 00000163 B92C000000          <1>  mov ecx, %3
   262                              <1>  %if %0 = 4
   262 00000168 BA00000000          <1>  mov edx, %4
   262                              <1>  %endif
   262                              <1>  %endif
   262                              <1>  %endif
   262 0000016D B813000000          <1>  mov eax, %1
   262                              <1> 
   262 00000172 CD40                <1>  int 40h
   263                                  
   264                                  ; play the .wav file.  Most of the good stuff is in here.
   265                                  
   266 00000174 E8B5050000                      call    PlayWav
   267                                  
   268                                  ; close the .wav file and exit.
   269                                  
   270 00000179 E826010000                      call    closeFile
   271                                  
   272                                  StopPlaying:
   273 0000017E 8A1D[530C0000]          	mov     bl, [ac97_int_ln_reg] ; Audio IRQ number
   274 00000184 28FF                    	sub	bh, bh ; 0 = Unlink IRQ from user
   275                                  	sys	_calbac 
   275                              <1> 
   275                              <1> 
   275                              <1> 
   275                              <1> 
   275                              <1>  %if %0 >= 2
   275                              <1>  mov ebx, %2
   275                              <1>  %if %0 >= 3
   275                              <1>  mov ecx, %3
   275                              <1>  %if %0 = 4
   275                              <1>  mov edx, %4
   275                              <1>  %endif
   275                              <1>  %endif
   275                              <1>  %endif
   275 00000186 B82C000000          <1>  mov eax, %1
   275                              <1> 
   275 0000018B CD40                <1>  int 40h
   276                                  
   277                                  	; Deallocate BDL buffer (not necessary just before exit!)
   278                                  	sys	_dalloc, BdlBuffer, 4096
   278                              <1> 
   278                              <1> 
   278                              <1> 
   278                              <1> 
   278                              <1>  %if %0 >= 2
   278 0000018D BB[00100000]        <1>  mov ebx, %2
   278                              <1>  %if %0 >= 3
   278 00000192 B900100000          <1>  mov ecx, %3
   278                              <1>  %if %0 = 4
   278                              <1>  mov edx, %4
   278                              <1>  %endif
   278                              <1>  %endif
   278                              <1>  %endif
   278 00000197 B82B000000          <1>  mov eax, %1
   278                              <1> 
   278 0000019C CD40                <1>  int 40h
   279                                  	; Deallocate DMA buffer (not necessary just before exit!)
   280                                  	sys	_dalloc, DmaBuffer, 65536  ; 14/03/2017
   280                              <1> 
   280                              <1> 
   280                              <1> 
   280                              <1> 
   280                              <1>  %if %0 >= 2
   280 0000019E BB[00000100]        <1>  mov ebx, %2
   280                              <1>  %if %0 >= 3
   280 000001A3 B900000100          <1>  mov ecx, %3
   280                              <1>  %if %0 = 4
   280                              <1>  mov edx, %4
   280                              <1>  %endif
   280                              <1>  %endif
   280                              <1>  %endif
   280 000001A8 B82B000000          <1>  mov eax, %1
   280                              <1> 
   280 000001AD CD40                <1>  int 40h
   281                                  Exit:           
   282                                  	sys	_exit	; Bye!
   282                              <1> 
   282                              <1> 
   282                              <1> 
   282                              <1> 
   282                              <1>  %if %0 >= 2
   282                              <1>  mov ebx, %2
   282                              <1>  %if %0 >= 3
   282                              <1>  mov ecx, %3
   282                              <1>  %if %0 = 4
   282                              <1>  mov edx, %4
   282                              <1>  %endif
   282                              <1>  %endif
   282                              <1>  %endif
   282 000001AF B801000000          <1>  mov eax, %1
   282                              <1> 
   282 000001B4 CD40                <1>  int 40h
   283                                  here:
   284 000001B6 EBFE                    	jmp	short here
   285                                  
   286                                  pmsg_usage:
   287                                  	sys	_msg, msg_usage, 255, 0Bh
   287                              <1> 
   287                              <1> 
   287                              <1> 
   287                              <1> 
   287                              <1>  %if %0 >= 2
   287 000001B8 BB[D00A0000]        <1>  mov ebx, %2
   287                              <1>  %if %0 >= 3
   287 000001BD B9FF000000          <1>  mov ecx, %3
   287                              <1>  %if %0 = 4
   287 000001C2 BA0B000000          <1>  mov edx, %4
   287                              <1>  %endif
   287                              <1>  %endif
   287                              <1>  %endif
   287 000001C7 B823000000          <1>  mov eax, %1
   287                              <1> 
   287 000001CC CD40                <1>  int 40h
   288 000001CE EBDF                    	jmp	short Exit
   289                                  
   290                                  error_exit:
   291                                  	sys	_msg, trdos386_err_msg, 255, 0Eh
   291                              <1> 
   291                              <1> 
   291                              <1> 
   291                              <1> 
   291                              <1>  %if %0 >= 2
   291 000001D0 BB[500B0000]        <1>  mov ebx, %2
   291                              <1>  %if %0 >= 3
   291 000001D5 B9FF000000          <1>  mov ecx, %3
   291                              <1>  %if %0 = 4
   291 000001DA BA0E000000          <1>  mov edx, %4
   291                              <1>  %endif
   291                              <1>  %endif
   291                              <1>  %endif
   291 000001DF B823000000          <1>  mov eax, %1
   291                              <1> 
   291 000001E4 CD40                <1>  int 40h
   292 000001E6 EBC7                    	jmp	short Exit
   293                                  
   294                                  DetectVT8233:
   295 000001E8 B806115930              	mov     eax, (VT8233_DID << 16) + VIA_VID
   296 000001ED E894020000                      call    pciFindDevice
   297 000001F2 7318                            jnc     short _1
   298                                  
   299                                  ; couldn't find the audio device!
   300                                  	sys	_msg, noDevMsg, 255, 0Fh
   300                              <1> 
   300                              <1> 
   300                              <1> 
   300                              <1> 
   300                              <1>  %if %0 >= 2
   300 000001F4 BB[860A0000]        <1>  mov ebx, %2
   300                              <1>  %if %0 >= 3
   300 000001F9 B9FF000000          <1>  mov ecx, %3
   300                              <1>  %if %0 = 4
   300 000001FE BA0F000000          <1>  mov edx, %4
   300                              <1>  %endif
   300                              <1>  %endif
   300                              <1>  %endif
   300 00000203 B823000000          <1>  mov eax, %1
   300                              <1> 
   300 00000208 CD40                <1>  int 40h
   301 0000020A EBA3                            jmp     short Exit
   302                                  
   303                                  _1:
   304                                  	; 05/03/2017 (TRDOS 386)
   305                                  	; 12/11/2016
   306                                  	; Erdogan Tan - 8/11/2016
   307                                  	; References: Kolibrios - vt823x.asm (2016)
   308                                  	;	      VIA VT8235 V-Link South Bridge (VT8235-VIA.PDF)(2002)
   309                                  	;	      lowlevel.eu - AC97 (2016)
   310                                  	;	      .wav player for DOS by Jeff Leyda (2002) -this file-
   311                                  	;	      Linux kernel - via82xx.c (2016)
   312                                  
   313                                  	; eax = BUS/DEV/FN
   314                                  	;	00000000BBBBBBBBDDDDDFFF00000000
   315                                  	; edx = DEV/VENDOR
   316                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
   317                                  
   318 0000020C A3[550C0000]            	mov	[bus_dev_fn], eax
   319 00000211 8915[590C0000]          	mov	[dev_vendor], edx
   320                                  
   321                                  	; init controller
   322 00000217 B004                    	mov	al, PCI_CMD_REG ; command register (04h)
   323 00000219 E8E7010000              	call	pciRegRead32
   324                                  
   325                                  	; eax = BUS/DEV/FN/REG
   326                                  	; edx = STATUS/COMMAND
   327                                  	; 	SSSSSSSSSSSSSSSSCCCCCCCCCCCCCCCC
   328 0000021E 8915[5D0C0000]          	mov	[stats_cmd], edx
   329                                  
   330 00000224 B010                    	mov	al, PCI_IO_BASE ; IO base address register (10h)
   331 00000226 E8DA010000              	call	pciRegRead32
   332                                  
   333 0000022B 6683E2C0                	and     dx, 0FFC0h	; IO_ADDR_MASK (0FFFE) ?
   334 0000022F 668915[610C0000]                mov     [ac97_io_base], dx
   335                                  
   336 00000236 B03C                    	mov	al, AC97_INT_LINE ; Interrupt line register (3Ch)
   337 00000238 E8C8010000              	call	pciRegRead32
   338                                  
   339 0000023D 81E2FF000000            	and 	edx, 0FFh
   340 00000243 8815[530C0000]            	mov     [ac97_int_ln_reg], dl
   341                                  
   342                                  	; 24/03/2017
   343                                  	; 05/03/2017 (TRDOS 386, INT 34h, IOCTL Interrupt)
   344                                  	; (Note: Interrupts are already enabled by TRDOS 386 kernel!)
   345                                  	; 28/11/2016
   346 00000249 6689D1                  	mov	cx, dx
   347                                  	
   348                                  	;in	al, 0A1h ; irq 8-15
   349 0000024C B2A1                    	mov	dl, 0A1h
   350 0000024E 28E4                    	sub	ah, ah ; 0 ; inb
   351 00000250 CD34                    	int	34h
   352                                  	
   353                                  	;mov	ah, al
   354 00000252 88C3                    	mov	bl, al
   355                                  	
   356                                  	;in	al, 21h  ; irq 0-7 
   357 00000254 B221                    	mov	dl, 21h	
   358                                  	;mov	ah, 0 ; inb
   359 00000256 CD34                    	int	34h	
   360                                  
   361 00000258 88DC                    	mov	ah, bl
   362 0000025A 660FB3C8                	btr	ax, cx	 ; unmask ; 17/03/2017
   363 0000025E 88E3                    	mov	bl, ah
   364                                  
   365                                  	;out	21h, al  ; enable interrupt (if irq <= 7)
   366 00000260 B401                    	mov	ah, 1 ; outb
   367 00000262 CD34                    	int	34h
   368                                  
   369                                  	;mov	al, ah
   370 00000264 88D8                    	mov	al, bl
   371                                  	;out	0A1h, al ; enable interrupt (if irq > 7)
   372 00000266 B2A1                    	mov	dl, 0A1h
   373                                  	;mov	ah, 1 ; outb
   374 00000268 CD34                    	int	34h		
   375                                  
   376 0000026A 66BAD104                	mov	dx, 4D1h	; 8259 ELCR1
   377                                      	;in	al, dx
   378 0000026E FECC                    	dec	ah ; 0 ; inb
   379 00000270 CD34                    	int	34h
   380                                  
   381                                  	;mov	ah, al
   382 00000272 88C3                    	mov	bl, al
   383                                  	
   384                                  	;mov	dx, 4D0h 
   385 00000274 FECA                    	dec	dl
   386                                  	;in	al, dx
   387                                  	;mov	ah, 0 ; inb
   388 00000276 CD34                    	int	34h
   389                                  
   390 00000278 88DC                    	mov	ah, bl
   391 0000027A 660FABC8                	bts	ax, cx
   392 0000027E 88E3                    	mov	bl, ah
   393                                  
   394                                  	;mov	dx, 4D0h
   395                                  	;out	dx, al		; set level-triggered mode
   396 00000280 B401                    	mov	ah, 1 ; outb	
   397 00000282 CD34                    	int	34h
   398                                  
   399                                  	;mov	al, ah
   400 00000284 88D8                    	mov	al, bl
   401                                  	;mov	dx, 4D1h
   402 00000286 FEC2                    	inc	dl
   403                                  	;out	dx, al		; set level-triggered mode
   404                                  	;mov	ah, 1 ; outb	
   405 00000288 CD34                    	int	34h
   406                                  
   407 0000028A C3                      	retn
   408                                  
   409                                  ;open or create file
   410                                  ;
   411                                  ;input: ds:dx-->filename (asciiz)
   412                                  ;       al=file Mode (create or open)
   413                                  ;output: none  cs:[FileHandle] filled
   414                                  ;
   415                                  openFile:
   416                                  	;;push	eax
   417                                  	;;push	ecx
   418                                  	;mov	ah, 3Bh	; start with a mode
   419                                  	;add	ah, al	; add in create or open mode
   420                                  	;xor	cx, cx
   421                                  	;int	21h
   422                                  	;jc	short _of1
   423                                  	;;mov	[cs:FileHandle], ax
   424                                  
   425                                  	sys	_open, wav_file_name, 0
   425                              <1> 
   425                              <1> 
   425                              <1> 
   425                              <1> 
   425                              <1>  %if %0 >= 2
   425 0000028B BB[810C0000]        <1>  mov ebx, %2
   425                              <1>  %if %0 >= 3
   425 00000290 B900000000          <1>  mov ecx, %3
   425                              <1>  %if %0 = 4
   425                              <1>  mov edx, %4
   425                              <1>  %endif
   425                              <1>  %endif
   425                              <1>  %endif
   425 00000295 B805000000          <1>  mov eax, %1
   425                              <1> 
   425 0000029A CD40                <1>  int 40h
   426 0000029C 7205                    	jc	short _of1
   427                                  
   428 0000029E A3[700B0000]            	mov	[FileHandle], eax
   429                                  _of1:
   430                                  	;;pop	ecx
   431                                  	;;pop	eax
   432 000002A3 C3                      	retn
   433                                  
   434                                  ; close the currently open file
   435                                  ; input: none, uses cs:[FileHandle]
   436                                  closeFile:
   437                                  	;push	eax
   438                                  	;push	ebx
   439 000002A4 833D[700B0000]FF        	cmp	dword [FileHandle], -1
   440 000002AB 740D                    	je	short _cf1
   441                                  	;mov    bx, [FileHandle]  
   442                                  	;mov    ax, 3E00h
   443                                          ;int    21h              ;close file
   444                                  
   445                                  	sys	_close, [FileHandle]
   445                              <1> 
   445                              <1> 
   445                              <1> 
   445                              <1> 
   445                              <1>  %if %0 >= 2
   445 000002AD 8B1D[700B0000]      <1>  mov ebx, %2
   445                              <1>  %if %0 >= 3
   445                              <1>  mov ecx, %3
   445                              <1>  %if %0 = 4
   445                              <1>  mov edx, %4
   445                              <1>  %endif
   445                              <1>  %endif
   445                              <1>  %endif
   445 000002B3 B806000000          <1>  mov eax, %1
   445                              <1> 
   445 000002B8 CD40                <1>  int 40h
   446                                  _cf1:
   447                                  	;pop	ebx
   448                                  	;pop	eax
   449 000002BA C3                      	retn
   450                                  
   451                                  getSampleRate:
   452                                  	
   453                                  ; reads the sample rate from the .wav file.
   454                                  ; entry: none - assumes file is already open
   455                                  ; exit: ax = sample rate (11025, 22050, 44100, 48000)
   456                                  ;	cx = number of channels (mono=1, stereo=2)
   457                                  ;	dx = bits per sample (8, 16)
   458                                  
   459 000002BB 53                      	push    ebx
   460                                  
   461                                          ;mov	ah, 42h
   462                                          ;mov	al, 0	; from start of file
   463                                          ;mov	bx, [FileHandle]
   464                                          ;xor	cx, cx
   465                                          ;mov	dx, 08h	; "WAVE"
   466                                          ;int	21h
   467                                  	
   468                                  	sys	_seek, [FileHandle], 8, 0
   468                              <1> 
   468                              <1> 
   468                              <1> 
   468                              <1> 
   468                              <1>  %if %0 >= 2
   468 000002BC 8B1D[700B0000]      <1>  mov ebx, %2
   468                              <1>  %if %0 >= 3
   468 000002C2 B908000000          <1>  mov ecx, %3
   468                              <1>  %if %0 = 4
   468 000002C7 BA00000000          <1>  mov edx, %4
   468                              <1>  %endif
   468                              <1>  %endif
   468                              <1>  %endif
   468 000002CC B813000000          <1>  mov eax, %1
   468                              <1> 
   468 000002D1 CD40                <1>  int 40h
   469                                  
   470                                          ;mov	dx, smpRBuff
   471                                          ;mov	cx, 28	; 28 bytes
   472                                  	;mov	ah, 3fh
   473                                          ;int	21h
   474                                  
   475                                  	sys	_read, [FileHandle], smpRBuff, 28
   475                              <1> 
   475                              <1> 
   475                              <1> 
   475                              <1> 
   475                              <1>  %if %0 >= 2
   475 000002D3 8B1D[700B0000]      <1>  mov ebx, %2
   475                              <1>  %if %0 >= 3
   475 000002D9 B9[630C0000]        <1>  mov ecx, %3
   475                              <1>  %if %0 = 4
   475 000002DE BA1C000000          <1>  mov edx, %4
   475                              <1>  %endif
   475                              <1>  %endif
   475                              <1>  %endif
   475 000002E3 B803000000          <1>  mov eax, %1
   475                              <1> 
   475 000002E8 CD40                <1>  int 40h
   476                                  
   477 000002EA 813D[630C0000]5741-     	cmp	dword [smpRBuff], 'WAVE'
   477 000002F2 5645               
   478 000002F4 7520                    	jne	short gsr_stc
   479                                  
   480 000002F6 66833D[6F0C0000]01      	cmp	word [smpRBuff+12], 1	; Offset 20, must be 1 (= PCM)
   481 000002FE 7516                    	jne	short gsr_stc
   482                                  
   483 00000300 668B0D[710C0000]        	mov	cx, [smpRBuff+14]	; return num of channels in CX
   484 00000307 66A1[730C0000]                  mov     ax, [smpRBuff+16]	; return sample rate in AX
   485 0000030D 668B15[7D0C0000]        	mov	dx, [smpRBuff+26]	; return bits per sample value in DX
   486                                  gsr_retn:
   487 00000314 5B                              pop     ebx
   488 00000315 C3                              retn
   489                                  gsr_stc:
   490 00000316 F9                      	stc
   491 00000317 EBFB                    	jmp	short gsr_retn
   492                                  
   493                                  ac97_int_handler:
   494                                  	; 14/03/2017
   495                                  	; 06/03/2017 (Signal Response Byte Check)
   496                                  	; 05/03/2017 (Modified for TRDOS 386 IRQ callback method)
   497                                  
   498 00000319 803D[4F0C0000]01        	cmp	byte [uLVI], 1
   499 00000320 733E                    	jnb	short _busy
   500                                  
   501 00000322 C605[4F0C0000]01        	mov	byte [uLVI], 1
   502                                  
   503 00000329 C605[4E0C0000]00        	mov	byte [irq_status], 0
   504                                  
   505 00000330 66BA0000                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   506 00000334 E8DA020000                      call    ctrl_io_r8
   507                                  
   508 00000339 A880                    	test    al, VIA_REG_STAT_ACTIVE
   509 0000033B 740E                            jz      short _callback_retn
   510                                  
   511 0000033D 2407                            and     al, VIA_REG_STAT_EOL + VIA_REG_STAT_FLAG + VIA_REG_STAT_STOPPED
   512 0000033F A2[4E0C0000]            	mov	[irq_status], al
   513 00000344 7405                            jz	short _callback_retn
   514                                  
   515                                  	; 28/11/2016 - Erdogan Tan
   516 00000346 E8C7040000              	call	tuneLoop
   517                                  _callback_retn:
   518 0000034B C605[4F0C0000]00        	mov	byte [uLVI], 0 ; 14/03/2017
   519                                  _callback_bsy_retn:
   520                                  	sys	_rele ; return from callback service 
   520                              <1> 
   520                              <1> 
   520                              <1> 
   520                              <1> 
   520                              <1>  %if %0 >= 2
   520                              <1>  mov ebx, %2
   520                              <1>  %if %0 >= 3
   520                              <1>  mov ecx, %3
   520                              <1>  %if %0 = 4
   520                              <1>  mov edx, %4
   520                              <1>  %endif
   520                              <1>  %endif
   520                              <1>  %endif
   520 00000352 B827000000          <1>  mov eax, %1
   520                              <1> 
   520 00000357 CD40                <1>  int 40h
   521                                  	; we must not come here !
   522                                  	sys	_exit
   522                              <1> 
   522                              <1> 
   522                              <1> 
   522                              <1> 
   522                              <1>  %if %0 >= 2
   522                              <1>  mov ebx, %2
   522                              <1>  %if %0 >= 3
   522                              <1>  mov ecx, %3
   522                              <1>  %if %0 = 4
   522                              <1>  mov edx, %4
   522                              <1>  %endif
   522                              <1>  %endif
   522                              <1>  %endif
   522 00000359 B801000000          <1>  mov eax, %1
   522                              <1> 
   522 0000035E CD40                <1>  int 40h
   523                                  _busy:
   524                                  	; 28/11/2016 - Erdogan Tan
   525 00000360 A0[4E0C0000]                    mov     al, [irq_status]   ;; ack ;;
   526 00000365 66BA0000                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   527 00000369 E899020000                      call    ctrl_io_w8
   528                                  
   529 0000036E F605[4E0C0000]01        	test	byte [irq_status], VIA_REG_STAT_FLAG 
   530 00000375 74D4                    	jz	short _callback_retn ; 21/04/2017
   531                                  
   532 00000377 66B82300                	mov	ax, VIA_REG_CTRL_INT
   533 0000037B 660D8000                	or	ax, VIA_REG_CTRL_START
   534 0000037F 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   535 00000383 E87F020000              	call    ctrl_io_w8
   536                                  	
   537 00000388 E8FE020000              	call	codec_check_ready
   538                                  
   539                                  	;jmp	short _callback_bsy_retn ; 14/03/2017
   540 0000038D EBBC                    	jmp	short _callback_retn ; 17/03/2017
   541                                  
   542                                  ;=============================================================================
   543                                  ;               PCI.ASM
   544                                  ;=============================================================================
   545                                  
   546                                  ; EQUATES
   547                                  
   548                                  ;constants of stuff that seem hard to remember at times.
   549                                  
   550                                  TRUE  EQU 1
   551                                  FALSE EQU 0
   552                                  
   553                                  ENABLED  EQU 1
   554                                  DISABLED EQU 0
   555                                  
   556                                  BIT0  EQU 1
   557                                  BIT1  EQU 2
   558                                  BIT2  EQU 4
   559                                  BIT3  EQU 8
   560                                  BIT4  EQU 10h
   561                                  BIT5  EQU 20h
   562                                  BIT6  EQU 40h
   563                                  BIT7  EQU 80h
   564                                  BIT8  EQU 100h
   565                                  BIT9  EQU 200h
   566                                  BIT10 EQU 400h
   567                                  BIT11 EQU 800h
   568                                  BIT12 EQU 1000h
   569                                  BIT13 EQU 2000h
   570                                  BIT14 EQU 4000h
   571                                  BIT15 EQU 8000h
   572                                  BIT16 EQU 10000h
   573                                  BIT17 EQU 20000h
   574                                  BIT18 EQU 40000h
   575                                  BIT19 EQU 80000h
   576                                  BIT20 EQU 100000h
   577                                  BIT21 EQU 200000h
   578                                  BIT22 EQU 400000h
   579                                  BIT23 EQU 800000h
   580                                  BIT24 EQU 1000000h
   581                                  BIT25 EQU 2000000h
   582                                  BIT26 EQU 4000000h
   583                                  BIT27 EQU 8000000h
   584                                  BIT28 EQU 10000000h
   585                                  BIT29 EQU 20000000h
   586                                  BIT30 EQU 40000000h
   587                                  BIT31 EQU 80000000h
   588                                  NOT_BIT31 EQU 7FFFFFFFh ; 19/03/2017
   589                                  
   590                                  ;special characters
   591                                  NUL     EQU 0
   592                                  NULL    EQU 0
   593                                  BELL    EQU 07
   594                                  BS      EQU 08
   595                                  TAB     EQU 09
   596                                  LF      EQU 10
   597                                  CR      EQU 13
   598                                  ESCAPE  EQU 27           ;ESC is a reserved word....
   599                                  
   600                                  ; PCI equates
   601                                  ; PCI function address (PFA)
   602                                  ; bit 31 = 1
   603                                  ; bit 23:16 = bus number     (0-255)
   604                                  ; bit 15:11 = device number  (0-31)
   605                                  ; bit 10:8 = function number (0-7)
   606                                  ; bit 7:0 = register number  (0-255)
   607                                  
   608                                  IO_ADDR_MASK    EQU     0FFFEh	; mask off bit 0 for reading BARs
   609                                  PCI_INDEX_PORT  EQU     0CF8h
   610                                  PCI_DATA_PORT   EQU     0CFCh
   611                                  PCI32           EQU     BIT31	; bitflag to signal 32bit access
   612                                  PCI16           EQU     BIT30	; bitflag for 16bit access
   613                                  NOT_PCI32_PCI16	EQU	03FFFFFFFh ; NOT BIT31+BIT30 ; 19/03/2017
   614                                  
   615                                  PCI_FN0         EQU     0 << 8
   616                                  PCI_FN1         EQU     1 << 8
   617                                  PCI_FN2         EQU     2 << 8
   618                                  PCI_FN3         EQU     3 << 8
   619                                  PCI_FN4         EQU     4 << 8
   620                                  PCI_FN5         EQU     5 << 8
   621                                  PCI_FN6         EQU     6 << 8
   622                                  PCI_FN7         EQU     7 << 8
   623                                  
   624                                  PCI_CMD_REG	EQU	04h	; reg 04, command reg
   625                                   IO_ENA		EQU	BIT0	; i/o decode enable
   626                                   MEM_ENA	EQU	BIT1	; memory decode enable
   627                                   BM_ENA		EQU     BIT2	; bus master enable
   628                                  
   629                                  ; CODE
   630                                  
   631                                  ; PCI device register reader/writers.
   632                                  
   633                                  ; 19/03/2017
   634                                  ; 05/03/2017 (TRDOS 386, INT 34h, IOCTL interrupt modifications)
   635                                  ; NASM version: Erdogan Tan (29/11/2016)
   636                                  
   637                                  ;===============================================================
   638                                  ; 8/16/32bit PCI reader
   639                                  ;
   640                                  ; Entry: EAX=PCI Bus/Device/fn/register number
   641                                  ;           BIT30 set if 32 bit access requested
   642                                  ;           BIT29 set if 16 bit access requested
   643                                  ;           otherwise defaults to 8bit read
   644                                  ;
   645                                  ; Exit:  DL,DX,EDX register data depending on requested read size
   646                                  ;
   647                                  ; Note: this routine is meant to be called via pciRegRead8, pciRegread16,
   648                                  ;	or pciRegRead32, listed below.
   649                                  ;
   650                                  ; Note2: don't attempt to read 32bits of data from a non dword aligned reg
   651                                  ;	 number.  Likewise, don't do 16bit reads from non word aligned reg #
   652                                  ; 
   653                                  pciRegRead:
   654 0000038F 53                      	push	ebx
   655 00000390 51                      	push	ecx
   656 00000391 89C3                            mov     ebx, eax		; save eax, dh
   657 00000393 88F1                            mov     cl, dh
   658                                  
   659 00000395 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; clear out data size request
   660 0000039A 0D00000080                      or      eax, BIT31		; make a PCI access request
   661 0000039F 24FC                            and     al, ~3 ; NOT 3		; force index to be dword
   662                                  
   663 000003A1 66BAF80C                        mov     dx, PCI_INDEX_PORT
   664                                          ;out	dx, eax			; write PCI selector
   665 000003A5 53                      	push	ebx
   666 000003A6 89C3                    	mov	ebx, eax ; Data dword		
   667 000003A8 B405                    	mov	ah, 5	; outd (32 bit write)
   668 000003AA CD34                    	int	34h	
   669 000003AC 5B                      	pop	ebx
   670                                  
   671 000003AD 66BAFC0C                        mov     dx, PCI_DATA_PORT
   672 000003B1 88D8                            mov     al, bl
   673 000003B3 2403                            and     al, 3			; figure out which port to
   674 000003B5 00C2                            add     dl, al			; read to
   675                                  
   676                                  	; 19/03/2017
   677 000003B7 B404                    	mov	ah, 4  ; ind
   678 000003B9 F7C300000080            	test    ebx, PCI32
   679 000003BF 750C                            jnz     short _pregr0
   680 000003C1 D0EC                    	shr	ah, 1  ; ah = 2 ; inw
   681 000003C3 F7C300000040            	test    ebx, PCI16
   682 000003C9 7502                            jnz     short _pregr0
   683 000003CB 28E4                    	sub	ah, ah ; ah = 0 ; inb
   684                                  _pregr0:	
   685 000003CD CD34                    	int	34h
   686                                  
   687 000003CF F7C300000080            	test    ebx, PCI32
   688 000003D5 7404                            jz      short _pregr1
   689                                  
   690 000003D7 89C2                            mov     edx, eax		; return 32bits of data
   691 000003D9 EB0D                    	jmp	short _pregr2
   692                                  _pregr1:
   693 000003DB 6689C2                  	mov	dx, ax			; return 16bits of data
   694 000003DE F7C300000040                    test    ebx, PCI16
   695 000003E4 7502                            jnz     short _pregr2
   696 000003E6 88CE                            mov     dh, cl			; restore dh for 8 bit read
   697                                  _pregr2:
   698 000003E8 89D8                            mov     eax, ebx		; restore eax
   699 000003EA 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; clear out data size request
   700 000003EF 59                      	pop	ecx
   701 000003F0 5B                      	pop	ebx
   702 000003F1 C3                      	retn
   703                                  
   704                                  pciRegRead8:
   705 000003F2 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; set up 8 bit read size
   706 000003F7 EB96                            jmp     short pciRegRead	; call generic PCI access
   707                                  
   708                                  pciRegRead16:
   709 000003F9 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; set up 16 bit read size
   710 000003FE 0D00000040                      or      eax, PCI16		; call generic PCI access
   711 00000403 EB8A                            jmp     short pciRegRead
   712                                  
   713                                  pciRegRead32:
   714 00000405 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; set up 32 bit read size
   715 0000040A 0D00000080                      or      eax, PCI32		; call generic PCI access
   716 0000040F E97BFFFFFF                      jmp     pciRegRead
   717                                  
   718                                  
   719                                  ; 23/03/2017
   720                                  ; 19/03/2017
   721                                  ;===============================================================
   722                                  ; 8/16/32bit PCI writer
   723                                  ;
   724                                  ; Entry: EAX=PCI Bus/Device/fn/register number
   725                                  ;           BIT31 set if 32 bit access requested
   726                                  ;           BIT30 set if 16 bit access requested
   727                                  ;           otherwise defaults to 8bit read
   728                                  ;        DL/DX/EDX data to write depending on size
   729                                  ;
   730                                  ;
   731                                  ; note: this routine is meant to be called via pciRegWrite8, pciRegWrite16,
   732                                  ; 	or pciRegWrite32 as detailed below.
   733                                  ;
   734                                  ; Note2: don't attempt to write 32bits of data from a non dword aligned reg
   735                                  ;	 number.  Likewise, don't do 16bit writes from non word aligned reg #
   736                                  ;
   737                                  pciRegWrite:
   738 00000414 53                      	push	ebx
   739 00000415 51                      	push	ecx
   740 00000416 89C3                            mov     ebx, eax		; save eax, edx
   741 00000418 89D1                            mov     ecx, edx
   742 0000041A 25FFFFFF3F              	and     eax, NOT_PCI32_PCI16	; clear out data size request
   743 0000041F 0D00000080                      or      eax, BIT31		; make a PCI access request
   744 00000424 24FC                            and     al, ~3 ; NOT 3		; force index to be dword
   745                                  
   746 00000426 66BAF80C                        mov     dx, PCI_INDEX_PORT
   747                                          ;out	dx, eax			; write PCI selector
   748 0000042A 53                      	push	ebx
   749 0000042B 89C3                    	mov	ebx, eax ; Data dword		
   750 0000042D B405                    	mov	ah, 5	; outd (32 bit write)
   751 0000042F CD34                    	int	34h	
   752 00000431 8B1C24                  	mov	ebx, [esp]
   753                                  
   754 00000434 66BAFC0C                        mov     dx, PCI_DATA_PORT
   755 00000438 88D8                            mov     al, bl
   756 0000043A 2403                            and     al, 3			; figure out which port to
   757 0000043C 00C2                            add     dl, al			; write to
   758                                  
   759                                  	; 19/03/2017
   760 0000043E F7C3000000C0            	test    ebx, PCI32+PCI16
   761 00000444 7506                            jnz     short _pregw0
   762 00000446 B401                    	mov	ah, 1
   763 00000448 88C8                    	mov	al, cl 			; put data into al
   764                                  	;int	34h
   765 0000044A EB0C                    	jmp	short _pregw2
   766                                  _pregw0:
   767                                  	;mov	ah, 5  ; outd
   768 0000044C F7C300000080            	test    ebx, PCI32
   769 00000452 7502                            jnz     short _pregw1
   770 00000454 B403                    	mov	ah, 3
   771                                  _pregw1:
   772 00000456 89CB                    	mov	ebx, ecx		; put data into ebx 		
   773                                  _pregw2:
   774 00000458 CD34                    	int	34h
   775                                  	;
   776 0000045A 5B                      	pop	ebx
   777 0000045B 89D8                            mov     eax, ebx		; restore eax
   778 0000045D 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; clear out data size request
   779 00000462 89CA                            mov     edx, ecx		; restore dx
   780 00000464 59                      	pop	ecx
   781 00000465 5B                      	pop	ebx
   782 00000466 C3                      	retn
   783                                  
   784                                  pciRegWrite8:
   785 00000467 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; set up 8 bit write size
   786 0000046C EBA6                            jmp	short pciRegWrite	; call generic PCI access
   787                                  
   788                                  pciRegWrite16:
   789 0000046E 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; set up 16 bit write size
   790 00000473 0D00000040                      or      eax, PCI16		; call generic PCI access
   791 00000478 EB9A                            jmp	short pciRegWrite
   792                                  
   793                                  pciRegWrite32:
   794 0000047A 25FFFFFF3F                      and     eax, NOT_PCI32_PCI16	; set up 32 bit write size
   795 0000047F 0D00000080                      or      eax, PCI32		; call generic PCI access
   796 00000484 EB8E                            jmp	pciRegWrite
   797                                  
   798                                  ;===============================================================
   799                                  ; PCIFindDevice: scan through PCI space looking for a device+vendor ID
   800                                  ;
   801                                  ; Entry: EAX=Device+Vendor ID
   802                                  ;
   803                                  ;  Exit: EAX=PCI address if device found
   804                                  ;	 EDX=Device+Vendor ID
   805                                  ;        CY clear if found, set if not found. EAX invalid if CY set.
   806                                  ;
   807                                  ; [old stackless] Destroys: ebx, esi, edi, cl
   808                                  ;
   809                                  pciFindDevice:
   810                                  	;push	ecx
   811 00000486 50                      	push	eax
   812                                  	;push	esi
   813                                  	;push	edi
   814                                  
   815 00000487 89C6                            mov     esi, eax                ; save off vend+device ID
   816 00000489 BF00FFFF7F                      mov     edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0
   817                                  
   818                                  nextPCIdevice:
   819 0000048E 81C700010000                    add     edi, 100h
   820 00000494 81FF00F8FF80                    cmp     edi, 80FFF800h		; scanned all devices?
   821 0000049A F9                              stc
   822 0000049B 740C                            je      short PCIScanExit       ; not found
   823                                  
   824 0000049D 89F8                            mov     eax, edi                ; read PCI registers
   825 0000049F E861FFFFFF                      call    pciRegRead32
   826 000004A4 39F2                            cmp     edx, esi                ; found device?
   827 000004A6 75E6                            jne     short nextPCIdevice
   828 000004A8 F8                              clc
   829                                  
   830                                  PCIScanExit:
   831 000004A9 9C                      	pushf
   832 000004AA B8FFFFFF7F              	mov	eax, NOT_BIT31 	; 19/03/2017
   833 000004AF 21F8                    	and	eax, edi	; return only bus/dev/fn #
   834 000004B1 9D                      	popf
   835                                  
   836                                  	;pop	edi
   837                                  	;pop	esi
   838 000004B2 5A                      	pop	edx
   839                                  	;pop	ecx
   840 000004B3 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 000004B4 C605[540C0000]00        	mov	byte [err_num], 0
  1034                                  
  1035 000004BB B802020000              	mov     eax, 0202h
  1036 000004C0 BA02000000              	mov	edx, CODEC_MASTER_VOL_REG ; 02h ; Line Out
  1037 000004C5 E8AA010000              	call	codec_write
  1038                                  	;jc	cconfig_error
  1039                                  
  1040 000004CA C605[540C0000]01        	mov	byte [err_num], 1
  1041                                  
  1042 000004D1 B802020000              	mov     eax, 0202h
  1043 000004D6 BA18000000              	mov	edx, CODEC_PCM_OUT_REG ; 18h ; Wave Output (Stereo)
  1044 000004DB E894010000              	call	codec_write
  1045                                  	;jc	cconfig_error
  1046                                        
  1047 000004E0 C605[540C0000]02        	mov	byte [err_num], 2
  1048                                  
  1049                                   	;xor    eax, eax
  1050 000004E7 B802020000              	mov	eax, 0202h
  1051 000004EC BA04000000              	mov	edx, CODEC_AUX_VOL ; 04h ; CODEC_HP_VOL_REG ; HeadPhone
  1052 000004F1 E87E010000              	call	codec_write
  1053                                  	;jc	cconfig_error
  1054                                  
  1055 000004F6 C605[540C0000]03        	mov	byte [err_num], 3
  1056                                  
  1057 000004FD B808000000                      mov     eax, 08h
  1058 00000502 BA0C000000                      mov	edx, 0Ch  ; AC97_PHONE_VOL ; TAD Input (Mono)
  1059 00000507 E868010000              	call	codec_write
  1060                                  	;jc	short cconfig_error
  1061                                  
  1062 0000050C C605[540C0000]04        	mov	byte [err_num], 4
  1063                                  
  1064 00000513 B808080000                      mov     eax, 0808h
  1065 00000518 BA10000000                      mov	edx, CODEC_LINE_IN_VOL_REG ; 10h ; Line Input (Stereo)	
  1066 0000051D E852010000              	call	codec_write
  1067                                  	;jc	short cconfig_error
  1068                                  
  1069 00000522 C605[540C0000]05        	mov	byte [err_num], 5
  1070                                  
  1071 00000529 B808080000              	mov     eax, 0808h
  1072 0000052E BA12000000                      mov	edx, CODEC_CD_VOL_REG ; 12h ; CR Input (Stereo)
  1073 00000533 E83C010000              	call	codec_write
  1074                                  	;jc	short cconfig_error
  1075                                  
  1076 00000538 C605[540C0000]06        	mov	byte [err_num], 6
  1077                                  
  1078 0000053F B808080000              	mov     eax, 0808h
  1079 00000544 BA16000000                      mov	edx, CODEC_AUX_VOL_REG ; 16h ; Aux Input (Stereo)
  1080 00000549 E826010000              	call	codec_write
  1081                                  	;jc	short cconfig_error
  1082                                  
  1083 0000054E C605[540C0000]07        	mov	byte [err_num], 7
  1084                                  
  1085                                  	; Extended Audio Status (2Ah)
  1086 00000555 B82A000000              	mov	eax, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah 
  1087 0000055A E8DC000000              	call	codec_read
  1088 0000055F 25FDFF0000                      and     eax, 0FFFFh - 2 ; clear DRA (BIT1)
  1089                                          ;or     eax, 1		; set VRA (BIT0)
  1090 00000564 83C805                  	or	eax, 5  	; VRA (BIT0) & S/PDIF (BIT2) ; 14/11/2016
  1091 00000567 BA2A000000              	mov	edx, CODEC_EXT_AUDIO_CTRL_REG
  1092 0000056C E803010000              	call	codec_write
  1093                                  	;jc	short cconfig_error
  1094                                  
  1095 00000571 C605[540C0000]08        	mov	byte [err_num], 8
  1096                                  set_sample_rate:
  1097 00000578 0FB705[7F0C0000]                movzx	eax, word [sample_rate]
  1098 0000057F BA2C000000              	mov	edx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch ; PCM Front DAC Rate
  1099                                          ;call	codec_write
  1100                                          ;retn
  1101 00000584 E9EB000000              	jmp	codec_write
  1102                                  	
  1103                                  cconfig_error:
  1104 00000589 A0[540C0000]            	mov	al, [err_num]
  1105 0000058E C3                              retn
  1106                                  
  1107                                  reset_codec:
  1108                                  	; 23/03/2017
  1109                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1110 0000058F A1[550C0000]            	mov	eax, [bus_dev_fn]
  1111 00000594 B041                     	mov	al, VIA_ACLINK_CTRL
  1112 00000596 B2E0                           	mov	dl, VIA_ACLINK_CTRL_ENABLE + VIA_ACLINK_CTRL_RESET + VIA_ACLINK_CTRL_SYNC
  1113 00000598 E8CAFEFFFF              	call	pciRegWrite8
  1114                                  
  1115 0000059D E82F030000              	call	delay_100ms 	; wait 100 ms
  1116                                  _rc_cold:
  1117 000005A2 E80A000000                      call    cold_reset
  1118 000005A7 7303                            jnc     short _reset_codec_ok
  1119                                  
  1120 000005A9 31C0                            xor     eax, eax         ; timeout error
  1121 000005AB C3                              retn
  1122                                  
  1123                                  _reset_codec_ok:
  1124 000005AC 31C0                            xor     eax, eax
  1125                                          ;mov	al, VIA_ACLINK_C00_READY ; 1
  1126 000005AE FEC0                            inc	al
  1127 000005B0 C3                      	retn
  1128                                  
  1129                                  cold_reset:
  1130                                  	; 23/03/2017
  1131                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1132                                  	;mov	eax, [bus_dev_fn]
  1133                                  	;mov	al, VIA_ACLINK_CTRL
  1134 000005B1 30D2                    	xor	dl, dl ; 0
  1135 000005B3 E8AFFEFFFF              	call	pciRegWrite8
  1136                                  
  1137 000005B8 E814030000              	call	delay_100ms 	; wait 100 ms
  1138                                  
  1139                                  	;; ACLink on, deassert ACLink reset, VSR, SGD data out
  1140                                          ;; note - FM data out has trouble with non VRA codecs !!
  1141                                          
  1142                                  	;mov	eax, [bus_dev_fn]
  1143                                  	;mov	al, VIA_ACLINK_CTRL
  1144 000005BD B2CC                    	mov	dl, VIA_ACLINK_CTRL_INIT
  1145 000005BF E8A3FEFFFF              	call	pciRegWrite8
  1146                                  
  1147 000005C4 B910000000              	mov	ecx, 16	; total 2s
  1148                                  
  1149                                  _crst_wait:
  1150                                  	;mov	eax, [bus_dev_fn]
  1151 000005C9 B040                    	mov	al, VIA_ACLINK_STAT
  1152 000005CB E822FEFFFF              	call	pciRegRead8	
  1153                                  
  1154 000005D0 F6C201                          test    dl, VIA_ACLINK_C00_READY
  1155 000005D3 750B                            jnz     short _crst_ok
  1156                                  
  1157 000005D5 51                      	push	ecx
  1158 000005D6 E8F6020000              	call	delay_100ms
  1159 000005DB 59                      	pop	ecx
  1160                                  
  1161 000005DC 49                              dec     ecx
  1162 000005DD 75EA                            jnz     short _crst_wait
  1163                                  
  1164                                  _crst_fail:
  1165 000005DF F9                              stc
  1166                                  _crst_ok:
  1167 000005E0 C3                      	retn
  1168                                  
  1169                                  codec_io_w16: ;w32
  1170 000005E1 668B15[610C0000]                mov	dx, [ac97_io_base]
  1171 000005E8 6681C28000                      add     dx, VIA_REG_AC97
  1172                                  	;out	dx, eax
  1173                                  	; 05/03/2017
  1174 000005ED 53                      	push	ebx
  1175 000005EE 89C3                    	mov	ebx, eax
  1176 000005F0 B405                    	mov	ah, 5 ; outd
  1177 000005F2 CD34                    	int	34h
  1178 000005F4 5B                      	pop	ebx
  1179 000005F5 C3                              retn
  1180                                  
  1181                                  codec_io_r16: ;r32
  1182 000005F6 668B15[610C0000]                mov     dx, [ac97_io_base]
  1183 000005FD 6681C28000                      add     dx, VIA_REG_AC97
  1184                                          ;in	eax, dx
  1185                                  	; 05/03/2017
  1186 00000602 B404                    	mov	ah, 4 ; ind
  1187 00000604 CD34                    	int	34h
  1188 00000606 C3                              retn
  1189                                  
  1190                                  ctrl_io_w8:
  1191 00000607 660315[610C0000]                add     dx, [ac97_io_base]
  1192                                          ;out	dx, al
  1193                                  	; 05/03/2017
  1194 0000060E B401                    	mov	ah, 1 ; outb
  1195 00000610 CD34                    	int	34h
  1196 00000612 C3                              retn
  1197                                  
  1198                                  ctrl_io_r8:
  1199 00000613 660315[610C0000]                add     dx, [ac97_io_base]
  1200                                          ;in	al, dx
  1201                                  	; 05/03/2017
  1202 0000061A B400                    	mov	ah, 0 ; inb
  1203 0000061C CD34                    	int	34h
  1204 0000061E C3                              retn
  1205                                  
  1206                                  ctrl_io_w32:
  1207 0000061F 660315[610C0000]                add     dx, [ac97_io_base]
  1208                                          ;out	dx, eax
  1209                                  	; 05/03/2017
  1210 00000626 53                      	push	ebx
  1211 00000627 89C3                    	mov	ebx, eax
  1212 00000629 B405                    	mov	ah, 5 ; outd
  1213 0000062B CD34                    	int	34h
  1214 0000062D 5B                      	pop	ebx
  1215 0000062E C3                              retn
  1216                                  
  1217                                  ctrl_io_r32:
  1218 0000062F 660315[610C0000]                add	dx, [ac97_io_base]
  1219                                  	;in	eax, dx
  1220                                  	; 05/03/2017
  1221 00000636 B404                    	mov	ah, 4 ; ind
  1222 00000638 CD34                    	int	34h
  1223 0000063A C3                              retn
  1224                                  
  1225                                  codec_read:
  1226                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1227                                          ; Use only primary codec.
  1228                                          ; eax = register
  1229 0000063B C1E010                          shl     eax, VIA_REG_AC97_CMD_SHIFT
  1230 0000063E 0D00008002                      or      eax, VIA_REG_AC97_PRIMARY_VALID + VIA_REG_AC97_READ
  1231                                  
  1232 00000643 E899FFFFFF              	call    codec_io_w16
  1233                                  
  1234                                        	; codec_valid
  1235 00000648 E83E000000              	call	codec_check_ready
  1236 0000064D 7301                            jnc	short _cr_ok
  1237                                  
  1238 0000064F C3                      	retn
  1239                                  
  1240                                  _cr_ok:
  1241                                  	; wait 25 ms
  1242 00000650 E889020000              	call	delay1_4ms
  1243 00000655 E884020000              	call	delay1_4ms
  1244 0000065A E87F020000              	call	delay1_4ms
  1245 0000065F E87A020000              	call	delay1_4ms
  1246 00000664 E875020000              	call	delay1_4ms
  1247                                  
  1248 00000669 E888FFFFFF                      call    codec_io_r16
  1249 0000066E 25FFFF0000                      and     eax, 0FFFFh
  1250 00000673 C3                              retn
  1251                                  
  1252                                  codec_write:
  1253                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1254                                          ; Use only primary codec.
  1255                                          
  1256                                  	; eax = data (volume)
  1257                                  	; edx = register (mixer register)
  1258                                  	
  1259 00000674 C1E210                  	shl     edx, VIA_REG_AC97_CMD_SHIFT
  1260                                  
  1261 00000677 C1E000                          shl     eax, VIA_REG_AC97_DATA_SHIFT ; shl eax, 0
  1262 0000067A 09C2                            or      edx, eax
  1263                                  
  1264 0000067C B800000000                      mov     eax, VIA_REG_AC97_CODEC_ID_PRIMARY
  1265 00000681 C1E01E                          shl     eax, VIA_REG_AC97_CODEC_ID_SHIFT
  1266 00000684 09D0                            or      eax, edx
  1267                                  
  1268 00000686 E856FFFFFF                      call    codec_io_w16
  1269                                          ;mov    [codec.regs+esi], ax
  1270                                  
  1271                                          ;call	codec_check_ready
  1272                                         	;retn
  1273                                  	;jmp	short _codec_check_ready	
  1274                                  
  1275                                  codec_check_ready:
  1276                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1277                                  
  1278                                  _codec_check_ready:
  1279 0000068B B914000000              	mov	ecx, 20	; total 2s
  1280                                  _ccr_wait:
  1281 00000690 51                      	push	ecx
  1282                                  
  1283 00000691 E860FFFFFF                      call    codec_io_r16
  1284 00000696 A900000001                      test    eax, VIA_REG_AC97_BUSY
  1285 0000069B 740B                            jz      short _ccr_ok
  1286                                  
  1287 0000069D E82F020000              	call	delay_100ms
  1288                                  
  1289 000006A2 59                      	pop	ecx
  1290                                  
  1291 000006A3 49                      	dec     ecx
  1292 000006A4 75EA                            jnz     short _ccr_wait
  1293                                  
  1294 000006A6 F9                              stc
  1295 000006A7 C3                              retn
  1296                                  
  1297                                  _ccr_ok:
  1298 000006A8 59                      	pop	ecx
  1299 000006A9 25FFFF0000              	and     eax, 0FFFFh
  1300 000006AE C3                              retn
  1301                                  
  1302                                  channel_reset:
  1303                                  	; 23/03/2017
  1304                                  	; 14/11/2016 - Erdogan Tan
  1305                                  	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1306 000006AF BA01000000                      mov	edx, VIA_REG_OFFSET_CONTROL
  1307 000006B4 B849000000                      mov     eax, VIA_REG_CTRL_PAUSE + VIA_REG_CTRL_TERMINATE + VIA_REG_CTRL_RESET
  1308 000006B9 E849FFFFFF                      call    ctrl_io_w8
  1309                                  
  1310                                          ;mov	edx, VIA_REG_OFFSET_CONTROL
  1311                                          ;call   ctrl_io_r8
  1312                                  
  1313 000006BE B90C000000              	mov	ecx, 12 ; 50 ms	
  1314                                  _ch_rst_wait:
  1315 000006C3 E816020000              	call	delay1_4ms
  1316 000006C8 49                      	dec	ecx
  1317 000006C9 75F8                    	jnz	short _ch_rst_wait     
  1318                                  
  1319                                          ; disable interrupts
  1320 000006CB BA01000000                      mov	edx, VIA_REG_OFFSET_CONTROL
  1321 000006D0 31C0                            xor     eax, eax
  1322 000006D2 E830FFFFFF                      call    ctrl_io_w8
  1323                                  
  1324                                          ; clear interrupts
  1325 000006D7 BA00000000                      mov	edx, VIA_REG_OFFSET_STATUS
  1326 000006DC B803000000              	mov	eax, 3
  1327 000006E1 E821FFFFFF                      call	ctrl_io_w8
  1328                                  
  1329                                  	;mov	edx, VIA_REG_OFFSET_CURR_PTR
  1330                                  	;xor	eax, eax
  1331                                  	;call	ctrl_io_w32
  1332                                  
  1333 000006E6 C3                              retn
  1334                                  
  1335                                  loadFromFile:
  1336                                  	; 17/03/2017
  1337                                  	; edi = buffer address
  1338                                  	; edx = buffer size
  1339                                  	; 10/03/2017
  1340                                          ;push	eax
  1341                                          ;push	ecx
  1342                                          ;push	edx
  1343                                  	;push	ebx
  1344 000006E7 F605[520C0000]01                test    byte [flags], ENDOFFILE	; have we already read the
  1345 000006EE F9                              stc			; last of the file?
  1346 000006EF 7531                            jnz     short endLFF
  1347                                  	;clc
  1348                                  	; load file into memory
  1349                                  	sys 	_read, [FileHandle], edi
  1349                              <1> 
  1349                              <1> 
  1349                              <1> 
  1349                              <1> 
  1349                              <1>  %if %0 >= 2
  1349 000006F1 8B1D[700B0000]      <1>  mov ebx, %2
  1349                              <1>  %if %0 >= 3
  1349 000006F7 89F9                <1>  mov ecx, %3
  1349                              <1>  %if %0 = 4
  1349                              <1>  mov edx, %4
  1349                              <1>  %endif
  1349                              <1>  %endif
  1349                              <1>  %endif
  1349 000006F9 B803000000          <1>  mov eax, %1
  1349                              <1> 
  1349 000006FE CD40                <1>  int 40h
  1350 00000700 89D1                    	mov	ecx, edx
  1351 00000702 720A                    	jc	short padfill ; error !
  1352 00000704 21C0                    	and	eax, eax
  1353 00000706 7406                    	jz	short padfill
  1354 00000708 29C1                    	sub	ecx, eax
  1355 0000070A 7416                    	jz	short endLFF
  1356 0000070C 01C7                    	add	edi, eax  
  1357                                  padfill:
  1358 0000070E 803D[4D0C0000]10        	cmp 	byte [bps], 16
  1359 00000715 740C                    	je	short _7
  1360                                  	; Minimum Value = 0
  1361 00000717 30C0                            xor     al, al
  1362 00000719 F3AA                    	rep	stosb
  1363                                  _6:
  1364                                          ;clc			; don't exit with CY yet.
  1365 0000071B 800D[520C0000]01                or	byte [flags], ENDOFFILE	; end of file flag
  1366                                  endLFF:
  1367                                  	;pop	ebx
  1368                                  	;pop	edx
  1369                                          ;pop	ecx
  1370                                          ;pop	eax
  1371 00000722 C3                              retn
  1372                                  _7:
  1373                                  	; Minimum value = 8000h (-32768)
  1374 00000723 D1E9                    	shr	ecx, 1 
  1375 00000725 66B80080                	mov	ax, 8000h ; -32768
  1376 00000729 F366AB                  	rep	stosw
  1377 0000072C EBED                    	jmp	short _6
  1378                                  
  1379                                  ;=============================================================================
  1380                                  ;               VIA_WAV.ASM
  1381                                  ;=============================================================================
  1382                                  
  1383                                  ; DOS based .WAV player using AC'97 and codec interface.
  1384                                  ; ---------------------------------------------------------------
  1385                                  ; VIA VT8233 Modification & NASM version: Erdogan Tan (29/11/2016)
  1386                                  ; Last Update: 08/12/2016 (by Erdogan Tan)
  1387                                  
  1388                                  ; player internal variables and other equates.
  1389                                  BUFFERSIZE      equ     32768	; 32K half buffer size. ; 14/03/2017
  1390                                  ENDOFFILE       equ     BIT0	; flag for knowing end of file
  1391                                  
  1392                                  ;===========================================================================
  1393                                  ; entry: none.  File is already open and [filehandle] filled.
  1394                                  ; exit:  not until the song is finished or the user aborts.
  1395                                  ;
  1396                                  	; 17/03/2017
  1397                                  PlayWav:
  1398                                  	;cld
  1399                                  	; clear (half) buffer 2
  1400 0000072E BF[00000100]                   	mov     edi, DmaBuffer
  1401                                  	;add	edi, BUFFERSIZE
  1402 00000733 BA00800000              	mov	edx, BUFFERSIZE
  1403 00000738 01D7                    	add	edi, edx
  1404 0000073A 6629C0                  	sub	ax, ax
  1405 0000073D B900400000              	mov	ecx, (BUFFERSIZE/2)
  1406 00000742 F366AB                  	rep	stosw
  1407                                  	
  1408                                         ; load 32768 bytes into half buffer 1
  1409                                  
  1410 00000745 BF[00000100]            	mov     edi, DmaBuffer
  1411                                  	;mov	edx, BUFFERSIZE
  1412 0000074A E898FFFFFF              	call	loadFromFile
  1413                                  
  1414                                         ; load 32768 bytes into half buffer 2
  1415                                  
  1416                                  	;mov	edi, Dma Buffer
  1417                                  	;mov	edx, BUFFERSIZE
  1418                                  	;add	edi, edx
  1419                                  	;call	loadFromFile
  1420                                  
  1421                                  ; write last valid index to 31 to start with.
  1422                                  ; The Last Valid Index register tells the DMA engine when to stop playing.
  1423                                  ; 
  1424                                  ; As we progress through the song we change the last valid index to always be
  1425                                  ; something other than the index we're currently playing.  
  1426                                  ;
  1427                                          ;;mov   al, 1
  1428                                          ;mov	al, 31
  1429                                  	;call   setLastValidIndex
  1430                                  
  1431                                  ; create Buffer Descriptor List
  1432                                  ;
  1433                                  ; A buffer descriptor list is a list of pointers and control bits that the
  1434                                  ; DMA engine uses to know where to get the .wav data and how to play it.
  1435                                  ;
  1436                                  ; I set it up to use only 2 buffers of .wav data, and whenever 1 buffer is
  1437                                  ; playing, I refresh the other one with good data.
  1438                                  ;
  1439                                  ;
  1440                                  ; For the control bits, you can specify that the DMA engine fire an interrupt
  1441                                  ; after a buffer has been processed, but I poll the current index register
  1442                                  ; to know when it's safe to update the other buffer.
  1443                                  ;
  1444                                  ; I set the BUP bit, which tells the DMA engine to just play 0's (silence)
  1445                                  ; if it ever runs out of data to play.  Good for safety.
  1446                                  ;
  1447                                  	; 05/03/2017 (32 bit buffer addresses)
  1448                                  
  1449                                  	; 14/02/2017
  1450 0000074F BF[00100000]                    mov     edi, BdlBuffer		; get BDL address
  1451 00000754 66B91000                        mov     cx, 32 / 2		; make 32 entries in BDL
  1452                                  _0:
  1453                                  
  1454                                  ; set buffer descriptor 0 to start of data file in memory
  1455                                  
  1456 00000758 A1[980C0000]                    mov	eax, [DMA_phy_buff]	; Physical address of DMA buffer
  1457 0000075D AB                              stosd				; store dmabuffer1 address
  1458                                  
  1459 0000075E 89C2                    	mov	edx, eax ; 05/03/2017
  1460                                  
  1461                                  ;
  1462                                  ; set length to 32k samples.  1 sample is 16bits or 2bytes.
  1463                                  ; Set control (bits 31:16) to BUP, bits 15:0=number of samples.
  1464                                  ; 
  1465                                  
  1466                                  ; VIA VT8235.PDF: (Page 110) (Erdogan Tan, 29/11/2016)
  1467                                  	;
  1468                                  	; 	Audio SGD Table Format
  1469                                  	;	-------------------------------
  1470                                  	;	63   62    61-56    55-32  31-0
  1471                                  	;	--   --   --------  -----  ----
  1472                                  	;	EOL FLAG -reserved- Base   Base
  1473                                  	;		    	    Count  Address
  1474                                  	;		            [23:0] [31:0]
  1475                                  	;	EOL: End Of Link. 
  1476                                  	;	     1 indicates this block is the last of the link.
  1477                                  	;	     If the channel Interrupt on EOL bit is set, then
  1478                                  	;	     an interrupt is generated at the end of the transfer.
  1479                                  	;
  1480                                  	;	FLAG: Block Flag. If set, transfer pauses at the end of this
  1481                                  	;	      block. If the channel Interrupt on FLAG bit is set,
  1482                                  	;	      then an interrupt is generated at the end of this block.
  1483                                  
  1484                                  	FLAG	EQU BIT30
  1485                                  	EOL	EQU BIT31
  1486                                  
  1487                                  	; 08/12/2016 - Erdogan Tan
  1488 00000760 B800800000              	mov	eax, BUFFERSIZE
  1489 00000765 01C2                    	add	edx, eax ; 05/03/2017
  1490 00000767 0D00000040              	or	eax, FLAG
  1491                                  	;or	eax, EOL
  1492 0000076C AB                      	stosd
  1493                                  
  1494                                  ; 2nd buffer:
  1495                                  
  1496 0000076D 89D0                            mov	eax, edx ; Physical address of the 2nd half of DMA buffer	
  1497 0000076F AB                      	stosd		 ; store dmabuffer2 address
  1498                                  
  1499                                  ; set length to 64k (32k of two 16 bit samples)
  1500                                  ; Set control (bits 31:16) to BUP, bits 15:0=number of samples
  1501                                  ; 
  1502                                  	; 08/12/2016 - Erdogan Tan
  1503 00000770 B800800000              	mov	eax, BUFFERSIZE
  1504 00000775 0D00000080              	or	eax, EOL
  1505                                  	;or	eax, FLAG
  1506 0000077A AB                      	stosd
  1507                                  
  1508 0000077B E2DB                            loop    _0
  1509                                  
  1510                                  ;
  1511                                  ; tell the DMA engine where to find our list of Buffer Descriptors.
  1512                                  ; this 32bit value is a flat mode memory offset (ie no segment:offset)
  1513                                  ;
  1514                                  ; write buffer descriptor list address
  1515                                  ;
  1516 0000077D A1[940C0000]                    mov	eax, [BDL_phy_buff] ; Physical address of the BDL
  1517                                  	
  1518                                  	; 12/11/2016 - Erdogan Tan 
  1519                                  	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
  1520 00000782 BA04000000              	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_TABLE_PTR
  1521 00000787 E893FEFFFF                      call    ctrl_io_w32
  1522                                  
  1523 0000078C E8FAFEFFFF              	call	codec_check_ready
  1524                                  
  1525 00000791 66BA0200                  	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_L
  1526 00000795 B802000000                      mov     eax, 2   ;31
  1527 0000079A E868FEFFFF                      call    ctrl_io_w8
  1528                                  
  1529 0000079F E8E7FEFFFF              	call	codec_check_ready
  1530                                  
  1531 000007A4 66BA0300                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_R
  1532 000007A8 66B80200                        mov     ax, 2   ;31
  1533 000007AC E856FEFFFF                      call    ctrl_io_w8
  1534                                  
  1535 000007B1 E8D5FEFFFF              	call	codec_check_ready
  1536                                  ;
  1537                                  ;
  1538                                  ; All set.  Let's play some music.
  1539                                  ;
  1540                                  ;
  1541                                         	;mov    dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
  1542                                          ;mov    ax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
  1543                                          ;call   ctrl_io_w32
  1544                                  
  1545                                  	;call	codec_check_ready
  1546                                  
  1547                                  	; 08/12/2016
  1548                                  	; 07/10/2016
  1549                                          ;mov	al, 1
  1550 000007B6 B01F                            mov	al, 31
  1551 000007B8 E8CC000000              	call    setLastValidIndex
  1552                                  
  1553 000007BD C605[500C0000]01        	mov	byte [tLoop], 1 ; 30/11/2016
  1554                                  
  1555 000007C4 B823000000                      mov	eax, VIA_REG_CTRL_INT ; 14/03/2017
  1556 000007C9 0D80000000                     	or	eax, VIA_REG_CTRL_START
  1557                                          ;mov	ax, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START
  1558                                  	; 28/11/2016
  1559                                  	;mov	ax, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START + VIA_REG_CTRL_INT_FLAG
  1560 000007CE 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1561 000007D2 E830FEFFFF                      call    ctrl_io_w8
  1562                                  
  1563 000007D7 E8AFFEFFFF              	call	codec_check_ready
  1564                                  
  1565                                  ; while DMA engine is running, examine current index and wait until it hits 1
  1566                                  ; as soon as it's 1, we need to refresh the data in wavbuffer1 with another
  1567                                  ; 64k.  Likewise when it's playing buffer 2, refresh buffer 1 and repeat.
  1568                                     
  1569                                  	; 21/04/2017
  1570                                  	; 17/03/2017
  1571                                  	; 05/03/2017 (TRDOS 386)
  1572                                  	; 14/02/2017
  1573                                  	; 13/02/2017
  1574                                  	; 08/12/2016
  1575                                  	; 28/11/2016
  1576                                  p_loop:
  1577 000007DC B401                    	mov     ah, 1		; any key pressed?
  1578 000007DE CD32                    	int     32h		; no, Loop.
  1579 000007E0 740C                    	jz	short q_loop
  1580                                  
  1581 000007E2 B400                    	mov     ah, 0		; flush key buffer...
  1582 000007E4 CD32                    	int     32h
  1583                                  p_return:
  1584 000007E6 C605[500C0000]00        	mov	byte [tLoop], 0	; 13/02/2017
  1585 000007ED C3                      	retn
  1586                                  q_loop:
  1587 000007EE 6631C0                  	xor	ax, ax
  1588 000007F1 8605[510C0000]          	xchg	al, [tBuff] ; AL = [tBuff], [tBuff] = 0
  1589 000007F7 3C01                    	cmp	al, 1
  1590 000007F9 72E1                    	jb	short p_loop
  1591                                  	; 21/04/2017
  1592                                  	;ja	short r_loop
  1593 000007FB BF[00000100]            	mov     edi, DmaBuffer
  1594 00000800 BA00800000              	mov	edx, BUFFERSIZE ; 32768 bytes
  1595                                  	; 05/03/2017
  1596                                       	;mov	edi, DmaBuffer ; [tBuff]=1 (from tuneLoop)
  1597                                  	;jmp	short s_loop
  1598                                  	; 21/04/2017
  1599 00000805 7702                           	ja	short s_loop ; fill buff 1 (current: buff 2)
  1600                                  	; fill buffer 2 (current: buffer 1)
  1601                                  r_loop:
  1602                                  	; 05/03/2017
  1603                                          ;mov	edi, DmaBuffer ; [tBuff]=2 (from tuneLoop)
  1604                                  	;add	edi, BUFFERSIZE
  1605                                  	; 21/04/2017
  1606 00000807 01D7                    	add	edi, edx
  1607                                  s_loop:
  1608                                  	; 17/03/2017
  1609                                  	;mov	edx, BUFFERSIZE ; 32768 bytes
  1610 00000809 E8D9FEFFFF              	call    loadFromFile
  1611 0000080E 73DE                    	jnc	short q_loop
  1612                                  	;mov	byte [tLoop], 0
  1613 00000810 EB60                    	jmp	short _exit_
  1614                                  
  1615                                  tuneLoop:
  1616                                  	; 21/04/2017
  1617                                  	; 24/03/2017
  1618                                  	; 17/03/2017
  1619                                  	; 14/03/2017
  1620                                  	; 05/03/2017 (TRDOS 386)
  1621                                  	; 08/12/2016
  1622                                  	; 28/11/2016 - Erdogan Tan
  1623                                  	
  1624 00000812 803D[500C0000]01        	cmp	byte [tLoop], 1
  1625 00000819 7257                    	jb	short _exit_
  1626                                  
  1627 0000081B BE00800B00              	mov	esi, 0B8000h ; video display page address
  1628 00000820 B44E                    	mov	ah, 4Eh
  1629 00000822 B031                    	mov	al, '1'
  1630                                  
  1631 00000824 C605[510C0000]01        	mov	byte [tBuff], 1 ; Buffer 1
  1632                                  
  1633 0000082B F605[4E0C0000]02        	test	byte [irq_status], VIA_REG_STAT_EOL 
  1634 00000832 7508                    	jnz	short _tlp1 ; EOL
  1635                                  	
  1636                                  	; FLAG
  1637 00000834 FE05[510C0000]          	inc	byte [tBuff]	; Buffer 2
  1638 0000083A FEC0                    	inc	al
  1639                                  _tlp1: 
  1640 0000083C 668906                  	mov	[esi], ax ; show playing buffer (1, 2)
  1641                                  
  1642 0000083F A0[4E0C0000]                    mov     al, [irq_status]  ;; ack ;;
  1643 00000844 66BA0000                        mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
  1644 00000848 E8BAFDFFFF                      call    ctrl_io_w8
  1645                                  
  1646 0000084D E839FEFFFF              	call	codec_check_ready
  1647                                  
  1648 00000852 F605[4E0C0000]01        	test	byte [irq_status], VIA_REG_STAT_FLAG 
  1649 00000859 7416                    	jz	short _tlp2
  1650                                  
  1651 0000085B 66B82300                	mov	ax, VIA_REG_CTRL_INT
  1652 0000085F 660D8000                	or	ax, VIA_REG_CTRL_START
  1653 00000863 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1654 00000867 E89BFDFFFF              	call    ctrl_io_w8
  1655                                  	
  1656 0000086C E81AFEFFFF              	call	codec_check_ready
  1657                                  _tlp2:	
  1658 00000871 C3                      	retn
  1659                                  _exit_:
  1660                                          ; finished with song, stop everything
  1661 00000872 66B82300                	mov     ax, VIA_REG_CTRL_INT
  1662 00000876 6683C840                        or      ax, VIA_REG_CTRL_TERMINATE
  1663 0000087A 66BA0100                	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1664 0000087E E884FDFFFF                      call    ctrl_io_w8
  1665                                  
  1666 00000883 E827FEFFFF                      call	channel_reset
  1667                                  _return:
  1668 00000888 C3                      	retn
  1669                                  
  1670                                  ;input AL = index # to stop on
  1671                                  setLastValidIndex:
  1672                                  	; 05/03/2017 (TRDOS 386)
  1673                                  	; 19/11/2016
  1674                                  	; 14/11/2016 - Erdogan Tan (Ref: VIA VT8235.PDF, Page 110)
  1675                                  	; 12/11/2016 - Erdogan Tan
  1676                                  	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
  1677                                  	;push	edx
  1678 00000889 50                      	push	eax
  1679                                  	;push	ecx
  1680 0000088A 0FB705[7F0C0000]        	movzx	eax, word [sample_rate] ; Hertz
  1681 00000891 BA00001000              	mov	edx, 100000h ; 2^20 = 1048576
  1682 00000896 F7E2                    	mul	edx
  1683 00000898 B980BB0000              	mov	ecx, 48000	
  1684 0000089D F7F1                    	div	ecx
  1685                                  	;and	eax, 0FFFFFh
  1686                                  	;pop	ecx
  1687 0000089F 5A                      	pop	edx 
  1688 000008A0 C1E218                  	shl	edx, 24  ; STOP Index Setting: Bit 24 to 31
  1689 000008A3 09D0                    	or	eax, edx
  1690                                  	; 19/11/2016
  1691 000008A5 803D[4D0C0000]10        	cmp	byte [bps], 16
  1692 000008AC 7505                    	jne	short sLVI_1
  1693 000008AE 0D00002000              	or	eax, VIA8233_REG_TYPE_16BIT
  1694                                  sLVI_1:
  1695 000008B3 803D[4C0C0000]02        	cmp	byte [stmo], 2
  1696 000008BA 7505                    	jne	short sLVI_2
  1697 000008BC 0D00001000              	or	eax, VIA8233_REG_TYPE_STEREO
  1698                                  sLVI_2:
  1699 000008C1 BA08000000              	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
  1700 000008C6 E854FDFFFF                      call    ctrl_io_w32
  1701 000008CB E8BBFDFFFF              	call	codec_check_ready
  1702                                  	;pop	edx
  1703 000008D0 C3                      	retn
  1704                                  
  1705                                  delay_100ms:
  1706                                  	; wait 100 ms
  1707 000008D1 B919000000              	mov	ecx, 25
  1708                                  _delay_x_ms:
  1709 000008D6 E803000000              	call	delay1_4ms
  1710 000008DB E2F9                            loop	_delay_x_ms
  1711 000008DD C3                      	retn
  1712                                  
  1713                                  ;       delay1_4ms - Delay for 1/4 millisecond.
  1714                                  ;	    1mS = 1000us
  1715                                  ;       Entry:
  1716                                  ;         None
  1717                                  ;       Exit:
  1718                                  ;	  None
  1719                                  ;
  1720                                  ;       Modified:
  1721                                  ;         None
  1722                                  ;
  1723                                  PORTB		EQU	061h
  1724                                  REFRESH_STATUS	EQU	010h	; Refresh signal status
  1725                                  
  1726                                  	; 05/03/2017 (TRDOS 386)
  1727                                  delay1_4ms:
  1728 000008DE 50                              push    eax 
  1729 000008DF 51                              push    ecx
  1730                                          ;mov	cl, 16		; close enough.
  1731 000008E0 B10C                    	mov	cl, 12 ; + INT 34h delay	
  1732                                  
  1733                                  	;in	al, PORTB
  1734                                  	
  1735 000008E2 66BA6100                	mov	dx,  PORTB
  1736 000008E6 28E4                    	sub	ah, ah ; 0 ; inb
  1737 000008E8 CD34                    	int	34h
  1738                                  	
  1739 000008EA 2410                    	and	al, REFRESH_STATUS
  1740 000008EC 88C5                    	mov	ch, al		; Start toggle state
  1741 000008EE 08C9                    	or	cl, cl
  1742 000008F0 7402                    	jz	short _d4ms1
  1743 000008F2 FEC1                    	inc	cl		; Throwaway first toggle
  1744                                  _d4ms1:	
  1745                                  	;in	al, PORTB	; Read system control port
  1746                                  	
  1747                                  	;mov	ah, 0 ; inb
  1748                                  	;mov	dx, PORTB
  1749 000008F4 CD34                    	int	34h
  1750                                  	
  1751 000008F6 2410                    	and	al, REFRESH_STATUS ; Refresh toggles 15.085 microseconds
  1752 000008F8 38C5                    	cmp	ch, al
  1753 000008FA 74F8                    	je	short _d4ms1	; Wait for state change
  1754                                  
  1755 000008FC 88C5                    	mov	ch, al		; Update with new state
  1756 000008FE FEC9                    	dec	cl
  1757 00000900 75F2                    	jnz	short _d4ms1
  1758                                  
  1759 00000902 59                              pop     ecx
  1760 00000903 58                              pop     eax
  1761 00000904 C3                              retn
  1762                                  
  1763                                  	; 05/03/2017 (TRDOS 386)
  1764                                  	; 13/11/2016 - Erdogan Tan
  1765                                  write_ac97_dev_info:
  1766                                  	; BUS/DEV/FN
  1767                                  	;	00000000BBBBBBBBDDDDDFFF00000000
  1768                                  	; DEV/VENDOR
  1769                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
  1770                                  
  1771 00000905 8B35[590C0000]          	mov	esi, [dev_vendor]
  1772 0000090B 6689F0                  	mov	ax, si
  1773 0000090E 0FB6D8                  	movzx	ebx, al
  1774 00000911 88DA                    	mov	dl, bl
  1775 00000913 80E30F                  	and	bl, 0Fh
  1776 00000916 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1777 0000091C A2[B70B0000]            	mov	[msgVendorId+3], al
  1778 00000921 88D3                    	mov	bl, dl
  1779 00000923 C0EB04                  	shr	bl, 4
  1780 00000926 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1781 0000092C A2[B60B0000]            	mov	[msgVendorId+2], al
  1782 00000931 88E3                    	mov	bl, ah
  1783 00000933 88DA                    	mov	dl, bl
  1784 00000935 80E30F                  	and	bl, 0Fh
  1785 00000938 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1786 0000093E A2[B50B0000]            	mov	[msgVendorId+1], al
  1787 00000943 88D3                    	mov	bl, dl
  1788 00000945 C0EB04                  	shr	bl, 4
  1789 00000948 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1790 0000094E A2[B40B0000]            	mov	[msgVendorId], al
  1791 00000953 C1EE10                  	shr	esi, 16
  1792 00000956 6689F0                  	mov	ax, si
  1793 00000959 88C3                    	mov	bl, al
  1794 0000095B 88DA                    	mov	dl, bl
  1795 0000095D 80E30F                  	and	bl, 0Fh
  1796 00000960 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1797 00000966 A2[C80B0000]            	mov	[msgDevId+3], al
  1798 0000096B 88D3                    	mov	bl, dl
  1799 0000096D C0EB04                  	shr	bl, 4
  1800 00000970 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1801 00000976 A2[C70B0000]            	mov	[msgDevId+2], al
  1802 0000097B 88E3                    	mov	bl, ah
  1803 0000097D 88DA                    	mov	dl, bl
  1804 0000097F 80E30F                  	and	bl, 0Fh
  1805 00000982 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1806 00000988 A2[C60B0000]            	mov	[msgDevId+1], al
  1807 0000098D 88D3                    	mov	bl, dl
  1808 0000098F C0EB04                  	shr	bl, 4
  1809 00000992 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1810 00000998 A2[C50B0000]            	mov	[msgDevId], al
  1811                                  
  1812 0000099D 8B35[550C0000]          	mov	esi, [bus_dev_fn]
  1813 000009A3 C1EE08                  	shr	esi, 8
  1814 000009A6 6689F0                  	mov	ax, si
  1815 000009A9 88C3                    	mov	bl, al
  1816 000009AB 88DA                    	mov	dl, bl
  1817 000009AD 80E307                  	and	bl, 7 ; bit 0,1,2
  1818 000009B0 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1819 000009B6 A2[EC0B0000]            	mov	[msgFncNo+1], al
  1820 000009BB 88D3                    	mov	bl, dl
  1821 000009BD C0EB03                  	shr	bl, 3
  1822 000009C0 88DA                    	mov	dl, bl
  1823 000009C2 80E30F                  	and	bl, 0Fh
  1824 000009C5 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1825 000009CB A2[DE0B0000]            	mov	[msgDevNo+1], al
  1826 000009D0 88D3                    	mov	bl, dl
  1827 000009D2 C0EB04                  	shr	bl, 4
  1828 000009D5 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1829 000009DB A2[DD0B0000]            	mov	[msgDevNo], al
  1830 000009E0 88E3                    	mov	bl, ah
  1831 000009E2 88DA                    	mov	dl, bl
  1832 000009E4 80E30F                  	and	bl, 0Fh
  1833 000009E7 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1834 000009ED A2[D20B0000]            	mov	[msgBusNo+1], al
  1835 000009F2 88D3                    	mov	bl, dl
  1836 000009F4 C0EB04                  	shr	bl, 4
  1837 000009F7 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1838 000009FD A2[D10B0000]            	mov	[msgBusNo], al
  1839                                  
  1840 00000A02 66A1[610C0000]          	mov	ax, [ac97_io_base]
  1841 00000A08 88C3                    	mov	bl, al
  1842 00000A0A 88DA                    	mov	dl, bl
  1843 00000A0C 80E30F                  	and	bl, 0Fh
  1844 00000A0F 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1845 00000A15 A2[050C0000]            	mov	[msgIOBaseAddr+3], al
  1846 00000A1A 88D3                    	mov	bl, dl
  1847 00000A1C C0EB04                  	shr	bl, 4
  1848 00000A1F 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1849 00000A25 A2[040C0000]            	mov	[msgIOBaseAddr+2], al
  1850 00000A2A 88E3                    	mov	bl, ah
  1851 00000A2C 88DA                    	mov	dl, bl
  1852 00000A2E 80E30F                  	and	bl, 0Fh
  1853 00000A31 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1854 00000A37 A2[030C0000]            	mov	[msgIOBaseAddr+1], al
  1855 00000A3C 88D3                    	mov	bl, dl
  1856 00000A3E C0EB04                  	shr	bl, 4
  1857 00000A41 8A83[740B0000]          	mov	al, [ebx+hex_chars]
  1858 00000A47 A2[020C0000]            	mov	[msgIOBaseAddr], al
  1859                                  
  1860                                  	; 24/11/2016
  1861 00000A4C 30E4                    	xor	ah, ah
  1862 00000A4E A0[530C0000]            	mov	al, [ac97_int_ln_reg]
  1863 00000A53 B10A                    	mov	cl, 10
  1864 00000A55 F6F1                    	div	cl
  1865 00000A57 660105[0D0C0000]        	add	[msgIRQ], ax
  1866 00000A5E 20C0                    	and	al, al
  1867 00000A60 750D                    	jnz	short _pmi
  1868 00000A62 A0[0E0C0000]            	mov	al, [msgIRQ+1]
  1869 00000A67 B420                    	mov	ah, ' '
  1870 00000A69 66A3[0D0C0000]          	mov	[msgIRQ], ax
  1871                                  _pmi:
  1872                                  	; EBX = Message address
  1873                                  	; ECX = Max. message length (or stop on ZERO character)
  1874                                  	;	(1 to 255)
  1875                                  	; DL  = Message color (07h = light gray, 0Fh = white) 
  1876                                       	sys 	_msg, msgAC97Info, 255, 07h
  1876                              <1> 
  1876                              <1> 
  1876                              <1> 
  1876                              <1> 
  1876                              <1>  %if %0 >= 2
  1876 00000A6F BB[850B0000]        <1>  mov ebx, %2
  1876                              <1>  %if %0 >= 3
  1876 00000A74 B9FF000000          <1>  mov ecx, %3
  1876                              <1>  %if %0 = 4
  1876 00000A79 BA07000000          <1>  mov edx, %4
  1876                              <1>  %endif
  1876                              <1>  %endif
  1876                              <1>  %endif
  1876 00000A7E B823000000          <1>  mov eax, %1
  1876                              <1> 
  1876 00000A83 CD40                <1>  int 40h
  1877 00000A85 C3                              retn
  1878                                  
  1879                                  ;=============================================================================
  1880                                  ;               preinitialized data
  1881                                  ;=============================================================================
  1882                                  
  1883                                  noDevMsg:
  1884 00000A86 4572726F723A20556E-     	db "Error: Unable to find VIA VT8233 based audio device!",CR,LF,0
  1884 00000A8F 61626C6520746F2066-
  1884 00000A98 696E64205649412056-
  1884 00000AA1 543832333320626173-
  1884 00000AAA 656420617564696F20-
  1884 00000AB3 646576696365210D0A-
  1884 00000ABC 00                 
  1885                                  
  1886                                  CodecErrMsg:
  1887 00000ABD 436F64656320457272-     	db	"Codec Error #"
  1887 00000AC6 6F722023           
  1888 00000ACA 3020210D0A00            ErrNo:	db 	"0 !", CR,LF,0
  1889                                  
  1890                                  msg_usage:
  1891 00000AD0 75736167653A207761-     	db	'usage: wavplay filename.wav',10,13,0
  1891 00000AD9 76706C61792066696C-
  1891 00000AE2 656E616D652E776176-
  1891 00000AEB 0A0D00             
  1892                                  Credits:
  1893 00000AEE 54696E792057415620-     	db	'Tiny WAV Player for TRDOS 386 by Erdogan Tan. '
  1893 00000AF7 506C6179657220666F-
  1893 00000B00 72205452444F532033-
  1893 00000B09 383620627920457264-
  1893 00000B12 6F67616E2054616E2E-
  1893 00000B1B 20                 
  1894 00000B1C 417072696C20323031-     	db	'April 2017.',10,13,0
  1894 00000B25 372E0A0D00         
  1895 00000B2A 32312F30342F323031-     	db	'21/04/2017', 10,13,0
  1895 00000B33 370A0D00           
  1896                                  noFileErrMsg:
  1897 00000B37 4572726F723A206669-     	db	'Error: file not found.',10,13,0
  1897 00000B40 6C65206E6F7420666F-
  1897 00000B49 756E642E0A0D00     
  1898                                  
  1899                                  trdos386_err_msg:
  1900 00000B50 5452444F5320333836-     	db	'TRDOS 386 System call error !',10,13,0
  1900 00000B59 2053797374656D2063-
  1900 00000B62 616C6C206572726F72-
  1900 00000B6B 20210A0D00         
  1901                                  
  1902                                  FileHandle:	
  1903 00000B70 FFFFFFFF                	dd	-1
  1904                                  
  1905                                  ; 13/11/2016
  1906 00000B74 303132333435363738-     hex_chars:	db "0123456789ABCDEF", 0
  1906 00000B7D 3941424344454600   
  1907 00000B85 414339372041756469-     msgAC97Info:	db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah 
  1907 00000B8E 6F20436F6E74726F6C-
  1907 00000B97 6C6572202620436F64-
  1907 00000BA0 656320496E666F0D0A 
  1908 00000BA9 56656E646F72204944-     		db "Vendor ID: "
  1908 00000BB2 3A20               
  1909 00000BB4 303030306820446576-     msgVendorId:	db "0000h Device ID: "
  1909 00000BBD 6963652049443A20   
  1910 00000BC5 30303030680D0A          msgDevId:	db "0000h", 0Dh, 0Ah
  1911 00000BCC 4275733A20              		db "Bus: "
  1912 00000BD1 303068204465766963-     msgBusNo:	db "00h Device: "
  1912 00000BDA 653A20             
  1913 00000BDD 3030682046756E6374-     msgDevNo:	db "00h Function: "
  1913 00000BE6 696F6E3A20         
  1914 00000BEB 303068                  msgFncNo:	db "00h"
  1915 00000BEE 0D0A                    		db 0Dh, 0Ah
  1916 00000BF0 492F4F204261736520-     		db "I/O Base Address: "
  1916 00000BF9 416464726573733A20 
  1917 00000C02 303030306820495251-     msgIOBaseAddr:	db "0000h IRQ: "
  1917 00000C0B 3A20               
  1918 00000C0D 3030                    msgIRQ:		dw 3030h
  1919 00000C0F 0D0A00                  		db 0Dh, 0Ah, 0
  1920 00000C12 53616D706C65205261-     msgSampleRate:	db "Sample Rate: "
  1920 00000C1B 74653A20           
  1921 00000C1F 303030303020487A20-     msgHertz:	db "00000 Hz ", 0
  1921 00000C28 00                 
  1922 00000C29 3820626974732000        msg8Bits:	db "8 bits ", 0
  1923 00000C31 4D6F6E6F0D0A00          msgMono:	db "Mono", 0Dh, 0Ah, 0
  1924 00000C38 313620626974732024      msg16Bits:	db "16 bits ", "$" 
  1925 00000C41 53746572656F0D0A00      msgStereo:	db "Stereo", 0Dh, 0Ah, 0
  1926                                  
  1927                                  ;; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
  1928                                  ;codec_id:	   dd 0
  1929                                  ;codec_chip_id:	   dd 0
  1930                                  ;codec_vendor_ids: dw 0
  1931                                  ;codec_chip_ids:   dw 0
  1932                                  
  1933                                  ;dword_str:	dd 30303030h, 30303030h
  1934                                  ;	 	db 'h', 0Dh, 0Ah, 0
  1935                                  
  1936                                  ;=============================================================================
  1937                                  ;        	uninitialized data
  1938                                  ;=============================================================================
  1939                                  
  1940                                  bss_start:
  1941                                  
  1942                                  ABSOLUTE bss_start
  1943                                  
  1944 00000C4A <res 00000002>          alignb 4
  1945                                  
  1946 00000C4C <res 00000001>          stmo	resb	1 ; stereo or mono  
  1947 00000C4D <res 00000001>          bps	resb	1 ; bits per sample (16)
  1948                                  
  1949 00000C4E <res 00000001>          irq_status:	resb 	1
  1950                                  
  1951 00000C4F <res 00000001>          uLVI:	resb	1 
  1952 00000C50 <res 00000001>          tLoop:	resb 	1
  1953 00000C51 <res 00000001>          tBuff:	resb	1
  1954 00000C52 <res 00000001>          flags:	resb	1
  1955                                  
  1956                                  ; 12/11/2016 - Erdogan Tan
  1957                                  
  1958 00000C53 <res 00000001>          ac97_int_ln_reg: resb 1 
  1959 00000C54 <res 00000001>          err_num:	resb 1
  1960                                  ;s_r_b:		resb 1 ; 06/03/2017	
  1961                                  	
  1962 00000C55 <res 00000004>          bus_dev_fn:	resd 1
  1963 00000C59 <res 00000004>          dev_vendor:	resd 1
  1964 00000C5D <res 00000004>          stats_cmd:	resd 1
  1965 00000C61 <res 00000002>          ac97_io_base:	resw 1
  1966                                  
  1967 00000C63 <res 0000001C>          smpRBuff:	resw 14 
  1968                                  
  1969                                  sample_rate:
  1970 00000C7F <res 00000002>          		resw 1
  1971                                  
  1972                                  wav_file_name:
  1973 00000C81 <res 00000010>          		resb 16
  1974                                  
  1975 00000C91 <res 00000003>          alignb 4
  1976                                  
  1977                                  ; 17/03/2017
  1978 00000C94 <res 00000004>          BDL_phy_buff:	resd 1
  1979 00000C98 <res 00000004>          DMA_phy_buff:	resd 1
  1980                                  
  1981 00000C9C <res 00000364>          alignb 4096
  1982                                  
  1983 00001000 <res 00001000>          BdlBuffer:	resb 4096 ; BDL_SIZE (round up to 1 page)
  1984                                  
  1985 00002000 <res 0000E000>          alignb 65536
  1986 00010000 <res 00010000>          DmaBuffer:	resb 65536 ; 2 * 32K half buffer (BUFFERSIZE)
  1987                                  EOF:
