home *** CD-ROM | disk | FTP | other *** search
- ; CRR Time overlay (c) 1993 Paul Martin, version 1.60
- ; ================
- ; Last update 14 Nov 93
- ;
- ; This is the standard overlay which works for standard CP/M 2.2
- ; CP/M 3.1 (Plus) and ZSDOS/ZDDOS.
- ;
- ; Under CP/M 3.1 the time is obtained using BDOS function 105.
- ; Under CP/M 2.2 the time is "fudged"
- ;
- ; This file should be assembled using David Goodenough's ZSM23,
- ;
- ; ZSM CRRTIM
- ;
- ; and applied to CRR using his ZPATCH
- ;
- ; ZPATCH CRR CRRTIM
- ;
- ;
- .org 0x2100
-
- entry:
- jp gettad
-
- ; table starts at 0x2103
-
- year: dw 0 ; Year
- month: db 0 ; Month 1=Jan, 2=Feb, .. 12=Dec
- day: db 0 ; Day of month
- dow: db 0 ; Day of week 1=Sun, 2=Mon,.., 7=Sat
- hour: db 0 ; Hour in 24h format 0=midnight, 13=1pm
- mins: db 0 ; Minute
- secs: db 0 ; Second (if supported, zero otherwise)
- rtc: db 0 ; non-zero if rtc present
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;; DO NOT CHANGE ANYTHING ABOVE THIS LINE ;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; The space 0x2100 to 0x22ff (512 bytes) has been set aside for
- ; real time clock overlays.
- ;
- ; You may freely modify this overlay for use as a CRR time
- ; overlay. The single condition of its use is that if you modify
- ; it, you should make public your modifications so that other
- ; people with similar equipment may be able to use it.
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Jul2Day
- ; - Day of year -> year,month,day converter
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- jul2day:
- ;
- ; Entry:
- ; HL = Day of year
- ; BC = Year
- ; Exit:
- ; E = Month
- ; D = Day
- ; BC = Year
- ; all other registers and flags preserved
- ;
- push af ; save registers
- push ix
- push hl
- push bc
-
- ld de,1 ; month = 1
- ld ix,dayinmo
- jullp: ld b,(ix) ; how many days in month(e)
- ld a,e ; a=month
- cp 2
- jr nz,jntlp ; not February
- ld a,c ; a=year mod 256 (no check for 2100AD)
- and 3
- jr nz,jntlp ; not leap year
- inc b ; 29 days in Feb in leap yr
- jntlp:
- ld a,l ; a=lsb end of "day of year"
- sub b ; subtract length of month
- ld l,a ; l=result (mod 256)
- jr c,jcarry ; b>l
- or a
- jr nz,jncrry ; l<>0
- or h ; h==0?
- jr z,jfin
-
- jncrry: inc e ; next month
- inc ix
- jr jullp
-
- jcarry:
- inc h
- dec h
- jr z,jfin
- dec h
- jr jncrry
-
- jfin: ld a,l
- add a,b
- ld d,a
- pop bc
- pop hl
- pop ix
- pop af
- ret
-
- dayinmo: ; data for jul2day
- db 31,28,31,30,31,30,31,31,30,31,30,31
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; BCD2Bin
- ; - BCD to Binary converter
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- bcd2bin:
- ;
- ; Entry:
- ; A = BCD number
- ; Exit:
- ; A = binary number
- ; flags corrupted
- ;
- push bc
- ld b,a ;save a
- and 0xf0 ; mask off lower bits
- srl a ;x8
- ld c,a ; store a*8
- srl a ;x4
- srl a ;x2
- add a,c ;x2 + x8 = x10
- ld c,a
- ld a,b
- and 0x0f
- add a,c
- pop bc
- ret
-
-
- ;;;;;;;;;;
- ; CPM2Jul
- ; CPMDate (days since Jan 1 1978) -> year, dayofyear
- ;;;;;;;;;;
- cpm2jul:
- ;
- ;
- ; Entry:
- ; HL = CPMdate
- ; Exit:
- ; BC = year
- ; HL = dayofyear
- ; all other registers and flags preserved
- ;
- push af
- push de
- ld de,1978 ; Base year = 1978
- c2jl: ld bc,365 ; yearlen = 365 days
- ld a,e ; is leap year?
- and 3
- jr nz,c2j1
- inc bc ; Yes, year = 366 days
- and a ; clear carry
- c2j1: sbc hl,bc ; cpmdate -= yearlen.
- jr c,c2j2
- jr z,c2j2
- inc de ; not this year
- jr c2jl ; go round again
- c2j2: add hl,bc ; restore days
- ld b,d
- ld c,e
- pop de
- pop af
- ret ; get out
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Zeller
- ; - Zeller's congruence for dates later than 1978
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- zeller:
- ;
- ; Entry conditions:
- ; year, month and day contain legal values
- ;
- ; Exit:
- ; dow is set correctly
- ;
- ; all registers and flags preserved
- ;
- push af
- push hl
- push de
- push bc
- ld bc,(year)
- ld de,(month)
-
- push bc ; save for later
- push de ; ditto
- ld h,b
- ld l,c ; HL = year
-
- push hl
- ld bc,1978
- or a
- sbc hl,bc ; HL = year - 1978
- jr nc,zdateok
- ld bc,1900 ; done too much
- add hl,bc ; add it back
- zdateok:
- ex (sp),hl ; (SP) = year-1978, HL=year
-
- ld bc,1976
- or a
- sbc hl,bc ; HL=year-1976
- jr nc,zdate2
- ld bc,1900 ; done too much
- add hl,bc ; add it back
- zdate2:
- srl h
- rr l ; div 2
- srl h
- rr l ; div 4
- ex de,hl
- pop hl ; HL = (year-78), DE=(year-76)div 4
- add hl,de ; HL = HL+DE
-
- pop de ; D = day, E = month
- push de ; save again
-
- push hl ; save this, too
- ld hl,monmod
- dec e
- ld d,0
- add hl,de
- ld e,(hl) ; table lookup, de = month correction
- pop hl
- add hl,de ; add correction
-
- pop de ; D/E=day/month
- ld c,d
- ld b,0 ; BC = day
- add hl,bc ; HL = accum+day
- dec hl
-
- pop bc ; BC = year
- ld a,c
- and 3
- jr nz,zncorr ; not a leap year
- ld a,e
- cp 3
- jr nc,zncorr ; March or later
- dec hl ; take off a day
-
- zncorr: ; Using repeated subtraction for space, not speed
- ld bc,7 ; mod 7
- or a ; clear carry
- znl: sbc hl,bc ; subtract
- jr nc,znl ; until carry
-
- add hl,bc ; add it back on
- ld a,l ; a = day(0-6)
- inc a ; (1-7)
- ld (dow),a
- pop bc
- pop de ; restore registers
- pop hl
- pop af
- ret
-
- monmod: ;data for zeller
- db 0,3,3,6,1,4,6,2,5,0,3,5
-
-
- .var bdos 0x0005 ; a handy definition
-
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ; This routine gets called by CRR
- ;;;;
- gettad:
- ;
- ; Entry:
- ; no special conditions
- ;
- ; Exit:
- ; year, month, day, dow, hour, mins, secs, and rtc
- ; should contain valid information.
- ;
- ; AF,BC,DE,HL may be changed on return
- ; Suggest IX,IY be unchanged (unsure)
- ;
- ;
- ld a,(0x010a)
- or a
- jr z,notzcpr
- ld c,48
- call bdos
- ld a,h
- cp 'S'
- jr z,iszcpr
- cp 'D'
- jr z,iszcpr
-
- notzcpr:ld c,12
- call bdos ; get CP/M version number.
- ld a,l
- cp 0x31 ; are we running under CP/M Plus?
- jr nc,cpmplus
- call zeller
- xor a
- ld (rtc),a ; Under this environment, there is no RTC
- ld hl,mins
- inc (hl) ; bump minutes
- ld a,59
- cp (hl)
- ret nc ; mins less than or equal to 59
- ld (hl),0 ; mins = 0
- dec hl ; point to hour
- inc (hl) ; bump hour
- ld a,23
- cp (hl)
- ret nc ; hour is less than or equal to 23
- ld (hl),23 ; can't be bothered with days
- inc hl
- inc hl
- inc (hl) ; bump seconds, so that MSGIDs are OK
- ret
- cpmplus:
- ld c,105
- ld de,datrec
- call bdos
- call bcd2bin
- ld (secs),a
- ld a,(datmn)
- call bcd2bin
- ld (mins),a
- ld a,(dathr)
- call bcd2bin
- ld (hour),a
- ld hl,(datint)
- call cpm2jul
- call jul2day
- ld (year),bc
- ld (month),de ; this sets day as well
- call zeller
- ld a,1
- ld (rtc),a
- ret
- ;
-
-
- iszcpr:
- ld c,98
- ld de,datrec
- call bdos
- ld a,(zcsec)
- call bcd2bin
- ld (secs),a
- ld a,(zcmin)
- call bcd2bin
- ld (mins),a
- ld a,(zchour)
- call bcd2bin
- ld (hour),a
- ld a,(zcday)
- or a ; Test for zero day
- jp z,notzcpr ; (no DOS clock) b/m 6/11/93
- call bcd2bin
- ld (day),a
- ld a,(zcmonth)
- call bcd2bin
- ld (month),a
- ld a,(zcyear)
- call bcd2bin
- ld h,0
- ld l,a
- ld de,1900
- add hl,de
- cp 77
- jr nc,zc1
- ld de,100
- add hl,de
- zc1: ld (year),hl
- call zeller
- ld a,1
- ld (rtc),a
- ret
-
-
- datrec: ; CP/M time record
- zcyear:
- datint: db 0
- zcmonth:
- db 0
- zcday:
- dathr: db 0
- zchour:
- datmn: db 0
- zcmin: db 0
- zcsec: db 0
-
- ;
- ; Many thanks to Bruce Morgen for pointing out a bug and a "gotcha" in
- ; the original version of the ZCPR ZSDOS and ZDDOS time support.
- ;
- ;-----
- ; 14-Nov-93
- ; Fixed bug which caused translation of 14 Oct 93 to 0 Feb 93
- ; Fixed bug which caused translation of 31 Dec xx to 0 Jan xx
- ;