home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-25 | 45.1 KB | 1,987 lines |
- ;
- ; Program to set the MM58167a chip in the Kenmore Clock, Anapro
- ; Clock for the Heath H89/90 or CDR Super 89 clock. The program
- ; reads and writes directly to the MM58167 and automatically
- ; adjusts for leap years and Daylight Savings Time. See the
- ; internal HELP for options.
- ;
- ; CLOCK ver 1.1 1985--Author unknown
- ;
- ; CLOCK ver 2.0 30-Oct-92 Biff Bueffel
- ;
- ; a) Changed DST routine from last Sunday to first Sunday in April
- ; b) Moved year storage to base port + 9, consistent with other
- ; programs for this clock chip
- ; c) Changed time format to be consistent with Ztime
- ; d) Added Military/Civilian time option. Can be configured
- ; for default and then toggle from command line
- ; e) Allow setting of date only(original was time or date/time)
- ; f) Used syslib and zslib routines where possible
- ; g) Base port is stored at beginning of program to allow easy
- ; modification. Whenever a port is read or written the
- ; base port is loaded and the appropriate offset is
- ; added and the value is placed in register C
- ; h) Silent option added to update clock for DST and leap year
- ; without sending date/time to CRT
- ; i) Command line option will continuously display the date and
- ; time until any key is struck
- ;
- ;
- ; Thanks to Ludo Van Hemelryck for code suggestions and for
- ; detailed commenting much of the code.
- ;
- ; Thanks to Terry Hazen for code suggestions and especially
- ; for creating the CFG file!
- ;
- ; CLOCK ver 2.1 16-Nov-92 Biff Bueffel
- ;
- ; a) Uses PDAT.REL for routines to print time and date.
- ; b) Added elapsed time option(including hundredths of a
- ; second). Code shamelessly stolen from Terry
- ; Hazen's ELAPSED who borrowed much of it from
- ; Gene Pizzetta. Thanks, Terry for your permission
- ; to use the code.
- ;
- ; CLOCK ver 2.2 15-Mar-93 Biff Bueffel
- ;
- ; Adds ability to place time data on the 25th line of
- ; a H19 terminal. Heath or ANSI(VT-52) modes possible.
- ; May work on other terminals but not tested. Use
- ; CFG file to change strings for 25th line and
- ; saving cursor position.
- ;
- ;*********************************************************************
- ;
- ; Clock base port is 0a0h for CDR Super 89
- ; 080h for Anapro clock
- ; 0e0h for Kenmore clock
- ;
- ; TENTHS = base port + 1 Hundreths/Tenths of Seconds
- ; SEC = base port + 2
- ; MIN = base port + 3
- ; HRS = base port + 4
- ; DOW = base port + 5 Day of Week
- ; DAY = base port + 6
- ; MON = base port + 7
- ; YEAR = base port + 9 RAM for 10ths and 100ths of Second
- ;
- ; FLAGS = base port + 14 DST and Leap year Flags
- ;
- ; CLKSTS = base port + 20 Status bit
- ; CLKGO = base port + 21 GO command
- ;
- ;*************************************************************
- ;
- ; ZCPR3 utility type. Configure your assembly/linking alias in one of
- ; the following ways to produce the type of file desired.
- ;
- ; Set ZTYPE to 1 to produce a type 1 utility loading and executing at
- ; 100h under any version of ZCPR3:
- ;
- ; ZMAC CLOCK;ZML CLOCK
- ; or Z80ASM CLOCK/M;SLRNKP CLOCK/N,/A:100/J,CLOCK,/E
- ;
- ;
- ; Set ZTYPE to 3 to produce a type 3 utility loading and executing at
- ; a specified address such as 8000h under ZCPR33+:
- ;
- ; ZMAC CLOCK;ZML CLOCK /A:8000
- ; or Z80ASM CLOCK/M;SLRNKP CLOCK/N,/A:8000/J,CLOCK,/E
- ;
- ;
- ; Set ZTYPE to 4 to produce a type 4 utility loading under the CCP
- ; or protected RSX and executing only under ZCPR34+:
- ;
- ; ZMAC CLOCK;ZML CLOCK,T4LDR.HDR/P
- ;
- ; Rather than re-editing this file each time ZTYPE is changed,
- ; ask for the type at assembly time:
- ;
- .accept ' - Configure CLOCK.REL for ZCPR3 Type 1, 3 or 4? ',type
-
- if (type=4)
- ztype equ 4
-
- public $memry ; End of code
-
- else
- if (type=3)
- ztype equ 3
- else
- ztype equ 1 ; Default is type 1 utility
- endif
- endif
- ;
- ;*********************************************************************
- ;
-
-
- vers equ 22
-
-
- lpflg: equ 00000001b ;Flag that this is a leap year
- yokflg: equ 00000010b ;Flag that the year has been fixed
- DSTflg: equ 00000100b ;Flag enabling Daylight savings time
- flgDST: equ 00001000b ;Flag daylight savings time in effect
- setflg: equ 01010000b ;Flag that the clock has been set
- okmask: equ 11110000b ;Mask for clock ok flag
-
- lpbit: equ 0
- okbit: equ 1
- DSTbit: equ 2
- bitDST: equ 3
-
-
- bdos equ 5
- tbuff equ 80h
-
- cr equ 0dh ; carriage return
- lf equ 0ah ; line feed
- bell equ 07h ; Bell
- bs equ 08h ; backspace
- esc equ 1bh ; escape
-
- .request pdat
- ext colon,pdat1,pday1,ptim1,ptim3,space
-
- .request nztim
- ext bc2bi,bi2bc
-
- .request zslib
- ext isbcdt
-
- .request vlib
- ext curon,curoff,z3vinit,at
-
- .request z3lib
- ext getmsg
-
- .request syslib
- ext caps,condin,cout,crlf,eprint,epstr
- ext pa2hc,phl4hc
-
- public envptr
-
- ;*********************************************************************
-
- entry:
- if ztype=3
- jr start0 ; Executes only under ZCPR33+
- defb 0 ; Filler
- else
- jp start ; T4LDR has already tested for Z34
- endif
-
- z3env: defb 'Z3ENV' ; ZCPR3 indentifier
- defb ztype ; Default is type 1 utility
- envptr: defw 0 ; Z3ENV address
-
- iff ztype=4
- load: defw entry ; ENTRY load address for type 3, dummy for type 1
- else
- $memry defw 0 ; Code size for type 4 filled in by linker here
- endif
-
- ;
- civflg: defb 0 ; 0=military time, NZ=civilian time
- ;
- port: defb 0a0h ; 0a0h for CDR Super 89
- ; 080h for Anapro clock
- ; 0e0h for Kenmore clock
-
- timreg: defb 18 ; First storage record
-
- ; Configures Heath/Zenith H19 terminal(or others?) for 25th line use
- ;
- line25: defb 0 ; ffh = put time on 25th line
- enable: defb esc,'x','1',0,0 ; turn on 25th line
- ; MUST remain a 5 byte string.
- ; Unused bytes should be 0
- ; = esc,'[','1','h' if h19 ansi
- defb 0 ; do not change
- ;
- disabl: defb esc,'y','1',0,0 ; turn off 25th line
- ; MUST remain a 5 byte string.
- ; Unused bytes should be 0
- ; = esc,'[','1','l' if h19 ansi
- defb 0 ; do not change
- ;
- cursav: defb esc,'j',0,0 ; save current cursor position
- ; MUST remain a 4 byte string.
- ; Unused bytes should be 0
- ; = esc,'[','s' if h19 ansi
- defb 0 ; do not change
- ;
- curret: defb esc,'k',0,0 ; return to saved cursor position
- ; MUST remain a 4 byte string.
- ; Unused bytes should be 0
- ; = esc,'[','u' if h19 ansi
- defb 0 ; do not change
- ;
- cfg: db 'CLOCK'
- db vers/10+'0',vers mod 10+'0'
- ds cfg+8-$,' ' ; Space for 8 bytes
- db 0 ; Termination
- ;
-
- ; Starting point for type 3
- ;
- if ztype=3
- start0: ld hl,0 ; Point to warm boot entry
- ld a,(hl) ; Get the opcode
- di ; Protect against interrupts
- ld (hl),0c9h ; Replace warm boot with a return
- rst 0 ; 'CALL 0' pushes retadr onto stack
- ;
- retadr: ld (hl),a ; Restore original opcode at 0
- dec sp ; Phony push to set stack pointer to
- dec sp ; to point to the value of retadr
- pop de ; DE = real retadr
- ;
- ei ; Enable interrupts
- ld hl,retadr ; This is where we should be
- or a ; Clear CARRY
- sbc hl,de ; Are we actually there?
- jp z,start ; Yes, begin real code
- ;
- ; We're not where we should be, so quit with error message
- ;
- ld hl,nz33msg-retadr ; Offset to message
- add hl,de
- ex de,hl ; Message pointer in DE
- ld c,9
- jp bdos ; Quit via BDOS print string function
- ;
- nz33msg:db 'Not Z33+$' ; Abort message if not Z33-compatible
- endif ; ztype=3
-
- ;
-
- ;======================================================================
- ;
- signon: call eprint
- defb CR,LF,'[CLOCK vers '
- defb vers/10+'0','.',vers mod 10+'0'
- ;
- db ' - Type '
- db ztype+30h
- db ' at ',0
- ld hl,entry ; Get load address
- call phl4hc ; Display it
- call eprint
- db 'h]'
- ;
- defb CR,LF,LF
- defb 'Clock Help:',CR,LF,LF
- defb ' CLOCK -- Show the date and time',CR,LF
- defb ' CLOCK 10-SEP-92 -- Set the date',CR,LF
- defb ' CLOCK 10/SEP/92 13:20 -- Set the date and time',CR,LF
- defb ' CLOCK 10-SEP-92 13:20 Y -- Set the date and time '
- defb 'and turn on the DST option',CR,LF
- defb ' CLOCK 10/SEP/92 13:20 N -- Set the date and time '
- defb 'and turn off the DST option',CR,LF
- defb ' CLOCK 13:20 [Y/N-DST] -- Set the hour and minute ',CR,LF
- defb ' CLOCK 13:20:33 [Y/N-DST] -- Set the time(including '
- defb 'seconds) NOW!',CR,LF
- defb ' CLOCK C -- Continuously display time'
- defb ' - strike a key to exit',CR,LF
- defb ' CLOCK M -- Toggle Military/Civilian time'
- defb CR,LF
- defb ' CLOCK Q -- Read and update clock quietly'
- defb CR,LF,0
- ld a,(z33flg)
- or a
- jp z,sign0
- call eprint
- defb ' CLOCK S -- Store current time in Z3'
- defb ' registers',CR,LF
- defb ' CLOCK E -- Display elapsed time since'
- defb ' option S',CR,LF,0
- sign0: ld a,(line25)
- or a
- jr z,sign1
- call eprint
- defb ' CLOCK D -- Disable(clear) the 25th line'
- defb ' on the H19 terminal',CR,LF,0
- sign1: call eprint
- defb ' CLOCK ? or / -- Display the clock registers '
- defb 'and HELP text',CR,LF,LF,0
- ret
-
- ;
- ;
-
- start: ld (stack),sp ; save old stack pointer
- ld sp,stack ; set up new one
-
- ; Initialize data areas
-
- xor a
- ld (dtonly),a ; be sure date_only is off
- ld (cont),a ; assure continuous time is off
- ld (z33flg),a ; No to Z3
-
- ld ix,(envptr) ; point to the Z3 ENV
- ld a,(ix+3) ; we should find a Z here
- cp 'Z'
- jr nz,star0 ; not ZCPR3
- ld a,0ffh ;
- ld (z33flg),a ; save the yes z33
- ld hl,(envptr) ; point to Z3 ENV
- call z3vinit ; initialize z3 and vlib extended TCAP
-
- ;
-
- star0: call readclk ; read the clock
- ;
- call z,BCDchk ; if no error, verify if readings legal
- ;
- ld a,0 ; Clear all flags in flgbyte
- jr z,star1 ; if all BCD values within bound
- ;
- set 7,a ; set flgbyte to illegal reading of BCD values
-
- star1: ld (flgbyte),a ; save this for later use
-
- ld a,(tbuff) ; A = <COMTAIL character count>
- or a
- jr nz,star2 ;
- call PrtDate ; if none, just print the time/date
- jp exit ; and quit
- ;
- star2: ld (CmTail),A ; Save COMTAIL character count
- ld hl,tbuff+1 ; Point to 1st character of COMTAIL
- ld (CMTptr),hl ; Store pointer
-
- ld a,(flgbyte)
- ld c,a ; C = <Flag byte>
-
- call eatspc ; Jump a 'space' in COMTAIL
- ; (If not a ' ' or if an illegal char,
- ; return to CCP)
- ;
- ld hl,(CMTptr) ; HL =.<Command Tail char.>
-
- ld a,(z33flg) ; running under ZCPR
- or a
- jr z,star3 ; NO!
- ld a,'S'
- cp (hl) ; Store time option?
- jp z,stortim
- ld a,'E'
- cp (hl) ; Elapsed time option?
- jp z,elapse
-
- star3: ld a,(hl) ;
- call caps ; Convert any lower case to upper case
- cp '?'
- jp z,ClkHlp ; if so, print registers plus help message
- cp '/' ; Z3 help request
- jp z,ClkHlp
-
- cp 'Q' ; Quiet command?
- jp z,exit ; Clock was read on entry so exit silently
- cp 'D' ; Disable 25th line?
- jr nz,star4
- ld a,(line25) ; be sure 25th line is enabled
- or a ;
- jp z,exit ; No
- ld hl,disabl ; Point to the string
- call epstr ; send it
-
- jp exit
-
- star4: cp 'M' ; Military/Civilian toggle
- jr nz,PrCT ;
- ld a,(civflg) ; get the current setting
- or a ;
- jr z,makeCv ; if 0 then Military go make it Civilian
- xor a ; was Civilian so make Military
- ld (civflg),a ;
- call PrtDate ; go print the date/time
- jp exit ;
- makeCv: ld a,0ffh ;
- ld (civflg),a ; make it civilian time
- call PrtDate ; go print the date/time
- jp exit ;
-
- PrCT: cp 'C' ; Continuous time display option
- jr nz,ParCT1 ; No
- ld a,0ffh ;
- ld (cont),a ; Store continous flag
-
- call curoff ; turn cursor off if Z3 with extended TCAP
-
- ld a,(line25) ;
- jr z,PrCT1 ;
- ld hl,cursav ; save current cursor position
- call epstr ;
-
- PrCT1: call PrtDate
- contin: call readclk
- call PrtDt1
- call condin ; Any key from the keyboard?
- jr z,contin ; No then continue updating time
-
- call curon
-
- ld a,(line25)
- or a
- jp z,exit
- ld hl,curret ; return to saved cursor position
- call epstr
- jp exit
-
- ;
- ParCT1: call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld d,a ; D = <Digit from COMTAIL (MS)>
- call CTLCha ; Get next character from COMTAIL
- ; (If illegal, return to CCP)
- bit 6,c ; Was it a decimal digit?
- jr nz,ParCT2 ; if so, process it
- ;
- ld e,d ; if not, move MS to LS
- ld d,0 ; position and clear MS
- jr ParCT3 ; (Single digit Day of Month)
- ;
- ParCT2: ld e,a ; E = <Digit from COMTAIL (MS)>
- call CTLCha ; Get next character from COMTAIL
- ; (If illegal, return to CCP)
- ;
- ParCT3: bit 3,c ; Was it a '-' or '/'?
- jr nz,ParDat ; if so, process DE (Day of Month)
- ;
- bit 7,c ; Illegal readings or none?
- jp nz,ClkHlp ; if so, clock broken or not set
- ; (Return to CCP)
- bit 2,c ; Was it a ':'?
- jp z,SyntErr ; if not, syntax error
- ; (Return to CCP)
- jp StoHM ; Process a ':'
- ;
- ; Store day of month as a BCD.
-
- ParDat: ld hl,dayBCD
- call DIGtoBCD ; Convert DE into BCD and save at (HL)
- ;
- ; Identify the Month # (return it in B).
-
- call cpyCTL ; Copy alpha chars from COMTAIL
- ; to Dbuf (Return on separator)
- ; (If illegal char, return to CCP)
- ;
- bit 3,c ; Was it a '-' or '/'?
- jp z,SyntErr ; if not, syntax error
- ; (Return to CCP)
- ld b,1
- ld de,Dbuf ; DE =.<Scratchpad base>
- ld hl,montbl ; HL =.<1st month table entry>
-
- ParDT0: ld a,(de) ; get a letter
- cp (hl) ; does it match?
- jr z,ParDT1 ; yes
- xor 00100000b ; reverse case of letter in A
- cp (hl) ; does it match now?
- ;
- jr nz,ParDT2 ; if no match
- ;
- ParDT1: inc de ; Bump pointers
- inc hl ; "
- ld a,(de)
- or a ; End of string?
- jr z,ParDT3 ; if so, found match
- ;
- jr ParDT0 ; Check next character...
- ;
- ParDT2: inc b ; Try next 'montbl' entry
- ld a,13
- cp b ; > 12 ?
- jp z,SyntErr ; if so, syntax error (overflow)
- ; (Return to CCP)
- push bc ; Save register
-
- ld bc,20
- xor a
- cpir ; HL =.<terminating 0> + 1
-
- pop bc ; Restore register
-
- ld de,Dbuf ; DE =.<Scratchpad base>
- jr ParDT0 ; Compare strings...
- ;
- ParDT3: ld d,0 ; Assume single digit month
- ld a,b ; A = <Month #> (binary)
- cp 10
- jr c,StoMo ; if A < 10
- ;
- ld d,1 ; Two digit month
- sub 10 ; A = <unit digit>
-
- StoMo: ld e,a ; DE = <2-digit month #>
- ; Store month as a BCD.
-
- ld hl,monBCD
- call DIGtoBCD ; Convert DE into BCD and save at (HL)
- ;
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld d,a ; D = <MS year digit>
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld e,a ; E = <LS year digit>
-
-
- ; Store year as a BCD.
-
- ld hl,yrBCD
- call DIGtoBCD ; Convert DE into BCD and save at (HL)
- ;
- ld a,(monBCD)
- cp 10h ; 2-digit month?
- jr c,StorDa ; if not
- ;
- sub 6 ; Convert 2-digit BCD to binary value
-
- StorDa: ld hl,lentbl-1 ; HL =.<month length table - 1>
- add a,l
- ld l,a
- jr nc,StorD1 ; if not crossing page boundary
- ;
- inc h ; Next page
-
- ; HL =.<Month length>
- StorD1: ld a,(dayBCD)
- cp (HL) ; Day of month legal?
- jr c,CalDOW ; accept
- ;
- jr z,CalDOW ; accept
- ;
- cp 29h ; Could it be a 29th?
- jp nz,DtErr ; if not, diagnostic and return
- ; (to CCP)
-
- ld hl,yrBCD
- ld A,(hl) ; A = <Year (BCD)>
- and 11110000B ; A = <Year's MS-digit>
- rrca ; Move to LS-nibble
- rrca
- rrca
- rrca
- inc a ; Add 1, in case A = 0, and
- ld b,a ; save in B
-
- ld a,(hl) ; A = <Year (BCD)>
- and 00001111B ; A = <Year's LS-digit>
-
- LpYrCk: add a,10
- djnz LpYrCk
- ;
- sub 10 ; Adjust for extra 10
- ; A = <Year (binary)>
- and 00000011B ; Multiple of 4 ?
- jp nz,DtErr ; if not leap year, display
- ; diagnostic and return
- ; (to CCP)
- CalDOW: ld a,c
- ld (flgbyte),a ; Save C
-
- ld a,(monBCD)
- call bc2bi ; Convert BCD to binary
- ;
- ld e,a ; and save in E
- dec a
- sla a ; A = <Offset in 'DOYtbl'>
-
- ld hl,DOYtbl ; HL =.<Day of year (for month) table>
- ; (Word format)
- add a,l
- ld l,a
- jr nc,ClDOW0 ; if not crossing page boundary
- ;
- inc h ; Next page
-
- ; HL =.<Day of year for month (in table)>
- ClDOW0: ld c,(hl) ; C = <LS-byte, day of year (for month)>
- inc hl
- ld b,(hl) ; B = <MS-byte, day of year (for month)>
- push bc ; Save register
-
- ld a,(dayBCD)
- call bc2bi ; Convert BCD to binary
- ;
- ld c,a ; and save in C
- ld a,(yrBCD)
- call bc2bi ; Convert BCD to binary
- ;
- ld d,a ; and save in D
- and 00000011B ; Multiple of 4 ?
- jr nz,ClDOW1 ; if not a leap year
- ;
- ld a,e ; A = month (binary)
- cp 3 ; March to December ?
- jr nc,ClDOW2 ; if so, do not decrement
- ;
- ClDOW1: dec c ; DOM, Jan-Feb, in leap years
-
- ClDOW2: pop hl ; HL = <Day of year for month>
- ld a,l
- add a,c ; Add day of month
- ld l,a
- jr nc,ClDOW3 ; if not crossing page boundary
- ;
- inc h ; Next page
-
- ; HL = <Day of year for date>
- ClDOW3: ld a,d ; D = <Year (binary)>
- cp 84
- jr nc,ClDOW4 ; if '84 or later
- ;
- add a,100 ; If not, add a century
- ld d,a ; and save. (D =< 84)
-
- ClDOW4: ld a,84 ; A = <Pivot year>
- ; (Starting on Sunday)
-
- ; Compute number of days between date and pivot year.
- ; (Accumulate in HL)
-
- ClDOW5: cp d
- jr z,ClDOW7
- ;
- ld bc,365 ; bc = <year lenght>
- ld e,a ; Save A
- and 00000011B ; Multiple of 4 ?
- jr nz,ClDOW6 ; if not a leap year
- ;
- inc bc ; If it is, add a day
-
- ClDOW6: add hl,bc ; Accumulate days
- ld a,e ; Retrieve year, and
- inc a ; prepare to add next one
- jr ClDOW5
- ;
- ClDOW7: ld bc,1
- add hl,bc ; = <inc HL>
- ld bc,7 ; bc = <1 week>
-
- ClDOW8: ld a,h
- or a
- jr nz,ClDOW9
- ;
- ld a,l
- cp 8
- jr c,StrDOW ; if less than 1 week
- ;
- ClDOW9: sbc hl,bc ; Subtract 1 week
- jr ClDOW8 ; Loop ...
- ;
- ; Store day of week (binary = BCD).
-
- StrDOW: ld hl,dowBCD
- ld (hl),a ; Store day of week
-
- ld a,(CmTail) ; A = <COMTAIL character count >
- or a ;
- jr nz,ParTim ; more to come to jump
- ;
-
- ; See if only wants to set the date
-
- ld a,0ffh ;
- ld (dtonly),a ; we only want to set the date
- jp SetClk ; go write it
-
-
-
- ParTim: call eatspc ; Jump a 'space' in COMTAIL
- ; (If not a ' ' or if an illegal char,
- ; return to CCP)
- ;
-
- ld a,(flgbyte)
- ld c,a ; C = <flgbyte>
-
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld d,a
- call CTLCha ; Get next character from COMTAIL
- ; (If illegal, return to CCP)
- ;
- bit 6,c ; Is it (another) digit?
- jr nz,PaTm1 ; if so, process it
- ;
- ld e,d ; if not, move MS to LS
- ld d,0 ; position and clear MS
- jr ColChk ; (Single digit Hour)
- ;
- PaTm1: ld e,a
- call CTLCha ; Get next character from COMTAIL
- ; (If illegal, return to CCP)
- ;
- ColChk: bit 2,c ; Is it a ':'?
- jp z,SyntErr ; if not, syntax error
- ; (Return to CCP)
- ; Store hour as a BCD.
-
- StoHM: ld hl,hrBCD
- call DIGtoBCD ; Convert DE into BCD and save at (HL)
- ;
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld d,a
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld e,a
- ;
- ; Store minutes as a BCD.
-
- ld hl,minBCD
- call DIGtoBCD ; Convert DE into BCD and save at (HL)
- ;
- call CTLNxt ; Get next character from COMTAIL,
- ; if some remain
- ; (on illegal char., return to CCP)
- jr nz,StHM1 ; if COMTAIL empty
- ;
- bit 4,c ; Is it a ' '?
- jr nz,StHM1 ; if so, gobble it
- ;
- bit 2,c ; Is it a ':'?
- jp z,SyntErr ; if not, syntax error
- ; (Return to CCP)
- ;
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld d,a
- call CTLDig ; Get a digit from COMTAIL
- ; (If not a decimal digit or if an
- ; illegal char, return to CCP)
- ;
- ld e,a
- jr StrSEC
- ;
- StHM1: ld de,0
- ; Store seconds as a BCD.
-
- StrSEC: ld hl,secBCD
- call DIGtoBCD ; Convert DE into BCD and save at (HL)
- ;
- DSTtog: call CTLNxt ; Get next character from COMTAIL,
- ; if some remain
- ; (on illegal char., return to CCP)
- ;
- jr nz,CkVals ; if COMTAIL empty
- ;
- bit 4,c ; Is it a ' '?
- jr nz,DSTtog ; if so, gobble it...
- ;
- bit 5,c ; Is it an alpha char.?
- jp z,SyntErr ; if not, syntax error
- ; (Return to CCP)
- ld hl,flgBCD
- cp 'Y'
- jr nz,DSTtg1
- ;
- ld a,(hl)
- OR 00000100B ; Merge-in DST flag
- ld (hl),a
- jr CkVals
- ;
- DSTtg1: cp 'N' ; Only other legal answer?
- jp nz,SyntErr ; if not, syntax error
- ; (Return to CCP)
- ld a,(hl)
- and 11111011B ; Reset DST flag
- ld (hl),a
-
- CkVals: ld a,c
- ld (flgbyte),a
- call BCDchk ; verify if readings legal
- ;
- jp nz,DtErr ; if a value out of bound,
- ; diagnostic and return
- ; (to CCP)
- SetClk: call writclk ;
- ;
- jr z,StClk1
- ;
- call eprint ; Display following string on console
- ;
- defb 'Unable to Set the Clock',CR,LF,0
-
- jp ClkHlp ; Give help message
- ;
- StClk1: call readclk ; read the clock
- ;
- jp nz,ClkHlp ; if Clock read error
- ; (Return to CCP)
- xor a
- ld (flgbyte),a
- call PrtDate ; Print the time/date
- ;
- ld a,(flgBCD)
- and 00000100B ; Check DST bit
- jr z,StClk2 ; if DST off
- ;
- call eprint ; Display following string on console
- ;
- defb CR,LF,'Daylight Savings Time '
- defb 'option is enabled.',CR,LF,0
-
- ;
- StClk2: ld a,(secBCD) ; A = <BCD seconds>
- or a
- jr nz,exit ; if set to some value, exit
- ; if not, hold the clock ...
-
- call eprint ; Display following string on console
- ;
- defb CR,LF,'Hit <RETURN> to start clock',0
-
- ;
- ; Go wait for a <CR>. (Keep zero-ing CLKGO)
-
- StClk3: ld b,21 ; point to CLKGO
- call portc ;
- out (c),a ; 0 -> (CLKGO)
- call condin ; Check console for input
- ;
- jr z,StClk3 ; if no input
- ;
- cp CR
- jr nz,StClk3 ; if not a <CR>
- ;
- ld b,21 ; point to CLKGO
- call portc
- out (c),a ; Load 0Dh -> (CLKGO)
-
- exit: ld sp,(stack) ;
- ret ; Back to CCP
- ;
- ClkErr: call eprint ; Display following string on console
- db CR,LF,'The clock is not operational '
- db 'or it has not been programmed.',CR,LF,bell,0
- jr exit
- ;
- ; Subroutine PrtDate - Display date & time.
- ;
- PrtDate: ld a,(flgbyte)
- bit 7,a ; Illegal readings or none?
- jp nz,ClkHlp ; if so, clock broken or not set
- ; (Return to CCP)
-
-
- ; Day of week.
-
- ld a,(line25) ; H19 and 25th line desired?
- or a
- jr z,noline25
- ld hl,cursav ; save current cursor position
- call epstr
- ld hl,enable ; turn on 25th line
- call epstr
- jr PrtDt1
-
- noline25:
- call eprint ;
- defb lf,0 ;
-
- PrtDt1: ; Entry 2nd+ pass of continuous time
-
- ld a,(line25) ; H19 with line 25 desired?
- or a
- jr z,PrtDta
- call at ; get to line 25, column 40
- defb 25,40
- jr PrtDtb
-
- PrtDta: call eprint
- defb cr,' ',0 ;
-
- PrtDtb: ld de,yrBCD ; point to the year
- call pday1 ; print DOW
- call space
- call space
- call pdat1 ; print the date
- inc de ; skip dayBCD
- call space
- call space
- ;
- ld a,(civflg) ; Get the Civilian time flag
- or a ; Is it Military time?
- jr z,PrtDt2 ; Yes, not Civilian time!
- call ptim1 ; print time in 12 hour version
- ld a,'m' ; add the m to p or a
- call cout
- jr timend ;
-
- PrtDt2: call ptim3 ; print 24 hour format
- call space
- ;
- Timend: ld a,0 ; default value (must not be xor a!)
- cont: equ $-1 ;
- or a ;
- ret nz ; We are in continuous update mode
- ld a,(line25) ; H19 with 25th line wanted?
- or a
- jr z,contc ; No?
- ld hl,curret ; return to saved position
- jp epstr
-
- contc: jp crlf
- ;
- ;
- ;
- ; Subroutine CTLNxt - Get character from COMTAIL,
- ; if some remain.
- ;
- CTLNxt: ld a,(CmTail) ; A = <COMTAIL character count>
- or a
- jr nz,CTLCha ; if more remain, get next
- ; and return via "CTLCha"
- ; (If illegal, do not return to Caller)
- ;
- dec a ; A = 0FFh, Z-flg Reset
- ret
- ;
- ;
- ; Subroutine CTLCha - Get a COMTAIL character.
- ; = "CTLChr" (but adds 1 Call level)
- ;
- CTLCha: call CTLChr ; Get a COMTAIL character
- ; (If illegal, do not return to Caller)
- ;
- cp a
- ret
- ;
- ;
- ; Subroutine CTLChr - Get a COMTAIL character.
- ; Inputs: (CMTptr) =.<Next COMTAIL character>
- ; (CmTail) = <Remaining COMTAIL char. count>
- ; Outputs: A = <Next COMTAIL character>
- ; If COMTAIL character: Return in C:
- ; ':' x0000100B
- ; '-' or '/' x0001000B
- ; ' ' x0010000B
- ; 'A .... Z' x0100000B
- ; or 'a .... z'
- ; '0 .... 9' x1000000B
- ; (In all cases bit-7 of C is not altered)
- ;
- ; Note: If none of the above (illegal or no character),
- ; CTLChr does not return to caller but exits via
- ; SyntErr.
- ;
- ;
- CTLChr: ld a,c
- and 10000000B
- ld c,a ; All but MS-bit cleared
-
- ld a,(CmTail) ; A = <COMTAIL character count>
- or a
- jp z,SyntErr ; if none left
- ;
- dec a
- ld (CmTail),a ; Count this one done
-
- ld hl,(CMTptr) ; HL =.<Command Tail char.>
- ld a,(hl) ; A = <Command Tail char.>
- inc hl ; Bump pointer and
- ld (CMTptr),hl ; save it
-
- set 2,c ; Assume ':'
- cp ':'
- ret z ; if ':'
- ;
- res 2,c ; Not a ':',
- set 3,c ; assume a '-' or '/'
- cp '-'
- ret z ; if '-'
- ;
- cp '/'
- ret z ; if '/'
- ;
- res 3,c ; Not a '-' nor '/',
- set 4,c ; assume a ' '
- cp ' '
- ret z ; if ' '
- ;
- res 4,c ; Not a ' ',
- set 6,c ; assume a digit
- cp '0'
- jr c,CTLCh1 ; if not a decimal digit
- ;
- cp ':'
- ret c ; if a decimal digit
- ;
- CTLCh1: res 6,c ; Not a digit,
- set 5,c ; assume an alphabetic char.
- call caps ; Convert A to upper case
- ;
- cp 'A'
- jr c,CTLCh2 ; if not an alphabetic char.
- ;
- cp '['
- ret c ; if an alphabetic character
- ;
- CTLCh2: res 5,c ; Not an alphabetic character
- jr SyntErr
- ;
- ;
- ; Subroutine CTLDig - Get a decimal digit from COMTAIL.
- ; Outputs A = <digit>, if one found.
- ; (If COMTAIL char. is no digit, do not return)
- ;
- CTLDig: call CTLChr ; Get a COMTAIL character
- ; (If illegal character, do not
- ; return to Caller)
- bit 6,c
- ret nz ; if a decimal digit
- ;
- jr SyntErr ; Do not return to Caller
-
- ;
- ; Subroutine eatspc - Accept a 'space' in COMTAIL.
- ; Outputs - If not a 'space', do not proceed.
- ;
- eatspc: call CTLChr ; Get a COMTAIL character
- ; (If illegal character, do not
- ; return to Caller)
- bit 4,c
- ret nz ; if a ' '
- ;
- jr SyntErr ; Do not return to Caller
- ;
- ;
- ; Subroutine cpyCTL - Copy alpha chars from COMTAIL to buffer.
- ; Insert terminating 0 if next character
- ; is not alphabetic.
- ;
- cpyCTL: ld de,Dbuf ; DE =.<Scratchpad>
- cpyCT1: call CTLCha ; Get next character from COMTAIL
- ; (If illegal, do not return to Caller)
- ;
- bit 5,c ; Alphabetic character?
- jr z,cpyCT2 ; if not
- ;
- ld (de),a ; Insert char. in Scratchpad
- inc de ; and bump pointer
- jr cpyCT1 ; Process next COMTAIL character
- ;
- cpyCT2: xor a
- ld (de),a ; Insert terminating 0
- ret
- ;
-
- DtErr: call eprint ; Display following string on console
- ;
- defb CR,LF,'Incorrect Date or Time entry: ',0
-
- jr FindErr
- ;
- SyntErr: call eprint ; Display following string on console
- ;
- defb CR,LF,'Date or Time MUST be entered as '
- defb 'DD-Mon-YY HH:MM only!',CR,LF,0
-
- ;
- FindErr: ld hl,(CMTptr) ; HL =.<Command Tail char.>
- ld a,(CmTail) ; A = <COMTAIL character count>
- or a
- jr nz,PrtErr ; if not the last one
- ;
- inc hl
- PrtErr: xor a
- ld (hl),a ; Insert terminating 0
-
- ld hl,tbuff+1 ; Point to 1st character of COMTAIL
- call epstr ; Print string HL is pointing at
-
- ;
- ClkHlp: call signon ; Display signon screen
-
- ; After printing help then show the clock register values
- ;
- call readclk ; read the clock
- jp nz,ClkErr ; if Clock read error
-
- call eprint
- defb ' Clock registers: ',CR,LF
- defb ' ',0
-
- ld a,(port) ; get the base port
- ld c,a ; C = <Clock base port>
- ld b,16 ; 16 registers to print
-
- PrtReg: in a,(c)
- call pa2hc ; print BCD value in A
- call space
- inc c ; next port
- djnz PrtReg
- ;
- ld b,14 ; make it the FLAGS port
- call portc
- ;
- ChkChr: in a,(c) ; Check charateristics and display
- and 01H
- jr z,ChkCh1
- ;
- call eprint
- defb ' NTL',0 ; Need to leap
- ;
- ChkCh1: in a,(c) ;
- and yokflg
- jr z,ChkCh2
- ;
- call eprint ;
- defb ' YOK',0 ; Year ok bit has been updated
- ;
- ChkCh2: in a,(c) ;
- and DSTflg
- jr z,ChkCh3
- ;
- call eprint ; DST feature enabled
- defb ' DST-opt',0
- ;
- ChkCh3: in a,(c) ;
- and flgDST
- jr z,ChkCh4
- ;
- call eprint ; We are on DST
- defb ' DST',0
- ;
- ChkCh4: call crlf ; Print CR,LF
-
- jp exit
- ;
-
- ;
- ; Subroutine BCDchk - Verify if BCD readings are legal.
- ; Outputs If all readings legal, Z-flg Set,
- ; If not, Z-flg Reset
- ;
- BCDchk: ld de,BCDmax
- ld hl,timBCD
- ld b,7
-
- BCDck1: ld a,(de) ; A = <BCD value>
- cp (hl)
- jr nc,BCDck2 ; if within bounds
- ;
- xor a ; if not,
- dec a ; clear Z-flg
- ret
- ;
- BCDck2: inc de ; Look at next slot,
- inc hl
- djnz BCDck1 ; if more to go...
- ;
- xor a ; Set Z-flg
- ret
- ;
- ;
- ; Subroutine DIGtoBCD - Convert 2 digits into Binary Coded
- ; Decimal and store at (HL).
- ; Inputs DE = <Input digits>
- ; HL =.<BCD storage buffer>
- ; Outputs BCD byte stored at (HL)
- ;
- DIGtoBCD: ld a,e
- and 0FH ; Extract lower nibble
- ld e,a ; E = <LS-digit>
- ld a,d ; D contains MS-digit
- and 0FH ; Extract lower nibble
-
- sla a ; Shift to upper nibble
- sla a
- sla a
- sla a
- or e ; Merge-in LS-digit
- ld (hl),a ; Store BCD
- ret
-
- ;
- ; routine to read the clock
-
- readclk:ld b,14
- call portc
- in a,(c) ; get flags
- ld e,a ;save them
- and okmask ;mask the check bits
- cp setflg ;has the clock been set?
- ret nz ; no. Return
-
- ld d,10 ;10 times to try the read
-
- readtry:ld b,20 ; point to status port
- call portc
- in a,(c) ;reset the counter changed bit
-
- ld b,9 ; year offset
- call portc ; make it so
- in a,(c) ;
- ld hl,yrBCD ; point to the year storage
- ld (hl),a ; save it
- dec c ; decrement the port
- ld b,7 ; read 7 registers
- inc hl ; point to month storage
-
- rdloop: dec c ; decrement the port
- ini ; get the value
- jr nz,rdloop ; again if not zero
-
- ld b,20 ; point to the clock status
- call portc ;
- in a,(c) ; counter bit different?
- or a ;
- jr z,rdok ; no.
-
- dec d ;decrement the attempt count
- jr nz,readtry ; try again if necessary
-
- xor a ;return error
- dec a ;clear the Z flag
- ret ;
-
- rdok: ld hl,monBCD ; point to the month
- ld a,(hl) ;
- dec hl ;point to the year
- bit okbit,e ; okay?
- jr z,fixyr ; no. check it
-
- ; The YEAROK bit is set, do we need to clear it?
-
- cp 7 ;July or later?
- jr c,yearok ; Nope. So jump.
- res okbit,e ;Make the bit 0
- jr yearok ;
-
- ; YEAROK bit not set, 'repair' needed?
-
- fixyr: cp 7 ;July or later??
- jr nc,yearok ; yes. leave the bit clear
- ld a,(hl) ;get the year back
- add a,1 ;increment it
- daa ;fixup BCD
- ld b,9 ; point to the hour
- call portc ;
- out (c),a ; store the updated year value
- ld (hl),a ;
- set okbit,e ;set the bit
-
- ; Leap year or before?
-
- yearok: ld a,(hl) ;get the year
- and 0f0h ;get the MSB
- rrca ;into
- rrca ; the
- rrca ; LSB
- rrca ;
- inc a ;make zero = 1
- ld b,a ;save the MSB
- ld a,(hl) ;get the year back
- inc hl ;HL--> monBCD
- and 00fh ;just the LSB
- ckleap: add a,10 ;add 10 for each MSB unit
- djnz ckleap ;and loop
- sub a,10 ;correct the count
- and 3h ;is it a leap year
- jr z,isleap ; yes. handle it
- cp 3 ;is it a PRE-Leap Year
- jr nz,clrleap ; no. clear the bit
-
- ; Before a leap year?
-
- ld a,(hl) ;get the month
- cp 3 ;after march?
- jr nc,setleap ; yes. set the flag
-
- ; turn the Leap year bit off
-
- clrleap: res lpbit,e ;clear the bit
- jr leapok
-
- ; Leap year stuff
-
- isleap: ld a,(hl) ;get the month code
- inc hl ;HL --> dayBCD
- cp 3 ;is it March yet
- jr c,setleap ; no. just set the bit
- jr nz,chkleap ; (not March) fixup the counters
- ld a,(hl) ;get the date
- cp 1 ;is it after the first
- jr nz,chkleap ; yes. go fixup the counters
-
- ; March 1=February 29
-
- bit lpbit,e ;do we need to lie?
- jr z,leapok ; no. we are done lying
- ld a,29h ;get the 29'th
- ld (hl),a ;store it
- dec hl ;HL --> monBCD
- ld a,2 ;get Februrary
- ld (hl),a ;store it
- jr leapok ;keep the bit set
-
-
- ; If Leap Year change the date
-
- chkleap: bit lpbit,e ;do we need to leap?
- jr z,leapok ; no. all done here
- ld a,(hl) ;get the date
- sub 1 ;backup
- daa ;fixup for BCD
- or a ;is this day zero
- jr nz,monok ; no. then the month is ok
- dec hl ;HL --> monBCD
- ld a,(hl) ;get the month
- sub 1 ;count it down
- daa ;fixit up
- ld (hl),a ;update our copy
- ld b,7 ; point to the month
- call portc ;
- out (c),a ;set the month
- bit 4,a ;is the month > 10?
- jr z,getday ; no. go get the days
- sub 6 ;BCD to Binary
- getday: ld hl,daytbl-3 ;point to our table (Jan Feb missing)
- add a,l ;compute the offset
- ld l,a ;
- jr nc,gotday ;
- inc h ;
- gotday: ld a,(hl) ;get the number of days in the month
- ld hl,dayBCD ;HL--> dayBCD
-
- ; adjust the day
-
- monok: ld (hl),a ;update our storage
- ld b,6 ; point to the day
- call portc ;
- out (c),a ;update the clock
- jr clrleap
-
- setleap: set lpbit,e ;set the leap year bit
-
- ; Leap year stuff done so check out DST
-
- leapok: bit DSTbit,e ;are we enabled?
- jp z,DSTdone ; no. all done
-
- ld hl,monBCD ;HL --> Month
- ld a,(hl) ;get the month
- inc hl ;HL --> dayBCD
- cp 4 ;before April
- jr c,notDST ; yes, not DST then
- jr z,DSTapr ; handle April
- cp 10h ;before October?
- jr c,isDST ; yes, still DST
- jr z,DSToct ; go handle October
- jr notDST ;after October no longer DST
-
- ; April DST stuff
-
- ; DST starts the first Sunday in April
-
- DSTapr: ld a,(hl) ;get the day
- cp 7 ;DST starts April 7 or sooner
- inc hl ;HL --> dowBCD
- jr z,ChkSun ;Today is April 7, is it Sunday?
- jr nc,isDST ;Must be DST as later than April 7
- ; it is April 6 or sooner
- sub (hl) ;Subtract DOW value from Date
- jp m,notDST ;DOW larger than date so Sunday
- ; hasn't happened yet
- ; Today must be 1st Sunday of April or later
-
- ChkSun: ld a,(hl) ;is Today Sunday?
- dec a ;
- jr nz,isDST ; no. then it's DST now
-
- inc hl ;HL --> hrBCD
- ld a,(hl) ;after 2 am
- cp 2 ;
- jr c,notDST ; no. still not DST
- jr isDST ;yes. it's DST now
-
- ; October DST stuff
-
- DSToct: ld a,(hl) ;get the day
- add a,8 ;compute date of next sunday
- daa
- inc hl ;HL --> dowBCD
- sub (hl) ;
- daa
- cp 32h ;will it occur in October?
- jr c,isDST ; Yes. it's still DST
- ld a,(hl) ;is Today Sunday?
- dec a ;
- jr nz,notDST ; no. then it's not DST
-
- inc hl ;HL --> hrBCD
- ld a,(hl) ;after 2 am
- cp 2 ;
- jr c,isDST ; no. it's still DST
- cp 3 ;before 3 am
- jr c,dstdone ; yes. don't change it yet
- jr notDST ;yes. it's not DST
-
- ; DST?
-
- isdst: bit bitDST,e ;have we already done DST?
- jr nz,DSTdone ; yes. Don't do again.
-
- ; Add one hour to the time
-
- ld b,1 ; point the the TENTHS
- call portc
- in a,(c) ; are we in danger of changing times?
- cp 99h ;
- jp z,readclk ; YES. start over
- ld b,4 ; point to hours
- call portc ;
- in a,(c) ; we can not do this at 23:00
- cp 23h ; as we would have to adjust
- jr z,DSTdone ; the day/month/year also!
-
- ld hl,hrBCD ;point to the hour
- ld a,(hl) ;get it
- add a,1 ;advance one hour
- jr DSTfinis ;finish up
-
- ; Not DST
-
- notDST: bit bitDST,e ;have we already cleared DST?
- jr z,DSTdone ; yes. good for us
-
- ; Should be one hour earlier!
- ld b,1 ; point to sec - 1
- call portc
-
- cp 99h ;
- jp z,readclk ; yes. Begin again.
-
- ld b,4 ; point to hours
- call portc ;
- in a,(c) ; Can't do at midnight
- or a ; as we'd have to change
- jr z,DSTdone ; the day/month/year also!
-
- ld hl,hrBCD ;
- ld a,(hl) ;get the hour
- sub a,1 ;backup one
-
- dstfinis: daa ;convert to BCD
- ; ld b,4 ; point to the hour
- ; call portc ;
- out (c),a ; send to the clock
- ld (hl),a ;send to this program also
- ld a,e ;set the DST flag
- xor flgDST ;
- ld e,a ;update our flag
-
- DSTdone: ld a,e ;get our flags
- ld (flgBCD),a ;update the RAM
- ld b,14 ; point to FLAGS
- call portc ;
- out (c),a ;and the clock
- xor a ; say we did it
- ret
-
- ; routine to write the clock
-
- writclk: ld a,(flgBCD) ;get the flag
- and DSTflg ; only do this bit
- or setflg+yokflg ;plus the other flag bytes
- ld e,a ; save the flags
-
- ld a,(monBCD) ;get the month
- cp 7 ;is it after june
- jr c,wr01 ; no.
- res okbit,e ;Yes. clear the yearok bit
-
- wr01: ld hl,yrBCD ;HL --> yrBCD
- ld a,(hl)
- inc hl ;HL --> monBCD
-
- ; See if Leap Year or before a leap year
-
- ld c,a ;save the year in C
- and 0f0h ;get the MSB
- rrca ;into
- rrca ; the
- rrca ; LSB
- rrca ;
- inc a ;make zero = 1
- ld b,a ;save it away
- ld a,c ;get the year back
- and 00fh ;get the LSB
- ck_leap: add a,10 ;add 10 years
- djnz ck_leap ;loop
- sub a,10 ;get the correct value
- and 3h ;is this a leap year
- jr z,leapyr ; yes.
- cp 3 ;is it a preleap
- jr nz,cl_leap ; no. clear the bit
-
- ld a,(hl) ;get the month
- cp 3 ;after march?
- jr nc,set_leap ; yes. set the flag
-
- ; turn the Leap year bit off
-
- cl_leap: ld a,e ;get our flags
- and 0ffh-lpflg ;clear the bit
- jr do_leap
-
- ; Make February 29 be March 1
-
- dofeb29: ld a,1 ;get the 1'st
- ld (hl),a ;store it
- dec hl ;HL --> monBCD
- ld a,3 ;get March
- ld (hl),a ;store it
- jr set_leap ;and set the flag
-
- ; Leap Year Routines
-
- leapyr: ld a,(hl) ;get the month code
- inc hl ;HL --> dayBCD
- cp 2 ;is it February?
- jr nz,notfeb ; no.
- ld a,(hl) ;get the day
- cp 29h ;is it the 29'th?
- jr z,dofeb29 ; yes. fixup our counters
- dec hl ;get the month back
- ld a,(hl) ;
- inc hl
-
- notfeb: cp 3 ;is it March yet
- jr nc,cl_leap ; yes. clear the bit
- ;Otherwise set the bit
-
- ; Assure leap year bit is on
-
- set_leap: ld a,e ;get our flags
- or lpflg ;set the bit
-
- do_leap: ld e,a ;update our internal copy
-
- ; Daylight Savings Time Routines
-
- and DSTflg ;are we enabled?
- jr z,wrtclk ; no. all done
-
- ld hl,monBCD ;HL --> Month
- ld a,(hl) ;get the month
- inc hl ;HL --> dayBCD
- cp 4 ;before April
- jr c,wrtclk ; yes, not DST then
- jr z,DST_apr ; handle April
- cp 10h ;before October
- jr c,is_DST ; yes. still DST
- jr z,DST_oct ; handle October
- jr wrtclk ;after October no longer DST
-
- ; April DST routines
-
- ; DST starts the first Sunday in April
-
- DST_apr:ld a,(hl) ;get the day
- cp 7 ;DST start April 7 or sooner
- inc hl ;HL --> dowBCD
- jr z,Chk_Sun ;Today is April 7, is it Sunday?
- jr nc,is_DST ;must be DST as later than April 7
-
- ; it is April 6 or sooner
-
- sub (hl) ;Subtract DOW value from Date
- jp m,wrtclk ;DOW larger than date so Sunday
- ; hasn't happened yet
- ; Today must be 1st Sunday of April or later
-
- Chk_Sun:ld a,(hl) ;is Today Sunday?
- dec a ;
- jr nz,is_DST ; no. then it's DST now
-
- inc hl ;HL --> hrBCD
- ld a,(hl) ;after 2 am
- cp 2 ;
- jr c,wrtclk ; no. still not DST
- jr is_DST ;yes. it's DST now
-
- ; October DST routines
-
- DST_oct: ld a,(hl) ;get the day
- add a,8 ;compute date of next sunday
- daa
- inc hl ;HL --> dowBCD
- sub (hl) ;
- daa
- cp 32h ;will it occur in October?
- jr c,is_DST ; Yes. it's still DST
- ld a,(hl) ;is Today Sunday?
- dec a ;
- jr nz,wrtclk ; no. then it's not DST
-
- inc hl ;HL --> hrBCD
- ld a,(hl) ;after 2 am
- cp 2 ;
- jr c,is_DST ; no. it's still DST
- jr wrtclk ;yes. it's not DST
-
- ; Daylight Savings Time
-
- is_DST: ld a,e ;get our flags
- or flgDST ;set the DST flag
- ld e,a ;update flags
-
-
- ; Write data to the clock RAM
-
- wrtclk: ld a,(dtonly) ; get date_only flag
- or a ;
- jr nz,wrtck1 ; wants to write date_only
-
- ld b,1 ; point to the TENTHS
- call portc ;
- ld hl,secBCD ;
- ld b,6 ; we have six registers to write
- jr wrtck2 ; go do the year stuff
-
- wrtck1: ld b,4 ; point to the hours
- call portc ;
- ld hl,dowBCD ;
- ld b,3 ; we have three registers to write
-
-
- wrtck2: inc c ; increment the port
- ld a,(hl) ; get the value
- out (c),a ; write it
- dec hl ; point to the next item
- djnz wrtck2 ; and loop
-
- ld b,9 ; point to the year
- call portc
- ld a,(hl) ; get yrBCD
- out (c),a ; send to the clock
-
- ld b,14 ; point to the flags
- call portc ;
- ld a,e ; get the flags
- out (c),a ; update the clock
- in a,(c) ; did clock accept the value?
- cp e ; See if in and out match
- jr nz,wrterr ; Clock is has malfunction or not available
- xor a ; write successful
- ret ; and return
-
- wrterr: xor a
- dec a ; report an error
- ret
- ;
- ; The following code stores the current time in the Z33 registers
- ; when the S option is invoked. Later use of the E option compares
- ; the current time with the saved time and displays the elapsed
- ; time to the hundredths of seconds. Code was removed verbatim
- ; from Terry Hazen's ELAPSED version 10 with only very minor changes
- ; (e.g. jp exit instead of ret!). I appreciate Terry's permission
- ; to use his code here.
- ;
- elapse: call getmsg
- ld a,(timreg)
- add a,30h
- ld e,a
- ld d,0
- add hl,de
- call isbcdt ; Check validity of memory date and time
- jp nz,msgerr
-
- inc hl ; Point to previous time
- inc hl
- inc hl
- inc hl
- ld de,oldbin
- ld a,(hl) ; Old hours
- call bc2bi
- ld (de),a
- inc hl
- inc de
- ld a,(hl) ; Old minutes
- call bc2bi
- ld (de),a
- inc hl
- inc de
- ld a,(hl) ; Old seconds
- call bc2bi
- ld (de),a
- inc hl
- inc de
- ld a,(hl) ; Old tenths
- call bc2bi
- ld (de),a
-
- ld hl,hrBCD
- ld a,(hl) ; New hours
- call bc2bi
- ld (hl),a
- inc hl
- ld a,(hl) ; New minutes
- call bc2bi
- ld (hl),a
- inc hl
- ld a,(hl) ; New seconds
- call bc2bi
- ld (hl),a
- inc hl
- ld a,(hl) ; New tenths
- call bc2bi
- ld (hl),a
-
- ld a,(de) ; DE = address of Julian (old time)
- ld b,a
- ld a,(hl) ; HL = address of Tenths (new time)
- sub b
- jr nc,etime0
- call adjtn
- sub b
-
- etime0: ld (oldbin+3),a ; Do seconds
- dec hl
- dec de
- ld a,(de)
- ld b,a
- ld a,(hl)
- sub b
- jr nc,etime1
- call adjsc
- sub b
-
- etime1: ld (oldbin+2),a
- dec hl ; Do minute
- dec de
- ld a,(de)
- ld b,a
- ld a,(hl)
- sub b
- jr nc,etime2
- call adjmn
- sub b
-
- etime2: ld (oldbin+1),a
- dec hl ; Do hour
- dec de
- ld a,(de)
- ld b,a
- ld a,(hl)
- sub b
- jr nc,etime3
- call adjhr
- sub b
-
- etime3: ld (oldbin),a
-
- ld a,(line25) ; 25th line of H19?
- or a
- jr z,etime6
- ld hl,cursav ; save cursor position
- call epstr
- ld hl,enable
- call epstr
- call at
- defb 25,1
-
- jr etime7
-
- etime6: call crlf
- etime7: call eprint
-
- db ' Elapsed time: ',0
- ld hl,oldbin ; Show elapsed time
- ld a,(hl)
- call bi2bc
- call pa2hc
- call colon
- inc hl
- ld a,(hl)
- call bi2bc
- call pa2hc
- call colon
- inc hl
- ld a,(hl)
- call bi2bc
- call pa2hc
- ld a,'.'
- call cout
- inc hl
- ld a,(hl)
- call bi2bc
- call pa2hc
- ld a,(line25) ; H19 with 25th line?
- or a
- jr z,etimea
- ld hl,curret ; return to save cursor position
- call epstr
- jp exit
- ;
- etimea: call crlf
- jp exit
-
- msgerr: call eprint
- db ' Use "S" option to store current time first!'
- db bell,cr,lf,0
- jp exit
-
- stortim:call getmsg ; Get message buffer address
- ld a,(timreg) ; Get first storage register
- add a,30h ; Add offset
- ld e,a
- ld d,0
- add hl,de
- ex de,hl ; Register address in DE
- ld hl,yrBCD ; Point to date and time buffer
- ld bc,8 ; Eight bytes to move
- ldir
- jp exit
-
- adjtn: dec hl ; Point to second
- ld a,(hl)
- or a ; Zero?
- jr z,adjtn1 ; (yes, adjust it)
- dec (hl) ; No, borrow one
- inc hl ; Point back to tenths
- ld a,(hl)
- add a,100 ; Add borrow
- ret
-
- adjtn1: dec hl ; Point to second
- call adjsc ; Borrow one
- dec (hl)
- inc hl ; Point to tenths
- ld (hl),99 ; Add borrow-1
- ret
-
- adjsc: dec hl ; Point to minute
- ld a,(hl)
- or a ; Zero?
- jr z,adjsc1 ; (yes, adjust it)
- dec (hl) ; No, borrow one
- inc hl ; Point back to second
- ld a,(hl)
- add a,60 ; Add borrow
- ret
-
- adjsc1: dec hl ; Point to hour
- call adjhr ; Borrow one
- dec (hl)
- inc hl ; Point to minute
- ld (hl),59 ; Add borrow -1
- inc hl ; Point back to second
- ld a,(hl)
- add a,60 ; Add borrow
- ret
-
- adjmn: dec hl ; Point to hour
- ld a,(hl)
- or a ; Zero?
- call z,adjhr ; (yes, adjust it)
- dec (hl)
- inc hl ; Point back to minute
- ld a,(hl)
- add a,60 ; Add borrow -1
- ret
-
- adjhr: ld a,(hl) ; Is hour zero?
- add a,24 ; Add borrow from day
- ld (hl),a
- ret
-
-
- ;
- ; Enter with desired port offset in B, returns with port number in C
- ;
- portc: push af ;
- ld a,(port) ;
- add a,b ;
- ld c,a ;
- pop af ;
- ret
-
- montbl: defb 'Jan',0
- defb 'Feb',0
- defb 'Mar',0
- defb 'Apr',0
- defb 'May',0
- defb 'Jun',0
- defb 'Jul',0
- defb 'Aug',0
- defb 'Sep',0
- defb 'Oct',0
- defb 'Nov',0
- defb 'Dec',0
-
- ; Highest legal BCD values in Clock buffer slots.
- ;
- BCDmax: defb 99h ; Year
- defb 12h ; Month
- defb 31h ; Day of month
- defb 07h ; Day of week
- defb 23h ; Hours
- defb 59h ; Minutes
- defb 59h ; Seconds
-
-
- ; Length of each month
-
- lentbl: defb 31H,28H ; lentbl includes daytbl below!
-
- ; BCD table of the days in a month during a leap year (Jan Feb not needed)
-
- daytbl: defb 31h,30h,31h,30h,31h,31h,30h,31h,30h,31h
-
- ; Day of year (for each month's beginning) table.
-
- DOYtbl: defw 0,31,59,90,120,151,181
- defw 212,243,273,304,334
- ;
-
- dseg ;
-
- timBCD:
- yrBCD: ds 1 ; Year goes here
- monBCD: ds 1 ; Month goes here
- dayBCD: ds 1 ; Day of Month goes here
- dowBCD: ds 1 ; Day of Week goes here
- hrBCD: ds 1 ; hours go here
- minBCD: ds 1 ; minutes go here
- secBCD: ds 1 ; seconds go here
- tenBCD: ds 1 ; tenths/hundredths go here
- flgBCD: ds 1 ; Flags
-
- oldbin: ds 4 ; Original binary time buffer
-
- flgbyte:ds 1 ; Flag byte
- CMTptr: ds 2 ; COMTAIL pointer buffer
- CmTail: ds 1 ; COMTAIL character count
- dtonly: ds 1 ; date_only flag
- z33flg: ds 1 ; z33 flag
- Dbuf: defs 60 ; Scratchpad
- defs 64 ; 64 byte stack
- stack: defs 2 ; system stack pointer
-
- END