     1                                  ; ****************************************************************************
     2                                  ; PLAYER.ASM - VIA VT8233 .wav player for DOS.			    PLAYER.COM
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 24/03/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 E86D01                          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 E87B01                          call    memAlloc
    31 00000009 A3[7E09]                        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 E87201                          call    memAlloc
    37 00000012 A3[8009]                        mov     [WAV_BUFFER1], ax		; segment
    38                                  
    39 00000015 B80010                  	mov	ax, FILESIZE / 16
    40 00000018 E86901                  	call	memAlloc
    41 0000001B A3[8209]                	mov	[WAV_BUFFER2], ax
    42                                  
    43                                  ; Detect/reset AC97 
    44                                  ;
    45 0000001E 66B806115930                    mov     eax, (VT8233_DID << 16) + VIA_VID
    46 00000024 E8E402                          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 E93401                          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[8609]              	mov	[bus_dev_fn], eax
    75 00000070 668916[8A09]            	mov	[dev_vendor], edx
    76                                  
    77                                  	; init controller
    78 00000075 B004                    	mov	al, PCI_CMD_REG ; command register (04h)
    79 00000077 E80702                  	call	pciRegRead32
    80                                  
    81                                  	; eax = BUS/DEV/FN/REG
    82                                  	; edx = STATUS/COMMAND
    83                                  	; 	SSSSSSSSSSSSSSSSCCCCCCCCCCCCCCCC
    84 0000007A 668916[8E09]            	mov	[stats_cmd], edx
    85                                  
    86 0000007F B010                    	mov	al, PCI_IO_BASE ; IO base address register (10h)
    87 00000081 E8FD01                  	call	pciRegRead32
    88                                  
    89 00000084 83E2C0                  	and     dx, 0FFC0h	; IO_ADDR_MASK (0FFFE) ?
    90 00000087 8916[9209]                      mov     [ac97_io_base], dx
    91                                  
    92 0000008B B03C                    	mov	al, AC97_INT_LINE ; Interrupt line register (3Ch)
    93 0000008D E8F101                  	call	pciRegRead32
    94                                  
    95 00000090 6681E2FF000000          	and 	edx, 0FFh
    96 00000097 8816[8409]                	mov     [ac97_int_ln_reg], dl
    97                                  
    98                                  	; 28/11/2016
    99                                  	;mov	bx, 1
   100 0000009B 89D1                    	mov	cx, dx
   101                                  	;shl	bx, cl
   102                                  	
   103                                  	;not	bx
   104 0000009D E4A1                    	in	al, 0A1h ; irq 8-15
   105 0000009F 88C4                    	mov	ah, al
   106 000000A1 E421                    	in	al, 21h  ; irq 0-7 
   107                                  	;and	ax, bx   ; unmask
   108 000000A3 0FB3D0                  	btr	ax, dx	 ; unmask
   109 000000A6 E621                    	out	21h, al  ; enable interrupt (if irq <= 7)
   110 000000A8 88E0                    	mov	al, ah
   111 000000AA E6A1                    	out	0A1h, al ; enable interrupt (if irq > 7)
   112                                  	;not	bx
   113                                  	
   114 000000AC BAD104                  	mov	dx, 4D1h			;8259 ELCR1
   115 000000AF EC                      	in	al, dx
   116 000000B0 88C4                    	mov	ah, al
   117 000000B2 BAD004                  	mov	dx, 4D0h 
   118 000000B5 EC                      	in	al, dx
   119                                  	;or	ax, bx        
   120 000000B6 0FABC8                  	bts	ax, cx
   121 000000B9 BAD004                  	mov	dx, 4D0h
   122 000000BC EE                      	out	dx, al                          ;set level-triggered mode
   123 000000BD 88E0                    	mov	al, ah
   124 000000BF BAD104                  	mov	dx, 4D1h
   125 000000C2 EE                      	out	dx, al                          ;set level-triggered mode
   126                                  
   127                                  	; 24/11/2016 - Erdogan Tan
   128 000000C3 89CB                    	mov	bx, cx
   129 000000C5 8A9F[9809]              	mov	bl, [bx+irq_int]
   130 000000C9 C1E302                  	shl	bx, 2 ; * 4
   131                                  
   132                                  	; set up interrupt vector
   133                                  	; 30/11/2016
   134 000000CC 06                      	push	es
   135 000000CD 31C0                    	xor	ax, ax
   136 000000CF 8EC0                    	mov	es, ax
   137 000000D1 26C707[A308]            	mov	word [es:bx], ac97_int_handler
   138 000000D6 8CC8                    	mov	ax, cs
   139 000000D8 26894702                	mov	[es:bx+2], ax
   140 000000DC 07                      	pop	es
   141                                  		
   142                                  	; init AC97 codec
   143                                  _a1:
   144                                  	; 19/03/2017
   145                                  	;mov	eax, [bus_dev_fn]
   146                                  	;mov	al, VIA_ACLINK_CTRL  ; AC link interface control (41h)
   147                                  	;call	pciRegRead8
   148                                  
   149                                  	;;mov	eax, [bus_dev_fn]
   150                                  	;mov	al, VIA_ACLINK_STAT  ; AC Link interface status (40h)
   151                                  	;call	pciRegRead8
   152                                  	
   153                                  	;movzx	eax, dl
   154                                  	;test	al, VIA_ACLINK_C00_READY  ; 1 ; primary codec ready ?
   155                                  	;jnz	short a_2
   156                                  
   157 000000DD E81A03                  	call	reset_codec
   158 000000E0 731E                    	jnc	short _a2 ; EAX = 1
   159                                  
   160                                  	;test	al, VIA_ACLINK_C00_READY 	
   161                                          ;jnz     short _a2
   162                                  
   163                                  _codec_err:
   164 000000E2 0E                      	push	cs
   165 000000E3 1F                      	pop	ds
   166 000000E4 BA[ED00]                        mov	dx, CodecErrMsg
   167 000000E7 B409                            mov     ah, 9
   168 000000E9 CD21                            int     21h
   169 000000EB EB7C                            jmp     exit
   170                                  
   171 000000ED 436F64656320457272-     CodecErrMsg db "Codec Error #"
   171 000000F6 6F722023           
   172 000000FA 3020210D0A24            ErrNo	db	"0 !", CR,LF,"$"
   173                                  
   174                                  _a2:
   175                                  	; eax = 1
   176 00000100 E85003                  	call	codec_io_w16 ; w32
   177                                  	
   178                                  	;call	detect_codec
   179                                  
   180 00000103 E8EB03                  	call	channel_reset
   181                                  
   182 00000106 E82A06                  	call	write_ac97_dev_info 
   183                                  
   184                                  ; check the command line for a file to play
   185                                  
   186                                          ;push	ds
   187 00000109 E88100                          call    processCmdline			; get the filename
   188                                  
   189                                  ; open the file
   190 0000010C B002                            mov     al, OPEN                        ; open existing file
   191 0000010E E89C00                          call    openFile                        ; no error? ok.
   192                                          ;pop	ds
   193 00000111 7322                            jnc     short _gsr
   194                                  
   195                                  ; file not found!
   196                                  
   197                                          ;push   cs
   198                                          ;pop    ds
   199 00000113 BA[1C01]                        mov	dx, noFileErrMsg
   200 00000116 B409                            mov     ah, 9
   201 00000118 CD21                            int     21h
   202 0000011A EB4D                            jmp     exit
   203                                  
   204 0000011C 4572726F723A206669-     noFileErrMsg  db "Error: file not found.",CR,LF,"$"
   204 00000125 6C65206E6F7420666F-
   204 0000012E 756E642E0D0A24     
   205                                  
   206                                  _gsr:
   207 00000135 E89C00                          call    getSampleRate                   ; read the sample rate
   208                                                                                  ; pass it onto codec.
   209 00000138 722F                    	jc	short exit ; 19/11/2016 - nothing to do
   210                                  
   211 0000013A A3[9409]                	mov	[sample_rate], ax
   212                                  	; 19/11/2016
   213 0000013D 880E[9609]              	mov	[stmo], cl
   214 00000141 8816[9709]              	mov	[bps], dl
   215                                  
   216 00000145 E80A07                  	call	write_sample_rate
   217                                  
   218                                  ; setup the Codec (actually mixer registers) 
   219 00000148 E8F601                          call    codecConfig                     ; unmute codec, set rates.
   220 0000014B 7307                    	jnc	short _a3
   221                                  
   222 0000014D 0430                    	add	al, '0'
   223 0000014F A2[FA00]                	mov	[ErrNo], al
   224 00000152 EB8E                    	jmp	short _codec_err
   225                                  
   226                                  _a3:
   227                                  	
   228                                  ;
   229                                  ; position file pointer to start in actual wav data
   230                                  ; MUCH improvement should really be done here to check if sample size is
   231                                  ; supported, make sure there are 2 channels, etc.  
   232                                  ;
   233 00000154 B442                            mov     ah, 42h
   234 00000156 B000                            mov     al, 0                           ; from start of file
   235 00000158 8B1E[7809]                      mov     bx, [filehandle]
   236 0000015C 31C9                            xor     cx, cx
   237 0000015E BA2C00                          mov     dx, 44                          ; jump past .wav/riff header
   238 00000161 CD21                            int     21h
   239                                  
   240                                  ; play the .wav file.  Most of the good stuff is in here.
   241                                  
   242 00000163 E8D303                          call    playWav
   243                                  
   244                                  ; close the .wav file and exit.
   245                                  
   246 00000166 E85600                          call    closeFile
   247                                  
   248                                  exit:
   249 00000169 B8004C                          mov     ax, 4c00h
   250 0000016C CD21                    	int 	21h
   251                                  
   252                                  here:
   253 0000016E EBFE                    	jmp	short here
   254                                  
   255                                  ; MEMALLOC.ASM
   256                                  ;-- SETFREE: Release memory not used  ----------------
   257                                  ;-- Input    : ES = address of PSP
   258                                  ;-- Output   : none
   259                                  ;-- Register : AX, BX, CL and FLAGS are changed 
   260                                  ;-- Info     : Since the stack-segment is always the last segment in an 
   261                                  ;              EXE-file, ES:0000 points to the beginning and SS:SP
   262                                  ;              to the end of the program in memory. Through this the
   263                                  ;              length of the program can be calculated 
   264                                  ; call this routine once at the beginning of the program to free up memory
   265                                  ; assigned to it by DOS.
   266                                  
   267                                  setFree:
   268 00000170 8CD3                              mov  bx, ss		;first subtract the two segment addresses
   269 00000172 8CC0                              mov  ax, es		;from each other. The result is
   270 00000174 29C3                              sub  bx, ax		;number of paragraphs from PSP
   271                                  				;to the beginning of the stack
   272 00000176 89E0                              mov  ax, sp		;since the stackpointer is at the end of
   273 00000178 B104                              mov  cl, 4		;the stack segment, its content indicates
   274 0000017A D3E8                              shr  ax, cl		;the length of the stack
   275 0000017C 01C3                              add  bx, ax		;add to current length
   276 0000017E 43                                inc  bx		;as precaution add another paragraph
   277                                  
   278 0000017F B44A                              mov  ah, 4ah		;pass new length to DOS
   279 00000181 CD21                              int  21h
   280                                  
   281 00000183 C3                                retn			;back to caller
   282                                  
   283                                  memAlloc:
   284                                  ; input: AX = # of paragraphs required
   285                                  ; output: AX = segment of block to use
   286                                  
   287 00000184 53                      	push	bx
   288 00000185 89C3                    	mov	bx, ax
   289 00000187 B448                    	mov	ah, 48h
   290 00000189 CD21                    	int	21h
   291 0000018B 5B                      	pop	bx
   292 0000018C C3                      	retn
   293                                  
   294                                  ; CMDLINE.ASM
   295                                  ; parse the command line
   296                                  ; entry: none
   297                                  ; exit: DS:DX to the 1st supplied item on the command line 
   298                                  
   299                                  processCmdline:
   300 0000018D 53                              push    bx
   301 0000018E 56                              push    si
   302                                  
   303                                          ;mov    ah, 51h
   304                                          ;int    21h
   305                                          ;mov    ds, bx
   306                                  
   307 0000018F BE8000                          mov     si, 80h
   308 00000192 0FB61C                          movzx   bx, byte [si]
   309 00000195 01DE                            add     si, bx
   310 00000197 46                              inc     si
   311                                  
   312 00000198 C60400                          mov     byte [si], NULL         ; zero terminate
   313                                  
   314 0000019B BE8100                          mov     si, 81h
   315                                  
   316                                  cmdlineloop:
   317 0000019E AC                              lodsb
   318                                  
   319 0000019F 3C00                            cmp     al, NULL                ; found end of line?
   320 000001A1 7404                            je      short exitpc
   321 000001A3 3C20                            cmp     al, ' '                 ; found a space?
   322 000001A5 74F7                            je      short cmdlineloop
   323                                  
   324                                          ; must be the filename here.
   325                                  exitpc:
   326 000001A7 4E                              dec     si                      ; point to start of filename
   327 000001A8 89F2                            mov     dx, si
   328 000001AA 5E                              pop     si
   329 000001AB 5B                              pop     bx
   330 000001AC C3                      	retn
   331                                  
   332                                  ; FILE.ASM
   333                                  ;open or create file
   334                                  ;
   335                                  ;input: ds:dx-->filename (asciiz)
   336                                  ;       al=file Mode (create or open)
   337                                  ;output: none  cs:[filehandle] filled
   338                                  ;
   339                                  openFile:
   340 000001AD 50                      	push	ax
   341 000001AE 51                      	push	cx
   342 000001AF B43B                    	mov	ah, 3bh			; start with a mode
   343 000001B1 00C4                    	add	ah, al			; add in create or open mode
   344 000001B3 31C9                    	xor	cx, cx
   345 000001B5 CD21                    	int	21h
   346 000001B7 7203                    	jc	short _of1
   347                                  	;mov	[cs:filehandle], ax
   348 000001B9 A3[7809]                	mov	[filehandle], ax
   349                                  _of1:
   350 000001BC 59                      	pop	cx
   351 000001BD 58                      	pop	ax
   352 000001BE C3                      	retn
   353                                  
   354                                  ; close the currently open file
   355                                  ; input: none, uses cs:[filehandle]
   356                                  closeFile:
   357 000001BF 50                      	push	ax
   358 000001C0 53                      	push	bx
   359 000001C1 833E[7809]FF            	cmp	word [filehandle], -1
   360 000001C6 7409                    	jz	short _cf1
   361 000001C8 8B1E[7809]              	mov     bx, [filehandle]  
   362 000001CC B8003E                  	mov     ax,3e00h
   363 000001CF CD21                            int     21h              ;close file
   364                                  _cf1:
   365 000001D1 5B                      	pop	bx
   366 000001D2 58                      	pop	ax
   367 000001D3 C3                      	retn
   368                                  
   369                                  getSampleRate:
   370                                  	; 08/12/2016
   371                                  ; reads the sample rate from the .wav file.
   372                                  ; entry: none - assumes file is already open
   373                                  	; 19/11/2016 - Erdogan Tan
   374                                  ; exit: ax = sample rate (11025, 22050, 44100, 48000)
   375                                  ;	cx = number of channels (mono=1, stereo=2)
   376                                  ;	dx = bits per sample (8, 16)
   377                                  
   378 000001D4 53                      	push    bx
   379                                  
   380 000001D5 B442                            mov     ah, 42h
   381 000001D7 B000                            mov     al, 0				; from start of file
   382 000001D9 8B1E[7809]                      mov     bx, [filehandle]
   383 000001DD 31C9                            xor     cx, cx
   384 000001DF BA0800                          mov     dx, 08h				; "WAVE"
   385 000001E2 CD21                            int     21h
   386                                  
   387 000001E4 BA[5C09]                        mov     dx, smpRBuff
   388 000001E7 B91C00                          mov     cx, 28				; 28 bytes
   389 000001EA B43F                    	mov	ah, 3fh
   390 000001EC CD21                            int     21h
   391                                  
   392 000001EE 813E[5C09]5741          	cmp	word [smpRBuff], 'WA'
   393 000001F4 751C                    	jne	short gsr_stc
   394                                  
   395 000001F6 813E[5E09]5645          	cmp	word [smpRBuff+2], 'VE'
   396 000001FC 7514                    	jne	short gsr_stc
   397                                  
   398 000001FE 833E[6809]01            	cmp	word [smpRBuff+12], 1	; Offset 20, must be 1 (= PCM)
   399 00000203 750D                    	jne	short gsr_stc
   400                                  
   401                                  
   402 00000205 8B0E[6A09]              	mov	cx, [smpRBuff+14]	; return num of channels in CX
   403 00000209 A1[6C09]                        mov     ax, [smpRBuff+16]	; return sample rate in AX
   404 0000020C 8B16[7609]              	mov	dx, [smpRBuff+26]	; return bits per sample value in DX
   405                                  gsr_retn:
   406 00000210 5B                              pop     bx
   407 00000211 C3                              retn
   408                                  
   409                                  gsr_stc:
   410 00000212 F9                      	stc
   411 00000213 EBFB                    	jmp	short gsr_retn
   412                                  
   413                                  %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> ; 20/03/2017
     5                              <1> NOT_BIT31 EQU 7FFFFFFFh
     6                              <1> NOT_PCI32_PCI16	EQU 03FFFFFFFh ; NOT BIT31+BIT30
     7                              <1> 
     8                              <1> ;===============================================================
     9                              <1> ; 8/16/32bit PCI reader
    10                              <1> ;
    11                              <1> ; Entry: EAX=PCI Bus/Device/fn/register number
    12                              <1> ;           BIT30 set if 32 bit access requested
    13                              <1> ;           BIT29 set if 16 bit access requested
    14                              <1> ;           otherwise defaults to 8bit read
    15                              <1> ;
    16                              <1> ; Exit:  DL,DX,EDX register data depending on requested read size
    17                              <1> ;
    18                              <1> ; Note: this routine is meant to be called via pciRegRead8, pciRegread16,
    19                              <1> ;	or pciRegRead32, listed below.
    20                              <1> ;
    21                              <1> ; Note2: don't attempt to read 32bits of data from a non dword aligned reg
    22                              <1> ;	 number.  Likewise, don't do 16bit reads from non word aligned reg #
    23                              <1> ; 
    24                              <1> pciRegRead:
    25 00000215 6653                <1> 	push	ebx
    26 00000217 6651                <1> 	push	ecx
    27 00000219 6689C3              <1>         mov     ebx, eax		; save eax, dh
    28 0000021C 88F1                <1>         mov     cl, dh
    29                              <1> 
    30 0000021E 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; clear out data size request
    31 00000224 660D00000080        <1>         or      eax, BIT31		; make a PCI access request
    32 0000022A 24FC                <1>         and     al, ~3 ; NOT 3		; force index to be dword
    33                              <1> 
    34 0000022C BAF80C              <1>         mov     dx, PCI_INDEX_PORT
    35 0000022F 66EF                <1>         out	dx, eax			; write PCI selector
    36                              <1> 	
    37 00000231 BAFC0C              <1>         mov     dx, PCI_DATA_PORT
    38 00000234 88D8                <1>         mov     al, bl
    39 00000236 2403                <1>         and     al, 3			; figure out which port to
    40 00000238 00C2                <1>         add     dl, al			; read to
    41                              <1> 
    42                              <1> 	; 20/03/2017
    43 0000023A 66F7C3000000C0      <1> 	test    ebx, PCI32+PCI16
    44 00000241 7507                <1>         jnz     short _pregr0
    45 00000243 EC                  <1> 	in	al, dx			; return 8bits of data
    46 00000244 88C2                <1>         mov	dl, al
    47 00000246 88CE                <1> 	mov     dh, cl			; restore dh for 8 bit read
    48 00000248 EB13                <1> 	jmp	short _pregr2
    49                              <1> _pregr0:	
    50 0000024A 66F7C300000080      <1> 	test    ebx, PCI32
    51 00000251 7505                <1>         jnz	short _pregr1
    52 00000253 ED                  <1> 	in	ax, dx
    53 00000254 89C2                <1>         mov     dx, ax			; return 16bits of data
    54 00000256 EB05                <1> 	jmp	short _pregr2
    55                              <1> _pregr1:
    56 00000258 66ED                <1> 	in	eax, dx			; return 32bits of data
    57 0000025A 6689C2              <1> 	mov	edx, eax
    58                              <1> _pregr2:
    59 0000025D 6689D8              <1> 	mov     eax, ebx		; restore eax
    60 00000260 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; clear out data size request
    61 00000266 6659                <1> 	pop	ecx
    62 00000268 665B                <1> 	pop	ebx
    63 0000026A C3                  <1> 	retn
    64                              <1> 
    65                              <1> pciRegRead8:
    66 0000026B 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; set up 8 bit read size
    67 00000271 EBA2                <1>         jmp     short pciRegRead	; call generic PCI access
    68                              <1> 
    69                              <1> pciRegRead16:
    70 00000273 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; set up 16 bit read size
    71 00000279 660D00000040        <1>         or      eax, PCI16		; call generic PCI access
    72 0000027F EB94                <1>         jmp     short pciRegRead
    73                              <1> 
    74                              <1> pciRegRead32:
    75 00000281 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; set up 32 bit read size
    76 00000287 660D00000080        <1>         or      eax, PCI32		; call generic PCI access
    77 0000028D EB86                <1>         jmp     pciRegRead
    78                              <1> 
    79                              <1> ;===============================================================
    80                              <1> ; 8/16/32bit PCI writer
    81                              <1> ;
    82                              <1> ; Entry: EAX=PCI Bus/Device/fn/register number
    83                              <1> ;           BIT31 set if 32 bit access requested
    84                              <1> ;           BIT30 set if 16 bit access requested
    85                              <1> ;           otherwise defaults to 8bit read
    86                              <1> ;        DL/DX/EDX data to write depending on size
    87                              <1> ;
    88                              <1> ;
    89                              <1> ; note: this routine is meant to be called via pciRegWrite8, pciRegWrite16,
    90                              <1> ; 	or pciRegWrite32 as detailed below.
    91                              <1> ;
    92                              <1> ; Note2: don't attempt to write 32bits of data from a non dword aligned reg
    93                              <1> ;	 number.  Likewise, don't do 16bit writes from non word aligned reg #
    94                              <1> ;
    95                              <1> pciRegWrite:
    96 0000028F 6653                <1> 	push	ebx
    97 00000291 6651                <1> 	push	ecx
    98 00000293 6689C3              <1>         mov     ebx, eax		; save eax, edx
    99 00000296 6689D1              <1>         mov     ecx, edx
   100 00000299 6625FFFFFF3F        <1> 	and     eax, NOT_PCI32_PCI16	; clear out data size request
   101 0000029F 660D00000080        <1>         or      eax, BIT31		; make a PCI access request
   102 000002A5 24FC                <1>         and     al, ~3 ; NOT 3		; force index to be dword
   103                              <1> 
   104 000002A7 BAF80C              <1>         mov     dx, PCI_INDEX_PORT
   105 000002AA 66EF                <1>         out	dx, eax			; write PCI selector
   106                              <1> 	
   107 000002AC BAFC0C              <1>         mov     dx, PCI_DATA_PORT
   108 000002AF 88D8                <1>         mov     al, bl
   109 000002B1 2403                <1>         and     al, 3			; figure out which port to
   110 000002B3 00C2                <1>         add     dl, al			; write to
   111                              <1> 
   112                              <1> 	; 20/03/2017
   113 000002B5 66F7C3000000C0      <1> 	test    ebx, PCI32+PCI16
   114 000002BC 7505                <1>         jnz     short _pregw0
   115 000002BE 88C8                <1> 	mov	al, cl 			; put data into al
   116 000002C0 EE                  <1> 	out	dx, al
   117 000002C1 EB13                <1> 	jmp	short _pregw2
   118                              <1> _pregw0:
   119 000002C3 66F7C300000080      <1> 	test    ebx, PCI32
   120 000002CA 7505                <1>         jnz     short _pregw1
   121 000002CC 89C8                <1> 	mov	ax, cx			; put data into ax
   122 000002CE EF                  <1> 	out	dx, ax
   123 000002CF EB05                <1> 	jmp	short _pregw2
   124                              <1> _pregw1:
   125 000002D1 6689C8              <1> 	mov	eax, ecx		; put data into eax 		
   126 000002D4 66EF                <1> 	out	dx, eax
   127                              <1> _pregw2:
   128 000002D6 6689D8              <1>         mov     eax, ebx		; restore eax
   129 000002D9 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; clear out data size request
   130 000002DF 6689CA              <1>         mov     edx, ecx		; restore dx
   131 000002E2 6659                <1> 	pop	ecx
   132 000002E4 665B                <1> 	pop	ebx
   133 000002E6 C3                  <1> 	retn
   134                              <1> 
   135                              <1> pciRegWrite8:
   136 000002E7 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; set up 8 bit write size
   137 000002ED EBA0                <1>         jmp	short pciRegWrite	; call generic PCI access
   138                              <1> 
   139                              <1> pciRegWrite16:
   140 000002EF 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; set up 16 bit write size
   141 000002F5 660D00000040        <1>         or      eax, PCI16		; call generic PCI access
   142 000002FB EB92                <1>         jmp	short pciRegWrite
   143                              <1> 
   144                              <1> pciRegWrite32:
   145 000002FD 6625FFFFFF3F        <1>         and     eax, NOT_PCI32_PCI16	; set up 32 bit write size
   146 00000303 660D00000080        <1>         or      eax, PCI32		; call generic PCI access
   147 00000309 EB84                <1>         jmp	pciRegWrite
   148                              <1> 
   149                              <1> ;===============================================================
   150                              <1> ; PCIFindDevice: scan through PCI space looking for a device+vendor ID
   151                              <1> ;
   152                              <1> ; Entry: EAX=Device+Vendor ID
   153                              <1> ;
   154                              <1> ;  Exit: EAX=PCI address if device found
   155                              <1> ;	 EDX=Device+Vendor ID
   156                              <1> ;        CY clear if found, set if not found. EAX invalid if CY set.
   157                              <1> ;
   158                              <1> ; [old stackless] Destroys: ebx, esi, edi, cl
   159                              <1> ;
   160                              <1> pciFindDevice:
   161                              <1> 	;push	cx
   162 0000030B 6650                <1> 	push	eax
   163                              <1> 	;push	esi
   164                              <1> 	;push	edi
   165                              <1> 
   166 0000030D 6689C6              <1>         mov     esi, eax                ; save off vend+device ID
   167 00000310 66BF00FFFF7F        <1>         mov     edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0
   168                              <1> 
   169                              <1> nextPCIdevice:
   170 00000316 6681C700010000      <1>         add     edi, 100h
   171 0000031D 6681FF00F8FF80      <1>         cmp     edi, 80FFF800h		; scanned all devices?
   172 00000324 F9                  <1>         stc
   173 00000325 740C                <1>         je      short PCIScanExit       ; not found
   174                              <1> 
   175 00000327 6689F8              <1>         mov     eax, edi                ; read PCI registers
   176 0000032A E854FF              <1>         call    pciRegRead32
   177 0000032D 6639F2              <1>         cmp     edx, esi                ; found device?
   178 00000330 75E4                <1>         jne     short nextPCIdevice
   179 00000332 F8                  <1>         clc
   180                              <1> 
   181                              <1> PCIScanExit:
   182 00000333 9C                  <1> 	pushf
   183 00000334 66B8FFFFFF7F        <1> 	mov	eax, NOT_BIT31 	; 19/03/2017
   184 0000033A 6621F8              <1> 	and	eax, edi	; return only bus/dev/fn #
   185 0000033D 9D                  <1> 	popf
   186                              <1> 
   187                              <1> 	;pop	edi
   188                              <1> 	;pop	esi
   189 0000033E 665A                <1> 	pop	edx
   190                              <1> 	;pop	ecx
   191 00000340 C3                  <1> 	retn
   414                                  %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> ; 24/03/2017
     5                              <1> ; 20/03/2017
     6                              <1> ; enable codec, unmute stuff, set output rate to 44.1
     7                              <1> ; entry: ax = desired sample rate
     8                              <1> ;
     9                              <1> codecConfig:
    10                              <1> 	; 15/11/2016
    11                              <1> 	; 14/11/2016
    12                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, 'setup_codec', codec.inc)
    13                              <1> 
    14                              <1> 	; 14/11/2016 - Erdogan Tan	
    15                              <1> 	; (Ref: Mpxplay, PDSoft, Attila Padar, SC_VIA82.C)
    16                              <1> ;;;	call	channel_reset
    17                              <1> 
    18 00000341 C606[8509]00        <1> 	mov	byte [err_num], 0
    19                              <1> 
    20 00000346 66B802020000        <1> 	mov     eax, 0202h
    21 0000034C 66BA02000000        <1> 	mov	edx, CODEC_MASTER_VOL_REG ; 02h ; Line Out
    22 00000352 E85A01              <1> 	call	codec_write
    23                              <1> 	;jc	cconfig_error
    24                              <1> 
    25 00000355 C606[8509]01        <1> 	mov	byte [err_num], 1
    26                              <1> 
    27 0000035A 66B802020000        <1> 	mov     eax, 0202h
    28 00000360 66BA18000000        <1> 	mov	edx, CODEC_PCM_OUT_REG ; 18h ; Wave Output (Stereo)
    29 00000366 E84601              <1> 	call	codec_write
    30                              <1> 	;jc	cconfig_error
    31                              <1>       
    32 00000369 C606[8509]02        <1> 	mov	byte [err_num], 2
    33                              <1> 
    34                              <1>  	;xor    eax, eax
    35 0000036E 66B802020000        <1> 	mov	eax, 0202h
    36 00000374 66BA04000000        <1> 	mov	edx, CODEC_AUX_VOL ; 04h ; CODEC_HP_VOL_REG ; HeadPhone
    37 0000037A E83201              <1> 	call	codec_write
    38                              <1> 	;jc	cconfig_error
    39                              <1> 
    40 0000037D C606[8509]03        <1> 	mov	byte [err_num], 3
    41                              <1> 
    42 00000382 B80800              <1>         mov     ax,  08h
    43 00000385 66BA0C000000        <1>         mov	edx, 0Ch  ; AC97_PHONE_VOL ; TAD Input (Mono)
    44 0000038B E82101              <1> 	call	codec_write
    45                              <1> 	;jc	short cconfig_error
    46                              <1> 
    47 0000038E C606[8509]04        <1> 	mov	byte [err_num], 4
    48                              <1> 
    49 00000393 B80808              <1>         mov     ax,  0808h
    50 00000396 66BA10000000        <1>         mov	edx, CODEC_LINE_IN_VOL_REG ; 10h ; Line Input (Stereo)	
    51 0000039C E81001              <1> 	call	codec_write
    52                              <1> 	;jc	short cconfig_error
    53                              <1> 
    54 0000039F C606[8509]05        <1> 	mov	byte [err_num], 5
    55                              <1> 
    56 000003A4 B80808              <1> 	mov     ax,  0808h
    57 000003A7 66BA12000000        <1>         mov	edx, CODEC_CD_VOL_REG ; 12h ; CR Input (Stereo)
    58 000003AD E8FF00              <1> 	call	codec_write
    59                              <1> 	;jc	short cconfig_error
    60                              <1> 
    61 000003B0 C606[8509]06        <1> 	mov	byte [err_num], 6
    62                              <1> 
    63 000003B5 B80808              <1> 	mov     ax,  0808h
    64 000003B8 66BA16000000        <1>         mov	edx, CODEC_AUX_VOL_REG ; 16h ; Aux Input (Stereo)
    65 000003BE E8EE00              <1> 	call	codec_write
    66                              <1> 	;jc	short cconfig_error
    67                              <1> 
    68 000003C1 C606[8509]07        <1> 	mov	byte [err_num], 7
    69                              <1> 
    70                              <1> 	; Extended Audio Status (2Ah)
    71 000003C6 66B82A000000        <1> 	mov	eax, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah 
    72 000003CC E8B400              <1> 	call	codec_read
    73 000003CF 6625FDFF0000        <1>         and     eax, 0FFFFh - 2			; clear DRA (BIT1)
    74                              <1>         ;or     eax, 1				; set VRA (BIT0)
    75 000003D5 6683C805            <1> 	or	eax, 5  	; VRA (BIT0) & S/PDIF (BIT2) ; 14/11/2016
    76 000003D9 66BA2A000000        <1> 	mov	edx, CODEC_EXT_AUDIO_CTRL_REG
    77 000003DF E8CD00              <1> 	call	codec_write
    78                              <1> 	;jc	short cconfig_error
    79                              <1> 
    80 000003E2 C606[8509]08        <1> 	mov	byte [err_num], 8
    81                              <1> set_sample_rate:
    82 000003E7 6631C0              <1>         xor	eax, eax
    83 000003EA A1[9409]            <1> 	mov	ax, [sample_rate]
    84 000003ED 66BA2C000000        <1> 	mov	edx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch ; PCM Front DAC Rate
    85                              <1>         ;call	codec_write
    86                              <1>         ;retn
    87 000003F3 E9B900              <1> 	jmp	codec_write
    88                              <1> 	
    89                              <1> cconfig_error:
    90 000003F6 A0[8509]            <1> 	mov	al, [err_num]
    91 000003F9 C3                  <1>         retn
    92                              <1> 
    93                              <1> reset_codec:
    94                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
    95 000003FA 66A1[8609]          <1> 	mov	eax, [bus_dev_fn]
    96 000003FE B041                <1>  	mov	al, VIA_ACLINK_CTRL
    97 00000400 B2E0                <1>        	mov	dl, VIA_ACLINK_CTRL_ENABLE + VIA_ACLINK_CTRL_RESET + VIA_ACLINK_CTRL_SYNC
    98                              <1> 
    99 00000402 E8E2FE              <1> 	call	pciRegWrite8
   100                              <1> 
   101 00000405 E84200              <1> 	call	delay_100ms 	; wait 100 ms
   102                              <1> _rc_cold:
   103 00000408 E80C00              <1>         call    cold_reset
   104 0000040B 7304                <1>         jnc     short _reset_codec_ok
   105                              <1> 
   106 0000040D 6631C0              <1>         xor     eax, eax         ; timeout error
   107 00000410 C3                  <1>         retn
   108                              <1> 
   109                              <1> _reset_codec_ok:
   110 00000411 6631C0              <1>         xor     eax, eax
   111                              <1>         ;mov	al, VIA_ACLINK_C00_READY ; 1
   112 00000414 FEC0                <1>         inc	al
   113 00000416 C3                  <1> 	retn
   114                              <1> 
   115                              <1> cold_reset:
   116                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   117                              <1> 	;mov	eax, [bus_dev_fn]
   118                              <1> 	;mov	al, VIA_ACLINK_CTRL
   119 00000417 30D2                <1> 	xor	dl, dl ; 0
   120 00000419 E8CBFE              <1> 	call	pciRegWrite8
   121                              <1> 
   122 0000041C E82B00              <1> 	call	delay_100ms 	; wait 100 ms
   123                              <1> 
   124                              <1> 	;; ACLink on, deassert ACLink reset, VSR, SGD data out
   125                              <1>         ;; note - FM data out has trouble with non VRA codecs !!
   126                              <1>         
   127                              <1> 	;mov	eax, [bus_dev_fn]
   128                              <1> 	;mov	al, VIA_ACLINK_CTRL
   129                              <1> 
   130 0000041F B2CC                <1> 	mov	dl, VIA_ACLINK_CTRL_INIT
   131                              <1> 
   132 00000421 E8C3FE              <1> 	call	pciRegWrite8
   133                              <1> 
   134                              <1> 	; 24/03/2017
   135 00000424 B91000              <1> 	mov	cx, 16	; total 2s
   136                              <1> _crst_wait:
   137                              <1> 	;mov	eax, [bus_dev_fn]
   138 00000427 B040                <1> 	mov	al, VIA_ACLINK_STAT
   139 00000429 E83FFE              <1> 	call	pciRegRead8	
   140                              <1> 
   141 0000042C F6C201              <1>         test    dl, VIA_ACLINK_C00_READY
   142 0000042F 750A                <1>         jnz     short _crst_ok
   143                              <1> 
   144 00000431 51                  <1> 	push	cx
   145 00000432 E81500              <1> 	call	delay_100ms
   146 00000435 59                  <1> 	pop	cx
   147                              <1> 
   148 00000436 49                  <1>         dec     cx
   149 00000437 75EE                <1>         jnz     short _crst_wait
   150                              <1> 
   151                              <1> _crst_fail:
   152 00000439 F9                  <1>         stc
   153 0000043A C3                  <1>         retn
   154                              <1> 
   155                              <1> _crst_ok:
   156                              <1> 	; are these necessary ? - 14/11/2016 - Erdogan Tan
   157                              <1> 
   158                              <1> 	;mov	eax, [bus_dev_fn]
   159                              <1> 	;mov	al, VIA_ACLINK_CTRL
   160 0000043B E82DFE              <1> 	call	pciRegRead8
   161                              <1> 
   162                              <1> 	;mov	eax, [bus_dev_fn]
   163                              <1> 	;mov	al, VIA_ACLINK_STAT
   164 0000043E E82AFE              <1> 	call	pciRegRead8
   165                              <1> 
   166 00000441 660FB6C2            <1> 	movzx	eax, dl
   167 00000445 2401                <1> 	and     al, VIA_ACLINK_C00_READY ; 1
   168 00000447 74F0                <1> 	jz	short _crst_fail
   169                              <1> 
   170 00000449 C3                  <1> 	retn
   171                              <1> 
   172                              <1> delay_100ms:
   173                              <1> 	; 24/03/2017
   174                              <1> 	; wait 100 ms
   175 0000044A B91900              <1> 	mov	cx, 25
   176                              <1> _delay_x_ms:
   177                              <1> 	;push	cx
   178 0000044D E8C302              <1> 	call	delay1_4ms
   179                              <1> 	;pop	cx
   180 00000450 E2FB                <1>         loop	_delay_x_ms
   181 00000452 C3                  <1> 	retn
   182                              <1> 
   183                              <1> codec_io_w16: ;w32
   184 00000453 8B16[9209]          <1>         mov	dx, [ac97_io_base]
   185 00000457 81C28000            <1>         add     dx, VIA_REG_AC97
   186 0000045B 66EF                <1>         out     dx, eax
   187 0000045D C3                  <1>         retn
   188                              <1> 
   189                              <1> codec_io_r16: ;r32
   190 0000045E 8B16[9209]          <1>         mov     dx, [ac97_io_base]
   191 00000462 81C28000            <1>         add     dx, VIA_REG_AC97
   192 00000466 66ED                <1>         in      eax, dx
   193 00000468 C3                  <1>         retn
   194                              <1> 
   195                              <1> ctrl_io_w8:
   196 00000469 0316[9209]          <1>         add     dx, [ac97_io_base]
   197 0000046D EE                  <1>         out     dx, al
   198 0000046E C3                  <1>         retn
   199                              <1> 
   200                              <1> ctrl_io_r8:
   201 0000046F 0316[9209]          <1>         add     dx, [ac97_io_base]
   202 00000473 EC                  <1>         in      al, dx
   203 00000474 C3                  <1>         retn
   204                              <1> 
   205                              <1> ctrl_io_w32:
   206 00000475 0316[9209]          <1>         add     dx, [ac97_io_base]
   207 00000479 66EF                <1>         out     dx, eax
   208 0000047B C3                  <1>         retn
   209                              <1> 
   210                              <1> ctrl_io_r32:
   211 0000047C 0316[9209]          <1>         add	dx, [ac97_io_base]
   212 00000480 66ED                <1>         in	eax, dx
   213 00000482 C3                  <1>         retn
   214                              <1> 
   215                              <1> codec_read:
   216                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   217                              <1>         ; Use only primary codec.
   218                              <1>         ; eax = register
   219 00000483 66C1E010            <1>         shl     eax, VIA_REG_AC97_CMD_SHIFT
   220 00000487 660D00008002        <1>         or      eax, VIA_REG_AC97_PRIMARY_VALID + VIA_REG_AC97_READ
   221                              <1> 
   222 0000048D E8C3FF              <1> 	call    codec_io_w16
   223                              <1> 
   224                              <1>       	; codec_valid
   225 00000490 E83700              <1> 	call	codec_check_ready
   226 00000493 7301                <1>         jnc	short _cr_ok
   227                              <1> 
   228 00000495 C3                  <1> 	retn
   229                              <1> 
   230                              <1> _cr_ok:
   231                              <1> 	; wait 25 ms
   232 00000496 E87A02              <1> 	call	delay1_4ms
   233 00000499 E87702              <1> 	call	delay1_4ms
   234 0000049C E87402              <1> 	call	delay1_4ms
   235 0000049F E87102              <1> 	call	delay1_4ms
   236 000004A2 E86E02              <1> 	call	delay1_4ms
   237                              <1> 
   238 000004A5 E8B6FF              <1>         call    codec_io_r16
   239 000004A8 6625FFFF0000        <1>         and     eax, 0FFFFh
   240 000004AE C3                  <1>         retn
   241                              <1> 
   242                              <1> codec_write:
   243                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   244                              <1>         ; Use only primary codec.
   245                              <1>         
   246                              <1> 	; eax = data (volume)
   247                              <1> 	; edx = register (mixer register)
   248                              <1> 	
   249 000004AF 66C1E210            <1> 	shl     edx, VIA_REG_AC97_CMD_SHIFT
   250                              <1> 
   251 000004B3 66C1E000            <1>         shl     eax, VIA_REG_AC97_DATA_SHIFT ; shl eax, 0
   252 000004B7 6609C2              <1>         or      edx, eax
   253                              <1> 
   254 000004BA 66B800000000        <1>         mov     eax, VIA_REG_AC97_CODEC_ID_PRIMARY
   255 000004C0 66C1E01E            <1>         shl     eax, VIA_REG_AC97_CODEC_ID_SHIFT
   256 000004C4 6609D0              <1>         or      eax, edx
   257                              <1> 
   258 000004C7 E889FF              <1>         call    codec_io_w16
   259                              <1>         ;mov    [codec.regs+esi], ax
   260                              <1> 
   261                              <1>         ;call	codec_check_ready
   262                              <1>        	;retn
   263                              <1> 	;jmp	short _codec_check_ready	
   264                              <1> 
   265                              <1> codec_check_ready:
   266                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   267                              <1> 
   268                              <1> _codec_check_ready:
   269 000004CA 66B914000000        <1> 	mov	ecx, 20	; total 2s
   270                              <1> _ccr_wait:
   271 000004D0 6651                <1> 	push	ecx
   272                              <1> 
   273 000004D2 E889FF              <1>         call    codec_io_r16
   274 000004D5 66A900000001        <1>         test    eax, VIA_REG_AC97_BUSY
   275 000004DB 740B                <1>         jz      short _ccr_ok
   276                              <1> 
   277 000004DD E86AFF              <1> 	call	delay_100ms
   278                              <1> 
   279 000004E0 6659                <1> 	pop	ecx
   280                              <1> 
   281 000004E2 6649                <1> 	dec     ecx
   282 000004E4 75EA                <1>         jnz     short _ccr_wait
   283                              <1> 
   284 000004E6 F9                  <1>         stc
   285 000004E7 C3                  <1>         retn
   286                              <1> 
   287                              <1> _ccr_ok:
   288 000004E8 6659                <1> 	pop	ecx
   289 000004EA 6625FFFF0000        <1> 	and     eax, 0FFFFh
   290 000004F0 C3                  <1>         retn
   291                              <1> 
   292                              <1> channel_reset:
   293                              <1> 	; 14/11/2016 - Erdogan Tan
   294                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   295 000004F1 66BA01000000        <1>         mov	edx, VIA_REG_OFFSET_CONTROL
   296 000004F7 66B849000000        <1>         mov     eax, VIA_REG_CTRL_PAUSE + VIA_REG_CTRL_TERMINATE + VIA_REG_CTRL_RESET
   297 000004FD E869FF              <1>         call    ctrl_io_w8
   298                              <1> 
   299                              <1>         ;mov	edx, VIA_REG_OFFSET_CONTROL
   300                              <1>         ;call   ctrl_io_r8
   301                              <1> 
   302 00000500 66B90C000000        <1> 	mov	ecx, 12 ; 50 ms	
   303                              <1> _ch_rst_wait:
   304 00000506 6651                <1> 	push	ecx
   305 00000508 E80802              <1> 	call	delay1_4ms
   306 0000050B 6659                <1> 	pop	ecx
   307 0000050D 6649                <1> 	dec	ecx
   308 0000050F 75F5                <1> 	jnz	short _ch_rst_wait     
   309                              <1> 
   310                              <1>         ; disable interrupts
   311 00000511 66BA01000000        <1>         mov	edx, VIA_REG_OFFSET_CONTROL
   312 00000517 6631C0              <1>         xor     eax, eax
   313 0000051A E84CFF              <1>         call    ctrl_io_w8
   314                              <1> 
   315                              <1>         ; clear interrupts
   316 0000051D 66BA00000000        <1>         mov	edx, VIA_REG_OFFSET_STATUS
   317                              <1> 	;mov	eax, 3
   318 00000523 66B8FF000000        <1>         mov     eax, 0FFh ; 14/11/2016 - SC_VIA82.C (Attila Padar)
   319 00000529 E83DFF              <1>         call	ctrl_io_w8
   320                              <1> 
   321                              <1> 	; 14/11/2016 (Ref: Attila Padar, Mpxplay, SC_VIA82.C)
   322 0000052C 66BA04000000        <1> 	mov	edx, VIA_REG_OFFSET_CURR_PTR
   323 00000532 6631C0              <1> 	xor	eax, eax
   324 00000535 E83DFF              <1> 	call	ctrl_io_w32
   325                              <1> 
   326 00000538 C3                  <1>         retn
   415                                  %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 00000539 06                  <1>         push	es
    18 0000053A A1[8209]            <1> 	mov     ax, [WAV_BUFFER2]
    19 0000053D 8EC0                <1> 	mov	es, ax
    20 0000053F 29C0                <1> 	sub	ax, ax
    21 00000541 89C7                <1> 	mov	di, ax ; 18/02/2017
    22 00000543 B90080              <1> 	mov	cx, (FILESIZE/2)
    23 00000546 F3AB                <1> 	rep	stosw
    24 00000548 07                  <1> 	pop	es	     
    25                              <1> 	
    26                              <1>        ; load 64k into buffer 1
    27                              <1> 
    28 00000549 A1[8009]            <1>         mov     ax, [WAV_BUFFER1]
    29 0000054C 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 0000054F 06                  <1>         push    es
    63 00000550 A1[7E09]            <1>         mov     ax, [BDL_BUFFER]		; get segment # for BDL
    64 00000553 8EC0                <1>         mov     es, ax
    65                              <1> 
    66 00000555 B91000              <1>         mov     cx, 32 / 2                      ; make 32 entries in BDL
    67 00000558 31FF                <1>         xor     di, di                          
    68                              <1> _0:
    69                              <1> 
    70                              <1> ; set buffer descriptor 0 to start of data file in memory
    71 0000055A 660FB706[8009]      <1>         movzx   eax, word [WAV_BUFFER1]
    72 00000560 66C1E004            <1>         shl     eax, 4                          ; convert seg:off ->0:offset
    73 00000564 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 00000566 66B800000100        <1> 	mov	eax, FILESIZE
   103 0000056C 660D00000040        <1> 	or	eax, FLAG
   104                              <1> 	;or	eax, EOL
   105 00000572 66AB                <1> 	stosd
   106                              <1> 
   107                              <1> ; 2nd buffer:
   108                              <1> 
   109 00000574 660FB706[8209]      <1>         movzx   eax, word [WAV_BUFFER2]
   110 0000057A 66C1E004            <1>         shl     eax, 4                          ; convert seg:off ->0:offset
   111 0000057E 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 00000580 66B800000100        <1> 	mov	eax, FILESIZE
   118 00000586 660D00000080        <1> 	or	eax, EOL
   119                              <1> 	;or	eax, FLAG
   120 0000058C 66AB                <1> 	stosd
   121                              <1> 
   122 0000058E E2CA                <1>         loop    _0
   123 00000590 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 00000591 660FB706[7E09]      <1>         movzx   eax, word [BDL_BUFFER]
   132 00000597 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 0000059B 66BA04000000        <1> 	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_TABLE_PTR
   137 000005A1 E8D1FE              <1>         call    ctrl_io_w32
   138                              <1> 
   139 000005A4 E823FF              <1> 	call	codec_check_ready
   140                              <1> 
   141 000005A7 BA0200              <1>   	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_L
   142 000005AA 66B802000000        <1>         mov     eax, 2   ;31
   143 000005B0 E8B6FE              <1>         call    ctrl_io_w8
   144                              <1> 
   145 000005B3 E814FF              <1> 	call	codec_check_ready
   146                              <1> 
   147 000005B6 BA0300              <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_R
   148 000005B9 B80200              <1>         mov     ax, 2   ;31
   149 000005BC E8AAFE              <1>         call    ctrl_io_w8
   150                              <1> 
   151 000005BF 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 000005C2 B01F                <1>         mov	al, 31
   167 000005C4 E8F400              <1> 	call    setLastValidIndex
   168                              <1> 
   169 000005C7 C606[7D09]01        <1> 	mov	byte [tLoop], 1 ; 30/11/2016
   170                              <1> 
   171 000005CC B82300              <1>         mov	ax, VIA_REG_CTRL_INT
   172 000005CF 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 000005D5 BA0100              <1> 	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   177 000005D8 E88EFE              <1>         call    ctrl_io_w8
   178                              <1> 
   179 000005DB 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 000005DE E82201              <1> 	call    check4keyboardstop      ; keyboard halt?
   189 000005E1 7306                <1>         jnc     short r_loop
   190                              <1> 
   191 000005E3 C606[7D09]00        <1> 	mov	byte [tLoop], 0
   192 000005E8 C3                  <1> 	retn
   193                              <1> r_loop:
   194                              <1> 	; 07/12/2016 - Erdogan Tan
   195 000005E9 90                  <1> 	nop
   196 000005EA 90                  <1> 	nop
   197 000005EB 90                  <1> 	nop
   198 000005EC 31C0                <1> 	xor	ax, ax
   199 000005EE 8606[5A09]          <1> 	xchg	al, [tBuff] ; AL = [tBuff], [tBuff] = 0
   200 000005F2 3C01                <1> 	cmp	al, 1
   201 000005F4 72E8                <1> 	jb	short p_loop
   202 000005F6 740A                <1> 	je	short q_loop
   203 000005F8 A1[8209]            <1>         mov     ax, [WAV_BUFFER2] ; [tBuff]=2 (from tuneLoop)
   204 000005FB E86C00              <1>         call    loadFromFile
   205 000005FE 7255                <1> 	jc	short _exit_
   206 00000600 EBE7                <1> 	jmp	short r_loop
   207                              <1> q_loop:
   208 00000602 A1[8009]            <1>      	mov     ax, [WAV_BUFFER1] ; [tBuff]=1 (from tuneLoop)
   209 00000605 E86200              <1>         call    loadFromFile
   210 00000608 724B                <1> 	jc	short _exit_
   211 0000060A 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 0000060C 803E[7D09]01        <1> 	cmp	byte [tLoop], 1
   218 00000611 7247                <1> 	jb	short _exit
   219                              <1> 
   220                              <1> 	; 07/12/2016
   221 00000613 06                  <1> 	push	es 
   222 00000614 29F6                <1> 	sub	si, si
   223 00000616 B800B8              <1> 	mov	ax, 0B800h ; video display page segment
   224 00000619 8EC0                <1> 	mov	es, ax
   225 0000061B B44E                <1> 	mov	ah, 4Eh
   226 0000061D B031                <1> 	mov	al, '1'
   227                              <1> 	
   228 0000061F C606[5A09]01        <1> 	mov	byte [tBuff], 1 ; Buffer 1
   229                              <1> 
   230 00000624 F606[7B09]02        <1> 	test	byte [irq_status], VIA_REG_STAT_EOL 
   231 00000629 7406                <1> 	jz	short _tlp1 ; FLAG
   232                              <1> 	
   233                              <1> 	; EOL
   234 0000062B FE06[5A09]          <1> 	inc	byte [tBuff] ; Buffer 2
   235 0000062F FEC0                <1> 	inc	al
   236                              <1> _tlp1: 
   237 00000631 268904              <1> 	mov	[es:si], ax ; show playing buffer (1, 2)
   238 00000634 07                  <1> 	pop	es
   239                              <1> 
   240 00000635 F606[7B09]01        <1> 	test	byte [irq_status], VIA_REG_STAT_FLAG 
   241 0000063A 740F                <1> 	jz	short _tlp2
   242                              <1> 
   243 0000063C B82300              <1> 	mov	ax, VIA_REG_CTRL_INT
   244 0000063F 0D8000              <1>        	or	ax, VIA_REG_CTRL_START
   245 00000642 BA0100              <1>        	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   246 00000645 E821FE              <1>         call    ctrl_io_w8
   247                              <1> 
   248 00000648 E87FFE              <1> 	call	codec_check_ready
   249                              <1> _tlp2:	
   250 0000064B A0[7B09]            <1>         mov     al, [irq_status]   ;; ack ;;
   251 0000064E BA0000              <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   252 00000651 E815FE              <1>         call    ctrl_io_w8
   253                              <1> 
   254 00000654 C3                  <1> 	retn
   255                              <1> 
   256                              <1> _exit_:
   257 00000655 C606[7D09]00        <1> 	mov	byte [tLoop], 0
   258                              <1> _exit:
   259                              <1>         ; finished with song, stop everything
   260 0000065A B82300              <1> 	mov     ax, VIA_REG_CTRL_INT
   261 0000065D 83C840              <1>         or      ax, VIA_REG_CTRL_TERMINATE
   262 00000660 BA0100              <1> 	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
   263 00000663 E803FE              <1>         call    ctrl_io_w8
   264                              <1> 
   265 00000666 E888FE              <1>         call	channel_reset
   266                              <1> _return:
   267 00000669 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 0000066A 50                  <1>         push    ax
   279 0000066B 51                  <1>         push    cx
   280 0000066C 52                  <1>         push    dx
   281                              <1> 	;push	es
   282 0000066D 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 0000066E F606[7A09]01        <1>         test    byte [flags], ENDOFFILE
   289 00000673 F9                  <1>         stc					; last of the file?
   290 00000674 7532                <1>         jnz     short endLFF
   291                              <1>         
   292 00000676 8ED8                <1> 	mov     ds, ax
   293 00000678 31D2                <1>         xor     dx, dx                          ; load file into memory
   294 0000067A B90080              <1>         mov     cx, (FILESIZE / 2)              ; 32k chunk
   295 0000067D B43F                <1> 	mov	ah, 3fh
   296 0000067F 2E8B1E[7809]        <1> 	mov	bx, [cs:filehandle]
   297 00000684 CD21                <1> 	int	21h
   298                              <1>         
   299 00000686 F8                  <1> 	clc
   300 00000687 39C8                <1>         cmp	ax, cx
   301                              <1> 	;je	short _lff1
   302 00000689 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 0000068B 01C2                <1>         add     dx, ax
   310                              <1> 
   311 0000068D B90080              <1>         mov     cx, (FILESIZE / 2)              ; 32k chunk
   312 00000690 B43F                <1> 	mov	ah, 3fh
   313 00000692 2E8B1E[7809]        <1> 	mov	bx, [cs:filehandle]
   314 00000697 CD21                <1> 	int	21h
   315 00000699 F8                  <1>         clc
   316 0000069A 39C8                <1>         cmp     ax, cx
   317 0000069C 740A                <1>         je      short endLFF
   318                              <1> _lff1:
   319                              <1>         ;or     byte [es:flags], ENDOFFILE      ; flag end of file
   320 0000069E 2E800E[7A09]01      <1>         or	byte [cs:flags], ENDOFFILE
   321 000006A4 E80600              <1> 	call    padfill                         ; blank pad the remainder
   322 000006A7 F8                  <1>         clc                                     ; don't exit with CY yet.
   323                              <1> endLFF:
   324 000006A8 1F                  <1>         pop	ds
   325                              <1> 	;pop	es
   326 000006A9 5A                  <1> 	pop     dx
   327 000006AA 59                  <1>         pop     cx
   328 000006AB 58                  <1>         pop     ax
   329 000006AC 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 000006AD 53                  <1>         push    bx
   338 000006AE 29C1                <1>         sub     cx, ax
   339 000006B0 89C3                <1>         mov     bx, ax
   340 000006B2 30C0                <1>         xor     al, al
   341                              <1> padfloop:
   342 000006B4 8807                <1>         mov     [bx], al
   343 000006B6 43                  <1>         inc     bx
   344 000006B7 E2FB                <1>         loop    padfloop
   345 000006B9 5B                  <1>         pop     bx
   346 000006BA 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 000006BB 50                  <1> 	push	ax
   367                              <1> 	;push	ecx
   368 000006BC 660FB706[9409]      <1> 	movzx	eax, word [sample_rate] ; Hertz
   369 000006C2 66BA00001000        <1> 	mov	edx, 100000h ; 2^20 = 1048576
   370 000006C8 66F7E2              <1> 	mul	edx
   371 000006CB 66B980BB0000        <1> 	mov	ecx, 48000	
   372 000006D1 66F7F1              <1> 	div	ecx
   373                              <1> 	;and	eax, 0FFFFFh
   374                              <1> 	;pop	ecx
   375 000006D4 5A                  <1> 	pop	dx 
   376 000006D5 66C1E218            <1> 	shl	edx, 24  ; STOP Index Setting: Bit 24 to 31
   377 000006D9 6609D0              <1> 	or	eax, edx
   378                              <1> 	; 19/11/2016
   379 000006DC 803E[9709]10        <1> 	cmp	byte [bps], 16
   380 000006E1 7506                <1> 	jne	short sLVI_1
   381 000006E3 660D00002000        <1> 	or	eax, VIA8233_REG_TYPE_16BIT
   382                              <1> sLVI_1:
   383 000006E9 803E[9609]02        <1> 	cmp	byte [stmo], 2
   384 000006EE 7506                <1> 	jne	short sLVI_2
   385 000006F0 660D00001000        <1> 	or	eax, VIA8233_REG_TYPE_STEREO
   386                              <1> sLVI_2:
   387 000006F6 66BA08000000        <1> 	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
   388 000006FC E876FD              <1>         call    ctrl_io_w32
   389 000006FF E8C8FD              <1> 	call	codec_check_ready
   390                              <1> 	;pop	edx
   391 00000702 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 00000703 06                  <1>         push    es
   397 00000704 6A00                <1>         push    0
   398 00000706 07                  <1>         pop     es		       ; examine BDA for keyboard flags
   399 00000707 26F606170403        <1>         test    byte [es:417h], (BIT0 | BIT1)
   400 0000070D 07                  <1>         pop     es
   401 0000070E F9                  <1>         stc
   402 0000070F 7501                <1>         jnz     short _cksr
   403 00000711 F8                  <1>         clc
   404                              <1> _cksr:
   405 00000712 C3                  <1>         retn
   416                                  
   417                                  ; UTILS.ASM
   418                                  ;----------------------------------------------------------------------------
   419                                  ;       delay1_4ms - Delay for 1/4 millisecond.
   420                                  ;		    1mS = 1000us
   421                                  ;       Entry:
   422                                  ;         None
   423                                  ;       Exit:
   424                                  ;	  None
   425                                  ;
   426                                  ;       Modified:
   427                                  ;         None
   428                                  ;
   429                                  PORTB			EQU	061h
   430                                    REFRESH_STATUS	EQU	010h		; Refresh signal status
   431                                  
   432                                  delay1_4ms:
   433 00000713 50                              push    ax 
   434 00000714 51                              push    cx
   435 00000715 B91000                          mov     cx, 16			; close enough.
   436 00000718 E461                    	in	al,PORTB
   437 0000071A 2410                    	and	al,REFRESH_STATUS
   438 0000071C 88C4                    	mov	ah,al			; Start toggle state
   439 0000071E 09C9                    	or	cx, cx
   440 00000720 7401                    	jz	short _d4ms1
   441 00000722 41                      	inc	cx			; Throwaway first toggle
   442                                  _d4ms1:	
   443 00000723 E461                    	in	al,PORTB		; Read system control port
   444 00000725 2410                    	and	al,REFRESH_STATUS	; Refresh toggles 15.085 microseconds
   445 00000727 38C4                    	cmp	ah,al
   446 00000729 74F8                    	je	short _d4ms1		; Wait for state change
   447                                  
   448 0000072B 88C4                    	mov	ah,al			; Update with new state
   449 0000072D 49                      	dec	cx
   450 0000072E 75F3                    	jnz	short _d4ms1
   451                                  
   452 00000730 59                              pop     cx
   453 00000731 58                              pop     ax
   454 00000732 C3                              retn
   455                                  
   456                                  	; 13/11/2016 - Erdogan Tan
   457                                  write_ac97_dev_info:
   458                                  	; BUS/DEV/FN
   459                                  	;	00000000BBBBBBBBDDDDDFFF00000000
   460                                  	; DEV/VENDOR
   461                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
   462                                  
   463 00000733 30FF                    	xor	bh, bh
   464 00000735 668B36[8A09]            	mov	esi, [dev_vendor]
   465 0000073A 89F0                    	mov	ax, si
   466 0000073C 88C3                    	mov	bl, al
   467 0000073E 88DA                    	mov	dl, bl
   468 00000740 80E30F                  	and	bl, 0Fh
   469 00000743 8A87[A809]              	mov	al, [bx+hex_chars]
   470 00000747 A2[EB09]                	mov	[msgVendorId+3], al
   471 0000074A 88D3                    	mov	bl, dl
   472 0000074C C0EB04                  	shr	bl, 4
   473 0000074F 8A87[A809]              	mov	al, [bx+hex_chars]
   474 00000753 A2[EA09]                	mov	[msgVendorId+2], al
   475 00000756 88E3                    	mov	bl, ah
   476 00000758 88DA                    	mov	dl, bl
   477 0000075A 80E30F                  	and	bl, 0Fh
   478 0000075D 8A87[A809]              	mov	al, [bx+hex_chars]
   479 00000761 A2[E909]                	mov	[msgVendorId+1], al
   480 00000764 88D3                    	mov	bl, dl
   481 00000766 C0EB04                  	shr	bl, 4
   482 00000769 8A87[A809]              	mov	al, [bx+hex_chars]
   483 0000076D A2[E809]                	mov	[msgVendorId], al
   484 00000770 66C1EE10                	shr	esi, 16
   485 00000774 89F0                    	mov	ax, si
   486 00000776 88C3                    	mov	bl, al
   487 00000778 88DA                    	mov	dl, bl
   488 0000077A 80E30F                  	and	bl, 0Fh
   489 0000077D 8A87[A809]              	mov	al, [bx+hex_chars]
   490 00000781 A2[FC09]                	mov	[msgDevId+3], al
   491 00000784 88D3                    	mov	bl, dl
   492 00000786 C0EB04                  	shr	bl, 4
   493 00000789 8A87[A809]              	mov	al, [bx+hex_chars]
   494 0000078D A2[FB09]                	mov	[msgDevId+2], al
   495 00000790 88E3                    	mov	bl, ah
   496 00000792 88DA                    	mov	dl, bl
   497 00000794 80E30F                  	and	bl, 0Fh
   498 00000797 8A87[A809]              	mov	al, [bx+hex_chars]
   499 0000079B A2[FA09]                	mov	[msgDevId+1], al
   500 0000079E 88D3                    	mov	bl, dl
   501 000007A0 C0EB04                  	shr	bl, 4
   502 000007A3 8A87[A809]              	mov	al, [bx+hex_chars]
   503 000007A7 A2[F909]                	mov	[msgDevId], al
   504                                  
   505 000007AA 668B36[8609]            	mov	esi, [bus_dev_fn]
   506 000007AF 66C1EE08                	shr	esi, 8
   507 000007B3 89F0                    	mov	ax, si
   508 000007B5 88C3                    	mov	bl, al
   509 000007B7 88DA                    	mov	dl, bl
   510 000007B9 80E307                  	and	bl, 7 ; bit 0,1,2
   511 000007BC 8A87[A809]              	mov	al, [bx+hex_chars]
   512 000007C0 A2[200A]                	mov	[msgFncNo+1], al
   513 000007C3 88D3                    	mov	bl, dl
   514 000007C5 C0EB03                  	shr	bl, 3
   515 000007C8 88DA                    	mov	dl, bl
   516 000007CA 80E30F                  	and	bl, 0Fh
   517 000007CD 8A87[A809]              	mov	al, [bx+hex_chars]
   518 000007D1 A2[120A]                	mov	[msgDevNo+1], al
   519 000007D4 88D3                    	mov	bl, dl
   520 000007D6 C0EB04                  	shr	bl, 4
   521 000007D9 8A87[A809]              	mov	al, [bx+hex_chars]
   522 000007DD A2[110A]                	mov	[msgDevNo], al
   523 000007E0 88E3                    	mov	bl, ah
   524 000007E2 88DA                    	mov	dl, bl
   525 000007E4 80E30F                  	and	bl, 0Fh
   526 000007E7 8A87[A809]              	mov	al, [bx+hex_chars]
   527 000007EB A2[060A]                	mov	[msgBusNo+1], al
   528 000007EE 88D3                    	mov	bl, dl
   529 000007F0 C0EB04                  	shr	bl, 4
   530 000007F3 8A87[A809]              	mov	al, [bx+hex_chars]
   531 000007F7 A2[050A]                	mov	[msgBusNo], al
   532                                  
   533 000007FA A1[9209]                	mov	ax, [ac97_io_base]
   534 000007FD 88C3                    	mov	bl, al
   535 000007FF 88DA                    	mov	dl, bl
   536 00000801 80E30F                  	and	bl, 0Fh
   537 00000804 8A87[A809]              	mov	al, [bx+hex_chars]
   538 00000808 A2[390A]                	mov	[msgIOBaseAddr+3], al
   539 0000080B 88D3                    	mov	bl, dl
   540 0000080D C0EB04                  	shr	bl, 4
   541 00000810 8A87[A809]              	mov	al, [bx+hex_chars]
   542 00000814 A2[380A]                	mov	[msgIOBaseAddr+2], al
   543 00000817 88E3                    	mov	bl, ah
   544 00000819 88DA                    	mov	dl, bl
   545 0000081B 80E30F                  	and	bl, 0Fh
   546 0000081E 8A87[A809]              	mov	al, [bx+hex_chars]
   547 00000822 A2[370A]                	mov	[msgIOBaseAddr+1], al
   548 00000825 88D3                    	mov	bl, dl
   549 00000827 C0EB04                  	shr	bl, 4
   550 0000082A 8A87[A809]              	mov	al, [bx+hex_chars]
   551 0000082E A2[360A]                	mov	[msgIOBaseAddr], al
   552                                  
   553                                  	; 24/11/2016
   554 00000831 30E4                    	xor	ah, ah
   555 00000833 A0[8409]                	mov	al, [ac97_int_ln_reg]
   556 00000836 B10A                    	mov	cl, 10
   557 00000838 F6F1                    	div	cl
   558 0000083A 0106[410A]              	add	[msgIRQ], ax
   559 0000083E 20C0                    	and	al, al
   560 00000840 7508                    	jnz	short _pmi
   561 00000842 A0[420A]                	mov	al, [msgIRQ+1]
   562 00000845 B420                    	mov	ah, ' '
   563 00000847 A3[410A]                	mov	[msgIRQ], ax
   564                                  _pmi:
   565 0000084A BA[B909]                        mov	dx, msgAC97Info
   566 0000084D B409                            mov     ah, 9
   567 0000084F CD21                            int     21h
   568 00000851 C3                              retn
   569                                  
   570                                  write_sample_rate:
   571                                  	; ax = sample rate (hertz)
   572                                  
   573 00000852 31D2                    	xor	dx, dx
   574 00000854 B90A00                  	mov	cx, 10
   575 00000857 F7F1                    	div	cx
   576 00000859 0016[570A]              	add	[msgHertz+4], dl
   577 0000085D 29D2                    	sub	dx, dx
   578 0000085F F7F1                    	div	cx
   579 00000861 0016[560A]              	add	[msgHertz+3], dl
   580 00000865 29D2                    	sub	dx, dx
   581 00000867 F7F1                    	div	cx
   582 00000869 0016[550A]              	add	[msgHertz+2], dl
   583 0000086D 29D2                    	sub	dx, dx
   584 0000086F F7F1                    	div	cx
   585 00000871 0016[540A]              	add	[msgHertz+1], dl
   586 00000875 0006[530A]              	add	[msgHertz], al
   587                                  	
   588 00000879 BA[460A]                        mov     dx, msgSampleRate
   589 0000087C B409                            mov     ah, 9
   590 0000087E CD21                            int     21h
   591                                  
   592                                  	; 19/11/2016
   593 00000880 BA[6C0A]                	mov	dx, msg16Bits
   594 00000883 803E[9709]10            	cmp	byte [bps], 16
   595 00000888 7403                    	je	short wsr_1
   596 0000088A BA[5D0A]                	mov	dx, msg8Bits
   597                                  wsr_1:
   598 0000088D B409                            mov     ah, 9
   599 0000088F CD21                            int     21h
   600                                  
   601 00000891 BA[650A]                	mov	dx, msgMono
   602 00000894 803E[9609]01            	cmp	byte [stmo], 1
   603 00000899 7403                    	je	short wsr_2
   604 0000089B BA[750A]                	mov	dx, msgStereo		
   605                                  wsr_2:
   606 0000089E B409                            mov     ah, 9
   607 000008A0 CD21                            int     21h
   608                                  
   609 000008A2 C3                              retn
   610                                  
   611                                  ;detect_codec:
   612                                  ;	; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   613                                  ;	mov	eax, 7Ch
   614                                  ;	call	codec_read
   615                                  ;       shl     eax, 16
   616                                  ;       mov     [codec_id], eax
   617                                  ;
   618                                  ;	mov	eax, 7Eh
   619                                  ;       call	codec_read
   620                                  ;       or      eax, [codec_id]
   621                                  ;       mov     [codec_chip_id], eax
   622                                  ;       and     eax, 0FFFFFF00h
   623                                  ;
   624                                  ;       mov     edi, codecs
   625                                  ;_dcb:
   626                                  ;       mov     ebx, [di]
   627                                  ;       test    ebx, ebx
   628                                  ;       jz      short _dco_unknown
   629                                  ;
   630                                  ;       cmp     eax, ebx
   631                                  ;       jne     short _dco_next
   632                                  ;       mov     ax, [di+4]
   633                                  ;       mov     [codec_vendor_ids], ax
   634                                  ;       movzx   esi, ax
   635                                  ;       call	print_msg
   636                                  ;       
   637                                  ;	mov	ax, [di+6]
   638                                  ;	call	detect_chip
   639                                  ;       retn
   640                                  ;
   641                                  ;_dco_next:
   642                                  ;       add     di, 8
   643                                  ;       jmp     short _dcb
   644                                  ;
   645                                  ;_dco_unknown:
   646                                  ;       mov    word [codec_vendor_ids], ac_unknown
   647                                  ;       mov    word [codec_chip_ids], chip_unknown
   648                                  ;       mov     esi, chip_unknown
   649                                  ;	call	print_msg
   650                                  ;       mov     eax, [codec_chip_id]
   651                                  ;       call    dword2str
   652                                  ;       call	print_msg
   653                                  ;       retn
   654                                  
   655                                  ;detect_chip:
   656                                  ;	; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   657                                  ;	mov	di, ax ; chip_tab
   658                                  ;       mov     eax, [codec_chip_id]
   659                                  ;       and     ax, 0FFh
   660                                  ;_dch1:
   661                                  ;       mov     bx, [di]
   662                                  ;       cmp     bx, 0FFh
   663                                  ;       je      short _dch_unknown
   664                                  ;
   665                                  ;       cmp     ax, bx
   666                                  ;       jne     short _dch_next
   667                                  ;       mov     ax, [di+2]
   668                                  ;       mov     [codec_chip_ids], ax
   669                                  ;       mov     si, ax
   670                                  ;       call	print_msg
   671                                  ;       retn
   672                                  
   673                                  ;_dch_next:
   674                                  ;       add     di, 4
   675                                  ;       jmp     short _dch1
   676                                  ;
   677                                  ;_dch_unknown:
   678                                  ;       mov    word [codec_chip_ids], chip_unknown
   679                                  ;       mov     si, chip_unknown
   680                                  ;       call	print_msg
   681                                  ;       mov     eax, [codec_chip_id]
   682                                  ;       call    dword2str
   683                                  ;       call	print_msg
   684                                  ;       retn
   685                                  
   686                                  ac97_int_handler:
   687 000008A3 50                      	push	ax
   688 000008A4 52                      	push	dx
   689 000008A5 51                      	push	cx
   690 000008A6 53                      	push	bx
   691 000008A7 56                      	push	si
   692 000008A8 57                      	push	di
   693                                  
   694                                  	; 28/11/2016
   695 000008A9 803E[7C09]01            	cmp	byte [uLVI], 1
   696 000008AE 7337                    	jnb	short _busy
   697                                  
   698 000008B0 C606[7C09]01            	mov	byte [uLVI], 1
   699                                  
   700 000008B5 C606[7B09]00            	mov	byte [irq_status], 0
   701                                  
   702 000008BA BA0000                          mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   703 000008BD E8AFFB                          call    ctrl_io_r8
   704                                  
   705 000008C0 A880                    	test    al, VIA_REG_STAT_ACTIVE
   706 000008C2 740A                            jz      short _ih0
   707                                  
   708 000008C4 2407                            and     al, VIA_REG_STAT_EOL + VIA_REG_STAT_FLAG + VIA_REG_STAT_STOPPED
   709 000008C6 A2[7B09]                	mov	[irq_status], al
   710 000008C9 7403                            jz	short _ih0
   711                                  
   712                                  	; 28/11/2016 - Erdogan Tan
   713 000008CB E83EFD                  	call	tuneLoop
   714                                  _ih0:
   715 000008CE C606[7C09]00            	mov	byte [uLVI], 0
   716                                  _p_i_retn:
   717 000008D3 B020                    	mov	al, 20h
   718 000008D5 F606[8409]08            	test	byte [ac97_int_ln_reg], 8
   719 000008DA 7402                    	jz	short _ih_1
   720 000008DC E6A0                    	out 	0A0h, al ; 20h ; EOI
   721                                  _ih_1:
   722 000008DE E620                    	out	20h, al  ; 20h ; EOI
   723                                  _ih_2:
   724 000008E0 5F                      	pop	di
   725 000008E1 5E                      	pop	si
   726 000008E2 5B                      	pop	bx
   727 000008E3 59                      	pop	cx
   728 000008E4 5A                      	pop	dx
   729 000008E5 58                      	pop	ax
   730 000008E6 CF                      	iret
   731                                  
   732                                  _busy:
   733                                  	; 28/11/2016 - Erdogan Tan
   734 000008E7 A0[7B09]                        mov     al, [irq_status]   ;; ack ;;
   735 000008EA BA0000                          mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   736 000008ED E879FB                          call    ctrl_io_w8
   737                                  
   738 000008F0 EBDC                    	jmp	short _ih0
   739                                  
   740                                  print_msg:
   741                                  	; 13/11/2016 - Erdogan Tan 
   742                                  	; esi = ASCIIZ text address
   743                                  	;
   744 000008F2 BB0700                  	mov	bx, 7h
   745 000008F5 B40E                    	mov	ah, 0Eh 
   746                                  pm_next_char:
   747 000008F7 AC                      	lodsb
   748 000008F8 20C0                    	and	al, al
   749 000008FA 7404                    	jz	short pm_retn
   750 000008FC CD10                    	int	10h
   751 000008FE EBF7                    	jmp	short pm_next_char
   752                                  pm_retn:
   753 00000900 C3                      	retn
   754                                  
   755                                  dword2str:
   756                                  	; 13/11/2016 - Erdogan Tan 
   757                                  	; eax = dword value
   758                                  	;
   759 00000901 E84400                  	call	dwordtohex
   760 00000904 668916[7E0A]            	mov	[dword_str], edx
   761 00000909 66A3[820A]              	mov	[dword_str+4], eax
   762 0000090D BE[7E0A]                	mov	si, dword_str
   763 00000910 C3                      	retn
   764                                  
   765                                  	; trdos386.s (unix386.s) - 10/05/2015
   766                                  	; Convert binary number to hexadecimal string
   767                                  
   768                                  bytetohex:
   769                                  	; INPUT ->
   770                                  	; 	AL = byte (binary number)
   771                                  	; OUTPUT ->
   772                                  	;	AX = hexadecimal string
   773                                  	;
   774 00000911 53                      	push	bx
   775 00000912 30FF                    	xor	bh, bh
   776 00000914 88C3                    	mov	bl, al
   777 00000916 C0EB04                  	shr	bl, 4
   778 00000919 8A9F[A809]              	mov	bl, [bx+hex_chars] 	 	
   779 0000091D 86D8                    	xchg	bl, al
   780 0000091F 80E30F                  	and	bl, 0Fh
   781 00000922 8AA7[A809]              	mov	ah, [bx+hex_chars] 
   782 00000926 5B                      	pop	bx	
   783 00000927 C3                      	retn
   784                                  
   785                                  wordtohex:
   786                                  	; INPUT ->
   787                                  	; 	AX = word (binary number)
   788                                  	; OUTPUT ->
   789                                  	;	EAX = hexadecimal string
   790                                  	;
   791 00000928 53                      	push	bx
   792 00000929 30FF                    	xor	bh, bh
   793 0000092B 86E0                    	xchg	ah, al
   794 0000092D 50                      	push	ax
   795 0000092E 88E3                    	mov	bl, ah
   796 00000930 C0EB04                  	shr	bl, 4
   797 00000933 8A87[A809]              	mov	al, [bx+hex_chars] 	 	
   798 00000937 88E3                    	mov	bl, ah
   799 00000939 80E30F                  	and	bl, 0Fh
   800 0000093C 8AA7[A809]              	mov	ah, [bx+hex_chars]
   801 00000940 66C1E010                	shl	eax, 16
   802 00000944 58                      	pop	ax
   803 00000945 5B                      	pop	bx
   804 00000946 EBC9                    	jmp	short bytetohex
   805                                  
   806                                  dwordtohex:
   807                                  	; INPUT ->
   808                                  	; 	EAX = dword (binary number)
   809                                  	; OUTPUT ->
   810                                  	;	EDX:EAX = hexadecimal string
   811                                  	;
   812 00000948 6650                    	push	eax
   813 0000094A 66C1E810                	shr	eax, 16
   814 0000094E E8D7FF                  	call	wordtohex
   815 00000951 6689C2                  	mov	edx, eax
   816 00000954 6658                    	pop	eax
   817 00000956 E8CFFF                  	call	wordtohex
   818 00000959 C3                      	retn
   819                                  
   820                                  _DATA:
   821                                  
   822 0000095A 02                      tBuff	db 2	; 08/12/2016
   823                                  
   824                                  ; 28/11/2016
   825 0000095B 90                      align 2
   826                                  
   827 0000095C 0000<rept>              smpRBuff	times 14 dw 0 ; 19/11/2016 - Erdogan Tan
   828                                  
   829 00000978 0000                    filehandle	dw	0
   830                                  
   831 0000097A 00                      flags	   db 0
   832 0000097B 00                      irq_status db 0
   833                                  
   834 0000097C 00                      uLVI	db 0
   835 0000097D 00                      tLoop	db 0
   836                                  
   837                                  ; 256 byte buffer for descriptor list
   838 0000097E 0000                    BDL_BUFFER      dw      0               ; segment of our 256byte BDL buffer
   839 00000980 0000                    WAV_BUFFER1     dw      0               ; segment of our WAV storage
   840                                  ; 64k buffers for wav file storage
   841 00000982 0000                    WAV_BUFFER2	dw	0		; segment of 2nd wav buffer
   842                                  
   843                                  ; 12/11/2016 - Erdogan Tan
   844                                  
   845 00000984 00                      ac97_int_ln_reg db	0 
   846 00000985 00                      err_num		db 	0
   847                                  
   848 00000986 00000000                bus_dev_fn	dd	0
   849 0000098A 00000000                dev_vendor	dd	0
   850 0000098E 00000000                stats_cmd	dd	0
   851 00000992 0000                    ac97_io_base	dw	0
   852 00000994 0000                    sample_rate	dw	0
   853                                  ; 19/11/2016
   854 00000996 00                      stmo		db	0 
   855 00000997 00                      bps		db	0
   856                                  
   857                                  ; 24/11/2016
   858                                  ;	       IRQ  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 
   859 00000998 08090A0B0C0D0E0F70-     irq_int		db 08h,09h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,70h,71h,72h,73h,74h,75h,76h,77h
   859 000009A1 71727374757677     
   860                                  
   861                                  ; 13/11/2016
   862 000009A8 303132333435363738-     hex_chars	db "0123456789ABCDEF", 0
   862 000009B1 3941424344454600   
   863 000009B9 414339372041756469-     msgAC97Info	db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah 
   863 000009C2 6F20436F6E74726F6C-
   863 000009CB 6C6572202620436F64-
   863 000009D4 656320496E666F0D0A 
   864 000009DD 56656E646F72204944-     		db "Vendor ID: "
   864 000009E6 3A20               
   865 000009E8 303030306820446576-     msgVendorId	db "0000h Device ID: "
   865 000009F1 6963652049443A20   
   866 000009F9 30303030680D0A          msgDevId	db "0000h", 0Dh, 0Ah
   867 00000A00 4275733A20              		db "Bus: "
   868 00000A05 303068204465766963-     msgBusNo	db "00h Device: "
   868 00000A0E 653A20             
   869 00000A11 3030682046756E6374-     msgDevNo	db "00h Function: "
   869 00000A1A 696F6E3A20         
   870 00000A1F 303068                  msgFncNo	db "00h"
   871 00000A22 0D0A                    		db 0Dh, 0Ah
   872 00000A24 492F4F204261736520-     		db "I/O Base Address: "
   872 00000A2D 416464726573733A20 
   873 00000A36 303030306820495251-     msgIOBaseAddr	db "0000h IRQ: "
   873 00000A3F 3A20               
   874 00000A41 3030                    msgIRQ		dw 3030h
   875 00000A43 0D0A24                  		db 0Dh, 0Ah, "$"
   876 00000A46 53616D706C65205261-     msgSampleRate	db "Sample Rate: "
   876 00000A4F 74653A20           
   877 00000A53 303030303020487A20-     msgHertz	db "00000 Hz ", "$" 
   877 00000A5C 24                 
   878 00000A5D 3820626974732024        msg8Bits	db "8 bits ", "$" 
   879 00000A65 4D6F6E6F0D0A24          msgMono		db "Mono", 0Dh, 0Ah, "$"
   880 00000A6C 313620626974732024      msg16Bits	db "16 bits ", "$" 
   881 00000A75 53746572656F0D0A24      msgStereo	db "Stereo", 0Dh, 0Ah, "$"
   882                                  
   883                                  ;; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   884                                  ;codec_id	dd 0
   885                                  ;codec_chip_id	dd 0
   886                                  ;codec_vendor_ids dw 0
   887                                  ;codec_chip_ids	dw 0
   888                                  
   889 00000A7E 3030303030303030        dword_str	 dd 30303030h, 30303030h
   890 00000A86 680D0A00                		 db 'h', 0Dh, 0Ah, 0
   891                                  
   892                                  ;ac_unknown     db 'unknown manufacturer',13,10,0
   893                                  ;ac_Realtek     db 'Realtek Semiconductor',13,10,0
   894                                  ;ac_Analog      db 'Analog Devices',13,10,0
   895                                  ;ac_CMedia      db 'C-Media Electronics',13,10,0
   896                                  ;ac_Cirrus      db 'Cirrus Logic',13,10,0
   897                                  ;ac_Wolfson     db 'Wolfson Microelectronics',13,10,0
   898                                  ;ac_VIA         db 'VIA Technologies',13,10,0
   899                                  ;ac_SigmaTel    db 'SigmaTel',13,10,0
   900                                  ;ac_eMicro      db 'eMicro',13,10,0
   901                                  ;
   902                                  ;chip_unknown   db 'unknown codec id ', 0
   903                                  
   904                                  ;CHIP_REALTEK   equ 414C4700h
   905                                  ;CHIP_CMEDIA    equ 434D4900h
   906                                  ;CHIP_VIA       equ 56494100h
   907                                  
   908                                  ;codecs        dd CHIP_CMEDIA
   909                                  ;	       dw ac_CMedia, chips_CMedia
   910                                  ;              dd CHIP_REALTEK
   911                                  ;	       dw ac_Realtek, chips_Realtek
   912                                  ;              dd CHIP_VIA
   913                                  ;	       dw ac_VIA, chips_VIA
   914                                  ;              dd 0
   915                                  
   916                                  ;chips_Realtek dw 10h, chip_ALC201a
   917                                  ;              dw 20h, chip_ALC650
   918                                  ;              dw 21h, chip_ALC650D
   919                                  ;              dw 22h, chip_ALC650E
   920                                  ;              dw 23h, chip_ALC650F
   921                                  ;              dw 60h, chip_ALC655
   922                                  ;              dw 80h, chip_ALC658
   923                                  ;              dw 81h, chip_ALC658D
   924                                  ;              dw 90h, chip_ALC850
   925                                  ;              dw 0FFh
   926                                  
   927                                  ;chips_CMedia  dw 41h, chip_CM9738
   928                                  ;              dw 61h, chip_CM9739
   929                                  ;              dw 69h, chip_CM9780
   930                                  ;              dw 78h, chip_CM9761
   931                                  ;              dw 82h, chip_CM9761
   932                                  ;              dw 83h, chip_CM9761
   933                                  ;              dw 0FFh
   934                                  
   935                                  ;chips_VIA     dw 61h, chip_VIA1612A
   936                                  ;              dw 0FFh
   937                                  
   938                                  ;Realtek
   939                                  ;chip_ALC201a    db 'ALC201a',0dh,0ah,00h
   940                                  ;chip_ALC650     db 'ALC650 ',0dh,0ah,00h
   941                                  ;chip_ALC650D    db 'ALC650D',0dh,0ah,00h
   942                                  ;chip_ALC650E    db 'ALC650E',0dh,0ah,00h
   943                                  ;chip_ALC650F    db 'ALC650F',0dh,0ah,00h
   944                                  ;chip_ALC655     db 'ALC655 ',0dh,0ah,00h
   945                                  ;chip_ALC658     db 'ALC658 ',0dh,0ah,00h
   946                                  ;chip_ALC658D    db 'ALC658D',0dh,0ah,00h
   947                                  ;chip_ALC850     db 'ALC850 ',0dh,0ah,00h
   948                                  
   949                                  ;CMedia
   950                                  ;chip_CM9738     db 'CMI9738', 0dh,0ah,0
   951                                  ;chip_CM9739     db 'CMI9739', 0dh,0ah,0
   952                                  ;chip_CM9780     db 'CMI9780', 0dh,0ah,0
   953                                  ;chip_CM9761     db 'CMI9761', 0dh,0ah,0
   954                                  
   955                                  ;VIA
   956                                  ;chip_VIA1612A   db 'VIA1612A',13,10,0
