;***************************************
;* VRrate by Tom Marshall - 08/18/94
;* Released into the public domain
;***************************************
;* Calculates the frame rate (refresh
;* rate) of the specified video mode.
;* Executes in one refresh period.
;***************************************
MODEL TINY
VIDMODE EQU 12h ;Video mode to test
CODESEG
ORG 0100h
Start: mov al,VIDMODE ;Set video mode via BIOS
mov ah,0
int 10h
cli
call SyncVR ;Wait til start of VR
mov al,36h ;Reset 8253 counter
out 43h,al
xor al,al
out 40h,al
out 40h,al
call SyncVR ;Wait for start of next VR
mov al,00h ;Read latch counter
out 43h,al
in al,40h
mov ah,al
in al,40h
xchg al,ah
neg ax ;Cvt countdown => elapsed
shr ax,1 ;Divide (why?)
sti
mov bx,ax ;Calc frame rate
mov dx,0012h ;Calc FPS = 1193180/Count
mov ax,34DCh
shr bx,1 ;Get 2*FPS = DX:AX/(BX\2) so
div bx ; we can round it
shr ax,1 ;2*FPS => FPS and round
adc ax,0
mov si,OFFSET NumBuf
call Hex2ASCII
mov ax,0003h ;Set 80x25 color text
int 10h
mov dx,OFFSET Info1$ ;Tell 'em what you know
call PrintString
mov dx,OFFSET NumBuf
call PrintString
mov dx,OFFSET Info2$
call PrintString
mov ax,4C00h
int 21h
;***************************************
;* SyncVR - Wait for start of VR
;* Entry: None
;* Exit : None
;* Regs : None
;***************************************
SyncVR PROC
push ax dx
mov dx,03DAh ;b3=1=VR
@@Loop1: in al,dx
test al,8
jnz @@Loop1
@@Loop2: in al,dx
test al,8
jz @@Loop2
pop dx ax
ret
SyncVR ENDP
;***************************************
;* Convert word to ASCII
;* Entry: AX = Word
;* SI = Buffer
;* Exit : SI points to null terminator
;* Regs : BX, CX, DX destroyed
;***************************************
Hex2ASCII PROC
mov bx,10 ;Init divisor
xor cx,cx ;Init counter
DivLoop: xor dx,dx ;Prepare for divide
div bx ; DX:AX / 10 => AX r DX
push dx ;Save digit on stack
inc cx ;Bump counter
or ax,ax
jnz DivLoop
OutLoop: pop ax ;Get digit
add al,'0' ;Convert to ASCII
mov [si],al ;Store in buffer
inc si
loop OutLoop
mov BYTE PTR [si],0 ;Null terminator
ret
Hex2ASCII ENDP
;***************************************
;* Print ASCIIZ string to STDOUT
;* Entry: DS:DX = Address of string
;* Exit : CF, AX as set by 21/40
;* Regs : All general regs destroyed
;* except DX
;***************************************
PrintString PROC
push dx
push es
push ds ;Setup ES:DI
pop es
mov di,dx
mov cx,0FFFFh ;Find length of string
xor al,al
cld
repne scasb
neg cx
sub cx,2
mov bx,1 ;Write string to STDOUT
mov ah,40h
int 21h
pop es
pop dx
ret
PrintString ENDP
Info1$ DB 13,10,13,10,'Frame rate is about ',0
Info2$ DB ' per second.',13,10,0
NumBuf DB 6 dup (?)
END Start