; -=[ CLOCKOUT - Displays Date & Time from Real-Time Clock/Calendar ]=- ; ; Hardware specific for Oki MSM5832 real-time clock/calendar accessed via ; port B of Z80 PIO (port 79h = data, port 7Bh = control) or via 8255 ; parallel interface (port 30h = clock data, port 31h = clock address, ; port 32h = clock control, port 33h = 8255 control) ; ; Written in 8080 mnemonics for assembly with ASM (or equivalent) by John ; D. Osnes, 1084 6th Street #41, Albany, CA (9/30/86). The author grate- ; fully acknowledges Mike Allen for his contribution of a clock design for ; Morrow Designs Rev.2 computers accessed via an 8255 parallel interface ; and for the corresponding READTIME routine which the 8255 option herein ; is based on. ; ; USER BE AWARE: the author has a Legacy clock accessed via a Z80 PIO, so ; the 8255 option in CLOCKOUT is UNTESTED. What should work may not and no ; fault should be attributed to Mike Allen's fine work. For that matter, ; the author specifically disclaims any warranties, implied or otherwise, ; as to the performance and suitability of CLOCKOUT. ; ; FURTHER NOTES BY MIKE ALLEN: The 8255 option has been verified on my ; homebrew clock using the 8255 option installed in my MD3 and it works as ; advertised. I thank John for some very good work. ; Mike Allen 11/16/86 ; ; FALSE EQU 0 TRUE EQU NOT FALSE ; ************************ ASSEMBLY-TIME OPTIONS ************************** DATE EQU TRUE ; If true, date will be displayed TIME EQU TRUE ; If true, time will be displayed DSPSEC EQU TRUE ; If true, seconds will be displayed in ; time DOFW EQU TRUE ; If true, day of week will be displayed ; with date NUMNTH EQU TRUE ; If true, date will be displayed in ; mn/dy/yr format (month dy, 19yr format ; otherwise) LEAPYR EQU TRUE ; If true, leap year msg will be displayed ; with date when leap year flag in clock ; is set (used primarily as a diagnostic) SPEED EQU 40 ; 10 times speed of CPU in MHz (40=4 MHz) Z80PIO EQU FALSE ; If true, clock accessed via Z80 PIO ; If false, clock accessed via 8255 IF Z80PIO ; Z80 PIO ports (defaults based on Legacy clock) CLKDAT EQU 79H ; Data port for clock (Z80 PIO port B) CLKCTL EQU 7BH ; Control port for clock (Z80 PIO port B) ENDIF ; Z80PIO IF NOT Z80PIO ; 8255 ports (defaults based on Mike Allen's ; design for Morrow Designs Rev.2 clock) CLKDAT EQU 30H ; Data port for clock (8255 port A) CLKADR EQU 31H ; Address port for clock (8255 port B) CLKCTL EQU 32H ; Control port for clock (8255 port C) PRTCTL EQU 33H ; 8255 control port ENDIF ; NOT Z80PIO (8255) ; *************************** END OF OPTIONS ****************************** BDOS EQU 0005H ; BDOS entry point CONOUT EQU 02H ; BDOS "Console Output" function PSTRNG EQU 09H ; BDOS "Print String" function LF EQU 0AH ; Linefeed CR EQU 0DH ; Carriage return ORG 0100H MVI A,13 ; Sweep through 13 addresses of clock MVI E,0 LXI H,SECS ; And store contents in memory SWCLOK: PUSH PSW CALL RDCLOK MOV M,A INR E INX H POP PSW DCR A JNZ SWCLOK IF TIME LXI H,HRS+1 ; Display hr:mn MOV A,M ANI 3 MOV B,A MOV A,M ANI 8 PUSH PSW JNZ HOUR MOV A,B ORA A JZ HOUR2 HOUR: MOV A,B CALL PDIG2 HOUR2: DCX H CALL PDIGIT MVI A,':' CALL PCHAR CALL PDIGIT CALL PDIGIT ENDIF IF TIME AND DSPSEC MVI A,':' ; Display :sc CALL PCHAR CALL PDIGIT CALL PDIGIT ENDIF IF TIME POP PSW ; Display a.m./p.m. if 12-hour clock LXI D,BLANKS ; Display a blanks if 24-hour clock JNZ DISPLA LXI D,AMPMSG+1 LDA HRS+1 ANI 4 JZ AMPM MVI A,'p' STAX D AMPM: DCX D DISPLA: MVI C,PSTRNG CALL BDOS ENDIF IF DATE AND DOFW LDA DOW ; Display day-of-week ADD A MVI D,0 MOV E,A LXI H,DAYS DAD D MOV E,M INX H MOV D,M MVI C,PSTRNG CALL BDOS ENDIF IF DATE AND NUMNTH ; Display mm/dy/yr LXI H,MNTH+1 CALL PDIGIT CALL PDIGIT MVI A,'/' CALL PCHAR MOV A,M ANI 3 CALL PDIG2 DCX H CALL PDIGIT MVI A,'/' CALL PCHAR ENDIF IF DATE AND NOT NUMNTH ; Display month dy, 19yr LXI H,MNTH+1 MOV A,M ADD A MOV B,A ADD A ADD A ADD B DCX H ADD M PUSH H LXI H,MONTHS DCR A ADD A MVI D,0 MOV E,A DAD D MOV E,M INX H MOV D,M MVI C,PSTRNG CALL BDOS POP H DCX H MOV A,M ANI 3 CNZ PDIG2 DCX H CALL PDIGIT MVI C,PSTRNG LXI D,CENTRY CALL BDOS ENDIF IF DATE LXI H,YEAR+1 CALL PDIGIT CALL PDIGIT ENDIF IF DATE AND LEAPYR LDA DAY+1 ; Display leap year flag ANI 4 JZ EXIT MVI C,PSTRNG LXI D,LEAPMS CALL BDOS ENDIF EXIT: MVI C,PSTRNG ; Terminate display with carriage LXI D,CRLF ; Return & linefeed JMP BDOS ; Return to CCP via BDOS PDIGIT: MOV A,M ; Display BCD digit pointed to by HL DCX H ; And decrement pointer PDIG2: ADI '0' ; Display BCD digit in A ; Fall thru PCHAR PCHAR: MOV E,A ; Display char in A MVI C,CONOUT PUSH H CALL BDOS POP H RET IF Z80PIO ; ************************************************************************* ; * Routine reads E=addr from clock interfaced by Z80 PIO and returns * ; * 1 BCD digit in A * ; ************************************************************************* HOLD EQU 10H ; Mask to halt clock READ EQU 20H ; Mask to read clock WRITE EQU 40H ; Mask to set clock ADDRIN EQU 80H ; Mask to enter addr MODE3 EQU 0CFH ; Byte to set clock port (Z80 PIO) to mode 3 RDCLOK: MVI A,MODE3 ; Set clock port to mode 3 OUT CLKCTL ; With all bits for output XRA A OUT CLKCTL MVI A,ADDRIN ; Send addr to clock ORA E OUT CLKDAT MOV A,E ; Latch addr OUT CLKDAT MVI A,MODE3 ; Set lower 4 bits of clock port OUT CLKCTL ; To input MVI A,0FH OUT CLKCTL MVI A,HOLD ; Halt clock OUT CLKDAT RDCLK1 EQU (150*SPEED)/170 MVI A,RDCLK1 ; Wait 150 microseconds RDCLK2: SUI 1 JNC RDCLK2 MVI A,READ+HOLD ; Send read request OUT CLKDAT RDCLK3 EQU (6*SPEED)/170 MVI A,RDCLK3 ; Wait 6 microseconds RDCLK4: SUI 1 JNC RDCLK4 IN CLKDAT ; Get BCD digit (in lower 4 bits) ANI 0FH ; Strip 4 high bits MOV B,A ; Save digit XRA A ; Clear read request & restart clock OUT CLKDAT MOV A,B ; Return BCD digit in A RET ENDIF ; Z80PIO IF NOT Z80PIO ; (8255) ; ************************************************************************* ; * Routine reads E=addr from clock interfaced by 8255 and returns * ; * 1 BCD digit in A (based on Mike Allen's READTIME in MDCLCK11.LBR) * ; ************************************************************************* RDCLOK: MVI A,90H ; Set up 8255 OUT PRTCTL MVI A,20H ; Send read request to clock OUT CLKCTL MOV A,E ; Send address to clock OUT CLKADR RDCLK1 EQU (6*SPEED)/170 MVI A,RDCLK1 ; Wait 6 microseconds RDCLK2: SUI 1 JNC RDCLK2 IN CLKDAT ; Get BCD digit (in lower 4 bits) ANI 0FH ; Strip 4 high bits MOV B,A ; Save digit XRA A ; Clear read request OUT CLKCTL MOV A,B ; Return BCD digit in A RET ENDIF ; NOT Z80PIO (8255) ; ***************************** DATA AREAS ******************************** IF TIME AMPMSG: DB ' a.m.' BLANKS: DB ' $' ENDIF IF DATE AND DOFW DAYS: DW SUN,MON,TUE,WED,THU,FRI,SAT SUN: DB 'Sunday $' MON: DB 'Monday $' TUE: DB 'Tuesday $' WED: DB 'Wednesday $' THU: DB 'Thursday $' FRI: DB 'Friday $' SAT: DB 'Saturday $' ENDIF IF DATE AND NOT NUMNTH MONTHS: DW JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC JAN: DB 'January $' FEB: DB 'February $' MAR: DB 'March $' APR: DB 'April $' MAY: DB 'May $' JUN: DB 'June $' JUL: DB 'July $' AUG: DB 'August $' SEP: DB 'September $' OCT: DB 'October $' NOV: DB 'November $' DEC: DB 'December $' CENTRY: DB ', 19$' ENDIF IF DATE AND LEAPYR LEAPMS: DB ' (Leap Year)$' ENDIF CRLF: DB CR,LF,'$' SECS EQU $ MINS EQU SECS+2 HRS EQU MINS+2 DOW EQU HRS+2 DAY EQU DOW+1 MNTH EQU DAY+2 YEAR EQU MNTH+2 END