     1                                  ; ****************************************************************************
     2                                  ; PLAYER.ASM - VIA VT8233 .wav player for DOS.			    PLAYER.COM
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 18/02/2017
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; Beginning: 07/11/2016
     7                                  ; ----------------------------------------------------------------------------
     8                                  ; Assembler: NASM version 2.11 (29/11/2016)
     9                                  ; ----------------------------------------------------------------------------
    10                                  ; Derived from '.wav file player for DOS' Jeff Leyda, Sep 02, 2002 
    11                                  ; ****************************************************************************
    12                                  ; Erdogan Tan (07/11/2016)
    13                                  
    14                                  [BITS 16]
    15                                  
    16                                  [ORG 100h] 
    17                                  
    18                                          %include 'constant.inc'
     1                              <1> ;constants of stuff that seem hard to remember at times.
     2                              <1> 
     3                              <1> TRUE  EQU 1
     4                              <1> FALSE EQU 0
     5                              <1> 
     6                              <1> ENABLED  EQU 1
     7                              <1> DISABLED EQU 0
     8                              <1> 
     9                              <1> BIT0  EQU 1
    10                              <1> BIT1  EQU 2
    11                              <1> BIT2  EQU 4
    12                              <1> BIT3  EQU 8
    13                              <1> BIT4  EQU 10h
    14                              <1> BIT5  EQU 20h
    15                              <1> BIT6  EQU 40h
    16                              <1> BIT7  EQU 80h
    17                              <1> BIT8  EQU 100h
    18                              <1> BIT9  EQU 200h
    19                              <1> BIT10 EQU 400h
    20                              <1> BIT11 EQU 800h
    21                              <1> BIT12 EQU 1000h
    22                              <1> BIT13 EQU 2000h
    23                              <1> BIT14 EQU 4000h
    24                              <1> BIT15 EQU 8000h
    25                              <1> BIT16 EQU 10000h
    26                              <1> BIT17 EQU 20000h
    27                              <1> BIT18 EQU 40000h
    28                              <1> BIT19 EQU 80000h
    29                              <1> BIT20 EQU 100000h
    30                              <1> BIT21 EQU 200000h
    31                              <1> BIT22 EQU 400000h
    32                              <1> BIT23 EQU 800000h
    33                              <1> BIT24 EQU 1000000h
    34                              <1> BIT25 EQU 2000000h
    35                              <1> BIT26 EQU 4000000h
    36                              <1> BIT27 EQU 8000000h
    37                              <1> BIT28 EQU 10000000h
    38                              <1> BIT29 EQU 20000000h
    39                              <1> BIT30 EQU 40000000h
    40                              <1> BIT31 EQU 80000000h
    41                              <1> 
    42                              <1> ;special characters
    43                              <1> NUL     EQU 0
    44                              <1> NULL    EQU 0
    45                              <1> BELL    EQU 07
    46                              <1> BS      EQU 08
    47                              <1> TAB     EQU 09
    48                              <1> LF      EQU 10
    49                              <1> CR      EQU 13
    50                              <1> ESCAPE  EQU 27           ;ESC is a reserved word....
    51                              <1> 
    52                              <1> 
    53                              <1> ;file stuff
    54                              <1> READONLY  EQU   BIT0
    55                              <1> HIDDEN    EQU   BIT1
    56                              <1> SYSTEM    EQU   BIT2
    57                              <1> VOLUME    EQU   BIT3         ;ignored for file access
    58                              <1> DIRECTORY EQU   BIT4         ;must be 0 for file access
    59                              <1> ARCHIVE   EQU   BIT5
    60                              <1> SHAREABLE EQU   BIT7         ;for novell networks
    61                              <1> OPEN	EQU	2		; open existing file
    62                              <1> CREATE	EQU	1		; create new file
    63                              <1> 
    64                              <1> 
    65                              <1> ; PCI equates
    66                              <1> ; PCI function address (PFA)
    67                              <1> ; bit 31 = 1
    68                              <1> ; bit 23:16 = bus number     (0-255)
    69                              <1> ; bit 15:11 = device number  (0-31)
    70                              <1> ; bit 10:8 = function number (0-7)
    71                              <1> ; bit 7:0 = register number  (0-255)
    72                              <1> 
    73                              <1> IO_ADDR_MASK    EQU     0FFFEh          ; mask off bit 0 for reading BARs
    74                              <1> PCI_INDEX_PORT  EQU     0CF8h
    75                              <1> PCI_DATA_PORT   EQU     0CFCh
    76                              <1> PCI32           EQU     BIT31           ; bitflag to signal 32bit access
    77                              <1> PCI16           EQU     BIT30           ; bitflag for 16bit access
    78                              <1> 
    79                              <1> PCI_FN0         EQU     0 << 8
    80                              <1> PCI_FN1         EQU     1 << 8
    81                              <1> PCI_FN2         EQU     2 << 8
    82                              <1> PCI_FN3         EQU     3 << 8
    83                              <1> PCI_FN4         EQU     4 << 8
    84                              <1> PCI_FN5         EQU     5 << 8
    85                              <1> PCI_FN6         EQU     6 << 8
    86                              <1> PCI_FN7         EQU     7 << 8
    87                              <1> 
    88                              <1> PCI_CMD_REG		EQU	04h		; reg 04, command reg
    89                              <1>  IO_ENA			EQU	BIT0		; i/o decode enable
    90                              <1>  MEM_ENA		EQU	BIT1		; memory decode enable
    91                              <1>  BM_ENA                 EQU     BIT2		; bus master enable
    19                                  	%include 'codec.inc' ; 28/11/2016
     1                              <1> ;Codec registers.
     2                              <1> ;
     3                              <1> ;Not all codecs are created equal. Refer to the spec for your specific codec.
     4                              <1> ;
     5                              <1> ;All registers are 16bits wide.  Access to codec registers over the AC97 link
     6                              <1> ;is defined by the OEM.  
     7                              <1> ;
     8                              <1> ;Secondary codec's are accessed by ORing in BIT7 of all register accesses.
     9                              <1> ;
    10                              <1> 
    11                              <1> ; each codec/mixer register is 16bits
    12                              <1> 
    13                              <1> CODEC_RESET_REG                 equ     00      ; reset codec
    14                              <1> CODEC_MASTER_VOL_REG            equ     02      ; master volume
    15                              <1> CODEC_HP_VOL_REG                equ     04      ; headphone volume
    16                              <1> CODEC_MASTER_MONO_VOL_REG       equ     06      ; master mono volume
    17                              <1> CODEC_MASTER_TONE_REG           equ     08      ; master tone (R+L)
    18                              <1> CODEC_PCBEEP_VOL_REG            equ     0ah     ; PC beep volume
    19                              <1> CODEC_PHONE_VOL_REG             equ     0bh     ; phone volume
    20                              <1> CODEC_MIC_VOL_REG               equ     0eh     ; MIC volume
    21                              <1> CODEC_LINE_IN_VOL_REG           equ     10h     ; line input volume
    22                              <1> CODEC_CD_VOL_REG                equ     12h     ; CD volume
    23                              <1> CODEC_VID_VOL_REG               equ     14h     ; video volume
    24                              <1> CODEC_AUX_VOL_REG               equ     16h     ; aux volume
    25                              <1> CODEC_PCM_OUT_REG               equ     18h     ; PCM output volume
    26                              <1> CODEC_RECORD_SELECT_REG         equ     1ah     ; record select input
    27                              <1> CODEC_RECORD_VOL_REG            equ     1ch     ; record volume
    28                              <1> CODEC_RECORD_MIC_VOL_REG        equ     1eh     ; record mic volume
    29                              <1> CODEC_GP_REG                    equ     20h     ; general purpose
    30                              <1> CODEC_3D_CONTROL_REG            equ     22h     ; 3D control
    31                              <1> ; 24h is reserved
    32                              <1> CODEC_POWER_CTRL_REG            equ     26h     ; powerdown control
    33                              <1> CODEC_EXT_AUDIO_REG             equ     28h     ; extended audio
    34                              <1> CODEC_EXT_AUDIO_CTRL_REG        equ     2ah     ; extended audio control
    35                              <1> CODEC_PCM_FRONT_DACRATE_REG     equ     2ch     ; PCM out sample rate
    36                              <1> CODEC_PCM_SURND_DACRATE_REG     equ     2eh     ; surround sound sample rate
    37                              <1> CODEC_PCM_LFE_DACRATE_REG       equ     30h     ; LFE sample rate
    38                              <1> CODEC_LR_ADCRATE_REG            equ     32h     ; PCM in sample rate
    39                              <1> CODEC_MIC_ADCRATE_REG           equ     34h     ; mic in sample rate
    40                              <1> 
    41                              <1> ; registers 36-7a are reserved on the ICH
    42                              <1> 
    43                              <1> CODEC_VENDORID1_REG             equ     7ch     ; codec vendor ID 1
    44                              <1> CODEC_VENDORID2_REG             equ     7eh     ; codec vendor ID 2
    45                              <1> 
    46                              <1> ; Mixer registers 0 through 51h reside in the ICH and are not forwarded over
    47                              <1> ; the AC97 link to the codec, which I think is a little weird.  Looks like
    48                              <1> ; the ICH makes it so you don't need a fully functional codec to play audio?
    49                              <1> ;
    50                              <1> ; whenever 2 codecs are present in the system, use BIT7 to access the 2nd
    51                              <1> ; set of registers, ie 80h-feh
    52                              <1> 
    53                              <1> PRIMARY_CODEC                   equ     0       ; 0-7F for primary codec
    54                              <1> SECONDARY_CODEC                 equ     BIT7    ; 80-8f registers for 2ndary
    55                              <1> 
    56                              <1> SAMPLE_RATE_441khz	equ     44100   ; 44.1Khz (cd quality) rate
    57                              <1> 
    58                              <1> ; each buffer descriptor BAR holds a pointer which has entries to the buffer
    59                              <1> ; contents of the .WAV file we're going to play.  Each entry is 8 bytes long
    60                              <1> ; (more on that later) and can contain 32 entries total, so each BAR is
    61                              <1> ; 256 bytes in length, thus:
    62                              <1> 
    63                              <1> BDL_SIZE                equ     32*8    ; Buffer Descriptor List size
    64                              <1> INDEX_MASK              equ     31      ; indexes must be 0-31
    65                              <1> 
    66                              <1> ;
    67                              <1> ; Buffer Descriptors List
    68                              <1> ; As stated earlier, each buffer descriptor list is a set of (up to) 32 
    69                              <1> ; descriptors, each 8 bytes in length.  Bytes 0-3 of a descriptor entry point
    70                              <1> ; to a chunk of memory to either play from or record to.  Bytes 4-7 of an
    71                              <1> ; entry describe various control things detailed below.
    72                              <1> ; 
    73                              <1> ; Buffer pointers must always be aligned on a Dword boundry.
    74                              <1> ;
    75                              <1> ;
    76                              <1> 
    77                              <1> IOC                     equ     BIT31   ; Fire an interrupt whenever this
    78                              <1>                                         ; buffer is complete.
    79                              <1> 
    80                              <1> BUP                     equ     BIT30   ; Buffer Underrun Policy.
    81                              <1>                                         ; if this buffer is the last buffer
    82                              <1>                                         ; in a playback, fill the remaining
    83                              <1>                                         ; samples with 0 (silence) or not.
    84                              <1>                                         ; It's a good idea to set this to 1
    85                              <1>                                         ; for the last buffer in playback,
    86                              <1>                                         ; otherwise you're likely to get a lot
    87                              <1>                                         ; of noise at the end of the sound.
    88                              <1> 
    89                              <1> ;
    90                              <1> ; Bits 15:0 contain the length of the buffer, in number of samples, which
    91                              <1> ; are 16 bits each, coupled in left and right pairs, or 32bits each.
    92                              <1> ; Luckily for us, that's the same format as .wav files.
    93                              <1> ;
    94                              <1> ; A value of FFFF is 65536 samples.  Running at 44.1Khz, that's just about
    95                              <1> ; 1.5 seconds of sample time.  FFFF * 32bits is 1FFFFh bytes or 128k of data.
    96                              <1> ;
    97                              <1> ; A value of 0 in these bits means play no samples.
    98                              <1> ;
    99                              <1> 
   100                              <1> ;VIA VT8233 (VT8235) AC97 Codec equates 
   101                              <1> ;(edited by Erdogan Tan, 7/11/2016)
   102                              <1> 
   103                              <1> ; PCI stuff
   104                              <1> 
   105                              <1> VIA_VID		equ     1106h           ; VIA's PCI vendor ID
   106                              <1> VT8233_DID      equ     3059h           ; VT8233 (VT8235) device ID
   107                              <1> 			
   108                              <1> PCI_IO_BASE          equ 10h
   109                              <1> AC97_INT_LINE        equ 3Ch
   110                              <1> VIA_ACLINK_CTRL      equ 41h
   111                              <1> VIA_ACLINK_STAT      equ 40h
   112                              <1> VIA_ACLINK_C00_READY equ 01h ; primary codec ready
   113                              <1> 	
   114                              <1> VIA_REG_AC97	     equ 80h ; dword
   115                              <1> 
   116                              <1> VIA_ACLINK_CTRL_ENABLE	equ   80h ; 0: disable, 1: enable
   117                              <1> VIA_ACLINK_CTRL_RESET	equ   40h ; 0: assert, 1: de-assert
   118                              <1> VIA_ACLINK_CTRL_SYNC	equ   20h ; 0: release SYNC, 1: force SYNC hi
   119                              <1> VIA_ACLINK_CTRL_VRA	equ   08h ; 0: disable VRA, 1: enable VRA
   120                              <1> VIA_ACLINK_CTRL_PCM	equ   04h ; 0: disable PCM, 1: enable PCM
   124                              <1> VIA_ACLINK_CTRL_INIT	equ  (VIA_ACLINK_CTRL_ENABLE +                               VIA_ACLINK_CTRL_RESET +                               VIA_ACLINK_CTRL_PCM +                               VIA_ACLINK_CTRL_VRA)
   125                              <1> 
   126                              <1> CODEC_AUX_VOL		equ   04h
   127                              <1> VIA_REG_AC97_BUSY	equ   01000000h ;(1<<24) 
   128                              <1> VIA_REG_AC97_CMD_SHIFT	equ   10h ; 16
   129                              <1> VIA_REG_AC97_PRIMARY_VALID equ 02000000h ;(1<<25)
   130                              <1> VIA_REG_AC97_READ	equ   00800000h ;(1<<23)
   131                              <1> VIA_REG_AC97_CODEC_ID_SHIFT   equ  1Eh ; 30
   132                              <1> VIA_REG_AC97_CODEC_ID_PRIMARY equ  0
   133                              <1> VIA_REG_AC97_DATA_SHIFT equ   0
   134                              <1> VIADEV_PLAYBACK         equ   0
   135                              <1> VIA_REG_OFFSET_STATUS   equ   0    ;; byte - channel status
   136                              <1> VIA_REG_OFFSET_CONTROL  equ   01h  ;; byte - channel control
   137                              <1> VIA_REG_CTRL_START	equ   80h  ;; WO
   138                              <1> VIA_REG_CTRL_TERMINATE  equ   40h  ;; WO
   139                              <1> VIA_REG_CTRL_PAUSE      equ   08h  ;; RW
   140                              <1> VIA_REG_CTRL_RESET      equ   01h  ;; RW - probably reset? undocumented
   141                              <1> VIA_REG_OFFSET_STOP_IDX equ   08h  ;; dword - stop index, channel type, sample rate
   142                              <1> VIA8233_REG_TYPE_16BIT  equ   200000h ;; RW
   143                              <1> VIA8233_REG_TYPE_STEREO equ   100000h ;; RW
   144                              <1> VIA_REG_OFFSET_CURR_INDEX equ 0Fh ;; byte - channel current index (for via8233 only)
   145                              <1> VIA_REG_OFFSET_TABLE_PTR equ  04h  ;; dword - channel table pointer
   146                              <1> VIA_REG_OFFSET_CURR_PTR equ   04h  ;; dword - channel current pointer
   147                              <1> VIA_REG_OFS_PLAYBACK_VOLUME_L equ  02h ;; byte
   148                              <1> VIA_REG_OFS_PLAYBACK_VOLUME_R equ  03h ;; byte
   149                              <1> VIA_REG_CTRL_AUTOSTART	equ   20h
   150                              <1> VIA_REG_CTRL_INT_EOL	equ   02h
   151                              <1> VIA_REG_CTRL_INT_FLAG	equ   01h
   154                              <1> VIA_REG_CTRL_INT	equ  (VIA_REG_CTRL_INT_FLAG +                               VIA_REG_CTRL_INT_EOL +                               VIA_REG_CTRL_AUTOSTART)
   155                              <1> ; 24/11/2016
   156                              <1> VIA_REG_STAT_STOPPED	equ   04h    ;; RWC
   157                              <1> VIA_REG_STAT_EOL	equ   02h    ;; RWC
   158                              <1> VIA_REG_STAT_FLAG	equ   01h    ;; RWC
   159                              <1> VIA_REG_STAT_ACTIVE	equ   80h    ;; RO
   160                              <1> ; 28/11/2016
   161                              <1> VIA_REG_STAT_LAST	equ   40h    ;; RO
   162                              <1> VIA_REG_STAT_TRIGGER_QUEUED equ 08h  ;; RO
   163                              <1> VIA_REF_CTRL_INT_STOP	equ   04h  ; Interrupt on Current Index = Stop Index
   164                              <1> 				   ; and End of Block			
    20                                  
    21                                  _STARTUP:
    22                                  
    23                                  ; memory allocation
    24                                  
    25 00000000 E87C01                          call    setFree                         ; deallocate unused DOS mem
    26                                  
    27                                  ; allocate 256 bytes of data for DCM_OUT Buffer Descriptor List. (BDL)
    28                                  
    29 00000003 B81000                          mov     ax, BDL_SIZE / 16
    30 00000006 E88A01                          call    memAlloc
    31 00000009 A3[8A09]                        mov     [BDL_BUFFER], ax		; segment 
    32                                  
    33                                  ; allocate 2 buffers, 64k each for now.
    34                                  
    35 0000000C B80010                          mov     ax, FILESIZE / 16               ; 64k for .WAV file
    36 0000000F E88101                          call    memAlloc
    37 00000012 A3[8C09]                        mov     [WAV_BUFFER1], ax		; segment
    38                                  
    39 00000015 B80010                  	mov	ax, FILESIZE / 16
    40 00000018 E87801                  	call	memAlloc
    41 0000001B A3[8E09]                	mov	[WAV_BUFFER2], ax
    42                                  
    43                                  ; Detect/reset AC97 
    44                                  ;
    45 0000001E 66B806115930                    mov     eax, (VT8233_DID << 16) + VIA_VID
    46 00000024 E8DF02                          call    pciFindDevice
    47 00000027 7343                            jnc     short _1
    48                                  
    49                                  ; couldn't find the audio device!
    50                                  
    51 00000029 0E                      	push	cs
    52 0000002A 1F                      	pop	ds
    53 0000002B BA[3500]                        mov     dx, noDevMsg
    54 0000002E B409                            mov     ah, 9
    55 00000030 CD21                            int     21h
    56 00000032 E94301                          jmp     exit
    57                                  
    58 00000035 4572726F723A20556E-     noDevMsg db "Error: Unable to find VIA VT8233 based audio device!",CR,LF,"$"
    58 0000003E 61626C6520746F2066-
    58 00000047 696E64205649412056-
    58 00000050 543832333320626173-
    58 00000059 656420617564696F20-
    58 00000062 646576696365210D0A-
    58 0000006B 24                 
    59                                  
    60                                  _1:
    61                                  	; 12/11/2016
    62                                  	; Erdogan Tan - 8/11/2016
    63                                  	; References: Kolibrios - vt823x.asm (2016)
    64                                  	;	      VIA VT8235 V-Link South Bridge (VT8235-VIA.PDF)(2002)
    65                                  	;	      lowlevel.eu - AC97 (2016)
    66                                  	;	      .wav player for DOS by Jeff Leyda (2002) -this file-
    67                                  	;	      Linux kernel - via82xx.c (2016)
    68                                  
    69                                  	; eax = BUS/DEV/FN
    70                                  	;	00000000BBBBBBBBDDDDDFFF00000000
    71                                  	; edx = DEV/VENDOR
    72                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
    73                                  
    74 0000006C 66A3[9209]              	mov	[bus_dev_fn], eax
    75 00000070 668916[9609]            	mov	[dev_vendor], edx
    76                                  
    77                                  	; init controller
    78 00000075 B004                    	mov	al, PCI_CMD_REG ; command register (04h)
    79 00000077 E80C02                  	call	pciRegRead32
    80                                  
    81                                  	; eax = BUS/DEV/FN/REG
    82                                  	; edx = STATUS/COMMAND
    83                                  	; 	SSSSSSSSSSSSSSSSCCCCCCCCCCCCCCCC
    84 0000007A 668916[9A09]            	mov	[stats_cmd], edx
    85                                  
    86 0000007F B010                    	mov	al, PCI_IO_BASE ; IO base address register (10h)
    87 00000081 E80202                  	call	pciRegRead32
    88                                  
    89 00000084 83E2C0                  	and     dx, 0FFC0h	; IO_ADDR_MASK (0FFFE) ?
    90 00000087 8916[9E09]                      mov     [ac97_io_base], dx
    91                                  
    92 0000008B B03C                    	mov	al, AC97_INT_LINE ; Interrupt line register (3Ch)
    93 0000008D E8F601                  	call	pciRegRead32
    94                                  
    95 00000090 6681E2FF000000          	and 	edx, 0FFh
    96 00000097 8816[9009]                	mov     [ac97_int_ln_reg], dl
    97                                  
    98                                  	; 28/11/2016
    99 0000009B BB0100                  	mov	bx, 1
   100 0000009E 89D1                    	mov	cx, dx
   101 000000A0 D3E3                    	shl	bx, cl
   102                                  
   103                                  	;not	bx
   104 000000A2 E4A1                    	in	al, 0A1h ; irq 8-15
   105 000000A4 88C4                            mov	ah, al
   106 000000A6 E421                            in	al, 21h  ; irq 0-7 
   107                                  	;and	ax, bx   ; unmask
   108 000000A8 0FB3D0                   	btr	ax, dx	 ; unmask
   109 000000AB E621                    	out	21h, al  ; enable interrupt (if irq <= 7)
   110 000000AD 88E0                    	mov	al, ah
   111 000000AF E6A1                    	out	0A1h, al ; enable interrupt (if irq > 7)
   112                                  	;not	bx
   113                                  
   114 000000B1 BAD104                  	mov	dx, 4D1h			;8259 ELCR1
   115 000000B4 EC                              in	al, dx
   116 000000B5 88C4                    	mov	ah, al
   117 000000B7 BAD004                  	mov	dx, 4D0h 
   118 000000BA EC                              in	al, dx
   119                                  	;or	ax, bx        
   120 000000BB 0FABC8                  	bts	ax, cx
   121 000000BE BAD004                  	mov	dx, 4D0h
   122 000000C1 EE                      	out	dx, al                          ;set level-triggered mode
   123 000000C2 88E0                    	mov	al, ah
   124 000000C4 BAD104                  	mov	dx, 4D1h
   125 000000C7 EE                      	out	dx, al                          ;set level-triggered mode
   126                                  
   127                                  	; 24/11/2016 - Erdogan Tan
   128 000000C8 89CB                    	mov	bx, cx
   129                                  	;mov	bx, dx
   130 000000CA 8A9F[A409]              	mov	bl, [bx+irq_int]
   131 000000CE C1E302                  	shl	bx, 2 ; * 4
   132                                  
   133                                  	; set up interrupt vector
   134                                  	; 30/11/2016
   135 000000D1 06                      	push	es
   136 000000D2 31C0                    	xor	ax, ax
   137 000000D4 8EC0                    	mov	es, ax
   138 000000D6 26C707[B008]            	mov	word [es:bx], ac97_int_handler
   139 000000DB 8CC8                    	mov	ax, cs
   140 000000DD 26894702                	mov	[es:bx+2], ax
   141 000000E1 07                      	pop	es
   142                                  		
   143                                  	; init AC97 codec
   144                                  _a1:
   145 000000E2 B041                    	mov	al, VIA_ACLINK_CTRL  ; AC link interface control (41h)
   146 000000E4 E88901                  	call	pciRegRead8
   147                                  
   148 000000E7 B040                    	mov	al, VIA_ACLINK_STAT  ; AC Link interface status (40h)
   149 000000E9 E88401                  	call	pciRegRead8
   150                                  	
   151                                  	;movzx	eax, dl
   152                                  	;test	al, VIA_ACLINK_C00_READY  ; 1 ; primary codec ready ?
   153                                  	;jnz	short _a2
   154                                  
   155 000000EC E80903                  	call	reset_codec
   156 000000EF 731E                    	jnc	short _a2 ; EAX = 1
   157                                  
   158                                  	;test	al, VIA_ACLINK_C00_READY 	
   159                                          ;jnz     short _a2
   160                                  
   161                                  _codec_err:
   162 000000F1 0E                      	push	cs
   163 000000F2 1F                      	pop	ds
   164 000000F3 BA[FC00]                        mov	dx, CodecErrMsg
   165 000000F6 B409                            mov     ah, 9
   166 000000F8 CD21                            int     21h
   167 000000FA EB7C                            jmp     exit
   168                                  
   169 000000FC 436F64656320457272-     CodecErrMsg db "Codec Error #"
   169 00000105 6F722023           
   170 00000109 3020210D0A24            ErrNo	db	"0 !", CR,LF,"$"
   171                                  
   172                                  _a2:
   173                                  	; eax = 1
   174 0000010F E84E03                  	call	codec_io_w16 ; w32
   175                                  	
   176                                  	;call	detect_codec
   177                                  
   178 00000112 E8E903                  	call	channel_reset
   179                                  
   180 00000115 E82806                  	call	write_ac97_dev_info 
   181                                  
   182                                  ; check the command line for a file to play
   183                                  
   184                                          ;push    ds
   185 00000118 E88100                          call    processCmdline			; get the filename
   186                                  
   187                                  ; open the file
   188 0000011B B002                            mov     al, OPEN                        ; open existing file
   189 0000011D E89C00                          call    openFile                        ; no error? ok.
   190                                          ;pop     ds
   191 00000120 7322                            jnc     short _gsr
   192                                  
   193                                  ; file not found!
   194                                  
   195                                          ;push   cs
   196                                          ;pop    ds
   197 00000122 BA[2B01]                        mov	dx, noFileErrMsg
   198 00000125 B409                            mov     ah, 9
   199 00000127 CD21                            int     21h
   200 00000129 EB4D                            jmp     exit
   201                                  
   202 0000012B 4572726F723A206669-     noFileErrMsg  db "Error: file not found.",CR,LF,"$"
   202 00000134 6C65206E6F7420666F-
   202 0000013D 756E642E0D0A24     
   203                                  
   204                                  _gsr:
   205 00000144 E89C00                          call    getSampleRate                   ; read the sample rate
   206                                                                                  ; pass it onto codec.
   207 00000147 722F                    	jc	short exit ; 19/11/2016 - nothing to do
   208                                  
   209 00000149 A3[A009]                	mov	[sample_rate], ax
   210                                  	; 19/11/2016
   211 0000014C 880E[A209]              	mov	[stmo], cl
   212 00000150 8816[A309]              	mov	[bps], dl
   213                                  
   214 00000154 E80807                  	call	write_sample_rate
   215                                  
   216                                  ; setup the Codec (actually mixer registers) 
   217 00000157 E8E501                          call    codecConfig                     ; unmute codec, set rates.
   218 0000015A 7307                    	jnc	short _a3
   219                                  
   220 0000015C 0430                    	add	al, '0'
   221 0000015E A2[0901]                	mov	[ErrNo], al
   222 00000161 EB8E                    	jmp	short _codec_err
   223                                  
   224                                  _a3:
   225                                  	
   226                                  ;
   227                                  ; position file pointer to start in actual wav data
   228                                  ; MUCH improvement should really be done here to check if sample size is
   229                                  ; supported, make sure there are 2 channels, etc.  
   230                                  ;
   231 00000163 B442                            mov     ah, 42h
   232 00000165 B000                            mov     al, 0                           ; from start of file
   233 00000167 8B1E[8409]                      mov     bx, [filehandle]
   234 0000016B 31C9                            xor     cx, cx
   235 0000016D BA2C00                          mov     dx, 44                          ; jump past .wav/riff header
   236 00000170 CD21                            int     21h
   237                                  
   238                                  ; play the .wav file.  Most of the good stuff is in here.
   239                                  
   240 00000172 E8D103                          call    playWav
   241                                  
   242                                  ; close the .wav file and exit.
   243                                  
   244 00000175 E85600                          call    closeFile
   245                                  
   246                                  exit:
   247 00000178 B8004C                          mov     ax, 4c00h
   248 0000017B CD21                    	int 	21h
   249                                  
   250                                  here:
   251 0000017D EBFE                    	jmp	short here
   252                                  
   253                                  ; MEMALLOC.ASM
   254                                  ;-- SETFREE: Release memory not used  ----------------
   255                                  ;-- Input    : ES = address of PSP
   256                                  ;-- Output   : none
   257                                  ;-- Register : AX, BX, CL and FLAGS are changed 
   258                                  ;-- Info     : Since the stack-segment is always the last segment in an 
   259                                  ;              EXE-file, ES:0000 points to the beginning and SS:SP
   260                                  ;              to the end of the program in memory. Through this the
   261                                  ;              length of the program can be calculated 
   262                                  ; call this routine once at the beginning of the program to free up memory
   263                                  ; assigned to it by DOS.
   264                                  
   265                                  setFree:
   266 0000017F 8CD3                              mov  bx,ss              ;first subtract the two segment addresses
   267 00000181 8CC0                              mov  ax,es              ;from each other. The result is
   268 00000183 29C3                              sub  bx,ax              ;number of paragraphs from PSP
   269                                                                    ;to the beginning of the stack
   270 00000185 89E0                              mov  ax,sp              ;since the stackpointer is at the end of
   271 00000187 B104                              mov  cl,4               ;the stack segment, its content indicates
   272 00000189 D3E8                              shr  ax,cl              ;the length of the stack
   273 0000018B 01C3                              add  bx,ax              ;add to current length
   274 0000018D 43                                inc  bx                 ;as precaution add another paragraph
   275                                  
   276 0000018E B44A                              mov  ah,4ah             ;pass new length to DOS
   277 00000190 CD21                              int  21h
   278                                  
   279 00000192 C3                                retn                     ;back to caller
   280                                  
   281                                  memAlloc:
   282                                  ; input: AX = # of paragraphs required
   283                                  ; output: AX = segment of block to use
   284                                  
   285 00000193 53                      	push	bx
   286 00000194 89C3                    	mov	bx, ax
   287 00000196 B448                    	mov	ah, 48h
   288 00000198 CD21                    	int	21h
   289 0000019A 5B                      	pop	bx
   290 0000019B C3                      	retn
   291                                  
   292                                  ; CMDLINE.ASM
   293                                  ; parse the command line
   294                                  ; entry: none
   295                                  ; exit: DS:DX to the 1st supplied item on the command line 
   296                                  
   297                                  processCmdline:
   298 0000019C 53                              push    bx
   299 0000019D 56                              push    si
   300                                  
   301                                          ;mov    ah, 51h
   302                                          ;int    21h
   303                                          ;mov    ds, bx
   304                                  
   305 0000019E BE8000                          mov     si, 80h
   306 000001A1 0FB61C                          movzx   bx, byte [si]
   307 000001A4 01DE                            add     si, bx
   308 000001A6 46                              inc     si
   309                                  
   310 000001A7 C60400                          mov     byte [si], NULL         ; zero terminate
   311                                  
   312 000001AA BE8100                          mov     si, 81h
   313                                  
   314                                  cmdlineloop:
   315 000001AD AC                              lodsb
   316                                  
   317 000001AE 3C00                            cmp     al, NULL                ; found end of line?
   318 000001B0 7404                            je      short exitpc
   319 000001B2 3C20                            cmp     al, ' '                 ; found a space?
   320 000001B4 74F7                            je      short cmdlineloop
   321                                  
   322                                          ; must be the filename here.
   323                                  exitpc:
   324 000001B6 4E                              dec     si                      ; point to start of filename
   325 000001B7 89F2                            mov     dx, si
   326 000001B9 5E                              pop     si
   327 000001BA 5B                              pop     bx
   328 000001BB C3                      	retn
   329                                  
   330                                  ; FILE.ASM
   331                                  ;open or create file
   332                                  ;
   333                                  ;input: ds:dx-->filename (asciiz)
   334                                  ;       al=file Mode (create or open)
   335                                  ;output: none  cs:[filehandle] filled
   336                                  ;
   337                                  openFile:
   338 000001BC 50                      	push	ax
   339 000001BD 51                      	push	cx
   340 000001BE B43B                    	mov	ah, 3bh			; start with a mode
   341 000001C0 00C4                    	add	ah, al			; add in create or open mode
   342 000001C2 31C9                    	xor	cx, cx
   343 000001C4 CD21                    	int	21h
   344 000001C6 7203                    	jc	short _of1
   345                                  	;mov	[cs:filehandle], ax
   346 000001C8 A3[8409]                	mov	[filehandle], ax
   347                                  _of1:
   348 000001CB 59                      	pop	cx
   349 000001CC 58                      	pop	ax
   350 000001CD C3                      	retn
   351                                  
   352                                  ; close the currently open file
   353                                  ; input: none, uses cs:[filehandle]
   354                                  closeFile:
   355 000001CE 50                      	push	ax
   356 000001CF 53                      	push	bx
   357 000001D0 833E[8409]FF            	cmp	word [filehandle], -1
   358 000001D5 7409                    	jz	short _cf1
   359 000001D7 8B1E[8409]              	mov     bx, [filehandle]  
   360 000001DB B8003E                  	mov     ax,3e00h
   361 000001DE CD21                            int     21h              ;close file
   362                                  _cf1:
   363 000001E0 5B                      	pop	bx
   364 000001E1 58                      	pop	ax
   365 000001E2 C3                      	retn
   366                                  
   367                                  getSampleRate:
   368                                  	; 08/12/2016
   369                                  ; reads the sample rate from the .wav file.
   370                                  ; entry: none - assumes file is already open
   371                                  	; 19/11/2016 - Erdogan Tan
   372                                  ; exit: ax = sample rate (11025, 22050, 44100, 48000)
   373                                  ;	cx = number of channels (mono=1, stereo=2)
   374                                  ;	dx = bits per sample (8, 16)
   375                                  
   376 000001E3 53                      	push    bx
   377                                  
   378 000001E4 B442                            mov     ah, 42h
   379 000001E6 B000                            mov     al, 0				; from start of file
   380 000001E8 8B1E[8409]                      mov     bx, [filehandle]
   381 000001EC 31C9                            xor     cx, cx
   382 000001EE BA0800                          mov     dx, 08h				; "WAVE"
   383 000001F1 CD21                            int     21h
   384                                  
   385 000001F3 BA[6809]                        mov     dx, smpRBuff
   386 000001F6 B91C00                          mov     cx, 28				; 28 bytes
   387 000001F9 B43F                    	mov	ah, 3fh
   388 000001FB CD21                            int     21h
   389                                  
   390 000001FD 813E[6809]5741          	cmp	word [smpRBuff], 'WA'
   391 00000203 751C                    	jne	short gsr_stc
   392                                  
   393 00000205 813E[6A09]5645          	cmp	word [smpRBuff+2], 'VE'
   394 0000020B 7514                    	jne	short gsr_stc
   395                                  
   396 0000020D 833E[7409]01            	cmp	word [smpRBuff+12], 1	; Offset 20, must be 1 (= PCM)
   397 00000212 750D                    	jne	short gsr_stc
   398                                  
   399                                  
   400 00000214 8B0E[7609]              	mov	cx, [smpRBuff+14]	; return num of channels in CX
   401 00000218 A1[7809]                        mov     ax, [smpRBuff+16]	; return sample rate in AX
   402 0000021B 8B16[8209]              	mov	dx, [smpRBuff+26]	; return bits per sample value in DX
   403                                  gsr_retn:
   404 0000021F 5B                              pop     bx
   405 00000220 C3                              retn
   406                                  
   407                                  gsr_stc:
   408 00000221 F9                      	stc
   409 00000222 EBFB                    	jmp	short gsr_retn
   410                                  
   411                                  %include 'pci.asm'  ; 29/11/2016
     1                              <1> ; PCI device register reader/writers.
     2                              <1> ; NASM version: Erdogan Tan (29/11/2016)
     3                              <1> 
     4                              <1> ;===============================================================
     5                              <1> ; 8/16/32bit PCI reader
     6                              <1> ;
     7                              <1> ; Entry: EAX=PCI Bus/Device/fn/register number
     8                              <1> ;           BIT30 set if 32 bit access requested
     9                              <1> ;           BIT29 set if 16 bit access requested
    10                              <1> ;           otherwise defaults to 8bit read
    11                              <1> ;
    12                              <1> ; Exit:  DL,DX,EDX register data depending on requested read size
    13                              <1> ;
    14                              <1> ; Note: this routine is meant to be called via pciRegRead8, pciRegread16,
    15                              <1> ;	or pciRegRead32, listed below.
    16                              <1> ;
    17                              <1> ; Note2: don't attempt to read 32bits of data from a non dword aligned reg
    18                              <1> ;	 number.  Likewise, don't do 16bit reads from non word aligned reg #
    19                              <1> ; 
    20                              <1> pciRegRead:
    21 00000224 6653                <1> 	push	ebx
    22 00000226 51                  <1> 	push	cx
    23 00000227 6689C3              <1>         mov     ebx, eax                        ; save eax, dh
    24 0000022A 88F1                <1>         mov     cl, dh
    25 0000022C 6625FFFFFFBF        <1>         and     eax, (~PCI32)+PCI16             ; clear out data size request
    26 00000232 660D00000080        <1>         or      eax, BIT31                      ; make a PCI access request
    27 00000238 24FC                <1>         and     al, ~3 ; NOT 3                  ; force index to be dword
    28                              <1> 
    29 0000023A BAF80C              <1>         mov     dx, PCI_INDEX_PORT
    30 0000023D 66EF                <1>         out     dx, eax                         ; write PCI selector
    31                              <1> 
    32 0000023F BAFC0C              <1>         mov     dx, PCI_DATA_PORT
    33 00000242 88D8                <1>         mov     al, bl
    34 00000244 2403                <1>         and     al, 3                           ; figure out which port to
    35 00000246 00C2                <1>         add     dl, al                          ; read to
    36                              <1> 
    37 00000248 66ED                <1> 	in      eax, dx                         ; do 32bit read
    38 0000024A 66F7C300000080      <1>         test    ebx, PCI32
    39 00000251 7403                <1>         jz      short _pregr1
    40                              <1> 
    41 00000253 6689C2              <1>         mov     edx, eax                        ; return 32bits of data
    42                              <1> _pregr1:
    43 00000256 89C2                <1> 	mov     dx, ax                          ; return 16bits of data
    44 00000258 66F7C3000000C0      <1>         test    ebx, PCI32+PCI16
    45 0000025F 7502                <1>         jnz     short _pregr2
    46 00000261 88CE                <1>         mov     dh, cl                          ; restore dh for 8 bit read
    47                              <1> _pregr2:
    48 00000263 6689D8              <1>         mov     eax, ebx                        ; restore eax
    49 00000266 6625FFFFFFBF        <1>         and     eax, (~PCI32)+PCI16             ; clear out data size request
    50 0000026C 59                  <1> 	pop	cx
    51 0000026D 665B                <1> 	pop	ebx
    52 0000026F C3                  <1> 	retn
    53                              <1> 
    54                              <1> pciRegRead8:
    55 00000270 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32             ; set up 8 bit read size
    56 00000276 EBAC                <1>         jmp     short pciRegRead		; call generic PCI access
    57                              <1> 
    58                              <1> pciRegRead16:
    59 00000278 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 16 bit read size
    60 0000027E 660D00000040        <1>         or      eax, PCI16			; call generic PCI access
    61 00000284 EB9E                <1>         jmp     short pciRegRead
    62                              <1> 
    63                              <1> pciRegRead32:
    64 00000286 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 32 bit read size
    65 0000028C 660D00000080        <1>         or      eax, PCI32			; call generic PCI access
    66 00000292 EB90                <1>         jmp     short pciRegRead
    67                              <1> 
    68                              <1> ;===============================================================
    69                              <1> ; 8/16/32bit PCI writer
    70                              <1> ;
    71                              <1> ; Entry: EAX=PCI Bus/Device/fn/register number
    72                              <1> ;           BIT31 set if 32 bit access requested
    73                              <1> ;           BIT30 set if 16 bit access requested
    74                              <1> ;           otherwise defaults to 8bit read
    75                              <1> ;        DL/DX/EDX data to write depending on size
    76                              <1> ;
    77                              <1> ;
    78                              <1> ; note: this routine is meant to be called via pciRegWrite8, pciRegWrite16,
    79                              <1> ; 	or pciRegWrite32 as detailed below.
    80                              <1> ;
    81                              <1> ; Note2: don't attempt to write 32bits of data from a non dword aligned reg
    82                              <1> ;	 number.  Likewise, don't do 16bit writes from non word aligned reg #
    83                              <1> ;
    84                              <1> pciRegWrite:
    85 00000294 6653                <1> 	push	ebx
    86 00000296 51                  <1> 	push	cx
    87 00000297 6689C3              <1>         mov     ebx, eax                        ; save eax, dx
    88 0000029A 89D1                <1>         mov     cx, dx
    89 0000029C 660D00000080        <1>         or      eax, BIT31                      ; make a PCI access request
    90 000002A2 6625FFFFFFBF        <1>         and     eax, ~PCI16 ; NOT PCI16         ; clear out data size request
    91 000002A8 24FC                <1>         and     al, ~3 ; NOT 3                  ; force index to be dword
    92                              <1> 
    93 000002AA BAF80C              <1>         mov     dx, PCI_INDEX_PORT
    94 000002AD 66EF                <1>         out     dx, eax                         ; write PCI selector
    95                              <1> 
    96 000002AF BAFC0C              <1>         mov     dx, PCI_DATA_PORT
    97 000002B2 88D8                <1>         mov     al, bl
    98 000002B4 2403                <1>         and     al, 3                           ; figure out which port to
    99 000002B6 00C2                <1>         add     dl, al                          ; write to
   100                              <1> 
   101 000002B8 6689D0              <1>         mov     eax, edx                        ; put data into eax
   102 000002BB 89C8                <1>         mov     ax, cx
   103                              <1> 
   104 000002BD EE                  <1>         out     dx, al
   105 000002BE 66F7C3000000C0      <1>         test    ebx, PCI16+PCI32                ; only 8bit access? bail
   106 000002C5 740C                <1>         jz      short _pregw1
   107                              <1> 
   108 000002C7 EF                  <1>         out     dx, ax                          ; write 16 bit value
   109 000002C8 66F7C300000040      <1>         test    ebx, PCI16                      ; 16bit requested?  bail
   110 000002CF 7502                <1>         jnz     short _pregw1
   111                              <1> 
   112 000002D1 66EF                <1>         out     dx, eax                         ; write full 32bit
   113                              <1> _pregw1:
   114 000002D3 6689D8              <1>         mov     eax, ebx                        ; restore eax
   115 000002D6 6625FFFFFFBF        <1>         and     eax, (~PCI32)+PCI16             ; clear out data size request
   116 000002DC 89CA                <1>         mov     dx, cx                          ; restore dx
   117 000002DE 59                  <1> 	pop	cx
   118 000002DF 665B                <1> 	pop	ebx
   119 000002E1 C3                  <1> 	ret
   120                              <1> 
   121                              <1> pciRegWrite8:
   122 000002E2 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 8 bit write size
   123 000002E8 EBAA                <1>         jmp     short pciRegWrite		; call generic PCI access
   124                              <1> 
   125                              <1> pciRegWrite16:
   126 000002EA 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 16 bit write size
   127 000002F0 660D00000040        <1>         or      eax, PCI16			; call generic PCI access
   128 000002F6 EB9C                <1>         jmp     short pciRegWrite
   129                              <1> 
   130                              <1> pciRegWrite32:
   131 000002F8 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 32 bit write size
   132 000002FE 660D00000080        <1>         or      eax, PCI32			; call generic PCI access
   133 00000304 EB8E                <1>         jmp     short pciRegWrite
   134                              <1> 
   135                              <1> ;===============================================================
   136                              <1> ; PCIFindDevice: scan through PCI space looking for a device+vendor ID
   137                              <1> ;
   138                              <1> ; Entry: EAX=Device+Vendor ID
   139                              <1> ;
   140                              <1> ;  Exit: EAX=PCI address if device found
   141                              <1> ;	 EDX=Device+Vendor ID
   142                              <1> ;        CY clear if found, set if not found. EAX invalid if CY set.
   143                              <1> ;
   144                              <1> ; [old stackless] Destroys: ebx, esi, edi, cl
   145                              <1> ;
   146                              <1> pciFindDevice:
   147                              <1> 	;push	cx
   148 00000306 6650                <1> 	push	eax
   149                              <1> 	;push	esi
   150                              <1> 	;push	edi
   151                              <1> 
   152 00000308 6689C6              <1>         mov     esi, eax                ; save off vend+device ID
   153 0000030B 66BF00FFFF7F        <1>         mov     edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0
   154                              <1> 
   155                              <1> nextPCIdevice:
   156 00000311 6681C700010000      <1>         add     edi, 100h
   157 00000318 6681FF00F8FF80      <1>         cmp     edi, 80FFF800h		; scanned all devices?
   158 0000031F F9                  <1>         stc
   159 00000320 740C                <1>         je      short PCIScanExit       ; not found
   160                              <1> 
   161 00000322 6689F8              <1>         mov     eax, edi                ; read PCI registers
   162 00000325 E85EFF              <1>         call    pciRegRead32
   163 00000328 6639F2              <1>         cmp     edx, esi                ; found device?
   164 0000032B 75E4                <1>         jne     short nextPCIdevice
   165 0000032D F8                  <1>         clc
   166                              <1> 
   167                              <1> PCIScanExit:
   168 0000032E 9C                  <1> 	pushf
   169 0000032F 66B800000080        <1> 	mov	eax, BIT31
   170 00000335 66F7D0              <1> 	not	eax
   171 00000338 6621F8              <1> 	and	eax, edi		; return only bus/dev/fn #
   172 0000033B 9D                  <1> 	popf
   173                              <1> 
   174                              <1> 	;pop	edi
   175                              <1> 	;pop	esi
   176 0000033C 665A                <1> 	pop	edx
   177                              <1> 	;pop	cx
   178 0000033E C3                  <1> 	retn
   412                                  %include 'codec.asm'  ; 29/11/2016
     1                              <1> ; codec configuration code.  Not much here really.
     2                              <1> ; NASM version: Erdogan Tan (29/11/2016)
     3                              <1> 
     4                              <1> ; enable codec, unmute stuff, set output rate to 44.1
     5                              <1> ; entry: ax = desired sample rate
     6                              <1> ;
     7                              <1> codecConfig:
     8                              <1> 	; 15/11/2016
     9                              <1> 	; 14/11/2016
    10                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, 'setup_codec', codec.inc)
    11                              <1> 
    12                              <1> 	; 14/11/2016 - Erdogan Tan	
    13                              <1> 	; (Ref: Mpxplay, PDSoft, Attila Padar, SC_VIA82.C)
    14                              <1> ;;;	call	channel_reset
    15                              <1> 
    16 0000033F C606[9109]00        <1> 	mov	byte [err_num], 0
    17                              <1> 
    18 00000344 66B802020000        <1> 	mov     eax, 0202h
    19 0000034A 66BA02000000        <1> 	mov	edx, CODEC_MASTER_VOL_REG ; 02h ; Line Out
    20 00000350 E86901              <1> 	call	codec_write
    21                              <1> 	;jc	cconfig_error
    22                              <1> 
    23 00000353 C606[9109]01        <1> 	mov	byte [err_num], 1
    24                              <1> 
    25 00000358 66B802020000        <1> 	mov     eax, 0202h
    26 0000035E 66BA18000000        <1> 	mov	edx, CODEC_PCM_OUT_REG ; 18h ; Wave Output (Stereo)
    27 00000364 E85501              <1> 	call	codec_write
    28                              <1> 	;jc	cconfig_error
    29                              <1>       
    30 00000367 C606[9109]02        <1> 	mov	byte [err_num], 2
    31                              <1> 
    32                              <1>  	;xor    eax, eax
    33 0000036C 66B802020000        <1> 	mov	eax, 0202h
    34 00000372 66BA04000000        <1> 	mov	edx, CODEC_AUX_VOL ; 04h ; CODEC_HP_VOL_REG ; HeadPhone
    35 00000378 E84101              <1> 	call	codec_write
    36                              <1> 	;jc	cconfig_error
    37                              <1> 
    38 0000037B C606[9109]03        <1> 	mov	byte [err_num], 3
    39                              <1> 
    40 00000380 B80800              <1>         mov     ax,  08h
    41 00000383 66BA0C000000        <1>         mov	edx, 0Ch  ; AC97_PHONE_VOL ; TAD Input (Mono)
    42 00000389 E83001              <1> 	call	codec_write
    43                              <1> 	;jc	short cconfig_error
    44                              <1> 
    45 0000038C C606[9109]04        <1> 	mov	byte [err_num], 4
    46                              <1> 
    47 00000391 B80808              <1>         mov     ax,  0808h
    48 00000394 66BA10000000        <1>         mov	edx, CODEC_LINE_IN_VOL_REG ; 10h ; Line Input (Stereo)	
    49 0000039A E81F01              <1> 	call	codec_write
    50                              <1> 	;jc	short cconfig_error
    51                              <1> 
    52 0000039D C606[9109]05        <1> 	mov	byte [err_num], 5
    53                              <1> 
    54 000003A2 B80808              <1> 	mov     ax,  0808h
    55 000003A5 66BA12000000        <1>         mov	edx, CODEC_CD_VOL_REG ; 12h ; CR Input (Stereo)
    56 000003AB E80E01              <1> 	call	codec_write
    57                              <1> 	;jc	short cconfig_error
    58                              <1> 
    59 000003AE C606[9109]06        <1> 	mov	byte [err_num], 6
    60                              <1> 
    61 000003B3 B80808              <1> 	mov     ax,  0808h
    62 000003B6 66BA16000000        <1>         mov	edx, CODEC_AUX_VOL_REG ; 16h ; Aux Input (Stereo)
    63 000003BC E8FD00              <1> 	call	codec_write
    64                              <1> 	;jc	short cconfig_error
    65                              <1> 
    66 000003BF C606[9109]07        <1> 	mov	byte [err_num], 7
    67                              <1> 
    68                              <1> 	; Extended Audio Status (2Ah)
    69 000003C4 66B82A000000        <1> 	mov	eax, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah 
    70 000003CA E8C300              <1> 	call	codec_read
    71 000003CD 6625FDFF0000        <1>         and     eax, 0FFFFh - 2			; clear DRA (BIT1)
    72                              <1>         ;or     eax, 1				; set VRA (BIT0)
    73 000003D3 6683C805            <1> 	or	eax, 5  	; VRA (BIT0) & S/PDIF (BIT2) ; 14/11/2016
    74 000003D7 66BA2A000000        <1> 	mov	edx, CODEC_EXT_AUDIO_CTRL_REG
    75 000003DD E8DC00              <1> 	call	codec_write
    76                              <1> 	;jc	short cconfig_error
    77                              <1> 
    78 000003E0 C606[9109]08        <1> 	mov	byte [err_num], 8
    79                              <1> set_sample_rate:
    80 000003E5 6631C0              <1>         xor	eax, eax
    81 000003E8 A1[A009]            <1> 	mov	ax, [sample_rate]
    82 000003EB 66BA2C000000        <1> 	mov	edx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch ; PCM Front DAC Rate
    83                              <1>         ;call	codec_write
    84                              <1>         ;retn
    85 000003F1 E9C800              <1> 	jmp	codec_write
    86                              <1> 	
    87                              <1> cconfig_error:
    88 000003F4 A0[9109]            <1> 	mov	al, [err_num]
    89 000003F7 C3                  <1>         retn
    90                              <1> 
    91                              <1> reset_codec:
    92                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
    93 000003F8 66A1[9209]          <1> 	mov	eax, [bus_dev_fn]
    94 000003FC B041                <1>  	mov	al, VIA_ACLINK_CTRL
    95 000003FE B2E0                <1>        	mov	dl, VIA_ACLINK_CTRL_ENABLE + VIA_ACLINK_CTRL_RESET + VIA_ACLINK_CTRL_SYNC
    96                              <1> 
    97 00000400 E8DFFE              <1> 	call	pciRegWrite8
    98                              <1> 
    99 00000403 E84A00              <1> 	call	delay_100ms 	; wait 100 ms
   100                              <1> _rc_cold:
   101 00000406 E80C00              <1>         call    cold_reset
   102 00000409 7304                <1>         jnc     short _reset_codec_ok
   103                              <1> 
   104 0000040B 6631C0              <1>         xor     eax, eax         ; timeout error
   105 0000040E C3                  <1>         retn
   106                              <1> 
   107                              <1> _reset_codec_ok:
   108 0000040F 6631C0              <1>         xor     eax, eax
   109                              <1>         ;mov	al, VIA_ACLINK_C00_READY ; 1
   110 00000412 FEC0                <1>         inc	al
   111 00000414 C3                  <1> 	retn
   112                              <1> 
   113                              <1> cold_reset:
   114                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   115                              <1> 	;mov	eax, [bus_dev_fn]
   116                              <1> 	;mov	al, VIA_ACLINK_CTRL
   117 00000415 30D2                <1> 	xor	dl, dl ; 0
   118 00000417 E8C8FE              <1> 	call	pciRegWrite8
   119                              <1> 
   120 0000041A E83300              <1> 	call	delay_100ms 	; wait 100 ms
   121                              <1> 
   122                              <1> 	;; ACLink on, deassert ACLink reset, VSR, SGD data out
   123                              <1>         ;; note - FM data out has trouble with non VRA codecs !!
   124                              <1>         
   125                              <1> 	;mov	eax, [bus_dev_fn]
   126                              <1> 	;mov	al, VIA_ACLINK_CTRL
   127                              <1> 
   128 0000041D B2CC                <1> 	mov	dl, VIA_ACLINK_CTRL_INIT
   129                              <1> 
   130 0000041F E8C0FE              <1> 	call	pciRegWrite8
   131                              <1> 
   132 00000422 66B910000000        <1> 	mov	ecx, 16	; total 2s
   133                              <1> 
   134                              <1> _crst_wait:
   135 00000428 6651                <1> 	push	ecx
   136                              <1> 
   137                              <1> 	;mov	eax, [bus_dev_fn]
   138 0000042A B040                <1> 	mov	al, VIA_ACLINK_STAT
   139 0000042C E841FE              <1> 	call	pciRegRead8	
   140                              <1> 
   141 0000042F F6C201              <1>         test    dl, VIA_ACLINK_C00_READY
   142 00000432 750B                <1>         jnz     short _crst_ok
   143                              <1> 
   144 00000434 E81900              <1> 	call	delay_100ms
   145                              <1> 
   146 00000437 6659                <1> 	pop	ecx
   147                              <1> 
   148 00000439 6649                <1>         dec     ecx
   149 0000043B 75EB                <1>         jnz     short _crst_wait
   150                              <1> 
   151                              <1> _crst_fail:
   152 0000043D F9                  <1>         stc
   153 0000043E C3                  <1>         retn
   154                              <1> 
   155                              <1> _crst_ok:
   156 0000043F 6659                <1> 	pop	ecx
   157                              <1> 
   158                              <1> 	; are these necessary ? - 14/11/2016 - Erdogan Tan
   159                              <1> 
   160                              <1> 	;mov	eax, [bus_dev_fn]
   161                              <1> 	;mov	al, VIA_ACLINK_CTRL
   162 00000441 E82CFE              <1> 	call	pciRegRead8
   163                              <1> 
   164                              <1> 	;mov	eax, [bus_dev_fn]
   165                              <1> 	;mov	al, VIA_ACLINK_STAT
   166 00000444 E829FE              <1> 	call	pciRegRead8
   167                              <1> 
   168 00000447 660FB6C2            <1> 	movzx	eax, dl
   169 0000044B 2401                <1> 	and     al, VIA_ACLINK_C00_READY ; 1
   170 0000044D 74EE                <1> 	jz	short _crst_fail
   171                              <1> 
   172 0000044F C3                  <1> 	retn
   173                              <1> 
   174                              <1> delay_100ms:
   175                              <1> 	; wait 100 ms
   176 00000450 66B919000000        <1> 	mov	ecx, 25
   177                              <1> _delay_x_ms:
   178 00000456 6651                <1> 	push	ecx
   179 00000458 E8C502              <1> 	call	delay1_4ms
   180 0000045B 6659                <1> 	pop	ecx
   181 0000045D E2F7                <1>         loop	_delay_x_ms
   182 0000045F C3                  <1> 	retn
   183                              <1> 
   184                              <1> codec_io_w16: ;w32
   185 00000460 8B16[9E09]          <1>         mov	dx, [ac97_io_base]
   186 00000464 81C28000            <1>         add     dx, VIA_REG_AC97
   187 00000468 66EF                <1>         out     dx, eax
   188 0000046A C3                  <1>         retn
   189                              <1> 
   190                              <1> codec_io_r16: ;r32
   191 0000046B 8B16[9E09]          <1>         mov     dx, [ac97_io_base]
   192 0000046F 81C28000            <1>         add     dx, VIA_REG_AC97
   193 00000473 66ED                <1>         in      eax, dx
   194 00000475 C3                  <1>         retn
   195                              <1> 
   196                              <1> ctrl_io_w8:
   197 00000476 0316[9E09]          <1>         add     dx, [ac97_io_base]
   198 0000047A EE                  <1>         out     dx, al
   199 0000047B C3                  <1>         retn
   200                              <1> 
   201                              <1> ctrl_io_r8:
   202 0000047C 0316[9E09]          <1>         add     dx, [ac97_io_base]
   203 00000480 EC                  <1>         in      al, dx
   204 00000481 C3                  <1>         retn
   205                              <1> 
   206                              <1> ctrl_io_w32:
   207 00000482 0316[9E09]          <1>         add     dx, [ac97_io_base]
   208 00000486 66EF                <1>         out     dx, eax
   209 00000488 C3                  <1>         retn
   210                              <1> 
   211                              <1> ctrl_io_r32:
   212 00000489 0316[9E09]          <1>         add	dx, [ac97_io_base]
   213 0000048D 66ED                <1>         in	eax, dx
   214 0000048F C3                  <1>         retn
   215                              <1> 
   216                              <1> codec_read:
   217                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   218                              <1>         ; Use only primary codec.
   219                              <1>         ; eax = register
   220 00000490 66C1E010            <1>         shl     eax, VIA_REG_AC97_CMD_SHIFT
   221 00000494 660D00008002        <1>         or      eax, VIA_REG_AC97_PRIMARY_VALID + VIA_REG_AC97_READ
   222                              <1> 
   223 0000049A E8C3FF              <1> 	call    codec_io_w16
   224                              <1> 
   225                              <1>       	; codec_valid
   226 0000049D E83700              <1> 	call	codec_check_ready
   227 000004A0 7301                <1>         jnc	short _cr_ok
   228                              <1> 
   229 000004A2 C3                  <1> 	retn
   230                              <1> 
   231                              <1> _cr_ok:
   232                              <1> 	; wait 25 ms
   233 000004A3 E87A02              <1> 	call	delay1_4ms
   234 000004A6 E87702              <1> 	call	delay1_4ms
   235 000004A9 E87402              <1> 	call	delay1_4ms
   236 000004AC E87102              <1> 	call	delay1_4ms
   237 000004AF E86E02              <1> 	call	delay1_4ms
   238                              <1> 
   239 000004B2 E8B6FF              <1>         call    codec_io_r16
   240 000004B5 6625FFFF0000        <1>         and     eax, 0FFFFh
   241 000004BB C3                  <1>         retn
   242                              <1> 
   243                              <1> codec_write:
   244                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   245                              <1>         ; Use only primary codec.
   246                              <1>         
   247                              <1> 	; eax = data (volume)
   248                              <1> 	; edx = register (mixer register)
   249                              <1> 	
   250 000004BC 66C1E210            <1> 	shl     edx, VIA_REG_AC97_CMD_SHIFT
   251                              <1> 
   252 000004C0 66C1E000            <1>         shl     eax, VIA_REG_AC97_DATA_SHIFT ; shl eax, 0
   253 000004C4 6609C2              <1>         or      edx, eax
   254                              <1> 
   255 000004C7 66B800000000        <1>         mov     eax, VIA_REG_AC97_CODEC_ID_PRIMARY
   256 000004CD 66C1E01E            <1>         shl     eax, VIA_REG_AC97_CODEC_ID_SHIFT
   257 000004D1 6609D0              <1>         or      eax, edx
   258                              <1> 
   259 000004D4 E889FF              <1>         call    codec_io_w16
   260                              <1>         ;mov    [codec.regs+esi], ax
   261                              <1> 
   262                              <1>         ;call	codec_check_ready
   263                              <1>        	;retn
   264                              <1> 	;jmp	short _codec_check_ready	
   265                              <1> 
   266                              <1> codec_check_ready:
   267                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   268                              <1> 
   269                              <1> _codec_check_ready:
   270 000004D7 66B914000000        <1> 	mov	ecx, 20	; total 2s
   271                              <1> _ccr_wait:
   272 000004DD 6651                <1> 	push	ecx
   273                              <1> 
   274 000004DF E889FF              <1>         call    codec_io_r16
   275 000004E2 66A900000001        <1>         test    eax, VIA_REG_AC97_BUSY
   276 000004E8 740B                <1>         jz      short _ccr_ok
   277                              <1> 
   278 000004EA E863FF              <1> 	call	delay_100ms
   279                              <1> 
   280 000004ED 6659                <1> 	pop	ecx
   281                              <1> 
   282 000004EF 6649                <1> 	dec     ecx
   283 000004F1 75EA                <1>         jnz     short _ccr_wait
   284                              <1> 
   285 000004F3 F9                  <1>         stc
   286 000004F4 C3                  <1>         retn
   287                              <1> 
   288                              <1> _ccr_ok:
   289 000004F5 6659                <1> 	pop	ecx
   290 000004F7 6625FFFF0000        <1> 	and     eax, 0FFFFh
   291 000004FD C3                  <1>         retn
   292                              <1> 
   293                              <1> channel_reset:
   294                              <1> 	; 14/11/2016 - Erdogan Tan
   295                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   296 000004FE 66BA01000000        <1>         mov	edx, VIA_REG_OFFSET_CONTROL
   297 00000504 66B849000000        <1>         mov     eax, VIA_REG_CTRL_PAUSE + VIA_REG_CTRL_TERMINATE + VIA_REG_CTRL_RESET
   298 0000050A E869FF              <1>         call    ctrl_io_w8
   299                              <1> 
   300                              <1>         ;mov	edx, VIA_REG_OFFSET_CONTROL
   301                              <1>         ;call   ctrl_io_r8
   302                              <1> 
   303 0000050D 66B90C000000        <1> 	mov	ecx, 12 ; 50 ms	
   304                              <1> _ch_rst_wait:
   305 00000513 6651                <1> 	push	ecx
   306 00000515 E80802              <1> 	call	delay1_4ms
   307 00000518 6659                <1> 	pop	ecx
   308 0000051A 6649                <1> 	dec	ecx
   309 0000051C 75F5                <1> 	jnz	short _ch_rst_wait     
   310                              <1> 
   311                              <1>         ; disable interrupts
   312 0000051E 66BA01000000        <1>         mov	edx, VIA_REG_OFFSET_CONTROL
   313 00000524 6631C0              <1>         xor     eax, eax
   314 00000527 E84CFF              <1>         call    ctrl_io_w8
   315                              <1> 
   316                              <1>         ; clear interrupts
   317 0000052A 66BA00000000        <1>         mov	edx, VIA_REG_OFFSET_STATUS
   318                              <1> 	;mov	eax, 3
   319 00000530 66B8FF000000        <1>         mov     eax, 0FFh ; 14/11/2016 - SC_VIA82.C (Attila Padar)
   320 00000536 E83DFF              <1>         call	ctrl_io_w8
   321                              <1> 
   322                              <1> 	; 14/11/2016 (Ref: Attila Padar, Mpxplay, SC_VIA82.C)
   323 00000539 66BA04000000        <1> 	mov	edx, VIA_REG_OFFSET_CURR_PTR
   324 0000053F 6631C0              <1> 	xor	eax, eax
   325 00000542 E83DFF              <1> 	call	ctrl_io_w32
   326                              <1> 
   327 00000545 C3                  <1>         retn
   413                                  %include 'via_wav.asm'  ; 29/11/2016
     1                              <1> ; DOS based .WAV player using AC'97 and codec interface.
     2                              <1> ; ---------------------------------------------------------------
     3                              <1> ; VIA VT8233 Modification & NASM version: Erdogan Tan (29/11/2016)
     4                              <1> ; Last Update: 18/02/2017 (by Erdogan Tan)
     5                              <1> 
     6                              <1> ; player internal variables and other equates.
     7                              <1> FILESIZE        equ     64 * 1024       ; 64k file buffer size.
     8                              <1> ENDOFFILE       equ     BIT0            ; flag for knowing end of file
     9                              <1> 
    10                              <1> ;===========================================================================
    11                              <1> ; entry: none.  File is already open and [filehandle] filled.
    12                              <1> ; exit:  not until the song is finished or the user aborts.
    13                              <1> ;
    14                              <1> playWav:
    15                              <1> 	
    16                              <1> 	; clear buffer 2
    17 00000546 06                  <1>         push	es
    18 00000547 A1[8E09]            <1> 	mov     ax, [WAV_BUFFER2]
    19 0000054A 8EC0                <1> 	mov	es, ax
    20 0000054C 29C0                <1> 	sub	ax, ax
    21 0000054E 89C7                <1> 	mov	di, ax ; 18/02/2017
    22 00000550 B90080              <1> 	mov	cx, (FILESIZE/2)
    23 00000553 F3AB                <1> 	rep	stosw
    24 00000555 07                  <1> 	pop	es	     
    25                              <1> 	
    26                              <1>        ; load 64k into buffer 1
    27                              <1> 
    28 00000556 A1[8C09]            <1>         mov     ax, [WAV_BUFFER1]
    29 00000559 E81B01              <1>         call    loadFromFile
    30                              <1> 
    31                              <1>        ; and 64k into buffer 2
    32                              <1> 
    33                              <1>        ;mov     ax, [WAV_BUFFER2]
    34                              <1>        ;call    loadFromFile
    35                              <1> 
    36                              <1> ; write last valid index to 31 to start with.
    37                              <1> ; The Last Valid Index register tells the DMA engine when to stop playing.
    38                              <1> ; 
    39                              <1> ; As we progress through the song we change the last valid index to always be
    40                              <1> ; something other than the index we're currently playing.  
    41                              <1> ;
    42                              <1>         ;;mov   al, 1
    43                              <1>         ;mov	al, 31
    44                              <1> 	;call   setLastValidIndex
    45                              <1> 
    46                              <1> ; create Buffer Descriptor List
    47                              <1> ;
    48                              <1> ; A buffer descriptor list is a list of pointers and control bits that the
    49                              <1> ; DMA engine uses to know where to get the .wav data and how to play it.
    50                              <1> ;
    51                              <1> ; I set it up to use only 2 buffers of .wav data, and whenever 1 buffer is
    52                              <1> ; playing, I refresh the other one with good data.
    53                              <1> ;
    54                              <1> ;
    55                              <1> ; For the control bits, you can specify that the DMA engine fire an interrupt
    56                              <1> ; after a buffer has been processed, but I poll the current index register
    57                              <1> ; to know when it's safe to update the other buffer.
    58                              <1> ;
    59                              <1> ; I set the BUP bit, which tells the DMA engine to just play 0's (silence)
    60                              <1> ; if it ever runs out of data to play.  Good for safety.
    61                              <1> ;
    62 0000055C 06                  <1>         push    es
    63 0000055D A1[8A09]            <1>         mov     ax, [BDL_BUFFER]		; get segment # for BDL
    64 00000560 8EC0                <1>         mov     es, ax
    65                              <1> 
    66 00000562 B91000              <1>         mov     cx, 32 / 2                      ; make 32 entries in BDL
    67 00000565 31FF                <1>         xor     di, di                          
    68                              <1> _0:
    69                              <1> 
    70                              <1> ; set buffer descriptor 0 to start of data file in memory
    71 00000567 660FB706[8C09]      <1>         movzx   eax, word [WAV_BUFFER1]
    72 0000056D 66C1E004            <1>         shl     eax, 4                          ; convert seg:off ->0:offset
    73 00000571 66AB                <1>         stosd                                   ; store pointer to wavbuffer1
    74                              <1> 
    75                              <1> ;
    76                              <1> ; set length to 32k samples.  1 sample is 16bits or 2bytes.
    77                              <1> ; Set control (bits 31:16) to BUP, bits 15:0=number of samples.
    78                              <1> ; 
    79                              <1> 
    80                              <1> ; VIA VT8235.PDF: (Page 110) (Erdogan Tan, 29/11/2016)
    81                              <1> 	;
    82                              <1> 	; 	Audio SGD Table Format
    83                              <1> 	;	-------------------------------
    84                              <1> 	;	63   62    61-56    55-32  31-0
    85                              <1> 	;	--   --   --------  -----  ----
    86                              <1> 	;	EOL FLAG -reserved- Base   Base
    87                              <1> 	;			    Count  Address
    88                              <1> 	;			    [23:0] [31:0]
    89                              <1> 	;	EOL: End Of Link. 
    90                              <1> 	;	     1 indicates this block is the last of the link.
    91                              <1> 	;	     If the channel Interrupt on EOL bit is set, then
    92                              <1> 	;	     an interrupt is generated at the end of the transfer.
    93                              <1> 	;
    94                              <1> 	;	FLAG: Block Flag. If set, transfer pauses at the end of this
    95                              <1> 	;	      block. If the channel Interrupt on FLAG bit is set,
    96                              <1> 	;	      then an interrupt is generated at the end of this block.
    97                              <1> 
    98                              <1> 	FLAG	EQU BIT30
    99                              <1> 	EOL	EQU BIT31
   100                              <1> 
   101                              <1> 	; 08/12/2016 - Erdogan Tan
   102 00000573 66B800000100        <1> 	mov	eax, FILESIZE
   103 00000579 660D00000040        <1> 	or	eax, FLAG
   104                              <1> 	;or	eax, EOL
   105 0000057F 66AB                <1> 	stosd
   106                              <1> 
   107                              <1> ; 2nd buffer:
   108                              <1> 
   109 00000581 660FB706[8E09]      <1>         movzx   eax, word [WAV_BUFFER2]
   110 00000587 66C1E004            <1>         shl     eax, 4                          ; convert seg:off ->0:offset
   111 0000058B 66AB                <1>         stosd                                   ; store pointer to wavbuffer2
   112                              <1> 
   113                              <1> ; set length to 64k (32k of two 16 bit samples)
   114                              <1> ; Set control (bits 31:16) to BUP, bits 15:0=number of samples
   115                              <1> ; 
   116                              <1> 	; 08/12/2016 - Erdogan Tan
   117 0000058D 66B800000100        <1> 	mov	eax, FILESIZE
   118 00000593 660D00000080        <1> 	or	eax, EOL
   119                              <1> 	;or	eax, FLAG
   120 00000599 66AB                <1> 	stosd
   121                              <1> 
   122 0000059B E2CA                <1>         loop    _0
   123 0000059D 07                  <1>         pop     es
   124                              <1> 
   125                              <1> ;
   126                              <1> ; tell the DMA engine where to find our list of Buffer Descriptors.
   127                              <1> ; this 32bit value is a flat mode memory offset (ie no segment:offset)
   128                              <1> ;
   129                              <1> ; write buffer descriptor list address
   130                              <1> ;
   131 0000059E 660FB706[8A09]      <1>         movzx   eax, word [BDL_BUFFER]
   132 000005A4 66C1E004            <1> 	shl     eax, 4                          ; convert seg:off to 0:off
   133                              <1>   
   134                              <1> 	; 12/11/2016 - Erdogan Tan 
   135                              <1> 	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
   136 000005A8 66BA04000000        <1> 	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_TABLE_PTR
   137 000005AE E8D1FE              <1>         call    ctrl_io_w32
   138                              <1> 
   139 000005B1 E823FF              <1> 	call	codec_check_ready
   140                              <1> 
   141 000005B4 BA0200              <1>   	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_L
   142 000005B7 66B802000000        <1>         mov     eax, 2   ;31
   143 000005BD E8B6FE              <1>         call    ctrl_io_w8
   144                              <1> 
   145 000005C0 E814FF              <1> 	call	codec_check_ready
   146                              <1> 
   147 000005C3 BA0300              <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_R
   148 000005C6 B80200              <1>         mov     ax, 2   ;31
   149 000005C9 E8AAFE              <1>         call    ctrl_io_w8
   150                              <1> 
   151 000005CC E808FF              <1> 	call	codec_check_ready
   152                              <1> ;
   153                              <1> ;
   154                              <1> ; All set.  Let's play some music.
   155                              <1> ;
   156                              <1> ;
   157                              <1>        	;mov    dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
   158                              <1>         ;mov    ax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
   159                              <1>         ;call   ctrl_io_w32
   160                              <1> 
   161                              <1> 	;call	codec_check_ready
   162                              <1> 
   163                              <1> 	; 08/12/2016
   164                              <1> 	; 07/10/2016
   165                              <1>         ;mov    al, 1
   166 000005CF B01F                <1>         mov	al, 31
   167 000005D1 E8F400              <1> 	call    setLastValidIndex
   168                              <1> 
   169 000005D4 C606[8909]01        <1> 	mov	byte [tLoop], 1 ; 30/11/2016
   170                              <1> 
   171 000005D9 B82300              <1>         mov	ax, VIA_REG_CTRL_INT
   172 000005DC 660D80000000        <1>        	or	eax, VIA_REG_CTRL_START
   173                              <1>         ;mov	ax, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START
   174                              <1> 	; 28/11/2016
   175                              <1> 	;mov	ax, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START + VIA_REG_CTRL_INT_FLAG
   176 000005E2 BA0100              <1> 	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   177 000005E5 E88EFE              <1>         call    ctrl_io_w8
   178                              <1> 
   179 000005E8 E8ECFE              <1> 	call	codec_check_ready
   180                              <1> 
   181                              <1> ; while DMA engine is running, examine current index and wait until it hits 1
   182                              <1> ; as soon as it's 1, we need to refresh the data in wavbuffer1 with another
   183                              <1> ; 64k.  Likewise when it's playing buffer 2, refresh buffer 1 and repeat.
   184                              <1>    
   185                              <1> 	; 08/12/2016
   186                              <1> 	; 28/11/2016
   187                              <1> p_loop:
   188 000005EB E82201              <1> 	call    check4keyboardstop      ; keyboard halt?
   189 000005EE 7306                <1>         jnc     short r_loop
   190                              <1> 
   191 000005F0 C606[8909]00        <1> 	mov	byte [tLoop], 0
   192 000005F5 C3                  <1> 	retn
   193                              <1> r_loop:
   194                              <1> 	; 07/12/2016 - Erdogan Tan
   195 000005F6 90                  <1> 	nop
   196 000005F7 90                  <1> 	nop
   197 000005F8 90                  <1> 	nop
   198 000005F9 31C0                <1> 	xor	ax, ax
   199 000005FB 8606[6709]          <1> 	xchg	al, [tBuff] ; AL = [tBuff], [tBuff] = 0
   200 000005FF 3C01                <1> 	cmp	al, 1
   201 00000601 72E8                <1> 	jb	short p_loop
   202 00000603 740A                <1> 	je	short q_loop
   203 00000605 A1[8E09]            <1>         mov     ax, [WAV_BUFFER2] ; [tBuff]=2 (from tuneLoop)
   204 00000608 E86C00              <1>         call    loadFromFile
   205 0000060B 7255                <1> 	jc	short _exit_
   206 0000060D EBE7                <1> 	jmp	short r_loop
   207                              <1> q_loop:
   208 0000060F A1[8C09]            <1>      	mov     ax, [WAV_BUFFER1] ; [tBuff]=1 (from tuneLoop)
   209 00000612 E86200              <1>         call    loadFromFile
   210 00000615 724B                <1> 	jc	short _exit_
   211 00000617 EBDD                <1> 	jmp	short r_loop
   212                              <1> 			
   213                              <1> tuneLoop:
   214                              <1> 	; 08/12/2016
   215                              <1> 	; 28/11/2016 - Erdogan Tan
   216                              <1> 	
   217 00000619 803E[8909]01        <1> 	cmp	byte [tLoop], 1
   218 0000061E 7247                <1> 	jb	short _exit
   219                              <1> 
   220                              <1> 	; 07/12/2016
   221 00000620 06                  <1> 	push	es 
   222 00000621 29F6                <1> 	sub	si, si
   223 00000623 B800B8              <1> 	mov	ax, 0B800h ; video display page segment
   224 00000626 8EC0                <1> 	mov	es, ax
   225 00000628 B44E                <1> 	mov	ah, 4Eh
   226 0000062A B031                <1> 	mov	al, '1'
   227                              <1> 	
   228 0000062C C606[6709]01        <1> 	mov	byte [tBuff], 1 ; Buffer 1
   229                              <1> 
   230 00000631 F606[8709]02        <1> 	test	byte [irq_status], VIA_REG_STAT_EOL 
   231 00000636 7406                <1> 	jz	short _tlp1 ; FLAG
   232                              <1> 	
   233                              <1> 	; EOL
   234 00000638 FE06[6709]          <1> 	inc	byte [tBuff] ; Buffer 2
   235 0000063C FEC0                <1> 	inc	al
   236                              <1> _tlp1: 
   237 0000063E 268904              <1> 	mov	[es:si], ax ; show playing buffer (1, 2)
   238 00000641 07                  <1> 	pop	es
   239                              <1> 
   240 00000642 F606[8709]01        <1> 	test	byte [irq_status], VIA_REG_STAT_FLAG 
   241 00000647 740F                <1> 	jz	short _tlp2
   242                              <1> 
   243 00000649 B82300              <1> 	mov	ax, VIA_REG_CTRL_INT
   244 0000064C 0D8000              <1>        	or	ax, VIA_REG_CTRL_START
   245 0000064F BA0100              <1>        	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   246 00000652 E821FE              <1>         call    ctrl_io_w8
   247                              <1> 
   248 00000655 E87FFE              <1> 	call	codec_check_ready
   249                              <1> _tlp2:	
   250 00000658 A0[8709]            <1>         mov     al, [irq_status]   ;; ack ;;
   251 0000065B BA0000              <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   252 0000065E E815FE              <1>         call    ctrl_io_w8
   253                              <1> 
   254 00000661 C3                  <1> 	retn
   255                              <1> 
   256                              <1> _exit_:
   257 00000662 C606[8909]00        <1> 	mov	byte [tLoop], 0
   258                              <1> _exit:
   259                              <1>         ; finished with song, stop everything
   260 00000667 B82300              <1> 	mov     ax, VIA_REG_CTRL_INT
   261 0000066A 83C840              <1>         or      ax, VIA_REG_CTRL_TERMINATE
   262 0000066D BA0100              <1> 	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   263 00000670 E803FE              <1>         call    ctrl_io_w8
   264                              <1> 
   265 00000673 E888FE              <1>         call	channel_reset
   266                              <1> _return:
   267 00000676 C3                  <1> 	retn
   268                              <1> 
   269                              <1> ; load data from file in 32k chunks.  Would be nice to load 1 64k chunk,
   270                              <1> ; but in DOS you can only load FFFF bytes at a time.
   271                              <1> ;
   272                              <1> ; entry: ax = segment to load data to
   273                              <1> ; exit: CY set if end of file reached.
   274                              <1> ; note: last file buffer is padded with 0's to avoid pops at the end of song.
   275                              <1> ; assumes file is already open.  uses [filehandle]
   276                              <1> ;
   277                              <1> loadFromFile:
   278 00000677 50                  <1>         push    ax
   279 00000678 51                  <1>         push    cx
   280 00000679 52                  <1>         push    dx
   281                              <1> 	;push	es
   282 0000067A 1E                  <1> 	push	ds
   283                              <1> 	
   284                              <1> 	;push	ds				; copy es->ds since we
   285                              <1> 	;pop	es				; mess with DS
   286                              <1> 
   287                              <1>         ;test   byte [es:flags], ENDOFFILE	; have we already read the
   288 0000067B F606[8609]01        <1>         test    byte [flags], ENDOFFILE
   289 00000680 F9                  <1>         stc					; last of the file?
   290 00000681 7532                <1>         jnz     short endLFF
   291                              <1>         
   292 00000683 8ED8                <1> 	mov     ds, ax
   293 00000685 31D2                <1>         xor     dx, dx                          ; load file into memory
   294 00000687 B90080              <1>         mov     cx, (FILESIZE / 2)              ; 32k chunk
   295 0000068A B43F                <1> 	mov	ah, 3fh
   296 0000068C 2E8B1E[8409]        <1> 	mov	bx, [cs:filehandle]
   297 00000691 CD21                <1> 	int	21h
   298                              <1>         
   299 00000693 F8                  <1> 	clc
   300 00000694 39C8                <1>         cmp	ax, cx
   301                              <1> 	;je	short _lff1
   302 00000696 7513                <1> 	jne	short _lff1
   303                              <1> 
   304                              <1> ;       or      byte [es:flags], ENDOFFILE      ; flag end of file
   305                              <1> ;       call    padfill                         ; blank pad the remainder
   306                              <1> ;       clc                                     ; don't exit with CY yet.
   307                              <1> ;       jmp	short endLFF
   308                              <1> ;_lff1:
   309 00000698 01C2                <1>         add     dx, ax
   310                              <1> 
   311 0000069A B90080              <1>         mov     cx, (FILESIZE / 2)              ; 32k chunk
   312 0000069D B43F                <1> 	mov	ah, 3fh
   313 0000069F 2E8B1E[8409]        <1> 	mov	bx, [cs:filehandle]
   314 000006A4 CD21                <1> 	int	21h
   315 000006A6 F8                  <1>         clc
   316 000006A7 39C8                <1>         cmp     ax, cx
   317 000006A9 740A                <1>         je      short endLFF
   318                              <1> _lff1:
   319                              <1>         ;or     byte [es:flags], ENDOFFILE      ; flag end of file
   320 000006AB 2E800E[8609]01      <1>         or	byte [cs:flags], ENDOFFILE
   321 000006B1 E80600              <1> 	call    padfill                         ; blank pad the remainder
   322 000006B4 F8                  <1>         clc                                     ; don't exit with CY yet.
   323                              <1> endLFF:
   324 000006B5 1F                  <1>         pop	ds
   325                              <1> 	;pop	es
   326 000006B6 5A                  <1> 	pop     dx
   327 000006B7 59                  <1>         pop     cx
   328 000006B8 58                  <1>         pop     ax
   329 000006B9 C3                  <1>         retn
   330                              <1> 
   331                              <1> ; entry ds:ax points to last byte in file
   332                              <1> ; cx=target size
   333                              <1> ; note: must do byte size fill
   334                              <1> ; destroys bx, cx
   335                              <1> ;
   336                              <1> padfill:
   337 000006BA 53                  <1>         push    bx
   338 000006BB 29C1                <1>         sub     cx, ax
   339 000006BD 89C3                <1>         mov     bx, ax
   340 000006BF 30C0                <1>         xor     al, al
   341                              <1> padfloop:
   342 000006C1 8807                <1>         mov     [bx], al
   343 000006C3 43                  <1>         inc     bx
   344 000006C4 E2FB                <1>         loop    padfloop
   345 000006C6 5B                  <1>         pop     bx
   346 000006C7 C3                  <1>         retn
   347                              <1> 
   348                              <1> ;; returns AL = current index value
   349                              <1> ;getCurrentIndex:
   350                              <1> ;	; 14/11/2016 - Erdogan Tan (Ref: VIA VT8235.PDF, Page 110)
   351                              <1> ;	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   352                              <1> ;	;push	edx
   353                              <1> ;	mov	edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CURR_INDEX
   354                              <1> ;       call    ctrl_io_r8
   355                              <1> ;	; AL = Current index
   356                              <1> ;	;pop	edx
   357                              <1> ;	retn
   358                              <1> 	
   359                              <1> ;input AL = index # to stop on
   360                              <1> setLastValidIndex:
   361                              <1> 	; 19/11/2016
   362                              <1> 	; 14/11/2016 - Erdogan Tan (Ref: VIA VT8235.PDF, Page 110)
   363                              <1> 	; 12/11/2016 - Erdogan Tan
   364                              <1> 	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
   365                              <1> 	;push	edx
   366 000006C8 50                  <1> 	push	ax
   367                              <1> 	;push	ecx
   368 000006C9 660FB706[A009]      <1> 	movzx	eax, word [sample_rate] ; Hertz
   369 000006CF 66BA00001000        <1> 	mov	edx, 100000h ; 2^20 = 1048576
   370 000006D5 66F7E2              <1> 	mul	edx
   371 000006D8 66B980BB0000        <1> 	mov	ecx, 48000	
   372 000006DE 66F7F1              <1> 	div	ecx
   373                              <1> 	;and	eax, 0FFFFFh
   374                              <1> 	;pop	ecx
   375 000006E1 5A                  <1> 	pop	dx 
   376 000006E2 66C1E218            <1> 	shl	edx, 24  ; STOP Index Setting: Bit 24 to 31
   377 000006E6 6609D0              <1> 	or	eax, edx
   378                              <1> 	; 19/11/2016
   379 000006E9 803E[A309]10        <1> 	cmp	byte [bps], 16
   380 000006EE 7506                <1> 	jne	short sLVI_1
   381 000006F0 660D00002000        <1> 	or	eax, VIA8233_REG_TYPE_16BIT
   382                              <1> sLVI_1:
   383 000006F6 803E[A209]02        <1> 	cmp	byte [stmo], 2
   384 000006FB 7506                <1> 	jne	short sLVI_2
   385 000006FD 660D00001000        <1> 	or	eax, VIA8233_REG_TYPE_STEREO
   386                              <1> sLVI_2:
   387 00000703 66BA08000000        <1> 	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
   388 00000709 E876FD              <1>         call    ctrl_io_w32
   389 0000070C E8C8FD              <1> 	call	codec_check_ready
   390                              <1> 	;pop	edx
   391 0000070F C3                  <1> 	retn
   392                              <1> 
   393                              <1> ; checks if either shift key has been pressed.  Exits with CY if so.
   394                              <1> ; 
   395                              <1> check4keyboardstop:
   396 00000710 06                  <1>         push    es
   397 00000711 6A00                <1>         push    0
   398 00000713 07                  <1>         pop     es		       ; examine BDA for keyboard flags
   399 00000714 26F606170403        <1>         test    byte [es:417h], (BIT0 | BIT1)
   400 0000071A 07                  <1>         pop     es
   401 0000071B F9                  <1>         stc
   402 0000071C 7501                <1>         jnz     short _cksr
   403 0000071E F8                  <1>         clc
   404                              <1> _cksr:
   405 0000071F C3                  <1>         retn
   414                                  
   415                                  ; UTILS.ASM
   416                                  ;----------------------------------------------------------------------------
   417                                  ;       delay1_4ms - Delay for 1/4 millisecond.
   418                                  ;		    1mS = 1000us
   419                                  ;       Entry:
   420                                  ;         None
   421                                  ;       Exit:
   422                                  ;	  None
   423                                  ;
   424                                  ;       Modified:
   425                                  ;         None
   426                                  ;
   427                                  PORTB			EQU	061h
   428                                    REFRESH_STATUS	EQU	010h		; Refresh signal status
   429                                  
   430                                  delay1_4ms:
   431 00000720 50                              push    ax 
   432 00000721 51                              push    cx
   433 00000722 B91000                          mov     cx, 16			; close enough.
   434 00000725 E461                    	in	al,PORTB
   435 00000727 2410                    	and	al,REFRESH_STATUS
   436 00000729 88C4                    	mov	ah,al			; Start toggle state
   437 0000072B 09C9                    	or	cx, cx
   438 0000072D 7401                    	jz	short _d4ms1
   439 0000072F 41                      	inc	cx			; Throwaway first toggle
   440                                  _d4ms1:	
   441 00000730 E461                    	in	al,PORTB		; Read system control port
   442 00000732 2410                    	and	al,REFRESH_STATUS	; Refresh toggles 15.085 microseconds
   443 00000734 38C4                    	cmp	ah,al
   444 00000736 74F8                    	je	short _d4ms1		; Wait for state change
   445                                  
   446 00000738 88C4                    	mov	ah,al			; Update with new state
   447 0000073A 49                      	dec	cx
   448 0000073B 75F3                    	jnz	short _d4ms1
   449                                  
   450 0000073D 59                              pop     cx
   451 0000073E 58                              pop     ax
   452 0000073F C3                              retn
   453                                  
   454                                  	; 13/11/2016 - Erdogan Tan
   455                                  write_ac97_dev_info:
   456                                  	; BUS/DEV/FN
   457                                  	;	00000000BBBBBBBBDDDDDFFF00000000
   458                                  	; DEV/VENDOR
   459                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
   460                                  
   461 00000740 30FF                    	xor	bh, bh
   462 00000742 668B36[9609]            	mov	esi, [dev_vendor]
   463 00000747 89F0                    	mov	ax, si
   464 00000749 88C3                    	mov	bl, al
   465 0000074B 88DA                    	mov	dl, bl
   466 0000074D 80E30F                  	and	bl, 0Fh
   467 00000750 8A87[B409]              	mov	al, [bx+hex_chars]
   468 00000754 A2[F709]                	mov	[msgVendorId+3], al
   469 00000757 88D3                    	mov	bl, dl
   470 00000759 C0EB04                  	shr	bl, 4
   471 0000075C 8A87[B409]              	mov	al, [bx+hex_chars]
   472 00000760 A2[F609]                	mov	[msgVendorId+2], al
   473 00000763 88E3                    	mov	bl, ah
   474 00000765 88DA                    	mov	dl, bl
   475 00000767 80E30F                  	and	bl, 0Fh
   476 0000076A 8A87[B409]              	mov	al, [bx+hex_chars]
   477 0000076E A2[F509]                	mov	[msgVendorId+1], al
   478 00000771 88D3                    	mov	bl, dl
   479 00000773 C0EB04                  	shr	bl, 4
   480 00000776 8A87[B409]              	mov	al, [bx+hex_chars]
   481 0000077A A2[F409]                	mov	[msgVendorId], al
   482 0000077D 66C1EE10                	shr	esi, 16
   483 00000781 89F0                    	mov	ax, si
   484 00000783 88C3                    	mov	bl, al
   485 00000785 88DA                    	mov	dl, bl
   486 00000787 80E30F                  	and	bl, 0Fh
   487 0000078A 8A87[B409]              	mov	al, [bx+hex_chars]
   488 0000078E A2[080A]                	mov	[msgDevId+3], al
   489 00000791 88D3                    	mov	bl, dl
   490 00000793 C0EB04                  	shr	bl, 4
   491 00000796 8A87[B409]              	mov	al, [bx+hex_chars]
   492 0000079A A2[070A]                	mov	[msgDevId+2], al
   493 0000079D 88E3                    	mov	bl, ah
   494 0000079F 88DA                    	mov	dl, bl
   495 000007A1 80E30F                  	and	bl, 0Fh
   496 000007A4 8A87[B409]              	mov	al, [bx+hex_chars]
   497 000007A8 A2[060A]                	mov	[msgDevId+1], al
   498 000007AB 88D3                    	mov	bl, dl
   499 000007AD C0EB04                  	shr	bl, 4
   500 000007B0 8A87[B409]              	mov	al, [bx+hex_chars]
   501 000007B4 A2[050A]                	mov	[msgDevId], al
   502                                  
   503 000007B7 668B36[9209]            	mov	esi, [bus_dev_fn]
   504 000007BC 66C1EE08                	shr	esi, 8
   505 000007C0 89F0                    	mov	ax, si
   506 000007C2 88C3                    	mov	bl, al
   507 000007C4 88DA                    	mov	dl, bl
   508 000007C6 80E307                  	and	bl, 7 ; bit 0,1,2
   509 000007C9 8A87[B409]              	mov	al, [bx+hex_chars]
   510 000007CD A2[2C0A]                	mov	[msgFncNo+1], al
   511 000007D0 88D3                    	mov	bl, dl
   512 000007D2 C0EB03                  	shr	bl, 3
   513 000007D5 88DA                    	mov	dl, bl
   514 000007D7 80E30F                  	and	bl, 0Fh
   515 000007DA 8A87[B409]              	mov	al, [bx+hex_chars]
   516 000007DE A2[1E0A]                	mov	[msgDevNo+1], al
   517 000007E1 88D3                    	mov	bl, dl
   518 000007E3 C0EB04                  	shr	bl, 4
   519 000007E6 8A87[B409]              	mov	al, [bx+hex_chars]
   520 000007EA A2[1D0A]                	mov	[msgDevNo], al
   521 000007ED 88E3                    	mov	bl, ah
   522 000007EF 88DA                    	mov	dl, bl
   523 000007F1 80E30F                  	and	bl, 0Fh
   524 000007F4 8A87[B409]              	mov	al, [bx+hex_chars]
   525 000007F8 A2[120A]                	mov	[msgBusNo+1], al
   526 000007FB 88D3                    	mov	bl, dl
   527 000007FD C0EB04                  	shr	bl, 4
   528 00000800 8A87[B409]              	mov	al, [bx+hex_chars]
   529 00000804 A2[110A]                	mov	[msgBusNo], al
   530                                  
   531 00000807 A1[9E09]                	mov	ax, [ac97_io_base]
   532 0000080A 88C3                    	mov	bl, al
   533 0000080C 88DA                    	mov	dl, bl
   534 0000080E 80E30F                  	and	bl, 0Fh
   535 00000811 8A87[B409]              	mov	al, [bx+hex_chars]
   536 00000815 A2[450A]                	mov	[msgIOBaseAddr+3], al
   537 00000818 88D3                    	mov	bl, dl
   538 0000081A C0EB04                  	shr	bl, 4
   539 0000081D 8A87[B409]              	mov	al, [bx+hex_chars]
   540 00000821 A2[440A]                	mov	[msgIOBaseAddr+2], al
   541 00000824 88E3                    	mov	bl, ah
   542 00000826 88DA                    	mov	dl, bl
   543 00000828 80E30F                  	and	bl, 0Fh
   544 0000082B 8A87[B409]              	mov	al, [bx+hex_chars]
   545 0000082F A2[430A]                	mov	[msgIOBaseAddr+1], al
   546 00000832 88D3                    	mov	bl, dl
   547 00000834 C0EB04                  	shr	bl, 4
   548 00000837 8A87[B409]              	mov	al, [bx+hex_chars]
   549 0000083B A2[420A]                	mov	[msgIOBaseAddr], al
   550                                  
   551                                  	; 24/11/2016
   552 0000083E 30E4                    	xor	ah, ah
   553 00000840 A0[9009]                	mov	al, [ac97_int_ln_reg]
   554 00000843 B10A                    	mov	cl, 10
   555 00000845 F6F1                    	div	cl
   556 00000847 0106[4D0A]              	add	[msgIRQ], ax
   557 0000084B 20C0                    	and	al, al
   558 0000084D 7508                    	jnz	short _pmi
   559 0000084F A0[4E0A]                	mov	al, [msgIRQ+1]
   560 00000852 B420                    	mov	ah, ' '
   561 00000854 A3[4D0A]                	mov	[msgIRQ], ax
   562                                  _pmi:
   563 00000857 BA[C509]                        mov	dx, msgAC97Info
   564 0000085A B409                            mov     ah, 9
   565 0000085C CD21                            int     21h
   566 0000085E C3                              retn
   567                                  
   568                                  write_sample_rate:
   569                                  	; ax = sample rate (hertz)
   570                                  
   571 0000085F 31D2                    	xor	dx, dx
   572 00000861 B90A00                  	mov	cx, 10
   573 00000864 F7F1                    	div	cx
   574 00000866 0016[630A]              	add	[msgHertz+4], dl
   575 0000086A 29D2                    	sub	dx, dx
   576 0000086C F7F1                    	div	cx
   577 0000086E 0016[620A]              	add	[msgHertz+3], dl
   578 00000872 29D2                    	sub	dx, dx
   579 00000874 F7F1                    	div	cx
   580 00000876 0016[610A]              	add	[msgHertz+2], dl
   581 0000087A 29D2                    	sub	dx, dx
   582 0000087C F7F1                    	div	cx
   583 0000087E 0016[600A]              	add	[msgHertz+1], dl
   584 00000882 0006[5F0A]              	add	[msgHertz], al
   585                                  	
   586 00000886 BA[520A]                        mov     dx, msgSampleRate
   587 00000889 B409                            mov     ah, 9
   588 0000088B CD21                            int     21h
   589                                  
   590                                  	; 19/11/2016
   591 0000088D BA[780A]                	mov	dx, msg16Bits
   592 00000890 803E[A309]10            	cmp	byte [bps], 16
   593 00000895 7403                    	je	short wsr_1
   594 00000897 BA[690A]                	mov	dx, msg8Bits
   595                                  wsr_1:
   596 0000089A B409                            mov     ah, 9
   597 0000089C CD21                            int     21h
   598                                  
   599 0000089E BA[710A]                	mov	dx, msgMono
   600 000008A1 803E[A209]01            	cmp	byte [stmo], 1
   601 000008A6 7403                    	je	short wsr_2
   602 000008A8 BA[810A]                	mov	dx, msgStereo		
   603                                  wsr_2:
   604 000008AB B409                            mov     ah, 9
   605 000008AD CD21                            int     21h
   606                                  
   607 000008AF C3                              retn
   608                                  
   609                                  ;detect_codec:
   610                                  ;	; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   611                                  ;	mov	eax, 7Ch
   612                                  ;	call	codec_read
   613                                  ;       shl     eax, 16
   614                                  ;       mov     [codec_id], eax
   615                                  ;
   616                                  ;	mov	eax, 7Eh
   617                                  ;       call	codec_read
   618                                  ;       or      eax, [codec_id]
   619                                  ;       mov     [codec_chip_id], eax
   620                                  ;       and     eax, 0FFFFFF00h
   621                                  ;
   622                                  ;       mov     edi, codecs
   623                                  ;_dcb:
   624                                  ;       mov     ebx, [di]
   625                                  ;       test    ebx, ebx
   626                                  ;       jz      short _dco_unknown
   627                                  ;
   628                                  ;       cmp     eax, ebx
   629                                  ;       jne     short _dco_next
   630                                  ;       mov     ax, [di+4]
   631                                  ;       mov     [codec_vendor_ids], ax
   632                                  ;       movzx   esi, ax
   633                                  ;       call	print_msg
   634                                  ;       
   635                                  ;	mov	ax, [di+6]
   636                                  ;	call	detect_chip
   637                                  ;       retn
   638                                  ;
   639                                  ;_dco_next:
   640                                  ;       add     di, 8
   641                                  ;       jmp     short _dcb
   642                                  ;
   643                                  ;_dco_unknown:
   644                                  ;       mov    word [codec_vendor_ids], ac_unknown
   645                                  ;       mov    word [codec_chip_ids], chip_unknown
   646                                  ;       mov     esi, chip_unknown
   647                                  ;	call	print_msg
   648                                  ;       mov     eax, [codec_chip_id]
   649                                  ;       call    dword2str
   650                                  ;       call	print_msg
   651                                  ;       retn
   652                                  
   653                                  ;detect_chip:
   654                                  ;	; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   655                                  ;	mov	di, ax ; chip_tab
   656                                  ;       mov     eax, [codec_chip_id]
   657                                  ;       and     ax, 0FFh
   658                                  ;_dch1:
   659                                  ;       mov     bx, [di]
   660                                  ;       cmp     bx, 0FFh
   661                                  ;       je      short _dch_unknown
   662                                  ;
   663                                  ;       cmp     ax, bx
   664                                  ;       jne     short _dch_next
   665                                  ;       mov     ax, [di+2]
   666                                  ;       mov     [codec_chip_ids], ax
   667                                  ;       mov     si, ax
   668                                  ;       call	print_msg
   669                                  ;       retn
   670                                  
   671                                  ;_dch_next:
   672                                  ;       add     di, 4
   673                                  ;       jmp     short _dch1
   674                                  ;
   675                                  ;_dch_unknown:
   676                                  ;       mov    word [codec_chip_ids], chip_unknown
   677                                  ;       mov     si, chip_unknown
   678                                  ;       call	print_msg
   679                                  ;       mov     eax, [codec_chip_id]
   680                                  ;       call    dword2str
   681                                  ;       call	print_msg
   682                                  ;       retn
   683                                  
   684                                  ac97_int_handler:
   685 000008B0 50                      	push	ax
   686 000008B1 52                      	push	dx
   687 000008B2 51                      	push	cx
   688 000008B3 53                      	push	bx
   689 000008B4 56                      	push	si
   690 000008B5 57                      	push	di
   691                                  
   692                                  	; 28/11/2016
   693 000008B6 803E[8809]01            	cmp	byte [uLVI], 1
   694 000008BB 7337                    	jnb	short _busy
   695                                  
   696 000008BD C606[8809]01            	mov	byte [uLVI], 1
   697                                  
   698 000008C2 C606[8709]00            	mov	byte [irq_status], 0
   699                                  
   700 000008C7 BA0000                          mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   701 000008CA E8AFFB                          call    ctrl_io_r8
   702                                  
   703 000008CD A880                    	test    al, VIA_REG_STAT_ACTIVE
   704 000008CF 740A                            jz      short _ih0
   705                                  
   706 000008D1 2407                            and     al, VIA_REG_STAT_EOL + VIA_REG_STAT_FLAG + VIA_REG_STAT_STOPPED
   707 000008D3 A2[8709]                	mov	[irq_status], al
   708 000008D6 7403                            jz	short _ih0
   709                                  
   710                                  	; 28/11/2016 - Erdogan Tan
   711 000008D8 E83EFD                  	call	tuneLoop
   712                                  _ih0:
   713 000008DB C606[8809]00            	mov	byte [uLVI], 0
   714                                  _p_i_retn:
   715 000008E0 B020                    	mov	al, 20h
   716 000008E2 F606[9009]08            	test	byte [ac97_int_ln_reg], 8
   717 000008E7 7402                    	jz	short _ih_1
   718 000008E9 E6A0                    	out 	0A0h, al ; 20h ; EOI
   719                                  _ih_1:
   720 000008EB E620                    	out	20h, al  ; 20h ; EOI
   721                                  _ih_2:
   722 000008ED 5F                      	pop	di
   723 000008EE 5E                      	pop	si
   724 000008EF 5B                      	pop	bx
   725 000008F0 59                      	pop	cx
   726 000008F1 5A                      	pop	dx
   727 000008F2 58                      	pop	ax
   728 000008F3 CF                      	iret
   729                                  
   730                                  _busy:
   731                                  	; 28/11/2016 - Erdogan Tan
   732 000008F4 A0[8709]                        mov     al, [irq_status]   ;; ack ;;
   733 000008F7 BA0000                          mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   734 000008FA E879FB                          call    ctrl_io_w8
   735                                  
   736 000008FD EBDC                    	jmp	short _ih0
   737                                  
   738                                  print_msg:
   739                                  	; 13/11/2016 - Erdogan Tan 
   740                                  	; esi = ASCIIZ text address
   741                                  	;
   742 000008FF BB0700                  	mov	bx, 7h
   743 00000902 B40E                    	mov	ah, 0Eh 
   744                                  pm_next_char:
   745 00000904 AC                      	lodsb
   746 00000905 20C0                    	and	al, al
   747 00000907 7404                    	jz	short pm_retn
   748 00000909 CD10                    	int	10h
   749 0000090B EBF7                    	jmp	short pm_next_char
   750                                  pm_retn:
   751 0000090D C3                      	retn
   752                                  
   753                                  dword2str:
   754                                  	; 13/11/2016 - Erdogan Tan 
   755                                  	; eax = dword value
   756                                  	;
   757 0000090E E84400                  	call	dwordtohex
   758 00000911 668916[8A0A]            	mov	[dword_str], edx
   759 00000916 66A3[8E0A]              	mov	[dword_str+4], eax
   760 0000091A BE[8A0A]                	mov	si, dword_str
   761 0000091D C3                      	retn
   762                                  
   763                                  	; trdos386.s (unix386.s) - 10/05/2015
   764                                  	; Convert binary number to hexadecimal string
   765                                  
   766                                  bytetohex:
   767                                  	; INPUT ->
   768                                  	; 	AL = byte (binary number)
   769                                  	; OUTPUT ->
   770                                  	;	AX = hexadecimal string
   771                                  	;
   772 0000091E 53                      	push	bx
   773 0000091F 30FF                    	xor	bh, bh
   774 00000921 88C3                    	mov	bl, al
   775 00000923 C0EB04                  	shr	bl, 4
   776 00000926 8A9F[B409]              	mov	bl, [bx+hex_chars] 	 	
   777 0000092A 86D8                    	xchg	bl, al
   778 0000092C 80E30F                  	and	bl, 0Fh
   779 0000092F 8AA7[B409]              	mov	ah, [bx+hex_chars] 
   780 00000933 5B                      	pop	bx	
   781 00000934 C3                      	retn
   782                                  
   783                                  wordtohex:
   784                                  	; INPUT ->
   785                                  	; 	AX = word (binary number)
   786                                  	; OUTPUT ->
   787                                  	;	EAX = hexadecimal string
   788                                  	;
   789 00000935 53                      	push	bx
   790 00000936 30FF                    	xor	bh, bh
   791 00000938 86E0                    	xchg	ah, al
   792 0000093A 50                      	push	ax
   793 0000093B 88E3                    	mov	bl, ah
   794 0000093D C0EB04                  	shr	bl, 4
   795 00000940 8A87[B409]              	mov	al, [bx+hex_chars] 	 	
   796 00000944 88E3                    	mov	bl, ah
   797 00000946 80E30F                  	and	bl, 0Fh
   798 00000949 8AA7[B409]              	mov	ah, [bx+hex_chars]
   799 0000094D 66C1E010                	shl	eax, 16
   800 00000951 58                      	pop	ax
   801 00000952 5B                      	pop	bx
   802 00000953 EBC9                    	jmp	short bytetohex
   803                                  
   804                                  dwordtohex:
   805                                  	; INPUT ->
   806                                  	; 	EAX = dword (binary number)
   807                                  	; OUTPUT ->
   808                                  	;	EDX:EAX = hexadecimal string
   809                                  	;
   810 00000955 6650                    	push	eax
   811 00000957 66C1E810                	shr	eax, 16
   812 0000095B E8D7FF                  	call	wordtohex
   813 0000095E 6689C2                  	mov	edx, eax
   814 00000961 6658                    	pop	eax
   815 00000963 E8CFFF                  	call	wordtohex
   816 00000966 C3                      	retn
   817                                  
   818                                  _DATA:
   819                                  
   820 00000967 02                      tBuff	db 2	; 08/12/2016
   821                                  
   822                                  ; 28/11/2016
   823                                  align 2
   824                                  
   825 00000968 0000<rept>              smpRBuff	times 14 dw 0 ; 19/11/2016 - Erdogan Tan
   826                                  
   827 00000984 0000                    filehandle	dw	0
   828                                  
   829 00000986 00                      flags	   db 0
   830 00000987 00                      irq_status db 0
   831                                  
   832 00000988 00                      uLVI	db 0
   833 00000989 00                      tLoop	db 0
   834                                  
   835                                  ; 256 byte buffer for descriptor list
   836 0000098A 0000                    BDL_BUFFER      dw      0               ; segment of our 256byte BDL buffer
   837 0000098C 0000                    WAV_BUFFER1     dw      0               ; segment of our WAV storage
   838                                  ; 64k buffers for wav file storage
   839 0000098E 0000                    WAV_BUFFER2	dw	0		; segment of 2nd wav buffer
   840                                  
   841                                  ; 12/11/2016 - Erdogan Tan
   842                                  
   843 00000990 00                      ac97_int_ln_reg db	0 
   844 00000991 00                      err_num		db 	0
   845                                  
   846 00000992 00000000                bus_dev_fn	dd	0
   847 00000996 00000000                dev_vendor	dd	0
   848 0000099A 00000000                stats_cmd	dd	0
   849 0000099E 0000                    ac97_io_base	dw	0
   850 000009A0 0000                    sample_rate	dw	0
   851                                  ; 19/11/2016
   852 000009A2 00                      stmo		db	0 
   853 000009A3 00                      bps		db	0
   854                                  
   855                                  ; 24/11/2016
   856                                  ;	       IRQ  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 
   857 000009A4 08090A0B0C0D0E0F70-     irq_int		db 08h,09h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,70h,71h,72h,73h,74h,75h,76h,77h
   857 000009AD 71727374757677     
   858                                  
   859                                  ; 13/11/2016
   860 000009B4 303132333435363738-     hex_chars	db "0123456789ABCDEF", 0
   860 000009BD 3941424344454600   
   861 000009C5 414339372041756469-     msgAC97Info	db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah 
   861 000009CE 6F20436F6E74726F6C-
   861 000009D7 6C6572202620436F64-
   861 000009E0 656320496E666F0D0A 
   862 000009E9 56656E646F72204944-     		db "Vendor ID: "
   862 000009F2 3A20               
   863 000009F4 303030306820446576-     msgVendorId	db "0000h Device ID: "
   863 000009FD 6963652049443A20   
   864 00000A05 30303030680D0A          msgDevId	db "0000h", 0Dh, 0Ah
   865 00000A0C 4275733A20              		db "Bus: "
   866 00000A11 303068204465766963-     msgBusNo	db "00h Device: "
   866 00000A1A 653A20             
   867 00000A1D 3030682046756E6374-     msgDevNo	db "00h Function: "
   867 00000A26 696F6E3A20         
   868 00000A2B 303068                  msgFncNo	db "00h"
   869 00000A2E 0D0A                    		db 0Dh, 0Ah
   870 00000A30 492F4F204261736520-     		db "I/O Base Address: "
   870 00000A39 416464726573733A20 
   871 00000A42 303030306820495251-     msgIOBaseAddr	db "0000h IRQ: "
   871 00000A4B 3A20               
   872 00000A4D 3030                    msgIRQ		dw 3030h
   873 00000A4F 0D0A24                  		db 0Dh, 0Ah, "$"
   874 00000A52 53616D706C65205261-     msgSampleRate	db "Sample Rate: "
   874 00000A5B 74653A20           
   875 00000A5F 303030303020487A20-     msgHertz	db "00000 Hz ", "$" 
   875 00000A68 24                 
   876 00000A69 3820626974732024        msg8Bits	db "8 bits ", "$" 
   877 00000A71 4D6F6E6F0D0A24          msgMono		db "Mono", 0Dh, 0Ah, "$"
   878 00000A78 313620626974732024      msg16Bits	db "16 bits ", "$" 
   879 00000A81 53746572656F0D0A24      msgStereo	db "Stereo", 0Dh, 0Ah, "$"
   880                                  
   881                                  ;; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   882                                  ;codec_id	dd 0
   883                                  ;codec_chip_id	dd 0
   884                                  ;codec_vendor_ids dw 0
   885                                  ;codec_chip_ids	dw 0
   886                                  
   887 00000A8A 3030303030303030        dword_str	 dd 30303030h, 30303030h
   888 00000A92 680D0A00                		 db 'h', 0Dh, 0Ah, 0
   889                                  
   890                                  ;ac_unknown     db 'unknown manufacturer',13,10,0
   891                                  ;ac_Realtek     db 'Realtek Semiconductor',13,10,0
   892                                  ;ac_Analog      db 'Analog Devices',13,10,0
   893                                  ;ac_CMedia      db 'C-Media Electronics',13,10,0
   894                                  ;ac_Cirrus      db 'Cirrus Logic',13,10,0
   895                                  ;ac_Wolfson     db 'Wolfson Microelectronics',13,10,0
   896                                  ;ac_VIA         db 'VIA Technologies',13,10,0
   897                                  ;ac_SigmaTel    db 'SigmaTel',13,10,0
   898                                  ;ac_eMicro      db 'eMicro',13,10,0
   899                                  ;
   900                                  ;chip_unknown   db 'unknown codec id ', 0
   901                                  
   902                                  ;CHIP_REALTEK   equ 414C4700h
   903                                  ;CHIP_CMEDIA    equ 434D4900h
   904                                  ;CHIP_VIA       equ 56494100h
   905                                  
   906                                  ;codecs        dd CHIP_CMEDIA
   907                                  ;	       dw ac_CMedia, chips_CMedia
   908                                  ;              dd CHIP_REALTEK
   909                                  ;	       dw ac_Realtek, chips_Realtek
   910                                  ;              dd CHIP_VIA
   911                                  ;	       dw ac_VIA, chips_VIA
   912                                  ;              dd 0
   913                                  
   914                                  ;chips_Realtek dw 10h, chip_ALC201a
   915                                  ;              dw 20h, chip_ALC650
   916                                  ;              dw 21h, chip_ALC650D
   917                                  ;              dw 22h, chip_ALC650E
   918                                  ;              dw 23h, chip_ALC650F
   919                                  ;              dw 60h, chip_ALC655
   920                                  ;              dw 80h, chip_ALC658
   921                                  ;              dw 81h, chip_ALC658D
   922                                  ;              dw 90h, chip_ALC850
   923                                  ;              dw 0FFh
   924                                  
   925                                  ;chips_CMedia  dw 41h, chip_CM9738
   926                                  ;              dw 61h, chip_CM9739
   927                                  ;              dw 69h, chip_CM9780
   928                                  ;              dw 78h, chip_CM9761
   929                                  ;              dw 82h, chip_CM9761
   930                                  ;              dw 83h, chip_CM9761
   931                                  ;              dw 0FFh
   932                                  
   933                                  ;chips_VIA     dw 61h, chip_VIA1612A
   934                                  ;              dw 0FFh
   935                                  
   936                                  ;Realtek
   937                                  ;chip_ALC201a    db 'ALC201a',0dh,0ah,00h
   938                                  ;chip_ALC650     db 'ALC650 ',0dh,0ah,00h
   939                                  ;chip_ALC650D    db 'ALC650D',0dh,0ah,00h
   940                                  ;chip_ALC650E    db 'ALC650E',0dh,0ah,00h
   941                                  ;chip_ALC650F    db 'ALC650F',0dh,0ah,00h
   942                                  ;chip_ALC655     db 'ALC655 ',0dh,0ah,00h
   943                                  ;chip_ALC658     db 'ALC658 ',0dh,0ah,00h
   944                                  ;chip_ALC658D    db 'ALC658D',0dh,0ah,00h
   945                                  ;chip_ALC850     db 'ALC850 ',0dh,0ah,00h
   946                                  
   947                                  ;CMedia
   948                                  ;chip_CM9738     db 'CMI9738', 0dh,0ah,0
   949                                  ;chip_CM9739     db 'CMI9739', 0dh,0ah,0
   950                                  ;chip_CM9780     db 'CMI9780', 0dh,0ah,0
   951                                  ;chip_CM9761     db 'CMI9761', 0dh,0ah,0
   952                                  
   953                                  ;VIA
   954                                  ;chip_VIA1612A   db 'VIA1612A',13,10,0
