🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #2210

Re: System timer reprogramming

#2210
From: Edward John Kalenda
Date: Thu, 13 Sep 1990 06:25
222 lines
4533 bytes
Dave Denson (densond@prism.cs.orst.edu) writes:
> I need to find out how to reprogram the IBM clock-tick timer to a faster
> rate. Norton's Programming Guide gives little or no information on this.
> I plan to use int 08h to decrement a one-byte timer for game clocking
> purposes.

I've excerpted the following from a MSC6.0 small model program I did
which should do what you want.

Ed
ekalenda@cup.portal.com

------- clip here --------------

	TITLE   timer.asm
	NAME    timer

_TEXT	SEGMENT  WORD PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT  WORD PUBLIC 'DATA'
_DATA	ENDS

	ASSUME  CS: _TEXT, DS: _DATA

_DATA	SEGMENT

; local stack for the timer interrupt handler
timer_stack		db	128 dup(0)
timer_stack_start	dw	8 dup(0)

rate		dw	0	; current tick rate
pass_int	dw	0	; used to pass int to old handler
active		dw	0

	public	_timer_count	; in C, declare as:
_timer_count	dd	0	; extern unsigned long timer_count

_DATA	ENDS


_TEXT	SEGMENT

; ================================================== _timer_start ===========

	PUBLIC	_timer_start

_timer_start	proc near

; save all registers used
	push	ax
	push	bx
	push	dx
	push	es

; check for already being active
	cmp	_timer_active,0
	jne	already_active

; initialize the counter
	mov	word ptr _timer_count,0
	mov	word ptr _timer_count+2,0

; take over the timer interrupt
	mov	ax,3508h	; get interrupt vector
	int	21h
	mov	word ptr cs:old_int08h,bx
	mov	word ptr cs:old_int08h+2,es
	mov	dx,offset _timer_handler
	push	ds
	push	cs
	pop	ds
	mov	ax,2508h	; set interrupt handler
	int	21h
	pop	ds

; reprogram the timer frequency
	pushf
	cli
	mov	al,34h
	out	43h,al
	mov	ax,0800h		; 32 times regular rate
	out	40h,al
	mov	al,ah
	out	40h,al
	mov	pass_int,0
	mov	_timer_active,1
	popf

; restore registers used
already_active:
	pop	es
	pop	dx
	pop	bx
	pop	ax
	ret

_timer_start	ENDP


; ================================================== _timer_stop ============

	PUBLIC	_timer_stop

_timer_stop	proc near

; save all registers used
	push	ax
	push	dx
	push	es

; check for timer not being active
	cmp	_timer_active,0
	je	not_active

; restore the timer frequency
	pushf
	cli
	mov	al,34h
	out	43h,al
	mov	al,0			; 0 means 65536
	out	40h,al
	out	40h,al
	mov	_timer_active,0

; restore the timer interrupt, do not use int21 as control-C will interrupt
; this operation causing the timer handler to not be restored
	push	ds
	lds	dx,cs:old_int08h
	mov	ax,0
	mov	es,ax
	mov	es:[20h],dx
	mov	es:[22h],ds
	pop	ds
	popf

; restore registers
not_active:
	pop	es
	pop	dx
	pop	ax
	ret

_timer_stop	endp


; ================================================== _timer_handler ===========

; in code segment to allow stack switch before saving registers
old_sp			dw	?
old_ss			dw	?
new_sp			dw	offset timer_stack_start
new_ss			dw	seg    timer_stack_start
our_ds			dw	_DATA

; in code segment to allow chain to old handler after restoring environment
; to that existing at the interrupt
old_int08h	dd	0	; old handler address

_timer_handler	proc far

; switch to a local stack
	mov	cs:old_ss,ss
	mov	cs:old_sp,sp
	mov	ss,cs:new_ss
	mov	sp,cs:new_sp

; save the registers used
	push	ax
	push	dx
	push	si
	push	ds
	push	es

; point to our data area
	mov	ds,cs:our_ds

; see if we are active yet
	cmp	_timer_active,0
	jne	do_stuff
	jmp	do_pass_int

; do our thing here, maintain a count of number of interrupts seen
do_stuff:
	add	word ptr _timer_count,1
	adc	word ptr _timer_count+2,0

; fall through to here, see if we pass control to the old handler
test_pass_int:
	mov	ax,0800h
	add	pass_int,ax
	jnc	do_not_pass_int

; restore the registers and the stack, then execute the real int08h handler
do_pass_int:
	pop	es
	pop	ds
	pop	si
	pop	dx
	pop	ax
	mov	ss,cs:old_ss
	mov	sp,cs:old_sp
	jmp	cs:[old_int08h]

do_not_pass_int:
; dismiss the interrupt and restore registers
	mov	al,20h
	out	20h,al
	pop	es
	pop	ds
	pop	si
	pop	dx
	pop	ax
	mov	ss,cs:old_ss
	mov	sp,cs:old_sp
	iret

_timer_handler	endp


_TEXT	ENDS

	END
Technical Details
Message-ID: <33855@cup.portal.com>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!cs.utexas.edu!usc!apple!portal!cup.portal.com!ekalenda
References: <20232@orstcs.CS.ORST.EDU>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!cs.utexas.edu!usc!apple!portal!cup.portal.com!ekalenda
From: ekalenda@cup.portal.com (Edward John Kalenda)
Newsgroups: comp.os.msdos.programmer
Subject: Re: System timer reprogramming
Message-ID: <33855@cup.portal.com>
Date: 13 Sep 90 06:25:44 GMT
References: <20232@orstcs.CS.ORST.EDU>
Organization: The Portal System (TM)
Lines: 222