;
; file : timer.clk.text
; date : 05-January-1984  kb
;
; FILE IS AN INCLUDE FILE FOR TIMER.DRV.TEXT , THE TIMER DRIVER.
; THIS IS THE UNITREAD AND UNITWRITE CODE FOR THE CALANDER CLOCK IN THE
; TIMER DRIVER.
;
; 04-23-82  kb  Changed IORESULT definitions to use the global file definitions
; 06-07-82  kb  Changed for new rev. 4 processor board changes, will find the
;                  correct address to use (either $30FE1 or $30F81)
; 07-07-82  kb  Changed error in RV3 and RV4 address equates, were reversed
; 09-20-82  lf  Changed write clock to stop/start clock in order to zero
;                  seconds and tenths fields
; 10-22-82  kb  Changed READCR so it reads 4 times with a MOVEP.L instruction.
;                  Checks to make sure the low order 3 bytes, all except the
;                  first read are the same.  If they are not it rereads the
;                  register.
; 07-22-83  kb  Added code to have read fail retries, up to ten (10) then
;                  returns an IOresult of Clock hardware failed.
; 01-05-84  kb  Changed RDCLOCK and READCR to catch all ticks (reg. = $0F).
;
  page
;
; EQUATES FOR THE CLOCK ROUTINES
; PARAMTER BLOCK INDICES - RANGE FOR PARAMETER IN PARENTHESIS
;
DAYOFWK     EQU        0                         ;DAY OF THE WEEK (1-7)
MONTH       EQU        DAYOFWK+2                 ;MONTH (1-12)
DAY         EQU        MONTH+2                   ;DAY (1-31)
HOUR        EQU        DAY+2                     ;HOURS (0-23)
MINS        EQU        HOUR+2                    ;MINUTES (0-59)
SECS        EQU        MINS+2                    ;SECONDS (0-59)
TENTHS      EQU        SECS+2                    ;TENTHS OF SECONDS (0-9)
LEAPYR      EQU        TENTHS+2                  ;LEAP YEAR (0-3)
;
LENPBR      EQU        TENTHS+2                  ;LENGTH OF READ PARAMETER BLOCK
NUMRP       EQU        LENPBR/2                  ;NUMBER OF READ PARAMETERS
;
LENPBW      EQU        LEAPYR+2                  ;LENGTH OF WRITE PARAMETER BLOCK
NUMWP       EQU        LENPBW/2                  ;NUMBER OF WRITE PARAMETERS
;
; CLOCK REGISTERS
;
RV4ADDR     EQU        $30F81                    ;SELECT/ADDRESS LATCH   **new board address
RV3ADDR     EQU        $30FE1                    ;SELECT/ADDRESS LATCH  **old board address
RWREG       EQU        $30D01                    ;READ/WRITE CLOCK REGISTERS
INTREG      EQU        15                        ;CLOCK INTERRUPT REG ADDR
STRTSTOP    EQU        14                        ;START/STOP REGISTER
LYREG       EQU        13                        ;LEAP YEAR REGISTER
TENTHSC     EQU         1                        ;TENTH OF SECONDS REGISTER {change 6/7}
;
RDERR       EQU        $0F                       ;REGISTER VALUE WHEN READ WHEN UPDATE
DSELCT      EQU        $10                       ;DESELECT CHIP
;
; IORESULT CODES
;
PBLENER     EQU        IOEprmln                  ;PARAMETER BLOCK WRONG LENGTH
CLOCKERR    EQU        IOEclkmf                  ;CLOCK NOT WORKING
;
  page
;
; TIMRD - UNITREAD OF CLOCK
;
; RETURN TO THE USER THE TIME IN THE REAL-TIME-CLOCK.
; USER PASSES PARAMETER BLOCK POINTER IN D1 OF WHERE TO PUT THE TIME INFO.
; TIME IS RETURNED IN BINARY, INTEGERS.   THE PARAMETER BLOCK HAS THE FORM :
;
; type ReadClockParameter = record
;                             DayofWeek :integer;
;                             Month : integer;
;                             Day : integer;
;                             Hour : integer;
;                             Mins : integer;
;                             Secs : integer;
;                             Tenths : integer;
;                           end;
;
TIMRD
            MOVE.L     D1,A6                     ;A6 = PARAMETER BLOCK PTR
            MOVE.L     D2,D4                     ;SAVE USER LENGTH
            BSR.S      RDCLOCK                   ;READ THE CLOCK
            TST.W      D7
            BNE.S      TRDEXIT                   ;CAN'T READ CLOCK
;
; CONVERT AND PUT RESULT IN PARAMETER BLOCK
;
            CMPI.W     #LENPBR,D4                ;IS PARAMETER BLOCK LONG ENOUGH
            BCS.S      TRDERR                    ;NO
            LEA        NUMBER,A5                 ;# OF NIBBLES IN PARAMETER
            LEA        DETAIL,A4                 ;REGISTER ARRAY INDICES
            LEA        REGARRAY,A3               ;REGISTER ARRAY
            CLR.L      D3                        ;INDEX INTO PARAM BLOCK
            CLR.L      D4                        ;INDEX INTO NUMBER ARRAY
            CLR.L      D6                        ;INDEX INTO DETAIL ARRAY
;
TRDGETP     MOVE.B     0(A5,D4.W),D0             ;# OF NIBBLES PARAMETER
            BSR.S      CVTOUT                    ;CONVERT - RETURNS IN D1
            MOVE.W     D1,0(A6,D3.W)             ;STORE PARAMETER
            ADDQ.W     #2,D3                     ;NEXT PARAMETER
            ADDQ.B     #1,D4                     ;DO 7 PARAMETERS
            CMPI.W     #NUMRP,D4
            BNE.S      TRDGETP                   ;DO AGAIN
TRDEXIT     RTS
;
; ERROR - PARAMETER BLOCK THE WRONG LENGTH
;
TRDERR      MOVEQ      #PBLENER,D7
            RTS
  page
;
; RDCLOCK - READ ALL THE CLOCK REGISTERS INTO THE REGISTER ARRAY
;
RDCLOCK     BSR.S      LDADDR                    ;GET CHIP ADDRESSES IN A0&A1
            MOVEQ      #7,D6                     ;COUNT OF FAILURES
;
; READ REGISTERS INTO ARRAY
;
RDCRST      SUBQ.B     #1,D6
            BMI.S      RDCERR                    ;RETRIED TO MANY TIMES
            MOVEQ      #RARDLEN,D0               ;D0 = REGISTER #    *kb 1/5/84*
            LEA        REGARRAY+RARDLEN,A2       ;DO REG=12 TO 1     *kb 1/5/84*
;
RDCREG      BSR.S      READCR                    ;READ A SINGLE REGISTER RETURNS IN D2
            BNE.S      RDCexit                   ;failed to read *kb 7/22/83*

; IF ANY REGISTER READ = $0F THEN READ REGISTERS WHEN TICKED AND MUST RESTART
;
            CMPI.B     #RDERR,D2                 ;got a tick         *kb 1/5/84*
            BEQ.S      RDCRST                    ;YES, Restart read  *kb 1/5/84*
            MOVE.B     D2,-(A2)                  ;PUT IN ARRAY       *kb 1/5/84*
            SUBQ.B     #1,D0                     ;STOP WHEN D0 = 0   *kb 1/5/84*
            BNE.S      RDCREG                    ;DO AGAIN

RDCexit     RTS                                  ;*kb 7/22/83*
;
; ERROR - CHIP NOT WORKING
;
RDCERR      MOVEQ      #CLOCKERR,D7
            RTS
;
; LDADDR - GET LATCH ADDRESS IN A0 AND R/W CLOCK ADDRESS IN A1
;
LDADDR      MOVEA.L    ADDRREG,A0                ; GET saved address {change 6/7}
            MOVE.L     A0, D0                    ; {change 6/7}
            BEQ.S      RDCERR                    ;NO CLOCK CHIP - ERROR EXIT {change 6/7}
            LEA        RWREG.L,A1
            RTS
  page
;
; CVOUT - CONVERT REGISTERS TO 1 PARAMETER
;           ENTRY : (D0) = # OF REGISTERS TO USE (# OF DETAIL ELEMENTS)
;                   DETAIL(D6) = REGISTER TO USE TO MAKE PARAMETER
;                   (A4) = ADDRESS OF THE INDICES OF REGARRAY FOR EACH PARAMETER
;                   (A3) = ADDRESS OF THE REGISTER ARRAY
;           EXIT  : (D1) = PARAMETER CONVERTED
;                   (D6) = UPDATED TO NEXT DETAIL ELEMENT FOR NEXT PARAMETER
;
CVTOUT      CLR.L      D2
            CLR.L      D1
            MOVE.B     0(A4,D6.W),D2             ;GET REGARRAY INDEX
            ADDQ.B     #1,D6                     ;UPDATE INDEX
            MOVE.B     0(A3,D2.W),D1             ;FIRST NIBBLE
;
            SUBQ.B     #1,D0                     ;IF NUMBER OF REGS=1  THEN
            BEQ.S      CVOEXIT                   ;THEN DONE-IS VALID BINARY
;
            LSL.B      #4,D1                     ;MOVE TO HI NIBBLE
            MOVE.B     0(A4,D6.W),D2             ;INDEX TO NEXT REGISTER
            ADDQ.B     #1,D6                     ;UPDATE INDEX
            OR.B       0(A3,D2.W),D1             ;PUT IN LOW NIBBLE
;
            BSR.S      CBCDBIN                   ;CONVERT BCD TO BINARY
CVOEXIT     RTS
  page
;
; CBCDBIN - CONVERT 1 BYTE OF BCD (2 DIGITS) TO 1 BYTE OF BINARY
;           ENTRY : (D1) = BCD BYTE OF DIGITS
;           EXIT  : (D1) = BINARY BYTE
;
CBCDBIN     CLR.L      D2
            MOVE.B     D1,D2                     ;COPY OF BCD
            ANDI.B     #$0F,D2                   ;LOW ORDER DIGIT
            LSR.W      #4,D1                     ;MOVE OVER HI DIGIT
            MULU       #10,D1                    ;MAKE 10*DIGIT
            ADD.W      D2,D1                     ;MAKE FULL NUMBER
            RTS
  page
;
; Changed routine on 10/22/82 kb
; READCR - READ CLOCK REGISTER
;       ENTRY : (A0) = LATCH ADDRESS
;               (A1) = R/W CLOCK ADDRESS
;               (D0) = REGISTER ADDRESS
;       EXIT  : (D2) = REGISTER VALUE READ
;               (D7) = IOresult
;
;  The movep.l instruction works because the I/O address space for the
;  clock is not fully decoded.
;
READCR      MOVEM.L    D3-D6,-(SP)               ;save regs                      *kb 10/22/82*
            MOVEQ      #10, D3                   ;do it 10 times *kb 7/22/83*

RDCR10      MOVEQ      #CLOCKERR,D7              ;failed to read                 *kb 1/5/84*
            SUBQ.W     #1, D3                    ;did do all tries *kb 7/22/83*
            BMI.S      RDCRexit                  ;yes, error                     *kb 1/5/84*
            CLR.L      D7                        ;no error                       *kb 1/5/84*
            BSR.S      SELREG                    ;DESELECT THEN SELECT ADDRESS   *kb 10/22/82*
            MOVEP.L    0(A1),D2                  ;read reg 4 times               *kb 10/22/82*
            MOVE.B     #DSELCT,(A0)              ;DESELECT CHIP
            ANDI.L     #$0F0F0F0F,D2             ;clear hi nibbles of all bytes  *kb 10/22/82*
;                                                                                *kb 10/22/82*
; make sure all bytes read are the same                                          *kb 10/22/82*
;                                                                                *kb 10/22/82*
            MOVEQ      #1, D4                    ;ignore hi order byte, 1st read *kb 10/22/82*
            MOVE.L     D2,D5                     ;save read value                *kb 10/22/82*
            CMPI.B     #RDERR,D5                 ;read a tick?                   *kb 1/5/84*
            BEQ.S      RDCRerr1                  ;yes, return tick result        *kb 1/5/84*
            MOVE.B     D5, D6                    ;compare all to last read       *kb 10/22/82*
RDCR20                                           ;                               *kb 10/22/82*
            LSR.L      #8, D5                    ;chk next byte                  *kb 10/22/82*
            CMPI.B     #RDERR,D5                 ;read a tick?                   *kb 1/5/84*
            BEQ.S      RDCRerr1                  ;yes, return tick result        *kb 1/5/84*
            CMP.B      D5, D6                    ;are they the same?             *kb 10/22/82*
            BNE.S      RDCR10                    ;No, read reg again             *kb 10/22/82*
            DBF        D4, RDCR20                ;Do until checked all 3 bytes   *kb 10/22/82*
            BRA.S      RDCRexit                  ;*kb 7/22/83*
RDCRerr1    MOVE.B     D5,D2                     ;return tick register value     *kb 1/5/84*
RDCRexit    MOVEM.L    (SP)+,D3-D6               ;restore regs                   *kb 10/22/82*
            TST.W      D7                        ;set error state *kb 7/22/83*
            RTS
;
; SELREG - DESELECT THEN SELECT CHIP REGISTER
;           ENTRY : (D0) = CLOCK REGISTER ADDRESS
;                   (A0) = LATCH ADDRESS
;
SELREG      MOVEQ      #DSELCT,D1
            OR.B       D0,D1
            MOVE.B     D1,(A0)                   ;DESELECT CHIP BY SETTING D4
            MOVE.B     D1,(A0)                   ;*kb 11/7/83* give uniplex more time
            MOVE.B     D0,(A0)                   ;SELECT ADDRESS
            MOVE.B     D0,(A0)                   ;*kb 11/7/83* give uniplex more time
            RTS
  page
;
; INITCLK - PROCEDURE CALLED BY UNITINSTALL CODE (TIMINST) TO INITIALIZE
;           THE CLOCK CHIP.
;   ASSUMES THAT THE FOLLOWING CODE DOES NOT RESET THE CLOCK.???????
;
INITCLK
;
; START CLOCK - MUST DO IT FOR BOTH ADDRESSES
;
            LEA        RWREG.L, A1               ;R/W ADDRESS           {change 6/7}
            LEA        RV3ADDR.L, A0             ;DO OLD ADDRESS FIRST  {change 6/7}
            BSR.S      STRTCLK                   ;                      {change 6/7}
            LEA        RV4ADDR.L, A0             ;DO NEW ADDRESS        {change 6/7}
            BSR.S      STRTCLK                   ;                      {change 6/7}
;                                                                       {change 6/7}
; FIND CORRECT ADDRESS OF THIS MACHINES PROCESSOR BOARD                 {change 6/7}
;                                                                       {change 6/7}
            BSR.S      FINDADDR                  ;                      {change 6/7}
            BNE.S      INITEXIT                  ;ERROR - NO CHIP       {change 6/7}
;
; INITIALIZE CHIP
;
            BSR        LDADDR                    ;GET CLOCK REGISTER ADDRESES
            CLR.L      D0                        ;REG ADDRESS
            CLR.L      D2                        ;DATA
            BSR        WRITECR                   ;PUT IN NON-TEST MODE
;
; CLEAR INTERRUPTS
;
            MOVEQ      #INTREG,D0                ;ADDRESS
            CLR.L      D2                        ;DATA
            BSR        WRITECR
            BSR        READCR                    ;READ 3 TIMES TO RESET
            BSR        READCR
            BSR        READCR
INITEXIT    RTS                                  ;{change 6/7}
  page
;
; STOPCLK - STOP CLOCK PROCEDURE                                        {09-20-82}
;       ASSUMES A0 AND A1 ARE INITIALIZED.                              {09-20-82}
;                                                                       {09-20-82}
STOPCLK     MOVEQ      #0,D2                     ;DATA                  {09-20-82}
            BRA.S      ST10                      ;                      {09-20-82}
;                                                                       {09-20-82}
; STRTCLK - START CLOCK PROCEDURE                                       {06-07-82}
;       ASSUMES A0 AND A1 ARE INITIALIZED.                              {06-07-82}
;                                                                       {06-07-82}
STRTCLK     MOVEQ      #1,D2                     ;DATA                  {06-07-82}
                                                 ;                      {09-20-82}
ST10        MOVEQ      #STRTSTOP,D0              ;ADDRESS               {09-20-82}
            BSR.S      WRITECR                   ;                      {06-07-82}
            RTS                                  ;                      {06-07-82}
;
; RDTENTHS - read the tenths register of clock
;       EXIT - (NC) = READ OK
;              (C)  = ERROR - WRONG ADDRESS
;              (D2) = REGISTER VALUE READ
;
RDTENTHS
            MOVEQ      #3,D5                     ;CHECK MAX. 4 TIMES FOR CLOCK TURNING

RDT10       MOVEQ      #TENTHSC,D0               ;read tenth of seconds register
            BSR        READCR
            CMPI.B     #RDERR, D2                ;do until (no read error) or
            DBNE       D5, RDT10                 ; (tried 4 times)

            CMPI.B     #9, D2                    ;if not a BCD digit then wrong address
            BHI.S      RDTERR                    ;USE OTHER Address
            CLR.L      D5
            RTS

RDTERR      MOVE.W     #CARRYST, CCR
            RTS
  page
; FINDADDR - FIND ADDRESS OF CHIP'S ADDRESS LATCH. IT IS EITHER RV3ADDR OR RV4ADDR
;            DEPENDING ON THE VERSION OF THIS PROCESSOR BOARD.
; routine added with 6/7 change.
;
FINDADDR
            LEA        ADDRREG, A3               ;WHERE TO SAVE CORRECT ADDRESS
            LEA        RWREG.L,A1
            LEA        RV4ADDR.L,A0              ;START WITH REV 4 ADDRESS
            MOVEQ      #1,D4                     ;TRY ONLY TWO ADDRESSES

; CHECK IF ADDRESS IN A0 IS CORRECT
;
FA10
            BSR.S      RDTENTHS                  ;GET STARTING VALUE
            BCS.S      FANXT                     ;WRONG CHIP TRY NEXT ADDRESS
            CMPI.B     #9, D2                    ;WAIT UNTIL TENTH OF SECONDS
            BEQ.S      FAZERO                    ;IS NEXT TENTH ==> D3.B
            MOVE.B     D2,D3
            ADDQ.B     #1,D3
            BRA.S      FA20
FAZERO      CLR.L      D3
FA20        MOVE.W     #30000,D6                 ;MUST READ AT LEAST TENTH SEC.

; READ TENTHS UNTIL IT CHANGES OR UNTIL IT TRIED TO LONG
;
FA30
            BSR.S      RDTENTHS                  ;GET NEXT VALUE
            BCS.S      FANXT                     ;WRONG CHIP TRY NEXT ADDRESS
            CMP.B      D2,D3                     ;HAS TIME TICKED
            BEQ.S      FAFNDIT                   ;YES, FOUND CORRECT ADDRESS
            DBF        D6, FA30                  ;READ AGAIN
;
; NOT THIS ADDRESS TRY OTHER ADDRESS
;
FANXT       LEA       RV3ADDR.L, A0
            DBF       D4, FA10

; ERROR - NEITHER ADDRESS WORKED
;
            CLR.L     (A3)                       ;SHOW NO CHIP ADDRESS
            MOVE.W    #CLOCKERR, D7
            RTS

; FOUND CORRECT ADDRESS
;
FAFNDIT     MOVE.L    A0, (A3)
            CLR.L     D7
            RTS
  page
;
;  WRITECR - WRITE A CLOCK REGISTER
;           ENTRY : (D0) = REGISTER ADDRESS
;                   (D2) = DATA
;
WRITECR     BSR        SELREG                    ;DESELECT THEN SELECT REG.
            MOVE.B     D2,(A1)                   ;WRITE DATA
            MOVE.B     D2,(A1)                   ;*kb 11/7/83* for uniplex
            MOVE.B     #DSELCT,(A0)              ;DESELECT CHIP
            RTS
;
; WRITEREGS - WRITE THE CLOCK REGISTERS FROM THE REGISTER ARRAY
;
WRITEREGS   BSR        LDADDR                    ;GET CHIP ADDRESSES
;
; WRITE REGISTERS
;
            MOVEQ      #1,D0                     ;REGISTER ADDRESS
            LEA        REGARRAY,A2
;
WRONER      MOVE.B     (A2)+,D2                  ;REGISTER DATA
            BSR.S      WRITECR                   ;WRITE DATA
            ADDQ.B     #1,D0                     ;NEXT REGISTER ADDRESS
            CMPI.B     #STRTSTOP,D0              ;STOP AT START/STOP REG.
            BNE.S      WRONER
            RTS
  page
;
; TIMWR - SET CLOCK FROM PARAMETER BLOCK
;           PARAMETER BLOCK FOR UNITWRITE :
;
; type WriteClockParameter = record                     range
;                             DayofWeek : integer;       1-7
;                             Month : integer;           1-12
;                             Day : integer;             1-31
;                             Hour : integer;            0-23
;                             Mins : integer;            0-59
;                             Secs : integer;            0-59
;                             Tenths : integer;          0-9
;                             LeapYear : integer;        0-3
;                            end;
;
TIMWR       MOVE.L     D1,A3                     ;ADDRESS OF PARAMETER BLOCK
;
; PROCESS BINARY PARAMETERS
;
            BSR.S      VALBIN                    ;VALIDATE PARAMS
            BCS.S      TWRERR                    ;NO GOOD
            BSR.S      CVTBINR                   ;CONVERT BINARY TO BCD OF REGISTERS
;
; ZERO SECONDS AND TENTHS OF SECONDS                                    {09-20-82}
;                                                                       {09-20-82}
            BSR        LDADDR                    ; GET CLOCK ADDRESSES  {09-20-82}
            BSR        STOPCLK                   ;                      {09-20-82}
            BSR        STRTCLK                   ;                      {09-20-82}
;
; WRITE OUT REGISTER ARRAY
;
            BSR.S      WRITEREGS
            RTS
;
; ERROR - INVALID CLOCK PARAMETER
;
TWRERR      MOVE.W     #INVPRM,D7
            RTS
  page
;
; VALBIN - VALIDATE BINARY PARAMETER BLOCK
;           ENTRY : (A3) = ADDRESS OF PARAMETER BLOCK
;           EXIT  : (NC) = GOOD PARAMETERS
;                   (C)  = ERROR, OUT OF RANGE
;
VALBIN      MOVEA.L    A3,A4                     ;SAVE PB ADDRESS
            MOVEQ      #NUMWP-1,D4               ;DO ALL 8 PARAMETERS
            LEA        RANGES,A5                 ;LIST OF PARAMETER RANGES(BYTES)
;
; COMPARE EACH PARAMETER TO IT'S LOW AND HI RANGE VALUE
;
VBCHK       CLR.L      D0
            MOVE.B     (A5)+,D0                  ;GET LOW BOUND RANGE
            CMP.W      (A4),D0                   ;PARAM>=LOW BOUND THEN OK
            BHI.S      VBERR                     ;ERROR, TO LOW
            MOVE.B     (A5)+,D0                  ;GET HI BOUND RANGE VALUE
            CMP.W      (A4),D0                   ;PARAM<=HI BOUND THEN OK
            BCS.S      VBERR                     ;ERROR, TO HIGH
            ADDQ.L     #2,A4                     ;NEXT PARAMETER LOW BYTE
            DBF        D4,VBCHK
            CLR.L      D0                        ;SHOW NO ERROR
            RTS
;
; ERROR EXIT - OUT OF RANGE
;
VBERR       MOVE.W     #CARRYST,CCR              ;SHOW ERROR
            RTS
  page
;
; CVTBINR - CONVERT VALID PARAMETER BLOCK FROM BINARY INTO REGARRAY BCD NIBLES
;           ENTRY : (A3) = ADDRESS OF PARAMETER BLOCK
;
CVTBINR     LEA        HI,A4                     ;HI NIBBLE HOLD ARRAY
            LEA        LOW,A5                    ;LOW NIBBLE HOLD ARRAY
            MOVEQ      #NUMWP-1,D4               ;FOR i := 8 to 1 do
            MOVEQ      #LEAPYR+1,D3              ;INDEX TO PARAMETER
;
CBRNIBS     CLR.L      D0
            MOVE.B     0(A3,D3.W),D0             ;GET PARAMETER[i]
            MOVE.L     D0,D1
            DIVU       #10,D1                    ;HI NIBBLE := PARAM DIV 10
            MOVE.L     D1,D0                     ;LOW IS REMAINDER FROM DIV
            SWAP       D0                        ;LOW := PARAMETER-(HI*10)
            MOVE.B     D1,0(A4,D4.W)             ;SAVE HI
            MOVE.B     D0,0(A5,D4.W)             ;SAVE LOW
            SUBQ.W     #2,D3                     ;NEXT PARAMETER INDEX
            DBF        D4,CBRNIBS                ;DOWNTO 0
;
; SETUP REGISTER ARRAY
;
            CLR.L      D3                        ;REMOVE GARBAGE
            LEA        REGARRAY,A3
            MOVEQ      #RAWRLEN-1,D4             ;MOVE TO 13 REGISTERS
            LEA        NIBBLE,A2                 ;WHICH NIBBLE FOR THIS REG.
            LEA        INREGB,A1                 ;WHICH PARAMETER IS REG FROM
;
CBRREGS     MOVE.B     0(A1,D4.W),D3             ;INDEX TO HI & LOW FOR THIS REG.
            MOVE.B     0(A5,D3.W),D0             ;ASSUME LOW NIBBLE
            TST.B      0(A2,D4.W)                ;IF 0 THEN USE LOW NIBBLE
            BEQ.S      CBRULOW                   ;IS LOW
            MOVE.B     0(A4,D3.W),D0             ;ELSE GET HI NIBBLE
CBRULOW     MOVE.B     D0,0(A3,D4.W)             ;PUT NIBBLE IN REGISTER HOLD
            DBF        D4,CBRREGS
;
            BSR.S      CVTLPYR                   ;CONVERT LEAP YEAR REG
            RTS
  page
;
; CVTLPYR - CONVERT LEAP YEAR PARAMETER TO THE REGISTER VALUE FOR THE
;           CLOCK CHIP.  8,4,2,1 WHERE 8 IS FOR LEAP YEAR AND THE OTHER NUMBERS
;           ARE FOR THE YEARS AFTER THE LEAP YEAR.  THEREFORE, 4 IS LEAP YEAR+1,
;           2 IS LEAP YEAR+2, 1 IS LEAP YEAR+3.
;
CVTLPYR     MOVE.B     LYREG-1(A3),D0            ;LEAP YEAR REG. = 13(INDEX=12)
            MOVEQ      #3,D1                     ;D0 IS PARAMETER (RANGE 0-3)
            SUB.B      D0,D1                     ;CALCULATE WHICH BIT TO SET
            CLR.L      D0                        ;BIT# := 3-PARAMETER
            BSET       D1,D0                     ;D0 IS LEAP YEAR VALUE
            MOVE.B     D0,LYREG-1(A3)            ;PUT IN REGISTER ARRAY
            RTS
