culberts@hplwbc.hpl.hp.com (Bruce Culbertson) (07/14/90)
Here's some code to set and get the time and date from the No-Slot clock on the PC532. There is some test code in a comment. The user interface for the test code is about as bad as you can get. I link this into Minix now and only used the test code to be sure the rest of the code worked. Maybe Jordan Hubbard will want to add this to his stand-alone library. Bruce Culbertson ================================================================ ;---------------------------------------------------------------- ; Routines to set and get date/time using the PC532 No-Slot clock. ; ; Time is set and returned via an eight byte buffer. Each byte of ; the buffer stores a BCD number. Out-of-range values for hours ; and day-of-week will switch the clock to other modes -- see ; manual. ; ; buf[0] 1/100's of seconds ; buf[1] seconds ; buf[2] minutes ; buf[3] hours ; buf[4] day of week ; buf[5] day of month ; buf[6] month ; buf[7] year (I use 90 for 1990) ;---------------------------------------------------------------- eprom_base: .equ h'10000000 ;reset address does not seem to work -- use a read instead ;rtcadr_reset: .equ 0+eprom_base rtcadr_reset: .equ rtcadr_rd rtcadr_wr0: .equ h'4000+eprom_base rtcadr_wr1: .equ h'4001+eprom_base rtcadr_rd: .equ h'4004+eprom_base cfg_dc: .equ 9 ;data cache bit of cfg reg ;---------------------------------------------------------------- ;; Test Code ;; ;; 1) Uncomment and assemble (the code is relocatable so you ;; really do not even have to link it) ;; 2) Load into RAM ;; 3) To set the clock, first put the date and time into the ;; buffer at address h'3000. Then run _tst_set from the ;; monitor. ;; 4) To read the clock, run _tst_get from the monitor. Then ;; read the time and date from the buffer at h'3000. ; ; .text ;tst_buf: .equ h'3000 ; ; ;_tst_set:: ; movd tst_buf,tos ; bsr _rtc_set ; adjspb -4 ; bpt ; ;_tst_get:: ; movd tst_buf,tos ; bsr _rtc_get ; adjspb -4 ; bpt ;---------------------------------------------------------------- ; Magic code to switch from EPROM to clock. rtc_code: .byte h'c5,h'3a,h'a3,h'5c .byte h'c5,h'3a,h'a3,h'5c ;---------------------------------------------------------------- ; Set the real-time-clock. ; C calling sequence: rtc_set(buf); ; char *buf; ;---------------------------------------------------------------- _rtc_set:: enter [r3],0 sprd cfg,r3 movd r3,r0 cbitb cfg_dc,r0 lprd cfg,r0 movb @rtcadr_reset,r0 movb @rtcadr_reset,r0 movb @rtcadr_reset,r0 addr rtc_code(pc),tos bsr rtc_wr64 movd 8(fp),tos bsr rtc_wr64 adjspb -8 lprd cfg,r3 exit [r3] ret 0 ;---------------------------------------------------------------- ; Set the real-time-clock. ; C calling sequence: rtc_get(buf); ; char *buf; ;---------------------------------------------------------------- _rtc_get:: enter [r3],0 sprd cfg,r3 movd r3,r0 cbitb cfg_dc,r0 lprd cfg,r0 movb @rtcadr_reset,r0 movb @rtcadr_reset,r0 movb @rtcadr_reset,r0 addr rtc_code(pc),tos bsr rtc_wr64 movd 8(fp),tos bsr rtc_rd64 adjspb -8 lprd cfg,r3 exit [r3] ret 0 ; rtc_wr64(buf) ; char *buf; ; ; Write 64 bits from buf to real time clock. ; ; r0 = data pointer ; r1 = counter ; r2 = tmp rtc_wr64: enter [],0 movd 8(fp),r0 movqb 0,r1 wr1: tbitb r1,0(r0) bfs wr2 movb @rtcadr_wr0,r2 br wr3 wr2: movb @rtcadr_wr1,r2 wr3: addqb 1,r1 cmpb 64,r1 bne wr1 exit [] ret 0 ; rtc_rd64(buf) ; char *buf; ; ; Read 64 bits from real time clock to buf. ; ; r0 = data pointer ; r1 = counter ; r2 = tmp rtc_rd64: enter [],0 movd 8(fp),r0 movqb 0,r1 rd1: movb @rtcadr_rd,r2 tbitb 0,r2 bfs rd2 cbitb r1,0(r0) br rd3 rd2: sbitb r1,0(r0) rd3: addqb 1,r1 cmpb 64,r1 bne rd1 exit [] ret 0