; FILLDMA.ASM - library for playing in normal mode (not pollplay) model large,pascal INCLUDE BORDER.INC .data EXTRN EndOfSong : BYTE ; Flag if we reach the end of the Song :( EXTRN DMAhalf : BYTE ; last part of DMAbuffer we have to fill EXTRN lastready : BYTE ; last part of DMAbuffer we calculated last call EXTRN NumBuffers : BYTE EXTRN BPT : WORD ; Bytes Per Tick - depends on tempo EXTRN _16Bit : BYTE EXTRN TICKBUFFER : DWORD EXTRN DMAbuffer : DWORD EXTRN toslow : BYTE EXTRN stereo : BYTE EXTRN JustInFill : BYTE EXTRN DMArealbufsize:WORD EXTRN savhandle:word EXTRN useEMS :byte EXTRN LQmode :byte errorsav DB ? ends .code .386 public fill_dmabuffer public mixroutines EXTRN calc_stereo_tick EXTRN calc_mono_tick mixroutines PROC NEAR cmp [stereo],0 je nostereo call near ptr calc_stereo_tick ret nostereo: call near ptr calc_mono_tick ret mixroutines ENDP convert_8 PROC NEAR ; IN: CX - count of values to convert ; ES:DI - pointer to DMAbuffer ; FS:SI - pointer to tickbuffer ; DS:?? - pointer to posttable ; Result: a 16bit to 8bit convert of CX values ; OUT: ; CX = 0 ; BX = OLD_SI+2*OLD_CX ; SI = OLD_SI ; DI = OLD_DI+OLD_CX ; AL ??? ; mov bx,si conv_loop: mov si,fs:[bx] add bx,2 mov al,ds:[si] mov es:[di],al inc di dec cx jnz conv_loop ret convert_8 ENDP LQconvert_8 PROC NEAR ; IN: CX - count of values to convert ; ES:DI - pointer to DMAbuffer ; FS:SI - pointer to tickbuffer ; DS:?? - pointer to posttable ; Result: a 16bit to 8bit convert of CX values ; OUT: ; CX = 0 ; BX = OLD_SI+2*OLD_CX ; SI = OLD_SI ; DI = OLD_DI+OLD_CX ; AL ??? ; cmp [LQmode],0 je convert_8 shl di,1 mov bx,si cmp [stereo],1 je st_cv LQc_loop: mov si,fs:[bx] add bx,2 mov al,ds:[si] mov ah,al mov es:[di],ax add di,2 dec cx jnz LQc_loop ret st_cv: shr cx,1 st_cvl: mov si,fs:[bx] add bx,2 mov al,ds:[si] mov si,fs:[bx] add bx,2 mov ah,ds:[si] mov es:[di],ax add di,2 mov es:[di],ax add di,2 dec cx jnz st_cvl ret LQconvert_8 ENDP ; --------------------------------------------------------------------------- ; PROC fill_DMABuffer .... called by IRQ (generated by SB) ; IN: nothing OUT: nothing (but crap :) ; WHAT TO DO: ; Convert DMArealBufsize[1] words from tickbuffer into playbuffer (position ; spezified with DMAhalf). If not enough data is left in tickbuffer call ; 'calcroutines' for next tick (calcroutines also do 'note' handling). ; --------------------------------------------------------------------------- fill_DMAbuffer PROC NEAR cmp [_16bit],0 jne is16bit again8: call fill_8bit mov al,[lastready] cmp al,[DMAhalf] jne again8 ret is16bit: ; do nothing :) ... is not written yet ! ret fill_DMAbuffer ENDP fill_8bit PROC NEAR ; New routine (faster ?) ; save these values (we are in an interrupt !) push eax ebx ecx edx ebp esi edi ds es fs gs ; check if we are allready in calculation routines ; if we are the PC is to slow -> how you wanna handle it ? cmp [justinfill],1 jne noproblem mov cx,0ffffh waitfor: mov ax,cx shl ax,16 shr ax,16 cmp [justinfill],1 loopz waitfor jnz slow noproblem: setborder 7 ; for check if to slow set a variable (flag that we are allready in calc) mov [justinfill],1 cmp [EndOfSong],0 jne Song_ends ; before calling mixroutines : ; save EMS mapping ! cmp [useEMS],0 je donotsave call near ptr SAVE_MAPPING donotsave: setborder 1 call near ptr mixroutines ; calc 'dmarealbufsize' bytes into the tickbuffer setborder 7 ; now restore EMS mapping: cmp [useEMS],0 je donotrestore call near ptr RESTORE_MAPPING donotrestore: mov ax,word ptr [tickbuffer+2] mov fs,ax ; FS is tickbuffer segment xor si,si ; start in tickbuffer mov ax,word ptr [DMAbuffer+2] mov es,ax ; ES is playbuffer segment mov ah,[numbuffers] dec ah mov al,[lastready] inc al and al,ah mov [lastready],al xor ah,ah mov di,ax shl di,1 mov di,[dmarealbufsize+di] ; startoffset in DMAbuffer mov cx,[DMArealBufsize+2] ; CX = number of bytes in tickbuffer call LQconvert_8 outside: mov [justinfill],0 endoffill: setborder 0 pop gs fs es ds edi esi ebp edx ecx ebx eax ret ; bye bye C ya later slow: ; sorry your PC is to slow - maincode may ignore this flag ; but it'll sound ugly :( mov [toslow],1 ; simply fill the half with last correct mixed value mov cx,[dmarealBufsize+2] ; we have to calc. dmarealBufsize bytes mov ax,word ptr [DMAbuffer+2] mov es,ax ; ES is playbuffer segment movzx di,[DMAhalf] shl di,1 mov di,[dmarealbufsize+di] ; start offset in DMAbuffer mov al,1 sub al,[DMAhalf] ; change DMAhalf : DMAhalf=1-DMAhalf mov [DMAhalf],al movzx si,[DMAhalf] shl si,1 mov si,[dmarealbufsize+si] ; start offset in DMAbuffer add si,[dmarealbufsize+2] mov al,es:[si-1] sub si,[dmarealbufsize+2] rep stosb ; fill dmabuffer jmp endoffill Song_ends:; MOD ends here - clear DMAbuffer les di,[DMAbuffer] movzx di,[DMAhalf] shl di,1 mov di,[dmarealbufsize+di] mov cx,[dmarealBufsize+2] shr cx,1 xor ax,ax rep stosw mov al,1 sub al,[DMAhalf] ; change DMAhalf : DMAhalf=1-DMAhalf mov [DMAhalf],al jmp outside fill_8bit ENDP SAVE_MAPPING PROC NEAR mov [errorsav],1 mov dx,[savhandle] mov ah,47h int 67h cmp ah,0 jne endofsave mov [errorsav],0 endofsave: ret SAVE_MAPPING ENDP RESTORE_MAPPING PROC NEAR cmp [errorsav],1 je endofrestore mov dx,[savHandle] mov ah,48h int 67h endofrestore: ret RESTORE_MAPPING ENDP ends end