pcs/stimer.asm

118 lines
3.6 KiB
NASM
Raw Normal View History

2023-05-20 05:57:06 -04:00
; =====> 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