INT 1Ah AH=02h reads the time from the CMOS real-time clock, the chip that keeps running from a battery when the PC is off. It returns the hours (0..23) in CH, the minutes in CL and the seconds in DH, each as a BCD byte: two decimal digits in the two nibbles. DL says whether the chip's daylight-saving option is enabled, which is almost never used. The BIOS waits for the chip's update cycle to finish before reading, so the three values belong together.
Since BCD bytes are decimal digits in hex nibbles, printing each byte with a hex routine shows the time directly:
MOV AH, 02h ; BIOS: read the real-time clockINT 1Ah ; CH = hours, CL = minutes, DH = seconds, BCDJC FAIL1 ; CF = 1: the clock is not runningMOV AL, CHCALL PHEX2 ; BCD prints as decimal through the hex routineMOV DL, ":" ; DL only: DH still holds the secondsMOV AH, 02h ; DOS: print the character in DLINT 21hMOV AL, CLCALL PHEX2MOV DL, ":"MOV AH, 02h ; DOS: print the character in DLINT 21hMOV AL, DHCALL PHEX2JMP DONE1FAIL1:MOV DX, OFFSET STOP1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hDONE1:STOP1 DB "the clock is not running$"PHEX2 PROC NEAR ; print AL as two hex digits; keeps every registerPUSH AXPUSH CXPUSH DXMOV DH, AL ; keep the byteMOV CL, 4SHR AL, CL ; the high nibbleCALL HEXN1MOV AL, DHAND AL, 0Fh ; the low nibbleCALL HEXN1POP DXPOP CXPOP AXRETHEXN1:ADD AL, "0"CMP AL, "9"JBE HEXN2ADD AL, 7 ; past "9": "A".."F"HEXN2:MOV DL, ALMOV AH, 02hINT 21hRETPHEX2 ENDP
Pitfalls
The original PC and XT have no RTC; their BIOS has no such function and returns with CF in whatever state, so on those machines check the BIOS date or fall back on DOS. An RTC with a flat battery reports CF = 1 or garbage. The RTC and the DOS time (INT 21h AH=2Ch) can disagree: DOS keeps its own time from the tick count and, before DOS 3.3, INT 21h AH=2Dh did not update the chip. Compare BCD values with BCD constants (CMP CH, 12h for noon), not with binary ones. AH=03h sets the RTC time from the same registers.