home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / latest / clock24.lbr / CLOCK24.ZZ0 / CLOCK24.Z80
Encoding:
Text File  |  1994-02-02  |  57.3 KB  |  2,538 lines

  1. ;
  2. ; Program to set the MM58167a chip in the Kenmore Clock, Anapro 
  3. ; Clock for the Heath H89/90 or CDR Super 89 clock. The program
  4. ; reads and writes directly to the MM58167 and automatically 
  5. ; adjusts for leap years and Daylight Savings Time. See the
  6. ; internal HELP for options.
  7. ;
  8. ; CLOCK ver 2.4 30-Jan-94   Biff Bueffel
  9. ;    Added an option to update(adjust) clock time based on
  10. ;        data stored in a one record buffer in the
  11. ;        program. Adjusts for slow or fast clock based
  12. ;        on two times being set accurately such as
  13. ;        using WWV. Basic code compliments of Terry Hazen.
  14. ;
  15. ; CLOCK ver 2.3 29-Jul-93   Biff Bueffel
  16. ;
  17. ;    Deleted use of IX register as it bombs on some systems.
  18. ;        DST option now configured from CFG file rather
  19. ;        than from command line as most users will not
  20. ;        ever change their original choice. Clock will
  21. ;        now report time or register data even if the
  22. ;        flag byte is corrupt. This is useful in trouble-
  23. ;        shooting. The date/time value may be correct while
  24. ;        only the flag byte is corrupt. If the flag byte is
  25. ;        corrupted an asterisk is printed after the time. 
  26. ;        Minor bug fixes.
  27. ;
  28. ; CLOCK ver 2.2 15-Mar-93   Biff Bueffel
  29. ;
  30. ;    Adds ability to place time data on the 25th line of
  31. ;          a H19 terminal. Heath or ANSI(VT-52) modes possible.
  32. ;          May work on other terminals but not tested. Use
  33. ;          CFG file to change strings for 25th line and
  34. ;          saving cursor position. 
  35. ;
  36. ; CLOCK ver 2.1 16-Nov-92   Biff Bueffel
  37. ;
  38. ;    a) Uses PDAT.REL for routines to print time and date.
  39. ;    b) Added elapsed time option(including hundredths of a
  40. ;        second). Code shamelessly stolen from Terry
  41. ;        Hazen's ELAPSED who borrowed much of it from
  42. ;        Gene Pizzetta. Thanks, Terry for your permission
  43. ;        to use the code.
  44. ;
  45. ; CLOCK  ver 2.0 30-Oct-92   Biff Bueffel 
  46. ;
  47. ;    a) Changed DST routine from last Sunday to first Sunday in April
  48. ;    b) Moved year storage to base port + 9, consistent with other
  49. ;        programs for this clock chip
  50. ;    c) Changed time format to be consistent with Ztime
  51. ;    d) Added Military/Civilian time option. Can be configured
  52. ;        for default and then toggle from command line
  53. ;    e) Allow setting of date only(original was time or date/time)
  54. ;    f) Used syslib and zslib routines where possible
  55. ;    g) Base port is stored at beginning of program to allow easy
  56. ;        modification. Whenever a port is read or written the 
  57. ;        base port is loaded and the appropriate offset is
  58. ;        added and the value is placed in register C
  59. ;    h) Silent option added to update clock for DST and leap year
  60. ;        without sending date/time to CRT
  61. ;    i) Command line option will continuously display the date and
  62. ;        time until any key is struck
  63. ;
  64. ;
  65. ;    Thanks to Ludo Van Hemelryck for code suggestions and for
  66. ;        detailed commenting much of the code.
  67. ;
  68. ;    Thanks to Terry Hazen for code suggestions and especially 
  69. ;        for creating the CFG file!
  70. ;
  71. ; CLOCK  ver 1.1  1985--Author unknown
  72. ;
  73. ;*********************************************************************
  74. ;
  75. ; Clock base port is 0a0h for CDR Super 89
  76. ;             080h for Anapro clock
  77. ;             0e0h for Kenmore clock
  78. ;
  79. ; TENTHS = base port + 1     Hundreths/Tenths of Seconds
  80. ; SEC     = base port + 2
  81. ; MIN     = base port + 3
  82. ; HRS     = base port + 4
  83. ; DOW     = base port + 5         Day of Week
  84. ; DAY     = base port + 6
  85. ; MON     = base port + 7
  86. ; YEAR     = base port + 9      RAM for 10ths and 100ths of Second
  87. ;
  88. ; FLAGS     = base port + 14     DST and Leap year Flags
  89. ;
  90. ; CLKSTS = base port + 20     Status bit
  91. ; CLKGO     = base port + 21     GO command
  92. ;
  93. ;*************************************************************
  94. ;
  95. ; ZCPR3 utility type.  Configure your assembly/linking alias in one of
  96. ; the following ways to produce the type of file desired.
  97. ;
  98. ; Set ZTYPE to 1 to produce a type 1 utility loading and executing at
  99. ; 100h under any version of ZCPR3:
  100. ;
  101. ;        ZMAC CLOCK;ZML CLOCK
  102. ;    or    Z80ASM CLOCK/M;SLRNKP CLOCK/N,/A:100/J,CLOCK,/E
  103. ;
  104. ;
  105. ; Set ZTYPE to 3 to produce a type 3 utility loading and executing at
  106. ; a specified address such as 8000h under ZCPR33+:
  107. ;
  108. ;        ZMAC CLOCK;ZML CLOCK /A:8000
  109. ;    or    Z80ASM CLOCK/M;SLRNKP CLOCK/N,/A:8000/J,CLOCK,/E
  110. ;
  111. ;
  112. ; Set ZTYPE to 4 to produce a type 4 utility loading under the CCP
  113. ; or protected RSX and executing only under ZCPR34+:
  114. ;
  115. ;        ZMAC CLOCK;ZML CLOCK,T4LDR.HDR/P
  116. ;
  117. ; Rather than re-editing this file each time ZTYPE is changed,
  118. ; ask for the type at assembly time:
  119. ;
  120.     .accept    ' - Configure CLOCK.REL for ZCPR3 Type 1, 3 or 4? ',type
  121.  
  122.       if    (type=4)
  123. ztype    equ    4
  124.  
  125.     public    $memry    ; End of code
  126.  
  127.       else
  128.        if    (type=3)
  129. ztype    equ    3
  130.        else
  131. ztype    equ    1        ; Default is type 1 utility
  132.        endif
  133.       endif
  134. ;
  135. ;*********************************************************************
  136. ;
  137.  
  138. vers    equ    24
  139.  
  140. lpflg:        equ    00000001b    ;Flag that this is a leap year
  141. yokflg:        equ    00000010b    ;Flag that the year has been fixed
  142. flgDST:        equ    00001000b    ;Flag daylight savings time in effect
  143. setflg:        equ    01010000b    ;Flag that the clock has been set
  144. okmask:        equ    11110000b    ;Mask for clock ok flag
  145.  
  146. lpbit:        equ    0        
  147. okbit:        equ    1        
  148. DSTbit:        equ    3        
  149.  
  150. bdos    equ    5
  151. tbuff    equ    80h
  152.  
  153. cr    equ    0dh    ; carriage return
  154. lf    equ    0ah    ; line feed
  155. bell    equ    07h    ; Bell
  156. bs    equ    08h    ; backspace
  157. esc    equ    1bh    ; escape
  158. fcb    equ    5ch
  159.  
  160.     public    envptr
  161.  
  162.     .request    pdat
  163.     ext    colon,pdat1,pday1,ptim1,ptim3,space
  164.  
  165.     .request    nztim
  166.     ext    bc2bi,bi2bc
  167.     ext    bc2ju,ju2bc,ss2cp
  168.  
  169.     .request    zslib
  170.     ext    isbcdt
  171.     ext    mullw,divlw,addlw,sublw,neglw
  172.  
  173.     .request    vlib
  174.     ext    curon,curoff,z3vinit,at
  175.  
  176.     .request    z3lib
  177.     ext    getmsg
  178.  
  179.     .request    syslib
  180.     ext    caps,condin,cout,crlf,eprint,epstr
  181.     ext    pa2hc,phl4hc,fillb
  182.     ext    setdma,f$exist,f$open,r$write,f$close
  183.     ext    putud,getud,logud
  184.  
  185. ;*********************************************************************
  186.  
  187. entry:     
  188.     if    ztype=3
  189.     jp    start0    ; Executes only under ZCPR33+
  190.     defb    0    ; Filler
  191.      else
  192.     jp    start    ; T4LDR has already tested for Z34
  193.      endif
  194.  
  195. z3env:    defb    'Z3ENV'    ; ZCPR3 indentifier
  196.     defb    ztype    ; Default is type 1 utility
  197. envptr:    defw    0    ; Z3ENV address
  198.  
  199.     iff    ztype=4
  200. load:    defw    entry    ; ENTRY load address for type 3, dummy for type 1
  201.     else
  202. $memry    defw    0    ;   Code size for type 4 filled in by linker here
  203.     endif
  204.  
  205. ;
  206. cfg:    db    'CLOCK'
  207.     db    vers/10+'0',vers mod 10+'0'
  208.     ds    cfg+8-$,' '    ; Space for 8 bytes
  209.     db    0        ; Termination
  210.  
  211. port:    defb    0a0h        ; 0a0h for CDR Super 89
  212.                 ; 080h for Anapro clock
  213.                 ; 0e0h for Kenmore clock
  214. ;
  215. civflg:    defb    0        ; 0=military time, NZ=civilian time
  216.  
  217. DSTflg:    defb    0ffh        ; Enable DST=0ffh, Disable DST=00h
  218.  
  219. updflg:    defb    0ffh        ; Enable clock updating = 0ffh
  220.                 ; Disable clock updating = 00h
  221.  
  222. wrtflg:    defb    000h        ; Allow setting of clock even if
  223.                 ;  updating is not enabled.
  224.                 ;  Can be used to allow only one
  225.                 ;  copy of the program to set the
  226.                 ;  clock. Other copies may only read 
  227.                 ;  it(00h). 0ffh=set okay even with
  228.                 ;  no update flag.
  229.  
  230. disk:    defb    0        ; A=1
  231. prgnam:    defb    'CLOCK   COM',0
  232. user:    defb    0
  233.  
  234. timreg:    defb    18        ; First storage record
  235.  
  236. ; Configures Heath/Zenith H19 terminal(or others?) for 25th line use
  237. ;
  238. line25:    defb    0        ; ffh = put time on 25th line
  239. enable:    defb    esc,'x','1',0,0    ; turn on 25th line
  240.                 ; MUST remain a 5 byte string.
  241.                 ; Unused bytes should be 0
  242.                 ; = esc,'[','1','h' if h19 ansi
  243.     defb    0        ; do not change
  244. ;
  245. disabl:    defb    esc,'y','1',0,0    ; turn off 25th line
  246.                 ; MUST remain a 5 byte string.
  247.                 ; Unused bytes should be 0
  248.                 ; = esc,'[','1','l' if h19 ansi
  249.     defb    0        ; do not change
  250. ;
  251. cursav:    defb    esc,'j',0,0    ; save current cursor position
  252.                 ; MUST remain a 4 byte string.
  253.                 ; Unused bytes should be 0
  254.                 ; = esc,'[','s' if h19 ansi
  255.     defb    0        ; do not change
  256. ;
  257. curret:    defb    esc,'k',0,0    ; return to saved cursor position
  258.                 ; MUST remain a 4 byte string.
  259.                 ; Unused bytes should be 0
  260.                 ; = esc,'[','u' if h19 ansi
  261.     defb    0        ; do not change
  262. ;
  263.  
  264. ;
  265. ; Start Buffer on record boundary
  266. ;
  267.     ds    128-[$-entry and 127] and 127    ; Second record
  268. ;
  269.  
  270. ;=======================================================================
  271. ;
  272. ; One-record buffer for data file containing 4 byte (32-bit) set archive
  273. ; time/dates in Julian Seconds format:    (db low,lmed,hmed,high)
  274. ; SST date/times are included for readability but aren't referenced.
  275. ;
  276. ; Baseline set date/time
  277. ;
  278. byr:    ds    6        ; SST
  279.     ds    6        ; Fill
  280. setbase:ds    4        ; JS32
  281. ;
  282. ; Latest set date/time
  283. ;
  284. syr:    ds    1        ; SST
  285. smo:    ds    1
  286. sda:    ds    1
  287. sho:    ds    1
  288. smi:    ds    1
  289. sse:    ds    1
  290.     ds    6        ; Fill
  291. setnew:    ds    4        ; JS32
  292. ;
  293. ; Current clock date/time
  294. ;
  295. tyr:    ds    1        ; SW/SST
  296. tmo:    ds    1
  297. tda:    ds    1
  298. tho:    ds    1
  299. tmi:    ds    1
  300. tse:    ds    1
  301. ttx:    ds    1
  302. ttn:    ds    1
  303.     ds    4        ; Fill
  304. clktim:    ds    4        ; JS32
  305. ;
  306.     ds    16        ; Fill
  307. ;
  308. ; Corrected clock date/time
  309. ;
  310. cyr:    ds    1        ; SST
  311. cmo:    ds    1
  312. cda:    ds    1
  313. cho:    ds    1
  314. cmi:    ds    1
  315. cse:    ds    1
  316. ctx:    ds    1
  317. ctn:    ds    1
  318.     ds    4        ; Fill
  319. cortim:    ds    4        ; JS32
  320.  
  321. delta:                ; Difference
  322. corr:    ds    4        ; Correction factor
  323.     ds    1        ; Fill
  324. udflg:    db    0        ; Has been updated via 'U' option
  325.     ds    4        ; Fill
  326. sign:    ds    1        ; LCF sign:  0=clock slow, 1=clock fast
  327.     ds    1        ; Fill
  328. lcf:    ds    4        ; Linear correction factor
  329.  
  330. ;=======================================================================
  331. ;
  332. ; Start code on record boundary
  333. ;
  334.     ds    256-[$-entry and 127] and 127    ;
  335. ;
  336. ; Starting point for type 3
  337. ;
  338.      if    ztype=3
  339. start0:    ld    hl,0        ; Point to warm boot entry
  340.     ld    a,(hl)        ; Get the opcode
  341.     di            ; Protect against interrupts
  342.     ld    (hl),0c9h    ; Replace warm boot with a return
  343.     rst    0        ; 'CALL 0' pushes retadr onto stack
  344. ;
  345. retadr:    ld    (hl),a        ; Restore original opcode at 0
  346.     dec    sp        ; Phony push to set stack pointer to
  347.     dec    sp        ;    to point to the value of retadr
  348.     pop    de        ; DE = real retadr
  349. ;
  350.     ei            ; Enable interrupts
  351.     ld    hl,retadr    ; This is where we should be
  352.     or    a        ; Clear CARRY
  353.     sbc    hl,de        ; Are we actually there?
  354.     jp    z,start        ; Yes, begin real code
  355. ;
  356. ; We're not where we should be, so quit with error message
  357. ;
  358.     ld    hl,nz33msg-retadr ; Offset to message
  359.     add    hl,de
  360.     ex    de,hl        ; Message pointer in DE
  361.     ld    c,9
  362.     jp    bdos        ; Quit via BDOS print string function
  363. ;
  364. nz33msg:db    'Not Z33+$'    ; Abort message if not Z33-compatible
  365.      endif    ; ztype=3
  366.  
  367. ;
  368.  
  369. ;======================================================================
  370. ;
  371. signon:    call    eprint
  372.     defb    CR,LF,'[CLOCK vers '
  373.     defb    vers/10+'0','.',vers mod 10+'0'
  374. ;
  375.     db    ' - Type '
  376.     db    ztype+30h
  377.     defb    ' at ',0
  378.     ld    hl,entry    ; Get load address
  379.     call    phl4hc        ; Display it
  380.     call    eprint
  381.     db    'h]'
  382. ;
  383.     defb    CR,LF,LF
  384.     defb    'Clock Help:',CR,LF,LF
  385.     defb    ' CLOCK                     --  Display the date and time'
  386.     defb    CR,LF,0
  387.     ld    a,(updflg)
  388.     or    a        ; print setting help if updating allowed
  389.     jr    nz,signo0
  390.     ld    a,(wrtflg)
  391.     or    a        ; don't print setting help if disabled
  392.     jp    z,signo1
  393. signo0:    call    eprint
  394.     defb    ' CLOCK 10/SEP/92 13:20     --  Set the date and time',CR,LF
  395.     defb    ' CLOCK 10-SEP-92           --  Set the date only',CR,LF
  396.     defb    ' CLOCK 13:20[:33]          --  Set the hour and minute['
  397.     defb    'and seconds NOW!]',CR,LF,0
  398. signo1:    call    eprint
  399.     defb    ' CLOCK C                   --  Continuously display time'
  400.     defb    ' - hit any key to quit',CR,LF
  401.     defb    ' CLOCK M                   --  Toggle Military/Civilian' 
  402.     defb    ' time',CR,LF
  403.     defb    ' CLOCK Q                   --  Read and update clock '
  404.     defb    'quietly',CR,LF,0
  405.     ld    a,(z33flg)
  406.     or    a
  407.     jp    z,sign0
  408.     call    eprint
  409.     defb    ' CLOCK S                   --  Store current time in Z3'
  410.     defb    ' registers',CR,LF
  411.     defb    ' CLOCK E                   --  Display elapsed time since'
  412.     defb    ' option S',CR,LF,0
  413. sign0:    ld    a,(updflg)
  414.     or    a
  415.     jr    z,signa
  416.     call    eprint
  417.     defb    ' CLOCK U                   --  Update clock using calculated'
  418.     defb    ' correction factor',CR,LF,0
  419. signa:    ld    a,(line25)
  420.     or    a
  421.     jr    z,sign1
  422.     call    eprint
  423.     defb    ' CLOCK D                   --  Disable(clear) the 25th line'
  424.     defb    ' on the H19 terminal',CR,LF,0
  425. sign1:    call    eprint
  426.     defb    ' CLOCK ? or /              --  Display the clock registers '
  427.     defb    'and HELP text',CR,LF,LF
  428.  
  429.     defb    'The Daylight Savings Time option is ',0
  430.     ld    a,(DSTflg)
  431.     or    a
  432.     jr    z,sign2
  433.     call    eprint
  434.     defb    'ON.',CR,LF,LF,0
  435.     jr    sign3
  436. sign2:    call    eprint
  437.     defb    'OFF.',CR,LF,LF,0
  438.  
  439. sign3:    ld    a,(corrupt)    ; Flag byte corrupt?
  440.     or    a
  441.     ret    z
  442.     call    eprint        ;
  443.     defb    1,'The clock is not',2,' properly programmed. '
  444.     defb    'Set the Date/Time Again!',CR,LF,LF,bell,0
  445.     ret
  446. ;
  447.  
  448. start:    ld    (stack),sp    ; save old stack pointer
  449.     ld    sp,stack    ; set up new one
  450.  
  451. ; Initialize data areas 
  452.  
  453.     xor    a
  454.     ld    hl,zero_it    ; start initialization here
  455.     ld    b,end_it - zero_it + 1    ; bytes to fill
  456.     call    fillb        ; fill with zero
  457.  
  458.     ld    hl,(envptr)    ; point to the Z3 ENV
  459.     push    hl        ; save it
  460.     inc    hl        ; move over 3 bytes
  461.     inc    hl
  462.     inc    hl
  463.     ld    a,(hl)        ; we should find a Z here
  464.     pop    hl        ; get envptr back
  465.     cp    'Z'
  466.     jr    nz,star0    ; not ZCPR3
  467.     ld    a,0ffh        ;
  468.     ld    (z33flg),a    ; save the yes z33
  469.     call    z3vinit        ; initialize z3 and vlib extended TCAP
  470. ;
  471.  
  472. star0:    call    putud        ; save current du: 
  473.     call    readclk        ; read the clock
  474. ;
  475.      call    z,BCDchk    ; if no error, verify if readings legal
  476. ;
  477.     ld    a,0        ; Clear all flags in flgbyte
  478.     jr    z,star1        ;  jump if all BCD values within bound
  479.     ld    a,0ffh
  480.     ld    (errflg),a    ; read or BCD value error
  481.     xor    a
  482. ;
  483.     set    7,a        ; set flgbyte to illegal reading of BCD values
  484.  
  485. star1:    ld    (flgbyte),a    ; save for later use
  486.  
  487.  
  488.  
  489.     ld    a,(tbuff)    ; A = <COMTAIL character count>
  490.     or    a
  491.     jr    nz,star2    ;
  492.     call    PrtDate        ; if none, just print the time/date
  493.     jp    exit        ;  and quit
  494. ;
  495. star2:    ld    (CmTail),A    ; Save COMTAIL character count
  496.     ld    hl,tbuff+1    ; Point to 1st character of COMTAIL
  497.     ld    (CMTptr),hl    ; Store pointer
  498.  
  499.     ld    a,(flgbyte)
  500.     ld    c,a        ; C = <Flag byte>
  501.  
  502.      call    eatspc        ; Jump a 'space' in COMTAIL
  503.                 ;  (If not a ' ' or if an illegal char,
  504.                 ;   return to CCP)
  505. ;
  506.     ld    hl,(CMTptr)    ; HL =.<Command Tail char.>
  507.  
  508.     ld    a,(z33flg)    ; running under ZCPR
  509.     or    a
  510.     jr    z,star3        ; NO!
  511.     ld    a,'S'
  512.     cp    (hl)        ; Store time option?
  513.     jp    z,stortim    
  514.     ld    a,'E'
  515.     cp    (hl)        ; Elapsed time option?
  516.     jp    z,elapse
  517.  
  518. star3:    ld    a,(hl)        ; 
  519.     call    caps        ; Convert any lower case to upper case
  520.     cp    '?'
  521.     jp    z,ClkHlp    ;  if so, print registers plus help message
  522.     cp    '/'        ; Z3 help request
  523.     jp    z,ClkHlp    
  524.  
  525.     cp    'U'        ; Update the clock time using 
  526.     jp    z,update    ;  stored know time values
  527.     cp    'Q'        ; Quiet command?
  528.     jp    z,exit        ; Clock was read on entry so exit silently
  529.     cp    'D'        ; Disable 25th line?
  530.     jr    nz,star4
  531.     ld    a,(line25)    ; be sure 25th line is enabled
  532.     or    a        ;
  533.     jp    z,exit        ; No
  534.     ld    hl,disabl    ; Point to the string
  535.     call    epstr        ; send it
  536.  
  537.     jp    exit
  538.  
  539. star4:    cp    'M'        ; Military/Civilian toggle
  540.     jr    nz,PrCT        ;
  541.     ld    a,(civflg)    ; get the current setting
  542.     or    a        ;
  543.     jr    z,makeCv    ; if 0 then Military go make it Civilian
  544.     xor    a        ;  was Civilian so make Military
  545.     ld    (civflg),a    ; 
  546.     call    PrtDate        ; go print the date/time
  547.     jp    exit        ;
  548. makeCv:    ld    a,0ffh        ;
  549.     ld    (civflg),a    ; make it civilian time
  550.     call    PrtDate        ;  go print the date/time
  551.     jp    exit        ;
  552.  
  553. PrCT:    cp    'C'        ; Continuous time display option
  554.     jr    nz,ParCT1    ; No
  555.     ld    a,0ffh        ;
  556.     ld    (cont),a    ; Store continous flag
  557.  
  558.     ld    a,(z33flg)    ; is Z33
  559.     or    a
  560.     jr    z,PrCTa        
  561.     call    curoff        ; turn cursor off if Z3 with extended TCAP
  562.  
  563. PrCTa:    ld    a,(line25)    ;
  564.     jr    z,PrCT1        ;
  565.     ld    hl,cursav    ; save current cursor position
  566.     call    epstr        ;
  567.  
  568. PrCT1:    call    PrtDate        
  569. contin:    call    readclk    
  570.     call    PrtDt1    
  571.     call    condin        ; Any key from the keyboard?
  572.     jr    z,contin    ; No then continue updating time
  573.  
  574.     ld    a,(z33flg)
  575.     or    a
  576.     jr    z,cont1
  577.     call    curon        
  578.  
  579. cont1:    ld    a,(line25)    
  580.     or    a        
  581.     jp    z,exit        
  582.     ld    hl,curret    ; return to saved cursor position 
  583.     call    epstr         
  584.     jp    exit        
  585.  
  586. ;
  587. ParCT1:    ld    hl,yr        ; point to program year storage
  588.     ld    de,tyr        ; move for use in updating
  589.     ld    bc,8        ; all 8 bytes
  590.     ldir            ; move 'em 
  591.  
  592.     call    CTLDig        ; Get a digit from COMTAIL
  593.                 ;  (If not a decimal digit or if an
  594.                 ;   illegal char, return to CCP)
  595. ;
  596.     ld    d,a        ; D = <Digit from COMTAIL (MS)>
  597.      call    CTLCha        ; Get next character from COMTAIL
  598.                 ;  (If illegal, return to CCP)
  599.     bit    6,c        ; Was it a decimal digit?
  600.     jr    nz,ParCT2    ;  if so, process it
  601. ;
  602.     ld    e,d        ;  if not, move MS to LS
  603.     ld    d,0        ;   position and clear MS
  604.     jr    ParCT3        ;   (Single digit Day of Month)
  605. ;
  606. ParCT2:    ld    e,a        ; E = <Digit from COMTAIL (MS)>
  607.      call    CTLCha        ; Get next character from COMTAIL
  608.                 ;  (If illegal, return to CCP)
  609. ;
  610. ParCT3:    bit    3,c        ; Was it a '-' or '/'?
  611.     jr    nz,ParDat    ;  if so, process DE (Day of Month)
  612. ;
  613.     bit    7,c        ; Illegal readings or none?
  614.     jp    nz,ClkHlp    ;  if so, clock broken or not set
  615.                 ;  (Return to CCP)
  616.     bit    2,c        ; Was it a ':'?
  617.     jp    z,SyntErr    ;  if not, syntax error
  618.                 ;  (Return to CCP)
  619.     jp    StoHM        ; Process a ':'
  620. ;
  621. ; Store day of month as a BCD.
  622.  
  623. ParDat:    ld    hl,da
  624.      call    DIGtoBCD    ; Convert DE into BCD and save at (HL)
  625. ;
  626. ; Identify the Month # (return it in B).
  627.  
  628.      call    cpyCTL        ; Copy alpha chars from COMTAIL
  629.                 ;  to Dbuf (Return on separator)
  630.                 ;  (If illegal char, return to CCP)
  631. ;
  632.     bit    3,c        ; Was it a '-' or '/'?
  633.     jp    z,SyntErr    ;  if not, syntax error
  634.                 ;  (Return to CCP)
  635.     ld    b,1
  636.     ld    de,Dbuf        ; DE =.<Scratchpad base>
  637.     ld    hl,montbl    ; HL =.<1st month table entry>
  638.  
  639. ParDT0:     ld    a,(de)        ; get a letter
  640.     cp    (hl)        ; does it match?
  641.     jr    z,ParDT1    ; yes
  642.     xor    00100000b    ; reverse case of letter in A
  643.     cp    (hl)        ; does it match now?
  644. ;
  645.     jr    nz,ParDT2    ;  if no match
  646. ;
  647. ParDT1:    inc    de        ; Bump pointers
  648.     inc    hl        ;      "
  649.     ld    a,(de)
  650.     or    a        ; End of string?
  651.     jr    z,ParDT3    ;  if so, found match
  652. ;
  653.     jr    ParDT0        ; Check next character...
  654. ;
  655. ParDT2:    inc    b        ; Try next 'montbl' entry
  656.     ld    a,13
  657.     cp    b        ; > 12 ?
  658.     jp    z,SyntErr    ;  if so, syntax error (overflow)
  659.                 ;  (Return to CCP)
  660.     push    bc        ; Save register
  661.  
  662.     ld    bc,20
  663.     xor    a
  664.     cpir            ; HL =.<terminating 0> + 1
  665.  
  666.     pop    bc        ; Restore register
  667.  
  668.     ld    de,Dbuf        ; DE =.<Scratchpad base>
  669.     jr    ParDT0        ; Compare strings...
  670. ;
  671. ParDT3:    ld    d,0        ; Assume single digit month
  672.     ld    a,b        ; A = <Month #> (binary)
  673.     cp    10
  674.     jr    c,StoMo        ;  if A < 10
  675. ;
  676.     ld    d,1        ; Two digit month
  677.     sub    10        ; A = <unit digit>
  678.  
  679. StoMo:    ld    e,a        ; DE = <2-digit month #>
  680. ; Store month as a BCD.
  681.  
  682.     ld    hl,mo
  683.      call    DIGtoBCD    ; Convert DE into BCD and save at (HL)
  684. ;
  685.      call    CTLDig        ; Get a digit from COMTAIL
  686.                 ;  (If not a decimal digit or if an
  687.                 ;   illegal char, return to CCP)
  688. ;
  689.     ld    d,a        ; D = <MS year digit>
  690.      call    CTLDig        ; Get a digit from COMTAIL
  691.                 ;  (If not a decimal digit or if an
  692.                 ;   illegal char, return to CCP)
  693. ;
  694.     ld    e,a        ; E = <LS year digit>
  695.  
  696.  
  697. ; Store year as a BCD.
  698.  
  699.     ld    hl,yr
  700.      call    DIGtoBCD    ; Convert DE into BCD and save at (HL)
  701. ;
  702.     ld    a,(mo)
  703.     cp    10h        ; 2-digit month?
  704.     jr    c,StorDa    ;  if not
  705. ;
  706.     sub    6        ; Convert 2-digit BCD to binary value
  707.  
  708. StorDa:    ld    hl,lentbl-1    ; HL =.<month length table - 1>
  709.     add    a,l
  710.     ld    l,a
  711.     jr    nc,StorD1    ;  if not crossing page boundary
  712. ;
  713.     inc    h        ; Next page
  714.  
  715. ; HL =.<Month length>
  716. StorD1:    ld    a,(da)
  717.     cp    (HL)        ; Day of month legal?
  718.     jr    c,CalDOW    ;  accept
  719. ;
  720.     jr    z,CalDOW    ;  accept
  721. ;
  722.     cp    29h        ; Could it be a 29th?
  723.     jp    nz,DtErr    ;  if not, diagnostic and return
  724.                 ;       (to CCP)
  725.  
  726.     ld    hl,yr
  727.     ld    A,(hl)        ; A = <Year (BCD)>
  728.     and    11110000B    ; A = <Year's MS-digit>
  729.     rrca            ; Move to LS-nibble
  730.     rrca
  731.     rrca
  732.     rrca
  733.     inc    a        ; Add 1, in case A = 0, and
  734.     ld    b,a        ;  save in B
  735.  
  736.     ld    a,(hl)        ; A = <Year (BCD)>
  737.     and    00001111B    ; A = <Year's LS-digit>
  738.  
  739. LpYrCk:    add    a,10
  740.     djnz    LpYrCk
  741. ;
  742.     sub    10        ; Adjust for extra 10
  743.                 ; A = <Year (binary)>
  744.     and    00000011B    ; Multiple of 4 ?
  745.     jp    nz,DtErr    ;  if not leap year, display
  746.                 ;   diagnostic and return
  747.                 ;       (to CCP)
  748. CalDOW:    ld    a,c
  749.     ld    (flgbyte),a    ; Save C
  750.  
  751.     ld    a,(mo)
  752.      call    bc2bi        ; Convert BCD to binary
  753. ;
  754.     ld    e,a        ;  and save in E
  755.     dec    a
  756.     sla    a        ; A = <Offset in 'DOYtbl'>
  757.  
  758.     ld    hl,DOYtbl    ; HL =.<Day of year (for month) table>
  759.                 ;      (Word format)
  760.     add    a,l
  761.     ld    l,a
  762.     jr    nc,ClDOW0    ;  if not crossing page boundary
  763. ;
  764.     inc    h        ; Next page
  765.  
  766. ; HL =.<Day of year for month (in table)>
  767. ClDOW0:    ld    c,(hl)        ; C = <LS-byte, day of year (for month)>
  768.     inc    hl
  769.     ld    b,(hl)        ; B = <MS-byte, day of year (for month)>
  770.     push    bc        ; Save register
  771.  
  772.     ld    a,(da)
  773.      call    bc2bi        ; Convert BCD to binary
  774. ;
  775.     ld    c,a        ;  and save in C
  776.     ld    a,(yr)
  777.      call    bc2bi        ; Convert BCD to binary
  778. ;
  779.     ld    d,a        ;  and save in D
  780.     and    00000011B    ; Multiple of 4 ?
  781.     jr    nz,ClDOW1    ;  if not a leap year
  782. ;
  783.     ld    a,e        ; A = month (binary)
  784.     cp    3        ; March to December ?
  785.     jr    nc,ClDOW2    ;  if so, do not decrement
  786. ;
  787. ClDOW1:    dec    c        ; DOM, Jan-Feb, in leap years
  788.  
  789. ClDOW2:    pop    hl        ; HL = <Day of year for month>
  790.     ld    a,l
  791.     add    a,c        ; Add day of month
  792.     ld    l,a
  793.     jr    nc,ClDOW3    ;  if not crossing page boundary
  794. ;
  795.     inc    h        ; Next page
  796.  
  797. ; HL = <Day of year for date>
  798. ClDOW3:    ld    a,d        ; D = <Year (binary)>
  799.     cp    84
  800.     jr    nc,ClDOW4    ;  if '84 or later
  801. ;
  802.     add    a,100        ; If not, add a century
  803.     ld    d,a        ;  and save. (D =< 84)
  804.  
  805. ClDOW4:    ld    a,84        ; A = <Pivot year>
  806.                 ;     (Starting on Sunday)
  807.  
  808. ; Compute number of days between date and pivot year.
  809. ; (Accumulate in HL)
  810.  
  811. ClDOW5:    cp    d
  812.     jr    z,ClDOW7
  813. ;
  814.     ld    bc,365        ; bc = <year lenght>
  815.     ld    e,a        ; Save A
  816.     and    00000011B    ; Multiple of 4 ?
  817.     jr    nz,ClDOW6    ;  if not a leap year
  818. ;
  819.     inc    bc        ; If it is, add a day
  820.  
  821. ClDOW6:    add    hl,bc        ; Accumulate days
  822.     ld    a,e        ; Retrieve year, and
  823.     inc    a        ;  prepare to add next one
  824.     jr    ClDOW5
  825. ;
  826. ClDOW7:    ld    bc,1
  827.     add    hl,bc        ; = <inc  HL>
  828.     ld    bc,7        ; bc = <1 week>
  829.  
  830. ClDOW8:    ld    a,h
  831.     or    a
  832.     jr    nz,ClDOW9
  833. ;
  834.     ld    a,l
  835.     cp    8
  836.     jr    c,StrDOW    ;  if less than 1 week
  837. ;
  838. ClDOW9:    sbc    hl,bc        ; Subtract 1 week
  839.     jr    ClDOW8        ; Loop ...
  840. ;
  841. ; Store day of week (binary = BCD).
  842.  
  843. StrDOW:    ld    hl,dw
  844.     ld    (hl),a        ; Store day of week
  845.  
  846.     ld    a,(CmTail)    ; A = <COMTAIL character count >
  847.     or    a        ;
  848.     jr    nz,ParTim    ; more to come to jump
  849.                 ;
  850.  
  851. ; Only wants to set the date
  852.     ld    a,(updflg)
  853.     or    a
  854.     jr    z,StrDW
  855.     call    eprint
  856.     defb    cr,lf
  857.     defb    'MUST enter TIME to update file! (DATE optional)',cr,lf,0
  858.     jp    exit
  859.  
  860. StrDW:    ld    a,0ffh
  861.     ld    (dtonly),a    ; we only want to set the date
  862.     jr    SetClk        ; go write it
  863.  
  864.  
  865.  
  866. ParTim:     call    eatspc        ; Jump a 'space' in COMTAIL
  867.                 ;  (If not a ' ' or if an illegal char,
  868.                 ;   return to CCP)
  869. ;
  870.  
  871.     ld    a,(flgbyte)
  872.     ld    c,a        ; C = <flgbyte>
  873.  
  874.      call    CTLDig        ; Get a digit from COMTAIL
  875.                 ;  (If not a decimal digit or if an
  876.                 ;   illegal char, return to CCP)
  877. ;
  878.     ld    d,a
  879.      call    CTLCha        ; Get next character from COMTAIL
  880.                 ;  (If illegal, return to CCP)
  881. ;
  882.     bit    6,c        ; Is it (another) digit?
  883.     jr    nz,PaTm1    ;  if so, process it
  884. ;
  885.     ld    e,d        ;  if not, move MS to LS
  886.     ld    d,0        ;   position and clear MS
  887.     jr    ColChk        ;   (Single digit Hour)
  888. ;
  889. PaTm1:    ld    e,a
  890.      call    CTLCha        ; Get next character from COMTAIL
  891.                 ;  (If illegal, return to CCP)
  892. ;
  893. ColChk:    bit    2,c        ; Is it a ':'?
  894.     jp    z,SyntErr    ;  if not, syntax error
  895.                 ;  (Return to CCP)
  896. ; Store hour as a BCD.
  897.  
  898. StoHM:    ld    hl,hr
  899.      call    DIGtoBCD    ; Convert DE into BCD and save at (HL)
  900. ;
  901.      call    CTLDig        ; Get a digit from COMTAIL
  902.                 ;  (If not a decimal digit or if an
  903.                 ;   illegal char, return to CCP)
  904. ;
  905.     ld    d,a
  906.      call    CTLDig        ; Get a digit from COMTAIL
  907.                 ;  (If not a decimal digit or if an
  908.                 ;   illegal char, return to CCP)
  909. ;
  910.     ld    e,a
  911. ;
  912. ; Store minutes as a BCD.
  913.  
  914.     ld    hl,mi
  915.      call    DIGtoBCD    ; Convert DE into BCD and save at (HL)
  916. ;
  917.      call    CTLNxt        ; Get next character from COMTAIL,
  918.                 ;  if some remain
  919.                 ;  (on illegal char., return to CCP)
  920.     jr    nz,StHM1    ;  if COMTAIL empty
  921. ;
  922.     bit    4,c        ; Is it a ' '?
  923.     jr    nz,StHM1    ;  if so, gobble it
  924. ;
  925.     bit    2,c        ; Is it a ':'?
  926.     jp    z,SyntErr    ;  if not, syntax error
  927.                 ;  (Return to CCP)
  928. ;
  929.      call    CTLDig        ; Get a digit from COMTAIL
  930.                 ;  (If not a decimal digit or if an
  931.                 ;   illegal char, return to CCP)
  932. ;
  933.     ld    d,a
  934.      call    CTLDig        ; Get a digit from COMTAIL
  935.                 ;  (If not a decimal digit or if an
  936.                 ;   illegal char, return to CCP)
  937. ;
  938.     ld    e,a
  939.     jr    StrSEC
  940. ;
  941. StHM1:    ld    de,0
  942. ; Store seconds as a BCD.
  943.  
  944. StrSEC:    ld    hl,se
  945.      call    DIGtoBCD    ; Convert DE into BCD and save at (HL)
  946. ;
  947. DSTtog:     call    CTLNxt        ; Get next character from COMTAIL,
  948.                 ;  if some remain
  949.                 ;  (on illegal char., return to CCP)
  950. ;
  951.     jr    nz,CkVals    ;  if COMTAIL empty
  952. ;
  953.     bit    4,c        ; Is it a ' '?
  954.     jr    nz,DSTtog    ;  if so, gobble it...
  955. ;
  956.     bit    5,c        ; Is it an alpha char.?
  957.     jp    z,SyntErr    ;  if not, syntax error
  958.                 ;  (Return to CCP)
  959. CkVals:    ld    a,c
  960.     ld    (flgbyte),a
  961.      call    BCDchk        ; verify if readings legal
  962. ;
  963.     jp    nz,DtErr    ;  if a value out of bound,
  964.                 ;   diagnostic and return
  965.                 ;   (to CCP)
  966. SetClk:    ld    a,(updflg)
  967.     or    a
  968.     call    nz,filchk    ; can we find this program on disk to update?
  969.  
  970.     call    writclk        ;
  971. ;
  972.     jr    z,StClk1
  973. ;
  974.      call    eprint        ; Display following string on console
  975. ;
  976.     defb    'Unable to Set the Clock',CR,LF,0
  977.  
  978.     jp    ClkHlp        ; Give help message
  979. ;
  980. StClk1:     call    readclk        ; read the clock
  981. ;
  982.     jp    nz,ClkHlp    ;  if Clock read error
  983.                 ;  (Return to CCP)
  984.     xor    a
  985.     ld    (flgbyte),a    ;
  986.     ld    (corrupt),a    ; make sure corrupt flag off
  987.      call    PrtDate        ; Print the time/date
  988. ;
  989.     ld    a,(flgBCD)
  990.     and    00000100B    ; Check DST bit
  991.     jr    z,StClk2    ;  if DST off
  992. ;
  993.      call    eprint        ; Display following string on console
  994. ;
  995.     defb    CR,LF,'Daylight Savings Time '
  996.     defb    'option is enabled.',CR,LF,0
  997.  
  998. ;
  999. StClk2:    ld    a,(se)    ; A = <BCD seconds>
  1000.     or    a
  1001.     jr    nz,StClk4    ;  if set to some value, exit
  1002.                 ;   if not, hold the clock ...
  1003.  
  1004.      call    eprint        ; Display following string on console
  1005. ;
  1006.     defb    CR,LF,'Hit <RETURN> to start clock',0
  1007.  
  1008. ;
  1009. ; Go wait for a <CR>. (Keep zero-ing CLKGO)
  1010.  
  1011. StClk3:    ld    b,21        ; point to CLKGO
  1012.     call    portc        ; 
  1013.     out (c),a        ; 0 -> (CLKGO)
  1014.      call    condin        ; Check console for input
  1015. ;
  1016.     jr    z,StClk3    ;  if no input
  1017. ;
  1018.     cp    CR
  1019.     jr    nz,StClk3    ;  if not a <CR>
  1020. ;
  1021.     ld    b,21        ; point to CLKGO
  1022.     call    portc
  1023.     out    (c),a        ; Load 0Dh -> (CLKGO)
  1024.  
  1025. StClk4:    ld    a,(updflg)    ; is update option allowed?
  1026.     or    a        ;
  1027.     call    nz,mkupdr    ; go make an update record if yes
  1028.  
  1029. exit:    call    getud        ; restore current du:
  1030.     ld    sp,(stack)    ;
  1031.     ret            ; Back to CCP
  1032. ;
  1033.  
  1034. ;
  1035. ;      Subroutine PrtDate - Display date & time.
  1036. ;
  1037. PrtDate: ld    a,(flgbyte)
  1038.     bit    7,a        ; Illegal readings or none?
  1039.     jp    nz,ClkHlp    ;  if so, clock broken or not set
  1040.                 ;  (Return to CCP)
  1041.  
  1042. ; Day of week.
  1043.  
  1044.     ld    a,(line25)    ; H19 and 25th line desired?
  1045.     or    a
  1046.     jr    z,noline25
  1047.     ld    hl,cursav    ; save current cursor position
  1048.     call    epstr
  1049.     ld    hl,enable    ; turn on 25th line
  1050.     call    epstr
  1051.     jr    PrtDt1
  1052.  
  1053. noline25:
  1054.     call    eprint        ;
  1055.     defb    lf,0        ;
  1056.  
  1057. PrtDt1:                ; Entry 2nd+ pass of continuous time
  1058.  
  1059.     ld    a,(line25)    ; H19 with line 25 desired?
  1060.     or    a
  1061.     jr    z,PrtDta
  1062.     call    at        ; get to line 25, column 40
  1063.     defb    25,40
  1064.     jr    PrtDtb
  1065.  
  1066. PrtDta:    call    eprint
  1067.     defb    cr,' ',0    ;
  1068.  
  1069. PrtDtb:    ld    de,yr    ; point to the year
  1070.     call    pday1        ; print DOW
  1071.     call    space
  1072.     call    space
  1073.     call    pdat1        ; print the date
  1074.     inc    de        ; skip da
  1075.     call    space
  1076.     call    space
  1077. ;
  1078.     ld    a,(civflg)    ; Get the Civilian time flag
  1079.     or    a        ; Is it Military time?
  1080.     jr    z,PrtDt2    ; Yes, not Civilian time!
  1081.     call    ptim1        ; print time in 12 hour version
  1082.     ld    a,'m'        ; add the m to p or a
  1083.     call    cout
  1084.     jr    PrtDt3        ; 
  1085.  
  1086. PrtDt2:    call    ptim3        ; print 24 hour format
  1087.     call    space
  1088. PrtDt3:    ld    a,(corrupt)    ; get corrupt flag byte flag
  1089.     or    a
  1090.     jr    z,Timend    ; Not corrupt
  1091.     ld    a,'*'        ; tell user it is corrupt
  1092.     call    cout
  1093. ;
  1094. Timend:    ld    a,0        ; default value (must not be xor a!)
  1095. cont:    equ    $-1        ;
  1096.     or    a        ;
  1097.     ret    nz        ; We are in continuous update mode 
  1098.     ld    a,(line25)    ; H19 with 25th line wanted?
  1099.     or    a
  1100.     jp    z,crlf        ; No?
  1101.     ld    hl,curret    ; return to saved position
  1102.     jp    epstr
  1103.  
  1104. ;
  1105. ;      Subroutine CTLNxt - Get character from COMTAIL,
  1106. ;                  if some remain.
  1107. ;
  1108. CTLNxt:    ld    a,(CmTail)    ; A = <COMTAIL character count>
  1109.     or    a
  1110.     jr    nz,CTLCha    ;  if more remain, get next
  1111.                 ;   and return via "CTLCha"
  1112.                 ;  (If illegal, do not return to Caller)
  1113. ;
  1114.     dec    a        ; A = 0FFh, Z-flg Reset
  1115.     ret
  1116. ;
  1117. ;
  1118. ;      Subroutine CTLCha - Get a COMTAIL character.
  1119. ;             = "CTLChr" (but adds 1 Call level)
  1120. ;
  1121. CTLCha:     call    CTLChr        ; Get a COMTAIL character
  1122.                 ;  (If illegal, do not return to Caller)
  1123. ;
  1124.     cp    a
  1125.     ret
  1126. ;
  1127. ;
  1128. ;      Subroutine CTLChr - Get a COMTAIL character.
  1129. ;         Inputs:  (CMTptr) =.<Next COMTAIL character>
  1130. ;              (CmTail) = <Remaining COMTAIL char. count>
  1131. ;         Outputs: A = <Next COMTAIL character>
  1132. ;              If COMTAIL character:    Return in C:
  1133. ;                   ':'        x0000100B
  1134. ;                '-' or '/'    x0001000B
  1135. ;                   ' '        x0010000B
  1136. ;                'A .... Z'    x0100000B
  1137. ;                 or 'a .... z'
  1138. ;                '0 .... 9'    x1000000B
  1139. ;              (In all cases bit-7 of C is not altered)
  1140. ;
  1141. ;         Note:    If none of the above (illegal or no character),
  1142. ;              CTLChr does not return to caller but exits via
  1143. ;              SyntErr.
  1144. ;
  1145. CTLChr:    ld    a,c
  1146.     and    10000000B
  1147.     ld    c,a        ; All but MS-bit cleared
  1148.  
  1149.     ld    a,(CmTail)    ; A = <COMTAIL character count>
  1150.     or    a
  1151.     jp    z,SyntErr    ;  if none left
  1152. ;
  1153.     dec    a
  1154.     ld    (CmTail),a    ; Count this one done
  1155.  
  1156.     ld    hl,(CMTptr)    ; HL =.<Command Tail char.>
  1157.     ld    a,(hl)        ; A = <Command Tail char.>
  1158.     inc    hl        ; Bump pointer and
  1159.     ld    (CMTptr),hl    ;  save it
  1160.  
  1161.     set    2,c        ; Assume ':'
  1162.     cp    ':'
  1163.     ret    z        ;  if ':'
  1164. ;
  1165.     res    2,c        ; Not a ':',
  1166.     set    3,c        ;  assume a '-' or '/'
  1167.     cp    '-'
  1168.     ret    z        ;  if '-'
  1169. ;
  1170.     cp    '/'
  1171.     ret    z        ;  if '/'
  1172. ;
  1173.     res    3,c        ; Not a '-' nor '/',
  1174.     set    4,c        ;  assume a ' '
  1175.     cp    ' '
  1176.     ret    z        ;  if ' '
  1177. ;
  1178.     res    4,c        ; Not a ' ',
  1179.     set    6,c        ;  assume a digit
  1180.     cp    '0'
  1181.     jr    c,CTLCh1    ;  if not a decimal digit
  1182. ;
  1183.     cp    ':'
  1184.     ret    c        ;  if a decimal digit
  1185. ;
  1186. CTLCh1:    res    6,c        ; Not a digit,
  1187.     set    5,c        ;  assume an alphabetic char.
  1188.      call    caps        ; Convert A to upper case
  1189. ;
  1190.     cp    'A'
  1191.     jr    c,CTLCh2    ;  if not an alphabetic char.
  1192. ;
  1193.     cp    '['
  1194.     ret    c        ;  if an alphabetic character
  1195. ;
  1196. CTLCh2:    res    5,c        ; Not an alphabetic character
  1197.     jr    SyntErr
  1198. ;
  1199. ;
  1200. ;      Subroutine CTLDig - Get a decimal digit from COMTAIL.
  1201. ;         Outputs A = <digit>, if one found.
  1202. ;             (If COMTAIL char. is no digit, do not return)
  1203. ;
  1204. CTLDig:     call    CTLChr        ; Get a COMTAIL character
  1205.                 ;  (If illegal character, do not
  1206.                 ;   return to Caller)
  1207.     bit    6,c
  1208.     ret    nz        ;  if a decimal digit
  1209. ;
  1210.     jr    SyntErr        ; Do not return to Caller
  1211.  
  1212. ;
  1213. ;      Subroutine eatspc - Accept a 'space' in COMTAIL.
  1214. ;         Outputs - If not a 'space', do not proceed.
  1215. ;
  1216. eatspc:     call    CTLChr        ; Get a COMTAIL character
  1217.                 ;  (If illegal character, do not
  1218.                 ;   return to Caller)
  1219.     bit    4,c
  1220.     ret    nz        ;  if a ' '
  1221. ;
  1222.     jr    SyntErr        ; Do not return to Caller
  1223. ;
  1224. ;
  1225. ;      Subroutine cpyCTL - Copy alpha chars from COMTAIL to buffer.
  1226. ;                  Insert terminating 0 if next character
  1227. ;                  is not alphabetic.
  1228. ;
  1229. cpyCTL:    ld    de,Dbuf        ; DE =.<Scratchpad>
  1230. cpyCT1:     call    CTLCha        ; Get next character from COMTAIL
  1231.                 ;  (If illegal, do not return to Caller)
  1232. ;
  1233.     bit    5,c        ; Alphabetic character?
  1234.     jr    z,cpyCT2    ;  if not
  1235. ;
  1236.     ld    (de),a        ; Insert char. in Scratchpad
  1237.     inc    de        ;  and bump pointer
  1238.     jr    cpyCT1        ; Process next COMTAIL character
  1239. ;
  1240. cpyCT2:    xor    a
  1241.     ld    (de),a        ; Insert terminating 0
  1242.     ret
  1243. ;
  1244.  
  1245. DtErr:     call    eprint        ; Display following string on console
  1246. ;
  1247.     defb    CR,LF,'Incorrect Date or Time entry: ',0
  1248.  
  1249.     jr    FindErr
  1250. ;
  1251. SyntErr: call    eprint        ; Display following string on console
  1252. ;
  1253.     defb    CR,LF,'Date or Time MUST be entered as '
  1254.     defb    'DD-Mon-YY HH:MM only!',CR,LF,0
  1255.  
  1256. ;
  1257. FindErr: ld    hl,(CMTptr)    ; HL =.<Command Tail char.>
  1258.     ld    a,(CmTail)    ; A = <COMTAIL character count>
  1259.     or    a
  1260.     jr    nz,PrtErr    ;  if not the last one
  1261. ;
  1262.     inc    hl
  1263. PrtErr:    xor    a
  1264.     ld    (hl),a        ; Insert terminating 0
  1265.  
  1266.     ld    hl,tbuff+1    ; Point to 1st character of COMTAIL
  1267.      call    epstr        ; Print string HL is pointing at
  1268.  
  1269. ;
  1270. ClkHlp:      call    signon        ; Display signon screen
  1271.  
  1272. ; After printing help then show the clock register values
  1273. ;
  1274.  
  1275.  
  1276. ClkHp1:    call    eprint
  1277.     defb    ' Clock registers: ',CR,LF
  1278.     defb    '   ',0
  1279.  
  1280.     ld    a,(port)    ; get the base port
  1281.     ld    c,a        ; C = <Clock base port>
  1282.     ld    b,16        ; 16 registers to print
  1283.  
  1284. PrtReg:    in    a,(c)
  1285.     call    pa2hc        ; print BCD value in A
  1286.     call    space
  1287.     inc    c        ; next port
  1288.     djnz    PrtReg
  1289. ;
  1290.     ld    b,14        ; make it the FLAGS port
  1291.     call    portc        
  1292. ;
  1293. ChkChr:    in    a,(c)        ; Check charateristics and display
  1294.     and    01H    
  1295.     jr    z,ChkCh1
  1296. ;
  1297.      call    eprint        
  1298.      defb    ' NTL',0    ; Need to leap
  1299. ;
  1300. ChkCh1:    in    a,(c)        ;
  1301.     and    yokflg
  1302.     jr    z,ChkCh2
  1303. ;
  1304.      call    eprint        ;
  1305.      defb    ' YOK',0    ; Year ok bit has been updated
  1306. ;
  1307. ;
  1308. ChkCh2:    in    a,(c)        ;
  1309.     and    flgDST
  1310.     jr    z,ChkCh3
  1311. ;
  1312.      call    eprint        ; We are on DST
  1313.      defb    ' DST',0
  1314. ;
  1315. ChkCh3:    call    crlf        ; Print CR,LF
  1316.  
  1317.     jp    exit
  1318. ;
  1319.  
  1320. ;
  1321. ;      Subroutine BCDchk - Verify if BCD readings are legal.
  1322. ;         Outputs If all readings legal, Z-flg Set,
  1323. ;             If not,            Z-flg Reset
  1324. ;
  1325. BCDchk:    ld    de,BCDmax
  1326.     ld    hl,timBCD
  1327.     ld    b,7
  1328.  
  1329. BCDck1:    ld    a,(de)        ; A = <BCD value>
  1330.     cp    (hl)
  1331.     jr    nc,BCDck2    ;  if within bounds
  1332. ;
  1333.     xor    a        ;  if not,
  1334.     dec    a        ;   clear Z-flg
  1335.     ret
  1336. ;
  1337. BCDck2:    inc    de        ; Look at next slot,
  1338.     inc    hl
  1339.     djnz    BCDck1        ;  if more to go...
  1340. ;
  1341.     xor    a        ; Set Z-flg
  1342.     ret
  1343. ;
  1344. ;
  1345. ;      Subroutine DIGtoBCD - Convert 2 digits into Binary Coded
  1346. ;                Decimal and store at (HL).
  1347. ;         Inputs  DE = <Input digits>
  1348. ;             HL =.<BCD storage buffer>
  1349. ;         Outputs BCD byte stored at (HL)
  1350. ;
  1351. DIGtoBCD: ld    a,e
  1352.     and    0FH        ; Extract lower nibble
  1353.     ld    e,a        ; E = <LS-digit>
  1354.     ld    a,d        ; D contains MS-digit
  1355.     and    0FH        ; Extract lower nibble
  1356.  
  1357.     sla    a        ; Shift to upper nibble
  1358.     sla    a
  1359.     sla    a
  1360.     sla    a
  1361.     or    e        ; Merge-in LS-digit
  1362.     ld    (hl),a        ; Store BCD
  1363.     ret
  1364.  
  1365. ;
  1366. ; routine to read the clock
  1367.  
  1368. readclk:ld    b,14
  1369.     call    portc
  1370.     in    a,(c)        ; get flags
  1371.     ld    e,a        ; save them
  1372.     and    okmask        ; mask the check bits        
  1373.     cp    setflg        ; has the clock been set?
  1374.     jr    z,rdclk        ; okay
  1375.     ld    a,0ffh
  1376.     ld    (corrupt),a    ; flag byte corrupt or clock not set
  1377.  
  1378. rdclk:    ld    d,10        ; 10 times to try the read
  1379.  
  1380. readtry:ld    b,20        ; point to status port
  1381.     call    portc
  1382.     in    a,(c)        ; reset the counter changed bit
  1383.     ld    hl,yr        ; point to the year storage
  1384.     ld    b,9        ; year offset
  1385.     call    portc        ; make it so
  1386.     in    a,(c)        ;
  1387.     ld    (hl),a        ; save it
  1388.     dec    c        ; decrement the port
  1389.     ld    b,7        ; read 7 registers
  1390.     inc    hl        ; point to month storage
  1391.  
  1392. rdloop:    dec    c        ; decrement the port
  1393.     ini            ; get the value
  1394.     jr    nz,rdloop    ; again if not zero
  1395.  
  1396.     ld    b,20        ; point to the clock status
  1397.     call    portc        ;
  1398.     in    a,(c)        ; counter bit different?
  1399.     or    a        ;
  1400.     jr    z,rdok        ; no.
  1401.  
  1402.     dec    d        ;decrement the attempt count
  1403.     jr    nz,readtry    ; try again if necessary
  1404.  
  1405.     xor    a        ;return error
  1406.     dec    a        ;clear the Z flag
  1407.     ret            ;
  1408.  
  1409. rdok:    ld    hl,mo            ; point to the month
  1410.     ld    a,(hl)        ;
  1411.     dec    hl        ; point to the year
  1412.     bit    okbit,e        ; okay?
  1413.     jr    z,fixyr        ; no. check it
  1414.  
  1415. ; The YEAROK bit is set, do we need to clear it?
  1416.  
  1417.     cp    7        ;July or later?
  1418.     jr    c,yearok    ; Nope. So jump.
  1419.     res    okbit,e        ;Make the bit 0
  1420.     jr    yearok        ;
  1421.  
  1422. ; YEAROK bit not set, 'repair' needed?
  1423.  
  1424. fixyr:    cp    7        ;July or later??
  1425.     jr    nc,yearok    ; yes. leave the bit clear
  1426.     ld    a,(hl)        ;get the year back
  1427.     add    a,1        ;increment it
  1428.     daa            ;fixup BCD
  1429.     ld    b,9        ; point to the hour
  1430.     call    portc        ;
  1431.     out    (c),a        ; store the updated year value
  1432.     ld    (hl),a        ;
  1433.     set    okbit,e        ;set the bit
  1434.  
  1435. ; Leap year or before?
  1436.  
  1437. yearok:    ld    a,(hl)        ;get the year
  1438.     and    0f0h        ;get the MSB
  1439.     rrca            ;into
  1440.     rrca            ; the
  1441.     rrca            ;  LSB
  1442.     rrca            ;   
  1443.     inc    a        ;make zero = 1
  1444.     ld    b,a        ;save the MSB
  1445.     ld    a,(hl)        ;get the year back
  1446.     inc    hl        ;HL--> mo
  1447.     and    00fh        ;just the LSB
  1448. ckleap:    add    a,10        ;add 10 for each MSB unit
  1449.     djnz    ckleap        ;and loop
  1450.     sub    a,10        ;correct the count
  1451.     and    3h        ;is it a leap year
  1452.     jr    z,isleap    ; yes. handle it
  1453.     cp    3        ;is it a PRE-Leap Year
  1454.     jr    nz,clrleap    ; no. clear the bit
  1455.  
  1456. ; Before a leap year?
  1457.  
  1458.     ld    a,(hl)        ;get the month
  1459.     cp    3        ;after march?
  1460.     jr    nc,setleap    ; yes. set the flag
  1461.  
  1462. ; turn the Leap year bit off
  1463.  
  1464. clrleap: res    lpbit,e        ;clear the bit
  1465.     jr    leapok
  1466.  
  1467. ; Leap year stuff
  1468.  
  1469. isleap:    ld    a,(hl)        ;get the month code
  1470.     inc    hl        ;HL --> da
  1471.     cp    3        ;is it March yet
  1472.     jr    c,setleap    ; no. just set the bit
  1473.     jr    nz,chkleap    ; (not March) fixup the counters
  1474.     ld    a,(hl)        ;get the date
  1475.     cp    1        ;is it after the first
  1476.     jr    nz,chkleap    ; yes. go fixup the counters
  1477.  
  1478. ; March 1=February 29
  1479.  
  1480.     bit    lpbit,e        ;do we need to lie?
  1481.     jr    z,leapok    ; no. we are done lying
  1482.     ld    a,29h        ;get the 29'th
  1483.     ld    (hl),a        ;store it
  1484.     dec    hl        ;HL --> mo
  1485.     ld    a,2        ;get Februrary
  1486.     ld    (hl),a        ;store it
  1487.     jr    leapok        ;keep the bit set
  1488.  
  1489.  
  1490. ; If Leap Year change the date
  1491.  
  1492. chkleap: bit    lpbit,e        ;do we need to leap?
  1493.     jr    z,leapok    ; no. all done here
  1494.     ld    a,(hl)        ;get the date
  1495.     sub    1        ;backup
  1496.     daa            ;fixup for BCD
  1497.     or    a        ;is this day zero
  1498.     jr    nz,monok    ; no. then the month is ok
  1499.     dec    hl        ;HL --> mo
  1500.     ld    a,(hl)        ;get the month
  1501.     sub    1        ;count it down
  1502.     daa            ;fixit up
  1503.     ld    (hl),a        ;update our copy
  1504.     ld    b,7        ; point to the month
  1505.     call    portc        ;
  1506.     out    (c),a        ; set the month
  1507.     bit    4,a        ; is the month > 10?
  1508.     jr    z,getday    ; no. go get the days
  1509.     sub    6        ; BCD to Binary
  1510. getday:    ld    hl,daytbl-3    ; point to our table (Jan Feb missing)
  1511.     add    a,l        ; compute the offset
  1512.     ld    l,a        ;
  1513.     jr    nc,gotday    ;
  1514.     inc    h        ;
  1515. gotday:    ld    a,(hl)        ; get the number of days in the month
  1516.     ld    hl,da        ; HL--> da
  1517.  
  1518. ; adjust the day
  1519.  
  1520. monok:    ld    (hl),a        ; update our storage
  1521.     ld    b,6        ; point to the day
  1522.     call    portc        ;
  1523.     out    (c),a        ; update the clock
  1524.     jr    clrleap
  1525.  
  1526. setleap: set    lpbit,e        ; set the leap year bit
  1527.  
  1528. ; Leap year stuff done so check out DST
  1529.  
  1530. leapok:    ld    a,(DSTflg)    ; are we enabled?
  1531.     or    a        ;
  1532.     
  1533.     jp    z,DSTdone    ; no so all done
  1534.  
  1535.     ld    hl,mo        ; HL --> Month
  1536.     ld    a,(hl)        ; get the month
  1537.     inc    hl        ; HL --> da
  1538.     cp    4        ; before April
  1539.     jr    c,notDST    ;  yes, not DST then
  1540.     jr    z,DSTapr    ;  handle April
  1541.     cp    10h        ; before October?
  1542.     jr    c,isDST        ;  yes, still DST
  1543.     jr    z,DSToct    ;  go handle October
  1544.     jr    notDST        ; after October no longer DST
  1545.  
  1546. ; April DST stuff
  1547.  
  1548. ; DST starts the first Sunday in April
  1549.  
  1550. DSTapr:    ld    a,(hl)        ;get the day
  1551.     cp    7        ;DST starts April 7 or sooner
  1552.     inc    hl        ;HL --> dw
  1553.     jr    z,ChkSun    ;Today is April 7, is it Sunday?
  1554.     jr    nc,isDST    ;Must be DST as later than April 7
  1555. ; it is April 6 or sooner
  1556.     sub    (hl)        ;Subtract DOW value from Date
  1557.     jp    m,notDST    ;DOW larger than date so Sunday
  1558.                 ;  hasn't happened yet
  1559. ; Today must be 1st Sunday of April or later
  1560.  
  1561. ChkSun:    ld    a,(hl)        ;is Today Sunday?
  1562.     dec    a        ;
  1563.     jr    nz,isDST    ; no. then it's DST now
  1564.  
  1565.     inc    hl        ;HL --> hr
  1566.     ld    a,(hl)        ;after 2 am
  1567.     cp    2        ;
  1568.     jr    c,notDST    ; no. still not DST
  1569.     jr    isDST        ;yes. it's DST now
  1570.  
  1571. ; October DST stuff
  1572.  
  1573. DSToct:    ld    a,(hl)        ;get the day
  1574.     add    a,8        ;compute date of next sunday
  1575.     daa
  1576.     inc    hl        ;HL --> dw
  1577.     sub    (hl)        ;
  1578.     daa
  1579.     cp    32h        ;will it occur in October?
  1580.     jr    c,isDST        ; Yes. it's still DST
  1581.     ld    a,(hl)        ;is Today Sunday?
  1582.     dec    a        ;
  1583.     jr    nz,notDST    ; no. then it's not DST
  1584.  
  1585.     inc    hl        ;HL --> hr
  1586.     ld    a,(hl)        ;after 2 am
  1587.     cp    2        ;
  1588.     jr    c,isDST        ; no. it's still DST
  1589.     cp    3        ;before 3 am
  1590.     jr    c,dstdone    ; yes. don't change it yet
  1591.     jr    notDST        ;yes. it's not DST
  1592.  
  1593. ; DST?
  1594.  
  1595. isdst:    bit    DSTbit,e    ;have we already done DST?
  1596.     jr    nz,DSTdone    ; yes. Don't do again.
  1597.  
  1598. ; Add one hour to the time
  1599.  
  1600.     ld    b,1        ; point the the TENTHS
  1601.     call    portc
  1602.     in    a,(c)        ; are we in danger of changing times?
  1603.     cp    99h        ;
  1604.     jp    z,readclk    ; YES. start over
  1605.     ld    b,4        ; point to hours
  1606.     call    portc        ;
  1607.     in    a,(c)        ; we can not do this at 23:00
  1608.     cp    23h        ; as we would have to adjust
  1609.     jr    z,DSTdone    ; the day/month/year also!
  1610.     ld    hl,hr        ; point to the hour
  1611.     ld    a,(hl)        ; get it
  1612.     add    a,1        ; advance one hour
  1613.     jr    DSTfinis    ; finish up
  1614.  
  1615. ; Not DST
  1616.  
  1617. notDST:    bit    DSTbit,e    ;have we already cleared DST?
  1618.     jr    z,DSTdone    ; yes. good for us
  1619.  
  1620. ; Should be one hour earlier!
  1621.     ld    b,1        ; point to sec - 1
  1622.     call    portc
  1623.     
  1624.     cp    99h        ;
  1625.     jp    z,readclk    ; yes. Begin again.
  1626.  
  1627.     ld    b,4        ; point to hours
  1628.     call    portc        ;
  1629.     in    a,(c)        ; Can't do at midnight
  1630.     or    a        ; as we'd have to change
  1631.     jr    z,DSTdone    ; the day/month/year also!
  1632.  
  1633.     ld    hl,hr        ;
  1634.     ld    a,(hl)        ;get the hour
  1635.     sub    a,1        ;backup one
  1636.  
  1637. dstfinis: daa            ;convert to BCD
  1638. ;    ld    b,4        ; point to the hour
  1639. ;    call    portc        ;
  1640.     out    (c),a        ; send to the clock
  1641.     ld    (hl),a        ;send to this program also
  1642.     ld    a,e        ;set the DST flag
  1643.     xor    flgDST        ;
  1644.     ld    e,a        ;update our flag
  1645.  
  1646. DSTdone: ld    a,e        ;get our flags
  1647.     ld    (flgBCD),a    ;update the RAM
  1648.     ld    b,14        ; point to FLAGS
  1649.     call    portc        ;
  1650.     out    (c),a        ;and the clock
  1651.     xor    a        ; say we did it
  1652.     ret
  1653.  
  1654. ; routine to write the clock
  1655.  
  1656. writclk:ld    a,(updflg)
  1657.     or    a
  1658.     jr    nz,writck1    ; write allowed with updating
  1659.  
  1660.     ld    a,(wrtflg)
  1661.     or    a
  1662.     jr    nz,writck1    ; no updating but clock write okay
  1663.  
  1664.     call    eprint
  1665.     db    cr,lf
  1666.     db    'You may NOT set the clock with this ',
  1667.     db    'copy of the program!',cr,lf
  1668.     db    'Use your ',27h,'updating',27h,' copy for this.',bell,0
  1669.     jp    exit
  1670.  
  1671. writck1:xor    a
  1672.     or    setflg+yokflg    ; set some flag bits
  1673.     ld    e,a        ; save the flags
  1674.  
  1675.     ld    a,(mo)    ; get the month
  1676.     cp    7        ; is it after june
  1677.     jr    c,wr01        ;  no.
  1678.     res    okbit,e        ; Yes. clear the yearok bit
  1679.  
  1680. wr01:    ld    hl,yr    ;HL --> yr
  1681.     ld    a,(hl)
  1682.     inc    hl        ;HL --> mo
  1683.  
  1684. ; See if Leap Year or before a leap year
  1685.  
  1686.     ld    c,a        ;save the year in C
  1687.     and    0f0h        ;get the MSB
  1688.     rrca            ;into
  1689.     rrca            ; the
  1690.     rrca            ;  LSB
  1691.     rrca            ;   
  1692.     inc    a        ;make zero = 1
  1693.     ld    b,a        ;save it away
  1694.     ld    a,c        ;get the year back
  1695.     and    00fh        ;get the LSB
  1696. ck_leap: add    a,10        ;add 10 years
  1697.     djnz    ck_leap        ;loop
  1698.     sub    a,10        ;get the correct value
  1699.     and    3h        ;is this a leap year
  1700.     jr    z,leapyr    ; yes.
  1701.     cp    3        ;is it a preleap
  1702.     jr    nz,cl_leap    ; no. clear the bit
  1703.  
  1704.     ld    a,(hl)        ;get the month
  1705.     cp    3        ;after march?
  1706.     jr    nc,set_leap    ; yes. set the flag
  1707.  
  1708. ; turn the Leap year bit off
  1709.  
  1710. cl_leap: ld    a,e        ;get our flags
  1711.     and    0ffh-lpflg    ;clear the bit
  1712.     jr    do_leap
  1713.  
  1714. ; Make February 29 be March 1
  1715.  
  1716. dofeb29: ld    a,1        ;get the 1'st
  1717.     ld    (hl),a        ;store it
  1718.     dec    hl        ;HL --> mo
  1719.     ld    a,3        ;get March
  1720.     ld    (hl),a        ;store it
  1721.     jr    set_leap    ;and set the flag
  1722.  
  1723. ; Leap Year Routines
  1724.  
  1725. leapyr: ld    a,(hl)        ;get the month code
  1726.     inc    hl        ;HL --> da
  1727.     cp    2        ;is it February?
  1728.     jr    nz,notfeb    ; no.
  1729.     ld    a,(hl)        ;get the day
  1730.     cp    29h        ;is it the 29'th?
  1731.     jr    z,dofeb29    ; yes. fixup our counters
  1732.     dec    hl        ;get the month back
  1733.     ld    a,(hl)        ;
  1734.     inc    hl
  1735.  
  1736. notfeb:    cp    3        ;is it March yet
  1737.     jr    nc,cl_leap    ; yes. clear the bit
  1738.                 ;Otherwise set the bit
  1739.  
  1740. ; Assure leap year bit is on
  1741.  
  1742. set_leap: ld    a,e        ;get our flags
  1743.        or    lpflg        ;set the bit
  1744.  
  1745. do_leap: ld    e,a        ;update our internal copy
  1746.  
  1747. ; Daylight Savings Time Routines
  1748.  
  1749.     ld    a,(DSTflg)    ; DST enabled?
  1750.     or    a        ;  
  1751.     jr    z,wrtclk    ; No. all done
  1752.  
  1753.     ld    hl,mo        ;HL --> Month
  1754.     ld    a,(hl)        ;get the month
  1755.     inc    hl        ;HL --> da
  1756.     cp    4        ;before April
  1757.     jr    c,wrtclk    ; yes, not DST then
  1758.     jr    z,DST_apr    ; handle April
  1759.     cp    10h        ;before October
  1760.     jr    c,is_DST    ; yes. still DST
  1761.     jr    z,DST_oct    ; handle October
  1762.     jr    wrtclk        ;after October no longer DST
  1763.  
  1764. ; April DST routines
  1765.  
  1766. ; DST starts the first Sunday in April
  1767.  
  1768. DST_apr:ld    a,(hl)        ;get the day
  1769.     cp    7        ;DST start April 7 or sooner
  1770.     inc    hl        ;HL --> dw
  1771.     jr    z,Chk_Sun    ;Today is April 7, is it Sunday?
  1772.     jr    nc,is_DST    ;must be DST as later than April 7
  1773.  
  1774. ; it is April 6 or sooner
  1775.  
  1776.     sub    (hl)        ;Subtract DOW value from Date
  1777.     jp    m,wrtclk    ;DOW larger than date so Sunday
  1778.                 ;  hasn't happened yet
  1779. ; Today must be 1st Sunday of April or later
  1780.  
  1781. Chk_Sun:ld    a,(hl)        ;is Today Sunday?
  1782.     dec    a        ;
  1783.     jr    nz,is_DST    ; no. then it's DST now
  1784.  
  1785.     inc    hl        ;HL --> hr
  1786.     ld    a,(hl)        ;after 2 am
  1787.     cp    2        ;
  1788.     jr    c,wrtclk    ; no. still not DST
  1789.     jr    is_DST        ;yes. it's DST now
  1790.  
  1791. ; October DST routines
  1792.  
  1793. DST_oct: ld    a,(hl)        ;get the day
  1794.     add    a,8        ;compute date of next sunday
  1795.     daa
  1796.     inc    hl        ;HL --> dw
  1797.     sub    (hl)        ;
  1798.     daa
  1799.     cp    32h        ;will it occur in October?
  1800.     jr    c,is_DST    ; Yes. it's still DST
  1801.     ld    a,(hl)        ;is Today Sunday?
  1802.     dec    a        ;
  1803.     jr    nz,wrtclk    ; no. then it's not DST
  1804.  
  1805.     inc    hl        ;HL --> hr
  1806.     ld    a,(hl)        ;after 2 am
  1807.     cp    2        ;
  1808.     jr    c,is_DST    ; no. it's still DST
  1809.     jr    wrtclk        ;yes. it's not DST
  1810.  
  1811. ;    Daylight Savings Time
  1812.  
  1813. is_DST: ld    a,e        ;get our flags
  1814.     or    flgDST        ;set the DST flag
  1815.     ld    e,a        ;update flags
  1816.  
  1817.  
  1818. ; Write data to the clock RAM
  1819.  
  1820. wrtclk:    ld    a,(dtonly)    ; get date_only flag
  1821.     or    a        ;
  1822.     jr    nz,wrtck1    ; wants to write date_only
  1823.  
  1824.     ld    b,1        ; point to the TENTHS
  1825.     call    portc        ;
  1826.     ld    hl,se    ;
  1827.     ld    b,6        ; we have six registers to write
  1828.     jr    wrtck2        ; go do the year stuff
  1829.  
  1830. wrtck1:    ld    b,4        ; point to the hours
  1831.     call    portc        ;
  1832.     ld    hl,dw    ;
  1833.     ld    b,3        ; we have three registers to write
  1834.  
  1835.  
  1836. wrtck2:    inc    c        ; increment the port
  1837.     ld    a,(hl)        ; get the value
  1838.     out    (c),a        ; write it
  1839.     dec    hl        ; point to the next item
  1840.     djnz    wrtck2        ; and loop
  1841.  
  1842.     ld    b,9        ; point to the year
  1843.     call    portc
  1844.     ld    a,(hl)        ; get yr
  1845.     out    (c),a        ; send to the clock
  1846.  
  1847.     ld    b,14        ; point to the flags
  1848.     call    portc        ;
  1849.     ld    a,e        ; get the flags
  1850.     out    (c),a        ; update the clock
  1851.     in    a,(c)        ; did clock accept the value?
  1852.     cp    e        ; See if in and out match
  1853.     jr    nz,wrterr    ; Clock is has malfunction or not available
  1854.     xor    a        ; write successful
  1855.     ret            ; and return
  1856.  
  1857. wrterr:    xor    a
  1858.     dec    a        ; report an error
  1859.     ret
  1860. ;
  1861. ; The following code stores the current time in the Z33 registers
  1862. ; when the S option is invoked. Later use of the E option compares
  1863. ; the current time with the saved time and displays the elapsed
  1864. ; time to the hundredths of seconds. Code was removed verbatim
  1865. ; from Terry Hazen's ELAPSED version 10 with only very minor changes
  1866. ; (e.g. jp exit instead of ret!). I appreciate Terry's permission 
  1867. ; to use his code here.
  1868. ;
  1869. elapse:    call    getmsg
  1870.     ld    a,(timreg)
  1871.     add    a,30h
  1872.     ld    e,a
  1873.     ld    d,0
  1874.     add    hl,de
  1875.     call    isbcdt        ; Check validity of memory date and time
  1876.     jp    nz,msgerr
  1877.  
  1878.     inc    hl        ; Point to previous time
  1879.     inc    hl
  1880.     inc    hl
  1881.     inc    hl
  1882.     ld    de,oldbin
  1883.     ld    a,(hl)        ; Old hours
  1884.     call    bc2bi
  1885.     ld    (de),a
  1886.     inc    hl
  1887.     inc    de
  1888.     ld    a,(hl)        ; Old minutes
  1889.     call    bc2bi
  1890.     ld    (de),a
  1891.     inc    hl
  1892.     inc    de
  1893.     ld    a,(hl)        ; Old seconds
  1894.     call    bc2bi
  1895.     ld    (de),a
  1896.     inc    hl
  1897.     inc    de
  1898.     ld    a,(hl)        ; Old tenths
  1899.     call    bc2bi
  1900.     ld    (de),a
  1901.  
  1902.     ld    hl,hr
  1903.     ld    a,(hl)        ; New hours
  1904.     call    bc2bi
  1905.     ld    (hl),a
  1906.     inc    hl
  1907.     ld    a,(hl)        ; New minutes
  1908.     call    bc2bi
  1909.     ld    (hl),a
  1910.     inc    hl
  1911.     ld    a,(hl)        ; New seconds
  1912.     call    bc2bi
  1913.     ld    (hl),a
  1914.     inc    hl
  1915.     ld    a,(hl)        ; New tenths
  1916.     call    bc2bi
  1917.     ld    (hl),a
  1918.  
  1919.     ld    a,(de)        ; DE = address of Julian (old time)
  1920.     ld    b,a
  1921.     ld    a,(hl)        ; HL = address of Tenths (new time)
  1922.     sub    b
  1923.     jr    nc,etime0
  1924.     call    adjtn
  1925.     sub    b
  1926.  
  1927. etime0:    ld    (oldbin+3),a    ; Do seconds
  1928.     dec    hl
  1929.     dec    de
  1930.     ld    a,(de)
  1931.     ld    b,a
  1932.     ld    a,(hl)
  1933.     sub    b
  1934.     jr    nc,etime1
  1935.     call    adjsc
  1936.     sub    b
  1937.  
  1938. etime1:    ld    (oldbin+2),a
  1939.     dec    hl        ; Do minute
  1940.     dec    de
  1941.     ld    a,(de)
  1942.     ld    b,a
  1943.     ld    a,(hl)
  1944.     sub    b
  1945.     jr    nc,etime2
  1946.     call    adjmn
  1947.     sub    b
  1948.  
  1949. etime2:    ld    (oldbin+1),a
  1950.     dec    hl        ; Do hour
  1951.     dec    de
  1952.     ld    a,(de)
  1953.     ld    b,a
  1954.     ld    a,(hl)
  1955.     sub    b
  1956.     jr    nc,etime3
  1957.     call    adjhr
  1958.     sub    b
  1959.  
  1960. etime3:    ld    (oldbin),a
  1961.  
  1962.     ld    a,(line25)    ; 25th line of H19?
  1963.     or    a        
  1964.     jr    z,etime6    
  1965.     ld    hl,cursav    ; save cursor position
  1966.     call    epstr        
  1967.     ld    hl,enable    
  1968.     call    epstr        
  1969.     call    at        
  1970.     defb    25,1        
  1971.  
  1972.     jr    etime7        
  1973.     
  1974. etime6:    call    crlf    
  1975. etime7:    call    eprint
  1976.  
  1977.     db    '   Elapsed time:  ',0
  1978.     ld    hl,oldbin    ; Show elapsed time
  1979.     ld    a,(hl)
  1980.     call    bi2bc
  1981.     call    pa2hc
  1982.     call    colon
  1983.     inc    hl
  1984.     ld    a,(hl)
  1985.     call    bi2bc
  1986.     call    pa2hc
  1987.     call    colon
  1988.     inc    hl
  1989.     ld    a,(hl)
  1990.     call    bi2bc
  1991.     call    pa2hc
  1992.     ld    a,'.'
  1993.     call    cout
  1994.     inc    hl
  1995.     ld    a,(hl)
  1996.     call    bi2bc
  1997.     call    pa2hc
  1998.     ld    a,(line25)    ; H19 with 25th line?
  1999.     or    a
  2000.     jr    z,etimea
  2001.     ld    hl,curret    ; return to save cursor position
  2002.     call    epstr
  2003.     jp    exit
  2004. ;
  2005. etimea:    call    crlf
  2006.     jp    exit
  2007.  
  2008. msgerr:    call    eprint
  2009.     db    '   Use "S" option to store current time first!'
  2010.     db    bell,cr,lf,0
  2011.     jp    exit
  2012.  
  2013. stortim:call    getmsg        ; Get message buffer address
  2014.     ld    a,(timreg)    ; Get first storage register
  2015.     add    a,30h        ; Add offset
  2016.     ld    e,a
  2017.     ld    d,0
  2018.     add    hl,de
  2019.     ex    de,hl        ; Register address in DE
  2020.     ld    hl,yr        ; Point to date and time buffer
  2021.     ld    bc,8        ; Eight bytes to move
  2022.     ldir
  2023.     jp    exit
  2024.  
  2025. adjtn:    dec    hl        ; Point to second
  2026.     ld    a,(hl)
  2027.     or    a        ; Zero?
  2028.     jr    z,adjtn1    ; (yes, adjust it)
  2029.     dec    (hl)        ; No, borrow one
  2030.     inc    hl        ; Point back to tenths
  2031.     ld    a,(hl)
  2032.     add    a,100        ; Add borrow
  2033.     ret
  2034.  
  2035. adjtn1:    dec    hl        ; Point to second
  2036.     call    adjsc        ; Borrow one
  2037.     dec    (hl)
  2038.     inc    hl        ; Point to tenths
  2039.     ld    (hl),99        ; Add borrow-1
  2040.     ret
  2041.  
  2042. adjsc:    dec    hl        ; Point to minute
  2043.     ld    a,(hl)
  2044.     or    a        ; Zero?
  2045.     jr    z,adjsc1    ; (yes, adjust it)
  2046.     dec    (hl)        ; No, borrow one
  2047.     inc    hl        ; Point back to second
  2048.     ld    a,(hl)
  2049.     add    a,60        ; Add borrow
  2050.     ret
  2051.  
  2052. adjsc1:    dec    hl        ; Point to hour
  2053.     call    adjhr        ; Borrow one
  2054.     dec    (hl)
  2055.     inc    hl        ; Point to minute
  2056.     ld    (hl),59        ; Add borrow -1
  2057.     inc    hl        ; Point back to second
  2058.     ld    a,(hl)
  2059.     add    a,60        ; Add borrow
  2060.     ret
  2061.  
  2062. adjmn:    dec    hl        ; Point to hour
  2063.     ld    a,(hl)
  2064.     or    a        ; Zero?
  2065.     call    z,adjhr        ; (yes, adjust it)
  2066.     dec    (hl)
  2067.     inc    hl        ; Point back to minute
  2068.     ld    a,(hl)
  2069.     add    a,60        ; Add borrow -1
  2070.     ret
  2071.  
  2072. adjhr:    ld    a,(hl)        ; Is hour zero?
  2073.     add    a,24        ; Add borrow from day
  2074.     ld    (hl),a
  2075.     ret
  2076.  
  2077. ; The following code creates a correction factor which will be used
  2078. ; to reset the clock base on known acurrate time values entered by
  2079. ; by the user such as from the Heath Most Accurate Clock. The clock
  2080. ; may be updated by the 'U' option from the command line.
  2081.  
  2082. mkupdr:    ld    a,(udflg)    ; has 'U' option been used?
  2083.     or    a
  2084.     jr    z,mkupda    ; No, so continue
  2085.  
  2086. ; Zero out data buffer and start over
  2087.     ld    hl,byr        ; beginning of buffer
  2088.     ld    b,128        ; one record to zero
  2089.     xor    a
  2090.     call    fillb
  2091.     
  2092.  
  2093. mkupda:    ld    hl,syr        ; Make new base archive TD
  2094.     ld    de,byr        ;    at BYR(SST)/SETBASE(JS32)
  2095.     ld    bc,16
  2096.     ldir
  2097. ;
  2098. mkupd:    call    swsst        ; Convert YR(SW) to (SYR)SST
  2099.     ld    hl,syr        ; Convert SYR(SST) to SETNEW(JS32)
  2100.     ld    de,setnew
  2101.     call    ss2js
  2102.     ld    a,(upflg)    ; doing an update?
  2103.     or    a
  2104.     ret    nz        ; yes, so quit here and return
  2105. ;
  2106.     ld    hl,setnew    ; Copy it to LCF buffer
  2107.     ld    de,lcf
  2108.     ld    bc,4
  2109.     push    hl
  2110.     push    bc
  2111.     ldir
  2112.     pop    bc        ; And to DELTA buffer
  2113.     pop    hl
  2114.     ld    de,delta
  2115.     ldir
  2116. ;
  2117.     ld    hl,tmi        ; Convert TYR(SW) to TYR(SST)
  2118.     ld    de,tho
  2119.     call    swsst0
  2120.     ld    hl,0        ; Clear last two bytes for clarity
  2121.     ld    (ttx),hl
  2122.     call    convclk        ; Convert TYR(SST) to CLKTIM(JS32)
  2123. ;
  2124.     ld    hl,delta
  2125.     ld    de,clktim
  2126.     call    sublw        ; Get difference
  2127.     ld    a,0
  2128.     jr    nc,clkslo    ; Clock is running slow
  2129. ;
  2130.     call    neglw        ; Two's complement, because
  2131.     inc    a        ; Clock is running fast
  2132. ;
  2133. clkslo:    ld    (sign),a    ; 0=slow clock, 0ffh=fast clock
  2134. ;
  2135.     ld    hl,lcf
  2136.     ld    de,setbase
  2137.     call    sublw        ; LCF=setnew-setbase
  2138. ;
  2139.     ld    de,delta
  2140.     call    divlw        ; Calculate LCF
  2141.  
  2142. ;
  2143. ; Write data file
  2144. ;
  2145. ; We get here with the file open and ready to write
  2146.  
  2147. wrtfile:ld    hl,byr        ; Point to start of buffer
  2148.     call    setdma
  2149.     
  2150. ;    the next instruction determines which record receives the data
  2151.  
  2152.     if    (ztype=4)
  2153.  
  2154.     ld    hl,[(byr-entry)/128]+2    ;allow for 2 record header
  2155.     else
  2156.     ld    hl,(byr-entry)/128
  2157.  
  2158.     endif
  2159.  
  2160.     ld    de,fcb
  2161.     call    r$write
  2162.     jr    nz,ferr        ; Report disk error
  2163. ;
  2164.     call    f$close        ; Close the file
  2165.     jr    nz,ferr        ; Report disk error
  2166. ;
  2167.     ret    
  2168. ;
  2169. filchk:    ld    hl,disk        ; point to program name
  2170.     ld    de,fcb        ; point to CPM fcb filename location
  2171.     ld    bc,14
  2172.     push    de
  2173.     ldir            ; move name there
  2174.     
  2175.     ld    a,(disk)    ; get clock.com disk
  2176.     dec    a
  2177.     ld    b,a
  2178.     ld    a,(user)    ;  and user
  2179.     ld    c,a
  2180.     call    logud        ; go there 
  2181.  
  2182.     pop    de
  2183.     call    f$exist        ; Test for file
  2184.     jr    z,nofil        ; File not on current du:
  2185. ;
  2186.     call    f$open        ; Open file
  2187.     inc    a        ; Check status
  2188.     jr    z,ferr        ; Bad open
  2189.     ret
  2190.  
  2191. ; No file 
  2192. ;
  2193. nofil:    call    eprint
  2194.     db    cr,lf,'+++ File to update not found on ',0
  2195.     ld    a,(disk)
  2196.     add    a,'@'    ; convert to ascii
  2197.     call    cout        
  2198.     ld    a,(user)
  2199.     add    a,'0'    ; convert to ascii
  2200.     call    cout
  2201.     call    eprint
  2202.     db    ': +++',bell,0
  2203.     jp    exit
  2204. ;
  2205. ; General file error message
  2206. ;
  2207. ferr:    call    eprint
  2208.     db    cr,lf,'+++ File Error +++',bell,0
  2209.     jp    exit
  2210. ;
  2211.  
  2212. ; Reset(update) clock using correction factor stored
  2213. ; in the second record of the program
  2214. ;
  2215. update:    call    filchk        ; can we find a valid updating file?
  2216.     
  2217.     ld    a,(errflg)    ; clock read error?
  2218.     or    a
  2219.     jp    nz,rderr    ; Quit if error
  2220. ;
  2221.     ld    hl,yr        ; Convert YR(SW)
  2222.     ld    de,tyr        ; To TYR(SST)
  2223.     ld    bc,3
  2224.     ldir
  2225.     inc    hl        ; Skip day of week
  2226.     call    swsst0
  2227.     call    convclk        ; Convert TYR(SST) to CLKTIM(JS32)
  2228. ;
  2229.     ld    hl,tyr        ; Copy TYR/CLKTIM to corrected time
  2230.     ld    de,cyr        ;   buffers CYR/CORTIM
  2231.     ld    bc,16
  2232.     ldir
  2233. ;
  2234.  
  2235.     call    updt        ; Yes, adjust the clock time
  2236.  
  2237.     ld    hl,cyr        ; move corrected values 
  2238.     ld    de,yr        ;  to clock buffer
  2239.     ld    bc,3
  2240.  
  2241.     push    bc
  2242.     ldir
  2243.     inc    de        ; skip dw
  2244.     pop    bc        ; get 3 back
  2245.     ldir            ; move the bytes to hr, etc
  2246.  
  2247.     call    writclk        ; go update clock
  2248.     or    a        ; see if error
  2249.     jr    z,updat1
  2250.     call    eprint
  2251.     defb    cr,lf
  2252.     defb    'Clock write error. Cannot '
  2253.     defb    'update clock.',0
  2254.     jp    exit
  2255.  
  2256. updat1:    ld    a,0ffh
  2257.     ld    (upflg),a    ; set update flag
  2258.     ld    (udflg),a    ; set buffer updated flag
  2259.     call    mkupd        ; adjust latest set date/time
  2260.     call    wrtfile        ; and save to disk
  2261.     call    PrtDate    
  2262.     call    eprint
  2263.     defb    CR,LF
  2264.     defb    'Clock has been reset with '
  2265.     defb    'corrected time.',0
  2266.     jp    exit
  2267.  
  2268. rderr:    call     eprint
  2269.     defb    cr,lf
  2270.     defb    'There has been a clock read error '
  2271.     defb    'so updating aborted.',0
  2272.  
  2273. ;-----------------------------------------------------------------------
  2274. ;
  2275. ; Subroutines
  2276. ;
  2277. ; Copy SmartWatch YS(SW) buffer to SYR(SST)
  2278. ;
  2279. swsst:    ld    hl,yr        ; Copy SW buffer
  2280.     ld    de,syr        ; To SST buffer
  2281.     ld    bc,3
  2282.     ldir
  2283.     inc    hl        ; Skip day of week
  2284. ;
  2285. swsst0:    ld    bc,3
  2286.     ldir
  2287.     ret
  2288. ;
  2289. ; Correct clock time and reset smartwatch if required
  2290. ;
  2291. updt:    ld    hl,setbase    ; Can't update if only one baseline
  2292.     call    nulchk        ; Check for null entry
  2293.     jr    nz,updta
  2294.     call    crlf
  2295.     call    prtdate
  2296.     call    eprint
  2297.     db    CR,LF
  2298.     db    'Cannot update clock without two '
  2299.     db    'baseline times in the data buffer.',bell,0
  2300.     jp    exit
  2301. ;    ret    z        ; Empty, so we're done
  2302. ;
  2303. updta:    ld    hl,clktim    ; Copy it to CORR(JS32)
  2304.     ld    de,corr
  2305.     ld    bc,4
  2306.     ldir
  2307. ;
  2308.     ld    hl,corr        ; Get SETNEW-CORR
  2309.     push    hl        ; Save pointer
  2310.     ld    de,setnew
  2311.     call    sublw
  2312.     ld    de,lcf
  2313.     call    divlw        ; Calculate LCF=LCF/(SETNEW-CORR)
  2314.     pop    hl        ; Restore correction pointer
  2315.     call    nulchk        ; Quit if no correction required
  2316.     jr    nz,updtb
  2317.     call     crlf
  2318.     call    prtdate        ; print date/time
  2319.     call    eprint
  2320.     db    CR,LF
  2321.     db    'Clock is acurrate. No updating required.',bell,0
  2322.     jp    exit
  2323. ;    ret    z
  2324. ;
  2325. updtb:    ld    hl,cortim    ; Set buffer pointers for correction
  2326.     ld    de,corr
  2327.     ld    a,(sign)    ; Check if fast or slow
  2328.     or    a
  2329.     jr    nz,upd0        ; Fast
  2330. ;
  2331.     call    addlw        ; Clock is slow, add correction
  2332.     jr    upd1
  2333. ;
  2334. upd0:    call    sublw        ; Clock is fast, subtract correction
  2335. ;
  2336. upd1:    jr    js2cyr        ; Convert CORTIM(JS32) to CYR(SST)
  2337. ;
  2338. ; Check JS32 buffer for null
  2339. ; Enter:HL=buffer pointer
  2340. ; Exit: Z if 0,0,0,0
  2341. ;
  2342. nulchk:    ld    b,4
  2343. ;
  2344. nullp:    ld    a,(hl)        ; Check first two bytes
  2345.     inc    hl 
  2346.     or    a
  2347.     ret    nz        ; Not null
  2348.     djnz    nullp
  2349. ;
  2350.     ret
  2351. ;
  2352. ; Convert TYR(SST) to CLKTIM(JS32)
  2353. ;
  2354. convclk:ld    hl,tyr        ; Point to clock time
  2355.     ld    de,clktim    ; And fall thru
  2356. ;
  2357. ; Convert time from SST format to 32-bit Julian Seconds format
  2358. ; Entry:HL=pointer to SST buffer
  2359. ;    DE=pointer to JS32 buffer
  2360. ; Uses: All
  2361. ;
  2362. ss2js:    ld    (ssptr),hl    ; Save pointers
  2363.     ld    (jsptr),de
  2364. ;
  2365.     ex    de,hl
  2366.     call    bc2ju        ; Convert yr/mo/day to Julian days
  2367.     ld    b,2
  2368.     xor    a
  2369.     call    fillb
  2370.     ld    hl,temp        ; And TEMP buffer
  2371.     ld    b,4
  2372.     call    fillb
  2373. ;
  2374.     ld    hl,24        ; Convert to hours
  2375.     call    multhl
  2376. ;
  2377.     ld    hl,(ssptr)
  2378.     inc    hl
  2379.     inc    hl
  2380.     inc    hl        ; Point to hour
  2381.     push    hl        ; Save SST pointer
  2382.     call    mov32        ; Add in hours
  2383. ;
  2384.     call    mult60        ; Convert to minutes
  2385.     pop    hl        ; Restore SST pointer
  2386.     inc    hl        ; Point to minutes
  2387.     push    hl        ; Save SST pointer
  2388.     call    mov32        ; Add in minutes
  2389. ;
  2390.     call    mult60        ; Convert to seconds
  2391.     pop    hl        ; Restore SST pointer
  2392.     inc    hl        ; Point to seconds and fall thru
  2393. ;
  2394. ; Convert byte pointed to by HL binary, add it to JS32 buffer
  2395. ;
  2396. mov32:    ld    a,(hl)        ; Get it
  2397.     call    bc2bi        ; Convert to binary
  2398.     ld    h,0
  2399.     ld    l,a
  2400.     ld    (temp),hl    ; Make sure higher byte is zero'd
  2401.     ld    de,temp        ; Point to buffers
  2402.     ld    hl,(jsptr)    ; JS32 pointer
  2403.     jp    addlw        ; Add it in
  2404. ;
  2405. ; Multiply by 60
  2406. ;
  2407. mult60:    ld    hl,60        ; Multiply by 60
  2408. ;
  2409. ; Multiply JS32 buffer by value in HL
  2410. ; Exit: HL points to result in JS32 buffer
  2411. ;
  2412. multhl:    ld    (temp),hl    ; Save in temp buffer
  2413.     ld    de,temp        ; Point to temp buffer
  2414.     ld    hl,(jsptr)    ; Point to JS32 buffer
  2415.     jp    mullw        ; Do multiplication
  2416. ;
  2417. ; Convert time from CORTIM(JS32) to CYR(SST)
  2418. ;
  2419. js2cyr:    ld    hl,cortim
  2420.     call    div60        ; Convert TIMDAT3 to minutes
  2421.     ld    a,(de)        ; Get seconds (remainder)
  2422.     call    bi2bc        ; Convert to BCD
  2423.     ld    (cse),a        ; Save it in SST buffer
  2424. ;
  2425.     call    div60        ; Convert to hours
  2426.     ld    a,(de)        ; Get minutes (remainder)
  2427.     call    bi2bc        ; Convert to BCD
  2428.     ld    (cmi),a        ; Save it in SST buffer
  2429. ;
  2430.     ld    de,24
  2431.     call    divde        ; Convert to days
  2432.     ld    a,(de)        ; Get hours (remainder)
  2433.     call    bi2bc        ; Convert to BCD
  2434.     ld    (cho),a        ; Save it in SST buffer
  2435. ;
  2436.     ld    de,cyr        ; Point to SST buffer
  2437.     jp    ju2bc        ; Convert to YY MM DD
  2438. ;
  2439. ; Divide by 60
  2440. ;
  2441. div60:    ld    de,60        ; Divide by 60
  2442. ;
  2443. ; Divide JS32 buffer by value in DE
  2444. ; Entry:HL points to JS32 buffer
  2445. ;    DE = dividend
  2446. ; Exit: HL points to result in JS32 buffer
  2447. ;    DE points to remainder JS32 buffer
  2448. ;
  2449. divde:    ld    (temp),de    ; Save in temp buffer
  2450.     ld    de,temp        ; Point to temp buffer
  2451.     jp    divlw        ; Do multiplication
  2452. ;
  2453.  
  2454.  
  2455. ;
  2456. ; Enter with desired port offset in B, returns with port number in C
  2457. ;
  2458. portc:    push    af        ; preserve register a
  2459.     ld    a,(port)    ; get base port into a
  2460.     add    a,b        ; add the offset
  2461.     ld    c,a        ; move value to register c
  2462.     pop    af        ; get original register value
  2463.     ret
  2464.  
  2465. montbl:    defb    'Jan',0
  2466.     defb    'Feb',0
  2467.     defb    'Mar',0
  2468.     defb    'Apr',0
  2469.     defb    'May',0
  2470.     defb    'Jun',0
  2471.     defb    'Jul',0        
  2472.     defb    'Aug',0
  2473.     defb    'Sep',0
  2474.     defb    'Oct',0
  2475.     defb    'Nov',0
  2476.     defb    'Dec',0
  2477.  
  2478. ; Highest legal BCD values in Clock buffer slots.
  2479. ;
  2480. BCDmax:    defb    99h    ; Year
  2481.     defb    12h    ; Month
  2482.     defb    31h    ; Day of month
  2483.     defb    07h    ; Day of week
  2484.     defb    23h    ; Hours
  2485.     defb    59h    ; Minutes
  2486.     defb    59h    ; Seconds
  2487.  
  2488.  
  2489. ; Length of each month
  2490.  
  2491. lentbl:    defb    31H,28H        ; lentbl includes daytbl below!
  2492.  
  2493. ; BCD table of the days in a month during a leap year (Jan Feb not needed)
  2494.  
  2495. daytbl:    defb    31h,30h,31h,30h,31h,31h,30h,31h,30h,31h
  2496.  
  2497. ; Day of year (for each month's beginning) table.
  2498.  
  2499. DOYtbl:    defw    0,31,59,90,120,151,181
  2500.     defw    212,243,273,304,334
  2501.  
  2502. ;
  2503.  
  2504.     dseg    ;
  2505.  
  2506. timBCD:
  2507. yr:    ds    1        ; Year goes here
  2508. mo:    ds    1        ; Month goes here
  2509. da:    ds    1        ; Day of Month goes here
  2510. dw:    ds    1        ; Day of Week goes here
  2511. hr:    ds    1        ; hours go here
  2512. mi:    ds    1        ; minutes go here
  2513. se:    ds    1        ; seconds go here
  2514. tn:    ds    1        ; tenths/hundredths go here
  2515. flgBCD:    ds    1        ; Flags
  2516.  
  2517. zero_it:            ; initialization beginning
  2518. oldbin:    ds    4        ; Original binary time buffer
  2519. corrupt:ds    1        ; Flag byte corrupt flag
  2520. upflg:    ds    1        ; 'U' option reset flag
  2521. flgbyte:ds    1        ; Flag byte
  2522. CMTptr:    ds    2        ; COMTAIL pointer buffer
  2523. CmTail:    ds    1        ; COMTAIL character count
  2524. dtonly:    ds    1        ; date_only flag
  2525. z33flg:    ds    1        ; z33 flag
  2526. errflg:    ds    1        ; clock read error
  2527. ;
  2528. ssptr:    ds    2        ; SST buffer pointer
  2529. jsptr:    ds    2        ; JS32 buffer pointer
  2530. temp:    ds    4        ; Temporary JS32 buffer
  2531. makef:    ds    1        ; 0=make file, else don't
  2532. Dbuf:    defs    60        ; Scratchpad
  2533. end_it:                ; initialization ending
  2534.     defs    64        ; 64 byte stack
  2535. stack:    defs    2        ; system stack pointer
  2536.  
  2537.     END
  2538.