home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
ZCPR33
/
S-Z
/
ZTIME23.LBR
/
ZTIME23.MAC
< prev
Wrap
Text File
|
2000-06-30
|
11KB
|
375 lines
;************************************************************************
;
; Version 2.3 Fixed buffer pointer to year to properly
; increment and update YEAR latch at new year.
;
; Included .Z80 pseudo-op for Microsoft M80
; assembler.
;
; Chan Webb -- October 20, 1987
;
;************************************************************************
;
; Version 2.1 Fixed days table to include Tuesday and indexing
; offset into days table.
;
; Richard Jacobson June 30, 1987
;
;************************************************************************
;
; Version 2.0 Fixed stack set-up error, moved stack and string
; buffers to DSEG at end, print "1987" rather than
; "'87", broke out console output stuff to subroutines
; and formatted as ZCPR33 type 3 COMfile. Will still
; work on non-Z33/BGii systems if linked at 100H (use
; ZT0100.COM, ZT8000.COM is linked at 8000H and is for
; for ZCPR33 or BGii - 1.13 or later - only).
;
; Bruce Morgen @11:01:11 June 25, 1987
;
;************************************************************************
;* *
;* Written by Fred Maxwell and released into the *
;* public domain in January of 1987. Do whatever *
;* you want with it, but please give credit where *
;* credit is due. *
;* *
;* ZTIME.MAC - This program reads the time from the Kenmore *
;* Computer Technologies Ztime-I calendar/clock for *
;* Z80 based systems. It is assumed that the clock *
;* is addressed to I/O address E0h. If not, edit *
;* this source file and change BASE to the address *
;* that you have your clock addressed to. There *
;* has been no attempt to optimize this program *
;* due to its inherently small size and fast speed. *
;* It was written with legibility in mind. To *
;* compile this program, use Z80ASM or Z80ASMP(+) *
;* from SLR systems. This is THE BEST Z80 assembler *
;* available and it's from a company that is still *
;* actively supporting CP/M users. Let's support *
;* them by buying their products. *
;* *
;* This program will print the date out as *
;* shown below: *
;* *
;* Sunday January 18, '87 07:43:26 *
;* *
;* * * * * * * * * SPECIAL FEATURE * * * * * * * * *
;* *
;* This program will keep the year correct as long *
;* as it is run at least once every 5 months. It *
;* does this by storing the year in a latch in the *
;* 58167 clock chip. It also stores the month in *
;* another latch. When the time is read, the *
;* current month is compared to the month stored *
;* in the latch. If the current month number is *
;* lower than the month number in the latch, the *
;* year is incremented by one and stored back in *
;* the latch. *
;* *
;************************************************************************
.Z80
BASE EQU 0E0H ; This is the base address of the 58167.
SEC EQU BASE+02H ; Second counter.
MIN EQU BASE+03H ; Minute counter.
HOUR EQU BASE+04H ; Hour counter.
DAY EQU BASE+05H ; Day of week counter.
DATE EQU BASE+06H ; Date of month counter.
MONTH EQU BASE+07H ; Month counter.
YEAR EQU BASE+09H ; 11s latch where we store year.
PRVMON EQU BASE+0FH ; Month on last clock access.
BDOS EQU 00005H ; Address of BDOS entry point.
ZTIME:
JP START
DB 'Z3ENV',3
DW 00
DW ZTIME
DAYS: ; 7 Days x 12 bytes per day (84 bytes).
DB 'Sunday $ '
DB 'Monday $ '
DB 'Tuesday $ '
DB 'Wednesday $'
DB 'Thursday $ '
DB 'Friday $ '
DB 'Saturday $ '
MONTHS: ; 12 months x 11 bytes per month (132 bytes).
DB 'January $ '
DB 'February $ '
DB 'March $ '
DB 'April $ '
DB 'May $ '
DB 'June $ '
DB 'July $ '
DB 'August $ '
DB 'September $'
DB 'October $ '
DB 'November $ '
DB 'December $ '
SEPARATER:
DB ', 19$' ; Between day of month and year.
SPACES:
DB ' - $' ; Between date and time.
CRLF:
DB 0DH,0AH,'$' ; Carriage Return, Linefeed.
START:
LD (STACK),SP
LD SP,STACK ; Use internal stack.
CALL CRLFST
LD HL,BUFFER ; <HL> ----> Date buffer (7 bytes)
CALL RDCLOK ; Get date & time into buffer in packed BCD.
DAY_PRINT:
LD A,(HL) ; Get day number into <A>
INC HL ; Point to month
PUSH HL
DEC A ; 0 = Sunday, 1 = Monday, ..., 6 = Saturday.
LD B,A ; <B> = day x 1
ADD A,A ; X 2
ADD A,A ; X 4
ADD A,B ; X 5
ADD A,A ; X 10
ADD A,B ; X 11
ADD A,B ; X 12
LD E,A ; <E> = Day x 12 = offset into day name table.
LD D,0 ; <DE> = Offset
LD HL,DAYS ; <HL> points to table of days.
ADD HL,DE ; <HL> points to name of day.
EX DE,HL ; <DE> points to name of day.
CALL BPSTR
MONTH_PRINT:
POP HL ; Get pointer to month.
XOR A ; Zero accumulator.
LD B,A ; Zero register <B>.
RLD ; Get tens digit.
JR Z,BINARY ; It's less than 10 if digit is 0
LD B,10 ; Add this to low nibble to make binary.
BINARY:
RLD ; Get ones digit into <A>.
ADD A,B ; Add tens digit.
INC HL ; Point to date.
PUSH HL ; Save pointer
LD B,A ; Save Packed BCD month number.
DEC A ; 0 = Jan., 1 = Feb, ..., 11 = Dec.
LD B,A ; <B> = month x 1
ADD A,A ; X 2
ADD A,A ; X 4
ADD A,B ; X 5
ADD A,A ; X 10
ADD A,B ; X 11
LD E,A ; <E> = Day x 11 = offset into month table.
LD D,0 ; <DE> = Offset
LD HL,MONTHS ; <HL> points to table of months.
ADD HL,DE ; <HL> points to name of month.
EX DE,HL ; <DE> points to name of month.
CALL BPSTR
DATE_PRINT:
POP HL ; Get pointer to date (packed BCD).
LD A,(HL) ; Get packed BCD into <A>.
INC HL ; Point to year.
PUSH HL ; Save pointer.
CALL BCD_PRINT ; Print 2 digits of date.
LD DE,SEPARATER ; Print ', 19'.
CALL BPSTR
YEAR_PRINT:
POP HL ; Get pointer to year (packed BCD).
LD A,(HL) ; Get packed BCD into <A>.
INC HL ; Point to hour.
PUSH HL ; Save pointer.
CALL BCD_PRINT ; Print 2 digits of year.
LD DE,SPACES ; Print " " (3 spaces).
CALL BPSTR
HOUR_PRINT:
POP HL ; Get pointer to hour (packed BCD).
LD A,(HL) ; Get packed BCD into <A>.
INC HL ; Point to minutes
PUSH HL ; Save pointer.
CALL BCD_PRINT ; Print 2 digits of date.
LD E,':' ; Print ":" (colon).
CALL BPCHAR
MIN_PRINT:
POP HL ; Get pointer to minutes (packed BCD).
LD A,(HL) ; Get packed BCD into <A>.
INC HL ; Point to seconds.
PUSH HL ; Save pointer.
CALL BCD_PRINT ; Print 2 digits of minutes.
LD E,'.' ; Print ":" (colon).
CALL BPCHAR
SEC_PRINT:
POP HL ; Get pointer to seconds (packed BCD).
LD A,(HL) ; Get packed BCD into <A>.
CALL BCD_PRINT ; Print 2 digits of seconds.
LD DE,CRLF ; Print CR,LF
CALL BPSTR
LD SP,(STACK) ; Restore it.
RET ; All done.
;************************************************************************
;* *
;* BCD_PRINT - this subroutine prints the two digit packed *
;* BCD number in <A> to the console. *
;* *
;* ON ENTRY: <A> contains packed BCD number. *
;* *
;* ON EXIT: All registers to be considered trashed. *
;* *
;************************************************************************
BCD_PRINT:
PUSH AF ; Save packed BCD number
SRL A ; Get tens digit in low nibble...
SRL A ; And high nibble zeroed.
SRL A
SRL A
ADD A,030H ; Make it ASCII.
LD E,A
CALL BPCHAR
POP AF ; Get packed BCD back in <A>.
AND 0FH ; Strip tens digit.
ADD A,030H ; Make ASCII.
LD E,A
JP BPCHAR
; RET ; All done.
;************************************************************************
;* *
;* RDCLOK - This routine reads the day (1-7), year (00-99), *
;* month (1-12), date (1-31), hours (0-23), minutes *
;* (0-59), and seconds (0-59). These values are *
;* returned as packed BCD in a buffer pointed to *
;* by <HL> in the format: *
;* *
;* BYTE CONTENTS *
;* ---- -------- *
;* 1 Day *
;* 2 Month *
;* 3 Date *
;* 4 Year *
;* 5 Hours *
;* 6 Minutes *
;* 7 Seconds *
;* *
;* NOTE: Since the year is stored in a static location in *
;* the clock, it is incremented whenever the current *
;* month is less than the previous month (also stored *
;* in a static location in the clock). *
;* *
;* ON ENTRY: <HL> points to buffer. *
;* *
;* ON EXIT : <HL> points to buffer. *
;* *
;* NOTE: The seconds are read at the beginning and end of the *
;* clock read. They must be the same to guarantee *
;* that the clock hasn't changed during the read. The *
;* status bit which indicates roll-over is basically *
;* worthless, since the clock can roll over between *
;* reading minutes and hours without ever setting the *
;* bit. This can lead to times like 11:00:00 when it *
;* really just turned to 12 o'clock. *
;* *
;************************************************************************
RDCLOK: PUSH HL ; Save address of buffer.
IN A,(SEC) ; Read seconds first and verify
LD E,A ; That they don't change.
LD C,DAY ; Get the day first.
INI ; Read it and store in buffer.
LD C,MONTH ; Now read the month into buffer.
INI
LD C,DATE ; Read date into buffer.
INI
LD C,YEAR ; Point to the year.
INI ; Read it into the buffer.
LD C,HOUR ; Now, read the hour.
INI
LD C,MIN ; Read minutes into buffer.
INI
IN A,(SEC) ; And finally, read seconds.
CP E ; Did clock change during read?
JR Z,AOK ; We're OK if seconds match.
POP HL ; Restore buffer address.
JR RDCLOK ; Try again.
AOK: LD (HL),A ; Store seconds in buffer.
; Now, adjust the year if current month is less than month at last
; clock read.
POP HL ; HL=start buffer address.
PUSH HL
INC HL ; Point to month storage.
IN A,(PRVMON) ; Month at last clock read.
LD B,A ; <B> = Previous Month
LD A,(HL) ; <A> = Current Month
OUT (PRVMON),A ; Update previous month storage.
CP B ; Is Current < Previous?
JR NC,DONE ; If not, we're done.
INC HL
INC HL ; Point back to year storage.
LD A,(HL) ; <A> = Year.
ADD A,1 ; Year <-- Year + 1
DAA ; Adjust for packed BCD.
LD (HL),A ; Store Year.
OUT (YEAR),A ; In chip, too.
DONE: POP HL ; Restore pointer to buffer.
RET ; All done.
BPCHAR: LD C,2
JR BDJP
CRLFST: LD DE,CRLF
BPSTR: LD C,9
BDJP: JP BDOS
DSEG
BUFFER: DS 7 ; Storage for date and time in packed BCD.
DS 30 ; 15 level stack.
STACK: DS 2
END