2000 .MODEL TINY .386 INCLUDE TSR_INST.MAC w EQU word ptr RECMODE EQU 0 PLAYMODE EQU 1 REC_KEY EQU 27h PLAY_KEY EQU 28h FINISHED EQU 0ffh .CODE ORG 100h start: jmp Install_TSR mstr STRUCT len dd 0 ; 32-bit number of bytes to transfer shand dw 0 ; Handle of source block soff dd 0 ; 32-bit offset into source block dhand dw 0 ; Handle of dest block doff dd 0 ; 32-bit offset into dest block mstr ENDS ms mstr <> xmsdriver dd ? xms_handle dw ? ;xms_freemem dw ? ;xms_totmem dw ? mode db ? voc_stat db ? counter dd ? bytesdone dd ? tempbuf db 16 dup(0) bufcntr dw ? Org_Rutin dd ? Org_Int08_Isr dd ? tick_cntr dw 0 hz18 dw 18 interv dw ? scancode db ? write_dsp PROC wd1: in al,dx or al,al js wd1 mov al,ah out dx,al ret write_dsp ENDP speaker_on PROC mov dx,22ch mov ah,0d1h call write_dsp mov ah,00h call set_lineinvol ret speaker_on ENDP speaker_off PROC mov dx,22ch mov ah,0d3h call write_dsp mov ah,0ffh call set_lineinvol speaker_off ENDP set_lineinvol PROC mov dx,224h mov al,2eh out dx,al inc dx mov al,ah out dx,al ret set_lineinvol ENDP ;--------------------------------------------------------------------------- Play_ISR PROC FAR push ds push ax push bx push dx push es push si push cs pop ds cmp voc_stat,FINISHED jz no_move mov dx,22ch wd1: in al,dx or al,al js wd1 mov al,10h out dx,al wd2: in al,dx or al,al js wd2 mov si,bufcntr mov al,tempbuf[si] out dx,al inc si mov bufcntr,si cmp si,16 jnz no_move mov bufcntr,0 mov ms.len,16 mov dx,xms_handle mov ms.shand,dx mov edx,counter mov ms.soff,edx mov ms.dhand,0 mov word ptr[ms.doff+2],cs mov word ptr[ms.doff],OFFSET tempbuf mov si,OFFSET ms call xms_move add counter,16 cmp word ptr[counter+2],2 jnz no_kuk mov counter,0 no_kuk: add bytesdone,16 cmp bytesdone,131072 jnz no_move mov voc_stat,FINISHED no_move: inc word ptr[tick_cntr] ;Call original timer ISR mov dx,interv cmp word ptr[tick_cntr],dx ;at proper time interval jnz end_of_ISR mov word ptr[tick_cntr],0 pushf call Org_Int08_Isr jmp skip_EOI end_of_ISR: mov al,20h ;Signal End of Interrupt out 20h,al skip_EOI: pop si pop es pop dx pop bx pop ax pop ds iret Play_ISR ENDP Rec_ISR PROC FAR push ds push ax push bx push dx push es push si push cs pop ds mov dx,22ch wd1: in al,dx or al,al js wd1 mov al,20h out dx,al mov dx,22eh wd2: in al,dx or al,al jns wd2 mov dx,22ah in al,dx mov si,bufcntr mov tempbuf[si],al inc si mov bufcntr,si cmp bufcntr,16 jnz no_move mov bufcntr,0 mov ms.len,16 mov ms.shand,0 mov word ptr[ms.soff+2],cs mov word ptr[ms.soff],OFFSET tempbuf mov dx,xms_handle mov ms.dhand,dx mov edx,counter mov ms.doff,edx mov si,OFFSET ms call xms_move add counter,16 cmp word ptr[counter+2],2 jnz no_move mov counter,0 no_move: inc word ptr[tick_cntr] ;Call original timer ISR mov dx,interv cmp word ptr[tick_cntr],dx ;at proper time interval jnz end_of_ISR mov word ptr[tick_cntr],0 pushf call Org_Int08_Isr jmp skip_EOI end_of_ISR: mov al,20h ;Signal End of Interrupt out 20h,al skip_EOI: pop si pop es pop dx pop bx pop ax pop ds iret Rec_ISR ENDP ;======================================================================= playrec PROC push bx push dx push es push si push di mov bufcntr,0 mov bytesdone,0 mov voc_stat,0 cli mov ax,0 mov es,ax mov di,20h cmp mode,PLAYMODE jnz rec call speaker_on mov ax,OFFSET Play_ISR jmp over_rec rec: call speaker_off mov ax,OFFSET Rec_ISR over_rec: stosw mov ax,cs stosw pop di pop si pop es pop dx pop bx ret playrec ENDP xms_move PROC mov ah,0bh xor bl,bl ; reset error code to zero call xmsdriver ; call the XMS driver ret xms_move ENDP start_tsr: Kbd_ISR PROC FAR sti push ds push cs pop ds push ax in al,60h ; Get scancode from keyboard processor cmp al,REC_KEY ; Check if Recording key (Alt-™) jz hotkey_ok cmp al,PLAY_KEY ; Check if Play key (Alt-ˇ) jnz no_hotkey hotkey_ok: mov scancode,al push es ; look into BIOS data area sub ax, ax ; (segment 0) to check shift state mov es, ax mov ax, es:[417h] ; Get SHIFT-key flags test ax,0000000000001000b ; Check if Alt-key pressed pop es jz no_hotkey cli ; Disable interrupts while resetting in al, 61h ; Get current port 61h state or al, 10000000b ; Turn on bit 7 to signal clear keybrd out 61h, al ; Send to port and al, 01111111b ; Turn off bit 7 to signal break out 61h, al ; Send to port cmp scancode,PLAY_KEY jnz rec mov mode,PLAYMODE jmp over_rec rec: mov mode,RECMODE over_rec: call playrec mov al, 20h ; Reset interrupt controller out 20h, al sti ; Reenable interrupts pop ax pop ds iret no_hotkey: pop ax ; Recover AX and fall through pop ds cli ; Interrupts cleared for service jmp cs:Org_Rutin ; jump to old Int 09 routine Kbd_ISR ENDP end_tsr: ;============================================================================ ;=====================HˇR SLUTAR RESIDENTA DELEN ============================ ;============================================================================ ; XMS.ASM (XMS.LIB) ; ;Externa XMS-rutiner f”r MASM ; ;Inparametrar: ; xms_alloc : DX = size in kb ; xms_free : DX = handle ; xms_move : SI = pekare till XMS-struktur ;Returv„rden: ; xms_setup: AX = 0 om ingen XMS-drivrutin (HIMEM.SYS) aktiv. ; ”vriga rutiner: bl = 0 om OK, annars error code ; xms_alloc : AX = XMS-handle ; xms_setup PROC mov ax,4300h ; XMS Driver installation check int 2fh cmp al,80h ; returns 80h if installed jz xmsfound mov ax,0 ; XMS Driver not present jmp exit_setup xmsfound: mov ax,4310h ; get address of XMS driver int 2fh mov w[xmsdriver],bx ; store offset mov w[xmsdriver+2],es ; store segment mov ax,1 exit_setup: ret xms_setup ENDP ;xms_get_freemem PROC ; mov ah,8 ; call xmsdriver ; mov xms_freemem,ax ; mov xms_totmem,dx ; ret ;xms_get_freemem ENDP xms_alloc PROC mov ah,09 call xmsdriver ; call the XMS driver mov ax,dx ; return handle in AX ret xms_alloc ENDP 783 ;xms_free PROC ; mov ah,0ah ; call xmsdriver ; call the XMS driver ; ret ;xms_free ENDP fix_timer PROC sub dx,dx mov ax,8000 ;calculate interval to call original rte div hz18 mov interv,ax cli mov dx,43h ;Programmera om Timer 0 mov al,36h out dx,al mov dx,40h ;Ny divisor mov al,95h ;0095h = 8000 Hz out dx,al ;006Ch = 11025 Hz mov al,00h out dx,al sti ret fix_timer ENDP set_adcs PROC mov dx,224h mov al,0ch out dx,al inc dx mov al,00010110b out dx,al ;set line-in as input source ret set_adcs ENDP reset_card PROC push cx push dx mov dx,226h mov al,1 out dx,al mov cx,0ffh w1: loop w1 mov al,0 out dx,al mov dx,22eh w2: in al,dx ;Check for data available or al,al jns w2 mov dx,22ah in al,dx ;Check for ready byte cmp al,0aah jnz w2 pop dx pop cx ret reset_card ENDP install_msg db 'SM5SXL RX audio recorder installed',13,10 db 'Alt-ˇ Records, Alt-™ Plays',13,10,'$' Install_TSR: mov al,08h ;H„mta vektorn till INT 08h mov ah,35h int 21h mov word ptr[Org_Int08_Isr],bx ;Org_Rutinens OFFSET h„mtas mov word ptr[Org_Int08_Isr+2],es ;Segment sparas call xms_setup mov dx,128 ;128 kb buffert i XMS-minne call xms_alloc mov xms_handle,ax call reset_card call set_adcs call fix_timer mov counter,0 mov mode,RECMODE call playrec mov ah,9 lea dx,cs:install_msg int 21h TSR_Inst 09h END start . 0