home *** CD-ROM | disk | FTP | other *** search
- ; MXC-ZS10.Z80
- ;
- ; MEX-Plus Clock Overlay for ZSDOS
- ;
- ; A hardware independent clock module, obtaining the time and date
- ; from ZSDOS.
- ;
- ; This module passes the current ZSDOS time and date to MEX for
- ; display. It also implements the CSET command to set the ZSDOS
- ; clock. There are two separate commands:
- ;
- ; CSET DATE {mm}/{dd}/{yy}
- ;
- ; and
- ;
- ; CSET TIME {hh}:{mm}:{ss}
- ;
- ; Entering all elements of a date or time specification is not
- ; necessary. Missing elements will be filled in from the current
- ; setting of the clock. In other words, if you just want to change
- ; the hour--perhaps to daylight saving time--enter:
- ; CSET TIME hh
- ; To adjust the minutes, use:
- ; CSET TIME :mm
- ; Or to tweek the seconds:
- ; CSET TIME ::ss
- ; The date parameter works the same way. As the examples indicate,
- ; leading delimiters are required, but trailing delimiters are not.
- ;
- ; If desired, date entry can be configured to use European format:
- ; CSET DATE dd.mm.yy
- ; See the EURDAT equate below.
- ;
- ; If ZSDOS returns no date and time, this clock module returns
- ; 12:00 a.m., January 1, 1978. Relative time is not supported.
- ;
- ; Please report any bugs.
- ; Gene Pizzetta
- ; 481 Revere St.
- ; Revere, MA 02151
- ;
- ; Voice: (617) 284-0891
- ; Newton Centre Z-Node: (617) 965-7259
- ; Ladera Z-Node Central: (213) 670-9465
- ;
- ; Version 1.0 -- June 16, 1991 -- Gene Pizzetta
- ; Based on MXC-DS10 overlay for DateStamper by Jim Lill, ZSLIB
- ; routines by Carson Wilson, and SYSLIB routines by Richard
- ; Conn.
- ;
- ; System addresses
- ;
- Bdos equ 0005h
- TPA equ 100h
- ;
- ; BDOS functions
- ;
- ZSGTime equ 98 ; ZSDOS get time function
- ZSSTime equ 99 ; ZSDOS set time function
- ;
- ; MEX functions
- ;
- MEX equ 0D00h ; MEX function entry
- LOOKUP equ 247 ; table search: see CMDTBL comments for info
- SBLANK equ 244 ; scan input stream to next non-blank
- GNC equ 241 ; get char from input, cy=1 if none
- ILP equ 240 ; inline print
- PRINT equ 9 ; simulated BDOS function 9: print string
- ;
- ; ASCII
- ;
- BELL equ 07h
- LF equ 0Ah
- CR equ 0Dh
- ;
- FALSE equ 0
- TRUE equ not FALSE
- ;
- ; Date format -- Select here either American (mm/dd/yy) or European
- ; (dd.mm.yy) date format for entry of date specification to CSET
- ; processor. MEX always displays the date in American format.
- ;
- EURDAT equ FALSE ; FALSE=American, TRUE=European
- ;
- org TPA ; we begin
- ;
- db 0C3h ; JP required by load
- ;
- ; Jump table for clock overlay
- ;
- org 0E00h ; start of clock overlay
-
- Start: jp GetTim ; get time
- jp GetDat ; get date
- jp CstCmd ; cset processor
- ret ; clock overlay init
- db 0,0
- ret ; clock overlay de-init
- db 0,0
- ;
- ; GetTim -- gets BCD time into DatTbl and then loads registers with
- ; binary equivalents for MEX:
- ; B = hours (0-23)
- ; C = minutes (0-59)
- ; D = seconds (0-59)
- ; E = hundredths of seconds (0-99)
- ;
- GetTim: call GetZST ; get time from ZSDOS
- jr z,GetTm1 ; (okay, continue)
- ld bc,0 ; no time, return midnight
- ld de,0
- ret
- ;
- GetTm1: ld a,(hours) ; BCD hours to A
- call BcdBin
- ld b,a ; binary hours to B
- ld a,(minute) ; BCD minutes to A
- call BcdBin
- ld c,a ; binary minutes to C
- ld a,(second) ; BCD seconds to A
- call BcdBin
- ld d,a ; binary seconds to D
- ld e,0 ; no 100th's of second
- ret
- ;
- ; GetDat -- gets BCD date into DatTbl and then loads registers with
- ; binary equivalents for MEX:
- ; BC = year (1978-2077)
- ; D = month (1=Jan, 2=Feb, etc.)
- ; E = day (1-31)
- ;
- GetDat: call GetZST ; get date from ZSDOS
- jr z,GetDt1 ; (okay, continue)
- ld e,1 ; no date, return Jan. 1, 1978
- ld d,e
- ld bc,1978
- ret
- ;
- GetDt1: ld a,(day) ; BCD day to A
- call BcdBin
- ld e,a ; binary day to E
- ld a,(month) ; BCD month to A
- call BcdBin
- ld d,a ; binary month to D
- ld a,(year) ; BCD year (00-99) to A
- call BcdBin
- ld c,a ; binary year in C
- ld b,0
- ld hl,1900 ; add century
- cp 78
- jr nc,GetDt2
- ld hl,2000
- GetDt2: add hl,bc
- ld c,l ; put year in BC
- ld b,h
- ret
- ;
- ; CSET Processor for ZSDOS
- ;
- CstCmd: ld c,SBLANK ; any arguments?
- call MEX
- jr c,CstErr ; if not, display defaults
- ld de,CstTbl
- ld c,LOOKUP
- call MEX ; parse the argument
- push hl ; save any parsed arguments
- ret nc ; ..and return to it
- pop hl ; not found
- CstErr: ld de,CstEms
- ld c,PRINT
- call MEX
- ret
- ;
- CstEms: db BELL,' CSET syntax error -- "CSET ?" for help',CR,LF,'$'
- ;
- CstTbl: dc '?' ; help
- dw CstHlp
- dc 'DATE' ; set date
- dw CsDate
- dc 'TIME' ; set time
- dw CsTime
- db 0 ; end of table
- ;
- ; CSET with "?" prints help message
- ;
- CstHlp: call SILP
- db ' CSET Options:',CR,LF
- db ' DATE '
- IF EURDAT
- db '{dd}.{mm}.{yy}'
- ELSE
- db '{mm}/{dd}/{yy}'
- ENDIF ; EURDAT
- db ' (sets ZSDOS date)',CR,LF
- db ' TIME {hh}:{mm}:{ss} (sets ZSDOS time)',CR,LF
- db 0
- ret
- ;
- ; CsDate -- sets ZSDOS system date
- ;
- CsDate: call MvDat ; move date to storage
- jp c,CstErr ; (none given)
- call GetZST ; fill DatTbl
- jr nz,ClkErr ; (clock error)
- call PrsDat ; parse date and make BCD
- jp nz,CstErr ; (invalid date)
- call SetZST ; set date
- jr nz,ClkErr ; (clock error)
- call SILP
- db 'ZSDOS Date Set',0
- ret
- ;
- ; CsTime -- sets ZSDOS system time
- ;
- CsTime: call MvDat ; move time to storage
- jp c,CstErr ; (none given)
- call GetZST ; fill DatTbl
- jr nz,ClkErr ; (clock error)
- call PrsTim ; parse time and make BCD
- jp nz,CstErr ; (invalid time)
- call SetZST ; set time
- jr nz,ClkErr ; (clock error)
- call SILP
- db 'ZSDOS Time Set',0
- ret
- ;
- ClkErr: call SILP
- db BELL,'ZSDOS clock error',0
- ret
- ;
- ; PrsDat -- parses date specification string. (Modified from ZSLIB's
- ; ZSPARSDS module by Carson Wilson.)
- ;
- PrsDat: ld de,DatTbl ; point to BCD date
- ld hl,DatStr-1 ; point to command line date
- push de
- ld b,d
- ld c,e
- inc bc ; BC --> storage + 1 (month)
- IF EURDAT
- inc bc ; BC --> storage + 2 (day)
- ENDIF ; EURDAT
- ;
- ; Test month (or day if EurDat)
- ;
- call GetNxt ; get next datespec character or abort
- cp '.' ; got character, use default month?
- jr z,TestDy ; (yes)
- cp '/'
- jr z,TestDy
- call IsDgt ; digit?
- jp nz,ErExit ; (no)
- call eval16 ; must be day spec. SYSLIB evaluates ASCII
- ; ..hex to binary and points HL to next
- TstMon: ld (bc),a ; save value
- ld a,(hl) ; get next
- cp '.' ; day spec?
- jr z,TestDy
- cp '/'
- jp nz,PsExit ; no, done
- ;
- TestDy:
- IF EURDAT
- dec bc ; BC --> storage + 1 (month)
- ELSE
- inc bc ; BC --> storage + 2 (day)
- ENDIF ; EURDAT
- call GetNxt ; get/abort
- cp '.' ; got character, use default day?
- jr z,TestYr ; (yes)
- cp '/'
- jr z,TestYr
- call IsDgt ; digit?
- jp nz,ErExit ; (no)
- call eval16 ; evaluate day
- TestD1: ld (bc),a ; save value
- ld a,(hl)
- cp ' '
- jr z,PsExit
- cp '.' ; got year?
- jr z,TestYr
- cp '/'
- jr nz,PsExit ; (no)
- ;
- TestYr: dec bc ; point to year
- IF NOT EURDAT
- dec bc
- ENDIF ; NOT EURDAT
- call GetNxt ; get/abort
- cp ' ' ; use default year?
- jr z,PsExit ; (yes)
- call IsDgt ; digit?
- jr nz,ErExit ; (no)
- call eval16 ; evaluate year
- TestY1: ld (bc),a ; save value
- jr PsExit ; (no, done)
- ;
- ; PrsTim -- parses time specification string
- ;
- PrsTim: ld bc,Hours
- ld de,DatTbl
- ld hl,DatStr-1
- push de
- TestHr: call GetNxt ; get next command character
- cp ':' ; use default hour?
- jr z,TestMn ; (yes)
- call IsDgt ; digit?
- jr nz,ErExit ; (no, error)
- call eval16 ; get hour
- ld (bc),a ; save value
- ld a,(hl)
- cp ':' ; got minute?
- jr nz,PsExit ; (no, done)
- ;
- TestMn: inc bc ; point to minute
- call GetNxt ; minute or wildcard
- cp ':' ; use default minute?
- jr z,TestSc ; (yes)
- cp ' '
- jr z,PsExit
- call IsDgt ; digit?
- jr nz,ErExit ; (no)
- call eval16 ; evaluate minute
- ld (bc),a ; save value
- ld a,(hl)
- cp ':' ; got second?
- jr nz,PsExit ; (no, done)
- ;
- TestSc: inc bc ; point to second
- call GetNxt ; second
- cp ' '
- jr z,PsExit
- call IsDgt ; digit?
- jr nz,ErExit ; (no)
- call eval16 ; evaluate second
- ld (bc),a ; save value
- ;
- PsExit: pop de ; point to stored date
- ex de,hl ; check value at HL
- call IsBcdd
- ex de,hl ; restore DE
- ret ; return (Z) if date OK.
- ;
- ErExit: pop de
- ret
- ;
- ; GetNxt -- get next date/time spec character for PrsDat and PrsTim
- ; On entry HL = address of next datespec position minus 1. On exit
- ; HL incremented by 1 and A = character pointed to by HL.
- ;
- GetNxt: inc hl ; next input
- ld a,(hl)
- or a ; done?
- ret nz ; (no)
- pop de ; yes, remove return address
- jr PsExit ; ..and exit parse
- ;
- ; IsBcdD -- Test BCD date and time at HL for validity. Returns NZ
- ; on error. (Modified from ZSLIB's ZSISBCDD module by Carson Wilson.)
- ;
- IsBcdD: push hl
- ld a,(hl) ; BCD year
- call IsBcd
- jr nc,NotBcd
- inc hl ; month
- ld a,(hl)
- or a
- jr z,NotBcd
- cp 13h
- call c,IsBcd
- jr nc,NotBcd
- inc hl ; day
- ld a,(hl)
- or a
- jr z,NotBcd
- cp 32h
- call c,IsBcd
- jr nc,NotBcd
- inc hl ; hour
- ld a,(hl)
- cp 24h
- call c,IsBcd
- jr nc,NotBcd
- inc hl ; min
- ld a,(hl)
- cp 60h
- call c,IsBcd
- jr nc,NotBcd
- inc hl ; sec
- ld a,(hl)
- cp 60h
- call c,IsBcd
- jr nc,NotBcd
- pop hl
- xor a ; return Z no error
- ret
-
- NotBcd: ld a,(hl) ; return NZ for error
- pop hl
- or 0FFh
- ret
- ;
- ; IsBcd -- Test if byte in A is BCD. Carry set (C) if byte is BCD.
- ;
- IsBcd: cp 09Ah ; see if nibbles in 0..9
- ret nc ; not BCD if > 99
- and 00001111b ; test right nibble
- cp 00Ah
- ret
- ;
- ; SetZST -- Set current date and time from DatTbl. Returns A=0 and
- ; zero flag set (Z) if clock set, zero flag reset (NZ) on error.
- ; (Modified from ZSLIB's ZSGSTIME module by Carson Wilson.)
- ;
- SetZST: ld c,ZSSTime
- jr GetSet
- ;
- ; GetZST -- Get current date and time to DatTbl. Returns A=0 and zero
- ; flag set (Z) if buffer filled, zero flag reset (NZ) on error.
- ;
- GetZST: ld c,ZSGTime
- ;
- GetSet: ld de,DatTbl ; point DE to buffer
- call Bdos
- dec a ; ZSDOS returns 1 if okay
- ret
- ;
- ; IsDgt -- returns Zero Flag Set if char in A is numeric (0-9).
- ; Returns NZ if not. Char in A is unaffected. (Modified from
- ; SYSLIB 3.6 SISDIGIT module by Richard Conn.)
- ;
- IsDgt: push bc ; save BC
- ld c,a ; save character in C
- and 7Fh ; mask out MSB
- cp '0' ; less than 0?
- jr c,NoDgt
- cp '9'+1 ; less than or equal to 9?
- jr nc,NoDgt
- xor a ; set flag
- ld a,c ; get character
- pop bc ; restore BC
- ret
- ;
- NoDgt: ld a,0FFh ; set flag
- or a
- ld a,c ; get character
- pop bc ; restore BC
- ret
- ;
- ; Eval16 -- Convert the string of ASCII hexadecimal digits pointed to
- ; by HL into a binary value; string is converted until invalid digit is
- ; encountered. On return, HL points to error character, DE=value,
- ; A=E (low order 8 bits of value). BC not affected. (SYSLIB 3.6
- ; SEVAL2 module by Richard Conn.)
- ;
- Eval16: push bc ; save BC
- ld de,0 ; set DE = 0 initially
- ; Get next digit and check for '0' - '9'
- E16L: ld a,(hl) ; get byte
- call Caps ; capitalize
- cp '0' ; check for range
- jr c,Done
- cp 'F'+1 ; check for range
- jr nc,Done
- cp '9'+1 ; check for 0-9
- jr c,ProDec
- cp 'A' ; check for out of range
- jr c,Done
- ProDec: sub '0' ; convert to binary
- cp 10
- jr c,Proc
- sub 7 ; adjust for 'A'-'F'
- ; Proceed with processing
- Proc: push af ; save value
- ; Multiply DE by 16
- Mul16: push hl ; save HL
- ld hl,0 ; Acc=0
- ld b,16 ; 16 loops
- Mul16L: add hl,de ; HL = HL + DE
- dec b ; count down
- jr nz,Mul16L
- ld d,h ; new DE
- ld e,l
- pop hl ; restore HL
- ; Add in A
- pop af ; get latest digit
- add a,e ; A = A + E
- ld e,a
- ld a,d ; add to D if necessary
- adc 0
- ; Continue
- inc hl ; point to next character
- jr E16L
-
- ; Done -- result already in DE; set A = E
- Done: ld a,e ; A = E
- pop bc ; restore BC
- ret
- ;
- ; BcdBin -- packed BCD in A converted to binary in A.
- ;
- BcdBin: push bc
- ld c,a ; move value to C
- and 0F0h ; mask lower nibble
- rra ; move upper nibble into lower
- rra
- rra
- rra
- ld b,a ; times 1
- add a
- add a ; times 4
- add b ; times 5
- add a ; times 10
- ld b,a ; 10's digit to B
- ld a,c ; lower digit to A
- and 0Fh
- add b ; combine digits
- pop bc
- ret
- ;
- ; Caps -- Capitalize ASCII Character in A. (SYSLIB 3.6 SCAPS module
- ; by Richard Conn.)
- ;
- Caps: and 7Fh ; mask out MSB
- cp 61h ; less than lower-case a?
- ret c
- cp 7Ah+1 ; between lower-case a and z?
- ret nc
- and 5Fh ; reset bit 5 to capitalize
- ret
- ;
- ; MvDat -- moves date or time from command line to storage
- ;
- MvDat: ld c,SBLANK ; any arguments?
- call MEX
- ret c ; (if not, error)
- ld hl,DatStr ; point to string storage
- ld b,8 ; eight characters maximum
- ld c,GNC
- MvDat1: push hl
- push bc
- call MEX
- pop bc
- pop hl
- jr c,MvDat2
- ld (hl),a
- inc hl
- djnz MvDat1
- MvDat2: xor a ; zero A and clear carry
- ld (hl),a ; insert a final null
- ret
- ;
- ; SILP -- In-line print routine (calls MEX)
- ;
- SILP: ld c,ILP
- jp MEX
- ;
- ; DatTbl -- BCD time and date storage
- ;
- DatTbl:
- Year: db 0 ; 00 - 99
- Month: db 0 ; 1 - 12
- Day: db 0 ; 1 - 31
- Hours: db 0 ; 00 - 23
- Minute: db 0 ; 00 - 59
- Second: db 0 ; 00 - 59
- ;
- DatStr: ds 9 ; command line date/time storage
- ;
- end