home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / GENASM / TIME11.MAC < prev    next >
Text File  |  2000-06-30  |  22KB  |  1,064 lines

  1. ;  Program:  TIME
  2. ;  Version:  1.1
  3. ;  Author:  Richard Conn
  4. ;  Date:  6 Mar 82
  5. ;  Previous Versions:  1.0 (2 Mar 82)
  6. VERS    equ    11    ;Version Number
  7.  
  8. ;    TIME is invoked by a command line of the form:
  9. ;
  10. ;        TIME <time> <date> <weekday> <display cmd>
  11. ;
  12. ;    All parameters are optional and may be present in any order.
  13. ;If all parameters are omitted, the time and date are printed.
  14. ;The various parameters are:
  15. ;    <time> -- Current time as hh:mm (hh and mm are 1-2 digits)
  16. ;        hh:mm may be followed by A or P (hh:mmA) for AM or PM
  17. ;            (defaults to current AM or PM)
  18. ;    <date> -- Current date as dd/mm/yy (all are 1-2 digits)
  19. ;    <weekday> -- Day of week (3 letters are generally required)
  20. ;    <display cmd> -- Either:
  21. ;        DISPLAY TIME, DISPLAY DATE, XDISK, or PRINT
  22. ;            (only 1st letter of each word required)
  23. ;            DISPLAY Sets Display on Chronograph
  24. ;            PRINT Sends Output to Printer
  25. ;            XDISK Sends Output to Disk File TIME.SYS
  26. ;    Each parameter is separated from its predecessor by one or more spaces.
  27. ;
  28.  
  29. ;
  30. ;  External Routines in SYSLIB Library
  31. ;
  32.     ext    cin    ; Console Input
  33.     ext    cout    ; Console Output
  34.     ext    lout    ; List Output
  35.     ext    pout    ; Punch (Clock) Output
  36.     ext    rin    ; Reader (Clock) Input
  37.     ext    crlf    ; New Line
  38.     ext    lcrlf    ; New Line to LST:
  39.     ext    print    ; Print String at Return Address
  40.     ext    lprint    ; Print String at Return Address on LST:
  41.     ext    pstr    ; Print String Pointed to by HL
  42.     ext    lpstr    ; Print String Pointed to by HL on LST:
  43.     ext    f$make    ; Create File
  44.     ext    fo$open    ; Open File for Byte-Oriented Output
  45.     ext    fo$close    ; Close File for Byte-Oriented Output
  46.     ext    f$put    ; Put Byte into File
  47.  
  48. ;  ASCII Constants
  49. CR    equ    0dh    ; <CR>
  50. LF    equ    0ah    ; <LF>
  51. CTRLC    equ    3    ; ^C
  52.  
  53. ;
  54. ;  CP/M Constants
  55. ;
  56. buff    equ    80H    ;Command Line Buffer
  57.  
  58. ;
  59. ;  Macros
  60. ;
  61. ;** Send AT Code and 2-letter command from Stack to Clock **
  62. sendat    macro
  63.     xthl        ;;Point to 1st letter of command
  64.     mvi    a,'A'    ;;Send AT Command Prefix
  65.     call    coclk    ;;Send to Clock
  66.     mvi    a,'T'
  67.     call    coclk
  68.     mov    a,m    ;;Get 1st Command Letter
  69.     call    coclk    ;;Send to Clock
  70.     inx    h    ;;Point to 2nd Command Letter
  71.     mov    a,m    ;;Get it
  72.     call    coclk    ;;Send to Clock
  73.     inx    h    ;;Point to Return Address
  74.     xthl        ;;Save it on Stack
  75.     endm
  76.  
  77. ;
  78. ;  TIME Program --
  79. ;
  80.     aseg
  81.     org    100H
  82.  
  83. ;
  84. ;  Set up for return
  85. ;
  86.     lxi    h,0    ;Obtain SP in HL
  87.     dad    sp
  88.     shld    stack    ;Save Return SP Value
  89.     lxi    sp,stack    ;Reset SP
  90.  
  91. ;
  92. ;  Check for Help Request
  93. ;
  94.     call    helpck
  95.  
  96. ;
  97. ;  Extract Data from Clock
  98. ;
  99.     call    readclock
  100.  
  101. ;
  102. ;  Set New Date or Time if one is specified
  103. ;
  104.     call    setclock
  105.  
  106. ;
  107. ;  Check Date and Time for Numeric Syntax Error
  108. ;
  109.     call    check
  110.  
  111. ;
  112. ;  Open Disk File for Output if Requested
  113. ;
  114.     call    dskopen
  115.  
  116. ;
  117. ;  Print Time/Date/Weekday on CON:, LST:, or Disk
  118. ;
  119.     call    prclock
  120.     call    dskclos    ;Close Disk if Disk Output Requested
  121.     lda    prflg    ;Check for LST: output and send CRLF if so
  122.     ora    a    ;0=CON: only
  123.     cnz    lcrlf    ;New Line to LST:
  124.  
  125. ;
  126. ;  Set Time/Date/Weekday if requested
  127. ;
  128.     lda    setit    ;Flag Set?
  129.     ora    a    ;0=no
  130.     cnz    doset
  131.  
  132. ;
  133. ;  Set Display if Requested
  134. ;
  135.     lda    disp    ;Flag Set?
  136.     ora    a    ;0=no
  137.     cnz    dodisp
  138.  
  139. ;
  140. ;  Return to Caller (CP/M or CP/ZM)
  141. ;
  142. return:
  143.     lhld    stack    ;Get original stack pointer
  144.     sphl        ;Load it
  145.     ret
  146.  
  147. ;
  148. ;  Clock Input/Output Entry Routines
  149. ;
  150. ciclk:
  151.     jmp    rin    ;Clock is on RDR:
  152. coclk:
  153.     jmp    pout    ;Clock is on PUN:
  154.  
  155. ;
  156. ;  Open Disk for Output if Requested
  157. ;
  158. dskopen:
  159.     lda    dskflg    ;Check flag
  160.     ora    a    ;0=no
  161.     rz
  162.     lxi    d,fcb    ;Pt to FCB
  163.     call    f$make    ;Make File
  164.     lxi    d,fcb    ;Pt to FCB
  165.     call    fo$open    ;Open File
  166.     ret
  167.  
  168. ;
  169. ;  Close Disk for Output if Requested
  170. ;
  171. dskclos:
  172.     lda    dskflg    ;Check flag
  173.     ora    a    ;0=no
  174.     rz
  175.     mvi    a,cr    ;New Line to file
  176.     call    f$put
  177.     mvi    a,lf
  178.     call    f$put
  179.     lxi    d,fcb    ;Pt to FCB
  180.     call    fo$close    ;Close File
  181.     ret
  182.  
  183. ;
  184. ;  Print Time/Date/Weekday on CON:
  185. ;
  186. prclock:
  187.     call    banner    ;Print Name of Program
  188.     call    prtime    ;Print Time
  189.     call    cprint
  190.     db    ' on ',0
  191.     call    prweek    ;Print Weekday
  192.     call    space    ;Space
  193.     call    prmonth    ;Print Month Name
  194.     call    space
  195.     call    prday    ;Print Day Number
  196.     call    pryear    ;Print Year
  197.     ret
  198.  
  199. ;
  200. ;  Print Name and Version of Program
  201. ;
  202. banner:
  203.     call    print
  204.     db    'TIME  Version '
  205.     db    VERS/10+'0','.',(VERS MOD 10)+'0'
  206.     db    '    ',0
  207.     ret
  208.  
  209. ;
  210. ;  Scan Input Buffer of Help Request (Token beginning with /)
  211. ;
  212. helpck:
  213.  
  214. ;  Place 0 after last char in command line
  215.     lxi    h,buff    ;Point to char count in command line
  216.     mov    a,m    ;Get char count
  217.     inx    h    ;Point to first char
  218.     add    l    ;Point to after last char in line
  219.     mov    l,a
  220.     mov    a,h
  221.     aci    0
  222.     mov    h,a    ;HL now points to after last char
  223.     mvi    m,0    ;Store 0 after last char
  224.  
  225. ;  Check for Token Beginning with /
  226.     lxi    h,buff+1    ;Pt to 1st char
  227. hckloop:
  228.     call    spskip    ;Skip to next token
  229.     ora    a    ;EOL?
  230.     rz        ;Done if so
  231.     cpi    '/'    ;Help?
  232.     jnz    hckloop    ;Fall thru to PRHELP if so
  233.  
  234. ;
  235. ;  Print Help Message
  236. ;
  237. prhelp:
  238.     call    crlf    ; New Line
  239.     call    banner    ; Print banner
  240.     call    crlf    ; New Line
  241.     call    print
  242.     db    cr,lf,'    TIME is invoked by a command line of the form:'
  243.     db    cr,lf
  244.     db    cr,lf,'        TIME <time> <date> <weekday> <display cmd>'
  245.     db    cr,lf
  246.     db    cr,lf,'    All parameters are optional and may be present in any'
  247.     db    ' order.'
  248.     db    cr,lf,'If all parameters are omitted, the time and date are'
  249.     db    ' printed.'
  250.     db    cr,lf,'The various parameters are:'
  251.     db    cr,lf,'    <time> -- Current time as hh:mm (hh and mm are 1-2'
  252.     db    ' digits)'
  253.     db    cr,lf,'        hh:mm may be followed by A or P (hh:mmA) for'
  254.     db    ' AM or PM '
  255.     db    cr,lf,'            (defaults to current AM or PM)'
  256.     db    cr,lf,'    <date> -- Current date as dd/mm/yy (all are 1-2'
  257.     db    ' digits)'
  258.     db    cr,lf,'    <weekday> -- Day of week (3 letters are generally'
  259.     db    ' required)'
  260.     db    cr,lf,'    <display cmd> -- Either:'
  261.     db    cr,lf,'        DISPLAY TIME, DISPLAY DATE, XDISK, or PRINT'
  262.     db    cr,lf,'            (only 1st letter of each word '
  263.     db    'required)'
  264.     db    cr,lf,'            DISPLAY Sets Display on Chronograph'
  265.     db    cr,lf,'            PRINT Sends Output to Printer'
  266.     db    cr,lf,'            XDISK Sends Output to Disk File '
  267.     db    'TIME.SYS'
  268.     db    cr,lf
  269.     db    cr,lf,'    Each parameter is separated from its predecessor by'
  270.     db    ' one or more spaces.'
  271.     db    cr,lf,0
  272.     jmp    return
  273.  
  274. ;
  275. ;  Set Time/Date/Weekday
  276. ;
  277. doset:
  278.     lda    sett    ;Set time?
  279.     ora    a    ;0=no
  280.     jz    doset1
  281.     call    print
  282.     db    cr,lf,'<< Setting Time -- Strike Any Key (^C=Abort) when '
  283.     db    'Ready >>',0
  284.     call    cin    ;Get Response
  285.     call    crlf    ;New Line
  286.     cpi    ctrlc    ;Abort?
  287.     jz    doset1    ;Continue if so
  288.     lxi    h,time    ;Set Time from Buffer
  289.     call    cmdo
  290.     db    'ST'    ;Set Time
  291. doset1:
  292.     lda    setd    ;Set date?
  293.     ora    a    ;0=no
  294.     jz    doset2
  295.     call    print
  296.     db    cr,lf,'<< Setting Date >>',cr,lf,0
  297.     lxi    h,date    ;Set Date from Buffer
  298.     call    cmdo
  299.     db    'SD'    ;Set Date
  300. doset2:
  301.     lda    setw    ;Set weekday?
  302.     ora    a    ;0=no
  303.     rz
  304.     call    print
  305.     db    cr,lf,'<< Setting Weekday >>',cr,lf,0
  306.     lxi    h,week    ;Set Weekday from Buffer
  307.     call    cmdo
  308.     db    'SW'    ;Set Weekday
  309.     ret
  310.  
  311. ;
  312. ;  Set Display Date or Time
  313. ;
  314. dodisp:
  315.     cpi    'D'    ;Date?
  316.     jz    dod1
  317.     call    cmd    ;Send Command
  318.     db    'DT'    ;Display Time
  319.     ret
  320. dod1:
  321.     call    cmd    ;Send Command
  322.     db    'DD'    ;Display Date
  323.     ret
  324.  
  325. ;
  326. ;  Send command pointed to by Return Address and command string pointed
  327. ;    to by HL to Clock and get Return Code
  328. ;
  329. cmdo:
  330.     sendat        ;Send ATcc
  331. cmdo1:
  332.     mov    a,m    ;Send command string
  333.     ora    a    ;End of string?
  334.     jz    cmdo2
  335.     call    coclk    ;Send to Clock
  336.     inx    h    ;Pt to next
  337.     jmp    cmdo1
  338. cmdo2:
  339.     mvi    a,cr    ;Send CR
  340.     call    coclk    ;To Clock
  341.     call    ciclk    ;Get Response
  342.     mov    b,a    ;Save in B
  343.     call    ciclk    ;Clear CR
  344.     mov    a,b    ;Get Result Code
  345.     sui    '0'    ;Convert to binary
  346.     rz        ;OK
  347.     cpi    9    ;Write Protect?
  348.     jnz    cmderr
  349.     call    print
  350.     db    cr,lf,'** Clock is Write-Protected -- Unprotect it to Set **',0
  351.     jmp    return    ;Immediate Return
  352. cmderr:
  353.     call    print
  354.     db    cr,lf,'** TIME Internal Syntax Error **',0
  355.     jmp    return    ;Immediate Return
  356.  
  357. ;
  358. ;  Simply send command at Return Address and check for error code
  359. ;
  360. cmd:
  361.     sendat        ;Send ATcc
  362.     jmp    cmdo2    ;Send CR and Check Error Code
  363.  
  364. ;
  365. ;  Read Time, Date, and Weekday from Clock
  366. ;
  367. readclock:
  368.     lxi    h,time    ;Point to Time Buffer
  369.     call    command
  370.     db    'RT'    ;Read Time
  371.     lxi    h,date    ;Point to Date Buffer
  372.     call    command
  373.     db    'RD'    ;Read Date
  374.     lxi    h,week    ;Point to Weekday Buffer
  375.     call    command
  376.     db    'RW'    ;Read Weekday
  377.     ret
  378.  
  379. ;
  380. ;  Print Time on CON: or LST:
  381. ;
  382. prtime:
  383.     lxi    h,time    ;Print Time Info
  384.     call    pr2s    ;Print 2 digits
  385.     call    colon    ;Print :
  386.     call    pr2    ;Print 2 digits
  387.     call    colon    ;Print :
  388.     call    pr2    ;Print 2 digits
  389.     call    space    ;Space
  390.     mov    a,m    ;Get A or P
  391.     call    cpout
  392.     mvi    a,'M'    ;Print M
  393.     call    cpout
  394.     ret
  395.  
  396. ;
  397. ;  Print Weekday on CON: or LST:
  398. ;
  399. prweek:
  400.     lda    week    ;Get week day number
  401.     sui    '0'    ;Convert to Binary
  402.     inr    a    ;Add 1
  403.     lxi    d,dlen    ;Length of Day Strings
  404.     lxi    h,days    ;Beginning of Day Strings
  405.     call    offset    ;Compute offset to desired string
  406.     call    cpstr    ;Print Day Name
  407.     ret
  408.  
  409. ;
  410. ;  Print Month Name
  411. ;
  412. prmonth:
  413.     lxi    h,date+2    ;Convert month number
  414.     mov    a,m    ;Get first digit
  415.     sui    '0'    ;Convert to Binary
  416.     mov    b,a    ;Save in B
  417.     add    a    ;*2
  418.     add    a    ;*4
  419.     add    b    ;*5
  420.     add    a    ;*10
  421.     inx    h    ;Point to next digit
  422.     mov    b,a    ;Value in B
  423.     mov    a,m    ;Get Digit
  424.     sui    '0'    ;Convert to Binary
  425.     add    b    ;Add in
  426.     lxi    d,mlen    ;Length of Month Strings
  427.     lxi    h,months    ;Beginning of Month Strings
  428.     call    offset    ;Compute Offset to Desired String
  429.     call    cpstr    ;Print Month Name
  430.     ret
  431.  
  432. ;
  433. ;  Print Day Number
  434. ;
  435. prday:
  436.     lxi    h,date+4    ;Point to Day Digits
  437.     call    pr2s    ;Print as 2 Digits
  438.     ret
  439.  
  440. ;
  441. ;  Print Year
  442. ;
  443. pryear:
  444.     call    cprint    ;Print Year Prefix
  445.     db    ', 19',0
  446.     lxi    h,date    ;Point to Year
  447.     call    pr2    ;Print 2 Digits
  448.     ret
  449.  
  450. ;
  451. ;  Print colon or space
  452. ;
  453. colon:
  454.     mvi    a,':'    ;Print colon
  455.     jmp    cpout
  456. space:
  457.     mvi    a,' '    ;Print space
  458.     jmp    cpout
  459.  
  460. ;
  461. ;  Command -- Issue 2-letter command pointed to by Return Address to Clock
  462. ;    and copy response into buffer pointed to by HL; affect all registers
  463. ;
  464. command:
  465.     sendat        ;Send ATcc
  466.     mvi    a,CR    ;Send <CR>
  467.     call    coclk    ;Send to Clock
  468. ;  Collect Response Chars
  469. cmdloop:
  470.     call    ciclk    ;Get letter
  471.     cpi    CR    ;End of Response?
  472.     jz    cmddone
  473.     mov    m,a    ;Store in Buffer
  474.     inx    h    ;Point to next position
  475.     jmp    cmdloop
  476. cmddone:
  477.     mvi    m,0    ;Store ending zero
  478.     ret
  479.  
  480. ;
  481. ;  PR2S -- Print chars pointed to by HL and HL+1; if first character is '0',
  482. ;    print only one char; affect all registers; on exit, HL points to byte
  483. ;    after 2nd char printed
  484. ;  PR2 -- PR2S but always print 2 digits
  485. ;
  486. pr2:
  487.     mov    a,m    ;Get first char
  488.     jmp    pr2a
  489. pr2s:
  490.     mov    a,m    ;Get first char
  491.     cpi    '0'    ;Leading zero?
  492.     jz    pr2b
  493. pr2a:
  494.     call    cpout    ;Print char
  495. pr2b:
  496.     inx    h    ;Point to next
  497.     mov    a,m    ;Get it
  498.     call    cpout
  499.     inx    h    ;Point to next
  500.     ret
  501.  
  502. ;
  503. ;  Compute Offset to selected string; on input, HL points to first
  504. ;    string, DE=string length, A=Number of String desired (first string = 1)
  505. ;
  506. offset:
  507.     dcr    a    ;Count down
  508.     rz
  509.     dad    d    ;Point to next
  510.     jmp    offset
  511.  
  512. ;
  513. ;  Check Date and Time for Numeric Error (Range)
  514. ;
  515. check:
  516.     lda    setit    ;Any Change?
  517.     ora    a    ;0=no
  518.     rz
  519.     lxi    h,time    ;Hours can't exceed 12
  520.     call    get2    ;Get 2 digits
  521.     cpi    12+1    ;Range ok?
  522.     jnc    chkerr    ;Error
  523.     lxi    h,time+2    ;Minutes can't exceed 60
  524.     call    get2    ;Get 2 digits
  525.     cpi    60+1    ;Range ok?
  526.     jnc    chkerr    ;Error
  527.     lxi    h,date+2    ;Month can't exceed 12
  528.     call    get2    ;Get 2 digits
  529.     cpi    12+1    ;Range ok?
  530.     jnc    chkerr    ;Error
  531.     lxi    h,date+4    ;Day can't exceed 31
  532.     call    get2    ;Get 2 digits
  533.     cpi    31+1    ;Range ok?
  534.     rc        ;Done if so
  535. chkerr:
  536.     call    print
  537.     db    cr,lf,'Argument Range Error -- Value in Error is ',0
  538.     mov    a,m    ;Get 1st digit
  539.     call    cout
  540.     inx    h    ;Pt to 2nd
  541.     mov    a,m    ;Get 2nd digit
  542.     call    cout
  543.     call    print
  544.     db    cr,lf,'Aborting to CP/M',0
  545.     jmp    return
  546. ;
  547. ;  Get two ASCII chars pted to by HL and convert them to integer in A
  548. ;
  549. get2:
  550.     push    h    ;Save ptr
  551.     mov    a,m    ;Get 10's digit
  552.     sui    '0'    ;Convert to binary
  553.     mov    b,a    ;Save in B
  554.     add    a    ;*2
  555.     add    a    ;*4
  556.     add    b    ;*5
  557.     add    a    ;*10
  558.     mov    b,a    ;Result in B
  559.     inx    h    ;Pt to next
  560.     mov    a,m    ;Get 1's digit
  561.     sui    '0'    ;Convert to binary
  562.     add    b    ;Add in
  563.     pop    h    ;Get ptr
  564.     ret
  565.  
  566. ;
  567. ;  Set Time, Date, or Weekday
  568. ;
  569. setclock:
  570. ;  Assume no Display Change and no Time/Date/Weekday Set
  571.     xra    a    ;A=0
  572.     sta    disp    ;No Display
  573.     sta    setit    ;No Set
  574.     sta    sett    ;No Set Time
  575.     sta    setd    ;No Set Date
  576.     sta    setw    ;No Set Weekday
  577.     sta    prflg    ;No Print
  578.     sta    dskflg    ;No Disk Output
  579.  
  580. ;  Skip to first non-blank char
  581.     lxi    h,buff+1    ;Point to first char
  582.     call    spskip    ;Skip to EOL or first token
  583.     ora    a    ;EOL?
  584.     rz
  585.     jmp    nxt1
  586.  
  587. ;  Skip to next token in command line
  588. nxtoken:
  589.     call    spskip    ;HL now points to first non-blank char; A is char
  590.     ora    a    ;Check for EOL
  591.     jnz    nxt1    ;Continue if not
  592.     mvi    a,0ffh    ;Set flag
  593.     sta    setit    ;Clock Set Flag
  594.     ret
  595.  
  596. ;  Main Token Processing Loop
  597. nxt1:
  598.  
  599. ;  Check for Number (Date or Time)
  600.     mov    a,m    ;Get next char
  601.     call    digit    ;Digit?
  602.     jz    wdchk    ;If not, check for Print, Weekday, or Display Command
  603.  
  604. ;  It is a number -- Determine if date or time
  605.     call    dtchk    ;Scan for ':' or '/' or ' ' or <NULL>
  606.     cpi    ' '+1    ;Error if no ':' or '/'
  607.     jnz    nxt2    ;Print error message and then Help message
  608.     call    print
  609.     db    cr,lf,'** Numeric Argument contains no Date (/) or Time (:)'
  610.     db    ' Separator **',0
  611.     jmp    prhelp
  612. nxt2:
  613.     cpi    ':'    ;Time?
  614.     jz    setime    ;Set Time
  615.  
  616. ;  Set Date
  617.     mvi    a,0ffh    ;Set flag
  618.     sta    setd    ;Set Date
  619.     call    number    ;Extract token as number char string
  620.     cpi    6    ;Must be 6 digits
  621.     jz    nxt3    ;Date error if not
  622.     call    print
  623.     db    cr,lf,'** Invalid Date Specification **',0
  624.     jmp    prhelp
  625. nxt3:
  626.     push    h    ;Save ptr
  627.     lxi    h,numbuf+4    ;Extract year digits
  628.     lxi    d,date    ;1st 2 in date buffer
  629.     call    copy2
  630.     lxi    h,numbuf+2    ;Extract month digits
  631.     call    copy2
  632.     lxi    h,numbuf    ;Extract day digits
  633.     call    copy2
  634.     pop    h    ;Get ptr
  635.     jmp    nxtoken    ;Get next token
  636.  
  637. ;  Set Time
  638. setime:
  639.     mvi    a,0ffh    ;Set flag
  640.     sta    sett    ;Set Time
  641.     call    number    ;Extract token as number char string
  642.     cpi    4    ;Must be 4 digits
  643.     jz    nxt4
  644.     jc    timerr    ;OK if more than 4 digits
  645.     call    print
  646.     db    cr,lf,'Warning -- Seconds Specified in Time Argument Ignored',0
  647.     jmp    nxt4
  648. timerr:
  649.     call    print
  650.     db    cr,lf,'** Invalid Time Specification **',0
  651.     jmp    prhelp
  652. nxt4:
  653.     push    h    ;Save ptr
  654.     lxi    h,numbuf    ;Place number in time buffer
  655.     lxi    d,time
  656.     call    copy4    ;Copy into buffer
  657.     mvi    a,'0'    ;Store ending 0's for seconds
  658.     stax    d
  659.     inx    d
  660.     stax    d
  661.     lda    letter    ;Get trailing letter, if any
  662.     cpi    'A'    ;AM?
  663.     cz    setlet    ;Set Letter
  664.     cpi    'P'    ;PM?
  665.     cz    setlet
  666.     pop    h    ;Get ptr
  667.     jmp    nxtoken
  668.  
  669. ;
  670. ;  Set Time Letter
  671. ;
  672. setlet:
  673.     sta    time+6    ;6th position
  674.     ret
  675.  
  676. ;  Check for Print, Weekday, or Display Command and Set it if so
  677. wdchk:
  678.     mov    a,m    ;Get 1st letter of command
  679.     cpi    'P'    ;Print?
  680.     jz    setpr
  681.     cpi    'X'    ;Disk Output?
  682.     jz    setdsk
  683.     cpi    'D'    ;Display Time or Date?
  684.     jz    display
  685.     mvi    a,0ffh    ;Set flag
  686.     sta    setw    ;Set Weekday
  687.     mov    a,m    ;Get Letter back
  688.     cpi    'T'    ;Tuesday or Thursday?
  689.     jnz    wdchk0
  690.     inx    h    ;Point to next char
  691.     mov    a,m    ;Get it
  692.     jmp    wdchk1
  693. wdchk0:
  694.     cpi    'S'    ;Saturday or Sunday?
  695.     jnz    wdchk1
  696.     inx    h    ;Point to next char
  697.     mov    a,m    ;Get it
  698.     cpi    ' '+1    ;In range?
  699.     jc    wderr
  700.     inx    h    ;Point to 3rd char
  701.     mov    a,m    ;Get it
  702. wdchk1:
  703.     push    h    ;Save ptr
  704.     lxi    h,daytab    ;Point to table of single letters (reverse)
  705.     mov    b,a    ;Char in B
  706.     mvi    c,7    ;Scan for 7 entries
  707. wdchk2:
  708.     mov    a,m    ;Get letter
  709.     cmp    b    ;Match?
  710.     jz    wdmatch
  711.     inx    h    ;Pt to next
  712.     dcr    c    ;Count down
  713.     jnz    wdchk2
  714.     pop    h    ;Get ptr
  715. wderr:
  716.     call    print    ;Error
  717.     db    cr,lf,'** Invalid Weekday Specification **',0
  718.     jmp    prhelp
  719. wdmatch:
  720.     pop    h    ;Get ptr
  721.     mov    a,c    ;Get weekday number +1
  722.     dcr    a    ;Adjust
  723.     adi    '0'    ;Convert to ASCII
  724.     sta    week    ;Set Day
  725.     jmp    nxtoken    ;Continue processing
  726.  
  727. ;  Display Time or Date
  728. display:
  729.     call    spskip    ;Skip to next token
  730.     cpi    'D'    ;Date?
  731.     jz    disp1
  732.     cpi    'T'    ;Time?
  733.     jz    disp1
  734.     call    print
  735.     db    cr,lf,'** Invalid Display Option -- Not Time or Date **',0
  736.     jmp    prhelp
  737. disp1:
  738.     sta    disp    ;Set Display Command
  739.     jmp    nxtoken    ;Continue
  740.  
  741. ;
  742. ;  Set Print Flag
  743. ;
  744. setpr:
  745.     mvi    a,0ffh    ;Set flag
  746.     sta    prflg
  747.     jmp    nxtoken    ;Continue
  748.  
  749. ;
  750. ;  Set Disk Output
  751. ;
  752. setdsk:
  753.     mvi    a,0ffh    ;Set flag
  754.     sta    dskflg
  755.     jmp    nxtoken    ;Continue
  756.  
  757. ;
  758. ;  Copy HL to DE for 2 or 4 bytes
  759. ;
  760. copy2:
  761.     mvi    b,2    ;2 Bytes
  762.     jmp    copyl
  763. copy4:
  764.     mvi    b,4    ;4 Bytes
  765. copyl:
  766.     mov    a,m    ;Get byte
  767.     stax    d    ;Put byte
  768.     inx    h    ;Pt to next
  769.     inx    d
  770.     dcr    b    ;Count down
  771.     jnz    copyl
  772.     ret
  773.  
  774. ;
  775. ;  Scan for Date or Time separator; terminate scan if found or <SP> or <NULL>
  776. ;    encountered; Do NOT affect HL
  777. ;
  778. dtchk:
  779.     push    h    ;Save HL
  780. dtchk1:
  781.     mov    a,m    ;Get char
  782.     inx    h    ;Pt to next
  783.     ora    a    ;<NULL>?
  784.     jz    dtchk2
  785.     cpi    ' '    ;<SP>?
  786.     jz    dtchk2
  787.     cpi    ':'    ;Time?
  788.     jz    dtchk2
  789.     cpi    '/'    ;Date?
  790.     jnz    dtchk1    ;Continue if not
  791. dtchk2:
  792.     pop    h    ;Found delimiter - Return with it in A
  793.     ret
  794.  
  795. ;
  796. ;  Skip to next space or <NULL>
  797. ;
  798. tosp:
  799.     mov    a,m    ;Get char
  800.     cpi    ' '    ;<SP>?
  801.     rz
  802.     ora    a    ;<NULL>?
  803.     rz
  804.     inx    h    ;Pt to next char
  805.     jmp    tosp
  806.  
  807. ;
  808. ;  Skip to next non-blank char after current token
  809. ;
  810. spskip:
  811.     call    tosp    ;Skip to white space
  812. spsk1:
  813.     mov    a,m    ;Get char
  814.     cpi    ' '    ;<SP>?
  815.     rnz
  816.     inx    h    ;Pt to next
  817.     jmp    spsk1
  818.  
  819. ;
  820. ;  Extract Number pted to by HL into numbuf; if number is followed by a letter,
  821. ;    return letter in 'letter' buffer; on exit, HL points to <SP> or <NULL>
  822. ;    after argument
  823. ;
  824. number:
  825.     lxi    d,numbuf    ;Pt to buffer
  826.     call    num2    ;Get 2 digits
  827.     mvi    c,0    ;0 so far
  828.     ora    a    ;No 1st digit?
  829.     jz    numb1
  830.     call    sepchk    ;Check for ':' or '/' separator and adv HL if so
  831.     mvi    c,2    ;2 so far
  832.     call    num2    ;Get 2 more digits
  833.     ora    a    ;No 1st digit?
  834.     jz    numb1
  835.     call    sepchk    ;Separator check
  836.     mvi    c,4    ;4 so far
  837.     call    num2    ;Get 2 more digits
  838.     ora    a    ;No 1st digit?
  839.     jz    numb1
  840.     mvi    c,6    ;6 so far
  841. numb1:
  842.     mov    a,m    ;Get terminating char
  843.     cpi    ' '+1    ;Letter?
  844.     jc    numb2
  845.     sta    letter    ;Set letter
  846.     call    tosp    ;Skip to <SP> or <NULL>
  847. numb2:
  848.     mov    a,c    ;Get digit count
  849.     ret
  850.  
  851. ;  Check to see that char pted to by HL is ':' or '/'; HL=HL+1 if so
  852. sepchk:
  853.     mov    a,m    ;Get char
  854.     cpi    ':'    ;':'?
  855.     jz    sepadv
  856.     cpi    '/'    ;'/'?
  857.     rnz
  858. sepadv:
  859.     inx    h    ;Inc HL
  860.     ret
  861.  
  862. ;  Extract at most 2 digits; on return, A=0 if no 1st digit; on return, A<>0
  863. ;    if 1st digit, DE=DE+2, HL pts to after digits
  864. num2:
  865.     mov    a,m    ;Get first char
  866.     call    digit    ;Digit?
  867.     rz        ;A=0
  868.     push    h    ;Save ptr
  869.     mvi    c,1    ;Assume 1 digit
  870.     mov    a,m    ;Get char
  871.     call    digit    ;Digit?
  872.     jnz    num2a    ;Continue if so
  873. num2err:
  874.     call    print
  875.     db    cr,lf,'** Invalid Digit Form in Numeric Argument **',0
  876.     jmp    prhelp
  877. num2a:
  878.     inx    h    ;Pt to next
  879.     mov    a,m    ;Get it
  880.     call    digit    ;Digit?
  881.     jz    num2b    ;Continue if not -- 1 digit
  882.     mvi    c,2    ;2 Digits
  883.     inx    h    ;Pt to next
  884.     mov    a,m    ;Get it
  885.     call    digit    ;Should NOT be digit
  886.     jnz    num2err    ;Error if it is
  887. num2b:
  888.     pop    h    ;Pt to first digit
  889.     mov    a,c    ;Get number of digits
  890.     cpi    2    ;2?
  891.     jz    numb2c    ;Skip if 2 digits
  892.     mvi    a,'0'    ;Store leading zero
  893.     stax    d
  894.     inx    d    ;Pt to next
  895. numb2c:
  896.     mov    a,m    ;Get digit
  897.     stax    d    ;Put digit
  898.     inx    h    ;Pt to next
  899.     inx    d
  900.     dcr    c    ;Count down
  901.     jnz    numb2c
  902.     mvi    a,1    ;Set OK
  903.     ret
  904.  
  905. ;  Determine if byte in A is ASCII digit; return with A=0 and Z if not
  906. digit:
  907.     cpi    '0'    ;Less than '0'?
  908.     jc    nodig
  909.     cpi    '9'+1    ;Greater than '9'?
  910.     jnc    nodig
  911.     mvi    a,0ffh    ;Set OK
  912.     ora    a    ;Set flags
  913.     ret
  914. nodig:
  915.     xra    a    ;Not digit
  916.     ret
  917.  
  918. ;
  919. ;  Send output to CON: or LST: depending on PRFLG
  920. ;
  921. cpout:
  922.     call    cout    ;Output to CON:
  923.     push    psw    ;Save char
  924.     lda    prflg    ;Check flag
  925.     ora    a    ;0=CON:
  926.     jz    cpout1
  927.     pop    psw    ;Get char
  928.     push    psw    ;Save char
  929.     call    lout    ;LST:
  930. cpout1:
  931.     lda    dskflg    ;Check flag
  932.     ora    a    ;<>0 = Disk
  933.     jz    cpout2
  934.     pop    psw    ;Get char
  935.     push    psw    ;Save char
  936.     call    f$put    ;Disk
  937. cpout2:
  938.     pop    psw    ;Get char
  939.     ret
  940.  
  941. ;
  942. ;  Print string pted to by return address on CON: or LST:
  943. ;
  944. cprint:
  945.     xthl        ;Pt to string
  946. cpr1:
  947.     mov    a,m    ;Get char
  948.     inx    h    ;Pt to next
  949.     ora    a    ;Done?
  950.     jz    cpr2
  951.     call    cpout    ;Print to CON: or LST:
  952.     jmp    cpr1
  953. cpr2:
  954.     xthl        ;Restore HL and Ret Adr
  955.     ret
  956.  
  957. ;
  958. ;  Print string pted to by HL on CON: or LST:
  959. ;
  960. cpstr:
  961.     push    h    ;Save ptr
  962.     push    psw    ;Save char
  963. cpstr1:
  964.     mov    a,m    ;Get next char
  965.     inx    h    ;Pt to next char
  966.     ora    a    ;Done?
  967.     jz    cpstr2
  968.     call    cpout    ;Print char
  969.     jmp    cpstr1
  970. cpstr2:
  971.     pop    psw    ;Get char
  972.     pop    h    ;Get ptr
  973.     ret
  974.  
  975. ;
  976. ;  Disk Output FCB
  977. ;
  978. fcb:
  979.     db    0,'TIME    SYS',0,0,0,0
  980.     db    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  981.     db    0,0,0
  982.  
  983. ;
  984. ;  Day Strings
  985. ;
  986. days:
  987.     db    'Monday',0,0,0,0
  988. days2:
  989.     db    'Tuesday',0,0,0
  990.     db    'Wednesday',0
  991.     db    'Thursday',0,0
  992.     db    'Friday',0,0,0,0
  993.     db    'Saturday',0,0
  994.     db    'Sunday',0,0,0,0
  995. dlen    equ    days2-days    ;Number of Bytes in Each Entry
  996.  
  997. ;
  998. ;  Quick-Reference Day Table (in Reverse Order)
  999. ;
  1000. daytab:
  1001.     db    'N'    ; suNday
  1002.     db    'T'    ; saTurday
  1003.     db    'F'    ; Friday
  1004.     db    'H'    ; tHursday
  1005.     db    'W'    ; Wednesday
  1006.     db    'U'    ; tUesday
  1007.     db    'M'    ; Monday
  1008.  
  1009. ;
  1010. ;  Month Strings
  1011. ;
  1012. months:
  1013.     db    'January',0,0,0
  1014. month1:
  1015.     db    'February',0,0
  1016.     db    'March',0,0,0,0,0
  1017.     db    'April',0,0,0,0,0
  1018.     db    'May',0,0,0,0,0,0,0
  1019.     db    'June',0,0,0,0,0,0
  1020.     db    'July',0,0,0,0,0,0
  1021.     db    'August',0,0,0,0
  1022.     db    'September',0
  1023.     db    'October',0,0,0
  1024.     db    'November',0,0
  1025.     db    'December',0,0
  1026. mlen    equ    month1-months    ;Number of Bytes in Each Entry
  1027.  
  1028. ;
  1029. ;  Stack Area
  1030. ;
  1031.     ds    40    ;20-Elt Stack
  1032. stack:    ds    2    ;Return SP Value
  1033.  
  1034. ;
  1035. ;  Input Buffers
  1036. ;
  1037. time:
  1038.     ds    10    ; Time Buffer
  1039. date:
  1040.     ds    10    ; Date Buffer
  1041. week:
  1042.     ds    10    ; Weekday Buffer
  1043. numbuf:
  1044.     ds    10    ; Number Input Buffer
  1045. disp:
  1046.     ds    1    ; Display Flag (0=Don't change Chronograph Display,
  1047.             ;   D=Display Date, T=Display Time)
  1048. letter:
  1049.     ds    1    ; Optional Letter after Time (A/P)
  1050. setit:
  1051.     ds    1    ; Set Time/Date/Weekday Flag (0=no)
  1052. sett:
  1053.     ds    1    ; Set Time (0=no)
  1054. setd:
  1055.     ds    1    ; Set Date (0=no)
  1056. setw:
  1057.     ds    1    ; Set Weekday (0=no)
  1058. prflg:
  1059.     ds    1    ; Print (0=no)
  1060. dskflg:
  1061.     ds    1    ; Disk Output (0=no)
  1062.  
  1063.     end
  1064.