; DS1302 RTC code ; ================= ;(c) R.G. van Silfhout 2025 ; rtc connected to PIA lines: ; clk - PA5 ; CE - PA6 ; I/O - PA7 ; data direction register bits: ; 76543210 ; -ooioooo bit 7 is output when writing data to rtc and vice versa ; ; procedure for r/w RTC is similar: ; both start with writing register address ; - raise CE to '1'; set least significant bit in PA7 ; - create posedge on clk (PA5) ; - next bit, lower clock ; - repeat 8 times ; whilst CE is still high: ; writing data is as above but reading: ; read data changes on negedge of clock and first bit thus available directly after ; writing of register address is done ; access to RTC is through 6821 PIA: pia equ $F004 pia address cs09 cpu piacra equ 1 piadata equ 0 piadira equ 0 ; external call vectors rinit equ $F800 cold start monitor tinit equ $F802 console init inchck equ $F804 test console character ready inch equ $F806 read one character from console terminal outch equ $F808 write one character to console pdata equ $F80A print a string (X) hexbyt equ $F80C print one hex byte (A) org 0 ; define RTC registers secreg rmb 1 seconds minreg rmb 1 minutes hrreg rmb 1 hours dtreg rmb 1 date mthreg rmb 1 month dayreg rmb 1 day of week yrreg rmb 1 year wpreg rmb 1 write protect tcsreg rmb 1 trickle charge fixdof equ $80 ; register offset tclch equ #%10100110 ;enable trickle charge, 1 diode, 4k resistor org $5000 fdb InitRTC fdb wrtrtc fdb rdrtc ; set RTC address, B holds register address, U PIA address ; a, b, x destroyed setaddr lda piacra,u ;get control register setting anda #$FB ;clear bit 2 to allow access to direction register sta piacra,u ;store setting lda piadira,u ;get current direction ora #$E0 ;set PA7,6,5 I/O line as output sta piadira,u ;set direction of PAx lines lda piacra,u ;get control register setting ora #$04 ;set bit 2 to allow access to data register sta piacra,u lda piadata,u ;get current pia output lines ora #$40 ;make CE high, assume clock is left low after initRTC sta piadata,u ; set address one bit at a time ldx #8 8 ;bits to shift ; shiftout one bit at a time rtcsd lsrb ;shift lsb from register address to carry bit bcc s1 ;branch if lsb is 0 s0 ora #$80 ;set i/o line high bra s2 s1 anda #$7F ;set i/o line low s2 sta piadata,u ;set pia lines ; create posedge on clk ora #$20 ;clk posedge sta piadata,u ;clk toggle anda #$DF ;clk down sta piadata,u ;clk toggle leax -1,x bne rtcsd rts ; write register DS1302 ; A - holds data for register ; B - holds address to be written wrtrtc pshs a,x,u ;save data lslb ;multiply address addb #$80 ;point at the right registers on chip ldu #pia ;get absolute pia address in U bsr setaddr ;set register address puls a ;restore a ; write out 8 bits ldx #8 ;8 bits to shift ; shiftout one bit at a time ldb piadata,u ;get current data line status rtc1 lsra ;shift lsb from register address to carry bit bcc f1f ;branch if lsb is 0 orb #$80 set i/o line high bra f2f f1f andb #$7F ;set i/o line low f2f stb piadata,u ;set pia lines ; create posedge on clk orb #$20 ;clk posedge stb piadata,u ;clk toggle andb #$DF ;clk down stb piadata,u ;clk toggle leax -1,x bne rtc1 ;repeat for all bits in A bra rtcrt ; read DS1302 ; A - holds data of register ; on return B - destroyed rdrtc pshs x,u lslb ;multiply address addb #$80 ;point at the right registers on chip incb ;update address for read ldu #pia ;get absolute pia address in U bsr setaddr ; set PA7 line to input lda piacra,u ;get control register setting anda #$FB ;clear bit 2 to allow access to direction register sta piacra,u ;store setting lda piadira,u ;get current direction anda #%01111111 ;set PA7 as input sta piadira,u ;set direction of PAx lines lda piacra,u ora #$04 ;select data register sta piacra,u ; read in 8 bits but only with 7 clock cycles ldx #7 ;7 clock pulses clra ; shiftin one bit at a time rtcrs ldb piadata,u andb #$80 beq rd2 ;branch PA7 is '0' ora #$80 ;register logic high on PA7 rd2 lsra ; move to next ; create posedge on clk ldb piadata,u orb #$20 ;clk posedge stb piadata,u ;clk toggle andb #$DF ;clk down stb piadata,u ;clk toggle ldb piadata,u andb #$80 beq rd1 ;branch PA7 is '0' ora #$80 ;register logic high on PA7 rd1 leax -1,x bne rd2 ;repeat for all bits in A ; pull CE down rtcrt ldb piadata,u ;get current pia output andb #$BF ;make CE go low stb piadata,u puls pc,x,u ; first thing is to write enable and to place in 'normal' mode ; also define trickle charge setting InitRTC ldb #wpreg ; clear WP bit clra bsr wrtrtc ; send it ldb #secreg ;enable clock bsr rdrtc ;get current seconds register contents cmpa #$80 ;MSB set? bhs in3 ;move on anda #$7F ;clear in3 ldb #secreg lbsr wrtrtc ;update RTC ldb #tcsreg ;update trickle lda #tclch ;value lbsr wrtrtc ;write rts ; print date & time dd-mm-yyyy hh:mm:ss prrtc leax daytim,pcr jsr [pdata] ldb #dtreg ;start with day bsr rdrtc ;read register jsr [hexbyt] ;print day lda #'- jsr [outch] ldb #mthreg ;start with day bsr rdrtc ;read register jsr [hexbyt] ;print month lda #'- jsr [outch] ;print separator lda #$20 ;prepare for yyyy jsr [hexbyt] ldb #yrreg lbsr rdrtc jsr [hexbyt] lda #$20 ;print space jsr [outch] ;print to console ldb #hrreg lbsr rdrtc ;get hour jsr [hexbyt] ;print lda #': jsr [outch] ;print separator ldb #minreg ;point to minutes lbsr rdrtc ;get jsr [hexbyt] ;print lda #': jsr [outch] ;print separator ldb #secreg ;and finally seconds lbsr rdrtc ;get jsr [hexbyt] ;print leax crline,pcr jmp [pdata] ; set time of day & date dd-mm-yyyy hh:mm:ss setrtc leax mday,pcr bsr indat bcs sterr ldb #dtreg lbsr wrtrtc leax mmth,pcr bsr indat bcs sterr ldb #mthreg lbsr wrtrtc leax myear,pcr bsr indat bcs sterr ldb #yrreg lbsr wrtrtc leax mhrs,pcr bsr indat bcs sterr ldb #hrreg lbsr wrtrtc leax mmin,pcr bsr indat bcs sterr ldb #minreg lbsr wrtrtc sterr rts ; get single digit number 0-9 from console getnum jsr [inch] ;get character cmpa #'0 ; is it digit? blo notnum cmpa #'9 bls getnum1 notnum orcc #$01 ;set carry bit rts getnum1 suba #'0 rts ; get double digit number from console indat jsr [pdata] ; print text bsr getnum bcs seterr ;branch if error lsla lsla lsla lsla tfr a,b ;copy to b bsr getnum bcs seterr pshs b adda ,s+ ;add a & b tfr a,b ;put in bcc rts seterr orcc #1 ;set carry flag rts ;text strings daytim fcc $0a,$0d,'D,'a,'t,'e,'&,'T,'i,'m,'e,':,0 mday fcc $0a,$0d,'D,'a,'y,' ,'D,'D,':,0 mmth fcc $0a,$0d,'M,'o,'n,'t,'h,' ,'M,'M,':,0 myear fcc $0a,$0d,'Y,'e,'a,'r,' ,'Y,'Y,':,0 mhrs fcc $0a,$0d,'H,'o,'u,'r,' ,'H,'H,':,0 mmin fcc $0a,$0d,'M,'i,'n,'u,'t,'e,' ,'M,'M,':,0 msec fcc $0a,$0d,'S,'e,'c,'o,'n,'d,' ,'S,'S,':,0 crline fcc $0a,$0d,0 end