118 lines
3.6 KiB
NASM
118 lines
3.6 KiB
NASM
|
; =====> 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
|
|||
|
|
|||
|
|