;From Igor Comba
;***** Clock 1 *****
;8-digit hex counter
;activate: both shifts+ALT
;stop: both shifts+CTRL
start:
jmp install
;***** Timer Interrupt Counter ******
newint8:
pushf
push ax,bx,cx,dx,si,di,bp,es,ds
xor ax,ax
mov ds,ax
mov ax,ds:[417h] ;shift status
and ax,0000001100000111b ;get what interests me
cmp ax,0000001000000011b ;2 shifts+ALT act. (start clock)
je act
cmp ax,0000000100000111b ;2 shifts desact + ctrl (stop clock)
jne goon1
mov byte ptr cs:[active],0 ;deactivate clock
mov word ptr cs:[segment1],0 ;reset clock (does not output this one)
mov word ptr cs:[segment2],0
jmp goon1
act:
mov byte ptr cs:[active],1 ;activate clock
goon1:
cmp byte ptr cs:[active],1 ;is the counter active?
jne oldint8
add word ptr cs:[segment2],1 ;inc counter (4 bytes)
adc word ptr cs:[segment1],0
;****screen output****
mov bx,cs:[segment2] ;Start with lower bytes. I'll output the
;numbers backwards, because it's easier
mov es,0B800h ;Video segment (por ahora CGA & VGA)
mov di,79*2 ;upper right corner of screen
std
mov dx,0
poke2:
mov cx,4 ;there are 4 numbers (1/4bits) in bx
poke:
mov ax,bx ;get ASCII code of hex number in 4 lower
and ax,0Fh ;bits of bx
add al,30h ;cover number to ASCII Hex Code
cmp al,3Ah
jb okey1
add al,7
okey1:
stosb ;dump number in screen
dec di ;jmp attribute byte
shr bx,1
shr bx,1
shr bx,1
shr bx,1 ;bx=bx/16 (next 4 bits)
loop poke
mov bx,cs:[segment1] ;get next 4 numbers (2 bytes)
cmp di,71*2 ;finished dumping?
ja poke2
oldint8:
pop ds,es,bp,di,si,dx,cx,bx,ax
int8:
popf
jmp far 0000:0000 ;transfer control to original int8
;*** Variables *****
segment1 dw 0 ;lower counter word
segment2 dw 0 ;high counter word
active db 0 ;activation flag
;*** Installation program *****
install:
mov ax,3508h
int 21h
mov cs:[int8+2],bx
mov cs:[int8+4],es ;keep old int so I can jump there later
mov dx,offset newint8
mov ax,2508h
int 21h ;set new int
mov dx,offset install
mov cl,4
shr dx,cl
inc dx
mov ax,3100h
int 21h ;exit & stay resident (exit code=00)