fb1 ; ISR routine for MORSE OPTION PROC:PRIVATE DOSSEG .MODEL SMALL .386 MORSEBUFSIZE EQU 128 EXTERN _morsebuf:WORD, _inptr:WORD, _outptr:WORD EXTERN _beep_on_val:BYTE, _beep_off_val:BYTE EXTERN _char_to_write:BYTE EXTERN _showstat:WORD EXTERN _fm_write:PROC .DATA PUBLIC _delay_cntr _delay_cntr word 0 int8sched word 0 tmr_count word 0ffffh old_int8_vect dword ? .CODE ASSUME CS:_TEXT, DS:@data PUBLIC _inst_morse_isr, _rest_morse_isr, _set_timer_count morse_isr PROC FAR push ax push bx push dx push ds mov ax, @data mov ds, ax cmp _delay_cntr, 0 jz no_dec dec _delay_cntr jnz chk_orig_int ;Not time to check for data yet no_dec: mov bx, _outptr cmp bx, _inptr ;inptr <> outptr (Data in buffer)? jz chk_orig_int ;No shl bx, 1 mov ax, _morsebuf[bx] ;Get data push ax ;Store away temporarily shr bx, 1 inc bx ;Increment out-buffer pointer and bx, MORSEBUFSIZE-1 ;Wrap if past end mov _outptr, bx ;Store updated buffer ptr test ax, 8000h ;Check if tone on or off jz tone_off mov bl, _beep_on_val ;Tone on key-on byte jmp out_tone tone_off: mov bl, _beep_off_val ;Tone off key-on byte out_tone: mov dx, 388h ;FM register port mov al, 0b0h ;Key-on register address chn 0 out dx, al ;Write register address in al, dx ;Dummy reads for recovery in al, dx inc dx ;FM data port mov al, bl ;Key-on byte out dx, al ;Write data pop ax ;Restore AX cmp _showstat, 1 ;If show status... jnz store_delay test ax, 4000h ;Check if character completed jz store_delay ;No ror ax, 5 ;Shift the ASCII bits right.. mov _char_to_write, al ;and store character for output by rol ax, 5 ;mainline store_delay: and ax, 0000000000011111b ;Mask out delay value.. mov _delay_cntr, ax ;and store in delay_cntr chk_orig_int: mov ax, tmr_count ;Check if it's time for add int8sched, ax ;orig ISR jnc send_EOI pushf call old_int8_vect ;Call orig ISR jmp skip_EOI send_EOI: mov dx, 20h mov al, 20h out dx, al skip_EOI: pop ds pop dx pop bx pop ax iret morse_isr ENDP _inst_morse_isr PROC push si push es mov ax, 3508h ;Get INT8 vector int 21h mov word ptr[old_int8_vect], bx ;Save old INT8 vector mov word ptr[old_int8_vect + 2], es push ds mov ax, 2508h ;Install new ISR push cs pop ds mov dx, offset morse_isr int 21h pop ds xor ax, ax mov es, ax mov ax, word ptr es:[46ch] ;Synchronize with wait_tick1: ;BIOS tick cmp word ptr es:[46ch], ax jz wait_tick1 cli mov al, 34h ;Set Mode 2 out 43h, al xor ax, ax jmp SHORT $+2 out 40h, al jmp SHORT $+2 out 40h, al sti pop es pop si ret _inst_morse_isr ENDP _rest_morse_isr PROC push si push es xor ax, ax mov es, ax mov ax, word ptr es:[46ch] ;Synchronize with wait_tick2: ;BIOS tick cmp word ptr es:[46ch], ax jz wait_tick2 cli mov al, 36h ;Back to mode 3 out 43h, al xor ax, ax ;Load count jmp SHORT $+2 out 40h, al jmp SHORT $+2 out 40h, al push ds ;Restore old INT 8 mov ax, 2508h mov dx, word ptr[old_int8_vect] mov ds, word ptr[old_int8_vect + 2] int 21h pop ds sti pop es pop si ret _rest_morse_isr ENDP _set_timer_count PROC push bp mov bp, sp push cx push es mov cx, [bp + 4] xor ax, ax mov es, ax mov ax, word ptr es:[46ch] ;Synchronize with wait_tick3: ;BIOS tick cmp word ptr es:[46ch], ax jz wait_tick3 cli mov al, cl ;Reload counter with out 40h, al ;new count mov al, ch jmp short $+2 out 40h, al mov tmr_count, cx ;Update tmr_count ; mov int8sched, 0 sti pop es pop cx pop bp ret _set_timer_count ENDP END . 0