;
;**********************************************************************
;
; MBC-KPRO.ASM -- Version 1.0 -- 03/01/84 -- by Kim Levitt
;
;       CLOCK routine for MBYE running on Kaypro 2 with Pro-Clock
;       (adapted from Kaypro Pro-Clock driver written by Greg Haerr)
;
;       This overlay is designed to work on a Kaypro II running MBYE
;       and equipped with a Business Computer Systems Pro-Clock RTC.
;       (Use the DATE program to initialize the clock outside of BYE.)
;       (BCS address: 5350 South 3600 West; Salt Lake City, UT 84118)
;
;       When called this routine will check the RTCBUF. If a '99H'
;       is in the first byte, the clock is initialized. Next the
;       seconds are checked, and if changed since last update of
;       RTC buffer, the clock is stopped, data copied to RTCBUF and
;       the clock is restarted. (If no change in seconds, the
;       routine returns immediately.)
;
;**********************************************************************
;
CLOCK:
       PUSH    PSW             ; save ALL regs that are used
       PUSH    B
       PUSH    H
       LDA     RTCBUF          ; get first BCD byte
       CPI     099H            ; 99 ?
       CZ      CLKINIT         ; if so, init clock...
       CALL    HOLDON          ; put clock on hold
       MVI     C,0             ; check low seconds
       CALL    RDPIO           ; to see if change...
       LXI     H,RTCBUF+2      ; compared to old secs
       XRA     M               ; value stored in
       ANI     0FH             ; RTC buffer (low nibble)
       JZ      CLKEXIT         ; if no change, skip update
       MVI     C,5             ; start with hi hours
       LXI     H,RTCBUF        ; and copy to RTCBUF
       CALL    GETCLK          ; (get time)
       MVI     C,12            ; start with hi year
       LXI     H,RTCBUF+4      ; and copy to RTCBUF
       CALL    GETCLK          ; (and date)
       LDA     RTCBUF          ; get hours
       ANI     03FH            ; mask out PM/24 hour bits
       STA     RTCBUF
       LDA     RTCBUF+6        ; get day
       ANI     03FH            ; mask out leap year bit
       STA     RTCBUF+6
CLKEXIT:
       MVI     C,13            ; set clock addr. to
       CALL    WRADDR          ; junk location so no data cleared
       CALL    HOLDOFF         ; when we take clock off hold..
       POP     H               ; restore ALL regs
       POP     B
       POP     PSW
       RET                     ; and return (for now..)
;
GETCLK:
       MVI     B,3             ; repeat 3 times for 3 BCD bytes
CLKLP:
       CALL    RDPIO           ; get data at address C
       RLC ! RLC ! RLC ! RLC   ; move to high nibble for BCD
       MOV     M,A             ; save at location temporarily
       DCR     C               ; decrement clock addr
       CALL    RDPIO           ; get data at next address
       ORA     M               ; OR with previously saved data
       MOV     M,A             ; and save it
       DCR     C               ; decrement clock addr
       INX     H               ; increment to next BCD byte
       DCR     B               ; decrement BCD counter
       JNZ     CLKLP           ; if 3rd BCD byte, done..
       RET                     ; return
;
; PIO STUFF
;
MODE3   EQU     0CFH    ; bit control mode
;
DATA    EQU     0AH     ; port B data
CMD     EQU     0BH     ; port B cmd
;
; mask values for clock chip
;
LATCH   EQU     80H     ; set address latch (active high)
WR      EQU     40H     ; write (active high)
RD      EQU     20H     ; read (active high)
HOLD    EQU     10H     ; time hold (active high)
;
CLKINIT:
       MVI     A,7             ; disable interrupts
       OUT     CMD
;
; fall into set output
;
; set output mode
;
SETOUT:
       LDA     FLAG            ; get current state
       OUT     DATA            ; preset data register
       MVI     A,MODE3         ; set bit control mode
       OUT     CMD
       XRA     A               ; set all outputs mask
       OUT     CMD
       LDA     FLAG
       OUT     DATA
       RET
;
; set input mode
;
SETIN:
       LDA     FLAG            ; get current state
       ORI     RD              ; set read line
       OUT     DATA
       MVI     A,MODE3
       OUT     CMD
       MVI     A,0FH           ; d7-d4 are still output, mask em'
       OUT     CMD
       LDA     FLAG
       ORI     RD
       OUT     DATA
       XCHG ! XCHG             ; delay for 6 uS min.
       RET
;
; send data in A to address in C
;
WRPIO:
       MOV     B,A             ; save data in B
       CALL    WRADDR          ; set address
       MOV     A,B             ; fall into write data
;
; write data in A
;
WRDATA:
       MOV     C,A             ; save in C
       LDA     FLAG            ; get current flag
       ORA     C               ; or in data
       OUT     DATA
       ORI     WR              ; and write it
       OUT     DATA
       NOP                     ; delay for 1 uS min
       NOP
       ANI     (NOT WR) AND 0FFH       ; reset write
       OUT     DATA
       RET
;
; read data into A from address in C
;
RDPIO:
       PUSH    B
       CALL    WRADDR          ; set address
;
; fall into read data
;
; read data into A
;
RDDATA:
       CALL    SETIN           ; set input mode
       IN      DATA            ; input data
       ANI     0FH             ; just in case
       MOV     C,A             ; save in C
       CALL    SETOUT          ; set to output mode
       MOV     A,C             ; get saved data
       POP     B               ; restore BC
       RET
;
; latch address in C
;
WRADDR:
       LDA     FLAG            ; get current flag
       ORA     C               ; or in address
       OUT     DATA            ; send address
       ORI     LATCH           ; set latch
       OUT     DATA            ; and latch it
       ANI     (NOT LATCH) AND 0FFH
       OUT     DATA
       RET
;
HOLDON:
       MVI     A,HOLD          ; set hold flag
       STA     FLAG
       CALL    WRDATA
HOLD0:
       MVI     B,20            ; wait 150 uS
HOLD1:
       XCHG ! XCHG
       DCR     B
       JNZ     HOLD1
       RET
;
HOLDOFF:
       XRA     A               ; reset hold flag
       STA     FLAG
       JMP     WRDATA
;
FLAG:   DB      0               ; current hold/nohold status flag
;
;**********************************************************************
;
; This is the end of the CLOCK routine overlay for MBYE-31. If you
; include this after your modem overlay, and have a Kaypro 2 equipped
; with a Pro-Clock, it SHOULD work fine...
;
;**********************************************************************
;