home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 mARCH
/
PCWK3A99.iso
/
Archiwiz
/
Tar320
/
SOURCES.ZIP
/
CTQUIRKS.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-12-31
|
3KB
|
162 lines
include farnear.inc
BIOS_timer equ 46Ch
_DATA segment byte public 'DATA'
cnt_suspend dw 0,0
_DATA ends
_TEXT segment byte public 'CODE'
assume cs:_TEXT, ds:_DATA
program _suspend_value
; unsigned long suspend_value(unsigned usec)
push bp
mov bp,sp
push ds
mov ax,_DATA
mov ds,ax
mov ax,cnt_suspend
or ax,cnt_suspend+2
; Was the initialization done?
jnz short calculate
xor ax,ax
mov ds,ax
; Test the availability of BIOS timer data
xor ah,ah
int 1Ah
cli
mov ax,ds:BIOS_timer
mov bx,ds:BIOS_timer+2
sti
; If the difference > 1
sub ax,dx
sbb bx,cx
jnz short dummy_counter
shr ax,1
jz short measure
; BIOS timer data unavailable - use dummy value
dummy_counter:
mov ax,60000 ; matches ~ 286/8 MHz
xor dx,dx
jmp short store_counter
; Measure computer performance for delay calculations
measure:
push si
push di
xor ax,ax
mov ds,ax
xor dx,dx
mov di,ds:BIOS_timer
wait_tick_over:
cmp di,ds:BIOS_timer
je short wait_tick_over
add di,6 ; wait for 5 more ticks
jmp short loop_condition
calibrate_loop:
add ax,1
adc dx,0 ; increase long
loop_condition:
mov cx,si ; begin long comparison
xor cx,ax
mov bx,di
xor bx,dx
or cx,bx ; finish long comparison
cmp di,ds:BIOS_timer
jne short calibrate_loop
; The result long number matches to 270272 microseconds
pop di
pop si
store_counter:
mov bx,_DATA
mov ds,bx
mov cnt_suspend,ax
mov cnt_suspend+2,dx
calculate:
; Get 48-bit multiplication
mov ax,cnt_suspend
mul word ptr arglist[0] ; microseconds
xchg bx,ax ; mov bx,ax
mov cx,dx
mov ax,cnt_suspend+2
mul word ptr arglist[0] ; microseconds
add ax,cx
adc dx,0 ; DX:AX:BX contains multiplication
; Add a half of divisor - arround the result of division
add bx,4064
adc ax,2
adc dx,0
; Begin long division - shift by 4 = divide by 16
mov cx,4
shift_loop:
shr dx,1
rcr ax,1
rcr bx,1
loop short shift_loop
; Finish long division - divide by 16892
mov cx,16892
div cx
xchg bx,ax
div cx
mov dx,bx
; DX:AX = (usec * cnt_suspend + uSEC/2) / uSEC
pop ds
pop bp
ret
_suspend_value endp
program _suspend
; void suspend(unsigned long counter)
push bp
mov bp,sp
push si
push di
push ds
mov si,arglist[0] ; counter
mov di,arglist[2]
xor ax,ax
mov ds,ax
xor dx,dx
jmp short loop_entry
delay_loop:
add ax,1
adc dx,0 ; increase long
loop_entry:
mov cx,si ; begin long comparison
xor cx,ax
mov bx,di
xor bx,dx
cmp di,ds:BIOS_timer
or cx,bx ; finish long comparison
jnz short delay_loop
pop ds
pop di
pop si
pop bp
ret
_suspend endp
program _ptr2abs
; long ptr2abs(void far *ptr)
push bp
mov bp,sp
mov ax,arglist[0] ; offset
mov bx,arglist[2] ; segment
mov cl,4
mov dx,bx
shl bx,cl
rol dx,cl
xor dx,bx ; clear all save page number
add ax,bx ; AX = page offset
adc dx,0 ; DX = page number
pop bp
ret
_ptr2abs endp
_TEXT ends
end