changeset 3118:ef66bdab9b45

mc09: Add mc09rtc command and GPIO registers defs in mc09.d New command mc09rtc to read/write a DS1802 RTC attached to multicomp09 GPIO. New help file mc09rtc.hp. Associated additions to mc09 makefile(s).
author Neal Crook <foofoobedoo@gmail.com>
date Tue, 01 Dec 2015 19:56:20 +0000
parents 47cd23dcf55e
children b230a123db20
files defs/mc09.d level1/cmds/mc09rtc.asm level1/mc09/cmds/makefile level1/mc09/sys/makefile level1/sys/mc09rtc.hp
diffstat 5 files changed, 768 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/defs/mc09.d	Sat Oct 17 21:19:39 2015 +0100
+++ b/defs/mc09.d	Tue Dec 01 19:56:20 2015 +0000
@@ -152,10 +152,19 @@
 UARTSTA2       EQU $FFD4
 UARTDAT2       EQU $FFD5
 
+********************************************************************
 * GPIO device
+* SEE VHDL HEADER FOR PROG GUIDE
 GPIOADR        EQU $FFD6
 GPIODAT        EQU $FFD7
 
+* values supported by GPIOADR register
+GPDAT0         EQU 0
+GPDDR1         EQU 1
+GPDAT2         EQU 2
+GPDDR3         EQU 3
+
+
 ********************************************************************
 * SDCARD CONTROL REGISTERS
 * SEE VHDL HEADER FOR PROG GUIDE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/cmds/mc09rtc.asm	Tue Dec 01 19:56:20 2015 +0000
@@ -0,0 +1,745 @@
+********************************************************************
+* mc09rtc - read/write DS1802 RTC attached to multicomp09 GPIO
+*
+* Rather than bloat the timer module (which is memory-resident)
+* this is a stand-alone utility that can either read the RTC and
+* update the system time, or read the system time and update the
+* RTC. It can be run from the startup file to set the time at boot.
+*
+* usage:
+*
+* mc09rtc -r
+* read RTC and update system time
+* mc09rtc -w
+* write RTC with current system time
+* mc09rtc -d
+* dump RTC clock and RAM contents
+*
+* This is for the 6809: it contains no 6309-specific code.
+*
+*   +-----------------+  <--  Y          (highest address)
+*   !                 !
+*   !   Parameter     !
+*   !     Area        !
+*   !                 !
+*   +-----------------+  <-- X, SP
+*   !                 !
+*   !   Data Area     !
+*   !                 !
+*   +- - - - - - - - -+
+*   !   Direct Page   !
+*   +-----------------+  <-- U, DP       (lowest address)
+*
+*   D = parameter area size
+*  PC = module entry point abs. address
+*  CC = F=0, I=0, others undefined
+*
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2015/11/07  Neal Crook
+* Created.
+*
+         nam   mc09rtc
+         ttl   Read/write DS1802 RTC, copy to/from system time
+
+         use   defsfile
+
+tylg     set   Prgrm+Objct
+atrv     set   ReEnt+rev
+rev      set   $00
+edition  set   1
+
+         mod   eom,name,tylg,atrv,start,size
+
+* Bit-masks for GPIO bits connected to RTC
+RTCCE     EQU 4      bit 2
+RTCCLK    EQU 2      bit 1
+RTCDAT    EQU 1      bit 0
+
+         org   0
+* buffer for NITROS9-format 6-byte "time packet"
+sysbuf   rmb    0       same as sysyear. [NAC HACK 2015Nov17] without "rmb 0" this becomes an offset in *code* space..
+sysyear  rmb    1
+sysmonth rmb    1
+sysdate  rmb    1       documentation refers to this as "day"
+syshour  rmb    1
+sysmin   rmb    1
+syssec   rmb    1
+
+* buffer for RTC time registers (and, in -D, for RTC RAM)
+rtcbuf  rmb     0       same as rtcsec. [NAC HACK 2015Nov17] without "rmb 0" this becomes an offset in *code* space..
+rtcsec  rmb     1
+rtcmin  rmb     1
+rtchour rmb     1
+rtcdate rmb     1
+rtcmonth rmb    1
+rtcday  rmb     1
+rtcyear rmb     1
+rtcprot rmb     1       have to read this as part of the burst
+rtcxxx  rmb     23      31 bytes total, to hold RTC RAM
+
+txtbuf  rmb   80        text output buffer
+        rmb   200       stack
+size    equ   .
+
+name    fcs   /mc09rtc/
+        fcb   edition
+
+WrMsg   fcc     'RTC updated from system time'
+WrMsgE
+RdMsg   fcc     'System time updated from RTC'
+RdMsgE
+
+DMsg1   fcc     'Yr Mo Dt Hr Mi Se'
+        fcb     C$CR
+DMsg2   fcc     '        NitrOS9 binary "time packet"'
+        fcb     C$CR
+DMsg3   fcc     'Se Mi Hr Dt Mo Dy Yr Pr'
+        fcb     C$CR
+DMsg4   fcc     '  DS1302 RTC BCD Date/protection'
+        fcb     C$CR
+DMsg5   fcc     '                       trickle'
+        fcb     C$CR
+DMsg6   fcc     '  RAM'
+DMsg7   fcb     C$CR
+
+
+********************************************************************
+* Start of program/Entry point
+start   pshs    x               preserve pointer to cmd line args
+
+* Load time from RTC - for use by -R and -D options.
+        lbsr    initio
+        lda     #$BF            cmd for clock read burst
+        ldx     #8              read 8 bytes
+        leay    rtcbuf,u        where to put it: the RTC buffer
+        lbsr    rd_n
+
+* Load system time - for use by -W and -D options.
+        leax    sysbuf,u        buffer
+        os9     F$Time          read system time into buffer
+        bcs     badexit         something bad happened
+
+* Now, what are we expected to do?
+        puls    x
+        lda     ,x+             first char of cmd-line arguments
+*                               leading spaces stripped by shell
+        cmpa    #$2D            require "-" for -R -W -D
+        bne     badexit         not found so set carry and exit
+        lda     ,x+             character after "-"
+        anda    #$df            force to upper case
+        cmpa    #'R
+        beq     read
+        cmpa    #'W
+        lbeq     write
+        cmpa    #'D
+        lbeq    dump
+badexit clrb                    exit code=0
+        orcc    #1              set C to indicate error
+        os9     F$Exit
+
+********************************************************************
+* "-R" - read from RTC and update system time.
+read
+* Time from RTC has already been loaded in.
+* Convert it and move it from RTC buffer to system time buffer.
+        lda     <rtcsec         0-59
+        anda    #$7f            omit CH flag
+        bsr     bcd2bin
+        sta     <syssec
+
+        lda     <rtcmin         0-59
+        bsr     bcd2bin
+        sta     <sysmin
+
+        lda     <rtchour        0-23
+        anda    #$3f            omit 12/24 flag
+        bsr     bcd2bin
+        sta     <syshour
+
+        lda     <rtcdate        1-31
+        bsr     bcd2bin
+        sta     <sysdate
+
+        lda     <rtcmonth       1-12
+        bsr     bcd2bin
+        sta     <sysmonth
+
+        lda     <rtcyear        0-99
+        bsr     bcd2bin
+        adda    #100            nitros stores year as offset from 1900
+        sta     <sysyear
+
+        leax    sysbuf,u        buffer
+        os9     F$STime         set system time from buffer
+
+* Report our action and exit
+        leax    >RdMsg,pcr      point to message
+        ldy     #RdMsgE-RdMsg   length
+        lbra    prexit
+
+
+********************************************************************
+bcd2bin
+*
+* in  A= value in BCD
+* out A= value in binary
+*
+* eg: $10 in, $0A out
+* CC modified, all other registers preserved.
+*
+* algorithm: take tens digit, multiply by 8 and then by 2 and add
+* those two values to the units.
+        pshs    b
+        tfr     a,b
+        anda    #$0f            units in A
+        andb    #$f0            tens in B
+        asrb                    tens move from *16 position to *8 position
+        pshs    b               }
+        adda    ,s+             } add b (8/10ths of tens) to a
+        asrb
+        asrb                    tens * 2
+        pshs    b               }
+        adda    ,s+             } units + 8/10ths + 2/10ths of tens
+        puls    b,pc
+
+
+********************************************************************
+bin2bcd
+*
+* in  A= value in binary
+* out A= value in BCD
+*
+* eg: $16 in, $24 out
+* CC modified, all other registers preserved.
+*
+* algorithm: do successive subtract of $0a and increment counter by
+* $10 each time. When result is less than $0a, add in count value.
+*
+        pshs    b
+        clrb
+bcdnxt  cmpa    #$0a
+        blo     bcddone         branch if lower ie 0-9 remaining
+        addb    #$10            bump up by bcd 10
+        suba    #$0a            as we subtract by binary 10
+        bra     bcdnxt          and go round again
+
+bcddone pshs    b               } add b to a
+        adda    ,s+             }
+        puls    b,pc
+
+
+********************************************************************
+* "-W" - write system time to RTC.
+write
+* System time has already been loaded in.
+* Convert it and move it from system time buffer to RTC buffer.
+        lda     <syssec         0-59 (I hope)
+        bsr     bin2bcd
+        sta     <rtcsec         CH bit is 0 so clock runs
+
+        lda     <sysmin         0-59 (I hope)
+        bsr     bin2bcd
+        sta     <rtcmin
+
+        lda     <syshour        0-23 (I hope)
+        anda    #$3f            select 24-hour clock
+        bsr     bin2bcd
+        sta     <rtchour
+
+        lda     <sysdate        1-31 (I hope)
+        bsr     bin2bcd
+        sta     <rtcdate
+
+        lda     <sysmonth       1-12 (I hope)
+        bsr     bin2bcd
+        sta     <rtcmonth
+
+        lda     #1
+        sta     <rtcday         1-7. Not used but want it legal
+
+        lda     <sysyear        100-199 (I hope)
+        suba    #100            [NAC HACK 2015Nov18] check first!! Error if last century.
+        bsr     bin2bcd
+        sta     <rtcyear
+
+* Write buffer to RTC
+        lbsr    initio
+        lda     #$BE            cmd for clock write burst
+        ldx     #8              read 8 bytes
+        leay    rtcbuf,u        get it from the RTC buffer
+        lbsr    wr_n
+
+* Report our action and exit
+        leax    >WrMsg,pcr      point to message
+        ldy     #WrMsgE-WrMsg   length
+        lbra    prexit
+
+********************************************************************
+* "-D" - dump RTC contents.
+dump
+* system and RTC buffer are already loaded. Print them out then
+* load and report in addition
+* 1 byte from trickle-charge register, 31 bytes from RAM
+*
+* Yr Mo Dt Hr Mi Se
+* xx xx xx xx xx xx         NitrOS9 binary "time packet"
+*
+* Se Mi Hr Dt Mo Dy Yr Pr
+* xx xx xx xx xx xx xx xx   DS1302 RTC BCD Date/protection
+* xx                        trickle
+* xx xx xx xx xx xx xx xx   RAM
+* xx xx xx xx xx xx xx xx
+* xx xx xx xx xx xx xx xx
+* xx xx xx xx xx xx xx
+*
+
+        leax    >DMsg1,pcr      point to message
+        ldy     #80             max length
+        lbsr    prbufb          print from x or die in the attempt
+
+        * display content of system time packet buffer
+        leay    sysbuf,u        data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #6              bytes to convert
+        lbsr    hex2buf
+        ldy     #18             2 digits + 1 space per
+        lbsr    prbufa          print txtbuf or die in the attempt
+
+        leax    >DMsg2,pcr      point to message
+        ldy     #80             max length
+        lbsr    prbufb          print from x or die in the attempt
+
+        leax    >DMsg7,pcr      point to message - extra CR
+        ldy     #80             max length
+        lbsr    prbufb          print from x or die in the attempt
+
+        leax    >DMsg3,pcr      point to message
+        ldy     #80             max length
+        lbsr    prbufb          print from x or die in the attempt
+
+        * display content of RTC time buffer
+        leay    rtcbuf,u        data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #8              bytes to convert
+        lbsr    hex2buf
+        ldy     #24             2 digits + 1 space per
+        lbsr    prbufa          print txtbuf or die in the attempt
+
+        leax    >DMsg4,pcr      point to message
+        ldy     #80             max length
+        lbsr    prbufb          print from x or die in the attempt
+
+        * read the 1-byte trickle register
+        leay    rtcbuf,u        where to store it
+        lda     #$91
+        lbsr    putcmd
+        lbsr    getbyte
+        sta     ,y+
+        lbsr    endtrans
+
+        * display 1 byte from RTC time buffer
+        leay    rtcbuf,u        data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #1              bytes to convert
+        lbsr    hex2buf
+        ldy     #3              2 digits + 1 space per
+        lbsr    prbufa          print txtbuf or die in the attempt
+
+        leax    >DMsg5,pcr      point to message
+        ldy     #80             max length
+        bsr     prbufb          print from x or die in the attempt
+
+        * read RAM
+        leay    rtcbuf,u        where to store it
+        lda     #$FF            RAM read burst
+        ldx     #31             read 31 bytes
+        leay    rtcbuf,u        where to put it: the RTC buffer
+        lbsr    rd_n
+
+        * display 1st 8 bytes of RTC RAM from RTC time buffer
+        leay    rtcbuf,u        data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #8              bytes to convert
+        bsr     hex2buf
+        ldy     #24             2 digits + 1 space per
+        bsr     prbufa          print txtbuf or die in the attempt
+
+        leax    >DMsg6,pcr      point to message
+        ldy     #80             max length
+        bsr     prbufb          print from x or die in the attempt
+
+        * display 2nd 8 bytes of RTC RAM from RTC time buffer
+        leay    8+rtcbuf,u      data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #8              bytes to convert
+        bsr     hex2buf
+        lda     #C$CR           add CR
+        sta     ,x+
+        ldy     #25             2 digits + 1 space per + CR
+        bsr     prbufa          print txtbuf or die in the attempt
+
+        * display 3rd 8 bytes of RTC RAM from RTC time buffer
+        leay    16+rtcbuf,u     data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #8              bytes to convert
+        bsr     hex2buf
+        lda     #C$CR           add CR
+        sta     ,x+
+        ldy     #25             2 digits + 1 space per + CR
+        bsr     prbufa          print txtbuf or die in the attempt
+
+        * display 4th 7 bytes of RTC RAM from RTC time buffer
+        leay    24+rtcbuf,u     data to display
+        leax    >txtbuf,pcr     buffer to store ASCII version
+        lda     #7              bytes to convert
+        bsr     hex2buf
+        lda     #C$CR           add CR
+        sta     ,x+
+        ldy     #22             2 digits + 1 space per + CR
+        leax    >txtbuf,pcr     where to display from
+prexit  bsr     prbufb          go display it
+        clrb                    success
+        os9     F$Exit          and exit
+
+
+********************************************************************
+prbufa  leax    >txtbuf,pcr     where to display from
+prbufb  lda     #1              standard out
+        os9     I$Writln        print it up to CR
+        bcs     prbad
+        rts
+prbad   os9     F$Exit
+
+
+********************************************************************
+hex2buf
+*
+* in:   Y binary data to convert
+*       X buffer to build ASCII version
+*       A number of bytes to convert
+*
+* out:  Y, X updated
+*       A,B,CC modified
+        ldb     ,y+             get byte
+        bsr     Byte2Hex        store ASCII version in buffer
+        ldb     #C$SPAC
+        stb     ,x+             add trailing space
+        deca
+        bne     hex2buf
+        rts
+
+********************************************************************
+* Convert byte in B to Hex string at X (from debug.asm)
+* B,X,CC altered.
+Byte2Hex pshs  b		save copy of B on stack
+         andb  #$F0		mask upper nibble
+         lsrb  			and bring to lower nibble
+         lsrb
+         lsrb
+         lsrb
+         bsr   Nibl2Hex		convert byte in B to ASCII
+         puls  b		get saved B
+         andb  #$0F		do lower nibble
+* Convert lower nibble in B to Hex character at X
+Nibl2Hex cmpb  #$09		9?
+         bls   n@		branch if lower/same
+         addb  #$07		else add 7
+n@       addb  #'0		and ASCII 0
+         stb   ,x+		save B
+         rts
+
+
+********************************************************************
+rd_n
+* Read from a sequence of RTC locations
+*
+* X = number of bytes to read
+* Y = where to store the read data
+* A = command byte
+*
+* Assumes IO has been initialised.
+        pshs    x               modified value is held on stack
+
+        lbsr    putcmd
+
+rd_nxt  lbsr    getbyte         read byte into A
+        sta     ,y+             store data byte read
+        puls    x               recover count value
+        leax    -1,x            update count
+        pshs    x               stash count value
+        bne     rd_nxt          go do next byte
+        bsr     endtrans        tidy up at end
+
+        puls    x,pc            tidy up the stack and return
+
+
+********************************************************************
+wr_n
+* Write to a sequence of RTC locations
+*
+* X = number of bytes to write
+* Y = where to get the write data from
+* A = command byte
+*
+* Assumes IO has been initialised.
+* Clears write protect first, sets it at end.
+        pshs    x               modified value is held on stack
+        pshs    a
+
+        * clear the write-protect bit
+        lda     #$8e
+        lbsr    putcmd
+        clra
+        lbsr    putbyte
+        bsr     endtrans
+
+        puls    a
+        lbsr    putcmd
+
+wr_nxt  lda     ,y+             get byte to write
+        lbsr    putbyte         write it
+        puls    x               recover count value
+        leax    -1,x            update count
+        pshs    x               stash count value
+        bne     wr_nxt          go do next byte
+        bsr     endtrans        tidy up at end
+
+        * set the write-protect bit
+        lda     #$8e
+        bsr     putcmd
+        lda     #$80
+        bsr     putbyte
+        bsr     endtrans
+
+        puls    x,pc            tidy up the stack and return
+
+
+********************************************************************
+* Low-level DS1802 read/write. Broken into the following parts:
+*
+* initio   - GPIO init
+* putcmd   - write 1st (cmd) byte
+* putbyte  - write 1 data byte
+* getbyte  - read 1 data byte
+* endtrans - end read or write transaction
+*
+* Leave CE and CLK permanently outputs.
+* Leave DAT as input by default, make it an output when it needs
+* to be but always end a routine with it set to an input. It is OK
+* to float DAT because the DS1302 provides an internal pulldown.
+*
+* designed to be used thus:
+* initio (one-time)
+* putcmd putbyte [putbyte..] endtrans
+* putcmd getbyte [getbyte..] endtrans
+*
+* Reads from and writes to clock registers *must* be done as
+* bursts to take advantage of the internal buffering. Without this,
+* it would be necessary to check for carries that occurred between
+* accessing one location and the next.
+
+
+********************************************************************
+initio
+*
+* only need to call this once.
+* in:       none
+* out:      none
+* modifies: A B CC, gpio state.
+*
+        clrb
+        lda     #GPDAT0
+        sta     GPIOADR     select dat0
+        stb     GPIODAT     set values to 0
+        lda     #GPDDR1
+        sta     GPIOADR     select ddr1
+        incb
+        stb     GPIODAT     CE out, CLK out, DAT in.
+        rts
+
+
+********************************************************************
+endtrans
+*
+* take CE back low and wait recovery time.
+* in:       none
+* out:      none
+* modifies: none
+*
+*        v-------------- send pattern ---------------------V
+* CE   H LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L
+* CLK  L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L
+* DAT  z zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz z
+*      ^-assumed on entry            xsition(if any) on exit-^
+*
+*        -------------------------------------------------->
+*        wait 4us in this state to meet recovery time
+*
+        pshs    a,cc
+        lda     #GPDAT0
+        sta     GPIOADR     select dat0
+        clr     GPIODAT     falling edge on CE, keep CLK=0.
+
+        bsr     wait1us
+        bsr     wait1us
+        bsr     wait1us
+        bsr     wait1us
+        puls    a,cc,pc
+
+
+********************************************************************
+putcmd
+*
+* in:       A=command byte to send
+* out:      none
+* modifies: A B CC X
+* enter with CE=0 CLK=0 DAT=0.
+* exit with CE=1 and TODO timing met
+*
+*        v-------------- send pattern ---------------------V
+* CE   L HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H
+* CLK  L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L
+* DAT  z zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz z
+*      ^-assumed on entry            xsition(if any) on exit-^
+*
+*        -------------------------------------------------->
+*        3us
+*
+*        v-------------- send pattern ---------------------V
+* CE   H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H
+* CLK  L LLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHHHH L
+* DAT  z 000000111111222222333333444444555555666666777777zzz z
+*      ^-assumed on entry            xsition(if any) on exit-^
+*
+*        <-> 1us high and low time on CLK
+*
+        pshs    a
+        lda     #GPDAT0
+        sta     GPIOADR     select dat0
+        lda     #RTCCE      assert CE
+        sta     GPIODAT
+
+        bsr     wait1us
+        bsr     wait1us
+        bsr     wait1us
+
+        puls    a
+        bra     putbyte
+
+
+********************************************************************
+putbyte
+*
+* in:       A=data byte to send
+* out:      none
+* modifies: A B CC X
+*
+*        v-------------- send pattern ---------------------V
+* CE   H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H
+* CLK  L LLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHHHH L
+* DAT  z 000000111111222222333333444444555555666666777777zzz z
+*      ^-assumed on entry            xsition(if any) on exit-^
+*
+*        <-> 1us high and low time on CLK
+*
+        ldb     #GPDDR1
+        stb     GPIOADR     select ddr1
+        clr     GPIODAT     CE out, CLK out, DAT out.
+
+        ldb     #GPDAT0
+        stb     GPIOADR     select dat0
+
+        ldx     #8          number of bits to send
+pblop
+        tfr     a,b
+        andb    #$1        keep LSB
+        orb     #RTCCE     LSB with CLK=0, CE=1
+        stb     GPIODAT    send out data bit with CLK=0
+        bsr     wait1us
+        eorb    #RTCCLK    set CLK=1
+        stb     GPIODAT    send out data bit with CLK=1
+        bsr     wait1us
+        rora            put next bit in LSB position
+        leax    -1,x
+        bne     pblop      more bits?
+
+        ldb     #GPDDR1
+        stb     GPIOADR     select ddr1
+        ldb     #1
+        stb     GPIODAT     DAT to input ie z.
+        bsr     wait1us
+
+        lda     #GPDAT0
+        sta     GPIOADR     select dat0
+        lda     #RTCCE
+        sta     GPIODAT     falling edge on CLK, keep CE=1.
+
+        rts
+
+
+********************************************************************
+getbyte
+*
+* in:       none
+* out:      A=data byte read
+* modifies: A B CC X
+*
+*        v-------------- send pattern ------------------V
+* CE   H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H
+* CLK  L LLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHH L
+* DAT  z 000000111111222222333333444444555555666666777777 0
+*      ^-assumed on entry         xsition(if any) on exit-^
+*
+* at entry falling edge has already occurred that will yield
+* the first data bit.
+* at exit falling edge has already occurred that will yield
+* the first data bit of the next byte. It's no problem if
+* no "next byte" is needed; taking CE high will stop everything
+* politely.
+*
+        ldb     #GPDAT0
+        stb     GPIOADR         select dat0
+
+        ldx     #8              number of bits to receive
+gblop
+        bsr     wait1us         wait with clock low
+        ldb     #RTCCE|RTCCLK
+        stb     GPIODAT         set CLK=1
+        ldb     GPIODAT         get DAT in LSB
+        * first incoming bit is bit 0 and will rotate
+        * all the way down to LSB of A
+        rorb                    rotate bit from B into C
+        rora                    rotate bit from C into A
+        bsr     wait1us         wait with clock high
+        ldb     #RTCCE
+        stb     GPIODAT         set CLK=0
+
+        leax    -1,x
+        bne     gblop           more bits?
+        rts
+
+
+********************************************************************
+wait1us
+*
+* wait for 1us (includes call/return time)
+* in:       none
+* out:      none
+* modifies: none
+        nop             [NAC HACK 2015Nov13] tune..
+        nop
+        nop
+        nop
+        nop
+        rts
+
+
+********************************************************************
+* all done here folks
+         emod
+eom      equ   *
+         end
+
--- a/level1/mc09/cmds/makefile	Sat Oct 17 21:19:39 2015 +0100
+++ b/level1/mc09/cmds/makefile	Tue Dec 01 19:56:20 2015 +0000
@@ -12,7 +12,7 @@
 CMDS		= asm attr backup binex build calldbg cmp cobbler copy cputype \
 		date dcheck debug ded deiniz del deldir devs dir dirsort disasm \
 		display dmode dsave dump echo edit error exbin format \
-		free grfdrv help ident iniz irqs link list load login makdir \
+		free grfdrv help ident iniz irqs link list load login makdir mc09rtc \
 		megaread mdir merge mfree minted mpi os9gen padrom park printerr procs prompt pwd pxd \
 		rename save setime shellplus shell_21 sleep \
 		tee tmode touch tsmon tuneport unlink verify xmode
--- a/level1/mc09/sys/makefile	Sat Oct 17 21:19:39 2015 +0100
+++ b/level1/mc09/sys/makefile	Tue Dec 01 19:56:20 2015 +0000
@@ -11,7 +11,7 @@
 		dir.hp dirsort.hp disasm.hp display.hp dmode.hp dsave.hp dump.hp echo.hp \
 		edit.hp error.hp ex.hp exbin.hp format.hp free.hp gfx.hp \
 		help.hp ident.hp iniz.hp inkey.hp irqs.hp kill.hp link.hp \
-		list.hp load.hp login.hp makdir.hp \
+		list.hp load.hp login.hp makdir.hp mc09rtc.hp \
 		mdir.hp megaread.hp merge.hp minted.hp mpi.hp mfree.hp os9gen.hp \
 		padrom.hp park.hp procs.hp prompt.hp pwd.hp pxd.hp \
 	 	rename.hp save.hp setime.hp \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/sys/mc09rtc.hp	Tue Dec 01 19:56:20 2015 +0000
@@ -0,0 +1,12 @@
+@MC09RTC
+Syntax: mc09rtc [<opts>]
+Usage : Read or write DS1302 RTC connected to Multicomp09 GPIO hardware.
+Opts  :
+  -r = read RTC -- update system time from RTC
+       use this in your startup file to set the system time at boot
+  -w = write RTC -- update RTC from system time
+       use this from the shell to initialise the RTC
+  -d = dump system time, RTC time and RAM
+
+futures/maybe:
+  add options to write bits/bytes of the RAM