home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
p
/
pcrte224.zip
/
SOURCE.ZIP
/
TIMER.INC
< prev
next >
Wrap
Text File
|
1992-06-09
|
7KB
|
212 lines
;;*************************************************************************
;; timer.inc timer.inc
;;*************************************************************************
;; Copyright (C) 1989 Northwestern University, Vance Morrison
;;
;;
;; Permission to view, compile, and modify for LOCAL (intra-organization)
;; USE ONLY is hereby granted, provided that this copyright and permission
;; notice appear on all copies. Any other use by permission only.
;;
;; Northwestern University makes no representations about the suitability
;; of this software for any purpose. It is provided "as is" without expressed
;; or implied warranty. See the copywrite notice file for complete details.
;;
;;*************************************************************************
;; timer.inc implements functions that will allow a task to wait a specific
;; amount of time
;;
;; Routines provided by this module
;;
;; TIMER_DECLARE name, task
;; TIMER_DEFINE name
;; TIMER_MARK_in_AX_const_CX_BP_ES name, code_label
;; TIMER_RETURN name
;;
;; AUTHOR: Vance Morrison
;; DATE : 4/22/89
;;*************************************************************************
TIMER_MAX = 32 ;; number of outstanding requests
timer_entry struc
timer_next dw 0 ;; this MUST be first !!!
timer_time dw 0
timer_jmp dw 0
timer_entry ends
timer_data struc
timer_next_time dw ?
timer_list dw ?
timer_free dw ?
timer_table timer_entry TIMER_MAX dup (<>)
timer_switch_ctr db ? ;; counts number of context switches
timer_data ends
;;************************************************************************
;; TIMER_DECLARE declares a structure called 'name' that can be used to
;; wait for a certain time. 'task' is the name of the task needed
;; by this module
;;
TIMER_DECLARE MACRO name, task
.errb <task>
.DATA
timer_&name&_task equ task
global timer_&name&_data:timer_data
.CODE
ENDM
;;************************************************************************
;; TIMER_DEFINE defines all the data storage and does initialization
;; functions for the timer object 'name'.
TIMER_DEFINE MACRO name
local around, start
.errb <name>
.data
timer_&name&_data timer_data <>
.code
jmp around
start:
TIMER_TASK name, %timer_&name&_task
;; this does not fall through
around:
mov CX, TIMER_MAX
xor DI, DI
mov SI, offset timer_&name&_data.timer_table+(TIMER_MAX*(size timer_entry))
init_loop:
sub SI, size timer_entry
mov [SI+timer_next], DI
mov DI, SI
dec CX
jnz init_loop
mov timer_&name&_data.timer_free, SI
mov timer_&name&_data.timer_list, 0
mov timer_&name&_data.timer_switch_ctr, 1
;; start the task
TASK_DEFINE %timer_&name&_task, start
ENDM
;;************************************************************************
;; TIMER_MARK_in_AX_const_CX_BP_ES sets the mark point so that
;; the code at 'code_label' will be called aftger AX ticks have elapsed.
;; (a tick is 18th of a second). The code should call TIMER_RETURN
;; when it is done processing
;; (Note that AX is limited to be 1024 seconds (32K ticks))
;;
TIMER_MARK_in_AX_const_CX_BP_ES MACRO name, code_label
local done, sort_loop, found
.errb <code_name>
;; get current time
TIMER_GET_TICK_out_BX_const_AX_CX_BP_SI_DI_ES
add AX, BX
mov DX, AX ;; DX holds expiration time
mov SI, offset timer_&name&_data.timer_list
mov DI, timer_&name&_data.timer_list
sort_loop: ;; find the position in the list
or DI, DI
jz found
cmp DX, [DI+timer_time]
js found
mov SI, DI
mov DI, [SI+timer_next]
jmp sort_loop
found:
mov BX, timer_&name&_data.timer_free
or BX, BX ;; anything on the free list?
jz done
mov AX, [BX+timer_next] ;; insert the record
mov timer_&name&_data.timer_free, AX
mov [BX+timer_time], DX
mov [BX+timer_jmp], offset code_label
mov [BX+timer_next], DI
mov [SI+timer_next], BX
mov BX, timer_&name&_data.timer_list
mov AX, [BX+timer_time]
mov timer_&name&_data.timer_next_time, AX
done:
ENDM
TIMER_RETURN MACRO name
.errb <name>
TASK_RETURN %timer_&name&_task
ENDM
;;************************************************************************
;; TIMER_TASK is the code that the TIMER task runs. This task basicly just
;; waits for the next event, and starts it when its time.
;;
TIMER_TASK MACRO name
local done, no_more, do_stuff
.errb <name>
dec timer_&name&_data.timer_switch_ctr ;; only check every 20 context
jz do_stuff
TASK_RETURN %timer_&name&_task
do_stuff:
mov timer_&name&_data.timer_switch_ctr, 20
TIMER_GET_TICK_out_BX_const_AX_CX_BP_SI_DI_ES
cmp BX, timer_&name&_data.timer_next_time
js done ;; if time is not up. Note that
;; this comparison works correctly
;; in the face of wraparound as long
;; as the delta T is < 32K
mov SI, timer_&name&_data.timer_list
or SI, SI
jz done
;; take event off the queue
mov BX, [SI+timer_next]
mov timer_&name&_data.timer_list, BX
or BX, BX
jz no_more
mov AX, [BX+timer_time]
mov timer_&name&_data.timer_next_time, AX
no_more:
mov AX, timer_&name&_data.timer_free
mov [SI+timer_next], AX
mov timer_&name&_data.timer_free, SI
jmp [SI+timer_jmp]
done:
TASK_RETURN %timer_&name&_task
ENDM
;;*************************************************************************
;; dig into low memory and get me the tick counter.
;;
;; This is where IBM Bios puts its tick counter. (18 ticks/sec)
;; Note that this location may be different on clones, but as far
;; I I can tell, most clones put the ticks here too.
IBM_BIOS_TICK equ 46CH
TIMER_GET_TICK_out_BX_const_AX_CX_BP_SI_DI_ES MACRO
mov DX, DS
xor BX, BX
mov DS, BX
mov BX, IBM_BIOS_TICK
mov BX, [BX]
mov DS, DX
ENDM