home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / kaypro / kp4time2.lbr / KP4TIME2.AQM / KP4TIME2.ASM
Assembly Source File  |  1985-02-09  |  22KB  |  491 lines

  1. ; TIME.COM (8080 version) Version 2.0.
  2. ; CP/M program to display and set the real-time clock on Kaypro 4-84.
  3. ; Written 04/22/84 by Bob Snider, Columbus Ohio. Greatly expanded 6/30/84.
  4. ; Dispaly is MM/DD HH:MM:SS and can be 24-hour format or 12-hour with
  5. ; AM/PM. Date is optional, and the ability to set the clock is optional
  6. ; for those who want a minimum length module. Customize this assembly
  7. ; by setting the options in the "Customization section".
  8. ; The clock is just displayed by the command "TIME". The clock is displayed
  9. ; and set by anything extra on the command line, ie. "TIME SET". The
  10. ; program will prompt for date and time value which must be entered as in the
  11. ; display format. Each of the following items can be set independently:
  12. ;    Date (month/day)
  13. ;    Day of the week
  14. ;    Time of day (seconds may be omitted)
  15. ; If the 12-hour format is on, AM or PM must always follow the time.
  16. ; Any omitted items are not changed in the clock.
  17. ; The clock is set at the carriage return. The input line is parsed for
  18. ; proper format, but not checked for valid dates or times. If nothing is
  19. ; entered the time is unchanged. If an error is detected, the position of
  20. ; the error in the string is flagged with a '^' and nothing is set.
  21. ; The clock is checked to see if an update has occurred while being read,
  22. ; and it is re-read if so, ensuring valid time displays.
  23. ; Problems or enhancements should be directed to the Kaypro User's Group on
  24. ; CompuServe, page PCS-25.
  25. ;
  26. ; CONDITIONAL ASSEMBLY CONSTANTS FOR CUSTOMIZATION.
  27. NO      EQU     0               ;VALUE FOR 'NO' IN OPTIONS.
  28. YES     EQU     1               ;VALUE FOR 'YES' IN OPTIONS.
  29. ;
  30. ; CUSTOMIZATION SECTION. EACH OPTION MUST BE CODED 'YES' OR 'NO'.
  31. ;
  32. AMPM    EQU     YES             ;12-HOUR CLOCK FORMAT WITH AM/PM. NO=24 HOUR.
  33. DATE    EQU     YES             ;DATE IS DISPLAYED.
  34. WEEKDAY EQU     YES             ;DAY OF WEEK IS DISPLAYED.
  35. ZEROSUP EQU     YES             ;SUPPRESS LEADING 0'S IN NUMBERS.
  36. SETTIME EQU     YES             ;ALLOW TIME TO BE SET. NO=DISPLAY ONLY.
  37. ;
  38. ; COMPILE-TIME CONSTANTS.
  39. ;
  40. BOOT    EQU     0000H           ;SYSTEM BOOT ADDRESS
  41. BDOS    EQU     0005H           ;BDOS ENTRY POINT
  42. COMTAIL EQU     0080H           ;COMMAND TAIL FROM COMMAND LINE (COUNT+CHARS)
  43. CONOUT  EQU     2               ;CODE FOR CONSOLE OUTPUT REQUEST
  44. RTCA    EQU     20H             ;CLOCK ADDRESS SELECT REG
  45. RTCD    EQU     24H             ;CLOCK DATA REGISTER
  46. RTCS    EQU     22H             ;CLOCK STATUS REGISTER
  47. REGEND  EQU     5+(DATE*3 OR WEEKDAY)  ;ENDING REGISTER COUNT FOR TIME LOOP
  48. CR      EQU     0DH             ;CARRIAGE RETURN CHAR
  49. LF      EQU     0AH             ;LINE FEED CHAR
  50. ;
  51. ; WE BEGIN.
  52. ;
  53.         ORG     0100H           
  54.         JMP     START           ;SKIP ID
  55.         DB      'TIME V2.0 RAS 6/30/84'
  56. START:
  57. ; FIRST SAVE CP/M STACK AND SET UP OURS.
  58.         LXI     H,0             ;CLEAR HL
  59.         DAD     SP              ;ADD SP+0 IN HL
  60.         SHLD    SAVESP          ;SAVE SP OF CPM
  61.         LXI     SP,STACK        ;POINT TO MY STACK AREA
  62. ;
  63. ; READ THE CLOCK TIME IN ONE BURST.
  64. READTIME:
  65.         MVI     A,0CFH          ;INITIAL STATUS SETUP BYTE
  66.         OUT     RTCS            ;SET PIO FOR MODE 3 IN/OUTPUT
  67.         MVI     A,0E0H          ;LOW 5 BITS OUTPUT, TOP 3 INPUT
  68.         OUT     RTCS            ;SET PIO IN/OUT BITS
  69.         MVI     A,03H           ;DISABLE INTERRUPTS
  70.         OUT     RTCS            ;DO IT
  71.         MVI     A,14H           ;STATUS REG ADDR
  72.         OUT     RTCA            ;SELECT IT
  73.         IN      RTCD            ;RESET STATUS BIT
  74. DOREAD:
  75.         LXI     H,VALUE         ;POINT TO TIME SAVE AREA
  76.         MVI     B,2             ;START WITH SECONDS
  77. BURST:
  78.         MOV     A,B             ;A IS REGISTER WE WANT TO READ
  79.         CPI     REGEND          ;GOTTEN ALL WE WANT?
  80.         JNC     CHECK           ;YES, DONE GETTING TIME
  81.         OUT     RTCA            ;SELECT THAT REGISTER OF CLOCK
  82.         IN      RTCD            ;READ THE CLOCK DATA
  83.         MOV     M,A             ;SAVE IN CORE
  84.         INX     H               ;NEXT MEMORY LOCATION
  85.         INR     B               ;NEXT REG ADDR
  86.         JMP     BURST           ;GO GET MORE DATA
  87. CHECK:
  88. ; SEE IF THE CLOCK ROLLED OVER DURING THE READS.
  89.         MVI     A,14H           ;STATUS REG ADDR
  90.         OUT     RTCA            ;SELECT IT
  91.         IN      RTCD            ;GET STATUS
  92.         ORA     A               ;WAS CLOCK ROLL?
  93.         JNZ     DOREAD          ;YES, GO READ AGAIN
  94. ;
  95. ; FORMAT THE DATE AND TIME AND SEND TO CONSOLE.
  96. ;
  97. GOTIT:
  98.     IF DATE                     ;INCLUDE ONLY IF DATE DISPLAY OPTION
  99.         LXI     H,MONTH         ;POINT TO MONTH VALUE
  100.         CALL    HEXOUTL         ;PRINT IT (MAYBE ZERO SUPPRESSED)
  101.         MVI     A,'/'           ;SEPARATOR
  102.         CALL    CHAROUT         ;SEND A CHAR
  103.         DCX     H               ;POINT TO DAY OF MONTH
  104.         CALL    HEXOUTL         ;PRINT IT (ALSO ZERO-SUP)
  105.         CALL    BLANK           ;PRINT A BLANK
  106.     ENDIF ;(DATE)
  107.     IF WEEKDAY                  ;INCLUDE IF DAY OF WEEK OPTION
  108.         DCX     H               ;POINT TO DAY OF WEEK
  109.         MOV     L,M             ;GET VALUE
  110.         DCR     L               ;ADJUST FOR 0-6
  111.         MVI     H,0             ;CLEAR TOP
  112.         LXI     D,DAYTAB        ;GET ADDRESS OF TABLE
  113.         XCHG                    ;FLIP HL,DE
  114.         DAD     D               ;TABLE+3*(HL)=NAME TO USE
  115.         DAD     D
  116.         DAD     D
  117.         MVI     B,3             ;3 CHARS TO SHOW
  118. WKOUT:  MOV     A,M             ;GET ONE
  119.         CALL    CHAROUT         ;SEND IT
  120.         INX     H               ;NEXT
  121.         DCR     B               ;COUNT IT
  122.         JNZ     WKOUT           ;LOOP
  123.         CALL    BLANK           ;PUT SPACER
  124.     ENDIF ;(WEEKDAY)
  125.         LXI     H,HOURS         ;POINT TO HOURS
  126.     IF AMPM                     ;INCLUDE ONLY IF 12 HOUR AM/PM DISPLAY OPT.
  127.         MOV     A,M             ;GET HOURS
  128.         MVI     B,'A'           ;ASSUME AM
  129.         CPI     12H             ;IS AFTERNOON?
  130.         JC      NOPMADJ         ;NO, NO MORE ADJUSTMENTS
  131.         MVI     B,'P'           ;YES, IS PM
  132.         JZ      NOPMADJ         ;IF STILL IN HOUR 12, NO NUMBERIC ADJUST
  133.         SBI     12H             ;SUBTRACT 12 HOURS
  134.         DAA                     ;DECIMAL ADJUST
  135. NOPMADJ:
  136.         CPI     00H             ;IS MIDNIGHT HOUR?
  137.         JNZ     NOMIDAM         ;NO
  138.         MVI     A,12H           ;YES, SET 12 AM
  139. NOMIDAM:
  140.         MOV     M,A             ;RESET HOURS
  141.         MOV     A,B             ;GET AM/PM FLAG
  142.         STA     AMPMFLAG        ;SAVE IT FOR LATER
  143.     ENDIF ;(AMPM)
  144.         CALL    HEXOUTL         ;PRINT HOURS (MAYBE ZERO SUPPRESSED)
  145.         CALL    COLON           ;PUT OUT A ":" FOLLOWED BY MINUTES
  146.         CALL    COLON           ;':' AND SECONDS
  147.     IF AMPM                     ;IF AM/PM DISPLAY OPTION
  148.         CALL    BLANK           ;PRINT A BLANK
  149.         LDA     AMPMFLAG        ;GET A OR P
  150.         CALL    CHAROUT         ;PRINT IT
  151.         MVI     A,'M'           ;GET AN M
  152.         CALL    CHAROUT         ;PRINT IT
  153.     ENDIF ;(AMPM)
  154.         CALL    CRLF            ;PUT OUT CR LF
  155. ;
  156. ; SEE IF CLOCK SET REQUESTED BY ANYTHING IN THE COMMAND TAIL.
  157. ; PROMPT FOR THE DATE AND TIME TO SET THE CLOCK IF REQUESTED.
  158. ;
  159.     IF SETTIME                  ;INCLUDE ONLY IF TIME SET OPTION
  160.         LDA     COMTAIL         ;GET THE COUNT
  161.         CPI     2               ;IS AT LEAST 2 CHARS?
  162.         JC      DONE            ;NO, RETURN NOW
  163. ; SET THE TIME REQUESTED.
  164. DOSET:
  165.         LXI     H,VALUE         ;POINT TO DATE/TIME VALUE AREA
  166.         MVI     B,6             ;COUNT TO CLEAR
  167. CLEAR:  MVI     M,0FFH          ;SET NO VALUE
  168.         INX     H               ;NEXT
  169.         DCR     B               ;COUNT
  170.         JNZ     CLEAR           ;LOOP FOR ALL
  171.         LXI     D,PROMPT        ;POINT TO PROMPT MESSAGE
  172.         MVI     C,09H           ;PRINT STRING FUNCTION
  173.         CALL    BDOS            ;PUT TEXT ON SCREEN.
  174.         MVI     A,30            ;GET BUFFER LENGTH
  175.         STA     INMAX           ;SET LENGTH
  176.         LXI     D,INMAX         ;POINT TO START OF BUFFER PARMS
  177.         MVI     C,0AH           ;READ BUFFER FUNCTION
  178.         CALL    BDOS            ;READ CONSOLE INPUT
  179.         CALL    CRLF            ;FEED A LINE
  180.         LXI     H,INLEN         ;POINT TO INPUT BUFFER LENGTH
  181.         MOV     A,M             ;GET RETURNED LENGTH
  182.         ORA     A               ;WAS IT ZERO?
  183.         JZ      NOTSET          ;YES, NOTHING TO SET
  184.         MOV     E,A             ;SAVE COUNT
  185.         MVI     D,0             ;CLEAR D
  186.         INX     H               ;POINT TO 1ST CHAR
  187.         DAD     D               ;POINT BEYOND LAST CHAR
  188.         MVI     M,' '           ;SET A SCAN DELIMITER
  189.         INX     H               ;POINT ONE MORE
  190.         MVI     M,0             ;SET FINAL PARSE DELIMITER
  191.         LXI     H,INBUF         ;POINT TO FIRST CHAR
  192.     ENDIF ;(SETTIME ALONE)
  193.     IF SETTIME AND DATE         ;INCLUDE IF DATE OPTION IS ON
  194.         SHLD    WKPTR           ;SAVE SCAN POINTER
  195.         CALL    NUMBER          ;DECODE A NUMBER AND DELIMITER
  196.         JC      NODATE          ;INVALID NUM, NO DATE THERE
  197.         CPI     '/'             ;WAS DELIM A SLASH?
  198.         JZ      OKDATE          ;YES, WE HAVE A DATE
  199.         LHLD    WKPTR           ;NO, RESTORE SCAN TO START
  200.         JMP     NODATE          ;CONTINUE NEXT ITEM
  201. OKDATE: MOV     A,C             ;GET DECODED VALUE
  202.         STA     MONTH           ;SET MONTH
  203.         INX     H               ;NEXT CHAR
  204.         CALL    NUMBER          ;TRY FOR DAY
  205.         JC      ERROR
  206.         CPI     ' '             ;WAS DELIM A BLANK?
  207.         JNZ     ERROR           ;NO, BAD
  208.         MOV     A,C             ;GET NUM
  209.         STA     DAY             ;SET DAY OF MONTH
  210.         INX     H               ;NEXT CHAR
  211.     ENDIF ;(SETTIME AND DATE)
  212. NODATE:
  213.     IF SETTIME AND WEEKDAY      ;INCLUDE WITH DAY OF WEEK OPTION
  214.         LXI     D,DAYTAB        ;POINT TO TABLE
  215.         MVI     C,1             ;INIT VALUE
  216.         SHLD    WKPTR           ;SAVE START POINTER
  217. LOOKUP: LHLD    WKPTR           ;GET START ADDR
  218.         MVI     B,3             ;LENGTH
  219. LOOKUPLOOP:
  220.         LDAX    D               ;GET TABLE CHAR
  221.         CPI     0               ;END OF TABLE?
  222.         JZ      NOWEEKDAY       ;YES, NOT FOUND, NOT ERROR YET
  223.         XRA     M               ;BASIC COMPARE
  224.         ANI     0DFH            ;ELIMINATE CASE DIFFERENCE
  225.         JZ      LOOKMATCH       ;MATCHES IF ZERO
  226. ADJUST: INX     D               ;NO MATCH, BUMP TABLE PTR
  227.         DCR     B               ;FOR REST OF LENGTH
  228.         JNZ     ADJUST          ;LOOP
  229.         INR     C               ;BUMP VALUE
  230.         JMP     LOOKUP          ;TRY NEXT
  231. LOOKMATCH:
  232.         INX     D               ;NEXT IN TABLE
  233.         INX     H               ;NEXT IN INPUT
  234.         DCR     B               ;COUNT
  235.         JNZ     LOOKUPLOOP      ;TRY NEXT CHAR
  236. ; GOOD WEEK DAY NAME FOUND.
  237.         MOV     A,C             ;GET DECODED VALUE
  238.         STA     DAYOFWEEK       ;SAVE
  239.         MOV     A,M             ;GET NEXT CHAR
  240.         CPI     ' '             ;IS GOOD DELIM?
  241.         JNZ     ERROR           ;NO, CRUSH IT
  242.         INX     H               ;POINT TO NEXT CHAR
  243.     ENDIF ;(WEEKDAY)
  244. NOWEEKDAY:
  245.     IF SETTIME                  ;INCLUDE IF SET TIME OPTION
  246.         CALL    NUMBER          ;GET NEXT NUMBER
  247.         JC      NOTIME          ;NO TIME THERE
  248.         CPI     ':'             ;WAS DELIM ':'?
  249.         JNZ     ERROR           ;NO, BAD INPUT
  250.         MOV     A,C             ;GET VALUE
  251.         STA     HOURS           ;SAVE
  252.         INX     H               ;NEXT
  253.         CALL    NUMBER          ;TRY FOR MINUTES
  254.         JC      ERROR
  255.         MOV     A,C
  256.         STA     MINUTES         ;SAVE MINUTES
  257.         MOV     A,M             ;GET DELIM AGAIN
  258.         CPI     ':'             ;CHECK DELIM
  259.         JNZ     NOSECS          ;ALLOW SECONDS TO BE OMITTED
  260.         INX     H               ;NEXT
  261.         CALL    NUMBER          ;TRY FOR SECONDS
  262.         JC      ERROR           ;BAD
  263.         MOV     A,C
  264.         STA     SECONDS         ;SAVE SECONDS
  265. NOSECS: MOV     A,M             ;GET DELIM AGAIN
  266.         CPI     ' '             ;VALID FINAL DELIM?
  267.         JNZ     ERROR           ;NO, GARBAGE
  268.         INX     H               ;NEXT CHAR
  269.     ENDIF ;(SETTIME)
  270.     IF SETTIME AND AMPM         ;INCLUDE DECODING FOR 12-HOUR FORMAT OPTION
  271.         MOV     A,M             ;GET NEXT CHAR
  272.         ANI     0DFH            ;MAKE UPPER CASE
  273.         CPI     'A'             ;IS A?
  274.         JZ      AOK             ;YES
  275.         CPI     'P'             ;IS P?
  276.         JNZ     ERROR           ;NO, ERROR
  277.         LDA     HOURS           ;FOR PM, GET HOURS BACK
  278.         CPI     12H             ;WAS IT NOON HOUR?
  279.         JZ      APOK            ;YES, NO ADJUST
  280.         ADI     12H             ;+12 HOURS FOR PM
  281.         DAA                     ;DECIMAL ADJUST
  282.         STA     HOURS           ;UPDATE VALUE
  283.         JMP     APOK            ;CONTINUE
  284. AOK:    LDA     HOURS           ;GET HOURS
  285.         CPI     12H             ;WAS MIDNIGHT HOUR?
  286.         JNZ     APOK            ;NO, NO ADJUST
  287.         MVI     A,00H           ;YES, SET TO 00 HOURS
  288.         STA     HOURS           ;UPDATE HOURS
  289. APOK:   INX     H               ;POINT TO 'M'
  290.         MOV     A,M             ;GET IT
  291.         ANI     0DFH            ;UPPER CASE
  292.         CPI     'M'             ;IS IT REALLY?
  293.         JNZ     ERROR           ;AW, SHUCKS
  294.         INX     H               ;LAST CHECK
  295.         MOV     A,M             ;GET DELIM
  296.         CPI     ' '             ;VALID?
  297.         JNZ     ERROR           ;NO
  298.         INX     H               ;NEXT
  299.     ENDIF ;(SETTIME AND AMPM)
  300. NOTIME:
  301.     IF SETTIME                  ;NOW FOR ALL SETS
  302.         MOV     A,M             ;LOOK AT LAST DELIM
  303.         ORA     A               ;WAS END OF STRING?
  304.         JNZ     ERROR           ;FOOEY
  305. ; NOW LOAD THE TIME VALUES INTO THE CLOCK DEVICE.
  306.         LDA     SECONDS         ;FIRST CHECK FOR SECONDS GIVEN
  307.         CPI     0FFH            ;WAS OMITTED?
  308.         JZ      NOGO            ;YES, NO GO COMMAND
  309.         MVI     A,15H           ;GET ADDRESS FOR 'GO' COMMAND
  310.         OUT     RTCA            ;RESET SECONDS AND BELOW
  311.         MVI     A,00H           ;JUST CLEAR REG
  312.         OUT     RTCD            ;CAUSE LOW REGS TO CLEAR
  313. NOGO:   MVI     B,2             ;START AT SECONDS REGISTER
  314.         LXI     H,SECONDS       ;POINT TO SAVED SECONDS VALUE
  315. OUTSET:
  316.         MOV     A,B             ;GET REG ADDR
  317.         CPI     REGEND          ;DONE ALL WE WANT?
  318.         JNC     SETOK           ;YES, SET IS DONE
  319.         OUT     RTCA            ;SELECT THAT REG
  320.         MOV     A,M             ;GET SAVED VALUE
  321.         CPI     0FFH            ;IS IT 'NO CHANGE'?
  322.         JZ      SKIPIT          ;YES, SKIP THIS ONE
  323.         OUT     RTCD            ;SET THE REGISTER
  324. SKIPIT: INX     H               ;POINT TO NEXT VALUE
  325.         INR     B               ;NEXT REG ADDR
  326.         JMP     OUTSET          ;LOOP FOR ALL REGS
  327. SETOK:
  328.         LXI     D,OKMSG         ;POINT TO TIME SET OK
  329. ECHOEXIT:
  330.         MVI     C,09H           ;PRINT STRING FUNCTION
  331.         CALL    BDOS            ;PUT TEXT ON SCREEN.
  332.         MVI     A,0             ;GET A ZERO
  333.         STA     COMTAIL         ;CLEAR COMMAND TAIL LENGTH
  334.         JMP     READTIME        ;DISPLAY NEW TIME AND EXIT
  335. ERROR:
  336.         PUSH    H               ;SAVE ADDR OF ERROR
  337.         MVI     B,30            ;SET UP TO CLEAR 30 CHARS
  338.         LXI     H,INBUF         ;POINT TO BUFFER
  339. FLAGLOOP:
  340.         MVI     M,' '           ;CLEAR A CHAR
  341.         INX     H               ;NEXT
  342.         DCR     B               ;COUNT
  343.         JNZ     FLAGLOOP        ;LOOP
  344.         POP     H               ;GET ERROR ADDR BACK
  345.         MVI     M,'^'           ;PUT A POINTER TO ERROR
  346.         INX     H               ;NEXT
  347.         MVI     M,'$'           ;PUT ENDING STRING
  348.         LXI     D,INBUF         ;POINT TO ERROR FLAG LINE
  349.         MVI     C,09H           ;PRINT STRING FUNCTION
  350.         CALL    BDOS            ;DISPLAY FLAG LINE
  351.         LXI     D,ERRMSG        ;POINT TO ERROR MESSAGE
  352.         MVI     C,09H           ;PRINT STRING
  353.         CALL    BDOS            ;DISPLAY ERROR MSG
  354.         JMP     READTIME        ;RE-TRY INPUT
  355. ; NOTHING ENTERED IN RESPONSE TO PROMPT. SAY NOT SETTING AND DONE.
  356. NOTSET:
  357.         LXI     D,NOSETMSG      ;POINT TO MSG
  358.         JMP     ECHOEXIT        ;EXIT WITH TIME DISPLAY
  359. ;
  360. ; ROUTINE TO DECODE A NUMBER UP TO 2 DIGITS AND A DELIMITER.
  361. ; INPUT IS HL POINTING TO NEXT IN BUFFER. 0 BYTE IS END OF STRING.
  362. ; NUMBER VALUE (IN BCD) IS RETURNED IN C. DELIMITER IS IN A.
  363. ; ANY ERROR DETECTED IN NUMBER CAUSES CARRY FLAG SET AND HL RESTORED.
  364. ;
  365. NUMBER:
  366.         MVI     B,2             ;INIT MAX DIGIT COUNTER
  367.         MVI     C,0             ;CLEAR ANSWER WORK AREA
  368.         SHLD    WKPTR           ;SAVE STARTING SCAN
  369. GETDIG:
  370.         MOV     A,M             ;GET CHAR FROM BUFFER
  371.         CPI     '0'             ;IS >= '0'?
  372.         JC      NONDIGIT        ;NO, NOT A DIGIT
  373.         CPI     '9'+1           ;IS <= '9'?
  374.         JNC     NONDIGIT        ;NO, NOT A DIGIT
  375.         ANI     0FH             ;ISOLATE DIGIT VALUE
  376.         MOV     D,A             ;SAVE IT
  377.         MOV     A,C             ;GET PREVIOUS VALUE
  378.         RLC ! RLC ! RLC ! RLC   ;SHIFT TO HIGH NYBBLE
  379.         ORA     D               ;ADD IN NEW DIGIT
  380.         MOV     C,A             ;SAVE NEW VALUE
  381.         INX     H               ;POINT TO NEXT CHAR
  382.         DCR     B               ;COUNT DIGIT
  383.         JNZ     GETDIG          ;TRY FOR ANOTHER IF LENGTH LEFT
  384. NONDIGIT:
  385.         MOV     A,B             ;LOOK AT COUNT
  386.         CPI     2               ;WERE THERE ANY DIGITS?
  387.         JZ      BADNUM          ;NO, ERROR
  388.         MOV     A,M             ;GET DELIMITER BACK
  389.         ORA     A               ;TURN OFF CARRY
  390.         RET                     ;RETURN GOOD
  391. BADNUM:
  392.         LHLD    WKPTR           ;RESTORE SCAN PTR
  393.         STC                     ;SET WE HAD AN ERROR
  394.         RET                     ;RETURN ERROR
  395. ; TIME SET MESSAGES.
  396. PROMPT:
  397.         DB      'Enter values in above format. Omitted values are unchanged.'
  398.         DB      CR,LF,'$'
  399. OKMSG   DB      'Set OK.',CR,LF,'$'
  400. ERRMSG  DB      CR,LF,'Invalid format.',CR,LF,'$'
  401. NOSETMSG:
  402.         DB      'Nothing set.',CR,LF,'$'
  403. ;
  404.     ENDIF ;(SETTIME)
  405. ;
  406. ; DONE. RESTORE PREVIOUS STACK AND RETURN TO CP/M.
  407. ;
  408. DONE:
  409.         LHLD    SAVESP          ;GET SAVED SP
  410.         SPHL                    ;SP=HL, RESTORE PREV SP
  411.         RET                     ;RETURN TO CP/M
  412. ;
  413. ; SUBROUTINE TO PUT A CHARACTER TO CONSOLE. CHAR IN A. SAVES HL.
  414. ;
  415. CHAROUT:
  416.         PUSH    H               ;SAVE NEEDED REG
  417.         PUSH    B
  418.         MVI     C,CONOUT        ;SET BDOS REQUEST CODE
  419.         MOV     E,A             ;PUT CHAR IN E
  420.         CALL    BDOS            ;SYSTEM CALL
  421.         POP     B       
  422.         POP     H               ;RESTORE
  423.         RET                     ;DONE
  424. ; ROUTINE ENTRY TO PUT A BLANK ON THE SCREEN.
  425. BLANK:
  426.         MVI     A,' '           ;GET A SPACE
  427.         JMP     CHAROUT         ;CONTINUE IN CHAROUT SUBROUTINE
  428. ; ROUTINE ENTRY TO PUT CR AND LF ON THE SCREEN.
  429. CRLF:
  430.         MVI     A,0DH           ;CARRIAGE RETURN
  431.         CALL    CHAROUT
  432.         MVI     A,0AH           ;LINE FEED
  433.         JMP     CHAROUT
  434. ;
  435. ; SUBROUTINE TO OUTPUT BYTE AS TWO HEX ASCII DIGITS ON CONSOLE.
  436. ; INPUT AT (HL).
  437. ;
  438. HEXOUTL:                        ;LEADING DIGIT OUTPUT ROUTINE
  439.     IF ZEROSUP                  ;IF LEADING ZERO SUPPRESSION OPTION
  440.         MOV     A,M             ;GET BYTE
  441.         ANI     0F0H            ;ISOLATE HIGH NYBBLE
  442.         JZ      HEXLOW          ;IF ZERO, DONT PRINT IT
  443.     ENDIF ;(ZEROSUP)
  444. HEXOUT:
  445.         MOV     A,M             ;GET BYTE
  446.         RRC                     ;MOVE TO LOW NYBBLE
  447.         RRC
  448.         RRC
  449.         RRC
  450.         ANI     0FH             ;ISOLATE LOW NYBBLE
  451.         ORI     30H             ;MAKE ASCII DIGIT
  452.         CALL    CHAROUT         ;PRINT IT
  453. HEXLOW: MOV     A,M             ;GET BYTE AGAIN
  454.         ANI     0FH             ;ISOLATE LOW NYBBLE
  455.         ORI     30H             ;ASCII AGAIN
  456.         CALL    CHAROUT         ;PRINT 2ND
  457.         RET                     ;DONE
  458. ; ROUTINE ENTRY TO PUT OUT A COLON FOLLOWED BY NEXT VALUE FROM TIME.
  459. COLON:  MVI     A,':'           ;GET A COLON
  460.         CALL    CHAROUT         ;PUT IT OUT IN CHAROUT
  461.         DCX     H               ;POINT TO NEXT VALUE TO GO
  462.         JMP     HEXOUT          ;PRINT IT AND RETURN
  463. ;
  464. ; CONSTANTS.
  465. ;
  466.     IF WEEKDAY                  ;FOR DAY OF WEEK OPTION
  467. DAYTAB:
  468.         DB      'SUNMONTUEWEDTHUFRISAT',0  ;DAY OF WEEK TABLE
  469.     ENDIF
  470. ;
  471. ; WORK AREA.
  472. ;
  473. WKPTR   DS      2               ;INPUT SCAN POINTER SAVE AREA
  474. AMPMFLAG DS     1               ;'A' OR 'M' FOR AM/PM OPTION
  475. SAVESP  DS      2               ;SAVE AREA FOR CP/M STACK POINTER
  476. VALUE   EQU     $               ;SAVED TIME VALUE WORK AREA
  477. SECONDS DS      1               ;SECONDS
  478. MINUTES DS      1               ;MINUTES
  479. HOURS   DS      1               ;HOURS
  480. DAYOFWEEK DS    1               ;DAY OF WEEK
  481. DAY     DS      1               ;DAY
  482. MONTH   DS      1               ;MONTH IS LAST THING
  483.         DS      32              ;16-POSITION STACK
  484. STACK:  EQU     $               ;STACK POINTER STARTS HERE
  485. INMAX   DS      1               ;MAXIMUM INPUT SIZE PUT HERE
  486. INLEN   DS      1               ;RETURNED INPUT CHAR COUNT
  487. INBUF   DS      32              ;INPUT BUFFER + ENDING DELIMS
  488. ;
  489.         END
  490.