     1                                  ; ****************************************************************************
     2                                  ; PLAYWAV.ASM - ICH AC97 .wav player for DOS.			   PLAYWAV.COM
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 19/05/2024 (Previous: 08/05/2024)
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; Beginning: 17/02/2017
     7                                  ; ----------------------------------------------------------------------------
     8                                  ; Assembler: NASM version 2.15
     9                                  ;	     nasm playwav.asm -l playwav.lst -o PLAYWAV.COM	
    10                                  ; ----------------------------------------------------------------------------
    11                                  ; Derived from '.wav file player for DOS' Jeff Leyda, Sep 02, 2002 
    12                                  ; ****************************************************************************
    13                                  ; Modidified from 'PLAYER.COM' for VIA VT8233 wav player source code by
    14                                  ; (PLAYER.ASM) by Erdogan Tan (07/11/2016 - 08/12/2016)
    15                                  
    16                                  ; TUNELOOP version (playing without AC97 interrupt) - 06/11/2023 - Erdogan Tan
    17                                  
    18                                  [BITS 16]
    19                                  
    20                                  [ORG 100h] 
    21                                  
    22                                  	%include 'ac97.inc' ; 17/02/2017
     1                              <1> ; 11/11/2023
     2                              <1> ; 05/11/2023
     3                              <1> ; 03/11/2023
     4                              <1> ; 17/02/2017 (Erdogan Tan, PLAYWAV.ASM)
     5                              <1> ; constant.inc & codec.inc (for ICH AC97 wav player, 'PLAYWAV.COM') 
     6                              <1> 
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; CONSTANT.INC
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> 
    11                              <1> ;constants of stuff that seem hard to remember at times.
    12                              <1> 
    13                              <1> TRUE  EQU 1
    14                              <1> FALSE EQU 0
    15                              <1> 
    16                              <1> ENABLED  EQU 1
    17                              <1> DISABLED EQU 0
    18                              <1> 
    19                              <1> BIT0  EQU 1
    20                              <1> BIT1  EQU 2
    21                              <1> BIT2  EQU 4
    22                              <1> BIT3  EQU 8
    23                              <1> BIT4  EQU 10h
    24                              <1> BIT5  EQU 20h
    25                              <1> BIT6  EQU 40h
    26                              <1> BIT7  EQU 80h
    27                              <1> BIT8  EQU 100h
    28                              <1> BIT9  EQU 200h
    29                              <1> BIT10 EQU 400h
    30                              <1> BIT11 EQU 800h
    31                              <1> BIT12 EQU 1000h
    32                              <1> BIT13 EQU 2000h
    33                              <1> BIT14 EQU 4000h
    34                              <1> BIT15 EQU 8000h
    35                              <1> BIT16 EQU 10000h
    36                              <1> BIT17 EQU 20000h
    37                              <1> BIT18 EQU 40000h
    38                              <1> BIT19 EQU 80000h
    39                              <1> BIT20 EQU 100000h
    40                              <1> BIT21 EQU 200000h
    41                              <1> BIT22 EQU 400000h
    42                              <1> BIT23 EQU 800000h
    43                              <1> BIT24 EQU 1000000h
    44                              <1> BIT25 EQU 2000000h
    45                              <1> BIT26 EQU 4000000h
    46                              <1> BIT27 EQU 8000000h
    47                              <1> BIT28 EQU 10000000h
    48                              <1> BIT29 EQU 20000000h
    49                              <1> BIT30 EQU 40000000h
    50                              <1> BIT31 EQU 80000000h
    51                              <1> 
    52                              <1> ;special characters
    53                              <1> NUL     EQU 0
    54                              <1> NULL    EQU 0
    55                              <1> BELL    EQU 07
    56                              <1> BS      EQU 08
    57                              <1> TAB     EQU 09
    58                              <1> LF      EQU 10
    59                              <1> CR      EQU 13
    60                              <1> ESCAPE  EQU 27           ;ESC is a reserved word....
    61                              <1> 
    62                              <1> 
    63                              <1> ;file stuff
    64                              <1> READONLY  EQU   BIT0
    65                              <1> HIDDEN    EQU   BIT1
    66                              <1> SYSTEM    EQU   BIT2
    67                              <1> VOLUME    EQU   BIT3         ;ignored for file access
    68                              <1> DIRECTORY EQU   BIT4         ;must be 0 for file access
    69                              <1> ARCHIVE   EQU   BIT5
    70                              <1> SHAREABLE EQU   BIT7         ;for novell networks
    71                              <1> OPEN	EQU	2		; open existing file
    72                              <1> CREATE	EQU	1		; create new file
    73                              <1> 
    74                              <1> 
    75                              <1> ; PCI equates
    76                              <1> ; PCI function address (PFA)
    77                              <1> ; bit 31 = 1
    78                              <1> ; bit 23:16 = bus number     (0-255)
    79                              <1> ; bit 15:11 = device number  (0-31)
    80                              <1> ; bit 10:8 = function number (0-7)
    81                              <1> ; bit 7:0 = register number  (0-255)
    82                              <1> 
    83                              <1> IO_ADDR_MASK    EQU     0FFFEh          ; mask off bit 0 for reading BARs
    84                              <1> PCI_INDEX_PORT  EQU     0CF8h
    85                              <1> PCI_DATA_PORT   EQU     0CFCh
    86                              <1> PCI32           EQU     BIT31           ; bitflag to signal 32bit access
    87                              <1> PCI16           EQU     BIT30           ; bitflag for 16bit access
    88                              <1> 
    89                              <1> PCI_FN0         EQU     0 << 8
    90                              <1> PCI_FN1         EQU     1 << 8
    91                              <1> PCI_FN2         EQU     2 << 8
    92                              <1> PCI_FN3         EQU     3 << 8
    93                              <1> PCI_FN4         EQU     4 << 8
    94                              <1> PCI_FN5         EQU     5 << 8
    95                              <1> PCI_FN6         EQU     6 << 8
    96                              <1> PCI_FN7         EQU     7 << 8
    97                              <1> 
    98                              <1> PCI_CMD_REG		EQU	04h		; reg 04, command reg
    99                              <1>  IO_ENA			EQU	BIT0		; i/o decode enable
   100                              <1>  MEM_ENA		EQU	BIT1		; memory decode enable
   101                              <1>  BM_ENA                 EQU     BIT2		; bus master enable
   102                              <1> 
   103                              <1> ; ----------------------------------------------------------------------------
   104                              <1> ; CODEC.INC
   105                              <1> ; ----------------------------------------------------------------------------
   106                              <1> 
   107                              <1> ;Codec registers.
   108                              <1> ;
   109                              <1> ;Not all codecs are created equal. Refer to the spec for your specific codec.
   110                              <1> ;
   111                              <1> ;All registers are 16bits wide.  Access to codec registers over the AC97 link
   112                              <1> ;is defined by the OEM.  
   113                              <1> ;
   114                              <1> ;Secondary codec's are accessed by ORing in BIT7 of all register accesses.
   115                              <1> ;
   116                              <1> 
   117                              <1> ; each codec/mixer register is 16bits
   118                              <1> 
   119                              <1> CODEC_RESET_REG                 equ     00      ; reset codec
   120                              <1> CODEC_MASTER_VOL_REG            equ     02      ; master volume
   121                              <1> CODEC_HP_VOL_REG                equ     04      ; headphone volume
   122                              <1> CODEC_MASTER_MONO_VOL_REG       equ     06      ; master mono volume
   123                              <1> CODEC_MASTER_TONE_REG           equ     08      ; master tone (R+L)
   124                              <1> CODEC_PCBEEP_VOL_REG            equ     0ah     ; PC beep volume
   125                              <1> CODEC_PHONE_VOL_REG             equ     0bh     ; phone volume
   126                              <1> CODEC_MIC_VOL_REG               equ     0eh     ; MIC volume
   127                              <1> CODEC_LINE_IN_VOL_REG           equ     10h     ; line input volume
   128                              <1> CODEC_CD_VOL_REG                equ     12h     ; CD volume
   129                              <1> CODEC_VID_VOL_REG               equ     14h     ; video volume
   130                              <1> CODEC_AUX_VOL_REG               equ     16h     ; aux volume
   131                              <1> CODEC_PCM_OUT_REG               equ     18h     ; PCM output volume
   132                              <1> CODEC_RECORD_SELECT_REG         equ     1ah     ; record select input
   133                              <1> CODEC_RECORD_VOL_REG            equ     1ch     ; record volume
   134                              <1> CODEC_RECORD_MIC_VOL_REG        equ     1eh     ; record mic volume
   135                              <1> CODEC_GP_REG                    equ     20h     ; general purpose
   136                              <1> CODEC_3D_CONTROL_REG            equ     22h     ; 3D control
   137                              <1> ; 24h is reserved
   138                              <1> CODEC_POWER_CTRL_REG            equ     26h     ; powerdown control
   139                              <1> CODEC_EXT_AUDIO_REG             equ     28h     ; extended audio
   140                              <1> CODEC_EXT_AUDIO_CTRL_REG        equ     2ah     ; extended audio control
   141                              <1> CODEC_PCM_FRONT_DACRATE_REG     equ     2ch     ; PCM out sample rate
   142                              <1> CODEC_PCM_SURND_DACRATE_REG     equ     2eh     ; surround sound sample rate
   143                              <1> CODEC_PCM_LFE_DACRATE_REG       equ     30h     ; LFE sample rate
   144                              <1> CODEC_LR_ADCRATE_REG            equ     32h     ; PCM in sample rate
   145                              <1> CODEC_MIC_ADCRATE_REG           equ     34h     ; mic in sample rate
   146                              <1> 
   147                              <1> ; registers 36-7a are reserved on the ICH
   148                              <1> 
   149                              <1> CODEC_VENDORID1_REG             equ     7ch     ; codec vendor ID 1
   150                              <1> CODEC_VENDORID2_REG             equ     7eh     ; codec vendor ID 2
   151                              <1> 
   152                              <1> ; Mixer registers 0 through 51h reside in the ICH and are not forwarded over
   153                              <1> ; the AC97 link to the codec, which I think is a little weird.  Looks like
   154                              <1> ; the ICH makes it so you don't need a fully functional codec to play audio?
   155                              <1> ;
   156                              <1> ; whenever 2 codecs are present in the system, use BIT7 to access the 2nd
   157                              <1> ; set of registers, ie 80h-feh
   158                              <1> 
   159                              <1> PRIMARY_CODEC                   equ     0       ; 0-7F for primary codec
   160                              <1> SECONDARY_CODEC                 equ     BIT7    ; 80-8f registers for 2ndary
   161                              <1> 
   162                              <1> SAMPLE_RATE_441khz	equ     44100   ; 44.1Khz (cd quality) rate
   163                              <1> 
   164                              <1> ; ----------------------------------------------------------------------------
   165                              <1> ; 17/02/2017
   166                              <1> PCI_IO_BASE	equ 10h			; = NAMBAR register offset
   167                              <1> AC97_INT_LINE   equ 3Ch			; AC97 Interrupt Line register offset
   168                              <1> 
   169                              <1> ; ----------------------------------------------------------------------------
   170                              <1> ; ICH2AC97.INC
   171                              <1> ; ----------------------------------------------------------------------------
   172                              <1> 
   173                              <1> ; PCI stuff
   174                              <1> 
   175                              <1> ; Intel ICH2 equates. It is assumed that ICH0 and plain ole ICH are compatible.
   176                              <1> 
   177                              <1> INTEL_VID       equ     8086h           ; Intel's PCI vendor ID
   178                              <1> ; 03/11/2023 - Erdogan Tan (Ref: MenuetOS AC97 WAV Player source code, 2004)
   179                              <1> SIS_VID		equ	1039h
   180                              <1> NVIDIA_VID	equ	10DEh	 ; Ref: MPXPLAY/SBEMU/KOLIBRIOS AC97 source c.
   181                              <1> AMD_VID		equ	1022h
   182                              <1> 
   183                              <1> ICH_DID         equ     2415h           ; ICH device ID
   184                              <1> ICH0_DID        equ     2425h           ; ICH0
   185                              <1> ICH2_DID        equ     2445h           ; ICH2 I think there are more ICHes.
   186                              <1>                                         ; they all should be compatible.
   187                              <1> 
   188                              <1> ; 17/02/2017 (Erdogan Tan, ref: ALSA Device IDs, ALSA project)
   189                              <1> ICH3_DID	equ     2485h           ; ICH3
   190                              <1> ICH4_DID        equ     24C5h           ; ICH4
   191                              <1> ICH5_DID	equ     24D5h           ; ICH5 
   192                              <1> ICH6_DID	equ     266Eh           ; ICH6
   193                              <1> ESB6300_DID	equ     25A6h           ; 6300ESB
   194                              <1> ESB631X_DID	equ     2698h           ; 631XESB
   195                              <1> ICH7_DID	equ	27DEh		; ICH7
   196                              <1> ; 03/11/2023 - Erdogan Tan (Ref: MenuetOS AC97 WAV Player source code, 2004)
   197                              <1> MX82440_DID	equ	7195h
   198                              <1> SI7012_DID	equ	7012h
   199                              <1> NFORCE_DID	equ	01B1h
   200                              <1> NFORCE2_DID	equ	006Ah
   201                              <1> AMD8111_DID	equ	746Dh
   202                              <1> AMD768_DID	equ	7445h
   203                              <1> ; 03/11/2023 - Erdogan Tan - Ref: MPXPLAY/SBEMU/KOLIBRIOS AC97 source code
   204                              <1> CK804_DID	equ	0059h
   205                              <1> MCP04_DID	equ	003Ah
   206                              <1> CK8_DID		equ	008Ah
   207                              <1> NFORCE3_DID	equ	00DAh
   208                              <1> CK8S_DID	equ	00EAh
   209                              <1> 
   210                              <1> NAMBAR_REG      equ     10h             ; native audio mixer BAR
   211                              <1>  NAM_SIZE       equ     256             ; 256 bytes required.
   212                              <1> 
   213                              <1> NABMBAR_REG     equ     14h             ; native audio bus mastering BAR
   214                              <1>  NABM_SIZE      equ     64              ; 64 bytes
   215                              <1> 
   216                              <1> ; BUS master registers, accessed via NABMBAR+offset
   217                              <1> 
   218                              <1> ; ICH supports 3 different types of register sets for three types of things
   219                              <1> ; it can do, thus:
   220                              <1> ;
   221                              <1> ; PCM in (for recording) aka PI
   222                              <1> ; PCM out (for playback) aka PO
   223                              <1> ; MIC in (for recording) aka MC
   224                              <1> 
   225                              <1> PI_BDBAR_REG            equ     0       ; PCM in buffer descriptor BAR
   226                              <1> PO_BDBAR_REG            equ     10h     ; PCM out buffer descriptor BAR
   227                              <1> MC_BDBAR_REG            equ     20h     ; MIC in buffer descriptor BAR
   228                              <1> 
   229                              <1> ; each buffer descriptor BAR holds a pointer which has entries to the buffer
   230                              <1> ; contents of the .WAV file we're going to play. Each entry is 8 bytes long
   231                              <1> ; (more on that later) and can contain 32 entries total, so each BAR is
   232                              <1> ; 256 bytes in length, thus:
   233                              <1> 
   234                              <1> BDL_SIZE                equ     32*8    ; Buffer Descriptor List size
   235                              <1> INDEX_MASK              equ     31      ; indexes must be 0-31
   236                              <1> 
   237                              <1> 
   238                              <1> 
   239                              <1> PI_CIV_REG              equ     4       ; PCM in current Index value (RO)
   240                              <1> PO_CIV_REG              equ     14h     ; PCM out current Index value (RO)
   241                              <1> MC_CIV_REG              equ     24h     ; MIC in current Index value (RO)
   242                              <1> ;8bit read only
   243                              <1> ; each current index value is simply a pointer showing us which buffer
   244                              <1> ; (0-31) the codec is currently processing. Once this counter hits 31, it
   245                              <1> ; wraps back to 0.
   246                              <1> ; this can be handy to know, as once it hits 31, we're almost out of data to
   247                              <1> ; play back or room to record!
   248                              <1> 
   249                              <1> 
   250                              <1> PI_LVI_REG              equ     5       ; PCM in Last Valid Index
   251                              <1> PO_LVI_REG              equ     15h     ; PCM out Last Valid Index
   252                              <1> MC_LVI_REG              equ     25h     ; MIC in Last Valid Index
   253                              <1> ;8bit read/write
   254                              <1> ; The Last Valid Index is a number (0-31) to let the codec know what buffer
   255                              <1> ; number to stop on after processing. It could be very nasty to play audio
   256                              <1> ; from buffers that aren't filled with the audio we want to play.
   257                              <1> 
   258                              <1> 
   259                              <1> PI_SR_REG               equ     6       ; PCM in Status register
   260                              <1> PO_SR_REG               equ     16h     ; PCM out Status register
   261                              <1> MC_SR_REG               equ     26h     ; MIC in Status register
   262                              <1> ;16bit read/write
   263                              <1> ; status registers.  Bitfields follow:
   264                              <1> 
   265                              <1> FIFO_ERR                equ     BIT4    ; FIFO Over/Underrun W1TC.
   266                              <1> 
   267                              <1> BCIS                    equ     BIT3    ; buffer completion interrupt status.
   268                              <1>                                         ; Set whenever the last sample in ANY
   269                              <1>                                         ; buffer is finished.  Bit is only
   270                              <1>                                         ; set when the Interrupt on Complete
   271                              <1>                                         ; (BIT4 of control reg) is set.
   272                              <1> 
   273                              <1> LVBCI                   equ     BIT2    ; Set whenever the codec has processed
   274                              <1>                                         ; the last buffer in the buffer list.
   275                              <1>                                         ; Will fire an interrupt if IOC bit is
   276                              <1>                                         ; set. Probably set after the last
   277                              <1>                                         ; sample in the last buffer is
   278                              <1>                                         ; processed.  W1TC
   279                              <1> 
   280                              <1>                                         ; 
   281                              <1> CELV                    equ     BIT1    ; Current buffer == last valid.
   282                              <1>                                         ; Bit is RO and remains set until LVI is
   283                              <1>                                         ; cleared.  Probably set up the start
   284                              <1>                                         ; of processing for the last buffer.
   285                              <1> 
   286                              <1> 
   287                              <1> DCH                     equ     BIT0    ; DMA controller halted.
   288                              <1>                                         ; set whenever audio stream is stopped
   289                              <1>                                         ; or something else goes wrong.
   290                              <1> 
   291                              <1> 
   292                              <1> PI_PICB_REG             equ     8       ; PCM in position in current buffer(RO)
   293                              <1> PO_PICB_REG             equ     18h     ; PCM out position in current buffer(RO)
   294                              <1> MC_PICB_REG             equ     28h     ; MIC in position in current buffer (RO)
   295                              <1> ;16bit read only
   296                              <1> ; position in current buffer regs show the number of dwords left to be
   297                              <1> ; processed in the current buffer.
   298                              <1> ; 
   299                              <1> 
   300                              <1> PI_PIV_REG              equ     0ah     ; PCM in Prefected index value
   301                              <1> PO_PIV_REG              equ     1ah     ; PCM out Prefected index value
   302                              <1> MC_PIV_REG              equ     2ah     ; MIC in Prefected index value
   303                              <1> ;8bit, read only
   304                              <1> ; Prefetched index value register.
   305                              <1> ; tells which buffer number (0-31) has be prefetched. I'd imagine this
   306                              <1> ; value follows the current index value fairly closely. (CIV+1)
   307                              <1> ;
   308                              <1> 
   309                              <1> 
   310                              <1> PI_CR_REG               equ     0bh     ; PCM in Control Register
   311                              <1> PO_CR_REG               equ     1bh     ; PCM out Control Register
   312                              <1> MC_CR_REG               equ     2bh     ; MIC in Control Register
   313                              <1> ; 8bit
   314                              <1> ; Control register *MUST* only be accessed as an 8bit value.
   315                              <1> ; Control register. See bitfields below.
   316                              <1> ;
   317                              <1> 
   318                              <1> 
   319                              <1> IOCE                    equ     BIT4    ; interrupt on complete enable.
   320                              <1>                                         ; set this bit if you want an intrtpt
   321                              <1>                                         ; to fire whenever LVBCI is set.
   322                              <1> FEIFE                   equ     BIT3    ; set if you want an interrupt to fire
   323                              <1>                                         ; whenever there is a FIFO (over or
   324                              <1>                                         ; under) error.
   325                              <1> LVBIE                   equ     BIT2    ; last valid buffer interrupt enable.
   326                              <1>                                         ; set if you want an interrupt to fire
   327                              <1>                                         ; whenever the completion of the last
   328                              <1>                                         ; valid buffer.
   329                              <1> RR                      equ     BIT1    ; reset registers.  Nukes all regs
   330                              <1>                                         ; except bits 4:2 of this register.
   331                              <1>                                         ; Only set this bit if BIT 0 is 0
   332                              <1> RPBM                    equ     BIT0    ; Run/Pause
   333                              <1>                                         ; set this bit to start the codec!
   334                              <1> 
   335                              <1> 
   336                              <1> GLOB_CNT_REG            equ     2ch     ; Global control register
   337                              <1> SEC_RES_EN              equ     BIT5    ; secondary codec resume event 
   338                              <1>                                         ; interrupt enable.  Not used here.
   339                              <1> PRI_RES_EN              equ     BIT4    ; ditto for primary. Not used here.
   340                              <1> ACLINK_OFF              equ     BIT3    ; Turn off the AC97 link
   341                              <1> ACWARM_RESET            equ     BIT2    ; Awaken the AC97 link from sleep.
   342                              <1>                                         ; registers preserved, bit self clears
   343                              <1> ACCOLD_RESET            equ     BIT1    ; Reset everything in the AC97 and
   344                              <1>                                         ; reset all registers.  Not self clearing
   345                              <1> 
   346                              <1> GPIIE                   equ     BIT0    ; GPI Interrupt enable.
   347                              <1>                                         ; set if you want an interrupt to
   348                              <1>                                         ; fire upon ANY of the bits in the
   349                              <1>                                         ; GPI (general pursose inputs?) not used.
   350                              <1> 
   351                              <1> GLOB_STS_REG            equ     30h     ; Global Status register (RO)
   352                              <1> 
   353                              <1> MD3                     equ     BIT17   ; modem powerdown status (yawn)
   354                              <1> AD3                     equ     BIT16   ; Audio powerdown status (yawn)
   355                              <1> RD_COMPLETE_STS         equ     BIT15   ; Codec read timed out. 0=normal
   356                              <1> BIT3SLOT12              equ     BIT14   ; shadowed status of bit 3 in slot 12
   357                              <1> BIT2SLOT12              equ     BIT13   ; shadowed status of bit 2 in slot 12
   358                              <1> BIT1SLOT12              equ     BIT12   ; shadowed status of bit 1 in slot 12
   359                              <1> SEC_RESUME_STS          equ     BIT11   ; secondary codec has resumed (and irqed)
   360                              <1> PRI_RESUME_STS          equ     BIT10   ; primary codec has resumed (and irqed)
   361                              <1> SEC_CODEC_RDY           equ     BIT9    ; secondary codec is ready for action
   362                              <1> PRI_CODEC_RDY           equ     BIT8    ; Primary codec is ready for action
   363                              <1>                                         ; software must check these bits before
   364                              <1>                                         ; starting the codec!
   365                              <1> MIC_IN_IRQ              equ     BIT7    ; MIC in caused an interrupt
   366                              <1> PCM_OUT_IRQ             equ     BIT6    ; One of the PCM out channels IRQed
   367                              <1> PCM_IN_IRQ              equ     BIT5    ; One of the PCM in channels IRQed
   368                              <1> MODEM_OUT_IRQ           equ     BIT2    ; modem out channel IRQed
   369                              <1> MODEM_IN_IRQ            equ     BIT1    ; modem in channel IRQed
   370                              <1> GPI_STS_CHANGE          equ     BIT0    ; set whenever GPI's have changed.
   371                              <1>                                         ; BIT0 of slot 12 also reflects this.
   372                              <1> 
   373                              <1> ACC_SEMA_REG            equ     34h     ; Codec write semiphore register
   374                              <1> CODEC_BUSY              equ     BIT0    ; codec register I/O is happening
   375                              <1>                                         ; self clearing
   376                              <1> ;
   377                              <1> ; Buffer Descriptors List
   378                              <1> ; As stated earlier, each buffer descriptor list is a set of (up to) 32 
   379                              <1> ; descriptors, each 8 bytes in length. Bytes 0-3 of a descriptor entry point
   380                              <1> ; to a chunk of memory to either play from or record to. Bytes 4-7 of an
   381                              <1> ; entry describe various control things detailed below.
   382                              <1> ; 
   383                              <1> ; Buffer pointers must always be aligned on a Dword boundry.
   384                              <1> ;
   385                              <1> 
   386                              <1> IOC                     equ     BIT31   ; Fire an interrupt whenever this
   387                              <1>                                         ; buffer is complete.
   388                              <1> 
   389                              <1> BUP                     equ     BIT30   ; Buffer Underrun Policy.
   390                              <1>                                         ; if this buffer is the last buffer
   391                              <1>                                         ; in a playback, fill the remaining
   392                              <1>                                         ; samples with 0 (silence) or not.
   393                              <1>                                         ; It's a good idea to set this to 1
   394                              <1>                                         ; for the last buffer in playback,
   395                              <1>                                         ; otherwise you're likely to get a lot
   396                              <1>                                         ; of noise at the end of the sound.
   397                              <1> 
   398                              <1> ;
   399                              <1> ; Bits 15:0 contain the length of the buffer, in number of samples, which
   400                              <1> ; are 16 bits each, coupled in left and right pairs, or 32bits each.
   401                              <1> ; Luckily for us, that's the same format as .wav files.
   402                              <1> ;
   403                              <1> ; A value of FFFF is 65536 samples. Running at 44.1Khz, that's just about
   404                              <1> ; 1.5 seconds of sample time. FFFF * 32bits is 1FFFFh bytes or 128k of data.
   405                              <1> ;
   406                              <1> ; A value of 0 in these bits means play no samples.
   407                              <1> ;
   408                              <1> 
   409                              <1> ; 11/11/2023
   410                              <1> CTRL_ST_CREADY		equ	BIT8+BIT9+BIT28 ; Primary Codec Ready
   411                              <1> CODEC_REG_POWERDOWN	equ	26h
    23                                  
    24                                  _STARTUP:
    25                                  
    26                                  ; memory allocation
    27                                  
    28 00000000 E81D01                          call    setFree				; deallocate unused DOS mem
    29                                  
    30                                  	; 17/02/2017
    31                                  	; Clear BSS (uninitialized data) area
    32 00000003 31C0                    	xor	ax, ax ; 0
    33 00000005 B91D40                  	mov	cx, (EOF - bss_start)/2
    34 00000008 BF[700A]                	mov	di, bss_start
    35 0000000B F3AB                    	rep	stosw
    36                                  
    37                                  ; allocate 256 bytes of data for DCM_OUT Buffer Descriptor List. (BDL)
    38                                  
    39 0000000D B81000                          mov     ax, BDL_SIZE / 16
    40 00000010 E81501                          call    memAlloc
    41 00000013 A3[940A]                        mov     [BDL_BUFFER], ax		; segment 
    42                                  
    43                                  ; allocate 2 buffers, 64k each for now.
    44                                  
    45 00000016 B80010                          mov     ax, BUFFERSIZE / 16		; 64k for .WAV file
    46 00000019 E80C01                          call    memAlloc
    47 0000001C A3[960A]                        mov     [WAV_BUFFER1], ax		; segment
    48                                  
    49 0000001F B80010                  	mov	ax, BUFFERSIZE / 16
    50 00000022 E80301                  	call	memAlloc
    51 00000025 A3[980A]                	mov	[WAV_BUFFER2], ax
    52                                  
    53                                  ; Detect/reset AC97 
    54                                  
    55 00000028 E87002                          call    pciFindDevice
    56 0000002B 7342                            jnc     short _1
    57                                  
    58                                  ; couldn't find the audio device!
    59                                  
    60 0000002D 0E                      	push	cs
    61 0000002E 1F                      	pop	ds
    62 0000002F BA[3900]                        mov     dx, noDevMsg
    63 00000032 B409                            mov     ah, 9
    64 00000034 CD21                            int     21h
    65 00000036 E9D700                          jmp     exit
    66                                  
    67                                  ; 17/02/2017
    68 00000039 4572726F723A20556E-     noDevMsg db "Error: Unable to find intel ICH based audio device!",CR,LF,"$"
    68 00000042 61626C6520746F2066-
    68 0000004B 696E6420696E74656C-
    68 00000054 204943482062617365-
    68 0000005D 6420617564696F2064-
    68 00000066 6576696365210D0A24 
    69                                  
    70                                  _1:
    71                                  	; eax = BUS/DEV/FN
    72                                  	;	00000000BBBBBBBBDDDDDFFF00000000
    73                                  	; edx = DEV/VENDOR
    74                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
    75                                  
    76 0000006F 66A3[9A0A]              	mov	[bus_dev_fn], eax
    77 00000073 668916[9E0A]            	mov	[dev_vendor], edx
    78                                  
    79                                  	; get ICH base address regs for mixer and bus master
    80                                  
    81 00000078 B010                            mov     al, NAMBAR_REG
    82 0000007A E89001                          call    pciRegRead16			; read PCI registers 10-11
    83                                          ;and    dx, IO_ADDR_MASK 		; mask off BIT0
    84                                  	; 19/05/2024
    85 0000007D 80E2FE                  	and	dl, 0FEh
    86                                  
    87 00000080 8916[900A]                      mov     [NAMBAR], dx			; save audio mixer base addr
    88                                  
    89 00000084 B014                    	mov     al, NABMBAR_REG
    90 00000086 E88401                          call    pciRegRead16
    91                                          ;and    dx, IO_ADDR_MASK
    92                                  	; 19/05/2024
    93 00000089 80E2C0                  	and	dl, 0C0h
    94                                  
    95 0000008C 8916[920A]                      mov     [NABMBAR], dx			; save bus master base addr
    96                                  
    97                                  	; 06/11/2023
    98                                  	;; init controller
    99                                  	;; 17/02/2017
   100                                  	;mov	al, PCI_CMD_REG ; command register (04h)
   101                                  	;call	pciRegRead16 ; pciRegRead8
   102                                  	;
   103                                  	;; eax = BUS/DEV/FN/REG
   104                                  	;;  dx = PCI Command Register Content ; 17/02/2017
   105                                  	;; 	00000000CCCCCCCC
   106                                  	;mov	[stats_cmd], dx
   107                                  	;
   108                                  	; 06/11/2023
   109                                  	;mov	al, PCI_IO_BASE ; IO base address register (10h)
   110                                  	;call	pciRegRead32
   111                                  	;
   112                                  	;and	dx, 0FFC0h	; IO_ADDR_MASK (0FFFE) ?
   113                                          ;mov	[ac97_io_base], dx
   114                                  
   115 00000090 B03C                    	mov	al, AC97_INT_LINE ; Interrupt line register (3Ch)
   116 00000092 E87001                  	call	pciRegRead8 ; 17/02/2017
   117                                  
   118 00000095 8816[8F0A]              	mov     [ac97_int_ln_reg], dl
   119                                  
   120                                  ; 05/11/2023
   121                                  %if 0
   122                                  	; 28/11/2016
   123                                  	mov	bx, 1
   124                                  	xor	dh, dh 	 ; 17/02/2017
   125                                  	mov	cx, dx
   126                                  	shl	bx, cl
   127                                  
   128                                  	; 04/11/2023
   129                                  	cli
   130                                  
   131                                  	;not	bx
   132                                  	in	al, 0A1h ; irq 8-15
   133                                          mov	ah, al
   134                                          in	al, 21h  ; irq 0-7 
   135                                  
   136                                  	; 04/11/2023
   137                                  	; save IRQ status
   138                                  	mov	[IRQ_status], ax
   139                                  
   140                                  	; 12/05/2024 (enable AC97 IRQ)
   141                                  	;mov	cl, dl
   142                                  	;mov	bx, 1
   143                                  	;shl	bx, cl
   144                                  	;not	bx
   145                                  	;and	ax, bx
   146                                  	;out	21h, al
   147                                  	;mov	al, ah
   148                                  	;out	0A1h, al
   149                                  
   150                                  	;and	ax, bx   ; unmask
   151                                   	btr	ax, dx	 ; unmask
   152                                  	out	21h, al  ; enable interrupt (if irq <= 7)
   153                                  	mov	al, ah
   154                                  	out	0A1h, al ; enable interrupt (if irq > 7)
   155                                  	;not	bx
   156                                  
   157                                  	; 04/11/2023
   158                                  	;mov	dx, 4D1h			;8259 ELCR1
   159                                          ;in	al, dx
   160                                  	;mov	ah, al
   161                                  	;mov	dx, 4D0h 
   162                                          ;in	al, dx
   163                                  	;;or	ax, bx
   164                                  	;bts	ax, cx
   165                                  	;mov	dx, 4D0h
   166                                  	;out	dx, al                          ;set level-triggered mode
   167                                  	;mov	al, ah
   168                                  	;mov	dx, 4D1h
   169                                  	;out	dx, al                          ;set level-triggered mode
   170                                  
   171                                  	; 24/11/2016 - Erdogan Tan
   172                                  	mov	bx, cx
   173                                  	;mov	bx, dx
   174                                  	mov	bl, [bx+irq_int]
   175                                  	shl	bx, 2 ; * 4
   176                                  
   177                                  	; set up interrupt vector
   178                                  	; 30/11/2016
   179                                  	push	es
   180                                  	xor	ax, ax
   181                                  	mov	es, ax
   182                                  	; 04/11/2023
   183                                  	; save interrupt vector
   184                                  	;mov	ax, [es:bx]
   185                                  	; 13/05/2024
   186                                  	mov	ax, ac97_int_handler
   187                                  	xchg	ax, [es:bx]
   188                                  	mov	[IRQ_vector], ax
   189                                  	;mov	ax, [es:bx+2]
   190                                  	; 13/05/2024
   191                                  	mov	ax, cs
   192                                  	xchg	ax, [es:bx+2]
   193                                  	mov	[IRQ_vector+2], ax
   194                                  
   195                                  	; 13/05/2024
   196                                  	;mov	word [es:bx], ac97_int_handler
   197                                  	;mov	ax, cs
   198                                  	;mov	[es:bx+2], ax
   199                                  	
   200                                  	pop	es
   201                                  
   202                                  	; 04/11/2023
   203                                  	sti
   204                                  
   205                                  %endif
   206                                  
   207 00000099 E83206                  	call	write_ac97_dev_info 
   208                                  
   209                                  ; check the command line for a file to play
   210                                  
   211                                          ;push	ds
   212 0000009C E89200                          call    processCmdline			; get the filename
   213                                  
   214                                  ; open the file
   215 0000009F B002                            mov     al, OPEN                        ; open existing file
   216 000000A1 E8AD00                          call    openFile                        ; no error? ok.
   217                                          ;pop	ds
   218 000000A4 7322                            jnc     short _gsr
   219                                  
   220                                  ; file not found!
   221                                  
   222                                          ;push   cs
   223                                          ;pop    ds
   224 000000A6 BA[AF00]                        mov	dx, noFileErrMsg
   225 000000A9 B409                            mov     ah, 9
   226 000000AB CD21                            int     21h
   227 000000AD EB61                            jmp     exit
   228                                  
   229                                  noFileErrMsg:
   230 000000AF 4572726F723A206669-     	db "Error: file not found.",CR,LF,"$"
   230 000000B8 6C65206E6F7420666F-
   230 000000C1 756E642E0D0A24     
   231                                  
   232                                  _gsr:
   233 000000C8 E8AD00                          call    getSampleRate                   ; read the sample rate
   234                                                                                  ; pass it onto codec.
   235 000000CB 7243                    	jc	short exit ; 19/11/2016 - nothing to do
   236                                  
   237 000000CD A3[A20A]                	mov	[sample_rate], ax
   238                                  	
   239                                  	; 19/11/2016
   240 000000D0 880E[A40A]              	mov	[stmo], cl
   241 000000D4 8816[A60A]              	mov	[bps], dl
   242                                  	
   243                                  	; 17/02/2017
   244 000000D8 C606[A80A]00            	mov	byte [fbs_shift], 0 ; 0 = stereo and 16 bit 
   245 000000DD FEC9                    	dec	cl
   246 000000DF 7504                    	jnz	short _gsr_1 ; stereo
   247 000000E1 FE06[A80A]              	inc	byte [fbs_shift] ; 1 = mono or 8 bit
   248                                  _gsr_1:	
   249 000000E5 80FA08                  	cmp	dl, 8 
   250 000000E8 7704                    	ja	short _gsr_2 ; 16 bit samples
   251 000000EA FE06[A80A]              	inc	byte [fbs_shift] ; 2 = mono and 8 bit
   252                                  _gsr_2:	
   253 000000EE E83307                  	call	write_sample_rate
   254                                  
   255                                  	; 05/11/2023
   256                                  _2:
   257 000000F1 E87605                  	call	check4keyboardstop  ; flush keyboard buffer
   258 000000F4 72FB                    	jc	short _2 	; 07/11/2023
   259                                  
   260                                  	; 05/11/2023
   261                                  	;mov	eax, [bus_dev_fn]
   262                                  	;mov	al, PCI_CMD_REG
   263                                  	;call	pciRegRead16			; read PCI command register
   264                                  	; 17/02/2017
   265                                  	;mov	dx, [stats_cmd]
   266                                          ;or	dl, IO_ENA+BM_ENA               ; enable IO and bus master
   267                                  	;call	pciRegWrite16 ; pciRegWrite8
   268                                  
   269                                  	; 19/05/2024
   270                                  	; 06/11/2023
   271                                  	;mov	eax, [bus_dev_fn]
   272                                  	;mov	al, PCI_CMD_REG
   273                                  	;call	pciRegRead8			; read PCI command register
   274                                  	;or	dl, IO_ENA+BM_ENA		; enable IO and bus master
   275                                  	;call	pciRegWrite8
   276                                  
   277                                  ; setup the Codec (actually mixer registers)
   278 000000F6 E8E301                          call    codecConfig                     ; unmute codec, set rates.
   279                                  	; 11/11/2023
   280 000000F9 721C                    	jc	short init_err
   281                                  ;
   282                                  ; position file pointer to start in actual wav data
   283                                  ; MUCH improvement should really be done here to check if sample size is
   284                                  ; supported, make sure there are 2 channels, etc.  
   285                                  ;
   286 000000FB B442                            mov     ah, 42h
   287 000000FD B000                            mov     al, 0                           ; from start of file
   288 000000FF 8B1E[8C0A]                      mov     bx, [filehandle]
   289 00000103 31C9                            xor     cx, cx
   290 00000105 BA2C00                          mov     dx, 44                          ; jump past .wav/riff header
   291 00000108 CD21                            int     21h
   292                                  
   293                                  ; play the .wav file. Most of the good stuff is in here.
   294                                  
   295 0000010A E88403                          call    playWav
   296                                  
   297                                  ; close the .wav file and exit.
   298                                  
   299                                  close_exit:			; 11/11/2023
   300 0000010D E85300                          call    closeFile
   301                                  
   302                                  exit:
   303 00000110 B8004C                          mov     ax, 4c00h
   304 00000113 CD21                    	int 	21h
   305                                  
   306                                  here:
   307 00000115 EBFE                    	jmp	short here
   308                                  
   309                                  	; 11/11/2023
   310                                  init_err:
   311 00000117 BA[060A]                	mov	dx, msg_init_err
   312                                  vra_err: ; 12/11/2023
   313 0000011A B409                            mov	ah, 9
   314 0000011C CD21                            int	21h
   315 0000011E EBED                    	jmp	short close_exit
   316                                  
   317                                  ; MEMALLOC.ASM
   318                                  ;-- SETFREE: Release memory not used  ----------------
   319                                  ;-- Input    : ES = address of PSP
   320                                  ;-- Output   : none
   321                                  ;-- Register : AX, BX, CL and FLAGS are changed 
   322                                  ;-- Info     : Since the stack-segment is always the last segment in an 
   323                                  ;              EXE-file, ES:0000 points to the beginning and SS:SP
   324                                  ;              to the end of the program in memory. Through this the
   325                                  ;              length of the program can be calculated 
   326                                  ; call this routine once at the beginning of the program to free up memory
   327                                  ; assigned to it by DOS.
   328                                  
   329                                  setFree:
   330 00000120 BB0010                  	  mov	bx, 65536/16	; 4K paragraphs ; 17/02/2017 (Erdogan Tan)
   331                                  
   332 00000123 B44A                              mov	ah, 4ah		; pass new length to DOS
   333 00000125 CD21                              int	21h
   334                                  
   335 00000127 C3                                retn			; back to caller 
   336                                  				; new size (allocated memory) = 64KB
   337                                  
   338                                  memAlloc:
   339                                  ; input: AX = # of paragraphs required
   340                                  ; output: AX = segment of block to use
   341                                  
   342 00000128 53                      	push	bx
   343 00000129 89C3                    	mov	bx, ax
   344 0000012B B448                    	mov	ah, 48h
   345 0000012D CD21                    	int	21h
   346 0000012F 5B                      	pop	bx
   347 00000130 C3                      	retn
   348                                  
   349                                  ; CMDLINE.ASM
   350                                  ; parse the command line
   351                                  ; entry: none
   352                                  ; exit: DS:DX to the 1st supplied item on the command line 
   353                                  
   354                                  processCmdline:
   355 00000131 53                              push    bx
   356 00000132 56                              push    si
   357                                  
   358                                          ;mov    ah, 51h
   359                                          ;int    21h
   360                                          ;mov    ds, bx
   361                                  
   362 00000133 BE8000                          mov     si, 80h
   363 00000136 0FB61C                          movzx   bx, byte [si]
   364 00000139 01DE                            add     si, bx
   365 0000013B 46                              inc     si
   366                                  
   367 0000013C C60400                          mov     byte [si], NULL         ; zero terminate
   368                                  
   369 0000013F BE8100                          mov     si, 81h
   370                                  
   371                                  cmdlineloop:
   372 00000142 AC                              lodsb
   373                                  
   374 00000143 3C00                            cmp     al, NULL                ; found end of line?
   375 00000145 7404                            je      short exitpc
   376 00000147 3C20                            cmp     al, ' '                 ; found a space?
   377 00000149 74F7                            je      short cmdlineloop
   378                                  
   379                                          ; must be the filename here.
   380                                  exitpc:
   381 0000014B 4E                              dec     si                      ; point to start of filename
   382 0000014C 89F2                            mov     dx, si
   383 0000014E 5E                              pop     si
   384 0000014F 5B                              pop     bx
   385 00000150 C3                      	retn
   386                                  
   387                                  ; FILE.ASM
   388                                  ;open or create file
   389                                  ;
   390                                  ;input: ds:dx-->filename (asciiz)
   391                                  ;       al=file Mode (create or open)
   392                                  ;output: none  cs:[filehandle] filled
   393                                  ;
   394                                  openFile:
   395 00000151 50                      	push	ax
   396 00000152 51                      	push	cx
   397 00000153 B43B                    	mov	ah, 3bh			; start with a mode
   398 00000155 00C4                    	add	ah, al			; add in create or open mode
   399 00000157 31C9                    	xor	cx, cx
   400 00000159 CD21                    	int	21h
   401 0000015B 7203                    	jc	short _of1
   402                                  	;mov	[cs:filehandle], ax
   403 0000015D A3[8C0A]                	mov	[filehandle], ax
   404                                  _of1:
   405 00000160 59                      	pop	cx
   406 00000161 58                      	pop	ax
   407 00000162 C3                      	retn
   408                                  
   409                                  ; close the currently open file
   410                                  ; input: none, uses cs:[filehandle]
   411                                  closeFile:
   412 00000163 50                      	push	ax
   413 00000164 53                      	push	bx
   414 00000165 833E[8C0A]FF            	cmp	word [filehandle], -1
   415 0000016A 7409                    	jz	short _cf1
   416 0000016C 8B1E[8C0A]              	mov     bx, [filehandle]
   417 00000170 B8003E                  	mov     ax,3e00h
   418 00000173 CD21                            int     21h              ;close file
   419                                  _cf1:
   420 00000175 5B                      	pop	bx
   421 00000176 58                      	pop	ax
   422 00000177 C3                      	retn
   423                                  
   424                                  getSampleRate:
   425                                  	; 08/12/2016
   426                                  ; reads the sample rate from the .wav file.
   427                                  ; entry: none - assumes file is already open
   428                                  	; 19/11/2016 - Erdogan Tan
   429                                  ; exit: ax = sample rate (11025, 22050, 44100, 48000)
   430                                  ;	cx = number of channels (mono=1, stereo=2)
   431                                  ;	dx = bits per sample (8, 16)
   432                                  
   433 00000178 53                      	push    bx
   434                                  
   435 00000179 B442                            mov     ah, 42h
   436 0000017B B000                            mov     al, 0				; from start of file
   437 0000017D 8B1E[8C0A]                      mov     bx, [filehandle]
   438 00000181 31C9                            xor     cx, cx
   439 00000183 BA0800                          mov     dx, 08h				; "WAVE"
   440 00000186 CD21                            int     21h
   441                                  
   442 00000188 BA[700A]                        mov     dx, smpRBuff
   443 0000018B B91C00                          mov     cx, 28				; 28 bytes
   444 0000018E B43F                    	mov	ah, 3fh
   445 00000190 CD21                            int     21h
   446                                  
   447 00000192 813E[700A]5741          	cmp	word [smpRBuff], 'WA'
   448 00000198 751C                    	jne	short gsr_stc
   449                                  
   450 0000019A 813E[720A]5645          	cmp	word [smpRBuff+2], 'VE'
   451 000001A0 7514                    	jne	short gsr_stc
   452                                  
   453 000001A2 833E[7C0A]01            	cmp	word [smpRBuff+12], 1	; Offset 20, must be 1 (= PCM)
   454 000001A7 750D                    	jne	short gsr_stc
   455                                  
   456                                  
   457 000001A9 8B0E[7E0A]              	mov	cx, [smpRBuff+14]	; return num of channels in CX
   458 000001AD A1[800A]                        mov     ax, [smpRBuff+16]	; return sample rate in AX
   459 000001B0 8B16[8A0A]              	mov	dx, [smpRBuff+26]	; return bits per sample value in DX
   460                                  gsr_retn:
   461 000001B4 5B                              pop     bx
   462 000001B5 C3                              retn
   463                                  
   464                                  gsr_stc:
   465 000001B6 F9                      	stc
   466 000001B7 EBFB                    	jmp	short gsr_retn
   467                                  
   468                                  %include 'ac97.asm' ; 29/11/2016 (AC97 codec configuration)
     1                              <1> ; 19/05/2024
     2                              <1> ; 12/11/2023
     3                              <1> ; 11/11/2023
     4                              <1> ; 06/11/2023
     5                              <1> ; 05/11/2023
     6                              <1> ; 04/11/2023
     7                              <1> ; 03/11/2023
     8                              <1> ; PCI and AC97 codec functions for wav player
     9                              <1> ; Erdogan Tan (17/02/2017)
    10                              <1> 
    11                              <1> ; ----------------------------------------------------------------------------
    12                              <1> ; PCI.ASM
    13                              <1> ; ----------------------------------------------------------------------------
    14                              <1> 
    15                              <1> ; PCI device register reader/writers.
    16                              <1> ; NASM version: Erdogan Tan (29/11/2016)
    17                              <1> ; 		Last Update: 17/02/2017
    18                              <1> 
    19                              <1> ;===============================================================
    20                              <1> ; 8/16/32bit PCI reader
    21                              <1> ;
    22                              <1> ; Entry: EAX=PCI Bus/Device/fn/register number
    23                              <1> ;           BIT30 set if 32 bit access requested
    24                              <1> ;           BIT29 set if 16 bit access requested
    25                              <1> ;           otherwise defaults to 8 bit read
    26                              <1> ;
    27                              <1> ; Exit:  DL,DX,EDX register data depending on requested read size
    28                              <1> ;
    29                              <1> ; Note: this routine is meant to be called via pciRegRead8, pciRegread16,
    30                              <1> ;	or pciRegRead32, listed below.
    31                              <1> ;
    32                              <1> ; Note2: don't attempt to read 32bits of data from a non dword aligned reg
    33                              <1> ;	 number. Likewise, don't do 16bit reads from non word aligned reg #
    34                              <1> ; 
    35                              <1> pciRegRead:
    36 000001B9 6653                <1> 	push	ebx
    37 000001BB 51                  <1> 	push	cx
    38 000001BC 6689C3              <1>         mov     ebx, eax                        ; save eax, dh
    39 000001BF 88F1                <1>         mov     cl, dh
    40 000001C1 6625FFFFFFBF        <1>         and     eax, (~PCI32)+PCI16             ; clear out data size request
    41 000001C7 660D00000080        <1>         or      eax, BIT31                      ; make a PCI access request
    42 000001CD 24FC                <1>         and     al, ~3 ; NOT 3                  ; force index to be dword
    43                              <1> 
    44 000001CF BAF80C              <1>         mov     dx, PCI_INDEX_PORT
    45 000001D2 66EF                <1>         out     dx, eax                         ; write PCI selector
    46                              <1> 
    47 000001D4 BAFC0C              <1>         mov     dx, PCI_DATA_PORT
    48 000001D7 88D8                <1>         mov     al, bl
    49 000001D9 2403                <1>         and     al, 3                           ; figure out which port to
    50 000001DB 00C2                <1>         add     dl, al                          ; read to
    51                              <1> 
    52 000001DD 66ED                <1> 	in      eax, dx                         ; do 32bit read
    53 000001DF 66F7C300000080      <1>         test    ebx, PCI32
    54 000001E6 7403                <1>         jz      short _pregr1
    55                              <1> 
    56 000001E8 6689C2              <1>         mov     edx, eax                        ; return 32bits of data
    57                              <1> _pregr1:
    58 000001EB 89C2                <1> 	mov     dx, ax                          ; return 16bits of data
    59 000001ED 66F7C3000000C0      <1>         test    ebx, PCI32+PCI16
    60 000001F4 7502                <1>         jnz     short _pregr2
    61 000001F6 88CE                <1>         mov     dh, cl                          ; restore dh for 8 bit read
    62                              <1> _pregr2:
    63 000001F8 6689D8              <1>         mov     eax, ebx                        ; restore eax
    64 000001FB 6625FFFFFFBF        <1>         and     eax, (~PCI32)+PCI16             ; clear out data size request
    65 00000201 59                  <1> 	pop	cx
    66 00000202 665B                <1> 	pop	ebx
    67 00000204 C3                  <1> 	retn
    68                              <1> 
    69                              <1> pciRegRead8:
    70 00000205 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32             ; set up 8 bit read size
    71 0000020B EBAC                <1>         jmp     short pciRegRead		; call generic PCI access
    72                              <1> 
    73                              <1> pciRegRead16:
    74 0000020D 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 16 bit read size
    75 00000213 660D00000040        <1>         or      eax, PCI16			; call generic PCI access
    76 00000219 EB9E                <1>         jmp     short pciRegRead
    77                              <1> 
    78                              <1> pciRegRead32:
    79 0000021B 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 32 bit read size
    80 00000221 660D00000080        <1>         or      eax, PCI32			; call generic PCI access
    81 00000227 EB90                <1>         jmp     short pciRegRead
    82                              <1> 
    83                              <1> ;===============================================================
    84                              <1> ; 8/16/32bit PCI writer
    85                              <1> ;
    86                              <1> ; Entry: EAX=PCI Bus/Device/fn/register number
    87                              <1> ;           BIT31 set if 32 bit access requested
    88                              <1> ;           BIT30 set if 16 bit access requested
    89                              <1> ;           otherwise defaults to 8bit read
    90                              <1> ;        DL/DX/EDX data to write depending on size
    91                              <1> ;
    92                              <1> ;
    93                              <1> ; note: this routine is meant to be called via pciRegWrite8, pciRegWrite16,
    94                              <1> ; 	or pciRegWrite32 as detailed below.
    95                              <1> ;
    96                              <1> ; Note2: don't attempt to write 32bits of data from a non dword aligned reg
    97                              <1> ;	 number. Likewise, don't do 16bit writes from non word aligned reg #
    98                              <1> ;
    99                              <1> pciRegWrite:
   100 00000229 6653                <1> 	push	ebx
   101 0000022B 51                  <1> 	push	cx
   102 0000022C 6689C3              <1>         mov     ebx, eax                        ; save eax, dx
   103 0000022F 89D1                <1>         mov     cx, dx
   104 00000231 660D00000080        <1>         or      eax, BIT31                      ; make a PCI access request
   105 00000237 6625FFFFFFBF        <1>         and     eax, ~PCI16 ; NOT PCI16         ; clear out data size request
   106 0000023D 24FC                <1>         and     al, ~3 ; NOT 3                  ; force index to be dword
   107                              <1> 
   108 0000023F BAF80C              <1>         mov     dx, PCI_INDEX_PORT
   109 00000242 66EF                <1>         out     dx, eax                         ; write PCI selector
   110                              <1> 
   111 00000244 BAFC0C              <1>         mov     dx, PCI_DATA_PORT
   112 00000247 88D8                <1>         mov     al, bl
   113 00000249 2403                <1>         and     al, 3                           ; figure out which port to
   114 0000024B 00C2                <1>         add     dl, al                          ; write to
   115                              <1> 
   116 0000024D 6689D0              <1>         mov     eax, edx                        ; put data into eax
   117 00000250 89C8                <1>         mov     ax, cx
   118                              <1> 
   119 00000252 EE                  <1>         out     dx, al
   120 00000253 66F7C3000000C0      <1>         test    ebx, PCI16+PCI32                ; only 8bit access? bail
   121 0000025A 740C                <1>         jz      short _pregw1
   122                              <1> 
   123 0000025C EF                  <1>         out     dx, ax                          ; write 16 bit value
   124 0000025D 66F7C300000040      <1>         test    ebx, PCI16                      ; 16bit requested?  bail
   125 00000264 7502                <1>         jnz     short _pregw1
   126                              <1> 
   127 00000266 66EF                <1>         out     dx, eax                         ; write full 32bit
   128                              <1> _pregw1:
   129 00000268 6689D8              <1>         mov     eax, ebx                        ; restore eax
   130 0000026B 6625FFFFFFBF        <1>         and     eax, (~PCI32)+PCI16             ; clear out data size request
   131 00000271 89CA                <1>         mov     dx, cx                          ; restore dx
   132 00000273 59                  <1> 	pop	cx
   133 00000274 665B                <1> 	pop	ebx
   134 00000276 C3                  <1> 	ret
   135                              <1> 
   136                              <1> pciRegWrite8:
   137 00000277 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 8 bit write size
   138 0000027D EBAA                <1>         jmp     short pciRegWrite		; call generic PCI access
   139                              <1> 
   140                              <1> pciRegWrite16:
   141 0000027F 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 16 bit write size
   142 00000285 660D00000040        <1>         or      eax, PCI16			; call generic PCI access
   143 0000028B EB9C                <1>         jmp     short pciRegWrite
   144                              <1> 
   145                              <1> pciRegWrite32:
   146 0000028D 6625FFFFFF3F        <1>         and     eax, (~PCI16)+PCI32		; set up 32 bit write size
   147 00000293 660D00000080        <1>         or      eax, PCI32			; call generic PCI access
   148 00000299 EB8E                <1>         jmp     short pciRegWrite
   149                              <1> 
   150                              <1> ; 17/02/2017 (Modifed by Erdogan Tan for various ICH device IDs)
   151                              <1> ;===============================================================
   152                              <1> ; PCIFindDevice: scan through PCI space looking for a device+vendor ID
   153                              <1> ;
   154                              <1> ;  ENTRY: none
   155                              <1> ;; Entry: EAX=Device+Vendor ID
   156                              <1> ;
   157                              <1> ;  Exit: EAX=PCI address if device found
   158                              <1> ;	 EDX=Device+Vendor ID
   159                              <1> ;        CY clear if found, set if not found. EAX invalid if CY set.
   160                              <1> ;
   161                              <1> ; [old stackless] Destroys: ebx, esi, edi, cl
   162                              <1> ;
   163                              <1> pciFindDevice:
   164                              <1> 	;push	cx
   165                              <1> 	;push	eax ; *
   166                              <1> 	;push	esi
   167                              <1> 	;push	edi
   168                              <1> 
   169                              <1>  	;mov     esi, eax                ; save off vend+device ID
   170                              <1> 
   171                              <1> 	; 17/02/2017
   172 0000029B BE[CB08]            <1> 	mov	si, valid_ids	; address of Valid ICH (AC97) Device IDs
   173 0000029E B91500              <1> 	mov	cx, valid_id_count
   174                              <1> pfd_0:
   175 000002A1 66BF00FFFF7F        <1>        	mov     edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0
   176                              <1> nextPCIdevice:
   177 000002A7 6681C700010000      <1>         add     edi, 100h
   178 000002AE 6681FF00F8FF80      <1>         cmp     edi, 80FFF800h		; scanned all devices?
   179                              <1>         ;stc
   180                              <1>         ;je 	short PCIScanExit       ; not found
   181 000002B5 720D                <1> 	jb	short pfd_1
   182 000002B7 66BF00000080        <1> 	mov     edi, 80000000h
   183 000002BD 83C604              <1> 	add	si, 4 ; scan for next device ID
   184 000002C0 E202                <1> 	loop	pfd_1	 
   185 000002C2 F9                  <1> 	stc	
   186                              <1> 	;jmp 	short PCIScanExit
   187 000002C3 C3                  <1> 	retn
   188                              <1> pfd_1:
   189 000002C4 6689F8              <1>         mov     eax, edi                ; read PCI registers
   190 000002C7 E851FF              <1>         call    pciRegRead32
   191                              <1>         ;cmp    edx, esi                ; found device?
   192 000002CA 663B14              <1>         cmp	edx, dword [si]
   193 000002CD 75D8                <1> 	jne     short nextPCIdevice
   194                              <1>         ;clc
   195                              <1> PCIScanExit:
   196                              <1> 	;pushf
   197 000002CF 66B800000080        <1> 	mov	eax, BIT31
   198 000002D5 66F7D0              <1> 	not	eax
   199 000002D8 6621F8              <1> 	and	eax, edi		; return only bus/dev/fn #
   200                              <1> 	;popf
   201                              <1> 
   202                              <1> 	;pop	edi
   203                              <1> 	;pop	esi
   204                              <1> 	;pop	edx ; *
   205                              <1> 	;pop	cx
   206 000002DB C3                  <1> 	retn
   207                              <1> 
   208                              <1> ; ----------------------------------------------------------------------------
   209                              <1> ; CODEC.ASM
   210                              <1> ; ----------------------------------------------------------------------------
   211                              <1> 
   212                              <1> ; codec configuration code. Not much here really.
   213                              <1> ; NASM version: Erdogan Tan (29/11/2016)
   214                              <1> 
   215                              <1> ; enable codec, unmute stuff, set output rate to 44.1
   216                              <1> ; entry: ax = desired sample rate
   217                              <1> 
   218                              <1> ; 19/05/2024
   219                              <1> ; 11/11/2023
   220                              <1> ; 06/11/2023
   221                              <1> %if 1
   222                              <1> 
   223                              <1> codecConfig:
   224                              <1> 	; 19/05/2024
   225                              <1> 	; 04/11/2023
   226                              <1> 	; 17/02/2017 
   227                              <1> 	; 07/11/2016 (Erdogan Tan)
   228                              <1> 	;PORT_NABM_GLB_CTRL_STAT equ 60h
   229                              <1> 
   230                              <1> 	; 03/11/2023 (MPXPLAY, 'SC_ICH.C', ac97_init)
   231                              <1>  	; 'AC97_DEF.H'
   232                              <1> 	;AC97_EXTENDED_STATUS equ 002Ah
   233                              <1> 	AC97_EA_SPDIF	equ 0002h
   234                              <1> 	AC97_EA_VRA	equ 0001h
   235                              <1> 	; 04/11/2023
   236                              <1> 	ICH_PO_CR_RESET equ 0002h  ; reset codec
   237                              <1> 	ICH_PCM_20BIT	equ 400000h ; 20-bit samples (ICH4)
   238                              <1> 	ICH_PCM_246_MASK equ 300000h ; 6 channels
   239                              <1> 
   240                              <1> 	; 04/11/2023
   241                              <1> init_ac97_controller:
   242 000002DC 66A1[9A0A]          <1> 	mov	eax, [bus_dev_fn]
   243 000002E0 B004                <1> 	mov	al, PCI_CMD_REG
   244 000002E2 E828FF              <1> 	call	pciRegRead16		; read PCI command register
   245 000002E5 80CA05              <1> 	or      dl, IO_ENA+BM_ENA	; enable IO and bus master
   246 000002E8 E894FF              <1> 	call	pciRegWrite16
   247                              <1> 
   248 000002EB E89801              <1> 	call	delay_100ms
   249                              <1> 
   250                              <1> 	; 19/05/2024
   251                              <1> 	; ('PLAYMOD3.ASM', Erdogan Tan, 18/05/2024)
   252                              <1> 
   253                              <1> init_ac97_codec:
   254                              <1> 	; 19/05/2024
   255 000002EE BD2800              <1> 	mov	bp, 40
   256                              <1> _initc_1:
   257                              <1> 	; 11/11/2023
   258                              <1> 	; (TRDOS 386 v2.0.5, 'audio.s')
   259 000002F1 BA2C00              <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
   260 000002F4 0316[920A]          <1> 	add	dx, [NABMBAR]
   261 000002F8 66ED                <1> 	in	eax, dx
   262                              <1> 
   263                              <1> 	; 19/05/2024
   264 000002FA E8B103              <1> 	call	delay1_4ms
   265                              <1> 
   266                              <1> 	; ?
   267 000002FD BA3000              <1> 	mov	dx, GLOB_STS_REG ; 30h
   268 00000300 0316[920A]          <1> 	add	dx, [NABMBAR]
   269 00000304 66ED                <1> 	in	eax, dx
   270                              <1> 
   271                              <1> 	; 19/05/2024
   272 00000306 E8A503              <1> 	call	delay1_4ms
   273                              <1> 
   274 00000309 6683F8FF            <1> 	cmp	eax, 0FFFFFFFFh ; -1
   275 0000030D 7508                <1> 	jne	short _initc_3
   276                              <1> _initc_2:
   277 0000030F 4D                  <1> 	dec	bp
   278 00000310 7412                <1> 	jz	short _ac97_codec_ready
   279                              <1> 
   280 00000312 E87101              <1> 	call	delay_100ms
   281 00000315 EBDA                <1> 	jmp	short _initc_1
   282                              <1> 
   283                              <1> _initc_3:
   284                              <1> 	; 19/05/2024
   285 00000317 66A900030010        <1> 	test	eax, CTRL_ST_CREADY
   286 0000031D 7505                <1> 	jnz	short _ac97_codec_ready
   287                              <1> 
   288 0000031F E8E400              <1> 	call	reset_ac97_codec
   289 00000322 EBEB                <1> 	jmp	short _initc_2
   290                              <1> 
   291                              <1> _ac97_codec_ready:
   292 00000324 8B16[900A]          <1> 	mov	dx, [NAMBAR]
   293                              <1> 	;add	dx, 0 ; ac_reg_0 ; reset register
   294 00000328 EF                  <1> 	out	dx, ax
   295                              <1> 
   296 00000329 E85A01              <1> 	call	delay_100ms
   297                              <1> 
   298                              <1> 	; 19/05/2024
   299 0000032C 09ED                <1> 	or	bp, bp
   300 0000032E 751F                <1> 	jnz	short _ac97_codec_init_ok
   301                              <1> 
   302 00000330 6631C0              <1> 	xor	eax, eax ; 0
   303 00000333 8B16[900A]          <1> 	mov	dx, [NAMBAR]
   304 00000337 83C226              <1> 	add	dx, CODEC_REG_POWERDOWN
   305 0000033A EF                  <1> 	out	dx, ax
   306                              <1> 
   307                              <1> 	; wait for 1 second
   308                              <1> 	;mov	ecx, 1000 ; 1000*0.25ms = 1s
   309                              <1> 	; 19/05/2024
   310 0000033B B92800              <1> 	mov	cx, 40
   311                              <1> _ac97_codec_rloop:
   312                              <1> 	;call	delay1_4ms
   313                              <1> 	;call	delay1_4ms
   314                              <1> 	;call	delay1_4ms
   315                              <1> 	;call	delay1_4ms
   316 0000033E E84501              <1> 	call	delay_100ms
   317                              <1> 
   318                              <1> 	;mov	dx, [NAMBAR]
   319                              <1> 	;add	dx, CODEC_REG_POWERDOWN
   320 00000341 ED                  <1> 	in	ax, dx
   321                              <1> 
   322 00000342 E86903              <1> 	call	delay1_4ms
   323                              <1> 
   324 00000345 83E00F              <1> 	and	ax, 0Fh
   325 00000348 3C0F                <1> 	cmp	al, 0Fh
   326 0000034A 7403                <1> 	je	short _ac97_codec_init_ok
   327 0000034C E2F0                <1> 	loop	_ac97_codec_rloop
   328                              <1> 
   329                              <1> init_ac97_codec_err1:
   330                              <1> 	;stc	; cf = 1 ; 19/05/2024
   331                              <1> 
   332                              <1> init_ac97_codec_err2:
   333 0000034E C3                  <1> 	retn
   334                              <1> 
   335                              <1> _ac97_codec_init_ok:
   336                              <1>         ; 11/11/2023
   337                              <1> 	;mov	al, 2 ; force set 16-bit 2-channel PCM
   338                              <1> 	;mov	dx, GLOB_CNT_REG ; 2Ch
   339                              <1> 	;add	dx, [NABMBAR]
   340                              <1> 	;out	dx, eax
   341                              <1> 
   342                              <1> 	;;call	delay1_4ms
   343                              <1> 
   344 0000034F E86D00              <1> 	call 	reset_ac97_controller
   345                              <1> 
   346                              <1> 	; 11/11/2023
   347                              <1> 	;call	delay1_4ms
   348                              <1> 	; 19/05/2024
   349 00000352 E83101              <1> 	call	delay_100ms
   350                              <1> 
   351                              <1> 	;call 	setup_ac97_codec
   352                              <1> 
   353                              <1> setup_ac97_codec:
   354                              <1> 	; 12/11/2023
   355 00000355 813E[A20A]80BB      <1> 	cmp	word [sample_rate], 48000
   356 0000035B 7435                <1> 	je	short skip_rate
   357                              <1> 
   358                              <1> ; 11/11/2023
   359                              <1> ; 05/11/2023
   360                              <1> ;%if 1
   361                              <1> 	AC97_EA_VRA equ BIT0 ; 11/11/2023
   362                              <1> 
   363                              <1> 	; 19/05/2024
   364 0000035D E84E03              <1> 	call	delay1_4ms
   365                              <1> 
   366                              <1> 	;; 19/05/2024
   367                              <1> 	;;mov	dx, [NAMBAR]
   368                              <1> 	;;add	dx, CODEC_EXT_AUDIO_REG	; 28h
   369                              <1> 	;;in	ax, dx
   370                              <1> 	;
   371                              <1> 	;; 19/05/2024
   372                              <1> 	;;test	al, 1 ; BIT0 ; Variable Rate Audio bit
   373                              <1> 	;;jz	short vra_not_supported
   374                              <1> 	;
   375                              <1> 	;; 19/05/2024
   376                              <1> 	;;call	delay1_4ms
   377                              <1> 
   378                              <1> 	; 11/11/2023
   379 00000360 8B16[900A]          <1> 	mov    	dx, [NAMBAR]
   380 00000364 83C22A              <1> 	add    	dx, CODEC_EXT_AUDIO_CTRL_REG  	; 2Ah
   381 00000367 ED                  <1> 	in     	ax, dx
   382                              <1> 
   383                              <1> 	; 19/05/2024
   384 00000368 E84303              <1> 	call	delay1_4ms
   385                              <1> 	
   386 0000036B 24FD                <1> 	and	al, ~BIT1 ; Clear DRA
   387 0000036D 0C01                <1> 	or	al, AC97_EA_VRA ; 1 ; 04/11/2023
   388 0000036F EF                  <1> 	out	dx, ax			; Enable variable rate audio
   389                              <1> 	
   390 00000370 B90A00              <1> 	mov	cx, 10
   391                              <1> check_vra:
   392 00000373 E81001              <1> 	call	delay_100ms
   393                              <1> 
   394                              <1> 	; 11/11/2023
   395 00000376 ED                  <1> 	in	ax, dx
   396 00000377 A801                <1> 	test	al, AC97_EA_VRA ; 1
   397 00000379 7509                <1> 	jnz	short set_rate
   398                              <1> 
   399                              <1> 	; 11/11/2023
   400 0000037B E2F6                <1> 	loop	check_vra
   401                              <1> 
   402                              <1> 	; 19/05/2024
   403                              <1> vra_not_supported:
   404                              <1> 	; 12/11/2023
   405 0000037D 58                  <1> 	pop	ax ; discard return address to the caller
   406 0000037E BA[370A]            <1> 	mov	dx, msg_no_vra
   407 00000381 E996FD              <1> 	jmp	vra_err
   408                              <1> 
   409                              <1> set_rate:
   410 00000384 A1[A20A]            <1> 	mov	ax, [sample_rate] ; 17/02/2017 (Erdogan Tan)
   411                              <1> 
   412 00000387 8B16[900A]          <1> 	mov    	dx, [NAMBAR]               	
   413 0000038B 83C22C              <1> 	add    	dx, CODEC_PCM_FRONT_DACRATE_REG	; 2Ch  	  
   414 0000038E EF                  <1> 	out	dx, ax 			; PCM Front/Center Output Sample Rate
   415                              <1> 
   416 0000038F E8F400              <1> 	call	delay_100ms
   417                              <1> 
   418                              <1> 	; 12/11/2023
   419                              <1> skip_rate:
   420                              <1> 	; 11/11/2023 (temporary)
   421                              <1> 
   422                              <1> 	;mov   	dx, [NAMBAR]               	
   423                              <1> 	;add   	dx, CODEC_PCM_SURND_DACRATE_REG	; 2Eh  	  
   424                              <1> 	;out	dx, ax 			; PCM Surround Output Sample Rate
   425                              <1> 
   426                              <1> 	;call	delay_100ms
   427                              <1> 
   428                              <1> 	;mov   	dx, [NAMBAR]               	
   429                              <1> 	;add   	dx, CODEC_PCM_LFE_DACRATE_REG	; 30h  	  
   430                              <1> 	;out	dx, ax 			; PCM LFE Output Sample Rate
   431                              <1> 
   432                              <1> 	;call	delay_100ms
   433                              <1> 
   434                              <1> 	; 05/11/2023 (temporary)
   435                              <1> 	;mov	dx, [NAMBAR]               	
   436                              <1> 	;add	dx, CODEC_LR_ADCRATE_REG 	; 32h  	  
   437                              <1> 	;out	dx, ax 			; PCM Input Sample Rate
   438                              <1> 	;
   439                              <1> 	;call	delay_100ms
   440                              <1> 
   441 00000392 B80202              <1> 	mov	ax, 0202h
   442 00000395 8B16[900A]          <1>   	mov     dx, [NAMBAR]
   443 00000399 83C202              <1>   	add     dx, CODEC_MASTER_VOL_REG	;02h 
   444 0000039C EF                  <1> 	out     dx, ax
   445                              <1> 
   446                              <1> 	; 11/11/2023
   447                              <1>         ;call	delay1_4ms
   448                              <1>         ;call	delay1_4ms
   449                              <1>         ;call	delay1_4ms
   450                              <1>         ;call	delay1_4ms
   451                              <1>  	;
   452                              <1>   	;mov	dx, [NAMBAR]
   453                              <1>   	;add	dx, CODEC_MASTER_MONO_VOL_REG	;06h 
   454                              <1>   	;out	dx, ax
   455                              <1> 
   456                              <1> 	; 11/11/2023
   457                              <1>         ;call	delay1_4ms
   458                              <1>         ;call	delay1_4ms
   459                              <1>         ;call	delay1_4ms
   460                              <1>         ;call	delay1_4ms
   461                              <1> 	;
   462                              <1> 	;mov	ax, 02h
   463                              <1>   	;mov	dx, [NAMBAR]
   464                              <1>   	;add	dx, CODEC_PCBEEP_VOL_REG	;0Ah 
   465                              <1>   	;out	dx, ax
   466                              <1> 
   467 0000039D E80E03              <1>         call    delay1_4ms
   468 000003A0 E80B03              <1>         call    delay1_4ms
   469 000003A3 E80803              <1>         call    delay1_4ms
   470 000003A6 E80503              <1>         call    delay1_4ms
   471                              <1> 
   472                              <1> 	;mov	ax, 0202h
   473 000003A9 8B16[900A]          <1>   	mov     dx, [NAMBAR]
   474 000003AD 83C218              <1>   	add     dx, CODEC_PCM_OUT_REG		;18h 
   475 000003B0 EF                  <1>   	out     dx, ax
   476                              <1> 
   477 000003B1 E8FA02              <1>         call    delay1_4ms
   478 000003B4 E8F702              <1>         call    delay1_4ms
   479 000003B7 E8F402              <1>         call    delay1_4ms
   480 000003BA E8F102              <1>         call    delay1_4ms
   481                              <1> 
   482                              <1> 	; 11/11/2023
   483                              <1> 	;mov	ax, 8008h ; Mute
   484                              <1>   	;mov	dx, [NAMBAR]
   485                              <1> 	;add	dx, CODEC_PHONE_VOL_REG		;0Ch
   486                              <1> 	;			 ; AC97_PHONE_VOL ; TAD Input (Mono)
   487                              <1>   	;out	dx, ax
   488                              <1> 	;
   489                              <1>         ;call	delay1_4ms
   490                              <1>         ;call	delay1_4ms
   491                              <1>         ;call	delay1_4ms
   492                              <1> 	;call	delay1_4ms
   493                              <1> 
   494                              <1> 	;mov	ax, 0808h
   495                              <1> 	;mov	dx, [NAMBAR]
   496                              <1> 	;add	dx, CODEC_LINE_IN_VOL_REG ;10h ; Line Input (Stereo)
   497                              <1> 	;out	dx, ax
   498                              <1> 	;
   499                              <1>         ;call	delay1_4ms
   500                              <1>         ;call	delay1_4ms
   501                              <1>         ;call	delay1_4ms
   502                              <1> 	;call	delay1_4ms
   503                              <1> 
   504                              <1>   	;mov	dx, [NAMBAR]
   505                              <1>         ;add	dx, CODEC_CD_VOL_REG ;12h ; CD Input (Stereo)
   506                              <1>   	;out	dx, ax
   507                              <1> 	;
   508                              <1>   	;mov	dx, [NAMBAR]
   509                              <1>         ;add	dx, CODEC_AUX_VOL_REG ;16h ; Aux Input (Stereo)
   510                              <1>   	;out	dx, ax
   511                              <1> 	;
   512                              <1>         ;call	delay1_4ms
   513                              <1>         ;call	delay1_4ms
   514                              <1>         ;call	delay1_4ms
   515                              <1> 	;call	delay1_4ms
   516                              <1> 
   517                              <1> 	; 19/05/2024
   518 000003BD F8                  <1> 	clc
   519                              <1> 
   520                              <1> ;detect_ac97_codec:
   521 000003BE C3                  <1>         retn
   522                              <1> 
   523                              <1> reset_ac97_controller:
   524                              <1> 	; 19/05/2024
   525                              <1> 	; 11/11/2023
   526                              <1> 	; 10/06/2017
   527                              <1> 	; 29/05/2017
   528                              <1> 	; 28/05/2017
   529                              <1> 	; reset AC97 audio controller registers
   530 000003BF 31C0                <1> 	xor     ax, ax
   531 000003C1 BA0B00              <1>         mov	dx, PI_CR_REG
   532 000003C4 0316[920A]          <1> 	add	dx, [NABMBAR]
   533 000003C8 EE                  <1> 	out     dx, al
   534                              <1> 
   535                              <1> 	; 19/05/2024
   536 000003C9 E8E202              <1> 	call	delay1_4ms
   537                              <1> 
   538 000003CC BA1B00              <1>         mov     dx, PO_CR_REG
   539 000003CF 0316[920A]          <1> 	add	dx, [NABMBAR]
   540 000003D3 EE                  <1> 	out     dx, al
   541                              <1> 
   542                              <1> 	; 19/05/2024
   543 000003D4 E8D702              <1> 	call	delay1_4ms
   544                              <1> 
   545 000003D7 BA2B00              <1>         mov     dx, MC_CR_REG
   546 000003DA 0316[920A]          <1> 	add	dx, [NABMBAR]
   547 000003DE EE                  <1> 	out     dx, al
   548                              <1> 
   549                              <1> 	; 19/05/2024
   550 000003DF E8CC02              <1> 	call	delay1_4ms
   551                              <1> 
   552 000003E2 B002                <1>         mov     al, RR
   553 000003E4 BA0B00              <1>         mov     dx, PI_CR_REG
   554 000003E7 0316[920A]          <1> 	add	dx, [NABMBAR]
   555 000003EB EE                  <1> 	out     dx, al
   556                              <1> 
   557                              <1> 	; 19/05/2024
   558 000003EC E8BF02              <1> 	call	delay1_4ms
   559                              <1> 
   560 000003EF BA1B00              <1>         mov     dx, PO_CR_REG
   561 000003F2 0316[920A]          <1> 	add	dx, [NABMBAR]
   562 000003F6 EE                  <1> 	out     dx, al
   563                              <1> 
   564                              <1> 	; 19/05/2024
   565 000003F7 E8B402              <1> 	call	delay1_4ms
   566                              <1> 
   567 000003FA BA2B00              <1>         mov     dx, MC_CR_REG
   568 000003FD 0316[920A]          <1> 	add	dx, [NABMBAR]
   569 00000401 EE                  <1> 	out     dx, al
   570                              <1> 
   571                              <1> 	; 19/05/2024
   572 00000402 E8A902              <1> 	call	delay1_4ms
   573                              <1> 
   574 00000405 C3                  <1> 	retn
   575                              <1> 
   576                              <1> reset_ac97_codec:
   577                              <1> 	; 11/11/2023
   578                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
   579 00000406 BA2C00              <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
   580 00000409 0316[920A]          <1> 	add	dx, [NABMBAR]
   581 0000040D 66ED                <1> 	in	eax, dx
   582                              <1> 
   583                              <1> 	;test	eax, 2
   584                              <1> 	; 06/08/2022
   585 0000040F A802                <1> 	test	al, 2
   586 00000411 7405                <1> 	jz	short _r_ac97codec_cold	
   587                              <1> 
   588 00000413 E80E00              <1> 	call	warm_ac97codec_reset
   589 00000416 7306                <1> 	jnc	short _r_ac97codec_ok
   590                              <1> _r_ac97codec_cold:
   591 00000418 E83400              <1>         call    cold_ac97codec_reset
   592 0000041B 7301                <1>         jnc     short _r_ac97codec_ok
   593                              <1> 	
   594                              <1> 	; 16/04/2017
   595                              <1>         ;xor	eax, eax	; timeout error
   596                              <1>        	;stc
   597 0000041D C3                  <1> 	retn
   598                              <1> 
   599                              <1> _r_ac97codec_ok:
   600 0000041E 6631C0              <1>         xor     eax, eax
   601                              <1>         ;mov	al, VIA_ACLINK_C00_READY ; 1
   602 00000421 FEC0                <1>         inc	al
   603 00000423 C3                  <1> 	retn
   604                              <1> 
   605                              <1> warm_ac97codec_reset:
   606                              <1> 	; 11/11/2023
   607                              <1> 	; 06/08/2022 - TRDOS 386 v2.0.5
   608                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
   609 00000424 66B806000000        <1> 	mov	eax, 6
   610 0000042A BA2C00              <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
   611 0000042D 0316[920A]          <1> 	add	dx, [NABMBAR]
   612 00000431 66EF                <1> 	out	dx, eax
   613                              <1> 
   614 00000433 B90A00              <1> 	mov	cx, 10	; total 1s
   615                              <1> _warm_ac97c_rst_wait:
   616 00000436 E84D00              <1> 	call	delay_100ms
   617                              <1> 
   618 00000439 BA3000              <1> 	mov	dx, GLOB_STS_REG ; 30h
   619 0000043C 0316[920A]          <1> 	add	dx, [NABMBAR]
   620 00000440 66ED                <1> 	in	eax, dx
   621                              <1> 
   622 00000442 66A900030010        <1> 	test	eax, CTRL_ST_CREADY
   623 00000448 7504                <1> 	jnz	short _warm_ac97c_rst_ok
   624                              <1> 
   625 0000044A 49                  <1>         dec     cx
   626 0000044B 75E9                <1>         jnz     short _warm_ac97c_rst_wait
   627                              <1> 
   628                              <1> _warm_ac97c_rst_fail:
   629 0000044D F9                  <1>         stc
   630                              <1> _warm_ac97c_rst_ok:
   631 0000044E C3                  <1> 	retn
   632                              <1> 
   633                              <1> cold_ac97codec_reset:
   634                              <1> 	; 11/11/2023
   635                              <1> 	; 06/08/2022 - TRDOS 386 v2.0.5
   636                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
   637 0000044F 66B802000000        <1>         mov	eax, 2
   638 00000455 BA2C00              <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
   639 00000458 0316[920A]          <1> 	add	dx, [NABMBAR]
   640 0000045C 66EF                <1> 	out	dx, eax
   641                              <1> 
   642 0000045E E82500              <1> 	call	delay_100ms 	; wait 100 ms
   643 00000461 E82200              <1> 	call	delay_100ms 	; wait 100 ms
   644 00000464 E81F00              <1> 	call	delay_100ms 	; wait 100 ms
   645 00000467 E81C00              <1> 	call	delay_100ms 	; wait 100 ms
   646                              <1> 
   647 0000046A B91000              <1> 	mov	cx, 16	; total 20*100 ms = 2s
   648                              <1> 
   649                              <1> _cold_ac97c_rst_wait:
   650 0000046D BA3000              <1> 	mov	dx, GLOB_STS_REG ; 30h
   651 00000470 0316[920A]          <1> 	add	dx, [NABMBAR]
   652 00000474 66ED                <1> 	in	eax, dx
   653                              <1> 
   654 00000476 66A900030010        <1> 	test	eax, CTRL_ST_CREADY
   655 0000047C 7507                <1> 	jnz	short _cold_ac97c_rst_ok
   656                              <1> 
   657 0000047E E80500              <1> 	call	delay_100ms
   658                              <1> 
   659 00000481 49                  <1>         dec     cx
   660 00000482 75E9                <1>         jnz     short _cold_ac97c_rst_wait
   661                              <1> 
   662                              <1> _cold_ac97c_rst_fail:
   663 00000484 F9                  <1>         stc
   664                              <1> _cold_ac97c_rst_ok:
   665 00000485 C3                  <1> 	retn
   666                              <1> 
   667                              <1> delay_100ms:
   668                              <1> 	; 11/11/2023
   669                              <1> 	; 29/05/2017
   670                              <1> 	; 24/03/2017 ('codec.asm')
   671                              <1> 	; wait 100 ms
   672 00000486 51                  <1> 	push	cx
   673 00000487 B99001              <1> 	mov	cx, 400  ; 400*0.25ms
   674                              <1> _delay_x_ms:
   675 0000048A E82102              <1> 	call	delay1_4ms
   676 0000048D E2FB                <1>         loop	_delay_x_ms
   677 0000048F 59                  <1> 	pop	cx
   678 00000490 C3                  <1> 	retn
   679                              <1> 
   680                              <1> %endif
   681                              <1> 
   682                              <1> ; 11/11/2023
   683                              <1> %if 0
   684                              <1> 
   685                              <1> codecConfig:
   686                              <1> 	; 06/11/2023
   687                              <1> 	; TUNELOOP version (playing without interrupt)
   688                              <1> 	; 04/11/2023
   689                              <1> 	; 17/02/2017 
   690                              <1> 	; 07/11/2016 (Erdogan Tan)
   691                              <1> 
   692                              <1> 	mov	ax, [sample_rate] ; 17/02/2017 (Erdogan Tan)
   693                              <1> 
   694                              <1> 	mov    	dx, [NAMBAR]               	
   695                              <1> 	add    	dx, CODEC_PCM_FRONT_DACRATE_REG	; 2Ch  	  
   696                              <1> 	out	dx, ax 				; out sample rate
   697                              <1> 		
   698                              <1> 	; 05/11/2023 temp
   699                              <1> 	;mov	dx, [NAMBAR]               	
   700                              <1> 	;add	dx, CODEC_LR_ADCRATE_REG 	; 32h  	  
   701                              <1> 	;out	dx, ax 
   702                              <1> 
   703                              <1>         call    delay1_4ms
   704                              <1>         call    delay1_4ms
   705                              <1>         call    delay1_4ms
   706                              <1>         call    delay1_4ms
   707                              <1> 
   708                              <1> 	mov	eax, [dev_vendor]
   709                              <1>         cmp	eax, (SI7012_DID<<16)+SIS_VID
   710                              <1>         jne	short cConfig1
   711                              <1> 
   712                              <1> 	; Unmute quirk specifically for the SiS7012
   713                              <1> 
   714                              <1> 	CUSTOM_SIS_7012_REG equ 4Ch ; SiS7012-specific register
   715                              <1> 	
   716                              <1>         mov     dx, [NABMBAR]
   717                              <1>         add     dx, CUSTOM_SIS_7012_REG
   718                              <1>         in      ax, dx
   719                              <1>         or	al, 1
   720                              <1>         out     dx, ax
   721                              <1> 
   722                              <1> cConfig1:
   723                              <1> 	; 03/11/2023 (MPXPLAY, 'SC_ICH.C', ac97_init)
   724                              <1> 	; initial ac97 volumes (and clear mute flag)
   725                              <1> 		
   726                              <1>   	mov     dx, [NAMBAR]
   727                              <1>   	add     dx, CODEC_MASTER_VOL_REG        ;02h ; STEREO
   728                              <1>   	;xor	ax, ax ; volume attenuation = 0 (max. volume)
   729                              <1>   	; 03/11/2023
   730                              <1> 	mov	ax, 0202h
   731                              <1> 	out     dx, ax
   732                              <1> 
   733                              <1>         call    delay1_4ms	; delays because codecs are slow
   734                              <1>         call    delay1_4ms
   735                              <1>         call    delay1_4ms
   736                              <1>         call    delay1_4ms
   737                              <1>  
   738                              <1>   	mov     dx, [NAMBAR]
   739                              <1>   	add     dx, CODEC_PCM_OUT_REG		;18h
   740                              <1>   	;;xor	ax, ax
   741                              <1> 	;mov	ax, 0202h
   742                              <1>   	out     dx, ax
   743                              <1> 
   744                              <1>         call    delay1_4ms
   745                              <1>         call    delay1_4ms
   746                              <1>         call    delay1_4ms
   747                              <1>         call    delay1_4ms
   748                              <1>  
   749                              <1> 	retn
   750                              <1> 
   751                              <1> %endif
   469                                  %include 'ich_wav.asm' ; 17/02/2017 (ICH AC97 wav playing functions)
     1                              <1> ; 19/05/2024
     2                              <1> ; 11/11/2023
     3                              <1> ; 08/11/2023
     4                              <1> ; 06/11/2023
     5                              <1> ; 05/11/2023
     6                              <1> ; 04/11/2023
     7                              <1> ; 03/11/2023
     8                              <1> ; DOS based .WAV player using AC'97 and codec interface.
     9                              <1> ; ---------------------------------------------------------------
    10                              <1> ; NASM version: Erdogan Tan (29/11/2016)
    11                              <1> ; Last Update: 17/02/2017 (by Erdogan Tan)
    12                              <1> 
    13                              <1> ; TUNELOOP version (playing without interrupt) - 06/11/2023 - Erdogan Tan
    14                              <1> 
    15                              <1> ; ICHWAV.ASM
    16                              <1> 
    17                              <1> ; player internal variables and other equates.
    18                              <1> BUFFERSIZE      equ     64 * 1024       ; 64k file buffer size.
    19                              <1> ENDOFFILE       equ     BIT0            ; flag for knowing end of file
    20                              <1> 
    21                              <1> ;===========================================================================
    22                              <1> ; entry: none. File is already open and [filehandle] filled.
    23                              <1> ; exit:  not until the song is finished or the user aborts.
    24                              <1> ;
    25                              <1> playWav:
    26                              <1> 	; 07/11/2023
    27                              <1> 	; clear buffer 2
    28                              <1>         ;push	es
    29                              <1> 	;mov	ax, [WAV_BUFFER2]
    30                              <1> 	;mov	es, ax
    31                              <1> 	;sub	ax, ax
    32                              <1> 	;mov	di, ax ; 17/02/2017
    33                              <1> 	;mov	cx, (BUFFERSIZE/2)
    34                              <1> 	;rep	stosw
    35                              <1> 	;pop	es	     
    36                              <1> 	
    37                              <1> 	; load 64k into buffer 1
    38 00000491 A1[960A]            <1>         mov     ax, [WAV_BUFFER1]
    39 00000494 E8D200              <1>         call    loadFromFile
    40                              <1> 
    41                              <1> 	; and 64k into buffer 2
    42 00000497 A1[980A]            <1> 	mov     ax, [WAV_BUFFER2]
    43 0000049A E8CC00              <1>        	call    loadFromFile
    44                              <1> 
    45                              <1> ; register reset the DMA engine. This may cause a pop noise on the output
    46                              <1> ; lines when the device is reset. Prolly a better idea to mute output, then
    47                              <1> ; reset.
    48                              <1> ;
    49                              <1> 	; 11/11/2023
    50                              <1>         ;mov	dx, [NABMBAR]
    51                              <1>         ;add	dx, PO_CR_REG		; set pointer to Ctrl reg
    52                              <1>         ;mov	al, RR			; set reset
    53                              <1> 	;out	dx, al			; self clearing bit
    54                              <1> 
    55                              <1> ; write last valid index to 31 to start with.
    56                              <1> ; The Last Valid Index register tells the DMA engine when to stop playing.
    57                              <1> ; 
    58                              <1> ; As we progress through the song we change the last valid index to always be
    59                              <1> ; something other than the index we're currently playing.  
    60                              <1> ;
    61                              <1> 	; 08/11/2023
    62                              <1> 	;; 07/11/2023
    63                              <1> 	;mov	al, 1
    64                              <1>         ;;mov	al, 31
    65                              <1> 	;call	setLastValidIndex
    66                              <1> 
    67                              <1> ; create Buffer Descriptor List
    68                              <1> ;
    69                              <1> ; A buffer descriptor list is a list of pointers and control bits that the
    70                              <1> ; DMA engine uses to know where to get the .wav data and how to play it.
    71                              <1> ;
    72                              <1> ; I set it up to use only 2 buffers of .wav data, and whenever 1 buffer is
    73                              <1> ; playing, I refresh the other one with good data.
    74                              <1> ;
    75                              <1> ;
    76                              <1> ; For the control bits, you can specify that the DMA engine fire an interrupt
    77                              <1> ; after a buffer has been processed, but I poll the current index register
    78                              <1> ; to know when it's safe to update the other buffer.
    79                              <1> ;
    80                              <1> ; I set the BUP bit, which tells the DMA engine to just play 0's (silence)
    81                              <1> ; if it ever runs out of data to play. Good for safety.
    82                              <1> ;
    83 0000049D 06                  <1>         push    es
    84 0000049E A1[940A]            <1>         mov     ax, [BDL_BUFFER]		; get segment # for BDL
    85 000004A1 8EC0                <1>         mov     es, ax
    86                              <1> 
    87 000004A3 B91000              <1>         mov     cx, 32 / 2                      ; make 32 entries in BDL
    88 000004A6 31FF                <1>         xor     di, di                          
    89                              <1> _0:
    90                              <1> 
    91                              <1> ; set buffer descriptor 0 to start of data file in memory
    92 000004A8 660FB706[960A]      <1>         movzx   eax, word [WAV_BUFFER1]
    93 000004AE 66C1E004            <1>         shl     eax, 4                          ; convert seg:off ->0:offset
    94 000004B2 66AB                <1>         stosd                                   ; store pointer to wavbuffer1
    95                              <1> 
    96                              <1> ;
    97                              <1> ; set length to 32k samples. 1 sample is 16bits or 2bytes.
    98                              <1> ; Set control (bits 31:16) to BUP, bits 15:0=number of samples.
    99                              <1> ; 
   100                              <1> 
   101                              <1> ; 17/02/2017 (Erdogan Tan)
   102                              <1> ; Intel® 82801AA (ICH) & Intel® 82801AB (ICH0) I/O Controller Hub AC’97
   103                              <1> ; Programmer’s Reference Manual
   104                              <1> 
   105                              <1> ; 2.2.1 Buffer Descriptor List  (on Page 13)
   106                              <1> 	;
   107                              <1> 	;  Generic Form of Buffer Descriptor
   108                              <1> 	;  ---------------------------------
   109                              <1> 	;  63   62    61-48    47-32   31-0
   110                              <1> 	;  ---  ---  --------  ------- -----
   111                              <1> 	;  IOC  BUP -reserved- Buffer  Buffer
   112                              <1> 	;		      Length   Pointer
   113                              <1> 	;		      [15:0]   [31:0]
   114                              <1> 	;
   115                              <1> 	;  IOC:	Interrupt On Completion. 
   116                              <1> 	;	1 = Enabled. 
   117                              <1> 	;	    When this is set, it means that the controller should
   118                              <1> 	;	    issue an interrupt upon completion of this buffer.
   119                              <1> 	;	    It should also set the IOC bit in the status register
   120                              <1> 	;	0 = Disabled	
   121                              <1> 	;
   122                              <1> 	;  BUP: Buffer Underrun Policy.
   123                              <1> 	;       0 = When this buffer is complete,
   124                              <1> 	;	    if the next buffer is not yet ready 
   125                              <1> 	;	    (i.e., the last valid buffer has been processed),
   126                              <1> 	;	    then continue to transmit the last valid sample.
   127                              <1> 	;	1 = When this buffer is complete,
   128                              <1> 	;     	    if this is the last valid buffer, transmit zeros after
   129                              <1> 	;	    this buffer has been processed completely.
   130                              <1> 	;	    This bit typically is set only if this is the last 
   131                              <1> 	;	    buffer in the current stream.
   132                              <1> 	;
   133                              <1> 	; [31:0]: Buffer pointer. This field points to the location of
   134                              <1> 	;	  the data buffer. Since samples can be as wide as one
   135                              <1> 	;	  word, the buffer must be aligned with word boundaries,
   136                              <1> 	;	  to prevent samples from straddling DWord boundaries.
   137                              <1> 	;
   138                              <1> 	; [15:0]: Buffer Length: This is the length of the data buffer,
   139                              <1> 	;	  in number of samples. The controller uses this data
   140                              <1> 	;	  to determine the length of the buffer, in bytes.
   141                              <1> 	;	  "0" indicates no sample to process.
   142                              <1> 
   143                              <1> ; ICH2AC97.INC
   144                              <1> 
   145                              <1> ;	IOC	equ     BIT31   ; Fire an interrupt whenever this
   146                              <1> 				; buffer is complete.
   147                              <1> 
   148                              <1> ;	BUP	equ     BIT30   ; Buffer Underrun Policy.
   149                              <1> 				; if this buffer is the last buffer
   150                              <1> 				; in a playback, fill the remaining
   151                              <1> 				; samples with 0 (silence) or not.
   152                              <1> 				; It's a good idea to set this to 1
   153                              <1> 				; for the last buffer in playback,
   154                              <1> 				; otherwise you're likely to get a lot
   155                              <1> 				; of noise at the end of the sound.
   156                              <1> ;
   157                              <1> ; Bits 15:0 contain the length of the buffer, in number of samples, which
   158                              <1> ; are 16 bits each, coupled in left and right pairs, or 32bits each.
   159                              <1> ; Luckily for us, that's the same format as .wav files.
   160                              <1> ;
   161                              <1> ; A value of FFFF is 65536 samples. Running at 44.1Khz, that's just about
   162                              <1> ; 1.5 seconds of sample time. FFFF * 32bits is 1FFFFh bytes or 128k of data.
   163                              <1> ;
   164                              <1> ; A value of 0 in these bits means play no samples.
   165                              <1> ;
   166                              <1> 
   167                              <1> ; ICHWAV.ASM
   168                              <1> 				    ; 19/05/2024
   169 000004B4 66B800800000        <1> 	mov	eax, BUFFERSIZE / 2 ; size of buffer (32K) in (16bit) words
   170                              <1> 	;or	eax, IOC + BUP
   171                              <1> 	; 06/11/2023 (TUNELOOP version, without interrupt)
   172 000004BA 660D00000040        <1> 	or	eax, BUP
   173 000004C0 66AB                <1> 	stosd
   174                              <1> 
   175                              <1> ; 2nd buffer:
   176                              <1> 
   177 000004C2 660FB706[980A]      <1>         movzx   eax, word [WAV_BUFFER2]
   178 000004C8 66C1E004            <1>         shl     eax, 4                          ; convert seg:off ->0:offset
   179 000004CC 66AB                <1>         stosd                                   ; store pointer to wavbuffer2
   180                              <1> 
   181                              <1> ; set length to 64k (32k of two 16 bit samples)
   182                              <1> ; Set control (bits 31:16) to BUP, bits 15:0=number of samples
   183                              <1> ; 
   184 000004CE 66B800800000        <1> 	mov	eax, BUFFERSIZE / 2
   185                              <1> 	;or	eax, IOC + BUP
   186                              <1> 	; 06/11/2023 (TUNELOOP version, without interrupt)
   187 000004D4 660D00000040        <1> 	or	eax, BUP
   188 000004DA 66AB                <1> 	stosd
   189                              <1> 
   190 000004DC E2CA                <1>         loop    _0
   191 000004DE 07                  <1>         pop     es
   192                              <1> 
   193                              <1> ;
   194                              <1> ; tell the DMA engine where to find our list of Buffer Descriptors.
   195                              <1> ; this 32bit value is a flat mode memory offset (ie no segment:offset)
   196                              <1> ;
   197                              <1> ; write NABMBAR+10h with offset of buffer descriptor list
   198                              <1> ;
   199 000004DF 660FB706[940A]      <1>         movzx   eax, word [BDL_BUFFER]
   200 000004E5 66C1E004            <1> 	shl     eax, 4                          ; convert seg:off to 0:off
   201 000004E9 8B16[920A]          <1>         mov     dx, [NABMBAR]
   202 000004ED 83C210              <1>         add     dx, PO_BDBAR_REG                ; set pointer to BDL
   203 000004F0 66EF                <1>         out     dx, eax                         ; write to AC97 controller
   204                              <1> 
   205                              <1> 	; 19/05/2024
   206 000004F2 E8B901              <1> 	call	delay1_4ms
   207                              <1> 
   208                              <1> ;
   209                              <1> ; All set. Let's play some music.
   210                              <1> ;
   211                              <1> 
   212                              <1> 	; 08/11/2023
   213                              <1> 	; 07/11/2023
   214                              <1> 	; 08/12/2016
   215                              <1> 	; 07/10/2016
   216                              <1>         ;mov	al, 1
   217 000004F5 B01F                <1>         mov	al, 31
   218 000004F7 E86701              <1> 	call	setLastValidIndex
   219                              <1> 
   220                              <1> 	; 06/11/2023 (not neccessary)
   221                              <1> 	;; 05/11/2023
   222                              <1> 	;; reset current index
   223                              <1> 	;mov	al, 0
   224                              <1> 	;call	setCurrentIndex
   225                              <1> 
   226                              <1> 	; 06/11/2023
   227                              <1> 	;mov	byte [tLoop], 1 ; 30/11/2016
   228                              <1> 
   229                              <1> 	; 19/05/2024
   230 000004FA E8B101              <1> 	call	delay1_4ms
   231                              <1> 
   232                              <1> 	; 17/02/2017
   233 000004FD 8B16[920A]          <1>         mov     dx, [NABMBAR]
   234 00000501 83C21B              <1>         add     dx, PO_CR_REG                   ; PCM out Control Register
   235                              <1>         ;mov	al, IOCE + RPBM	; Enable 'Interrupt On Completion' + run
   236                              <1> 	;			; (LVBI interrupt will not be enabled)
   237                              <1> 	; 06/11/2023 (TUNELOOP version, without interrupt)
   238 00000504 B001                <1> 	mov	al, RPBM
   239 00000506 EE                  <1> 	out     dx, al                          ; Start bus master operation.
   240                              <1> 
   241                              <1> 	; 19/05/2024
   242                              <1> 	; 06/11/2023
   243 00000507 E8A401              <1> 	call	delay1_4ms
   244 0000050A E8A101              <1> 	call	delay1_4ms
   245 0000050D E89E01              <1> 	call	delay1_4ms
   246 00000510 E89B01              <1> 	call	delay1_4ms
   247                              <1> 
   248                              <1> ; while DMA engine is running, examine current index and wait until it hits 1
   249                              <1> ; as soon as it's 1, we need to refresh the data in wavbuffer1 with another
   250                              <1> ; 64k. Likewise when it's playing buffer 2, refresh buffer 1 and repeat.
   251                              <1>    
   252                              <1> ; 06/11/2023 (TUNELOOP version, without interrupt)
   253                              <1> %if 0
   254                              <1> 	; 08/12/2016
   255                              <1> 	; 28/11/2016
   256                              <1> p_loop:
   257                              <1> 	call    check4keyboardstop      ; keyboard halt?
   258                              <1>         jc	short r_loop		; no ; 05/11/2023
   259                              <1> 
   260                              <1> 	;mov	byte [tLoop], 0
   261                              <1> 	; 04/11/2023
   262                              <1> 	;mov	byte [audio_play_cmd], 0
   263                              <1> 	;call	ac97_stop
   264                              <1> 	;retn
   265                              <1> _exit_:
   266                              <1> 	; 04/11/2023
   267                              <1> 	; finished with song, stop everything
   268                              <1> 	call	ac97_stop
   269                              <1> 	
   270                              <1> 	; restore previous interrupt vector and interrupt_status
   271                              <1> 	cli
   272                              <1> 	in	al, 0A1h ; irq 8-15
   273                              <1> 	mov	al, [IRQ_status+1]
   274                              <1> 	out	0A1h, al 
   275                              <1> 	in	al, 021h ; irq 0-7
   276                              <1> 	mov	al, [IRQ_status]
   277                              <1> 	out	21h, al 
   278                              <1> 	; ...
   279                              <1> 	push	es
   280                              <1> 	xor	ax, ax
   281                              <1> 	mov	es, ax
   282                              <1> 	mov	ax, [IRQ_vector]
   283                              <1> 	mov	[es:bx], ax
   284                              <1> 	mov	ax, [IRQ_vector+2]
   285                              <1> 	mov	[es:bx+2], ax
   286                              <1> 	pop	es
   287                              <1> 	sti
   288                              <1> 	retn
   289                              <1> 
   290                              <1> r_loop:
   291                              <1> 	; 07/12/2016 - Erdogan Tan
   292                              <1> 	nop
   293                              <1> 	nop
   294                              <1> 	nop
   295                              <1> 	; 17/02/2017
   296                              <1> 	mov	al, [tBuff]
   297                              <1> 	dec	al ; 1-32 -> 0-31 or 0 -> 0FFh
   298                              <1> 	js	short  p_loop
   299                              <1> 	mov	byte [tBuff], 0 ; reset
   300                              <1> 	and	al, 1
   301                              <1> 	jnz	short q_loop
   302                              <1>         mov     ax, [WAV_BUFFER2] ; [tBuff]=2 (from tuneLoop)
   303                              <1> s_loop:
   304                              <1>         call    loadFromFile
   305                              <1> 	;jc	short _exit_
   306                              <1> 	; 05/11/2023
   307                              <1> 	jc	short exit_loop
   308                              <1> 	jmp	short r_loop
   309                              <1> q_loop:
   310                              <1>      	mov     ax, [WAV_BUFFER1] ; [tBuff]=1 (from tuneLoop)
   311                              <1>         ;call	loadFromFile
   312                              <1> 	;jc	short _exit_
   313                              <1> 	;jmp	short r_loop
   314                              <1> 	; 05/11/2023
   315                              <1> 	jmp	short s_loop
   316                              <1> 
   317                              <1> exit_loop: 
   318                              <1> 	mov	byte [tLoop], 0
   319                              <1> 	retn
   320                              <1> 		
   321                              <1> tuneLoop:
   322                              <1> 	; 05/11/2023
   323                              <1> 	; 08/12/2016
   324                              <1> 	; 28/11/2016 - Erdogan Tan
   325                              <1> 	
   326                              <1> 	cmp	byte [tLoop], 1
   327                              <1> 	jb	short _exit_ ; 05/11/2023
   328                              <1> _tlp_1:	
   329                              <1> 	; 17/02/2017
   330                              <1> 	call	getCurrentIndex
   331                              <1> 	inc	al ; 0-31 -> 1-32
   332                              <1> 	mov	[tBuff], al
   333                              <1> 
   334                              <1> 	; 05/11/2023
   335                              <1> 	dec	ax
   336                              <1> 	dec	ax
   337                              <1> 	and	al, 1Fh
   338                              <1> 	call	setLastValidIndex
   339                              <1> 
   340                              <1> 	; 05/11/2023
   341                              <1> 	; 17/02/2017 - Buffer switch test (temporary)
   342                              <1> 	push	ds
   343                              <1> 	push	si 
   344                              <1> 	mov	si, 0B800h ; video display page segment
   345                              <1> 	mov	ds, si
   346                              <1> 	sub	si, si ; 0
   347                              <1> 	mov	ah, 4Eh
   348                              <1> 	and	al, 1
   349                              <1> 	add	al, '1'
   350                              <1> 	mov	[si], ax ; show current play buffer (1, 2)
   351                              <1> 	pop	si
   352                              <1> 	pop	ds
   353                              <1> 
   354                              <1> 	; 17/02/2017
   355                              <1> 
   356                              <1> 	;test	byte [irq_status], LVBCI ; last buff completion intr.
   357                              <1> 	;jz	short _tlp2 ; BCIS ; Buffer completion interrupt
   358                              <1> 
   359                              <1> 	; Last Valid Buffer Completion Interrupt (LVBCI).
   360                              <1> 	;   1 = Last valid buffer has been processed. 
   361                              <1> 	;	It remains active until cleared by software. 
   362                              <1> 	;	This bit indicates the occurrence of the event 
   363                              <1> 	;	signified by the last valid buffer being processed.
   364                              <1> 	;	Thus, this is an event status bit that can be cleared
   365                              <1> 	;	by software once this event has been recognized.
   366                              <1> 	;	This event causes an interrupt if the enable bit
   367                              <1> 	;	in the Control Register is set. The interrupt is
   368                              <1> 	;	cleared when the software clears this bit.
   369                              <1> 	;	In the case of Transmits (PCM out, Modem out) this bit
   370                              <1> 	;	is set, after the last valid buffer has been
   371                              <1> 	;	fetched (not after transmitting it).
   372                              <1> 	;	While in the case of Receives, this bit is set after
   373                              <1> 	;	the data for the last buffer has been written to memory.
   374                              <1> 	;   0 = Cleared by writing a "1" to this bit position.
   375                              <1> 
   376                              <1> 	; Note: We are not using LVBCI 
   377                              <1> 	;     Last Buffer Completion Interrupt !!!
   378                              <1> 
   379                              <1> 	; 17/02/2017
   380                              <1>         ;mov     dx, [NABMBAR]
   381                              <1>         ;add     dx, PO_SR_REG	; PCM out Status register
   382                              <1>         ;mov     al, [irq_status]
   383                              <1>         ;out     dx, al		; Clear (LVBCI) interrupt status
   384                              <1> 	;retn
   385                              <1> 
   386                              <1> ;_tlp2:
   387                              <1> 	; Buffer Completion Interrupt Status (BCIS).
   388                              <1> 	;   1 =	Set by the hardware after the last sample 
   389                              <1> 	; 	of a buffer has been processed, AND if the Interrupt
   390                              <1> 	; 	on Completion (IOC) bit is set in the command byte of 
   391                              <1> 	; 	the buffer descriptor. It remains active
   392                              <1> 	; 	until cleared by software.
   393                              <1> 	;   0 =	Cleared by writing a "1" to this bit position.
   394                              <1> 
   395                              <1> 	; 17/02/2017
   396                              <1>         mov     dx, [NABMBAR]
   397                              <1>         add     dx, PO_SR_REG	; PCM out Status register
   398                              <1>         mov     al, [pcm_irq_status] ; 05/11/2023
   399                              <1>         out     dx, al		; Clear (BCI) interrupt status
   400                              <1> 	retn
   401                              <1> 
   402                              <1> ;_exit_:
   403                              <1> ;	mov	byte [tLoop], 0
   404                              <1> ;_exit:
   405                              <1> ;       ; finished with song, stop everything
   406                              <1> ;	mov     dx, [NABMBAR]		
   407                              <1> ;       add     dx, PO_CR_REG           ; PCM out Control Register
   408                              <1> ;       mov     al, 0
   409                              <1> ;       out     dx, al                  ; stop player
   410                              <1> ;_return:
   411                              <1> ;	retn
   412                              <1> 
   413                              <1> %endif
   414                              <1> 
   415                              <1> ; while DMA engine is running, examine current index and wait until it hits 1
   416                              <1> ; as soon as it's 1, we need to refresh the data in wavbuffer1 with another
   417                              <1> ; 64k. Likewise when it's playing buffer 2, refresh buffer 1 and repeat.
   418                              <1> 
   419                              <1> ; 08/11/2023
   420                              <1> ; 07/11/2023
   421                              <1> %if 1
   422                              <1> 
   423                              <1> tuneLoop:
   424                              <1> 	; 08/11/2023
   425                              <1> 	; 06/11/2023
   426 00000513 B031                <1> 	mov	al, '1'
   427 00000515 E84300              <1> 	call	tL0
   428                              <1> tL1:
   429 00000518 E81B01              <1> 	call    updateLVI	; /set LVI != CIV/
   430 0000051B 7432                <1> 	jz	short _exit_	; 08/11/2023
   431 0000051D E84A01              <1> 	call    check4keyboardstop
   432 00000520 722D                <1> 	jc	short _exit_
   433 00000522 E80801              <1> 	call    getCurrentIndex
   434 00000525 A801                <1> 	test	al, BIT0
   435 00000527 74EF                <1> 	jz	short tL1	; loop if buffer 2 is not playing
   436                              <1> 
   437                              <1> 	; load buffer 1
   438 00000529 A1[960A]            <1> 	mov     ax, [WAV_BUFFER1]
   439 0000052C E83A00              <1> 	call	loadFromFile
   440 0000052F 721E                <1> 	jc	short _exit_	; end of file
   441                              <1> 
   442 00000531 B032                <1> 	mov	al, '2'
   443 00000533 E82500              <1> 	call	tL0
   444                              <1> tL2:
   445 00000536 E8FD00              <1> 	call    updateLVI
   446 00000539 7414                <1> 	jz	short _exit_	; 08/11/2023
   447 0000053B E82C01              <1> 	call    check4keyboardstop
   448 0000053E 720F                <1> 	jc	short _exit_
   449 00000540 E8EA00              <1> 	call    getCurrentIndex
   450 00000543 A801                <1> 	test	al, BIT0
   451 00000545 75EF                <1> 	jnz	short tL2	; loop if buffer 1 is not playing
   452                              <1> 
   453                              <1> 	; load buffer 2
   454 00000547 A1[980A]            <1> 	mov     ax, [WAV_BUFFER2]
   455 0000054A E81C00              <1> 	call	loadFromFile
   456 0000054D 73C4                <1> 	jnc	short tuneLoop
   457                              <1> _exit_:
   458 0000054F 8B16[920A]          <1> 	mov	dx, [NABMBAR]		
   459 00000553 83C21B              <1> 	add	dx, PO_CR_REG	; PCM out Control Register
   460 00000556 B000                <1> 	mov	al, 0
   461 00000558 EE                  <1> 	out	dx, al		; stop player
   462                              <1> 
   463 00000559 0430                <1> 	add	al, '0'
   464                              <1> 	;call	tL0
   465                              <1> 	;
   466                              <1> 	;retn
   467                              <1> 	; 06/11/2023
   468                              <1> 	;jmp	short tL0
   469                              <1> 	;retn
   470                              <1> 
   471                              <1> 	; 06/11/2023
   472                              <1> tL0:
   473                              <1> 	; 08/11/2023
   474                              <1> 	; 05/11/2023
   475                              <1> 	; 17/02/2017 - Buffer switch test (temporary)
   476                              <1> 	; 06/11/2023
   477                              <1> 	; al = buffer indicator ('1', '2' or '0' -stop- )
   478 0000055B 1E                  <1> 	push	ds
   479                              <1> 	;push	bx 
   480 0000055C BB00B8              <1> 	mov	bx, 0B800h ; video display page segment
   481 0000055F 8EDB                <1> 	mov	ds, bx
   482 00000561 29DB                <1> 	sub	bx, bx ; 0
   483 00000563 B44E                <1> 	mov	ah, 4Eh
   484 00000565 8907                <1> 	mov	[bx], ax ; show current play buffer (1, 2)
   485                              <1> 	;pop	bx
   486 00000567 1F                  <1> 	pop	ds
   487 00000568 C3                  <1> 	retn
   488                              <1> 
   489                              <1> %endif
   490                              <1> 
   491                              <1> ; 08/11/2023
   492                              <1> ; 07/11/2023
   493                              <1> %if 0
   494                              <1> 
   495                              <1> tuneLoop:
   496                              <1> 	; 07/11/2023
   497                              <1> 	;mov	dx, NABMBAR
   498                              <1> 	;add	dx, PO_CIV_REG ; 14h
   499                              <1> tL1:
   500                              <1> 	call    updateLVI	; set LVI != CIV
   501                              <1> 	call    check4keyboardstop
   502                              <1> 	jc	short _exit_
   503                              <1> 	call    getCurrentIndex
   504                              <1> 	test	al, BIT0
   505                              <1> 	jz	short tL1	; loop if buffer 2 is not playing
   506                              <1> 
   507                              <1> 	; load buffer 1
   508                              <1> 	mov     ax, [WAV_BUFFER1]
   509                              <1> 	call	loadFromFile
   510                              <1> 	jc	short _exit_	; end of file
   511                              <1> tL2:
   512                              <1> 	call    updateLVI
   513                              <1> 	call    check4keyboardstop
   514                              <1> 	jc	short _exit_
   515                              <1> 	call    getCurrentIndex
   516                              <1> 	test	al, BIT0
   517                              <1> 	jnz	short tL2	; loop if buffer 1 is not playing
   518                              <1> 
   519                              <1> 	; load buffer 2
   520                              <1> 	mov     ax, [WAV_BUFFER2]
   521                              <1> 	call	loadFromFile
   522                              <1> 	jnc	short tuneLoop
   523                              <1> _exit_:
   524                              <1> 	mov	dx, [NABMBAR]		
   525                              <1> 	add	dx, PO_CR_REG	; PCM out Control Register
   526                              <1> 	mov	al, 0
   527                              <1> 	out	dx, al		; stop player
   528                              <1> 	retn
   529                              <1> 
   530                              <1> %endif
   531                              <1> 
   532                              <1> ; load data from file in 32k chunks. Would be nice to load 1 64k chunk,
   533                              <1> ; but in DOS you can only load FFFF bytes at a time.
   534                              <1> ;
   535                              <1> ; entry: ax = segment to load data to
   536                              <1> ; exit: CY set if end of file reached.
   537                              <1> ; note: last file buffer is padded with 0's to avoid pops at the end of song.
   538                              <1> ; assumes file is already open. uses [filehandle]
   539                              <1> 
   540                              <1> ; 07/11/2023
   541                              <1> %if 0
   542                              <1> 
   543                              <1> loadFromFile:
   544                              <1> 	; 07/11/2023
   545                              <1> 	; 06/11/2023
   546                              <1> 	; 17/02/2017
   547                              <1> 	;push	ax
   548                              <1> 	;push	cx
   549                              <1> 	;push	dx
   550                              <1> 	;push	bx
   551                              <1> 
   552                              <1> 	;push	es
   553                              <1> 	;push	ds
   554                              <1> 	
   555                              <1>         test    byte [flags], ENDOFFILE	; have we already read the
   556                              <1> 	;stc				; last of the file?
   557                              <1> 	; 05/11/2023
   558                              <1> 	;jnz	endLFF
   559                              <1> 	jz	short lff_12	; 06/11/2023
   560                              <1> 	; 06/11/2023
   561                              <1> 	;;mov	byte [tLoop], 0
   562                              <1> 	;jmp	endLFF
   563                              <1> 	stc
   564                              <1> 	retn
   565                              <1> 
   566                              <1> lff_12:	; 06/11/2023    
   567                              <1> 	mov	[fbs_seg], ax ; save buffer segment
   568                              <1> 	xor	dx, dx
   569                              <1> lff_0:
   570                              <1> 	mov	[fbs_off], dx ; buffer offset
   571                              <1> 
   572                              <1> 	mov     bx, (BUFFERSIZE / 2)	; 32k chunk
   573                              <1> 	mov	cl, [fbs_shift]   
   574                              <1> 	and	cl, cl
   575                              <1> 	jz	short lff_1 ; stereo, 16 bit	
   576                              <1> 
   577                              <1> 	; fbs_shift =
   578                              <1> 	;	2 for mono and 8 bit sample (multiplier = 4)
   579                              <1> 	;	1 for mono or 8 bit sample (multiplier = 2)
   580                              <1> 	shr	bx, cl ; 32K / multiplier
   581                              <1> 
   582                              <1> 	mov	ax, cs
   583                              <1> 	mov	dx, temp_buffer ; temporary buffer for wav data
   584                              <1> lff_1:
   585                              <1> 	; 17/02/2017 (stereo/mono, 8bit/16bit corrections)
   586                              <1> 	; load file into memory
   587                              <1>         mov	cx, bx                         
   588                              <1> 	mov	bx, [filehandle]
   589                              <1> 	mov     ds, ax
   590                              <1>        	mov	ah, 3fh
   591                              <1> 	int	21h
   592                              <1> 
   593                              <1> 	mov	bx, cs
   594                              <1> 	mov	ds, bx
   595                              <1> 
   596                              <1> 	jc	short lff_9 ; error !
   597                              <1> 
   598                              <1> 	and	ax, ax
   599                              <1> 	jz	short lff_10
   600                              <1> 	
   601                              <1> 	mov	bl, [fbs_shift] ; shift count  
   602                              <1> 	or	bl, bl
   603                              <1> 	jz	short lff_7 ; 16 bit stereo samples
   604                              <1> 
   605                              <1> 	push	es
   606                              <1> 	; 06/11/2023
   607                              <1> 	;push	di
   608                              <1> 	;push	si
   609                              <1> 	mov	di, [fbs_off]
   610                              <1> 	mov	si, [fbs_seg] ; buffer segment
   611                              <1> 	mov	es, si
   612                              <1> 	mov	si, temp_buffer ; temporary buffer address
   613                              <1> 	mov	cl, [bps] ; bits per sample (8 or 16)
   614                              <1> 	cmp	cl, 8
   615                              <1> 	jne	short lff_4 ; 16 bit samples
   616                              <1> 	; 8 bit samples
   617                              <1> 	mov	cx, ax ; byte count
   618                              <1> 	dec	bl  ; shift count, 1 = stereo, 2 = mono
   619                              <1> 	jz	short lff_3 ; 8 bit, stereo
   620                              <1> lff_2:
   621                              <1> 	; mono & 8 bit
   622                              <1> 	lodsb
   623                              <1> 	shl	ax, 8 ; convert 8 bit sample to 16 bit sample
   624                              <1> 	stosw	; left channel
   625                              <1> 	stosw	; right channel
   626                              <1> 	loop	lff_2
   627                              <1> 	jmp	short lff_6	
   628                              <1> lff_3:
   629                              <1> 	; stereo & 8 bit
   630                              <1> 	lodsb
   631                              <1> 	shl	ax, 8 ; convert 8 bit sample to 16 bit sample
   632                              <1> 	stosw
   633                              <1> 	loop	lff_3			
   634                              <1> 	jmp	short lff_6
   635                              <1> lff_4:
   636                              <1> 	; 16 bit mono samples
   637                              <1> 	mov	cx, ax ; word count
   638                              <1> lff_5:	
   639                              <1> 	lodsw
   640                              <1> 	stosw	; left channel
   641                              <1> 	stosw	; right channel
   642                              <1> 	loop	lff_5
   643                              <1> lff_6:
   644                              <1> 	mov	ax, di ; save next buffer offset/position
   645                              <1> 	; 06/11/2023
   646                              <1> 	;pop	si
   647                              <1> 	;pop	di
   648                              <1> 	pop	es
   649                              <1> ;lff_7:        
   650                              <1> 	; 06/11/2023
   651                              <1> 	and	ax, ax
   652                              <1> 	jz	short endLFF ; end of 2nd half
   653                              <1> 	mov	cx, (BUFFERSIZE / 2)
   654                              <1> lff_7:
   655                              <1> 	cmp	ax, cx
   656                              <1> 	je	short endLFF	 ; 06/11/2023
   657                              <1> 	;jb	short lff_11
   658                              <1> 	;xor	cx, cx
   659                              <1> 	;sub	cx, ax
   660                              <1> 	;neg	cx
   661                              <1> 	jmp	short lff_11
   662                              <1> lff_8:
   663                              <1> 	; 07/11/2023
   664                              <1> 	cmp	word [fbs_off], (BUFFERSIZE / 2) ; 32768
   665                              <1> 	jnb	short endLFF
   666                              <1> 	
   667                              <1> 	mov	dx, ax ; buffer offset
   668                              <1> 	mov	ax, [fbs_seg] ; buffer segment
   669                              <1> 	jmp	lff_0
   670                              <1> lff_9:  
   671                              <1> 	; 07/11/2023
   672                              <1> 	;; 06/11/2023 (temporary)
   673                              <1> 	;mov	al, '!'  ; error
   674                              <1> 	;call	tL0
   675                              <1> 
   676                              <1> 	xor	ax, ax
   677                              <1> lff_10:
   678                              <1> 	; 07/11/2023
   679                              <1> 	;mov	cx, (BUFFERSIZE / 2)  
   680                              <1> lff_11:
   681                              <1> 	call    padfill				; blank pad the remainder
   682                              <1>         ;clc					; don't exit with CY yet.
   683                              <1>         or	byte [flags], ENDOFFILE		; end of file flag
   684                              <1> endLFF:
   685                              <1>         ;pop	ds
   686                              <1> 	;pop	es
   687                              <1> 	; 06/11/2023
   688                              <1> 	;pop	bx
   689                              <1> 	;pop	dx
   690                              <1>         ;pop	cx
   691                              <1>         ;pop	ax
   692                              <1>         retn
   693                              <1> 
   694                              <1> %endif
   695                              <1> 
   696                              <1> ; 08/11/2023
   697                              <1> ; 07/11/2023
   698                              <1> %if 1
   699                              <1> 
   700                              <1> loadFromFile:
   701                              <1> 	; 07/11/2023
   702                              <1> 
   703 00000569 F606[8E0A]01        <1>         test    byte [flags], ENDOFFILE	; have we already read the
   704                              <1> 					; last of the file?
   705 0000056E 7402                <1> 	jz	short lff_0		; no
   706 00000570 F9                  <1> 	stc
   707 00000571 C3                  <1> 	retn
   708                              <1> 
   709                              <1> lff_0:
   710                              <1> 	; 08/11/2023
   711 00000572 89C5                <1> 	mov	bp, ax ; save buffer segment	
   712                              <1> 
   713 00000574 8A0E[A80A]          <1> 	mov	cl, [fbs_shift]   
   714 00000578 20C9                <1> 	and	cl, cl
   715 0000057A 7467                <1> 	jz	short lff_1 ; stereo, 16 bit	
   716                              <1> 
   717 0000057C BFFFFF              <1> 	mov	di, BUFFERSIZE - 1 ; 65535
   718                              <1> 
   719                              <1> 	; fbs_shift =
   720                              <1> 	;	2 for mono and 8 bit sample (multiplier = 4)
   721                              <1> 	;	1 for mono or 8 bit sample (multiplier = 2)
   722 0000057F D3EF                <1> 	shr	di, cl
   723 00000581 47                  <1> 	inc	di ; 16384 for 8 bit and mono	
   724                              <1> 		   ; 32768 for 8 bit or mono	
   725                              <1> 
   726 00000582 8CC8                <1> 	mov	ax, cs
   727 00000584 BA[AA0A]            <1> 	mov	dx, temp_buffer ; temporary buffer for wav data
   728                              <1> 
   729                              <1> 	; 17/02/2017 (stereo/mono, 8bit/16bit corrections)
   730                              <1> 	; load file into memory
   731 00000587 89F9                <1>         mov	cx, di                       
   732 00000589 8B1E[8C0A]          <1> 	mov	bx, [filehandle]
   733 0000058D 8ED8                <1> 	mov     ds, ax
   734 0000058F B43F                <1>        	mov	ah, 3Fh
   735 00000591 CD21                <1> 	int	21h
   736                              <1> 
   737 00000593 8CCB                <1> 	mov	bx, cs
   738 00000595 8EDB                <1> 	mov	ds, bx
   739                              <1> 
   740 00000597 727C                <1> 	jc	short lff_4 ; error !
   741                              <1> 
   742                              <1> 	; 08/11/2023
   743 00000599 31D2                <1> 	xor	dx, dx ; 0
   744                              <1> 
   745 0000059B 21C0                <1> 	and	ax, ax
   746 0000059D 746D                <1> 	jz	short lff_3
   747                              <1> 
   748 0000059F 8A1E[A80A]          <1> 	mov	bl, [fbs_shift]
   749                              <1> 
   750 000005A3 06                  <1> 	push	es
   751 000005A4 89D7                <1> 	mov	di, dx ; 0 ; [fbs_off]
   752                              <1> 	;mov	bp, [fbs_seg] ; buffer segment
   753 000005A6 8EC5                <1> 	mov	es, bp
   754 000005A8 BE[AA0A]            <1> 	mov	si, temp_buffer ; temporary buffer address
   755 000005AB 89C1                <1> 	mov	cx, ax ; byte count
   756 000005AD 803E[A60A]08        <1> 	cmp	byte [bps], 8 ; bits per sample (8 or 16)
   757 000005B2 751B                <1> 	jne	short lff_7 ; 16 bit samples
   758                              <1> 	; 8 bit samples
   759 000005B4 FECB                <1> 	dec	bl  ; shift count, 1 = stereo, 2 = mono
   760 000005B6 740C                <1> 	jz	short lff_6 ; 8 bit, stereo
   761                              <1> lff_5:
   762                              <1> 	; mono & 8 bit
   763 000005B8 AC                  <1> 	lodsb
   764 000005B9 2C80                <1> 	sub	al, 80h ; 08/11/2023
   765 000005BB C1E008              <1> 	shl	ax, 8 ; convert 8 bit sample to 16 bit sample
   766 000005BE AB                  <1> 	stosw	; left channel
   767 000005BF AB                  <1> 	stosw	; right channel
   768 000005C0 E2F6                <1> 	loop	lff_5
   769 000005C2 EB12                <1> 	jmp	short lff_9	
   770                              <1> lff_6:
   771                              <1> 	; stereo & 8 bit
   772 000005C4 AC                  <1> 	lodsb
   773 000005C5 2C80                <1> 	sub	al, 80h ; 08/11/2023
   774 000005C7 C1E008              <1> 	shl	ax, 8 ; convert 8 bit sample to 16 bit sample
   775 000005CA AB                  <1> 	stosw
   776 000005CB E2F7                <1> 	loop	lff_6			
   777 000005CD EB07                <1> 	jmp	short lff_9
   778                              <1> lff_7:
   779 000005CF D1E9                <1> 	shr	cx, 1 ; word count
   780                              <1> lff_8:
   781 000005D1 AD                  <1> 	lodsw
   782 000005D2 AB                  <1> 	stosw	; left channel
   783 000005D3 AB                  <1> 	stosw	; right channel
   784 000005D4 E2FB                <1> 	loop	lff_8
   785                              <1> lff_9:
   786 000005D6 07                  <1> 	pop	es
   787 000005D7 09FF                <1> 	or	di, di
   788 000005D9 7439                <1> 	jz	short endLFF ; 64KB ok 
   789                              <1> 	
   790 000005DB 89F8                <1> 	mov	ax, di ; [fbs_off]
   791 000005DD 48                  <1> 	dec	ax
   792 000005DE B9FFFF              <1> 	mov	cx, BUFFERSIZE - 1 ; 65535
   793 000005E1 EB29                <1> 	jmp	short lff_3
   794                              <1> 	
   795                              <1> lff_1:  
   796                              <1> 	;mov	bp, ax ; save buffer segment
   797 000005E3 31D2                <1> 	xor	dx, dx
   798                              <1> 	; load file into memory
   799 000005E5 B90080              <1>         mov	cx, (BUFFERSIZE / 2)	; 32k chunk
   800 000005E8 8B1E[8C0A]          <1> 	mov	bx, [filehandle]
   801 000005EC 8ED8                <1> 	mov     ds, ax
   802 000005EE B43F                <1>        	mov	ah, 3Fh
   803 000005F0 CD21                <1> 	int	21h
   804                              <1> 
   805 000005F2 8CCF                <1> 	mov	di, cs
   806 000005F4 8EDF                <1> 	mov	ds, di
   807                              <1> 
   808                              <1> 	; 07/11/2023
   809 000005F6 721D                <1> 	jc	short lff_4 ; error !
   810                              <1> 	
   811 000005F8 39C8                <1> 	cmp	ax, cx
   812 000005FA 7510                <1> 	jne	short lff_3
   813                              <1> lff_2:
   814                              <1> 	; 08/11/2023
   815 000005FC 01C2                <1> 	add	dx, ax
   816                              <1> 	;mov	cx, (BUFFERSIZE / 2)	; 32k chunk
   817                              <1> 	;mov	bx, [filehandle]
   818 000005FE 8EDD                <1> 	mov     ds, bp
   819 00000600 B43F                <1>        	mov	ah, 3Fh
   820 00000602 CD21                <1> 	int	21h
   821                              <1> 
   822                              <1> 	;mov	di, cs
   823 00000604 8EDF                <1> 	mov	ds, di
   824                              <1> 
   825 00000606 720D                <1> 	jc	short lff_4 ; error !
   826                              <1> 
   827 00000608 39C8                <1> 	cmp	ax, cx
   828 0000060A 7408                <1> 	je	short endLFF
   829                              <1> lff_3:
   830 0000060C E80F00              <1> 	call    padfill			; blank pad the remainder
   831                              <1>         ;clc				; don't exit with CY yet.
   832 0000060F 800E[8E0A]01        <1>         or	byte [flags], ENDOFFILE	; end of file flag
   833                              <1> endLFF:
   834 00000614 C3                  <1>         retn
   835                              <1> lff_4:
   836                              <1> 	; 08/11/2023
   837 00000615 B021                <1> 	mov	al, '!'  ; error
   838 00000617 E841FF              <1> 	call	tL0
   839                              <1> 
   840 0000061A 31C0                <1> 	xor	ax, ax
   841 0000061C EBEE                <1> 	jmp	short lff_3
   842                              <1> 
   843                              <1> %endif
   844                              <1> 
   845                              <1> ; entry ds:ax points to last byte in file
   846                              <1> ; cx=target size
   847                              <1> ; note: must do byte size fill
   848                              <1> ; destroys bx, cx
   849                              <1> ;
   850                              <1> padfill:
   851                              <1> 	; 07/11/2023
   852                              <1> 	; 06/11/2023
   853                              <1> 	; 17/02/2017
   854 0000061E 06                  <1> 	push	es
   855                              <1>         ;push	di
   856                              <1> 	;mov	di, [fbs_seg]
   857                              <1> 	;mov	es, di
   858 0000061F 8EC5                <1>         mov	es, bp
   859 00000621 29C1                <1> 	sub	cx, ax
   860                              <1> 	; 08/11/2023
   861                              <1> 	;mov	di, ax ; (wrong)
   862 00000623 89D7                <1> 	mov	di, dx ; buffer offset
   863 00000625 01C7                <1> 	add	di, ax       	
   864                              <1> 	; 07/11/2023
   865                              <1> 	;add	di, [fbs_off]
   866 00000627 30C0                <1>         xor	al, al
   867 00000629 F3AA                <1> 	rep	stosb
   868                              <1> 	;mov	[fbs_off], di
   869                              <1> 	;pop	di
   870 0000062B 07                  <1>         pop	es
   871 0000062C C3                  <1> 	retn
   872                              <1> 
   873                              <1> ; returns AL = current index value
   874                              <1> getCurrentIndex:
   875                              <1> 	; 08/11/2023
   876                              <1> 	;push	dx
   877 0000062D 8B16[920A]          <1> 	mov	dx, [NABMBAR]      		
   878 00000631 83C214              <1> 	add	dx, PO_CIV_REG
   879 00000634 EC                  <1> 	in	al, dx
   880                              <1> 	;pop	dx
   881                              <1> uLVI2:	;	06/11/2023
   882 00000635 C3                  <1> 	retn
   883                              <1> 
   884                              <1> ; examines the CIV and the LVI. When they're the same, we set LVI <> CIV
   885                              <1> ; that way, we never run out of buffers to play
   886                              <1> 
   887                              <1> ; 08/11/2023
   888                              <1> %if 0
   889                              <1> 	; 07/11/2023
   890                              <1> updateLVI:
   891                              <1> 	push	ax
   892                              <1> 	push	dx
   893                              <1> 	; 06/11/2023
   894                              <1> 	mov	dx, [NABMBAR]
   895                              <1> 	add	dx, PO_CIV_REG
   896                              <1> 	; (Current Index Value and Last Valid Index value)
   897                              <1> 	in	ax, dx
   898                              <1> 
   899                              <1> 	cmp	al, ah ; is current index = last index ?
   900                              <1> 	jne	short uLVI1
   901                              <1> 
   902                              <1> 	call	setNewIndex
   903                              <1> uLVI1:
   904                              <1> 	pop	dx
   905                              <1> 	pop	ax
   906                              <1> 	retn
   907                              <1> 
   908                              <1> setNewIndex:
   909                              <1> 	; 07/11/2023
   910                              <1> 	push	ax
   911                              <1>         call    getCurrentIndex                 ; get CIV
   912                              <1>         test    byte [flags], ENDOFFILE
   913                              <1>         jnz     short sni_1
   914                              <1>         ; not at the end of the file yet.
   915                              <1>         dec     al                              ; make new index <> current
   916                              <1>         and     al, INDEX_MASK                  ; make sure new value is 0-31
   917                              <1> sni_1:
   918                              <1>         call    setLastValidIndex               ; write new value
   919                              <1>         clc
   920                              <1>         pop	ax
   921                              <1> 	retn
   922                              <1> 
   923                              <1> %endif	
   924                              <1> 
   925                              <1> ; 08/11/2023
   926                              <1> ; 07/11/2023
   927                              <1> ;%if 1
   928                              <1> updateLVI:
   929                              <1> 	; 06/11/2023
   930 00000636 8B16[920A]          <1> 	mov	dx, [NABMBAR]      		
   931 0000063A 83C214              <1> 	add	dx, PO_CIV_REG
   932                              <1> 	; (Current Index Value and Last Valid Index value)
   933 0000063D ED                  <1> 	in	ax, dx
   934                              <1> 
   935 0000063E 38E0                <1> 	cmp	al, ah ; is current index = last index ?
   936 00000640 75F3                <1> 	jne	short uLVI2
   937                              <1> 
   938                              <1> 	; 08/11/2023	
   939 00000642 E8E8FF              <1> 	call	getCurrentIndex
   940                              <1>  
   941 00000645 F606[8E0A]01        <1> 	test	byte [flags], ENDOFFILE
   942                              <1> 	;jnz	short uLVI1
   943 0000064A 7411                <1> 	jz	short uLVI0  ; 08/11/2023
   944                              <1> 
   945                              <1> 	; 08/11/2023
   946 0000064C 50                  <1> 	push	ax
   947 0000064D 8B16[920A]          <1> 	mov	dx, [NABMBAR]
   948 00000651 83C216              <1> 	add	dx, PO_SR_REG  ; PCM out status register
   949 00000654 ED                  <1> 	in	ax, dx
   950                              <1> 
   951 00000655 A803                <1> 	test	al, 3 ; bit 1 = Current Equals Last Valid (CELV)
   952                              <1> 		      ; (has been processed)
   953                              <1> 		      ; bit 0 = 1 -> DMA Controller Halted (DCH)
   954 00000657 58                  <1> 	pop	ax
   955 00000658 7407                <1> 	jz	short uLVI1
   956                              <1> uLVI3:
   957 0000065A 31C0                <1> 	xor	ax, ax
   958                              <1> 	; zf = 1
   959 0000065C C3                  <1> 	retn
   960                              <1> uLVI0:
   961                              <1>         ; not at the end of the file yet.
   962 0000065D FEC8                <1> 	dec	al
   963 0000065F 241F                <1> 	and	al, 1Fh
   964                              <1> uLVI1:
   965                              <1> 	;call	setLastValidIndex
   966                              <1> ;uLVI2:
   967                              <1> 	;retn
   968                              <1> 
   969                              <1> ;%endif
   970                              <1> 	
   971                              <1> ;input AL = index # to stop on
   972                              <1> setLastValidIndex:
   973                              <1> 	; 08/11/2023
   974                              <1> 	;push	dx
   975 00000661 8B16[920A]          <1> 	mov	dx, [NABMBAR]
   976 00000665 83C215              <1> 	add	dx, PO_LVI_REG
   977 00000668 EE                  <1>         out     dx, al
   978                              <1> 	;pop	dx
   979 00000669 C3                  <1> 	retn
   980                              <1> 
   981                              <1> ; 06/11/2023
   982                              <1> ;	; 05/11/2023
   983                              <1> ;setCurrentIndex:
   984                              <1> ;	;push	dx
   985                              <1> ;	mov	dx, [NABMBAR]
   986                              <1> ;	add	dx, PO_CIV_REG
   987                              <1> ;	out	dx, al
   988                              <1> ;	;pop	dx
   989                              <1> ;	retn
   990                              <1> 
   991                              <1> ; checks if either shift key has been pressed. Exits with CY if so.
   992                              <1> ; 
   993                              <1> check4keyboardstop:
   994                              <1> 
   995                              <1> ; 06/11/2023
   996                              <1> %if 1
   997                              <1> 	; 19/05/2024
   998                              <1> 	; 08/11/2023
   999                              <1> 	; 04/11/2023
  1000 0000066A B401                <1> 	mov	ah, 1
  1001 0000066C CD16                <1> 	int	16h
  1002                              <1> 	;clc
  1003 0000066E 7439                <1> 	jz	short _cksr
  1004                              <1> 
  1005 00000670 30E4                <1> 	xor	ah, ah
  1006 00000672 CD16                <1> 	int	16h
  1007                              <1> 
  1008                              <1> 	;;;
  1009                              <1> 	; 19/05/2024 (change PCM out volume)
  1010 00000674 3C2B                <1> 	cmp	al, '+'
  1011 00000676 750B                <1> 	jne	short p_1
  1012                              <1> 	
  1013 00000678 A0[AD06]            <1> 	mov	al, [volume]
  1014 0000067B 3C00                <1> 	cmp	al, 0
  1015 0000067D 762B                <1> 	jna	short p_3
  1016 0000067F FEC8                <1> 	dec	al
  1017 00000681 EB0D                <1> 	jmp	short p_2
  1018                              <1> p_1:
  1019 00000683 3C2D                <1> 	cmp	al, '-'
  1020 00000685 7524                <1> 	jne	short p_4
  1021                              <1> 
  1022 00000687 A0[AD06]            <1> 	mov	al, [volume]
  1023 0000068A 3C1F                <1> 	cmp	al, 31
  1024 0000068C 731C                <1> 	jnb	short p_3
  1025 0000068E FEC0                <1> 	inc	al
  1026                              <1> p_2:
  1027 00000690 A2[AD06]            <1> 	mov	[volume], al
  1028 00000693 88C4                <1> 	mov	ah, al
  1029 00000695 8B16[900A]          <1> 	mov     dx, [NAMBAR]
  1030                              <1>   	;add    dx, CODEC_MASTER_VOL_REG
  1031 00000699 83C218              <1> 	add	dx, CODEC_PCM_OUT_REG
  1032 0000069C EF                  <1> 	out     dx, ax
  1033                              <1> 
  1034 0000069D E80E00              <1> 	call    delay1_4ms
  1035 000006A0 E80B00              <1>         call    delay1_4ms
  1036 000006A3 E80800              <1>         call    delay1_4ms
  1037 000006A6 E80500              <1>         call    delay1_4ms
  1038                              <1> _cksr:		; 19/05/2024
  1039 000006A9 F8                  <1> 	clc
  1040                              <1> p_3:
  1041 000006AA C3                  <1> 	retn
  1042                              <1> p_4:
  1043                              <1> 	;;;
  1044                              <1> ;_cskr:	
  1045 000006AB F9                  <1> 	stc
  1046 000006AC C3                  <1> 	retn
  1047                              <1> 
  1048                              <1> ; 19/05/2024
  1049 000006AD 02                  <1> volume:	db 02h
  1050                              <1> 
  1051                              <1> %endif
  1052                              <1> 
  1053                              <1> ; 06/11/2023
  1054                              <1> ; 04/11/2023
  1055                              <1> %if 0	
  1056                              <1>         push    ds
  1057                              <1>         push    0
  1058                              <1>         pop     ds		       ; examine BDA for keyboard flags
  1059                              <1>         test    byte [417h], (BIT0 | BIT1)
  1060                              <1>         pop     ds
  1061                              <1>         stc
  1062                              <1>         jnz	short _cksr ; 07/11/2023
  1063                              <1> 	;jz	short _cksr ; 06/11/2023
  1064                              <1>         clc
  1065                              <1> _cksr:
  1066                              <1>         retn
  1067                              <1> %endif
   470                                  
   471                                  ; UTILS.ASM
   472                                  ;----------------------------------------------------------------------------
   473                                  ;       delay1_4ms - Delay for 1/4 millisecond.
   474                                  ;		    1mS = 1000us
   475                                  ;       Entry:
   476                                  ;         None
   477                                  ;       Exit:
   478                                  ;	  None
   479                                  ;
   480                                  ;       Modified:
   481                                  ;         None
   482                                  ;
   483                                  PORTB			EQU	061h
   484                                    REFRESH_STATUS	EQU	010h		; Refresh signal status
   485                                  
   486                                  delay1_4ms:
   487 000006AE 50                              push    ax 
   488 000006AF 51                              push    cx
   489 000006B0 B91000                          mov     cx, 16			; close enough.
   490 000006B3 E461                    	in	al,PORTB
   491 000006B5 2410                    	and	al,REFRESH_STATUS
   492 000006B7 88C4                    	mov	ah,al			; Start toggle state
   493 000006B9 09C9                    	or	cx, cx
   494 000006BB 7401                    	jz	short _d4ms1
   495 000006BD 41                      	inc	cx			; Throwaway first toggle
   496                                  _d4ms1:	
   497 000006BE E461                    	in	al,PORTB		; Read system control port
   498 000006C0 2410                    	and	al,REFRESH_STATUS	; Refresh toggles 15.085 microseconds
   499 000006C2 38C4                    	cmp	ah,al
   500 000006C4 74F8                    	je	short _d4ms1		; Wait for state change
   501                                  
   502 000006C6 88C4                    	mov	ah,al			; Update with new state
   503 000006C8 49                      	dec	cx
   504 000006C9 75F3                    	jnz	short _d4ms1
   505                                  
   506 000006CB 59                              pop     cx
   507 000006CC 58                              pop     ax
   508 000006CD C3                              retn
   509                                  
   510                                  	; 13/11/2016 - Erdogan Tan
   511                                  write_ac97_dev_info:
   512                                  	; BUS/DEV/FN
   513                                  	;	00000000BBBBBBBBDDDDDFFF00000000
   514                                  	; DEV/VENDOR
   515                                  	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
   516                                  
   517 000006CE 30FF                    	xor	bh, bh
   518 000006D0 668B36[9E0A]            	mov	esi, [dev_vendor]
   519 000006D5 89F0                    	mov	ax, si
   520 000006D7 88C3                    	mov	bl, al
   521 000006D9 88DA                    	mov	dl, bl
   522 000006DB 80E30F                  	and	bl, 0Fh
   523 000006DE 8A87[1F09]              	mov	al, [bx+hex_chars]
   524 000006E2 A2[6209]                	mov	[msgVendorId+3], al
   525 000006E5 88D3                    	mov	bl, dl
   526 000006E7 C0EB04                  	shr	bl, 4
   527 000006EA 8A87[1F09]              	mov	al, [bx+hex_chars]
   528 000006EE A2[6109]                	mov	[msgVendorId+2], al
   529 000006F1 88E3                    	mov	bl, ah
   530 000006F3 88DA                    	mov	dl, bl
   531 000006F5 80E30F                  	and	bl, 0Fh
   532 000006F8 8A87[1F09]              	mov	al, [bx+hex_chars]
   533 000006FC A2[6009]                	mov	[msgVendorId+1], al
   534 000006FF 88D3                    	mov	bl, dl
   535 00000701 C0EB04                  	shr	bl, 4
   536 00000704 8A87[1F09]              	mov	al, [bx+hex_chars]
   537 00000708 A2[5F09]                	mov	[msgVendorId], al
   538 0000070B 66C1EE10                	shr	esi, 16
   539 0000070F 89F0                    	mov	ax, si
   540 00000711 88C3                    	mov	bl, al
   541 00000713 88DA                    	mov	dl, bl
   542 00000715 80E30F                  	and	bl, 0Fh
   543 00000718 8A87[1F09]              	mov	al, [bx+hex_chars]
   544 0000071C A2[7309]                	mov	[msgDevId+3], al
   545 0000071F 88D3                    	mov	bl, dl
   546 00000721 C0EB04                  	shr	bl, 4
   547 00000724 8A87[1F09]              	mov	al, [bx+hex_chars]
   548 00000728 A2[7209]                	mov	[msgDevId+2], al
   549 0000072B 88E3                    	mov	bl, ah
   550 0000072D 88DA                    	mov	dl, bl
   551 0000072F 80E30F                  	and	bl, 0Fh
   552 00000732 8A87[1F09]              	mov	al, [bx+hex_chars]
   553 00000736 A2[7109]                	mov	[msgDevId+1], al
   554 00000739 88D3                    	mov	bl, dl
   555 0000073B C0EB04                  	shr	bl, 4
   556 0000073E 8A87[1F09]              	mov	al, [bx+hex_chars]
   557 00000742 A2[7009]                	mov	[msgDevId], al
   558                                  
   559 00000745 668B36[9A0A]            	mov	esi, [bus_dev_fn]
   560 0000074A 66C1EE08                	shr	esi, 8
   561 0000074E 89F0                    	mov	ax, si
   562 00000750 88C3                    	mov	bl, al
   563 00000752 88DA                    	mov	dl, bl
   564 00000754 80E307                  	and	bl, 7 ; bit 0,1,2
   565 00000757 8A87[1F09]              	mov	al, [bx+hex_chars]
   566 0000075B A2[9709]                	mov	[msgFncNo+1], al
   567 0000075E 88D3                    	mov	bl, dl
   568 00000760 C0EB03                  	shr	bl, 3
   569 00000763 88DA                    	mov	dl, bl
   570 00000765 80E30F                  	and	bl, 0Fh
   571 00000768 8A87[1F09]              	mov	al, [bx+hex_chars]
   572 0000076C A2[8909]                	mov	[msgDevNo+1], al
   573 0000076F 88D3                    	mov	bl, dl
   574 00000771 C0EB04                  	shr	bl, 4
   575 00000774 8A87[1F09]              	mov	al, [bx+hex_chars]
   576 00000778 A2[8809]                	mov	[msgDevNo], al
   577 0000077B 88E3                    	mov	bl, ah
   578 0000077D 88DA                    	mov	dl, bl
   579 0000077F 80E30F                  	and	bl, 0Fh
   580 00000782 8A87[1F09]              	mov	al, [bx+hex_chars]
   581 00000786 A2[7D09]                	mov	[msgBusNo+1], al
   582 00000789 88D3                    	mov	bl, dl
   583 0000078B C0EB04                  	shr	bl, 4
   584 0000078E 8A87[1F09]              	mov	al, [bx+hex_chars]
   585 00000792 A2[7C09]                	mov	[msgBusNo], al
   586                                  
   587 00000795 A1[900A]                	mov	ax, [NAMBAR]
   588 00000798 88C3                    	mov	bl, al
   589 0000079A 88DA                    	mov	dl, bl
   590 0000079C 80E30F                  	and	bl, 0Fh
   591 0000079F 8A87[1F09]              	mov	al, [bx+hex_chars]
   592 000007A3 A2[A609]                	mov	[msgNamBar+3], al
   593 000007A6 88D3                    	mov	bl, dl
   594 000007A8 C0EB04                  	shr	bl, 4
   595 000007AB 8A87[1F09]              	mov	al, [bx+hex_chars]
   596 000007AF A2[A509]                	mov	[msgNamBar+2], al
   597 000007B2 88E3                    	mov	bl, ah
   598 000007B4 88DA                    	mov	dl, bl
   599 000007B6 80E30F                  	and	bl, 0Fh
   600 000007B9 8A87[1F09]              	mov	al, [bx+hex_chars]
   601 000007BD A2[A409]                	mov	[msgNamBar+1], al
   602 000007C0 88D3                    	mov	bl, dl
   603 000007C2 C0EB04                  	shr	bl, 4
   604 000007C5 8A87[1F09]              	mov	al, [bx+hex_chars]
   605 000007C9 A2[A309]                	mov	[msgNamBar], al
   606                                  
   607                                  	; 08/05/2024 (ebx->bx)
   608                                  	; 05/11/2023
   609 000007CC A1[920A]                	mov	ax, [NABMBAR]
   610 000007CF 88C3                    	mov	bl, al
   611 000007D1 88DA                    	mov	dl, bl
   612 000007D3 80E30F                  	and	bl, 0Fh
   613 000007D6 8A87[1F09]              	mov	al, [bx+hex_chars]
   614 000007DA A2[B509]                	mov	[msgNabmBar+3], al
   615 000007DD 88D3                    	mov	bl, dl
   616 000007DF C0EB04                  	shr	bl, 4
   617 000007E2 8A87[1F09]              	mov	al, [bx+hex_chars]
   618 000007E6 A2[B409]                	mov	[msgNabmBar+2], al
   619 000007E9 88E3                    	mov	bl, ah
   620 000007EB 88DA                    	mov	dl, bl
   621 000007ED 80E30F                  	and	bl, 0Fh
   622 000007F0 8A87[1F09]              	mov	al, [bx+hex_chars]
   623 000007F4 A2[B309]                	mov	[msgNabmBar+1], al
   624 000007F7 88D3                    	mov	bl, dl
   625 000007F9 C0EB04                  	shr	bl, 4
   626 000007FC 8A87[1F09]              	mov	al, [bx+hex_chars]
   627 00000800 A2[B209]                	mov	[msgNabmBar], al
   628                                  
   629                                  	; 24/11/2016
   630 00000803 30E4                    	xor	ah, ah
   631 00000805 A0[8F0A]                	mov	al, [ac97_int_ln_reg]
   632 00000808 B10A                    	mov	cl, 10
   633 0000080A F6F1                    	div	cl
   634 0000080C 0106[BD09]              	add	[msgIRQ], ax
   635 00000810 20C0                    	and	al, al
   636 00000812 7508                    	jnz	short _pmi
   637 00000814 A0[BE09]                	mov	al, [msgIRQ+1]
   638 00000817 B420                    	mov	ah, ' '
   639 00000819 A3[BD09]                	mov	[msgIRQ], ax
   640                                  _pmi:
   641 0000081C BA[3009]                        mov	dx, msgAC97Info
   642 0000081F B409                            mov     ah, 9
   643 00000821 CD21                            int     21h
   644 00000823 C3                              retn
   645                                  
   646                                  write_sample_rate:
   647                                  	; ax = sample rate (hertz)
   648                                  
   649 00000824 31D2                    	xor	dx, dx
   650 00000826 B90A00                  	mov	cx, 10
   651 00000829 F7F1                    	div	cx
   652 0000082B 0016[D309]              	add	[msgHertz+4], dl
   653 0000082F 29D2                    	sub	dx, dx
   654 00000831 F7F1                    	div	cx
   655 00000833 0016[D209]              	add	[msgHertz+3], dl
   656 00000837 29D2                    	sub	dx, dx
   657 00000839 F7F1                    	div	cx
   658 0000083B 0016[D109]              	add	[msgHertz+2], dl
   659 0000083F 29D2                    	sub	dx, dx
   660 00000841 F7F1                    	div	cx
   661 00000843 0016[D009]              	add	[msgHertz+1], dl
   662 00000847 0006[CF09]              	add	[msgHertz], al
   663                                  	
   664 0000084B BA[C209]                        mov     dx, msgSampleRate
   665 0000084E B409                            mov     ah, 9
   666 00000850 CD21                            int     21h
   667                                  
   668                                  	; 19/11/2016
   669 00000852 BA[E809]                	mov	dx, msg16Bits
   670 00000855 803E[A60A]10            	cmp	byte [bps], 16
   671 0000085A 7403                    	je	short wsr_1
   672 0000085C BA[D909]                	mov	dx, msg8Bits
   673                                  wsr_1:
   674 0000085F B409                            mov     ah, 9
   675 00000861 CD21                            int     21h
   676                                  
   677 00000863 BA[E109]                	mov	dx, msgMono
   678 00000866 803E[A40A]01            	cmp	byte [stmo], 1
   679 0000086B 7403                    	je	short wsr_2
   680 0000086D BA[F109]                	mov	dx, msgStereo
   681                                  wsr_2:
   682 00000870 B409                            mov     ah, 9
   683 00000872 CD21                            int     21h
   684                                  
   685 00000874 C3                              retn
   686                                  
   687                                  ;detect_codec:
   688                                  ;	; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   689                                  ;	mov	eax, 7Ch
   690                                  ;	call	codec_read
   691                                  ;       shl     eax, 16
   692                                  ;       mov     [codec_id], eax
   693                                  ;
   694                                  ;	mov	eax, 7Eh
   695                                  ;       call	codec_read
   696                                  ;       or      eax, [codec_id]
   697                                  ;       mov     [codec_chip_id], eax
   698                                  ;       and     eax, 0FFFFFF00h
   699                                  ;
   700                                  ;       mov     edi, codecs
   701                                  ;_dcb:
   702                                  ;       mov     ebx, [di]
   703                                  ;       test    ebx, ebx
   704                                  ;       jz      short _dco_unknown
   705                                  ;
   706                                  ;       cmp     eax, ebx
   707                                  ;       jne     short _dco_next
   708                                  ;       mov     ax, [di+4]
   709                                  ;       mov     [codec_vendor_ids], ax
   710                                  ;       movzx   esi, ax
   711                                  ;       call	print_msg
   712                                  ;       
   713                                  ;	mov	ax, [di+6]
   714                                  ;	call	detect_chip
   715                                  ;       retn
   716                                  ;
   717                                  ;_dco_next:
   718                                  ;       add     di, 8
   719                                  ;       jmp     short _dcb
   720                                  ;
   721                                  ;_dco_unknown:
   722                                  ;       mov    word [codec_vendor_ids], ac_unknown
   723                                  ;       mov    word [codec_chip_ids], chip_unknown
   724                                  ;       mov     esi, chip_unknown
   725                                  ;	call	print_msg
   726                                  ;       mov     eax, [codec_chip_id]
   727                                  ;       call    dword2str
   728                                  ;       call	print_msg
   729                                  ;       retn
   730                                  
   731                                  ;detect_chip:
   732                                  ;	; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
   733                                  ;	mov	di, ax ; chip_tab
   734                                  ;       mov     eax, [codec_chip_id]
   735                                  ;       and     ax, 0FFh
   736                                  ;_dch1:
   737                                  ;       mov     bx, [di]
   738                                  ;       cmp     bx, 0FFh
   739                                  ;       je      short _dch_unknown
   740                                  ;
   741                                  ;       cmp     ax, bx
   742                                  ;       jne     short _dch_next
   743                                  ;       mov     ax, [di+2]
   744                                  ;       mov     [codec_chip_ids], ax
   745                                  ;       mov     si, ax
   746                                  ;       call	print_msg
   747                                  ;       retn
   748                                  
   749                                  ;_dch_next:
   750                                  ;       add     di, 4
   751                                  ;       jmp     short _dch1
   752                                  ;
   753                                  ;_dch_unknown:
   754                                  ;       mov    word [codec_chip_ids], chip_unknown
   755                                  ;       mov     si, chip_unknown
   756                                  ;       call	print_msg
   757                                  ;       mov     eax, [codec_chip_id]
   758                                  ;       call    dword2str
   759                                  ;       call	print_msg
   760                                  ;       retn
   761                                  
   762                                  ; 19/05/2024
   763                                  ; 16/05/2024
   764                                  %if 0
   765                                  	; 16/05/2024
   766                                  	; 15/05/2024
   767                                  ac97_int_handler:
   768                                  	; 13/05/2024
   769                                  	; 12/05/2024
   770                                  	; 11/05/2024
   771                                  	; 11/11/2023
   772                                  	; 10/11/2023
   773                                  	; 17/02/2016
   774                                  	push	ax ; +	; 16/05/2024
   775                                  	;push	eax ; *	; 11/11/2023
   776                                  	push	dx ; **
   777                                  	; 05/11/2023
   778                                  	;push	cx
   779                                  	;push	bx
   780                                  	;push	si
   781                                  	;push	di
   782                                  
   783                                  	; 16/05/2024
   784                                  	; 10/11/2023
   785                                  	; EOI at first
   786                                  	mov	al, 20h
   787                                  	test	byte [ac97_int_ln_reg], 8
   788                                  	jz	short _ih_0
   789                                  	out 	0A0h, al ; 20h	; EOI
   790                                  _ih_0:
   791                                  	out	20h, al  ; 20h	; EOI
   792                                  
   793                                  	; 16/05/2024
   794                                  ;	mov	dx, GLOB_STS_REG
   795                                  ;	add	dx, [NABMBAR]
   796                                  ;	in	eax, dx
   797                                  ;
   798                                  ;	inc	eax	; 0FFFFFFFFh
   799                                  ;	jz	short _ih_3
   800                                  ;	dec	eax	; 0
   801                                  ;	;jz	short _ih_3
   802                                  ;_ih_3:
   803                                  ;	; 16/05/2024
   804                                  ;	push	eax ; ***
   805                                  
   806                                  	; 16/05/2024
   807                                  	; 24/11/2023 (TRDOS386 'audio.s')
   808                                          mov	dx, [NABMBAR]
   809                                  	add	dx, PO_SR_REG
   810                                  	in	ax, dx
   811                                  
   812                                  	test	al, BCIS ; bit 3, 8
   813                                  	jz	short _ih_2
   814                                  
   815                                  	; 15/05/2024
   816                                  	cmp	byte [tLoop], 1
   817                                  	jb	short _ih_2
   818                                  _ih_1:
   819                                  	; 16/05/2024
   820                                  	; 13/05/2024
   821                                  	;mov	ax, 1Ch ; FIFOE(=16)+BCIS(=8)+LVBCI(=4)
   822                                  	;add	dx, PO_SR_REG
   823                                          ;add	dx, [NABMBAR]
   824                                  	;out	dx, ax
   825                                  
   826                                  	; 16/05/2024
   827                                  	push	ax ; ****
   828                                  
   829                                  	; 13/05/2024
   830                                  	mov	dx, PO_CIV_REG
   831                                          add	dx, [NABMBAR]
   832                                  	in	al, dx
   833                                  	mov	ah, al
   834                                  	dec	al
   835                                  	and	al, 1Fh
   836                                          mov     dx, PO_LVI_REG
   837                                          add	dx, [NABMBAR]
   838                                          out	dx, al
   839                                  	and	ah, 1
   840                                  	; 13/05/2024
   841                                  	inc	ah
   842                                  	mov	[tBuff], ah ; 1 = Buffer 1, 2 = Buffer 2
   843                                  
   844                                  	; 13/05/2024
   845                                  	; 10/11/2023
   846                                  	; 28/11/2016 - Erdogan Tan
   847                                  	;call	tuneLoop
   848                                  
   849                                  	; 16/05/2024
   850                                  	pop	ax ; ****
   851                                  
   852                                  	; 16/05/2024
   853                                  _ih_2:
   854                                  	;mov	ax, 1Ch ; FIFOE(=16)+BCIS(=8)+LVBCI(=4)
   855                                  	mov	dx, [NABMBAR]
   856                                  	add	dx, PO_SR_REG
   857                                  	out	dx, ax
   858                                  
   859                                  ;	; 16/05/2024
   860                                  ;	pop	eax ; ***
   861                                  ;	
   862                                  ;	or	eax, eax
   863                                  ;	jz	short _ih_4
   864                                  ;	
   865                                  ;	mov	dx, GLOB_STS_REG
   866                                  ;	add	dx, [NABMBAR]
   867                                  ;	out	dx, eax
   868                                  
   869                                  	; 16/05/2024
   870                                  _ih_4:
   871                                  	; 10/11/2023
   872                                  	;mov	al, 20h
   873                                  	;test	byte [ac97_int_ln_reg], 8
   874                                  	;jz	short _ih_5
   875                                  	;out 	0A0h, al ; 20h	; EOI
   876                                  ;_ih_5:
   877                                  	;out	20h, al  ; 20h	; EOI
   878                                  ;_ih_6:
   879                                  	;pop	di
   880                                  	;pop	si
   881                                  	;pop	bx
   882                                  	;pop	cx
   883                                  	pop	dx ; **
   884                                  	;pop	eax ; *	; 11/11/2023
   885                                  	pop	ax ; + ; 16/05/2024
   886                                  	iret
   887                                  %endif
   888                                  
   889                                  print_msg:
   890                                  	; 13/11/2016 - Erdogan Tan 
   891                                  	; esi = ASCIIZ text address
   892                                  	;
   893 00000875 BB0700                  	mov	bx, 7h
   894 00000878 B40E                    	mov	ah, 0Eh 
   895                                  pm_next_char:
   896 0000087A AC                      	lodsb
   897 0000087B 20C0                    	and	al, al
   898 0000087D 7404                    	jz	short pm_retn
   899 0000087F CD10                    	int	10h
   900 00000881 EBF7                    	jmp	short pm_next_char
   901                                  pm_retn:
   902 00000883 C3                      	retn
   903                                  
   904                                  ; 06/11/2023
   905                                  ;dword2str:
   906                                  ;	; 13/11/2016 - Erdogan Tan
   907                                  ;	; eax = dword value
   908                                  ;	;
   909                                  ;	call	dwordtohex
   910                                  ;	mov	[dword_str], edx
   911                                  ;	mov	[dword_str+4], eax
   912                                  ;	mov	si, dword_str
   913                                  ;	retn
   914                                  
   915                                  	; trdos386.s (unix386.s) - 10/05/2015
   916                                  	; Convert binary number to hexadecimal string
   917                                  
   918                                  bytetohex:
   919                                  	; INPUT ->
   920                                  	; 	AL = byte (binary number)
   921                                  	; OUTPUT ->
   922                                  	;	AX = hexadecimal string
   923                                  	;
   924 00000884 53                      	push	bx
   925 00000885 30FF                    	xor	bh, bh
   926 00000887 88C3                    	mov	bl, al
   927 00000889 C0EB04                  	shr	bl, 4
   928 0000088C 8A9F[1F09]              	mov	bl, [bx+hex_chars]
   929 00000890 86D8                    	xchg	bl, al
   930 00000892 80E30F                  	and	bl, 0Fh
   931 00000895 8AA7[1F09]              	mov	ah, [bx+hex_chars]
   932 00000899 5B                      	pop	bx	
   933 0000089A C3                      	retn
   934                                  
   935                                  wordtohex:
   936                                  	; INPUT ->
   937                                  	; 	AX = word (binary number)
   938                                  	; OUTPUT ->
   939                                  	;	EAX = hexadecimal string
   940                                  	;
   941 0000089B 53                      	push	bx
   942 0000089C 30FF                    	xor	bh, bh
   943 0000089E 86E0                    	xchg	ah, al
   944 000008A0 50                      	push	ax
   945 000008A1 88E3                    	mov	bl, ah
   946 000008A3 C0EB04                  	shr	bl, 4
   947 000008A6 8A87[1F09]              	mov	al, [bx+hex_chars]
   948 000008AA 88E3                    	mov	bl, ah
   949 000008AC 80E30F                  	and	bl, 0Fh
   950 000008AF 8AA7[1F09]              	mov	ah, [bx+hex_chars]
   951 000008B3 66C1E010                	shl	eax, 16
   952 000008B7 58                      	pop	ax
   953 000008B8 5B                      	pop	bx
   954 000008B9 EBC9                    	jmp	short bytetohex
   955                                  
   956                                  ; 06/11/2023
   957                                  ;dwordtohex:
   958                                  ;	; INPUT ->
   959                                  ;	; 	EAX = dword (binary number)
   960                                  ;	; OUTPUT ->
   961                                  ;	;	EDX:EAX = hexadecimal string
   962                                  ;	;
   963                                  ;	push	eax
   964                                  ;	shr	eax, 16
   965                                  ;	call	wordtohex
   966                                  ;	mov	edx, eax
   967                                  ;	pop	eax
   968                                  ;	call	wordtohex
   969                                  ;	retn
   970                                  
   971                                  _DATA:
   972                                  
   973                                  ; 24/11/2016
   974                                  ;	IRQ  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 
   975 000008BB 08090A0B0C0D0E0F70-     irq_int	 db 08h,09h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,70h,71h,72h,73h,74h,75h,76h,77h
   975 000008C4 71727374757677     
   976                                  
   977                                  ; 17/02/2017
   978                                  ; Valid ICH device IDs
   979                                  
   980                                  valid_ids:
   981 000008CB 86801524                dd	(ICH_DID << 16) + INTEL_VID  	 ; 8086h:2415h
   982 000008CF 86802524                dd	(ICH0_DID << 16) + INTEL_VID 	 ; 8086h:2425h
   983 000008D3 86804524                dd	(ICH2_DID << 16) + INTEL_VID 	 ; 8086h:2445h
   984 000008D7 86808524                dd	(ICH3_DID << 16) + INTEL_VID 	 ; 8086h:2485h
   985 000008DB 8680C524                dd	(ICH4_DID << 16) + INTEL_VID 	 ; 8086h:24C5h
   986 000008DF 8680D524                dd	(ICH5_DID << 16) + INTEL_VID 	 ; 8086h:24D5h
   987 000008E3 86806E26                dd	(ICH6_DID << 16) + INTEL_VID 	 ; 8086h:266Eh
   988 000008E7 8680A625                dd	(ESB6300_DID << 16) + INTEL_VID  ; 8086h:25A6h
   989 000008EB 86809826                dd	(ESB631X_DID << 16) + INTEL_VID  ; 8086h:2698h
   990 000008EF 8680DE27                dd	(ICH7_DID << 16) + INTEL_VID 	 ; 8086h:27DEh
   991                                  ; 03/11/2023 - Erdogan Tan
   992 000008F3 86809571                dd	(MX82440_DID << 16) + INTEL_VID  ; 8086h:7195h
   993 000008F7 39101270                dd	(SI7012_DID << 16)  + SIS_VID	 ; 1039h:7012h
   994 000008FB DE10B101                dd 	(NFORCE_DID << 16)  + NVIDIA_VID ; 10DEh:01B1h
   995 000008FF DE106A00                dd 	(NFORCE2_DID << 16) + NVIDIA_VID ; 10DEh:006Ah
   996 00000903 22106D74                dd 	(AMD8111_DID << 16) + AMD_VID 	 ; 1022h:746Dh
   997 00000907 22104574                dd 	(AMD768_DID << 16)  + AMD_VID 	 ; 1022h:7445h
   998 0000090B DE105900                dd 	(CK804_DID << 16) + NVIDIA_VID	 ; 10DEh:0059h
   999 0000090F DE103A00                dd 	(MCP04_DID << 16) + NVIDIA_VID	 ; 10DEh:003Ah
  1000 00000913 DE108A00                dd 	(CK8_DID << 16) + NVIDIA_VID	 ; 1022h:008Ah
  1001 00000917 DE10DA00                dd 	(NFORCE3_DID << 16) + NVIDIA_VID ; 10DEh:00DAh
  1002 0000091B DE10EA00                dd 	(CK8S_DID << 16) + NVIDIA_VID	 ; 10DEh:00EAh
  1003                                  
  1004                                  valid_id_count:	equ ($ - valid_ids)>>2 ; 05/11/2023
  1005                                  
  1006                                  ; 13/11/2016
  1007 0000091F 303132333435363738-     hex_chars	db "0123456789ABCDEF", 0
  1007 00000928 3941424344454600   
  1008 00000930 414339372041756469-     msgAC97Info	db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah 
  1008 00000939 6F20436F6E74726F6C-
  1008 00000942 6C6572202620436F64-
  1008 0000094B 656320496E666F0D0A 
  1009 00000954 56656E646F72204944-     		db "Vendor ID: "
  1009 0000095D 3A20               
  1010 0000095F 303030306820446576-     msgVendorId	db "0000h Device ID: "
  1010 00000968 6963652049443A20   
  1011 00000970 30303030680D0A          msgDevId	db "0000h", 0Dh, 0Ah
  1012 00000977 4275733A20              		db "Bus: "
  1013 0000097C 303068204465766963-     msgBusNo	db "00h Device: "
  1013 00000985 653A20             
  1014 00000988 3030682046756E6374-     msgDevNo	db "00h Function: "
  1014 00000991 696F6E3A20         
  1015 00000996 303068                  msgFncNo	db "00h"
  1016 00000999 0D0A                    		db 0Dh, 0Ah
  1017                                  ; 05/11/2023	
  1018 0000099B 4E414D4241523A20        		db "NAMBAR: "
  1019 000009A3 303030306820            msgNamBar	db "0000h "
  1020 000009A9 4E41424D4241523A20      		db "NABMBAR: "
  1021 000009B2 303030306820495251-     msgNabmBar	db "0000h IRQ: "
  1021 000009BB 3A20               
  1022 000009BD 3030                    msgIRQ		dw 3030h
  1023 000009BF 0D0A24                  		db 0Dh, 0Ah, "$"
  1024 000009C2 53616D706C65205261-     msgSampleRate	db "Sample Rate: "
  1024 000009CB 74653A20           
  1025 000009CF 303030303020487A20-     msgHertz	db "00000 Hz ", "$" 
  1025 000009D8 24                 
  1026 000009D9 3820626974732024        msg8Bits	db "8 bits ", "$" 
  1027 000009E1 4D6F6E6F0D0A24          msgMono		db "Mono", 0Dh, 0Ah, "$"
  1028 000009E8 313620626974732024      msg16Bits	db "16 bits ", "$" 
  1029 000009F1 53746572656F0D0A24      msgStereo	db "Stereo", 0Dh, 0Ah, "$"
  1030                                  
  1031                                  ;; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc)
  1032                                  ;codec_id	dd 0
  1033                                  ;codec_chip_id	dd 0
  1034                                  ;codec_vendor_ids dw 0
  1035                                  ;codec_chip_ids	dw 0
  1036                                  
  1037 000009FA 3030303030303030        dword_str	 dd 30303030h, 30303030h
  1038 00000A02 680D0A00                		 db 'h', 0Dh, 0Ah, 0
  1039                                  
  1040                                  ;ac_unknown     db 'unknown manufacturer',13,10,0
  1041                                  ;ac_Realtek     db 'Realtek Semiconductor',13,10,0
  1042                                  ;ac_Analog      db 'Analog Devices',13,10,0
  1043                                  ;ac_CMedia      db 'C-Media Electronics',13,10,0
  1044                                  ;ac_Cirrus      db 'Cirrus Logic',13,10,0
  1045                                  ;ac_Wolfson     db 'Wolfson Microelectronics',13,10,0
  1046                                  ;ac_VIA         db 'VIA Technologies',13,10,0
  1047                                  ;ac_SigmaTel    db 'SigmaTel',13,10,0
  1048                                  ;ac_eMicro      db 'eMicro',13,10,0
  1049                                  ;
  1050                                  ;chip_unknown   db 'unknown codec id ', 0
  1051                                  
  1052                                  ;CHIP_REALTEK   equ 414C4700h
  1053                                  ;CHIP_CMEDIA    equ 434D4900h
  1054                                  ;CHIP_VIA       equ 56494100h
  1055                                  
  1056                                  ;codecs        dd CHIP_CMEDIA
  1057                                  ;	       dw ac_CMedia, chips_CMedia
  1058                                  ;              dd CHIP_REALTEK
  1059                                  ;	       dw ac_Realtek, chips_Realtek
  1060                                  ;              dd CHIP_VIA
  1061                                  ;	       dw ac_VIA, chips_VIA
  1062                                  ;              dd 0
  1063                                  
  1064                                  ;chips_Realtek dw 10h, chip_ALC201a
  1065                                  ;              dw 20h, chip_ALC650
  1066                                  ;              dw 21h, chip_ALC650D
  1067                                  ;              dw 22h, chip_ALC650E
  1068                                  ;              dw 23h, chip_ALC650F
  1069                                  ;              dw 60h, chip_ALC655
  1070                                  ;              dw 80h, chip_ALC658
  1071                                  ;              dw 81h, chip_ALC658D
  1072                                  ;              dw 90h, chip_ALC850
  1073                                  ;              dw 0FFh
  1074                                  
  1075                                  ;chips_CMedia  dw 41h, chip_CM9738
  1076                                  ;              dw 61h, chip_CM9739
  1077                                  ;              dw 69h, chip_CM9780
  1078                                  ;              dw 78h, chip_CM9761
  1079                                  ;              dw 82h, chip_CM9761
  1080                                  ;              dw 83h, chip_CM9761
  1081                                  ;              dw 0FFh
  1082                                  
  1083                                  ;chips_VIA     dw 61h, chip_VIA1612A
  1084                                  ;              dw 0FFh
  1085                                  
  1086                                  ;Realtek
  1087                                  ;chip_ALC201a    db 'ALC201a',0dh,0ah,00h
  1088                                  ;chip_ALC650     db 'ALC650 ',0dh,0ah,00h
  1089                                  ;chip_ALC650D    db 'ALC650D',0dh,0ah,00h
  1090                                  ;chip_ALC650E    db 'ALC650E',0dh,0ah,00h
  1091                                  ;chip_ALC650F    db 'ALC650F',0dh,0ah,00h
  1092                                  ;chip_ALC655     db 'ALC655 ',0dh,0ah,00h
  1093                                  ;chip_ALC658     db 'ALC658 ',0dh,0ah,00h
  1094                                  ;chip_ALC658D    db 'ALC658D',0dh,0ah,00h
  1095                                  ;chip_ALC850     db 'ALC850 ',0dh,0ah,00h
  1096                                  
  1097                                  ;CMedia
  1098                                  ;chip_CM9738     db 'CMI9738', 0dh,0ah,0
  1099                                  ;chip_CM9739     db 'CMI9739', 0dh,0ah,0
  1100                                  ;chip_CM9780     db 'CMI9780', 0dh,0ah,0
  1101                                  ;chip_CM9761     db 'CMI9761', 0dh,0ah,0
  1102                                  
  1103                                  ;VIA
  1104                                  ;chip_VIA1612A   db 'VIA1612A',13,10,0
  1105                                  
  1106                                  ; 11/11/2023
  1107                                  msg_init_err:
  1108 00000A06 0D0A                    	db	CR, LF
  1109 00000A08 4143393720436F6E74-     	db	"AC97 Controller/Codec initialization error !"
  1109 00000A11 726F6C6C65722F436F-
  1109 00000A1A 64656320696E697469-
  1109 00000A23 616C697A6174696F6E-
  1109 00000A2C 206572726F722021   
  1110 00000A34 0D0A24                  	db	CR, LF, "$"
  1111                                  
  1112                                  ; 12/11/2023
  1113                                  msg_no_vra:
  1114 00000A37 0D0A                    	db	CR, LF
  1115 00000A39 4E6F20565241207375-     	db	"No VRA support ! Only 48 kHZ sample rate supported !"
  1115 00000A42 70706F72742021204F-
  1115 00000A4B 6E6C79203438206B48-
  1115 00000A54 5A2073616D706C6520-
  1115 00000A5D 726174652073757070-
  1115 00000A66 6F727465642021     
  1116 00000A6D 0D0A24                  	db	CR, LF, "$"
  1117                                  
  1118                                  ; 17/02/2017
  1119                                  bss_start:
  1120                                  
  1121                                  ABSOLUTE bss_start
  1122                                  
  1123                                  alignb 2
  1124                                  
  1125                                  ; 28/11/2016
  1126                                  
  1127 00000A70 <res 1Ch>               smpRBuff:	resw 14 ; 19/11/2016 - Erdogan Tan
  1128                                  
  1129 00000A8C ????                    filehandle:	resw 1
  1130                                  
  1131 00000A8E ??                      flags:		resb 1
  1132                                  ; 06/11/2023
  1133 00000A8F ??                      ac97_int_ln_reg: resb 1
  1134                                  
  1135                                  ; 06/11/2023
  1136                                  ;pcm_irq_status: resb 1	; 05/11/2023
  1137                                  ;
  1138                                  ;inside:	resb 1
  1139                                  ;tLoop:		resb 1
  1140                                  
  1141                                  ; 06/11/2023
  1142                                  ; 05/11/2023
  1143                                  ; 04/11/2023
  1144                                  ;IRQ_status:	resw 1	; IRQ status before enabling audio interrupt
  1145                                  ;IRQ_vector:	resd 1  ; Previous interrupt handler address	
  1146                                  
  1147                                  ; 17/02/2017
  1148                                  ; NAMBAR:  Native Audio Mixer Base Address Register
  1149                                  ;    (ICH, Audio D31:F5, PCI Config Space) Address offset: 10h-13h
  1150                                  ; NABMBAR: Native Audio Bus Mastering Base Address register
  1151                                  ;    (ICH, Audio D31:F5, PCI Config Space) Address offset: 14h-17h
  1152 00000A90 ????                    NAMBAR:		resw 1			; BAR for mixer
  1153 00000A92 ????                    NABMBAR:	resw 1			; BAR for bus master regs
  1154                                  
  1155                                  ; 256 byte buffer for descriptor list
  1156 00000A94 ????                    BDL_BUFFER:	resw 1			; segment of our 256byte BDL buffer
  1157 00000A96 ????                    WAV_BUFFER1:	resw 1			; segment of our WAV storage
  1158                                  ; 64k buffers for wav file storage
  1159 00000A98 ????                    WAV_BUFFER2:	resw 1			; segment of 2nd wav buffer
  1160                                  
  1161                                  ; 06/11/2023
  1162                                  ;tBuff:		resb 1
  1163                                  ;ac97_int_ln_reg: resb 1
  1164                                  
  1165                                  ; 12/11/2016 - Erdogan Tan
  1166                                  
  1167 00000A9A ????????                bus_dev_fn:	resd 1
  1168 00000A9E ????????                dev_vendor:	resd 1
  1169                                  ; 06/11/2023
  1170                                  ;stats_cmd:	resw 1 ; 17/02/2017
  1171                                  ; 05/11/2023
  1172                                  ;ac97_io_base:	resw 1
  1173 00000AA2 ????                    sample_rate:	resw 1
  1174                                  
  1175                                  ; 19/11/2016
  1176 00000AA4 ????                    stmo:		resw 1 
  1177 00000AA6 ????                    bps:		resw 1
  1178                                  
  1179                                  ; 08/11/2023
  1180                                  ; 07/11/2023
  1181 00000AA8 ??                      fbs_shift:	resb 1
  1182 00000AA9 ??                      		resb 1 ; 08/11/2023
  1183                                  
  1184                                  ;fbs_seg:	resw 1
  1185                                  ;fbs_off:	resw 1
  1186                                  
  1187                                  ;alignb 2
  1188                                  
  1189                                  ; 32 kilo bytes for temporay buffer
  1190                                  ; (for stereo-mono, 8bit/16bit corrections)
  1191 00000AAA <res 8000h>             temp_buffer:	resb 32768
  1192                                  
  1193                                  ;alignb 16
  1194                                  EOF:
