pcs/stimer.asm

118 lines
3.6 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; =====> STIMER.ASM
;***************************************
;* TIPC Scheme '84 Engine Timer *
;* Utilities *
;* *
;* (C) Copyright 1984,1985 by Texas *
;* Instruments Incorporated. *
;* All rights reserved. *
;* *
;* Date Written: June 1985 *
;* Last Modification: 30 July 1985 *
;***************************************
include scheme.equ
DGROUP group data
data segment word public 'DATA'
assume DS:DGROUP
timer_int db 58h ;40 Hz timer interrupt number
data ends
PGROUP group prog
prog segment byte public 'PROG'
assume CS:PGROUP
dos_func equ 21h ;DOS function call interrupt number
get_vec equ 35h ;DOS call to retrieve interrupt vector
set_vec equ 25h ;Call to set vector
public tickstat
tickstat db -1 ;0=timeout, 1=engine running,
; -1=no engine running (normal)
clk_ptr dw 0,0 ;Former timer vector
lo_time dw 0 ;Timer ticks
hi_time dw 0
; Start timer running
; Calling sequence: set_timer(hi,lo)
; Where ---- hi,lo: upper,lower words of initial timer value
; Returns nonzero iff the set was during normal VM running mode
set_args struc
dw ? ;Caller's BP
dw ? ;Return address
hi dw ? ;High word
lo dw ? ;Low word
set_args ends
public settimer
settimer proc near
cmp PC_MAKE,252 ;Is computer an IBM variant?
jb nochange ;Jump if not
mov timer_int,1ch ;Otherwise, set to IBM's vector
nochange: xor AX,AX ;Clear AX
cmp CS:tickstat,-1 ;Check for normal run mode
jne no_set ;Abort if timeout or engine running
push BP
mov BP,SP
push ES ;Save ES
mov AH,get_vec ;Put present timer interrupt vector
mov AL,timer_int ; into ES:BX
int dos_func
mov CS:clk_ptr,BX ;Save vector
mov CS:clk_ptr+2,ES
pop ES ;Restore ES
mov AX,[BP].hi ;Set timer
mov CS:hi_time,AX
mov AX,[BP].lo
mov CS:lo_time,AX
push DS ;Save DS
mov AH,set_vec ;Set new interrupt vector
mov AL,timer_int
push CS ;Put vector segment number in DS
pop DS
mov DX,offset tick ;Vector offset in DX
int dos_func
pop DS ;Restore DS
mov AL,1 ;Denote engine running
mov CS:tickstat,AL
pop BP ;Restore BP
no_set: ret
settimer endp
; Stop the timer
; Calling sequence: rst_timer();
; Returns the number in the counter at the time of reset
public rsttimer
rsttimer proc near
cmp CS:tickstat,1 ;Only if timeout or engine running
ja no_reset ;Otherwise forget it
mov AH,set_vec ;Prepare to reset timer interrupt
mov AL,timer_int
push DS ;Save DS
lds DX,dword ptr CS:clk_ptr ;Put original vector into DS:DX
int dos_func
pop DS ;Restore DS
mov CS:tickstat,-1 ;Denote normal mode
no_reset: mov AX,CS:hi_time ;Return 32-bit clock value
mov BX,CS:lo_time
ret
rsttimer endp
;The new timer code
tick proc near
sti ;Re-enable interrupts
cmp CS:tickstat,0 ;If timeout, do nothing special
je norm_vec
sub CS:lo_time,1 ;Otherwise decrement counter
sbb CS:hi_time,0
jnz norm_vec ;If not zero, jump ahead
cmp CS:lo_time,0
jnz norm_vec
mov CS:tickstat,0 ;Otherwise, record timeout event
C_call force_ti ;Force a timeout condition
norm_vec: jmp dword ptr CS:clk_ptr ;Jump to original timer code
tick endp
prog ends
end