;------------------------- KPLTIME.ASM -------------------------------- ; TIME program for the LEGACY Computer Systems Real Time Clock (RTC) ; Modified for Kaypro, prints time/date string on screen or in reverse ; video or on the 25th status line on a Kaypro video capable machines. ; This program will run on either the Kaypro 2/4 or Kaypro 10 depending ; on the on selected equates, in the optional configuration section below. ; ; Use: A0>time print time/date ; A0>time set set the clock mode, can also be ; A0>time s ;---------------------------------------------------------------------- ; 07/11/86 This version contains equates so this program will work for ; V 3.0 Kaypro 2,4,or 10 depending on the equates set. Other NEW ; equates allow you to either or do reverse video, so this ; program can also be used on 83 machines. ; Ernest-Hintz KAY+FUN-RCP/M-SYSTEM (415)572-8219 ;---------------------------------------------------------------------- ; modified from K10TIME.ASM ; Modified for Kaypro 10, prints time/date string on the ; 25th status line in inverse video. - Steve Sanders ;---------------------------------------------------------------------- VER1 EQU 03 ; Main program version number VER2 EQU 00 ; Program version number ;MINE EQU 00 ; Your own version number for own changes ; NO EQU 0 YES EQU NOT NO ; For conditional assembly ;====================================================================== ; OPTIONAL CONFIGURATION SECTION ;====================================================================== ; NOTK10 EQU YES ; YES, if Kaypro 2 or 4 KPRO10 EQU NO ; YES if Kaypro 10 ; The above has written intentionally ; to protect the novice if he messes up. ; VIDEO EQU NO ; YES, if using Kaypro video ; NO, for no reverse video LINE25 EQU NO ; YES, if using the 25th status line ; this will not work on 83 kaypro's ;====================================================================== ; Pio addresses with the standard Ports for ; ; KAYPRO 2 or 4 IF NOTK10 AND (NOT KPRO10) BDATA EQU 0AH ; port B data BCMND EQU 0BH ; port B command ENDIF ; ; KAYPRO 10 IF KPRO10 AND (NOT NOTK10) BDATA EQU 079H ; port B data BCMND EQU 07AH ; port B command ENDIF ; HOLD EQU 16 ; Hold 5832 to set up read/write WR EQU 64 ; Read 5832 RD EQU 32 ; Write 5832 MODE0 EQU 0FH ; Pio output mode MODE3 EQU 0CFH ; Pio control mode ; ;---------------------------------------------------------------------- ; Bdos equates ; BDOS EQU 5 ; CP/M entry point CONO EQU 2 ; Console output function CPRT EQU 9 ; Print string to console function RCONS EQU 10 ; Read console buffer function FCB EQU 5CH ; Default file control block CBUF EQU 80H ; console buffer TPA EQU 100H ; Transient Program Area ; ; ASCII equates ; CR EQU 13 ; Carriage return code LF EQU 10 ; Line feed code ; ;---------------------------------------------------------------------- ; Program begins ; ORG TPA ; Transient Program Area ; START: LXI H,0 ; clear it DAD SP ; put stack ptr in it SHLD STACK ; save it for exit LXI SP,STACK ; set local stack ; ; Set port to output mode ; BEGIN: MVI A,MODE0 ; output mode OUT BCMND ; command port MVI A,3 ; disable interrupts OUT BCMND ; command port ; ;---------------------------------------------------------------------- ; Main program ; LXI H,TIME ; clock buffer MVI C,13 ; read 13 bytes MVI A,1 CL1: MOV M,A ; move em to buffer INX H DCR C ; dec register JNZ CL1 ; if not zero, loop ; LDA FCB+1 ; check the fcb for set option ANI 5FH ; force upper case CPI 'S' ; is it 's' or 'S' JNZ TIM ; if not, tell time and exit CALL SETTIM ; or do the set clock routines ; ;---------------------------------------------------------------------- ; Screen display time/date either plain, video, or 25th status line. ; TIM: CALL ILPRT ; print to Kaypro CRT ; ; For video kaypro's only IF LINE25 DB 1BH,'C7' ; disable 25th line DB 1AH ; clear screen/25th line DB 1BH,'B7' ; enable 25th line DB 1BH,'=8 ' ; load cursor to 25,0 ENDIF ; IF VIDEO DB 1BH,'B0' ; inverse video ON DB 1BH,'B1' ; dim video on ENDIF ; DB ' Time ',0 ; print time/date line CALL TELTIM ; tell the time JMP EXIT ; and exit ; ; Read the clock digits from the buffer ; TELTIM: CALL RDMOD ; set chb to read mode LXI H,TIME ; clock buffer MVI C,13 ; # bytes to read TTLP: MOV A,L ANI 0FH ; mask off high nybble CALL RDCLK MOV M,A ; store it in clock buffer INX H ; bump buffer ptr DCR C ; finished? JNZ TTLP ; guess not ; ; Output clock buffer to screen ; hh:mm:ss format ; LHLD HOUR ; hours MOV A,H ; 10's digit ANI 3 ; mask hi bits CALL ASCII ; to screen MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,':' ; separator CALL TYPE ; to screen LHLD MIN ; minutes MOV A,H ; 10's digit CALL ASCII ; to screen MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,':' ; separator CALL TYPE ; to screen LHLD SEC ; seconds MOV A,H ; 10's digit CALL ASCII ; to screen MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,' ' ; space CALL TYPE ; to screen MVI A,' ' ; turn up a CALL TYPE ; blank space MVI A,' ' ; ditto CALL TYPE ; ; Day of the week LDA DAY ; varies from 0 - 6 ANI 7 ; mask hi bits MOV L,A ; preset hl MVI H,0 DAD H ; day * 2 for table offset LXI D,DAYS ; point to days table DAD D ; point to day of week MOV E,M ; move pointer to de INX H MOV D,M MVI C,CPRT ; print string CALL BDOS ; print day of week MVI A,' ' ; print a CALL TYPE ; blank space ; ; Month of the year (varies from 1 to 12) LDA MONTH+1 ; 10's digit ANI 1 ; is it October or later? JZ MONT ; guess not MVI A,10 MONT: MOV L,A ; A = 0 or 10 MVI H,0 LDA MONTH ; 1's digit ANI 0FH ; mask hi bits ADD L MOV L,A ; month in hl DCX H ; rel zero for months table DAD H ; times 2 for offset LXI D,MONTHS ; point to table DAD D ; point to month MOV E,M ; move pointer to de INX H MOV D,M MVI C,CPRT CALL BDOS ; month to console ; Date of the month LHLD DATE ; date of month MOV A,H ; 10's digit ORA A ; is it zero? JZ DATL ; if so CALL ASCII ; to screen if not DATL: MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,',' ; space CALL TYPE ; to screen mvi a,' ' ; print a call type ; blank space ; Print year to console CALL ILPRT DB '19',0 ; print century LDA YEAR+1 ; 10's digit CALL ASCII ; to screen LDA YEAR ; 1's digit CALL ASCII ; to screen CALL ILPRT ; print ; ; For video kaypro IF VIDEO DB ' ',1BH,'C0' ; inverse video OFF DB 1BH,'C1' ; dim video off ENDIF IF LINE25 DB 1AH ; home cursor/clear screen ENDIF DB 0 RET ; to exit SETTIM: ; ; Ask 'What time is it?' ; MVI A,80H ; max console buffer length STA CBUF ; init buffer length CALL ILPRT ; print setting message DB 1AH ; clr screen ; ; For video kaypro IF VIDEO DB 1BH,'B0',1BH,'B1' ; clr screen/inverse video on DB ' Set Kaypro Legacy Clock. ' DB 'Ver ',VER1+'0','.',VER2+'0' DB 1BH,'B2',' CTRL-C to Exit ' DB 1BH,'C0',1BH,'C1',1BH,'C2' ; inverse video & blinking off DB CR,LF,LF ENDIF ; ; For regular kaypro IF (NOT VIDEO) DB ' Set Kaypro Legacy Clock. ' DB 'Ver ',VER1+'0','.',VER2+'0' DB ' CTRL-C to Exit ' DB CR,LF,LF ENDIF ; ; For video kaypro IF VIDEO DB 1BH,'B3' ; dim mode on DB 'Enter the year? (e.g. 86) ' DB 1BH,'C3',' : ',0 ; dim mode off ENDIF ; ; For non-video kaypro IF (NOT VIDEO) DB 'Enter the year? (e.g. 86) : ',0 ENDIF ; LXI D,CBUF ; console buffer MVI C,RCONS ; read console buffer CALL BDOS LDA CBUF+1 ; length ORA A ; no entry? JZ SMONTH ; next LXI H,CBUF+2 ; first digit MOV A,M ANI 0FH ; strip ascii STA YEAR+1 ; store it INX H ; next digit MOV A,M ANI 0FH ; strip ascii STA YEAR ; store it ; SMONTH: CALL ILPRT DB CR,LF,CR,LF ; ; For video kaypro IF VIDEO DB 1BH,'B3' ; dim mode on DB 'Enter month? (Jan = 01, Feb = 02, etc.) ' DB 1BH,'C3',' : ',0 ; dim mode off ENDIF ; ; For non-video kaypro IF (NOT VIDEO) DB 'Enter month? (Jan = 01, Feb = 02, etc.) : ',0 ENDIF ; LXI D,CBUF MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ SDATE ; no month specified LDA CBUF+2 ANI 0FH STA MONTH+1 LDA CBUF+3 ANI 0FH STA MONTH ; SDATE: CALL ILPRT ; in-line print DB CR,LF,CR,LF ; ; ; For video kaypro IF VIDEO DB 1BH,'B3' ; dim mode on DB 'Enter today''s date? (i.e. 01 to 31) ' DB 1BH,'C3',' : ',0 ; dim mode off ENDIF ; ; For non-video kaypro IF (NOT VIDEO) DB 'Enter today''s date? (i.e. 01 to 31) : ',0 ENDIF ; LXI D,CBUF ; console buffer MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ SDAY ; LDA CBUF+2 ; 10's digit ANI 0FH ; mask hi nybble STA DATE+1 LDA CBUF+3 ANI 0FH STA DATE ; SDAY: CALL ILPRT DB CR,LF,CR,LF ; ; For video kaypro IF VIDEO DB 1BH,'B3' ; dim mode on DB 'Enter the day (Sun = 1, Mon = 2, etc.) ' DB 1BH,'C3',' : ',0 ; dim mode off ENDIF ; ; For non-video kaypro IF (NOT VIDEO) DB 'Enter the day (Sun = 1, Mon = 2, etc.) : ',0 ENDIF ; LXI D,CBUF MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ STIME ; no day specified LDA CBUF+2 ANI 0FH DCR A ; rel 0 STA DAY ; STIME: CALL ILPRT DB CR,LF,CR,LF ; ; For video kaypro IF VIDEO DB 1BH,'B3' ; dim mode on DB 'Enter current time (24-hour mode 1545 = 3:45p) ' DB 1BH,'C3',' : ',0 ; dim mode off ENDIF ; ; For non-video kaypro IF (NOT VIDEO) DB 'Enter current time (24-hour mode 1545 = 3:45p) : ',0 ENDIF ; LXI D,CBUF MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ SETCLK ; no time specified LDA CBUF+2 ANI 0FH ORI 8 ; 24 hour format STA HOUR+1 LDA CBUF+3 ANI 0FH STA HOUR LDA CBUF+4 ANI 0FH STA MIN+1 LDA CBUF+5 ANI 0FH STA MIN CALL ILPRT ;LINE FEED THEN PRINT DB CR,LF,CR,LF,LF,0 ; ; Write the time buffer to the clock ; SETCLK: CALL WRMOD LXI H,TIME MVI C,13 STCLK1: MOV E,M MOV A,L ANI 0FH CALL WRCLK INX H DCR C JNZ STCLK1 RET ; ILPRT: POP H ; hl points to string ILP1: MOV A,M ; get the character INX H ; point to next character ORA A ; is this the zero terminator? JZ ILEX ; yep. we'RE DONE CALL TYPE ; to screen JMP ILP1 ; do it again ILEX: PCHL ; jump to instruction following string ; ASCII: ADI 30H ; binary to ascii TYPE: PUSH PSW ; out to screen, saving all registers PUSH H PUSH D PUSH B MOV E,A MVI C,CONO ; console output CALL BDOS POP B POP D POP H POP PSW RET ; RDCLK: ; FOR KCLOCK push psw ; save address call wrmod ; setup pio pop psw ori hold+80h ; add hold and address gate bit out bdata ; set address and gate ani 7fh ; reset gate bit out bdata ; address is now latched call wait ; 150 usec to establish hold call rdmod ; setup to read lo nybble mvi a,hold+rd ; add read command to hold out bdata call wait1 ; wait 6 usec in bdata ; read clock ani 0fh ; mask hi nybble push psw ; save it xra a ; clear a out bdata ; release hold pop psw ; restore clock data ret ; wrclk: ; for KClock push psw ; save address call wrmod pop psw ori hold+80h ; hold plus address gate bit out bdata ANI 7FH ; reset gate bit out bdata call wait ; wait 150 usec to establish hold mvi a,hold+wr ; add write command to hold ORA e ; data to write out bdata PUSH PSW call wait1 ; wait 6 usec POP PSW XRI WR ; turn off write command OUT BDATA xra a ; clear a out bdata ; release hold ret ; ; set port b to write the clock WRMOD: MVI A,MODE3 ; control mode OUT BCMND MVI A,0 ; write to clock OUT BCMND RET ; ; set port b to read the clock RDMOD: MVI A,MODE3 ; control mode OUT BCMND MVI A,0FH ; to read clock OUT BCMND RET ; wait: ; 150 usec timing loop mvi a,54 ; loop control w0: dcr a jnz w0 ret ; wait1: ; 6 usec timing loop mvi a,3 jmp w0 ; EXIT: LHLD STACK SPHL RET ; TIME: EQU $+15 AND 0FFF0H ; 16-byte boundary ORG TIME SEC: DS 2 ; seconds MIN: DS 2 ; minutes HOUR: DS 2 DAY: DS 1 ; day of week DATE: DS 2 MONTH: DS 2 YEAR: DS 2 ; DAYS: DW SUN DW MON DW TUE DW WED DW THU DW FRI DW SAT ; SUN DB 'Sunday $' MON DB 'Monday $' TUE DB 'Tuesday $' WED DB 'Wednesday $' THU DB 'Thursday $' FRI DB 'Friday $' SAT DB 'Saturday $' ; MONTHS: DW JAN DW FEB DW MAR DW APR DW MAY DW JUN DW JUL DW AUG DW SEP DW OCT DW NOV DW 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 $' ; DS 32 STACK: END START