---

; By Joshua Jensen ; ; I realize this isn't the most efficiently coded piece of work, but I was in ; a hurry, so you'll have to deal with it! ideal P286 model Huge jumps stack 1024 codeseg assume cs:@code,ds:MyData Base dw 220h proc UDelay push dx ax mov dx,300h in al,dx in al,dx in al,dx in al,dx in al,dx in al,dx in al,dx pop ax dx ret endp UDelay ; BX:CX Set to whatever. proc U_Peek push dx mov dx,[cs:Base] add dx,103h ; 103h mov al,43h out dx,al inc dx ; 104h mov ax,cx out dx,ax dec dx ; 103h mov al,44h out dx,al add dx,2 mov al,bl out dx,al add dx,2 in al,dx pop dx ret endp U_Peek ; BX:CX Set to whatever. ; AX Value to poke proc U_Poke push dx ax mov dx,[cs:Base] add dx,103h mov al,43h out dx,al inc dx mov ax,cx out dx,ax dec dx mov al,44h out dx,al add dx,2 mov al,bl out dx,al add dx,2 pop ax out dx,al pop dx ret endp U_Poke ; DX - Base. proc U_Probe mov dx,[cs:Base] add dx,0103h ; 103h mov al,4Ch out dx,al add dx,2 ; 105h mov al,0 out dx,al call UDelay call UDelay sub dx,2 ; 103h mov al,4Ch out dx,al add dx,2 ; 105h mov al,1 out dx,al mov ax,0AAh mov bx,0 mov cx,0 call U_Poke mov ax,055h mov bx,1 call U_Poke mov bx,0 call U_Peek push ax mov ax,0 call U_Poke sub dx,2 ; 103h mov al,4Ch out dx,al add dx,2 ; 105h mov al,0 out dx,al pop ax cmp al,0AAh jnz @@Nope clc ret @@Nope: stc ret endp U_Probe proc U_Reset mov dx,[cs:Base] add dx,103h ; 103h mov al,4Ch ; Turns on memory writes. out dx,al add dx,2 ; 105h mov al,1 out dx,al call UDelay sub dx,2 mov al,4Ch ; ??? The samples won't play without it. out dx,al add dx,2 ; 105h mov al,7 out dx,al sub dx,2 mov al,0Eh ; Turn off stereo (or something). out dx,al ; Try taking it out and running PlayFile. add dx,2 mov al,0dfh out dx,al mov cx,0 ; Voice Number @@VoiceLoop: mov dx,[cs:Base] add dx,102h ; 102h mov al,cl out dx,al inc dx ; 103h mov al,0 out dx,al add dx,2 ; 105h mov al,3 out dx,al sub dx,2 ; 103h inc cx cmp cx,32 jl @@VoiceLoop ret endp U_Reset ; Returns: ; 0 = No Ram ; 1 = 256k ; 2 = 512k ; 3 = 768k ; 4 = 1024k proc U_SizeDRAM mov bx,0 mov cx,0 @@DRAMLoop: push cx mov cx,0 mov ax,0AAh call U_Poke call U_Peek pop cx cmp al,0AAh jnz @@Exit add bx,4 inc cx cmp cx,4 jbe @@DRAMLoop @@Exit: mov ax,cx ret endp U_SizeDRAM ; BX - Voice ; AX - Frequency proc U_SetFreq ; Close enough for me... xor dx,dx mov cx,19 div cx push ax mov dx,[cs:Base] add dx,102h ; 102h mov ax,bx out dx,al inc dx ; 103h mov al,1 out dx,al inc dx ; 104h pop ax out dx,ax ret endp U_SetFreq ; AX - Voice ; BX - Balance (0-f) 7 is middle proc U_SetBalance mov dx,[cs:Base] add dx,102h out dx,al inc dx mov al,0ch out dx,al add dx,2 mov ax,bx out dx,al ret endp U_SetBalance ; AX - Voice ; BX - Volume proc U_SetVolume mov dx,[cs:Base] add dx,102h out dx,al inc dx mov al,9 out dx,al inc dx mov ax,bx out dx,ax ret endp U_SetVolume ; AX - Voice ; BX - Mode ; bit 0: 0=voice on (along with bit 1) ; bit 1: 0=voice on (along with bit 0) ; bit 2: 0=8 bit data, 1=16 bit data ; bit 3: 0=No loop, 1=Loop ; bit 4: 0=Go forward, 1=Go backward proc U_SetLoopMode mov dx,[cs:Base] add dx,102h out dx,al inc dx mov al,80h add dx,2 in al,dx mov bh,al sub dx,2 xor al,al out dx,al add dx,2 and bh,0e7h or bh,bl mov al,bh out dx,al ret endp U_SetLoopMode ; AX - Voice proc U_StopVoice mov dx,[cs:Base] add dx,102h out dx,al inc dx mov al,80h add dx,2 in al,dx mov bh,al sub dx,2 xor al,al out dx,al add dx,2 mov al,bh and bh,0dfh or al,3 out dx,al call UDelay sub dx,2 xor al,al out dx,al add dx,2 mov al,bh and bh,0dfh or al,3 out dx,al ret endp U_StopVoice SampleBegin dd 0 ; (Start location in DRAM, apparently 32-byte aligned) SampleStart dd 0 ; (Start location of loop) SampleEnd dd 0 ; (End of sample) ; AX - Voice ; BX - Mode proc U_StartVoice push bx mov dx,[cs:Base] add dx,102h ; 102h out dx,al ; Send sample begin inc dx ; 103h mov al,0ah out dx,al inc dx ; 104h mov ax,[Word cs:SampleBegin] mov cx,[Word cs:SampleBegin+2] call RShift out dx,ax dec dx ; 103h mov al,0bh out dx,al inc dx ; 104h mov ax,[Word cs:SampleBegin] shl ax,9 out dx,ax dec dx ; 103h ; Send sample start mov al,2 out dx,al inc dx ; 104h mov ax,[Word cs:SampleStart] mov cx,[Word cs:SampleStart+2] call RShift out dx,ax dec dx ; 103h mov al,3 out dx,al inc dx ; 104h mov ax,[Word cs:SampleStart] shl ax,9 out dx,ax dec dx ; 103h ; Send sample end mov al,4 out dx,al inc dx ; 104h mov ax,[Word cs:SampleEnd] mov cx,[Word cs:SampleEnd+2] call RShift out dx,ax dec dx ; 103h mov al,5 out dx,al inc dx ; 104h mov ax,[Word cs:SampleEnd] shl ax,9 out dx,ax dec dx ; 103h mov al,0 out dx,al pop ax add dx,2 ; 105h out dx,al ret endp U_StartVoice ; CX:AX - Number proc RShift mov bx,cx shr ax,7 shr cx,7 shl bx,9 or ax,bx ret endp RShift ; AX - Voice ; Returns: DX:AX - Position proc U_ReadPos mov dx,[cs:Base] add dx,102h ; 102h out dx,al inc dx ; 103h mov al,8ah out dx,al inc dx ; 104h in ax,dx ; TEMP0 mov cx,ax dec dx ; 103h mov al,8bh out dx,al inc dx ; 104h in ax,dx ; TEMP1 shl cx,7 shr ax,9 and ax,7Fh mov dx,ax and dx,0Fh mov ax,cx ret endp U_ReadPos ; AX-Mixer control ; bit 0: 0=linein on, 1=linein off ; bit 1: 0=output on, 1=output off ; bit 2: 0=micin off, 1=micin on proc U_ChangeInOut mov dx,[cs:Base] out dx,al ret endp U_ChangeInOut ; The only reason I do it this way is because I haven't figured out the dump ; RAM to DRAM via DMA yet. ; ; Dump sample to Ram ; ES:BX - Max 64k sample to dump to RAM. ; SI:DI - DRAM location to dump to. ; CX - Max bytes to dump. ; AH - Xor value for twos complement. Should actually be negated, but ; oh, well. ; ; Approximate time to dump 1 megabyte of samples to DRAM (assuming they were ; all loaded in memory) is 5 seconds. proc U_DumpSampleToDRAM mov dx,[cs:Base] add dx,103h mov al,44h ; Dump upper byte, only do it on carry from now out dx,al ; on. add dx,2 push ax mov ax,si out dx,al pop ax sub dx,2 @@MainLoop: mov al,43h out dx,al inc dx push ax mov ax,di out dx,ax pop ax dec dx add di,1 jnc @@DumpByte inc si mov al,44h out dx,al add dx,2 push ax mov ax,si out dx,al pop ax sub dx,2 @@DumpByte: add dx,4 mov al,[es:bx] xor al,ah inc bx out dx,al sub dx,4 loop @@MainLoop ret endp U_DumpSampleToDRAM proc U_DumpDRAMToMemory mov dx,[cs:Base] add dx,103h mov al,44h ; Dump upper byte, only do it on carry from now out dx,al ; on. add dx,2 mov ax,si out dx,al sub dx,2 @@MainLoop: mov al,43h out dx,al inc dx mov ax,di out dx,ax dec dx add di,1 jnc @@DumpByte inc si mov al,44h out dx,al add dx,2 mov ax,si out dx,al sub dx,2 @@DumpByte: add dx,4 in al,dx mov [es:bx],al inc bx sub dx,4 loop @@MainLoop ret endp U_DumpDRAMToMemory ; Carry set - No GUS ; No carry - GUS at Base proc U_DetectGUS mov [Word cs:Base],210h @@TestIt: call U_Probe jnb @@FoundIt add [Word cs:Base],10h cmp [Word cs:Base],270h jb @@TestIt stc @@FoundIt: ret endp U_DetectGUS proc LoadDumpSample mov ah,48h mov bx,14848/4+1 int 21h mov [SampleSeg],ax mov ax,3D00h mov dx,offset FName int 21h mov bx,ax push ds mov ah,3Fh mov cx,14848 mov dx,0 mov ds,[SampleSeg] int 21h pop ds mov ax,3E00h int 21h mov es,[SampleSeg] mov bx,0 mov cx,14848 mov si,0 mov di,0 mov ah,10000000b call U_DumpSampleToDRAM ret endp LoadDumpSample proc LoadDumpSample2 mov ah,48h mov bx,9900/4+1 int 21h mov [SampleSeg2],ax mov ax,3D00h mov dx,offset FName2 int 21h mov bx,ax push ds mov ah,3Fh mov cx,9900 mov dx,0 mov ds,[SampleSeg2] int 21h pop ds mov ax,3E00h int 21h mov es,[SampleSeg2] mov bx,0 mov cx,9900 mov si,1 mov di,0 mov ah,0 call U_DumpSampleToDRAM ret endp LoadDumpSample2 Balance db 7 Volume dw 0d000h Mode db 0 Start: mov ax,es mov bx,zzzzzseg sub bx,ax add bx,2 mov ah, 4ah int 21h mov ax,MyData mov ds,ax call U_DetectGUS call U_Reset mov al,0 call U_ChangeInOut call LoadDumpSample call LoadDumpSample2 mov ax,1 mov bx,7 call U_SetBalance mov bx,1 mov ax,8448 call U_SetFreq mov ax,1 mov bx,0ffffh call U_SetVolume mov [Word cs:SampleBegin],0 mov [Word cs:SampleBegin+2],0 mov [Word cs:SampleStart],0 mov [Word cs:SampleStart+2],0 mov [Word cs:SampleEnd],14847 mov [Word cs:SampleEnd+2],0 mov ax,1 mov bx,00001000b call U_StartVoice mov ax,0 mov bx,7 call U_SetBalance mov bx,0 mov ax,27186 call U_SetFreq mov ax,0 mov bx,[cs:Volume] call U_SetVolume mov [Word cs:SampleBegin],0 mov [Word cs:SampleBegin+2],1 mov [Word cs:SampleStart],0 mov [Word cs:SampleStart+2],1 mov [Word cs:SampleEnd],9899 mov [Word cs:SampleEnd+2],1 mov ax,0 mov bx,00001000b call U_StartVoice @@KeyLoop: mov ah,0 int 16h cmp al,'=' jnz @@CheckNext cmp [Byte cs:Balance],15 jz @@KeyLoop inc [Byte cs:Balance] mov ax,1 mov bl,[cs:Balance] call U_SetBalance jmp @@KeyLoop @@CheckNext: cmp al,'-' jnz @@CheckVolUp cmp [Byte cs:Balance],0 jz @@KeyLoop dec [Byte cs:Balance] mov ax,1 mov bl,[cs:Balance] call U_SetBalance jmp @@KeyLoop @@CheckVolUp: cmp al,'2' jnz @@CheckVolDown add [Word cs:Volume],500 jnc @@SetVol mov [Word cs:Volume],0ffffh @@SetVol: mov ax,0 mov bx,[cs:Volume] call U_SetVolume jmp @@KeyLoop @@CheckVolDown: cmp al,'1' jnz @@CheckSpace sub [Word cs:Volume],500 jnc @@SetVol2 mov [Word cs:Volume],0 @@SetVol2: mov ax,0 mov bx,[cs:Volume] call U_SetVolume jmp @@KeyLoop @@CheckSpace: cmp al,' ' jnz @@CheckQuit xor [Byte Mode],00000011b mov ax,1 mov bl,[Mode] call U_SetLoopMode jmp @@KeyLoop @@CheckQuit: cmp al,27 jnz @@KeyLoop mov ax,0 call U_StopVoice mov ax,1 call U_StopVoice mov ah,49h mov es,[SampleSeg] int 21h mov ah,49h mov es,[SampleSeg2] int 21h mov ax,4C00h int 21h segment MyData SampleSeg dw ? SampleSeg2 dw ? FName db 's',0 FName2 db 'orchhit',0 ends MyData segment zzzzzseg db 16 dup (?) ends zzzzzseg end Start

---

The views and opinions stated within this web page are those of the author or authors which wrote them and may not reflect the views and opinions of the ISP or account user which hosts the web page. The opinions may or may not be those of the Chairman of The Skeptic Tank.

Return to The Skeptic Tank's main Index page.

E-Mail Fredric L. Rice / The Skeptic Tank