; ARK02PAT.AZM ; ---------- ; This is a patch file for ARK02.COM that will set the date and time on all ; members to be added or updated to the system date and time. To install for ; your system, write a routine at SYSDT: which fills the bytes at ; MONTH,DAY,YEAR,HOUR,MIN, and SEC with the appropriate values. (If, ; for instance, you have system date but not time, just fill in the date; ; the time will default to midnight.) As it stands this file is configured ; to make a CP/M 3 "get date and time" BDOS call. ; ; When you're ready to do the patch, assemble with Z1 (included) or some other ; assembler: ; Z1 ARKPAT ; and overlay with DDT, or (better) Ron Fowler's MLOAD: ; MLOAD ARK02.COM,ARKPAT ; And et voila! ARK will now fill in the system date & time. ; ; Acknowledgements: ; First of all, of course, Thom Henderson for inventing the MSDOS ARC format! ; Brian Moore for porting and hand-optimizing (ugh!!) ARK02. ; Tom P. Douglas for digging into ARK02 and locating ARKDATE:, and ; releasing ARKDATER.LBR. This program patched ARK to permanently ; change the default date and time. ; Steven G. Greenberg, for his LDIR-B library directory program, from ; which the code to interpret a DRI date was lifted almost unchanged. ; ;--------------------------------------------------------------------------- ; ORG 100h JP GETDT ;get date before beginning program START: EQU 2A21H ;ARK has a JP 2A21H at 100h, which we overlaid ENDPRG: EQU 4901H ;This is 1 byte after the last page of ARK ARKDATE: EQU 453EH ;Address of default date-and-time within ARK ; ; KAYPRO RTC EQUATES ; PIOADD EQU 0FH ; pio address CLKADD EQU 20H ; rtc register select CLKCTL EQU 22H ; rtc mode control CLKDAT EQU 24H ; rtc data MONRTC EQU 07H ; rtc months register DAYRTC EQU 06H ; rtc days register HRSRTC EQU 04H ; rtc hours register MINRTC EQU 03H ; rtc minutes register SECRTC EQU 02H ; rtc seconds register ORG ENDPRG MONTBL: DB 31 ;This is the table of month lengths used FEB: DB 28,31,30,31,30,31,31,30,31,30,31 ;in the SYSDAT routine. Note!!! If the ;SYSDAT routine in the original ARKPAT.AZM ;is used, MONTBL MUST BEGIN AT xx01h (i.e. ;1 byte after a page boundary). MONTH: DB 0 ;these values will be filled in by SYSDT DAY: DB 0 YEAR: DB 0 HOUR: DB 0 MIN: DB 0 SEC: DB 0 ADDIT: ;subroutine to add A to HL &shift B bits right ADD A,L ;low byte LD L,A ;save it LD A,H ;high byte ADC A,0 ;include possible carry LD H,A ;save it INC B ;is B zero? DEC B RET Z ;yes, don't shift SHIFTR: ADD HL,HL ;shift left one bit DJNZ SHIFTR ;loop B times RET ;return GETDT: CALL SYSDT ;fill in date and time LD HL,0 ;clean slate LD A,(YEAR) ;get year SUB 80 ;MSDOS dates begin with 1980 LD B,4 ;shift 4 bits CALL ADDIT ;do it LD A,(MONTH) ;get month LD B,5 ;shift 5 more bits CALL ADDIT ;do it LD A,(DAY) ;get day CALL ADDIT ;shift zero bits LD (ARKDATE),HL ;save into ARK LD HL,0 ;clean slate LD A,(HOUR) ;get hour LD B,6 ;shift 6 bits CALL ADDIT ;do it LD A,(MIN) ;get minute LD B,4 ;shift 4 bits CALL ADDIT ;do it LD A,(SEC) ;get second LD B,1 ;shift 1 bit CALL ADDIT ;do it LD (ARKDATE+2),HL ;save into ARK JP START ;continue with ARK program ; BCD2BIN: ;subroutine to convert from BCD to binary LD B,0 ;zero counter OR A ;if BCD is zero, get out RET Z BBLOOP: INC B ;count one DEC A ;dec one (BCD) DAA JR NZ,BBLOOP ;continue if not done LD A,B ;load binary value RET ;done ; CPM3DT: ;data area filled by BDOS CJUL: DW 0 ;days since 31 Dec 79 CHR: DB 0 ;hour (BCD) CMIN: DB 0 ;min (BCD) CSEC: DB 0 ;sec (BCD) SYSDT: ; ; FETCH RTC DATA ; LD A,PIOADD ; set rtc status OUT CLKCTL,A LD A,88H ; year for kaypro CALL BCD2BIN LD (YEAR),A LD A,MONRTC ; get month CALL GETDRI CALL BCD2BIN LD (MONTH),A LD A,DAYRTC ; get day CALL GETDRI CALL BCD2BIN LD (DAY),A LD A,HRSRTC ; get hour CALL GETDRI CALL BCD2BIN LD (HOUR),A LD A,MINRTC ; get minute CALL GETDRI CALL BCD2BIN LD (MIN),A LD A,SECRTC ; get second CALL GETDRI CALL BCD2BIN LD (SEC),A ; ; GET DATE/TIME FROM RTC SUBROUTINE ; ŠGETDRI: OUT CLKADD,A ; output rtc address IN A,CLKDAT ; input rtc data RET ;---------------------------- ; The rest of the code is lifted almost without change from Steven G. ; Greenberg's LDIR-B utility (release 1.2). Many thanks. LD A,78 ; Init to 1978 LD DE,365 ; Amount to subtract per year (except leap) LD B,28 ; # of days in Feb for current year ; YRLP: AND A ; Clear carry SBC HL,DE ; Subtract 1 year JR Z,GOTYR JR C,GOTYR ; If carry, we've gone too far INC A ; Else incr year by one AND A SBC HL,DE ; Repeat for the following [non-leap] year JR Z,GOTYR JR C,GOTYR INC A INC B ; The following year IS a leap year INC DE ; So use 366 for DE and flag B with a "29" AND A SBC HL,DE JR Z,GOTYR JR C,GOTYR INC A DEC DE ; Put year and # of Feb days back to normal DEC B AND A SBC HL,DE ; Repeat for one more [non-leap] year JR Z,GOTYR JR C,GOTYR INC A JR YRLP ; And loop ; ;............................................................................ ; GOTYR: ADD HL,DE ; Reverse the last subtraction with current val LD (YEAR),A ; The correct year value LD A,B ; And save current Feb val for future ref LD (FEB),A LD BC,MONTBL ; Table of # of days/month ; MNTHLP: LD A,(BC) ; Get # of days LD E,A ; Put it in DE LD D,0 AND A SBC HL,DE ; Subtract JR Z,GOTMON JR C,GOTMON ; If carry, we've gone too far again INC BC ; Else move ahead to the next month LD A,C CP 13 ; (table is <256 bytes, so this is OK) JR NZ,MNTHLP ; GOTMON: ADD HL,DE ; Once again, add back in LD A,C ; month # LD (MONTH),A LD A,L ; The remainder should be the day# OKD: LD (DAY),A RET ; And that's it! ;