; ; ARKDATE - support for Time and Date stamping ; ; 4/18/89 -- Written for Z80DOS file-modify stamps ; ; ; The user should use the area starting at Z80Date .z80 aseg ; keep M80 happy.... org 103h yr: DB 88 ; [103h] mo: DB 4 ; [104h] day: DB 14 ; [105h] hour: db 0 ; [106h] min: db 0 ; [107h] TDate_: jp Signon ; Today's-Date (called at init-time) [108h] FDate_: jp Z80Date ; File-Date (called immediately after F_OPEN) [10Bh] CDate_: ds 3 ; convert and save date (don't overwrite this) [10Eh] Puts_: ds 3 ; handy output routine Signon: ld hl,Version call Puts_ ret Version: db 'Z80DOS Version',10,0 ; Get Z80-DOS date, convert to YYMMDDHHMM and save at 0103h -- DO NOT ; ALTER BC, IX, or IY Z80Date:push ix push iy push bc ld c,54 ; Z80Dos Get-Stamp call 5 ld de,mo inc hl ; skip over creation date inc hl ; and we point to Last Modify ld bc,4 ; only care about the next 4 (no seconds) ldir ; and move for easier access ld hl,(mo) ; ; DATEHL converts the value in HL to BCD year, month, day ; for use with Z80DOS time stamps. ; ; Inputs: HL contains hex days since December 31, 1977 ; ; Outputs: H contains BCD 20th century year ; L contains BCD month ; A contains BCD day ; ; Zero flag set (Z) and A=0 if invalid date (zero) detected, ; Zero flag reset (NZ) and A=0ffh otherwise. ; Converted to 8080 from DATEHL by Carson Wilson who Adapted from B5C-CPM3.INS DateHL: LD A,H OR L ; Test blank date (zero) jp Z,nodate ; make date = 00/00/00 00:00 LD (DAYS),HL ; Save initial value LD B,78 ; Set years counter loop: call ckleap LD DE,-365 ; Set up for subtract jr NZ,NOLPY ; Skip if no leap year DEC DE ; Set for leap year nolpy: ADD HL,DE ; Subtract jr NC,YDONE ; Continue if years done LD A,H OR L jr Z,YDONE LD (DAYS),HL ; Else save days count INC B ; Increment years count jr LOOP ; And do again ; ; The years are now finished, the years count is in 'B' (HL is invalid) ; ydone: LD A,B LD (yr),A ; save year ; call ckleap ; Check if leap year LD A,-28 JP NZ,FEBNO ; February not 29 days LD A,-29 ; Leap year febno: LD (FEB),A ; Set february LD HL,(DAYS) ; Get days count LD DE,MTABLE ; Point to months table LD B,0FFH ; Set up 'B' for subtract LD A,0 ; Set a for # of months mloop: PUSH AF LD A,(DE) ; Get month LD C,A ; Put in 'C' for subtract POP AF LD (DAYS),HL ; save days count ADD HL,BC ; Subtract INC DE ; Increment months counter INC A jr C,MLOOP ; Loop for next month ; ; The months are finished, days count is on stack. First, calculate ; month. ; mdone: LD B,A ; Save months LD HL,(DAYS) LD A,H OR L jr NZ,NZD DEC DE DEC DE LD A,(DE) CPL INC A LD L,A DEC B nzd: LD A,L ; Retrieve binary day of month ld (day),a ; LD A,B ; Retrieve the binary month ld (mo),a ; OR A ; Set NZ flag jtoc4: ld a,(hour) ; Z80DOS (and DRI) want the time as BCD -- call bcd2bin ; better convert it to binary for ARK ld (hour),a ld a,(min) call bcd2bin ld (min),a nodate: pop bc pop iy pop ix call CDate_ ; make it readable to ARK ret bcd2bin: ld d,a and 0fh ; E = the 1's digit ld e,a ld a,d ; get back our BCD number and 0f0h ; mask off ones for just the 10's rrca rrca rrca rrca ; and put in LS bits ld d,a ; save a copy for multiplying back add a,a ; times 2 add a,a ; " 4 add a,a ; times 8 add a,d ; times 9 add a,d ; times 10 add a,e ; add in ones ret ; and we're done! ; ; Support Routines: ; ; ; Check for leap years. ; ckleap: LD A,B AND 0FCH CP B ret mtable: db -31 ;January feb: db -28 ;February db -31,-30,-31,-30 ;Mar-Jun db -31,-31,-30 ;Jul-Sep db -31,-30,-31 ;Oct-Dec days: dw 0 ; temp storage end