home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / assemutl.zip / CLOCK.ASM < prev    next >
Assembly Source File  |  1985-05-11  |  11KB  |  338 lines

  1.     PAGE    66,132
  2. ;****************************************************************************
  3. ;
  4. ; PROGRAM: CLOCK
  5. ;
  6. ; DESCRIPTION: PRINT DATE AND TIME ON SCREEN
  7. ;
  8. ; INPUT: NONE
  9. ;
  10. ; OUTPUT: CURRENT DATE AND TIME ON SCREEN
  11. ;
  12. ; TYPE OF FILE: .COM FILE
  13. ;
  14. ; COMMENTS: THIS PROGRAM WILL PICK UP THE CURRENT DATE AND TIME AND
  15. ;     DISPLAY DAY, DATE AND TIME ON THE SCREEN.  DATE IS FORMATTED OUT
  16. ;     TO MONTH NAME, DAY AND YEAR, TIME IS HH:MM:SS.  THIS PROGRAM WILL
  17. ;     LOOP UNTIL CONTROL BREAK IS INTERCEPTED.
  18. ;
  19. ;  TO INCREASE READABILITY OF THE DISPLAY, IT WILL SAVE THE CURRENT
  20. ;     CURSOR TYPE, AND ERASE THE CURSOR.  WHEN CONTROL-BREAK IS DETECTED,
  21. ;     THE PROGRAM WILL INTERCEPT THE INTERRUPT AT ROUTINE TERMIN, RESTORE
  22. ;     THE CURSOR AND TERMINATE.
  23. ;
  24. ;  THIS PROGRAM ALSO CHECKS FOR DOS 2.0 OR ABOVE, AND IF IT IS NOT
  25. ;     PRESENT, TERMINATE IMMEDIATELY
  26. ;
  27. ;  THIS PROGRAM USES THE EQUATIONS FROM WES MEIER'S DFACT.BAS TO COMPUTE
  28. ;     THE DAY OF THE WEEK.  THEY ARE:
  29. ;
  30. ;    F = 365 * YEAR + DAY + (31 * (MONTH - 1))
  31. ;
  32. ;    IF MONTH < 3 THEN F = F + INT ((YEAR - 1) / 4) -
  33. ;       INT ((INT ((YEAR / 100) + 1)) * 3 / 4)
  34. ;
  35. ;    IF MONTH >= 3 THEN F = F + INT ((MONTH + 23) * 4 / 10) +
  36. ;       INT (YEAR / 4) - INT ((INT (YEAR / 100) + 1) * 3 / 4)
  37. ;
  38. ;    DAY NUMBER = F MOD 7 (REMAINDER OF F / 7) AND IS FIGURED AS
  39. ;
  40. ;    WHERE 0 = SATURDAY, 1 = SUNDAY, ETC.
  41. ;
  42. ;    NOTE: THE DAY NUMBER IS FIGURED AS (F MOD 7000) MOD 7 TO
  43. ;       PREVENT AN OVERFLOW CAUSED BY DIVIDING A LARGE NUMBER
  44. ;       BY A SMALL ONE.
  45. ;
  46. ;  THIS PROGRAM IS MADE TO RUN AS A .COM FILE, AND MUST BE RUN THROUGH
  47. ;     EXE2BIN.EXE IN ORDER TO OPERATE CORRECTLY
  48. ;
  49. ;****************************************************************************;
  50.     IF1                    ;DURING PASS 1
  51.     INCLUDE ASSEMBLE.MAC            ;INCLUDE MACRO LIBRARY
  52.     ENDIF
  53. ;
  54. COLUMNS EQU    80                ;NUMBER OF COLUMNS ON SCREEN
  55. ;
  56. BDATES    STRUC                    ;STRUCTURE FOR BINARY DATE
  57. MONTH    DB    0                ;BYTE MONTH
  58. DAY    DB    0                ;BYTE DAY
  59. YEAR    DW    0                ;WORD YEAR
  60. BDATES    ENDS
  61. ;
  62. DATETIME SEGMENT PARA PUBLIC 'CODE'
  63.     ASSUME    CS:DATETIME, DS:DATETIME, ES:DATETIME, SS:NOTHING
  64.     ORG    100H                ;SET ORIGIN TO XXXX:0100H
  65. ENTRY    LABEL    NEAR                ;ENTRY POINT
  66.     JMP    CODE_START            ;JUMP AROUND DATA AREAS
  67.     DB    'CLOCK.ASM'                     ;COPYRIGHT NOTICE
  68.     DB    'COPYRIGHT (C) 1983'
  69.     DB    'JERRY D. STUCKLE'
  70.     DB    'PUBLIC DOMAIN SOFTWARE'        ;PROGRAM FOR PUBLIC DOMAIN
  71. CSRSAVE DW    ?                ;CURSOR MODE SAVE AREA
  72. WRKAREA DB    11 DUP (?)            ;WORK AREA
  73. TIME    DB    8 DUP (0),'$'                   ;AREA FOR ASCII TIME
  74. BDATE    BDATES    <,,>                ;BINARY DATE AREA
  75. CURRDAY DB    10 DUP (?)            ;AREA FOR ASCII DAY
  76. DATEOUT DB    20 DUP (?)            ;AREA FOR ASCII DATE
  77. DOSERR    DB    'DOS 2.0 OR ABOVE REQUIRED.  PROGRAM TERMINATED.',0AH,0DH
  78. ;
  79. MO_TBL    LABEL    WORD                ;POINTER TO MONTH NAMES
  80.     DW    OFFSET JAN            ;JANUARY
  81.     DW    OFFSET FEB            ;FEBRUARY
  82.     DW    OFFSET MAR            ;MARCH
  83.     DW    OFFSET APR            ;APRIL
  84.     DW    OFFSET MAY            ;MAY
  85.     DW    OFFSET JUN            ;JUNE
  86.     DW    OFFSET JUL            ;JULY
  87.     DW    OFFSET AUG            ;AUGUST
  88.     DW    OFFSET SEP            ;SEPTEMBER
  89.     DW    OFFSET OCT            ;OCTOBER
  90.     DW    OFFSET NOV            ;NOVEMBER
  91.     DW    OFFSET DEC            ;DECEMBER
  92. ;                        ;ASCIIZ STRINGS FO MONTH NAMES
  93. JAN    DB    'JANUARY ',0
  94. FEB    DB    'FEBRUARY ',0
  95. MAR    DB    'MARCH ',0
  96. APR    DB    'APRIL ',0
  97. MAY    DB    'MAY ',0
  98. JUN    DB    'JUNE ',0
  99. JUL    DB    'JULY ',0
  100. AUG    DB    'AUGUST ',0
  101. SEP    DB    'SEPTEMBER ',0
  102. OCT    DB    'OCTOBER ',0
  103. NOV    DB    'NOVEMBER ',0
  104. DEC    DB    'DECEMBER ',0
  105. ;
  106. ;
  107. DAY_NAM LABEL    WORD                ;POINTER TO DAY NAMES
  108.     DW    OFFSET SAT            ;SATURDAY
  109.     DW    OFFSET SUN            ;SUNDAY
  110.     DW    OFFSET MON            ;MONDAY
  111.     DW    OFFSET TUE            ;TUESDAY
  112.     DW    OFFSET WED            ;WEDNESDAY
  113.     DW    OFFSET THU            ;THURSDAY
  114.     DW    OFFSET FRI            ;FRIDAY
  115. ;                        ;ASCIIZ STRINGS OF DAY NAMES
  116. SAT    DB    'SATURDAY',0
  117. SUN    DB    'SUNDAY',0
  118. MON    DB    'MONDAY',0
  119. TUE    DB    'TUESDAY',0
  120. WED    DB    'WEDNESDAY',0
  121. THU    DB    'THURSDAY',0
  122. FRI    DB    'FRIDAY',0
  123. ;
  124. CODE_START LABEL NEAR
  125. ;
  126. ;    FIRST, WE CLEAR THE SCREEN.  THEN, IF NOT AT AT LEAST DOS 2.0,
  127. ;    WE TERMINATE THE PROGRAM.
  128. ;
  129.     CLS
  130.     DOSCALL 30H                ;GET DOS VERSION NUMBER
  131.     CMP    AL,2                ;AT LEAST DOS 2.0?
  132.     JGE    CONT                ;YES - CONTINUE
  133.     DISPLAY DOSERR                ;NO - DISPLAY DOS ERROR MESSAGE
  134.     INT    20H                ;AND TERMINATE
  135. ;
  136. ;    SAVE THE CURSOR MODE, THEN ERASE IT
  137. ;    ALSO, SET THE CONTROL-BREAK INTERRUPT VECTOR
  138. ;
  139. CONT:                        ;DOS VERSION GOOD
  140.     CURSOR    SAVE,CSRSAVE            ;SAVE CURSOR MODE
  141.     CURSOR    ERASE                ;ERASE CURSOR
  142.     SETINT    23H,TERMIN            ;SET CNTL-BREAK VECTOR
  143.     CALL    PROCESS_DATE            ;GET THE DATE
  144. ;
  145. ;    DATE PROCESSING IS COMPLETE.  PROCESS THE TIME
  146. ;    NOTE: WHEN DX IS LOADED, THE 2 CHARACTERS ARE SWAPPED, SO THE
  147. ;    COMPARE '32' IS FOR THE 23'RD HOUR.
  148. ;
  149. PROCESS_TIME:
  150.     GETTIME WRKAREA,CHAR            ;GET CURRENT TIME IN ASCII
  151.     MOV    DX,WORD PTR TIME        ;GET OLD HOUR IN DH
  152.     MOVE    TIME,WRKAREA,8            ;MOVE IT INTO THE TIME FIELD
  153.     CMP    DX,WORD PTR TIME        ;SAME AS NEW AREA?
  154.     JE    SHOW_TIME            ;YES - NO NEED TO DISPLAY DATE
  155.     CMP    DX,'32'                         ;WAS IT 23:XX:XX?
  156.     JNE    SHOW_TIME            ;NO - DON'T DISPLAY THE DATE
  157.     CALL    PROCESS_DATE            ;DAY HAS CHANGED - DISPLAY IT
  158. SHOW_TIME:
  159.     LOCATE    15,(COLUMNS-8)/2        ;LOCATE THE CURSOR
  160.     DISPLAY TIME                ;AND DISPLAY IT
  161.     JMP    PROCESS_TIME            ;AND GO PROCESS THE TIME AGAIN
  162. ;
  163. ;    GET THE CURRENT DATE AND PROCESS IT
  164. ;
  165. PROCESS_DATE PROC NEAR                ;PROCESS DATE
  166.     GETDATE BDATE,BIN            ;GET CURRENT DATE IN BINARY
  167. ;
  168. ;       F = 365 * YEAR + DAY + (31 * (MONTH - 1))
  169. ;
  170.     MOV    AX,BDATE.YEAR            ;GET CURRENT YEAR
  171.     SAVE    AX                ;SAVE ON STACK
  172.     MOV    BX,365                ;NUMBER OF DAYS IN A YEAR
  173.     MUL    BX                ;MULTIPLY
  174.     CLEAR    BH                ;CLEAR BH
  175.     MOV    BL,BDATE.DAY            ;GET THE DAY
  176.     ADD    AX,BX                ;ADD TO AX
  177.     ADC    DX,0                ;ADD ANY CARRY TO DX
  178.     MOV    WORD PTR WRKAREA,AX        ;SAVE IN WORK AREA
  179.     MOV    WORD PTR WRKAREA+2,DX        ;SAVE HIGH ORDER, TOO.
  180.     CLEAR    AH                ;CLEAR AH
  181.     MOV    AL,BDATE.MONTH            ;GET THE MONTH
  182.     DEC    AL                ;DECREMENT
  183.     MOV    BL,31                ;MAX DAYS IN MONTH
  184.     MUL    BL                ;MULTIPLY
  185.     ADD    WORD PTR WRKAREA,AX        ;ADD TO WRKAREA
  186.     ADC    WORD PTR WRKAREA+2,0        ;ADD ANY CARRY
  187. ;NOW WE MUST USE ONE OF TWO DIFFERENT ROUTINES
  188.     CMP    BDATE.MONTH,3            ;JANUARY OR FEBRUARY?
  189.     JGE    PROCESS_DATE_2            ;NO - GO TO SECOND ROUTINE
  190. ;
  191. ;    IF MONTH < 3 THEN F = F + INT ((YEAR - 1) / 4) -
  192. ;       INT ((INT ((YEAR / 100) + 1)) * 3 / 4)
  193. ;
  194.     RESTORE AX                ;GET YEAR BACK
  195.     DEC    AX                ;DECREMENT UEAR
  196.     SAVE    AX                ;AND SAVE IT AGAIN
  197.     SHR    AX,1                ;DIVIDE BY 2...
  198.     SHR    AX,1                ;AND AGAIN.
  199.     ADD    WORD PTR WRKAREA,AX        ;ADD TO WORK AREA
  200.     ADC    WORD PTR WRKAREA+2,0        ;ADD ANY CARRY
  201.     RESTORE AX                ;GET (YEAR-1) BACK
  202.     MOV    BL,100                ;100 TO DL
  203.     DIV    BL                ;AND DIVIDE
  204.     INC    AL                ;INCREMENT IT
  205.     MOV    BL,3                ;MULTIPLY BY 3...
  206.     MUL    BL                ;DO IT
  207.     SHR    AX,1                ;DIVIDE BY 2...
  208.     SHR    AX,1                ;AND THEN AGAIN.
  209.     CLEAR    AH                ;THROW AWAY REMAINDER
  210.     SUB    WORD PTR WRKAREA,AX        ;SUBTRACT NUMBER OF LEAP DAYS
  211.     SBB    WORD PTR WRKAREA,0        ;AND ANY BORROW REQUIRED.
  212.     JMP    PROCESS_DATE_3            ;GO BACK TO COMMON ROUTINE
  213. PROCESS_DATE_2:
  214. ;
  215. ;    IF MONTH >= 3 THEN F = F + INT ((MONTH + 23) * 4 / 10) +
  216. ;       INT (YEAR / 4) - INT ((INT (YEAR / 100) + 1) * 3 / 4)
  217. ;
  218.     MOV    AL,BDATE.MONTH            ;GET THE MONTH IN AL
  219.     CLEAR    AH                ;CLEAR HIGH ORDER BYTE
  220.     SHL    AX,1                ;MULTIPLY BY 2...
  221.     SHL    AX,1                ;AND AGAIN BY 2
  222.     ADD    AX,23                ;ADD 23
  223.     MOV    BL,10                ;MOVE 10 TO BL
  224.     DIV    BL                ;AND DIVIDE
  225.     CLEAR    AH                ;THROW OUT REMAINDER
  226.     SUB    WORD PTR WRKAREA,AX        ;SUBTRACT FROM WORK AREA
  227.     SBB    WORD PTR WRKAREA+2,0        ;AND SUBTRACT ANY BORROW.
  228.     RESTORE AX                ;GET YEAR BACK
  229.     SAVE    AX                ;SAVE IT AGAIN
  230.     SHR    AX,1                ;DIVIDE BY 2
  231.     SHR    AX,1                ;AND DO IT AGAIN
  232.     ADD    WORD PTR WRKAREA,AX        ;ADD TO WORK AREA
  233.     ADC    WORD PTR WRKAREA+2,0        ;ADD ANY CARRY
  234.     RESTORE AX                ;GET (YEAR-1) BACK
  235.     MOV    BL,100                ;100 TO DL
  236.     DIV    BL                ;AND DIVIDE
  237.     INC    AL                ;INCREMENT IT
  238.     MOV    BL,3                ;MULTIPLY BY 3...
  239.     MUL    BL                ;DO IT
  240.     SHR    AX,1                ;DIVIDE BY 2...
  241.     SHR    AX,1                ;AND THEN AGAIN.
  242.     CLEAR    AH                ;THROW AWAY REMAINDER
  243.     SUB    WORD PTR WRKAREA,AX        ;SUBTRACT NUMBER OF LEAP DAYS
  244.     SBB    WORD PTR WRKAREA,0        ;AND ANY BORROW REQUIRED.
  245. PROCESS_DATE_3:
  246. ;
  247. ;    DAY NUMBER = (F MOD 7000) MOD 7
  248. ;
  249.     MOV    AX,WORD PTR WRKAREA        ;GET TOTAL IN AX...
  250.     MOV    DX,WORD PTR WRKAREA+2        ;AND HIGH ORDER IN DX
  251.     MOV    BX,7000             ;DIVIDE BY 7000 SO WE...
  252.     DIV    BX                ;...DON'T GET AN OVERFLOW
  253.     MOV    AX,DX                ;REMAINDER TO AX
  254.     CLEAR    DX                ;CLEAR HIGH ORDER WORD
  255.     MOV    BX,7                ;NOW DIVIDE BY 7 IN 32...
  256.     DIV    BX                ;BIT MODE SO WE DON'T OVERFLOW.
  257.     MOV    BX,DX                ;GET DAY NUMBER IN BL
  258.     SHL    BX,1                ;SHIFT FOR TABLE LOOKUP
  259.     MOV    SI,WORD PTR DAY_NAM [BX]    ;GET DAY NAME
  260.     LEA    DI,CURRDAY            ;GET ADDRESS OF DAY AREA
  261.     CLD                    ;SET INCREMENT
  262. ;
  263. ;    WE HAVE THE CURRENT DAY.  MOVE IT INTO THE WORK AREA AND DISPLAY
  264. ;    IT, CENTERED. FORMULA FOR CENTERING IS (COLUMNS+1-LENGTH)/2
  265. ;    AND IS FIGURED BY ((START ADDRESS+COLUMNS+1)-END ADDRESS)/2
  266. ;
  267. DAY_LOOP:
  268.     MOVSB                    ;MOVE A BYTE
  269.     CMP    BYTE PTR [SI],0         ;END OF STRING?
  270.     JNE    DAY_LOOP            ;NO - WE'RE NOT DONE
  271.     MOV    BYTE PTR [DI],'$'               ;MOVE IN A '$'
  272.     LEA    BX,CURRDAY+(COLUMNS+1)        ;START ADDRESS + LINE LENGTH
  273.     SUB    BX,DI                ;SUBTRACE END ADDRESS
  274.     SHR    BL,1                ;AND DIVIDE BY 2
  275.     CLS                    ;CLEAR THE SCEEN
  276.     LOCATE    11,BL                ;LOCAT THE CURSOR
  277.     DISPLAY CURRDAY             ;AND DISPLAY THE DAY
  278. ;
  279. ;    NOW WE MUST MOVE THE CURRENT MONTH INTO THE STRING
  280. ;
  281.     MOV    BL,BDATE.MONTH            ;GET CURRENT MONTH
  282.     DEC    BL                ;DECREMENT FOR TABLE LOOKUP
  283.     SHL    BX,1                ;MULTIPLY BY 2
  284.     MOV    SI,MO_TBL[BX]            ;GET ADDRESS OF MONTH NAME
  285.     LEA    DI,DATEOUT            ;GET TO STRING ADDRESS
  286.     CLD                    ;INCREMENT ADDRESSES
  287. MONTH_LOOP:                    ;MOVE THE MONTH NAME
  288.     MOVSB                    ;NO - MOVE THE BYTE
  289.     CMP    BYTE PTR [SI],0         ;IS THE NEXT BYTE 0?
  290.     JNE    MONTH_LOOP            ;AND GO CHECK THE NEXT BYTE
  291. ;
  292. ;    CURRENT MONTH NAME IS READY.  LET'S GET THE DAY NEXT, CONVERT IT
  293. ;    TO ASCII, AND PUT IT IN THE STRING
  294. ;
  295. MOVE_DAY:
  296.     MOV    AL,BDATE.DAY            ;GET THE DAY IN AL
  297.     AAM                    ;CONVERT TO UNPACKED DECIMAL
  298.     OR    AX,3030H            ;CONVERT TO ASCII
  299.     CMP    AH,'0'                          ;IS THE FIRST CHARACTER 0?
  300.     JE    MOVE_LOW_DATE            ;YES - DO NOT MOVE IT
  301.     MOV    BYTE PTR [DI],AH        ;NO - MOVE IT
  302.     INC    DI                ;AND INCREMENT DESTINATION
  303. MOVE_LOW_DATE:
  304.     MOV    BYTE PTR [DI],AL        ;MOVE IN LOW DATE
  305.     INC    DI                ;POINT TO NEXT BYTE
  306.     MOV    BYTE PTR [DI],','               ;MOVE IN A COMMA
  307.     INC    DI                ;POINT TO NEXT BYTE
  308.     MOV    BYTE PTR [DI],' '               ;A SPACE GOES HERE
  309.     INC    DI                ;AND POINT AT NEXT BYTE
  310. ;
  311. ;    DAY PROCESSING IS COMPLETE, NOW DO THE SAME TO THE YEAR
  312. ;
  313.     MOV    AX,BDATE.YEAR            ;GET CURRENT YEAR
  314.     SAVE    DI                ;SAVE DESTINATION ADDRESS
  315.     CVD    WRKAREA,BDATE.YEAR        ;CONVERT THE YEAR TO ASCII
  316.     RESTORE DI                ;RESTORE DESTINATION ADDRESS
  317.     MOVE    [DI],WRKAREA,4            ;MOVE YEAR TO DESTINATION
  318.     MOV    BYTE PTR [DI],'$'               ;SET A '$' AT THE END
  319. ;
  320. ;    STRING IS BUILT.  CENTER IT USING THE SAME EQUATION AS THE DAY.
  321. ;
  322.     LEA    BX,DATEOUT+COLUMNS        ;START ADDRESS + LINE LENGTH
  323.     SUB    BX,DI                ;SUBTRACE END ADDRESS
  324.     SHR    BX,1                ;AND DIVIDE BY 2
  325.     LOCATE    13,BL                   ;LOCATE THE CURSOR
  326.     DISPLAY DATEOUT             ;AND DISPLAY THE DATE
  327.     RET                    ;RETURN TO CALLER
  328. PROCESS_DATE ENDP
  329. TERMIN    PROC    NEAR                ;TERMINATION PROCEDURE
  330.     CURSOR    SET,CSRSAVE            ;RESTORE CURSOR
  331.     CLS                    ;CLEAR THE SCREEN
  332.     CLEAR    AX                ;RETURN CODE 0
  333.     DOSCALL 4CH                ;AND TERMINATE
  334. TERMIN    ENDP
  335. DATETIME ENDS
  336.     END    ENTRY
  337.  
  338.