.model small .386P DGROUP group _DATA tchannel struct PLAYPOS DD ? STARTLOOP DD ? ENDLOOP DD ? SPEEDMAJ DD ? SPEEDMIN DW ? MINORPOS DW ? SMPTYPE DW ?;0 - DISABLED, 1 - 8 BIT, 2 - 16 BIT VOLUMELEFT DW ? VOLUMERIGHT DW ? tchannel ends rm_playdata struct XLAT_TAB DB 256 DUP(?) SCANOFS DW ? SCANSEG DW ? PORT DW ? rm_playdata ends extrn _chaninfo:dword extrn _mixbuffer:dword extrn _backsnd:dword ;ukazatel na buffer s hudbou na pozadi (64Kb) extrn _backstep:dword ;krok o kolik se meni _backsnd extrn _backfine:dword ;citac udavajici kdy se zmeni _backsnd extrn _backsndbuff:dword ;buffer hudby na pozadi extrn _call_back_data:dword ;data_call_back_procedury extrn _call_back_sel:word ;data_call_back_procedury extrn _jumptable:dword[3] ;[0] - skip, [1] - mix8, [2] - mix16 extrn _getdma:dword extrn _ido:dword extrn _predstih:word extrn _lastdma:dword extrn _lastmix:dword extrn _surpos:dword extrn _mixpos:dword extrn _mixsize:dword extrn _samplerate:dword extrn _dmaposadr:dword extrn _dmasizadr:dword extrn _dmanum:byte extrn _dpmiselector:word extrn _idt_map:dword extrn _test_counter:dword extrn _mixer_zavora:byte extrn _timer_test_port:word extrn _oldvect:dword extrn _devport:dword extrn _devirq:dword extrn _gus_dma_type:byte extrn _gus_last_buff:byte _TEXT segment byte public 'CODE' use32 assume CS:_TEXT assume DS:DGROUP gus_out equ 0 gus_irqs equ 6 gus_timer_c equ 8 gus_timer_d equ 9 gus_irq_dma equ 0bh gus_voice equ 102h gus_reg equ 103h gus_reg_data equ 104h gus_pio equ 107h gus_block equ 2000h PUBLIC MIXER_ MIXER_: ;THIS IS MAIN MIXING PROCEDURE. ;BEFORE USING, YOU MUST SET UP ALL VARIBLES TO THE CORRECT VALUES. ;_MIXBUFFER MUST START ON PAGE OF MEMORY (EX. 0x10000 0x20000 0x30000) ;PROCEDURE MUST BE CALLED EACH 55ms OR LITTLE. ;IF YOU USING INTERRUPT, REMEBER, THAT YOU MUST STORE ALL REGISTERS ;BEFORE USE. cmp _mixer_zavora,0 jnz mixend inc _mixer_zavora CALL calcsize ;VYPOCET DELKY MIXOVANI mov edi,_mixpos ;Nejprve se vymaze mixovaci pamet mov ecx,_mixsize shr ecx,2 jz MIXALL MIXOK: xor eax,eax MIXCLR: mov [edi],ax add di,2 mov [edi],ax add di,2 dec ecx jnz MIXCLR lea ebx,_chaninfo ;TED SE ZACNE MIXOVAT MIXING: xor eax,eax mov ax,smptype[ebx] call _jumptable[eax*4] add ebx,sizeof(tchannel) cmp ebx,(32*sizeof(tchannel))+offset _chaninfo jnz MIXING call _ido mov ecx,_mixsize add word ptr _mixpos,cx MIXALL: mov _mixer_zavora,0 MIXEND: ret CALCSIZE:call _getdma ;eax - pozice v mixovaci pameti mov ecx,eax ;ecx - pozice dma sub cx,word ptr _mixpos ;odecti mixpos (dma-mix_pos<0) js CALCOK shr cx,2 ;add _predstih,cx ;add _predstih,64 CALCOK: mov ebx,_lastdma mov _lastdma,eax sub ax,bx add ax,_predstih add ax,word ptr _lastdma mov bx,word ptr _mixpos sub ax,bx js CALCEND and ax,not 3 add ax,4 and eax,0ffffh mov _mixsize,eax ret CALCEND:mov _mixsize,0 ret ADDC macro REG1,REG2,CLIP local addc1 add REG1,REG2 jno addc1 shl REG2,1 Mov REG2,CLIP adc REG2,0 mov REG1,REG2 addc1: endm MIXS_ :;primixuje sampl do bufferu (8-bit stereo) ;musi platit vsechny promenne a ebx je adresa kanalu mov edi,_mixpos mov ecx,_mixsize mov esi,[ebx] push ebp mov bp,minorpos[ebx] mixslp: mov dl,[esi] mov dh,dl mov al,byte ptr volumeleft[ebx+1] imul dl shl eax,1 mov dl,ah mov al,byte ptr volumeright[ebx+1] imul dh shl eax,1 mov dh,ah mov ax,[edi] addc al,dl,7fh addc ah,dh,7fh mov [edi],ax ;je smixovano add di,2 ;dalsi pozice add bp,speedmin[ebx] adc esi,speedmaj[ebx] cmp esi,endloop[ebx] jc mixsskp mov esi,startloop[ebx] cmp esi,endloop[ebx] jnz mixsskp mov smptype[ebx],0 jmp mixsend mixsskp:dec ecx dec ecx jnz mixslp mixsend:mov minorpos[ebx],bp mov playpos[ebx],esi pop ebp ret mixskip:ret mixs2 :;primixuje sampl do bufferu (16-bit stereo) ;musi platit vsechny promenne a ebx je adresa kanalu mov edi,_mixpos ;vem mixovaci pozici mov ecx,_mixsize ;vem pocet potrebnych bajtu mov esi,[ebx] ;vyzvedni ukazatel na sample push ebp ;zachovej bp mov bp,minorpos[ebx] ;bp pro tuto chvili predstavuje minorpozici mix2slp:mov dl,[esi+1] ;vem sample, ale jen vyssi bajt mov dh,dl ;zkopiruj levy kanal do praveho mov al,byte ptr volumeleft[ebx+1];vyzvedni hlasitost leveho kanalu imul dl ;nasob vzorek hlasitosti shl eax,1 ;vysledek je v ah vydelen 256x mov dl,ah ;schovej vysledek do dl mov al,byte ptr volumeright[ebx+1];to same pro pravy kanal imul dh shl eax,1 mov dh,ah mov ax,[edi] ;ted precti aktualni stav samplu v bufferu addc al,dl,7fh ;pricti levy kanal s clippingem addc ah,dh,7fh ;pricti pravy kanal s clippingem mov [edi],ax ;je smixovano add di,2 ;dalsi pozice add bp,speedmin[ebx] ;skok po minor hodnotach lahf ;uchovej priznaky v ah (hlavne cf) adc esi,speedmaj[ebx] ;skok po major hodnotach sahf ;obnov cf adc esi,speedmaj[ebx] ;a jeste jednou celkem o 2xvic nez je rychlost cmp esi,endloop[ebx] ;test na konec samplu jc mix2sskp ;pokud jsme prekrocili konec mohou nastat dva mov esi,startloop[ebx];pripady: cmp esi,endloop[ebx] ; bud ma sampl opakovani pak zacina na adrese jnz mix2sskp ; startloop nebo nema mov smptype[ebx],0 ; pak je vypnut jmp mix2send ;skoc na konec mix2sskp:dec ecx ;pokracujeme v prehravani dec ecx ;byly naplneny 2 bajty, citac o 2 dolu jnz mix2slp ;opakuj cele mixovani dokud neni citac nule mix2send:mov minorpos[ebx],bp ;uloz minorpozici mov playpos[ebx],esi ;uloz majorpozici pop ebp ;obnov BP ret ;konec m8sido: mov esi,_mixpos ;vem mixovaci pozici sub si,2 ;o jeden sampl dozadu and esi,not 1 mov edi,_backfine ;finepozice mov ebx,_backsnd ;pozice v bufferu mov ecx,_mixsize ;pocet bajtu sub ecx,2 shl ecx,16 ;uloz do horni poloviny ecx mov ax,[esi] ;vezmi sample xor eax,8080h ;neznaminkova korekce m8sido1:add si,2 ;dalsi sample mov dx,[esi] ;nacti do dx sample xor edx,8080h ;neznaminkova korekce add al,dl ;secti leve kanaly rcr al,1 ;nasleduje deleni 2x prumer add ah,dh ;totez pro prave kanaly rcr ah,1 xor eax,8080h ;neznaminkova korekce mov cl,byte ptr _backsndbuff[1+ebx*4] ;nacti back sound pro levej kanal mov ch,byte ptr _backsndbuff[3+ebx*4];nactu back sound pro pravej kanal addc al,cl,7fh ;secti s clippingem levy kanal addc ah,ch,7fh ;secti s clippingem pravy kanal add di,word ptr _backstep ;pricti fine pozici adc bx,word ptr [_backstep+2];preteceni jde do bx plus step ; and ebx,03ffffh ;celkem 16384*4 samplu xor eax,8080h ;neznaminkova korekce sub si,2 ;uloz na zdrojovou pozici mov [esi],ax add si,2 mov eax,edx ;pouzity sampl pro prumerovani se sub ecx,20000h ;do ax a odecti dva takty pro citac jnc m8sido1 ;a opakuj dokud neni konec mov _backsnd,ebx mov _backfine,edi ret ;navrat sbdma: mov edx,_dmaposadr out 0ch,al out 0d8h,al xor eax,eax in al,dx xchg al,ah in al,dx xchg al,ah cmp _dmanum,4 jc sbdma1 shl eax,1 sbdma1: add eax,_mixbuffer ret PUBLIC setsbpro_ setsbpro_: lea edi,_jumptable mov eax,offset mixskip stosd mov eax,offset mixs_ stosd mov eax,offset mixs2 stosd mov _getdma,offset sbdma mov _ido,offset m8sido ret MIXM_ :;primixuje sampl do bufferu (8-bit mono) ;musi platit vsechny promenne a ebx je adresa kanalu mov edi,_mixpos ;vezmi mixovaci pozici mov ecx,_mixsize ;vezmi delku mixovani mov esi,[ebx] ;nacti ukazatel na aktualni pozici v samplu push ebp ;uchovej docasne BP mov bp,minorpos[ebx] ;bp ma novou ulohu, drzi minor pozici mov al,byte ptr volumeleft[ebx+1] ;vypocti hlasitost mov ah,byte ptr volumeright[ebx+1] add al,ah rcr al,1 ;jak prumer leve a prave hlasitosti mov dh,al mixmlp: mov al,[esi] ;vezmi sample imul dh ;vynasob s hlasitosti shl eax,1 ;vydel /256x (ah je vysledek) mov al,[edi] ;vezmi momentalni obsah bufferu addc al,ah,7fh ;secti s clippingem mov [edi],al ;je smixovano inc di ;dalsi pozice add bp,speedmin[ebx] adc esi,speedmaj[ebx] cmp esi,endloop[ebx] jc mixmskp mov esi,startloop[ebx] cmp esi,endloop[ebx] jnz mixmskp mov smptype[ebx],0 jmp mixmend mixmskp:dec ecx jnz mixmlp mixmend:mov minorpos[ebx],bp mov playpos[ebx],esi pop ebp ret MIXM2 :;primixuje sampl 16 do bufferu (8-bit mono) ;musi platit vsechny promenne a ebx je adresa kanalu mov edi,_mixpos ;vezmi mixovaci pozici mov ecx,_mixsize ;vezmi delku mixovani mov esi,[ebx] ;nacti ukazatel na aktualni pozici v samplu push ebp ;uchovej docasne BP mov bp,minorpos[ebx] ;bp ma novou ulohu, drzi minor pozici mov al,byte ptr volumeleft[ebx+1] ;vypocti hlasitost mov ah,byte ptr volumeright[ebx+1] add al,ah rcr al,1 ;jak prumer leve a prave hlasitosti mov dh,al mixmlp2:mov al,[esi+1] ;vezmi sample imul dh ;vynasob s hlasitosti shl eax,1 ;vydel /256x (ah je vysledek) mov al,[edi] ;vezmi momentalni obsah bufferu addc al,ah,7fh ;secti s clippingem mov [edi],al ;je smixovano inc di ;dalsi pozice add bp,speedmin[ebx] lahf ;uchovej priznaky v ah (hlavne cf) adc esi,speedmaj[ebx] ;skok po major hodnotach sahf ;obnov cf adc esi,speedmaj[ebx] ;a jeste jednou celkem o 2xvic nez je rychlost cmp esi,endloop[ebx] jc mixmskp2 mov esi,startloop[ebx] cmp esi,endloop[ebx] jnz mixmskp2 mov smptype[ebx],0 jmp mixmend2 mixmskp2:dec ecx jnz mixmlp2 mixmend2:mov minorpos[ebx],bp mov playpos[ebx],esi pop ebp ret m8mido: mov esi,_mixpos ;vem mixovaci pozici dec si ;o jeden sampl dozadu lea edi,_backfine ;ukazatel na back sound buffer mov ebx,_backsnd ;pozice v bufferu mov ecx,_mixsize ;pocet bajtu dec ecx shl ecx,16 ;uloz do horni poloviny ecx mov al,[esi] ;vezmi sample xor eax,80h ;neznaminkova korekce m8mido1:inc si ;dalsi sample mov dl,[esi] ;nacti do dx xor edx,80h ;neznaminkova korekce add al,dl ;secti kanal rcr al,1 ;nasleduje deleni 2x prumer xor eax,80h ;vysledek oznamenkuj - bude se scitat mov cl,byte ptr _backsndbuff[1+ebx*4];nacti back sound pro levej kanal mov ch,byte ptr _backsndbuff[3+ebx*4];nactu back sound pro pravej kanal add di,word ptr _backstep ;pricti fine pozici adc bx,word ptr [_backstep+2];preteceni jde do bx plus step ; and ebx,03ffffh ;celkem 16384*4 samplu sar cl,1 ;del levy kanal 2ma sar ch,1 ;del pravy kanal 2ma add cl,ch ;secti oba kanaly addc al,cl,7fh ;secti s clippingem kanal xor eax,80h ;neznaminkova korekce pro SB Pro dec si ;uloz na zdrojovou pozici mov [esi],al inc si mov eax,edx ;pouzity sampl pro prumerovani se sub ecx,10000h ;do ax a odecti jeden takt pro citac jnc m8mido1 ;a opakuj dokud neni konec mov _backsnd,ebx ret ;navrat m8midos:mov esi,_mixpos ;vem mixovaci pozici dec si ;o jeden sampl dozadu lea edi,_backfine ;ukazatel na back sound buffer mov ebx,_backsnd ;pozice v bufferu mov ecx,_mixsize ;pocet bajtu dec ecx shl ecx,16 ;uloz do horni poloviny ecx mov al,[esi] ;vezmi sample xor eax,80h ;neznaminkova korekce m8mido2:inc si ;dalsi sample mov dl,[esi] ;nacti do dx xor edx,80h ;neznaminkova korekce add al,dl ;secti kanal rcr al,1 ;nasleduje deleni 2x prumer xor eax,80h ;vysledek oznamenkuj - bude se scitat mov cl,byte ptr _backsndbuff[1+ebx*4];nacti back sound pro levej kanal mov ch,byte ptr _backsndbuff[3+ebx*4];nactu back sound pro pravej kanal add di,word ptr _backstep ;pricti fine pozici adc bx,word ptr [_backstep+2];preteceni jde do bx plus step ; and ebx,03ffffh ;celkem 16384*4 samplu sar cl,1 ;del levy kanal 2ma sar ch,1 ;del pravy kanal 2ma add cl,ch ;secti oba kanaly addc al,cl,7fh ;secti s clippingem kanal dec si ;uloz na zdrojovou pozici mov [esi],al inc si mov eax,edx ;pouzity sampl pro prumerovani se sub ecx,10000h ;do ax a odecti jeden takt pro citac jnc m8mido2 ;a opakuj dokud neni konec mov _backsnd,ebx ret ;navrat PUBLIC setsb2_ setsb2_: lea edi,_jumptable mov eax,offset mixskip stosd mov eax,offset mixm_ stosd mov eax,offset mixm2 stosd mov _getdma,offset sbdma mov _ido,offset m8mido ret PUBLIC setsb2_s_ setsb2_s_: lea edi,_jumptable mov eax,offset mixskip stosd mov eax,offset mixm_ stosd mov eax,offset mixm2 stosd mov _getdma,offset sbdma mov _ido,offset m8midos ret MIX16_ :;primixuje sampl do bufferu (16-bit stereo) ;musi platit vsechny promenne a ebx je adresa kanalu mov edi,_mixpos ;vem mixovaci pozici mov ecx,_mixsize ;vem mixovaci delku mov esi,[ebx] ;vyzvedni ukazatel na sample push ebp ;uchovej BP mov bp,minorpos[ebx] ;bp bude drzet minor pozice mix1lp: mov al,[esi] ;nacti sample mov dl,al ;al a dl obsahuji levej a pravej kanal mov ah,byte ptr volumeright[ebx+1] ;nacti pravou hlastitot imul ah ;vynasob hlasitosti shl eax,1 ;vse je vyreseno, deleni neni potreba xchg edx,eax ;ted pracuj s druhym kanalem mov ah,byte ptr volumeleft[ebx+1] ;nactu hlasitost imul ah ;vynasob shl eax,1 addc [edi],dx,7fffh ;k aktualnimu vzorku pricti hodnotu add di,2 ;dalsi pozice addc [edi],ax,7fffh ;je smixovano add di,2 ;dalsi pozice add bp,speedmin[ebx] adc esi,speedmaj[ebx] cmp esi,endloop[ebx] jc mix1skp mov esi,startloop[ebx] cmp esi,endloop[ebx] jnz mix1skp mov smptype[ebx],0 jmp mix1end mix1skp:sub ecx,4 jnz mix1lp mix1end:mov minorpos[ebx],bp mov playpos[ebx],esi pop ebp ret mix162: ;primixuje sampl do bufferu (16-bit stereo) ;musi platit vsechny promenne a ebx je adresa kanalu mov edi,_mixpos ;vem mixovaci pozici mov ecx,_mixsize ;vem mixovaci delku mov esi,[ebx] ;vyzvedni ukazatel na sample push ebp ;uchovej BP mov bp,minorpos[ebx] ;bp bude drzet minor pozice mix12lp:movsx eax,word ptr [esi] ;nacti sample imul word ptr volumeright[ebx] ;nacti pravou hlastitot a vynasob shl edx,1 ;vse je vyreseno, deleni neni potreba addc [edi],dx,7fffh ;k aktualnimu vzorku pricti hodnotu add di,2 ;dalsi pozice movsx eax,word ptr [esi] ;nacti sample imul word ptr volumeleft[ebx] ;nacti pravou hlastitot a vynasob shl edx,1 ;vse je vyreseno, deleni neni potreba addc [edi],dx,7fffh ;k aktualnimu vzorku pricti hodnotu add di,2 ;dalsi pozice add bp,speedmin[ebx] lahf ;uchovej priznaky v ah (hlavne cf) adc esi,speedmaj[ebx] ;skok po major hodnotach sahf ;obnov cf adc esi,speedmaj[ebx] cmp esi,endloop[ebx] jc mix12skp mov esi,startloop[ebx] cmp esi,endloop[ebx] jnz mix12skp mov smptype[ebx],0 jmp mix12end mix12skp:sub ecx,4 jnz mix12lp mix12end:mov minorpos[ebx],bp mov playpos[ebx],esi pop ebp ret m16ido: push ebp mov esi,_mixpos ;vem mixovaci pozici sub si,4 ;o jeden sampl dozadu mov edi,_backfine ;finepozice mov ebx,_backsnd ;pozice v bufferu mov ecx,_mixsize ;pocet bajtu sub ecx,4 shl ecx,16 ;uloz do horni poloviny ecx mov eax,[esi] ;vezmi sample xor eax,80008000h ;neznaminkova korekce m16ido1:add si,4 ;dalsi sample mov ebp,eax and ebp,0ffff0000h mov edx,[esi] ;nacti do dx sample xor edx,80008000h ;neznaminkova korekce add ax,dx ;secti leve kanaly rcr ax,1 ;nasleduje deleni 2x prumer add ebp,edx ;totez pro prave kanaly rcr ebp,1 shld eax,ebp,16 xor eax,80008000h ;neznaminkova korekce mov cx,word ptr _backsndbuff[ebx*4] ;nacti back sound pro levej kanal addc ax,cx,7fffh ;secti s clippingem levy kanal mov cx,word ptr _backsndbuff[2+ebx*4];nacti back sound pro pravej kanal rol eax,16 addc ax,cx,7fffh ;secti s clippingem pravy kanal add di,word ptr _backstep ;pricti fine pozici adc bx,word ptr [_backstep+2];preteceni jde do bx plus step ; and ebx,03ffffh ;celkem 16384*4 samplu sub si,4 ;uloz na zdrojovou pozici mov [esi],eax add si,4 mov eax,edx ;pouzity sampl pro prumerovani se sub ecx,40000h ;do ax a odecti ctyri takty pro citac jnc m16ido1 ;a opakuj dokud neni konec pop ebp mov _backsnd,ebx mov _backfine,edi ret ;navrat PUBLIC setsb16_ setsb16_: lea edi,_jumptable mov eax,offset mixskip stosd mov eax,offset mix16_ stosd mov eax,offset mix162 stosd mov _getdma,offset sbdma mov _ido,offset m16ido ret dpmibufalloc: mov ax,0100h int 31h ret public buff_dealloc_ buff_dealloc_: mov dx,_dpmiselector mov ax,0101h int 31h ret public buff_alloc_ buff_alloc_: mov ebx,4200 call dpmibufalloc jc allcerror test eax,0fffh jz allc_ok push eax mov eax,0101h int 31h pop eax mov ebx,eax and ebx,0f000h add ebx,1000h sub ebx,eax dec ebx call dpmibufalloc jc allcerror push edx call buff_alloc_ mov ecx,edx pop edx push eax mov eax,0101h int 31h pop eax ret allc_ok:mov _dpmiselector,dx shl eax,4 ret allcerror: mov word ptr _dpmiselector,0 xor eax,eax ret public int_relocation_ int_relocation_: mov eax,0de0ah int 67h shl ebx,16 mov bx,cx rol ebx,16 mov eax,ebx ret public int_mixer_alloc_ int_mixer_alloc_: lea eax,_idt_map sidt [eax] ; db 0fh ; db 01 ; db 08h add eax,2 mov eax,[eax] shl ebx,3 add eax,ebx cli mov edi,eax push ds pop es mov ecx,offset int_normal_ mov eax,ecx stosw mov ax,cs stosw mov eax,8e00h stosw mov eax,ecx shr eax,16 stosw sti mov ebx,1000h call dpmibufalloc mov esi,4*8 mov edi,offset rm_old mov ecx,4 rep movsb mov _call_back_sel,dx mov esi,offset rm_data_ mov edi,eax shl edi,4 mov _call_back_data,edi mov ecx,1000 rep movsb mov edi,4*8 mov word ptr [edi],8 mov [edi+2],ax ret public int_high_alloc_ int_high_alloc_: lea eax,_idt_map sidt [eax] add eax,2 mov eax,[eax] shl ebx,3 add eax,ebx cli mov edi,eax push ds pop es mov ecx,offset int_hspd_ mov eax,ecx stosw mov ax,cs stosw mov eax,8e00h stosw mov eax,ecx shr eax,16 stosw sti mov ebx,1000h call dpmibufalloc mov esi,4*8 mov edi,offset rm_old mov ecx,4 rep movsb mov _call_back_sel,dx mov esi,offset rm_data_ mov edi,eax shl edi,4 mov _call_back_data,edi mov ecx,1000 rep movsb mov edi,4*8 ; mov word ptr [edi],(high_speed - rm_data_) ; mov [edi+2],ax ret public high_speed_parm_ ;eax dos delay ;edx port ;ebx mixbuffer ;esi xlattab high_speed_parm_: mov edi,offset w_max mov [edi],ax mov edi,offset rm_hspd mov ecx,64 rep movsd xor eax,eax stosw mov eax,ebx shr eax,4 stosw mov eax,edx stosw ret public int_dealloc_ int_dealloc_: mov edi,4*8 mov esi,offset rm_old mov ecx,4 rep movsb mov dx,_call_back_sel mov ax,101h int 31h ret public write_adlib_ write_adlib_: mov dx,_timer_test_port out dx,al in al,dx in al,dx in al,dx in al,dx in al,dx in al,dx mov al,ah inc edx out dx,al mov ah,36 dec edx wwait: in al,dx dec ah jnz wwait ret public write_adlib_nodelay_ write_adlib_nodelay_: mov dx,_timer_test_port out dx,al in al,dx in al,dx in al,dx in al,dx in al,dx in al,dx mov al,ah inc edx out dx,al ret ;public int_normal_: int_normal_: cli pushad push ds push es mov ax,seg _DATA mov ds,ax mov es,ax mov al,20h out 20h,al mov dx,_timer_test_port or dx,dx jz intn_ok in al,dx test al,80h jz intn_call_dos; mov ax,8004h call write_adlib_ intn_ok:inc _test_counter sti call mixer_ cli intn_sk:pop es pop ds popad iretd intn_call_dos:call _oldvect jmp intn_sk public int_hspd_: ;high speed mode interrupt - pro D/A a PC Speaker int_hspd_: push ds push esi push ebx push edx push eax mov al,20h out 20h,al mov ax,seg _DATA mov ds,ax mov ebx,_call_back_data add ebx,(offset rm_hspd-offset rm_data_) xor eax,eax xor esi,esi mov ax,[ebx+scanofs] mov si,[ebx+scanseg] shl esi,4 add esi,eax mov dx,[ebx+port] lodsb xlatb out dx,al inc word ptr [ebx+scanofs] mov ebx,_call_back_data dec word ptr [ebx] jnz hs_end mov ax,[ebx+2] mov [ebx],ax sti call mixer_ cli hs_end: pop eax pop ebx pop edx pop esi pop ds iretd ;------------------------------- ULTRASND LIB ----------------- ;Special thanx for Dalibor Straka gus_sv macro voice mov edx,_devport add edx,gus_voice mov al,voice out dx,al ENDM gus_w macro reg,data mov edx,_devport mov al,reg add edx,gus_reg out dx,al mov eax,data add edx,gus_reg_data-gus_reg out dx,ax in ax,dx in ax,dx in ax,dx in ax,dx in ax,dx in ax,dx mov eax,data out dx,ax ENDM gus_wb macro reg,data mov edx,_devport mov al,reg add edx,gus_reg out dx,al mov al,data add edx,gus_reg_data-gus_reg+1 out dx,al in al,dx in al,dx in al,dx in al,dx in al,dx in al,dx mov al,data out dx,al ENDM gus_wbd macro reg,data mov edx,_devport mov al,reg add edx,gus_reg out dx,al mov al,data add edx,gus_reg_data-gus_reg+1 out dx,al endm gus_r macro reg ;vysledek v eax mov edx,_devport mov al,reg add edx,gus_reg out dx,al add edx,gus_reg_data-gus_reg in ax,dx movzx eax,ax ENDM ;organizace GUS RAM ;<0 - gus_block> prehravaci blok ;<32768 - +gus_block> mirror buffer (prazdny) extrn prepare_dma_:proc ;priprava DMA public stop_gus_ ;deinicializuje GUS stop_gus_: mov cl,31 ;ted se vyresetuji vsechny kanaly igus_2: gus_sv cl ;vyber hlas gus_wb 0,2 ;vypni hlas gus_wb 1,0 ;nastav krok na 0 gus_w 2,0003h ;nastav hlas na konec 64KB bloku gus_w 3,0ff00h gus_w 4,0003h gus_w 5,0ff00h gus_w 0Ah,0003h gus_w 0Bh,0ff00h gus_wb 0Dh,3fh ;vypni volume ramp gus_wb 07h,0fh ;hlasitost 0 gus_wb 08h,10h ;hlasitost 0 gus_w 09h,0 ;hlasitost 0 sub cl,1 jnc igus_2 ret gus_dma db 0,11h,11h,22h,22h,33h,44h,55h public init_gus_ ;inicializuje GUS do rezimu prehravani samplu init_gus_: mov edx,_devport mov al,19h ;zapni out out dx,al mov edx,_devport lea edx,[edx+gus_irq_dma] movzx eax,_dmanum mov al,cs:gus_dma[eax] out dx,al ;nastav DMA gus_wbd 4ch,0 ;reset gus mov edx,_devport add edx,6 mov ecx,1000 igus_3: in al,dx loop igus_3 ;cekani gus_wbd 4ch,1 ;reset gus add edx,6 mov ecx,1000 igus_4: in al,dx loop igus_4 gus_wbd 4ch,3 ;povol dac mov edx,_devport mov edi,_mixbuffer mov ecx, 65536 shr 2 xor eax,eax rep stosd ;vynuluj dma_buffer mov edx,_devport add edx,gus_irqs in al,dx gus_r 41h gus_wb 41h,0 mov edx,_devport add edx,gus_irqs in al,dx gus_r 41h gus_r 41h gus_w 42h,0 mov eax,_mixbuffer mov edx,65536 call prepare_dma_ movzx ecx,_gus_dma_type gus_wb 41h,cl ;vynuluj prvnich 64KB GUSRAM xor edx,edx mov eax,617400 mov ecx,_samplerate div ecx add dx,8000h adc al,0 cmp al,33 jc igus_1 mov al,32 igus_1: dec al or al,0c0h mov cl,al gus_wb 0eh,cl call stop_gus_ gus_sv 0 mov ecx,0 ;nastaveni hlasu cislo 0 gus_w 2,ecx ;zacni na 0 gus_w 3,ecx gus_w 0Ah,ecx gus_w 0Bh,ecx mov ecx,(gus_block-4) shl 8 ;konec az za gus_blockem gus_w 5,ecx shr ecx,16 gus_w 4,ecx mov ecx,(1 shl 0bh) gus_w 1,ecx ;krok 2 gus_w 9,0ffffh ;hlasitost max gus_wb 0ch,0 ;panning vlevo gus_wb 00,0ch ;spust hlas gus_sv 1 ;nastaveni hlasu cislo 1 mov ecx,2 shl 8 gus_w 3,ecx ;zacni na 2 gus_w 0Bh,ecx shr ecx,16 gus_w 2,ecx gus_w 0Ah,ecx mov ecx,(gus_block-2) shl 8 ;konec az za gus_blockem gus_w 5,ecx shr ecx,16 gus_w 4,ecx mov ecx,(1 shl 0bh) gus_w 1,ecx ;krok 2 gus_w 9,0ffffh ;hlasitost max gus_wb 0ch,0fh ;panning vpravo gus_wb 00,0ch ;spust hlas ret gus_move_buff: ;presun bufferu do GUS push eax mov edx,_devport add edx,gus_irqs in al,dx gus_r 41h gus_wbd 41h,0 mov edx,_devport add edx,gus_irqs in al,dx gus_r 41h gus_r 41h mov edx,_devport add edx,gus_irqs in al,dx pop eax xor esi,esi and ah,1fh or ah,ah jz gus_mb1 mov esi,(gus_block shr 1) gus_mb1:mov cl,4 test _gus_dma_type,4 jz gus_mb2 inc cl gus_mb2:shr esi,cl push esi mov eax,_mixbuffer mov edx,ebx call prepare_dma_ pop esi gus_w 42h,esi movzx ecx,_gus_dma_type gus_wbd 41h,cl ret gus_skip:mov eax,_mixbuffer mov _mixpos,eax xor ecx,ecx mov _mixsize,ecx mov cl,_gus_last_buff gus_sv 0 gus_r 8Ah shl eax,8 cmp eax,gus_block shr 1 rcl ch,1 xor cl,ch jz gus_ie mov ah,ch mov _gus_last_buff,ch mov ecx,(gus_block shr 1) mov _mixsize,ecx gus_ie: pop eax ret m16idog:push ebp mov esi,_mixpos ;vem mixovaci pozici mov edi,_backfine ;finepozice mov ebx,_backsnd ;pozice v bufferu mov ecx,_mixsize ;pocet bajtu shr ecx,2 dec ecx shl ecx,16 m16ido2:mov eax,[esi] mov cx,word ptr _backsndbuff[ebx*4] ;nacti back sound pro levej kanal addc ax,cx,7fffh ;secti s clippingem levy kanal mov cx,word ptr _backsndbuff[2+ebx*4];nacti back sound pro pravej kanal rol eax,16 addc ax,cx,7fffh ;secti s clippingem pravy kanal add di,word ptr _backstep ;pricti fine pozici adc bx,word ptr [_backstep+2];preteceni jde do bx plus step and ebx,03ffffh ;celkem 16384*4 samplu mov [esi],eax add si,4 sub ecx,10000h ;do ax a odecti ctyri takty pro citac jnc m16ido2 ;a opakuj dokud neni konec pop ebp mov _backsnd,ebx mov _backfine,edi mov ah,_gus_last_buff mov ebx,_mixsize ;pocet bajtu call gus_move_buff ret ;navrat PUBLIC setGUS_ setGUS_: lea edi,_jumptable mov eax,offset mixskip stosd mov eax,offset mix16_ stosd mov eax,offset mix162 stosd mov _getdma,offset GUS_SKIP mov _ido,offset m16idog ret public gus_setchan_vol_ gus_setchan_vol_: ;ecx,eax gus_sv al gus_w 9,ecx ret public gus_setchan_pan_ gus_setchan_pan_: ;ecx,eax gus_sv al gus_wb 0ch,cl ret _TEXT16 SEGMENT BYTE PUBLIC USE16 'CODE' ASSUME cs:_TEXT16 public rm_proc_: rm_data_: w_count:dw 2 ;citac preruseni w_max dw 2 ;maximalni hodnota citace rm_old dw ? ;stary vektor preruseni dw ? rm_proc_: cli int 1ch cli push si xor si,si dec word ptr cs:[si] jnz w_skip push ax mov ax,cs:[si+2] mov cs:[si],ax pop ax pushf call dword ptr cs:[si+4] w_skip: pop si iret rm_hspd db 300 dup(?) high_speed: push ds push si push bx push dx push ax mov bx,offset rm_hspd-offset rm_data_ lds si,cs:[bx+scanofs] mov dx,cs:[bx+port] lodsb xlat cs: out dx,al mov cs:[bx+scanofs],si mov al,20h out 20h,al dec word ptr cs:[0] jnz hspd_end mov ax,cs:[2] mov cs:[0],ax pushf call dword ptr cs:[4] int 1ch hspd_end: pop ax pop dx pop bx pop si pop ds iret _TEXT16 ends _TEXT ends END