; (C)opyright Erdogan Tan - 30 April 2000  (3)
;
; INT1C.ASM
;
; Handles INT 1Ch for showing current date and time.
; This is INT 1Ch handling type version of CDT.ASM or DATETIME.ASM.
;
; Program uses INT 15h Function 85h, SysReq key handler
; for checking stop/exit request. (Alt+SysRq keystrokes.)
;
; After performing SysReq procedure, program restores
; original INT 1Ch and INT 15h vectors.
;
; TSR (Terminate and Stay Resident) Type MS-DOS (TR-DOS) Program
; (If INT 20h would be used instead of INT 27h, program would be
; standalone...)
; ROM-BIOS functions are derived from American Megatrend Inc.'s
; AMIBIOS Programming Guide (1993).
		PAGE    60,132
;哪哪哪哪哪 CODE_SEG_1  哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
CODE_SEG_1	segment para public
		assume  CS:CODE_SEG_1, DS:CODE_SEG_1, SS:CODE_SEG_1, ES:CODE_SEG_1
		org	100h
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
;
;		ENTRY POINT
;
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
;
;		PROCEDURE proc_start
;
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
proc_start      proc    near
start:		; N-Ref=0
                jmp     load
Magic_Word:     dw      0
var_INT15h_off: dw      0
var_INT15h_seg: dw      0
var_INT1Ch_off: dw      0
var_INT1Ch_seg: dw      0
proc_start	endp
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
;
;              PROCEDURE proc_handler
;
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
proc_handler    proc    near
INT1Ch_handler:
                pushf
                call    dword ptr CS:var_INT1Ch_off
                push ax
                push bx
                push cx
                push dx
                push si
                push di
                push ds
                push es
                push cs
                pop  ds
                mov ah, 03h
                mov bx, 07h
                int 10h                 ; Return Cursor Position
                mov word ptr [CursorPos], dx
                mov ah, 04h
                int 1Ah
                mov al, ch
                call proc_hex
                mov word ptr [Century], ax
                mov al, cl
                call proc_hex
                mov word ptr [Year], ax
                mov al, dh
                call proc_hex
                mov word ptr [Month], ax
                mov al, dl
                call proc_hex
                mov word ptr [Day], ax
                mov ah, 02h
                int 1Ah
                mov al, ch
                call proc_hex
                mov word ptr [Hour], ax
                mov al, cl
                call proc_hex
                mov word ptr [Minute], ax
                mov al, dh
                call proc_hex
                mov word ptr [Second], ax
                mov dx, 30h
                mov ah, 02h
                mov bx, 07h
                int 10h                 ; Set Cursor Position
                mov si, offset Msg_Date
                call proc_printmsg
return_from_INT1Ch:
                mov dx, word ptr [CursorPos]
                mov ah, 02h
                mov bx, 07h
                int 10h                 ; Set Cursor Position
                pop es
                pop ds
                pop di
                pop si
                pop dx
                pop cx
                pop bx
                pop ax
                IRET
SYSREQ_handler:
                push ax
                pushf
                call  dword ptr CS:var_INT15h_off
                pop ax
                push ax
                push si
                push di
                push ds
                push es
                push cs
                pop  ds
                cmp ah, 85h
                jnz short return_from_INT15h
                xor ax, ax
                mov es, ax
                mov di, 70h
                mov si, offset var_INT1Ch_off
                movsw
                movsw
                mov di, 54h
                mov si, offset var_INT15h_off
                movsw
                movsw
Return_from_INT15h:
                pop es
                pop ds
                pop di
                pop si
                pop ax
                IRET
proc_handler    endp
proc_printmsg   proc near
loc_print:
		lodsb                           ; Load byte at DS:SI to AL
		and     AL,AL            
                je      short end_of_print      ; If AL = 00h then return
		mov     AH,0Eh                  
		mov     BX,07h             
		int     10h                     ; BIOS Service func ( ah ) = 0Eh
						; Write char as TTY
						;AL-char BH-page BL-color
		jmp     short loc_print           
end_of_print:
		retn
proc_printmsg   endp
;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; From binary (byte) to hexadecimal (character) converter    ;
;                                                            ;
; input -> AL = byte (binary number) to be converted         ;
; output -> AH = First character of hexadecimal number       ;
; output -> AL = Second character of hexadecimal number      ;
;                                                            ;
; (c) Erdogan TAN  1998 - 1999                               ;
;............................................................;
; 1998
proc_hex        proc    near
		db 0D4h,10h                     ; Undocumented inst. AAM
						; AH = AL / 10h
						; AL = AL MOD 10h
		or AX,'00'                      ; Make it ZERO (ASCII) based
		xchg AH,AL
; 1999
		cmp AL,'9'
		jna pass_cc_al
		add AL,7
pass_cc_al:
		cmp AH,'9'
		jna pass_cc_ah
		add AH,7
pass_cc_ah:
; 1998
		retn
proc_hex        endp
Msg_Copyrights:
                db   0Dh, 0Ah
                db   0Dh, 0Ah
                db   "INT 1Ah FUNCTION 04h DATE AND 02h TIME OUTPUTS"
                db   0Dh, 0Ah
                db   "via INT 1Ch Periodic Timer Interrupt"
                db   0Dh, 0Ah
                db   "and INT 15h FUNCTION 85h SysReq Key Handler"
                db   0Dh, 0Ah
                db   0Dh, 0Ah
                db   "(c) Erdogan Tan  [ 2000 ]"
                db   0Dh, 0Ah
                db   0Dh, 0Ah
                db   "Press Alt+SysRq keys when you want to exit."
                db   0Dh, 0Ah
                db   0Dh, 0Ah, 0
Msg_Date:       db   "Date: "
Day:            db   '0'
		db   '0'
                db   '/'
Month:          db   '0'
		db   '0'
                db   '/'
Century:        db   '0'
                db   '0'
Year:           db   '0'
		db   '0'
                db    20h
                db    20h
                db   'Time: '
Hour:           db   '0'
		db   '0'
                db   ':'
Minute:         db   '0'
		db   '0'
                db   ':'
Second:         db   '0'
		db   '0'
                db   0Dh, 0Ah
                db   0Dh, 0Ah
                db   0
CursorTyp:      dw   0
CursorPos:      dw   0
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
;
;              PROCEDURE proc_load
;
;北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
proc_load       proc    near
load:          
                xor     BX,BX
                mov     ES,BX
                mov     SI,70h
                mov     AX, offset INT1Ch_handler
                mov     DX, Word ptr ES:[SI]
                cmp     AX,DX
                jnz     short pass_INT1Ch_magicword_ctrl
                mov     BX, AX
                sub     BX, 10
                cmp     word ptr [BX], 417
                jz      short loc_return
pass_INT1Ch_magicword_ctrl:
                mov     word ptr ES:[SI],AX
                mov     Word Ptr [var_INT1Ch_off],DX 
                mov     DX, Word ptr ES:[SI]+2
                mov     Word Ptr [var_INT1Ch_seg],DX
                mov     DX,DS
                mov     word ptr ES:[SI]+2,DX
                mov     word ptr [Magic_Word], 417
                mov     SI, 54h
                mov     AX, word ptr ES:[SI]
                mov     word ptr [var_INT15h_off],AX
                mov     AX, word ptr ES:[SI]+2
                mov     word ptr [var_INT15h_seg],AX
                mov     AX, offset SYSREQ_handler
                mov     word ptr ES:[SI],AX
                mov     word ptr ES:[SI]+2,DX
                mov si, offset Msg_Copyrights
                call proc_printmsg
loc_return:
                mov     DX,offset load  
		int	27h			; Terminate and stay resident
						;DX-offset of non-resident part
proc_load       endp
CODE_SEG_1	ends
		end	start