; Real time clock display
;
; Version 1.0NK
;
; 1st october 1987
;
; Modified version of the Jim Bates' clock program - does not display
; seconds (what's the point???)
;

Screen EQU 90H ;Location of first position on screen

INT8_OFF EQU 20H   ; INT 8 Offset
INT8_SEG EQU 22H   ; INT 8 Segment

CTRL_KEYS EQU 417H ; Position of control keys byte
TIM_HI	  EQU 46EH ; Position of timer lo word
TIM_LO	  EQU 46CH ; Position of timer hi word

BEGIN: JMP INSTALL

FLAG:  DB 0; Shows condition of control keys
DELAY: DB 0; Counts up to 18 to allow update

NEW_INT8 PROC NEAR

PUSH AX,BX,CX,DX,DS,SI,BP ; Save all registers etc..
SUB  AX,AX		  ; Zero AX register
MOV  DS,AX		  ; Access zero page of RAM
MOV  AH,DS:[CTRL_KEYS]	  ; Keyboard access
AND  AH,05H		  ; <CTRL> <R-SHIFT> ??
CMP  AH,05H
JNZ  CLOCK		  ; Yes!
MOV  AX,CS		  ; Get CS into DS
MOV  DS,AX		  ; Now point to our segment
CMP  BYTE PTR [FLAG],0FFH ; Check FLAG indicator
JZ   QUITSTEP
MOV  BYTE PTR [FLAG],0FFH ; Set flag active
XOR  BYTE PTR [SWITCH],9DH ; Toggle jump instruction
JMP  QUITSTEP

CLOCK:

PUSH CS
POP  DS 		  ; Put our segment into DS
MOV  BYTE PTR [FLAG],0	  ; Set flag - keys released
INC  BYTE PTR [DELAY]	  ; Bump the delay counter
CMP  BYTE PTR DELAY,12H   ; Update every 18 timer ticks (1 second)

SWITCH:

JBE QUITSTEP		  ; Change to JMP to disable
MOV BYTE PTR [DELAY],0	  ; Reset the counter
SUB AX,AX
MOV DS,AX
MOV CX,DS:[TIM_HI]	  ; Get system clock time
MOV AX,DS:[TIM_LO]

;-----Divide down to find hours, mins and seconds-----

PUSH CX 		 ; This already represents hours
MOV DX,0		 ; Prepare to divide
MOV CX,91		 ; by 91 (18.2 * 5)
DIV CX			 ; Quotient in AX, remainder in DX
MOV BX,DX		 ; Save remainder in BL
MOV DX,0		 ; Prepare to divide by 12
MOV CX,12		 ; To get minutes
DIV CX
MOV BH,AL		 ; Save minutes
XCHG DX,AX		 ; Remainder in AX
MOV DX,0		 ; Prepare to multiply by 5
MOV CX,5		 ; (Back to seconds)
MUL CX			 ; AX has major seconds

L1:

SUB BL,18		 ; How many 18's in BL??
JC L2
INC AX
JMP L1

QUITSTEP:

JMP QUIT		 ; This is a stepping stone only

L2:

POP CX			 ; Recover hours
PUSH AX 		 ; Save seconds
XCHG CH,CL		 ; Hours into CH
MOV CL,BH		 ; Minutes into CL
PUSH CX 		 ; Save hours and minutes

RAM:

MOV AX,0B000H		; Screen RAM (Set by INSTALL)
MOV DS,AX		; Set DS to point to screen segment
POP CX			; Hours and minutes
MOV AL,CH		; Hours
AAM			; Change to decimal
OR  AX,3030H		; to ASCII
MOV DS:[SCREEN],AH	; Tens of hrs to screen
MOV DS:[SCREEN+2],AL	; Units of hrs to screen
SUB AX,AX
MOV AL,CL		; Minutes
AAM			; To decimal
OR  AX,3030H		; Ascii adjust
MOV BL,AH		;
MOV DS:[SCREEN+6],AH
MOV BL,AL
MOV DS:[SCREEN+8],AL
MOV BYTE PTR DS:[SCREEN+4],3AH ; Colon	to screen
MOV BYTE PTR DS:[SCREEN+10],3AH
POP CX			; Remove hundredths from stack
MOV AL,CL
AAM
OR AX,3030H
MOV BL,AH
MOV DS:[SCREEN+12],AH
MOV BL,AL
MOV DS:[SCREEN+14],AL

QUIT:

POP BP,SI,DS,DX,CX,BX,AX

DB 0EAH

JSEG: DB 0,0
JOFF: DB 0,0

NEW_INT8 ENDP

PROTECTOR LABEL BYTE

; All code to here will be protected by DOS

INSTALL PROC NEAR

PUSH DS
LEA DX,MSG1
MOV AH,9
INT 21H
SUB AX,AX
MOV DS,AX
MOV SI,DS:[INT8_OFF]
MOV DX,DS:[INT8_SEG]
MOV DS,DX
CMP WORD PTR [SI],5350H
JNZ NEXT1
POP DS
LEA DX,MSG3
MOV AH,9
INT 21H
INT 20H

NEXT1:

MOV DS,AX
MOV AX,DS:[INT8_OFF]
MOV DX,DS:[INT8_SEG]
POP DS
MOV [JSEG],AX
MOV [JOFF],DX
INT 11H
AND AL,30H
CMP AL,30H
JZ NEXT2
MOV BYTE PTR [RAM+2],0B8H

NEXT2:

LEA DX,NEW_INT8
MOV AX,2508H
INT 21H
LEA DX,MSG2
MOV AH,9
INT 21H
LEA DX,PROTECTOR
INT 27H

MSG1 DB 'NK''s toggle clock. Use <CTRL> <RIGHTSHIFT> to toggle',13,10,'$'
MSG2 DB 'Installed OK',13,10,'$'
MSG3 DB 'Clock already installed',13,10,'$'


                                  