diff --git a/trdos386/programs/16bit/AC97PLAY.COM b/trdos386/programs/16bit/AC97PLAY.COM new file mode 100644 index 0000000..d99f0c4 Binary files /dev/null and b/trdos386/programs/16bit/AC97PLAY.COM differ diff --git a/trdos386/programs/16bit/PLAYMOD4.ASM b/trdos386/programs/16bit/PLAYMOD4.ASM new file mode 100644 index 0000000..6285089 --- /dev/null +++ b/trdos386/programs/16bit/PLAYMOD4.ASM @@ -0,0 +1,3822 @@ +; **************************************************************************** +; playmod4.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; PLAYMOD4.COM ! ICH AC97 MOD PLAYER & VGA DEMO program by Erdogan TAN +; +; 13/11/2024 +; +; [ Last Modification: 13/11/2024 ] +; +; Modified from 'PLAYMOD2.ASM' (20/05/2024) source code +; (Assembler: NASM 2.15) +; +; Assembler: FASM 1.73 +; ---------------------------------------------------------------------------- +; fasm playmod4.asm PLAYMOD4.COM +; ---------------------------------------------------------------------------- + +; playmod2.asm (20/05/2024) + +; TUNELOOP version (playing without AC97 interrupt) ; 12/05/2024 + +;[BITS 16] +;[org 100h] +; 13/11/2024 +use16 +org 100h + +Start: + call DetectICH ; Detect AC97 Audio Device +GetFileName: ; Parse the Command line... + mov si, 80h + mov bl, [si] + xor bh, bh + inc bx + mov byte [si+bx], 0 ; make AsciiZ filename. + inc si +ScanName: + lodsb + test al, al + je pmsg_2017 + cmp al, 20h + je short ScanName ; scan start of name. + mov di, si + dec di +ScanPeriod: + lodsb + cmp al, '.' ; if period NOT found, + je short PrintMesg ; then add a .MOD extension. + test al, al + jnz short ScanPeriod + dec si +SetExt: + ;mov byte [si+0], '.' + ;mov byte [si+1], 'M' + ;mov byte [si+2], 'O' + ;mov byte [si+3], 'D' + mov dword [si], '.MOD' + mov byte [si+4], 0 + +PrintMesg: + mov ax, 0900h ; Prints the Credits Text. + ;lea dx, [Credits] + mov dx, Credits + int 21h + + ; 13/05/2024 + call write_ac97_dev_info + mov ax, 0900h ; Prints the Credits Text. + mov dx, CRLF + int 21h +LoadMod: + ; es:di = Filename address + push es + push di + call LoadModule ; Load the MODule... + + cmp word [ErrorInfo], 0 ; any error loading? + je short init_codec + + mov ax, 0900h ; yes, print error and Exit. + ;lea dx, [ErrorMesg] + mov dx, ErrorMesg + int 21h + jmp Exit + +init_codec: + ; 13/05/2024 + ;call write_ac97_dev_info + + ; 08/05/2024 + ; 17/02/2017 + ;mov dx, [stats_cmd] + ;or dl, IO_ENA+BM_ENA ; enable IO and bus master + ;call pciRegWrite16 ; pciRegWrite8 + + ; 18/02/2017 + ;mov word [sample_rate], 22050 ; Mixing at 22.050 kHz + ; 14/05/2024 + mov word [sample_rate], 24000 + + ; 08/05/2024 + ; (48 kHZ mixing is necessary + ; if the AC97 hardware/codec has not got VRA feature) + ; ((or frequency converting code would be needed)) + ;mov word [sample_rate], 48000 ; Mixing at 48 kHz + +; setup the Codec (actually mixer registers) + call codecConfig ; unmute codec, set rates. + jnc short PlayNow + +_codec_err: + push cs + pop ds + mov dx, CodecErrMsg + mov ah, 9 + int 21h + jmp Exit + +CodecErrMsg db "Codec Error!" + db CR,LF,"$" +PlayNow: + mov ax, BdlBuffer + mov [BDL_BUFFER], ax + + mov ax, DmaBuffer ; DmaBuffer (4096 bytes) buff addr + mov [DMA_BUFFER1], ax ; 2048 byte half buffer 1 + + add ax, BUFFERSIZE ; code/current segment + mov [DMA_BUFFER2], ax ; 2048 byte half buffer 2 + + ;mov word [MixSpeed], 22050 ; Mixing at 22.050 kHz + + call StartPlaying + + mov ax, 0013h ; Set Mode 320x200x256 + int 10h + + mov cx, 128 ; Make a lookup table + xor bx, bx ; for fastest pixel + mov dx, 320*(100-64) ; addressing. +MakeOfs: + mov [RowOfs+bx], dx + mov [RowOfs+bx+2], dx + add dx, 320 + add bx, 4 + loop MakeOfs + +; Note: Normally IRQ 0 calls the ModPlay Polling at 18.2Hz thru +; the software interrupt 1Ch. If the IRQ 0 is disabled, then +; the INT 1Ch MUST BE CALLED at least MixSpeed/1024 times per +; second, or the module will sound "looped". +; Because we need better sync with the ModPlayer to draw the scope, +; the polling is called from my routine, and then the irq 0 must be +; disabled. The [DmaBuffer] points to the current buffer of 8-bit +; samples played by the Sound Blaster. Note that some samples are +; discarded in the next code, just for fun! + + ;in al, 21h ; disable irq 0! + ;or al, 00000001b + ;out 21h, al + + call ModPlay ; 13/02/2017 + + ;in al, 21h ; enable irq 0! + ;and al, 11111110b + ;out 21h, al + + mov ax, 0003h ; Set Text Mode 80x25x16 + int 10h + + call StopPlaying ; STOP! +Exit: + ;call FreeModule ; Free MODule core. +error_exit: + mov ax, 4C00h ; Bye! + int 21h +here: + jmp short here + +pmsg_2017: + mov ax, 0900h ; Prints the Credits Text. + ;lea dx, [msg_2017] + mov dx, msg_2017 + int 21h + jmp short Exit + +DetectICH: + ; 18/02/2017 + ; Detech Intel ICH based AC97 Audio Device + call pciFindDevice ; AC97.ASM (PLAYWAV.COM) + jnc short _1 + +; couldn't find the audio device! + ;push cs + ;pop ds + mov dx, noDevMsg + mov ah, 9 + int 21h + jmp short error_exit + +noDevMsg db "Error: Unable to find Intel ICH based audio device!",CR,LF,"$" + +_1: + ; 18/02/2017 + ; eax = BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; edx = DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + mov [bus_dev_fn], eax + mov [dev_vendor], edx + + ; get ICH base address regs for mixer and bus master + + mov al, NAMBAR_REG + call pciRegRead16 ; read PCI registers 10-11 + ;and dx, IO_ADDR_MASK ; mask off BIT0 + ; 14/05/2024 + and dl, 0FEh + + mov [NAMBAR], dx ; save audio mixer base addr + + mov al, NABMBAR_REG + call pciRegRead16 + ;and dx, IO_ADDR_MASK + ;/14/05/2024 + and dl, 0C0h + + mov [NABMBAR], dx ; save bus master base addr + + ; 08/05/2024 + ; 06/11/2023 + ;; init controller + ;; 17/02/2017 + ;mov al, PCI_CMD_REG ; command register (04h) + ;call pciRegRead16 ; pciRegRead8 + ; + ;; eax = BUS/DEV/FN/REG + ;; dx = PCI Command Register Content ; 17/02/2017 + ;; 00000000CCCCCCCC + ;mov [stats_cmd], dx + ; + ; 06/11/2023 + ;mov al, PCI_IO_BASE ; IO base address register (10h) + ;call pciRegRead32 + ; + ;and dx, 0FFC0h ; IO_ADDR_MASK (0FFFE) ? + ;mov [ac97_io_base], dx + + mov al, AC97_INT_LINE ; Interrupt line register (3Ch) + call pciRegRead8 ; 17/02/2017 + + mov [ac97_int_ln_reg], dl + +; 13/11/2024 ('%if' -> 'if' conversion for FASM) +; 12/05/2024 (tuneloop version) +;%if 0 +if 0 + ; 28/11/2016 + ;mov bx, 1 ; 08/05/2024 + xor dh, dh ; 17/02/2017 + ; 10/11/2023 + ;mov cx, dx + ;shl bx, cl + + ; 04/11/2023 + cli + + ;not bx + in al, 0A1h ; irq 8-15 + mov ah, al + in al, 21h ; irq 0-7 + + ; 04/11/2023 + ; save IRQ status + mov [IRQ_status], ax + + ; 08/05/2024 + ;mov dx, 4D1h ;8259 ELCR1 + ;in al, dx + ;mov ah, al + ;mov dx, 4D0h + ;in al, dx + ;;or ax, bx + ;bts ax, cx + ;mov dx, 4D0h + ;out dx, al ;set level-triggered mode + ;mov al, ah + ;mov dx, 4D1h + ;out dx, al ;set level-triggered mode + + ; 24/11/2016 - Erdogan Tan + ;mov bx, cx + ; 10/11/2023 + mov bx, dx + mov bl, [bx+irq_int] + shl bx, 2 ; * 4 + + ; set up interrupt vector + ; 30/11/2016 + push es + xor ax, ax + mov es, ax + ; 04/11/2023 + ; save interrupt vector + mov ax, [es:bx] + mov [IRQ_vector], ax + mov ax, [es:bx+2] + mov [IRQ_vector+2], ax + + mov word [es:bx], ac97_int_handler + mov ax, cs + mov [es:bx+2], ax + pop es + + ; 04/11/2023 + sti +;%endif +end if + retn + +; 12/05/2024 (tuneloop version) +;%if 0 +if 0 ; 13/11/2024 + +ac97_int_handler: + ; 11/05/2024 + ; 11/11/2023 + ; 10/11/2023 + ; 17/02/2016 + push eax ; 11/11/2023 + push dx + ; 05/11/2023 + ;push cx + ;push bx + ;push si + ;push di + + ; 10/11/2023 + ; EOI at first + mov al, 20h + test byte [ac97_int_ln_reg], 8 + jz short _ih_0 + out 0A0h, al ; 20h ; EOI +_ih_0: + out 20h, al ; 20h ; EOI + + ; 11/11/2023 + ; 09/11/2023 + mov dx, GLOB_STS_REG + add dx, [NABMBAR] + in eax, dx + + ; 12/05/2024 + ; 09/11/2023, + ;cmp eax, 0FFFFFFFFh ; -1 + ;je short _ih_2 + + ; 12/05/2024 + ;test al, 40h ; PCM Out Interrupt + ;jnz short _ih_1 + + ;test eax, eax + ;jz short _ih_2 + ; 12/05/2024 + test ax, PCM_OUT_IRQ+BCIS + jnz short _ih_1 + + ;mov dx, GLOB_STS_REG + ;add dx, [NABMBAR] + out dx, eax + jmp short _ih_2 + + ; ..... + ;mov al, 1 + ; 10/11/2023 + ;mov [tLoop], al ; 1 + + ;cmp [inside], al ; 1 + ;jnb short _ih_3 ; busy + + ;mov [inside], al ; 1 + ; + ;; 09/11/2023 + ;mov dx, [NABMBAR] + ;add dx, PO_SR_REG ; set pointer to Status reg + ;in al, dx + ;; 10/11/2023 + ;;;out dx, eax + ;;out dx, al ; clear interrupt event + ; ; (by writing 1 to same bits) + ; + ;;mov [pcm_irq_status], al ; 05/11/2023 + ;test al, BCIS ; Buffer Completion Interrupt Status (Bit 3) + ;jz short _ih_2 + ; ..... + +_ih_1: + ; 11/11/2023 + push eax + + ;mov ax, 1Ch ; FIFOE(=16)+BCIS(=8)+LVBCI(=4) + ;mov dx, PO_SR_REG + ;add dx, [NABMBAR] + ;out dx, ax + + ; 10/11/2023 + ; 28/11/2016 - Erdogan Tan + call tuneLoop + + ; 11/11/2023 + pop eax + mov dx, GLOB_STS_REG + add dx, [NABMBAR] + out dx, eax +_ih_2: + ; 11/11/2023 + mov dx, [NABMBAR] + add dx, PO_SR_REG ; set pointer to Status reg + mov ax, 1Ch + out dx, ax + +; ; 10/11/2023 +; mov al, 20h +; test byte [ac97_int_ln_reg], 8 +; jz short _ih_3 +; out 0A0h, al ; 20h ; EOI +;_ih_3: +; out 20h, al ; 20h ; EOI +;_ih_4: + ;mov byte [inside], 0 + ;pop di + ;pop si + ;pop bx + ;pop cx + pop dx + pop eax ; 11/11/2023 + iret + +;%endif +end if + +;============================================================================= +; PCI.ASM +;============================================================================= + +; EQUATES + +;constants of stuff that seem hard to remember at times. + +TRUE EQU 1 +FALSE EQU 0 + +ENABLED EQU 1 +DISABLED EQU 0 + +BIT0 EQU 1 +BIT1 EQU 2 +BIT2 EQU 4 +BIT3 EQU 8 +BIT4 EQU 10h +BIT5 EQU 20h +BIT6 EQU 40h +BIT7 EQU 80h +BIT8 EQU 100h +BIT9 EQU 200h +BIT10 EQU 400h +BIT11 EQU 800h +BIT12 EQU 1000h +BIT13 EQU 2000h +BIT14 EQU 4000h +BIT15 EQU 8000h +BIT16 EQU 10000h +BIT17 EQU 20000h +BIT18 EQU 40000h +BIT19 EQU 80000h +BIT20 EQU 100000h +BIT21 EQU 200000h +BIT22 EQU 400000h +BIT23 EQU 800000h +BIT24 EQU 1000000h +BIT25 EQU 2000000h +BIT26 EQU 4000000h +BIT27 EQU 8000000h +BIT28 EQU 10000000h +BIT29 EQU 20000000h +BIT30 EQU 40000000h +BIT31 EQU 80000000h + +;special characters +NUL EQU 0 +NULL EQU 0 +BELL EQU 07 +BS EQU 08 +TAB EQU 09 +; 13/11/2024 +LF = 10 +CR = 13 +ESCAPE EQU 27 ;ESC is a reserved word.... + + +;file stuff +READONLY EQU BIT0 +HIDDEN EQU BIT1 +SYSTEM EQU BIT2 +VOLUME EQU BIT3 ;ignored for file access +DIRECTORY EQU BIT4 ;must be 0 for file access +ARCHIVE EQU BIT5 +SHAREABLE EQU BIT7 ;for novell networks +OPEN EQU 2 ; open existing file +CREATE EQU 1 ; create new file + + +; PCI equates +; PCI function address (PFA) +; bit 31 = 1 +; bit 23:16 = bus number (0-255) +; bit 15:11 = device number (0-31) +; bit 10:8 = function number (0-7) +; bit 7:0 = register number (0-255) + +IO_ADDR_MASK EQU 0FFFEh ; mask off bit 0 for reading BARs +PCI_INDEX_PORT EQU 0CF8h +PCI_DATA_PORT EQU 0CFCh +PCI32 EQU BIT31 ; bitflag to signal 32bit access +PCI16 EQU BIT30 ; bitflag for 16bit access + +PCI_FN0 EQU 0 << 8 +PCI_FN1 EQU 1 << 8 +PCI_FN2 EQU 2 << 8 +PCI_FN3 EQU 3 << 8 +PCI_FN4 EQU 4 << 8 +PCI_FN5 EQU 5 << 8 +PCI_FN6 EQU 6 << 8 +PCI_FN7 EQU 7 << 8 + +PCI_CMD_REG EQU 04h ; reg 04, command reg + IO_ENA EQU BIT0 ; i/o decode enable + MEM_ENA EQU BIT1 ; memory decode enable + BM_ENA EQU BIT2 ; bus master enable + +; CODE + +; AC97.ASM +; PCI device register reader/writers. +; NASM version: Erdogan Tan (29/11/2016) +; Last Update: 17/02/2017 + +;=============================================================== +; 8/16/32bit PCI reader +; +; Entry: EAX=PCI Bus/Device/fn/register number +; BIT30 set if 32 bit access requested +; BIT29 set if 16 bit access requested +; otherwise defaults to 8bit read +; +; Exit: DL,DX,EDX register data depending on requested read size +; +; Note: this routine is meant to be called via pciRegRead8, pciRegread16, +; or pciRegRead32, listed below. +; +; Note2: don't attempt to read 32bits of data from a non dword aligned reg +; number. Likewise, don't do 16bit reads from non word aligned reg # +; +pciRegRead: + push ebx + push cx + mov ebx, eax ; save eax, dh + mov cl, dh + ; 13/11/2024 ('~' to 'NOT' conversion for FASM) + and eax, (NOT PCI32)+PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; read to + + in eax, dx ; do 32bit read + test ebx, PCI32 + jz short _pregr1 + + mov edx, eax ; return 32bits of data +_pregr1: + mov dx, ax ; return 16bits of data + test ebx, PCI32+PCI16 + jnz short _pregr2 + mov dh, cl ; restore dh for 8 bit read +_pregr2: + mov eax, ebx ; restore eax + and eax, (NOT PCI32)+PCI16 ; clear out data size request + pop cx + pop ebx + retn + +pciRegRead8: + and eax, (NOT PCI16)+PCI32 ; set up 8 bit read size + jmp short pciRegRead ; call generic PCI access + +pciRegRead16: + and eax, (NOT PCI16)+PCI32 ; set up 16 bit read size + or eax, PCI16 ; call generic PCI access + jmp short pciRegRead + +pciRegRead32: + and eax, (NOT PCI16)+PCI32 ; set up 32 bit read size + or eax, PCI32 ; call generic PCI access + jmp short pciRegRead + +;=============================================================== +; 8/16/32bit PCI writer +; +; Entry: EAX=PCI Bus/Device/fn/register number +; BIT31 set if 32 bit access requested +; BIT30 set if 16 bit access requested +; otherwise defaults to 8bit read +; DL/DX/EDX data to write depending on size +; +; +; note: this routine is meant to be called via pciRegWrite8, pciRegWrite16, +; or pciRegWrite32 as detailed below. +; +; Note2: don't attempt to write 32bits of data from a non dword aligned reg +; number. Likewise, don't do 16bit writes from non word aligned reg # +; +pciRegWrite: + push ebx + push cx + mov ebx, eax ; save eax, dx + mov cx, dx + or eax, BIT31 ; make a PCI access request + ; 13/11/2024 ('~' to 'NOT' conversion for FASM) + and eax, NOT PCI16 ; clear out data size request + and al, NOT 3 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; write to + + mov eax, edx ; put data into eax + mov ax, cx + + out dx, al + test ebx, PCI16+PCI32 ; only 8bit access? bail + jz short _pregw1 + + out dx, ax ; write 16 bit value + test ebx, PCI16 ; 16bit requested? bail + jnz short _pregw1 + + out dx, eax ; write full 32bit +_pregw1: + mov eax, ebx ; restore eax + and eax, (NOt PCI32)+PCI16 ; clear out data size request + mov dx, cx ; restore dx + pop cx + pop ebx + ret + +pciRegWrite8: + and eax, (NOT PCI16)+PCI32 ; set up 8 bit write size + jmp short pciRegWrite ; call generic PCI access + +pciRegWrite16: + and eax, (NOT PCI16)+PCI32 ; set up 16 bit write size + or eax, PCI16 ; call generic PCI access + jmp short pciRegWrite + +pciRegWrite32: + and eax, (NOT PCI16)+PCI32 ; set up 32 bit write size + or eax, PCI32 ; call generic PCI access + jmp short pciRegWrite + +; AC97.ASM (PLAYWAV.COM) +; 17/02/2017 (Modifed by Erdogan Tan for various ICH device IDs) +;=============================================================== +; PCIFindDevice: scan through PCI space looking for a device+vendor ID +; +; ENTRY: none +;; Entry: EAX=Device+Vendor ID +; +; Exit: EAX=PCI address if device found +; EDX=Device+Vendor ID +; CY clear if found, set if not found. EAX invalid if CY set. +; +; [old stackless] Destroys: ebx, esi, edi, cl +; +pciFindDevice: + ;push cx + ;push eax ; * + ;push esi + ;push edi + + ;mov esi, eax ; save off vend+device ID + + ; 17/02/2017 + mov si, valid_ids ; address of Valid ICH (AC97) Device IDs + mov cx, valid_id_count +pfd_0: + mov edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0 +nextPCIdevice: + add edi, 100h + cmp edi, 80FFF800h ; scanned all devices? + ;stc + ;je short PCIScanExit ; not found + jb short pfd_1 + mov edi, 80000000h + add si, 4 ; scan for next device ID + loop pfd_1 + stc + ;jmp short PCIScanExit + retn +pfd_1: + mov eax, edi ; read PCI registers + call pciRegRead32 + ;cmp edx, esi ; found device? + cmp edx, dword [si] + jne short nextPCIdevice + ;clc +PCIScanExit: + ;pushf + mov eax, BIT31 + not eax + and eax, edi ; return only bus/dev/fn # + ;popf + + ;pop edi + ;pop esi + ;pop edx ; * + ;pop cx + retn + +;============================================================================= +; CODEC.ASM +;============================================================================= + +; EQUATES + +;Codec registers. +; +;Not all codecs are created equal. Refer to the spec for your specific codec. +; +;All registers are 16bits wide. Access to codec registers over the AC97 link +;is defined by the OEM. +; +;Secondary codec's are accessed by ORing in BIT7 of all register accesses. +; + +; each codec/mixer register is 16bits + +CODEC_RESET_REG equ 00 ; reset codec +CODEC_MASTER_VOL_REG equ 02 ; master volume +CODEC_HP_VOL_REG equ 04 ; headphone volume +CODEC_MASTER_MONO_VOL_REG equ 06 ; master mono volume +CODEC_MASTER_TONE_REG equ 08 ; master tone (R+L) +CODEC_PCBEEP_VOL_REG equ 0ah ; PC beep volume +CODEC_PHONE_VOL_REG equ 0bh ; phone volume +CODEC_MIC_VOL_REG equ 0eh ; MIC volume +CODEC_LINE_IN_VOL_REG equ 10h ; line input volume +CODEC_CD_VOL_REG equ 12h ; CD volume +CODEC_VID_VOL_REG equ 14h ; video volume +CODEC_AUX_VOL_REG equ 16h ; aux volume +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_RECORD_SELECT_REG equ 1ah ; record select input +CODEC_RECORD_VOL_REG equ 1ch ; record volume +CODEC_RECORD_MIC_VOL_REG equ 1eh ; record mic volume +CODEC_GP_REG equ 20h ; general purpose +CODEC_3D_CONTROL_REG equ 22h ; 3D control +; 24h is reserved +CODEC_POWER_CTRL_REG equ 26h ; powerdown control +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate +CODEC_LR_ADCRATE_REG equ 32h ; PCM in sample rate +CODEC_MIC_ADCRATE_REG equ 34h ; mic in sample rate + +; registers 36-7a are reserved on the ICH + +CODEC_VENDORID1_REG equ 7ch ; codec vendor ID 1 +CODEC_VENDORID2_REG equ 7eh ; codec vendor ID 2 + +; Mixer registers 0 through 51h reside in the ICH and are not forwarded over +; the AC97 link to the codec, which I think is a little weird. Looks like +; the ICH makes it so you don't need a fully functional codec to play audio? +; +; whenever 2 codecs are present in the system, use BIT7 to access the 2nd +; set of registers, ie 80h-feh + +PRIMARY_CODEC equ 0 ; 0-7F for primary codec +SECONDARY_CODEC equ BIT7 ; 80-8f registers for 2ndary + +SAMPLE_RATE_441khz equ 44100 ; 44.1Khz (cd quality) rate + +; ---------------------------------------------------------------------------- +; 17/02/2017 +PCI_IO_BASE equ 10h ; = NAMBAR register offset +; 13/11/2024 ('equ' to '=' conversion for FASM) +AC97_INT_LINE = 3Ch ; AC97 Interrupt Line register offset + +; ---------------------------------------------------------------------------- +; ICH2AC97.INC +; ---------------------------------------------------------------------------- + +; PCI stuff + +; Intel ICH2 equates. It is assumed that ICH0 and plain ole ICH are compatible. + +INTEL_VID equ 8086h ; Intel's PCI vendor ID + +; 08/05/2024 +; 03/11/2023 - Erdogan Tan (Ref: MenuetOS AC97 WAV Player source code, 2004) +SIS_VID equ 1039h +NVIDIA_VID equ 10DEh ; Ref: MPXPLAY/SBEMU/KOLIBRIOS AC97 source c. +AMD_VID equ 1022h + +ICH_DID equ 2415h ; ICH device ID +ICH0_DID equ 2425h ; ICH0 +ICH2_DID equ 2445h ; ICH2 I think there are more ICHes. + ; they all should be compatible. +; 08/05/2024 +; 17/02/2017 (Erdogan Tan, ref: ALSA Device IDs, ALSA project) +ICH3_DID equ 2485h ; ICH3 +ICH4_DID equ 24C5h ; ICH4 +ICH5_DID equ 24D5h ; ICH5 +ICH6_DID equ 266Eh ; ICH6 +ESB6300_DID equ 25A6h ; 6300ESB +ESB631X_DID equ 2698h ; 631XESB +ICH7_DID equ 27DEh ; ICH7 +; 03/11/2023 - Erdogan Tan (Ref: MenuetOS AC97 WAV Player source code, 2004) +MX82440_DID equ 7195h +SI7012_DID equ 7012h +NFORCE_DID equ 01B1h +NFORCE2_DID equ 006Ah +AMD8111_DID equ 746Dh +AMD768_DID equ 7445h +; 03/11/2023 - Erdogan Tan - Ref: MPXPLAY/SBEMU/KOLIBRIOS AC97 source code +CK804_DID equ 0059h +MCP04_DID equ 003Ah +CK8_DID equ 008Ah +NFORCE3_DID equ 00DAh +CK8S_DID equ 00EAh + +; 13/11/2024 ('equ' to '=' conversion for FASM) +NAMBAR_REG = 10h ; native audio mixer BAR + NAM_SIZE equ 256 ; 256 bytes required. + +NABMBAR_REG = 14h ; native audio bus mastering BAR + NABM_SIZE equ 64 ; 64 bytes + +; BUS master registers, accessed via NABMBAR+offset + +; ICH supports 3 different types of register sets for three types of things +; it can do, thus: +; +; PCM in (for recording) aka PI +; PCM out (for playback) aka PO +; MIC in (for recording) aka MC + +PI_BDBAR_REG equ 0 ; PCM in buffer descriptor BAR +PO_BDBAR_REG equ 10h ; PCM out buffer descriptor BAR +MC_BDBAR_REG equ 20h ; MIC in buffer descriptor BAR + +; each buffer descriptor BAR holds a pointer which has entries to the buffer +; contents of the .WAV file we're going to play. Each entry is 8 bytes long +; (more on that later) and can contain 32 entries total, so each BAR is +; 256 bytes in length, thus: + +BDL_SIZE equ 32*8 ; Buffer Descriptor List size +INDEX_MASK equ 31 ; indexes must be 0-31 + + + +PI_CIV_REG equ 4 ; PCM in current Index value (RO) +PO_CIV_REG equ 14h ; PCM out current Index value (RO) +MC_CIV_REG equ 24h ; MIC in current Index value (RO) +;8bit read only +; each current index value is simply a pointer showing us which buffer +; (0-31) the codec is currently processing. Once this counter hits 31, it +; wraps back to 0. +; this can be handy to know, as once it hits 31, we're almost out of data to +; play back or room to record! + + +PI_LVI_REG equ 5 ; PCM in Last Valid Index +PO_LVI_REG equ 15h ; PCM out Last Valid Index +MC_LVI_REG equ 25h ; MIC in Last Valid Index +;8bit read/write +; The Last Valid Index is a number (0-31) to let the codec know what buffer +; number to stop on after processing. It could be very nasty to play audio +; from buffers that aren't filled with the audio we want to play. + + +PI_SR_REG equ 6 ; PCM in Status register +PO_SR_REG equ 16h ; PCM out Status register +MC_SR_REG equ 26h ; MIC in Status register +;16bit read/write +; status registers. Bitfields follow: + +FIFO_ERR equ BIT4 ; FIFO Over/Underrun W1TC. + +BCIS equ BIT3 ; buffer completion interrupt status. + ; Set whenever the last sample in ANY + ; buffer is finished. Bit is only + ; set when the Interrupt on Complete + ; (BIT4 of control reg) is set. + +LVBCI equ BIT2 ; Set whenever the codec has processed + ; the last buffer in the buffer list. + ; Will fire an interrupt if IOC bit is + ; set. Probably set after the last + ; sample in the last buffer is + ; processed. W1TC + + ; +CELV equ BIT1 ; Current buffer == last valid. + ; Bit is RO and remains set until LVI is + ; cleared. Probably set up the start + ; of processing for the last buffer. + + +DCH equ BIT0 ; DMA controller halted. + ; set whenever audio stream is stopped + ; or something else goes wrong. + +PI_PICB_REG equ 8 ; PCM in position in current buffer(RO) +PO_PICB_REG equ 18h ; PCM out position in current buffer(RO) +MC_PICB_REG equ 28h ; MIC in position in current buffer (RO) +;16bit read only +; position in current buffer regs show the number of dwords left to be +; processed in the current buffer. +; + +PI_PIV_REG equ 0ah ; PCM in Prefected index value +PO_PIV_REG equ 1ah ; PCM out Prefected index value +MC_PIV_REG equ 2ah ; MIC in Prefected index value +;8bit, read only +; Prefetched index value register. +; tells which buffer number (0-31) has be prefetched. I'd imagine this +; value follows the current index value fairly closely. (CIV+1) +; + +PI_CR_REG equ 0bh ; PCM in Control Register +PO_CR_REG equ 1bh ; PCM out Control Register +MC_CR_REG equ 2bh ; MIC in Control Register +; 8bit +; Control register *MUST* only be accessed as an 8bit value. +; Control register. See bitfields below. +; + +IOCE equ BIT4 ; interrupt on complete enable. + ; set this bit if you want an intrtpt + ; to fire whenever LVBCI is set. +FEIFE equ BIT3 ; set if you want an interrupt to fire + ; whenever there is a FIFO (over or + ; under) error. +LVBIE equ BIT2 ; last valid buffer interrupt enable. + ; set if you want an interrupt to fire + ; whenever the completion of the last + ; valid buffer. +RR equ BIT1 ; reset registers. Nukes all regs + ; except bits 4:2 of this register. + ; Only set this bit if BIT 0 is 0 +RPBM equ BIT0 ; Run/Pause + ; set this bit to start the codec! + + +GLOB_CNT_REG equ 2ch ; Global control register +SEC_RES_EN equ BIT5 ; secondary codec resume event + ; interrupt enable. Not used here. +PRI_RES_EN equ BIT4 ; ditto for primary. Not used here. +ACLINK_OFF equ BIT3 ; Turn off the AC97 link +ACWARM_RESET equ BIT2 ; Awaken the AC97 link from sleep. + ; registers preserved, bit self clears +ACCOLD_RESET equ BIT1 ; Reset everything in the AC97 and + ; reset all registers. Not self clearing + +GPIIE equ BIT0 ; GPI Interrupt enable. + ; set if you want an interrupt to + ; fire upon ANY of the bits in the + ; GPI (general pursose inputs?) not used. + +GLOB_STS_REG equ 30h ; Global Status register (RO) + +MD3 equ BIT17 ; modem powerdown status (yawn) +AD3 equ BIT16 ; Audio powerdown status (yawn) +RD_COMPLETE_STS equ BIT15 ; Codec read timed out. 0=normal +BIT3SLOT12 equ BIT14 ; shadowed status of bit 3 in slot 12 +BIT2SLOT12 equ BIT13 ; shadowed status of bit 2 in slot 12 +BIT1SLOT12 equ BIT12 ; shadowed status of bit 1 in slot 12 +SEC_RESUME_STS equ BIT11 ; secondary codec has resumed (and irqed) +PRI_RESUME_STS equ BIT10 ; primary codec has resumed (and irqed) +SEC_CODEC_RDY equ BIT9 ; secondary codec is ready for action +PRI_CODEC_RDY equ BIT8 ; Primary codec is ready for action + ; software must check these bits before + ; starting the codec! +MIC_IN_IRQ equ BIT7 ; MIC in caused an interrupt +PCM_OUT_IRQ equ BIT6 ; One of the PCM out channels IRQed +PCM_IN_IRQ equ BIT5 ; One of the PCM in channels IRQed +MODEM_OUT_IRQ equ BIT2 ; modem out channel IRQed +MODEM_IN_IRQ equ BIT1 ; modem in channel IRQed +GPI_STS_CHANGE equ BIT0 ; set whenever GPI's have changed. + ; BIT0 of slot 12 also reflects this. + + +ACC_SEMA_REG equ 34h ; Codec write semiphore register +CODEC_BUSY equ BIT0 ; codec register I/O is happening + ; self clearing +; +; Buffer Descriptors List +; As stated earlier, each buffer descriptor list is a set of (up to) 32 +; descriptors, each 8 bytes in length. Bytes 0-3 of a descriptor entry point +; to a chunk of memory to either play from or record to. Bytes 4-7 of an +; entry describe various control things detailed below. +; +; Buffer pointers must always be aligned on a Dword boundry. +; +; + +IOC equ BIT31 ; Fire an interrupt whenever this + ; buffer is complete. + +BUP equ BIT30 ; Buffer Underrun Policy. + ; if this buffer is the last buffer + ; in a playback, fill the remaining + ; samples with 0 (silence) or not. + ; It's a good idea to set this to 1 + ; for the last buffer in playback, + ; otherwise you're likely to get a lot + ; of noise at the end of the sound. + +; +; Bits 15:0 contain the length of the buffer, in number of samples, which +; are 16 bits each, coupled in left and right pairs, or 32bits each. +; Luckily for us, that's the same format as .wav files. +; +; A value of FFFF is 65536 samples. Running at 44.1Khz, that's just about +; 1.5 seconds of sample time. FFFF * 32bits is 1FFFFh bytes or 128k of data. +; +; A value of 0 in these bits means play no samples. +; + +; CODE + +; AC97.ASM + +; codec configuration code. Not much here really. +; NASM version: Erdogan Tan (29/11/2016) + +; enable codec, unmute stuff, set output rate to 44.1 +; entry: ax = desired sample rate +; + +; 13/11/2024 ('%if' to 'if' conversion for FASM) +; 08/04/2024 +;%if 0 +if 0 + +codecConfig: + ; 17/02/2017 + ; 07/11/2016 (Erdogan Tan) + PORT_NABM_GLB_CTRL_STAT equ 60h + + ;mov dx, [NAMBAR] ; mixer base address + ;add dx, CODEC_EXT_AUDIO_REG ; 28h + ;in ax, dx + ;and ax, 1 + ;jnz short _ssr + ;pop ax + ;jmp short cconf_1 + +_ssr: + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + or ax, 1 + out dx, ax ; Enable variable rate audio + + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + mov ax, [sample_rate] ; 17/02/2017 (Erdogan Tan) + + mov dx, [NAMBAR] + add dx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch + out dx, ax ; out sample rate + + ;mov dx, [NAMBAR] + ;add dx, CODEC_LR_ADCRATE_REG ; 32h + ;out dx, ax + + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + +;cconf_1: + mov dx, [NAMBAR] ; mixer base address + add dx, CODEC_RESET_REG ; reset register + mov ax, 42 + out dx, ax ; reset + + mov dx, [NABMBAR] ; bus master base address + add dx, PORT_NABM_GLB_CTRL_STAT + mov ax, 2 + out dx, ax + + mov cx, 7 +_100ms: + push cx + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + pop cx + loop _100ms + + mov dx, [NAMBAR] + add dx, CODEC_MASTER_VOL_REG ;02h + xor ax, ax ; ; volume attenuation = 0 (max. volume) + out dx, ax + + mov dx, [NAMBAR] + add dx, CODEC_MASTER_MONO_VOL_REG ;06h + ;xor ax, ax + out dx, ax + + mov dx, [NAMBAR] + add dx, CODEC_PCBEEP_VOL_REG ;0Ah + ;xor ax, ax + out dx, ax + + mov dx, [NAMBAR] + add dx, CODEC_PCM_OUT_REG ;18h + ;xor ax, ax + out dx, ax + + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + retn +;%else +else + ; 12/05/2024 + ; 08/05/2024 + ; (ac97_vra.asm, 19/11/2023, Erdogan Tan, playwav3.asm) +codecConfig: + ; 02/12/2023 + ; 26/11/2023 + ; 21/11/2023 + ; 20/11/2023 + ; 19/11/2023 (TRDOS 386 v2.0.7) + ; 15/11/2023 + ; 04/11/2023 + ; 17/02/2017 + ; 07/11/2016 (Erdogan Tan) + ;PORT_NABM_GLB_CTRL_STAT equ 60h + + ; 03/11/2023 (MPXPLAY, 'SC_ICH.C', ac97_init) + ; 'AC97_DEF.H' + ;AC97_EXTENDED_STATUS equ 002Ah + AC97_EA_SPDIF equ 0002h + AC97_EA_VRA equ 0001h + ; 04/11/2023 + ICH_PO_CR_RESET equ 0002h ; reset codec + ICH_PCM_20BIT equ 400000h ; 20-bit samples (ICH4) + ICH_PCM_246_MASK equ 300000h ; 6 channels + + ; 08/05/2024 + ; 11/11/2023 + CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + CODEC_REG_POWERDOWN equ 26h + + ; 04/11/2023 +init_ac97_controller: + mov eax, [bus_dev_fn] + mov al, PCI_CMD_REG + call pciRegRead16 ; read PCI command register + or dl, IO_ENA+BM_ENA ; enable IO and bus master + call pciRegWrite16 + + ; 14/05/2024 + ; 02/12/2023 + call delay_100ms ; 29/05/2017 + + ; 02/12/2023 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + +init_ac97_codec: + ; 18/11/2023 + mov bp, 40 + ; 14/05/2024 + ;mov bp, 100 +_initc_1: + ; 11/11/2023 + ; (TRDOS 386 v2.0.5, 'audio.s') + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + in eax, dx + + ; 14/05/2024 + ; 02/12/2023 + call delay1_4ms + + ; ? + ;; 15/11/2023 + ;;mov cx, 40 + ;mov bp, 40 ; 18/11/2023 +;_initc_1: + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + ; 14/05/2024 + ; 02/12/2023 + call delay1_4ms + + cmp eax, 0FFFFFFFFh ; -1 + ;je short init_ac97_codec_err1 + ; 15/11/2023 + jne short _initc_3 +_initc_2: + ;dec cx + dec bp ; 18/11/2023 + ;jz short init_ac97_codec_err1 + ; 19/11/2023 + jz short _ac97_codec_ready + + call delay_100ms + jmp short _initc_1 +_initc_3: + test eax, CTRL_ST_CREADY + jnz short _ac97_codec_ready + + call reset_ac97_codec + ; 11/11/2023 + ;jc short init_ac97_codec_err2 + ; 15/11/2023 + ;jc short _initc_2 + ; 26/11/2023 + jmp short _initc_2 + +_ac97_codec_ready: + mov dx, [NAMBAR] + ;add dx, 0 ; ac_reg_0 ; reset register + out dx, ax + + call delay_100ms + + ; 19/11/2023 + or bp, bp + jnz short _ac97_codec_init_ok + + xor eax, eax ; 0 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + out dx, ax + + ; 19/11/2023 + ; wait for 1 second + ; 14/05/2024 + ;mov ecx, 1000 ; 1000*4*0.25ms = 1s + ;mov cx, 10 + ; 20/05/2024 + ;mov cx, 40 ; 19/05/2024 + mov ecx, 40 +_ac97_codec_rloop: + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + call delay_100ms + + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + in ax, dx + + ; 14/05/2024 + ; 02/12/2023 + call delay1_4ms + + and ax, 0Fh + cmp al, 0Fh + je short _ac97_codec_init_ok + loop _ac97_codec_rloop + + ; 12/05/2024 + ; cf = 1 +init_ac97_codec_err1: + ;stc ; 12/05/2024 +init_ac97_codec_err2: + retn + +_ac97_codec_init_ok: + ; 11/11/2023 + ;mov al, 2 ; force set 16-bit 2-channel PCM + ;mov dx, GLOB_CNT_REG ; 2Ch + ;add dx, [NABMBAR] + ;out dx, eax + + ;;call delay1_4ms + + call reset_ac97_controller + + ; 11/11/2023 + ;call delay1_4ms + ; 21/11/2023 - temporary + call delay_100ms + + ;call setup_ac97_codec + +setup_ac97_codec: + ; 08/05/2028 + ; [sample_rate] = 22050 + ; 12/11/2023 + ;cmp word [sample_rate], 48000 + ;je short skip_rate + +; 11/11/2023 +; 05/11/2023 +;%if 1 + AC97_EA_VRA equ BIT0 ; 11/11/2023 + + ; 18/05/2024 + call delay1_4ms + + ; 16/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_REG ; 28h + in ax, dx + + ; 18/05/2024 + ; 16/05/2024 + call delay1_4ms + ; 17/05/2024 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + + ; 17/05/2024 + ;call delay_100ms + + ; 14/05/2024 + test al, 1 ; BIT0 ; Variable Rate Audio bit + jz short vra_not_supported + + ; 11/11/2023 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + + ; 14/05/2024 + ; 02/12/2023 + call delay1_4ms + + ; 13/11/2024 ('~' to 'NOT' conversion for FASM) + and al, NOT BIT1 ; Clear DRA + or al, AC97_EA_VRA ; 1 ; 04/11/2023 + out dx, ax ; Enable variable rate audio + + mov cx, 10 +check_vra: + call delay_100ms + + ; 11/11/2023 + in ax, dx + test al, AC97_EA_VRA ; 1 + jnz short set_rate + + ; 11/11/2023 + loop check_vra + + ; 13/11/2023 + ;mov byte [VRA], 0 + ; 14/05/2024 +vra_not_supported: + ; 08/05/2024 + mov word [sample_rate], 48000 + jmp short skip_rate + + ; 12/11/2023 + ;pop ax ; discard return address to the caller + ;mov dx, msg_no_vra + ;jmp vra_err + +set_rate: + mov ax, [sample_rate] ; 17/02/2017 (Erdogan Tan) + ; 08/05/2024 + ; ax = 22050 (Hz) + + mov dx, [NAMBAR] + add dx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch + out dx, ax ; PCM Front/Center Output Sample Rate + + call delay_100ms + + ; 12/11/2023 +skip_rate: + ; 11/11/2023 (temporary) + + ;mov dx, [NAMBAR] + ;add dx, CODEC_PCM_SURND_DACRATE_REG ; 2Eh + ;out dx, ax ; PCM Surround Output Sample Rate + + ;call delay_100ms + + ;mov dx, [NAMBAR] + ;add dx, CODEC_PCM_LFE_DACRATE_REG ; 30h + ;out dx, ax ; PCM LFE Output Sample Rate + + ;call delay_100ms + + ; 05/11/2023 (temporary) + ;mov dx, [NAMBAR] + ;add dx, CODEC_LR_ADCRATE_REG ; 32h + ;out dx, ax ; PCM Input Sample Rate + ; + ;call delay_100ms + + mov ax, 0202h + mov [volume], al ; 29 + mov dx, [NAMBAR] + add dx, CODEC_MASTER_VOL_REG ; 02h + out dx, ax + + ; 11/11/2023 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ; + ;mov dx, [NAMBAR] + ;add dx, CODEC_MASTER_MONO_VOL_REG ; 06h + ;out dx, ax + + ; 11/11/2023 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ; + ;mov ax, 02h + ;mov dx, [NAMBAR] + ;add dx, CODEC_PCBEEP_VOL_REG ; 0Ah + ;out dx, ax + + ; 14/05/2024 + ; 20/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + ; 21/11/2023 temporary + ;call delay_100ms + + ;mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_PCM_OUT_REG ; 18h + out dx, ax + + ; 14/05/2024 + ; 20/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + ; 14/05/2024 + ; 21/11/2023 - temporary + ;call delay_100ms + + ; 11/11/2023 + ;mov ax, 8008h ; Mute + ;mov dx, [NAMBAR] + ;add dx, CODEC_PHONE_VOL_REG ; 0Ch + ; ; AC97_PHONE_VOL ; TAD Input (Mono) + ;out dx, ax + ; + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + + ;mov ax, 0808h + ;mov dx, [NAMBAR] + ;add dx, CODEC_LINE_IN_VOL_REG ;10h ; Line Input (Stereo) + ;out dx, ax + ; + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + + ;mov dx, [NAMBAR] + ;add dx, CODEC_CD_VOL_REG ;12h ; CD Input (Stereo) + ;out dx, ax + ; + ;mov dx, [NAMBAR] + ;add dx, CODEC_AUX_VOL_REG ;16h ; Aux Input (Stereo) + ;out dx, ax + ; + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + + ; 14/05/2024 + ;call delay_100ms + + ; 14/05/2024 + clc + +;detect_ac97_codec: + retn + +reset_ac97_controller: + ; 11/11/2023 + ; 10/06/2017 + ; 29/05/2017 + ; 28/05/2017 + ; reset AC97 audio controller registers + xor ax, ax + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 14/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 14/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 14/05/2024 + call delay1_4ms + + mov al, RR + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 14/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 14/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 14/05/2024 + call delay1_4ms + + retn + +reset_ac97_codec: + ; 11/11/2023 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + in eax, dx + + ;test eax, 2 + ; 06/08/2022 + test al, 2 + jz short _r_ac97codec_cold + + call warm_ac97codec_reset + jnc short _r_ac97codec_ok +_r_ac97codec_cold: + call cold_ac97codec_reset + jnc short _r_ac97codec_ok + + ; 16/04/2017 + ;xor eax, eax ; timeout error + ;stc + retn + +_r_ac97codec_ok: + xor eax, eax + ;mov al, VIA_ACLINK_C00_READY ; 1 + inc al + retn + +warm_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 6 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + mov cx, 10 ; total 1s +_warm_ac97c_rst_wait: + call delay_100ms + + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _warm_ac97c_rst_ok + + dec cx + jnz short _warm_ac97c_rst_wait + +_warm_ac97c_rst_fail: + stc +_warm_ac97c_rst_ok: + retn + +cold_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 2 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + + mov cx, 16 ; total 20*100 ms = 2s + +_cold_ac97c_rst_wait: + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _cold_ac97c_rst_ok + + call delay_100ms + + dec cx + jnz short _cold_ac97c_rst_wait + +_cold_ac97c_rst_fail: + stc +_cold_ac97c_rst_ok: + retn + +delay_100ms: + ; 11/11/2023 + ; 29/05/2017 + ; 24/03/2017 ('codec.asm') + ; wait 100 ms + push cx + mov cx, 400 ; 400*0.25ms +_delay_x_ms: + call delay1_4ms + loop _delay_x_ms + pop cx + retn + +;%endif +end if + +;============================================================================= +; ICH_WAV.ASM +;============================================================================= + +; DOS based .WAV player using AC'97 and codec interface. +; --------------------------------------------------------------- +; NASM version: Erdogan Tan (29/11/2016) +; Last Update: 17/02/2017 (by Erdogan Tan) + +; ICHWAV.ASM +; PLAYMOD.ASM +; player internal variables and other equates. +;BUFFERSIZE equ 2048*4 ; 8K half buffer size. 18/02/2017 +; 13/11/2024 ('equ' to '=' conversion for FASM) +; 14/05/2024 +BUFFERSIZE = 2560*4 +ENDOFFILE equ BIT0 ; flag for knowing end of file + +;=========================================================================== +; entry: none. File is already open and [filehandle] filled. +; exit: not until the song is finished or the user aborts. +; +; 18/02/2017 +ModPlay: ; 13/02/2017 ; ModPlay Polling! + ;cld + ; clear (half) buffer 2 + ;mov di, [DMA_BUFFER2] + ;sub ax, ax + ;mov cx, (BUFFERSIZE/2) + ;rep stosw + + ; 15/05/2024 + push es + push ds + pop es + mov cx, 320 + mov di, MOD_BUFFER + mov ax, 8080h + rep stosw + mov cx, 0A000h + mov es, cx + call ScopeLoop + pop es + + ; load 2048 bytes into buffer 1 + mov si, [DMA_BUFFER1] + ; 11/05/2024 + ;mov cx, BUFFERSIZE + ;push ds ; segment + ;push si ; offset + ;push cx ; count + call GetSamples_ICH ; 18/02/2017 + + ; load 2048 bytes into buffer 2 + mov si, [DMA_BUFFER2] + ; 11/05/2024 + ;mov cx, BUFFERSIZE + ;push ds ; segment + ;push si ; offset + ;push cx ; count + call GetSamples_ICH ; 18/02/2017 + +; register reset the DMA engine. This may cause a pop noise on the output +; lines when the device is reset. Prolly a better idea to mute output, then +; reset. + + ; 08/05/2024 + ;mov dx, [NABMBAR] + ;add dx, PO_CR_REG ; set pointer to Ctrl reg + ;mov al, RR ; set reset + ;out dx, al ; self clearing bit + +; write last valid index to 31 to start with. +; The Last Valid Index register tells the DMA engine when to stop playing. +; +; As we progress through the song we change the last valid index to always be +; something other than the index we're currently playing. +; + ;;mov al, 1 + ;mov al, 31 + ;call setLastValidIndex + +; create Buffer Descriptor List +; +; A buffer descriptor list is a list of pointers and control bits that the +; DMA engine uses to know where to get the .wav data and how to play it. +; +; I set it up to use only 2 buffers of .wav data, and whenever 1 buffer is +; playing, I refresh the other one with good data. +; +; +; For the control bits, you can specify that the DMA engine fire an interrupt +; after a buffer has been processed, but I poll the current index register +; to know when it's safe to update the other buffer. +; +; I set the BUP bit, which tells the DMA engine to just play 0's (silence) +; if it ever runs out of data to play. Good for safety. +; + ; 14/02/2017 + mov di, [BDL_BUFFER] ; get BDL address + mov cx, 32 / 2 ; make 32 entries in BDL + xor edx, edx + mov dx, ds + shl edx, 4 ; segment*16 (linear/physical address of the segment) +_0: + +; set buffer descriptor 0 to start of data file in memory + ; 14/02/2017 + movzx eax, word [DMA_BUFFER1] + add eax, edx ; linear/physical address of the buffer (seg*16+off) + stosd ; store dmabuffer1 address + +; +; set length to 32k samples. 1 sample is 16bits or 2bytes. +; Set control (bits 31:16) to BUP, bits 15:0=number of samples. +; + +; 17/02/2017 (Erdogan Tan) +; Intel® 82801AA (ICH) & Intel® 82801AB (ICH0) I/O Controller Hub AC ’97 +; Programmer’s Reference Manual + +; 2.2.1 Buffer Descriptor List (on Page 13) + ; + ; Generic Form of Buffer Descriptor + ; --------------------------------- + ; 63 62 61-48 47-32 31-0 + ; --- --- -------- ------- ----- + ; IOC BUP -reserved- Buffer Buffer + ; Length Pointer + ; [15:0] [31:0] + ; + ; IOC: Interrupt On Completion. + ; 1 = Enabled. + ; When this is set, it means that the controller should + ; issue an interrupt upon completion of this buffer. + ; It should also set the IOC bit in the status register + ; 0 = Disabled + ; + ; BUP: Buffer Underrun Policy. + ; 0 = When this buffer is complete, + ; if the next buffer is not yet ready + ; (i.e., the last valid buffer has been processed), + ; then continue to transmit the last valid sample. + ; 1 = When this buffer is complete, + ; if this is the last valid buffer, transmit zeros after + ; this buffer has been processed completely. + ; This bit typically is set only if this is the last + ; buffer in the current stream. + ; + ; [31:0]: Buffer pointer. This field points to the location of + ; the data buffer. Since samples can be as wide as one + ; word, the buffer must be aligned with word boundaries, + ; to prevent samples from straddling DWord boundaries. + ; + ; [15:0]: Buffer Length: This is the length of the data buffer, + ; in number of samples. The controller uses this data + ; to determine the length of the buffer, in bytes. + ; "0" indicates no sample to process. + +; ICH2AC97.INC + +; IOC equ BIT31 ; Fire an interrupt whenever this + ; buffer is complete. + +; BUP equ BIT30 ; Buffer Underrun Policy. + ; if this buffer is the last buffer + ; in a playback, fill the remaining + ; samples with 0 (silence) or not. + ; It's a good idea to set this to 1 + ; for the last buffer in playback, + ; otherwise you're likely to get a lot + ; of noise at the end of the sound. +; +; Bits 15:0 contain the length of the buffer, in number of samples, which +; are 16 bits each, coupled in left and right pairs, or 32bits each. +; Luckily for us, that's the same format as .wav files. +; +; A value of FFFF is 65536 samples. Running at 44.1Khz, that's just about +; 1.5 seconds of sample time. FFFF * 32bits is 1FFFFh bytes or 128k of data. +; +; A value of 0 in these bits means play no samples. +; + ; 08/12/2016 - Erdogan Tan + ;mov eax, BUFFERSIZE + ;or eax, IOC + BUP + ; 12/05/2024 + mov eax, BUFFERSIZE/2 + or eax, BUP ; (tuneloop without interrupt) + stosd + +; 2nd buffer: + ; 14/02/2017 + movzx eax, word [DMA_BUFFER2] + add eax, edx ; linear/physical address of the buffer (seg*16+off) + stosd ; store dmabuffer2 address + +; set length to 64k (32k of two 16 bit samples) +; Set control (bits 31:16) to BUP, bits 15:0=number of samples +; + ; 08/12/2016 - Erdogan Tan + ;mov eax, BUFFERSIZE + ;or eax, IOC + BUP + ; 12/05/2024 + mov eax, BUFFERSIZE/2 + ; 12/05/2024 + or eax, BUP ; (tuneloop without interrupt) + stosd + loop _0 + +; +; tell the DMA engine where to find our list of Buffer Descriptors. +; this 32bit value is a flat mode memory offset (ie no segment:offset) +; +; write NABMBAR+10h with offset of buffer descriptor list +; + movzx eax, word [BDL_BUFFER] + ; 14/02/2017 + add eax, edx ; linear/physical address of the BDL + ; 18/02/2017 + mov dx, [NABMBAR] + add dx, PO_BDBAR_REG ; set pointer to BDL + out dx, eax ; write to AC97 controller + +; +; All set. Let's play some music. +; + ; 08/12/2016 + ; 07/10/2016 + ;mov al, 1 + mov al, 31 + ; 08/05/2024 + mov [LVI], al ; 10/11/2023 + + call setLastValidIndex + + mov byte [tLoop], 1 ; 30/11/2016 + +; 13/11/2024 ('%if' -> 'if' conversion for FASM) +; 12/05/2024 (tuneloop, without interrupt) +;%if 0 +if 0 + ; 12/05/2024 + ; 17/02/2017 + ;mov dx, [NABMBAR] + ;add dx, PO_CR_REG ; PCM out Control Register + ;mov al, IOCE + RPBM ; Enable 'Interrupt On Completion' + run + ; ; (LVBI interrupt will not be enabled) + ;out dx, al ; Start bus master operation. + +; while DMA engine is running, examine current index and wait until it hits 1 +; as soon as it's 1, we need to refresh the data in wavbuffer1 with another +; 64k. Likewise when it's playing buffer 2, refresh buffer 1 and repeat. + + ; 18/02/2017 + ; 14/02/2017 + ; 13/02/2017 + ; 08/12/2016 + ; 28/11/2016 + + push es + mov ax, 0A000h + mov es, ax + ;mov bp, DmaBuffer ; 14/02/2017 +p_loop: + mov ah, 1 ; any key pressed? + int 16h ; no, Loop. + jz short q_loop + + mov ah, 0 ; flush key buffer... + int 16h +p_return: + mov byte [tLoop], 0 ; 13/02/2017 + pop es + retn +q_loop: + ; 10/05/2024 + xor ax, ax + xchg al, [tBuff] ; AL = [tBuff], [tBuff] = 0 + cmp al, 1 + ja short r_loop + jb short ScopeLoop + ; + mov si, [DMA_BUFFER1] ; [tBuff]=1 (from tuneLoop) + jmp short s_loop +r_loop: + ; 13/02/2017 + mov si, [DMA_BUFFER2] ; [tBuff]=2 (from tuneLoop) +s_loop: + ; 14/02/2017 + ;mov bp, si ; save current buffer addres in bp register + ; 11/05/2024 + ;mov cx, BUFFERSIZE ; 2048*4 byte + ;push ds ; segment + ;push si ; offset + ;push cx ; count + call GetSamples_ICH ; 18/02/2017 + ; +ScopeLoop: + ;mov si, bp ; get current samples + mov si, MOD_BUFFER ; 18/02/2017 + xor cx, cx ; to be drawed ... + xor dx, dx +DrawLoop: + mov bx, dx ; (save Index) + mov di, [Scope+bx] ; get old SCOPE pixel address + mov byte [es:di], 0 ; erase it! + lodsb ; get a sample (8-bit) + mov bl, al ; calc new pixel address... + xor bh, bh + shl bx, 1 + mov di, [RowOfs+bx] + add di, cx + mov bx, dx ; (restore Index) + mov [Scope+bx], di ; save new address... + mov byte [es:di], 10 ; 0Ah ; and DRAW. + add dx, 2 ; the next pixel... + inc cx + cmp cx, 320 ; 320 pixels drawed? + jb short DrawLoop + jmp short p_loop + +tuneLoop: + ; 11/05/2024 + ; 11/11/2023 + ; 10/11/2023 + ; 18/02/2017 + ; 08/12/2016 + ; 28/11/2016 - Erdogan Tan + + ; 11/05/2024 + cmp byte [tLoop], 1 + jb short tL3 + + call getCurrentIndex + + ; 10/11/2023 + cmp al, [LVI] + jne short tL1 + + dec ax + and al, 1Fh + call setLastValidIndex + xchg al, [LVI] +tL1: + test al, BIT0 + jz short tL2 + + ; 11/05/2024 + mov byte [tBuff], 1 + retn +tL2: + mov byte [tBuff], 2 +tL3: + retn + +; returns AL = current index value +getCurrentIndex: + ;push dx + mov dx, [NABMBAR] + add dx, PO_CIV_REG + in al, dx + ;pop dx + retn + +;input AL = index # to stop on +setLastValidIndex: + ;push dx + mov dx, [NABMBAR] + add dx, PO_LVI_REG + out dx, al + ;pop dx + retn +;%else +else + ; 12/05/2024 + ; 17/02/2017 + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + ;mov al, IOCE + RPBM ; Enable 'Interrupt On Completion' + run + ; ; (LVBI interrupt will not be enabled) + ; 06/11/2023 (TUNELOOP version, without interrupt) + mov al, RPBM + out dx, al ; Start bus master operation. + + push es + mov ax, 0A000h + mov es, ax + + ; 12/05/2024 +;p_loop: +; call tuneLoop +; cmp byte [tLoop], 0 +; ja short p_loop +; pop es +; retn + +p_loop: + mov ah, 1 ; any key pressed? + ;mov ah, 11h + int 16h ; no, Loop. + jz short q_loop + + mov ah, 0 + ;mov ah, 10h ; flush key buffer... + int 16h + + ; 12/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + cmp al, 0 + jna short q_loop + dec al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_return + + mov al, [volume] + cmp al, 31 + jnb short q_loop + inc al +p_2: + mov [volume], al + mov ah, al + mov dx, [NAMBAR] + ;add dx, CODEC_MASTER_VOL_REG + add dx, CODEC_PCM_OUT_REG + out dx, ax + + ; 12/05/2024 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + jmp short q_loop + +p_return: + pop es + retn +q_loop: +tuneLoop: + ; 12/05/2024 + ; 18/11/2023 (ich_wav4.asm, Erdogan Tan) +tL1: + call updateLVI ; /set LVI != CIV/ + ;call check4keyboardstop + ;jc short _exit_ + call getCurrentIndex + test al, BIT0 + jz short tL1 ; loop if buffer 2 is not playing + + mov si, [DMA_BUFFER1] + call GetSamples_ICH + + call ScopeLoop +tL2: + call updateLVI + ;call check4keyboardstop + ;jc short _exit_ + call getCurrentIndex + test al, BIT0 + jnz short tL2 ; loop if buffer 1 is not playing + + mov si, [DMA_BUFFER2] + call GetSamples_ICH + + call ScopeLoop + jmp short p_loop + +ScopeLoop: + ;mov si, bp ; get current samples + mov si, MOD_BUFFER ; 18/02/2017 + xor cx, cx ; to be drawed ... + xor dx, dx +DrawLoop: + mov bx, dx ; (save Index) + mov di, [Scope+bx] ; get old SCOPE pixel address + mov byte [es:di], 0 ; erase it! + ;lodsb ; get a sample (8-bit) + ; 14/05/2024 + lodsw + mov bl, al ; calc new pixel address... + xor bh, bh + shl bx, 1 + mov di, [RowOfs+bx] + add di, cx + mov bx, dx ; (restore Index) + mov [Scope+bx], di ; save new address... + mov byte [es:di], 10 ; 0Ah ; and DRAW. + add dx, 2 ; the next pixel... + inc cx + cmp cx, 320 ; 320 pixels drawed? + jb short DrawLoop + retn + +;_exit_: + ;mov byte [tLoop], 0 + ;retn + + ; 12/05/2024 +updateLVI: + ; 06/11/2023 + mov dx, [NABMBAR] + add dx, PO_CIV_REG + ; (Current Index Value and Last Valid Index value) + in ax, dx + + cmp al, ah ; is current index = last index ? + jne short uLVI_exit ; 12/05/2024 + + ; 08/11/2023 + call getCurrentIndex + + dec al + and al, 1Fh + +;input AL = index # to stop on +setLastValidIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_LVI_REG + out dx, al + ;pop dx +uLVI_exit: ; 12/05/2024 + retn + +; returns AL = current index value +getCurrentIndex: + ;push dx + mov dx, [NABMBAR] + add dx, PO_CIV_REG + in al, dx + ;pop dx + retn + + ; 12/05/2024 +check4keyboardstop: + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + jz short _cksr + xor ah, ah + int 16h + stc +_cksr: + retn +;%endif +end if + +;============================================================================= +; MODLOAD.ASM +;============================================================================= + +; Amiga Module Loader v0.1b by Carlos Hasan. +; July 10th, 1993. + +; STRUCTURES + +; 13/11/2024 ('resb','resw,'resd' to 'rb','rw','rd' conversions for FASM) + +;struc ModSample +struc _ModSample +{ +.msName rb 22 +.msLength: rw 1 +.msFinetune: rb 1 +.msVolume: rb 1 +.msRepeat: rw 1 +.msRepLen: rw 1 +.size: +;endstruc +} + +; 13/11/2024 +virtual at 0 + ModSample _ModSample + sizeof.ModSample = $ +end virtual + +;struc ModHeader +struc _ModHeader +{ +.mhName: rb 20 +.mhSamples: rb sizeof.ModSample*31 +.mhOrderLen: rb 1 +.mhReStart: rb 1 +.mhOrder: rb 128 +.mhSign: rw 2 +.size: +;endstruc +} + +; 13/11/2024 +virtual at 0 + ModHeader _ModHeader + sizeof.ModHeader = $ +end virtual + +;struc ModInfoRec +struc _ModInfoRec +{ +.OrderLen: rb 1 +.ReStart: rb 1 +.Order: rb 128 +.Patterns: rd 1 +.SampOfs: rw 31 +.SampSeg: rw 31 +.SampLen: rw 31 +.SampRep: rw 31 +.SampRepLen: rw 31 +.SampVol: rw 31 +.size: +;endstruc +} + +; 13/11/2024 +virtual at 0 + ModInfoRec _ModInfoRec + sizeof.ModInfoRec = $ +end virtual + +; CODE + +LoadModule: + ;es:di = filename + + ;[sp+4] = es + ;[sp+2] = di + + FileName equ 4 + + push bp + mov bp, sp + pusha + push ds + push es + + mov word [ErrorInfo], 1 + + call ClearModInfo +OpenFile: + push ds + mov ax, 3D00h + lds dx, [bp+FileName] + int 21h + pop ds + jc Failed + mov [FileHandle], ax + +ReadHeader: + mov ax, 3F00h + mov bx, [FileHandle] + ;mov cx, ModHeader.size + ; 13/11/2024 + mov cx, sizeof.ModHeader + ;lea dx, [Header] + mov dx, Header + int 21h + jc CloseFile +CheckMK: + cmp word [Header+ModHeader.mhSign], 'M.' + jne short CheckFLT4 + cmp word [Header+ModHeader.mhSign+2], 'K.' + je short IsModFile +CheckFLT4: + cmp word [Header+ModHeader.mhSign], 'FL' + jne short Is15Inst + cmp word [Header+ModHeader.mhSign+2], 'T4' + je short IsModFile +Is15Inst: + ;mov si, (Header+ModHeader.mhSamples) + (15*ModSample.size) + ; 13/11/2024 + mov si, (Header+ModHeader.mhSamples) + (15*sizeof.ModSample) + mov di, Header+ModHeader.mhOrderLen + mov ax, ds + mov es, ax + cld + mov cx, 130 + rep movsb + ;mov di, Header+ModHeader.mhSamples + (15*ModSample.size) + ; 13/11/2024 + mov di, Header+ModHeader.mhSamples + (15*sizeof.ModSample) + xor ax, ax + ;mov cx, 16*ModSample.size + ; 13/11/2024 + mov cx, 16*sizeof.ModSample + rep stosb +SeekPatterns: + mov ax, 4200h + mov bx, [FileHandle] + mov cx, 0 + mov dx, 600 + int 21h +IsModFile: + mov al, [Header+ModHeader.mhOrderLen] + mov [ModInfo.OrderLen], al + + mov al, [Header+ModHeader.mhReStart] + cmp al, [Header+ModHeader.mhOrderLen] + jb short SetReStart + mov al, 7Fh +SetReStart: + mov [ModInfo.ReStart], al + + mov cx, 128 + xor ax, ax + xor bx, bx +CopyOrder: + mov ah, [Header+ModHeader.mhOrder+bx] + mov [ModInfo.Order+bx], ah + cmp ah, al + jb short NextOrder + mov al, ah +NextOrder: + inc bx + loop CopyOrder +AllocPatterns: + ; Erdogan Tan (13/02/2017) + xor ah, ah + inc al + ; al = count of 1024 bytes + mov bx, ax + ; count of paragraphs = al*64 + shl ax, 6 ; *64 + mov bp, ax + mov dx, cs ; current (code) segment + add dx, 1000h ; next 64K (4096*16) + ; + mov word [ModInfo.Patterns], 0 + mov [ModInfo.Patterns+2], dx + ; + add bp, dx ; next segment for samples +ReadPatterns: + push ds + mov ax, 3F00h + mov cx, bx ; count of 1024 bytes + shl cx, 10 ; byte count (cx*1024) + mov bx, [FileHandle] + ;lds dx, [ModInfo.Patterns] + mov ds, dx + xor dx, dx + int 21h + pop ds + jc CloseFile + + ;lea si, [Header+ModHeader.mhSamples] + mov si, Header+ModHeader.mhSamples + xor di, di +CopySamples: + mov ax, [si+ModSample.msLength] + xchg al, ah + shl ax, 1 + mov [ModInfo.SampLen+di], ax + mov al, [si+ModSample.msVolume] + xor ah, ah + mov [ModInfo.SampVol+di], ax + mov ax, [si+ModSample.msRepeat] + xchg al, ah + shl ax, 1 + mov [ModInfo.SampRep+di], ax + mov ax, [si+ModSample.msRepLen] + xchg al, ah + shl ax, 1 + mov [ModInfo.SampRepLen+di], ax + ;add si, ModSample.size + ; 13/11/2024 + add si, sizeof.ModSample + add di, 2 + cmp di, 2*31 + jb short CopySamples + + xor si, si +AllocSamples: + ; Erdogan Tan (13/02/2017) + ;mov bx, [ModInfo.SampLen+si] + mov cx, [ModInfo.SampLen+si] + mov bx, cx + shr bx, 4 ; byte count / 16 + jz short NextSample + inc bx ; number of paragraphs + mov word [ModInfo.SampOfs+si], 0 + mov [ModInfo.SampSeg+si], bp + mov dx, bp + add bp, bx ; next segment for sample +ReadSample: + push ds + mov ax, 3F00h + mov bx, [FileHandle] + ;mov cx, [ModInfo.SampLen+si] + ;mov dx, [ModInfo.SampOfs+si] + ;mov ds, [ModInfo.SampSeg+si] + mov ds, dx + xor dx, dx + int 21h + pop ds + jc short CloseFile +NextSample: + add si, 2 + cmp si, 2*31 + jb short AllocSamples + + mov word [ErrorInfo], 0 +CloseFile: + mov ax, 3E00h + mov bx, [FileHandle] + int 21h +Failed: + pop es + pop ds + popa + pop bp + ret 4 + +FreeModule: + ; Erdogan Tan (13/02/2017) + ; nothing to do here for memory de-allocation +ClearModInfo: + pusha + push es + mov ax, ds + mov es, ax + ;lea di, [ModInfo] + mov di, ModInfo + ;mov cx, ModInfoRec.size + ; 13/11/2024 + mov cx, sizeof.ModInfoRec + cld + xor ax, ax + rep stosb + pop es + popa + retn + +;============================================================================= +; MODPLAY.ASM +;============================================================================= + +; Amiga Module Player v0.3b by Carlos Hasan. +; July 23th, 1993. + +; EQUATES + +NumTracks equ 4 +DefTempo equ 6 +DefBpm equ 125 +MidCRate equ 8448 +MixBufSize equ 4096 + +; STRUCTURES + +; 13/11/2024 ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +;struc TrackInfo +struc _TrackInfo +{ +.Samples: rd 1 +.Position: rw 1 +.Len: rw 1 +.Repeat: rw 1 +.RepLen: rw 1 +.Volume: rb 1 +.Error: rb 1 +.Period: rw 1 +.Pitch: rw 1 +.Effect: rw 1 +.PortTo: rw 1 +.PortParm: rb 1 +.VibPos: rb 1 +.VibParm: rb 1 +.OldSampOfs: rb 1 +.Arp: rw 3 +.ArpIndex: rw 1 +.size: +;endstruc +} + +; 13/11/2024 +virtual at 0 + TrackInfo _TrackInfo + sizeof.TrackInfo = $ +end virtual + +; CODE + +;-------------------------------------------------------------------------- +; BeatTrack: Process the next beat in one track. +; In: +; ds:di - Track info Address. +;-------------------------------------------------------------------------- + +BeatTrack: + mov dx, [di+TrackInfo.Effect] + test dx, dx + je short None + cmp dh, 00h + je short Arpeggio + cmp dh, 01h + je short PortUp + cmp dh, 02h + je short PortDown + cmp dh, 03h + je short TonePort + cmp dh, 04h + je Vibrato + cmp dh, 05h + je PortSlide + cmp dh, 06h + je VibSlide + cmp dh, 0Ah + je VolSlide +None: + retn +Arpeggio: + mov bx, [di+TrackInfo.ArpIndex] + mov ax, [di+TrackInfo.Arp+bx] + mov [di+TrackInfo.Pitch], ax + add bx, 2 + cmp bx, 6 + jb short SetArpIndex + xor bx,bx +SetArpIndex: + mov [di+TrackInfo.ArpIndex], bx + retn +PortUp: + xor dh, dh + mov bx, [di+TrackInfo.Period] + sub bx, dx + cmp bx, 113 + jge short NotSmall + mov bx, 113 +NotSmall: + mov [di+TrackInfo.Period], bx + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Pitch], ax + retn +PortDown: + xor dh, dh + mov bx, [di+TrackInfo.Period] + add bx, dx + cmp bx, 856 + jle short NotBig + mov bx, 856 +NotBig: mov [di+TrackInfo.Period], bx + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Pitch], ax + retn +TonePort: + xor dh, dh + mov ax, [di+TrackInfo.PortTo] + mov bx, [di+TrackInfo.Period] + cmp bx, ax + je short NoPort + jg short PortToUp +PortToDown: + add bx, dx + cmp bx, ax + jle short SetPort +FixPort: + mov bx, ax + jmp short SetPort +PortToUp: + sub bx, dx + cmp bx, ax + jl short FixPort +SetPort: + mov [di+TrackInfo.Period], bx + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Pitch], ax +NoPort: + retn +Vibrato: + mov dh, dl + and dl, 0Fh + shr dh, 4 + shl dh, 2 + add [di+TrackInfo.VibPos], dh + mov dh, [di+TrackInfo.VibPos] + mov bl, dh + shr bl, 2 + and bx, 1Fh + mov al, [SinTable+bx] + mul dl + rol ax, 1 + xchg al, ah + and ah, 1 + test dh, dh + jns short VibUp + neg ax +VibUp: + add ax, [di+TrackInfo.Period] + mov bx, ax + cmp bx, 113 + jge short NoLoVib + mov bx, 113 +NoLoVib: + cmp bx, 856 + jle short NoHiVib + mov bx, 856 +NoHiVib: + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Pitch], ax + retn +PortSlide: + call VolSlide + mov dl, [di+TrackInfo.PortParm] + jmp short TonePort +VibSlide: + call VolSlide + mov dl, [di+TrackInfo.VibParm] + jmp short Vibrato +VolSlide: + mov dh, dl + and dl, 0Fh + shr dh, 4 + mov al, [di+TrackInfo.Volume] + sub al, dl + jge short NoLoVol + xor al, al +NoLoVol: + add al, dh + cmp al, 64 + jbe short NoHiVol + mov al, 64 +NoHiVol: + mov [di+TrackInfo.Volume], al + retn + +;-------------------------------------------------------------------------- +; GetTrack: Get the next Note from a pattern. +; In: +; ds:di - Track info Address. +; es:si - Pattern Note Address. +; Out: +; es:si - The Next Pattern Note address. +;-------------------------------------------------------------------------- + +GetTrack: + es lodsw + xchg al, ah + mov bl, ah + and ah, 0Fh + mov cx, ax + es lodsw + xchg al, ah + mov bh, ah + and ah, 0Fh + mov dx, ax + mov [di+TrackInfo.Effect], dx + and bl, 0F0h + shr bh, 4 + or bl, bh + je short SetPeriod +SetSample: + xor bh, bh + dec bx + add bx, bx + mov ax, [ModInfo.SampVol+bx] + mov [di+TrackInfo.Volume], al + mov ax, [ModInfo.SampOfs+bx] + mov [di+TrackInfo.Samples], ax + mov ax, [ModInfo.SampSeg+bx] + mov [di+TrackInfo.Samples+2], ax + mov ax, [ModInfo.SampLen+bx] + mov [di+TrackInfo.Len], ax + mov ax, [ModInfo.SampRep+bx] + mov [di+TrackInfo.Repeat], ax + mov ax, [ModInfo.SampRepLen+bx] + mov [di+TrackInfo.RepLen], ax +SetPeriod: + test cx, cx + je short SetEffect + + mov [di+TrackInfo.PortTo], cx + cmp dh, 03h + je short SetEffect + + mov [di+TrackInfo.Period], cx + mov bx, cx + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Pitch], ax + mov word [di+TrackInfo.Position], 0 +SetEffect: + test dx, dx + je short InitNone + cmp dh, 00h + je InitArpeggio + cmp dh, 03h + je short InitTonePort + cmp dh, 04h + je short InitVibrato + cmp dh, 09h + je short SampleOfs + cmp dh, 0Bh + je short PosJump + cmp dh, 0Ch + je short SetVolume + cmp dh, 0Dh + ;je short Break + je short _Break ; 13/11/2024 (FASM modification) + cmp dh, 0Fh + je short SetSpeed +InitNone: + retn +InitTonePort: + test dl, dl + jne short SetPortParm + mov dl, [di+TrackInfo.PortParm] +SetPortParm: + mov [di+TrackInfo.PortParm], dl + mov [di+TrackInfo.Effect], dx + retn +InitVibrato: + mov al, [di+TrackInfo.VibParm] + mov ah, al + and al, 0Fh + and ah, 0F0h + test dl, 0Fh + jne short OkDepth + or dl, al +OkDepth: + test dl, 0F0h + jne short OkRate + or dl, ah +OkRate: + mov [di+TrackInfo.VibParm], dl + mov [di+TrackInfo.Effect], dx + test cx, cx + je short OkPos + mov byte [di+TrackInfo.VibPos], 0 +OkPos: + retn +SampleOfs: + test dl, dl + jne short SetSampleOfs + mov dl, [di+TrackInfo.OldSampOfs] +SetSampleOfs: + mov [di+TrackInfo.OldSampOfs], dl + mov dh, dl + xor dl, dl + mov [di+TrackInfo.Position], dx + retn +PosJump: + mov [OrderPos], dl + mov byte [Row], 64 + retn +SetVolume: + cmp dl, 64 + jbe short OkVol + mov dl, 64 +OkVol: + mov [di+TrackInfo.Volume], dl + retn +;Break: + ; 13/11/2024 +_Break: + mov dh, dl + and dl, 0Fh + shr dh, 4 + add dh, dh + add dl, dh + shl dh, 2 + add dl, dh + mov [BreakRow], dl + mov byte [Row], 64 + retn +SetSpeed: + test dl,dl + je Skip + cmp dl,31 + ja short SetBpm +SetTempo: + mov [Tempo], dl + mov [TempoWait], dl + retn +SetBpm: + mov [Bpm], dl + mov al, 103 + mul dl + mov bl, ah + xor bh, bh + mov ax, [MixSpeed] + xor dx, dx + div bx + mov [BpmSamples], ax +Skip: + retn +InitArpeggio: + mov dh, dl + and dl, 0Fh + shr dh, 4 + mov cx, 36 + xor bx, bx + mov ax, [di+TrackInfo.Period] +gt_ScanPeriod: + cmp ax, [PeriodTable+bx] + jae short SetArp + add bx, 2 + loop gt_ScanPeriod +SetArp: + add dx, dx + add dh, bl + add dl, bl + mov bx, [PeriodTable+bx] + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Arp], ax + mov bl, dh + xor bh, bh + mov bx, [PeriodTable+bx] + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Arp+2], ax + mov bl, dl + xor bh, bh + mov bx, [PeriodTable+bx] + add bx, bx + mov ax, [PitchTable+bx] + mov [di+TrackInfo.Arp+4], ax + mov word [di+TrackInfo.ArpIndex], 0 + retn + +;-------------------------------------------------------------------------- +; UpdateTracks: Main code to process the next tick to be played. +;-------------------------------------------------------------------------- + +UpdateTracks: + dec byte [TempoWait] + jz short GetTracks + + mov cx, NumTracks + mov di, Tracks +BeatTracks: + call BeatTrack + ;add di, TrackInfo.size + ; 13/11/2024 + add di, sizeof.TrackInfo + loop BeatTracks + retn +GetTracks: + mov al, [Tempo] + mov [TempoWait], al + + les si, [Note] + cmp byte [Row], 64 + jb short NoPattWrap + + les si, [ModInfo.Patterns] + mov bl, [OrderPos] + cmp bl, [ModInfo.OrderLen] + jb short NoOrderWrap + mov bl, [ModInfo.ReStart] + mov [OrderPos], bl + cmp bl, [ModInfo.OrderLen] + jae short NoUpdate +NoOrderWrap: + xor bh, bh + mov bl, [ModInfo.Order+bx] + shl bx, 10 + add si, bx + mov bl, [BreakRow] + mov [Row], bl + xor bh, bh + mov [BreakRow], bh + shl bx, 4 + add si, bx + mov [Note], si + mov [Note+2], es + inc byte [OrderPos] +NoPattWrap: + inc byte [Row] + + cld + mov cx, NumTracks + mov di, Tracks +GetTracks_next: + push cx + call GetTrack + pop cx + ;add di, TrackInfo.size + ; 13/11/2024 + add di, sizeof.TrackInfo + loop GetTracks_next + + mov [Note], si +NoUpdate: + retn + +;-------------------------------------------------------------------------- +; MixTrack: Mixes one track into a CLEAN buffer. +; In: +; ds:si - Track Info Address. +; ds:di - Buffer Address. +; cx - Buffer Size. +;-------------------------------------------------------------------------- + +MixTrack: + cmp word [si+TrackInfo.RepLen], 2 + ja short MixLooped +MixNonLooped: + les dx, [si+TrackInfo.Samples] + mov bx, [si+TrackInfo.Position] + mov bp, [si+TrackInfo.Len] + push dx + push si + add bx, dx + add bp, dx + mov dx, [si+TrackInfo.Pitch] + mov al, [si+TrackInfo.Volume] + mov ah, [si+TrackInfo.Error] + mov si, bx + mov bh, al + mov al, dl + mov dl, dh + xor dh, dh +nlMixSamp: + cmp si, bp + jae short nlMixBye + mov bl, [es:si] + mov bl, [VolTable+bx] + add [di], bl + inc di + add ah, al + adc si, dx + loop nlMixSamp +nlMixBye: + mov bx, si + pop si + pop dx + sub bx, dx + mov [si+TrackInfo.Position], bx + mov [si+TrackInfo.Error], ah + retn +MixLooped: + les dx, [si+TrackInfo.Samples] + mov bx, [si+TrackInfo.Position] + mov bp, [si+TrackInfo.RepLen] + mov [BufRep], bp + add bp, [si+TrackInfo.Repeat] + push dx + push si + add bx, dx + add bp, dx + mov dx, [si+TrackInfo.Pitch] + mov al, [si+TrackInfo.Volume] + mov ah, [si+TrackInfo.Error] + mov si, bx + mov bh, al + mov al, dl + mov dl, dh + xor dh, dh +lpMixSamp: + cmp si, bp + jb short lpMixNow + sub si, [BufRep] +lpMixNow: + mov bl, [es:si] + mov bl, [VolTable+bx] + add [di], bl + inc di + add ah, al + adc si, dx + loop lpMixSamp +lpMixBye: + mov bx, si + pop si + pop dx + sub bx, dx + mov [si+TrackInfo.Position], bx + mov [si+TrackInfo.Error], ah + retn + +GetSamples_ICH: + ; 11/05/2024 + ; 18/02/2017 + ; 8 bit mono samples + ; must be converted to 16 bit, stereo samples (for ICH) ! + ; (ICH AC97 Modification by Erdogan Tan) + mov [_si_], si ; DMA Buff Addr, [DMA_BUFFER1] or [DMA_BUFFER2] + ; 11/05/2024 + ;mov si, MOD_BUFFER + ;shr cx, 2 ; mod buffer size = dma (half) buffer size / 4 (*) + +;-------------------------------------------------------------------------- +; GetSamples: Returns the next chunk of samples to be played. +; In: +; Buffer - Buffer Address. +; Count - Buffer Size. +;-------------------------------------------------------------------------- + +GetSamples: + ;ds:si = buffer address + ;cx = count + + ; 11/05/2024 + ; + ;;[sp+6] = ds + ;;[sp+4] = si + ;;[sp+2] = count + ; + ;Count equ 4 + ;Buffer equ 6 + ; + ;push bp + ;mov bp, sp + ; + ;push es + ;;;push ds + ;;;pusha + ; + ;cld + ; + ;les di, [bp+Buffer] + ;mov bx, [bp+Count] + + ; 11/05/2024 + ; ds = cs + push es ; + + + push ds + pop es + + ; 11/05/2024 + mov di, MOD_BUFFER + mov bx, (BUFFERSIZE/4) ; (*) ; 2048 +NextChunk: + cmp word [BufLen], 0 + jne short CopyChunk + + ; 11/05/2024 + push es + push bx + push di +MixChunk: + ;lea di, [MixBuffer] + mov di, MixBuffer + mov cx, [BpmSamples] + mov [BufPtr], di + mov [BufLen], cx + + ; 12/05/2024 + ; es = ds + ;mov ax, ds + ;mov es, ax + + mov al, 80h + rep stosb + + mov cx, NumTracks + ;mov si, Tracks - TrackInfo.size + ; 13/11/2024 + mov si, Tracks - sizeof.TrackInfo +GetSamples_next: + push cx + ;add si, TrackInfo.size + ; 13/11/2024 + add si, sizeof.TrackInfo + mov cx, [BufLen] + mov di, [BufPtr] + call MixTrack + pop cx + loop GetSamples_next + + call UpdateTracks + + pop di + pop bx + pop es ; es = ds ; 12/05/2024 +CopyChunk: + mov cx, [BufLen] + cmp cx, bx + jbe short MoveChunk + mov cx, bx +MoveChunk: + mov si, [BufPtr] + add [BufPtr], cx + sub [BufLen], cx + sub bx, cx + rep movsb + test bx, bx + jnz short NextChunk + + ;;popa + ;;pop ds + ;pop es + ;pop bp + ;ret 6 + +; GetSamples_ICH_convert_samples: + ; 11/05/2024 + ; es = ds = cs + ; 18/02/2017 + ;mov di, ds + ;mov es, di + mov di, [_si_] ; DMA Buffer Address (16 bit, stereo) + mov si, MOD_BUFFER - 1 ; buffer for 8 bit mono samples + mov cx, (BUFFERSIZE/4) ; (*) ; 2048 ; 11/04/2024 + xor al, al +gscs_loop: + inc si + mov ah, [si] ; convert 8 bit sample to 16 bit sample + ; 11/05/2024 + sub ah, 80h + + stosw ; left channel + stosw ; right channel + loop gscs_loop + + ; 11/05/2024 + pop es ; + + ;pop bp + ;ret 6 + retn + +;-------------------------------------------------------------------------- +; StartPlaying: Initializes the Sound System. +; In: +; Module Information Resources. +;-------------------------------------------------------------------------- + +StartPlaying: + pusha + push ds + push es +SetModParms: + mov byte [OrderPos], 0 + mov byte [Tempo], DefTempo + mov byte [TempoWait], DefTempo + mov byte [Bpm], DefBpm + mov byte [Row], 64 + mov byte [BreakRow], 0 + mov ax, [MixSpeed] + xor dx, dx + mov bx, 24*DefBpm/60 + div bx + mov [BpmSamples], ax +ClearTracks: + mov di, Tracks + mov ax, ds + mov es, ax + ;mov cx, NumTracks*TrackInfo.size + ; 13/11/2024 + mov cx, NumTracks*sizeof.TrackInfo + xor ax, ax + cld + rep stosb + + mov [BufPtr], ax + mov [BufLen], ax +MakePitch: + mov ax, MidCRate + mov bx, 428 + mul bx + div word [MixSpeed] + xor dh, dh + mov dl, ah + mov ah, al + xor al, al + mov cx, 857 + xor bx, bx + mov di, PitchTable +PitchLoop: + push ax + push dx + cmp dx, bx + jae short NoDiv + div bx +NoDiv: + stosw + pop dx + pop ax + inc bx + loop PitchLoop +MakeVolume: + mov cx, 16640 + mov bx, cx +VolLoop: + dec bx + mov al, bl + imul bh + mov [VolTable+bx], ah + loop VolLoop + + pop es + pop ds + popa + retn ; 12/05/2024 + +;-------------------------------------------------------------------------- +; StopPlaying: ShutDown the Sound System. +;-------------------------------------------------------------------------- + +StopPlaying: + ; 08/05/2024 + ; 04/11/2023 + ; finished with song, stop everything + call ac97_stop + +; 13/11/2024 ('%if' -> 'if' conversion for FASM) +; 12/05/2024 (tuneloop version) +;%if 0 +if 0 + ; 11/11/2023 +irq_restore: + ; restore previous interrupt vector and interrupt_status + cli + in al, 0A1h ; irq 8-15 + mov al, [IRQ_status+1] + out 0A1h, al + in al, 021h ; irq 0-7 + mov al, [IRQ_status] + out 21h, al + ; ... + push es + xor ax, ax + mov es, ax + mov ax, [IRQ_vector] + mov [es:bx], ax + mov ax, [IRQ_vector+2] + mov [es:bx+2], ax + pop es + + sti +;%endif +end if + retn + +;============================================================================= +; PLAYER.ASM +;============================================================================= + +; UTILS.ASM +;---------------------------------------------------------------------------- +; delay1_4ms - Delay for 1/4 millisecond. +; 1mS = 1000us +; Entry: +; None +; Exit: +; None +; +; Modified: +; None +; +PORTB EQU 061h + REFRESH_STATUS EQU 010h ; Refresh signal status + +delay1_4ms: + push ax + push cx + mov cx, 16 ; close enough. + in al,PORTB + and al,REFRESH_STATUS + mov ah,al ; Start toggle state + or cx, cx + jz short _d4ms1 + inc cx ; Throwaway first toggle +_d4ms1: + in al,PORTB ; Read system control port + and al,REFRESH_STATUS ; Refresh toggles 15.085 microseconds + cmp ah,al + je short _d4ms1 ; Wait for state change + + mov ah,al ; Update with new state + dec cx + jnz short _d4ms1 + + pop cx + pop ax + retn + +print_msg: + ; 13/11/2016 - Erdogan Tan + ; esi = ASCIIZ text address + ; + mov bx, 7h + mov ah, 0Eh +pm_next_char: + lodsb + and al, al + jz short pm_retn + int 10h + jmp short pm_next_char +pm_retn: + retn + +dword2str: + ; 13/11/2016 - Erdogan Tan + ; eax = dword value + ; + call dwordtohex + mov [dword_str], edx + mov [dword_str+4], eax + mov si, dword_str + retn + + ; trdos386.s (unix386.s) - 10/05/2015 + ; Convert binary number to hexadecimal string + +bytetohex: + ; INPUT -> + ; AL = byte (binary number) + ; OUTPUT -> + ; AX = hexadecimal string + ; + push bx + xor bh, bh + mov bl, al + shr bl, 4 + mov bl, [bx+hex_chars] + xchg bl, al + and bl, 0Fh + mov ah, [bx+hex_chars] + pop bx + retn + +wordtohex: + ; INPUT -> + ; AX = word (binary number) + ; OUTPUT -> + ; EAX = hexadecimal string + ; + push bx + xor bh, bh + xchg ah, al + push ax + mov bl, ah + shr bl, 4 + mov al, [bx+hex_chars] + mov bl, ah + and bl, 0Fh + mov ah, [bx+hex_chars] + shl eax, 16 + pop ax + pop bx + jmp short bytetohex + +dwordtohex: + ; INPUT -> + ; EAX = dword (binary number) + ; OUTPUT -> + ; EDX:EAX = hexadecimal string + ; + push eax + shr eax, 16 + call wordtohex + mov edx, eax + pop eax + call wordtohex + retn + + ; 13/11/2016 - Erdogan Tan +write_ac97_dev_info: + ; BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + xor bh, bh + mov esi, [dev_vendor] + mov ax, si + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId], al + shr esi, 16 + mov ax, si + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId], al + + mov esi, [bus_dev_fn] + shr esi, 8 + mov ax, si + mov bl, al + mov dl, bl + and bl, 7 ; bit 0,1,2 + mov al, [bx+hex_chars] + mov [msgFncNo+1], al + mov bl, dl + shr bl, 3 + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevNo], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBusNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBusNo], al + + ;mov ax, [ac97_io_base] + ; 08/05/2024 + mov ax, [NABMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgIOBaseAddr+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgIOBaseAddr+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgIOBaseAddr+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgIOBaseAddr], al + + ; 24/11/2016 + xor ah, ah + mov al, [ac97_int_ln_reg] + mov cl, 10 + div cl + add [msgIRQ], ax + and al, al + jnz short _pmi + mov al, byte [msgIRQ+1] ; 13/11/2024 + mov ah, ' ' + mov [msgIRQ], ax +_pmi: + mov dx, msgAC97Info + mov ah, 9 + int 21h + + retn + + ; 08/05/2024 +ac97_stop: + ; 11/11/2023 + ; 09/11/2023 + ; 05/11/2023 + ; 04/11/2023 + ; 28/05/2017 (TRDOS 386 v2, 'audio.s') + ;mov byte [tLoop], 0 ; stop ! ; 05/11/2023 +;_ac97_stop: + + ; 11/11/2023 + mov dx, [NAMBAR] + ;add dx, 0 ; ac_reg_0 ; reset register + out dx, ax + + ; 04/11/2023 + ; 09/10/2017 (TRDOS 386 v2, 'audio.s') + ; 11/06/2017 + xor al, al ; 0 + call ac97_po_cmd + + ; (Ref: KolibriOS, intelac97.asm, 'stop:') + ; Clear FIFOE, BCIS, LVBCI (Ref: Intel ICH hub manual) + mov ax, 1Ch + mov dx, [NABMBAR] + add dx, PO_SR_REG + out dx, ax + + ; 11/06/2017 + mov al, RR +ac97_po_cmd: + ; 11/06/2017 + ; 29/05/2017 + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out control register + out dx, al + retn + +;============================================================================= +; preinitialized data +;============================================================================= + +;============================================================================= +; PLAY.ASM - DATA +;============================================================================= + +msg_2017: + db 'Tiny MOD Player by Erdogan Tan. November 2024.',10,13 + db 'usage: playmod4 filename.mod', 10, 13, '$' + db '18/02/2017',0 + db '20/05/2024',0 + db '13/11/2024',0 + +Credits: db 'Tiny MOD Player v0.1b by Carlos Hasan. July 1993.' +CRLF: ; 13/05/2024 + db 10,13,'$' +ErrorMesg: db 'Error loading Module file.',10,13,'$' + db 0 ; 13/11/2024 (4070 bytes) + +;============================================================================= +; MODPLAY.ASM - DATA +;============================================================================= + +;Credits: db 'Amiga Module Player v0.3b by Carlos Hasan.' + +SinTable: db 0,25,50,74,98,120,142,162,180,197,212,225 + db 236,244,250,254,255,254,250,244,236,225 + db 212,197,180,162,142,120,98,74,50,25 + +PeriodTable: dw 856,808,762,720,678,640,604,570,538,508,480,453 + dw 428,404,381,360,339,320,302,285,269,254,240,226 + dw 214,202,190,180,170,160,151,143,135,127,120,113 + +;============================================================================= +; PLAYWAV.ASM / PLAYER.ASM - DATA +;============================================================================= + +; 24/11/2016 +; IRQ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +irq_int: db 08h,09h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,70h,71h,72h,73h,74h,75h,76h,77h + +; 13/11/2024 +; ('<<' to 'shl' conversion for FASM) + +; 17/02/2017 +; Valid ICH device IDs + +valid_ids: +;dd (ICH_DID << 16) + INTEL_VID ; 8086h:2415h +dd (ICH_DID shl 16) + INTEL_VID ; 8086h:2415h +dd (ICH0_DID shl 16) + INTEL_VID ; 8086h:2425h +dd (ICH2_DID shl 16) + INTEL_VID ; 8086h:2445h +dd (ICH3_DID shl 16) + INTEL_VID ; 8086h:2485h +dd (ICH4_DID shl 16) + INTEL_VID ; 8086h:24C5h +dd (ICH5_DID shl 16) + INTEL_VID ; 8086h:24D5h +dd (ICH6_DID shl 16) + INTEL_VID ; 8086h:266Eh +dd (ESB6300_DID shl 16) + INTEL_VID ; 8086h:25A6h +dd (ESB631X_DID shl 16) + INTEL_VID ; 8086h:2698h +dd (ICH7_DID shl 16) + INTEL_VID ; 8086h:27DEh +; 03/11/2023 - Erdogan Tan +dd (MX82440_DID shl 16) + INTEL_VID ; 8086h:7195h +dd (SI7012_DID shl 16) + SIS_VID ; 1039h:7012h +dd (NFORCE_DID shl 16) + NVIDIA_VID ; 10DEh:01B1h +dd (NFORCE2_DID shl 16) + NVIDIA_VID ; 10DEh:006Ah +dd (AMD8111_DID shl 16) + AMD_VID ; 1022h:746Dh +dd (AMD768_DID shl 16) + AMD_VID ; 1022h:7445h +dd (CK804_DID shl 16) + NVIDIA_VID ; 10DEh:0059h +dd (MCP04_DID shl 16) + NVIDIA_VID ; 10DEh:003Ah +dd (CK8_DID shl 16) + NVIDIA_VID ; 1022h:008Ah +dd (NFORCE3_DID shl 16) + NVIDIA_VID ; 10DEh:00DAh +dd (CK8S_DID shl 16) + NVIDIA_VID ; 10DEh:00EAh + +;valid_id_count equ ($ - valid_ids)>>2 ; 05/11/2023 +; 13/11/2024 +valid_id_count = ($ - valid_ids) shr 2 ; 05/11/2023 + +; 13/11/2016 +hex_chars db "0123456789ABCDEF", 0 +msgAC97Info db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah + db "Vendor ID: " +msgVendorId db "0000h Device ID: " +msgDevId db "0000h", 0Dh, 0Ah + db "Bus: " +msgBusNo db "00h Device: " +msgDevNo db "00h Function: " +msgFncNo db "00h" + db 0Dh, 0Ah + db "I/O Base Address: " +msgIOBaseAddr db "0000h IRQ: " +msgIRQ dw 3030h + db 0Dh, 0Ah, "$" + +;msgSampleRate db "Sample Rate: " +;msgHertz db "00000 Hz ", "$" +;msg8Bits db "8 bits ", "$" +;msgMono db "Mono", 0Dh, 0Ah, "$" +;msg16Bits db "16 bits ", "$" +;msgStereo db "Stereo", 0Dh, 0Ah, "$" + +;; 13/11/2016 - Erdogan Tan (Ref: KolibriOS, codec.inc) +;codec_id dd 0 +;codec_chip_id dd 0 +;codec_vendor_ids dw 0 +;codec_chip_ids dw 0 + +dword_str dd 30303030h, 30303030h + db 'h', 0Dh, 0Ah, 0 + +;============================================================================= +; uninitialized data +;============================================================================= + +bss_start: + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +align 4 ; alignb 4 (NASM) + +; 17/02/2017 +; NAMBAR: Native Audio Mixer Base Address Register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 10h-13h +; NABMBAR: Native Audio Bus Mastering Base Address register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 14h-17h +NAMBAR: rw 1 ; BAR for mixer +NABMBAR rw 1 ; BAR for bus master regs + +tBuff: rb 1 +;irq_status: rb 1 +pcm_irq_status: rb 1 ; 08/05/2024 + +inside: rb 1 +tLoop: rb 1 + +; 08/05/2024 +IRQ_status: rw 1 ; IRQ status before enabling audio interrupt +IRQ_vector: rd 1 ; Previous interrupt handler address + +; 256 byte buffer for descriptor list +BDL_BUFFER: rw 1 ; segment of our 256byte BDL buffer +DMA_BUFFER1: rw 1 ; Pointer to 1st half of DMA Buffer +DMA_BUFFER2: rw 1 ; Pointer to 2nd half of DMA Buffer + +; 12/11/2016 - Erdogan Tan + +ac97_int_ln_reg: rb 1 +err_num: rb 1 + +bus_dev_fn: rd 1 +dev_vendor: rd 1 +; 08/05/2024 +;stats_cmd: rd 1 +;ac97_io_base: rw 1 +LVI: rb 1 +; 12/05/2024 +volume: rb 1 + +align 4 ; alignb 4 (NASM) + +BdlBuffer: rb BDL_SIZE ; 13/02/2017 +DmaBuffer: rb 2*BUFFERSIZE ; 13/02/2017 + +; MODLOAD.ASM +FileHandle: rw 1 +ErrorInfo: rw 1 +Header: rb sizeof.ModHeader + +sample_rate: ; PLAYER.ASM (22050Hz) +; MODPLAY.ASM +MixSpeed: rw 1 + +ModInfo: +ModInfo.OrderLen: rb 1 +ModInfo.ReStart: rb 1 +ModInfo.Order: rb 128 +ModInfo.Patterns: rd 1 + +ModInfo.SampOfs: rw 31 +ModInfo.SampSeg: rw 31 +ModInfo.SampLen: rw 31 +ModInfo.SampRep: rw 31 +ModInfo.SampRepLen: rw 31 +ModInfo.SampVol: rw 31 + +; MODPLAY.ASM +PitchTable: rw 857 +VolTable: rb 16640 +MixBuffer rb MixBufSize + +; MODPLAY.ASM +OrderPos: rb 1 +Tempo: rb 1 +TempoWait: rb 1 +Bpm: rb 1 +Row: rb 1 +BreakRow: rb 1 +BpmSamples: rw 1 +BufPtr: rw 1 +BufLen: rw 1 +BufRep: rw 1 +Note: rd 1 +;Tracks: rb TrackInfo.size*NumTracks +; 13/11/2024 +Tracks: rb sizeof.TrackInfo*NumTracks + +align 16 ; alignb 16 (NASM) + +; PLAY.ASM +Scope: rw 320 +RowOfs: rw 256 + +; 18/02/2017 +_si_: rw 1 +MOD_BUFFER: rb BUFFERSIZE/4 ; 2048 ; 11/05/2024 +EOF: \ No newline at end of file diff --git a/trdos386/programs/16bit/PLAYWAV8.COM b/trdos386/programs/16bit/PLAYWAV8.COM new file mode 100644 index 0000000..36d94c8 Binary files /dev/null and b/trdos386/programs/16bit/PLAYWAV8.COM differ diff --git a/trdos386/programs/16bit/PLAYWAV9.COM b/trdos386/programs/16bit/PLAYWAV9.COM new file mode 100644 index 0000000..2a2ccc0 Binary files /dev/null and b/trdos386/programs/16bit/PLAYWAV9.COM differ diff --git a/trdos386/programs/16bit/PLAYWAVX.COM b/trdos386/programs/16bit/PLAYWAVX.COM new file mode 100644 index 0000000..1487f53 Binary files /dev/null and b/trdos386/programs/16bit/PLAYWAVX.COM differ diff --git a/trdos386/programs/16bit/SB16PLAY.COM b/trdos386/programs/16bit/SB16PLAY.COM new file mode 100644 index 0000000..aba1a23 Binary files /dev/null and b/trdos386/programs/16bit/SB16PLAY.COM differ diff --git a/trdos386/programs/16bit/ac97play.asm b/trdos386/programs/16bit/ac97play.asm new file mode 100644 index 0000000..171084f --- /dev/null +++ b/trdos386/programs/16bit/ac97play.asm @@ -0,0 +1,6763 @@ +; **************************************************************************** +; ac97play.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; AC97PLAY.COM ! AC'97 (ICH) .WAV PLAYER program by Erdogan TAN +; +; 28/11/2024 +; +; [ Last Modification: 18/12/2024 ] +; +; Modified from PLAYWAV8.COM .wav player program by Erdogan Tan, 25/11/2024 +; +; Assembler: FASM 1.73 +; fasm ac97play.asm AC97PLAY.COM +; ---------------------------------------------------------------------------- +; In the visualization part of the code, the source code of Matan Alfasi's +; (Ami-Asaf) player.exe program was partially used. +; ---------------------------------------------------------------------------- +; Previous versions of this Wav Player were based in part on .wav file player +; (for DOS) source code written by Jeff Leyla in 2002. + +; playwav8.asm (25/11/2024) + +; TUNELOOP version (playing without AC97 interrupt) - 06/11/2023 - Erdogan Tan +; sample rate conversion version - 18/11/2023 - Erdogan Tan + +; CODE + + ; 13/11/2024 +macro sys_msg op1,op2 +{ ; 30/05/2024 + mov si, op1 ; message + mov bl, op2 ; text color + xor bh, bh ; video page 0 + mov ah, 0Eh + call p_msg +} + +; player internal variables and other equates. +;BUFFERSIZE equ 64 * 1024 ; 64k file buffer size. +; 17/11/2024 +BUFFERSIZE equ 65520 +ENDOFFILE equ 1 ; flag for knowing end of file + +use16 + +org 100h + + include 'ac97.inc' ; 17/02/2017 + +_STARTUP: + ; 30/05/2024 + ; Prints the Credits Text. + sys_msg Credits, 0Bh + + ; 30/05/2024 + call setFree ; deallocate unused DOS mem + + ; 17/02/2017 + ; Clear BSS (uninitialized data) area + xor ax, ax ; 0 + mov cx, (bss_end - bss_start)/2 + mov di, bss_start + rep stosw + + ; Detect (& Enable) AC'97 Audio Device + call DetectAC97 + ;jnc short GetFileName + ; 30/05/2024 + jnc short allocate_memory + + ; 30/05/2024 +_dev_not_ready: + ; couldn't find the audio device! + sys_msg noDevMsg, 0Fh + jmp Exit + + ; 30/05/2024 +allocate_memory: + +; allocate 256 bytes of data for DCM_OUT Buffer Descriptor List. (BDL) + + mov ax, BDL_SIZE / 16 + call memAlloc + mov [BDL_BUFFER], ax ; segment + +; allocate 2 buffers, 64k each for now. + + mov ax, BUFFERSIZE / 16 ; 64k for .WAV file + call memAlloc + mov [WAV_BUFFER1], ax ; segment + + mov ax, BUFFERSIZE / 16 + call memAlloc + mov [WAV_BUFFER2], ax + + ;;; + ; 28/11/2024 +Player_InitalizePSP: + mov si, 81h + mov [PSP_CurrentOffset], si + cmp byte [si], 0Dh ; "CR": No command line parameters + ja short Player_ParseParameters + jmp pmsg_usage + +Player_ParseParameters: + ; 29/11/2024 + ; 18/12/2024 + ;mov dx, wav_file_name + cmp byte [IsInSplash], 0 + jna short check_p_command + + call write_audio_dev_info + + mov dx, SplashFileName + jmp short _1 + +check_p_command: + cmp byte [command], 'P' + je short Player_ParsePreviousParameter + + mov si, [PSP_CurrentOffset] + cmp byte [si], 0Dh + ja short Player_ParseNextParameter +jmp_Player_Quit: + jmp Player_Quit + +Player_ParsePreviousParameter: + ; 29/11/2024 + ;mov byte [command], 0 + + mov si, [PSP_CurrentOffset] + + cmp si, 81h + je short Player_ParseNextParameter + + ;; Search for previous space character + dec si + mov cx, 2 +PSPParsePrev_Search: + dec si + mov al, [si] + cmp al, 20h + jne short PSPParsePrev_Search + + cmp si, 81h + jna PSPParsePrev_Copy + loop PSPParsePrev_Search + +PSPParsePrev_Copy: + mov [PSP_CurrentOffset], si + +Player_ParseNextParameter: + ; 29/11/2024 + call GetFileName + jcxz jmp_Player_Quit + + ; 28/11/2024 + mov dx, wav_file_name + ;;; +_1: + +; open the file + ; open existing file + ; 14/11/2024 + ;mov al, OPEN ; open existing file + ; 28/11/2024 + ;mov dx, wav_file_name + call openFile ; no error? ok. + jnc getwavparms ; 14/11/2024 + + ; 28/11/2024 + cmp byte [IsInSplash], 0 + ja Player_SplashScreen + + ; 29/11/2024 + cmp byte [filecount], 0 + ja short check_p_command + + call ClearScreen + sys_msg Credits, 0Bh + call write_audio_dev_info + +wav_file_open_error: +; file not found! + sys_msg noFileErrMsg, 0Ch +_exit_: + jmp Exit + + ; 29/11/2024 + ; 30/05/2024 +GetFileName: + mov di, wav_file_name + mov si, [PSP_CurrentOffset] + xor cx, cx ; 0 +ScanName: + lodsb + ;test al, al + ;jz short a_4 + ; 29/11/2024 + cmp al, 0Dh + jna short a_4 + cmp al, 20h + je short ScanName ; scan start of name. + stosb + mov ah, 0FFh + ;;; + ; 14/11/2024 + ; (max. path length = 64 bytes for MSDOS ?) (*) + ;xor cx, cx ; 0 + ;;; +a_0: + inc ah +a_1: + ;;; + ; 14/11/2024 + inc cx + ;;; + lodsb + stosb + cmp al, '.' + je short a_0 + ; 29/11/2024 + cmp al, 20h + ;and al, al + ;jnz short a_1 + ;;; + ; 14/11/2024 + jna short a_3 + and ah, ah + jz short a_2 + cmp al, '\' + jne short a_2 + mov ah, 0 +a_2: + cmp cl, 75 ; 64+8+'.'+3 -> offset 75 is the last chr + jb short a_1 + ; 29/11/2024 + sub cx, cx + jmp short a_4 +a_3: + ; 29/11/2024 + dec di + ;;; + or ah, ah ; if period NOT found, + jnz short a_4 ; then add a .WAV extension. +SetExt: + ; 29/11/2024 + ;dec di + mov dword [di], '.WAV' ; ! 64+12 is DOS limit + ; but writing +4 must not + ; destroy the following data + ;mov byte [di+4], 0 ; so, 80 bytes path + 0 is possible here + ; 29/11/2024 + add cx, 4 + add di, 4 +a_4: + mov byte [di], 0 + dec si + mov [PSP_CurrentOffset], si + retn + +getwavparms: + ; 14/11/2024 + call getWAVParameters + jc short _exit_ ; nothing to do + + ; 17/11/2024 + mov bl, 4 + sub bl, byte [WAVE_BlockAlign] + ; = 0 for 16 bit stereo + ; = 2 for 8 bit stereo or 16 bit mono + ; = 3 for 8 bit mono + + shr bl, 1 ; 0 --> 0, 2 --> 1, 3 --> 1 + ; 15/11/2024 + adc bl, 0 ; 3 --> 1 --> 2 + mov byte [fbs_shift], bl ; = 2 mono and 8 bit + ; = 0 stereo and 16 bit + ; = 1 mono or 8 bit + ; 30/05/2024 + call codecConfig ; unmute codec, set rates. + jc init_err + + ; 28/11/2024 + cmp byte [IsInSplash], 0 + jna short Player_Template + + ; 28/11/2024 +Player_SplashScreen: + ; 15/11/2024 + ;; Set video mode to 03h (not necessary) + mov ax, 03h + int 10h + + ; 15/11/2024 + ;; Get the cursor type + mov ah, 03h + int 10h + mov [cursortype], cx ; save + + ; 15/11/2024 + ;; Set the cursor to invisible + mov ah, 01h + mov cx, 2607h + int 10h + + ; 15/11/2024 + ;xor dx, dx + ;call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, SplashScreen + int 10h + ;;; + + ;;; + ; 22/11/2024 + ; set wave volume led addresses + mov bx, 13*80*2 + mov bp, 80 + mov di, wleds_addr +wleds_sa_1: + mov cx, 7 +wleds_sa_2: + mov ax, 80*2 + mul cx + add ax, bx + stosw + loop wleds_sa_2 + mov ax, bx + stosw + inc bx + inc bx + dec bp + jnz short wleds_sa_1 + ;;; + + ; 28/11/2024 + cmp word [filehandle], -1 + jne short StartPlay + + ;;; wait for 3 seconds + mov cx, 002Dh + mov dx, 0C6C0h + mov ah, 86h + int 15h + ;;; + + ; 28/11/2024 + mov byte [IsInSplash], 0 + ;mov dx, wav_file_name + ;jmp _1 + ; 29/11/2024 + jmp Player_ParseNextParameter + + ; 28/11/2024 +Player_Template: + ;;; + ; 09/12/2024 + ; 29/11/2024 + inc byte [filecount] + mov byte [command], 0 + ;;; + + xor dx, dx + call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + ; 09/12/2024 + ; dx = 0 + ;mov dx, 0 + + mov bp, Template + int 10h + ;;; + + ; 14/11/2024 + call SetTotalTime + call UpdateFileInfo + + ; 28/11/2024 +StartPlay: + ; 25/11/2023 + ; ------------------------------------------ + + ; 18/11/2023 (ich_wav4.asm) + ; 13/11/2023 (ich_wav3.asm) + + cmp byte [VRA], 1 + jb short chk_sample_rate + +playwav_48_khz: + mov word [loadfromwavfile], loadFromFile + ;mov word [loadsize], 0 ; 65536 + ;;; + ; 17/11/2024 + ;mov word [buffersize], 32768 + mov ax, BUFFERSIZE/2 ; 32760 + mov [buffersize], ax ; 16 bit samples + shl ax, 1 ; bytes + mov cl, [fbs_shift] + shr ax, cl + mov [loadsize], ax ; 16380 or 32760 or 65520 + ;;; + jmp PlayNow ; 30/05/2024 + +chk_sample_rate: + ; set conversion parameters + ; (for 8, 11.025, 16, 22.050, 24, 32 kHZ) + mov ax, [WAVE_SampleRate] + cmp ax, 48000 + je short playwav_48_khz +chk_22khz: + cmp ax, 22050 + jne short chk_11khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_22khz_1 + mov bx, load_22khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_22khz_2 + mov bx, load_22khz_mono_16_bit + jmp short chk_22khz_2 +chk_22khz_1: + mov bx, load_22khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_22khz_2 + mov bx, load_22khz_mono_8_bit +chk_22khz_2: + mov ax, 7514 ; (442*17) + mov dx, 37 + mov cx, 17 + jmp set_sizes +chk_11khz: + cmp ax, 11025 + jne short chk_44khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_11khz_1 + mov bx, load_11khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_11khz_2 + mov bx, load_11khz_mono_16_bit + jmp short chk_11khz_2 +chk_11khz_1: + mov bx, load_11khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_11khz_2 + mov bx, load_11khz_mono_8_bit +chk_11khz_2: + mov ax, 3757 ; (221*17) + mov dx, 74 + mov cx, 17 + jmp set_sizes +chk_44khz: + cmp ax, 44100 + jne short chk_16khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_44khz_1 + mov bx, load_44khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_44khz_2 + mov bx, load_44khz_mono_16_bit + jmp short chk_44khz_2 +chk_44khz_1: + mov bx, load_44khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_44khz_2 + mov bx, load_44khz_mono_8_bit +chk_44khz_2: + ;mov ax, 15065 ; (655*23) + ; 18/11/2023 ((file size + bss + stack) <= 64KB) + ;mov ax, 14076 ; (612*23) + ; 17/11/2024 + mov ax, 12650 ; (550*23) + mov dx, 25 + mov cx, 23 + jmp set_sizes +chk_16khz: + cmp ax, 16000 + jne short chk_8khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_16khz_1 + mov bx, load_16khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_16khz_2 + mov bx, load_16khz_mono_16_bit + jmp short chk_16khz_2 +chk_16khz_1: + mov bx, load_16khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_16khz_2 + mov bx, load_16khz_mono_8_bit +chk_16khz_2: + ;mov ax, 5461 + ; 17/11/2024 + mov ax, 5460 + mov dx, 3 + mov cx, 1 + jmp set_sizes +chk_8khz: + cmp ax, 8000 + jne short chk_24khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_8khz_1 + mov bx, load_8khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_8khz_2 + mov bx, load_8khz_mono_16_bit + jmp short chk_8khz_2 +chk_8khz_1: + mov bx, load_8khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_8khz_2 + mov bx, load_8khz_mono_8_bit +chk_8khz_2: + mov ax, 2730 + mov dx, 6 + mov cx, 1 + jmp short set_sizes +chk_24khz: + cmp ax, 24000 + jne short chk_32khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_24khz_1 + mov bx, load_24khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_24khz_2 + mov bx, load_24khz_mono_16_bit + jmp short chk_24khz_2 +chk_24khz_1: + mov bx, load_24khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_24khz_2 + mov bx, load_24khz_mono_8_bit +chk_24khz_2: + ;mov ax, 8192 + ; 17/11/2024 + mov ax, 8190 + mov dx, 2 + mov cx, 1 + jmp short set_sizes +chk_32khz: + cmp ax, 32000 + jne short vra_needed + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_32khz_1 + mov bx, load_32khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_32khz_2 + mov bx, load_32khz_mono_16_bit + jmp short chk_32khz_2 +chk_32khz_1: + mov bx, load_32khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_32khz_2 + mov bx, load_32khz_mono_8_bit +chk_32khz_2: + ;mov ax, 10922 + ; 17/11/2024 + mov ax, 10920 + mov dx, 3 + mov cx, 2 + ;jmp short set_sizes +set_sizes: + ;;; + ; 17/11/2024 + push cx + mov cl, 2 + sub cl, [fbs_shift] + ; = 2 for 16 bit stereo + ; = 1 for 16 bit mono or 8 bit stereo + ; = 0 for 8 bit mono + shl ax, cl + pop cx + mov [loadsize], ax ; (one) read count in bytes + ;;; + mul dx + cmp cx, 1 + je short s_2 +s_1: + div cx +s_2: + ;;; + ; ax = byte count of (to be) converted samples + + ; 17/11/2024 + ;;; + mov cl, [fbs_shift] + + shl ax, cl + ; *1 for 16 bit stereo + ; *2 for 16 bit mono or 8 bit stereo + ; *4 for for 8 bit mono + ;;; + + ; ax = 16 bit stereo byte count (target buffer size) + + shr ax, 1 ; buffer size is 16 bit sample count + mov [buffersize], ax + mov [loadfromwavfile], bx + jmp short PlayNow + +vra_needed: + ; 13/11/2023 + pop ax ; discard return address to the caller + ; 30/05/2024 +vra_err: + sys_msg msg_no_vra, 0Fh + jmp Exit + + ; 15/11/2024 + ; 30/05/2024 + ; 13/11/2023 (ich_wav4.asm) +;loadfromwavfile: +; dw loadFromFile +;loadsize: ; read from wav file +; dw 0 +;buffersize: ; write to DMA buffer +; dd 32768 ; 16 bit samples (not bytes) + +PlayNow: + ;;; + ; 14/11/2024 + ;mov al, 3 ; 0 = max, 31 = min + ; 14/12/2024 + mov al, [volume] + call SetPCMOutVolume@ + ; 15/11/2024 + ;;call SetMasterVolume + ;call SetPCMOutVolume + + ; 29/11/2024 + cmp byte [IsInSplash], 0 + ;ja short PlayNow@ + ; 02/12/2024 + jna short PlayNow@ + +;PlayNow@: + ; 28/11/2024 + ;cmp byte [IsInSplash], 0 + ;ja short _3 + ; + ;call UpdateVolume + ; + ; 02/12/2024 + jmp short _3 + + ; 02/12/2024 +PlayNow@: + ; reset file loading and EOF parameters + ;mov word [count], 0 + mov word [LoadedDataBytes], 0 + mov word [LoadedDataBytes+2], 0 + mov byte [flags], 0 + mov byte [stopped], 0 + ;jmp short PlayNow@@ + +PlayNow@@: + ;;; + ; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 30/05/2024 + ; playwav4.asm +_2: + call check4keyboardstop ; flush keyboard buffer + jc short _2 ; 07/11/2023 + +; play the .wav file. Most of the good stuff is in here. + +_3: + call PlayWav + + ; 29/11/2024 + ; 28/11/2024 + call closeFile + ;mov dx, wav_file_name + cmp byte [IsInSplash], 0 + ;jna short Exit + jna short _4 ; 29/11/2024 + mov byte [IsInSplash], 0 + ;jmp _1 + ; 29/11/2024 + jmp Player_ParseNextParameter + + ; 29/11/2024 +_4: + cmp byte [command], 'Q' + je short Exit + jmp check_p_command + +; close the .wav file and exit. + +Exit: + ; 15/11/2024 + ;; Restore Cursor Type + mov cx, [cursortype] + cmp cx, 0 + jz short Exit@ + mov ah, 01h + int 10h +Exit@: + ; 29/11/2024 + ;call closeFile +Exit@@: + mov ax, 4C00h ; bye ! + int 21h +here: + jmp short here ; do not come here ! + + ; 30/05/2024 +pmsg_usage: + sys_msg msg_usage, 0Fh ; 14/11/2024 + jmp short Exit + + ; 30/05/2024 +init_err: + sys_msg msg_init_err, 0Fh + jmp short Exit + + ; 29/11/2024 +Player_Quit: + call ClearScreen + jmp short Exit@@ +ClearScreen: + mov ax, 03h + int 10h + retn + + ; -------------------------------------------- + + ; 29/05/2024 (TRDOS 386, playwav7.s) + ; ((Modified from playwav4.asm, ich_wav4.asm)) + ; ------------------ +;playwav_vra: +PlayWav: + ; create Buffer Descriptor List + + ; Generic Form of Buffer Descriptor + ; --------------------------------- + ; 63 62 61-48 47-32 31-0 + ; --- --- -------- ------- ----- + ; IOC BUP -reserved- Buffer Buffer + ; Length Pointer + ; [15:0] [31:0] + + push es + mov ax, [BDL_BUFFER] ; get segment # for BDL + mov es, ax + + mov cx, 32 / 2 ; make 32 entries in BDL + xor di, di +_0: + movzx eax, word [WAV_BUFFER1] + shl eax, 4 ; convert seg:off ->0:offset + stosd ; store pointer to wavbuffer1 + + ;mov eax, BUFFERSIZE / 2 ; size of buffer (32K) in (16bit) words + ; 13/11/2023 (ich_wav3.asm) - 18/11/2023 (ich_wav4.asm) + mov eax, [buffersize] + + ;or eax, IOC + BUP + ; 06/11/2023 (TUNELOOP version, without interrupt) + or eax, BUP + stosd + + movzx eax, word [WAV_BUFFER2] + shl eax, 4 ; convert seg:off ->0:offset + stosd ; store pointer to wavbuffer2 + + ;mov eax, BUFFERSIZE / 2 ; size of half buffer (32K) + ; 13/11/2023 (ich_wav3.asm) - 18/11/2023 (ich_wav4.asm) + mov eax, [buffersize] + + ;or eax, IOC + BUP + ; 06/11/2023 (TUNELOOP version, without interrupt) + or eax, BUP + stosd + + loop _0 + pop es + + ; 18/12/2024 + mov word [count], cx ; 0 + ; 14/11/2024 + ;mov dword [LoadedDataBytes], 0 + + ; 19/11/2024 +RePlayWav: + + ; load 64k into buffer 1 + mov ax, [WAV_BUFFER1] + ;call loadFromFile + ; 13/11/2023 + call word [loadfromwavfile] + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; and 64k into buffer 2 + mov ax, [WAV_BUFFER2] + ;call loadFromFile + ; 13/11/2023 + call word [loadfromwavfile] + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; write NABMBAR+10h with offset of buffer descriptor list + + movzx eax, word [BDL_BUFFER] + shl eax, 4 ; convert seg:off to 0:off + mov dx, [NABMBAR] + add dx, PO_BDBAR_REG ; set pointer to BDL + out dx, eax ; write to AC97 controller + + ; 19/05/2024 + call delay1_4ms + + mov al, 31 + call setLastValidIndex + + ; 19/05/2024 + ;call delay1_4ms + + ; 17/02/2017 + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + ;mov al, IOCE + RPBM ; Enable 'Interrupt On Completion' + run + ; ; (LVBI interrupt will not be enabled) + ; 06/11/2023 (TUNELOOP version, without interrupt) + mov al, RPBM + out dx, al ; Start bus master operation. + + ; 19/05/2024 + ; 06/11/2023 + call delay1_4ms ; 30/05/2024 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + +; while DMA engine is running, examine current index and wait until it hits 1 +; as soon as it's 1, we need to refresh the data in wavbuffer1 with another +; 64k. Likewise when it's playing buffer 2, refresh buffer 1 and repeat. + +; 18/11/2023 +; 08/11/2023 +; 07/11/2023 + + ; 19/11/2024 + mov byte [wleds], 1 + + ;;; + ; 09/12/2024 + mov ax, 10548 ; (48000*10/182)*4 + cmp byte [VRA], 0 + jna short sL0 ; 48kHZ (interpolation) + ; + mov ax, [WAVE_SampleRate] + mov cx, 10 + mul cx + mov cl, 182 + div cx + ; ax = samples per 1/18.2 second + ;mov cl, byte [WAVE_BlockAlign] + ; 09/12/2024 + ;mov cl, 4 ; 16 bit, stereo + ;mul cx + shl ax, 2 ; * 4 +sL0: + mov [wleds_dif], ax ; buffer read differential (distance) + ; for wave volume leds update + ; (byte stream per 1/18.2 second) + ;;; + ; 28/11/2024 + cmp byte [IsInSplash], 0 + jna short tuneLoop + +sL1: + call updateLVI ; /set LVI != CIV/ + jz short sL3 + call getCurrentIndex + test al, BIT0 + jz short sL1 ; loop if buffer 2 is not playing + + ; load buffer 1 + mov ax, [WAV_BUFFER1] + call word [loadfromwavfile] + jc short sL3 +sL2: + call updateLVI + jz short sL3 + call getCurrentIndex + test al, BIT0 + jnz short sL2 ; loop if buffer 1 is not playing + + ; load buffer 2 + mov ax, [WAV_BUFFER2] + call word [loadfromwavfile] + jnc short sL1 +sL3: + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + mov al, 0 + out dx, al ; stop player + + ; 29/11/2024 + ;; reset file loading and EOF parameters + ;;mov word [count], 0 + ;mov word [LoadedDataBytes], 0 + ;mov word [LoadedDataBytes+2], 0 + ;mov byte [flags], 0 + + retn + + ; 29/11/2024 +tuneLoop: + ; 30/05/2024 + ; 18/11/2023 (ich_wav4.asm) + ; 08/11/2023 + ; 06/11/2023 + +tLWait: + ; 18/11/2024 + cmp byte [stopped], 0 + ;jna short tL@ + ; 21/11/2024 + ja short tLWait@ + mov al, [tLP] + cmp al, '1' + ja short tL2@ + je short tL1@ + mov al, '1' + mov [tLP], al + jmp short tL1@ +tLWait@: ; 21/11/2024 + ;;; + ; 09/12/2024 + cmp byte [stopped], 3 + jnb _exitt_ + ;;; + call checkUpdateEvents + jc _exitt_ + ;;; + ; 29/11/2024 + cmp byte [command], 'N' + je _exitt_ + cmp byte [command], 'P' + je _exitt_ + ;;; + cmp byte [tLO], '0' + je short tLWait + call tLZ + mov byte [tLO], '0' + jmp short tLWait + +;tLO: db 0 + +tL1@: + ;mov al, '1' + ; 19/11/2024 + mov [tLO], al + call tL0 +tL1: + call updateLVI ; /set LVI != CIV/ + jz short _exitt_ ; 08/11/2023 + ;;; + ;call check4keyboardstop + ; 14/11/2024 + call checkUpdateEvents + jc short _exitt_ + ; 18/11/2024 + cmp byte [stopped], 0 + ja short tLWait@ ; 21/11/2024 + ;;; + call getCurrentIndex + test al, BIT0 + jz short tL1 ; loop if buffer 2 is not playing + + ; load buffer 1 + mov ax, [WAV_BUFFER1] + ;call loadFromFile + ; 18/11/2023 + call word [loadfromwavfile] + jc short _exitt_ ; end of file + + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + mov al, '2' + ; 21/11/2024 + mov [tLP], al +tL2@: + ; 19/11/2024 + mov [tLO], al + call tL0 +tL2: + call updateLVI + jz short _exitt_ ; 08/11/2023 + ;;; + ;call check4keyboardstop + ; 14/11/2024 + call checkUpdateEvents + jc short _exitt_ + ; 18/11/2024 + cmp byte [stopped], 0 + ja tLWait@ ; 21/11/2024 + ;;; + call getCurrentIndex + test al, BIT0 + jnz short tL2 ; loop if buffer 1 is not playing + + ; load buffer 2 + mov ax, [WAV_BUFFER2] + ;call loadFromFile + ; 18/11/2023 + call word [loadfromwavfile] + ;jnc short tuneLoop + jc short _exitt_ + + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + ; 21/11/2024 + mov byte [tLP], '1' + jmp tuneLoop +_exitt_: + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + mov al, 0 + out dx, al ; stop player + + ;;; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 18/11/2024 +tLZ: + ; 30/05/2024 + mov al, '0' + + ;add al, '0' + ;call tL0 + ; + ;retn + ; 06/11/2023 + ;jmp short tL0 + ;retn + + ; 06/11/2023 +tL0: + ; 08/11/2023 + ; 05/11/2023 + ; 17/02/2017 - Buffer switch test (temporary) + ; 06/11/2023 + ; al = buffer indicator ('1', '2' or '0' -stop- ) + + push ds + ;push bx + mov bx, 0B800h ; video display page segment + mov ds, bx + sub bx, bx ; 0 + mov ah, 4Eh + mov [bx], ax ; show current play buffer (1, 2) + ;pop bx + pop ds + + retn + +; ------------------------------------------- + + ; 14/11/2024 +;SetMasterVolume: + ; 15/11/2024 +SetPCMOutVolume: + ;cmp al, 31 + ;ja short setvolume_ok + mov [volume], al ; max = 0, min = 31 +SetPCMOutVolume@: ; 19/11/2024 + mov ah, al + mov dx, [NAMBAR] + ; 15/11/2024 (QEMU) + ;add dx, CODEC_MASTER_VOL_REG + add dx, CODEC_PCM_OUT_REG + out dx, ax +;setvolume_ok: + retn + +; ------------------------------------------- + + ; 30/05/2024 +DetectAC97: +DetectICH: + ; 22/11/2023 + ; 19/11/2023 + ; 01/11/2023 - TRDOS 386 Kernel v2.0.7 + ;; 10/06/2017 + ;; 05/06/2017 + ;; 29/05/2017 + ;; 28/05/2017 + + ; 19/11/2023 + mov si, valid_ids ; address of Valid ICH (AC97) Device IDs + mov cx, valid_id_count +pfd_1: + lodsd + call pciFindDevice + jnc short d_ac97_1 + loop pfd_1 + + ;stc + retn + +d_ac97_1: + ; eax = BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; edx = DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + ; playwav4.asm - 19/05/2024 + + mov [bus_dev_fn], eax + mov [dev_vendor], edx + + ; get ICH base address regs for mixer and bus master + + mov al, NAMBAR_REG + call pciRegRead16 ; read PCI registers 10-11 + ;and dx, IO_ADDR_MASK ; mask off BIT0 + ; 19/05/2024 + and dl, 0FEh + + mov [NAMBAR], dx ; save audio mixer base addr + + mov al, NABMBAR_REG + call pciRegRead16 + ;and dx, IO_ADDR_MASK + ; 19/05/2024 + and dl, 0C0h + + mov [NABMBAR], dx ; save bus master base addr + + mov al, AC97_INT_LINE ; Interrupt line register (3Ch) + call pciRegRead8 ; 17/02/2017 + + mov [ac97_int_ln_reg], dl + + ;clc + + retn + +; ---------------------------------- + + ; 14/11/2024 + ; INPUT: ds:dx = file name address + ; OUTPUT: [filehandle] = ; -1 = not open +openFile: + mov ax, 3D00h ; open File for read + int 21h + jnc short _of1 + mov ax, -1 + ; cf = 1 -> not found or access error +_of1: + mov [filehandle], ax + retn + +; ---------------------------------- + +; close the currently open file + + ; 14/11/2024 + ; INPUT: [filehandle] ; -1 = not open + ; OUTPUT: none +closeFile: + cmp word [filehandle], -1 + jz short _cf1 + mov bx, [filehandle] + mov ax, 3E00h + int 21h ; close file +_cf1: + retn + +; ---------------------------------- + + ; 14/11/2024 - Erdogan Tan +getWAVParameters: +; reads WAV file header(s) (44 bytes) from the .wav file. +; entry: none - assumes file is already open +; exit: ax = sample rate (11025, 22050, 44100, 48000) +; cx = number of channels (mono=1, stereo=2) +; dx = bits per sample (8, 16) +; bx = number of bytes per sample (1 to 4) + + mov dx, WAVFILEHEADERbuff + mov bx, [filehandle] + mov cx, 44 ; 44 bytes + mov ah, 3Fh + int 21h + jc short gwavp_retn + + cmp ax, 44 + jb short gwavp_retn + + cmp dword [RIFF_Format], 'WAVE' + jne short gwavp_stc_retn + + cmp word [WAVE_AudioFormat], 1 ; Offset 20, must be 1 (= PCM) + ;jne short gwavp_stc_retn + je short gwavp_retn ; 15/11/2024 + + ; 15/11/2024 + ;mov cx, [WAVE_NumChannels] ; return num of channels in CX + ;mov ax, [WAVE_SampleRate] ; return sample rate in AX + ;mov dx, [WAVE_BitsPerSample] + ; return bits per sample value in DX + ;mov bx, [WAVE_BlockAlign] ; return bytes per sample in BX +;gwavp_retn: + ;retn + +gwavp_stc_retn: + stc +gwavp_retn: + retn + +; ---- 30/05/2024 (playwav4.asm, 19/05/2024) + +; MEMALLOC.ASM +;-- SETFREE: Release memory not used ---------------- +;-- Input : ES = address of PSP +;-- Output : none +;-- Register : AX, BX, CL and FLAGS are changed +;-- Info : Since the stack-segment is always the last segment in an +; EXE-file, ES:0000 points to the beginning and SS:SP +; to the end of the program in memory. Through this the +; length of the program can be calculated +; call this routine once at the beginning of the program to free up memory +; assigned to it by DOS. + +setFree: + mov bx, 65536/16 ; 4K paragraphs ; 17/02/2017 (Erdogan Tan) + + mov ah, 4Ah ; pass new length to DOS + int 21h + + retn ; back to caller + ; new size (allocated memory) = 64KB + +memAlloc: +; input: AX = # of paragraphs required +; output: AX = segment of block to use + + push bx + mov bx, ax + mov ah, 48h + int 21h + pop bx + retn + +; ---- + +; ///// + + ; 30/05/2024 (ich_wav4.asm, 19/05/2024) +loadFromFile: + ; 07/11/2023 + + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff_0 ; no + stc + retn + +lff_0: + ; 08/11/2023 + mov bp, ax ; save buffer segment + + ; 17/11/2024 + mov bx, [filehandle] + + ; 17/11/2024 + mov cx, [loadsize] + xor di, di ; 0 + + ;mov cl, [fbs_shift] + ;and cl, cl + ;jz short lff_1 ; stereo, 16 bit + ; 17/11/2024 + cmp byte [fbs_shift], 0 + jna short lff_1 ; stereo, 16 bit + + ;mov di, BUFFERSIZE - 1 ; 65535 + + ;; fbs_shift = + ;; 2 for mono and 8 bit sample (multiplier = 4) + ;; 1 for mono or 8 bit sample (multiplier = 2) + ;shr di, cl + ;inc di ; 16384 for 8 bit and mono + ; ; 32768 for 8 bit or mono + + ; 17/11/2024 + ;mov cx, [loadsize] ; 16380 or 32760 + + ;mov ax, cs + mov dx, temp_buffer ; temporary buffer for wav data + + ; 17/02/2017 (stereo/mono, 8bit/16bit corrections) + ; load file into memory + ;mov cx, di ; 17/11/2024 + ;mov bx, [filehandle] ; 17/11/2024 + ;mov ds, ax + mov ah, 3Fh + int 21h + + ;mov bx, cs + ;mov ds, bx + ; 17/11/2024 + ;push cs + ;pop ds + + jc lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + + ; 17/11/2024 + ; 08/11/2023 + ;xor dx, dx ; 0 + + and ax, ax + jz short lff_3 + + mov bl, [fbs_shift] + + push es + ;mov di, dx ; 0 ; [fbs_off] + ; 17/11/2024 + ; di = 0 + ;mov bp, [fbs_seg] ; buffer segment + mov es, bp + mov si, temp_buffer ; temporary buffer address + mov cx, ax ; byte count + cmp byte [WAVE_BitsPerSample], 8 ; bits per sample (8 or 16) + jne short lff_7 ; 16 bit samples + ; 8 bit samples + dec bl ; shift count, 1 = stereo, 2 = mono + jz short lff_6 ; 8 bit, stereo +lff_5: + ; mono & 8 bit + lodsb + sub al, 80h ; 08/11/2023 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; left channel + stosw ; right channel + loop lff_5 + jmp short lff_9 +lff_6: + ; stereo & 8 bit + lodsb + sub al, 80h ; 08/11/2023 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw + loop lff_6 + jmp short lff_9 +lff_7: + shr cx, 1 ; word count +lff_8: + lodsw + stosw ; left channel + stosw ; right channel + loop lff_8 +lff_9: + pop es + + ;or di, di + ;jz short endLFF ; 64KB ok + ;mov ax, di ; [fbs_off] + ;dec ax + ; 17/11/2024 + mov ax, di + ;cmp ax, BUFFERSIZE ; 65520 + ;jnb short endLFF + + ;mov cx, BUFFERSIZE - 1 ; 65535 + ; 17/11/2024 + mov cx, BUFFERSIZE + ; 17/11/2024 + ; ax = di + cmp ax, cx + ;jnb short endLFF + ;jmp short lff_3 + jb short lff_3 + retn + +lff_1: + ;mov bp, ax ; save buffer segment + xor dx, dx + ; load file into memory + ;mov cx, (BUFFERSIZE / 2) ; 32k chunk + + ; 17/11/2024 + ;mov cx, [buffersize] ; BUFFERSIZE / 2 + ; 17/11/2024 (*) + ; cx = [loadsize] = 2*[buffersize] + + ;mov bx, [filehandle] ; 17/11/2024 + mov ds, ax ; mov ds, bp + mov ah, 3Fh + int 21h + + ;mov di, cs + ;mov ds, di + ; 17/11/2024 + push cs + pop ds + + ; 07/11/2023 + jc short lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + ; 17/11/2024 + ; di = 0 + +; 17/11/2024 (*) +if 0 + cmp ax, cx + jne short lff_3 +lff_2: + ; 08/11/2023 + add dx, ax + ;;mov cx, (BUFFERSIZE / 2) ; 32k chunk + ;mov cx, [buffersize] ; BUFFERSIZE / 2 + ;mov bx, [filehandle] + mov ds, bp + mov ah, 3Fh + int 21h + + ;;mov di, cs + ;mov ds, di + ; 17/11/2024 + push cs + pop ds + + jc short lff_4 ; error ! + + ; 17/11/2024 + ; 14/11/2024 + add [count], ax +end if + + cmp ax, cx + je short endLFF + ; 17/11/2024 + ; di = 0 + mov di, ax +lff_3: + call padfill ; blank pad the remainder + ;clc ; don't exit with CY yet. + or byte [flags], ENDOFFILE ; end of file flag +endLFF: + retn +lff_4: + ; 08/11/2023 + mov al, '!' ; error + call tL0 + + xor ax, ax + jmp short lff_3 + +; entry ds:ax points to last byte in file +; cx = target size +; note: must do byte size fill +; destroys bx, cx +; +padfill: + ; 14/12/2024 + ; 17/11/2024 + ; di = offset (to be filled with ZEROs) + ; bp = buffer segment + ; ax = di = number of bytes loaded + ; cx = buffer size (> loaded bytes) + ; 07/11/2023 + ; 06/11/2023 + ; 17/02/2017 + push es + ;push di + ;mov di, [fbs_seg] + ;mov es, di + mov es, bp + sub cx, ax + ; 08/11/2023 + ;mov di, ax ; (wrong) + ; 17/11/2024 + ;mov di, dx ; buffer offset + ;add di, ax + ; 07/11/2023 + ;add di, [fbs_off] + ; 25/11/2024 + xor ax, ax + ; 14/12/2024 + rep stosb + ;mov [fbs_off], di + ;pop di + pop es + retn +; ///// + +write_audio_dev_info: + ; 30/05/2024 + sys_msg msgAudioCardInfo, 0Fh + retn + +write_ac97_pci_dev_info: + ; 19/11/2024 + ; 30/05/2024 + ; 06/06/2017 + ; 03/06/2017 + ; BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + mov eax, [dev_vendor] + xor bh, bh + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId], al + shr eax, 16 + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId], al + + mov eax, [bus_dev_fn] + shr eax, 8 + mov bl, al + mov dl, bl + and bl, 7 ; bit 0,1,2 + mov al, [bx+hex_chars] + mov [msgFncNo+1], al + mov bl, dl + shr bl, 3 + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevNo], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBusNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBusNo], al + + ;mov ax, [ac97_NamBar] + mov ax, [NAMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNamBar+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNamBar+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNamBar+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNamBar], al + + ;mov ax, [ac97_NabmBar] + mov ax, [NABMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNabmBar+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNabmBar+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNabmBar+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNabmBar], al + + xor eax, eax + mov al, [ac97_int_ln_reg] + mov cl, 10 + div cl + ; 23/11/2024 + ;add [msgIRQ], ax + add ax, 3030h + mov [msgIRQ], ax + ;and al, al + cmp al, 30h + jnz short _w_ac97imsg_ + mov al, byte [msgIRQ+1] + mov ah, ' ' + mov [msgIRQ], ax +_w_ac97imsg_: + ; 19/11/2024 + call clear_window + mov dh, 13 + mov dl, 0 + call setCursorPosition + ;;; + ; 30/05/2024 + sys_msg msgAC97Info, 07h + + ; 19/11/2024 + ;retn + + ; 30/05/2024 +write_VRA_info: + sys_msg msgVRAheader, 07h + cmp byte [VRA], 0 + jna short _w_VRAi_no +_w_VRAi_yes: + sys_msg msgVRAyes, 07h + retn +_w_VRAi_no: + sys_msg msgVRAno, 07h + retn + +; 30/05/2024 (playwav6.asm) +; 18/11/2023 (ich_wav3.asm & ich_wav4.asm) +; 15/11/2023 (ich_wav3.asm) +; 14/11/2023 +; 13/11/2023 - Erdogan Tan - (VRA, sample rate conversion) +; -------------------------------------------------------- + +;;Note: At the end of every buffer load, +;; during buffer switch/swap, there will be discontinuity +;; between the last converted sample and the 1st sample +;; of the next buffer. +;; (like as a dot noises vaguely between normal sound samples) +;; -To avoid this defect, the 1st sample of +;; the next buffer may be read from the wav file but +;; the file pointer would need to be set to 1 sample back +;; again via seek system call. Time comsumption problem! - +;; +;; Erdogan Tan - 15/11/2023 +;; +;; ((If entire wav data would be loaded at once.. conversion +;; defect/noise would disappear.. but for DOS, to keep +;; 64KB buffer limit is important also it is important +;; for running under 1MB barrier without HIMEM.SYS or DPMI. +;; I have tested this program by using 2-30MB wav files.)) +;; +;; Test Computer: ASUS desktop/mainboard, M2N4-SLI, 2010. +;; AMD Athlon 64 X2 2200 MHZ CPU. +;; NFORCE4 (CK804) AC97 audio hardware. +;; Realtek ALC850 codec. +;; Retro DOS v4.2 (MSDOS 6.22) operating system. + +load_8khz_mono_8_bit: + ; 15/11/2023 + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8m_0 ; no + stc + retn + +lff8m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + ;jc short lff8m_5 ; error ! + ; 14/11/2023 + jnc short lff8m_6 + jmp lff8m_5 + +lff8m_6: + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + and ax, ax + ;jz short lff8m_3 + ; 15/11/2023 + jz short lff8_eof + + mov cx, ax ; byte count +lff8m_1: + lodsb + mov [previous_val], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + ; 14/11/2023 + mov al, 80h + dec cx + jz short lff8m_2 + mov al, [si] +lff8m_2: + ;mov [next_val], ax + mov bh, al ; [next_val] + mov ah, [previous_val] + add al, ah ; [previous_val] + rcr al, 1 + mov dl, al ; this is interpolated middle (3th) sample + add al, ah ; [previous_val] + rcr al, 1 + mov bl, al ; this is temporary interpolation value + add al, ah ; [previous_val] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + mov al, dl + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (L) + stosw ; this is middle (3th) interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, dl + rcr al, 1 + mov bl, al ; this is temporary interpolation value + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (L) + stosw ; this is 4th interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (L) + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff8m_1 + + ; -------------- + +lff8s_3: +lff8m_3: +lff8s2_3: +lff8m2_3: +lff16s_3: +lff16m_3: +lff16s2_3: +lff16m2_3: +lff24_3: +lff32_3: +lff44_3: +lff22_3: +lff11_3: + mov cx, [buffersize] ; 16 bit (48 kHZ, stereo) sample size + shl cx, 1 ; byte count + sub cx, di + jna short lff8m_4 + ;inc cx + shr cx, 1 + xor ax, ax ; fill (remain part of) buffer with zeros + rep stosw +lff8m_4: + push cs + pop es + retn + +lff8_eof: +lff16_eof: +lff24_eof: +lff32_eof: +lff44_eof: +lff22_eof: +lff11_eof: + ; 15/11/2023 + mov byte [flags], ENDOFFILE + jmp short lff8m_3 + +lff8s_5: +lff8m_5: +lff8s2_5: +lff8m2_5: +lff16s_5: +lff16m_5: +lff16s2_5: +lff16m2_5: +lff24_5: +lff32_5: +lff44_5: +lff22_5: +lff11_5: + mov al, '!' ; error + call tL0 + + ;jmp short lff8m_3 + ; 15/11/2023 + jmp lff8_eof + + ; -------------- + +load_8khz_stereo_8_bit: + ; 15/11/2023 + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8s_0 ; no + stc + retn + +lff8s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8s_5 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;;and ax, ax + ;jz short lff8s_3 + ; 15/11/2023 + jz short lff8_eof + + mov cx, ax ; word count +lff8s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + ; 14/11/2023 + mov ax, 8080h + dec cx + jz short lff8s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff8s_2: + mov [next_val_l], al + mov [next_val_r], ah + mov ah, [previous_val_l] + add al, ah + rcr al, 1 + mov dl, al ; this is interpolated middle (3th) sample (L) + add al, ah + rcr al, 1 + mov bl, al ; this is temporary interpolation value (L) + add al, ah + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + mov al, [next_val_r] + mov ah, [previous_val_r] + add al, ah + rcr al, 1 + mov dh, al ; this is interpolated middle (3th) sample (R) + add al, ah + rcr al, 1 + mov bh, al ; this is temporary interpolation value (R) + add al, ah + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + mov al, bh + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (R) + mov al, dl + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (L) + mov al, dh + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (R) + mov al, [next_val_l] + add al, dl + rcr al, 1 + mov bl, al ; this is temporary interpolation value (L) + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (L) + mov al, [next_val_r] + add al, dh + rcr al, 1 + mov bh, al ; this is temporary interpolation value (R) + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (R) + mov al, [next_val_l] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (L) + mov al, [next_val_r] + add al, bh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + jcxz lff8s_6 + jmp lff8s_1 +lff8s_6: + jmp lff8s_3 + +load_8khz_mono_16_bit: + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8m2_0 ; no + stc + retn + +lff8m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff8m2_8 + ;jmp lff8m2_3 + ; 15/11/2023 + jmp lff8_eof + +lff8m2_8: + mov cx, ax ; word count +lff8m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val], ax + xor ax, ax + dec cx + jz short lff8m2_2 + mov ax, [si] +lff8m2_2: + add ah, 80h ; convert sound level to 0-65535 format + mov bp, ax ; [next_val] + add ax, [previous_val] + rcr ax, 1 + mov dx, ax ; this is interpolated middle (3th) sample + add ax, [previous_val] + rcr ax, 1 ; this is temporary interpolation value + mov bx, ax + add ax, [previous_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov ax, bx + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + mov ax, dx + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is middle (3th) interpolated sample (L) + stosw ; this is middle (3th) interpolated sample (R) + mov ax, bp + add ax, dx + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (L) + stosw ; this is 4th interpolated sample (R) + mov ax, bp + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 5th interpolated sample (L) + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff8m2_1 + jmp lff8m2_3 + +lff8m2_7: +lff8s2_7: + jmp lff8m2_5 ; error + +load_8khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8s2_0 ; no + stc + retn + +lff8s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff8s2_8 + ;jmp lff8s2_3 + ; 15/11/2023 + jmp lff8_eof + +lff8s2_8: + mov cx, ax ; dword count +lff8s2_1: + lodsw + stosw ; original sample (L) + ; 15/11/2023 + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val_r], ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff8s2_2 + mov ax, [si] + mov dx, [si+2] +lff8s2_2: + add ah, 80h ; convert sound level to 0-65535 format + mov [next_val_l], ax + add dh, 80h ; convert sound level to 0-65535 format + mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + mov dx, ax ; this is interpolated middle (3th) sample (L) + add ax, [previous_val_l] + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (L) + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + mov ax, [next_val_r] + add ax, [previous_val_r] + rcr ax, 1 + mov bp, ax ; this is interpolated middle (3th) sample (R) + add ax, [previous_val_r] + rcr ax, 1 + push ax ; * ; this is temporary interpolation value (R) + add ax, [previous_val_r] + rcr ax, 1 + sub ah, 80h + stosw ; this is 1st interpolated sample (R) + mov ax, bx + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + pop ax ; * + add ax, bp + rcr ax, 1 + sub ah, 80h + stosw ; this is 2nd interpolated sample (R) + mov ax, dx + sub ah, 80h + stosw ; this is middle (3th) interpolated sample (L) + mov ax, bp + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is middle (3th) interpolated sample (R) + mov ax, [next_val_l] + add ax, dx + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (L) + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (L) + mov ax, [next_val_r] + add ax, bp + rcr ax, 1 + push ax ; ** ; this is temporary interpolation value (R) + add ax, bp + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (R) + mov ax, [next_val_l] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 5th interpolated sample (L) + pop ax ; ** + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + jcxz lff8_s2_9 + jmp lff8s2_1 +lff8_s2_9: + jmp lff8s2_3 + +; ..................... + +load_16khz_mono_8_bit: + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16m_0 ; no + stc + retn + +lff16m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff16m_8 + ;jmp lff16m_3 + ; 15/11/2023 + jmp lff16_eof + +lff16m_8: + mov cx, ax ; byte count +lff16m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + ; 14/11/22023 + mov al, 80h + dec cx + jz short lff16m_2 + mov al, [si] +lff16m_2: + ;mov [next_val], al + mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + mov dl, al ; this is interpolated middle (temp) sample + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16m_1 + jmp lff16m_3 + +lff16m_7: +lff16s_7: + jmp lff16m_5 ; error + +load_16khz_stereo_8_bit: + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16s_0 ; no + stc + retn + +lff16s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff16s_8 + ;jmp lff16s_3 + ; 15/11/2023 + jmp lff16_eof + +lff16s_8: + mov cx, ax ; word count +lff16s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + ; 14/11/2023 + mov ax, 8080h + dec cx + jz short lff16s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff16s_2: + ;mov [next_val_l], al + ;mov [next_val_r], ah + mov bx, ax + add al, [previous_val_l] + rcr al, 1 + mov dl, al ; this is temporary interpolation value (L) + add al, [previous_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + mov dh, al ; this is temporary interpolation value (R) + add al, [previous_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (R) + mov al, dl + add al, bl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + mov al, dh + add al, bh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16s_1 + jmp lff16s_3 + +load_16khz_mono_16_bit: + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16m2_0 ; no + stc + retn + +lff16m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff16m2_8 + ;jmp lff16m2_3 + ; 15/11/2023 + jmp lff16_eof + +lff16m2_8: + mov cx, ax ; word count +lff16m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + mov bx, ax + xor ax, ax + dec cx + jz short lff16m2_2 + mov ax, [si] +lff16m2_2: + add ah, 80h ; convert sound level 0 to 65535 format + mov bp, ax ; [next_val] + ;add ax, [previous_val] + add ax, bx + rcr ax, 1 + mov dx, ax ; this is temporary interpolation value + ;add ax, [previous_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov ax, bp + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + ; 16 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16m2_1 + jmp lff16m2_3 + +lff16m2_7: +lff16s2_7: + jmp lff16m2_5 ; error + +load_16khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16s2_0 ; no + stc + retn + +lff16s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + ;shr ax, 1 + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff16s2_8 + ;jmp lff16s2_3 + ; 15/11/2023 + jmp lff16_eof + +lff16s2_8: + mov cx, ax ; dword count +lff16s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_r], ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff16s2_2 + mov ax, [si] + mov dx, [si+2] +lff16s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_l], ax + mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + mov dx, ax ; this is temporary interpolation value (L) + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + mov ax, [next_val_r] + add ax, [previous_val_r] + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (R) + add ax, [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (R) + ;mov ax, [next_val_l] + mov ax, bp + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + mov ax, [next_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16s2_1 + jmp lff16s2_3 + +; ..................... + +load_24khz_mono_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24m_0 ; no + stc + retn + +lff24m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff24m_8 + jmp lff24_eof + +lff24m_8: + mov cx, ax ; byte count +lff24m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + mov al, 80h + dec cx + jz short lff24m_2 + mov al, [si] +lff24m_2: + ;;mov [next_val], al + ;mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; 24 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24m_1 + jmp lff24_3 + +lff24m_7: +lff24s_7: + jmp lff24_5 ; error + +load_24khz_stereo_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24s_0 ; no + stc + retn + +lff24s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff24s_8 + jmp lff24_eof + +lff24s_8: + mov cx, ax ; word count +lff24s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + mov ax, 8080h + dec cx + jz short lff24s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff24s_2: + ;;mov [next_val_l], al + ;;mov [next_val_r], ah + ;mov bx, ax + mov bh, ah + add al, [previous_val_l] + rcr al, 1 + ;mov dl, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + ;mov dh, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (R) + + ; 24 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24s_1 + jmp lff24_3 + +load_24khz_mono_16_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24m2_0 ; no + stc + retn + +lff24m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff24m2_8 + jmp lff24_eof + +lff24m2_8: + mov cx, ax ; word count +lff24m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + ;mov bx, ax + ;xor ax, ax + xor bx, bx + dec cx + jz short lff24m2_2 + ;mov ax, [si + mov bx, [si] +lff24m2_2: + ;add ah, 80h ; convert sound level 0 to 65535 format + ;mov bp, ax ; [next_val] + ;add ax, [previous_val] + ; ax = [previous_val] + ; bx = [next_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + ; 24 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24m2_1 + jmp lff24_3 + +lff24m2_7: +lff24s2_7: + jmp lff24_5 ; error + +load_24khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24s2_0 ; no + stc + retn + +lff24s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + ;shr ax, 1 + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff24s2_8 + jmp lff24_eof + +lff24s2_8: + mov cx, ax ; dword count +lff24s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val_r], ax + mov bx, ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff24s2_2 + mov ax, [si] + mov dx, [si+2] +lff24s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;;mov [next_val_l], ax + ;mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + ;mov ax, [next_val_r] + mov ax, dx + ;add ax, [previous_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (R) + + ; 24 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24s2_1 + jmp lff24_3 + +; ..................... + +load_32khz_mono_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32m_0 ; no + stc + retn + +lff32m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff32m_8 + jmp lff32_eof + +lff32m_8: + mov cx, ax ; byte count +lff32m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + mov al, 80h + dec cx + jz short lff32m_2 + mov al, [si] +lff32m_2: + ;;mov [next_val], al + ;mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32m_3 + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (left channel) + stosw ; original sample (right channel) + + ; 32 kHZ mono to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32m_1 +lff32m_3: + jmp lff32_3 + +lff32m_7: +lff32s_7: + jmp lff32_5 ; error + +load_32khz_stereo_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32s_0 ; no + stc + retn + +lff32s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff32s_8 + jmp lff32_eof + +lff32s_8: + mov cx, ax ; word count +lff32s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + mov ax, 8080h + dec cx + jz short lff32s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff32s_2: + ;;mov [next_val_l], al + ;;mov [next_val_r], ah + ;mov bx, ax + mov bh, ah + add al, [previous_val_l] + rcr al, 1 + ;mov dl, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + ;mov dh, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32s_3 + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (left channel) + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (right channel) + + ; 32 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32s_1 +lff32s_3: + jmp lff32_3 + +load_32khz_mono_16_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32m2_0 ; no + stc + retn + +lff32m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff32m2_8 + jmp lff32_eof + +lff32m2_8: + mov cx, ax ; word count +lff32m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + ;mov bx, ax + ;xor ax, ax + xor bx, bx + dec cx + jz short lff32m2_2 + ;mov ax, [si + mov bx, [si] +lff32m2_2: + ;add ah, 80h ; convert sound level 0 to 65535 format + ;mov bp, ax ; [next_val] + ;add ax, [previous_val] + ; ax = [previous_val] + ; bx = [next_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32m2_3 + + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + + ; 32 kHZ mono to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32m2_1 +lff32m2_3: + jmp lff32_3 + +lff32m2_7: +lff32s2_7: + jmp lff32_5 ; error + +load_32khz_stereo_16_bit: + ;16/11/2023 + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32s2_0 ; no + stc + retn + +lff32s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; 16/11/2023 (word left ch + word right ch) + ;and ax, ax + jnz short lff32s2_8 + jmp lff32_eof + +lff32s2_8: + mov cx, ax ; dword count +lff32s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val_r], ax + mov bx, ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff32s2_2 + mov ax, [si] + mov dx, [si+2] +lff32s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;;mov [next_val_l], ax + ;mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + ;mov ax, [next_val_r] + mov ax, dx + ;add ax, [previous_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32s2_3 + + lodsw + stosw ; original sample (L) + lodsw + stosw ; original sample (R) + + ; 32 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32s2_1 +lff32s2_3: + jmp lff32_3 + +; ..................... + +load_22khz_mono_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22m_0 ; no + stc + retn + +lff22m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff22m_8 + jmp lff22_eof + +lff22m_8: + mov cx, ax ; byte count +lff22m_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phases +lff22m_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsb + mov dl, 80h + dec cx + jz short lff22m_2_1 + mov dl, [si] +lff22m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_3_8bit_mono ; 1 of 17 + jcxz lff22m_3 +lff22m_2_2: + lodsb + mov dl, 80h + dec cx + jz short lff22m_2_3 + mov dl, [si] +lff22m_2_3: + call interpolating_2_8bit_mono ; 2 of 17 .. 6 of 17 + jcxz lff22m_3 + dec bp + jnz short lff22m_2_2 + + mov al, [faz] + dec al + jz short lff22m_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22m_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22m_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +lff22m_3: +lff22s_3: + jmp lff22_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff22m_7: +lff22s_7: + jmp lff22_5 ; error + +load_22khz_stereo_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22s_0 ; no + stc + retn + +lff22s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff22s_8 + jmp lff22_eof + +lff22s_8: + mov cx, ax ; word count +lff22s_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phase +lff22s_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + mov dx, 8080h + dec cx + jz short lff22s_2_1 + mov dx, [si] +lff22s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_3_8bit_stereo ; 1 of 17 + jcxz lff22s_3 +lff22s_2_2: + lodsw + mov dx, 8080h + dec cx + jz short lff22s_2_3 + mov dx, [si] +lff22s_2_3: + call interpolating_2_8bit_stereo ; 2 of 17 .. 6 of 17 + jcxz lff22s_3 + dec bp + jnz short lff22s_2_2 + + mov al, [faz] + dec al + jz short lff22s_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22s_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22s_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +load_22khz_mono_16_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22m2_0 ; no + stc + retn + +lff22m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff22m2_8 + jmp lff22_eof + +lff22m2_8: + mov cx, ax ; word count +lff22m2_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phases +lff22m2_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + xor dx, dx + dec cx + jz short lff22m2_2_1 + mov dx, [si] +lff22m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_3_16bit_mono ; 1 of 17 + jcxz lff22m2_3 +lff22m2_2_2: + lodsw + xor dx, dx + dec cx + jz short lff22m2_2_3 + mov dx, [si] +lff22m2_2_3: + call interpolating_2_16bit_mono ; 2 of 17 .. 6 of 17 + jcxz lff22m2_3 + dec bp + jnz short lff22m2_2_2 + + mov al, [faz] + dec al + jz short lff22m2_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22m2_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22m2_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +lff22m2_3: +lff22s2_3: + jmp lff22_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff22m2_7: +lff22s2_7: + jmp lff22_5 ; error + +load_22khz_stereo_16_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22s2_0 ; no + stc + retn + +lff22s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff22s2_8 + jmp lff22_eof + +lff22s2_8: + mov cx, ax ; dword count +lff22s2_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phase +lff22s2_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff22s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx +lff22s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_3_16bit_stereo ; 1 of 17 + jcxz lff22s2_3 +lff22s2_2_2: + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff22s2_2_3 + xor dx, dx ; 0 + mov [next_val_l], dx +lff22s2_2_3: + call interpolating_2_16bit_stereo ; 2 of 17 .. 6 of 17 + jcxz lff22s2_3 + dec bp + jnz short lff22s2_2_2 + + mov al, [faz] + dec al + jz short lff22s2_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22s2_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22s2_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +; ..................... + +load_11khz_mono_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11m_0 ; no + stc + retn + +lff11m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff11m_8 + jmp lff11_eof + +lff11m_8: + mov cx, ax ; byte count +lff11m_9: + mov bp, 6 ; interpolation (one step) loop count +lff11m_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_1 + mov dl, [si] +lff11m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_5_8bit_mono + jcxz lff11m_3 +lff11m_2_2: + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_3 + mov dl, [si] +lff11m_2_3: + call interpolating_4_8bit_mono + jcxz lff11m_3 + + dec bp + jz short lff11m_9 + + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_4 + mov dl, [si] +lff11m_2_4: + call interpolating_4_8bit_mono + jcxz lff11m_3 + jmp short lff11m_1 + +lff11m_3: +lff11s_3: + jmp lff11_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff11m_7: +lff11s_7: + jmp lff11_5 ; error + +load_11khz_stereo_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11s_0 ; no + stc + retn + +lff11s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff11s_8 + jmp lff11_eof + +lff11s_8: + mov cx, ax ; word count +lff11s_9: + mov bp, 6 ; interpolation (one step) loop count +lff11s_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_1 + mov dx, [si] +lff11s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_5_8bit_stereo + jcxz lff11s_3 +lff11s_2_2: + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_3 + mov dx, [si] +lff11s_2_3: + call interpolating_4_8bit_stereo + jcxz lff11s_3 + + dec bp + jz short lff11s_9 + + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_4 + mov dx, [si] +lff11s_2_4: + call interpolating_4_8bit_stereo + jcxz lff11s_3 + jmp short lff11s_1 + +load_11khz_mono_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11m2_0 ; no + stc + retn + +lff11m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff11m2_8 + jmp lff11_eof + +lff11m2_8: + mov cx, ax ; word count +lff11m2_9: + mov bp, 6 ; interpolation (one step) loop count +lff11m2_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_1 + mov dx, [si] +lff11m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_5_16bit_mono + jcxz lff11m2_3 +lff11m2_2_2: + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_3 + mov dx, [si] +lff11m2_2_3: + call interpolating_4_16bit_mono + jcxz lff11m2_3 + + dec bp + jz short lff11m2_9 + + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_4 + mov dx, [si] +lff11m2_2_4: + call interpolating_4_16bit_mono + jcxz lff11m2_3 + jmp short lff11m2_1 + +lff11m2_7: +lff11s2_7: + jmp lff11_5 ; error + +load_11khz_stereo_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11s2_0 ; no + stc + retn + +lff11s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff11s2_8 + jmp lff11_eof + +lff11m2_3: +lff11s2_3: + jmp lff11_3 ; padfill + ; (put zeros in the remain words of the buffer) + +lff11s2_8: + mov cx, ax ; dword count +lff11s2_9: + mov bp, 6 ; interpolation (one step) loop count +lff11s2_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_5_16bit_stereo + jcxz lff11s2_3 +lff11s2_2_2: + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_3 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_3: + call interpolating_4_16bit_stereo + jcxz lff11s2_3 + + dec bp + jz short lff11s2_9 + + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_4 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_4: + call interpolating_4_16bit_stereo + jcxz lff11s2_3 + jmp short lff11s2_1 + +; ..................... + +load_44khz_mono_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44m_0 ; no + stc + retn + +lff44m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff44m_8 + jmp lff44_eof + +lff44m_8: + mov cx, ax ; byte count +lff44m_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phases +lff44m_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsb + mov dl, 80h + dec cx + jz short lff44m_2_1 + mov dl, [si] +lff44m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_2_8bit_mono + jcxz lff44m_3 +lff44m_2_2: + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (L) + stosw ; (R) + + dec cx + jz short lff44m_3 + dec bp + jnz short lff44m_2_2 + + dec byte [faz] + jz short lff44m_9 + mov bp, 11 + jmp short lff44m_1 + +lff44m_3: +lff44s_3: + jmp lff44_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff44m_7: +lff44s_7: + jmp lff44_5 ; error + +load_44khz_stereo_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44s_0 ; no + stc + retn + +lff44s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff44s_8 + jmp lff44_eof + +lff44s_8: + mov cx, ax ; word count +lff44s_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phase +lff44s_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + mov dx, 8080h + dec cx + jz short lff44s_2_1 + mov dx, [si] +lff44s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_2_8bit_stereo + jcxz lff44s_3 +lff44s_2_2: + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (L) + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (R) + + dec cx + jz short lff44s_3 + dec bp + jnz short lff44s_2_2 + + dec byte [faz] + jz short lff44s_9 + mov bp, 11 + jmp short lff44s_1 + +load_44khz_mono_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44m2_0 ; no + stc + retn + +lff44m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff44m2_8 + jmp lff44_eof + +lff44m2_8: + mov cx, ax ; word count +lff44m2_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phases +lff44m2_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + xor dx, dx + dec cx + jz short lff44m2_2_1 + mov dx, [si] +lff44m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_2_16bit_mono + jcxz lff44m2_3 +lff44m2_2_2: + lodsw + stosw ; (L)eft Channel + stosw ; (R)ight Channel + + dec cx + jz short lff44m2_3 + dec bp + jnz short lff44m2_2_2 + + dec byte [faz] + jz short lff44m2_9 + mov bp, 11 + jmp short lff44m2_1 + +lff44m2_3: +lff44s2_3: + jmp lff44_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff44m2_7: +lff44s2_7: + jmp lff44_5 ; error + +load_44khz_stereo_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44s2_0 ; no + stc + retn + +lff44s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff44s2_8 + jmp lff44_eof + +lff44s2_8: + mov cx, ax ; dword count +lff44s2_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phase +lff44s2_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff44s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx +lff44s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_2_16bit_stereo + jcxz lff44s2_3 +lff44s2_2_2: + ;lodsw + ;stosw ; (L) + ;lodsw + ;stosw ; (R) + movsw ; (L)eft Channel + movsw ; (R)ight Channel + + dec cx + jz short lff44s2_3 + dec bp + jnz short lff44s2_2_2 + + dec byte [faz] + jz short lff44s2_9 + mov bp, 11 + jmp short lff44s2_1 + +; ..................... + +interpolating_3_8bit_mono: + ; 16/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + mov bh, al ; interpolated middle (temporary) + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bh + add al, dl ; [next_val] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + retn + +interpolating_3_8bit_stereo: + ; 16/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + push ax ; * ; al = interpolated middle (L) (temporary) + add al, bl ; [previous_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + push ax ; ** ; al = interpolated middle (R) (temporary) + add al, bh ; [previous_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + pop bx ; ** + pop ax ; * + add al, dl ; [next_val_l] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bl + add al, dh ; [next_val_r] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (R) + retn + +interpolating_2_8bit_mono: + ; 16/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (L) + stosw ; interpolated sample (R) + retn + +interpolating_2_8bit_stereo: + ; 16/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl ; [previous_val_l] + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (R) + retn + +interpolating_3_16bit_mono: + ; 16/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val] + add dh, 80h + add ax, dx + rcr ax, 1 + pop bx ; * + xchg bx, ax ; bx = interpolated middle (temporary) + add ax, bx ; [previous_val] + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov ax, bx + add ax, dx ;interpolated middle + [next_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + retn + +interpolating_3_16bit_stereo: + ; 16/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + ; original-interpolated-interpolated + + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + xchg ax, bx ; ax = [previous_val_l] + add ax, bx ; bx = interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + pop ax ; * + add dh, 80h ; convert sound level 0 to 65535 format + push dx ; * ; [next_val_r] + xchg ax, dx + add ax, dx ; [next_val_r] + [previous_val_r] + rcr ax, 1 ; / 2 + push ax ; ** ; interpolated middle (R) + add ax, dx ; + [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, [next_val_l] + add ax, bx ; + interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + pop ax ; ** + pop dx ; * + add ax, dx ; interpolated middle + [next_val_r] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + retn + + +interpolating_2_16bit_mono: + ; 16/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + add dh, 80h + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (L) + stosw ; interpolated sample (R) + retn + +interpolating_2_16bit_stereo: + ; 16/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + ; original-interpolated + + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + add dh, 80h + add ax, dx ; [previous_val_r] + [next_val_r] + rcr ax, 1 ; / 2 + push ax ; * ; interpolated sample (R) + mov ax, [next_val_l] + add ah, 80h + add bh, 80h + add ax, bx ; [next_val_l] + [previous_val_l] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (L) + pop ax ; * + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (R) + retn + +interpolating_5_8bit_mono: + ; 17/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpltd-interpltd-interpltd-interpltd + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + mov bh, al ; interpolated middle (temporary) + add al, bl ; [previous_val] + rcr al, 1 + mov dh, al ; interpolated 1st quarter (temporary) + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bh + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov al, bh + add al, dl ; [next_val] + rcr al, 1 + mov dh, al ; interpolated 3rd quarter (temporary) + add al, bh + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + mov al, dh + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (L) + stosw ; interpolated sample 4 (R) + retn + +interpolating_5_8bit_stereo: + ; 17/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpltd-interpltd-interpltd-interpltd + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + push dx ; * + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + push ax ; ** ; al = interpolated middle (L) (temporary) + add al, bl ; [previous_val_l] + rcr al, 1 + xchg al, bl + add al, bl ; bl = interpolated 1st quarter (L) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + push ax ; *** ; al = interpolated middle (R) (temporary) + add al, bh ; [previous_val_r] + rcr al, 1 + xchg al, bh + add al, bh ; bh = interpolated 1st quarter (R) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + pop dx ; *** + pop ax ; ** ; al = interpolated middle (L) (temporary) + xchg al, bl ; al = interpolated 1st quarter (L) (temp) + add al, bl ; bl = interpolated middle (L) (temporary) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, dl ; interpolated middle (R) (temporary) + xchg al, bh ; al = interpolated 1st quarter (R) (temp) + add al, bh ; bh = interpolated middle (R) (temporary) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (R) + pop dx ; * + mov al, bl ; interpolated middle (L) (temporary) + add al, dl ; [next_val_l] + rcr al, 1 + xchg al, bl ; al = interpolated middle (R) (temporary) + add al, bl ; bl = interpolated 3rd quarter (L) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + mov al, bh + add al, dh ; interpolated middle (R) + [next_val_r] + rcr al, 1 + xchg al, bh ; al = interpolated middle (R) + add al, bh ; bh = interpolated 3rd quarter (R) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (R) + retn + +interpolating_4_8bit_mono: + ; 17/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated-interpolated-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + xchg al, bl ; al = [previous_val] + add al, bl ; bl = interpolated middle (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bl ; interpolated middle (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov al, bl + add al, dl ; [next_val] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + retn + +interpolating_4_8bit_stereo: + ; 17/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated-interpolated-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + xchg al, bl ; al = [previous_val_l] + add al, bl ; bl = interpolated middle (L) (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + xchg al, bh ; al = [previous_val_h] + add al, bh ; bh = interpolated middle (R) (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + mov al, bl ; interpolated middle (L) (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bh ; interpolated middle (L) (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (R) + retn + +interpolating_5_16bit_mono: + ; 18/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpltd-interpltd-interpltd-interpltd + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov bx, ax ; [previous_val] + add dh, 80h + add ax, dx + rcr ax, 1 + push ax ; * ; interpolated middle (temporary) + add ax, bx ; interpolated middle + [previous_val] + rcr ax, 1 + push ax ; ** ; interpolated 1st quarter (temporary) + add ax, bx ; 1st quarter + [previous_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + pop ax ; ** + pop bx ; * + add ax, bx ; 1st quarter + middle + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, dx ; interpolated middle + [next_val] + rcr ax, 1 + push ax ; * ; interpolated 3rd quarter (temporary) + add ax, bx ; + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + pop ax ; * + add ax, dx ; 3rd quarter + [next_val] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (L) + stosw ; interpolated sample 4 (R) + retn + +interpolating_5_16bit_stereo: + ; 18/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; [next_val_r] + ; original-interpltd-interpltd-interpltd-interpltd + push cx ; ! + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + mov cx, ax ; interpolated middle (L) + add ax, bx + rcr ax, 1 + mov dx, ax ; interpolated 1st quarter (L) + add ax, bx ; [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + mov ax, cx + add ax, dx ; middle (L) + 1st quarter (L) + rcr ax, 1 ; / 2 + mov bx, ax ; interpolated sample 2 (L) + pop dx ; * ; [previous_val_r] + mov ax, dx + add byte [next_val_r+1], 80h + add ax, [next_val_r] + rcr ax, 1 + push ax ; * ; interpolated middle (R) + add ax, dx + rcr ax, 1 + push ax ; ** ; interpolated 1st quarter (R) + add ax, dx ; [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, bx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + pop ax ; ** + pop dx ; * + add ax, dx ; 1st quarter (R) + middle (R) + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (R) + mov ax, cx + add ax, [next_val_l] + rcr ax, 1 + push ax ; * ; interpolated 3rd quarter (L) + add ax, cx ; interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + mov ax, dx + add ax, [next_val_r] + rcr ax, 1 + push ax ; ** ; interpolated 3rd quarter (R) + add ax, dx ; interpolated middle (R) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (R) + pop bx ; ** + pop ax ; * + add ax, [next_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (L) + mov ax, bx + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (R) + pop cx ; ! + retn + +interpolating_4_16bit_mono: + ; 18/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov bx, ax ; [previous_val] + add dh, 80h + add ax, dx ; [previous_val] + [next_val] + rcr ax, 1 + xchg ax, bx + add ax, bx ; [previous_val] + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov ax, bx ; interpolated middle + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, dx ; interpolated middle + [next_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + retn + +interpolating_4_16bit_stereo: + ; 18/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; [next_val_r] + ; original-interpolated-interpolated-interpolated + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov dx, ax ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + xchg ax, bx + add ax, bx ; bx = interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + add byte [next_val_r+1], 80h + mov ax, dx ; [previous_val_r] + add ax, [next_val_r] + rcr ax, 1 + xchg ax, dx + add ax, dx ; dx = interpolated middle (R) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, bx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + mov ax, dx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, [next_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + mov ax, dx + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (R) + retn + +; 13/11/2023 +previous_val: +previous_val_l: dw 0 +previous_val_r: dw 0 +next_val: +next_val_l: dw 0 +next_val_r: dw 0 + +; 16/11/2023 +faz: db 0 + +; -------------------------------------------------------- +; 27/05/2024 - (TRDOS 386 Kernel) audio.s +; -------------------------------------------------------- + +NOT_PCI32_PCI16 EQU 03FFFFFFFh ; NOT BIT31+BIT30 ; 19/03/2017 +NOT_BIT31 EQU 7FFFFFFFh + +pciFindDevice: + ; 19/11/2023 + ; 03/04/2017 ('pci.asm', 20/03/2017) + ; + ; scan through PCI space looking for a device+vendor ID + ; + ; Entry: EAX=Device+Vendor ID + ; + ; Exit: EAX=PCI address if device found + ; EDX=Device+Vendor ID + ; CY clear if found, set if not found. EAX invalid if CY set. + ; + ; Destroys: ebx, edi ; 19/11/2023 + + ; 19/11/2023 + mov ebx, eax + mov edi, 80000000h +nextPCIdevice: + mov eax, edi ; read PCI registers + call pciRegRead32 + ; 19/11/2023 + cmp edx, ebx + je short PCIScanExit ; found + ; 19/11/2023 + cmp edi, 80FFF800h + jnb short pfd_nf ; not found + add edi, 100h + jmp short nextPCIdevice +pfd_nf: + stc + retn +PCIScanExit: + ;pushf + mov eax, NOT_BIT31 ; 19/03/2017 + and eax, edi ; return only bus/dev/fn # + retn + +pciRegRead: + ; 30/05/2024 + ; 03/04/2017 ('pci.asm', 20/03/2017) + ; + ; 8/16/32bit PCI reader + ; + ; Entry: EAX=PCI Bus/Device/fn/register number + ; BIT30 set if 32 bit access requested + ; BIT29 set if 16 bit access requested + ; otherwise defaults to 8 bit read + ; + ; Exit: DL,DX,EDX register data depending on requested read size + ; + ; Note1: this routine is meant to be called via pciRegRead8, + ; pciRegread16 or pciRegRead32, listed below. + ; + ; Note2: don't attempt to read 32 bits of data from a non dword + ; aligned reg number. Likewise, don't do 16 bit reads from + ; non word aligned reg # + + push ebx + push cx + mov ebx, eax ; save eax, dh + mov cl, dh + + and eax, NOT_PCI32_PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; 13/11/2024 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; read to + + test ebx, PCI32+PCI16 + jnz short _pregr0 + + in al, dx ; return 8 bits of data + + mov dl, al + mov dh, cl ; restore dh for 8 bit read + jmp short _pregr2 +_pregr0: + test ebx, PCI32 + jnz short _pregr1 + + in ax, dx + + mov dx, ax ; return 16 bits of data + jmp short _pregr2 +_pregr1: + in eax, dx ; return 32 bits of data + + mov edx, eax +_pregr2: + mov eax, ebx ; restore eax + and eax, NOT_PCI32_PCI16 ; clear out data size request + pop cx + pop ebx + retn + +pciRegRead8: + and eax, NOT_PCI32_PCI16 ; set up 8 bit read size + jmp short pciRegRead ; call generic PCI access + +pciRegRead16: + and eax, NOT_PCI32_PCI16 ; set up 16 bit read size + or eax, PCI16 ; call generic PCI access + jmp short pciRegRead + +pciRegRead32: + and eax, NOT_PCI32_PCI16 ; set up 32 bit read size + or eax, PCI32 ; call generic PCI access + jmp pciRegRead + +pciRegWrite: + ; 30/05/2024 + ; 03/04/2017 ('pci.asm', 29/11/2016) + ; + ; 8/16/32bit PCI writer + ; + ; Entry: EAX=PCI Bus/Device/fn/register number + ; BIT31 set if 32 bit access requested + ; BIT30 set if 16 bit access requested + ; otherwise defaults to 8bit read + ; DL/DX/EDX data to write depending on size + ; + ; Note1: this routine is meant to be called via pciRegWrite8, + ; pciRegWrite16 or pciRegWrite32 as detailed below. + ; + ; Note2: don't attempt to write 32bits of data from a non dword + ; aligned reg number. Likewise, don't do 16 bit writes from + ; non word aligned reg # + + push ebx + push ecx + mov ebx, eax ; save eax, edx + mov ecx, edx + and eax, NOT_PCI32_PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; 13/11/2024 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; write to + + test ebx, PCI32+PCI16 + jnz short _pregw0 + + mov al, cl ; put data into al + out dx, al + + jmp short _pregw2 +_pregw0: + test ebx, PCI32 + jnz short _pregw1 + + mov ax, cx ; put data into ax + out dx, ax + + jmp short _pregw2 +_pregw1: + mov eax, ecx ; put data into eax + out dx, eax +_pregw2: + mov eax, ebx ; restore eax + and eax, NOT_PCI32_PCI16 ; clear out data size request + mov edx, ecx ; restore dx + pop ecx + pop ebx + retn + +pciRegWrite8: + and eax, NOT_PCI32_PCI16 ; set up 8 bit write size + jmp short pciRegWrite ; call generic PCI access + +pciRegWrite16: + and eax, NOT_PCI32_PCI16 ; set up 16 bit write size + or eax, PCI16 ; call generic PCI access + jmp short pciRegWrite + +pciRegWrite32: + and eax, NOT_PCI32_PCI16 ; set up 32 bit write size + or eax, PCI32 ; call generic PCI access + jmp pciRegWrite + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ac97_vra.asm +; -------------------------------------------------------- + + ; 13/11/2023 + +;VRA: db 1 + +codecConfig: + ; 30/05/2024 + ; 19/05/2024 + ; 19/11/2023 + ; 15/11/2023 + ; 04/11/2023 + ; 17/02/2017 + ; 07/11/2016 (Erdogan Tan) + + ;AC97_EA_VRA equ 1 + AC97_EA_VRA equ BIT0 + + ; 04/11/2023 +init_ac97_controller: + mov eax, [bus_dev_fn] + mov al, PCI_CMD_REG + call pciRegRead16 ; read PCI command register + or dl, IO_ENA+BM_ENA ; enable IO and bus master + call pciRegWrite16 + + ;call delay_100ms + + ; 19/05/2024 + ; ('PLAYMOD3.ASM', Erdogan Tan, 18/05/2024) + +init_ac97_codec: + ; 18/11/2023 + mov bp, 40 + ; 29/05/2024 + ;mov bp, 1000 +_initc_1: + ; 30/05/2024 + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + ; 19/05/2024 + call delay1_4ms + + cmp eax, 0FFFFFFFFh ; -1 + jne short _initc_3 +_initc_2: + dec bp + jz short _ac97_codec_ready + + call delay_100ms + jmp short _initc_1 +_initc_3: + test eax, CTRL_ST_CREADY + jnz short _ac97_codec_ready + + ; 30/05/2024 + cmp byte [reset], 1 + jnb short _initc_2 + + call reset_ac97_codec + ; 30/05/2024 + mov byte [reset], 1 + ; 19/05/2024 + jmp short _initc_2 + +_ac97_codec_ready: + mov dx, [NAMBAR] + ;add dx, 0 ; ac_reg_0 ; reset register + out dx, ax + + call delay_100ms + + ; 19/11/2023 + or bp, bp + jnz short _ac97_codec_init_ok + + xor ax, ax ; 0 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + out dx, ax + + ; 30/05/2024 + call delay1_4ms + + ; 19/11/2023 + ; wait for 1 second + ; 19/05/2024 + mov cx, 1000 ; 1000*4*0.25ms = 1s + ;;mov cx, 10 + ; 30/05/2024 + ;mov cx, 40 +_ac97_codec_rloop: + ;call delay_100ms + + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + in ax, dx + + call delay1_4ms + + and ax, 0Fh + cmp al, 0Fh + je short _ac97_codec_init_ok + loop _ac97_codec_rloop + +init_ac97_codec_err1: + ;stc ; cf = 1 ; 19/05/2024 +init_ac97_codec_err2: + retn + +_ac97_codec_init_ok: + call reset_ac97_controller + + ; 30/05/2024 + ; 19/05/2024 + ;call delay_100ms + + ; 30/05/2024 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + +setup_ac97_codec: + ; 12/11/2023 + cmp word [WAVE_SampleRate], 48000 + je short skip_rate + + ; 30/05/2024 + ; 19/05/2024 + ;call delay1_4ms + + ; 30/05/2024 + ;cmp byte [VRA], 0 + ;jna short skip_rate + + ; 11/11/2023 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + + ; 30/05/2024 + ; 19/05/2024 + call delay1_4ms + + ; 13/11/2024 + ;and al, NOT BIT1 ; Clear DRA + ;;; + ; 30/05/2024 + and al, NOT (BIT1+BIT0) ; Clear DRA+VRA + out dx, ax + + call check_vra + + cmp byte [VRA], 0 + jna short skip_rate + + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + ;and al, ~BIT1 ; Clear DRA + ;;; + + or al, AC97_EA_VRA ; 1 ; 04/11/2023 + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + + out dx, ax ; Enable variable rate audio + + mov cx, 10 +check_vra_loop: + call delay_100ms + ; 30/05/2024 + ;call delay1_4ms + + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + ; 11/11/2023 + in ax, dx + + test al, AC97_EA_VRA ; 1 + jnz short set_rate + + ; 11/11/2023 + loop check_vra_loop + +;vra_not_supported: ; 19/05/2024 + mov byte [VRA], 0 + jmp short skip_rate + +set_rate: + mov ax, [WAVE_SampleRate] ; 17/02/2017 (Erdogan Tan) + + mov dx, [NAMBAR] + add dx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch + out dx, ax ; PCM Front/Center Output Sample Rate + + ;call delay_100ms + ; 30/05/2024 + call delay1_4ms + + ; 12/11/2023 +skip_rate: + mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_MASTER_VOL_REG ;02h + out dx, ax + + ; 11/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_PCM_OUT_REG ;18h + out dx, ax + + ; 11/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + ; 30/05/2024 + ; 19/05/2024 + ;clc + + retn + +reset_ac97_controller: + ; 19/05/2024 + ; 11/11/2023 + ; 10/06/2017 + ; 29/05/2017 + ; 28/05/2017 + ; reset AC97 audio controller registers + xor ax, ax + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov al, RR + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + retn + +reset_ac97_codec: + ; 11/11/2023 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + in eax, dx + + ;test eax, 2 + ; 06/08/2022 + test al, 2 + jz short _r_ac97codec_cold + + call warm_ac97codec_reset + jnc short _r_ac97codec_ok +_r_ac97codec_cold: + call cold_ac97codec_reset + jnc short _r_ac97codec_ok + + ; 16/04/2017 + ;xor eax, eax ; timeout error + ;stc + retn + +_r_ac97codec_ok: + xor eax, eax + ;mov al, VIA_ACLINK_C00_READY ; 1 + inc al + retn + +warm_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 6 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + mov cx, 10 ; total 1s +_warm_ac97c_rst_wait: + call delay_100ms + + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _warm_ac97c_rst_ok + + dec cx + jnz short _warm_ac97c_rst_wait + +_warm_ac97c_rst_fail: + stc +_warm_ac97c_rst_ok: + retn + +cold_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 2 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + + mov cx, 16 ; total 20*100 ms = 2s + +_cold_ac97c_rst_wait: + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _cold_ac97c_rst_ok + + call delay_100ms + + dec cx + jnz short _cold_ac97c_rst_wait + +_cold_ac97c_rst_fail: + stc +_cold_ac97c_rst_ok: + retn + +; 13/11/2024 +; 30/05/2024 +if 1 +check_vra: + ; 30/05/2024 + mov byte [VRA], 1 + + ; 29/05/2024 - audio.s (TRDOS 386 Kernel) - 27/05/2024 + ; 24/05/2024 + ; 23/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_REG ; 28h + in ax, dx + + ; 30/05/2024 + ; 23/05/2024 + call delay1_4ms + + ; 30/05/2024 + test al, BIT0 + ;test al, 1 ; BIT0 ; Variable Rate Audio bit + jnz short check_vra_ok + +vra_not_supported: + ; 13/11/2023 + mov byte [VRA], 0 +check_vra_ok: + retn +end if + +; -------------------------------------------------------- + +; 18/11/2024 +; Ref: TRDOS 386 v2.0.9, audio.s, Erdogan Tan, 06/06/2024 + +ac97_stop: + ; 18/11/2024 + mov byte [stopped], 2 + +ac97_po_cmd@: + xor al, al ; 0 +ac97_po_cmd: + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out control register + out dx, al + retn + +ac97_pause: + mov byte [stopped], 1 ; paused + ;mov al, 0 + ;jmp short ac97_po_cmd + jmp short ac97_po_cmd@ + +ac97_play: ; continue to play (after pause) + mov byte [stopped], 0 + mov al, RPBM + jmp short ac97_po_cmd + +; -------------------------------------------------------- + +PORTB EQU 061h +REFRESH_STATUS EQU 010h ; Refresh signal status + +delay_100ms: + ; 11/11/2023 + ; 29/05/2017 + ; 24/03/2017 ('codec.asm') + ; wait 100 ms + push cx + mov cx, 400 ; 400*0.25ms +_delay_x_ms: + call delay1_4ms + loop _delay_x_ms + pop cx + retn + +delay1_4ms: + push ax + push cx + mov cx, 16 ; close enough. + in al,PORTB + and al,REFRESH_STATUS + mov ah,al ; Start toggle state + or cx, cx + jz short _d4ms1 + inc cx ; Throwaway first toggle +_d4ms1: + in al,PORTB ; Read system control port + and al,REFRESH_STATUS ; Refresh toggles 15.085 microseconds + cmp ah,al + je short _d4ms1 ; Wait for state change + + mov ah,al ; Update with new state + dec cx + jnz short _d4ms1 + + ; 30/05/2024 + clc + + pop cx + pop ax + retn + +; -------------------------------------------------------- +; 14/11/2024 - Erdogan Tan +; -------------------------------------------------------- + + ; 29/11/2024 +checkUpdateEvents: + call check4keyboardstop + jc short c4ue_ok + + ; 18/11/2024 + push ax ; * + or ax, ax + jz c4ue_cpt + + ; 18/11/2024 + cmp al, 20h ; SPACE (spacebar) ; pause/play + jne short ch4ue_chk_s + cmp byte [stopped], 0 + ja short c4ue_chk_ps + ; pause + call ac97_pause + ; 21/11/2024 + mov al, [tLO] + mov byte [tLP], al + jmp c4ue_cpt +c4ue_chk_ps: + cmp byte [stopped], 1 + ja short c4ue_replay + ; continue to play (after a pause) + call ac97_play + jmp c4ue_cpt +c4ue_replay: + ; 19/11/2024 + pop ax ; * + pop ax ; return address + call codecConfig + mov al, [volume] + call SetPCMOutVolume@ + mov byte [stopped], 0 + call move_to_beginning + jmp PlayWav + +ch4ue_chk_s: + cmp al, 'S' ; stop + jne short ch4ue_chk_fb + cmp byte [stopped], 0 + ja short c4ue_cpt ; Already stopped/paused + call ac97_stop + ; 19/11/2024 + mov byte [tLO], 0 + ; 21/11/2024 + mov byte [tLP], '0' + jmp short c4ue_cpt + +ch4ue_chk_fb: + ; 17/11/2024 + cmp al, 'F' + jne short c4ue_chk_b + call Player_ProcessKey_Forwards + jmp short c4ue_cpt + + ; 18/11/2024 +c4ue_ok: + retn + +c4ue_chk_b: + cmp al, 'B' + ;;jne short c4ue_cpt + ; 19/11/2024 + ;jne short c4ue_chk_h + ; 29/11/2024 + jne short c4ue_chk_n + call Player_ProcessKey_Backwards + jmp short c4ue_cpt + + ;;; + ; 29/11/2024 +c4ue_chk_n: + cmp al, 'N' + je short c4ue_nps +c4ue_chk_p: + cmp al, 'P' + jne short c4ue_chk_h +c4ue_nps: + mov byte [stopped], 3 + jmp short c4ue_cpt + ;;; + +c4ue_chk_h: + ; 19/11/2024 + cmp al, 'H' + jne short c4ue_chk_cr + mov byte [wleds], 0 + call write_ac97_pci_dev_info + mov dh, 24 + mov dl, 79 + call setCursorPosition +c4ue_chk_cr: + ; 19/11/2024 + cmp al, 0Dh ; ENTER/CR key + jne short c4ue_cpt + ;inc byte [wleds] + ;jnz short c4ue_cpt + ;inc byte [wleds] + ;;; + ; 23/11/2024 + xor bx, bx + mov bl, [wleds] + inc bl + and bl, 0Fh + jnz short c4ue_sc + inc bx +c4ue_sc: + mov [wleds], bl + shr bl, 1 + mov al, [bx+colors] + jnc short c4ue_sc_@ + or al, 10h ; blue (dark) background +c4ue_sc_@: + mov [ccolor], al + ;;; +c4ue_cpt: + push ds + mov bx, 40h + mov ds, bx + mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;cli + mov ax, [bx] + mov dx, [bx+2] + ;sti + pop ds + ; 18/11/2024 + pop cx ; * + cmp dx, [timerticks+2] + jne short c4ue_utt + cmp ax, [timerticks] + ;je short c4ue_ok + ; 18/11/2024 + je short c4ue_skip_utt +c4ue_utt: + mov [timerticks], ax + mov [timerticks+2], dx + jmp short c4ue_cpt_@ +c4ue_skip_utt: + ; 18/11/2024 + and cx, cx + jz short c4ue_ok +c4ue_cpt_@: + ; 18/11/2024 + cmp byte [stopped], 0 + ja short c4ue_ok + + call CalcProgressTime + + cmp ax, [ProgressTime] + ;je short c4ue_ok + ; same second, no need to update + ; 23/11/2024 + je short c4ue_uvb + + ;call UpdateProgressTime + ;call UpdateProgressBar@ + call UpdateProgressBar + + ; 23/11/2024 +c4ue_uvb: + cmp byte [wleds], 0 + jna short c4ue_vb_ok + + call UpdateWaveLeds + +c4ue_vb_ok: + retn + + ;clc +;c4ue_ok: +; retn + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ich_wav4.asm +; -------------------------------------------------------- + + ; 29/11/2024 +check4keyboardstop: + ; 19/05/2024 + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + ;clc + jz short _cksr + + xor ah, ah + int 16h + + ; 29/11/2024 + mov [command], al + + ;;; + ; 19/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + cmp al, 0 + jna short p_3 + dec al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_4 + + mov al, [volume] + cmp al, 31 + jnb short p_3 + inc al +p_2: + mov [volume], al + ; 14/11/2024 + call SetPCMOutVolume + ; 15/11/2024 (QEMU) + ;call SetMasterVolume + ;call UpdateVolume + ;;clc + ;retn + jmp UpdateVolume + ;mov ah, al + ;mov dx, [NAMBAR] + ;;add dx, CODEC_MASTER_VOL_REG + ;add dx, CODEC_PCM_OUT_REG + ;out dx, ax + ; + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms +_cksr: ; 19/05/2024 + ; 18/11/2024 + xor ax, ax + ;clc +p_3: + retn +p_4: + ; 17/11/2024 + cmp ah, 01h ; ESC + je short p_q + cmp al, 03h ; CTRL+C + je short p_q + + ; 18/11/2024 + cmp al, 20h + je short p_r + + ; 19/11/2024 + cmp al, 0Dh ; CR/ENTER + je short p_r + + and al, 0DFh + + ; 29/11/2024 + mov [command], al + + ;cmp al, 'B' + ;je short p_r + ;cmp al, 'F' + ;je short p_r + + ; 29/11/2024 + ;cmp al, 'N' + ;je short p_r + ;cmp al, 'P' + ;je short p_r + + cmp al, 'Q' + ;je short p_q + je short p_quit ; 29/11/2024 + + clc + retn + + ;;; +;_cskr: +p_q: + ; 29/11/2024 + mov byte [command], 'Q' +p_quit: + stc +p_r: + retn + +; returns AL = current index value +getCurrentIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_CIV_REG + in al, dx + ;pop dx +uLVI2: ; 06/11/2023 + retn + +updateLVI: + ; 06/11/2023 + mov dx, [NABMBAR] + add dx, PO_CIV_REG + ; (Current Index Value and Last Valid Index value) + in ax, dx + + cmp al, ah ; is current index = last index ? + jne short uLVI2 + + ; 08/11/2023 + call getCurrentIndex + + test byte [flags], ENDOFFILE + ;jnz short uLVI1 + jz short uLVI0 ; 08/11/2023 + + ; 08/11/2023 + push ax + mov dx, [NABMBAR] + add dx, PO_SR_REG ; PCM out status register + in ax, dx + + test al, 3 ; bit 1 = Current Equals Last Valid (CELV) + ; (has been processed) + ; bit 0 = 1 -> DMA Controller Halted (DCH) + pop ax + jz short uLVI1 +uLVI3: + xor ax, ax + ; zf = 1 + retn +uLVI0: + ; not at the end of the file yet. + dec al + and al, 1Fh +uLVI1: + ;call setLastValidIndex +;uLVI2: + ;retn + +;input AL = index # to stop on +setLastValidIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_LVI_REG + out dx, al + ;pop dx + retn + +; 29/05/2024 +; 19/05/2024 +volume: ;db 02h + db 03h ; 14/12/2024 + +; -------------------------------------------------------- + + ; 14/11/2024 +setCursorPosition: + ; dh = Row + ; dl = Column + mov ax, 0500h + int 10h + mov ah, 02h + mov bh, 00h + ;mov dh, setCursorPosition_Row + ;mov dl, setCursorPosition_Column + int 10h + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; NAME: SetTotalTime +;; DESCRIPTION: Calculates the total time in seconds in file +;; INPUT: DATA_SubchunkSize, WAVE_SampleRate, WAVE_BlockAlign +;; OUTPUT: CurrentTotalTime=Total time in seconds in file, +;; Output on the screen of the total time in seconds + +SetTotalTime: + ;; Calculate total seconds in file + mov ax, [DATA_SubchunkSize] + mov dx, [DATA_SubchunkSize + 2] + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + + mov bx, [WAVE_BlockAlign] + + div bx + + mov [TotalTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 42 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 45 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + ;jmp short PrintNumber + +; -------------------------------------------------------- + +PrintNumber: + ; bp = digits + ; ax = binary number + mov bx, 10 + xor cx, cx +printNumber_CutNumber: + inc cx + xor dx, dx + div bx + push dx + cmp cx, bp + je short printNumber_printloop + jmp printNumber_CutNumber + +printNumber_printloop: + pop ax + mov dl, '0' + add dl, al + mov ah, 02h + int 21h + loop printNumber_printloop + + retn + +; -------------------------------------------------------- + + ; 14/11/2024 - Erdogan Tan +SetProgressTime: + ;; Calculate playing/progress seconds in file + call CalcProgressTime + +UpdateProgressTime: + ; ax = (new) progress time + + mov [ProgressTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 33 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 36 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + jmp short PrintNumber + +; -------------------------------------------------------- + + ; 17/11/2024 + ; 14/11/2024 +CalcProgressTime: + mov ax, [LoadedDataBytes] + mov dx, [LoadedDataBytes+2] + mov bx, ax + or bx, dx + jz short cpt_ok + + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + mov bx, [WAVE_BlockAlign] + div bx +cpt_ok: + ; ax = (new) progress time + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; DESCRIPTION: Update file information on template +;; PARAMS: WAVE parameters and other variables +;; REGS: AX(RW) +;; VARS: CurrentFileName, WAVE_SampleRate, +;; RETURNS: On-screen file info is updated. + +UpdateFileInfo: + ;; Print File Name + mov dh, 9 + mov dl, 23 + call setCursorPosition + + mov si, wav_file_name + + ;;; + ; 14/11/2024 + ; skip directory separators + ; (note: asciiz string, max. 79 bytes except zero tail) + mov bx, si +chk4_nxt_sep: + lodsb + cmp al, '\' + je short chg_fpos + and al, al + jz short chg_fpos_ok + jmp short chk4_nxt_sep +chg_fpos: + mov bx, si + jmp short chk4_nxt_sep +chg_fpos_ok: + mov si, bx ; file name (without its path/directory) + ;;; + + call PrintString + + ;; Print Frequency + mov dh, 10 + mov dl, 23 + call setCursorPosition + mov ax, [WAVE_SampleRate] + mov bp, 5 + call PrintNumber + + ;; Print BitRate + mov dh, 9 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_BitsPerSample] + mov bp, 2 + call PrintNumber + + ;; Print Channel Number + mov dh, 10 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_NumChannels] + mov bp, 1 + call PrintNumber + + ;call UpdateVolume + ;retn + +; -------------------------------------------------------- + + ; 14/11/2024 +UpdateVolume: + ;; Print Volume + mov dh, 24 + mov dl, 75 + call setCursorPosition + + mov al, [volume] + + mov bl, 100 + mul bl + + mov bl, 31 + div bl + + neg ax + add ax, 100 + + xor ah, ah + mov bp, 3 + ;call PrintNumber + ;retn + jmp PrintNumber + +; -------------------------------------------------------- + + ; 14/11/2024 +PrintString: + ; si = string address + mov bx, 0Fh ; white + mov ah, 0Eh ; write as tty +printstr_loop: + lodsb + or al, al + jz short printstr_ok + int 10h + jmp short printstr_loop +printstr_ok: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 + ; (Ref: player.asm , Matan Alfasi, 2017) + ; (Modification: Erdogan Tan, 14/11/2024) + + PROGRESSBAR_ROW equ 23 + +UpdateProgressBar: + call SetProgressTime ; 14/11/2024 + + mov ax, [ProgressTime] +UpdateProgressBar@: + mov dx, 80 + mul dx + mov bx, [TotalTime] + div bx + + ;; Push for the 'Clean' part + push ax ; ** + push ax ; * + + ;; Set cursor position + mov dh, PROGRESSBAR_ROW + mov dl, 0 + call setCursorPosition + + pop ax ; * + or ax, ax + jz short UpdateProgressBar_Clean + +UpdateProgressBar_DrawProgress: + mov cx, ax + mov ah, 09h + mov al, 223 + mov bx, 0Fh + int 10h + +UpdateProgressBar_DrawCursor: + ;mov ax, cx + mov dh, PROGRESSBAR_ROW + ;mov dl, al + dec cx + mov dl, cl + call setCursorPosition + + mov ah, 09h + mov al, 223 + mov bx, 0Ch + mov cx, 1 + int 10h + +UpdateProgressBar_Clean: + pop ax ; ** + mov cx, ax + mov dh, PROGRESSBAR_ROW + mov dl, al + call setCursorPosition + + neg cx + add cx, 80 ; cf = 1 ; + + ;; CX = No. of times to print a clean character + ;mov cx, 80 + ;sub cx, ax + ;; 09h = Write character multiple times + mov ah, 09h + ;; 32 = Space ASCII code + ;mov al, 32 + ;mov bx, 0 + ; 15/11/2024 + mov al, 223 + mov bx, 8 + int 10h + ; 14/11/2024 + clc ; + + + retn + +; -------------------------------------------------------- +; 17/11/2024 + +Player_ProcessKey_Backwards: + ;; In order to go backwards 5 seconds: + ;; Update file pointer to the beginning, skip headers + mov cl, 'B' + jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_Forwards: + ;; In order to fast-forward 5 seconds, set the file pointer + ;; to CUR_SEEK + 5 * Freq + + mov cl, 'F' + ;jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_B_or_F: + ; 17/11/2024 + ; 04/11/2024 + ; (Ref: player.asm, Matan Alfasi, 2017) + + ; 04/11/2024 + mov ax, 5 + mov bx, [WAVE_BlockAlign] + mul bx + mov bx, [WAVE_SampleRate] + mul bx + ; dx:ax = transfer byte count for 5 seconds + + ; 17/11/2024 + cmp cl, 'B' + mov bx, [LoadedDataBytes] + mov cx, [LoadedDataBytes+2] + jne short move_forward ; cl = 'F' +move_backward: + sub bx, ax + sbb cx, dx + jnc short move_file_pointer +move_to_beginning: + xor cx, cx ; 0 + xor bx, bx ; 0 + jmp short move_file_pointer +move_forward: + add bx, ax + adc cx, dx + jc short move_to_end + cmp cx, [DATA_SubchunkSize+2] + ja short move_to_end + jb short move_file_pointer + cmp bx, [DATA_SubchunkSize] + jna short move_file_pointer +move_to_end: + mov bx, [DATA_SubchunkSize] + mov cx, [DATA_SubchunkSize+2] +move_file_pointer: + mov dx, bx + mov [LoadedDataBytes], dx + mov [LoadedDataBytes+2], cx + add dx, 44 ; + header + adc cx, 0 + + ; seek + mov bx, [filehandle] + mov ax, 4200h + int 21h + + retn + +; -------------------------------------------------------- + + ; 23/11/2024 + ; 19/11/2024 +clear_window: + xor ax, ax + jmp short clear_window_@ + +reset_wave_leds: + ; 23/11/2024 + ;mov al, 254 + ;mov ah, 8 ; gray (dark) + mov ax, 08FEh +clear_window_@: + push es + mov di, 0B800h + mov es, di + mov di, 2080 ; 13*80*2 + mov cx, 8*80 ; 8 rows + rep stosw + pop es + retn + +; -------------------------------------------------------- + + ; 09/12/2024 + ; 19/11/2024 +UpdateWaveLeds: + ; 23/11/2024 + call reset_wave_leds + ; 09/12/2024 + ;jmp short turn_on_leds + +; -------------------------------------------------------- + + ; 09/12/2024 +turn_on_leds: + ; 19/11/2024 +;turn_on_leds_stereo_16bit: + push es + push ds + + cmp byte [tLO],'2' + jne short tol_buffer_1 + +tol_buffer_2: + ; 21/11/2024 + mov si, [WAV_BUFFER2] + jmp short tol_@ + +tol_buffer_1: + cmp byte [tLO],'1' + ;jne short tol_retn + ; 23/11/2024 + jne short tol_clc_retn + + mov si, [WAV_BUFFER1] +tol_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + mov cx, [buffersize] ; word + shl cx, 1 ; byte + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol_o_@ + cmp si, cx + jna short tol_s_buf +tol_o_@: + mov si, cx + jmp short tol_s_buf + +tol_clc_retn: + ; 23/11/2024 + clc +tol_retn: + pop ds + pop es + retn + +tol_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol_s_buf: + mov [pbuf_o], si + +tol_buf_@: + ; 21/11/2024 + mov ds, [pbuf_s] + mov di, 0B800h + mov es, di + ;mov di, (20*80*2)-2 + + ; 23/11/2024 + mov cx, 80 + + ; 22/11/2024 + mov bx, wleds_addr + +tol_fill_c: + ; 22/11/2024 + ;inc di + ;inc di + ;push di + lodsw ; left + ;shr ax, 8 + mov dx, ax + lodsw ; right + ;shr ax, 8 + ;;; + ; 23/11/2024 + add ax, dx + ; 09/12/2024 + ;shr ax, 8 + ;;shr ax, 9 + ;add al, 80h + ;shr ax, 5 + add ah, 80h + shr ax, 13 + ;;; + ;;shr ax, 6 + + push bx + shl ax, 1 + add bx, ax + mov di, [cs:bx] + ; 23/11/2024 + mov ah, [cs:ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol_fill_c + + jmp short tol_retn + +; -------------------------------------------------------- + +; 30/05/2024 +print_msg: + mov bx, 07h +p_msg: + push es + push bp + push cx + push dx + + push ds + pop es + mov bp, si + mov ah, 03h ; Return cursor position (in DX) + ; bh = video page number + int 10h + xor cx, cx +p_msg_0: + lodsb + or al, al + jz short p_msg_1 + inc cx + jmp short p_msg_0 +p_msg_1: + or cx, cx + jz short p_msg_x + ; cx = number of chars + ; dx = screen (cursor) position + ; bl = color/attribute + ; bh = video page number + ; es:bp = string buffer + ;mov al, 1 ; attribute in BL, update cursor pos + ;mov ah, 13h ; write character string + mov ax, 1301h + int 10h +p_msg_x: + pop dx + pop cx + pop bp + pop es + retn + +; -------------------------------------------------------- +; -------------------------------------------------------- + +; DATA + +; 30/05/2024 +;reset: db 0 + +Credits: + db 'Tiny WAV Player for Retro DOS by Erdogan Tan. ' + db 'December 2024.',10,13,0 + db '18/12/2024', 10,13 +; 15/11/2024 +reset: + db 0 + +msgAudioCardInfo: + db 'for Intel AC97 (ICH) Audio Controller.', 10,13,0 + +msg_usage: + db 'usage: AC97PLAY <...>',10,13,0 ; 28/11/2024 + +noDevMsg: + db 'Error: Unable to find AC97 audio device!' + db 10,13,0 + +noFileErrMsg: + db 'Error: file not found.',10,13,0 + +msg_error: ; 30/05/2024 + +; 29/05/2024 +; 11/11/2023 +msg_init_err: + db CR, LF + db "AC97 Controller/Codec initialization error !" + db CR, LF, 0 ; 07/12/2024 + +; 25/11/2023 +msg_no_vra: + db 10,13 + db "No VRA support ! Only 48 kHZ sample rate supported !" + db 10,13,0 + +; 13/11/2024 +; ('<<' to 'shl' conversion for FASM) +; +; 29/05/2024 (TRDOS 386) +; 17/02/2017 +; Valid ICH device IDs + +valid_ids: +;dd (ICH_DID << 16) + INTEL_VID ; 8086h:2415h +dd (ICH_DID shl 16) + INTEL_VID ; 8086h:2415h +dd (ICH0_DID shl 16) + INTEL_VID ; 8086h:2425h +dd (ICH2_DID shl 16) + INTEL_VID ; 8086h:2445h +dd (ICH3_DID shl 16) + INTEL_VID ; 8086h:2485h +dd (ICH4_DID shl 16) + INTEL_VID ; 8086h:24C5h +dd (ICH5_DID shl 16) + INTEL_VID ; 8086h:24D5h +dd (ICH6_DID shl 16) + INTEL_VID ; 8086h:266Eh +dd (ESB6300_DID shl 16) + INTEL_VID ; 8086h:25A6h +dd (ESB631X_DID shl 16) + INTEL_VID ; 8086h:2698h +dd (ICH7_DID shl 16) + INTEL_VID ; 8086h:27DEh +; 03/11/2023 - Erdogan Tan +dd (MX82440_DID shl 16) + INTEL_VID ; 8086h:7195h +dd (SI7012_DID shl 16) + SIS_VID ; 1039h:7012h +dd (NFORCE_DID shl 16) + NVIDIA_VID ; 10DEh:01B1h +dd (NFORCE2_DID shl 16) + NVIDIA_VID ; 10DEh:006Ah +dd (AMD8111_DID shl 16) + AMD_VID ; 1022h:746Dh +dd (AMD768_DID shl 16) + AMD_VID ; 1022h:7445h +dd (CK804_DID shl 16) + NVIDIA_VID ; 10DEh:0059h +dd (MCP04_DID shl 16) + NVIDIA_VID ; 10DEh:003Ah +dd (CK8_DID shl 16) + NVIDIA_VID ; 1022h:008Ah +dd (NFORCE3_DID shl 16) + NVIDIA_VID ; 10DEh:00DAh +dd (CK8S_DID shl 16) + NVIDIA_VID ; 10DEh:00EAh + +;valid_id_count equ ($ - valid_ids)>>2 ; 05/11/2023 +; 13/11/2024 +valid_id_count = ($ - valid_ids) shr 2 ; 05/11/2023 + +; 19/11/2024 +; 03/06/2017 +hex_chars db "0123456789ABCDEF", 0 +msgAC97Info db 0Dh, 0Ah + db " AC97 Audio Controller & Codec Info", 0Dh, 0Ah + db " Vendor ID: " +msgVendorId db "0000h Device ID: " +msgDevId db "0000h", 0Dh, 0Ah + db " Bus: " +msgBusNo db "00h Device: " +msgDevNo db "00h Function: " +msgFncNo db "00h" + db 0Dh, 0Ah + db " NAMBAR: " +msgNamBar db "0000h " + db "NABMBAR: " +msgNabmBar db "0000h IRQ: " +msgIRQ dw 3030h + db 0Dh, 0Ah, 0 +; 25/11/2023 +msgVRAheader db " VRA support: " + db 0 +msgVRAyes db "YES", 0Dh, 0Ah, 0 +msgVRAno db "NO ", 0Dh, 0Ah + db " (Interpolated sample rate playing method)" + db 0Dh, 0Ah, 0 + +; -------------------------------------------------------- +; 14/11/2024 (Ref: player.asm, Matan Alfasi, 2017) + +; 23/11/2024 (overwrite splashscreen, a method to solve 64KB limit problem) +; wave volume leds address array +wleds_addr: ; 80*16 bytes + +SplashScreen: + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " _______ ______ _______. ", 221, 219, 222 + db 221, 219, 222, " | \ / __ \ / | ", 221, 219, 222 + db 221, 219, 222, " | .--. | | | | | (----` ", 221, 219, 222 + db 221, 219, 222, " | | | | | | | \ \ ", 221, 219, 222 + db 221, 219, 222, " | '--' | `--' | .----) | ", 221, 219, 222 + db 221, 219, 222, " |_______/ \______/ |_______/ ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " .______ __ ___ ____ ____ _______ .______ ", 221, 219, 222 + db 221, 219, 222, " | _ \ | | / \ \ \ / / | ____|| _ \ ", 221, 219, 222 + db 221, 219, 222, " | |_) | | | / ^ \ \ \/ / | |__ | |_) | ", 221, 219, 222 + db 221, 219, 222, " | ___/ | | / /_\ \ \_ _/ | __| | / ", 221, 219, 222 + db 221, 219, 222, " | | | `----./ _____ \ | | | |____ | |\ \----. ", 221, 219, 222 + db 221, 219, 222, " | _| |_______/__/ \__\ |__| |_______|| _| `._____| ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " WELCOME TO ", 221, 219, 222 + db 221, 219, 222, " DOS PLAYER ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db " " +Template: + db 201, 78 dup(205), 187 + db 186, 33 dup(219), " DOS Player ", 33 dup(219), 186 + db 204, 78 dup(205), 185 + db 186, 33 dup(32), " User Guide ", 33 dup(32), 186 + ; 29/11/2024 + db 186, 6 dup(32), " Play/Pause ", 4 dup(32), "/

Next/Previous", 9 dup(32), 186 + db 186, 6 dup(32), " Stop ", 4 dup(32), " Wave Lighting", 9 dup(32), 186 + db 186, 6 dup(32), " Forwards ", 4 dup(32), "<+>/<-> Inc/Dec Volume", 8 dup(32), 186 + db 186, 6 dup(32), " Backwards ", 4 dup(32), " Quit Program ", 9 dup(32), 186 + db 204, 78 dup(205), 185 + db 186, 6 dup(32), "File Name : ", 4 dup(32), "Bit-Rate : 0 Bits ", 9 dup(32), 186 + db 186, 6 dup(32), "Frequency : 0 Hz ", 4 dup(32), "#-Channels: 0 ", 9 dup(32), 186 + db 200, 78 dup(205), 188 + db 80 dup(32) +improper_samplerate_txt: ; 03/11/2024 +read_error_txt: + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(205) + db 80 dup(32) + db 33 dup(32), "00:00 ", 174, 175, " 00:00", 24 dup(32), "VOL 000%" +; 28/11/2024 +IsInSplash: db 1 +SplashFileName: db "SPLASH.WAV", 0 + +; 23/11/2024 +colors: db 0Fh, 0Bh, 0Ah, 0Ch, 0Eh, 09h, 0Dh, 0Fh + ; white, cyan, green, red, yellow, blue, magenta +ccolor: db 0Bh ; cyan + +EOF: + +; BSS + +align 2 + +; 22/11/2024 +; wave volume leds address array +;wleds_addr: rw 80*8 ; rb 2*80*8 + +; 14/11/2024 +; 17/02/2017 +bss_start: + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +; 18/11/2024 +stopped: rb 1 +tLO: rb 1 +; 21/11/2024 +tLP: rb 1 +; 19/11/2024 +wleds: rb 1 +wleds_dif: rw 1 +pbuf_s: rw 1 +pbuf_o: rw 1 + +; 29/11/2024 +command: rb 1 + +; 30/05/2024 +VRA: rb 1 ; Variable Rate Audio Support Status + +;;;;;;;;;;;;;; +; 14/11/2024 +; (Ref: player.asm, Matan Alfasi, 2017) +WAVFILEHEADERbuff: +RIFF_ChunkID: rd 1 ; Must be equal to "RIFF" - big-endian + ; 0x52494646 +RIFF_ChunkSize: + rd 1 ; Represents total file size, not + ; including the first 2 fields + ; (Total_File_Size - 8), little-endian +RIFF_Format: + rd 1 ; Must be equal to "WAVE" - big-endian + ; 0x57415645 + +;; WAVE header parameters ("Sub-chunk") +WAVE_SubchunkID: + rd 1 ; Must be equal to "fmt " - big-endian + ; 0x666d7420 +WAVE_SubchunkSize: + rd 1 ; Represents total chunk size +WAVE_AudioFormat: + rw 1 ; PCM (Raw) - is 1, other - is a form + ; of compression, not supported. +WAVE_NumChannels: + rw 1 ; Number of channels, Mono-1, Stereo-2 +WAVE_SampleRate: + rd 1 ; Frequency rate, in Hz (8000, 44100 ...) +WAVE_ByteRate: rd 1 ; SampleRate * NumChannels * BytesPerSample +WAVE_BlockAlign: + rw 1 ; NumChannels * BytesPerSample + ; Number of bytes for one sample. +WAVE_BitsPerSample: + rw 1 ; 8 = 8 bits, 16 = 16 bits, etc. + +;; DATA header parameters +DATA_SubchunkID: + rd 1 ; Must be equal to "data" - big-endian + ; 0x64617461 +DATA_SubchunkSize: + rd 1 ; NumSamples * NumChannels * BytesPerSample + ; Number of bytes in the data. +;;;;;;;;;;;;;; + +; 15/11/2024 +cursortype: rw 1 + +filehandle: rw 1 + +flags: rb 1 +; 06/11/2023 +ac97_int_ln_reg: rb 1 + +; 28/11/2024 +PSP_CurrentOffset: rw 1 + +; 30/05/2024 +wav_file_name: + rb 80 ; wave file, path name (<= 80 bytes) + + rw 1 + +; 12/11/2016 - Erdogan Tan +bus_dev_fn: rd 1 +dev_vendor: rd 1 + +; 17/02/2017 +; NAMBAR: Native Audio Mixer Base Address Register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 10h-13h +; NABMBAR: Native Audio Bus Mastering Base Address register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 14h-17h +NAMBAR: rw 1 ; BAR for mixer +NABMBAR: rw 1 ; BAR for bus master regs + +; 256 byte buffer for descriptor list +BDL_BUFFER: rw 1 ; segment of our 256byte BDL buffer +WAV_BUFFER1: rw 1 ; segment of our WAV storage +; 64k buffers for wav file storage +WAV_BUFFER2: rw 1 ; segment of 2nd wav buffer + +; 09/12/2024 +; 23/11/2024 +;turn_on_leds: rw 1 ; turn_on_leds procedure pointer (m8,m16,s8,s16) + +; 08/11/2023 +; 07/11/2023 +fbs_shift: rb 1 +; 29/11/2024 +filecount: rb 1 + +; 15/11/2024 +loadfromwavfile: + rw 1 ; 'loadfromfile' or load+conversion proc address +loadsize: rw 1 ; (.wav file) read count (bytes) per one time +buffersize: rd 1 ; 16 bit samples (not bytes) + +; 14/11/2024 +TotalTime: rw 1 ; Total (WAV File) Playing Time in seconds +ProgressTime: rw 1 +count: rw 1 ; byte count of one (wav file) read +LoadedDataBytes: + rd 1 ; total read/load count + +timerticks: rd 1 ; (to eliminate excessive lookup of events in tuneloop) + ; (in order to get the emulator/qemu to run correctly) +; 14/11/2024 +bss_end: + +;alignb 2 + +; 32 kilo bytes for temporay buffer +; (for stereo-mono, 8bit/16bit corrections) +; 14/11/2024 +;temp_buffer: rb 32768 +; 17/11/2024 +temp_buffer: rb 50600 ; (44.1 kHZ stereo 12650 samples) +; 18/11/2023 +;temp_buffer: rb 56304 ; (44.1 kHZ stereo 14076 samples) + +;alignb 16 +;bss_end: \ No newline at end of file diff --git a/trdos386/programs/16bit/ac97play_com_2024.zip b/trdos386/programs/16bit/ac97play_com_2024.zip new file mode 100644 index 0000000..f8fa189 Binary files /dev/null and b/trdos386/programs/16bit/ac97play_com_2024.zip differ diff --git a/trdos386/programs/16bit/playmod4.com b/trdos386/programs/16bit/playmod4.com new file mode 100644 index 0000000..bb63317 Binary files /dev/null and b/trdos386/programs/16bit/playmod4.com differ diff --git a/trdos386/programs/16bit/playmod4_com_fasm_2024.zip b/trdos386/programs/16bit/playmod4_com_fasm_2024.zip new file mode 100644 index 0000000..1caaea4 Binary files /dev/null and b/trdos386/programs/16bit/playmod4_com_fasm_2024.zip differ diff --git a/trdos386/programs/16bit/playwav7.asm b/trdos386/programs/16bit/playwav7.asm new file mode 100644 index 0000000..35e2793 --- /dev/null +++ b/trdos386/programs/16bit/playwav7.asm @@ -0,0 +1,5214 @@ +; **************************************************************************** +; playwav7.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; PLAYWAV7.COM ! AC'97 (ICH) .WAV PLAYER program by Erdogan TAN +; +; 13/11/2024 +; +; [ Last Modification: 13/11/2024 ] +; +; Modified from PLAYWAV6.COM .wav player program by Erdogan Tan, 30/05/2024 +; (Assembler: NASM 2.15) +; +; Assembler: FASM 1.73 +; fasm playwav7.asm PLAYWAV7.COM +; ---------------------------------------------------------------------------- + +; playwav6.asm (30/05/2024) + +; TUNELOOP version (playing without AC97 interrupt) - 06/11/2023 - Erdogan Tan +; sample rate conversion version - 18/11/2023 - Erdogan Tan + +; CODE + + ; 13/11/2024 +macro sys_msg op1,op2 +{ ; 30/05/2024 + mov si, op1 ; message + mov bl, op2 ; text color + xor bh, bh ; video page 0 + mov ah, 0Eh + call p_msg +} + +; player internal variables and other equates. +BUFFERSIZE equ 64 * 1024 ; 64k file buffer size. +ENDOFFILE equ 1 ; flag for knowing end of file + +use16 + +org 100h + + include 'ac97.inc' ; 17/02/2017 + +_STARTUP: + ; 30/05/2024 + ; Prints the Credits Text. + sys_msg Credits, 0Bh + + ; 30/05/2024 + call setFree ; deallocate unused DOS mem + + ; 17/02/2017 + ; Clear BSS (uninitialized data) area + xor ax, ax ; 0 + mov cx, (bss_end - bss_start)/2 + mov di, bss_start + rep stosw + + ; Detect (& Enable) AC'97 Audio Device + call DetectAC97 + ;jnc short GetFileName + ; 30/05/2024 + jnc short allocate_memory + + ; 30/05/2024 +_dev_not_ready: + ; couldn't find the audio device! + sys_msg noDevMsg, 0Fh + jmp Exit + + ; 30/05/2024 +allocate_memory: + +; allocate 256 bytes of data for DCM_OUT Buffer Descriptor List. (BDL) + + mov ax, BDL_SIZE / 16 + call memAlloc + mov [BDL_BUFFER], ax ; segment + +; allocate 2 buffers, 64k each for now. + + mov ax, BUFFERSIZE / 16 ; 64k for .WAV file + call memAlloc + mov [WAV_BUFFER1], ax ; segment + + mov ax, BUFFERSIZE / 16 + call memAlloc + mov [WAV_BUFFER2], ax + + ; 30/05/2024 +GetFileName: + mov di, wav_file_name + mov si, 80h + mov bl, [si] + xor bh, bh + inc bx + mov byte [si+bx], 0 ; make AsciiZ filename. + inc si +ScanName: + lodsb + test al, al + jz pmsg_usage + cmp al, 20h + je short ScanName ; scan start of name. + stosb + mov ah, 0FFh +a_0: + inc ah +a_1: + lodsb + stosb + cmp al, '.' + je short a_0 + and al, al + jnz short a_1 + + or ah, ah ; if period NOT found, + jnz short _1 ; then add a .WAV extension. +SetExt: + dec di + mov dword [di], '.WAV' + mov byte [di+4], 0 + +_1: + call write_audio_dev_info + +; open the file + ; open existing file + mov al, OPEN ; open existing file + mov dx, wav_file_name + call openFile ; no error? ok. + jnc short _gsr + +; file not found! + sys_msg noFileErrMsg, 0Fh +_exit_: + jmp Exit + +_gsr: + call getSampleRate ; read the sample rate + ; pass it onto codec. + ; 25/11/2023 + jc short _exit_ ; nothing to do + + mov [sample_rate], ax + mov [stmo], cl + mov [bps], dl + + ; 26/11/2023 + mov byte [fbs_shift], 0 ; 0 = stereo and 16 bit + dec cl + jnz short _gsr_1 ; stereo + inc byte [fbs_shift] ; 1 = mono or 8 bit +_gsr_1: + cmp dl, 8 + ja short _gsr_2 ; 16 bit samples + inc byte [fbs_shift] ; 2 = mono and 8 bit +_gsr_2: + ; 29/05/2024 + call write_ac97_pci_dev_info + + ; 30/05/2024 + ; 29/05/2024 + ;call check_vra + + ; 30/05/2024 + call codecConfig ; unmute codec, set rates. + jc init_err + + ; 25/11/2023 + call write_VRA_info + + ; 01/05/2017 + call write_wav_file_info + + ; 25/11/2023 + ; ------------------------------------------ + + ; 18/11/2023 (ich_wav4.asm) + ; 13/11/2023 (ich_wav3.asm) + + cmp byte [VRA], 1 + jb short chk_sample_rate +playwav_48_khz: + mov word [loadfromwavfile], loadFromFile + ;mov word [loadsize], 0 ; 65536 + mov word [buffersize], 32768 ; samples + jmp PlayNow ; 30/05/2024 + +chk_sample_rate: + ; set conversion parameters + ; (for 8, 11.025, 16, 22.050, 24, 32 kHZ) + mov ax, [sample_rate] + cmp ax, 48000 + je short playwav_48_khz +chk_22khz: + cmp ax, 22050 + jne short chk_11khz + cmp byte [bps], 8 + jna short chk_22khz_1 + mov bx, load_22khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_22khz_2 + mov bx, load_22khz_mono_16_bit + jmp short chk_22khz_2 +chk_22khz_1: + mov bx, load_22khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_22khz_2 + mov bx, load_22khz_mono_8_bit +chk_22khz_2: + mov ax, 7514 ; (442*17) + mov dx, 37 + mov cx, 17 + jmp set_sizes +chk_11khz: + cmp ax, 11025 + jne short chk_44khz + cmp byte [bps], 8 + jna short chk_11khz_1 + mov bx, load_11khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_11khz_2 + mov bx, load_11khz_mono_16_bit + jmp short chk_11khz_2 +chk_11khz_1: + mov bx, load_11khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_11khz_2 + mov bx, load_11khz_mono_8_bit +chk_11khz_2: + mov ax, 3757 ; (221*17) + mov dx, 74 + mov cx, 17 + jmp set_sizes +chk_44khz: + cmp ax, 44100 + jne short chk_16khz + cmp byte [bps], 8 + jna short chk_44khz_1 + mov bx, load_44khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_44khz_2 + mov bx, load_44khz_mono_16_bit + jmp short chk_44khz_2 +chk_44khz_1: + mov bx, load_44khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_44khz_2 + mov bx, load_44khz_mono_8_bit +chk_44khz_2: + ;mov ax, 15065 ; (655*23) + ; 18/11/2023 ((file size + bss + stack) <= 64KB) + mov ax, 14076 ; (612 *23) + mov dx, 25 + mov cx, 23 + jmp set_sizes +chk_16khz: + cmp ax, 16000 + jne short chk_8khz + cmp byte [bps], 8 + jna short chk_16khz_1 + mov bx, load_16khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_16khz_2 + mov bx, load_16khz_mono_16_bit + jmp short chk_16khz_2 +chk_16khz_1: + mov bx, load_16khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_16khz_2 + mov bx, load_16khz_mono_8_bit +chk_16khz_2: + mov ax, 5461 + mov dx, 3 + mov cx, 1 + jmp set_sizes +chk_8khz: + cmp ax, 8000 + jne short chk_24khz + cmp byte [bps], 8 + jna short chk_8khz_1 + mov bx, load_8khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_8khz_2 + mov bx, load_8khz_mono_16_bit + jmp short chk_8khz_2 +chk_8khz_1: + mov bx, load_8khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_8khz_2 + mov bx, load_8khz_mono_8_bit +chk_8khz_2: + mov ax, 2730 + mov dx, 6 + mov cx, 1 + jmp short set_sizes +chk_24khz: + cmp ax, 24000 + jne short chk_32khz + cmp byte [bps], 8 + jna short chk_24khz_1 + mov bx, load_24khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_24khz_2 + mov bx, load_24khz_mono_16_bit + jmp short chk_24khz_2 +chk_24khz_1: + mov bx, load_24khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_24khz_2 + mov bx, load_24khz_mono_8_bit +chk_24khz_2: + mov ax, 8192 + mov dx, 2 + mov cx, 1 + jmp short set_sizes +chk_32khz: + cmp ax, 32000 + jne short vra_needed + cmp byte [bps], 8 + jna short chk_32khz_1 + mov bx, load_32khz_stereo_16_bit + cmp byte [stmo], 1 + jne short chk_32khz_2 + mov bx, load_32khz_mono_16_bit + jmp short chk_32khz_2 +chk_32khz_1: + mov bx, load_32khz_stereo_8_bit + cmp byte [stmo], 1 + jne short chk_32khz_2 + mov bx, load_32khz_mono_8_bit +chk_32khz_2: + mov ax, 10922 + mov dx, 3 + mov cx, 2 + ;jmp short set_sizes +set_sizes: + cmp byte [stmo], 1 + je short ss_1 + shl ax, 1 +ss_1: + cmp byte [bps], 8 + jna short ss_2 + ; 16 bit samples + shl ax, 1 +ss_2: + mov [loadsize], ax + mul dx + ;cmp cx, 1 + ;je short ss_3 +;ss_3: + div cx + mov cl, [fbs_shift] + shl ax, cl + shr ax, 1 ; buffer size is 16 bit sample count + mov [buffersize], ax + mov [loadfromwavfile], bx + jmp short PlayNow + +vra_needed: + ; 13/11/2023 + pop ax ; discard return address to the caller + ; 30/05/2024 +vra_err: + sys_msg msg_no_vra, 0Fh + jmp Exit + + ; 30/05/2024 + ; 13/11/2023 (ich_wav4.asm) +loadfromwavfile: + dw loadFromFile +loadsize: ; read from wav file + dw 0 +buffersize: ; write to DMA buffer + dd 32768 ; 16 bit samples (not bytes) + +PlayNow: + ; 30/05/2024 + ; playwav4.asm +_2: + call check4keyboardstop ; flush keyboard buffer + jc short _2 ; 07/11/2023 + + ;call codecConfig ; unmute codec, set rates. + ; 11/11/2023 + ;jc short init_err + +; position file pointer to start in actual wav data +; MUCH improvement should really be done here to check if sample size is +; supported, make sure there are 2 channels, etc. +; + mov ah, 42h + mov al, 0 ; from start of file + mov bx, [filehandle] + xor cx, cx + mov dx, 44 ; jump past .wav/riff header + int 21h + + ; 30/05/2024 + sys_msg nextline, 07h + +; play the .wav file. Most of the good stuff is in here. + + call PlayWav + +; close the .wav file and exit. + +Exit: + call closeFile + + mov ax, 4c00h ; bye ! + int 21h +here: + jmp short here ; do not come here ! + + ; 30/05/2024 +pmsg_usage: + sys_msg msg_usage, 0Bh + jmp short Exit + + ; 30/05/2024 +init_err: + sys_msg msg_init_err, 0Fh + jmp short Exit + + ; 30/05/2024 +error_exit: + sys_msg msg_error, 0Eh + jmp short Exit + + ; -------------------------------------------- + + ; 29/05/2024 (TYRDOS 386, playwav7.s) + ; ((Modified from playwav4.asm, ich_wav4.asm)) + ; ------------------ +;playwav_vra: +PlayWav: + ; create Buffer Descriptor List + + ; Generic Form of Buffer Descriptor + ; --------------------------------- + ; 63 62 61-48 47-32 31-0 + ; --- --- -------- ------- ----- + ; IOC BUP -reserved- Buffer Buffer + ; Length Pointer + ; [15:0] [31:0] + + push es + mov ax, [BDL_BUFFER] ; get segment # for BDL + mov es, ax + + mov cx, 32 / 2 ; make 32 entries in BDL + xor di, di +_0: + movzx eax, word [WAV_BUFFER1] + shl eax, 4 ; convert seg:off ->0:offset + stosd ; store pointer to wavbuffer1 + + ;mov eax, BUFFERSIZE / 2 ; size of buffer (32K) in (16bit) words + ; 13/11/2023 (ich_wav3.asm) - 18/11/2023 (ich_wav4.asm) + mov eax, [buffersize] + + ;or eax, IOC + BUP + ; 06/11/2023 (TUNELOOP version, without interrupt) + or eax, BUP + stosd + + movzx eax, word [WAV_BUFFER2] + shl eax, 4 ; convert seg:off ->0:offset + stosd ; store pointer to wavbuffer2 + + ;mov eax, BUFFERSIZE / 2 ; size of half buffer (32K) + ; 13/11/2023 (ich_wav3.asm) - 18/11/2023 (ich_wav4.asm) + mov eax, [buffersize] + + ;or eax, IOC + BUP + ; 06/11/2023 (TUNELOOP version, without interrupt) + or eax, BUP + stosd + + loop _0 + pop es + + ; load 64k into buffer 1 + mov ax, [WAV_BUFFER1] + ;call loadFromFile + ; 13/11/2023 + call word [loadfromwavfile] + + ; and 64k into buffer 2 + mov ax, [WAV_BUFFER2] + ;call loadFromFile + ; 13/11/2023 + call word [loadfromwavfile] + + ; write NABMBAR+10h with offset of buffer descriptor list + + movzx eax, word [BDL_BUFFER] + shl eax, 4 ; convert seg:off to 0:off + mov dx, [NABMBAR] + add dx, PO_BDBAR_REG ; set pointer to BDL + out dx, eax ; write to AC97 controller + + ; 19/05/2024 + call delay1_4ms + + mov al, 31 + call setLastValidIndex + + ; 19/05/2024 + ;call delay1_4ms + + ; 17/02/2017 + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + ;mov al, IOCE + RPBM ; Enable 'Interrupt On Completion' + run + ; ; (LVBI interrupt will not be enabled) + ; 06/11/2023 (TUNELOOP version, without interrupt) + mov al, RPBM + out dx, al ; Start bus master operation. + + ; 19/05/2024 + ; 06/11/2023 + call delay1_4ms ; 30/05/2024 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + +; while DMA engine is running, examine current index and wait until it hits 1 +; as soon as it's 1, we need to refresh the data in wavbuffer1 with another +; 64k. Likewise when it's playing buffer 2, refresh buffer 1 and repeat. + +; 18/11/2023 +; 08/11/2023 +; 07/11/2023 + +tuneLoop: + ; 30/05/2024 + ; 18/11/2023 (ich_wav4.asm) + ; 08/11/2023 + ; 06/11/2023 + mov al, '1' + call tL0 +tL1: + call updateLVI ; /set LVI != CIV/ + jz short _exitt_ ; 08/11/2023 + call check4keyboardstop + jc short _exitt_ + call getCurrentIndex + test al, BIT0 + jz short tL1 ; loop if buffer 2 is not playing + + ; load buffer 1 + mov ax, [WAV_BUFFER1] + ;call loadFromFile + ; 18/11/2023 + call word [loadfromwavfile] + jc short _exitt_ ; end of file + + mov al, '2' + call tL0 +tL2: + call updateLVI + jz short _exitt_ ; 08/11/2023 + call check4keyboardstop + jc short _exitt_ + call getCurrentIndex + test al, BIT0 + jnz short tL2 ; loop if buffer 1 is not playing + + ; load buffer 2 + mov ax, [WAV_BUFFER2] + ;call loadFromFile + ; 18/11/2023 + call word [loadfromwavfile] + jnc short tuneLoop +_exitt_: + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + mov al, 0 + out dx, al ; stop player + + ; 30/05/2024 + mov al, '0' + + ;add al, '0' + ;call tL0 + ; + ;retn + ; 06/11/2023 + ;jmp short tL0 + ;retn + + ; 06/11/2023 +tL0: + ; 08/11/2023 + ; 05/11/2023 + ; 17/02/2017 - Buffer switch test (temporary) + ; 06/11/2023 + ; al = buffer indicator ('1', '2' or '0' -stop- ) + push ds + ;push bx + mov bx, 0B800h ; video display page segment + mov ds, bx + sub bx, bx ; 0 + mov ah, 4Eh + mov [bx], ax ; show current play buffer (1, 2) + ;pop bx + pop ds + retn + + ; ------------------ + + ; 30/05/2024 +DetectAC97: +DetectICH: + ; 22/11/2023 + ; 19/11/2023 + ; 01/11/2023 - TRDOS 386 Kernel v2.0.7 + ;; 10/06/2017 + ;; 05/06/2017 + ;; 29/05/2017 + ;; 28/05/2017 + + ; 19/11/2023 + mov si, valid_ids ; address of Valid ICH (AC97) Device IDs + mov cx, valid_id_count +pfd_1: + lodsd + call pciFindDevice + jnc short d_ac97_1 + loop pfd_1 + + ;stc + retn + +d_ac97_1: + ; eax = BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; edx = DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + ; playwav4.asm - 19/05/2024 + + mov [bus_dev_fn], eax + mov [dev_vendor], edx + + ; get ICH base address regs for mixer and bus master + + mov al, NAMBAR_REG + call pciRegRead16 ; read PCI registers 10-11 + ;and dx, IO_ADDR_MASK ; mask off BIT0 + ; 19/05/2024 + and dl, 0FEh + + mov [NAMBAR], dx ; save audio mixer base addr + + mov al, NABMBAR_REG + call pciRegRead16 + ;and dx, IO_ADDR_MASK + ; 19/05/2024 + and dl, 0C0h + + mov [NABMBAR], dx ; save bus master base addr + + mov al, AC97_INT_LINE ; Interrupt line register (3Ch) + call pciRegRead8 ; 17/02/2017 + + mov [ac97_int_ln_reg], dl + + ;clc + + retn + +; FILE.ASM +;open or create file +; +;input: ds:dx-->filename (asciiz) +; al=file Mode (create or open) +;output: none cs:[filehandle] filled +; +openFile: ; (playwav4.asm) + push ax + push cx + mov ah, 3Bh ; start with a mode + add ah, al ; add in create or open mode + xor cx, cx + int 21h + jc short _of1 + ;mov [cs:filehandle], ax + mov [filehandle], ax +_of1: + pop cx + pop ax + retn + +; close the currently open file +; input: none, uses cs:[filehandle] +closeFile: ; (playwav4.asm) + push ax + push bx + cmp word [filehandle], -1 + jz short _cf1 + mov bx, [filehandle] + mov ax,3e00h + int 21h ;close file +_cf1: + pop bx + pop ax + retn + +getSampleRate: ; (playwav4.asm) + ; 08/12/2016 +; reads the sample rate from the .wav file. +; entry: none - assumes file is already open + ; 19/11/2016 - Erdogan Tan +; exit: ax = sample rate (11025, 22050, 44100, 48000) +; cx = number of channels (mono=1, stereo=2) +; dx = bits per sample (8, 16) + + push bx + + mov ah, 42h + mov al, 0 ; from start of file + mov bx, [filehandle] + xor cx, cx + mov dx, 08h ; "WAVE" + int 21h + + mov dx, smpRBuff + mov cx, 28 ; 28 bytes + mov ah, 3fh + int 21h + + cmp word [smpRBuff], 'WA' + jne short gsr_stc + + cmp word [smpRBuff+2], 'VE' + jne short gsr_stc + + cmp word [smpRBuff+12], 1 ; Offset 20, must be 1 (= PCM) + jne short gsr_stc + + + mov cx, [smpRBuff+14] ; return num of channels in CX + mov ax, [smpRBuff+16] ; return sample rate in AX + mov dx, [smpRBuff+26] ; return bits per sample value in DX +gsr_retn: + pop bx + retn + +gsr_stc: + stc + jmp short gsr_retn + +; ---- 30/05/2024 (playwav4.asm, 19/05/2024) + +; MEMALLOC.ASM +;-- SETFREE: Release memory not used ---------------- +;-- Input : ES = address of PSP +;-- Output : none +;-- Register : AX, BX, CL and FLAGS are changed +;-- Info : Since the stack-segment is always the last segment in an +; EXE-file, ES:0000 points to the beginning and SS:SP +; to the end of the program in memory. Through this the +; length of the program can be calculated +; call this routine once at the beginning of the program to free up memory +; assigned to it by DOS. + +setFree: + mov bx, 65536/16 ; 4K paragraphs ; 17/02/2017 (Erdogan Tan) + + mov ah, 4Ah ; pass new length to DOS + int 21h + + retn ; back to caller + ; new size (allocated memory) = 64KB + +memAlloc: +; input: AX = # of paragraphs required +; output: AX = segment of block to use + + push bx + mov bx, ax + mov ah, 48h + int 21h + pop bx + retn + +; ---- + +; ///// + + ; 30/05/2024 (ich_wav4.asm, 19/05/2024) +loadFromFile: + ; 07/11/2023 + + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff_0 ; no + stc + retn + +lff_0: + ; 08/11/2023 + mov bp, ax ; save buffer segment + + mov cl, [fbs_shift] + and cl, cl + jz short lff_1 ; stereo, 16 bit + + mov di, BUFFERSIZE - 1 ; 65535 + + ; fbs_shift = + ; 2 for mono and 8 bit sample (multiplier = 4) + ; 1 for mono or 8 bit sample (multiplier = 2) + shr di, cl + inc di ; 16384 for 8 bit and mono + ; 32768 for 8 bit or mono + + mov ax, cs + mov dx, temp_buffer ; temporary buffer for wav data + + ; 17/02/2017 (stereo/mono, 8bit/16bit corrections) + ; load file into memory + mov cx, di + mov bx, [filehandle] + mov ds, ax + mov ah, 3Fh + int 21h + + mov bx, cs + mov ds, bx + + jc short lff_4 ; error ! + + ; 08/11/2023 + xor dx, dx ; 0 + + and ax, ax + jz short lff_3 + + mov bl, [fbs_shift] + + push es + mov di, dx ; 0 ; [fbs_off] + ;mov bp, [fbs_seg] ; buffer segment + mov es, bp + mov si, temp_buffer ; temporary buffer address + mov cx, ax ; byte count + cmp byte [bps], 8 ; bits per sample (8 or 16) + jne short lff_7 ; 16 bit samples + ; 8 bit samples + dec bl ; shift count, 1 = stereo, 2 = mono + jz short lff_6 ; 8 bit, stereo +lff_5: + ; mono & 8 bit + lodsb + sub al, 80h ; 08/11/2023 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; left channel + stosw ; right channel + loop lff_5 + jmp short lff_9 +lff_6: + ; stereo & 8 bit + lodsb + sub al, 80h ; 08/11/2023 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw + loop lff_6 + jmp short lff_9 +lff_7: + shr cx, 1 ; word count +lff_8: + lodsw + stosw ; left channel + stosw ; right channel + loop lff_8 +lff_9: + pop es + or di, di + jz short endLFF ; 64KB ok + + mov ax, di ; [fbs_off] + dec ax + mov cx, BUFFERSIZE - 1 ; 65535 + jmp short lff_3 + +lff_1: + ;mov bp, ax ; save buffer segment + xor dx, dx + ; load file into memory + mov cx, (BUFFERSIZE / 2) ; 32k chunk + mov bx, [filehandle] + mov ds, ax + mov ah, 3Fh + int 21h + + mov di, cs + mov ds, di + + ; 07/11/2023 + jc short lff_4 ; error ! + + cmp ax, cx + jne short lff_3 +lff_2: + ; 08/11/2023 + add dx, ax + ;mov cx, (BUFFERSIZE / 2) ; 32k chunk + ;mov bx, [filehandle] + mov ds, bp + mov ah, 3Fh + int 21h + + ;mov di, cs + mov ds, di + + jc short lff_4 ; error ! + + cmp ax, cx + je short endLFF +lff_3: + call padfill ; blank pad the remainder + ;clc ; don't exit with CY yet. + or byte [flags], ENDOFFILE ; end of file flag +endLFF: + retn +lff_4: + ; 08/11/2023 + mov al, '!' ; error + call tL0 + + xor ax, ax + jmp short lff_3 + +; entry ds:ax points to last byte in file +; cx=target size +; note: must do byte size fill +; destroys bx, cx +; +padfill: + ; 07/11/2023 + ; 06/11/2023 + ; 17/02/2017 + push es + ;push di + ;mov di, [fbs_seg] + ;mov es, di + mov es, bp + sub cx, ax + ; 08/11/2023 + ;mov di, ax ; (wrong) + mov di, dx ; buffer offset + add di, ax + ; 07/11/2023 + ;add di, [fbs_off] + xor al, al + rep stosb + ;mov [fbs_off], di + ;pop di + pop es + retn +; ///// + +write_audio_dev_info: + ; 30/05/2024 + sys_msg msgAudioCardInfo, 0Fh + retn + +write_wav_file_info: + ; 30/05/2024 + ; 01/05/2017 + sys_msg msgWavFileName, 0Fh + sys_msg wav_file_name, 0Fh + +write_sample_rate: + ; 30/05/2024 + ; 01/05/2017 + mov ax, [sample_rate] + ; ax = sample rate (hertz) + xor dx, dx + mov cx, 10 + div cx + add [msgHertz+4], dl + sub dx, dx + div cx + add [msgHertz+3], dl + sub dx, dx + div cx + add [msgHertz+2], dl + sub dx, dx + div cx + add [msgHertz+1], dl + add [msgHertz], al + + ; 30/05/2024 + sys_msg msgSampleRate, 0Fh + + ; 19/11/2016 + mov dx, msg16Bits + cmp byte [bps], 16 + je short wsr_1 + mov dx, msg8Bits +wsr_1: + ; 30/05/2024 + sys_msg dx, 0Fh + + mov dx, msgMono + cmp byte [stmo], 1 + je short wsr_2 + mov dx, msgStereo +wsr_2: + ; 30/05/2024 + sys_msg dx, 0Fh + ; 30/05/2024 + sys_msg nextline, 07h + retn + +write_ac97_pci_dev_info: + ; 30/05/2024 + ; 06/06/2017 + ; 03/06/2017 + ; BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + mov eax, [dev_vendor] + xor bh, bh + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId], al + shr eax, 16 + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId], al + + mov eax, [bus_dev_fn] + shr eax, 8 + mov bl, al + mov dl, bl + and bl, 7 ; bit 0,1,2 + mov al, [bx+hex_chars] + mov [msgFncNo+1], al + mov bl, dl + shr bl, 3 + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevNo], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBusNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBusNo], al + + ;mov ax, [ac97_NamBar] + mov ax, [NAMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNamBar+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNamBar+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNamBar+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNamBar], al + + ;mov ax, [ac97_NabmBar] + mov ax, [NABMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNabmBar+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNabmBar+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNabmBar+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNabmBar], al + + xor eax, eax + mov al, [ac97_int_ln_reg] + mov cl, 10 + div cl + add [msgIRQ], ax + and al, al + jnz short _w_ac97imsg_ + mov al, byte [msgIRQ+1] + mov ah, ' ' + mov [msgIRQ], ax +_w_ac97imsg_: + ; 30/05/2024 + sys_msg msgAC97Info, 07h + + retn + + ; 30/05/2024 +write_VRA_info: + sys_msg msgVRAheader, 07h + cmp byte [VRA], 0 + jna short _w_VRAi_no +_w_VRAi_yes: + sys_msg msgVRAyes, 07h + retn +_w_VRAi_no: + sys_msg msgVRAno, 07h + retn + +; 30/05/2024 (playwav6.asm) +; 18/11/2023 (ich_wav3.asm & ich_wav4.asm) +; 15/11/2023 (ich_wav3.asm) +; 14/11/2023 +; 13/11/2023 - Erdogan Tan - (VRA, sample rate conversion) +; -------------------------------------------------------- + +;;Note: At the end of every buffer load, +;; during buffer switch/swap, there will be discontinuity +;; between the last converted sample and the 1st sample +;; of the next buffer. +;; (like as a dot noises vaguely between normal sound samples) +;; -To avoid this defect, the 1st sample of +;; the next buffer may be read from the wav file but +;; the file pointer would need to be set to 1 sample back +;; again via seek system call. Time comsumption problem! - +;; +;; Erdogan Tan - 15/11/2023 +;; +;; ((If entire wav data would be loaded at once.. conversion +;; defect/noise would disappear.. but for DOS, to keep +;; 64KB buffer limit is important also it is important +;; for running under 1MB barrier without HIMEM.SYS or DPMI. +;; I have tested this program by using 2-30MB wav files.)) +;; +;; Test Computer: ASUS desktop/mainboard, M2N4-SLI, 2010. +;; AMD Athlon 64 X2 2200 MHZ CPU. +;; NFORCE4 (CK804) AC97 audio hardware. +;; Realtek ALC850 codec. +;; Retro DOS v4.2 (MSDOS 6.22) operating system. + +load_8khz_mono_8_bit: + ; 15/11/2023 + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8m_0 ; no + stc + retn + +lff8m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + ;jc short lff8m_5 ; error ! + ; 14/11/2023 + jnc short lff8m_6 + jmp lff8m_5 + +lff8m_6: + mov si, dx ; temp_buffer ; temporary buffer address + and ax, ax + ;jz short lff8m_3 + ; 15/11/2023 + jz short lff8_eof + + mov cx, ax ; byte count +lff8m_1: + lodsb + mov [previous_val], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + ; 14/11/2023 + mov al, 80h + dec cx + jz short lff8m_2 + mov al, [si] +lff8m_2: + ;mov [next_val], ax + mov bh, al ; [next_val] + mov ah, [previous_val] + add al, ah ; [previous_val] + rcr al, 1 + mov dl, al ; this is interpolated middle (3th) sample + add al, ah ; [previous_val] + rcr al, 1 + mov bl, al ; this is temporary interpolation value + add al, ah ; [previous_val] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + mov al, dl + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (L) + stosw ; this is middle (3th) interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, dl + rcr al, 1 + mov bl, al ; this is temporary interpolation value + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (L) + stosw ; this is 4th interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (L) + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff8m_1 + + ; -------------- + +lff8s_3: +lff8m_3: +lff8s2_3: +lff8m2_3: +lff16s_3: +lff16m_3: +lff16s2_3: +lff16m2_3: +lff24_3: +lff32_3: +lff44_3: +lff22_3: +lff11_3: + mov cx, [buffersize] ; 16 bit (48 kHZ, stereo) sample size + shl cx, 1 ; byte count + sub cx, di + jna short lff8m_4 + ;inc cx + shr cx, 1 + xor ax, ax ; fill (remain part of) buffer with zeros + rep stosw +lff8m_4: + push cs + pop es + retn + +lff8_eof: +lff16_eof: +lff24_eof: +lff32_eof: +lff44_eof: +lff22_eof: +lff11_eof: + ; 15/11/2023 + mov byte [flags], ENDOFFILE + jmp short lff8m_3 + +lff8s_5: +lff8m_5: +lff8s2_5: +lff8m2_5: +lff16s_5: +lff16m_5: +lff16s2_5: +lff16m2_5: +lff24_5: +lff32_5: +lff44_5: +lff22_5: +lff11_5: + mov al, '!' ; error + call tL0 + + ;jmp short lff8m_3 + ; 15/11/2023 + jmp lff8_eof + + ; -------------- + +load_8khz_stereo_8_bit: + ; 15/11/2023 + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8s_0 ; no + stc + retn + +lff8s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8s_5 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;;and ax, ax + ;jz short lff8s_3 + ; 15/11/2023 + jz short lff8_eof + + mov cx, ax ; word count +lff8s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + ; 14/11/2023 + mov ax, 8080h + dec cx + jz short lff8s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff8s_2: + mov [next_val_l], al + mov [next_val_r], ah + mov ah, [previous_val_l] + add al, ah + rcr al, 1 + mov dl, al ; this is interpolated middle (3th) sample (L) + add al, ah + rcr al, 1 + mov bl, al ; this is temporary interpolation value (L) + add al, ah + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + mov al, [next_val_r] + mov ah, [previous_val_r] + add al, ah + rcr al, 1 + mov dh, al ; this is interpolated middle (3th) sample (R) + add al, ah + rcr al, 1 + mov bh, al ; this is temporary interpolation value (R) + add al, ah + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + mov al, bh + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (R) + mov al, dl + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (L) + mov al, dh + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (R) + mov al, [next_val_l] + add al, dl + rcr al, 1 + mov bl, al ; this is temporary interpolation value (L) + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (L) + mov al, [next_val_r] + add al, dh + rcr al, 1 + mov bh, al ; this is temporary interpolation value (R) + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (R) + mov al, [next_val_l] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (L) + mov al, [next_val_r] + add al, bh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + jcxz lff8s_6 + jmp lff8s_1 +lff8s_6: + jmp lff8s_3 + +load_8khz_mono_16_bit: + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8m2_0 ; no + stc + retn + +lff8m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff8m2_8 + ;jmp lff8m2_3 + ; 15/11/2023 + jmp lff8_eof + +lff8m2_8: + mov cx, ax ; word count +lff8m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val], ax + xor ax, ax + dec cx + jz short lff8m2_2 + mov ax, [si] +lff8m2_2: + add ah, 80h ; convert sound level to 0-65535 format + mov bp, ax ; [next_val] + add ax, [previous_val] + rcr ax, 1 + mov dx, ax ; this is interpolated middle (3th) sample + add ax, [previous_val] + rcr ax, 1 ; this is temporary interpolation value + mov bx, ax + add ax, [previous_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov ax, bx + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + mov ax, dx + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is middle (3th) interpolated sample (L) + stosw ; this is middle (3th) interpolated sample (R) + mov ax, bp + add ax, dx + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (L) + stosw ; this is 4th interpolated sample (R) + mov ax, bp + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 5th interpolated sample (L) + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff8m2_1 + jmp lff8m2_3 + +lff8m2_7: +lff8s2_7: + jmp lff8m2_5 ; error + +load_8khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8s2_0 ; no + stc + retn + +lff8s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff8s2_8 + ;jmp lff8s2_3 + ; 15/11/2023 + jmp lff8_eof + +lff8s2_8: + mov cx, ax ; dword count +lff8s2_1: + lodsw + stosw ; original sample (L) + ; 15/11/2023 + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val_r], ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff8s2_2 + mov ax, [si] + mov dx, [si+2] +lff8s2_2: + add ah, 80h ; convert sound level to 0-65535 format + mov [next_val_l], ax + add dh, 80h ; convert sound level to 0-65535 format + mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + mov dx, ax ; this is interpolated middle (3th) sample (L) + add ax, [previous_val_l] + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (L) + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + mov ax, [next_val_r] + add ax, [previous_val_r] + rcr ax, 1 + mov bp, ax ; this is interpolated middle (3th) sample (R) + add ax, [previous_val_r] + rcr ax, 1 + push ax ; * ; this is temporary interpolation value (R) + add ax, [previous_val_r] + rcr ax, 1 + sub ah, 80h + stosw ; this is 1st interpolated sample (R) + mov ax, bx + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + pop ax ; * + add ax, bp + rcr ax, 1 + sub ah, 80h + stosw ; this is 2nd interpolated sample (R) + mov ax, dx + sub ah, 80h + stosw ; this is middle (3th) interpolated sample (L) + mov ax, bp + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is middle (3th) interpolated sample (R) + mov ax, [next_val_l] + add ax, dx + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (L) + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (L) + mov ax, [next_val_r] + add ax, bp + rcr ax, 1 + push ax ; ** ; this is temporary interpolation value (R) + add ax, bp + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (R) + mov ax, [next_val_l] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 5th interpolated sample (L) + pop ax ; ** + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + jcxz lff8_s2_9 + jmp lff8s2_1 +lff8_s2_9: + jmp lff8s2_3 + +; ..................... + +load_16khz_mono_8_bit: + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16m_0 ; no + stc + retn + +lff16m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16m_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff16m_8 + ;jmp lff16m_3 + ; 15/11/2023 + jmp lff16_eof + +lff16m_8: + mov cx, ax ; byte count +lff16m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + ; 14/11/22023 + mov al, 80h + dec cx + jz short lff16m_2 + mov al, [si] +lff16m_2: + ;mov [next_val], al + mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + mov dl, al ; this is interpolated middle (temp) sample + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16m_1 + jmp lff16m_3 + +lff16m_7: +lff16s_7: + jmp lff16m_5 ; error + +load_16khz_stereo_8_bit: + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16s_0 ; no + stc + retn + +lff16s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16s_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff16s_8 + ;jmp lff16s_3 + ; 15/11/2023 + jmp lff16_eof + +lff16s_8: + mov cx, ax ; word count +lff16s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + ; 14/11/2023 + mov ax, 8080h + dec cx + jz short lff16s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff16s_2: + ;mov [next_val_l], al + ;mov [next_val_r], ah + mov bx, ax + add al, [previous_val_l] + rcr al, 1 + mov dl, al ; this is temporary interpolation value (L) + add al, [previous_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + mov dh, al ; this is temporary interpolation value (R) + add al, [previous_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (R) + mov al, dl + add al, bl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + mov al, dh + add al, bh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16s_1 + jmp lff16s_3 + +load_16khz_mono_16_bit: + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16m2_0 ; no + stc + retn + +lff16m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff16m2_8 + ;jmp lff16m2_3 + ; 15/11/2023 + jmp lff16_eof + +lff16m2_8: + mov cx, ax ; word count +lff16m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + mov bx, ax + xor ax, ax + dec cx + jz short lff16m2_2 + mov ax, [si] +lff16m2_2: + add ah, 80h ; convert sound level 0 to 65535 format + mov bp, ax ; [next_val] + ;add ax, [previous_val] + add ax, bx + rcr ax, 1 + mov dx, ax ; this is temporary interpolation value + ;add ax, [previous_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov ax, bp + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + ; 16 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16m2_1 + jmp lff16m2_3 + +lff16m2_7: +lff16s2_7: + jmp lff16m2_5 ; error + +load_16khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16s2_0 ; no + stc + retn + +lff16s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + ;shr ax, 1 + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff16s2_8 + ;jmp lff16s2_3 + ; 15/11/2023 + jmp lff16_eof + +lff16s2_8: + mov cx, ax ; dword count +lff16s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_r], ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff16s2_2 + mov ax, [si] + mov dx, [si+2] +lff16s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_l], ax + mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + mov dx, ax ; this is temporary interpolation value (L) + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + mov ax, [next_val_r] + add ax, [previous_val_r] + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (R) + add ax, [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (R) + ;mov ax, [next_val_l] + mov ax, bp + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + mov ax, [next_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16s2_1 + jmp lff16s2_3 + +; ..................... + +load_24khz_mono_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24m_0 ; no + stc + retn + +lff24m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24m_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff24m_8 + jmp lff24_eof + +lff24m_8: + mov cx, ax ; byte count +lff24m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + mov al, 80h + dec cx + jz short lff24m_2 + mov al, [si] +lff24m_2: + ;;mov [next_val], al + ;mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; 24 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24m_1 + jmp lff24_3 + +lff24m_7: +lff24s_7: + jmp lff24_5 ; error + +load_24khz_stereo_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24s_0 ; no + stc + retn + +lff24s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24s_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff24s_8 + jmp lff24_eof + +lff24s_8: + mov cx, ax ; word count +lff24s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + mov ax, 8080h + dec cx + jz short lff24s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff24s_2: + ;;mov [next_val_l], al + ;;mov [next_val_r], ah + ;mov bx, ax + mov bh, ah + add al, [previous_val_l] + rcr al, 1 + ;mov dl, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + ;mov dh, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (R) + + ; 24 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24s_1 + jmp lff24_3 + +load_24khz_mono_16_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24m2_0 ; no + stc + retn + +lff24m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff24m2_8 + jmp lff24_eof + +lff24m2_8: + mov cx, ax ; word count +lff24m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + ;mov bx, ax + ;xor ax, ax + xor bx, bx + dec cx + jz short lff24m2_2 + ;mov ax, [si + mov bx, [si] +lff24m2_2: + ;add ah, 80h ; convert sound level 0 to 65535 format + ;mov bp, ax ; [next_val] + ;add ax, [previous_val] + ; ax = [previous_val] + ; bx = [next_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + ; 24 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24m2_1 + jmp lff24_3 + +lff24m2_7: +lff24s2_7: + jmp lff24_5 ; error + +load_24khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24s2_0 ; no + stc + retn + +lff24s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + ;shr ax, 1 + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff24s2_8 + jmp lff24_eof + +lff24s2_8: + mov cx, ax ; dword count +lff24s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val_r], ax + mov bx, ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff24s2_2 + mov ax, [si] + mov dx, [si+2] +lff24s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;;mov [next_val_l], ax + ;mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + ;mov ax, [next_val_r] + mov ax, dx + ;add ax, [previous_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (R) + + ; 24 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24s2_1 + jmp lff24_3 + +; ..................... + +load_32khz_mono_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32m_0 ; no + stc + retn + +lff32m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32m_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff32m_8 + jmp lff32_eof + +lff32m_8: + mov cx, ax ; byte count +lff32m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + mov al, 80h + dec cx + jz short lff32m_2 + mov al, [si] +lff32m_2: + ;;mov [next_val], al + ;mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32m_3 + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (left channel) + stosw ; original sample (right channel) + + ; 32 kHZ mono to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32m_1 +lff32m_3: + jmp lff32_3 + +lff32m_7: +lff32s_7: + jmp lff32_5 ; error + +load_32khz_stereo_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32s_0 ; no + stc + retn + +lff32s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32s_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff32s_8 + jmp lff32_eof + +lff32s_8: + mov cx, ax ; word count +lff32s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + mov ax, 8080h + dec cx + jz short lff32s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff32s_2: + ;;mov [next_val_l], al + ;;mov [next_val_r], ah + ;mov bx, ax + mov bh, ah + add al, [previous_val_l] + rcr al, 1 + ;mov dl, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + ;mov dh, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32s_3 + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (left channel) + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (right channel) + + ; 32 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32s_1 +lff32s_3: + jmp lff32_3 + +load_32khz_mono_16_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32m2_0 ; no + stc + retn + +lff32m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff32m2_8 + jmp lff32_eof + +lff32m2_8: + mov cx, ax ; word count +lff32m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + ;mov bx, ax + ;xor ax, ax + xor bx, bx + dec cx + jz short lff32m2_2 + ;mov ax, [si + mov bx, [si] +lff32m2_2: + ;add ah, 80h ; convert sound level 0 to 65535 format + ;mov bp, ax ; [next_val] + ;add ax, [previous_val] + ; ax = [previous_val] + ; bx = [next_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32m2_3 + + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + + ; 32 kHZ mono to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32m2_1 +lff32m2_3: + jmp lff32_3 + +lff32m2_7: +lff32s2_7: + jmp lff32_5 ; error + +load_32khz_stereo_16_bit: + ;16/11/2023 + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32s2_0 ; no + stc + retn + +lff32s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; 16/11/2023 (word left ch + word right ch) + ;and ax, ax + jnz short lff32s2_8 + jmp lff32_eof + +lff32s2_8: + mov cx, ax ; dword count +lff32s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val_r], ax + mov bx, ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff32s2_2 + mov ax, [si] + mov dx, [si+2] +lff32s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;;mov [next_val_l], ax + ;mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + ;mov ax, [next_val_r] + mov ax, dx + ;add ax, [previous_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32s2_3 + + lodsw + stosw ; original sample (L) + lodsw + stosw ; original sample (R) + + ; 32 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32s2_1 +lff32s2_3: + jmp lff32_3 + +; ..................... + +load_22khz_mono_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22m_0 ; no + stc + retn + +lff22m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22m_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff22m_8 + jmp lff22_eof + +lff22m_8: + mov cx, ax ; byte count +lff22m_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phases +lff22m_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsb + mov dl, 80h + dec cx + jz short lff22m_2_1 + mov dl, [si] +lff22m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_3_8bit_mono ; 1 of 17 + jcxz lff22m_3 +lff22m_2_2: + lodsb + mov dl, 80h + dec cx + jz short lff22m_2_3 + mov dl, [si] +lff22m_2_3: + call interpolating_2_8bit_mono ; 2 of 17 .. 6 of 17 + jcxz lff22m_3 + dec bp + jnz short lff22m_2_2 + + mov al, [faz] + dec al + jz short lff22m_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22m_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22m_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +lff22m_3: +lff22s_3: + jmp lff22_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff22m_7: +lff22s_7: + jmp lff22_5 ; error + +load_22khz_stereo_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22s_0 ; no + stc + retn + +lff22s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22s_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff22s_8 + jmp lff22_eof + +lff22s_8: + mov cx, ax ; word count +lff22s_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phase +lff22s_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + mov dx, 8080h + dec cx + jz short lff22s_2_1 + mov dx, [si] +lff22s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_3_8bit_stereo ; 1 of 17 + jcxz lff22s_3 +lff22s_2_2: + lodsw + mov dx, 8080h + dec cx + jz short lff22s_2_3 + mov dx, [si] +lff22s_2_3: + call interpolating_2_8bit_stereo ; 2 of 17 .. 6 of 17 + jcxz lff22s_3 + dec bp + jnz short lff22s_2_2 + + mov al, [faz] + dec al + jz short lff22s_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22s_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22s_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +load_22khz_mono_16_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22m2_0 ; no + stc + retn + +lff22m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff22m2_8 + jmp lff22_eof + +lff22m2_8: + mov cx, ax ; word count +lff22m2_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phases +lff22m2_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + xor dx, dx + dec cx + jz short lff22m2_2_1 + mov dx, [si] +lff22m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_3_16bit_mono ; 1 of 17 + jcxz lff22m2_3 +lff22m2_2_2: + lodsw + xor dx, dx + dec cx + jz short lff22m2_2_3 + mov dx, [si] +lff22m2_2_3: + call interpolating_2_16bit_mono ; 2 of 17 .. 6 of 17 + jcxz lff22m2_3 + dec bp + jnz short lff22m2_2_2 + + mov al, [faz] + dec al + jz short lff22m2_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22m2_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22m2_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +lff22m2_3: +lff22s2_3: + jmp lff22_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff22m2_7: +lff22s2_7: + jmp lff22_5 ; error + +load_22khz_stereo_16_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22s2_0 ; no + stc + retn + +lff22s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff22s2_8 + jmp lff22_eof + +lff22s2_8: + mov cx, ax ; dword count +lff22s2_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phase +lff22s2_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff22s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx +lff22s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_3_16bit_stereo ; 1 of 17 + jcxz lff22s2_3 +lff22s2_2_2: + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff22s2_2_3 + xor dx, dx ; 0 + mov [next_val_l], dx +lff22s2_2_3: + call interpolating_2_16bit_stereo ; 2 of 17 .. 6 of 17 + jcxz lff22s2_3 + dec bp + jnz short lff22s2_2_2 + + mov al, [faz] + dec al + jz short lff22s2_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22s2_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22s2_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +; ..................... + +load_11khz_mono_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11m_0 ; no + stc + retn + +lff11m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11m_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff11m_8 + jmp lff11_eof + +lff11m_8: + mov cx, ax ; byte count +lff11m_9: + mov bp, 6 ; interpolation (one step) loop count +lff11m_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_1 + mov dl, [si] +lff11m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_5_8bit_mono + jcxz lff11m_3 +lff11m_2_2: + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_3 + mov dl, [si] +lff11m_2_3: + call interpolating_4_8bit_mono + jcxz lff11m_3 + + dec bp + jz short lff11m_9 + + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_4 + mov dl, [si] +lff11m_2_4: + call interpolating_4_8bit_mono + jcxz lff11m_3 + jmp short lff11m_1 + +lff11m_3: +lff11s_3: + jmp lff11_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff11m_7: +lff11s_7: + jmp lff11_5 ; error + +load_11khz_stereo_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11s_0 ; no + stc + retn + +lff11s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11s_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff11s_8 + jmp lff11_eof + +lff11s_8: + mov cx, ax ; word count +lff11s_9: + mov bp, 6 ; interpolation (one step) loop count +lff11s_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_1 + mov dx, [si] +lff11s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_5_8bit_stereo + jcxz lff11s_3 +lff11s_2_2: + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_3 + mov dx, [si] +lff11s_2_3: + call interpolating_4_8bit_stereo + jcxz lff11s_3 + + dec bp + jz short lff11s_9 + + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_4 + mov dx, [si] +lff11s_2_4: + call interpolating_4_8bit_stereo + jcxz lff11s_3 + jmp short lff11s_1 + +load_11khz_mono_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11m2_0 ; no + stc + retn + +lff11m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff11m2_8 + jmp lff11_eof + +lff11m2_8: + mov cx, ax ; word count +lff11m2_9: + mov bp, 6 ; interpolation (one step) loop count +lff11m2_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_1 + mov dx, [si] +lff11m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_5_16bit_mono + jcxz lff11m2_3 +lff11m2_2_2: + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_3 + mov dx, [si] +lff11m2_2_3: + call interpolating_4_16bit_mono + jcxz lff11m2_3 + + dec bp + jz short lff11m2_9 + + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_4 + mov dx, [si] +lff11m2_2_4: + call interpolating_4_16bit_mono + jcxz lff11m2_3 + jmp short lff11m2_1 + +lff11m2_7: +lff11s2_7: + jmp lff11_5 ; error + +load_11khz_stereo_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11s2_0 ; no + stc + retn + +lff11s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff11s2_8 + jmp lff11_eof + +lff11m2_3: +lff11s2_3: + jmp lff11_3 ; padfill + ; (put zeros in the remain words of the buffer) + +lff11s2_8: + mov cx, ax ; dword count +lff11s2_9: + mov bp, 6 ; interpolation (one step) loop count +lff11s2_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_5_16bit_stereo + jcxz lff11s2_3 +lff11s2_2_2: + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_3 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_3: + call interpolating_4_16bit_stereo + jcxz lff11s2_3 + + dec bp + jz short lff11s2_9 + + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_4 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_4: + call interpolating_4_16bit_stereo + jcxz lff11s2_3 + jmp short lff11s2_1 + +; ..................... + +load_44khz_mono_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44m_0 ; no + stc + retn + +lff44m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44m_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff44m_8 + jmp lff44_eof + +lff44m_8: + mov cx, ax ; byte count +lff44m_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phases +lff44m_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsb + mov dl, 80h + dec cx + jz short lff44m_2_1 + mov dl, [si] +lff44m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_2_8bit_mono + jcxz lff44m_3 +lff44m_2_2: + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (L) + stosw ; (R) + + dec cx + jz short lff44m_3 + dec bp + jnz short lff44m_2_2 + + dec byte [faz] + jz short lff44m_9 + mov bp, 11 + jmp short lff44m_1 + +lff44m_3: +lff44s_3: + jmp lff44_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff44m_7: +lff44s_7: + jmp lff44_5 ; error + +load_44khz_stereo_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44s_0 ; no + stc + retn + +lff44s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44s_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff44s_8 + jmp lff44_eof + +lff44s_8: + mov cx, ax ; word count +lff44s_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phase +lff44s_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + mov dx, 8080h + dec cx + jz short lff44s_2_1 + mov dx, [si] +lff44s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_2_8bit_stereo + jcxz lff44s_3 +lff44s_2_2: + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (L) + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (R) + + dec cx + jz short lff44s_3 + dec bp + jnz short lff44s_2_2 + + dec byte [faz] + jz short lff44s_9 + mov bp, 11 + jmp short lff44s_1 + +load_44khz_mono_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44m2_0 ; no + stc + retn + +lff44m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44m2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff44m2_8 + jmp lff44_eof + +lff44m2_8: + mov cx, ax ; word count +lff44m2_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phases +lff44m2_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + xor dx, dx + dec cx + jz short lff44m2_2_1 + mov dx, [si] +lff44m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_2_16bit_mono + jcxz lff44m2_3 +lff44m2_2_2: + lodsw + stosw ; (L)eft Channel + stosw ; (R)ight Channel + + dec cx + jz short lff44m2_3 + dec bp + jnz short lff44m2_2_2 + + dec byte [faz] + jz short lff44m2_9 + mov bp, 11 + jmp short lff44m2_1 + +lff44m2_3: +lff44s2_3: + jmp lff44_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff44m2_7: +lff44s2_7: + jmp lff44_5 ; error + +load_44khz_stereo_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44s2_0 ; no + stc + retn + +lff44s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff44s2_8 + jmp lff44_eof + +lff44s2_8: + mov cx, ax ; dword count +lff44s2_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phase +lff44s2_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff44s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx +lff44s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_2_16bit_stereo + jcxz lff44s2_3 +lff44s2_2_2: + ;lodsw + ;stosw ; (L) + ;lodsw + ;stosw ; (R) + movsw ; (L)eft Channel + movsw ; (R)ight Channel + + dec cx + jz short lff44s2_3 + dec bp + jnz short lff44s2_2_2 + + dec byte [faz] + jz short lff44s2_9 + mov bp, 11 + jmp short lff44s2_1 + +; ..................... + +interpolating_3_8bit_mono: + ; 16/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + mov bh, al ; interpolated middle (temporary) + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bh + add al, dl ; [next_val] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + retn + +interpolating_3_8bit_stereo: + ; 16/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + push ax ; * ; al = interpolated middle (L) (temporary) + add al, bl ; [previous_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + push ax ; ** ; al = interpolated middle (R) (temporary) + add al, bh ; [previous_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + pop bx ; ** + pop ax ; * + add al, dl ; [next_val_l] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bl + add al, dh ; [next_val_r] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (R) + retn + +interpolating_2_8bit_mono: + ; 16/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (L) + stosw ; interpolated sample (R) + retn + +interpolating_2_8bit_stereo: + ; 16/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl ; [previous_val_l] + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (R) + retn + +interpolating_3_16bit_mono: + ; 16/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val] + add dh, 80h + add ax, dx + rcr ax, 1 + pop bx ; * + xchg bx, ax ; bx = interpolated middle (temporary) + add ax, bx ; [previous_val] + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov ax, bx + add ax, dx ;interpolated middle + [next_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + retn + +interpolating_3_16bit_stereo: + ; 16/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + ; original-interpolated-interpolated + + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + xchg ax, bx ; ax = [previous_val_l] + add ax, bx ; bx = interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + pop ax ; * + add dh, 80h ; convert sound level 0 to 65535 format + push dx ; * ; [next_val_r] + xchg ax, dx + add ax, dx ; [next_val_r] + [previous_val_r] + rcr ax, 1 ; / 2 + push ax ; ** ; interpolated middle (R) + add ax, dx ; + [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, [next_val_l] + add ax, bx ; + interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + pop ax ; ** + pop dx ; * + add ax, dx ; interpolated middle + [next_val_r] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + retn + + +interpolating_2_16bit_mono: + ; 16/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + add dh, 80h + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (L) + stosw ; interpolated sample (R) + retn + +interpolating_2_16bit_stereo: + ; 16/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + ; original-interpolated + + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + add dh, 80h + add ax, dx ; [previous_val_r] + [next_val_r] + rcr ax, 1 ; / 2 + push ax ; * ; interpolated sample (R) + mov ax, [next_val_l] + add ah, 80h + add bh, 80h + add ax, bx ; [next_val_l] + [previous_val_l] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (L) + pop ax ; * + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (R) + retn + +interpolating_5_8bit_mono: + ; 17/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpltd-interpltd-interpltd-interpltd + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + mov bh, al ; interpolated middle (temporary) + add al, bl ; [previous_val] + rcr al, 1 + mov dh, al ; interpolated 1st quarter (temporary) + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bh + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov al, bh + add al, dl ; [next_val] + rcr al, 1 + mov dh, al ; interpolated 3rd quarter (temporary) + add al, bh + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + mov al, dh + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (L) + stosw ; interpolated sample 4 (R) + retn + +interpolating_5_8bit_stereo: + ; 17/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpltd-interpltd-interpltd-interpltd + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + push dx ; * + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + push ax ; ** ; al = interpolated middle (L) (temporary) + add al, bl ; [previous_val_l] + rcr al, 1 + xchg al, bl + add al, bl ; bl = interpolated 1st quarter (L) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + push ax ; *** ; al = interpolated middle (R) (temporary) + add al, bh ; [previous_val_r] + rcr al, 1 + xchg al, bh + add al, bh ; bh = interpolated 1st quarter (R) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + pop dx ; *** + pop ax ; ** ; al = interpolated middle (L) (temporary) + xchg al, bl ; al = interpolated 1st quarter (L) (temp) + add al, bl ; bl = interpolated middle (L) (temporary) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, dl ; interpolated middle (R) (temporary) + xchg al, bh ; al = interpolated 1st quarter (R) (temp) + add al, bh ; bh = interpolated middle (R) (temporary) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (R) + pop dx ; * + mov al, bl ; interpolated middle (L) (temporary) + add al, dl ; [next_val_l] + rcr al, 1 + xchg al, bl ; al = interpolated middle (R) (temporary) + add al, bl ; bl = interpolated 3rd quarter (L) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + mov al, bh + add al, dh ; interpolated middle (R) + [next_val_r] + rcr al, 1 + xchg al, bh ; al = interpolated middle (R) + add al, bh ; bh = interpolated 3rd quarter (R) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (R) + retn + +interpolating_4_8bit_mono: + ; 17/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated-interpolated-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + xchg al, bl ; al = [previous_val] + add al, bl ; bl = interpolated middle (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bl ; interpolated middle (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov al, bl + add al, dl ; [next_val] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + retn + +interpolating_4_8bit_stereo: + ; 17/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated-interpolated-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + xchg al, bl ; al = [previous_val_l] + add al, bl ; bl = interpolated middle (L) (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + xchg al, bh ; al = [previous_val_h] + add al, bh ; bh = interpolated middle (R) (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + mov al, bl ; interpolated middle (L) (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bh ; interpolated middle (L) (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (R) + retn + +interpolating_5_16bit_mono: + ; 18/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpltd-interpltd-interpltd-interpltd + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov bx, ax ; [previous_val] + add dh, 80h + add ax, dx + rcr ax, 1 + push ax ; * ; interpolated middle (temporary) + add ax, bx ; interpolated middle + [previous_val] + rcr ax, 1 + push ax ; ** ; interpolated 1st quarter (temporary) + add ax, bx ; 1st quarter + [previous_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + pop ax ; ** + pop bx ; * + add ax, bx ; 1st quarter + middle + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, dx ; interpolated middle + [next_val] + rcr ax, 1 + push ax ; * ; interpolated 3rd quarter (temporary) + add ax, bx ; + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + pop ax ; * + add ax, dx ; 3rd quarter + [next_val] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (L) + stosw ; interpolated sample 4 (R) + retn + +interpolating_5_16bit_stereo: + ; 18/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; [next_val_r] + ; original-interpltd-interpltd-interpltd-interpltd + push cx ; ! + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + mov cx, ax ; interpolated middle (L) + add ax, bx + rcr ax, 1 + mov dx, ax ; interpolated 1st quarter (L) + add ax, bx ; [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + mov ax, cx + add ax, dx ; middle (L) + 1st quarter (L) + rcr ax, 1 ; / 2 + mov bx, ax ; interpolated sample 2 (L) + pop dx ; * ; [previous_val_r] + mov ax, dx + add byte [next_val_r+1], 80h + add ax, [next_val_r] + rcr ax, 1 + push ax ; * ; interpolated middle (R) + add ax, dx + rcr ax, 1 + push ax ; ** ; interpolated 1st quarter (R) + add ax, dx ; [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, bx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + pop ax ; ** + pop dx ; * + add ax, dx ; 1st quarter (R) + middle (R) + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (R) + mov ax, cx + add ax, [next_val_l] + rcr ax, 1 + push ax ; * ; interpolated 3rd quarter (L) + add ax, cx ; interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + mov ax, dx + add ax, [next_val_r] + rcr ax, 1 + push ax ; ** ; interpolated 3rd quarter (R) + add ax, dx ; interpolated middle (R) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (R) + pop bx ; ** + pop ax ; * + add ax, [next_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (L) + mov ax, bx + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (R) + pop cx ; ! + retn + +interpolating_4_16bit_mono: + ; 18/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov bx, ax ; [previous_val] + add dh, 80h + add ax, dx ; [previous_val] + [next_val] + rcr ax, 1 + xchg ax, bx + add ax, bx ; [previous_val] + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov ax, bx ; interpolated middle + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, dx ; interpolated middle + [next_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + retn + +interpolating_4_16bit_stereo: + ; 18/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; [next_val_r] + ; original-interpolated-interpolated-interpolated + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov dx, ax ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + xchg ax, bx + add ax, bx ; bx = interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + add byte [next_val_r+1], 80h + mov ax, dx ; [previous_val_r] + add ax, [next_val_r] + rcr ax, 1 + xchg ax, dx + add ax, dx ; dx = interpolated middle (R) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, bx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + mov ax, dx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, [next_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + mov ax, dx + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (R) + retn + +; 13/11/2023 +previous_val: +previous_val_l: dw 0 +previous_val_r: dw 0 +next_val: +next_val_l: dw 0 +next_val_r: dw 0 + +; 16/11/2023 +faz: db 0 + +; -------------------------------------------------------- +; 27/05/2024 - (TRDOS 386 Kernel) audio.s +; -------------------------------------------------------- + +NOT_PCI32_PCI16 EQU 03FFFFFFFh ; NOT BIT31+BIT30 ; 19/03/2017 +NOT_BIT31 EQU 7FFFFFFFh + +pciFindDevice: + ; 19/11/2023 + ; 03/04/2017 ('pci.asm', 20/03/2017) + ; + ; scan through PCI space looking for a device+vendor ID + ; + ; Entry: EAX=Device+Vendor ID + ; + ; Exit: EAX=PCI address if device found + ; EDX=Device+Vendor ID + ; CY clear if found, set if not found. EAX invalid if CY set. + ; + ; Destroys: ebx, edi ; 19/11/2023 + + ; 19/11/2023 + mov ebx, eax + mov edi, 80000000h +nextPCIdevice: + mov eax, edi ; read PCI registers + call pciRegRead32 + ; 19/11/2023 + cmp edx, ebx + je short PCIScanExit ; found + ; 19/11/2023 + cmp edi, 80FFF800h + jnb short pfd_nf ; not found + add edi, 100h + jmp short nextPCIdevice +pfd_nf: + stc + retn +PCIScanExit: + ;pushf + mov eax, NOT_BIT31 ; 19/03/2017 + and eax, edi ; return only bus/dev/fn # + retn + +pciRegRead: + ; 30/05/2024 + ; 03/04/2017 ('pci.asm', 20/03/2017) + ; + ; 8/16/32bit PCI reader + ; + ; Entry: EAX=PCI Bus/Device/fn/register number + ; BIT30 set if 32 bit access requested + ; BIT29 set if 16 bit access requested + ; otherwise defaults to 8 bit read + ; + ; Exit: DL,DX,EDX register data depending on requested read size + ; + ; Note1: this routine is meant to be called via pciRegRead8, + ; pciRegread16 or pciRegRead32, listed below. + ; + ; Note2: don't attempt to read 32 bits of data from a non dword + ; aligned reg number. Likewise, don't do 16 bit reads from + ; non word aligned reg # + + push ebx + push cx + mov ebx, eax ; save eax, dh + mov cl, dh + + and eax, NOT_PCI32_PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; 13/11/2024 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; read to + + test ebx, PCI32+PCI16 + jnz short _pregr0 + + in al, dx ; return 8 bits of data + + mov dl, al + mov dh, cl ; restore dh for 8 bit read + jmp short _pregr2 +_pregr0: + test ebx, PCI32 + jnz short _pregr1 + + in ax, dx + + mov dx, ax ; return 16 bits of data + jmp short _pregr2 +_pregr1: + in eax, dx ; return 32 bits of data + + mov edx, eax +_pregr2: + mov eax, ebx ; restore eax + and eax, NOT_PCI32_PCI16 ; clear out data size request + pop cx + pop ebx + retn + +pciRegRead8: + and eax, NOT_PCI32_PCI16 ; set up 8 bit read size + jmp short pciRegRead ; call generic PCI access + +pciRegRead16: + and eax, NOT_PCI32_PCI16 ; set up 16 bit read size + or eax, PCI16 ; call generic PCI access + jmp short pciRegRead + +pciRegRead32: + and eax, NOT_PCI32_PCI16 ; set up 32 bit read size + or eax, PCI32 ; call generic PCI access + jmp pciRegRead + +pciRegWrite: + ; 30/05/2024 + ; 03/04/2017 ('pci.asm', 29/11/2016) + ; + ; 8/16/32bit PCI writer + ; + ; Entry: EAX=PCI Bus/Device/fn/register number + ; BIT31 set if 32 bit access requested + ; BIT30 set if 16 bit access requested + ; otherwise defaults to 8bit read + ; DL/DX/EDX data to write depending on size + ; + ; Note1: this routine is meant to be called via pciRegWrite8, + ; pciRegWrite16 or pciRegWrite32 as detailed below. + ; + ; Note2: don't attempt to write 32bits of data from a non dword + ; aligned reg number. Likewise, don't do 16 bit writes from + ; non word aligned reg # + + push ebx + push ecx + mov ebx, eax ; save eax, edx + mov ecx, edx + and eax, NOT_PCI32_PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; 13/11/2024 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; write to + + test ebx, PCI32+PCI16 + jnz short _pregw0 + + mov al, cl ; put data into al + out dx, al + + jmp short _pregw2 +_pregw0: + test ebx, PCI32 + jnz short _pregw1 + + mov ax, cx ; put data into ax + out dx, ax + + jmp short _pregw2 +_pregw1: + mov eax, ecx ; put data into eax + out dx, eax +_pregw2: + mov eax, ebx ; restore eax + and eax, NOT_PCI32_PCI16 ; clear out data size request + mov edx, ecx ; restore dx + pop ecx + pop ebx + retn + +pciRegWrite8: + and eax, NOT_PCI32_PCI16 ; set up 8 bit write size + jmp short pciRegWrite ; call generic PCI access + +pciRegWrite16: + and eax, NOT_PCI32_PCI16 ; set up 16 bit write size + or eax, PCI16 ; call generic PCI access + jmp short pciRegWrite + +pciRegWrite32: + and eax, NOT_PCI32_PCI16 ; set up 32 bit write size + or eax, PCI32 ; call generic PCI access + jmp pciRegWrite + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ac97_vra.asm +; -------------------------------------------------------- + + ; 13/11/2023 + +;VRA: db 1 + +codecConfig: + ; 30/05/2024 + ; 19/05/2024 + ; 19/11/2023 + ; 15/11/2023 + ; 04/11/2023 + ; 17/02/2017 + ; 07/11/2016 (Erdogan Tan) + + ;AC97_EA_VRA equ 1 + AC97_EA_VRA equ BIT0 + + ; 04/11/2023 +init_ac97_controller: + mov eax, [bus_dev_fn] + mov al, PCI_CMD_REG + call pciRegRead16 ; read PCI command register + or dl, IO_ENA+BM_ENA ; enable IO and bus master + call pciRegWrite16 + + ;call delay_100ms + + ; 19/05/2024 + ; ('PLAYMOD3.ASM', Erdogan Tan, 18/05/2024) + +init_ac97_codec: + ; 18/11/2023 + mov bp, 40 + ; 29/05/2024 + ;mov bp, 1000 +_initc_1: + ; 30/05/2024 + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + ; 19/05/2024 + call delay1_4ms + + cmp eax, 0FFFFFFFFh ; -1 + jne short _initc_3 +_initc_2: + dec bp + jz short _ac97_codec_ready + + call delay_100ms + jmp short _initc_1 +_initc_3: + test eax, CTRL_ST_CREADY + jnz short _ac97_codec_ready + + ; 30/05/2024 + cmp byte [reset], 1 + jnb short _initc_2 + + call reset_ac97_codec + ; 30/05/2024 + mov byte [reset], 1 + ; 19/05/2024 + jmp short _initc_2 + +_ac97_codec_ready: + mov dx, [NAMBAR] + ;add dx, 0 ; ac_reg_0 ; reset register + out dx, ax + + call delay_100ms + + ; 19/11/2023 + or bp, bp + jnz short _ac97_codec_init_ok + + xor ax, ax ; 0 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + out dx, ax + + ; 30/05/2024 + call delay1_4ms + + ; 19/11/2023 + ; wait for 1 second + ; 19/05/2024 + mov cx, 1000 ; 1000*4*0.25ms = 1s + ;;mov cx, 10 + ; 30/05/2024 + ;mov cx, 40 +_ac97_codec_rloop: + ;call delay_100ms + + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + in ax, dx + + call delay1_4ms + + and ax, 0Fh + cmp al, 0Fh + je short _ac97_codec_init_ok + loop _ac97_codec_rloop + +init_ac97_codec_err1: + ;stc ; cf = 1 ; 19/05/2024 +init_ac97_codec_err2: + retn + +_ac97_codec_init_ok: + call reset_ac97_controller + + ; 30/05/2024 + ; 19/05/2024 + ;call delay_100ms + + ; 30/05/2024 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + +setup_ac97_codec: + ; 12/11/2023 + cmp word [sample_rate], 48000 + je short skip_rate + + ; 30/05/2024 + ; 19/05/2024 + ;call delay1_4ms + + ; 30/05/2024 + ;cmp byte [VRA], 0 + ;jna short skip_rate + + ; 11/11/2023 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + + ; 30/05/2024 + ; 19/05/2024 + call delay1_4ms + + ; 13/11/2024 + ;and al, NOT BIT1 ; Clear DRA + ;;; + ; 30/05/2024 + and al, NOT (BIT1+BIT0) ; Clear DRA+VRA + out dx, ax + + call check_vra + + cmp byte [VRA], 0 + jna short skip_rate + + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + ;and al, ~BIT1 ; Clear DRA + ;;; + + or al, AC97_EA_VRA ; 1 ; 04/11/2023 + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + + out dx, ax ; Enable variable rate audio + + mov cx, 10 +check_vra_loop: + call delay_100ms + ; 30/05/2024 + ;call delay1_4ms + + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + ; 11/11/2023 + in ax, dx + + test al, AC97_EA_VRA ; 1 + jnz short set_rate + + ; 11/11/2023 + loop check_vra_loop + +;vra_not_supported: ; 19/05/2024 + mov byte [VRA], 0 + jmp short skip_rate + +set_rate: + mov ax, [sample_rate] ; 17/02/2017 (Erdogan Tan) + + mov dx, [NAMBAR] + add dx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch + out dx, ax ; PCM Front/Center Output Sample Rate + + ;call delay_100ms + ; 30/05/2024 + call delay1_4ms + + ; 12/11/2023 +skip_rate: + mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_MASTER_VOL_REG ;02h + out dx, ax + + ; 11/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_PCM_OUT_REG ;18h + out dx, ax + + ; 11/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + ; 30/05/2024 + ; 19/05/2024 + ;clc + + retn + +reset_ac97_controller: + ; 19/05/2024 + ; 11/11/2023 + ; 10/06/2017 + ; 29/05/2017 + ; 28/05/2017 + ; reset AC97 audio controller registers + xor ax, ax + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov al, RR + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + retn + +reset_ac97_codec: + ; 11/11/2023 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + in eax, dx + + ;test eax, 2 + ; 06/08/2022 + test al, 2 + jz short _r_ac97codec_cold + + call warm_ac97codec_reset + jnc short _r_ac97codec_ok +_r_ac97codec_cold: + call cold_ac97codec_reset + jnc short _r_ac97codec_ok + + ; 16/04/2017 + ;xor eax, eax ; timeout error + ;stc + retn + +_r_ac97codec_ok: + xor eax, eax + ;mov al, VIA_ACLINK_C00_READY ; 1 + inc al + retn + +warm_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 6 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + mov cx, 10 ; total 1s +_warm_ac97c_rst_wait: + call delay_100ms + + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _warm_ac97c_rst_ok + + dec cx + jnz short _warm_ac97c_rst_wait + +_warm_ac97c_rst_fail: + stc +_warm_ac97c_rst_ok: + retn + +cold_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 2 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + + mov cx, 16 ; total 20*100 ms = 2s + +_cold_ac97c_rst_wait: + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _cold_ac97c_rst_ok + + call delay_100ms + + dec cx + jnz short _cold_ac97c_rst_wait + +_cold_ac97c_rst_fail: + stc +_cold_ac97c_rst_ok: + retn + +; 13/11/2024 +; 30/05/2024 +if 1 +check_vra: + ; 30/05/2024 + mov byte [VRA], 1 + + ; 29/05/2024 - audio.s (TRDOS 386 Kernel) - 27/05/2024 + ; 24/05/2024 + ; 23/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_REG ; 28h + in ax, dx + + ; 30/05/2024 + ; 23/05/2024 + call delay1_4ms + + ; 30/05/2024 + test al, BIT0 + ;test al, 1 ; BIT0 ; Variable Rate Audio bit + jnz short check_vra_ok + +vra_not_supported: + ; 13/11/2023 + mov byte [VRA], 0 +check_vra_ok: + retn +end if + +; -------------------------------------------------------- + +PORTB EQU 061h +REFRESH_STATUS EQU 010h ; Refresh signal status + +delay_100ms: + ; 11/11/2023 + ; 29/05/2017 + ; 24/03/2017 ('codec.asm') + ; wait 100 ms + push cx + mov cx, 400 ; 400*0.25ms +_delay_x_ms: + call delay1_4ms + loop _delay_x_ms + pop cx + retn + +delay1_4ms: + push ax + push cx + mov cx, 16 ; close enough. + in al,PORTB + and al,REFRESH_STATUS + mov ah,al ; Start toggle state + or cx, cx + jz short _d4ms1 + inc cx ; Throwaway first toggle +_d4ms1: + in al,PORTB ; Read system control port + and al,REFRESH_STATUS ; Refresh toggles 15.085 microseconds + cmp ah,al + je short _d4ms1 ; Wait for state change + + mov ah,al ; Update with new state + dec cx + jnz short _d4ms1 + + ; 30/05/2024 + clc + + pop cx + pop ax + retn + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ich_wav4.asm +; -------------------------------------------------------- + +check4keyboardstop: + ; 19/05/2024 + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + ;clc + jz short _cksr + + xor ah, ah + int 16h + + ;;; + ; 19/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + cmp al, 0 + jna short p_3 + dec al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_4 + + mov al, [volume] + cmp al, 31 + jnb short p_3 + inc al +p_2: + mov [volume], al + mov ah, al + mov dx, [NAMBAR] + ;add dx, CODEC_MASTER_VOL_REG + add dx, CODEC_PCM_OUT_REG + out dx, ax + + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms +_cksr: ; 19/05/2024 + clc +p_3: + retn +p_4: + ;;; +;_cskr: + stc + retn + +; returns AL = current index value +getCurrentIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_CIV_REG + in al, dx + ;pop dx +uLVI2: ; 06/11/2023 + retn + +updateLVI: + ; 06/11/2023 + mov dx, [NABMBAR] + add dx, PO_CIV_REG + ; (Current Index Value and Last Valid Index value) + in ax, dx + + cmp al, ah ; is current index = last index ? + jne short uLVI2 + + ; 08/11/2023 + call getCurrentIndex + + test byte [flags], ENDOFFILE + ;jnz short uLVI1 + jz short uLVI0 ; 08/11/2023 + + ; 08/11/2023 + push ax + mov dx, [NABMBAR] + add dx, PO_SR_REG ; PCM out status register + in ax, dx + + test al, 3 ; bit 1 = Current Equals Last Valid (CELV) + ; (has been processed) + ; bit 0 = 1 -> DMA Controller Halted (DCH) + pop ax + jz short uLVI1 +uLVI3: + xor ax, ax + ; zf = 1 + retn +uLVI0: + ; not at the end of the file yet. + dec al + and al, 1Fh +uLVI1: + ;call setLastValidIndex +;uLVI2: + ;retn + +;input AL = index # to stop on +setLastValidIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_LVI_REG + out dx, al + ;pop dx + retn + +; 29/05/2024 +; 19/05/2024 +volume: db 02h + +; -------------------------------------------------------- + +; DATA + +FileHandle: + dd -1 + +; 30/05/2024 +reset: db 0 + +Credits: + db 'Tiny WAV Player for Retro DOS by Erdogan Tan. ' + db 'November 2024.',10,13,0 + db '13/11/2024', 10,13,0 + +msgAudioCardInfo: + db 'for Intel AC97 (ICH) Audio Controller.', 10,13,0 + +msg_usage: + db 'usage: playwav7 filename.wav',10,13,0 ; 30/05/2024 + +noDevMsg: + db 'Error: Unable to find AC97 audio device!' + db 10,13,0 + +noFileErrMsg: + db 'Error: file not found.',10,13,0 + +msg_error: ; 30/05/2024 + +; 29/05/2024 +; 11/11/2023 +msg_init_err: + db CR, LF + db "AC97 Controller/Codec initialization error !" + db CR, LF, "$" + +; 25/11/2023 +msg_no_vra: + db 10,13 + db "No VRA support ! Only 48 kHZ sample rate supported !" + db 10,13,0 + +; 13/11/2024 +; ('<<' to 'shl' conversion for FASM) +; +; 29/05/2024 (TRDOS 386) +; 17/02/2017 +; Valid ICH device IDs + +valid_ids: +;dd (ICH_DID << 16) + INTEL_VID ; 8086h:2415h +dd (ICH_DID shl 16) + INTEL_VID ; 8086h:2415h +dd (ICH0_DID shl 16) + INTEL_VID ; 8086h:2425h +dd (ICH2_DID shl 16) + INTEL_VID ; 8086h:2445h +dd (ICH3_DID shl 16) + INTEL_VID ; 8086h:2485h +dd (ICH4_DID shl 16) + INTEL_VID ; 8086h:24C5h +dd (ICH5_DID shl 16) + INTEL_VID ; 8086h:24D5h +dd (ICH6_DID shl 16) + INTEL_VID ; 8086h:266Eh +dd (ESB6300_DID shl 16) + INTEL_VID ; 8086h:25A6h +dd (ESB631X_DID shl 16) + INTEL_VID ; 8086h:2698h +dd (ICH7_DID shl 16) + INTEL_VID ; 8086h:27DEh +; 03/11/2023 - Erdogan Tan +dd (MX82440_DID shl 16) + INTEL_VID ; 8086h:7195h +dd (SI7012_DID shl 16) + SIS_VID ; 1039h:7012h +dd (NFORCE_DID shl 16) + NVIDIA_VID ; 10DEh:01B1h +dd (NFORCE2_DID shl 16) + NVIDIA_VID ; 10DEh:006Ah +dd (AMD8111_DID shl 16) + AMD_VID ; 1022h:746Dh +dd (AMD768_DID shl 16) + AMD_VID ; 1022h:7445h +dd (CK804_DID shl 16) + NVIDIA_VID ; 10DEh:0059h +dd (MCP04_DID shl 16) + NVIDIA_VID ; 10DEh:003Ah +dd (CK8_DID shl 16) + NVIDIA_VID ; 1022h:008Ah +dd (NFORCE3_DID shl 16) + NVIDIA_VID ; 10DEh:00DAh +dd (CK8S_DID shl 16) + NVIDIA_VID ; 10DEh:00EAh + +;valid_id_count equ ($ - valid_ids)>>2 ; 05/11/2023 +; 13/11/2024 +valid_id_count = ($ - valid_ids) shr 2 ; 05/11/2023 + +msgWavFileName: db 0Dh, 0Ah, "WAV File Name: ",0 +msgSampleRate: db 0Dh, 0Ah, "Sample Rate: " +msgHertz: db "00000 Hz, ", 0 +msg8Bits: db "8 bits, ", 0 +;msgMono: db "Mono", 0Dh, 0Ah, 0 +msgMono: db "Mono", 0 +msg16Bits: db "16 bits, ", 0 +;msgStereo: db "Stereo" +msgStereo: db "Stereo",0 +nextline: db 0Dh, 0Ah, 0 + +; 03/06/2017 +hex_chars db "0123456789ABCDEF", 0 +msgAC97Info db 0Dh, 0Ah + db "AC97 Audio Controller & Codec Info", 0Dh, 0Ah + db "Vendor ID: " +msgVendorId db "0000h Device ID: " +msgDevId db "0000h", 0Dh, 0Ah + db "Bus: " +msgBusNo db "00h Device: " +msgDevNo db "00h Function: " +msgFncNo db "00h" + db 0Dh, 0Ah + db "NAMBAR: " +msgNamBar db "0000h " + db "NABMBAR: " +msgNabmBar db "0000h IRQ: " +msgIRQ dw 3030h + db 0Dh, 0Ah, 0 +; 25/11/2023 +msgVRAheader: db "VRA support: " + db 0 +msgVRAyes: db "YES", 0Dh, 0Ah, 0 +msgVRAno: db "NO ", 0Dh, 0Ah + db "(Interpolated sample rate playing method)" + db 0Dh, 0Ah, 0 + +; 30/05/2024 +print_msg: + mov bx, 07h +p_msg: + push es + push bp + push cx + push dx + + push ds + pop es + mov bp,si + mov ah, 03h ; Return cursor position (in DX) + ; bh = video page number + int 10h + xor cx, cx +p_msg_0: + lodsb + or al, al + jz short p_msg_1 + inc cx + jmp short p_msg_0 +p_msg_1: + or cx, cx + jz short p_msg_x + ; cx = number of chars + ; dx = screen (cursor) position + ; bl = color/attribute + ; bh = video page number + ; es:bp = string buffer + ;mov al, 1 ; attribute in BL, update cursor pos + ;mov ah, 13h ; write character string + mov ax, 1301h + int 10h +p_msg_x: + pop dx + pop cx + pop bp + pop es + retn + +EOF: + +; BSS + +; 17/02/2017 +bss_start: + +align 2 + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +; 30/05/2024 +VRA: rb 1 ; Variable Rate Audio Support Status + rb 1 +; 28/11/2016 + +smpRBuff: rw 14 ; 19/11/2016 - Erdogan Tan + +filehandle: rw 1 + +flags: rb 1 +; 06/11/2023 +ac97_int_ln_reg: rb 1 + +; 30/05/2024 +wav_file_name: + rb 80 ; wave file, path name (<= 80 bytes) + + rw 1 + +; 17/02/2017 +; NAMBAR: Native Audio Mixer Base Address Register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 10h-13h +; NABMBAR: Native Audio Bus Mastering Base Address register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 14h-17h +NAMBAR: rw 1 ; BAR for mixer +NABMBAR: rw 1 ; BAR for bus master regs + +; 256 byte buffer for descriptor list +BDL_BUFFER: rw 1 ; segment of our 256byte BDL buffer +WAV_BUFFER1: rw 1 ; segment of our WAV storage +; 64k buffers for wav file storage +WAV_BUFFER2: rw 1 ; segment of 2nd wav buffer + +; 12/11/2016 - Erdogan Tan + +bus_dev_fn: rd 1 +dev_vendor: rd 1 + +; 06/11/2023 +sample_rate: rw 1 + +; 19/11/2016 +stmo: rw 1 +bps: rw 1 + +; 08/11/2023 +; 07/11/2023 +fbs_shift: rb 1 + rb 1 ; 08/11/2023 + +;alignb 2 + +; 32 kilo bytes for temporay buffer +; (for stereo-mono, 8bit/16bit corrections) +;temp_buffer: rb 32768 +; 18/11/2023 +temp_buffer: rb 56304 ; (44.1 kHZ stereo 14076 samples) + +;alignb 16 +bss_end: \ No newline at end of file diff --git a/trdos386/programs/16bit/playwav7.com b/trdos386/programs/16bit/playwav7.com new file mode 100644 index 0000000..f5aa634 Binary files /dev/null and b/trdos386/programs/16bit/playwav7.com differ diff --git a/trdos386/programs/16bit/playwav7_com_fasm_2024.zip b/trdos386/programs/16bit/playwav7_com_fasm_2024.zip new file mode 100644 index 0000000..6a5bd1e Binary files /dev/null and b/trdos386/programs/16bit/playwav7_com_fasm_2024.zip differ diff --git a/trdos386/programs/16bit/playwav8.asm b/trdos386/programs/16bit/playwav8.asm new file mode 100644 index 0000000..dce94be --- /dev/null +++ b/trdos386/programs/16bit/playwav8.asm @@ -0,0 +1,6503 @@ +; **************************************************************************** +; playwav8.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; PLAYWAV8.COM ! AC'97 (ICH) .WAV PLAYER program by Erdogan TAN +; +; 14/11/2024 +; +; [ Last Modification: 18/12/2024 ] +; +; Modified from PLAYWAV7.COM .wav player program by Erdogan Tan, 13/11/2024 +; +; Assembler: FASM 1.73 +; fasm playwav8.asm PLAYWAV8.COM +; ---------------------------------------------------------------------------- +; In the visualization part of the code, the source code of Matan Alfasi's +; (Ami-Asaf) player.exe program was partially used. +; ---------------------------------------------------------------------------- +; Previous versions of this Wav Player were based in part on .wav file player +; (for DOS) source code written by Jeff Leyla in 2002. + +; playwav7.asm (13/11/2024) + +; TUNELOOP version (playing without AC97 interrupt) - 06/11/2023 - Erdogan Tan +; sample rate conversion version - 18/11/2023 - Erdogan Tan + +; CODE + + ; 13/11/2024 +macro sys_msg op1,op2 +{ ; 30/05/2024 + mov si, op1 ; message + mov bl, op2 ; text color + xor bh, bh ; video page 0 + mov ah, 0Eh + call p_msg +} + +; player internal variables and other equates. +;BUFFERSIZE equ 64 * 1024 ; 64k file buffer size. +; 17/11/2024 +BUFFERSIZE equ 65520 +ENDOFFILE equ 1 ; flag for knowing end of file + +use16 + +org 100h + + include 'ac97.inc' ; 17/02/2017 + +_STARTUP: + ; 30/05/2024 + ; Prints the Credits Text. + sys_msg Credits, 0Bh + + ; 30/05/2024 + call setFree ; deallocate unused DOS mem + + ; 17/02/2017 + ; Clear BSS (uninitialized data) area + xor ax, ax ; 0 + mov cx, (bss_end - bss_start)/2 + mov di, bss_start + rep stosw + + ; Detect (& Enable) AC'97 Audio Device + call DetectAC97 + ;jnc short GetFileName + ; 30/05/2024 + jnc short allocate_memory + + ; 30/05/2024 +_dev_not_ready: + ; couldn't find the audio device! + sys_msg noDevMsg, 0Fh + jmp Exit + + ; 30/05/2024 +allocate_memory: + +; allocate 256 bytes of data for DCM_OUT Buffer Descriptor List. (BDL) + + mov ax, BDL_SIZE / 16 + call memAlloc + mov [BDL_BUFFER], ax ; segment + +; allocate 2 buffers, 64k each for now. + + mov ax, BUFFERSIZE / 16 ; 64k for .WAV file + call memAlloc + mov [WAV_BUFFER1], ax ; segment + + mov ax, BUFFERSIZE / 16 + call memAlloc + mov [WAV_BUFFER2], ax + + ; 30/05/2024 +GetFileName: + mov di, wav_file_name + mov si, 80h + mov bl, [si] + xor bh, bh + inc bx + mov byte [si+bx], 0 ; make AsciiZ filename. + inc si +ScanName: + lodsb + test al, al + jz pmsg_usage + cmp al, 20h + je short ScanName ; scan start of name. + stosb + mov ah, 0FFh + ;;; + ; 14/11/2024 + ; (max. path length = 64 bytes for MSDOS ?) (*) + xor cx, cx ; 0 + ;;; +a_0: + inc ah +a_1: + ;;; + ; 14/11/2024 + inc cx + ;;; + lodsb + stosb + cmp al, '.' + je short a_0 + and al, al + ;jnz short a_1 + ;;; + ; 14/11/2024 + jz short a_3 + and ah, ah + jz short a_2 + cmp al, '\' + jne short a_2 + mov ah, 0 +a_2: + cmp cl, 75 ; 64+8+'.'+3 -> offset 75 is the last chr + jb short a_1 +a_3: + ;;; + or ah, ah ; if period NOT found, + jnz short _1 ; then add a .WAV extension. +SetExt: + dec di + mov dword [di], '.WAV' ; ! 64+12 is DOS limit + ; but writing +4 must not + ; destroy the following data + mov byte [di+4], 0 ; so, 80 bytes path + 0 is possible here +_1: + call write_audio_dev_info + +; open the file + ; open existing file + ; 14/11/2024 + ;mov al, OPEN ; open existing file + mov dx, wav_file_name + call openFile ; no error? ok. + jnc short getwavparms ; 14/11/2024 + +; file not found! + sys_msg noFileErrMsg, 0Ch +_exit_: + jmp Exit + +getwavparms: + ; 14/11/2024 + call getWAVParameters + jc short _exit_ ; nothing to do + + ; 17/11/2024 + mov bl, 4 + sub bl, byte [WAVE_BlockAlign] + ; = 0 for 16 bit stereo + ; = 2 for 8 bit stereo or 16 bit mono + ; = 3 for 8 bit mono + + shr bl, 1 ; 0 --> 0, 2 --> 1, 3 --> 1 + ; 15/11/2024 + adc bl, 0 ; 3 --> 1 --> 2 + mov byte [fbs_shift], bl ; = 2 mono and 8 bit + ; = 0 stereo and 16 bit + ; = 1 mono or 8 bit + ; 30/05/2024 + call codecConfig ; unmute codec, set rates. + jc init_err + + ; 15/11/2024 + ;; Set video mode to 03h (not necessary) + mov ax, 03h + int 10h + + ; 15/11/2024 + ;; Get the cursor type + mov ah, 03h + int 10h + mov [cursortype], cx ; save + + ; 15/11/2024 + ;; Set the cursor to invisible + mov ah, 01h + mov cx, 2607h + int 10h + + ;;; 14/11/2024 +Player_SplashScreen: + ; 15/11/2024 + ;xor dx, dx + ;call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, SplashScreen + int 10h + ;;; + + ;;; + ; 22/11/2024 + ; set wave volume led addresses + mov bx, 13*80*2 + mov bp, 80 + mov di, wleds_addr +wleds_sa_1: + mov cx, 7 +wleds_sa_2: + mov ax, 80*2 + mul cx + add ax, bx + stosw + loop wleds_sa_2 + mov ax, bx + stosw + inc bx + inc bx + dec bp + jnz short wleds_sa_1 + ;;; + + ;;; wait for 3 seconds + mov cx, 002Dh + mov dx, 0C6C0h + mov ah, 86h + int 15h + ;;; + + ;;; +Player_Template: + xor dx, dx + call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + ; 09/12/2024 + ; dx = 0 + ;mov dx, 0 + + mov bp, Template + int 10h + ;;; + + ; 14/11/2024 + call SetTotalTime + call UpdateFileInfo + + ; 25/11/2023 + ; ------------------------------------------ + + ; 18/11/2023 (ich_wav4.asm) + ; 13/11/2023 (ich_wav3.asm) + + cmp byte [VRA], 1 + jb short chk_sample_rate + +playwav_48_khz: + mov word [loadfromwavfile], loadFromFile + ;mov word [loadsize], 0 ; 65536 + ;;; + ; 17/11/2024 + ;mov word [buffersize], 32768 + mov ax, BUFFERSIZE/2 ; 32760 + mov [buffersize], ax ; 16 bit samples + shl ax, 1 ; bytes + mov cl, [fbs_shift] + shr ax, cl + mov [loadsize], ax ; 16380 or 32760 or 65520 + ;;; + jmp PlayNow ; 30/05/2024 + +chk_sample_rate: + ; set conversion parameters + ; (for 8, 11.025, 16, 22.050, 24, 32 kHZ) + mov ax, [WAVE_SampleRate] + cmp ax, 48000 + je short playwav_48_khz +chk_22khz: + cmp ax, 22050 + jne short chk_11khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_22khz_1 + mov bx, load_22khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_22khz_2 + mov bx, load_22khz_mono_16_bit + jmp short chk_22khz_2 +chk_22khz_1: + mov bx, load_22khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_22khz_2 + mov bx, load_22khz_mono_8_bit +chk_22khz_2: + mov ax, 7514 ; (442*17) + mov dx, 37 + mov cx, 17 + jmp set_sizes +chk_11khz: + cmp ax, 11025 + jne short chk_44khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_11khz_1 + mov bx, load_11khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_11khz_2 + mov bx, load_11khz_mono_16_bit + jmp short chk_11khz_2 +chk_11khz_1: + mov bx, load_11khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_11khz_2 + mov bx, load_11khz_mono_8_bit +chk_11khz_2: + mov ax, 3757 ; (221*17) + mov dx, 74 + mov cx, 17 + jmp set_sizes +chk_44khz: + cmp ax, 44100 + jne short chk_16khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_44khz_1 + mov bx, load_44khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_44khz_2 + mov bx, load_44khz_mono_16_bit + jmp short chk_44khz_2 +chk_44khz_1: + mov bx, load_44khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_44khz_2 + mov bx, load_44khz_mono_8_bit +chk_44khz_2: + ;mov ax, 15065 ; (655*23) + ; 18/11/2023 ((file size + bss + stack) <= 64KB) + ;mov ax, 14076 ; (612*23) + ; 17/11/2024 + mov ax, 12650 ; (550*23) + mov dx, 25 + mov cx, 23 + jmp set_sizes +chk_16khz: + cmp ax, 16000 + jne short chk_8khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_16khz_1 + mov bx, load_16khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_16khz_2 + mov bx, load_16khz_mono_16_bit + jmp short chk_16khz_2 +chk_16khz_1: + mov bx, load_16khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_16khz_2 + mov bx, load_16khz_mono_8_bit +chk_16khz_2: + ;mov ax, 5461 + ; 17/11/2024 + mov ax, 5460 + mov dx, 3 + mov cx, 1 + jmp set_sizes +chk_8khz: + cmp ax, 8000 + jne short chk_24khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_8khz_1 + mov bx, load_8khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_8khz_2 + mov bx, load_8khz_mono_16_bit + jmp short chk_8khz_2 +chk_8khz_1: + mov bx, load_8khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_8khz_2 + mov bx, load_8khz_mono_8_bit +chk_8khz_2: + mov ax, 2730 + mov dx, 6 + mov cx, 1 + jmp short set_sizes +chk_24khz: + cmp ax, 24000 + jne short chk_32khz + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_24khz_1 + mov bx, load_24khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_24khz_2 + mov bx, load_24khz_mono_16_bit + jmp short chk_24khz_2 +chk_24khz_1: + mov bx, load_24khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_24khz_2 + mov bx, load_24khz_mono_8_bit +chk_24khz_2: + ;mov ax, 8192 + ; 17/11/2024 + mov ax, 8190 + mov dx, 2 + mov cx, 1 + jmp short set_sizes +chk_32khz: + cmp ax, 32000 + jne short vra_needed + cmp byte [WAVE_BitsPerSample], 8 + jna short chk_32khz_1 + mov bx, load_32khz_stereo_16_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_32khz_2 + mov bx, load_32khz_mono_16_bit + jmp short chk_32khz_2 +chk_32khz_1: + mov bx, load_32khz_stereo_8_bit + cmp byte [WAVE_NumChannels], 1 + jne short chk_32khz_2 + mov bx, load_32khz_mono_8_bit +chk_32khz_2: + ;mov ax, 10922 + ; 17/11/2024 + mov ax, 10920 + mov dx, 3 + mov cx, 2 + ;jmp short set_sizes +set_sizes: + ;;; + ; 17/11/2024 + push cx + mov cl, 2 + sub cl, [fbs_shift] + ; = 2 for 16 bit stereo + ; = 1 for 16 bit mono or 8 bit stereo + ; = 0 for 8 bit mono + shl ax, cl + pop cx + mov [loadsize], ax ; (one) read count in bytes + ;;; + mul dx + cmp cx, 1 + je short s_2 +s_1: + div cx +s_2: + ;;; + ; ax = byte count of (to be) converted samples + + ; 17/11/2024 + ;;; + mov cl, [fbs_shift] + + shl ax, cl + ; *1 for 16 bit stereo + ; *2 for 16 bit mono or 8 bit stereo + ; *4 for for 8 bit mono + ;;; + + ; ax = 16 bit stereo byte count (target buffer size) + + shr ax, 1 ; buffer size is 16 bit sample count + mov [buffersize], ax + mov [loadfromwavfile], bx + jmp short PlayNow + +vra_needed: + ; 13/11/2023 + pop ax ; discard return address to the caller + ; 30/05/2024 +vra_err: + sys_msg msg_no_vra, 0Fh + jmp Exit + + ; 15/11/2024 + ; 30/05/2024 + ; 13/11/2023 (ich_wav4.asm) +;loadfromwavfile: +; dw loadFromFile +;loadsize: ; read from wav file +; dw 0 +;buffersize: ; write to DMA buffer +; dd 32768 ; 16 bit samples (not bytes) + +PlayNow: + ;;; + ; 14/11/2024 + mov al, 3 ; 0 = max, 31 = min + ; 15/11/2024 + ;call SetMasterVolume + call SetPCMOutVolume + call UpdateVolume + ;;; + + ;;; + ; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 30/05/2024 + ; playwav4.asm +_2: + call check4keyboardstop ; flush keyboard buffer + jc short _2 ; 07/11/2023 + +; play the .wav file. Most of the good stuff is in here. + + call PlayWav + +; close the .wav file and exit. + +Exit: + ; 15/11/2024 + ;; Restore Cursor Type + mov cx, [cursortype] + cmp cx, 0 + jz short Exit@ + mov ah, 01h + int 10h +Exit@: + call closeFile + + mov ax, 4C00h ; bye ! + int 21h +here: + jmp short here ; do not come here ! + + ; 30/05/2024 +pmsg_usage: + sys_msg msg_usage, 0Fh ; 14/11/2024 + jmp short Exit + + ; 30/05/2024 +init_err: + sys_msg msg_init_err, 0Fh + jmp short Exit + + ; -------------------------------------------- + + ; 29/05/2024 (TYRDOS 386, playwav7.s) + ; ((Modified from playwav4.asm, ich_wav4.asm)) + ; ------------------ +;playwav_vra: +PlayWav: + ; create Buffer Descriptor List + + ; Generic Form of Buffer Descriptor + ; --------------------------------- + ; 63 62 61-48 47-32 31-0 + ; --- --- -------- ------- ----- + ; IOC BUP -reserved- Buffer Buffer + ; Length Pointer + ; [15:0] [31:0] + + push es + mov ax, [BDL_BUFFER] ; get segment # for BDL + mov es, ax + + mov cx, 32 / 2 ; make 32 entries in BDL + xor di, di +_0: + movzx eax, word [WAV_BUFFER1] + shl eax, 4 ; convert seg:off ->0:offset + stosd ; store pointer to wavbuffer1 + + ;mov eax, BUFFERSIZE / 2 ; size of buffer (32K) in (16bit) words + ; 13/11/2023 (ich_wav3.asm) - 18/11/2023 (ich_wav4.asm) + mov eax, [buffersize] + + ;or eax, IOC + BUP + ; 06/11/2023 (TUNELOOP version, without interrupt) + or eax, BUP + stosd + + movzx eax, word [WAV_BUFFER2] + shl eax, 4 ; convert seg:off ->0:offset + stosd ; store pointer to wavbuffer2 + + ;mov eax, BUFFERSIZE / 2 ; size of half buffer (32K) + ; 13/11/2023 (ich_wav3.asm) - 18/11/2023 (ich_wav4.asm) + mov eax, [buffersize] + + ;or eax, IOC + BUP + ; 06/11/2023 (TUNELOOP version, without interrupt) + or eax, BUP + stosd + + loop _0 + pop es + + ; 14/11/2024 + ;mov word [count], cx ; 0 + ;mov dword [LoadedDataBytes], 0 + + ; 19/11/2024 +RePlayWav: + + ; load 64k into buffer 1 + mov ax, [WAV_BUFFER1] + ;call loadFromFile + ; 13/11/2023 + call word [loadfromwavfile] + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + ; 18/12/2024 + mov word [count], 0 + + ; and 64k into buffer 2 + mov ax, [WAV_BUFFER2] + ;call loadFromFile + ; 13/11/2023 + call word [loadfromwavfile] + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; write NABMBAR+10h with offset of buffer descriptor list + + movzx eax, word [BDL_BUFFER] + shl eax, 4 ; convert seg:off to 0:off + mov dx, [NABMBAR] + add dx, PO_BDBAR_REG ; set pointer to BDL + out dx, eax ; write to AC97 controller + + ; 19/05/2024 + call delay1_4ms + + mov al, 31 + call setLastValidIndex + + ; 19/05/2024 + ;call delay1_4ms + + ; 17/02/2017 + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + ;mov al, IOCE + RPBM ; Enable 'Interrupt On Completion' + run + ; ; (LVBI interrupt will not be enabled) + ; 06/11/2023 (TUNELOOP version, without interrupt) + mov al, RPBM + out dx, al ; Start bus master operation. + + ; 19/05/2024 + ; 06/11/2023 + call delay1_4ms ; 30/05/2024 + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + +; while DMA engine is running, examine current index and wait until it hits 1 +; as soon as it's 1, we need to refresh the data in wavbuffer1 with another +; 64k. Likewise when it's playing buffer 2, refresh buffer 1 and repeat. + +; 18/11/2023 +; 08/11/2023 +; 07/11/2023 + + ; 19/11/2024 + mov byte [wleds], 1 + + ;;; + ; 09/12/2024 + mov ax, 10548 ; (48000*10/182)*4 + cmp byte [VRA], 0 + jna short _3 ; 48kHZ (interpolation) + ; + mov ax, [WAVE_SampleRate] + mov cx, 10 + mul cx + mov cl, 182 + div cx + ; ax = samples per 1/18.2 second + ;mov cl, byte [WAVE_BlockAlign] + ; 09/12/2024 + ;mov cl, 4 ; 16 bit, stereo + ;mul cx + shl ax, 2 ; * 4 +_3: + mov [wleds_dif], ax ; buffer read differential (distance) + ; for wave volume leds update + ; (byte stream per 1/18.2 second) + ;;; + +tuneLoop: + ; 30/05/2024 + ; 18/11/2023 (ich_wav4.asm) + ; 08/11/2023 + ; 06/11/2023 + +tLWait: + ; 18/11/2024 + cmp byte [stopped], 0 + ;jna short tL@ + ; 21/11/2024 + ja short tLWait@ + mov al, [tLP] + cmp al, '1' + ja short tL2@ + je short tL1@ + mov al, '1' + mov [tLP], al + jmp short tL1@ +tLWait@: ; 21/11/2024 + call checkUpdateEvents + jc _exitt_ + cmp byte [tLO], '0' + je short tLWait + call tLZ + mov byte [tLO], '0' + jmp short tLWait + +;tLO: db 0 + +tL1@: + ;mov al, '1' + ; 19/11/2024 + mov [tLO], al + call tL0 +tL1: + call updateLVI ; /set LVI != CIV/ + jz short _exitt_ ; 08/11/2023 + ;;; + ;call check4keyboardstop + ; 14/11/2024 + call checkUpdateEvents + jc short _exitt_ + ; 18/11/2024 + cmp byte [stopped], 0 + ja short tLWait@ ; 21/11/2024 + ;;; + call getCurrentIndex + test al, BIT0 + jz short tL1 ; loop if buffer 2 is not playing + + ; load buffer 1 + mov ax, [WAV_BUFFER1] + ;call loadFromFile + ; 18/11/2023 + call word [loadfromwavfile] + jc short _exitt_ ; end of file + + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + mov al, '2' + ; 21/11/2024 + mov [tLP], al +tL2@: + ; 19/11/2024 + mov [tLO], al + call tL0 +tL2: + call updateLVI + jz short _exitt_ ; 08/11/2023 + ;;; + ;call check4keyboardstop + ; 14/11/2024 + call checkUpdateEvents + jc short _exitt_ + ; 18/11/2024 + cmp byte [stopped], 0 + ja short tLWait@ ; 21/11/2024 + ;;; + call getCurrentIndex + test al, BIT0 + jnz short tL2 ; loop if buffer 1 is not playing + + ; load buffer 2 + mov ax, [WAV_BUFFER2] + ;call loadFromFile + ; 18/11/2023 + call word [loadfromwavfile] + ;jnc short tuneLoop + jc short _exitt_ + + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + ; 21/11/2024 + mov byte [tLP], '1' + jmp tuneLoop +_exitt_: + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out Control Register + mov al, 0 + out dx, al ; stop player + + ;;; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 18/11/2024 +tLZ: + ; 30/05/2024 + mov al, '0' + + ;add al, '0' + ;call tL0 + ; + ;retn + ; 06/11/2023 + ;jmp short tL0 + ;retn + + ; 06/11/2023 +tL0: + ; 08/11/2023 + ; 05/11/2023 + ; 17/02/2017 - Buffer switch test (temporary) + ; 06/11/2023 + ; al = buffer indicator ('1', '2' or '0' -stop- ) + + push ds + ;push bx + mov bx, 0B800h ; video display page segment + mov ds, bx + sub bx, bx ; 0 + mov ah, 4Eh + mov [bx], ax ; show current play buffer (1, 2) + ;pop bx + pop ds + + retn + +; ------------------------------------------- + + ; 14/11/2024 +;SetMasterVolume: + ; 15/11/2024 +SetPCMOutVolume: + ;cmp al, 31 + ;ja short setvolume_ok + mov [volume], al ; max = 0, min = 31 +SetPCMOutVolume@: ; 19/11/2024 + mov ah, al + mov dx, [NAMBAR] + ; 15/11/2024 (QEMU) + ;add dx, CODEC_MASTER_VOL_REG + add dx, CODEC_PCM_OUT_REG + out dx, ax +;setvolume_ok: + retn + +; ------------------------------------------- + + ; 30/05/2024 +DetectAC97: +DetectICH: + ; 22/11/2023 + ; 19/11/2023 + ; 01/11/2023 - TRDOS 386 Kernel v2.0.7 + ;; 10/06/2017 + ;; 05/06/2017 + ;; 29/05/2017 + ;; 28/05/2017 + + ; 19/11/2023 + mov si, valid_ids ; address of Valid ICH (AC97) Device IDs + mov cx, valid_id_count +pfd_1: + lodsd + call pciFindDevice + jnc short d_ac97_1 + loop pfd_1 + + ;stc + retn + +d_ac97_1: + ; eax = BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; edx = DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + ; playwav4.asm - 19/05/2024 + + mov [bus_dev_fn], eax + mov [dev_vendor], edx + + ; get ICH base address regs for mixer and bus master + + mov al, NAMBAR_REG + call pciRegRead16 ; read PCI registers 10-11 + ;and dx, IO_ADDR_MASK ; mask off BIT0 + ; 19/05/2024 + and dl, 0FEh + + mov [NAMBAR], dx ; save audio mixer base addr + + mov al, NABMBAR_REG + call pciRegRead16 + ;and dx, IO_ADDR_MASK + ; 19/05/2024 + and dl, 0C0h + + mov [NABMBAR], dx ; save bus master base addr + + mov al, AC97_INT_LINE ; Interrupt line register (3Ch) + call pciRegRead8 ; 17/02/2017 + + mov [ac97_int_ln_reg], dl + + ;clc + + retn + +; ---------------------------------- + + ; 14/11/2024 + ; INPUT: ds:dx = file name address + ; OUTPUT: [filehandle] = ; -1 = not open +openFile: + mov ax, 3D00h ; open File for read + int 21h + jnc short _of1 + mov ax, -1 + ; cf = 1 -> not found or access error +_of1: + mov [filehandle], ax + retn + +; ---------------------------------- + +; close the currently open file + + ; 14/11/2024 + ; INPUT: [filehandle] ; -1 = not open + ; OUTPUT: none +closeFile: + cmp word [filehandle], -1 + jz short _cf1 + mov bx, [filehandle] + mov ax, 3E00h + int 21h ; close file +_cf1: + retn + +; ---------------------------------- + + ; 14/11/2024 - Erdogan Tan +getWAVParameters: +; reads WAV file header(s) (44 bytes) from the .wav file. +; entry: none - assumes file is already open +; exit: ax = sample rate (11025, 22050, 44100, 48000) +; cx = number of channels (mono=1, stereo=2) +; dx = bits per sample (8, 16) +; bx = number of bytes per sample (1 to 4) + + mov dx, WAVFILEHEADERbuff + mov bx, [filehandle] + mov cx, 44 ; 44 bytes + mov ah, 3Fh + int 21h + jc short gwavp_retn + + cmp ax, 44 + jb short gwavp_retn + + cmp dword [RIFF_Format], 'WAVE' + jne short gwavp_stc_retn + + cmp word [WAVE_AudioFormat], 1 ; Offset 20, must be 1 (= PCM) + ;jne short gwavp_stc_retn + je short gwavp_retn ; 15/11/2024 + + ; 15/11/2024 + ;mov cx, [WAVE_NumChannels] ; return num of channels in CX + ;mov ax, [WAVE_SampleRate] ; return sample rate in AX + ;mov dx, [WAVE_BitsPerSample] + ; return bits per sample value in DX + ;mov bx, [WAVE_BlockAlign] ; return bytes per sample in BX +;gwavp_retn: + ;retn + +gwavp_stc_retn: + stc +gwavp_retn: + retn + +; ---- 30/05/2024 (playwav4.asm, 19/05/2024) + +; MEMALLOC.ASM +;-- SETFREE: Release memory not used ---------------- +;-- Input : ES = address of PSP +;-- Output : none +;-- Register : AX, BX, CL and FLAGS are changed +;-- Info : Since the stack-segment is always the last segment in an +; EXE-file, ES:0000 points to the beginning and SS:SP +; to the end of the program in memory. Through this the +; length of the program can be calculated +; call this routine once at the beginning of the program to free up memory +; assigned to it by DOS. + +setFree: + mov bx, 65536/16 ; 4K paragraphs ; 17/02/2017 (Erdogan Tan) + + mov ah, 4Ah ; pass new length to DOS + int 21h + + retn ; back to caller + ; new size (allocated memory) = 64KB + +memAlloc: +; input: AX = # of paragraphs required +; output: AX = segment of block to use + + push bx + mov bx, ax + mov ah, 48h + int 21h + pop bx + retn + +; ---- + +; ///// + + ; 30/05/2024 (ich_wav4.asm, 19/05/2024) +loadFromFile: + ; 07/11/2023 + + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff_0 ; no + stc + retn + +lff_0: + ; 08/11/2023 + mov bp, ax ; save buffer segment + + ; 17/11/2024 + mov bx, [filehandle] + + ; 17/11/2024 + mov cx, [loadsize] + xor di, di ; 0 + + ;mov cl, [fbs_shift] + ;and cl, cl + ;jz short lff_1 ; stereo, 16 bit + ; 17/11/2024 + cmp byte [fbs_shift], 0 + jna short lff_1 ; stereo, 16 bit + + ;mov di, BUFFERSIZE - 1 ; 65535 + + ;; fbs_shift = + ;; 2 for mono and 8 bit sample (multiplier = 4) + ;; 1 for mono or 8 bit sample (multiplier = 2) + ;shr di, cl + ;inc di ; 16384 for 8 bit and mono + ; ; 32768 for 8 bit or mono + + ; 17/11/2024 + ;mov cx, [loadsize] ; 16380 or 32760 + + ;mov ax, cs + mov dx, temp_buffer ; temporary buffer for wav data + + ; 17/02/2017 (stereo/mono, 8bit/16bit corrections) + ; load file into memory + ;mov cx, di ; 17/11/2024 + ;mov bx, [filehandle] ; 17/11/2024 + ;mov ds, ax + mov ah, 3Fh + int 21h + + ;mov bx, cs + ;mov ds, bx + ; 17/11/2024 + ;push cs + ;pop ds + + jc lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + + ; 17/11/2024 + ; 08/11/2023 + ;xor dx, dx ; 0 + + and ax, ax + jz short lff_3 + + mov bl, [fbs_shift] + + push es + ;mov di, dx ; 0 ; [fbs_off] + ; 17/11/2024 + ; di = 0 + ;mov bp, [fbs_seg] ; buffer segment + mov es, bp + mov si, temp_buffer ; temporary buffer address + mov cx, ax ; byte count + cmp byte [WAVE_BitsPerSample], 8 ; bits per sample (8 or 16) + jne short lff_7 ; 16 bit samples + ; 8 bit samples + dec bl ; shift count, 1 = stereo, 2 = mono + jz short lff_6 ; 8 bit, stereo +lff_5: + ; mono & 8 bit + lodsb + sub al, 80h ; 08/11/2023 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; left channel + stosw ; right channel + loop lff_5 + jmp short lff_9 +lff_6: + ; stereo & 8 bit + lodsb + sub al, 80h ; 08/11/2023 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw + loop lff_6 + jmp short lff_9 +lff_7: + shr cx, 1 ; word count +lff_8: + lodsw + stosw ; left channel + stosw ; right channel + loop lff_8 +lff_9: + pop es + + ;or di, di + ;jz short endLFF ; 64KB ok + ;mov ax, di ; [fbs_off] + ;dec ax + ; 17/11/2024 + mov ax, di + ;cmp ax, BUFFERSIZE ; 65520 + ;jnb short endLFF + + ;mov cx, BUFFERSIZE - 1 ; 65535 + ; 17/11/2024 + mov cx, BUFFERSIZE + ; 17/11/2024 + ; ax = di + cmp ax, cx + ;jnb short endLFF + ;jmp short lff_3 + jb short lff_3 + retn + +lff_1: + ;mov bp, ax ; save buffer segment + xor dx, dx + ; load file into memory + ;mov cx, (BUFFERSIZE / 2) ; 32k chunk + + ; 17/11/2024 + ;mov cx, [buffersize] ; BUFFERSIZE / 2 + ; 17/11/2024 (*) + ; cx = [loadsize] = 2*[buffersize] + + ;mov bx, [filehandle] ; 17/11/2024 + mov ds, ax ; mov ds, bp + mov ah, 3Fh + int 21h + + ;mov di, cs + ;mov ds, di + ; 17/11/2024 + push cs + pop ds + + ; 07/11/2023 + jc short lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + ; 17/11/2024 + ; di = 0 + +; 17/11/2024 (*) +if 0 + cmp ax, cx + jne short lff_3 +lff_2: + ; 08/11/2023 + add dx, ax + ;;mov cx, (BUFFERSIZE / 2) ; 32k chunk + ;mov cx, [buffersize] ; BUFFERSIZE / 2 + ;mov bx, [filehandle] + mov ds, bp + mov ah, 3Fh + int 21h + + ;;mov di, cs + ;mov ds, di + ; 17/11/2024 + push cs + pop ds + + jc short lff_4 ; error ! + + ; 17/11/2024 + ; 14/11/2024 + add [count], ax +end if + + cmp ax, cx + je short endLFF + ; 17/11/2024 + ; di = 0 + mov di, ax +lff_3: + call padfill ; blank pad the remainder + ;clc ; don't exit with CY yet. + or byte [flags], ENDOFFILE ; end of file flag +endLFF: + retn +lff_4: + ; 08/11/2023 + mov al, '!' ; error + call tL0 + + xor ax, ax + jmp short lff_3 + +; entry ds:ax points to last byte in file +; cx = target size +; note: must do byte size fill +; destroys bx, cx +; +padfill: + ; 14/12/2024 + ; 17/11/2024 + ; di = offset (to be filled with ZEROs) + ; bp = buffer segment + ; ax = di = number of bytes loaded + ; cx = buffer size (> loaded bytes) + ; 07/11/2023 + ; 06/11/2023 + ; 17/02/2017 + push es + ;push di + ;mov di, [fbs_seg] + ;mov es, di + mov es, bp + sub cx, ax + ; 08/11/2023 + ;mov di, ax ; (wrong) + ; 17/11/2024 + ;mov di, dx ; buffer offset + ;add di, ax + ; 07/11/2023 + ;add di, [fbs_off] + ; 25/11/2024 + xor ax, ax + ; 14/12/2024 + rep stosb + ;mov [fbs_off], di + ;pop di + pop es + retn +; ///// + +write_audio_dev_info: + ; 30/05/2024 + sys_msg msgAudioCardInfo, 0Fh + retn + +write_ac97_pci_dev_info: + ; 19/11/2024 + ; 30/05/2024 + ; 06/06/2017 + ; 03/06/2017 + ; BUS/DEV/FN + ; 00000000BBBBBBBBDDDDDFFF00000000 + ; DEV/VENDOR + ; DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV + + mov eax, [dev_vendor] + xor bh, bh + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgVendorId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgVendorId], al + shr eax, 16 + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevId+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevId], al + + mov eax, [bus_dev_fn] + shr eax, 8 + mov bl, al + mov dl, bl + and bl, 7 ; bit 0,1,2 + mov al, [bx+hex_chars] + mov [msgFncNo+1], al + mov bl, dl + shr bl, 3 + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgDevNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgDevNo], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBusNo+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBusNo], al + + ;mov ax, [ac97_NamBar] + mov ax, [NAMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNamBar+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNamBar+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNamBar+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNamBar], al + + ;mov ax, [ac97_NabmBar] + mov ax, [NABMBAR] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNabmBar+3], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNabmBar+2], al + mov bl, ah + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgNabmBar+1], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgNabmBar], al + + xor eax, eax + mov al, [ac97_int_ln_reg] + mov cl, 10 + div cl + ; 23/11/2024 + ;add [msgIRQ], ax + add ax, 3030h + mov [msgIRQ], ax + ;and al, al + cmp al, 30h + jnz short _w_ac97imsg_ + mov al, byte [msgIRQ+1] + mov ah, ' ' + mov [msgIRQ], ax +_w_ac97imsg_: + ; 19/11/2024 + call clear_window + mov dh, 13 + mov dl, 0 + call setCursorPosition + ;;; + ; 30/05/2024 + sys_msg msgAC97Info, 07h + + ; 19/11/2024 + ;retn + + ; 30/05/2024 +write_VRA_info: + sys_msg msgVRAheader, 07h + cmp byte [VRA], 0 + jna short _w_VRAi_no +_w_VRAi_yes: + sys_msg msgVRAyes, 07h + retn +_w_VRAi_no: + sys_msg msgVRAno, 07h + retn + +; 30/05/2024 (playwav6.asm) +; 18/11/2023 (ich_wav3.asm & ich_wav4.asm) +; 15/11/2023 (ich_wav3.asm) +; 14/11/2023 +; 13/11/2023 - Erdogan Tan - (VRA, sample rate conversion) +; -------------------------------------------------------- + +;;Note: At the end of every buffer load, +;; during buffer switch/swap, there will be discontinuity +;; between the last converted sample and the 1st sample +;; of the next buffer. +;; (like as a dot noises vaguely between normal sound samples) +;; -To avoid this defect, the 1st sample of +;; the next buffer may be read from the wav file but +;; the file pointer would need to be set to 1 sample back +;; again via seek system call. Time comsumption problem! - +;; +;; Erdogan Tan - 15/11/2023 +;; +;; ((If entire wav data would be loaded at once.. conversion +;; defect/noise would disappear.. but for DOS, to keep +;; 64KB buffer limit is important also it is important +;; for running under 1MB barrier without HIMEM.SYS or DPMI. +;; I have tested this program by using 2-30MB wav files.)) +;; +;; Test Computer: ASUS desktop/mainboard, M2N4-SLI, 2010. +;; AMD Athlon 64 X2 2200 MHZ CPU. +;; NFORCE4 (CK804) AC97 audio hardware. +;; Realtek ALC850 codec. +;; Retro DOS v4.2 (MSDOS 6.22) operating system. + +load_8khz_mono_8_bit: + ; 15/11/2023 + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8m_0 ; no + stc + retn + +lff8m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + ;jc short lff8m_5 ; error ! + ; 14/11/2023 + jnc short lff8m_6 + jmp lff8m_5 + +lff8m_6: + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + and ax, ax + ;jz short lff8m_3 + ; 15/11/2023 + jz short lff8_eof + + mov cx, ax ; byte count +lff8m_1: + lodsb + mov [previous_val], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + ; 14/11/2023 + mov al, 80h + dec cx + jz short lff8m_2 + mov al, [si] +lff8m_2: + ;mov [next_val], ax + mov bh, al ; [next_val] + mov ah, [previous_val] + add al, ah ; [previous_val] + rcr al, 1 + mov dl, al ; this is interpolated middle (3th) sample + add al, ah ; [previous_val] + rcr al, 1 + mov bl, al ; this is temporary interpolation value + add al, ah ; [previous_val] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + mov al, dl + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (L) + stosw ; this is middle (3th) interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, dl + rcr al, 1 + mov bl, al ; this is temporary interpolation value + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (L) + stosw ; this is 4th interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (L) + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff8m_1 + + ; -------------- + +lff8s_3: +lff8m_3: +lff8s2_3: +lff8m2_3: +lff16s_3: +lff16m_3: +lff16s2_3: +lff16m2_3: +lff24_3: +lff32_3: +lff44_3: +lff22_3: +lff11_3: + mov cx, [buffersize] ; 16 bit (48 kHZ, stereo) sample size + shl cx, 1 ; byte count + sub cx, di + jna short lff8m_4 + ;inc cx + shr cx, 1 + xor ax, ax ; fill (remain part of) buffer with zeros + rep stosw +lff8m_4: + push cs + pop es + retn + +lff8_eof: +lff16_eof: +lff24_eof: +lff32_eof: +lff44_eof: +lff22_eof: +lff11_eof: + ; 15/11/2023 + mov byte [flags], ENDOFFILE + jmp short lff8m_3 + +lff8s_5: +lff8m_5: +lff8s2_5: +lff8m2_5: +lff16s_5: +lff16m_5: +lff16s2_5: +lff16m2_5: +lff24_5: +lff32_5: +lff44_5: +lff22_5: +lff11_5: + mov al, '!' ; error + call tL0 + + ;jmp short lff8m_3 + ; 15/11/2023 + jmp lff8_eof + + ; -------------- + +load_8khz_stereo_8_bit: + ; 15/11/2023 + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8s_0 ; no + stc + retn + +lff8s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8s_5 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;;and ax, ax + ;jz short lff8s_3 + ; 15/11/2023 + jz short lff8_eof + + mov cx, ax ; word count +lff8s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + ; 14/11/2023 + mov ax, 8080h + dec cx + jz short lff8s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff8s_2: + mov [next_val_l], al + mov [next_val_r], ah + mov ah, [previous_val_l] + add al, ah + rcr al, 1 + mov dl, al ; this is interpolated middle (3th) sample (L) + add al, ah + rcr al, 1 + mov bl, al ; this is temporary interpolation value (L) + add al, ah + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + mov al, [next_val_r] + mov ah, [previous_val_r] + add al, ah + rcr al, 1 + mov dh, al ; this is interpolated middle (3th) sample (R) + add al, ah + rcr al, 1 + mov bh, al ; this is temporary interpolation value (R) + add al, ah + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + mov al, bh + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (R) + mov al, dl + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (L) + mov al, dh + sub al, 80h + shl ax, 8 + stosw ; this is middle (3th) interpolated sample (R) + mov al, [next_val_l] + add al, dl + rcr al, 1 + mov bl, al ; this is temporary interpolation value (L) + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (L) + mov al, [next_val_r] + add al, dh + rcr al, 1 + mov bh, al ; this is temporary interpolation value (R) + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 4th interpolated sample (R) + mov al, [next_val_l] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (L) + mov al, [next_val_r] + add al, bh + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + jcxz lff8s_6 + jmp lff8s_1 +lff8s_6: + jmp lff8s_3 + +load_8khz_mono_16_bit: + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8m2_0 ; no + stc + retn + +lff8m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff8m2_8 + ;jmp lff8m2_3 + ; 15/11/2023 + jmp lff8_eof + +lff8m2_8: + mov cx, ax ; word count +lff8m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val], ax + xor ax, ax + dec cx + jz short lff8m2_2 + mov ax, [si] +lff8m2_2: + add ah, 80h ; convert sound level to 0-65535 format + mov bp, ax ; [next_val] + add ax, [previous_val] + rcr ax, 1 + mov dx, ax ; this is interpolated middle (3th) sample + add ax, [previous_val] + rcr ax, 1 ; this is temporary interpolation value + mov bx, ax + add ax, [previous_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov ax, bx + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + mov ax, dx + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is middle (3th) interpolated sample (L) + stosw ; this is middle (3th) interpolated sample (R) + mov ax, bp + add ax, dx + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (L) + stosw ; this is 4th interpolated sample (R) + mov ax, bp + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 5th interpolated sample (L) + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff8m2_1 + jmp lff8m2_3 + +lff8m2_7: +lff8s2_7: + jmp lff8m2_5 ; error + +load_8khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff8s2_0 ; no + stc + retn + +lff8s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff8s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff8s2_8 + ;jmp lff8s2_3 + ; 15/11/2023 + jmp lff8_eof + +lff8s2_8: + mov cx, ax ; dword count +lff8s2_1: + lodsw + stosw ; original sample (L) + ; 15/11/2023 + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level to 0-65535 format + mov [previous_val_r], ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff8s2_2 + mov ax, [si] + mov dx, [si+2] +lff8s2_2: + add ah, 80h ; convert sound level to 0-65535 format + mov [next_val_l], ax + add dh, 80h ; convert sound level to 0-65535 format + mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + mov dx, ax ; this is interpolated middle (3th) sample (L) + add ax, [previous_val_l] + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (L) + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + mov ax, [next_val_r] + add ax, [previous_val_r] + rcr ax, 1 + mov bp, ax ; this is interpolated middle (3th) sample (R) + add ax, [previous_val_r] + rcr ax, 1 + push ax ; * ; this is temporary interpolation value (R) + add ax, [previous_val_r] + rcr ax, 1 + sub ah, 80h + stosw ; this is 1st interpolated sample (R) + mov ax, bx + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + pop ax ; * + add ax, bp + rcr ax, 1 + sub ah, 80h + stosw ; this is 2nd interpolated sample (R) + mov ax, dx + sub ah, 80h + stosw ; this is middle (3th) interpolated sample (L) + mov ax, bp + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is middle (3th) interpolated sample (R) + mov ax, [next_val_l] + add ax, dx + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (L) + add ax, dx + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (L) + mov ax, [next_val_r] + add ax, bp + rcr ax, 1 + push ax ; ** ; this is temporary interpolation value (R) + add ax, bp + rcr ax, 1 + sub ah, 80h + stosw ; this is 4th interpolated sample (R) + mov ax, [next_val_l] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 5th interpolated sample (L) + pop ax ; ** + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h + stosw ; this is 5th interpolated sample (R) + ; 8 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + jcxz lff8_s2_9 + jmp lff8s2_1 +lff8_s2_9: + jmp lff8s2_3 + +; ..................... + +load_16khz_mono_8_bit: + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16m_0 ; no + stc + retn + +lff16m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff16m_8 + ;jmp lff16m_3 + ; 15/11/2023 + jmp lff16_eof + +lff16m_8: + mov cx, ax ; byte count +lff16m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + ; 14/11/22023 + mov al, 80h + dec cx + jz short lff16m_2 + mov al, [si] +lff16m_2: + ;mov [next_val], al + mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + mov dl, al ; this is interpolated middle (temp) sample + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + ;mov al, [next_val] + mov al, bh + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16m_1 + jmp lff16m_3 + +lff16m_7: +lff16s_7: + jmp lff16m_5 ; error + +load_16khz_stereo_8_bit: + ; 14/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16s_0 ; no + stc + retn + +lff16s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff16s_8 + ;jmp lff16s_3 + ; 15/11/2023 + jmp lff16_eof + +lff16s_8: + mov cx, ax ; word count +lff16s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + ; 14/11/2023 + mov ax, 8080h + dec cx + jz short lff16s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff16s_2: + ;mov [next_val_l], al + ;mov [next_val_r], ah + mov bx, ax + add al, [previous_val_l] + rcr al, 1 + mov dl, al ; this is temporary interpolation value (L) + add al, [previous_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + mov dh, al ; this is temporary interpolation value (R) + add al, [previous_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 1st interpolated sample (R) + mov al, dl + add al, bl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (L) + mov al, dh + add al, bh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16s_1 + jmp lff16s_3 + +load_16khz_mono_16_bit: + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16m2_0 ; no + stc + retn + +lff16m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff16m2_8 + ;jmp lff16m2_3 + ; 15/11/2023 + jmp lff16_eof + +lff16m2_8: + mov cx, ax ; word count +lff16m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + mov bx, ax + xor ax, ax + dec cx + jz short lff16m2_2 + mov ax, [si] +lff16m2_2: + add ah, 80h ; convert sound level 0 to 65535 format + mov bp, ax ; [next_val] + ;add ax, [previous_val] + add ax, bx + rcr ax, 1 + mov dx, ax ; this is temporary interpolation value + ;add ax, [previous_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + stosw ; this is 1st interpolated sample (R) + mov ax, bp + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + stosw ; this is 2nd interpolated sample (R) + ; 16 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16m2_1 + jmp lff16m2_3 + +lff16m2_7: +lff16s2_7: + jmp lff16m2_5 ; error + +load_16khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + ; 13/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff16s2_0 ; no + stc + retn + +lff16s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff16s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + ;shr ax, 1 + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff16s2_8 + ;jmp lff16s2_3 + ; 15/11/2023 + jmp lff16_eof + +lff16s2_8: + mov cx, ax ; dword count +lff16s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_r], ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff16s2_2 + mov ax, [si] + mov dx, [si+2] +lff16s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_l], ax + mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + mov dx, ax ; this is temporary interpolation value (L) + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (L) + mov ax, [next_val_r] + add ax, [previous_val_r] + rcr ax, 1 + mov bx, ax ; this is temporary interpolation value (R) + add ax, [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 1st interpolated sample (R) + ;mov ax, [next_val_l] + mov ax, bp + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (L) + mov ax, [next_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is 2nd interpolated sample (R) + + ; 16 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff16s2_1 + jmp lff16s2_3 + +; ..................... + +load_24khz_mono_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24m_0 ; no + stc + retn + +lff24m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff24m_8 + jmp lff24_eof + +lff24m_8: + mov cx, ax ; byte count +lff24m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + mov al, 80h + dec cx + jz short lff24m_2 + mov al, [si] +lff24m_2: + ;;mov [next_val], al + ;mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; 24 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24m_1 + jmp lff24_3 + +lff24m_7: +lff24s_7: + jmp lff24_5 ; error + +load_24khz_stereo_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24s_0 ; no + stc + retn + +lff24s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff24s_8 + jmp lff24_eof + +lff24s_8: + mov cx, ax ; word count +lff24s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + mov ax, 8080h + dec cx + jz short lff24s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff24s_2: + ;;mov [next_val_l], al + ;;mov [next_val_r], ah + ;mov bx, ax + mov bh, ah + add al, [previous_val_l] + rcr al, 1 + ;mov dl, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + ;mov dh, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (R) + + ; 24 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24s_1 + jmp lff24_3 + +load_24khz_mono_16_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24m2_0 ; no + stc + retn + +lff24m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff24m2_8 + jmp lff24_eof + +lff24m2_8: + mov cx, ax ; word count +lff24m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + ;mov bx, ax + ;xor ax, ax + xor bx, bx + dec cx + jz short lff24m2_2 + ;mov ax, [si + mov bx, [si] +lff24m2_2: + ;add ah, 80h ; convert sound level 0 to 65535 format + ;mov bp, ax ; [next_val] + ;add ax, [previous_val] + ; ax = [previous_val] + ; bx = [next_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + ; 24 kHZ mono to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24m2_1 + jmp lff24_3 + +lff24m2_7: +lff24s2_7: + jmp lff24_5 ; error + +load_24khz_stereo_16_bit: + ; 16/11/2023 + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff24s2_0 ; no + stc + retn + +lff24s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff24s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + ;shr ax, 1 + shr ax, 2 ; 16/11/2023 + ;and ax, ax + jnz short lff24s2_8 + jmp lff24_eof + +lff24s2_8: + mov cx, ax ; dword count +lff24s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val_r], ax + mov bx, ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff24s2_2 + mov ax, [si] + mov dx, [si+2] +lff24s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;;mov [next_val_l], ax + ;mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + ;mov ax, [next_val_r] + mov ax, dx + ;add ax, [previous_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (R) + + ; 24 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + or cx, cx + jnz short lff24s2_1 + jmp lff24_3 + +; ..................... + +load_32khz_mono_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32m_0 ; no + stc + retn + +lff32m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff32m_8 + jmp lff32_eof + +lff32m_8: + mov cx, ax ; byte count +lff32m_1: + lodsb + ;mov [previous_val], al + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (left channel) + stosw ; original sample (right channel) + ;xor ax, ax + mov al, 80h + dec cx + jz short lff32m_2 + mov al, [si] +lff32m_2: + ;;mov [next_val], al + ;mov bh, al + ;add al, [previous_val] + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32m_3 + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (left channel) + stosw ; original sample (right channel) + + ; 32 kHZ mono to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32m_1 +lff32m_3: + jmp lff32_3 + +lff32m_7: +lff32s_7: + jmp lff32_5 ; error + +load_32khz_stereo_8_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32s_0 ; no + stc + retn + +lff32s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff32s_8 + jmp lff32_eof + +lff32s_8: + mov cx, ax ; word count +lff32s_1: + lodsb + mov [previous_val_l], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + lodsb + mov [previous_val_r], al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + + ;xor ax, ax + mov ax, 8080h + dec cx + jz short lff32s_2 + ; convert 8 bit sample to 16 bit sample + mov ax, [si] +lff32s_2: + ;;mov [next_val_l], al + ;;mov [next_val_r], ah + ;mov bx, ax + mov bh, ah + add al, [previous_val_l] + rcr al, 1 + ;mov dl, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (L) + mov al, bh ; [next_val_r] + add al, [previous_val_r] + rcr al, 1 + ;mov dh, al + sub al, 80h + shl ax, 8 + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32s_3 + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (left channel) + + lodsb + sub al, 80h + shl ax, 8 + stosw ; original sample (right channel) + + ; 32 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32s_1 +lff32s_3: + jmp lff32_3 + +load_32khz_mono_16_bit: + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32m2_0 ; no + stc + retn + +lff32m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff32m2_8 + jmp lff32_eof + +lff32m2_8: + mov cx, ax ; word count +lff32m2_1: + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val], ax + ;mov bx, ax + ;xor ax, ax + xor bx, bx + dec cx + jz short lff32m2_2 + ;mov ax, [si + mov bx, [si] +lff32m2_2: + ;add ah, 80h ; convert sound level 0 to 65535 format + ;mov bp, ax ; [next_val] + ;add ax, [previous_val] + ; ax = [previous_val] + ; bx = [next_val] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32m2_3 + + lodsw + stosw ; original sample (left channel) + stosw ; original sample (right channel) + + ; 32 kHZ mono to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32m2_1 +lff32m2_3: + jmp lff32_3 + +lff32m2_7: +lff32s2_7: + jmp lff32_5 ; error + +load_32khz_stereo_16_bit: + ;16/11/2023 + ; 15/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff32s2_0 ; no + stc + retn + +lff32s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff32s2_7 ; error ! + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; 16/11/2023 (word left ch + word right ch) + ;and ax, ax + jnz short lff32s2_8 + jmp lff32_eof + +lff32s2_8: + mov cx, ax ; dword count +lff32s2_1: + lodsw + stosw ; original sample (L) + add ah, 80h ; convert sound level 0 to 65535 format + mov [previous_val_l], ax + lodsw + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + ;mov [previous_val_r], ax + mov bx, ax + xor dx, dx + xor ax, ax + ; 16/11/2023 + dec cx + jz short lff32s2_2 + mov ax, [si] + mov dx, [si+2] +lff32s2_2: + add ah, 80h ; convert sound level 0 to 65535 format + ;;mov [next_val_l], ax + ;mov bp, ax + add dh, 80h ; convert sound level 0 to 65535 format + ;mov [next_val_r], dx + add ax, [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (L) + ;mov ax, [next_val_r] + mov ax, dx + ;add ax, [previous_val_r] + add ax, bx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; this is interpolated sample (R) + + ; different than 8-16-24 kHZ ! + ; 'original-interpolated-original' trio samples + jcxz lff32s2_3 + + lodsw + stosw ; original sample (L) + lodsw + stosw ; original sample (R) + + ; 32 kHZ stereo to 48 kHZ stereo conversion of the sample is OK + dec cx + jnz short lff32s2_1 +lff32s2_3: + jmp lff32_3 + +; ..................... + +load_22khz_mono_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22m_0 ; no + stc + retn + +lff22m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff22m_8 + jmp lff22_eof + +lff22m_8: + mov cx, ax ; byte count +lff22m_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phases +lff22m_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsb + mov dl, 80h + dec cx + jz short lff22m_2_1 + mov dl, [si] +lff22m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_3_8bit_mono ; 1 of 17 + jcxz lff22m_3 +lff22m_2_2: + lodsb + mov dl, 80h + dec cx + jz short lff22m_2_3 + mov dl, [si] +lff22m_2_3: + call interpolating_2_8bit_mono ; 2 of 17 .. 6 of 17 + jcxz lff22m_3 + dec bp + jnz short lff22m_2_2 + + mov al, [faz] + dec al + jz short lff22m_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22m_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22m_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +lff22m_3: +lff22s_3: + jmp lff22_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff22m_7: +lff22s_7: + jmp lff22_5 ; error + +load_22khz_stereo_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22s_0 ; no + stc + retn + +lff22s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff22s_8 + jmp lff22_eof + +lff22s_8: + mov cx, ax ; word count +lff22s_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phase +lff22s_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + mov dx, 8080h + dec cx + jz short lff22s_2_1 + mov dx, [si] +lff22s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_3_8bit_stereo ; 1 of 17 + jcxz lff22s_3 +lff22s_2_2: + lodsw + mov dx, 8080h + dec cx + jz short lff22s_2_3 + mov dx, [si] +lff22s_2_3: + call interpolating_2_8bit_stereo ; 2 of 17 .. 6 of 17 + jcxz lff22s_3 + dec bp + jnz short lff22s_2_2 + + mov al, [faz] + dec al + jz short lff22s_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22s_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22s_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +load_22khz_mono_16_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22m2_0 ; no + stc + retn + +lff22m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff22m2_8 + jmp lff22_eof + +lff22m2_8: + mov cx, ax ; word count +lff22m2_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phases +lff22m2_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + xor dx, dx + dec cx + jz short lff22m2_2_1 + mov dx, [si] +lff22m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_3_16bit_mono ; 1 of 17 + jcxz lff22m2_3 +lff22m2_2_2: + lodsw + xor dx, dx + dec cx + jz short lff22m2_2_3 + mov dx, [si] +lff22m2_2_3: + call interpolating_2_16bit_mono ; 2 of 17 .. 6 of 17 + jcxz lff22m2_3 + dec bp + jnz short lff22m2_2_2 + + mov al, [faz] + dec al + jz short lff22m2_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22m2_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22m2_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +lff22m2_3: +lff22s2_3: + jmp lff22_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff22m2_7: +lff22s2_7: + jmp lff22_5 ; error + +load_22khz_stereo_16_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff22s2_0 ; no + stc + retn + +lff22s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff22s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff22s2_8 + jmp lff22_eof + +lff22s2_8: + mov cx, ax ; dword count +lff22s2_9: + mov bp, 5 ; interpolation (one step) loop count + mov byte [faz], 3 ; 3 steps/phase +lff22s2_1: + ; 3:2:2:2:2:2::3:2:2:2:2::3:2:2:2:2:2 ; 37/17 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff22s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx +lff22s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_3_16bit_stereo ; 1 of 17 + jcxz lff22s2_3 +lff22s2_2_2: + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff22s2_2_3 + xor dx, dx ; 0 + mov [next_val_l], dx +lff22s2_2_3: + call interpolating_2_16bit_stereo ; 2 of 17 .. 6 of 17 + jcxz lff22s2_3 + dec bp + jnz short lff22s2_2_2 + + mov al, [faz] + dec al + jz short lff22s2_9 + dec byte [faz] + mov bp, 4 + dec al + jnz short lff22s2_1 ; 3:2:2:2:2 ; 7-11 of 17 + inc bp ; 5 + jmp short lff22s2_1 ; 3:2:2:2:2:2 ; 12-17 of 17 + +; ..................... + +load_11khz_mono_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11m_0 ; no + stc + retn + +lff11m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff11m_8 + jmp lff11_eof + +lff11m_8: + mov cx, ax ; byte count +lff11m_9: + mov bp, 6 ; interpolation (one step) loop count +lff11m_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_1 + mov dl, [si] +lff11m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_5_8bit_mono + jcxz lff11m_3 +lff11m_2_2: + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_3 + mov dl, [si] +lff11m_2_3: + call interpolating_4_8bit_mono + jcxz lff11m_3 + + dec bp + jz short lff11m_9 + + lodsb + mov dl, 80h + dec cx + jz short lff11m_2_4 + mov dl, [si] +lff11m_2_4: + call interpolating_4_8bit_mono + jcxz lff11m_3 + jmp short lff11m_1 + +lff11m_3: +lff11s_3: + jmp lff11_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff11m_7: +lff11s_7: + jmp lff11_5 ; error + +load_11khz_stereo_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11s_0 ; no + stc + retn + +lff11s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff11s_8 + jmp lff11_eof + +lff11s_8: + mov cx, ax ; word count +lff11s_9: + mov bp, 6 ; interpolation (one step) loop count +lff11s_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_1 + mov dx, [si] +lff11s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_5_8bit_stereo + jcxz lff11s_3 +lff11s_2_2: + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_3 + mov dx, [si] +lff11s_2_3: + call interpolating_4_8bit_stereo + jcxz lff11s_3 + + dec bp + jz short lff11s_9 + + lodsw + mov dx, 8080h + dec cx + jz short lff11s_2_4 + mov dx, [si] +lff11s_2_4: + call interpolating_4_8bit_stereo + jcxz lff11s_3 + jmp short lff11s_1 + +load_11khz_mono_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11m2_0 ; no + stc + retn + +lff11m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff11m2_8 + jmp lff11_eof + +lff11m2_8: + mov cx, ax ; word count +lff11m2_9: + mov bp, 6 ; interpolation (one step) loop count +lff11m2_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_1 + mov dx, [si] +lff11m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_5_16bit_mono + jcxz lff11m2_3 +lff11m2_2_2: + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_3 + mov dx, [si] +lff11m2_2_3: + call interpolating_4_16bit_mono + jcxz lff11m2_3 + + dec bp + jz short lff11m2_9 + + lodsw + xor dx, dx + dec cx + jz short lff11m2_2_4 + mov dx, [si] +lff11m2_2_4: + call interpolating_4_16bit_mono + jcxz lff11m2_3 + jmp short lff11m2_1 + +lff11m2_7: +lff11s2_7: + jmp lff11_5 ; error + +load_11khz_stereo_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff11s2_0 ; no + stc + retn + +lff11s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff11s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff11s2_8 + jmp lff11_eof + +lff11m2_3: +lff11s2_3: + jmp lff11_3 ; padfill + ; (put zeros in the remain words of the buffer) + +lff11s2_8: + mov cx, ax ; dword count +lff11s2_9: + mov bp, 6 ; interpolation (one step) loop count +lff11s2_1: + ; 5:4:4::5:4:4::5:4:4::5:4:4::5:4:4::5:4 ; 74/17 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_5_16bit_stereo + jcxz lff11s2_3 +lff11s2_2_2: + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_3 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_3: + call interpolating_4_16bit_stereo + jcxz lff11s2_3 + + dec bp + jz short lff11s2_9 + + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + mov [next_val_r], dx + dec cx + jnz short lff11s2_2_4 + xor dx, dx ; 0 + mov [next_val_l], dx + mov [next_val_r], dx +lff11s2_2_4: + call interpolating_4_16bit_stereo + jcxz lff11s2_3 + jmp short lff11s2_1 + +; ..................... + +load_44khz_mono_8_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44m_0 ; no + stc + retn + +lff44m_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44m_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + and ax, ax + jnz short lff44m_8 + jmp lff44_eof + +lff44m_8: + mov cx, ax ; byte count +lff44m_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phases +lff44m_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsb + mov dl, 80h + dec cx + jz short lff44m_2_1 + mov dl, [si] +lff44m_2_1: + ; al = [previous_val] + ; dl = [next_val] + call interpolating_2_8bit_mono + jcxz lff44m_3 +lff44m_2_2: + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (L) + stosw ; (R) + + dec cx + jz short lff44m_3 + dec bp + jnz short lff44m_2_2 + + dec byte [faz] + jz short lff44m_9 + mov bp, 11 + jmp short lff44m_1 + +lff44m_3: +lff44s_3: + jmp lff44_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff44m_7: +lff44s_7: + jmp lff44_5 ; error + +load_44khz_stereo_8_bit: + ; 16/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44s_0 ; no + stc + retn + +lff44s_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44s_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff44s_8 + jmp lff44_eof + +lff44s_8: + mov cx, ax ; word count +lff44s_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phase +lff44s_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + mov dx, 8080h + dec cx + jz short lff44s_2_1 + mov dx, [si] +lff44s_2_1: + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dl = [next_val_r] + call interpolating_2_8bit_stereo + jcxz lff44s_3 +lff44s_2_2: + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (L) + lodsb + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; (R) + + dec cx + jz short lff44s_3 + dec bp + jnz short lff44s_2_2 + + dec byte [faz] + jz short lff44s_9 + mov bp, 11 + jmp short lff44s_1 + +load_44khz_mono_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44m2_0 ; no + stc + retn + +lff44m2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44m2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 1 + ;and ax, ax + jnz short lff44m2_8 + jmp lff44_eof + +lff44m2_8: + mov cx, ax ; word count +lff44m2_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phases +lff44m2_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + xor dx, dx + dec cx + jz short lff44m2_2_1 + mov dx, [si] +lff44m2_2_1: + ; ax = [previous_val] + ; dx = [next_val] + call interpolating_2_16bit_mono + jcxz lff44m2_3 +lff44m2_2_2: + lodsw + stosw ; (L)eft Channel + stosw ; (R)ight Channel + + dec cx + jz short lff44m2_3 + dec bp + jnz short lff44m2_2_2 + + dec byte [faz] + jz short lff44m2_9 + mov bp, 11 + jmp short lff44m2_1 + +lff44m2_3: +lff44s2_3: + jmp lff44_3 ; padfill + ; (put zeros in the remain words of the buffer) +lff44m2_7: +lff44s2_7: + jmp lff44_5 ; error + +load_44khz_stereo_16_bit: + ; 18/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff44s2_0 ; no + stc + retn + +lff44s2_0: + mov es, ax ; buffer segment + xor di, di + mov dx, temp_buffer ; temporary buffer for wav data + ; ds = cs + + ; load file into memory + mov cx, [loadsize] + mov bx, [filehandle] + mov ah, 3Fh + int 21h + jc short lff44s2_7 ; error ! + + ; 14/11/2024 + mov [count], ax + + mov si, dx ; temp_buffer ; temporary buffer address + + shr ax, 2 ; dword (left chan word + right chan word) + ;and ax, ax + jnz short lff44s2_8 + jmp lff44_eof + +lff44s2_8: + mov cx, ax ; dword count +lff44s2_9: + mov bp, 10 ; interpolation (one step) loop count + mov byte [faz], 2 ; 2 steps/phase +lff44s2_1: + ; 2:1:1:1:1:1:1:1:1:1:1:: ; 25/23 + ; 2:1:1:1:1:1:1:1:1:1:1:1 + lodsw + mov bx, ax + lodsw + mov dx, [si] + mov [next_val_l], dx + mov dx, [si+2] + dec cx + jnz short lff44s2_2_1 + xor dx, dx ; 0 + mov [next_val_l], dx +lff44s2_2_1: + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + call interpolating_2_16bit_stereo + jcxz lff44s2_3 +lff44s2_2_2: + ;lodsw + ;stosw ; (L) + ;lodsw + ;stosw ; (R) + movsw ; (L)eft Channel + movsw ; (R)ight Channel + + dec cx + jz short lff44s2_3 + dec bp + jnz short lff44s2_2_2 + + dec byte [faz] + jz short lff44s2_9 + mov bp, 11 + jmp short lff44s2_1 + +; ..................... + +interpolating_3_8bit_mono: + ; 16/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + mov bh, al ; interpolated middle (temporary) + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bh + add al, dl ; [next_val] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + retn + +interpolating_3_8bit_stereo: + ; 16/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + push ax ; * ; al = interpolated middle (L) (temporary) + add al, bl ; [previous_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + push ax ; ** ; al = interpolated middle (R) (temporary) + add al, bh ; [previous_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + pop bx ; ** + pop ax ; * + add al, dl ; [next_val_l] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bl + add al, dh ; [next_val_r] + rcr al, 1 + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (R) + retn + +interpolating_2_8bit_mono: + ; 16/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (L) + stosw ; interpolated sample (R) + retn + +interpolating_2_8bit_stereo: + ; 16/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl ; [previous_val_l] + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample (R) + retn + +interpolating_3_16bit_mono: + ; 16/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val] + add dh, 80h + add ax, dx + rcr ax, 1 + pop bx ; * + xchg bx, ax ; bx = interpolated middle (temporary) + add ax, bx ; [previous_val] + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov ax, bx + add ax, dx ;interpolated middle + [next_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + retn + +interpolating_3_16bit_stereo: + ; 16/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + ; original-interpolated-interpolated + + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + xchg ax, bx ; ax = [previous_val_l] + add ax, bx ; bx = interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + pop ax ; * + add dh, 80h ; convert sound level 0 to 65535 format + push dx ; * ; [next_val_r] + xchg ax, dx + add ax, dx ; [next_val_r] + [previous_val_r] + rcr ax, 1 ; / 2 + push ax ; ** ; interpolated middle (R) + add ax, dx ; + [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, [next_val_l] + add ax, bx ; + interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + pop ax ; ** + pop dx ; * + add ax, dx ; interpolated middle + [next_val_r] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + retn + + +interpolating_2_16bit_mono: + ; 16/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + add dh, 80h + add ax, dx + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (L) + stosw ; interpolated sample (R) + retn + +interpolating_2_16bit_stereo: + ; 16/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; dx = [next_val_r] + ; original-interpolated + + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + add dh, 80h + add ax, dx ; [previous_val_r] + [next_val_r] + rcr ax, 1 ; / 2 + push ax ; * ; interpolated sample (R) + mov ax, [next_val_l] + add ah, 80h + add bh, 80h + add ax, bx ; [next_val_l] + [previous_val_l] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (L) + pop ax ; * + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample (R) + retn + +interpolating_5_8bit_mono: + ; 17/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpltd-interpltd-interpltd-interpltd + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + mov bh, al ; interpolated middle (temporary) + add al, bl ; [previous_val] + rcr al, 1 + mov dh, al ; interpolated 1st quarter (temporary) + add al, bl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bh + add al, dh + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov al, bh + add al, dl ; [next_val] + rcr al, 1 + mov dh, al ; interpolated 3rd quarter (temporary) + add al, bh + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + mov al, dh + add al, dl + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (L) + stosw ; interpolated sample 4 (R) + retn + +interpolating_5_8bit_stereo: + ; 17/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpltd-interpltd-interpltd-interpltd + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + push dx ; * + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + push ax ; ** ; al = interpolated middle (L) (temporary) + add al, bl ; [previous_val_l] + rcr al, 1 + xchg al, bl + add al, bl ; bl = interpolated 1st quarter (L) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + push ax ; *** ; al = interpolated middle (R) (temporary) + add al, bh ; [previous_val_r] + rcr al, 1 + xchg al, bh + add al, bh ; bh = interpolated 1st quarter (R) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + pop dx ; *** + pop ax ; ** ; al = interpolated middle (L) (temporary) + xchg al, bl ; al = interpolated 1st quarter (L) (temp) + add al, bl ; bl = interpolated middle (L) (temporary) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, dl ; interpolated middle (R) (temporary) + xchg al, bh ; al = interpolated 1st quarter (R) (temp) + add al, bh ; bh = interpolated middle (R) (temporary) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (R) + pop dx ; * + mov al, bl ; interpolated middle (L) (temporary) + add al, dl ; [next_val_l] + rcr al, 1 + xchg al, bl ; al = interpolated middle (R) (temporary) + add al, bl ; bl = interpolated 3rd quarter (L) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + mov al, bh + add al, dh ; interpolated middle (R) + [next_val_r] + rcr al, 1 + xchg al, bh ; al = interpolated middle (R) + add al, bh ; bh = interpolated 3rd quarter (R) (temp) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 4 (R) + retn + +interpolating_4_8bit_mono: + ; 17/11/2023 + ; al = [previous_val] + ; dl = [next_val] + ; original-interpolated-interpolated-interpolated + mov bl, al + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + stosw ; original sample (R) + mov al, bl + add al, dl + rcr al, 1 + xchg al, bl ; al = [previous_val] + add al, bl ; bl = interpolated middle (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov al, bl ; interpolated middle (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov al, bl + add al, dl ; [next_val] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + retn + +interpolating_4_8bit_stereo: + ; 17/11/2023 + ; al = [previous_val_l] + ; ah = [previous_val_r] + ; dl = [next_val_l] + ; dh = [next_val_r] + ; original-interpolated-interpolated-interpolated + mov bx, ax + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (L) + mov al, bh + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; original sample (R) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + xchg al, bl ; al = [previous_val_l] + add al, bl ; bl = interpolated middle (L) (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + xchg al, bh ; al = [previous_val_h] + add al, bh ; bh = interpolated middle (R) (sample 2) + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 1 (R) + mov al, bl ; interpolated middle (L) (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bh ; interpolated middle (L) (sample 2) + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 2 (L) + mov al, bl + add al, dl ; [next_val_l] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (L) + mov al, bh + add al, dh ; [next_val_r] + rcr al, 1 + sub al, 80h + shl ax, 8 ; convert 8 bit sample to 16 bit sample + stosw ; interpolated sample 3 (R) + retn + +interpolating_5_16bit_mono: + ; 18/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpltd-interpltd-interpltd-interpltd + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov bx, ax ; [previous_val] + add dh, 80h + add ax, dx + rcr ax, 1 + push ax ; * ; interpolated middle (temporary) + add ax, bx ; interpolated middle + [previous_val] + rcr ax, 1 + push ax ; ** ; interpolated 1st quarter (temporary) + add ax, bx ; 1st quarter + [previous_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + pop ax ; ** + pop bx ; * + add ax, bx ; 1st quarter + middle + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, dx ; interpolated middle + [next_val] + rcr ax, 1 + push ax ; * ; interpolated 3rd quarter (temporary) + add ax, bx ; + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + pop ax ; * + add ax, dx ; 3rd quarter + [next_val] + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (L) + stosw ; interpolated sample 4 (R) + retn + +interpolating_5_16bit_stereo: + ; 18/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; [next_val_r] + ; original-interpltd-interpltd-interpltd-interpltd + push cx ; ! + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + push ax ; * ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + mov cx, ax ; interpolated middle (L) + add ax, bx + rcr ax, 1 + mov dx, ax ; interpolated 1st quarter (L) + add ax, bx ; [previous_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + mov ax, cx + add ax, dx ; middle (L) + 1st quarter (L) + rcr ax, 1 ; / 2 + mov bx, ax ; interpolated sample 2 (L) + pop dx ; * ; [previous_val_r] + mov ax, dx + add byte [next_val_r+1], 80h + add ax, [next_val_r] + rcr ax, 1 + push ax ; * ; interpolated middle (R) + add ax, dx + rcr ax, 1 + push ax ; ** ; interpolated 1st quarter (R) + add ax, dx ; [previous_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, bx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + pop ax ; ** + pop dx ; * + add ax, dx ; 1st quarter (R) + middle (R) + rcr ax, 1 ; / 2 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (R) + mov ax, cx + add ax, [next_val_l] + rcr ax, 1 + push ax ; * ; interpolated 3rd quarter (L) + add ax, cx ; interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + mov ax, dx + add ax, [next_val_r] + rcr ax, 1 + push ax ; ** ; interpolated 3rd quarter (R) + add ax, dx ; interpolated middle (R) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (R) + pop bx ; ** + pop ax ; * + add ax, [next_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (L) + mov ax, bx + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 4 (R) + pop cx ; ! + retn + +interpolating_4_16bit_mono: + ; 18/11/2023 + ; ax = [previous_val] + ; dx = [next_val] + ; original-interpolated + + stosw ; original sample (L) + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov bx, ax ; [previous_val] + add dh, 80h + add ax, dx ; [previous_val] + [next_val] + rcr ax, 1 + xchg ax, bx + add ax, bx ; [previous_val] + interpolated middle + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + stosw ; interpolated sample 1 (R) + mov ax, bx ; interpolated middle + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, dx ; interpolated middle + [next_val] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + stosw ; interpolated sample 3 (R) + retn + +interpolating_4_16bit_stereo: + ; 18/11/2023 + ; bx = [previous_val_l] + ; ax = [previous_val_r] + ; [next_val_l] + ; [next_val_r] + ; original-interpolated-interpolated-interpolated + xchg ax, bx + stosw ; original sample (L) + xchg ax, bx + stosw ; original sample (R) + add ah, 80h ; convert sound level 0 to 65535 format + mov dx, ax ; [previous_val_r] + add bh, 80h + add byte [next_val_l+1], 80h + mov ax, [next_val_l] + add ax, bx ; [previous_val_l] + rcr ax, 1 + xchg ax, bx + add ax, bx ; bx = interpolated middle (L) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (L) + add byte [next_val_r+1], 80h + mov ax, dx ; [previous_val_r] + add ax, [next_val_r] + rcr ax, 1 + xchg ax, dx + add ax, dx ; dx = interpolated middle (R) + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 1 (R) + mov ax, bx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (L) + mov ax, dx + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 2 (R) + mov ax, bx + add ax, [next_val_l] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (L) + mov ax, dx + add ax, [next_val_r] + rcr ax, 1 + sub ah, 80h ; -32768 to +32767 format again + stosw ; interpolated sample 3 (R) + retn + +; 13/11/2023 +previous_val: +previous_val_l: dw 0 +previous_val_r: dw 0 +next_val: +next_val_l: dw 0 +next_val_r: dw 0 + +; 16/11/2023 +faz: db 0 + +; -------------------------------------------------------- +; 27/05/2024 - (TRDOS 386 Kernel) audio.s +; -------------------------------------------------------- + +NOT_PCI32_PCI16 EQU 03FFFFFFFh ; NOT BIT31+BIT30 ; 19/03/2017 +NOT_BIT31 EQU 7FFFFFFFh + +pciFindDevice: + ; 19/11/2023 + ; 03/04/2017 ('pci.asm', 20/03/2017) + ; + ; scan through PCI space looking for a device+vendor ID + ; + ; Entry: EAX=Device+Vendor ID + ; + ; Exit: EAX=PCI address if device found + ; EDX=Device+Vendor ID + ; CY clear if found, set if not found. EAX invalid if CY set. + ; + ; Destroys: ebx, edi ; 19/11/2023 + + ; 19/11/2023 + mov ebx, eax + mov edi, 80000000h +nextPCIdevice: + mov eax, edi ; read PCI registers + call pciRegRead32 + ; 19/11/2023 + cmp edx, ebx + je short PCIScanExit ; found + ; 19/11/2023 + cmp edi, 80FFF800h + jnb short pfd_nf ; not found + add edi, 100h + jmp short nextPCIdevice +pfd_nf: + stc + retn +PCIScanExit: + ;pushf + mov eax, NOT_BIT31 ; 19/03/2017 + and eax, edi ; return only bus/dev/fn # + retn + +pciRegRead: + ; 30/05/2024 + ; 03/04/2017 ('pci.asm', 20/03/2017) + ; + ; 8/16/32bit PCI reader + ; + ; Entry: EAX=PCI Bus/Device/fn/register number + ; BIT30 set if 32 bit access requested + ; BIT29 set if 16 bit access requested + ; otherwise defaults to 8 bit read + ; + ; Exit: DL,DX,EDX register data depending on requested read size + ; + ; Note1: this routine is meant to be called via pciRegRead8, + ; pciRegread16 or pciRegRead32, listed below. + ; + ; Note2: don't attempt to read 32 bits of data from a non dword + ; aligned reg number. Likewise, don't do 16 bit reads from + ; non word aligned reg # + + push ebx + push cx + mov ebx, eax ; save eax, dh + mov cl, dh + + and eax, NOT_PCI32_PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; 13/11/2024 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; read to + + test ebx, PCI32+PCI16 + jnz short _pregr0 + + in al, dx ; return 8 bits of data + + mov dl, al + mov dh, cl ; restore dh for 8 bit read + jmp short _pregr2 +_pregr0: + test ebx, PCI32 + jnz short _pregr1 + + in ax, dx + + mov dx, ax ; return 16 bits of data + jmp short _pregr2 +_pregr1: + in eax, dx ; return 32 bits of data + + mov edx, eax +_pregr2: + mov eax, ebx ; restore eax + and eax, NOT_PCI32_PCI16 ; clear out data size request + pop cx + pop ebx + retn + +pciRegRead8: + and eax, NOT_PCI32_PCI16 ; set up 8 bit read size + jmp short pciRegRead ; call generic PCI access + +pciRegRead16: + and eax, NOT_PCI32_PCI16 ; set up 16 bit read size + or eax, PCI16 ; call generic PCI access + jmp short pciRegRead + +pciRegRead32: + and eax, NOT_PCI32_PCI16 ; set up 32 bit read size + or eax, PCI32 ; call generic PCI access + jmp pciRegRead + +pciRegWrite: + ; 30/05/2024 + ; 03/04/2017 ('pci.asm', 29/11/2016) + ; + ; 8/16/32bit PCI writer + ; + ; Entry: EAX=PCI Bus/Device/fn/register number + ; BIT31 set if 32 bit access requested + ; BIT30 set if 16 bit access requested + ; otherwise defaults to 8bit read + ; DL/DX/EDX data to write depending on size + ; + ; Note1: this routine is meant to be called via pciRegWrite8, + ; pciRegWrite16 or pciRegWrite32 as detailed below. + ; + ; Note2: don't attempt to write 32bits of data from a non dword + ; aligned reg number. Likewise, don't do 16 bit writes from + ; non word aligned reg # + + push ebx + push ecx + mov ebx, eax ; save eax, edx + mov ecx, edx + and eax, NOT_PCI32_PCI16 ; clear out data size request + or eax, BIT31 ; make a PCI access request + and al, NOT 3 ; 13/11/2024 ; force index to be dword + + mov dx, PCI_INDEX_PORT + out dx, eax ; write PCI selector + + mov dx, PCI_DATA_PORT + mov al, bl + and al, 3 ; figure out which port to + add dl, al ; write to + + test ebx, PCI32+PCI16 + jnz short _pregw0 + + mov al, cl ; put data into al + out dx, al + + jmp short _pregw2 +_pregw0: + test ebx, PCI32 + jnz short _pregw1 + + mov ax, cx ; put data into ax + out dx, ax + + jmp short _pregw2 +_pregw1: + mov eax, ecx ; put data into eax + out dx, eax +_pregw2: + mov eax, ebx ; restore eax + and eax, NOT_PCI32_PCI16 ; clear out data size request + mov edx, ecx ; restore dx + pop ecx + pop ebx + retn + +pciRegWrite8: + and eax, NOT_PCI32_PCI16 ; set up 8 bit write size + jmp short pciRegWrite ; call generic PCI access + +pciRegWrite16: + and eax, NOT_PCI32_PCI16 ; set up 16 bit write size + or eax, PCI16 ; call generic PCI access + jmp short pciRegWrite + +pciRegWrite32: + and eax, NOT_PCI32_PCI16 ; set up 32 bit write size + or eax, PCI32 ; call generic PCI access + jmp pciRegWrite + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ac97_vra.asm +; -------------------------------------------------------- + + ; 13/11/2023 + +;VRA: db 1 + +codecConfig: + ; 30/05/2024 + ; 19/05/2024 + ; 19/11/2023 + ; 15/11/2023 + ; 04/11/2023 + ; 17/02/2017 + ; 07/11/2016 (Erdogan Tan) + + ;AC97_EA_VRA equ 1 + AC97_EA_VRA equ BIT0 + + ; 04/11/2023 +init_ac97_controller: + mov eax, [bus_dev_fn] + mov al, PCI_CMD_REG + call pciRegRead16 ; read PCI command register + or dl, IO_ENA+BM_ENA ; enable IO and bus master + call pciRegWrite16 + + ;call delay_100ms + + ; 19/05/2024 + ; ('PLAYMOD3.ASM', Erdogan Tan, 18/05/2024) + +init_ac97_codec: + ; 18/11/2023 + mov bp, 40 + ; 29/05/2024 + ;mov bp, 1000 +_initc_1: + ; 30/05/2024 + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + ; 19/05/2024 + call delay1_4ms + + cmp eax, 0FFFFFFFFh ; -1 + jne short _initc_3 +_initc_2: + dec bp + jz short _ac97_codec_ready + + call delay_100ms + jmp short _initc_1 +_initc_3: + test eax, CTRL_ST_CREADY + jnz short _ac97_codec_ready + + ; 30/05/2024 + cmp byte [reset], 1 + jnb short _initc_2 + + call reset_ac97_codec + ; 30/05/2024 + mov byte [reset], 1 + ; 19/05/2024 + jmp short _initc_2 + +_ac97_codec_ready: + mov dx, [NAMBAR] + ;add dx, 0 ; ac_reg_0 ; reset register + out dx, ax + + call delay_100ms + + ; 19/11/2023 + or bp, bp + jnz short _ac97_codec_init_ok + + xor ax, ax ; 0 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + out dx, ax + + ; 30/05/2024 + call delay1_4ms + + ; 19/11/2023 + ; wait for 1 second + ; 19/05/2024 + mov cx, 1000 ; 1000*4*0.25ms = 1s + ;;mov cx, 10 + ; 30/05/2024 + ;mov cx, 40 +_ac97_codec_rloop: + ;call delay_100ms + + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_REG_POWERDOWN + in ax, dx + + call delay1_4ms + + and ax, 0Fh + cmp al, 0Fh + je short _ac97_codec_init_ok + loop _ac97_codec_rloop + +init_ac97_codec_err1: + ;stc ; cf = 1 ; 19/05/2024 +init_ac97_codec_err2: + retn + +_ac97_codec_init_ok: + call reset_ac97_controller + + ; 30/05/2024 + ; 19/05/2024 + ;call delay_100ms + + ; 30/05/2024 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + +setup_ac97_codec: + ; 12/11/2023 + cmp word [WAVE_SampleRate], 48000 + je short skip_rate + + ; 30/05/2024 + ; 19/05/2024 + ;call delay1_4ms + + ; 30/05/2024 + ;cmp byte [VRA], 0 + ;jna short skip_rate + + ; 11/11/2023 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + + ; 30/05/2024 + ; 19/05/2024 + call delay1_4ms + + ; 13/11/2024 + ;and al, NOT BIT1 ; Clear DRA + ;;; + ; 30/05/2024 + and al, NOT (BIT1+BIT0) ; Clear DRA+VRA + out dx, ax + + call check_vra + + cmp byte [VRA], 0 + jna short skip_rate + + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + in ax, dx + ;and al, ~BIT1 ; Clear DRA + ;;; + + or al, AC97_EA_VRA ; 1 ; 04/11/2023 + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + + out dx, ax ; Enable variable rate audio + + mov cx, 10 +check_vra_loop: + call delay_100ms + ; 30/05/2024 + ;call delay1_4ms + + ; 30/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah + ; 11/11/2023 + in ax, dx + + test al, AC97_EA_VRA ; 1 + jnz short set_rate + + ; 11/11/2023 + loop check_vra_loop + +;vra_not_supported: ; 19/05/2024 + mov byte [VRA], 0 + jmp short skip_rate + +set_rate: + mov ax, [WAVE_SampleRate] ; 17/02/2017 (Erdogan Tan) + + mov dx, [NAMBAR] + add dx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch + out dx, ax ; PCM Front/Center Output Sample Rate + + ;call delay_100ms + ; 30/05/2024 + call delay1_4ms + + ; 12/11/2023 +skip_rate: + mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_MASTER_VOL_REG ;02h + out dx, ax + + ; 11/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + mov ax, 0202h + mov dx, [NAMBAR] + add dx, CODEC_PCM_OUT_REG ;18h + out dx, ax + + ; 11/11/2023 + call delay1_4ms + call delay1_4ms + call delay1_4ms + call delay1_4ms + + ; 30/05/2024 + ; 19/05/2024 + ;clc + + retn + +reset_ac97_controller: + ; 19/05/2024 + ; 11/11/2023 + ; 10/06/2017 + ; 29/05/2017 + ; 28/05/2017 + ; reset AC97 audio controller registers + xor ax, ax + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov al, RR + mov dx, PI_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, PO_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + mov dx, MC_CR_REG + add dx, [NABMBAR] + out dx, al + + ; 19/05/2024 + call delay1_4ms + + retn + +reset_ac97_codec: + ; 11/11/2023 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + in eax, dx + + ;test eax, 2 + ; 06/08/2022 + test al, 2 + jz short _r_ac97codec_cold + + call warm_ac97codec_reset + jnc short _r_ac97codec_ok +_r_ac97codec_cold: + call cold_ac97codec_reset + jnc short _r_ac97codec_ok + + ; 16/04/2017 + ;xor eax, eax ; timeout error + ;stc + retn + +_r_ac97codec_ok: + xor eax, eax + ;mov al, VIA_ACLINK_C00_READY ; 1 + inc al + retn + +warm_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 6 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + mov cx, 10 ; total 1s +_warm_ac97c_rst_wait: + call delay_100ms + + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _warm_ac97c_rst_ok + + dec cx + jnz short _warm_ac97c_rst_wait + +_warm_ac97c_rst_fail: + stc +_warm_ac97c_rst_ok: + retn + +cold_ac97codec_reset: + ; 11/11/2023 + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm) + mov eax, 2 + mov dx, GLOB_CNT_REG ; 2Ch + add dx, [NABMBAR] + out dx, eax + + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + call delay_100ms ; wait 100 ms + + mov cx, 16 ; total 20*100 ms = 2s + +_cold_ac97c_rst_wait: + mov dx, GLOB_STS_REG ; 30h + add dx, [NABMBAR] + in eax, dx + + test eax, CTRL_ST_CREADY + jnz short _cold_ac97c_rst_ok + + call delay_100ms + + dec cx + jnz short _cold_ac97c_rst_wait + +_cold_ac97c_rst_fail: + stc +_cold_ac97c_rst_ok: + retn + +; 13/11/2024 +; 30/05/2024 +if 1 +check_vra: + ; 30/05/2024 + mov byte [VRA], 1 + + ; 29/05/2024 - audio.s (TRDOS 386 Kernel) - 27/05/2024 + ; 24/05/2024 + ; 23/05/2024 + mov dx, [NAMBAR] + add dx, CODEC_EXT_AUDIO_REG ; 28h + in ax, dx + + ; 30/05/2024 + ; 23/05/2024 + call delay1_4ms + + ; 30/05/2024 + test al, BIT0 + ;test al, 1 ; BIT0 ; Variable Rate Audio bit + jnz short check_vra_ok + +vra_not_supported: + ; 13/11/2023 + mov byte [VRA], 0 +check_vra_ok: + retn +end if + +; -------------------------------------------------------- + +; 18/11/2024 +; Ref: TRDOS 386 v2.0.9, audio.s, Erdogan Tan, 06/06/2024 + +ac97_stop: + ; 18/11/2024 + mov byte [stopped], 2 + +ac97_po_cmd@: + xor al, al ; 0 +ac97_po_cmd: + mov dx, [NABMBAR] + add dx, PO_CR_REG ; PCM out control register + out dx, al + retn + +ac97_pause: + mov byte [stopped], 1 ; paused + ;mov al, 0 + ;jmp short ac97_po_cmd + jmp short ac97_po_cmd@ + +ac97_play: ; continue to play (after pause) + mov byte [stopped], 0 + mov al, RPBM + jmp short ac97_po_cmd + +; -------------------------------------------------------- + +PORTB EQU 061h +REFRESH_STATUS EQU 010h ; Refresh signal status + +delay_100ms: + ; 11/11/2023 + ; 29/05/2017 + ; 24/03/2017 ('codec.asm') + ; wait 100 ms + push cx + mov cx, 400 ; 400*0.25ms +_delay_x_ms: + call delay1_4ms + loop _delay_x_ms + pop cx + retn + +delay1_4ms: + push ax + push cx + mov cx, 16 ; close enough. + in al,PORTB + and al,REFRESH_STATUS + mov ah,al ; Start toggle state + or cx, cx + jz short _d4ms1 + inc cx ; Throwaway first toggle +_d4ms1: + in al,PORTB ; Read system control port + and al,REFRESH_STATUS ; Refresh toggles 15.085 microseconds + cmp ah,al + je short _d4ms1 ; Wait for state change + + mov ah,al ; Update with new state + dec cx + jnz short _d4ms1 + + ; 30/05/2024 + clc + + pop cx + pop ax + retn + +; -------------------------------------------------------- +; 14/11/2024 - Erdogan Tan +; -------------------------------------------------------- + +checkUpdateEvents: + call check4keyboardstop + jc short c4ue_ok + + ; 18/11/2024 + push ax ; * + or ax, ax + jz c4ue_cpt + + ; 18/11/2024 + cmp al, 20h ; SPACE (spacebar) ; pause/play + jne short ch4ue_chk_s + cmp byte [stopped], 0 + ja short ch4ue_chk_ps + ; pause + call ac97_pause + ; 21/11/2024 + mov al, [tLO] + mov byte [tLP], al + jmp c4ue_cpt +ch4ue_chk_ps: + cmp byte [stopped], 1 + ja short ch4ue_replay + ; continue to play (after a pause) + call ac97_play + jmp short c4ue_cpt +ch4ue_replay: + ; 19/11/2024 + pop ax ; * + pop ax ; return address + call codecConfig + mov al, [volume] + call SetPCMOutVolume@ + mov byte [stopped], 0 + call move_to_beginning + jmp PlayWav + +ch4ue_chk_s: + cmp al, 'S' ; stop + jne short ch4ue_chk_fb + cmp byte [stopped], 0 + ja short c4ue_cpt ; Already stopped/paused + call ac97_stop + ; 19/11/2024 + mov byte [tLO], 0 + ; 21/11/2024 + mov byte [tLP], '0' + jmp short c4ue_cpt + +ch4ue_chk_fb: + ; 17/11/2024 + cmp al, 'F' + jne short c4ue_chk_b + call Player_ProcessKey_Forwards + jmp short c4ue_cpt + + ; 18/11/2024 +c4ue_ok: + retn + +c4ue_chk_b: + cmp al, 'B' + ;jne short c4ue_cpt + ; 19/11/2024 + jne short c4ue_chk_h + call Player_ProcessKey_Backwards + jmp short c4ue_cpt +c4ue_chk_h: + ; 19/11/2024 + cmp al, 'H' + jne short c4ue_chk_cr + mov byte [wleds], 0 + call write_ac97_pci_dev_info + mov dh, 24 + mov dl, 79 + call setCursorPosition +c4ue_chk_cr: + ; 19/11/2024 + cmp al, 0Dh ; ENTER/CR key + jne short c4ue_cpt + ;inc byte [wleds] + ;jnz short c4ue_cpt + ;inc byte [wleds] + ;;; + ; 23/11/2024 + xor bx, bx + mov bl, [wleds] + inc bl + and bl, 0Fh + jnz short c4ue_sc + inc bx +c4ue_sc: + mov [wleds], bl + shr bl, 1 + mov al, [bx+colors] + jnc short c4ue_sc_@ + or al, 10h ; blue (dark) background +c4ue_sc_@: + mov [ccolor], al + ;;; +c4ue_cpt: + push ds + mov bx, 40h + mov ds, bx + mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;cli + mov ax, [bx] + mov dx, [bx+2] + ;sti + pop ds + ; 18/11/2024 + pop cx ; * + cmp dx, [timerticks+2] + jne short c4ue_utt + cmp ax, [timerticks] + ;je short c4ue_ok + ; 18/11/2024 + je short c4ue_skip_utt +c4ue_utt: + mov [timerticks], ax + mov [timerticks+2], dx + jmp short c4ue_cpt_@ +c4ue_skip_utt: + ; 18/11/2024 + and cx, cx + jz short c4ue_ok +c4ue_cpt_@: + ; 18/11/2024 + cmp byte [stopped], 0 + ja short c4ue_ok + + call CalcProgressTime + + cmp ax, [ProgressTime] + ;je short c4ue_ok + ; same second, no need to update + ; 23/11/2024 + je short c4ue_uvb + + ;call UpdateProgressTime + ;call UpdateProgressBar@ + call UpdateProgressBar + + ; 23/11/2024 +c4ue_uvb: + cmp byte [wleds], 0 + jna short c4ue_vb_ok + + call UpdateWaveLeds + +c4ue_vb_ok: + retn + + ;clc +;c4ue_ok: +; retn + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ich_wav4.asm +; -------------------------------------------------------- + +check4keyboardstop: + ; 19/05/2024 + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + ;clc + jz short _cksr + + xor ah, ah + int 16h + + ;;; + ; 19/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + cmp al, 0 + jna short p_3 + dec al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_4 + + mov al, [volume] + cmp al, 31 + jnb short p_3 + inc al +p_2: + mov [volume], al + ; 14/11/2024 + call SetPCMOutVolume + ; 15/11/2024 (QEMU) + ;call SetMasterVolume + ;call UpdateVolume + ;;clc + ;retn + jmp UpdateVolume + ;mov ah, al + ;mov dx, [NAMBAR] + ;;add dx, CODEC_MASTER_VOL_REG + ;add dx, CODEC_PCM_OUT_REG + ;out dx, ax + ; + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms + ;call delay1_4ms +_cksr: ; 19/05/2024 + ; 18/11/2024 + xor ax, ax + ;clc +p_3: + retn +p_4: + ; 17/11/2024 + cmp ah, 01h ; ESC + je short p_q + cmp al, 03h ; CTRL+C + je short p_q + + ; 18/11/2024 + cmp al, 20h + je short p_r + + ; 19/11/2024 + cmp al, 0Dh ; CR/ENTER + je short p_r + + and al, 0DFh + cmp al, 'B' + je short p_r + cmp al, 'F' + je short p_r + cmp al, 'Q' + je short p_q + + clc + retn + + ;;; +;_cskr: +p_q: + stc +p_r: + retn + +; returns AL = current index value +getCurrentIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_CIV_REG + in al, dx + ;pop dx +uLVI2: ; 06/11/2023 + retn + +updateLVI: + ; 06/11/2023 + mov dx, [NABMBAR] + add dx, PO_CIV_REG + ; (Current Index Value and Last Valid Index value) + in ax, dx + + cmp al, ah ; is current index = last index ? + jne short uLVI2 + + ; 08/11/2023 + call getCurrentIndex + + test byte [flags], ENDOFFILE + ;jnz short uLVI1 + jz short uLVI0 ; 08/11/2023 + + ; 08/11/2023 + push ax + mov dx, [NABMBAR] + add dx, PO_SR_REG ; PCM out status register + in ax, dx + + test al, 3 ; bit 1 = Current Equals Last Valid (CELV) + ; (has been processed) + ; bit 0 = 1 -> DMA Controller Halted (DCH) + pop ax + jz short uLVI1 +uLVI3: + xor ax, ax + ; zf = 1 + retn +uLVI0: + ; not at the end of the file yet. + dec al + and al, 1Fh +uLVI1: + ;call setLastValidIndex +;uLVI2: + ;retn + +;input AL = index # to stop on +setLastValidIndex: + ; 08/11/2023 + ;push dx + mov dx, [NABMBAR] + add dx, PO_LVI_REG + out dx, al + ;pop dx + retn + +; 29/05/2024 +; 19/05/2024 +volume: db 02h + +; -------------------------------------------------------- + + ; 14/11/2024 +setCursorPosition: + ; dh = Row + ; dl = Column + mov ax, 0500h + int 10h + mov ah, 02h + mov bh, 00h + ;mov dh, setCursorPosition_Row + ;mov dl, setCursorPosition_Column + int 10h + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; NAME: SetTotalTime +;; DESCRIPTION: Calculates the total time in seconds in file +;; INPUT: DATA_SubchunkSize, WAVE_SampleRate, WAVE_BlockAlign +;; OUTPUT: CurrentTotalTime=Total time in seconds in file, +;; Output on the screen of the total time in seconds + +SetTotalTime: + ;; Calculate total seconds in file + mov ax, [DATA_SubchunkSize] + mov dx, [DATA_SubchunkSize + 2] + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + + mov bx, [WAVE_BlockAlign] + + div bx + + mov [TotalTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 42 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 45 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + ;jmp short PrintNumber + +; -------------------------------------------------------- + +PrintNumber: + ; bp = digits + ; ax = binary number + mov bx, 10 + xor cx, cx +printNumber_CutNumber: + inc cx + xor dx, dx + div bx + push dx + cmp cx, bp + je short printNumber_printloop + jmp printNumber_CutNumber + +printNumber_printloop: + pop ax + mov dl, '0' + add dl, al + mov ah, 02h + int 21h + loop printNumber_printloop + + retn + +; -------------------------------------------------------- + + ; 14/11/2024 - Erdogan Tan +SetProgressTime: + ;; Calculate playing/progress seconds in file + call CalcProgressTime + +UpdateProgressTime: + ; ax = (new) progress time + + mov [ProgressTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 33 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 36 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + jmp short PrintNumber + +; -------------------------------------------------------- + + ; 17/11/2024 + ; 14/11/2024 +CalcProgressTime: + mov ax, [LoadedDataBytes] + mov dx, [LoadedDataBytes+2] + mov bx, ax + or bx, dx + jz short cpt_ok + + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + mov bx, [WAVE_BlockAlign] + div bx +cpt_ok: + ; ax = (new) progress time + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; DESCRIPTION: Update file information on template +;; PARAMS: WAVE parameters and other variables +;; REGS: AX(RW) +;; VARS: CurrentFileName, WAVE_SampleRate, +;; RETURNS: On-screen file info is updated. + +UpdateFileInfo: + ;; Print File Name + mov dh, 9 + mov dl, 23 + call setCursorPosition + + mov si, wav_file_name + + ;;; + ; 14/11/2024 + ; skip directory separators + ; (note: asciiz string, max. 79 bytes except zero tail) + mov bx, si +chk4_nxt_sep: + lodsb + cmp al, '\' + je short chg_fpos + and al, al + jz short chg_fpos_ok + jmp short chk4_nxt_sep +chg_fpos: + mov bx, si + jmp short chk4_nxt_sep +chg_fpos_ok: + mov si, bx ; file name (without its path/directory) + ;;; + + call PrintString + + ;; Print Frequency + mov dh, 10 + mov dl, 23 + call setCursorPosition + mov ax, [WAVE_SampleRate] + mov bp, 5 + call PrintNumber + + ;; Print BitRate + mov dh, 9 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_BitsPerSample] + mov bp, 2 + call PrintNumber + + ;; Print Channel Number + mov dh, 10 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_NumChannels] + mov bp, 1 + call PrintNumber + + ;call UpdateVolume + ;retn + +; -------------------------------------------------------- + + ; 14/11/2024 +UpdateVolume: + ;; Print Volume + mov dh, 24 + mov dl, 75 + call setCursorPosition + + mov al, [volume] + + mov bl, 100 + mul bl + + mov bl, 31 + div bl + + neg ax + add ax, 100 + + xor ah, ah + mov bp, 3 + ;call PrintNumber + ;retn + jmp PrintNumber + +; -------------------------------------------------------- + + ; 14/11/2024 +PrintString: + ; si = string address + mov bx, 0Fh ; white + mov ah, 0Eh ; write as tty +printstr_loop: + lodsb + or al, al + jz short printstr_ok + int 10h + jmp short printstr_loop +printstr_ok: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 + ; (Ref: player.asm , Matan Alfasi, 2017) + ; (Modification: Erdogan Tan, 14/11/2024) + + PROGRESSBAR_ROW equ 23 + +UpdateProgressBar: + call SetProgressTime ; 14/11/2024 + + mov ax, [ProgressTime] +UpdateProgressBar@: + mov dx, 80 + mul dx + mov bx, [TotalTime] + div bx + + ;; Push for the 'Clean' part + push ax ; ** + push ax ; * + + ;; Set cursor position + mov dh, PROGRESSBAR_ROW + mov dl, 0 + call setCursorPosition + + pop ax ; * + or ax, ax + jz short UpdateProgressBar_Clean + +UpdateProgressBar_DrawProgress: + mov cx, ax + mov ah, 09h + mov al, 223 + mov bx, 0Fh + int 10h + +UpdateProgressBar_DrawCursor: + ;mov ax, cx + mov dh, PROGRESSBAR_ROW + ;mov dl, al + dec cx + mov dl, cl + call setCursorPosition + + mov ah, 09h + mov al, 223 + mov bx, 0Ch + mov cx, 1 + int 10h + +UpdateProgressBar_Clean: + pop ax ; ** + mov cx, ax + mov dh, PROGRESSBAR_ROW + mov dl, al + call setCursorPosition + + neg cx + add cx, 80 ; cf = 1 ; + + ;; CX = No. of times to print a clean character + ;mov cx, 80 + ;sub cx, ax + ;; 09h = Write character multiple times + mov ah, 09h + ;; 32 = Space ASCII code + ;mov al, 32 + ;mov bx, 0 + ; 15/11/2024 + mov al, 223 + mov bx, 8 + int 10h + ; 14/11/2024 + clc ; + + + retn + +; -------------------------------------------------------- +; 17/11/2024 + +Player_ProcessKey_Backwards: + ;; In order to go backwards 5 seconds: + ;; Update file pointer to the beginning, skip headers + mov cl, 'B' + jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_Forwards: + ;; In order to fast-forward 5 seconds, set the file pointer + ;; to CUR_SEEK + 5 * Freq + + mov cl, 'F' + ;jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_B_or_F: + ; 17/11/2024 + ; 04/11/2024 + ; (Ref: player.asm, Matan Alfasi, 2017) + + ; 04/11/2024 + mov ax, 5 + mov bx, [WAVE_BlockAlign] + mul bx + mov bx, [WAVE_SampleRate] + mul bx + ; dx:ax = transfer byte count for 5 seconds + + ; 17/11/2024 + cmp cl, 'B' + mov bx, [LoadedDataBytes] + mov cx, [LoadedDataBytes+2] + jne short move_forward ; cl = 'F' +move_backward: + sub bx, ax + sbb cx, dx + jnc short move_file_pointer +move_to_beginning: + xor cx, cx ; 0 + xor bx, bx ; 0 + jmp short move_file_pointer +move_forward: + add bx, ax + adc cx, dx + jc short move_to_end + cmp cx, [DATA_SubchunkSize+2] + ja short move_to_end + jb short move_file_pointer + cmp bx, [DATA_SubchunkSize] + jna short move_file_pointer +move_to_end: + mov bx, [DATA_SubchunkSize] + mov cx, [DATA_SubchunkSize+2] +move_file_pointer: + mov dx, bx + mov [LoadedDataBytes], dx + mov [LoadedDataBytes+2], cx + add dx, 44 ; + header + adc cx, 0 + + ; seek + mov bx, [filehandle] + mov ax, 4200h + int 21h + + retn + +; -------------------------------------------------------- + + ; 23/11/2024 + ; 19/11/2024 +clear_window: + xor ax, ax + jmp short clear_window_@ + +reset_wave_leds: + ; 23/11/2024 + ;mov al, 254 + ;mov ah, 8 ; gray (dark) + mov ax, 08FEh +clear_window_@: + push es + mov di, 0B800h + mov es, di + mov di, 2080 ; 13*80*2 + mov cx, 8*80 ; 8 rows + rep stosw + pop es + retn + +; -------------------------------------------------------- + + ; 09/12/2024 + ; 19/11/2024 +UpdateWaveLeds: + ; 23/11/2024 + call reset_wave_leds + ; 09/12/2024 + ;jmp short turn_on_leds + +; -------------------------------------------------------- + + ; 09/12/2024 +turn_on_leds: + ; 19/11/2024 +;turn_on_leds_stereo_16bit: + push es + push ds + + cmp byte [tLO],'2' + jne short tol_buffer_1 + +tol_buffer_2: + ; 21/11/2024 + mov si, [WAV_BUFFER2] + jmp short tol_@ + +tol_buffer_1: + cmp byte [tLO],'1' + ;jne short tol_retn + ; 23/11/2024 + jne short tol_clc_retn + + mov si, [WAV_BUFFER1] +tol_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + mov cx, [buffersize] ; word + shl cx, 1 ; byte + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol_o_@ + cmp si, cx + jna short tol_s_buf +tol_o_@: + mov si, cx + jmp short tol_s_buf + +tol_clc_retn: + ; 23/11/2024 + clc +tol_retn: + pop ds + pop es + retn + +tol_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol_s_buf: + mov [pbuf_o], si + +tol_buf_@: + ; 21/11/2024 + mov ds, [pbuf_s] + mov di, 0B800h + mov es, di + ;mov di, (20*80*2)-2 + + ; 23/11/2024 + mov cx, 80 + + ; 22/11/2024 + mov bx, wleds_addr + +tol_fill_c: + ; 22/11/2024 + ;inc di + ;inc di + ;push di + lodsw ; left + ;shr ax, 8 + mov dx, ax + lodsw ; right + ;shr ax, 8 + ;;; + ; 23/11/2024 + add ax, dx + ; 09/12/2024 + ;shr ax, 8 + ;;shr ax, 9 + ;add al, 80h + ;shr ax, 5 + add ah, 80h + shr ax, 13 + ;;; + ;;shr ax, 6 + + push bx + shl ax, 1 + add bx, ax + mov di, [cs:bx] + ; 23/11/2024 + mov ah, [cs:ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol_fill_c + + jmp short tol_retn + +; -------------------------------------------------------- + +; 30/05/2024 +print_msg: + mov bx, 07h +p_msg: + push es + push bp + push cx + push dx + + push ds + pop es + mov bp, si + mov ah, 03h ; Return cursor position (in DX) + ; bh = video page number + int 10h + xor cx, cx +p_msg_0: + lodsb + or al, al + jz short p_msg_1 + inc cx + jmp short p_msg_0 +p_msg_1: + or cx, cx + jz short p_msg_x + ; cx = number of chars + ; dx = screen (cursor) position + ; bl = color/attribute + ; bh = video page number + ; es:bp = string buffer + ;mov al, 1 ; attribute in BL, update cursor pos + ;mov ah, 13h ; write character string + mov ax, 1301h + int 10h +p_msg_x: + pop dx + pop cx + pop bp + pop es + retn + +; -------------------------------------------------------- +; -------------------------------------------------------- + +; DATA + +; 30/05/2024 +;reset: db 0 + +Credits: + db 'Tiny WAV Player for Retro DOS by Erdogan Tan. ' + db 'December 2024.',10,13,0 + db '18/12/2024', 10,13 +; 15/11/2024 +reset: + db 0 + +msgAudioCardInfo: + db 'for Intel AC97 (ICH) Audio Controller.', 10,13,0 + +msg_usage: + db 'usage: playwav8 filename.wav',10,13,0 ; 14/11/2024 + +noDevMsg: + db 'Error: Unable to find AC97 audio device!' + db 10,13,0 + +noFileErrMsg: + db 'Error: file not found.',10,13,0 + +msg_error: ; 30/05/2024 + +; 29/05/2024 +; 11/11/2023 +msg_init_err: + db CR, LF + db "AC97 Controller/Codec initialization error !" + db CR, LF, 0 ; 07/12/2024 + +; 25/11/2023 +msg_no_vra: + db 10,13 + db "No VRA support ! Only 48 kHZ sample rate supported !" + db 10,13,0 + +; 13/11/2024 +; ('<<' to 'shl' conversion for FASM) +; +; 29/05/2024 (TRDOS 386) +; 17/02/2017 +; Valid ICH device IDs + +valid_ids: +;dd (ICH_DID << 16) + INTEL_VID ; 8086h:2415h +dd (ICH_DID shl 16) + INTEL_VID ; 8086h:2415h +dd (ICH0_DID shl 16) + INTEL_VID ; 8086h:2425h +dd (ICH2_DID shl 16) + INTEL_VID ; 8086h:2445h +dd (ICH3_DID shl 16) + INTEL_VID ; 8086h:2485h +dd (ICH4_DID shl 16) + INTEL_VID ; 8086h:24C5h +dd (ICH5_DID shl 16) + INTEL_VID ; 8086h:24D5h +dd (ICH6_DID shl 16) + INTEL_VID ; 8086h:266Eh +dd (ESB6300_DID shl 16) + INTEL_VID ; 8086h:25A6h +dd (ESB631X_DID shl 16) + INTEL_VID ; 8086h:2698h +dd (ICH7_DID shl 16) + INTEL_VID ; 8086h:27DEh +; 03/11/2023 - Erdogan Tan +dd (MX82440_DID shl 16) + INTEL_VID ; 8086h:7195h +dd (SI7012_DID shl 16) + SIS_VID ; 1039h:7012h +dd (NFORCE_DID shl 16) + NVIDIA_VID ; 10DEh:01B1h +dd (NFORCE2_DID shl 16) + NVIDIA_VID ; 10DEh:006Ah +dd (AMD8111_DID shl 16) + AMD_VID ; 1022h:746Dh +dd (AMD768_DID shl 16) + AMD_VID ; 1022h:7445h +dd (CK804_DID shl 16) + NVIDIA_VID ; 10DEh:0059h +dd (MCP04_DID shl 16) + NVIDIA_VID ; 10DEh:003Ah +dd (CK8_DID shl 16) + NVIDIA_VID ; 1022h:008Ah +dd (NFORCE3_DID shl 16) + NVIDIA_VID ; 10DEh:00DAh +dd (CK8S_DID shl 16) + NVIDIA_VID ; 10DEh:00EAh + +;valid_id_count equ ($ - valid_ids)>>2 ; 05/11/2023 +; 13/11/2024 +valid_id_count = ($ - valid_ids) shr 2 ; 05/11/2023 + +; 19/11/2024 +; 03/06/2017 +hex_chars db "0123456789ABCDEF", 0 +msgAC97Info db 0Dh, 0Ah + db " AC97 Audio Controller & Codec Info", 0Dh, 0Ah + db " Vendor ID: " +msgVendorId db "0000h Device ID: " +msgDevId db "0000h", 0Dh, 0Ah + db " Bus: " +msgBusNo db "00h Device: " +msgDevNo db "00h Function: " +msgFncNo db "00h" + db 0Dh, 0Ah + db " NAMBAR: " +msgNamBar db "0000h " + db "NABMBAR: " +msgNabmBar db "0000h IRQ: " +msgIRQ dw 3030h + db 0Dh, 0Ah, 0 +; 25/11/2023 +msgVRAheader db " VRA support: " + db 0 +msgVRAyes db "YES", 0Dh, 0Ah, 0 +msgVRAno db "NO ", 0Dh, 0Ah + db " (Interpolated sample rate playing method)" + db 0Dh, 0Ah, 0 + +; -------------------------------------------------------- +; 14/11/2024 (Ref: player.asm, Matan Alfasi, 2017) + +; 23/11/2024 (overwrite splashscreen, a method to solve 64KB limit problem) +; wave volume leds address array +wleds_addr: ; 80*16 bytes + +SplashScreen: + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " _______ ______ _______. ", 221, 219, 222 + db 221, 219, 222, " | \ / __ \ / | ", 221, 219, 222 + db 221, 219, 222, " | .--. | | | | | (----` ", 221, 219, 222 + db 221, 219, 222, " | | | | | | | \ \ ", 221, 219, 222 + db 221, 219, 222, " | '--' | `--' | .----) | ", 221, 219, 222 + db 221, 219, 222, " |_______/ \______/ |_______/ ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " .______ __ ___ ____ ____ _______ .______ ", 221, 219, 222 + db 221, 219, 222, " | _ \ | | / \ \ \ / / | ____|| _ \ ", 221, 219, 222 + db 221, 219, 222, " | |_) | | | / ^ \ \ \/ / | |__ | |_) | ", 221, 219, 222 + db 221, 219, 222, " | ___/ | | / /_\ \ \_ _/ | __| | / ", 221, 219, 222 + db 221, 219, 222, " | | | `----./ _____ \ | | | |____ | |\ \----. ", 221, 219, 222 + db 221, 219, 222, " | _| |_______/__/ \__\ |__| |_______|| _| `._____| ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " WELCOME TO ", 221, 219, 222 + db 221, 219, 222, " DOS PLAYER ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db " " +Template: + db 201, 78 dup(205), 187 + db 186, 33 dup(219), " DOS Player ", 33 dup(219), 186 + db 204, 78 dup(205), 185 + db 186, 33 dup(32), " User Guide ", 33 dup(32), 186 + db 186, 6 dup(32), " Play/Pause ", 4 dup(32), " Hardware Info", 9 dup(32), 186 + db 186, 6 dup(32), " Stop ", 4 dup(32), " Wave Lighting", 9 dup(32), 186 + db 186, 6 dup(32), " Forwards ", 4 dup(32), "<+>/<-> Inc/Dec Volume", 8 dup(32), 186 + db 186, 6 dup(32), " Backwards ", 4 dup(32), " Quit Program ", 9 dup(32), 186 + db 204, 78 dup(205), 185 + db 186, 6 dup(32), "File Name : ", 4 dup(32), "Bit-Rate : 0 Bits ", 9 dup(32), 186 + db 186, 6 dup(32), "Frequency : 0 Hz ", 4 dup(32), "#-Channels: 0 ", 9 dup(32), 186 + db 200, 78 dup(205), 188 + db 80 dup(32) +improper_samplerate_txt: ; 03/11/2024 +read_error_txt: + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(205) + db 80 dup(32) + db 33 dup(32), "00:00 ", 174, 175, " 00:00", 24 dup(32), "VOL 000%" + +; 23/11/2024 +colors: db 0Fh, 0Bh, 0Ah, 0Ch, 0Eh, 09h, 0Dh, 0Fh + ; white, cyan, green, red, yellow, blue, magenta +ccolor: db 0Bh ; cyan + +EOF: + +; BSS + +align 2 + +; 22/11/2024 +; wave volume leds address array +;wleds_addr: rw 80*8 ; rb 2*80*8 + +; 14/11/2024 +; 17/02/2017 +bss_start: + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +; 18/11/2024 +stopped: rb 1 +tLO: rb 1 +; 21/11/2024 +tLP: rb 1 +; 19/11/2024 +wleds: rb 1 +wleds_dif: rw 1 +pbuf_s: rw 1 +pbuf_o: rw 1 + +; 30/05/2024 +VRA: rb 1 ; Variable Rate Audio Support Status + rb 1 + +;;;;;;;;;;;;;; +; 14/11/2024 +; (Ref: player.asm, Matan Alfasi, 2017) +WAVFILEHEADERbuff: +RIFF_ChunkID: rd 1 ; Must be equal to "RIFF" - big-endian + ; 0x52494646 +RIFF_ChunkSize: + rd 1 ; Represents total file size, not + ; including the first 2 fields + ; (Total_File_Size - 8), little-endian +RIFF_Format: + rd 1 ; Must be equal to "WAVE" - big-endian + ; 0x57415645 + +;; WAVE header parameters ("Sub-chunk") +WAVE_SubchunkID: + rd 1 ; Must be equal to "fmt " - big-endian + ; 0x666d7420 +WAVE_SubchunkSize: + rd 1 ; Represents total chunk size +WAVE_AudioFormat: + rw 1 ; PCM (Raw) - is 1, other - is a form + ; of compression, not supported. +WAVE_NumChannels: + rw 1 ; Number of channels, Mono-1, Stereo-2 +WAVE_SampleRate: + rd 1 ; Frequency rate, in Hz (8000, 44100 ...) +WAVE_ByteRate: rd 1 ; SampleRate * NumChannels * BytesPerSample +WAVE_BlockAlign: + rw 1 ; NumChannels * BytesPerSample + ; Number of bytes for one sample. +WAVE_BitsPerSample: + rw 1 ; 8 = 8 bits, 16 = 16 bits, etc. + +;; DATA header parameters +DATA_SubchunkID: + rd 1 ; Must be equal to "data" - big-endian + ; 0x64617461 +DATA_SubchunkSize: + rd 1 ; NumSamples * NumChannels * BytesPerSample + ; Number of bytes in the data. +;;;;;;;;;;;;;; + +; 15/11/2024 +cursortype: rw 1 + +filehandle: rw 1 + +flags: rb 1 +; 06/11/2023 +ac97_int_ln_reg: rb 1 + +; 30/05/2024 +wav_file_name: + rb 80 ; wave file, path name (<= 80 bytes) + + rw 1 + +; 12/11/2016 - Erdogan Tan + +bus_dev_fn: rd 1 +dev_vendor: rd 1 + +; 17/02/2017 +; NAMBAR: Native Audio Mixer Base Address Register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 10h-13h +; NABMBAR: Native Audio Bus Mastering Base Address register +; (ICH, Audio D31:F5, PCI Config Space) Address offset: 14h-17h +NAMBAR: rw 1 ; BAR for mixer +NABMBAR: rw 1 ; BAR for bus master regs + +; 256 byte buffer for descriptor list +BDL_BUFFER: rw 1 ; segment of our 256byte BDL buffer +WAV_BUFFER1: rw 1 ; segment of our WAV storage +; 64k buffers for wav file storage +WAV_BUFFER2: rw 1 ; segment of 2nd wav buffer + +; 09/12/2024 +; 23/11/2024 +;turn_on_leds: rd 1 ; turn_on_leds procedure pointer (m8,m16,s8,s16) + +; 15/11/2024 +; 06/11/2023 +;sample_rate: rw 1 ; HZ (carrier frequency) +; 15/11/2024 +; 19/11/2016 +;stmo: rw 1 ; channels +;btps: rw 1 ; bits per ONE sample +; 14/11/2024 +;byps: rw 1 ; bytes per sample (channels * sample length) + ; sample length = 2 for 16 bit samples + ; = 1 for 8 bit samples + ; channels = 2 for stereo + ; = 1 for mono +; 08/11/2023 +; 07/11/2023 +fbs_shift: rb 1 + rb 1 ; 08/11/2023 + +; 15/11/2024 +loadfromwavfile: + rw 1 ; 'loadfromfile' or load+conversion proc address +loadsize: rw 1 ; (.wav file) read count (bytes) per one time +buffersize: rd 1 ; 16 bit samples (not bytes) + +; 14/11/2024 +TotalTime: rw 1 ; Total (WAV File) Playing Time in seconds +ProgressTime: rw 1 +count: rw 1 ; byte count of one (wav file) read +LoadedDataBytes: + rd 1 ; total read/load count + +timerticks: rd 1 ; (to eliminate excessive lookup of events in tuneloop) + ; (in order to get the emulator/qemu to run correctly) +; 14/11/2024 +bss_end: + +;alignb 2 + +; 32 kilo bytes for temporay buffer +; (for stereo-mono, 8bit/16bit corrections) +; 14/11/2024 +;temp_buffer: rb 32768 +; 17/11/2024 +temp_buffer: rb 50600 ; (44.1 kHZ stereo 12650 samples) +; 18/11/2023 +;temp_buffer: rb 56304 ; (44.1 kHZ stereo 14076 samples) + +;alignb 16 +;bss_end: \ No newline at end of file diff --git a/trdos386/programs/16bit/playwav8_com_2024.zip b/trdos386/programs/16bit/playwav8_com_2024.zip new file mode 100644 index 0000000..b36c858 Binary files /dev/null and b/trdos386/programs/16bit/playwav8_com_2024.zip differ diff --git a/trdos386/programs/16bit/playwav9.asm b/trdos386/programs/16bit/playwav9.asm new file mode 100644 index 0000000..5e577c0 --- /dev/null +++ b/trdos386/programs/16bit/playwav9.asm @@ -0,0 +1,2626 @@ +; **************************************************************************** +; playwav9.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; PLAYWAV9.COM ! Sound Blaster 16 (DOS) .WAV PLAYER program by Erdogan TAN +; +; 24/11/2024 +; +; [ Last Modification: 18/12/2024 ] +; +; Modified from PLAYWAV8.COM .wav player program by Erdogan Tan, 23/11/2024 +; +; Assembler: FASM 1.73 +; fasm playwav9.asm PLAYWAV9.COM +; ---------------------------------------------------------------------------- +; In the visualization part of the code, the source code of Matan Alfasi's +; (Ami-Asaf) player.exe program was partially used. +; ---------------------------------------------------------------------------- +; Previous versions of this Wav Player were based in part on .wav file player +; (for DOS) source code written by Jeff Leyla in 2002. + +; playwav8.asm (23/11/2024) + +; INTERRUPT (SRB) + TUNELOOP version ; 24/11/2024 +; (running in DOSBOX, VIRTUALBOX, QEMU is ok) +; Signal Response Byte = message/signal to user about an event/interrupt +; as requested (TuneLoop procedure continuously checks this SRB) +; (TRDOS 386 v2 feature is used here as very simple interrupt handler output) + +; CODE + + ; 13/11/2024 +macro sys_msg op1,op2 +{ ; 30/05/2024 + mov si, op1 ; message + mov bl, op2 ; text color + xor bh, bh ; video page 0 + mov ah, 0Eh + call p_msg +} + + ; 24/11/2024 +macro SbOut op1 +{ +local .wait +.wait: + in al, dx + or al, al + js short .wait + mov al, op1 ; command + out dx, al +} + +; player internal variables and other equates. +; 17/11/2024 +;BUFFERSIZE equ 65520 +; 24/11/2024 +;dma_buffer_size equ 32768 +;LOADSIZE equ 16384 +ENDOFFILE equ 1 ; flag for knowing end of file +; 27/11/2024 +dma_buffer_size equ 44100 +LOADSIZE equ 22050 + +use16 + +org 100h + +_STARTUP: + ; 30/05/2024 + ; Prints the Credits Text. + sys_msg Credits, 0Bh + + ; 30/05/2024 + call setFree ; deallocate unused DOS mem + + ; 17/02/2017 + ; Clear BSS (uninitialized data) area + xor ax, ax ; 0 + mov cx, (bss_end - bss_start)/2 + mov di, bss_start + rep stosw + + ; 24/11/2024 + ; Detect (& Reset) Sound Blaster 16 Audio Device + call DetectSB16 + jnc short GetFileName + + ; 30/05/2024 +_dev_not_ready: + ; couldn't find the audio device! + sys_msg noDevMsg, 0Fh + jmp Exit + + ; 30/05/2024 +GetFileName: + mov di, wav_file_name + mov si, 80h + mov bl, [si] + xor bh, bh + inc bx + mov byte [si+bx], 0 ; make AsciiZ filename. + inc si +ScanName: + lodsb + test al, al + jz pmsg_usage + cmp al, 20h + je short ScanName ; scan start of name. + stosb + mov ah, 0FFh + ;;; + ; 14/11/2024 + ; (max. path length = 64 bytes for MSDOS ?) (*) + xor cx, cx ; 0 + ;;; +a_0: + inc ah +a_1: + ;;; + ; 14/11/2024 + inc cx + ;;; + lodsb + stosb + cmp al, '.' + je short a_0 + and al, al + ;jnz short a_1 + ;;; + ; 14/11/2024 + jz short a_3 + and ah, ah + jz short a_2 + cmp al, '\' + jne short a_2 + mov ah, 0 +a_2: + cmp cl, 75 ; 64+8+'.'+3 -> offset 75 is the last chr + jb short a_1 +a_3: + ;;; + or ah, ah ; if period NOT found, + jnz short _1 ; then add a .WAV extension. +SetExt: + dec di + mov dword [di], '.WAV' ; ! 64+12 is DOS limit + ; but writing +4 must not + ; destroy the following data + mov byte [di+4], 0 ; so, 80 bytes path + 0 is possible here +_1: + call write_audio_dev_info + +; open the file + ; open existing file + ; 14/11/2024 + ;mov al, OPEN ; open existing file + mov dx, wav_file_name + call openFile ; no error? ok. + jnc short getwavparms ; 14/11/2024 + +; file not found! + sys_msg noFileErrMsg, 0Ch +_exit_: + jmp Exit + +getwavparms: + ; 14/11/2024 + call getWAVParameters + jc short _exit_ ; nothing to do + + ; 15/11/2024 + ;; Set video mode to 03h (not necessary) + mov ax, 03h + int 10h + + ; 15/11/2024 + ;; Get the cursor type + mov ah, 03h + int 10h + mov [cursortype], cx ; save + + ; 15/11/2024 + ;; Set the cursor to invisible + mov ah, 01h + mov cx, 2607h + int 10h + + ;;; 14/11/2024 +Player_SplashScreen: + ; 15/11/2024 + ;xor dx, dx + ;call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, SplashScreen + int 10h + ;;; + + ;;; + ; 22/11/2024 + ; set wave volume led addresses + mov bx, 13*80*2 + mov bp, 80 + mov di, wleds_addr +wleds_sa_1: + mov cx, 7 +wleds_sa_2: + mov ax, 80*2 + mul cx + add ax, bx + stosw + loop wleds_sa_2 + mov ax, bx + stosw + inc bx + inc bx + dec bp + jnz short wleds_sa_1 + ;;; + + ;;; + ; 23/11/2024 + cmp byte [WAVE_NumChannels], 1 + ja short stolp_s +stolp_m: + cmp byte [WAVE_BitsPerSample], 8 + ja short stolp_m16 +stolp_m8: + mov word [turn_on_leds], turn_on_leds_mono_8bit + jmp short stolp_ok +stolp_m16: + mov word [turn_on_leds], turn_on_leds_mono_16bit + jmp short stolp_ok +stolp_s: + cmp byte [WAVE_BitsPerSample], 8 + ja short stolp_s16 +stolp_s8: + mov word [turn_on_leds], turn_on_leds_stereo_8bit + jmp short stolp_ok +stolp_s16: + mov word [turn_on_leds], turn_on_leds_stereo_16bit + jmp short stolp_ok +stolp_ok: + ;;; + + ;;; wait for 3 seconds + ;mov cx, 002Dh + ;mov dx, 0C6C0h + ;mov ah, 86h + ;int 15h + ;;; + ; 26/11/2024 + ;mov cx, 3*18 + ; 27/11/2024 + mov cx, 2*18 +getticks: + ; 26/11/2024 + call GetTimerTicks + + cmp ax, [timerticks] + jne short chkws + cmp dx, [timerticks+2] + je short getticks +chkws: + mov [timerticks], ax + mov [timerticks+2], dx + loop getticks + ;;; + + ;;; +Player_Template: + xor dx, dx + call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, Template + int 10h + ;;; + + ; 14/11/2024 + call SetTotalTime + call UpdateFileInfo + +PlayNow: + ; 24/11/2024 + mov al, 5 ; 15 = max, 0 = min + ; 27/11/2024 + mov [volume], al + ; 15/11/2024 + call SetMasterVolume + call UpdateVolume + ;;; + + ;;; + ; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 30/05/2024 + ; playwav4.asm +_2: + call check4keyboardstop ; flush keyboard buffer + jc short _2 ; 07/11/2023 + +; play the .wav file. Most of the good stuff is in here. + + call PlayWav + +Exit@@: + ; 27/11/2024 + ; 24/11/2024 + ; restore old interrupt vector + mov al, [IRQnum] + xor ah, ah ; reset + call set_hardware_int_vector + +; close the .wav file and exit. + +Exit: + ; 15/11/2024 + ;; Restore Cursor Type + mov cx, [cursortype] + cmp cx, 0 + jz short Exit@ + mov ah, 01h + int 10h +Exit@: + call closeFile + + mov ax, 4C00h ; bye ! + int 21h +here: + jmp short here ; do not come here ! + + ; 30/05/2024 +pmsg_usage: + sys_msg msg_usage, 0Fh ; 14/11/2024 + jmp short Exit + + ; 30/05/2024 +init_err: + sys_msg msg_init_err, 0Fh + jmp short Exit + + ; -------------------------------------------- + + ; 24/11/2024 +PlayWav: + mov ax, wav_buffer1 + call loadFromFile + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + mov ax, wav_buffer2 + call loadFromFile + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; 25/11/2024 + call SB16Init_play ; initialize SB16 card + ; set sample rate, start to play + jc init_err + + ; 19/11/2024 + mov byte [wleds], 1 + + mov ax, [WAVE_SampleRate] + mov cx, 10 + mul cx + mov cl, 182 + div cx + ; ax = samples per 1/18.2 second + mov cl, byte [WAVE_BlockAlign] + mul cx + mov [wleds_dif], ax ; buffer read differential (distance) + ; for wave volume leds update + ; (byte stream per 1/18.2 second) + ; 27/11/2024 + ; set audio interrupt vector (to user's handler) + mov al, [IRQnum] + mov ah, 1 ; set + mov dx, IRQ_service + call set_hardware_int_vector + + ; 26/11/2024 + call check4keyboardstop + jc _exitt_ + + ; 27/11/2024 + mov byte [IRQnum], 0 + + ; 27/11/2024 + ; 24/11/2024 +TuneLoop: + ; 30/05/2024 + ; 18/11/2023 (ich_wav4.asm) + ; 08/11/2023 + ; 06/11/2023 +tLWait: + ; 18/11/2024 + cmp byte [stopped], 0 + ; 24/11/2024 + jna short tL1 +tLWait@: ; 21/11/2024 + call checkUpdateEvents + jc _exitt_ + cmp byte [tLO], '0' + je short tLWait + call tLZ + mov byte [tLO], '0' + jmp short tLWait +tL1: + ; 27/11/2024 + ; Check SB 16 interrupt status + cmp byte [IRQnum], 0 + ja short tL3 +tL2: + call checkUpdateEvents + jc _exitt_ + jmp short tLWait +tL3: + xor byte [half_buffer], 1 + + mov byte [IRQnum], 0 + + ; load buffer 1 + ;mov ax, wav_buffer1 + mov ax, dma_buffer ; wav_buffer1 + cmp byte [half_buffer], 0 + jna short tL4 + + ; load buffer 2 + ;mov ax, wav_buffer2 + add ax, LOADSIZE ; dma_buffer_size/2 +tL4: + call loadFromFile + jc short _exitt_ ; end of file + + ; 26/11/2024 + mov al, [half_buffer] + add al, '1' + ; 19/11/2024 + mov [tLO], al + call tL0 + ; 24/11/2024 + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; 27/11/2024 + jmp short tL2 + +_exitt_: + ; 24/11/2024 + call sb16_stop + + ;;; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 18/11/2024 +tLZ: + ; 30/05/2024 + mov al, '0' + + ; 06/11/2023 +tL0: + ; 08/11/2023 + ; 05/11/2023 + ; 17/02/2017 - Buffer switch test (temporary) + ; 06/11/2023 + ; al = buffer indicator ('1', '2' or '0' -stop- ) + + push ds + ;push bx + mov bx, 0B800h ; video display page segment + mov ds, bx + sub bx, bx ; 0 + mov ah, 4Eh + mov [bx], ax ; show current play buffer (1, 2) + ;pop bx + pop ds + + retn + +; ------------------------------------------- + +; 27/11/2024 +; ; 24/11/2024 +;IRQ_ack: +; ; 26/11/2024 +; push dx +; push ax +; mov dx, [audio_io_base] +; ;add dx, 0Eh +; add dl, 0Eh ; 8bit DMA-mode int ack +; ; 25/11/2024 +; cmp byte [WAVE_BitsPerSample], 8 +; jna short irq_ack_@ +; inc dl ; 0Fh ; 16bit DMA-mode int ack +;irq_ack_@: +; in al, dx ; SB acknowledge. +; ; 27/11/2024 +; ;mov al, 20h +; ;out 20h, al ; Hardware acknowledge. +;irq_ack_ok: +; ; 26/11/2024 +; pop ax +; pop dx +; retn + +; ------------------------------------------- + + ; 24/11/2024 +SetMasterVolume: + ; al = sound volume (15 = max, 0 = min) + push ax + ; Tell the SB 16 card which register to write + mov dx, [audio_io_base] + ;add dx, 4 ; Mixer chip address port + add dl, 4 + mov al, 22h + out dx, al + pop ax + ;and al, 0Fh + ; Set the volume for both L and R + mov bl, 11h + mul bl + ; Set new volume + mov dx, [audio_io_base] + ;add dx, 5 + add dl, 5 + out dx, al + retn + +; ------------------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; DetectSB procedure (06/08/2022, v2.0.5) +DetectSB16: + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 24/04/2017 +ScanPort: + mov bx, 0210h ; start scanning ports + ; 210h, 220h, .. 260h +ResetDSP: + ; 26/11/2024 + mov dx, bx ; try to reset the DSP. + add dl, 06h + + mov al, 1 + out dx, al + + in al, dx + in al, dx + in al, dx + in al, dx + + xor al, al + out dx, al + + ;add dx, 08h + add dl, 08h + mov cx, 100 +WaitID: + in al, dx + or al, al + js short GetID + loop WaitID + jmp short NextPort +GetID: + ;sub dx, 04h + sub dl, 04h + in al, dx + cmp al, 0AAh + je short Found + ;add dx, 04h + add dl, 04h + loop WaitID +NextPort: + ;add bx, 10h ; if not response, + add bl, 10h + ;cmp bx, 260h ; try the next port. + cmp bl, 60h + jbe short ResetDSP + stc + retn +Found: + mov [audio_io_base], bx ; SB Port Address Found! +ScanIRQ: +SetIrqs: + sub al, al ; 0 + mov [IRQnum], al ; reset + ; 27/11/2024 + ;mov [audio_intr], al + + ; 25/11/2024 + ; save IRQ status + in al, 21h ; save the IMR. + mov [IRQstatus], al + + ; ah > 0 -> set IRQ vector + ; al = IRQ number + mov ax, 105h ; IRQ 5 + ; 26/11/2024 + mov dx, IRQ5_service + call set_hardware_int_vector + mov ax, 107h ; IRQ 7 + ; 26/11/2024 + mov dx, IRQ7_service + call set_hardware_int_vector + + mov dx, [audio_io_base] ; tells to the SB to + ;add dx, 0Ch ; generate a IRQ! + add dl, 0Ch +WaitSb: + in al, dx + or al, al + js short WaitSb + mov al, 0F2h + out dx, al + ; 24/11/2024 + xor cx, cx ; wait until IRQ level +WaitIRQ: + mov al, [IRQnum] + cmp al, 0 ; is changed or timeout. + ja short IrqOk + dec cx + jnz short WaitIRQ + jmp short RestoreIrqs +IrqOk: + ;;; + ; 27/11/2024 + mov [audio_intr], al + mov dx, [audio_io_base] + ;add dx, 0Eh + add dl, 0Eh ; 8bit DMA-mode int ack + in al, dx ; SB acknowledge. + inc dx ; 0Fh ; 16bit DMA-mode int ack + in al, dx ; SB 16 acknowledge. + ;;; + mov al, 20h + out 20h, al ; Hardware acknowledge. +RestoreIrqs: + ; ah = 0 -> reset IRQ vector + ; al = IRQ number + mov ax, 5 ; IRQ 5 + call set_hardware_int_vector + mov ax, 7 ; IRQ 7 + call set_hardware_int_vector + + cmp byte [IRQnum], 1 ; IRQ level was changed? + + retn + +; ---------------------------------- + + ; 24/11/2024 +set_hardware_int_vector: + or ah, ah + jnz short shintv_1 ; set user's audio interrupt handler + +rhintv_1: + ; reset the interrupt vector to the old interrupt handler + push ds + cmp al, 5 + jne short rhintv_2 + + ; 25/11/2024 + ; restore IRQ 5 status + mov ah, [IRQstatus] + in al, 21h + and ah, 00100000b ; 20h + or al, ah + out 21h, al + + mov dx, [old_irq5v_o] + mov ds, [old_irq5v_s] +shintv_3: + mov al, 0Dh + mov ah, 25h + int 21h + pop ds + retn + +rhintv_2: + ; 25/11/2024 + ; restore IRQ 7 status + mov ah, [IRQstatus] + in al, 21h + and ah, 10000000b ; 80h + or al, ah + out 21h, al + + mov dx, [old_irq7v_o] + mov ds, [old_irq7v_s] +shintv_4: + mov al, 0Fh + mov ah, 25h + int 21h + pop ds + retn + +shintv_1: + push es + + cmp al, 5 + jne short shintv_2 + + ; INT 0Dh = IRQ 5 (default) interrupt number + + ; 25/11/2024 + ; enable IRQ 5 + ; 26/11/2024 + in al, 21h + and al, 11011111b + out 21h, al + + mov al, 0Fh + mov ah, 35h ; Get Interrupt Vector + int 21h + mov [old_irq5v_s], es + mov [old_irq5v_o], bx + pop es + push ds + ; 27/11/2024 + ;mov dx, IRQ5_service + jmp short shintv_3 + +shintv_2: + ; al = 7 + ; INT 0Fh = IRQ 7 (default) interrupt number + + ; 25/11/2024 + ; enable IRQ 7 + ; 26/11/2024 + in al, 21h + and al, 01111111b + out 21h, al + + mov al, 0Fh + mov ah, 35h ; Get Interrupt Vector + int 21h + mov [old_irq7v_s], es + mov [old_irq7v_o], bx + pop es + push ds + ; 27/11/2024 + ;mov dx, IRQ7_service + jmp short shintv_4 + +IRQ5_service: + mov byte [cs:IRQnum], 5 + iret + +IRQ7_service: + mov byte [cs:IRQnum], 7 + iret + + ; 27/11/2024 +IRQ_service: + push ds + push dx + push ax + ; + push cs + pop ds + mov byte [IRQnum], 5 + mov dx, [audio_io_base] + ;add dx, 0Eh + add dl, 0Eh ; 8bit DMA-mode int ack + cmp byte [WAVE_BitsPerSample], 8 + jna short irq_ack_@ + inc dl ; 0Fh ; 16bit DMA-mode int ack +irq_ack_@: + in al, dx ; SB acknowledge. + ; + mov al, 20h + out 20h, al ; Hardware acknowledge + ; + pop ax + pop dx + pop ds + iret + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_stop procedure (06/08/2022, v2.0.5) +sb16_stop: + mov dx, [audio_io_base] + ;add dx, 0Ch + add dl, 0Ch + + mov bl, 0D9h ; exit auto-initialize 16 bit transfer + ; stop autoinitialized DMA transfer mode + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb16_stop_1 + ;mov bl, 0DAh ; exit auto-initialize 8 bit transfer + inc bl +sb16_stop_1: + SbOut bl ; exit auto-initialize transfer command + + xor al, al ; stops all DMA processes on selected channel + + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb16_stop_2 + out 0Ch, al ; clear selected channel register + jmp short sb16_stop_3 + +sb16_stop_2: + out 0D8h, al ; clear selected channel register + +sb16_stop_3: + ; 24/11/2024 + mov byte [stopped], 2 ; stop ! +SbDone: + ;mov dx, [audio_io_base] + ;add dx, 0Ch + SbOut 0D0h + SbOut 0D3h +sb16_stop_4: + retn + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_pause procedure (06/08/2022, v2.0.5) +sb16_pause: + mov dx, [audio_io_base] + ;add dx, 0Ch ; Command & Data Port + add dl, 0Ch + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_pause_1 + ; 8 bit samples + mov bl, 0D0h ; 8 bit DMA mode + jmp short sb_pause_2 +sb_pause_1: + ; 16 bit samples + mov bl, 0D5h ; 16 bit DMA mode +sb_pause_2: + SbOut bl ; bCommand +sb_pause_3: + retn + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_continue procedure (06/08/2022, v2.0.5) +sb16_play: +sb16_continue: + mov dx, [audio_io_base] + ;add dx, 0Ch ; Command & Data Port + add dl, 0Ch + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_cont_1 + ; 8 bit samples + mov bl, 0D4h ; 8 bit DMA mode + jmp short sb_cont_2 +sb_cont_1: + ; 16 bit samples + mov bl, 0D6h ; 16 bit DMA mode +sb_cont_2: + SbOut bl ; bCommand +sb_cont_3: + retn + +; ---------------------------------- + + ; 14/11/2024 + ; INPUT: ds:dx = file name address + ; OUTPUT: [filehandle] = ; -1 = not open +openFile: + mov ax, 3D00h ; open File for read + int 21h + jnc short _of1 + mov ax, -1 + ; cf = 1 -> not found or access error +_of1: + mov [filehandle], ax + retn + +; ---------------------------------- + +; close the currently open file + + ; 14/11/2024 + ; INPUT: [filehandle] ; -1 = not open + ; OUTPUT: none +closeFile: + cmp word [filehandle], -1 + jz short _cf1 + mov bx, [filehandle] + mov ax, 3E00h + int 21h ; close file +_cf1: + retn + +; ---------------------------------- + + ; 14/11/2024 - Erdogan Tan +getWAVParameters: +; reads WAV file header(s) (44 bytes) from the .wav file. +; entry: none - assumes file is already open +; exit: ax = sample rate (11025, 22050, 44100, 48000) +; cx = number of channels (mono=1, stereo=2) +; dx = bits per sample (8, 16) +; bx = number of bytes per sample (1 to 4) + + mov dx, WAVFILEHEADERbuff + mov bx, [filehandle] + mov cx, 44 ; 44 bytes + mov ah, 3Fh + int 21h + jc short gwavp_retn + + cmp ax, 44 + jb short gwavp_retn + + cmp dword [RIFF_Format], 'WAVE' + jne short gwavp_stc_retn + + cmp word [WAVE_AudioFormat], 1 ; Offset 20, must be 1 (= PCM) + ;jne short gwavp_stc_retn + je short gwavp_retn ; 15/11/2024 + + ; 15/11/2024 + ;mov cx, [WAVE_NumChannels] ; return num of channels in CX + ;mov ax, [WAVE_SampleRate] ; return sample rate in AX + ;mov dx, [WAVE_BitsPerSample] + ; return bits per sample value in DX + ;mov bx, [WAVE_BlockAlign] ; return bytes per sample in BX +;gwavp_retn: + ;retn + + ; 27/11/2024 + ; frequency limit (for SB16) = 44100 kHz + ;cmp word [WAVE_SampleRate], 44101 ; 48000 + ;cmc + ;retn + +gwavp_stc_retn: + stc +gwavp_retn: + retn + +; ---- 30/05/2024 (playwav4.asm, 19/05/2024) + +; MEMALLOC.ASM +;-- SETFREE: Release memory not used ---------------- +;-- Input : ES = address of PSP +;-- Output : none +;-- Register : AX, BX, CL and FLAGS are changed +;-- Info : Since the stack-segment is always the last segment in an +; EXE-file, ES:0000 points to the beginning and SS:SP +; to the end of the program in memory. Through this the +; length of the program can be calculated +; call this routine once at the beginning of the program to free up memory +; assigned to it by DOS. + +setFree: + mov bx, 65536/16 ; 4K paragraphs ; 17/02/2017 (Erdogan Tan) + + mov ah, 4Ah ; pass new length to DOS + int 21h + + retn ; back to caller + ; new size (allocated memory) = 64KB + + ; 27/11/2024 +;memAlloc: +;; input: AX = # of paragraphs required +;; output: AX = segment of block to use +; +; push bx +; mov bx, ax +; mov ah, 48h +; int 21h +; pop bx +; retn + +; ---- + +; ///// + + ; 24/11/2024 (SB16 version of playwav8.asm -> playwav9.asm) + ; 30/05/2024 (ich_wav4.asm, 19/05/2024) +loadFromFile: + ; 18/12/2024 + mov word [count], 0 + + ; 07/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff_0 ; no + stc + retn + +lff_0: + ; 24/11/2024 + ; 08/11/2023 + mov di, ax ; save buffer address + ; 17/11/2024 + mov bx, [filehandle] + + ; 24/11/2024 + mov cx, LOADSIZE + mov dx, ax ; buffer address + + ; 24/11/2024 + ; load/read file + ; bx = file handle + ; ds = cs + ; ds:dx = buffer + ; cx = read count + mov ah, 3Fh + int 21h + jc short lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + + cmp ax, cx + je short endLFF + ; 24/11/2024 + ; di = buffer address + add di, ax +lff_3: + call padfill ; blank pad the remainder + ;clc ; don't exit with CY yet. + or byte [flags], ENDOFFILE ; end of file flag +endLFF: + retn +lff_4: + ; 08/11/2023 + mov al, '!' ; error + call tL0 + + xor ax, ax + jmp short lff_3 + +; entry ds:ax points to last byte in file +; cx = target size +; note: must do byte size fill +; destroys bx, cx +; +padfill: + ; 24/11/2024 + ; di = offset (to be filled with ZEROs) + ; es = ds = cs + ; ax = di = number of bytes loaded + ; cx = buffer size (> loaded bytes) + sub cx, ax + xor ax, ax + cmp byte [WAVE_BitsPerSample], 8 + ja short padfill@ + mov al, 80h +padfill@: + rep stosb + retn +; ///// + +write_audio_dev_info: + ; 30/05/2024 + sys_msg msgAudioCardInfo, 0Fh + retn + +write_sb16_dev_info: + ; 24/11/2024 + mov ax, [audio_io_base] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBasePort+2], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBasePort+1], al + mov bl, ah + mov dl, bl + ;and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBasePort], al + + xor ax, ax + ;mov al, [IRQnum] + ; 27/11/2024 + mov al, [audio_intr] + ;mov cl, 10 + ;div cl + ;add ah, 30h + ;mov [msgIRQ], ah + ; 25/11/2024 + add al, 30h + mov [msgIRQ], al + + call clear_window + mov dh, 13 + mov dl, 0 + call setCursorPosition + + sys_msg msgSB16Info, 07h + + retn + +; -------------------------------------------------------- +; 24/11/2024 - Sound Blaster 16 initialization +; -------------------------------------------------------- + + ; 25/11/2024 + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9, audio.s (06/06/2024) + ; SbInit_play procedure (06/08/2024, v2.0.5) +SB16Init_play: + mov ax, ds + mov dx, ax + shr dx, 12 + shl ax, 4 + add ax, dma_buffer + adc dx, 0 + mov bx, ax ; linear address + ; dx = page number + + mov cx, dma_buffer_size + + cmp byte [WAVE_BitsPerSample], 16 + jne short sbInit_0 ; set 8 bit DMA buffer + + ; 26/11/2024 + mov ax, dx ; page number + + ; convert byte count to word count + ; 26/11/2024 + ;dec cx + shr cx, 1 + dec cx ; word count - 1 + + ; convert byte offset to word offset + shr ax, 1 + rcr bx, 1 + ; 26/11/2024 + ;shr bx, 1 + + ; 16 bit DMA buffer setting (DMA channel 5) + mov al, 05h ; set mask bit for channel 5 (4+1) + out 0D4h, al + + xor al, al ; stops all DMA processes on selected channel + out 0D8h, al ; clear selected channel register + + mov al, bl ; byte 0 of DMA buffer offset in words (physical) + out 0C4h, al ; DMA channel 5 port number + + mov al, bh ; byte 1 of DMA buffer offset in words (physical) + out 0C4h, al + + ; 26/11/2024 + and dl, 0FEh ; clear bit 0 (not necessary, it will be ignored) + + mov al, dl ; byte 2 of DMA buffer address (physical) + out 8Bh, al ; page register port addr for channel 5 + + mov al, cl ; low byte of DMA count - 1 + out 0C6h, al ; count register port addr for channel 5 + + mov al, ch ; high byte of DMA count - 1 + out 0C6h, al + + ; channel 5, read, autoinitialized, single mode + mov al, 59h + out 0D6h, al ; DMA mode register port address + + mov al, 01h ; clear mask bit for channel 5 + out 0D4h, al ; DMA mask register port address + + jmp short ResetDsp + +sbInit_0: + dec cx ; byte count - 1 + + ; 8 bit DMA buffer setting (DMA channel 1) + mov al, 05h ; set mask bit for channel 1 (4+1) + out 0Ah, al ; DMA mask register + + xor al, al ; stops all DMA processes on selected channel + out 0Ch, al ; clear selected channel register + + mov al, bl ; byte 0 of DMA buffer address (physical) + out 02h, al ; DMA channel 1 port number + + mov al, bh ; byte 1 of DMA buffer address (physical) + out 02h, al + + mov al, dl ; byte 2 of DMA buffer address (physical) + out 83h, al ; page register port addr for channel 1 + + mov al, cl ; low byte of DMA count - 1 + out 03h, al ; count register port addr for channel 1 + + mov al, ch ; high byte of DMA count - 1 + out 03h, al + + ; channel 1, read, autoinitialized, single mode + mov al, 59h + out 0Bh, al ; DMA mode register port address + + mov al, 01h ; clear mask bit for channel 1 + out 0Ah, al ; DMA mask register port address + +ResetDsp: + mov dx, [audio_io_base] + ;add dx, 06h + add dl, 06h + mov al, 1 + out dx, al + + in al, dx + in al, dx + in al, dx + in al, dx + + xor ax, ax + out dx, al + + mov cx, 100 +WaitId: + mov dx, [audio_io_base] + add dl, 0Eh + in al, dx + or al, al + ;js short sb_GetId + ; 26/11/2024 + jns short sb_next + ;loop WaitId + ;jmp sb_Exit + +sb_GetId: + mov dx, [audio_io_base] + ;add dx, 0Ah + add dl, 0Ah + in al, dx + cmp al, 0AAh + je short SbOk +sb_next: + loop WaitId + stc + retn +SbOk: + mov dx, [audio_io_base] + ;add dx, 0Ch + add dl, 0Ch + SbOut 0D1h ; Turn on speaker + SbOut 41h ; 8 bit or 16 bit transfer + mov bx, [WAVE_SampleRate] ; sampling rate (Hz) + SbOut bh ; sampling rate high byte + SbOut bl ; sampling rate low byte + + ; 25/11/2024 + +StartDMA: + ; autoinitialized mode + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_play_1 + ; 8 bit samples + mov bx, 0C6h ; 8 bit output (0C6h) + cmp byte [WAVE_NumChannels], 2 ; 1 = mono, 2 = stereo + jb short sb_play_2 + mov bh, 20h ; 8 bit stereo (20h) + jmp short sb_play_2 +sb_play_1: + ; 16 bit samples + mov bx, 10B6h ; 16 bit output (0B6h) + cmp byte [WAVE_NumChannels], 2 ; 1 = mono, 2 = stereo + jb short sb_play_2 + add bh, 20h ; 16 bit stereo (30h) +sb_play_2: + ; PCM output (8/16 bit mono autoinitialized transfer) + SbOut bl ; bCommand + SbOut bh ; bMode + ; 25/11/2024 + mov bx, dma_buffer_size/2 + ; half buffer size + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit DMA + jne short sb_play_3 + shr bx, 1 ; byte count to word count (samples) +sb_play_3: + dec bx ; wBlkSize is one less than the actual size + SbOut bl + SbOut bh + + ; 24/11/2024 + ;mov byte [stopped], 0 ; playing ! +sb_Exit: + retn + +; -------------------------------------------------------- +; 14/11/2024 - Erdogan Tan +; -------------------------------------------------------- + + ; 24/11/2024 (SB16 version) +checkUpdateEvents: + call check4keyboardstop + jc short c4ue_ok + + ; 18/11/2024 + push ax ; * + or ax, ax + jz c4ue_cpt + + ; 18/11/2024 + cmp al, 20h ; SPACE (spacebar) ; pause/play + jne short ch4ue_chk_s + cmp byte [stopped], 0 + ja short ch4ue_chk_ps + ; pause + call sb16_pause ; 24/11/2024 + ; 27/11/2024 + mov byte [stopped], 1 + jmp c4ue_cpt +ch4ue_chk_ps: + cmp byte [stopped], 1 + ja short ch4ue_replay + ; continue to play (after a pause) + call sb16_play ; 24/11/2024 + ; 27/11/2024 + mov byte [stopped], 0 + jmp short c4ue_cpt +ch4ue_replay: + ; 19/11/2024 + pop ax ; * + pop ax ; return address + ; 24/11/2024 + ; initialize (again) + ; and start playing (after stop) + call SB16Init_play + mov al, [volume] + call SetMasterVolume ; 24/11/2024 + mov byte [stopped], 0 + ; 24/11/2024 + mov byte [half_buffer], 1 + call move_to_beginning + jmp PlayWav + +ch4ue_chk_s: + cmp al, 'S' ; stop + jne short ch4ue_chk_fb + cmp byte [stopped], 0 + ja short c4ue_cpt ; Already stopped/paused + call sb16_stop ; 24/11/2024 + ; 19/11/2024 + mov byte [tLO], 0 + jmp short c4ue_cpt + +ch4ue_chk_fb: + ; 17/11/2024 + cmp al, 'F' + jne short c4ue_chk_b + call Player_ProcessKey_Forwards + jmp short c4ue_cpt + + ; 18/11/2024 +c4ue_ok: + retn + +c4ue_chk_b: + cmp al, 'B' + ; 19/11/2024 + jne short c4ue_chk_h + call Player_ProcessKey_Backwards + jmp short c4ue_cpt +c4ue_chk_h: + ; 19/11/2024 + cmp al, 'H' + jne short c4ue_chk_cr + mov byte [wleds], 0 + call write_sb16_dev_info + mov dh, 24 + mov dl, 79 + call setCursorPosition +c4ue_chk_cr: + ; 19/11/2024 + cmp al, 0Dh ; ENTER/CR key + jne short c4ue_cpt + ; 23/11/2024 + xor bx, bx + mov bl, [wleds] + inc bl + and bl, 0Fh + jnz short c4ue_sc + inc bx +c4ue_sc: + mov [wleds], bl + shr bl, 1 + mov al, [bx+colors] + jnc short c4ue_sc_@ + or al, 10h ; blue (dark) background +c4ue_sc_@: + mov [ccolor], al + ;;; +c4ue_cpt: + ;push ds + ;mov bx, 40h + ;mov ds, bx + ;mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;;cli + ;mov ax, [bx] + ;mov dx, [bx+2] + ;;sti + ;pop ds + ; 26/11/2024 + call GetTimerTicks + + ; 18/11/2024 + pop cx ; * + cmp dx, [timerticks+2] + jne short c4ue_utt + cmp ax, [timerticks] + ; 18/11/2024 + je short c4ue_skip_utt +c4ue_utt: + mov [timerticks], ax + mov [timerticks+2], dx + jmp short c4ue_cpt_@ +c4ue_skip_utt: + ; 18/11/2024 + and cx, cx + jz short c4ue_ok +c4ue_cpt_@: + ; 18/11/2024 + cmp byte [stopped], 0 + ja short c4ue_ok + + call CalcProgressTime + + cmp ax, [ProgressTime] + ; 23/11/2024 + je short c4ue_uvb + ; same second, no need to update + + call UpdateProgressBar + + ; 23/11/2024 +c4ue_uvb: + cmp byte [wleds], 0 + jna short c4ue_vb_ok + + call UpdateWaveLeds + +c4ue_vb_ok: + retn + + ; 26/11/2024 +GetTimerTicks: + push ds + mov bx, 40h + mov ds, bx + mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;cli + mov ax, [bx] + mov dx, [bx+2] + ;sti + pop ds + retn + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ich_wav4.asm +; -------------------------------------------------------- + + ; 24/11/2024 (SB16 version) +check4keyboardstop: + ; 19/05/2024 + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + ;clc + jz short _cksr + + xor ah, ah + int 16h + + ;;; + ; 19/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + ; 24/11/2024 + cmp al, 15 + jnb short p_3 + inc al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_4 + + mov al, [volume] + ; 24/11/2024 + cmp al, 0 + jna short p_3 + dec al +p_2: + mov [volume], al + ; 24/11/2024 + call SetMasterVolume + ;call UpdateVolume + ;;clc + ;retn + jmp UpdateVolume +_cksr: + ; 18/11/2024 + xor ax, ax + ;clc +p_3: + retn +p_4: + ; 17/11/2024 + cmp ah, 01h ; ESC + je short p_q + cmp al, 03h ; CTRL+C + je short p_q + + ; 18/11/2024 + cmp al, 20h + je short p_r + + ; 19/11/2024 + cmp al, 0Dh ; CR/ENTER + je short p_r + + and al, 0DFh + cmp al, 'B' + je short p_r + cmp al, 'F' + je short p_r + cmp al, 'Q' + je short p_q + + clc + retn + + ;;; +;_cskr: +p_q: + stc +p_r: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 +setCursorPosition: + ; dh = Row + ; dl = Column + mov ax, 0500h + int 10h + mov ah, 02h + mov bh, 00h + ;mov dh, setCursorPosition_Row + ;mov dl, setCursorPosition_Column + int 10h + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; NAME: SetTotalTime +;; DESCRIPTION: Calculates the total time in seconds in file +;; INPUT: DATA_SubchunkSize, WAVE_SampleRate, WAVE_BlockAlign +;; OUTPUT: CurrentTotalTime=Total time in seconds in file, +;; Output on the screen of the total time in seconds + +SetTotalTime: + ;; Calculate total seconds in file + mov ax, [DATA_SubchunkSize] + mov dx, [DATA_SubchunkSize + 2] + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + + mov bx, [WAVE_BlockAlign] + + div bx + + mov [TotalTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 42 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 45 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + ;jmp short PrintNumber + +; -------------------------------------------------------- + +PrintNumber: + ; bp = digits + ; ax = binary number + mov bx, 10 + xor cx, cx +printNumber_CutNumber: + inc cx + xor dx, dx + div bx + push dx + cmp cx, bp + je short printNumber_printloop + jmp printNumber_CutNumber + +printNumber_printloop: + pop ax + mov dl, '0' + add dl, al + mov ah, 02h + int 21h + loop printNumber_printloop + + retn + +; -------------------------------------------------------- + + ; 14/11/2024 - Erdogan Tan +SetProgressTime: + ;; Calculate playing/progress seconds in file + call CalcProgressTime + +UpdateProgressTime: + ; ax = (new) progress time + + mov [ProgressTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 33 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 36 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + jmp short PrintNumber + +; -------------------------------------------------------- + + ; 17/11/2024 + ; 14/11/2024 +CalcProgressTime: + mov ax, [LoadedDataBytes] + mov dx, [LoadedDataBytes+2] + mov bx, ax + or bx, dx + jz short cpt_ok + + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + mov bx, [WAVE_BlockAlign] + div bx +cpt_ok: + ; ax = (new) progress time + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; DESCRIPTION: Update file information on template +;; PARAMS: WAVE parameters and other variables +;; REGS: AX(RW) +;; VARS: CurrentFileName, WAVE_SampleRate, +;; RETURNS: On-screen file info is updated. + +UpdateFileInfo: + ;; Print File Name + mov dh, 9 + mov dl, 23 + call setCursorPosition + + mov si, wav_file_name + + ;;; + ; 14/11/2024 + ; skip directory separators + ; (note: asciiz string, max. 79 bytes except zero tail) + mov bx, si +chk4_nxt_sep: + lodsb + cmp al, '\' + je short chg_fpos + and al, al + jz short chg_fpos_ok + jmp short chk4_nxt_sep +chg_fpos: + mov bx, si + jmp short chk4_nxt_sep +chg_fpos_ok: + mov si, bx ; file name (without its path/directory) + ;;; + + call PrintString + + ;; Print Frequency + mov dh, 10 + mov dl, 23 + call setCursorPosition + mov ax, [WAVE_SampleRate] + mov bp, 5 + call PrintNumber + + ;; Print BitRate + mov dh, 9 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_BitsPerSample] + mov bp, 2 + call PrintNumber + + ;; Print Channel Number + mov dh, 10 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_NumChannels] + mov bp, 1 + call PrintNumber + + ;call UpdateVolume + ;retn + +; -------------------------------------------------------- + + ; 24/11/2024 + ; 14/11/2024 +UpdateVolume: + ;; Print Volume + mov dh, 24 + mov dl, 75 + call setCursorPosition + + mov al, [volume] + + mov bl, 100 + mul bl + + mov bl, 15 ; 24/11/2024 + div bl + + xor ah, ah + mov bp, 3 + ;call PrintNumber + ;retn + jmp PrintNumber + +; 24/11/2024 +; 29/05/2024 +; 19/05/2024 +volume: db 12 + +; -------------------------------------------------------- + + ; 14/11/2024 +PrintString: + ; si = string address + mov bx, 0Fh ; white + mov ah, 0Eh ; write as tty +printstr_loop: + lodsb + or al, al + jz short printstr_ok + int 10h + jmp short printstr_loop +printstr_ok: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 + ; (Ref: player.asm , Matan Alfasi, 2017) + ; (Modification: Erdogan Tan, 14/11/2024) + + PROGRESSBAR_ROW equ 23 + +UpdateProgressBar: + call SetProgressTime ; 14/11/2024 + + mov ax, [ProgressTime] +UpdateProgressBar@: + mov dx, 80 + mul dx + mov bx, [TotalTime] + div bx + + ;; Push for the 'Clean' part + push ax ; ** + push ax ; * + + ;; Set cursor position + mov dh, PROGRESSBAR_ROW + mov dl, 0 + call setCursorPosition + + pop ax ; * + or ax, ax + jz short UpdateProgressBar_Clean + +UpdateProgressBar_DrawProgress: + mov cx, ax + mov ah, 09h + mov al, 223 + mov bx, 0Fh + int 10h + +UpdateProgressBar_DrawCursor: + ;mov ax, cx + mov dh, PROGRESSBAR_ROW + ;mov dl, al + dec cx + mov dl, cl + call setCursorPosition + + mov ah, 09h + mov al, 223 + mov bx, 0Ch + mov cx, 1 + int 10h + +UpdateProgressBar_Clean: + pop ax ; ** + mov cx, ax + mov dh, PROGRESSBAR_ROW + mov dl, al + call setCursorPosition + + neg cx + add cx, 80 ; cf = 1 ; + + ;; CX = No. of times to print a clean character + ;mov cx, 80 + ;sub cx, ax + ;; 09h = Write character multiple times + mov ah, 09h + ;; 32 = Space ASCII code + ;mov al, 32 + ;mov bx, 0 + ; 15/11/2024 + mov al, 223 + mov bx, 8 + int 10h + ; 14/11/2024 + clc ; + + + retn + +; -------------------------------------------------------- +; 17/11/2024 + +Player_ProcessKey_Backwards: + ;; In order to go backwards 5 seconds: + ;; Update file pointer to the beginning, skip headers + mov cl, 'B' + jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_Forwards: + ;; In order to fast-forward 5 seconds, set the file pointer + ;; to CUR_SEEK + 5 * Freq + + mov cl, 'F' + ;jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_B_or_F: + ; 17/11/2024 + ; 04/11/2024 + ; (Ref: player.asm, Matan Alfasi, 2017) + + ; 04/11/2024 + mov ax, 5 + mov bx, [WAVE_BlockAlign] + mul bx + mov bx, [WAVE_SampleRate] + mul bx + ; dx:ax = transfer byte count for 5 seconds + + ; 17/11/2024 + cmp cl, 'B' + mov bx, [LoadedDataBytes] + mov cx, [LoadedDataBytes+2] + jne short move_forward ; cl = 'F' +move_backward: + sub bx, ax + sbb cx, dx + jnc short move_file_pointer +move_to_beginning: + xor cx, cx ; 0 + xor bx, bx ; 0 + jmp short move_file_pointer +move_forward: + add bx, ax + adc cx, dx + jc short move_to_end + cmp cx, [DATA_SubchunkSize+2] + ja short move_to_end + jb short move_file_pointer + cmp bx, [DATA_SubchunkSize] + jna short move_file_pointer +move_to_end: + mov bx, [DATA_SubchunkSize] + mov cx, [DATA_SubchunkSize+2] +move_file_pointer: + mov dx, bx + mov [LoadedDataBytes], dx + mov [LoadedDataBytes+2], cx + add dx, 44 ; + header + adc cx, 0 + + ; seek + mov bx, [filehandle] + mov ax, 4200h + int 21h + + retn + +; -------------------------------------------------------- + + ; 19/11/2024 +UpdateWaveLeds: + ; 23/11/2024 + call reset_wave_leds + ;call word [turn_on_leds] + ;retn + jmp word [turn_on_leds] + +; -------------------------------------------------------- + + ; 23/11/2024 + ; 19/11/2024 +clear_window: + xor ax, ax + jmp short clear_window_@ + +reset_wave_leds: + ; 23/11/2024 + ;mov al, 254 + ;mov ah, 8 ; gray (dark) + mov ax, 08FEh +clear_window_@: + push es + mov di, 0B800h + mov es, di + mov di, 2080 ; 13*80*2 + mov cx, 8*80 ; 8 rows + rep stosw + pop es + retn + +; -------------------------------------------------------- + + ; 24/11/2024 + ; 19/11/2024 +turn_on_leds_stereo_16bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol_buffer_1 + +tol_buffer_2: + ; 21/11/2024 + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol_@ + +tol_buffer_1: + cmp byte [tLO],'1' + ;jne short tol_retn + ; 23/11/2024 + jne short tol_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol_o_@ + cmp si, cx + jna short tol_s_buf +tol_o_@: + mov si, cx + jmp short tol_s_buf + +tol_clc_retn: + ; 23/11/2024 + clc +tol_retn: + ; 25/11/2024 + pop es + retn + +tol_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol_s_buf: + mov [pbuf_o], si + +tol_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + ;mov di, (20*80*2)-2 + + ; 23/11/2024 + mov cx, 80 + + ; 22/11/2024 + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol_fill_c: + ; 22/11/2024 + ;inc di + ;inc di + ;push di + lodsw ; left + ;shr ax, 8 + mov dx, ax + lodsw ; right + ;shr ax, 8 + ;;; + ; 23/11/2024 + add ax, dx + shr ax, 8 + ;shr ax, 9 + add al, 80h + shr ax, 5 + ;;; + ;shr ax, 6 + + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + ; 23/11/2024 + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol_fill_c + + jmp short tol_retn + + + ; 24/11/2024 + ; 23/11/2024 +turn_on_leds_mono_16bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol2_buffer_1 + +tol2_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol2_@ + +tol2_buffer_1: + cmp byte [tLO],'1' + jne short tol_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol2_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol2_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol2_o_@ + cmp si, cx + jna short tol2_s_buf +tol2_o_@: + mov si, cx + jmp short tol2_s_buf + +;tol2_clc_retn: +; clc +;tol2_retn: +; ; 25/11/2024 +; pop es +; retn + +tol2_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol2_s_buf: + mov [pbuf_o], si + +tol2_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol2_fill_c: + lodsw + shr ax, 8 + add al, 80h + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol2_fill_c + + jmp tol_retn + + ; 24/11/2024 +turn_on_leds_stereo_8bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol3_buffer_1 + +tol3_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol3_@ + +tol3_buffer_1: + cmp byte [tLO],'1' + jne short tol3_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol3_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol3_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol3_o_@ + cmp si, cx + jna short tol3_s_buf +tol3_o_@: + mov si, cx + jmp short tol3_s_buf + +tol3_clc_retn: + clc +tol3_retn: + ; 25/11/2024 + pop es + retn + +tol3_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol3_s_buf: + mov [pbuf_o], si + +tol3_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol3_fill_c: + lodsw ; left (al), right (ah) + add al, ah + add al, 80h + xor ah, ah + ;shr ax, 6 + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol3_fill_c + + jmp short tol3_retn + + ; 24/11/2024 + ; 23/11/2024 +turn_on_leds_mono_8bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol4_buffer_1 + +tol4_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol4_@ + +tol4_buffer_1: + cmp byte [tLO],'1' + jne short tol3_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol4_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol4_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol4_o_@ + cmp si, cx + jna short tol4_s_buf +tol4_o_@: + mov si, cx + jmp short tol4_s_buf + +;tol4_clc_retn: +; clc +;tol4_retn: +; ; 25/11/2024 +; pop es +; retn + +tol4_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol4_s_buf: + mov [pbuf_o], si + +tol4_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol4_fill_c: + lodsb + ; 27/11/2024 + add ax, ax + add al, 80h + xor ah, ah + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol4_fill_c + + jmp tol3_retn + +; -------------------------------------------------------- + +; 30/05/2024 +print_msg: + mov bx, 07h +p_msg: + push es + push bp + push cx + push dx + + push ds + pop es + mov bp, si + mov ah, 03h ; Return cursor position (in DX) + ; bh = video page number + int 10h + xor cx, cx +p_msg_0: + lodsb + or al, al + jz short p_msg_1 + inc cx + jmp short p_msg_0 +p_msg_1: + or cx, cx + jz short p_msg_x + ; cx = number of chars + ; dx = screen (cursor) position + ; bl = color/attribute + ; bh = video page number + ; es:bp = string buffer + ;mov al, 1 ; attribute in BL, update cursor pos + ;mov ah, 13h ; write character string + mov ax, 1301h + int 10h +p_msg_x: + pop dx + pop cx + pop bp + pop es + retn + +; -------------------------------------------------------- +; -------------------------------------------------------- + +; DATA + +Credits: + db 'Tiny WAV Player for Retro DOS by Erdogan Tan. ' + db 'December 2024.',10,13,0 + db '18/12/2024', 10,13,0 + +msgAudioCardInfo: + db 'for Sound Blaster 16 audio device.', 10,13,0 + +msg_usage: + db 'usage: playwav9 filename.wav',10,13,0 ; 24/11/2024 + + ; 24/11/2024 +noDevMsg: + db 'Error: Unable to find Sound Blaster 16 audio device!' + db 10,13,0 + +noFileErrMsg: + db 'Error: file not found.',10,13,0 + +msg_error: ; 30/05/2024 + +; 24/11/2024 +msg_init_err: + db 0Dh, 0Ah + db "Sound Blaster 16 hardware initialization error !" + db 0Dh, 0Ah, 0 ; 07/12/2024 + +; 19/11/2024 +; 03/06/2017 +hex_chars: db "0123456789ABCDEF", 0 + +; 24/11/2024 +msgSB16Info: db 0Dh, 0Ah + db " Audio Hardware: Sound Blaster 16", 0Dh, 0Ah + db " Base Port: " +msgBasePort: db "000h", 0Dh, 0Ah + db " IRQ: " +msgIRQ: db 30h + db 0Dh, 0Ah, 0 + +; -------------------------------------------------------- +; 14/11/2024 (Ref: player.asm, Matan Alfasi, 2017) + +SplashScreen: + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " _______ ______ _______. ", 221, 219, 222 + db 221, 219, 222, " | \ / __ \ / | ", 221, 219, 222 + db 221, 219, 222, " | .--. | | | | | (----` ", 221, 219, 222 + db 221, 219, 222, " | | | | | | | \ \ ", 221, 219, 222 + db 221, 219, 222, " | '--' | `--' | .----) | ", 221, 219, 222 + db 221, 219, 222, " |_______/ \______/ |_______/ ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " .______ __ ___ ____ ____ _______ .______ ", 221, 219, 222 + db 221, 219, 222, " | _ \ | | / \ \ \ / / | ____|| _ \ ", 221, 219, 222 + db 221, 219, 222, " | |_) | | | / ^ \ \ \/ / | |__ | |_) | ", 221, 219, 222 + db 221, 219, 222, " | ___/ | | / /_\ \ \_ _/ | __| | / ", 221, 219, 222 + db 221, 219, 222, " | | | `----./ _____ \ | | | |____ | |\ \----. ", 221, 219, 222 + db 221, 219, 222, " | _| |_______/__/ \__\ |__| |_______|| _| `._____| ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " WELCOME TO ", 221, 219, 222 + db 221, 219, 222, " DOS PLAYER ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db " " +Template: + db 201, 78 dup(205), 187 + db 186, 33 dup(219), " DOS Player ", 33 dup(219), 186 + db 204, 78 dup(205), 185 + db 186, 33 dup(32), " User Guide ", 33 dup(32), 186 + db 186, 6 dup(32), " Play/Pause ", 4 dup(32), " Hardware Info", 9 dup(32), 186 + db 186, 6 dup(32), " Stop ", 4 dup(32), " Wave Lighting", 9 dup(32), 186 + db 186, 6 dup(32), " Forwards ", 4 dup(32), "<+>/<-> Inc/Dec Volume", 8 dup(32), 186 + db 186, 6 dup(32), " Backwards ", 4 dup(32), " Quit Program ", 9 dup(32), 186 + db 204, 78 dup(205), 185 + db 186, 6 dup(32), "File Name : ", 4 dup(32), "Bit-Rate : 0 Bits ", 9 dup(32), 186 + db 186, 6 dup(32), "Frequency : 0 Hz ", 4 dup(32), "#-Channels: 0 ", 9 dup(32), 186 + db 200, 78 dup(205), 188 + db 80 dup(32) +improper_samplerate_txt: ; 03/11/2024 +read_error_txt: + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(205) + db 80 dup(32) + db 33 dup(32), "00:00 ", 174, 175, " 00:00", 24 dup(32), "VOL 000%" + +; 23/11/2024 +colors: db 0Fh, 0Bh, 0Ah, 0Ch, 0Eh, 09h, 0Dh, 0Fh + ; white, cyan, green, red, yellow, blue, magenta +ccolor: db 0Bh ; cyan + +; 24/11/2024 +half_buffer: db 1 ; dma half buffer 1 or 2 (0 or 1) + ; (initial value = 1 -> after xor in TuneLoop -> 0) +EOF: + +; BSS + +align 2 + +; 24/11/2024 +; 22/11/2024 +; wave volume leds address array +wleds_addr: rw 80*8 ; rb 2*80*8 + +; 24/11/2024 (SB16 version of playwav8.com -> playwav9.com) +; 14/11/2024 +; 17/02/2017 +bss_start: + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +; 24/11/2024 +old_irq5v_o: rw 1 +old_irq5v_s: rw 1 +old_irq7v_o: rw 1 +old_irq7v_s: rw 1 +; +IRQnum: rb 1 +; 27/11/2024 +audio_intr: rb 1 +; 25/11/2024 +IRQstatus: rb 1 + +; 18/11/2024 +stopped: rb 1 +tLO: rb 1 +; 19/11/2024 +wleds: rb 1 +wleds_dif: rw 1 +pbuf_s: rw 1 +pbuf_o: rw 1 + +; 25/11/2024 +align 4 + +;;;;;;;;;;;;;; +; 14/11/2024 +; (Ref: player.asm, Matan Alfasi, 2017) +WAVFILEHEADERbuff: +RIFF_ChunkID: rd 1 ; Must be equal to "RIFF" - big-endian + ; 0x52494646 +RIFF_ChunkSize: + rd 1 ; Represents total file size, not + ; including the first 2 fields + ; (Total_File_Size - 8), little-endian +RIFF_Format: + rd 1 ; Must be equal to "WAVE" - big-endian + ; 0x57415645 + +;; WAVE header parameters ("Sub-chunk") +WAVE_SubchunkID: + rd 1 ; Must be equal to "fmt " - big-endian + ; 0x666d7420 +WAVE_SubchunkSize: + rd 1 ; Represents total chunk size +WAVE_AudioFormat: + rw 1 ; PCM (Raw) - is 1, other - is a form + ; of compression, not supported. +WAVE_NumChannels: + rw 1 ; Number of channels, Mono-1, Stereo-2 +WAVE_SampleRate: + rd 1 ; Frequency rate, in Hz (8000, 44100 ...) +WAVE_ByteRate: rd 1 ; SampleRate * NumChannels * BytesPerSample +WAVE_BlockAlign: + rw 1 ; NumChannels * BytesPerSample + ; Number of bytes for one sample. +WAVE_BitsPerSample: + rw 1 ; 8 = 8 bits, 16 = 16 bits, etc. + +;; DATA header parameters +DATA_SubchunkID: + rd 1 ; Must be equal to "data" - big-endian + ; 0x64617461 +DATA_SubchunkSize: + rd 1 ; NumSamples * NumChannels * BytesPerSample + ; Number of bytes in the data. +;;;;;;;;;;;;;; + +; 15/11/2024 +cursortype: rw 1 + +filehandle: rw 1 + +flags: rb 1 ; (END_OF_FILE flag) + rb 1 + +audio_io_base: rw 1 ; Sound Blaster 16 base port address (220h) + +; 30/05/2024 +wav_file_name: + rb 80 ; wave file, path name (<= 80 bytes) + + rw 1 +; 24/11/2024 +align 4 + +; 23/11/2024 +turn_on_leds: rw 1 ; turn_on_leds procedure pointer (m8,m16,s8,s16) + +; 14/11/2024 +TotalTime: rw 1 ; Total (WAV File) Playing Time in seconds +ProgressTime: rw 1 +count: rw 1 ; byte count of one (wav file) read +LoadedDataBytes: + rd 1 ; total read/load count + +timerticks: rd 1 ; (to eliminate excessive lookup of events in TuneLoop) + ; (in order to get the emulator/qemu to run correctly) +align 16 + +; 24/11/2024 +dma_buffer: ; 32768 bytes +wav_buffer1: rb dma_buffer_size/2 ; 16384 +wav_buffer2: rb dma_buffer_size/2 ; 16384 + +bss_end: diff --git a/trdos386/programs/16bit/playwav9_com_sb16_2024.zip b/trdos386/programs/16bit/playwav9_com_sb16_2024.zip new file mode 100644 index 0000000..d17fb07 Binary files /dev/null and b/trdos386/programs/16bit/playwav9_com_sb16_2024.zip differ diff --git a/trdos386/programs/16bit/playwavx.asm b/trdos386/programs/16bit/playwavx.asm new file mode 100644 index 0000000..7f6b49a --- /dev/null +++ b/trdos386/programs/16bit/playwavx.asm @@ -0,0 +1,2628 @@ +; **************************************************************************** +; playwav9.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; PLAYWAV9.COM ! Sound Blaster 16 (DOS) .WAV PLAYER program by Erdogan TAN +; +; 24/11/2024 +; +; [ Last Modification: 18/12/2024 ] +; +; Modified from PLAYWAV8.COM .wav player program by Erdogan Tan, 23/11/2024 +; +; Assembler: FASM 1.73 +; fasm playwav9.asm PLAYWAV9.COM +; ---------------------------------------------------------------------------- +; In the visualization part of the code, the source code of Matan Alfasi's +; (Ami-Asaf) player.exe program was partially used. +; ---------------------------------------------------------------------------- +; Previous versions of this Wav Player were based in part on .wav file player +; (for DOS) source code written by Jeff Leyla in 2002. + +; playwav8.asm (23/11/2024) + +; TUNELOOP version ; 27/11/2024 +; (running in DOSBOX, VIRTUALBOX is ok, QEMU fails) +; ((checking SB16 interrupt status via mixer register 82h)) + +; CODE + + ; 13/11/2024 +macro sys_msg op1,op2 +{ ; 30/05/2024 + mov si, op1 ; message + mov bl, op2 ; text color + xor bh, bh ; video page 0 + mov ah, 0Eh + call p_msg +} + + ; 24/11/2024 +macro SbOut op1 +{ +local .wait +.wait: + in al, dx + or al, al + js short .wait + mov al, op1 ; command + out dx, al +} + +; player internal variables and other equates. +; 17/11/2024 +;BUFFERSIZE equ 65520 +; 24/11/2024 +;dma_buffer_size equ 32768 +;LOADSIZE equ 16384 +ENDOFFILE equ 1 ; flag for knowing end of file +; 27/11/2024 +dma_buffer_size equ 44100 +LOADSIZE equ 22050 + +use16 + +org 100h + +_STARTUP: + ; 30/05/2024 + ; Prints the Credits Text. + sys_msg Credits, 0Bh + + ; 30/05/2024 + call setFree ; deallocate unused DOS mem + + ; 17/02/2017 + ; Clear BSS (uninitialized data) area + xor ax, ax ; 0 + mov cx, (bss_end - bss_start)/2 + mov di, bss_start + rep stosw + + ; 24/11/2024 + ; Detect (& Reset) Sound Blaster 16 Audio Device + call DetectSB16 + jnc short GetFileName + + ; 30/05/2024 +_dev_not_ready: + ; couldn't find the audio device! + sys_msg noDevMsg, 0Fh + jmp Exit + + ; 30/05/2024 +GetFileName: + mov di, wav_file_name + mov si, 80h + mov bl, [si] + xor bh, bh + inc bx + mov byte [si+bx], 0 ; make AsciiZ filename. + inc si +ScanName: + lodsb + test al, al + jz pmsg_usage + cmp al, 20h + je short ScanName ; scan start of name. + stosb + mov ah, 0FFh + ;;; + ; 14/11/2024 + ; (max. path length = 64 bytes for MSDOS ?) (*) + xor cx, cx ; 0 + ;;; +a_0: + inc ah +a_1: + ;;; + ; 14/11/2024 + inc cx + ;;; + lodsb + stosb + cmp al, '.' + je short a_0 + and al, al + ;jnz short a_1 + ;;; + ; 14/11/2024 + jz short a_3 + and ah, ah + jz short a_2 + cmp al, '\' + jne short a_2 + mov ah, 0 +a_2: + cmp cl, 75 ; 64+8+'.'+3 -> offset 75 is the last chr + jb short a_1 +a_3: + ;;; + or ah, ah ; if period NOT found, + jnz short _1 ; then add a .WAV extension. +SetExt: + dec di + mov dword [di], '.WAV' ; ! 64+12 is DOS limit + ; but writing +4 must not + ; destroy the following data + mov byte [di+4], 0 ; so, 80 bytes path + 0 is possible here +_1: + call write_audio_dev_info + +; open the file + ; open existing file + ; 14/11/2024 + ;mov al, OPEN ; open existing file + mov dx, wav_file_name + call openFile ; no error? ok. + jnc short getwavparms ; 14/11/2024 + +; file not found! + sys_msg noFileErrMsg, 0Ch +_exit_: + jmp Exit + +getwavparms: + ; 14/11/2024 + call getWAVParameters + jc short _exit_ ; nothing to do + + ; 15/11/2024 + ;; Set video mode to 03h (not necessary) + mov ax, 03h + int 10h + + ; 15/11/2024 + ;; Get the cursor type + mov ah, 03h + int 10h + mov [cursortype], cx ; save + + ; 15/11/2024 + ;; Set the cursor to invisible + mov ah, 01h + mov cx, 2607h + int 10h + + ;;; 14/11/2024 +Player_SplashScreen: + ; 15/11/2024 + ;xor dx, dx + ;call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, SplashScreen + int 10h + ;;; + + ;;; + ; 22/11/2024 + ; set wave volume led addresses + mov bx, 13*80*2 + mov bp, 80 + mov di, wleds_addr +wleds_sa_1: + mov cx, 7 +wleds_sa_2: + mov ax, 80*2 + mul cx + add ax, bx + stosw + loop wleds_sa_2 + mov ax, bx + stosw + inc bx + inc bx + dec bp + jnz short wleds_sa_1 + ;;; + + ;;; + ; 23/11/2024 + cmp byte [WAVE_NumChannels], 1 + ja short stolp_s +stolp_m: + cmp byte [WAVE_BitsPerSample], 8 + ja short stolp_m16 +stolp_m8: + mov word [turn_on_leds], turn_on_leds_mono_8bit + jmp short stolp_ok +stolp_m16: + mov word [turn_on_leds], turn_on_leds_mono_16bit + jmp short stolp_ok +stolp_s: + cmp byte [WAVE_BitsPerSample], 8 + ja short stolp_s16 +stolp_s8: + mov word [turn_on_leds], turn_on_leds_stereo_8bit + jmp short stolp_ok +stolp_s16: + mov word [turn_on_leds], turn_on_leds_stereo_16bit + jmp short stolp_ok +stolp_ok: + ;;; + + ;;; wait for 3 seconds + ;mov cx, 002Dh + ;mov dx, 0C6C0h + ;mov ah, 86h + ;int 15h + ;;; + ; 26/11/2024 + mov cx, 3*18 +getticks: + ; 26/11/2024 + call GetTimerTicks + + cmp ax, [timerticks] + jne short chkws + cmp dx, [timerticks+2] + je short getticks +chkws: + mov [timerticks], ax + mov [timerticks+2], dx + loop getticks + ;;; + + ;;; +Player_Template: + xor dx, dx + call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, Template + int 10h + ;;; + + ; 14/11/2024 + call SetTotalTime + call UpdateFileInfo + +PlayNow: + ; 24/11/2024 + mov al, 5 ; 15 = max, 0 = min + ; 27/11/2024 + mov [volume], al + ; 15/11/2024 + call SetMasterVolume + call UpdateVolume + ;;; + + ;;; + ; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 30/05/2024 + ; playwav4.asm +_2: + call check4keyboardstop ; flush keyboard buffer + jc short _2 ; 07/11/2023 + +; play the .wav file. Most of the good stuff is in here. + + call PlayWav + +Exit@@: + ; 27/11/2024 + ; 24/11/2024 + ; restore old interrupt vector + ;mov al, [IRQnum] + ;xor ah, ah ; reset + ;call set_hardware_int_vector + +; close the .wav file and exit. + +Exit: + ; 15/11/2024 + ;; Restore Cursor Type + mov cx, [cursortype] + cmp cx, 0 + jz short Exit@ + mov ah, 01h + int 10h +Exit@: + call closeFile + + mov ax, 4C00h ; bye ! + int 21h +here: + jmp short here ; do not come here ! + + ; 30/05/2024 +pmsg_usage: + sys_msg msg_usage, 0Fh ; 14/11/2024 + jmp short Exit + + ; 30/05/2024 +init_err: + sys_msg msg_init_err, 0Fh + jmp short Exit + + ; -------------------------------------------- + + ; 24/11/2024 +PlayWav: + mov ax, wav_buffer1 + call loadFromFile + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + mov ax, wav_buffer2 + call loadFromFile + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; 25/11/2024 + call SB16Init_play ; initialize SB16 card + ; set sample rate, start to play + jc init_err + + ; 19/11/2024 + mov byte [wleds], 1 + + mov ax, [WAVE_SampleRate] + mov cx, 10 + mul cx + mov cl, 182 + div cx + ; ax = samples per 1/18.2 second + mov cl, byte [WAVE_BlockAlign] + mul cx + mov [wleds_dif], ax ; buffer read differential (distance) + ; for wave volume leds update + ; (byte stream per 1/18.2 second) + ; 27/11/2024 + ; set audio interrupt vector (to user's handler) + ;mov al, [IRQnum] + ;mov ah, 1 ; set + ;mov dx, IRQ_service + ;call set_hardware_int_vector + + ; 26/11/2024 + call check4keyboardstop + jc _exitt_ + + ;mov byte [IRQnum], 0 + + ; 27/11/2024 + ; 24/11/2024 +TuneLoop: + ; 30/05/2024 + ; 18/11/2023 (ich_wav4.asm) + ; 08/11/2023 + ; 06/11/2023 +tLWait: + ; 18/11/2024 + cmp byte [stopped], 0 + ; 24/11/2024 + jna short tL1 +tLWait@: ; 21/11/2024 + call checkUpdateEvents + jc _exitt_ + cmp byte [tLO], '0' + je short tLWait + call tLZ + mov byte [tLO], '0' + jmp short tLWait +tL1: + ; 27/11/2024 + ; Check SB 16 interrupt status + mov al, 82h + mov dx, [audio_io_base] + add dl, 4 ; 2x4h + out dx, al + inc dx ; 2x5h + in al, dx + + test al, 00000011b + jnz short tL3 +tL2: + call checkUpdateEvents + jc _exitt_ + jmp short tLWait +tL3: + ; 27/11/2024 + ;mov dx, [audio_io_base] + ;;add dx, 0Eh + ;add dl, 0Eh ; 8bit DMA-mode int ack + add dl, 0Eh-05h + in al, dx ; SB acknowledge. + inc dx ; 0Fh ; 16bit DMA-mode int ack + in al, dx ; SB 16 acknowledge. + + xor byte [half_buffer], 1 + + ; load buffer 1 + ;mov ax, wav_buffer1 + mov ax, dma_buffer ; wav_buffer1 + cmp byte [half_buffer], 0 + jna short tL4 + + ; load buffer 2 + ;mov ax, wav_buffer2 + add ax, LOADSIZE ; dma_buffer_size/2 +tL4: + call loadFromFile + jc short _exitt_ ; end of file + + ; 26/11/2024 + mov al, [half_buffer] + add al, '1' + ; 19/11/2024 + mov [tLO], al + call tL0 + ; 24/11/2024 + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; 27/11/2024 + jmp short tL2 + +_exitt_: + ; 24/11/2024 + call sb16_stop + + ;;; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 18/11/2024 +tLZ: + ; 30/05/2024 + mov al, '0' + + ; 06/11/2023 +tL0: + ; 08/11/2023 + ; 05/11/2023 + ; 17/02/2017 - Buffer switch test (temporary) + ; 06/11/2023 + ; al = buffer indicator ('1', '2' or '0' -stop- ) + + push ds + ;push bx + mov bx, 0B800h ; video display page segment + mov ds, bx + sub bx, bx ; 0 + mov ah, 4Eh + mov [bx], ax ; show current play buffer (1, 2) + ;pop bx + pop ds + + retn + +; ------------------------------------------- + +; 27/11/2024 +; ; 24/11/2024 +;IRQ_ack: +; ; 26/11/2024 +; push dx +; push ax +; mov dx, [audio_io_base] +; ;add dx, 0Eh +; add dl, 0Eh ; 8bit DMA-mode int ack +; ; 25/11/2024 +; cmp byte [WAVE_BitsPerSample], 8 +; jna short irq_ack_@ +; inc dl ; 0Fh ; 16bit DMA-mode int ack +;irq_ack_@: +; in al, dx ; SB acknowledge. +; ; 27/11/2024 +; ;mov al, 20h +; ;out 20h, al ; Hardware acknowledge. +;irq_ack_ok: +; ; 26/11/2024 +; pop ax +; pop dx +; retn + +; ------------------------------------------- + + ; 24/11/2024 +SetMasterVolume: + ; al = sound volume (15 = max, 0 = min) + push ax + ; Tell the SB 16 card which register to write + mov dx, [audio_io_base] + ;add dx, 4 ; Mixer chip address port + add dl, 4 + mov al, 22h + out dx, al + pop ax + ;and al, 0Fh + ; Set the volume for both L and R + mov bl, 11h + mul bl + ; Set new volume + mov dx, [audio_io_base] + ;add dx, 5 + add dl, 5 + out dx, al + retn + +; ------------------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; DetectSB procedure (06/08/2022, v2.0.5) +DetectSB16: + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 24/04/2017 +ScanPort: + mov bx, 0210h ; start scanning ports + ; 210h, 220h, .. 260h +ResetDSP: + ; 26/11/2024 + mov dx, bx ; try to reset the DSP. + add dl, 06h + + mov al, 1 + out dx, al + + in al, dx + in al, dx + in al, dx + in al, dx + + xor al, al + out dx, al + + ;add dx, 08h + add dl, 08h + mov cx, 100 +WaitID: + in al, dx + or al, al + js short GetID + loop WaitID + jmp short NextPort +GetID: + ;sub dx, 04h + sub dl, 04h + in al, dx + cmp al, 0AAh + je short Found + ;add dx, 04h + add dl, 04h + loop WaitID +NextPort: + ;add bx, 10h ; if not response, + add bl, 10h + ;cmp bx, 260h ; try the next port. + cmp bl, 60h + jbe short ResetDSP + stc + retn +Found: + mov [audio_io_base], bx ; SB Port Address Found! +ScanIRQ: +SetIrqs: + sub al, al ; 0 + mov [IRQnum], al ; reset + + ; 25/11/2024 + ; save IRQ status + in al, 21h ; save the IMR. + mov [IRQstatus], al + + ; ah > 0 -> set IRQ vector + ; al = IRQ number + mov ax, 105h ; IRQ 5 + ; 26/11/2024 + mov dx, IRQ5_service + call set_hardware_int_vector + mov ax, 107h ; IRQ 7 + ; 26/11/2024 + mov dx, IRQ7_service + call set_hardware_int_vector + + mov dx, [audio_io_base] ; tells to the SB to + ;add dx, 0Ch ; generate a IRQ! + add dl, 0Ch +WaitSb: + in al, dx + or al, al + js short WaitSb + mov al, 0F2h + out dx, al + ; 24/11/2024 + xor cx, cx ; wait until IRQ level +WaitIRQ: + mov al, [IRQnum] + cmp al, 0 ; is changed or timeout. + ja short IrqOk + dec cx + jnz short WaitIRQ + jmp short RestoreIrqs +IrqOk: + ;;; + ; 27/11/2024 + mov dx, [audio_io_base] + ;add dx, 0Eh + add dl, 0Eh ; 8bit DMA-mode int ack + in al, dx ; SB acknowledge. + inc dx ; 0Fh ; 16bit DMA-mode int ack + in al, dx ; SB 16 acknowledge. + ;;; + mov al, 20h + out 20h, al ; Hardware acknowledge. +RestoreIrqs: + ; ah = 0 -> reset IRQ vector + ; al = IRQ number + mov ax, 5 ; IRQ 5 + call set_hardware_int_vector + mov ax, 7 ; IRQ 7 + call set_hardware_int_vector + + cmp byte [IRQnum], 1 ; IRQ level was changed? + + retn + +; ---------------------------------- + + ; 24/11/2024 +set_hardware_int_vector: + or ah, ah + jnz short shintv_1 ; set user's audio interrupt handler + +rhintv_1: + ; reset the interrupt vector to the old interrupt handler + push ds + cmp al, 5 + jne short rhintv_2 + + ; 25/11/2024 + ; restore IRQ 5 status + mov ah, [IRQstatus] + in al, 21h + and ah, 00100000b ; 20h + or al, ah + out 21h, al + + mov dx, [old_irq5v_o] + mov ds, [old_irq5v_s] +shintv_3: + mov al, 0Dh + mov ah, 25h + int 21h + pop ds + retn + +rhintv_2: + ; 25/11/2024 + ; restore IRQ 7 status + mov ah, [IRQstatus] + in al, 21h + and ah, 10000000b ; 80h + or al, ah + out 21h, al + + mov dx, [old_irq7v_o] + mov ds, [old_irq7v_s] +shintv_4: + mov al, 0Fh + mov ah, 25h + int 21h + pop ds + retn + +shintv_1: + push es + + cmp al, 5 + jne short shintv_2 + + ; INT 0Dh = IRQ 5 (default) interrupt number + + ; 25/11/2024 + ; enable IRQ 5 + ; 26/11/2024 + in al, 21h + and al, 11011111b + out 21h, al + + mov al, 0Fh + mov ah, 35h ; Get Interrupt Vector + int 21h + mov [old_irq5v_s], es + mov [old_irq5v_o], bx + pop es + push ds + ; 27/11/2024 + ;mov dx, IRQ5_service + jmp short shintv_3 + +shintv_2: + ; al = 7 + ; INT 0Fh = IRQ 7 (default) interrupt number + + ; 25/11/2024 + ; enable IRQ 7 + ; 26/11/2024 + in al, 21h + and al, 01111111b + out 21h, al + + mov al, 0Fh + mov ah, 35h ; Get Interrupt Vector + int 21h + mov [old_irq7v_s], es + mov [old_irq7v_o], bx + pop es + push ds + ; 27/11/2024 + ;mov dx, IRQ7_service + jmp short shintv_4 + +IRQ5_service: + mov byte [cs:IRQnum], 5 + iret + +IRQ7_service: + mov byte [cs:IRQnum], 7 + iret + +; ; 27/11/2024 +;IRQ_service: +; push ds +; push dx +; push ax +; ; +; push cs +; pop ds +; mov byte [IRQnum], 5 +; mov dx, [audio_io_base] +; ;add dx, 0Eh +; add dl, 0Eh ; 8bit DMA-mode int ack +; cmp byte [WAVE_BitsPerSample], 8 +; jna short irq_ack_@ +; inc dl ; 0Fh ; 16bit DMA-mode int ack +;irq_ack_@: +; in al, dx ; SB acknowledge. +; ; +; mov al, 20h +; out 20h, al ; Hardware acknowledge +; ; +; pop ax +; pop dx +; pop ds +; iret + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_stop procedure (06/08/2022, v2.0.5) +sb16_stop: + mov dx, [audio_io_base] + ;add dx, 0Ch + add dl, 0Ch + + mov bl, 0D9h ; exit auto-initialize 16 bit transfer + ; stop autoinitialized DMA transfer mode + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb16_stop_1 + ;mov bl, 0DAh ; exit auto-initialize 8 bit transfer + inc bl +sb16_stop_1: + SbOut bl ; exit auto-initialize transfer command + + xor al, al ; stops all DMA processes on selected channel + + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb16_stop_2 + out 0Ch, al ; clear selected channel register + jmp short sb16_stop_3 + +sb16_stop_2: + out 0D8h, al ; clear selected channel register + +sb16_stop_3: + ; 24/11/2024 + mov byte [stopped], 2 ; stop ! +SbDone: + ;mov dx, [audio_io_base] + ;add dx, 0Ch + SbOut 0D0h + SbOut 0D3h +sb16_stop_4: + retn + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_pause procedure (06/08/2022, v2.0.5) +sb16_pause: + mov dx, [audio_io_base] + ;add dx, 0Ch ; Command & Data Port + add dl, 0Ch + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_pause_1 + ; 8 bit samples + mov bl, 0D0h ; 8 bit DMA mode + jmp short sb_pause_2 +sb_pause_1: + ; 16 bit samples + mov bl, 0D5h ; 16 bit DMA mode +sb_pause_2: + SbOut bl ; bCommand +sb_pause_3: + retn + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_continue procedure (06/08/2022, v2.0.5) +sb16_play: +sb16_continue: + mov dx, [audio_io_base] + ;add dx, 0Ch ; Command & Data Port + add dl, 0Ch + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_cont_1 + ; 8 bit samples + mov bl, 0D4h ; 8 bit DMA mode + jmp short sb_cont_2 +sb_cont_1: + ; 16 bit samples + mov bl, 0D6h ; 16 bit DMA mode +sb_cont_2: + SbOut bl ; bCommand +sb_cont_3: + retn + +; ---------------------------------- + + ; 14/11/2024 + ; INPUT: ds:dx = file name address + ; OUTPUT: [filehandle] = ; -1 = not open +openFile: + mov ax, 3D00h ; open File for read + int 21h + jnc short _of1 + mov ax, -1 + ; cf = 1 -> not found or access error +_of1: + mov [filehandle], ax + retn + +; ---------------------------------- + +; close the currently open file + + ; 14/11/2024 + ; INPUT: [filehandle] ; -1 = not open + ; OUTPUT: none +closeFile: + cmp word [filehandle], -1 + jz short _cf1 + mov bx, [filehandle] + mov ax, 3E00h + int 21h ; close file +_cf1: + retn + +; ---------------------------------- + + ; 14/11/2024 - Erdogan Tan +getWAVParameters: +; reads WAV file header(s) (44 bytes) from the .wav file. +; entry: none - assumes file is already open +; exit: ax = sample rate (11025, 22050, 44100, 48000) +; cx = number of channels (mono=1, stereo=2) +; dx = bits per sample (8, 16) +; bx = number of bytes per sample (1 to 4) + + mov dx, WAVFILEHEADERbuff + mov bx, [filehandle] + mov cx, 44 ; 44 bytes + mov ah, 3Fh + int 21h + jc short gwavp_retn + + cmp ax, 44 + jb short gwavp_retn + + cmp dword [RIFF_Format], 'WAVE' + jne short gwavp_stc_retn + + cmp word [WAVE_AudioFormat], 1 ; Offset 20, must be 1 (= PCM) + ;jne short gwavp_stc_retn + je short gwavp_retn ; 15/11/2024 + + ; 15/11/2024 + ;mov cx, [WAVE_NumChannels] ; return num of channels in CX + ;mov ax, [WAVE_SampleRate] ; return sample rate in AX + ;mov dx, [WAVE_BitsPerSample] + ; return bits per sample value in DX + ;mov bx, [WAVE_BlockAlign] ; return bytes per sample in BX +;gwavp_retn: + ;retn + + ; 27/11/2024 + ; frequency limit (for SB16) = 44100 kHz + ;cmp word [WAVE_SampleRate], 44101 ; 48000 + ;cmc + ;retn + +gwavp_stc_retn: + stc +gwavp_retn: + retn + +; ---- 30/05/2024 (playwav4.asm, 19/05/2024) + +; MEMALLOC.ASM +;-- SETFREE: Release memory not used ---------------- +;-- Input : ES = address of PSP +;-- Output : none +;-- Register : AX, BX, CL and FLAGS are changed +;-- Info : Since the stack-segment is always the last segment in an +; EXE-file, ES:0000 points to the beginning and SS:SP +; to the end of the program in memory. Through this the +; length of the program can be calculated +; call this routine once at the beginning of the program to free up memory +; assigned to it by DOS. + +setFree: + mov bx, 65536/16 ; 4K paragraphs ; 17/02/2017 (Erdogan Tan) + + mov ah, 4Ah ; pass new length to DOS + int 21h + + retn ; back to caller + ; new size (allocated memory) = 64KB + + ; 27/11/2024 +;memAlloc: +;; input: AX = # of paragraphs required +;; output: AX = segment of block to use +; +; push bx +; mov bx, ax +; mov ah, 48h +; int 21h +; pop bx +; retn + +; ---- + +; ///// + + ; 24/11/2024 (SB16 version of playwav8.asm -> playwav9.asm) + ; 30/05/2024 (ich_wav4.asm, 19/05/2024) +loadFromFile: + ; 18/12/2024 + mov word [count], 0 + + ; 07/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff_0 ; no + stc + retn + +lff_0: + ; 24/11/2024 + ; 08/11/2023 + mov di, ax ; save buffer address + ; 17/11/2024 + mov bx, [filehandle] + + ; 24/11/2024 + mov cx, LOADSIZE + mov dx, ax ; buffer address + + ; 24/11/2024 + ; load/read file + ; bx = file handle + ; ds = cs + ; ds:dx = buffer + ; cx = read count + mov ah, 3Fh + int 21h + jc short lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + + cmp ax, cx + je short endLFF + ; 24/11/2024 + ; di = buffer address + add di, ax +lff_3: + call padfill ; blank pad the remainder + ;clc ; don't exit with CY yet. + or byte [flags], ENDOFFILE ; end of file flag +endLFF: + retn +lff_4: + ; 08/11/2023 + mov al, '!' ; error + call tL0 + + xor ax, ax + jmp short lff_3 + +; entry ds:ax points to last byte in file +; cx = target size +; note: must do byte size fill +; destroys bx, cx +; +padfill: + ; 24/11/2024 + ; di = offset (to be filled with ZEROs) + ; es = ds = cs + ; ax = di = number of bytes loaded + ; cx = buffer size (> loaded bytes) + sub cx, ax + xor ax, ax + cmp byte [WAVE_BitsPerSample], 8 + ja short padfill@ + mov al, 80h +padfill@: + rep stosb + retn +; ///// + +write_audio_dev_info: + ; 30/05/2024 + sys_msg msgAudioCardInfo, 0Fh + retn + +write_sb16_dev_info: + ; 24/11/2024 + mov ax, [audio_io_base] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBasePort+2], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBasePort+1], al + mov bl, ah + mov dl, bl + ;and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBasePort], al + + xor ax, ax + mov al, [IRQnum] + ;mov cl, 10 + ;div cl + ;add ah, 30h + ;mov [msgIRQ], ah + ; 25/11/2024 + add al, 30h + mov [msgIRQ], al + + call clear_window + mov dh, 13 + mov dl, 0 + call setCursorPosition + + sys_msg msgSB16Info, 07h + + retn + +; -------------------------------------------------------- +; 24/11/2024 - Sound Blaster 16 initialization +; -------------------------------------------------------- + + ; 25/11/2024 + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9, audio.s (06/06/2024) + ; SbInit_play procedure (06/08/2024, v2.0.5) +SB16Init_play: + mov ax, ds + mov dx, ax + shr dx, 12 + shl ax, 4 + add ax, dma_buffer + adc dx, 0 + mov bx, ax ; linear address + ; dx = page number + + mov cx, dma_buffer_size + + cmp byte [WAVE_BitsPerSample], 16 + jne short sbInit_0 ; set 8 bit DMA buffer + + ; 26/11/2024 + mov ax, dx ; page number + + ; convert byte count to word count + ; 26/11/2024 + ;dec cx + shr cx, 1 + dec cx ; word count - 1 + + ; convert byte offset to word offset + shr ax, 1 + rcr bx, 1 + ; 26/11/2024 + ;shr bx, 1 + + ; 16 bit DMA buffer setting (DMA channel 5) + mov al, 05h ; set mask bit for channel 5 (4+1) + out 0D4h, al + + xor al, al ; stops all DMA processes on selected channel + out 0D8h, al ; clear selected channel register + + mov al, bl ; byte 0 of DMA buffer offset in words (physical) + out 0C4h, al ; DMA channel 5 port number + + mov al, bh ; byte 1 of DMA buffer offset in words (physical) + out 0C4h, al + + ; 26/11/2024 + and dl, 0FEh ; clear bit 0 (not necessary, it will be ignored) + + mov al, dl ; byte 2 of DMA buffer address (physical) + out 8Bh, al ; page register port addr for channel 5 + + mov al, cl ; low byte of DMA count - 1 + out 0C6h, al ; count register port addr for channel 5 + + mov al, ch ; high byte of DMA count - 1 + out 0C6h, al + + ; channel 5, read, autoinitialized, single mode + mov al, 59h + out 0D6h, al ; DMA mode register port address + + mov al, 01h ; clear mask bit for channel 5 + out 0D4h, al ; DMA mask register port address + + jmp short ResetDsp + +sbInit_0: + dec cx ; byte count - 1 + + ; 8 bit DMA buffer setting (DMA channel 1) + mov al, 05h ; set mask bit for channel 1 (4+1) + out 0Ah, al ; DMA mask register + + xor al, al ; stops all DMA processes on selected channel + out 0Ch, al ; clear selected channel register + + mov al, bl ; byte 0 of DMA buffer address (physical) + out 02h, al ; DMA channel 1 port number + + mov al, bh ; byte 1 of DMA buffer address (physical) + out 02h, al + + mov al, dl ; byte 2 of DMA buffer address (physical) + out 83h, al ; page register port addr for channel 1 + + mov al, cl ; low byte of DMA count - 1 + out 03h, al ; count register port addr for channel 1 + + mov al, ch ; high byte of DMA count - 1 + out 03h, al + + ; channel 1, read, autoinitialized, single mode + mov al, 59h + out 0Bh, al ; DMA mode register port address + + mov al, 01h ; clear mask bit for channel 1 + out 0Ah, al ; DMA mask register port address + +ResetDsp: + mov dx, [audio_io_base] + ;add dx, 06h + add dl, 06h + mov al, 1 + out dx, al + + in al, dx + in al, dx + in al, dx + in al, dx + + xor ax, ax + out dx, al + + mov cx, 100 +WaitId: + mov dx, [audio_io_base] + add dl, 0Eh + in al, dx + or al, al + ;js short sb_GetId + ; 26/11/2024 + jns short sb_next + ;loop WaitId + ;jmp sb_Exit + +sb_GetId: + mov dx, [audio_io_base] + ;add dx, 0Ah + add dl, 0Ah + in al, dx + cmp al, 0AAh + je short SbOk +sb_next: + loop WaitId + stc + retn +SbOk: + mov dx, [audio_io_base] + ;add dx, 0Ch + add dl, 0Ch + SbOut 0D1h ; Turn on speaker + SbOut 41h ; 8 bit or 16 bit transfer + mov bx, [WAVE_SampleRate] ; sampling rate (Hz) + SbOut bh ; sampling rate high byte + SbOut bl ; sampling rate low byte + + ; 25/11/2024 + +StartDMA: + ; autoinitialized mode + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_play_1 + ; 8 bit samples + mov bx, 0C6h ; 8 bit output (0C6h) + cmp byte [WAVE_NumChannels], 2 ; 1 = mono, 2 = stereo + jb short sb_play_2 + mov bh, 20h ; 8 bit stereo (20h) + jmp short sb_play_2 +sb_play_1: + ; 16 bit samples + mov bx, 10B6h ; 16 bit output (0B6h) + cmp byte [WAVE_NumChannels], 2 ; 1 = mono, 2 = stereo + jb short sb_play_2 + add bh, 20h ; 16 bit stereo (30h) +sb_play_2: + ; PCM output (8/16 bit mono autoinitialized transfer) + SbOut bl ; bCommand + SbOut bh ; bMode + ; 25/11/2024 + mov bx, dma_buffer_size/2 + ; half buffer size + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit DMA + jne short sb_play_3 + shr bx, 1 ; byte count to word count (samples) +sb_play_3: + dec bx ; wBlkSize is one less than the actual size + SbOut bl + SbOut bh + + ; 24/11/2024 + ;mov byte [stopped], 0 ; playing ! +sb_Exit: + retn + +; -------------------------------------------------------- +; 14/11/2024 - Erdogan Tan +; -------------------------------------------------------- + + ; 24/11/2024 (SB16 version) +checkUpdateEvents: + call check4keyboardstop + jc short c4ue_ok + + ; 18/11/2024 + push ax ; * + or ax, ax + jz c4ue_cpt + + ; 18/11/2024 + cmp al, 20h ; SPACE (spacebar) ; pause/play + jne short ch4ue_chk_s + cmp byte [stopped], 0 + ja short ch4ue_chk_ps + ; pause + call sb16_pause ; 24/11/2024 + ; 27/11/2024 + mov byte [stopped], 1 + jmp c4ue_cpt +ch4ue_chk_ps: + cmp byte [stopped], 1 + ja short ch4ue_replay + ; continue to play (after a pause) + call sb16_play ; 24/11/2024 + ; 27/11/2024 + mov byte [stopped], 0 + jmp short c4ue_cpt +ch4ue_replay: + ; 19/11/2024 + pop ax ; * + pop ax ; return address + ; 24/11/2024 + ; initialize (again) + ; and start playing (after stop) + call SB16Init_play + mov al, [volume] + call SetMasterVolume ; 24/11/2024 + mov byte [stopped], 0 + ; 24/11/2024 + mov byte [half_buffer], 1 + call move_to_beginning + jmp PlayWav + +ch4ue_chk_s: + cmp al, 'S' ; stop + jne short ch4ue_chk_fb + cmp byte [stopped], 0 + ja short c4ue_cpt ; Already stopped/paused + call sb16_stop ; 24/11/2024 + ; 19/11/2024 + mov byte [tLO], 0 + jmp short c4ue_cpt + +ch4ue_chk_fb: + ; 17/11/2024 + cmp al, 'F' + jne short c4ue_chk_b + call Player_ProcessKey_Forwards + jmp short c4ue_cpt + + ; 18/11/2024 +c4ue_ok: + retn + +c4ue_chk_b: + cmp al, 'B' + ; 19/11/2024 + jne short c4ue_chk_h + call Player_ProcessKey_Backwards + jmp short c4ue_cpt +c4ue_chk_h: + ; 19/11/2024 + cmp al, 'H' + jne short c4ue_chk_cr + mov byte [wleds], 0 + call write_sb16_dev_info + mov dh, 24 + mov dl, 79 + call setCursorPosition +c4ue_chk_cr: + ; 19/11/2024 + cmp al, 0Dh ; ENTER/CR key + jne short c4ue_cpt + ; 23/11/2024 + xor bx, bx + mov bl, [wleds] + inc bl + and bl, 0Fh + jnz short c4ue_sc + inc bx +c4ue_sc: + mov [wleds], bl + shr bl, 1 + mov al, [bx+colors] + jnc short c4ue_sc_@ + or al, 10h ; blue (dark) background +c4ue_sc_@: + mov [ccolor], al + ;;; +c4ue_cpt: + ;push ds + ;mov bx, 40h + ;mov ds, bx + ;mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;;cli + ;mov ax, [bx] + ;mov dx, [bx+2] + ;;sti + ;pop ds + ; 26/11/2024 + call GetTimerTicks + + ; 18/11/2024 + pop cx ; * + cmp dx, [timerticks+2] + jne short c4ue_utt + cmp ax, [timerticks] + ; 18/11/2024 + je short c4ue_skip_utt +c4ue_utt: + mov [timerticks], ax + mov [timerticks+2], dx + jmp short c4ue_cpt_@ +c4ue_skip_utt: + ; 18/11/2024 + and cx, cx + jz short c4ue_ok +c4ue_cpt_@: + ; 18/11/2024 + cmp byte [stopped], 0 + ja short c4ue_ok + + call CalcProgressTime + + cmp ax, [ProgressTime] + ; 23/11/2024 + je short c4ue_uvb + ; same second, no need to update + + call UpdateProgressBar + + ; 23/11/2024 +c4ue_uvb: + cmp byte [wleds], 0 + jna short c4ue_vb_ok + + call UpdateWaveLeds + +c4ue_vb_ok: + retn + + ; 26/11/2024 +GetTimerTicks: + push ds + mov bx, 40h + mov ds, bx + mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;cli + mov ax, [bx] + mov dx, [bx+2] + ;sti + pop ds + retn + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ich_wav4.asm +; -------------------------------------------------------- + + ; 24/11/2024 (SB16 version) +check4keyboardstop: + ; 19/05/2024 + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + ;clc + jz short _cksr + + xor ah, ah + int 16h + + ;;; + ; 19/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + ; 24/11/2024 + cmp al, 15 + jnb short p_3 + inc al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_4 + + mov al, [volume] + ; 24/11/2024 + cmp al, 0 + jna short p_3 + dec al +p_2: + mov [volume], al + ; 24/11/2024 + call SetMasterVolume + ;call UpdateVolume + ;;clc + ;retn + jmp UpdateVolume +_cksr: + ; 18/11/2024 + xor ax, ax + ;clc +p_3: + retn +p_4: + ; 17/11/2024 + cmp ah, 01h ; ESC + je short p_q + cmp al, 03h ; CTRL+C + je short p_q + + ; 18/11/2024 + cmp al, 20h + je short p_r + + ; 19/11/2024 + cmp al, 0Dh ; CR/ENTER + je short p_r + + and al, 0DFh + cmp al, 'B' + je short p_r + cmp al, 'F' + je short p_r + cmp al, 'Q' + je short p_q + + clc + retn + + ;;; +;_cskr: +p_q: + stc +p_r: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 +setCursorPosition: + ; dh = Row + ; dl = Column + mov ax, 0500h + int 10h + mov ah, 02h + mov bh, 00h + ;mov dh, setCursorPosition_Row + ;mov dl, setCursorPosition_Column + int 10h + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; NAME: SetTotalTime +;; DESCRIPTION: Calculates the total time in seconds in file +;; INPUT: DATA_SubchunkSize, WAVE_SampleRate, WAVE_BlockAlign +;; OUTPUT: CurrentTotalTime=Total time in seconds in file, +;; Output on the screen of the total time in seconds + +SetTotalTime: + ;; Calculate total seconds in file + mov ax, [DATA_SubchunkSize] + mov dx, [DATA_SubchunkSize + 2] + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + + mov bx, [WAVE_BlockAlign] + + div bx + + mov [TotalTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 42 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 45 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + ;jmp short PrintNumber + +; -------------------------------------------------------- + +PrintNumber: + ; bp = digits + ; ax = binary number + mov bx, 10 + xor cx, cx +printNumber_CutNumber: + inc cx + xor dx, dx + div bx + push dx + cmp cx, bp + je short printNumber_printloop + jmp printNumber_CutNumber + +printNumber_printloop: + pop ax + mov dl, '0' + add dl, al + mov ah, 02h + int 21h + loop printNumber_printloop + + retn + +; -------------------------------------------------------- + + ; 14/11/2024 - Erdogan Tan +SetProgressTime: + ;; Calculate playing/progress seconds in file + call CalcProgressTime + +UpdateProgressTime: + ; ax = (new) progress time + + mov [ProgressTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 33 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 36 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + jmp short PrintNumber + +; -------------------------------------------------------- + + ; 17/11/2024 + ; 14/11/2024 +CalcProgressTime: + mov ax, [LoadedDataBytes] + mov dx, [LoadedDataBytes+2] + mov bx, ax + or bx, dx + jz short cpt_ok + + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + mov bx, [WAVE_BlockAlign] + div bx +cpt_ok: + ; ax = (new) progress time + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; DESCRIPTION: Update file information on template +;; PARAMS: WAVE parameters and other variables +;; REGS: AX(RW) +;; VARS: CurrentFileName, WAVE_SampleRate, +;; RETURNS: On-screen file info is updated. + +UpdateFileInfo: + ;; Print File Name + mov dh, 9 + mov dl, 23 + call setCursorPosition + + mov si, wav_file_name + + ;;; + ; 14/11/2024 + ; skip directory separators + ; (note: asciiz string, max. 79 bytes except zero tail) + mov bx, si +chk4_nxt_sep: + lodsb + cmp al, '\' + je short chg_fpos + and al, al + jz short chg_fpos_ok + jmp short chk4_nxt_sep +chg_fpos: + mov bx, si + jmp short chk4_nxt_sep +chg_fpos_ok: + mov si, bx ; file name (without its path/directory) + ;;; + + call PrintString + + ;; Print Frequency + mov dh, 10 + mov dl, 23 + call setCursorPosition + mov ax, [WAVE_SampleRate] + mov bp, 5 + call PrintNumber + + ;; Print BitRate + mov dh, 9 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_BitsPerSample] + mov bp, 2 + call PrintNumber + + ;; Print Channel Number + mov dh, 10 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_NumChannels] + mov bp, 1 + call PrintNumber + + ;call UpdateVolume + ;retn + +; -------------------------------------------------------- + + ; 24/11/2024 + ; 14/11/2024 +UpdateVolume: + ;; Print Volume + mov dh, 24 + mov dl, 75 + call setCursorPosition + + mov al, [volume] + + mov bl, 100 + mul bl + + mov bl, 15 ; 24/11/2024 + div bl + + xor ah, ah + mov bp, 3 + ;call PrintNumber + ;retn + jmp PrintNumber + +; 24/11/2024 +; 29/05/2024 +; 19/05/2024 +volume: db 12 + +; -------------------------------------------------------- + + ; 14/11/2024 +PrintString: + ; si = string address + mov bx, 0Fh ; white + mov ah, 0Eh ; write as tty +printstr_loop: + lodsb + or al, al + jz short printstr_ok + int 10h + jmp short printstr_loop +printstr_ok: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 + ; (Ref: player.asm , Matan Alfasi, 2017) + ; (Modification: Erdogan Tan, 14/11/2024) + + PROGRESSBAR_ROW equ 23 + +UpdateProgressBar: + call SetProgressTime ; 14/11/2024 + + mov ax, [ProgressTime] +UpdateProgressBar@: + mov dx, 80 + mul dx + mov bx, [TotalTime] + div bx + + ;; Push for the 'Clean' part + push ax ; ** + push ax ; * + + ;; Set cursor position + mov dh, PROGRESSBAR_ROW + mov dl, 0 + call setCursorPosition + + pop ax ; * + or ax, ax + jz short UpdateProgressBar_Clean + +UpdateProgressBar_DrawProgress: + mov cx, ax + mov ah, 09h + mov al, 223 + mov bx, 0Fh + int 10h + +UpdateProgressBar_DrawCursor: + ;mov ax, cx + mov dh, PROGRESSBAR_ROW + ;mov dl, al + dec cx + mov dl, cl + call setCursorPosition + + mov ah, 09h + mov al, 223 + mov bx, 0Ch + mov cx, 1 + int 10h + +UpdateProgressBar_Clean: + pop ax ; ** + mov cx, ax + mov dh, PROGRESSBAR_ROW + mov dl, al + call setCursorPosition + + neg cx + add cx, 80 ; cf = 1 ; + + ;; CX = No. of times to print a clean character + ;mov cx, 80 + ;sub cx, ax + ;; 09h = Write character multiple times + mov ah, 09h + ;; 32 = Space ASCII code + ;mov al, 32 + ;mov bx, 0 + ; 15/11/2024 + mov al, 223 + mov bx, 8 + int 10h + ; 14/11/2024 + clc ; + + + retn + +; -------------------------------------------------------- +; 17/11/2024 + +Player_ProcessKey_Backwards: + ;; In order to go backwards 5 seconds: + ;; Update file pointer to the beginning, skip headers + mov cl, 'B' + jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_Forwards: + ;; In order to fast-forward 5 seconds, set the file pointer + ;; to CUR_SEEK + 5 * Freq + + mov cl, 'F' + ;jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_B_or_F: + ; 17/11/2024 + ; 04/11/2024 + ; (Ref: player.asm, Matan Alfasi, 2017) + + ; 04/11/2024 + mov ax, 5 + mov bx, [WAVE_BlockAlign] + mul bx + mov bx, [WAVE_SampleRate] + mul bx + ; dx:ax = transfer byte count for 5 seconds + + ; 17/11/2024 + cmp cl, 'B' + mov bx, [LoadedDataBytes] + mov cx, [LoadedDataBytes+2] + jne short move_forward ; cl = 'F' +move_backward: + sub bx, ax + sbb cx, dx + jnc short move_file_pointer +move_to_beginning: + xor cx, cx ; 0 + xor bx, bx ; 0 + jmp short move_file_pointer +move_forward: + add bx, ax + adc cx, dx + jc short move_to_end + cmp cx, [DATA_SubchunkSize+2] + ja short move_to_end + jb short move_file_pointer + cmp bx, [DATA_SubchunkSize] + jna short move_file_pointer +move_to_end: + mov bx, [DATA_SubchunkSize] + mov cx, [DATA_SubchunkSize+2] +move_file_pointer: + mov dx, bx + mov [LoadedDataBytes], dx + mov [LoadedDataBytes+2], cx + add dx, 44 ; + header + adc cx, 0 + + ; seek + mov bx, [filehandle] + mov ax, 4200h + int 21h + + retn + +; -------------------------------------------------------- + + ; 19/11/2024 +UpdateWaveLeds: + ; 23/11/2024 + call reset_wave_leds + ;call word [turn_on_leds] + ;retn + jmp word [turn_on_leds] + +; -------------------------------------------------------- + + ; 23/11/2024 + ; 19/11/2024 +clear_window: + xor ax, ax + jmp short clear_window_@ + +reset_wave_leds: + ; 23/11/2024 + ;mov al, 254 + ;mov ah, 8 ; gray (dark) + mov ax, 08FEh +clear_window_@: + push es + mov di, 0B800h + mov es, di + mov di, 2080 ; 13*80*2 + mov cx, 8*80 ; 8 rows + rep stosw + pop es + retn + +; -------------------------------------------------------- + + ; 24/11/2024 + ; 19/11/2024 +turn_on_leds_stereo_16bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol_buffer_1 + +tol_buffer_2: + ; 21/11/2024 + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol_@ + +tol_buffer_1: + cmp byte [tLO],'1' + ;jne short tol_retn + ; 23/11/2024 + jne short tol_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol_o_@ + cmp si, cx + jna short tol_s_buf +tol_o_@: + mov si, cx + jmp short tol_s_buf + +tol_clc_retn: + ; 23/11/2024 + clc +tol_retn: + ; 25/11/2024 + pop es + retn + +tol_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol_s_buf: + mov [pbuf_o], si + +tol_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + ;mov di, (20*80*2)-2 + + ; 23/11/2024 + mov cx, 80 + + ; 22/11/2024 + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol_fill_c: + ; 22/11/2024 + ;inc di + ;inc di + ;push di + lodsw ; left + ;shr ax, 8 + mov dx, ax + lodsw ; right + ;shr ax, 8 + ;;; + ; 23/11/2024 + add ax, dx + shr ax, 8 + ;shr ax, 9 + add al, 80h + shr ax, 5 + ;;; + ;shr ax, 6 + + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + ; 23/11/2024 + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol_fill_c + + jmp short tol_retn + + + ; 24/11/2024 + ; 23/11/2024 +turn_on_leds_mono_16bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol2_buffer_1 + +tol2_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol2_@ + +tol2_buffer_1: + cmp byte [tLO],'1' + jne short tol_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol2_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol2_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol2_o_@ + cmp si, cx + jna short tol2_s_buf +tol2_o_@: + mov si, cx + jmp short tol2_s_buf + +;tol2_clc_retn: +; clc +;tol2_retn: +; ; 25/11/2024 +; pop es +; retn + +tol2_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol2_s_buf: + mov [pbuf_o], si + +tol2_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol2_fill_c: + lodsw + shr ax, 8 + add al, 80h + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol2_fill_c + + jmp tol_retn + + ; 24/11/2024 +turn_on_leds_stereo_8bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol3_buffer_1 + +tol3_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol3_@ + +tol3_buffer_1: + cmp byte [tLO],'1' + jne short tol3_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol3_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol3_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol3_o_@ + cmp si, cx + jna short tol3_s_buf +tol3_o_@: + mov si, cx + jmp short tol3_s_buf + +tol3_clc_retn: + clc +tol3_retn: + ; 25/11/2024 + pop es + retn + +tol3_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol3_s_buf: + mov [pbuf_o], si + +tol3_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol3_fill_c: + lodsw ; left (al), right (ah) + add al, ah + add al, 80h + xor ah, ah + ;shr ax, 6 + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol3_fill_c + + jmp short tol3_retn + + ; 24/11/2024 + ; 23/11/2024 +turn_on_leds_mono_8bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol4_buffer_1 + +tol4_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol4_@ + +tol4_buffer_1: + cmp byte [tLO],'1' + jne short tol3_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol4_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol4_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol4_o_@ + cmp si, cx + jna short tol4_s_buf +tol4_o_@: + mov si, cx + jmp short tol4_s_buf + +;tol4_clc_retn: +; clc +;tol4_retn: +; ; 25/11/2024 +; pop es +; retn + +tol4_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol4_s_buf: + mov [pbuf_o], si + +tol4_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol4_fill_c: + lodsb + ; 27/11/2024 + add ax, ax + add al, 80h + xor ah, ah + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol4_fill_c + + jmp tol3_retn + +; -------------------------------------------------------- + +; 30/05/2024 +print_msg: + mov bx, 07h +p_msg: + push es + push bp + push cx + push dx + + push ds + pop es + mov bp, si + mov ah, 03h ; Return cursor position (in DX) + ; bh = video page number + int 10h + xor cx, cx +p_msg_0: + lodsb + or al, al + jz short p_msg_1 + inc cx + jmp short p_msg_0 +p_msg_1: + or cx, cx + jz short p_msg_x + ; cx = number of chars + ; dx = screen (cursor) position + ; bl = color/attribute + ; bh = video page number + ; es:bp = string buffer + ;mov al, 1 ; attribute in BL, update cursor pos + ;mov ah, 13h ; write character string + mov ax, 1301h + int 10h +p_msg_x: + pop dx + pop cx + pop bp + pop es + retn + +; -------------------------------------------------------- +; -------------------------------------------------------- + +; DATA + +Credits: + db 'Tiny WAV Player for Retro DOS by Erdogan Tan. ' + db 'December 2024.',10,13,0 + db '18/12/2024', 10,13,0 + +msgAudioCardInfo: + db 'for Sound Blaster 16 audio device.', 10,13,0 + +msg_usage: + db 'usage: playwav9 filename.wav',10,13,0 ; 24/11/2024 + + ; 24/11/2024 +noDevMsg: + db 'Error: Unable to find Sound Blaster 16 audio device!' + db 10,13,0 + +noFileErrMsg: + db 'Error: file not found.',10,13,0 + +msg_error: ; 30/05/2024 + +; 24/11/2024 +msg_init_err: + db 0Dh, 0Ah + db "Sound Blaster 16 hardware initialization error !" + db 0Dh, 0Ah, 0 ; 07/12/2024 + +; 19/11/2024 +; 03/06/2017 +hex_chars: db "0123456789ABCDEF", 0 + +; 24/11/2024 +msgSB16Info: db 0Dh, 0Ah + db " Audio Hardware: Sound Blaster 16", 0Dh, 0Ah + db " Base Port: " +msgBasePort: db "000h", 0Dh, 0Ah + db " IRQ: " +msgIRQ: db 30h + db 0Dh, 0Ah, 0 + +; -------------------------------------------------------- +; 14/11/2024 (Ref: player.asm, Matan Alfasi, 2017) + +SplashScreen: + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " _______ ______ _______. ", 221, 219, 222 + db 221, 219, 222, " | \ / __ \ / | ", 221, 219, 222 + db 221, 219, 222, " | .--. | | | | | (----` ", 221, 219, 222 + db 221, 219, 222, " | | | | | | | \ \ ", 221, 219, 222 + db 221, 219, 222, " | '--' | `--' | .----) | ", 221, 219, 222 + db 221, 219, 222, " |_______/ \______/ |_______/ ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " .______ __ ___ ____ ____ _______ .______ ", 221, 219, 222 + db 221, 219, 222, " | _ \ | | / \ \ \ / / | ____|| _ \ ", 221, 219, 222 + db 221, 219, 222, " | |_) | | | / ^ \ \ \/ / | |__ | |_) | ", 221, 219, 222 + db 221, 219, 222, " | ___/ | | / /_\ \ \_ _/ | __| | / ", 221, 219, 222 + db 221, 219, 222, " | | | `----./ _____ \ | | | |____ | |\ \----. ", 221, 219, 222 + db 221, 219, 222, " | _| |_______/__/ \__\ |__| |_______|| _| `._____| ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " WELCOME TO ", 221, 219, 222 + db 221, 219, 222, " DOS PLAYER ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db " " +Template: + db 201, 78 dup(205), 187 + db 186, 33 dup(219), " DOS Player ", 33 dup(219), 186 + db 204, 78 dup(205), 185 + db 186, 33 dup(32), " User Guide ", 33 dup(32), 186 + db 186, 6 dup(32), " Play/Pause ", 4 dup(32), " Hardware Info", 9 dup(32), 186 + db 186, 6 dup(32), " Stop ", 4 dup(32), " Wave Lighting", 9 dup(32), 186 + db 186, 6 dup(32), " Forwards ", 4 dup(32), "<+>/<-> Inc/Dec Volume", 8 dup(32), 186 + db 186, 6 dup(32), " Backwards ", 4 dup(32), " Quit Program ", 9 dup(32), 186 + db 204, 78 dup(205), 185 + db 186, 6 dup(32), "File Name : ", 4 dup(32), "Bit-Rate : 0 Bits ", 9 dup(32), 186 + db 186, 6 dup(32), "Frequency : 0 Hz ", 4 dup(32), "#-Channels: 0 ", 9 dup(32), 186 + db 200, 78 dup(205), 188 + db 80 dup(32) +improper_samplerate_txt: ; 03/11/2024 +read_error_txt: + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(205) + db 80 dup(32) + db 33 dup(32), "00:00 ", 174, 175, " 00:00", 24 dup(32), "VOL 000%" + +; 23/11/2024 +colors: db 0Fh, 0Bh, 0Ah, 0Ch, 0Eh, 09h, 0Dh, 0Fh + ; white, cyan, green, red, yellow, blue, magenta +ccolor: db 0Bh ; cyan + +; 24/11/2024 +half_buffer: db 1 ; dma half buffer 1 or 2 (0 or 1) + ; (initial value = 1 -> after xor in TuneLoop -> 0) +EOF: + +; BSS + +align 2 + +; 24/11/2024 +; 22/11/2024 +; wave volume leds address array +wleds_addr: rw 80*8 ; rb 2*80*8 + +; 24/11/2024 (SB16 version of playwav8.com -> playwav9.com) +; 14/11/2024 +; 17/02/2017 +bss_start: + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +; 24/11/2024 +old_irq5v_o: rw 1 +old_irq5v_s: rw 1 +old_irq7v_o: rw 1 +old_irq7v_s: rw 1 +; +IRQnum: rb 1 +; 25/11/2024 +IRQstatus: rb 1 + rb 1 +; 18/11/2024 +stopped: rb 1 +tLO: rb 1 +; 19/11/2024 +wleds: rb 1 +wleds_dif: rw 1 +pbuf_s: rw 1 +pbuf_o: rw 1 + +; 25/11/2024 +align 4 + +;;;;;;;;;;;;;; +; 14/11/2024 +; (Ref: player.asm, Matan Alfasi, 2017) +WAVFILEHEADERbuff: +RIFF_ChunkID: rd 1 ; Must be equal to "RIFF" - big-endian + ; 0x52494646 +RIFF_ChunkSize: + rd 1 ; Represents total file size, not + ; including the first 2 fields + ; (Total_File_Size - 8), little-endian +RIFF_Format: + rd 1 ; Must be equal to "WAVE" - big-endian + ; 0x57415645 + +;; WAVE header parameters ("Sub-chunk") +WAVE_SubchunkID: + rd 1 ; Must be equal to "fmt " - big-endian + ; 0x666d7420 +WAVE_SubchunkSize: + rd 1 ; Represents total chunk size +WAVE_AudioFormat: + rw 1 ; PCM (Raw) - is 1, other - is a form + ; of compression, not supported. +WAVE_NumChannels: + rw 1 ; Number of channels, Mono-1, Stereo-2 +WAVE_SampleRate: + rd 1 ; Frequency rate, in Hz (8000, 44100 ...) +WAVE_ByteRate: rd 1 ; SampleRate * NumChannels * BytesPerSample +WAVE_BlockAlign: + rw 1 ; NumChannels * BytesPerSample + ; Number of bytes for one sample. +WAVE_BitsPerSample: + rw 1 ; 8 = 8 bits, 16 = 16 bits, etc. + +;; DATA header parameters +DATA_SubchunkID: + rd 1 ; Must be equal to "data" - big-endian + ; 0x64617461 +DATA_SubchunkSize: + rd 1 ; NumSamples * NumChannels * BytesPerSample + ; Number of bytes in the data. +;;;;;;;;;;;;;; + +; 15/11/2024 +cursortype: rw 1 + +filehandle: rw 1 + +flags: rb 1 ; (END_OF_FILE flag) + rb 1 + +audio_io_base: rw 1 ; Sound Blaster 16 base port address (220h) + +; 30/05/2024 +wav_file_name: + rb 80 ; wave file, path name (<= 80 bytes) + + rw 1 +; 24/11/2024 +align 4 + +; 23/11/2024 +turn_on_leds: rw 1 ; turn_on_leds procedure pointer (m8,m16,s8,s16) + +; 14/11/2024 +TotalTime: rw 1 ; Total (WAV File) Playing Time in seconds +ProgressTime: rw 1 +count: rw 1 ; byte count of one (wav file) read +LoadedDataBytes: + rd 1 ; total read/load count + +timerticks: rd 1 ; (to eliminate excessive lookup of events in TuneLoop) + ; (in order to get the emulator/qemu to run correctly) +align 16 + +; 24/11/2024 +dma_buffer: ; 32768 bytes +wav_buffer1: rb dma_buffer_size/2 ; 16384 +wav_buffer2: rb dma_buffer_size/2 ; 16384 + +bss_end: diff --git a/trdos386/programs/16bit/sb16play.asm b/trdos386/programs/16bit/sb16play.asm new file mode 100644 index 0000000..d44eeae --- /dev/null +++ b/trdos386/programs/16bit/sb16play.asm @@ -0,0 +1,2880 @@ +; **************************************************************************** +; sb16play.asm (for Retro DOS) +; ---------------------------------------------------------------------------- +; SB16PLAY.COM ! Sound Blaster 16 (DOS) .WAV PLAYER program by Erdogan TAN +; +; 29/11/2024 +; +; [ Last Modification: 18/12/2024 ] +; +; Modified from PLAYWAV9.COM .wav player program by Erdogan Tan, 27/11/2024 +; +; Assembler: FASM 1.73 +; fasm sb16play.asm SB16PLAY.COM +; ---------------------------------------------------------------------------- +; In the visualization part of the code, the source code of Matan Alfasi's +; (Ami-Asaf) player.exe program was partially used. +; ---------------------------------------------------------------------------- +; Previous versions of this Wav Player were based in part on .wav file player +; (for DOS) source code written by Jeff Leyla in 2002. + +; playwav9.asm (27/11/2024) -- ref: ac97play.asm, 29/11/2024 -- + +; INTERRUPT (SRB) + TUNELOOP version ; 24/11/2024 +; (running in DOSBOX, VIRTUALBOX, QEMU is ok) +; Signal Response Byte = message/signal to user about an event/interrupt +; as requested (TuneLoop procedure continuously checks this SRB) +; (TRDOS 386 v2 feature is used here as very simple interrupt handler output) + +; CODE + + ; 13/11/2024 +macro sys_msg op1,op2 +{ ; 30/05/2024 + mov si, op1 ; message + mov bl, op2 ; text color + xor bh, bh ; video page 0 + mov ah, 0Eh + call p_msg +} + + ; 24/11/2024 +macro SbOut op1 +{ +local .wait +.wait: + in al, dx + or al, al + js short .wait + mov al, op1 ; command + out dx, al +} + +; player internal variables and other equates. +; 17/11/2024 +;BUFFERSIZE equ 65520 +; 24/11/2024 +;dma_buffer_size equ 32768 +;LOADSIZE equ 16384 +ENDOFFILE equ 1 ; flag for knowing end of file +; 27/11/2024 +dma_buffer_size equ 44100 +LOADSIZE equ 22050 + +use16 + +org 100h + +_STARTUP: + ; 30/05/2024 + ; Prints the Credits Text. + sys_msg Credits, 0Bh + + ; 30/05/2024 + call setFree ; deallocate unused DOS mem + + ; 17/02/2017 + ; Clear BSS (uninitialized data) area + xor ax, ax ; 0 + mov cx, (bss_end - bss_start)/2 + mov di, bss_start + rep stosw + + ; 24/11/2024 + ; Detect (& Reset) Sound Blaster 16 Audio Device + call DetectSB16 + ;jnc short GetFileName + ; 29/11/2024 + jnc short Player_InitalizePSP + + ; 30/05/2024 +_dev_not_ready: + ; couldn't find the audio device! + sys_msg noDevMsg, 0Fh + jmp Exit + + ;;; + ; 28/11/2024 (ac97play.asm) +Player_InitalizePSP: + mov si, 81h + mov [PSP_CurrentOffset], si + cmp byte [si], 0Dh ; "CR": No command line parameters + ja short Player_ParseParameters + jmp pmsg_usage + +Player_ParseParameters: + ; 18/12/2024 + ; 29/11/2024 + ;mov dx, wav_file_name + cmp byte [IsInSplash], 0 + jna short check_p_command + + call write_audio_dev_info + + mov dx, SplashFileName + jmp short _1 + +check_p_command: + cmp byte [command], 'P' + je short Player_ParsePreviousParameter + + mov si, [PSP_CurrentOffset] + cmp byte [si], 0Dh + ja short Player_ParseNextParameter +jmp_Player_Quit: + jmp Player_Quit + +Player_ParsePreviousParameter: + ; 29/11/2024 + ;mov byte [command], 0 + + mov si, [PSP_CurrentOffset] + + cmp si, 81h + je short Player_ParseNextParameter + + ;; Search for previous space character + dec si + mov cx, 2 +PSPParsePrev_Search: + dec si + mov al, [si] + cmp al, 20h + jne short PSPParsePrev_Search + + cmp si, 81h + jna PSPParsePrev_Copy + loop PSPParsePrev_Search + +PSPParsePrev_Copy: + mov [PSP_CurrentOffset], si + +Player_ParseNextParameter: + ; 29/11/2024 + call GetFileName + jcxz jmp_Player_Quit + + ; 28/11/2024 + mov dx, wav_file_name + ;;; +_1: + +; open the file + ; open existing file + ; 14/11/2024 + ;mov al, OPEN ; open existing file + ; 28/11/2024 + ;mov dx, wav_file_name + call openFile ; no error? ok. + jnc getwavparms ; 14/11/2024 + + ; 28/11/2024 + cmp byte [IsInSplash], 0 + ja Player_SplashScreen + + ; 29/11/2024 + cmp byte [filecount], 0 + ja short check_p_command + + call ClearScreen + sys_msg Credits, 0Bh + call write_audio_dev_info + +wav_file_open_error: +; file not found! + sys_msg noFileErrMsg, 0Ch +_exit_: + jmp Exit + + ; 29/11/2024 + ; 30/05/2024 +GetFileName: + mov di, wav_file_name + mov si, [PSP_CurrentOffset] + xor cx, cx ; 0 +ScanName: + lodsb + ;test al, al + ;jz short a_4 + ; 29/11/2024 + cmp al, 0Dh + jna short a_4 + cmp al, 20h + je short ScanName ; scan start of name. + stosb + mov ah, 0FFh + ;;; + ; 14/11/2024 + ; (max. path length = 64 bytes for MSDOS ?) (*) + ;xor cx, cx ; 0 + ;;; +a_0: + inc ah +a_1: + ;;; + ; 14/11/2024 + inc cx + ;;; + lodsb + stosb + cmp al, '.' + je short a_0 + ; 29/11/2024 + cmp al, 20h + ;and al, al + ;jnz short a_1 + ;;; + ; 14/11/2024 + jna short a_3 + and ah, ah + jz short a_2 + cmp al, '\' + jne short a_2 + mov ah, 0 +a_2: + cmp cl, 75 ; 64+8+'.'+3 -> offset 75 is the last chr + jb short a_1 + ; 29/11/2024 + sub cx, cx + jmp short a_4 +a_3: + ; 29/11/2024 + dec di + ;;; + or ah, ah ; if period NOT found, + jnz short a_4 ; then add a .WAV extension. +SetExt: + ; 29/11/2024 + ;dec di + mov dword [di], '.WAV' ; ! 64+12 is DOS limit + ; but writing +4 must not + ; destroy the following data + ;mov byte [di+4], 0 ; so, 80 bytes path + 0 is possible here + ; 29/11/2024 + add cx, 4 + add di, 4 +a_4: + mov byte [di], 0 + dec si + mov [PSP_CurrentOffset], si + retn + +getwavparms: + ; 14/11/2024 + call getWAVParameters + jc short _exit_ ; nothing to do + + ; 29/11/2024 + cmp byte [IsInSplash], 0 + jna short Player_Template + + ; 29/11/2024 +Player_SplashScreen: + ; 15/11/2024 + ;; Set video mode to 03h (not necessary) + mov ax, 03h + int 10h + + ; 15/11/2024 + ;; Get the cursor type + mov ah, 03h + int 10h + mov [cursortype], cx ; save + + ; 15/11/2024 + ;; Set the cursor to invisible + mov ah, 01h + mov cx, 2607h + int 10h + + ; 15/11/2024 + ;xor dx, dx + ;call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, SplashScreen + int 10h + ;;; + + ;;; + ; 22/11/2024 + ; set wave volume led addresses + mov bx, 13*80*2 + mov bp, 80 + mov di, wleds_addr +wleds_sa_1: + mov cx, 7 +wleds_sa_2: + mov ax, 80*2 + mul cx + add ax, bx + stosw + loop wleds_sa_2 + mov ax, bx + stosw + inc bx + inc bx + dec bp + jnz short wleds_sa_1 + ;;; + + ; 29/11/2024 + cmp word [filehandle], -1 + jne short PlayNow + + ;;; wait for 3 seconds + ;mov cx, 002Dh + ;mov dx, 0C6C0h + ;mov ah, 86h + ;int 15h + ;;; + ; 26/11/2024 + ;mov cx, 3*18 + ; 27/11/2024 + mov cx, 2*18 +getticks: + ; 26/11/2024 + call GetTimerTicks + + cmp ax, [timerticks] + jne short chkws + cmp dx, [timerticks+2] + je short getticks +chkws: + mov [timerticks], ax + mov [timerticks+2], dx + loop getticks + ;;; + + ; 28/11/2024 (ac97play.asm) + mov byte [IsInSplash], 0 + ; 29/11/2024 + jmp Player_ParseNextParameter + + ; 29/11/2024 +Player_Template: + ;;; + ; 23/11/2024 + cmp byte [WAVE_NumChannels], 1 + ja short stolp_s +stolp_m: + cmp byte [WAVE_BitsPerSample], 8 + ja short stolp_m16 +stolp_m8: + mov word [turn_on_leds], turn_on_leds_mono_8bit + jmp short stolp_ok +stolp_m16: + mov word [turn_on_leds], turn_on_leds_mono_16bit + jmp short stolp_ok +stolp_s: + cmp byte [WAVE_BitsPerSample], 8 + ja short stolp_s16 +stolp_s8: + mov word [turn_on_leds], turn_on_leds_stereo_8bit + jmp short stolp_ok +stolp_s16: + mov word [turn_on_leds], turn_on_leds_stereo_16bit + jmp short stolp_ok +stolp_ok: + ; 29/11/2024 + inc byte [filecount] + mov byte [command], 0 + ;;; + + xor dx, dx + call setCursorPosition + + ;; Print the splash screen in white + mov ax, 1300h + mov bx, 000Fh + mov cx, 1999 + mov dx, 0 + + mov bp, Template + int 10h + ;;; + + ; 14/11/2024 + call SetTotalTime + call UpdateFileInfo + +PlayNow: + ; 29/11/2024 + cmp byte [IsInSplash], 0 + ;ja short PlayNow@ + ; 02/12/2024 + jna short PlayNow@ + +;PlayNow@: + ; 24/11/2024 + mov al, 5 ; 15 = max, 0 = min + ; 27/11/2024 + mov [volume], al + ; 15/11/2024 + call SetMasterVolume + + ; 29/11/2024 + ;cmp byte [IsInSplash], 0 + ;ja short _3 + ; + ;call UpdateVolume + ; + ; 02/12/2024 + jmp short _3 + +PlayNow@: + ; reset file loading and EOF parameters + ;mov word [count], 0 + mov word [LoadedDataBytes], 0 + mov word [LoadedDataBytes+2], 0 + mov byte [flags], 0 + mov byte [stopped], 0 + ;jmp short PlayNow@@ + +PlayNow@@: + ;;; + ; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 30/05/2024 + ; playwav4.asm +_2: + call check4keyboardstop ; flush keyboard buffer + jc short _2 ; 07/11/2023 + +; play the .wav file. Most of the good stuff is in here. + +_3: + call PlayWav + + ; 29/11/2024 + ; 28/11/2024 (ac97play.asm) + call closeFile + ;mov dx, wav_file_name + cmp byte [IsInSplash], 0 + ;jna short Exit@@ + jna short _4 ; 29/11/2024 + mov byte [IsInSplash], 0 + ; 29/11/2024 + jmp Player_ParseNextParameter + + ; 29/11/2024 +_4: + cmp byte [command], 'Q' + je short Exit@@ + jmp check_p_command + +Exit@@: + ; 27/11/2024 + ; 24/11/2024 + ; restore old interrupt vector + mov al, [IRQnum] + xor ah, ah ; reset + call set_hardware_int_vector + +; close the .wav file and exit. + +Exit: + ; 15/11/2024 + ;; Restore Cursor Type + mov cx, [cursortype] + cmp cx, 0 + jz short Exit@ + mov ah, 01h + int 10h +Exit@: + ; 29/11/2024 + ;call closeFile +terminate: + mov ax, 4C00h ; bye ! + int 21h +here: + jmp short here ; do not come here ! + + ; 30/05/2024 +pmsg_usage: + sys_msg msg_usage, 0Fh ; 14/11/2024 + jmp short Exit + + ; 30/05/2024 +init_err: + sys_msg msg_init_err, 0Fh + jmp short Exit + + ; 29/11/2024 +Player_Quit: + call ClearScreen + jmp short terminate +ClearScreen: + mov ax, 03h + int 10h + retn + + ; -------------------------------------------- + + ; 24/11/2024 +PlayWav: + mov ax, wav_buffer1 + call loadFromFile + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + mov ax, wav_buffer2 + call loadFromFile + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; 25/11/2024 + call SB16Init_play ; initialize SB16 card + ; set sample rate, start to play + jc init_err + + ; 19/11/2024 + mov byte [wleds], 1 + + mov ax, [WAVE_SampleRate] + mov cx, 10 + mul cx + mov cl, 182 + div cx + ; ax = samples per 1/18.2 second + mov cl, byte [WAVE_BlockAlign] + mul cx + mov [wleds_dif], ax ; buffer read differential (distance) + ; for wave volume leds update + ; (byte stream per 1/18.2 second) + ; 27/11/2024 + ; set audio interrupt vector (to user's handler) + mov al, [IRQnum] + mov ah, 1 ; set + mov dx, IRQ_service + call set_hardware_int_vector + + ; 26/11/2024 + call check4keyboardstop + jc _exitt_ + + ; 27/11/2024 + mov byte [IRQnum], 0 + + ; 29/11/2024 + cmp byte [IsInSplash], 0 + jna short TuneLoop + +sL1: + cmp byte [IRQnum], 0 + ja short sL2 + + ; delay + nop + in al, 0EBh + out 0EBh, al + nop + jmp short sL1 + +sL2: + xor byte [half_buffer], 1 + mov byte [IRQnum], 0 + + mov ax, dma_buffer ; wav_buffer1 + cmp byte [half_buffer], 0 + jna short sL3 + + ; load buffer 2 + ;mov ax, wav_buffer2 + add ax, LOADSIZE ; dma_buffer_size/2 +sL3: + call loadFromFile + jnc short sL1 + +sL4: + ; end of file + ;call sb16_stop + ;retn + jmp sb16_stop + + ; 29/11/2024 + ; 27/11/2024 + ; 24/11/2024 +TuneLoop: + ; 30/05/2024 + ; 18/11/2023 (ich_wav4.asm) + ; 08/11/2023 + ; 06/11/2023 +tLWait: + ; 18/11/2024 + cmp byte [stopped], 0 + ; 24/11/2024 + jna short tL1 +tLWait@: ; 21/11/2024 + call checkUpdateEvents + jc _exitt_ + ;;; + ; 29/11/2024 + cmp byte [command], 'N' + je _exitt_ + cmp byte [command], 'P' + je _exitt_ + ;;; + cmp byte [tLO], '0' + je short tLWait + call tLZ + mov byte [tLO], '0' + jmp short tLWait +tL1: + ; 27/11/2024 + ; Check SB 16 interrupt status + cmp byte [IRQnum], 0 + ja short tL3 +tL2: + call checkUpdateEvents + jc _exitt_ + jmp short tLWait +tL3: + xor byte [half_buffer], 1 + + mov byte [IRQnum], 0 + + ; load buffer 1 + ;mov ax, wav_buffer1 + mov ax, dma_buffer ; wav_buffer1 + cmp byte [half_buffer], 0 + jna short tL4 + + ; load buffer 2 + ;mov ax, wav_buffer2 + add ax, LOADSIZE ; dma_buffer_size/2 +tL4: + call loadFromFile + jc short _exitt_ ; end of file + + ; 26/11/2024 + mov al, [half_buffer] + add al, '1' + ; 19/11/2024 + mov [tLO], al + call tL0 + ; 24/11/2024 + ; 14/11/2024 + mov ax, [count] + add [LoadedDataBytes], ax + adc word [LoadedDataBytes+2], 0 + + ; 27/11/2024 + jmp short tL2 + +_exitt_: + ; 24/11/2024 + call sb16_stop + + ;;; + ; 14/11/2024 + call UpdateProgressBar + ;;; + + ; 18/11/2024 +tLZ: + ; 30/05/2024 + mov al, '0' + + ; 06/11/2023 +tL0: + ; 08/11/2023 + ; 05/11/2023 + ; 17/02/2017 - Buffer switch test (temporary) + ; 06/11/2023 + ; al = buffer indicator ('1', '2' or '0' -stop- ) + + push ds + ;push bx + mov bx, 0B800h ; video display page segment + mov ds, bx + sub bx, bx ; 0 + mov ah, 4Eh + mov [bx], ax ; show current play buffer (1, 2) + ;pop bx + pop ds + + retn + +; ------------------------------------------- + +; 27/11/2024 +; ; 24/11/2024 +;IRQ_ack: +; ; 26/11/2024 +; push dx +; push ax +; mov dx, [audio_io_base] +; ;add dx, 0Eh +; add dl, 0Eh ; 8bit DMA-mode int ack +; ; 25/11/2024 +; cmp byte [WAVE_BitsPerSample], 8 +; jna short irq_ack_@ +; inc dl ; 0Fh ; 16bit DMA-mode int ack +;irq_ack_@: +; in al, dx ; SB acknowledge. +; ; 27/11/2024 +; ;mov al, 20h +; ;out 20h, al ; Hardware acknowledge. +;irq_ack_ok: +; ; 26/11/2024 +; pop ax +; pop dx +; retn + +; ------------------------------------------- + + ; 24/11/2024 +SetMasterVolume: + ; al = sound volume (15 = max, 0 = min) + push ax + ; Tell the SB 16 card which register to write + mov dx, [audio_io_base] + ;add dx, 4 ; Mixer chip address port + add dl, 4 + mov al, 22h + out dx, al + pop ax + ;and al, 0Fh + ; Set the volume for both L and R + mov bl, 11h + mul bl + ; Set new volume + mov dx, [audio_io_base] + ;add dx, 5 + add dl, 5 + out dx, al + retn + +; ------------------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; DetectSB procedure (06/08/2022, v2.0.5) +DetectSB16: + ; 06/08/2022 - TRDOS 386 v2.0.5 + ; 24/04/2017 +ScanPort: + mov bx, 0210h ; start scanning ports + ; 210h, 220h, .. 260h +ResetDSP: + ; 26/11/2024 + mov dx, bx ; try to reset the DSP. + add dl, 06h + + mov al, 1 + out dx, al + + in al, dx + in al, dx + in al, dx + in al, dx + + xor al, al + out dx, al + + ;add dx, 08h + add dl, 08h + mov cx, 100 +WaitID: + in al, dx + or al, al + js short GetID + loop WaitID + jmp short NextPort +GetID: + ;sub dx, 04h + sub dl, 04h + in al, dx + cmp al, 0AAh + je short Found + ;add dx, 04h + add dl, 04h + loop WaitID +NextPort: + ;add bx, 10h ; if not response, + add bl, 10h + ;cmp bx, 260h ; try the next port. + cmp bl, 60h + jbe short ResetDSP + stc + retn +Found: + mov [audio_io_base], bx ; SB Port Address Found! +ScanIRQ: +SetIrqs: + sub al, al ; 0 + mov [IRQnum], al ; reset + ; 27/11/2024 + ;mov [audio_intr], al + + ; 25/11/2024 + ; save IRQ status + in al, 21h ; save the IMR. + mov [IRQstatus], al + + ; ah > 0 -> set IRQ vector + ; al = IRQ number + mov ax, 105h ; IRQ 5 + ; 26/11/2024 + mov dx, IRQ5_service + call set_hardware_int_vector + mov ax, 107h ; IRQ 7 + ; 26/11/2024 + mov dx, IRQ7_service + call set_hardware_int_vector + + mov dx, [audio_io_base] ; tells to the SB to + ;add dx, 0Ch ; generate a IRQ! + add dl, 0Ch +WaitSb: + in al, dx + or al, al + js short WaitSb + mov al, 0F2h + out dx, al + ; 24/11/2024 + xor cx, cx ; wait until IRQ level +WaitIRQ: + mov al, [IRQnum] + cmp al, 0 ; is changed or timeout. + ja short IrqOk + dec cx + jnz short WaitIRQ + jmp short RestoreIrqs +IrqOk: + ;;; + ; 27/11/2024 + mov [audio_intr], al + mov dx, [audio_io_base] + ;add dx, 0Eh + add dl, 0Eh ; 8bit DMA-mode int ack + in al, dx ; SB acknowledge. + inc dx ; 0Fh ; 16bit DMA-mode int ack + in al, dx ; SB 16 acknowledge. + ;;; + mov al, 20h + out 20h, al ; Hardware acknowledge. +RestoreIrqs: + ; ah = 0 -> reset IRQ vector + ; al = IRQ number + mov ax, 5 ; IRQ 5 + call set_hardware_int_vector + mov ax, 7 ; IRQ 7 + call set_hardware_int_vector + + cmp byte [IRQnum], 1 ; IRQ level was changed? + + retn + +; ---------------------------------- + + ; 24/11/2024 +set_hardware_int_vector: + or ah, ah + jnz short shintv_1 ; set user's audio interrupt handler + +rhintv_1: + ; reset the interrupt vector to the old interrupt handler + push ds + cmp al, 5 + jne short rhintv_2 + + ; 25/11/2024 + ; restore IRQ 5 status + mov ah, [IRQstatus] + in al, 21h + and ah, 00100000b ; 20h + or al, ah + out 21h, al + + mov dx, [old_irq5v_o] + mov ds, [old_irq5v_s] +shintv_3: + mov al, 0Dh + mov ah, 25h + int 21h + pop ds + retn + +rhintv_2: + ; 25/11/2024 + ; restore IRQ 7 status + mov ah, [IRQstatus] + in al, 21h + and ah, 10000000b ; 80h + or al, ah + out 21h, al + + mov dx, [old_irq7v_o] + mov ds, [old_irq7v_s] +shintv_4: + mov al, 0Fh + mov ah, 25h + int 21h + pop ds + retn + +shintv_1: + push es + + cmp al, 5 + jne short shintv_2 + + ; INT 0Dh = IRQ 5 (default) interrupt number + + ; 25/11/2024 + ; enable IRQ 5 + ; 26/11/2024 + in al, 21h + and al, 11011111b + out 21h, al + + mov al, 0Fh + mov ah, 35h ; Get Interrupt Vector + int 21h + mov [old_irq5v_s], es + mov [old_irq5v_o], bx + pop es + push ds + ; 27/11/2024 + ;mov dx, IRQ5_service + jmp short shintv_3 + +shintv_2: + ; al = 7 + ; INT 0Fh = IRQ 7 (default) interrupt number + + ; 25/11/2024 + ; enable IRQ 7 + ; 26/11/2024 + in al, 21h + and al, 01111111b + out 21h, al + + mov al, 0Fh + mov ah, 35h ; Get Interrupt Vector + int 21h + mov [old_irq7v_s], es + mov [old_irq7v_o], bx + pop es + push ds + ; 27/11/2024 + ;mov dx, IRQ7_service + jmp short shintv_4 + +IRQ5_service: + mov byte [cs:IRQnum], 5 + iret + +IRQ7_service: + mov byte [cs:IRQnum], 7 + iret + + ; 27/11/2024 +IRQ_service: + push ds + push dx + push ax + ; + push cs + pop ds + mov byte [IRQnum], 5 + mov dx, [audio_io_base] + ;add dx, 0Eh + add dl, 0Eh ; 8bit DMA-mode int ack + cmp byte [WAVE_BitsPerSample], 8 + jna short irq_ack_@ + inc dl ; 0Fh ; 16bit DMA-mode int ack +irq_ack_@: + in al, dx ; SB acknowledge. + ; + mov al, 20h + out 20h, al ; Hardware acknowledge + ; + pop ax + pop dx + pop ds + iret + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_stop procedure (06/08/2022, v2.0.5) +sb16_stop: + mov dx, [audio_io_base] + ;add dx, 0Ch + add dl, 0Ch + + mov bl, 0D9h ; exit auto-initialize 16 bit transfer + ; stop autoinitialized DMA transfer mode + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb16_stop_1 + ;mov bl, 0DAh ; exit auto-initialize 8 bit transfer + inc bl +sb16_stop_1: + SbOut bl ; exit auto-initialize transfer command + + xor al, al ; stops all DMA processes on selected channel + + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb16_stop_2 + out 0Ch, al ; clear selected channel register + jmp short sb16_stop_3 + +sb16_stop_2: + out 0D8h, al ; clear selected channel register + +sb16_stop_3: + ; 24/11/2024 + mov byte [stopped], 2 ; stop ! +SbDone: + ;mov dx, [audio_io_base] + ;add dx, 0Ch + SbOut 0D0h + SbOut 0D3h +sb16_stop_4: + retn + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_pause procedure (06/08/2022, v2.0.5) +sb16_pause: + mov dx, [audio_io_base] + ;add dx, 0Ch ; Command & Data Port + add dl, 0Ch + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_pause_1 + ; 8 bit samples + mov bl, 0D0h ; 8 bit DMA mode + jmp short sb_pause_2 +sb_pause_1: + ; 16 bit samples + mov bl, 0D5h ; 16 bit DMA mode +sb_pause_2: + SbOut bl ; bCommand +sb_pause_3: + retn + +; ---------------------------------- + + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9 audio.s (06/06/2024) + ; sb16_continue procedure (06/08/2022, v2.0.5) +sb16_play: +sb16_continue: + mov dx, [audio_io_base] + ;add dx, 0Ch ; Command & Data Port + add dl, 0Ch + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_cont_1 + ; 8 bit samples + mov bl, 0D4h ; 8 bit DMA mode + jmp short sb_cont_2 +sb_cont_1: + ; 16 bit samples + mov bl, 0D6h ; 16 bit DMA mode +sb_cont_2: + SbOut bl ; bCommand +sb_cont_3: + retn + +; ---------------------------------- + + ; 14/11/2024 + ; INPUT: ds:dx = file name address + ; OUTPUT: [filehandle] = ; -1 = not open +openFile: + mov ax, 3D00h ; open File for read + int 21h + jnc short _of1 + mov ax, -1 + ; cf = 1 -> not found or access error +_of1: + mov [filehandle], ax + retn + +; ---------------------------------- + +; close the currently open file + + ; 14/11/2024 + ; INPUT: [filehandle] ; -1 = not open + ; OUTPUT: none +closeFile: + cmp word [filehandle], -1 + jz short _cf1 + mov bx, [filehandle] + mov ax, 3E00h + int 21h ; close file +_cf1: + retn + +; ---------------------------------- + + ; 14/11/2024 - Erdogan Tan +getWAVParameters: +; reads WAV file header(s) (44 bytes) from the .wav file. +; entry: none - assumes file is already open +; exit: ax = sample rate (11025, 22050, 44100, 48000) +; cx = number of channels (mono=1, stereo=2) +; dx = bits per sample (8, 16) +; bx = number of bytes per sample (1 to 4) + + mov dx, WAVFILEHEADERbuff + mov bx, [filehandle] + mov cx, 44 ; 44 bytes + mov ah, 3Fh + int 21h + jc short gwavp_retn + + cmp ax, 44 + jb short gwavp_retn + + cmp dword [RIFF_Format], 'WAVE' + jne short gwavp_stc_retn + + cmp word [WAVE_AudioFormat], 1 ; Offset 20, must be 1 (= PCM) + ;jne short gwavp_stc_retn + je short gwavp_retn ; 15/11/2024 + + ; 15/11/2024 + ;mov cx, [WAVE_NumChannels] ; return num of channels in CX + ;mov ax, [WAVE_SampleRate] ; return sample rate in AX + ;mov dx, [WAVE_BitsPerSample] + ; return bits per sample value in DX + ;mov bx, [WAVE_BlockAlign] ; return bytes per sample in BX +;gwavp_retn: + ;retn + + ; 27/11/2024 + ; frequency limit (for SB16) = 44100 kHz + ;cmp word [WAVE_SampleRate], 44101 ; 48000 + ;cmc + ;retn + +gwavp_stc_retn: + stc +gwavp_retn: + retn + +; ---- 30/05/2024 (playwav4.asm, 19/05/2024) + +; MEMALLOC.ASM +;-- SETFREE: Release memory not used ---------------- +;-- Input : ES = address of PSP +;-- Output : none +;-- Register : AX, BX, CL and FLAGS are changed +;-- Info : Since the stack-segment is always the last segment in an +; EXE-file, ES:0000 points to the beginning and SS:SP +; to the end of the program in memory. Through this the +; length of the program can be calculated +; call this routine once at the beginning of the program to free up memory +; assigned to it by DOS. + +setFree: + mov bx, 65536/16 ; 4K paragraphs ; 17/02/2017 (Erdogan Tan) + + mov ah, 4Ah ; pass new length to DOS + int 21h + + retn ; back to caller + ; new size (allocated memory) = 64KB + + ; 27/11/2024 +;memAlloc: +;; input: AX = # of paragraphs required +;; output: AX = segment of block to use +; +; push bx +; mov bx, ax +; mov ah, 48h +; int 21h +; pop bx +; retn + +; ---- + +; ///// + + ; 24/11/2024 (SB16 version of playwav8.asm -> playwav9.asm) + ; 30/05/2024 (ich_wav4.asm, 19/05/2024) +loadFromFile: + ; 18/12/2024 + mov word [count], 0 + + ; 07/11/2023 + test byte [flags], ENDOFFILE ; have we already read the + ; last of the file? + jz short lff_0 ; no + stc + retn + +lff_0: + ; 24/11/2024 + ; 08/11/2023 + mov di, ax ; save buffer address + ; 17/11/2024 + mov bx, [filehandle] + + ; 24/11/2024 + mov cx, LOADSIZE + mov dx, ax ; buffer address + + ; 24/11/2024 + ; load/read file + ; bx = file handle + ; ds = cs + ; ds:dx = buffer + ; cx = read count + mov ah, 3Fh + int 21h + jc short lff_4 ; error ! + + ; 14/11/2024 + mov [count], ax + + cmp ax, cx + je short endLFF + ; 24/11/2024 + ; di = buffer address + add di, ax +lff_3: + call padfill ; blank pad the remainder + ;clc ; don't exit with CY yet. + or byte [flags], ENDOFFILE ; end of file flag +endLFF: + retn +lff_4: + ; 08/11/2023 + mov al, '!' ; error + call tL0 + + xor ax, ax + jmp short lff_3 + +; entry ds:ax points to last byte in file +; cx = target size +; note: must do byte size fill +; destroys bx, cx +; +padfill: + ; 24/11/2024 + ; di = offset (to be filled with ZEROs) + ; es = ds = cs + ; ax = di = number of bytes loaded + ; cx = buffer size (> loaded bytes) + sub cx, ax + xor ax, ax + cmp byte [WAVE_BitsPerSample], 8 + ja short padfill@ + mov al, 80h +padfill@: + rep stosb + retn +; ///// + +write_audio_dev_info: + ; 30/05/2024 + sys_msg msgAudioCardInfo, 0Fh + retn + +write_sb16_dev_info: + ; 24/11/2024 + mov ax, [audio_io_base] + mov bl, al + mov dl, bl + and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBasePort+2], al + mov bl, dl + shr bl, 4 + mov al, [bx+hex_chars] + mov [msgBasePort+1], al + mov bl, ah + mov dl, bl + ;and bl, 0Fh + mov al, [bx+hex_chars] + mov [msgBasePort], al + + xor ax, ax + ;mov al, [IRQnum] + ; 27/11/2024 + mov al, [audio_intr] + ;mov cl, 10 + ;div cl + ;add ah, 30h + ;mov [msgIRQ], ah + ; 25/11/2024 + add al, 30h + mov [msgIRQ], al + + call clear_window + mov dh, 13 + mov dl, 0 + call setCursorPosition + + sys_msg msgSB16Info, 07h + + retn + +; -------------------------------------------------------- +; 24/11/2024 - Sound Blaster 16 initialization +; -------------------------------------------------------- + + ; 25/11/2024 + ; 24/11/2024 + ; Ref: TRDOS 386 Kernel v2.0.9, audio.s (06/06/2024) + ; SbInit_play procedure (06/08/2022, v2.0.5) +SB16Init_play: + mov ax, ds + mov dx, ax + shr dx, 12 + shl ax, 4 + add ax, dma_buffer + adc dx, 0 + mov bx, ax ; linear address + ; dx = page number + + mov cx, dma_buffer_size + + cmp byte [WAVE_BitsPerSample], 16 + jne short sbInit_0 ; set 8 bit DMA buffer + + ; 26/11/2024 + mov ax, dx ; page number + + ; convert byte count to word count + ; 26/11/2024 + ;dec cx + shr cx, 1 + dec cx ; word count - 1 + + ; convert byte offset to word offset + shr ax, 1 + rcr bx, 1 + ; 26/11/2024 + ;shr bx, 1 + + ; 16 bit DMA buffer setting (DMA channel 5) + mov al, 05h ; set mask bit for channel 5 (4+1) + out 0D4h, al + + xor al, al ; stops all DMA processes on selected channel + out 0D8h, al ; clear selected channel register + + mov al, bl ; byte 0 of DMA buffer offset in words (physical) + out 0C4h, al ; DMA channel 5 port number + + mov al, bh ; byte 1 of DMA buffer offset in words (physical) + out 0C4h, al + + ; 26/11/2024 + and dl, 0FEh ; clear bit 0 (not necessary, it will be ignored) + + mov al, dl ; byte 2 of DMA buffer address (physical) + out 8Bh, al ; page register port addr for channel 5 + + mov al, cl ; low byte of DMA count - 1 + out 0C6h, al ; count register port addr for channel 5 + + mov al, ch ; high byte of DMA count - 1 + out 0C6h, al + + ; channel 5, read, autoinitialized, single mode + mov al, 59h + out 0D6h, al ; DMA mode register port address + + mov al, 01h ; clear mask bit for channel 5 + out 0D4h, al ; DMA mask register port address + + jmp short ResetDsp + +sbInit_0: + dec cx ; byte count - 1 + + ; 8 bit DMA buffer setting (DMA channel 1) + mov al, 05h ; set mask bit for channel 1 (4+1) + out 0Ah, al ; DMA mask register + + xor al, al ; stops all DMA processes on selected channel + out 0Ch, al ; clear selected channel register + + mov al, bl ; byte 0 of DMA buffer address (physical) + out 02h, al ; DMA channel 1 port number + + mov al, bh ; byte 1 of DMA buffer address (physical) + out 02h, al + + mov al, dl ; byte 2 of DMA buffer address (physical) + out 83h, al ; page register port addr for channel 1 + + mov al, cl ; low byte of DMA count - 1 + out 03h, al ; count register port addr for channel 1 + + mov al, ch ; high byte of DMA count - 1 + out 03h, al + + ; channel 1, read, autoinitialized, single mode + mov al, 59h + out 0Bh, al ; DMA mode register port address + + mov al, 01h ; clear mask bit for channel 1 + out 0Ah, al ; DMA mask register port address + +ResetDsp: + mov dx, [audio_io_base] + ;add dx, 06h + add dl, 06h + mov al, 1 + out dx, al + + in al, dx + in al, dx + in al, dx + in al, dx + + xor ax, ax + out dx, al + + mov cx, 100 +WaitId: + mov dx, [audio_io_base] + add dl, 0Eh + in al, dx + or al, al + ;js short sb_GetId + ; 26/11/2024 + jns short sb_next + ;loop WaitId + ;jmp sb_Exit + +sb_GetId: + mov dx, [audio_io_base] + ;add dx, 0Ah + add dl, 0Ah + in al, dx + cmp al, 0AAh + je short SbOk +sb_next: + loop WaitId + stc + retn +SbOk: + mov dx, [audio_io_base] + ;add dx, 0Ch + add dl, 0Ch + SbOut 0D1h ; Turn on speaker + SbOut 41h ; 8 bit or 16 bit transfer + mov bx, [WAVE_SampleRate] ; sampling rate (Hz) + SbOut bh ; sampling rate high byte + SbOut bl ; sampling rate low byte + + ; 25/11/2024 + +StartDMA: + ; autoinitialized mode + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit samples + je short sb_play_1 + ; 8 bit samples + mov bx, 0C6h ; 8 bit output (0C6h) + cmp byte [WAVE_NumChannels], 2 ; 1 = mono, 2 = stereo + jb short sb_play_2 + mov bh, 20h ; 8 bit stereo (20h) + jmp short sb_play_2 +sb_play_1: + ; 16 bit samples + mov bx, 10B6h ; 16 bit output (0B6h) + cmp byte [WAVE_NumChannels], 2 ; 1 = mono, 2 = stereo + jb short sb_play_2 + add bh, 20h ; 16 bit stereo (30h) +sb_play_2: + ; PCM output (8/16 bit mono autoinitialized transfer) + SbOut bl ; bCommand + SbOut bh ; bMode + ; 25/11/2024 + mov bx, dma_buffer_size/2 + ; half buffer size + cmp byte [WAVE_BitsPerSample], 16 ; 16 bit DMA + jne short sb_play_3 + shr bx, 1 ; byte count to word count (samples) +sb_play_3: + dec bx ; wBlkSize is one less than the actual size + SbOut bl + SbOut bh + + ; 24/11/2024 + ;mov byte [stopped], 0 ; playing ! +sb_Exit: + retn + +; -------------------------------------------------------- +; 14/11/2024 - Erdogan Tan +; -------------------------------------------------------- + + ; 29/11/2024 + ; 24/11/2024 (SB16 version) +checkUpdateEvents: + call check4keyboardstop + jc short c4ue_ok + + ; 18/11/2024 + push ax ; * + or ax, ax + jz c4ue_cpt + + ; 18/11/2024 + cmp al, 20h ; SPACE (spacebar) ; pause/play + jne short ch4ue_chk_s + cmp byte [stopped], 0 + ja short ch4ue_chk_ps + ; pause + call sb16_pause ; 24/11/2024 + ; 27/11/2024 + mov byte [stopped], 1 + jmp c4ue_cpt +ch4ue_chk_ps: + cmp byte [stopped], 1 + ja short ch4ue_replay + ; continue to play (after a pause) + call sb16_play ; 24/11/2024 + ; 27/11/2024 + mov byte [stopped], 0 + jmp c4ue_cpt +ch4ue_replay: + ; 19/11/2024 + pop ax ; * + pop ax ; return address + ; 24/11/2024 + ; initialize (again) + ; and start playing (after stop) + call SB16Init_play + mov al, [volume] + call SetMasterVolume ; 24/11/2024 + mov byte [stopped], 0 + ; 24/11/2024 + mov byte [half_buffer], 1 + call move_to_beginning + jmp PlayWav + +ch4ue_chk_s: + cmp al, 'S' ; stop + jne short ch4ue_chk_fb + cmp byte [stopped], 0 + ja short c4ue_cpt ; Already stopped/paused + call sb16_stop ; 24/11/2024 + ; 19/11/2024 + mov byte [tLO], 0 + jmp short c4ue_cpt + +ch4ue_chk_fb: + ; 17/11/2024 + cmp al, 'F' + jne short c4ue_chk_b + call Player_ProcessKey_Forwards + jmp short c4ue_cpt + + ; 18/11/2024 +c4ue_ok: + retn + +c4ue_chk_b: + cmp al, 'B' + ;;jne short c4ue_cpt + ; 19/11/2024 + ;jne short c4ue_chk_h + ; 29/11/2024 + jne short c4ue_chk_n + call Player_ProcessKey_Backwards + jmp short c4ue_cpt + + ;;; + ; 29/11/2024 +c4ue_chk_n: + cmp al, 'N' + je short c4ue_nps +c4ue_chk_p: + cmp al, 'P' + jne short c4ue_chk_h +c4ue_nps: + mov byte [stopped], 3 + jmp short c4ue_cpt + ;;; + +c4ue_chk_h: + ; 19/11/2024 + cmp al, 'H' + jne short c4ue_chk_cr + mov byte [wleds], 0 + call write_sb16_dev_info + mov dh, 24 + mov dl, 79 + call setCursorPosition +c4ue_chk_cr: + ; 19/11/2024 + cmp al, 0Dh ; ENTER/CR key + jne short c4ue_cpt + ; 23/11/2024 + xor bx, bx + mov bl, [wleds] + inc bl + and bl, 0Fh + jnz short c4ue_sc + inc bx +c4ue_sc: + mov [wleds], bl + shr bl, 1 + mov al, [bx+colors] + jnc short c4ue_sc_@ + or al, 10h ; blue (dark) background +c4ue_sc_@: + mov [ccolor], al + ;;; +c4ue_cpt: + ;push ds + ;mov bx, 40h + ;mov ds, bx + ;mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;;cli + ;mov ax, [bx] + ;mov dx, [bx+2] + ;;sti + ;pop ds + ; 26/11/2024 + call GetTimerTicks + + ; 18/11/2024 + pop cx ; * + cmp dx, [timerticks+2] + jne short c4ue_utt + cmp ax, [timerticks] + ; 18/11/2024 + je short c4ue_skip_utt +c4ue_utt: + mov [timerticks], ax + mov [timerticks+2], dx + jmp short c4ue_cpt_@ +c4ue_skip_utt: + ; 18/11/2024 + and cx, cx + jz short c4ue_ok +c4ue_cpt_@: + ; 18/11/2024 + cmp byte [stopped], 0 + ja short c4ue_ok + + call CalcProgressTime + + cmp ax, [ProgressTime] + ; 23/11/2024 + je short c4ue_uvb + ; same second, no need to update + + call UpdateProgressBar + + ; 23/11/2024 +c4ue_uvb: + cmp byte [wleds], 0 + jna short c4ue_vb_ok + + call UpdateWaveLeds + +c4ue_vb_ok: + retn + + ; 26/11/2024 +GetTimerTicks: + push ds + mov bx, 40h + mov ds, bx + mov bx, 6Ch ; counter (INT 08h, 18.2 ticks per sec) + ;cli + mov ax, [bx] + mov dx, [bx+2] + ;sti + pop ds + retn + +; -------------------------------------------------------- +; 19/05/2024 - (playwav4.asm) ich_wav4.asm +; -------------------------------------------------------- + + ; 29/11/2024 + ; 24/11/2024 (SB16 version) +check4keyboardstop: + ; 19/05/2024 + ; 08/11/2023 + ; 04/11/2023 + mov ah, 1 + int 16h + ;clc + jz short _cksr + + xor ah, ah + int 16h + + ; 29/11/2024 + mov [command], al + + ;;; + ; 19/05/2024 (change PCM out volume) + cmp al, '+' + jne short p_1 + + mov al, [volume] + ; 24/11/2024 + cmp al, 15 + jnb short p_3 + inc al + jmp short p_2 +p_1: + cmp al, '-' + jne short p_4 + + mov al, [volume] + ; 24/11/2024 + cmp al, 0 + jna short p_3 + dec al +p_2: + mov [volume], al + ; 24/11/2024 + call SetMasterVolume + ;call UpdateVolume + ;;clc + ;retn + jmp UpdateVolume +_cksr: + ; 18/11/2024 + xor ax, ax + ;clc +p_3: + retn +p_4: + ; 17/11/2024 + cmp ah, 01h ; ESC + je short p_q + cmp al, 03h ; CTRL+C + je short p_q + + ; 18/11/2024 + cmp al, 20h + je short p_r + + ; 19/11/2024 + cmp al, 0Dh ; CR/ENTER + je short p_r + + and al, 0DFh + + ; 29/11/2024 + mov [command], al + + ;cmp al, 'B' + ;je short p_r + ;cmp al, 'F' + ;je short p_r + + ; 29/11/2024 + ;cmp al, 'N' + ;je short p_r + ;cmp al, 'P' + ;je short p_r + + cmp al, 'Q' + ;je short p_q + je short p_quit ; 29/11/2024 + + clc + retn + + ;;; +;_cskr: +p_q: + ; 29/11/2024 + mov byte [command], 'Q' +p_quit: + stc +p_r: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 +setCursorPosition: + ; dh = Row + ; dl = Column + mov ax, 0500h + int 10h + mov ah, 02h + mov bh, 00h + ;mov dh, setCursorPosition_Row + ;mov dl, setCursorPosition_Column + int 10h + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; NAME: SetTotalTime +;; DESCRIPTION: Calculates the total time in seconds in file +;; INPUT: DATA_SubchunkSize, WAVE_SampleRate, WAVE_BlockAlign +;; OUTPUT: CurrentTotalTime=Total time in seconds in file, +;; Output on the screen of the total time in seconds + +SetTotalTime: + ;; Calculate total seconds in file + mov ax, [DATA_SubchunkSize] + mov dx, [DATA_SubchunkSize + 2] + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + + mov bx, [WAVE_BlockAlign] + + div bx + + mov [TotalTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 42 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 45 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + ;jmp short PrintNumber + +; -------------------------------------------------------- + +PrintNumber: + ; bp = digits + ; ax = binary number + mov bx, 10 + xor cx, cx +printNumber_CutNumber: + inc cx + xor dx, dx + div bx + push dx + cmp cx, bp + je short printNumber_printloop + jmp printNumber_CutNumber + +printNumber_printloop: + pop ax + mov dl, '0' + add dl, al + mov ah, 02h + int 21h + loop printNumber_printloop + + retn + +; -------------------------------------------------------- + + ; 14/11/2024 - Erdogan Tan +SetProgressTime: + ;; Calculate playing/progress seconds in file + call CalcProgressTime + +UpdateProgressTime: + ; ax = (new) progress time + + mov [ProgressTime], ax + + mov bl, 60 + div bl + + ;; al = minutes, ah = seconds + push ax ; ** + push ax ; * + + mov dh, 24 + mov dl, 33 + call setCursorPosition + + pop ax ; * + xor ah, ah + mov bp, 2 + call PrintNumber + + mov dh, 24 + mov dl, 36 + call setCursorPosition + + pop ax ; ** + mov al, ah + xor ah, ah + ;mov bp, 2 + jmp short PrintNumber + +; -------------------------------------------------------- + + ; 17/11/2024 + ; 14/11/2024 +CalcProgressTime: + mov ax, [LoadedDataBytes] + mov dx, [LoadedDataBytes+2] + mov bx, ax + or bx, dx + jz short cpt_ok + + mov bx, [WAVE_SampleRate] + div bx + xor dx, dx + mov bx, [WAVE_BlockAlign] + div bx +cpt_ok: + ; ax = (new) progress time + retn + +; -------------------------------------------------------- +; 14/11/2024 +; (Ref: player.asm, out_cs.asm, Matan Alfasi, 2017) + +;; DESCRIPTION: Update file information on template +;; PARAMS: WAVE parameters and other variables +;; REGS: AX(RW) +;; VARS: CurrentFileName, WAVE_SampleRate, +;; RETURNS: On-screen file info is updated. + +UpdateFileInfo: + ;; Print File Name + mov dh, 9 + mov dl, 23 + call setCursorPosition + + mov si, wav_file_name + + ;;; + ; 14/11/2024 + ; skip directory separators + ; (note: asciiz string, max. 79 bytes except zero tail) + mov bx, si +chk4_nxt_sep: + lodsb + cmp al, '\' + je short chg_fpos + and al, al + jz short chg_fpos_ok + jmp short chk4_nxt_sep +chg_fpos: + mov bx, si + jmp short chk4_nxt_sep +chg_fpos_ok: + mov si, bx ; file name (without its path/directory) + ;;; + + call PrintString + + ;; Print Frequency + mov dh, 10 + mov dl, 23 + call setCursorPosition + mov ax, [WAVE_SampleRate] + mov bp, 5 + call PrintNumber + + ;; Print BitRate + mov dh, 9 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_BitsPerSample] + mov bp, 2 + call PrintNumber + + ;; Print Channel Number + mov dh, 10 + mov dl, 57 + call setCursorPosition + mov ax, [WAVE_NumChannels] + mov bp, 1 + call PrintNumber + + ;call UpdateVolume + ;retn + +; -------------------------------------------------------- + + ; 24/11/2024 + ; 14/11/2024 +UpdateVolume: + ;; Print Volume + mov dh, 24 + mov dl, 75 + call setCursorPosition + + mov al, [volume] + + mov bl, 100 + mul bl + + mov bl, 15 ; 24/11/2024 + div bl + + xor ah, ah + mov bp, 3 + ;call PrintNumber + ;retn + jmp PrintNumber + +; 24/11/2024 +; 29/05/2024 +; 19/05/2024 +volume: db 12 + +; -------------------------------------------------------- + + ; 14/11/2024 +PrintString: + ; si = string address + mov bx, 0Fh ; white + mov ah, 0Eh ; write as tty +printstr_loop: + lodsb + or al, al + jz short printstr_ok + int 10h + jmp short printstr_loop +printstr_ok: + retn + +; -------------------------------------------------------- + + ; 14/11/2024 + ; (Ref: player.asm , Matan Alfasi, 2017) + ; (Modification: Erdogan Tan, 14/11/2024) + + PROGRESSBAR_ROW equ 23 + +UpdateProgressBar: + call SetProgressTime ; 14/11/2024 + + mov ax, [ProgressTime] +UpdateProgressBar@: + mov dx, 80 + mul dx + mov bx, [TotalTime] + div bx + + ;; Push for the 'Clean' part + push ax ; ** + push ax ; * + + ;; Set cursor position + mov dh, PROGRESSBAR_ROW + mov dl, 0 + call setCursorPosition + + pop ax ; * + or ax, ax + jz short UpdateProgressBar_Clean + +UpdateProgressBar_DrawProgress: + mov cx, ax + mov ah, 09h + mov al, 223 + mov bx, 0Fh + int 10h + +UpdateProgressBar_DrawCursor: + ;mov ax, cx + mov dh, PROGRESSBAR_ROW + ;mov dl, al + dec cx + mov dl, cl + call setCursorPosition + + mov ah, 09h + mov al, 223 + mov bx, 0Ch + mov cx, 1 + int 10h + +UpdateProgressBar_Clean: + pop ax ; ** + mov cx, ax + mov dh, PROGRESSBAR_ROW + mov dl, al + call setCursorPosition + + neg cx + add cx, 80 ; cf = 1 ; + + ;; CX = No. of times to print a clean character + ;mov cx, 80 + ;sub cx, ax + ;; 09h = Write character multiple times + mov ah, 09h + ;; 32 = Space ASCII code + ;mov al, 32 + ;mov bx, 0 + ; 15/11/2024 + mov al, 223 + mov bx, 8 + int 10h + ; 14/11/2024 + clc ; + + + retn + +; -------------------------------------------------------- +; 17/11/2024 + +Player_ProcessKey_Backwards: + ;; In order to go backwards 5 seconds: + ;; Update file pointer to the beginning, skip headers + mov cl, 'B' + jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_Forwards: + ;; In order to fast-forward 5 seconds, set the file pointer + ;; to CUR_SEEK + 5 * Freq + + mov cl, 'F' + ;jmp short Player_ProcessKey_B_or_F + +Player_ProcessKey_B_or_F: + ; 17/11/2024 + ; 04/11/2024 + ; (Ref: player.asm, Matan Alfasi, 2017) + + ; 04/11/2024 + mov ax, 5 + mov bx, [WAVE_BlockAlign] + mul bx + mov bx, [WAVE_SampleRate] + mul bx + ; dx:ax = transfer byte count for 5 seconds + + ; 17/11/2024 + cmp cl, 'B' + mov bx, [LoadedDataBytes] + mov cx, [LoadedDataBytes+2] + jne short move_forward ; cl = 'F' +move_backward: + sub bx, ax + sbb cx, dx + jnc short move_file_pointer +move_to_beginning: + xor cx, cx ; 0 + xor bx, bx ; 0 + jmp short move_file_pointer +move_forward: + add bx, ax + adc cx, dx + jc short move_to_end + cmp cx, [DATA_SubchunkSize+2] + ja short move_to_end + jb short move_file_pointer + cmp bx, [DATA_SubchunkSize] + jna short move_file_pointer +move_to_end: + mov bx, [DATA_SubchunkSize] + mov cx, [DATA_SubchunkSize+2] +move_file_pointer: + mov dx, bx + mov [LoadedDataBytes], dx + mov [LoadedDataBytes+2], cx + add dx, 44 ; + header + adc cx, 0 + + ; seek + mov bx, [filehandle] + mov ax, 4200h + int 21h + + retn + +; -------------------------------------------------------- + + ; 19/11/2024 +UpdateWaveLeds: + ; 23/11/2024 + call reset_wave_leds + ;call word [turn_on_leds] + ;retn + jmp word [turn_on_leds] + +; -------------------------------------------------------- + + ; 23/11/2024 + ; 19/11/2024 +clear_window: + xor ax, ax + jmp short clear_window_@ + +reset_wave_leds: + ; 23/11/2024 + ;mov al, 254 + ;mov ah, 8 ; gray (dark) + mov ax, 08FEh +clear_window_@: + push es + mov di, 0B800h + mov es, di + mov di, 2080 ; 13*80*2 + mov cx, 8*80 ; 8 rows + rep stosw + pop es + retn + +; -------------------------------------------------------- + + ; 24/11/2024 + ; 19/11/2024 +turn_on_leds_stereo_16bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol_buffer_1 + +tol_buffer_2: + ; 21/11/2024 + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol_@ + +tol_buffer_1: + cmp byte [tLO],'1' + ;jne short tol_retn + ; 23/11/2024 + jne short tol_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol_o_@ + cmp si, cx + jna short tol_s_buf +tol_o_@: + mov si, cx + jmp short tol_s_buf + +tol_clc_retn: + ; 23/11/2024 + clc +tol_retn: + ; 25/11/2024 + pop es + retn + +tol_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol_s_buf: + mov [pbuf_o], si + +tol_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + ;mov di, (20*80*2)-2 + + ; 23/11/2024 + mov cx, 80 + + ; 22/11/2024 + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol_fill_c: + ; 22/11/2024 + ;inc di + ;inc di + ;push di + lodsw ; left + ;shr ax, 8 + mov dx, ax + lodsw ; right + ;shr ax, 8 + ;;; + ; 23/11/2024 + add ax, dx + shr ax, 8 + ;shr ax, 9 + add al, 80h + shr ax, 5 + ;;; + ;shr ax, 6 + + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + ; 23/11/2024 + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol_fill_c + + jmp short tol_retn + + + ; 24/11/2024 + ; 23/11/2024 +turn_on_leds_mono_16bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol2_buffer_1 + +tol2_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol2_@ + +tol2_buffer_1: + cmp byte [tLO],'1' + jne short tol_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol2_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol2_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol2_o_@ + cmp si, cx + jna short tol2_s_buf +tol2_o_@: + mov si, cx + jmp short tol2_s_buf + +;tol2_clc_retn: +; clc +;tol2_retn: +; ; 25/11/2024 +; pop es +; retn + +tol2_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol2_s_buf: + mov [pbuf_o], si + +tol2_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol2_fill_c: + lodsw + shr ax, 8 + add al, 80h + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol2_fill_c + + jmp tol_retn + + ; 24/11/2024 +turn_on_leds_stereo_8bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol3_buffer_1 + +tol3_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol3_@ + +tol3_buffer_1: + cmp byte [tLO],'1' + jne short tol3_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol3_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol3_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol3_o_@ + cmp si, cx + jna short tol3_s_buf +tol3_o_@: + mov si, cx + jmp short tol3_s_buf + +tol3_clc_retn: + clc +tol3_retn: + ; 25/11/2024 + pop es + retn + +tol3_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol3_s_buf: + mov [pbuf_o], si + +tol3_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol3_fill_c: + lodsw ; left (al), right (ah) + add al, ah + add al, 80h + xor ah, ah + ;shr ax, 6 + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol3_fill_c + + jmp short tol3_retn + + ; 24/11/2024 + ; 23/11/2024 +turn_on_leds_mono_8bit: + ; 25/11/2024 + push es + + cmp byte [tLO],'2' + jne short tol4_buffer_1 + +tol4_buffer_2: + mov si, wav_buffer2 ; 24/11/2024 + jmp short tol4_@ + +tol4_buffer_1: + cmp byte [tLO],'1' + jne short tol3_clc_retn + + mov si, wav_buffer1 ; 24/11/2024 +tol4_@: + ; calculate differential + cmp [pbuf_s], si + jne short tol4_ns_buf + mov bx, [wleds_dif] + mov si, [pbuf_o] + ; 24/11/2024 + mov cx, LOADSIZE + sub cx, bx ; sub cx, [wleds_dif] + add si, bx + jc short tol4_o_@ + cmp si, cx + jna short tol4_s_buf +tol4_o_@: + mov si, cx + jmp short tol4_s_buf + +;tol4_clc_retn: +; clc +;tol4_retn: +; ; 25/11/2024 +; pop es +; retn + +tol4_ns_buf: + mov [pbuf_s], si + xor si, si ; 0 +tol4_s_buf: + mov [pbuf_o], si + +tol4_buf_@: + ; 25/11/2024 + mov di, 0B800h + mov es, di + + mov cx, 80 + + mov bx, wleds_addr + + ; 27/11/2024 + add si, [pbuf_s] +tol4_fill_c: + lodsb + ; 27/11/2024 + add ax, ax + add al, 80h + xor ah, ah + shr ax, 5 + push bx + shl ax, 1 + add bx, ax + ; 25/11/2024 + mov di, [bx] + mov ah, [ccolor] + mov al, 254 + mov [es:di], ax + pop bx + add bx, 16 + loop tol4_fill_c + + jmp tol3_retn + +; -------------------------------------------------------- + +; 30/05/2024 +print_msg: + mov bx, 07h +p_msg: + push es + push bp + push cx + push dx + + push ds + pop es + mov bp, si + mov ah, 03h ; Return cursor position (in DX) + ; bh = video page number + int 10h + xor cx, cx +p_msg_0: + lodsb + or al, al + jz short p_msg_1 + inc cx + jmp short p_msg_0 +p_msg_1: + or cx, cx + jz short p_msg_x + ; cx = number of chars + ; dx = screen (cursor) position + ; bl = color/attribute + ; bh = video page number + ; es:bp = string buffer + ;mov al, 1 ; attribute in BL, update cursor pos + ;mov ah, 13h ; write character string + mov ax, 1301h + int 10h +p_msg_x: + pop dx + pop cx + pop bp + pop es + retn + +; -------------------------------------------------------- +; -------------------------------------------------------- + +; DATA + +Credits: + db 'Tiny WAV Player for Retro DOS by Erdogan Tan. ' + db 'December 2024.',10,13,0 + db '18/12/2024', 10,13,0 + +msgAudioCardInfo: + db 'for Sound Blaster 16 audio device.', 10,13,0 + +msg_usage: + db 'usage: SB16PLAY <...>',10,13,0 ; 29/11/2024 + + ; 24/11/2024 +noDevMsg: + db 'Error: Unable to find Sound Blaster 16 audio device!' + db 10,13,0 + +noFileErrMsg: + db 'Error: file not found.',10,13,0 + +msg_error: ; 30/05/2024 + +; 24/11/2024 +msg_init_err: + db 0Dh, 0Ah + db "Sound Blaster 16 hardware initialization error !" + db 0Dh, 0Ah, 0 + +; 19/11/2024 +; 03/06/2017 +hex_chars: db "0123456789ABCDEF", 0 + +; 24/11/2024 +msgSB16Info: db 0Dh, 0Ah + db " Audio Hardware: Sound Blaster 16", 0Dh, 0Ah + db " Base Port: " +msgBasePort: db "000h", 0Dh, 0Ah + db " IRQ: " +msgIRQ: db 30h + db 0Dh, 0Ah, 0 + +; -------------------------------------------------------- +; 14/11/2024 (Ref: player.asm, Matan Alfasi, 2017) + +SplashScreen: + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " _______ ______ _______. ", 221, 219, 222 + db 221, 219, 222, " | \ / __ \ / | ", 221, 219, 222 + db 221, 219, 222, " | .--. | | | | | (----` ", 221, 219, 222 + db 221, 219, 222, " | | | | | | | \ \ ", 221, 219, 222 + db 221, 219, 222, " | '--' | `--' | .----) | ", 221, 219, 222 + db 221, 219, 222, " |_______/ \______/ |_______/ ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " .______ __ ___ ____ ____ _______ .______ ", 221, 219, 222 + db 221, 219, 222, " | _ \ | | / \ \ \ / / | ____|| _ \ ", 221, 219, 222 + db 221, 219, 222, " | |_) | | | / ^ \ \ \/ / | |__ | |_) | ", 221, 219, 222 + db 221, 219, 222, " | ___/ | | / /_\ \ \_ _/ | __| | / ", 221, 219, 222 + db 221, 219, 222, " | | | `----./ _____ \ | | | |____ | |\ \----. ", 221, 219, 222 + db 221, 219, 222, " | _| |_______/__/ \__\ |__| |_______|| _| `._____| ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " WELCOME TO ", 221, 219, 222 + db 221, 219, 222, " DOS PLAYER ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db 221, 219, 222, " ", 221, 219, 222 + db " " +Template: + db 201, 78 dup(205), 187 + db 186, 33 dup(219), " DOS Player ", 33 dup(219), 186 + db 204, 78 dup(205), 185 + db 186, 33 dup(32), " User Guide ", 33 dup(32), 186 + ; 29/11/2024 + db 186, 6 dup(32), " Play/Pause ", 4 dup(32), "/

Next/Previous", 9 dup(32), 186 + db 186, 6 dup(32), " Stop ", 4 dup(32), " Wave Lighting", 9 dup(32), 186 + db 186, 6 dup(32), " Forwards ", 4 dup(32), "<+>/<-> Inc/Dec Volume", 8 dup(32), 186 + db 186, 6 dup(32), " Backwards ", 4 dup(32), " Quit Program ", 9 dup(32), 186 + db 204, 78 dup(205), 185 + db 186, 6 dup(32), "File Name : ", 4 dup(32), "Bit-Rate : 0 Bits ", 9 dup(32), 186 + db 186, 6 dup(32), "Frequency : 0 Hz ", 4 dup(32), "#-Channels: 0 ", 9 dup(32), 186 + db 200, 78 dup(205), 188 + db 80 dup(32) +improper_samplerate_txt: ; 03/11/2024 +read_error_txt: + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(32) + db 80 dup(205) + db 80 dup(32) + db 33 dup(32), "00:00 ", 174, 175, " 00:00", 24 dup(32), "VOL 000%" +; 29/11/2024 +IsInSplash: db 1 +SplashFileName: db "SPLASH.WAV", 0 + +; 23/11/2024 +colors: db 0Fh, 0Bh, 0Ah, 0Ch, 0Eh, 09h, 0Dh, 0Fh + ; white, cyan, green, red, yellow, blue, magenta +ccolor: db 0Bh ; cyan + +; 24/11/2024 +half_buffer: db 1 ; dma half buffer 1 or 2 (0 or 1) + ; (initial value = 1 -> after xor in TuneLoop -> 0) +EOF: + +; BSS + +align 2 + +; 24/11/2024 +; 22/11/2024 +; wave volume leds address array +wleds_addr: rw 80*8 ; rb 2*80*8 + +; 24/11/2024 (SB16 version of playwav8.com -> playwav9.com) +; 14/11/2024 +; 17/02/2017 +bss_start: + +; 13/11/2024 +; ('resb','resw','resd' to 'rb','rw','rd' conversions for FASM) + +; 24/11/2024 +old_irq5v_o: rw 1 +old_irq5v_s: rw 1 +old_irq7v_o: rw 1 +old_irq7v_s: rw 1 +; +IRQnum: rb 1 +; 27/11/2024 +audio_intr: rb 1 +; 25/11/2024 +IRQstatus: rb 1 + +; 18/11/2024 +stopped: rb 1 +tLO: rb 1 +; 19/11/2024 +wleds: rb 1 +wleds_dif: rw 1 +pbuf_s: rw 1 +pbuf_o: rw 1 + +; 25/11/2024 +align 4 + +;;;;;;;;;;;;;; +; 14/11/2024 +; (Ref: player.asm, Matan Alfasi, 2017) +WAVFILEHEADERbuff: +RIFF_ChunkID: rd 1 ; Must be equal to "RIFF" - big-endian + ; 0x52494646 +RIFF_ChunkSize: + rd 1 ; Represents total file size, not + ; including the first 2 fields + ; (Total_File_Size - 8), little-endian +RIFF_Format: + rd 1 ; Must be equal to "WAVE" - big-endian + ; 0x57415645 + +;; WAVE header parameters ("Sub-chunk") +WAVE_SubchunkID: + rd 1 ; Must be equal to "fmt " - big-endian + ; 0x666d7420 +WAVE_SubchunkSize: + rd 1 ; Represents total chunk size +WAVE_AudioFormat: + rw 1 ; PCM (Raw) - is 1, other - is a form + ; of compression, not supported. +WAVE_NumChannels: + rw 1 ; Number of channels, Mono-1, Stereo-2 +WAVE_SampleRate: + rd 1 ; Frequency rate, in Hz (8000, 44100 ...) +WAVE_ByteRate: rd 1 ; SampleRate * NumChannels * BytesPerSample +WAVE_BlockAlign: + rw 1 ; NumChannels * BytesPerSample + ; Number of bytes for one sample. +WAVE_BitsPerSample: + rw 1 ; 8 = 8 bits, 16 = 16 bits, etc. + +;; DATA header parameters +DATA_SubchunkID: + rd 1 ; Must be equal to "data" - big-endian + ; 0x64617461 +DATA_SubchunkSize: + rd 1 ; NumSamples * NumChannels * BytesPerSample + ; Number of bytes in the data. +;;;;;;;;;;;;;; + +; 15/11/2024 +cursortype: rw 1 + +filehandle: rw 1 + +flags: rb 1 ; (END_OF_FILE flag) + rb 1 + +audio_io_base: rw 1 ; Sound Blaster 16 base port address (220h) + +; 29/11/2024 +command: rb 1 +filecount: rb 1 +PSP_CurrentOffset: rw 1 + +; 30/05/2024 +wav_file_name: + rb 80 ; wave file, path name (<= 80 bytes) + + rw 1 +; 24/11/2024 +align 4 + +; 23/11/2024 +turn_on_leds: rw 1 ; turn_on_leds procedure pointer (m8,m16,s8,s16) + +; 14/11/2024 +TotalTime: rw 1 ; Total (WAV File) Playing Time in seconds +ProgressTime: rw 1 +count: rw 1 ; byte count of one (wav file) read +LoadedDataBytes: + rd 1 ; total read/load count + +timerticks: rd 1 ; (to eliminate excessive lookup of events in TuneLoop) + ; (in order to get the emulator/qemu to run correctly) +align 16 + +; 24/11/2024 +dma_buffer: ; 32768 bytes +wav_buffer1: rb dma_buffer_size/2 ; 16384 +wav_buffer2: rb dma_buffer_size/2 ; 16384 + +bss_end: diff --git a/trdos386/programs/16bit/sb16play_com_2024.zip b/trdos386/programs/16bit/sb16play_com_2024.zip new file mode 100644 index 0000000..de6fce3 Binary files /dev/null and b/trdos386/programs/16bit/sb16play_com_2024.zip differ