INTRODUCTION This code example provides a set of keyboard routines to control sound output while waiting for a user to enter a keyboard character. The advantage to this method is that a main routine can call these sound routines to play a sound sequence, and the sound routines will return control back to the main routine whenever the user enters keyboard data so that the main routine can continue computing while the sound plays in the background. The code example has two different code entry points for getting keyboard data. One code entry point is a standard get_keyinput call which will wait for a key and update the sound data until a key code is found. The other code entry point is the get_keyinput_to call, which will wait a set amount of time for a key code and if none is found, return with a no key code found condition. The calling routine puts a timeout counter value in register AX on entry. The counter value is based on the system clock which ticks at 18.2 times per second. The entry point start_table_sound is used to begin a background sound sequence. On entry, the register BX indexes a table of sound data. The table has a format of four byte entries and is terminated by a data word of zero. The four bytes are used as two words: the first is a duration count and the second is a tone value. There are two code entry points for turning the background sound off and on. There is also a utility to flush out the keyboard buffer that can be executed with a call to flush_keyboard. ;Set of keyboard routines with sound outputs.MODEL small.STACK 500.DATA ;define table for sound output;sample_sounds dw 8,45000 ;long low sound; dw 2,2000 ;short high sound; dw 0 ;end of sample sound tablesound_table dw 0sound_time_m dw 0sound_time_l dw 0sound_flag db 0sound_on_flag db 0,0key_time_out_m dw 0key_time_out_l dw 0.CODE;************ ^^^^^^^^^^ *************;### code entry point #####get_keyinput proc near;this routine checks for keyboard data in BIOS buffer ; and returns with data if there;else it updates sound output data and loops to check for ; keyboard data again until keyboard data found;on exit AX has keyboard data public get_keyinput push bx push cx push dxget_keyinput_loop: mov ah,1 ;set AH for scan int 16H ;BIOS Call ;branch if no keyboard data jz sound_update mov ah,0 ;set AH for get key int 16H ;BIOS Call pop dx pop cx pop bx ret;******* -------- *******sound_update: cmp sound_flag,0 ;check for sound on???? jz get_keyinput_loop ;branch out if sound off mov cx,sound_time_m ;else check for sound update mov ax,sound_time_l call test_current_time ;is it time for update ?? jc get_keyinput_loop ;branch if not time mov bx,sound_table mov ax,[bx] ;get next sound update value or ax,ax ;?? end of sound ?? jz turn_sound_off ;branch if end sound call get_time_plus_ax ;reset sound duration mov sound_time_m,cx mov sound_time_l,ax inc bx inc bx mov ax,[bx] inc bx inc bx mov sound_table,bx call sound_out_ax ;go set sound frequency jmp get_keyinput_loop ;branch to keyboard loopturn_sound_off: call sound_off mov sound_flag,0 jmp get_keyinput_loop ;branch to keyboard loopget_keyinput endp;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;************ ########## *************;### code entry point #####get_keyinput_to proc near;get keyboard data with timeout if no data available;on entry AX has time duration in 18 ticks per second;on exit if carry clear then AX has keyboard data public get_keyinput_to push bx push cx push dx call get_time_plus_ax ;add duration to current time mov key_time_out_m,cx ;set timeout value mov key_time_out_l,axget_keyinput_to_loop: mov ah,1 ;ready to scan keyboard data int 16H ;BIOS Call jz sound_update_to ;branch if no keyboard data mov ah,0 ;ready to get key data int 16H ;BIOS Call pop dx pop cx pop bx clc ;set keyboard data flag retget_keyinput_to_1: mov cx,key_time_out_m ;check for timeout mov ax,key_time_out_l call test_current_time jc get_keyinput_to_loop ;branch if no timeout xor ax,ax ;else timeout return condition pop dx pop cx pop bx stc ;set no keyboard data flag ret; ******** %%%%%%% ********sound_update_to: cmp sound_flag,0 ;check for sound on???? jz get_keyinput_to_1 ;branch if sound off mov cx,sound_time_m ;else check for sound update mov ax,sound_time_l call test_current_time jc get_keyinput_to_1 ;branch if not ready for update mov bx,sound_table mov ax,[bx] or ax,ax ;test for end of table jz turn_sound_off_to ;branch if end of table data call get_time_plus_ax mov sound_time_m,cx mov sound_time_l,ax inc bx inc bx mov ax,[bx] inc bx inc bx mov sound_table,bx call sound_out_ax jmp get_keyinput_to_1turn_sound_off_to: call sound_off mov sound_flag,0 jmp get_keyinput_to_1get_keyinput_to endp;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;************ @@@@@@@@@@ ************;### code entry point #####start_table_sound proc near ;subroutine to start background sound output ;on entry BX indexes sound data table public start_table_sound push ax push bx mov ax,[bx] call get_time_plus_ax mov sound_time_m,cx mov sound_time_l,ax inc bx inc bx mov ax,[bx] inc bx inc bx mov sound_table,bx call sound_out_ax mov sound_flag,0FFH pop bx pop ax retstart_table_sound endp;************ ========== *************;### code entry point #####flush_keyboard proc near ;utility to flush contents of keyboard buffer public flush_keyboard mov ah,1 int 16H ;BIOS Call ;scan for keyboard data jz flush_keyboard_x ;branch if no keyboard data mov ah,0 ;else get keyboard data int 16H ;BIOS Call jmp flush_keyboardflush_keyboard_x: retflush_keyboard endp;************* ----------- **************sound_out_ax proc near ;set sound out frequency to data value in AX push ax push ax cmp sound_on_flag,0 jne sound_out_1 in al,61H ;input port 61h or al,3 out 61H,al ;output port 61hsound_out_1: mov al,0B6H out 43H,al ;output port 43h pop ax out 42H,al ;output port 42h xchg al,ah out 42H,al ;output port 42h mov sound_on_flag,0FFH pop ax retsound_out_ax endp;*********** $$$$$$$$$$ ************;###### code entry point #######sound_off proc near ;turn sound port off public sound_off push ax cmp sound_on_flag,0 je sound_off_exit in al,61H ;input port 61h and al,0FCH out 61H,al ;output port 61h mov sound_on_flag,0sound_off_exit: pop ax retsound_off endp;************** %%%%%%%%%% ***************;with all CX:AX time values, CX is most significant ; and AX is least significantget_current_time proc near;on exit CX:AX has 32 bit day clock value ; in 18.2 ticks per second push dx xor ax,ax ;set AH to zero int 1AH ;BIOS Call get time mov ax,dx pop dx retget_current_time endp;****************************get_time_plus_ax proc near;on entry AX has 16 bit value to add to current clock time;on exit CX:AX has new 32 bit clock value push dx push ax xor ax,ax int 1AH ;BIOS Call pop ax add ax,dx adc cx,0 pop dx retget_time_plus_ax endp;************ ######## ************test_current_time proc near;on entry CX:AX has time value ; to be subtracted from the current time;on exit if carry set then current time ; is less than CX:AX time push dx push cx push ax xor ax,ax int 1AH ;BIOS Call cmp dx,18 jb test_current_time_2test_current_time_1: pop ax sub dx,ax pop dx sbb cx,dx mov cx,dx pop dx rettest_current_time_2: or cx,cx jnz test_current_time_1 pop ax ;this is fix code for midnight factor pop dx pop dx clc ;clear carry condition rettest_current_time endp;***************************************** end  
|