TITLE 'DIGITAL CLOCK; 26 JUNE 82' ; ;DISPLAY TIME OF DAY IN LARGE NUMERALS ; ;EACH NUMERAL WILL BE IN A 7 X 7 BOX ; SSEG RS 80H STACK_TOP: DB 0 ; DSEG ORG 100H ZERO DB ' 00000 ' BOX_WIDTH EQU OFFSET $ - OFFSET ZERO DB '0 0' DB '0 0' DB '0 0' DB '0 0' DB '0 0' DB ' 00000 ' BOX_HIGHTH EQU (OFFSET $ - OFFSET ZERO) / BOX_WIDTH ONE DB ' 11 ' DB ' 111 ' DB ' 1111 ' DB ' 11 ' DB ' 11 ' DB ' 11 ' DB '1111111' ; TWO DB ' 22222 ' DB '2 2' DB ' 2 ' DB ' 2 ' DB ' 2 ' DB ' 2 ' DB '2222222' ; THREE DB ' 33333 ' DB '3 3' DB ' 3' DB ' 3333' DB ' 3' DB '3 3' DB ' 33333 ' ; FOUR DB ' 44 ' DB ' 4 4 ' DB ' 4 4 ' DB ' 4 4 ' DB '4444444' DB ' 4 ' DB ' 4 ' ; FIVE DB '5555555' DB '5 ' DB '5 ' DB ' 55555 ' DB ' 5' DB ' 5' DB '5555555' ; SIX DB ' 66 ' DB '6 ' DB '6 ' DB '6666666' DB '6 6' DB '6 6' DB '6666666' ; SEVEN DB '7777777' DB ' 7 ' DB ' 7 ' DB ' 7 ' DB ' 7 ' DB ' 7 ' DB ' 7 ' ; EIGHT DB ' 88888 ' DB '8 8' DB '8 8' DB ' 88888 ' DB '8 8' DB '8 8' DB ' 88888 ' ; NINE DB ' 99999 ' DB '9 9' DB '9 9' DB ' 999999' DB ' 9' DB ' 9' DB ' 9999 ' ; NUMERAL_ADDRESS: DW OFFSET ZERO DW OFFSET ONE DW OFFSET TWO DW OFFSET THREE DW OFFSET FOUR DW OFFSET FIVE DW OFFSET SIX DW OFFSET SEVEN DW OFFSET EIGHT DW OFFSET NINE ; BOX_POSITION: DW 7*256+12 DW 16*256+12 DW 29*256+12 DW 38*256+12 DW 51*256+12 DW 60*256+12 ; CURRENT_TIME: DW 0 DB 0 CUR_MIN DB 0 CUR_SEC DB 0 PREVIOUS_TIME: DW 0ffh DB 0ffh PRE_MIN DB 0ffh PRE_SEC DB 0ffh ; CLS DB 'Z'-40H,'PRESS ANY KEY TO STOP$' REVERSE_ATTRIB: DB ESC,')$' NORM_ATTRIB: DB ESC,'($' ; GET_DATE_TIME EQU 155 DELAY EQU 141 CON_STAT EQU 11 EJECT CSEG ; MOV AX,.015H ! MOV SS,AX ! MOV SP,OFFSET STACK_TOP MOV DX,OFFSET CLS ! CALL P_MESSAGE MAIN_LOOP: CALL TIME_OF_DAY CALL UPDATE_SCREEN CALL MOVE_CURRENT_TO_PREVIOUS CALL CHECK_FOR_STOP JMP MAIN_LOOP ; DELAY_IT: MOV DX,58 ! MOV CL,DELAY ! CALL BDOS RET ; ; TIME_OF_DAY: MOV CL,GET_DATE_TIME ! MOV DX,OFFSET CURRENT_TIME JMP BDOS ; MOVE_CURRENT_TO_PREVIOUS: MOV SI,OFFSET CURRENT_TIME ! MOV DI,OFFSET PREVIOUS_TIME MOVSW ! MOVSW ! MOVSB RET ; UPDATE_SCREEN: MOV CX,3 ! MOV SI,OFFSET CUR_SEC MOV DI,OFFSET PRE_SEC ! MOV BX,5 UPDATE_LOOP: MOV AL,[SI] ! MOV AH,[DI] ! CMP AL,AH JZ NO_UPDATE ;DON'T CHANGE THE TIME PUSH CX ! PUSH SI ! PUSH DI ! PUSH BX PUSH AX ! AND AH,0FH ! AND AL,0FH ;GET THE LOW BCD DIGITS CMP AL,AH ! JE NEXT_BCD ;IF = DON'T CHANGE CALL UPDATE_NUMBER NEXT_BCD: POP AX ! POP BX DEC BX ! PUSH BX ;POINT TO NEXT BOX ADDRESS AND AH,0F0H ! AND AL,0F0H CMP AH,AL ! JE CLEAR_STACK MOV CL,4 ! SHR AL,CL CALL UPDATE_NUMBER CLEAR_STACK: POP BX ! DEC BX POP DI ! DEC DI POP SI ! DEC SI POP CX LOOP UPDATE_LOOP RET NO_UPDATE: CALL DELAY_IT RET ;AT THIS TIME THERE IS NO REASON TO RETURN TO MAIN LOOP ; SO LET'S SEE WHAT HAPPENS WHEN OUR TIME SLICE IS GIVEN UP ; ; UPDATE_NUMBER: ;AL=DECIMAL DIGIT ;BX=DIGIT POSITION (HOURS= POSITION 0 AND 1) XOR AH,AH ! MOV DI,OFFSET NUMERAL_ADDRESS SHL AX,1 ! ADD DI,AX ! MOV SI,[DI] SHL BX,1 ! MOV DI,OFFSET BOX_POSITION ADD DI,BX ! MOV AX,[DI] JMP SHOW_NUMERAL ; ; SHOW_NUMERAL: ;INPUT AX=ROW,COL ; SI= OFFSET OF NUMERAL ; ;PUT NUMERAL AT SPECIFIED CURSOR LOCATION ; MOV CX,BOX_HIGHTH SHOW_LOOP: PUSH CX ! PUSH AX ! PUSH SI CALL PLACE POP SI ! PUSH SI MOV CX,BOX_WIDTH ! CALL PUT_CHARS POP SI ! ADD SI,BOX_WIDTH POP AX ! INC AL ;GO TO NEXT ROW POP CX LOOP SHOW_LOOP RET ; PUT_CHARS: ;INPUT CX= # OF CHARS ; SI= OFFSET OF CHARS ; ;PUT # OF CHARS POINTED TO BY SI ON SCREEN ; LODSB ! CMP AL,' ' ! JE BLANK_LOOP_1 NUM_LOOP_1: PUSH CX ! PUSH SI ! PUSH AX CALL REVERSE_ATTRIBUTE POP DX JMP NUM_LOOP_2 NUM_LOOP: LODSB ! CMP AL,' ' ! JE BLANK_LOOP_1 PUSH CX ! PUSH SI MOV DL,AL NUM_LOOP_2: MOV CL,CON_OUT ! CALL BDOS POP SI ! POP CX LOOP NUM_LOOP RET BLANK_LOOP_1: PUSH CX ! PUSH SI ! PUSH AX CALL NORM_ATTRIBUTE POP DX JMP BLANK_LOOP_2 BLANK_LOOP: LODSB ! CMP AL,' ' ! JNE NUM_LOOP_1 PUSH CX ! PUSH SI MOV DL,AL BLANK_LOOP_2: MOV CL,CON_OUT ! CALL BDOS POP SI ! POP CX LOOP BLANK_LOOP RET ; REVERSE_ATTRIBUTE: MOV DX,OFFSET REVERSE_ATTRIB ! JMP P_MESSAGE NORM_ATTRIBUTE: MOV DX,OFFSET NORM_ATTRIB ! JMP P_MESSAGE ; CHECK_FOR_STOP: MOV CL,CON_STAT ! CALL BDOS CMP AL,0 ! JNE GOOD_BYE RET GOOD_BYE: MOV DX,OFFSET NORM_ATTRIB ! CALL P_MESSAGE XOR CX,CX ! JMP BDOS ; NOLIST INCLUDE ROUTINES.A86