home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / GLEN / CLOCKS11.ZIP / SCRNCLK.ASM < prev    next >
Assembly Source File  |  1985-11-01  |  10KB  |  238 lines

  1.         TITLE   SCREEN CLOCK FOR MS-DOS
  2.     PAGE    60,132
  3. ;    SCRNCLK -- SCREEN CLOCK FOR MS-DOS (Z-150 OR IBM PC)
  4. ;    
  5. ;       THIS PROGRAM PROVIDES A SCREEN CLOCK FOR MS-DOS THAT FUNCTIONS
  6. ;       LIKE THE HDOS AND CP/M SCREEN CLOCK PRESENTED IN REMARK #22,
  7. ;       NOV., 1981.
  8. ;
  9. ;       THE CLOCK IS TIMED INTERNALLY DUE TO THE INABILITY TO ACCESS THE 
  10. ;       SYSTEM TIME FROM THE BIOS.  IT CAN BE SET TO THE SYSTEM TIME WITH
  11. ;       THE COMPANION PROGRAM "CLOCK".  THE COLOR OF THE DISPLAYED CLOCK
  12. ;       IS DETERMINED BY THE LABEL "COLOR", BELOW.  IF YOU ARE IN A B/W
  13. ;       MODE, THE COLOR IS AUTOMATICALLY SET TO WHITE.
  14. ;
  15. ;       BY PAT SWAYNE, Heath Users Group  22-MAY-84
  16.  
  17. ;       DEFINITIONS
  18.  
  19. BLUE    EQU    001B                    ;color control bits
  20. GREEN    EQU    010B
  21. CYAN    EQU    011B
  22. RED    EQU    100B
  23. MAGENTA    EQU    101B
  24. YELLOW    EQU    110B                    ;(IBM calls it brown)
  25. WHITE    EQU    111B
  26.  
  27. COLOR    EQU    WHITE                   ;clock color
  28. ROW    EQU    0                       ;put clock on top row
  29. CALFAC    EQU    89                      ;calibration factor
  30. SCRINT    EQU    10H                     ;screen control interrupt
  31. SCP    EQU    2                       ;set cursor position
  32. GCP    EQU    3                       ;get curosr position
  33. WCHAR    EQU    9                       ;write character
  34. GVS    EQU    15                      ;get video state
  35. TIMEINT    EQU    1CH*4                   ;IBM-PC timer interrupt vector
  36.  
  37. CLK     SEGMENT
  38.         ASSUME  CS:CLK,DS:CLK,ES:CLK,SS:CLK
  39.         ORG     100H
  40.  
  41. START:  JMP     SETUP                   ;set up clock interrupt, etc.
  42.  
  43. ;       clock data area
  44.  
  45. CLKFLG  DB      1                       ;clock on/off flag
  46. SEC     DB      0                       ;second (binary)
  47. MIN     DB      0                       ;minute
  48. HOU     DB      0                       ;hour
  49. TICCNT  DB      18                      ;tick counter
  50. SECCNT  DB      0                       ;second counter (for calibration)
  51. OLDIP   DW      0                       ;old instruction pointer
  52. SYSSTK  DW      0                       ;system stack
  53. SYSSTKS DW      0                       ;system stack segment
  54. CPOS    DW      0                       ;cursor position
  55. CMODE   DB      0                       ;current video state
  56. MODES   DB      0,1,2,3,1,0,2,2         ;decoded modes
  57. TIMSTR  DB      ' '                     ;space before time
  58. HOUR    DW      0                       ;hour (ascii)
  59.         DB      ':'
  60. MINUTE  DW      0                       ;minute
  61.         DB      ':'
  62. SECOND  DW      0                       ;second
  63.         DB      0FFH
  64.         DB      256 DUP(?)              ;stack space
  65. MYSTAK  EQU     $
  66.  
  67. ;       process clock interrupts here
  68.  
  69.         DB      'CK'                    ;identifier
  70. MYTIME: POP     CS:OLDIP                ;save instruction pointer
  71.         PUSH    AX
  72.         DEC     CS:TICCNT               ;decrement tick counter
  73.         JNZ     TIMEXIT                 ;not timed out
  74.         MOV     CS:TICCNT,18            ;else, reset tick counter
  75.         MOV     AL,CS:SECCNT            ;get second counter
  76.         INC     AL                      ;add one
  77.         CMP     AL,CALFAC               ;reached calibration factor?
  78.         MOV     CS:SECCNT,AL            ;update counter
  79.         JNZ     NOTCAL                  ;cal factor not reached
  80.         MOV     CS:SECCNT,0             ;else, zero counter
  81.         JMP     SHORT TIMEXIT           ;and exit
  82. NOTCAL: MOV     AL,CS:SEC               ;get seconds
  83.         INC     AL                      ;add one
  84.         CMP     AL,60                   ;60 seconds?
  85.         MOV     CS:SEC,AL               ;reset seconds
  86.         JNZ     CHKFLG                  ;not a minute, check flag
  87.         MOV     CS:SEC,0                ;else, zero seconds
  88.         MOV     AL,CS:MIN               ;get minutes
  89.         INC     AL                      ;add one
  90.         CMP     AL,60                   ;60 minutes?
  91.         MOV     CS:MIN,AL               ;reset minutes
  92.         JNZ     CHKFLG                  ;not an hour
  93.         MOV     CS:MIN,0                ;else, zero minutes
  94.         MOV     AL,CS:HOU               ;get hour
  95.         INC     AL                      ;add one
  96.         CMP     AL,24                   ;24 hours?
  97.         MOV     CS:HOU,AL               ;reset hours
  98.         JNZ     CHKFLG                  ;not a day
  99.         MOV     CS:HOU,0                ;else, zero hour
  100. CHKFLG: CMP     CS:CLKFLG,0             ;clock enabled?
  101.         JNZ     UPDATE                  ;if so, update screen clock
  102. TIMEXIT:POP     AX                      
  103.         PUSH    CS:OLDIP                ;restore old instruction pointer
  104. TIMEX   DB      0EAH                    ;far jump instruction
  105.         DB      0,0,0,0                 ;system timer address goes here
  106.  
  107. ;       a second has passed, print time on the screen
  108.  
  109. UPDATE: MOV     CS:CLKFLG,0             ;disable other clock interrupts
  110.         MOV     CS:SYSSTK,SP            ;else, save system stack
  111.         MOV     CS:SYSSTKS,SS           ;save system stack segment
  112.         CLI                             ;kill interrupts (on at entry)
  113.         MOV     AX,CS
  114.         MOV     SS,AX                   ;put stack segment here
  115.         MOV     SP,OFFSET MYSTAK        ;set local stack
  116.         STI                             ;set interrupts
  117.         PUSH    BX                      ;save registers
  118.         PUSH    CX
  119.         PUSH    DX
  120.         PUSH    SI
  121.         PUSH    DI
  122.         PUSH    DS
  123.         PUSH    ES
  124.         PUSH    BP
  125.         MOV     AX,CS
  126.         MOV     DS,AX                   ;put ds here
  127. PTIME:  MOV     AL,HOU                  ;get hours
  128.         CALL    CONASC                  ;convert to ascii
  129.         MOV     HOUR,AX                 ;result to buffer
  130.         MOV     AL,MIN                  ;get minutes
  131.         CALL    CONASC                  ;convert to ascii
  132.         MOV     MINUTE,AX               ;result to buffer
  133.         MOV     AL,SEC                  ;get seconds
  134.         CALL    CONASC                  ;convert to ascii
  135.         MOV     SECOND,AX               ;result to buffer
  136.         MOV     AH,GVS
  137.         INT     SCRINT                  ;get video state
  138.         PUSH    BX                      ;save page
  139.         MOV     BX,OFFSET MODES         ;point to video modes
  140.         XLAT                            ;get mode code
  141.         MOV     CMODE,AL                ;save decoded mode
  142.         POP     BX                      ;get page
  143.         MOV     AH,GCP
  144.         INT     SCRINT                  ;get cursor position
  145.     MOV    CPOS,DX                 ;save it
  146.     MOV    DH,ROW                  ;get row for clock
  147.     MOV    DL,31                   ;assume column 31
  148.     CMP    BYTE PTR CMODE,2        ;80 column mode?
  149.     JB    PTIME0                  ;no
  150.     MOV    DL,71                   ;else, set column 71
  151. PTIME0:    MOV    AH,SCP
  152.     INT    SCRINT                  ;set cursor position to time area
  153.     MOV    CX,9                    ;set a counter
  154.     MOV    BL,WHITE                ;assume white color
  155.     CMP    BYTE PTR CMODE,0        ;40 column B/W?
  156.     JZ    PTIME1                  ;yes
  157.         CMP     BYTE PTR CMODE,2        ;80 column B/W?
  158.         JZ      PTIME1
  159.         MOV     BL,COLOR                ;else, use color
  160. PTIME1: MOV     SI,OFFSET TIMSTR        ;point to time string
  161. PTMLP:  LODSB                           ;get a digit
  162.         PUSH    CX                      ;save counter
  163.         PUSH    SI                      ;save pointer
  164.         CALL    PDIGIT                  ;print digit
  165.         POP     SI
  166.         POP     CX
  167.         LOOP    PTMLP                   ;loop until done
  168. PDONE:  MOV     AH,SCP
  169.         MOV     DX,CPOS
  170.         INT     SCRINT                  ;restore cursor to user's position
  171.         POP     BP
  172.         POP     ES
  173.         POP     DS
  174.         POP     DI
  175.         POP     SI
  176.         POP     DX
  177.         POP     CX
  178.         POP     BX
  179.         CLI                             ;clear interrupts
  180.         MOV     SS,CS:SYSSTKS           ;restore system stack
  181.         MOV     SP,CS:SYSSTK
  182.         STI                             ;set interrupts
  183.         MOV     CS:CLKFLG,1             ;re-enable clock
  184.         JMP     TIMEXIT                 ;and exit
  185.  
  186. ;       convert number in al to ascii digits in al,ah
  187.  
  188. CONASC: MOV     AH,0                    ;clear ah
  189.         MOV     BH,10                   ;get radix
  190.         DIV     BH                      ;divide by it
  191.         ADD     AX,'00'                 ;add ascii
  192.         RET
  193.  
  194. ;       print a digit on the screen
  195.  
  196. PDIGIT: MOV     AH,WCHAR
  197.         MOV     CX,1
  198.         INT     SCRINT                  ;write character
  199.         MOV     AH,GCP
  200.         INT     SCRINT                  ;get cursor position
  201.         INC     DL                      ;move it over
  202.         MOV     AH,SCP
  203.         INT     SCRINT                  ;set new cursor position
  204.         RET
  205. LEND:                                   ;end of resident code
  206.  
  207. ;       set up clock vector and initialize time
  208. ;       then exit with program resident
  209.  
  210. SETUP:  MOV     AH,2CH
  211.         INT     21H                     ;get time
  212.         MOV     SEC,DH                  ;save second
  213. WFSEC:  MOV     AH,2CH
  214.         INT     21H                     ;get time again
  215.         CMP     SEC,DH                  ;same second?
  216.         JZ      WFSEC                   ;wait for a new second
  217.         MOV     SEC,DH                  ;set seconds
  218.         MOV     WORD PTR MIN,CX         ;set minutes, hours
  219.         PUSH    DS                      ;save ds
  220.         XOR     AX,AX
  221.         MOV     DS,AX                   ;DS at 0
  222.         MOV     SI,OFFSET TIMEINT       ;point to timer interrupt
  223.         LES     DI,DWORD PTR [SI]       ;get vector in ES:DI
  224.         CMP     WORD PTR ES:-2[DI],'KC' ;clock already in?
  225.         JZ      ITSIN                   ;yes
  226.         CLI                             ;else, turn off interrupts
  227.         MOV     WORD PTR [SI],OFFSET MYTIME     ;put in my vector
  228.         MOV     2[SI],CS                ;and this segment
  229.         POP     DS                      ;restore DS
  230.         MOV     WORD PTR TIMEX+1,DI     ;put old vector at our exit
  231.         MOV     WORD PTR TIMEX+3,ES
  232.         STI
  233.         MOV     DX,OFFSET LEND          ;point to end of res. code
  234.         INT     27H                     ;exit, leave program here
  235. ITSIN:  INT     20H                     ;exit, nothing done
  236. CLK     ENDS
  237.         END     START
  238.