home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / modem / mxc-zs10.z80 < prev    next >
Encoding:
Text File  |  1994-09-02  |  12.9 KB  |  571 lines

  1. ; MXC-ZS10.Z80
  2. ;
  3. ;    MEX-Plus Clock Overlay for ZSDOS
  4. ;
  5. ; A hardware independent clock module, obtaining the time and date
  6. ; from ZSDOS.
  7. ;
  8. ; This module passes the current ZSDOS time and date to MEX for
  9. ; display.  It also implements the CSET command to set the ZSDOS
  10. ; clock.  There are two separate commands:
  11. ;
  12. ;    CSET DATE {mm}/{dd}/{yy}
  13. ;
  14. ; and
  15. ;
  16. ;    CSET TIME {hh}:{mm}:{ss}
  17. ;
  18. ; Entering all elements of a date or time specification is not
  19. ; necessary.  Missing elements will be filled in from the current
  20. ; setting of the clock.  In other words, if you just want to change
  21. ; the hour--perhaps to daylight saving time--enter:
  22. ;    CSET TIME hh
  23. ; To adjust the minutes, use:
  24. ;    CSET TIME :mm
  25. ; Or to tweek the seconds:
  26. ;    CSET TIME ::ss
  27. ; The date parameter works the same way.  As the examples indicate,
  28. ; leading delimiters are required, but trailing delimiters are not.
  29. ;
  30. ; If desired, date entry can be configured to use European format:
  31. ;    CSET DATE dd.mm.yy
  32. ; See the EURDAT equate below.
  33. ;
  34. ; If ZSDOS returns no date and time, this clock module returns
  35. ; 12:00 a.m., January 1, 1978.  Relative time is not supported.
  36. ;
  37. ; Please report any bugs.
  38. ;    Gene Pizzetta
  39. ;    481 Revere St.
  40. ;    Revere, MA 02151
  41. ;
  42. ;    Voice:  (617) 284-0891
  43. ;    Newton Centre Z-Node:  (617) 965-7259
  44. ;    Ladera Z-Node Central:  (213) 670-9465
  45. ;
  46. ; Version 1.0 -- June 16, 1991 -- Gene Pizzetta
  47. ;    Based on MXC-DS10 overlay for DateStamper by Jim Lill, ZSLIB
  48. ;    routines by Carson Wilson, and SYSLIB routines by Richard
  49. ;    Conn.
  50. ;
  51. ; System addresses
  52. ;
  53. Bdos    equ    0005h
  54. TPA    equ    100h
  55. ;
  56. ; BDOS functions
  57. ;
  58. ZSGTime    equ    98        ; ZSDOS get time function
  59. ZSSTime    equ    99        ; ZSDOS set time function
  60. ;
  61. ; MEX functions
  62. ;
  63. MEX    equ    0D00h        ; MEX function entry
  64. LOOKUP    equ    247        ; table search: see CMDTBL comments for info
  65. SBLANK    equ    244        ; scan input stream to next non-blank
  66. GNC    equ    241        ; get char from input, cy=1 if none
  67. ILP    equ    240        ; inline print
  68. PRINT    equ    9        ; simulated BDOS function 9: print string
  69. ;
  70. ; ASCII
  71. ;
  72. BELL    equ    07h
  73. LF    equ    0Ah
  74. CR    equ    0Dh
  75. ;
  76. FALSE    equ    0
  77. TRUE    equ    not FALSE
  78. ;
  79. ; Date format -- Select here either American (mm/dd/yy) or European
  80. ; (dd.mm.yy) date format for entry of date specification to CSET
  81. ; processor.  MEX always displays the date in American format.
  82. ;
  83. EURDAT    equ    FALSE        ; FALSE=American, TRUE=European
  84. ;
  85.     org    TPA        ; we begin
  86. ;
  87.     db    0C3h        ; JP required by load
  88. ;
  89. ; Jump table for clock overlay
  90. ;
  91.     org    0E00h        ; start of clock overlay
  92.  
  93. Start:    jp    GetTim        ; get time
  94.     jp    GetDat        ; get date
  95.     jp    CstCmd        ; cset processor
  96.     ret            ; clock overlay init
  97.     db    0,0
  98.     ret            ; clock overlay de-init
  99.     db    0,0
  100. ;
  101. ; GetTim -- gets BCD time into DatTbl and then loads registers with
  102. ; binary equivalents for MEX:
  103. ;    B = hours (0-23)
  104. ;    C = minutes (0-59)
  105. ;    D = seconds (0-59)
  106. ;    E = hundredths of seconds (0-99)
  107. ;
  108. GetTim:    call    GetZST        ; get time from ZSDOS
  109.     jr    z,GetTm1    ; (okay, continue)
  110.     ld    bc,0        ; no time, return midnight
  111.     ld    de,0
  112.     ret
  113. ;
  114. GetTm1:    ld     a,(hours)    ; BCD hours to A
  115.     call    BcdBin
  116.     ld    b,a        ; binary hours to B
  117.     ld    a,(minute)    ; BCD minutes to A
  118.     call    BcdBin
  119.     ld    c,a        ; binary minutes to C
  120.     ld    a,(second)    ; BCD seconds to A
  121.     call    BcdBin
  122.     ld    d,a        ; binary seconds to D
  123.     ld    e,0        ; no 100th's of second
  124.     ret
  125. ;
  126. ; GetDat -- gets BCD date into DatTbl and then loads registers with
  127. ; binary equivalents for MEX:
  128. ;    BC = year (1978-2077)
  129. ;    D  = month (1=Jan, 2=Feb, etc.)
  130. ;    E  = day (1-31)
  131. ;
  132. GetDat:    call    GetZST        ; get date from ZSDOS
  133.     jr    z,GetDt1    ; (okay, continue)
  134.     ld    e,1        ; no date, return Jan. 1, 1978
  135.     ld    d,e
  136.     ld    bc,1978
  137.     ret
  138. ;
  139. GetDt1:    ld     a,(day)        ; BCD day to A
  140.     call    BcdBin
  141.     ld    e,a        ; binary day to E
  142.     ld    a,(month)    ; BCD month to A
  143.     call    BcdBin
  144.     ld    d,a        ; binary month to D
  145.     ld    a,(year)    ; BCD year (00-99) to A
  146.     call    BcdBin
  147.     ld    c,a        ; binary year in C
  148.     ld    b,0
  149.     ld    hl,1900        ; add century
  150.     cp    78
  151.     jr    nc,GetDt2
  152.     ld    hl,2000
  153. GetDt2:    add    hl,bc
  154.     ld    c,l        ; put year in BC
  155.     ld    b,h
  156.     ret
  157. ;
  158. ; CSET Processor for ZSDOS
  159. ;
  160. CstCmd:    ld    c,SBLANK    ; any arguments?
  161.     call    MEX
  162.     jr    c,CstErr    ; if not, display defaults
  163.     ld    de,CstTbl
  164.     ld    c,LOOKUP
  165.     call    MEX        ; parse the argument
  166.     push    hl        ; save any parsed arguments
  167.     ret    nc        ; ..and return to it
  168.     pop    hl        ; not found
  169. CstErr:    ld    de,CstEms
  170.     ld    c,PRINT
  171.     call    MEX
  172.     ret
  173. ;
  174. CstEms:    db    BELL,'  CSET syntax error -- "CSET ?" for help',CR,LF,'$'
  175. ;
  176. CstTbl:    dc    '?'        ; help
  177.     dw    CstHlp
  178.     dc    'DATE'        ; set date
  179.     dw    CsDate
  180.     dc    'TIME'        ; set time
  181.     dw    CsTime
  182.     db    0        ; end of table
  183. ;
  184. ; CSET with "?" prints help message
  185. ;
  186. CstHlp:    call    SILP
  187.     db    '  CSET Options:',CR,LF
  188.     db    '    DATE      '
  189.   IF EURDAT
  190.     db    '{dd}.{mm}.{yy}'
  191.   ELSE
  192.     db    '{mm}/{dd}/{yy}'
  193.   ENDIF    ; EURDAT
  194.     db    '    (sets ZSDOS date)',CR,LF
  195.     db    '    TIME      {hh}:{mm}:{ss}    (sets ZSDOS time)',CR,LF
  196.     db    0
  197.     ret
  198. ;
  199. ; CsDate -- sets ZSDOS system date
  200. ;
  201. CsDate:    call    MvDat        ; move date to storage
  202.     jp    c,CstErr    ; (none given)
  203.     call    GetZST        ; fill DatTbl
  204.     jr    nz,ClkErr    ; (clock error)
  205.     call    PrsDat        ; parse date and make BCD
  206.     jp    nz,CstErr    ; (invalid date)
  207.     call    SetZST        ; set date
  208.     jr    nz,ClkErr    ; (clock error)
  209.     call    SILP
  210.     db    'ZSDOS Date Set',0
  211.     ret
  212. ;
  213. ; CsTime -- sets ZSDOS system time
  214. ;
  215. CsTime:    call    MvDat        ; move time to storage
  216.     jp    c,CstErr    ; (none given)
  217.     call    GetZST        ; fill DatTbl
  218.     jr    nz,ClkErr    ; (clock error)
  219.     call    PrsTim        ; parse time and make BCD
  220.     jp    nz,CstErr    ; (invalid time)
  221.     call    SetZST        ; set time
  222.     jr    nz,ClkErr    ; (clock error)
  223.     call    SILP
  224.     db    'ZSDOS Time Set',0
  225.     ret
  226. ;
  227. ClkErr:    call    SILP
  228.     db    BELL,'ZSDOS clock error',0
  229.     ret
  230. ;
  231. ; PrsDat -- parses date specification string.  (Modified from ZSLIB's
  232. ; ZSPARSDS module by Carson Wilson.)
  233. ;
  234. PrsDat:    ld    de,DatTbl    ; point to BCD date
  235.     ld    hl,DatStr-1    ; point to command line date
  236.     push    de
  237.     ld    b,d
  238.     ld    c,e
  239.     inc    bc        ; BC --> storage + 1 (month)
  240.   IF EURDAT
  241.     inc    bc        ; BC --> storage + 2 (day)
  242.   ENDIF    ; EURDAT
  243. ;
  244. ; Test month (or day if EurDat)
  245. ;
  246.     call    GetNxt        ; get next datespec character or abort
  247.     cp    '.'        ; got character, use default month?
  248.     jr    z,TestDy    ; (yes)
  249.     cp    '/'
  250.     jr    z,TestDy
  251.     call    IsDgt        ; digit?
  252.     jp    nz,ErExit    ; (no)
  253.     call    eval16        ; must be day spec.  SYSLIB evaluates ASCII
  254.                 ; ..hex to binary and points HL to next
  255. TstMon:    ld    (bc),a        ; save value
  256.     ld    a,(hl)        ; get next
  257.     cp    '.'        ; day spec?
  258.     jr    z,TestDy
  259.     cp    '/'
  260.     jp    nz,PsExit    ; no, done
  261. ;
  262. TestDy:
  263.   IF EURDAT
  264.     dec    bc        ; BC --> storage + 1 (month)
  265.   ELSE
  266.     inc    bc        ; BC --> storage + 2 (day)
  267.   ENDIF    ; EURDAT
  268.     call    GetNxt        ; get/abort 
  269.     cp    '.'        ; got character, use default day?
  270.     jr    z,TestYr    ; (yes)
  271.     cp    '/'
  272.     jr    z,TestYr
  273.     call    IsDgt        ; digit?
  274.     jp    nz,ErExit    ; (no)
  275.     call    eval16        ; evaluate day
  276. TestD1:    ld    (bc),a        ; save value
  277.     ld    a,(hl)
  278.     cp    ' '
  279.     jr    z,PsExit
  280.     cp    '.'        ; got year?
  281.     jr    z,TestYr
  282.     cp    '/'
  283.     jr    nz,PsExit    ; (no)
  284. ;
  285. TestYr:    dec    bc        ; point to year
  286.   IF NOT EURDAT
  287.     dec    bc
  288.   ENDIF    ; NOT EURDAT
  289.     call    GetNxt        ; get/abort
  290.     cp    ' '        ; use default year?
  291.     jr    z,PsExit    ; (yes)
  292.     call    IsDgt        ; digit?
  293.     jr    nz,ErExit    ; (no)
  294.     call    eval16        ; evaluate year
  295. TestY1:    ld    (bc),a        ; save value
  296.     jr    PsExit        ; (no, done)
  297. ;
  298. ; PrsTim -- parses time specification string
  299. ;
  300. PrsTim:    ld    bc,Hours
  301.     ld    de,DatTbl
  302.     ld    hl,DatStr-1
  303.     push    de
  304. TestHr:    call    GetNxt        ; get next command character
  305.     cp    ':'        ; use default hour?
  306.     jr    z,TestMn    ; (yes)
  307.     call    IsDgt        ; digit?
  308.     jr    nz,ErExit    ; (no, error)
  309.     call    eval16        ; get hour
  310.     ld    (bc),a        ; save value
  311.     ld    a,(hl)
  312.     cp    ':'        ; got minute?
  313.     jr    nz,PsExit    ; (no, done)
  314. ;
  315. TestMn:    inc    bc        ; point to minute
  316.     call    GetNxt        ; minute or wildcard
  317.     cp    ':'        ; use default minute?
  318.     jr    z,TestSc    ; (yes)
  319.     cp    ' '
  320.     jr    z,PsExit
  321.     call    IsDgt        ; digit?
  322.     jr    nz,ErExit    ; (no)
  323.     call    eval16        ; evaluate minute
  324.     ld    (bc),a        ; save value
  325.     ld    a,(hl)
  326.     cp    ':'        ; got second?
  327.     jr    nz,PsExit    ; (no, done)
  328. ;
  329. TestSc:    inc    bc        ; point to second
  330.     call    GetNxt        ; second
  331.     cp    ' '
  332.     jr    z,PsExit
  333.     call    IsDgt        ; digit?
  334.     jr    nz,ErExit    ; (no)
  335.     call    eval16        ; evaluate second
  336.     ld    (bc),a        ; save value
  337. ;
  338. PsExit:    pop    de        ; point to stored date
  339.     ex    de,hl        ; check value at HL
  340.     call    IsBcdd
  341.     ex    de,hl        ; restore DE
  342.     ret            ; return (Z) if date OK.
  343. ;
  344. ErExit:    pop    de
  345.     ret
  346. ;
  347. ; GetNxt -- get next date/time spec character for PrsDat and PrsTim
  348. ; On entry HL = address of next datespec position minus 1.  On exit
  349. ; HL incremented by 1 and A = character pointed to by HL.
  350. ;
  351. GetNxt:    inc    hl        ; next input
  352.     ld    a,(hl)
  353.     or    a        ; done?
  354.     ret    nz        ; (no)
  355.     pop    de        ; yes, remove return address
  356.     jr    PsExit        ; ..and exit parse
  357. ;
  358. ; IsBcdD -- Test BCD date and time at HL for validity.  Returns NZ
  359. ; on error.  (Modified from ZSLIB's ZSISBCDD module by Carson Wilson.)
  360. ;
  361. IsBcdD:    push    hl
  362.     ld    a,(hl)        ; BCD year
  363.     call    IsBcd
  364.     jr    nc,NotBcd
  365.     inc    hl        ; month
  366.     ld    a,(hl)
  367.     or    a
  368.     jr    z,NotBcd
  369.     cp    13h
  370.     call    c,IsBcd
  371.     jr    nc,NotBcd
  372.     inc    hl        ; day
  373.     ld    a,(hl)
  374.     or    a
  375.     jr    z,NotBcd
  376.     cp    32h
  377.     call    c,IsBcd
  378.     jr    nc,NotBcd
  379.     inc    hl        ; hour
  380.     ld    a,(hl)
  381.     cp    24h
  382.     call    c,IsBcd
  383.     jr    nc,NotBcd
  384.     inc    hl        ; min
  385.     ld    a,(hl)
  386.     cp    60h
  387.     call    c,IsBcd
  388.     jr    nc,NotBcd
  389.     inc    hl        ; sec
  390.     ld    a,(hl)
  391.     cp    60h
  392.     call    c,IsBcd
  393.     jr    nc,NotBcd
  394.     pop    hl
  395.     xor    a        ; return Z no error
  396.     ret
  397.  
  398. NotBcd:    ld    a,(hl)        ; return NZ for error
  399.     pop    hl
  400.     or    0FFh
  401.     ret
  402. ;
  403. ; IsBcd -- Test if byte in A is BCD.  Carry set (C) if byte is BCD.
  404. ;
  405. IsBcd:    cp    09Ah        ; see if nibbles in 0..9
  406.     ret    nc        ; not BCD if > 99
  407.     and    00001111b    ; test right nibble
  408.     cp    00Ah
  409.     ret
  410. ;
  411. ; SetZST -- Set current date and time from DatTbl.  Returns A=0 and
  412. ; zero flag set (Z) if clock set, zero flag reset (NZ) on error.
  413. ; (Modified from ZSLIB's ZSGSTIME module by Carson Wilson.)
  414. ;
  415. SetZST:    ld    c,ZSSTime
  416.     jr    GetSet
  417. ;
  418. ; GetZST -- Get current date and time to DatTbl.  Returns A=0 and zero
  419. ; flag set (Z) if buffer filled, zero flag reset (NZ) on error.
  420. ;
  421. GetZST:    ld    c,ZSGTime
  422. ;
  423. GetSet:    ld    de,DatTbl    ; point DE to buffer
  424.     call    Bdos
  425.     dec    a        ; ZSDOS returns 1 if okay
  426.     ret
  427. ;
  428. ; IsDgt -- returns Zero Flag Set if char in A is numeric (0-9).
  429. ; Returns NZ if not.  Char in A is unaffected.  (Modified from
  430. ; SYSLIB 3.6 SISDIGIT module by Richard Conn.)
  431. ;
  432. IsDgt:    push    bc        ; save BC
  433.     ld    c,a        ; save character in C
  434.     and    7Fh        ; mask out MSB
  435.     cp    '0'        ; less than 0?
  436.     jr    c,NoDgt
  437.     cp    '9'+1        ; less than or equal to 9?
  438.     jr    nc,NoDgt
  439.     xor    a        ; set flag
  440.     ld    a,c        ; get character
  441.     pop    bc        ; restore BC
  442.     ret
  443. ;
  444. NoDgt:    ld    a,0FFh        ; set flag
  445.     or    a
  446.     ld    a,c        ; get character
  447.     pop    bc        ; restore BC
  448.     ret
  449. ;
  450. ; Eval16 -- Convert the string of ASCII hexadecimal digits pointed to
  451. ; by HL into a binary value; string is converted until invalid digit is
  452. ; encountered.  On return, HL points to error character, DE=value,
  453. ; A=E (low order 8 bits of value).  BC not affected.  (SYSLIB 3.6
  454. ; SEVAL2 module by Richard Conn.)
  455. ;
  456. Eval16:    push    bc        ; save BC
  457.     ld    de,0        ; set DE = 0 initially
  458. ; Get next digit and check for '0' - '9'
  459. E16L:    ld    a,(hl)        ; get byte
  460.     call    Caps        ; capitalize
  461.     cp    '0'        ; check for range
  462.     jr    c,Done
  463.     cp    'F'+1        ; check for range
  464.     jr    nc,Done
  465.     cp    '9'+1        ; check for 0-9
  466.     jr    c,ProDec
  467.     cp    'A'        ; check for out of range
  468.     jr    c,Done
  469. ProDec:    sub    '0'        ; convert to binary
  470.     cp    10
  471.     jr    c,Proc
  472.     sub    7        ; adjust for 'A'-'F'
  473. ; Proceed with processing
  474. Proc:    push    af        ; save value
  475. ; Multiply DE by 16
  476. Mul16:    push    hl        ; save HL
  477.     ld    hl,0        ; Acc=0
  478.     ld    b,16        ; 16 loops
  479. Mul16L:    add    hl,de        ; HL = HL + DE
  480.     dec    b        ; count down
  481.     jr    nz,Mul16L
  482.     ld    d,h        ; new DE
  483.     ld    e,l
  484.     pop    hl        ; restore HL
  485. ; Add in A
  486.     pop    af        ; get latest digit
  487.     add    a,e        ; A = A + E
  488.     ld    e,a
  489.     ld    a,d        ; add to D if necessary
  490.     adc    0
  491. ; Continue
  492.     inc    hl        ; point to next character
  493.     jr    E16L
  494.  
  495. ;  Done -- result already in DE; set A = E
  496. Done:    ld    a,e        ; A = E
  497.     pop    bc        ; restore BC
  498.     ret
  499. ;
  500. ; BcdBin -- packed BCD in A converted to binary in A.
  501. ;
  502. BcdBin:    push    bc
  503.     ld    c,a        ; move value to C
  504.     and    0F0h        ; mask lower nibble
  505.     rra            ; move upper nibble into lower
  506.     rra
  507.     rra
  508.     rra
  509.     ld    b,a        ; times 1 
  510.     add    a
  511.     add    a        ; times 4
  512.     add    b        ; times 5 
  513.     add    a        ; times 10
  514.     ld    b,a        ; 10's digit to B
  515.     ld    a,c        ; lower digit to A    
  516.     and    0Fh
  517.     add    b        ; combine digits
  518.     pop    bc
  519.     ret
  520. ;
  521. ; Caps -- Capitalize ASCII Character in A.  (SYSLIB 3.6 SCAPS module
  522. ; by Richard Conn.)
  523. ;
  524. Caps:    and    7Fh        ; mask out MSB
  525.     cp    61h        ; less than lower-case a?
  526.     ret    c
  527.     cp    7Ah+1        ; between lower-case a and z?
  528.     ret    nc
  529.     and    5Fh        ; reset bit 5 to capitalize
  530.     ret
  531. ;
  532. ; MvDat -- moves date or time from command line to storage
  533. ;
  534. MvDat:    ld    c,SBLANK    ; any arguments?
  535.     call    MEX
  536.     ret    c        ; (if not, error)
  537.     ld    hl,DatStr    ; point to string storage
  538.     ld    b,8        ; eight characters maximum
  539.     ld    c,GNC
  540. MvDat1:    push    hl
  541.     push    bc
  542.     call    MEX
  543.     pop    bc
  544.     pop    hl
  545.     jr    c,MvDat2
  546.     ld    (hl),a
  547.     inc    hl
  548.     djnz    MvDat1
  549. MvDat2:    xor    a        ; zero A and clear carry
  550.     ld    (hl),a        ; insert a final null
  551.     ret
  552. ;
  553. ; SILP -- In-line print routine (calls MEX)
  554. ;
  555. SILP:    ld    c,ILP
  556.     jp    MEX
  557. ;
  558. ; DatTbl -- BCD time and date storage
  559. ;
  560. DatTbl:
  561. Year:    db    0        ; 00 - 99
  562. Month:    db    0        ;  1 - 12
  563. Day:    db    0        ;  1 - 31
  564. Hours:    db    0        ; 00 - 23
  565. Minute:    db    0        ; 00 - 59
  566. Second:    db    0        ; 00 - 59
  567. ;
  568. DatStr:    ds    9        ; command line date/time storage
  569. ;
  570.     end
  571.