* Written by Roger Schaefer
*
* DS1202 Serial Timekeeping Chip
* DALLAS SEMICONDUCTOR
*
* The following subroutines read and write to a
* DS1202 or the newer DS1302 real time chip.
*
*
*
CLK_INIT        EQU     *       
        BCLR    RTClkPort RST           ;be sure RST low        
        BSET    RTClkDDR RST
        BCLR    RTClkPort SCLK          ;clock low
        BSET    RTClkDDR SCLK
        BCLR    RTClkPort I_O           ;i/o line low
        BSET    RTClkDDR I_O
        RTS
*********************************
Get_Seconds:            ;return in A in packed BCD
        ldaa    #0      ;seconds
        jsr     READ_CLK
        rts
Get_Minutes:            ;return in A in packed BCD
        ldaa    #1      ;minutes
        jsr     READ_CLK
        rts
Get_Hour:               ;return in A in packed BCD
        ldaa    #2      ;hour
        jsr     READ_CLK
        rts
Get_am_pm:              ;return 0 if am; $FF if pm
        ldaa    #2      ;hour
        jsr     READ_CLK
        anda    #%00100000
        beq     am
        ldaa    #$ff
am      rts
Get_Date:               ;return in A in packed BCD
        ldaa    #3      ;date
        jsr     READ_CLK
        rts
Get_Day:                ;return in A in packed BCD
        ldaa    #5      ;weekday
        jsr     READ_CLK
        rts
Get_Month:              ;return in A in packed BCD
        ldaa    #4      ;month
        jsr     READ_CLK
        rts
Get_Year:               ;return in A in packed BCD
        ldaa    #6      ;year
        jsr     READ_CLK
        rts
*
* Read a register from the DS1202 clock
* Enter with the register number in A
* Return with the data in A
*
READ_CLK  EQU     *             
        ANDA    #$7                     ;lower 3 bits only
        LSLA
        ORAA    #%10000001              ;read command
RD_CK0  PSHX
        LDX     #REGBS
        BSR     CLK_INIT
        BSET    RTClkPort,X RST         ;enable chip
        BSR     WT_CK1
        BCLR    RTClkDDR,X I_O          ;now input
        LDAB    #8
RD_CK4  BCLR    RTClkPort,X SCLK
        CLC
        BRCLR   RTClkPort,X, I_O, RD_CK5
        SEC
RD_CK5  RORA
        BSET    RTClkPort,X SCLK
        DECB
        BNE     RD_CK4
        BCLR    RTClkPort,X RST
        PULX
        RTS
*
WT_CK1  LDAB    #8
RD_CK1  BCLR    RTClkPort,X SCLK
        LSRA
        BCS     RD_CK2
        BCLR    RTClkPort,X I_O
        BRA     RD_CK3
RD_CK2  BSET    RTClkPort,X I_O
RD_CK3  BSET    RTClkPort,X SCLK
        DECB
        BNE     RD_CK1
        RTS
*
ISPDIGIT      EQU *
        PSHB
        ANDB    #$F
        CMPB    #9
        BHI     ISPD_BAD
        PULB
        PSHB
        LSRB
        LSRB
        LSRB
        LSRB
        CMPB    #9
        BHI     ISPD_BAD
        PULB
        SEC                     ;Set C if OK
        RTS
*
ISPD_BAD     EQU *
        LDX     #MSG9
        JSR     OUTSTRG
        PULB
        CLC                     ;Clear C if not OK
        RTS
*
SET_MINUTE      EQU *
        JSR     WSKIP
        JSR     BUFFARG
        TST     COUNT
        BEQ     SET_M9          ;go if no argument
        LDAB    SHFTREG+1
        BSR     ISPDIGIT
        BCC     SET_M9
        CLRA
        CLRB                    ;Set seconds to 0
        BSR     WRITE_CLK
        LDAB    SHFTREG+1
        LDAA    #1              ;Reg Addr MIN
        BSR     WRITE_CLK
SET_M9  JSR     SHOW_TIME
        RTS
*
SET_HOUR        EQU *
        JSR     WSKIP
        JSR     BUFFARG
        TST     COUNT
        BEQ     SET_H9          ;go if no argument
        LDAB    SHFTREG+1
        BSR     ISPDIGIT
        BCC     SET_H9
        LDAA    #2              ;Reg Addr HR
        BSR     WRITE_CLK
SET_H9  JSR     SHOW_TIME
        RTS
*
SET_DAY         EQU *
        JSR     WSKIP
        JSR     BUFFARG
        TST     COUNT
        BEQ     SET_D9          ;go if no argument
        LDAB    SHFTREG+1
        BSR     ISPDIGIT
        BCC     SET_D9
        LDAA    #3              ;Reg Addr DATE
        BSR     WRITE_CLK
SET_D9  JSR     SHOW_DATE
        RTS
*
SET_MONTH    EQU *
        JSR     WSKIP
        JSR     BUFFARG
        TST     COUNT
        BEQ     SET_MO9         ;go if no argument
        LDAB    SHFTREG+1
        JSR     ISPDIGIT
        BCC     SET_MO9
        LDAA    #4              ;Reg Addr MONTH
        BSR     WRITE_CLK
SET_MO9 JSR     SHOW_DATE
        RTS
*
SET_YEAR      EQU *
        JSR     WSKIP
        JSR     BUFFARG
        TST     COUNT
        BEQ     SET_Y9          ;go if no argument
        LDAB    SHFTREG+1
        JSR     ISPDIGIT
        BCC     SET_Y9
        LDAA    #6              ;Reg Addr YEAR
        BSR     WRITE_CLK
SET_Y9  JSR     SHOW_DATE
        RTS
*
*
* Write a register to the DS1202 clock
* Enter with the DS1202 register in A and
* the data to write in B
*
WRITE_CLK  EQU  *
        PSHA
        PSHB
        LDAA    #7              ;Control register
        LDAB    #0              ;OK to write
        BSR     WT_CK0
        PULB
        PULA                    ;get data back
        BSR     WT_CK0
WT_CK3  LDAA    #7
        LDAB    #$80            ;Set WP
WT_CK0  ANDA    #$7             ;lower 3 bits only
        LSLA
        ORAA    #%10000000      ;write command
WT_CK2  PSHX
        PSHB
        LDX     #REGBS
        JSR     CLK_INIT
        BSET    RTClkPort,X RST         ;enable chip
        JSR     WT_CK1
        PULB
        TBA
        JSR     WT_CK1
;       BCLR    RTClkDDR,X %00011000
        BCLR    RTClkPort,X RST
        PULX
        RTS
*
*
* Read a ram location from the DS1202 chip
* Enter with the address in A
* Return with the data in A
*
READ_RAM:      
        ANDA    #$3F
        LSLA
        ORAA    #%11000001      ;read command
        JMP     RD_CK0          ;reuse code
*
* Enter with the DS1202 register in A and
* the data to write in B
*
WRITE_RAM:      
        PSHA
        PSHB
        LDAA    #7              ;Control register
        LDAB    #0              ;OK to write
        BSR     WT_CK0
        PULB
        PULA                    ;get data back
        ANDA    #$3F
        LSLA
        ORAA    #%11000000      ;write command
        BSR     WT_CK2
        BRA     WT_CK3          ;Set WP & Goodbye
**************************************************
        END
