Você está na página 1de 3

CGROUP

VECTOR

GROUP VECTOR,CODESEG
SEGMENT AT 0H
DB
6CH DUP(?)
TIME_LO DW
?
TIME_HI DW
?
VEC_IP DW
VEC_CS DW
VECTOR ENDS

;FILLER
;DOS TIME
;DOS TIME
;CLOCK UPDATE VECTOR IP
;CLOCK UPDATE VECTOR CS

CODESEG SEGMENT PARA


ASSUME CS:CODESEG,DS:CGROUP
ORG 100H
CLK
PROC FAR
JMP SETUP
;ATTACH TO DOS
INTRPT LABEL DWORD
INT_IP DW
0
;OLD UPDATE VECTOR IP
INT_CS DW
0
;OLD UPDATE VECROR CS
TICKS
DW
0
;TICK COUNTER
SCR_OFF DB
0,0
;SCREEN OFFSET IN BUFFER
CRT_PORT DW
0
;SCREEN STATUS PORT
flag
db
0
TIME
DB
8 DUP(':',0BH)
;TIME SAVE AREA
CLK_INT LABEL NEAR
PUSH AX
;SAVE REGISTERS
PUSH CX
PUSH DI
PUSH SI
PUSH DS
PUSH ES
PUSHF
; AND FLAGS
CALL CS:[INTRPT]
;DO OLD UPDATE INTERRUPT
MOV CX,0040H
;GET SEGMENT OF DOS TABLE
MOV DS,CX
;PUT IN DS
MOV CX,CS:TICKS
;GET TICK COUNT
INC CX
;INCREMENT IT
CMP CX,20
;01F4H
;HAS A MINUTE GONE BY?
JB
NO_MINUTE
;NO, MOVE ON
CALL UPDATE
;YES, UPDATE CLOCK AND
MOV CX,0
; RESET TICK COUNTER
NO_MINUTE:
MOV CS:TICKS,CX
;SAVE UPDATED TICK COUNT
MOV CX,0B000H
;GET VIDEO SEGMENT
MOV ES,CX
;PUT IN ES
MOV DX,CS:CRT_PORT
;GET CRT STATUS PORT ADDR
MOV DI,WORD PTR CS:SCR_OFF ;GET SCREEN BUFFER OFFSET
LEA SI,CS:TIME
;GET DOS TIME
MOV CX,16
;SET UP TO MOVE 10 BYTES
CLI
;DISABLE OTHER INTERRUPTS
WAIT1: IN
AL,DX
;READ CRT STATUS
TEST AL,1
;CHECK FOR VERTICAL RETRACE
JNZ WAIT1
;WAIT FOR RETRACE LOW
MOV AH,CS:[SI]
;GET FIRST BYTE TO MOVE
WAIT2: IN
AL,DX
;GET CRT STATUS
TEST AL,1
;CHECK FOR VERTICAL RETRACE
JZ
WAIT2
;WAIT FOR RETRACE HIGH
MOV ES:[DI],AH
;MOVE BYTE TO SCREEN
INC DI
;INCREMENT INDEX
INC SI
LOOP WAIT1
;MOVE NEXT BYTE
STI
;ENABLE INTERRUPTS

CLK
UPDATE

HOUR:

H1:

POP
POP
POP
POP
POP
POP
IRET
ENDP
PROC
PUSH
PUSH
PUSH
PUSH
PUSH
MOV
MOV
MOV
mov
CMP
JLE
mov
SUB
JMP
AAM
ADD
LEA
MOV
MOV
MOV
MOV
SHR
MOV
MUL
SHR
AAM
ADD
MOV
MOV
mov
cmp
jz
mov

ES
DS
SI
DI
CX
AX

;RESTORE REGISTERS

mov
POP
POP
POP
POP
POP
RET
ENDP
MOV
MOV
CLI
MOV
MOV
MOV
MOV
MOV
MOV

byte ptr cs:[bx+14],'m'


DS
;RESTORE REGISTERS
DX
CX
BX
AX

;RETURN FROM INTERRUPT


NEAR
AX
BX
CX
DX
DS
AX,0040H
DS,AX
AX,TIME_HI
flag,0
AX,0CH
H1
flag,1
AX,0CH
HOUR

;SAVE REGISTERS

;GET ADDRESS OF DOS TABLE


;PUT IN DS
;GET HIGH BYTE OF DOS TIME
;am flag
;CONVERT TO HOURS
;set to pm
;CONVERT TO ASCII

AX,3030H
BX,CS:TIME
CS:[BX],AH
CS:[BX+2],AL
AX,TIME_LO
CX,8H
AX,CL
DX,3CH
DL
AX,CL

;GET ADDRESS OF TIME AREA


;SAVE HOURS FIRST DIGIT
;SAVE HOURS SECOND DIGIT
;GET DOS TIME LOW BYTE
;CONVERT TO MINUTES

;CONVERT TO ASCII
AX,3030H
CS:[BX+6],AH
;SAVE MINUTES FIRST DIGIT
CS:[BX+8],AL
;SAVE MINUTES SECOND DIGIT
byte ptr cs:[bx+12],'a'
flag,0
;is it am?
goahead
byte ptr cs:[bx+12],'p'

goahead:

UPDATE
SETUP:

AX,0
DS,AX

;GET ADDRESS OF VECTOR TABLE


;PUT IN DS
;DISABLE FURTHER INTERRUPTS
AX,[VEC_IP]
;GET ADDRESS OF OLD UPDATE IP
CS:[INT_IP],AX
;SAVE IT
AX,[VEC_CS]
;GET ADDRESS OF OLD UPDATE CS
CS:[INT_CS],AX
;SAVE IT
VEC_IP,OFFSET CLK_INT ;PUT ADDRESS OF CLK IN VECTOR IP
VEC_CS,CS
;PUT CS OF CLK IN VECTOR CS

STI
MOV
INT
SUB
SHL
MOV
MOV
TEST
JNZ
ADD
MOV
MONO:
CALL
MOV
INT
DB
CODESEG ENDS
END

;ENABLE INTERRUPTS
AH,0FH
;READ VIDEO STATUS
10H
AH,8
;SUBTRACT 8 CHAR TIME FROM NCOLS
AH,1
;MULTIPLY BY 2 FOR ATTRIBUTE
CS:SCR_OFF,AH
;SAVE SCREEN TIME LOCATION
WORD PTR CS:CRT_PORT,03BAH ;SAVE MONO STATUS PORT ADDR
AL,4
;CHECK FOR COLOR MONITOR
MONO
;IF MONO, MOVE ON
WORD PTR CS:SCR_OFF,8000H ;ADD COLOR OFFSET TO TIME OFFSET
WORD PTR CS:CRT_PORT,03DAH ;SAVE COLOR STATUS PORT ADDR
UPDATE
;DO FIRST UPDATE & PRINT TIME
DX,OFFSET SETUP
;GET END ADDRESS OF NEW INTERRUPT
27H
;TERMINATE AND REMAIN RESIDENT
117 DUP(0)
;FILLER
CLK

Você também pode gostar