;ALARM CLOCK SOURCE CODE FILE FOR CK2 CIRCUIT BOARD
;Written by Brian Beard, http://www.cs.net/lucid/
;Revision history
;0.0 - 11NOV98, Initial creation.
;0.1 - 26FEB99, Add: IRQ handler, Power Out DownCounter,
;               Colon Display FLAG BIT.
;0.2 - 28FEB99, Remove TFMT calls from time and alarm set.
;
;Crystal frequency (Fosc) = 4.194304MHz
;Operating frequency (Fop) = 2.097152MHz, Cycle = 476.8 nsec
;Timer overflow rate = 2048Hz, Period = 488usec
;CASM ASSEMBLER DIRECTIVES ------------------------------------
$BASE     0AH        ;Change default base to decimal.
;68HC705J1A MEMORY MAP ----------------------------------------
; $000-$01F     MPU REGISTERS
; $020-$0BF     UNUSED
; $0C0-$0FF     USER RAM AND STACK AREA
; $100-$2FF     UNUSED
; $300-$7CF     USER EPROM
; $7D0-$7ED     UNUSED
; $7EE-$7EF     TEST ROM
; $7F0-$7FF     MASK OPTION REGISTER AND VECTORS
;
;MCU PORT AND I/O USAGE ---------------------------------------
;IRQ is used to sense main power status.
; IRQ   IN      PULLUP  1 = POWER_OK
;
;PORT A, SWITCH INPUTS, SENSE INPUTS, AND ALARMS
; PA0   IN      PULLUP  TIME SET, ACTIVE LOW
; PA1   IN      PULLUP  ALARM SET, ACTIVE LOW
; PA2   IN      PULLUP  HOURS SET, ACTIVE LOW
; PA3   IN      PULLUP  MINUTES SET, ACTIVE LOW
; PA4   IN      PULLUP  ALARM ENABLE, ACTIVE HIGH
; PA5   IN      PULLUP  12/24 SELECT, 0 = 24 HOUR FORMAT
; PA6   IN      PULLUP  BATTERY SENSE, 0 = BATTERY LOW
; PA7   OUT             ALARM OUTPUT, 1 = ALARM ON
TSET    EQU     0
ASET    EQU     1
HSET    EQU     2
MSET    EQU     3
AEN     EQU     4
FMT     EQU     5
BAT     EQU     6
ALARM   EQU     7
;
;PORT B, EXTERNAL INTERFACES
; PB0   OUT             DISPLAY DATA
; PB1   OUT             DISPLAY CLOCK
; PB2   OUT             DISPLAY SELECT, ACTIVE LOW
; PB3   IN              NC
; PB4   IN              NC
; PB5   IN              NC
DD      EQU     0
DC      EQU     1
DS      EQU     2
;
;MCU EQUATES --------------------------------------------------
PADAT   EQU     $000    ;Port A DATa register
PBDAT   EQU     $001
PADDR   EQU     $004    ;Port A Data Direction Register
PBDDR   EQU     $005
TSCR    EQU     $008    ;Timer Status and Control Register
TCR     EQU     $009    ;Timer CounteR data
ISCR    EQU     $00A    ;IRQ Status and Control Register
PDRA    EQU     $010    ;PullDown Register for port A
PDRB    EQU     $011    ;PullDown Register for port B
EPROG   EQU     $018
STACK   EQU     $0FF    ;Top of RAM
COPR    EQU     $7F0    ;Computer Operating Properly Register
MOR     EQU     $7F1    ;Mask Option Register
;
ENRTI   EQU     $1F     ;Enable R.T.I. every 2^17 cycles
;
;DISPLAY DATA -------------------------------------------------
; The CC56-21EWA display is 4 digits with colon.
; The colon is segment-h on digits 3 and 4.
; The digits are numbered from left to right: 12:34
;
; The Display Board's MC14489 is wired so that:
;       BANK1 = DIGIT1 = tens of hours,   X_:__
;       BANK2 = DIGIT2 = hours digit,     _X:__
;       BANK3 = DIGIT3 = tens of minutes, __:X_
;       BANK4 = DIGIT4 = minutes digit,   __:_X
;       BANK5 = 4 LED annunciators,      :__:__:
;               D1 = SEGMENT a = Upper Left = ALARM ENABLED
;               D2 = SEGMENT b = Upper Right = AM
;               D3 = SEGMENT c = Lower Right = PM
;               D4 = SEGMENT d = Lower Left = BATTERY LOW
;
; MC14489 CONFIGURATION REGISTER -
; BIT C0 CONTROLS THE ENTIRE DISPLAY;
;       1=NORMAL MODE, 0=LOW POWER AKA STANDBY MODE.
; BITS C1-C5 CONTROL DECODE OF BANKS 1-5 RESPECTIVELY;
;       1=OPTIONAL DECODE, 0=HEX DECODE.
; BITS C6,C7 = 1,1 TO ALLOW SPECIAL DECODE FOR ALL BANKS.
;
;DISPLAY CONTROLLER (MC14489) EQUATES -------------------------
; DECODE KEY:   H = HEX DECODE
;               S = SPECIAL DECODE
;               N = NO DECODE
;                               LEDs  DIGITS
CR1234  EQU     %00100001     ;  N     HH:HH   FOUR DIGITS
CR_234  EQU     %00100011     ;  N     NH:HH   THREE DIGITS
CR____  EQU     %00100000     ;  N     HH:HH   STANDBY MODE
;
DR2_B1  EQU     %11110000     ;BRIGHT, COLON ON, BANK5=0
DR2_B0  EQU     %10000000     ;BRIGHT, COLON OFF, BANK5=0
DR2_D1  EQU     %01110000     ;DIM, COLON ON, BANK5=0
DR2_D0  EQU     %00000000     ;DIM, COLON OFF, BANK5=0
DR2_AE  EQU     %00000001     ;ALARM_ENABLED LED ON
DR2_AM  EQU     %00000010     ;AM LED ON
DR2_PM  EQU     %00000100     ;PM LED ON
DR2_LB  EQU     %00001000     ;LOW_BATTERY LED ON
;
;RAM AREA -----------------------------------------------------
        ORG     $0C0
TODAY   RMB     4        ;binary Time-Of-DAY in these 4 bytes
HRS     EQU     TODAY    ;HouRS counter
MINS    EQU     TODAY+1  ;MINuteS counter
SECS    EQU     TODAY+2  ;SECondS counter
TICKS   EQU     TODAY+3  ;interrupt counter
;
A_HRS   RMB     1       ;Alarm HouRS
A_MINS  RMB     1       ;Alarm MINuteS
;
D_HRS   RMB     1       ;Display HouRS
D_MINS  RMB     1       ;Display MINuteS
;
S_HRS   RMB     1       ;Set time HouRS
S_MINS  RMB     1       ;Set time MINuteS
;
;BCD DISPLAY DATA
DIG1    RMB     1       ; #-:--
DIG2    RMB     1       ; -#:--
DIG3    RMB     1       ; --:#-
DIG4    RMB     1       ; --:-#
;
;DISPLAY CONTROLLER (MC14489) DATA STORAGE
CR_0    RMB     1     ;Configuration Register, C7-C0
DR_2    RMB     1     ;Display Register, D23-D16, COLON/DIG5
DR_1    RMB     1     ;Display Register, D15-D08, DIG4/DIG3
DR_0    RMB     1     ;Display Register, D07-D00, DIG2/DIG1
;
FLAG    RMB     1       ;FLAG byte
CI      EQU     7       ;1 = Clock Initialized
AM      EQU     6       ;1 = AM, 0000-1159
PM      EQU     5       ;1 = PM, 1200-2359
LP      EQU     4       ;1 = Low Power operation
AC      EQU     3       ;1 = Alarm Condition
CD      EQU     2       ;1 = Colon Display
;
OLDSEC  RMB     1       ;Previous second count
DDV     RMB     1       ;Decreasing Delay Value
PODC    RMB     1       ;Power Out Down-Counter
;
;EPROM AREA ---------------------------------------------------
        ORG     $0300
;ROLLOVER TABLE FOR TIME VALUES.
RLOVR   FCB     24      ;HOURS PER DAY
        FCB     60      ;MINUTES PER HOUR
        FCB     60      ;SECONDS PER MINUTE
        FCB     16      ;TICKS PER SECOND
;
;SUBROUTINES --------------------------------------------------
;SEND BYTE IN A TO DISPLAY.
; SYNCHRONOUS SERIAL TRANSMISSION, MSB TO LSB.
; ENTER WITH CLOCK AND SELECT LINE LOW, DC=DS=0.
SD_OUT  LDX     #8         ;INITIALIZE BIT COUNT
SD_10   ASLA               ;PUT NEXT DATA BIT IN C
        BCS     SD_11
        BCLR    DD,PBDAT   ;DATA = 0
        BRA     SD_20
SD_11   BSET    DD,PBDAT   ;DATA = 1
        NOP
SD_20   BSET    DC,PBDAT   ;CLOCK = 1, 150nSEC MIN
        BCLR    DC,PBDAT   ;CLOCK = 0, 3.4uSEC MIN
        DECX               ;DECREMENT BIT COUNT
        BNE     SD_10      ;BRANCH IF NOT 0
        RTS
;
;SEND CONFIGURATION REGISTER DATA TO DISPLAY.
CR_OUT  BCLR    DC,PBDAT   ;CLOCK = 0
        BCLR    DS,PBDAT   ;SELECT = 0
        LDA     CR_0       ;CONFIGURATION DATA
        JSR     SD_OUT     ;SEND DATA
        BSET    DS,PBDAT   ;SELECT = 1
        RTS
;
;SEND DISPLAY REGISTER DATA TO DISPLAY.
DR_OUT  BCLR    DC,PBDAT   ;CLOCK = 0
        BCLR    DS,PBDAT   ;SELECT = 0
        LDA     DR_2       ;DISPLAY DATA D23-D16
        JSR     SD_OUT     ;SEND DATA
        LDA     DR_1       ;DISPLAY DATA D15-D08
        JSR     SD_OUT     ;SEND DATA
        LDA     DR_0       ;DISPLAY DATA D07-D00
        JSR     SD_OUT     ;SEND DATA
        BSET    DS,PBDAT   ;SELECT = 1
        RTS
;
;SUBROUTINE TO CONVERT BINARY TIMES IN (D_HRS) AND (D_MINS)
; TO BCD CHARACTERS IN (DIG1) THROUGH (DIG4).
B2C     CLR     DIG1       ;CLEAR ALL INCREMENTED
        CLR     DIG3       ;  CHARACTER VALUES
        LDA     D_HRS      ;BINARY HOURS
B2C10   SUB     #10        ;DECREMENT HOURS BY 10
        BMI     B2C15      ;BRANCH IF < 10
        INC     DIG1       ;ELSE INC TENS DIGIT
        BRA     B2C10      ;AGAIN
B2C15   ADD     #10
        STA     DIG2       ;STORE UNITS DIGIT
        LDA     D_MINS     ;BINARY MINUTES
B2C20   SUB     #10        ;DECREMENT MINUTES BY 10
        BMI     B2C25      ;BRANCH IF < 10
        INC     DIG3       ;ELSE INC TENS DIGIT
        BRA     B2C20      ;AGAIN
B2C25   ADD     #10
        STA     DIG4       ;STORE UNITS DIGIT
        RTS
;
;MODIFY DISPLAY HOURS (D_HRS) FOR CURRENT TIME FORMAT,
; SET AM/PM FLAGS AS REQUIRED, CONVERT BINARY TIME TO BCD,
; AND LOAD CONFIGURATION DATA IN CR_0.
TFMT    LDA     #CR1234         ;DEFAULT IS FOUR
        STA     CR_0            ; DIGIT DISPLAY
        BRSET   FMT,PADAT,TF12
;24HOUR FORMAT, AM & PM LEDs BOTH OFF
TF24    BCLR    AM,FLAG         ;CLEAR AM FLAG BIT
        BCLR    PM,FLAG         ;CLEAR PM FLAG BIT
        JSR     B2C             ;BINARY TO BCD
        BRA     TF99
;12HOUR FORMAT
TF12    LDA     D_HRS
        CMP     #11           ;MORNING ?
        BHI     TF12A         ;BRANCH IF NOON OR AFTER
        BSET    AM,FLAG       ;ELSE, SET AM FLAG BIT
        BCLR    PM,FLAG       ;AND CLEAR PM FLAG BIT
        CMP     #0            ;MIDNIGHT ?
        BNE     TF12D
        LDA     #12           ;MIDNIGHT TO 1AM
        STA     D_HRS
        BRA     TF12D
TF12A   BCLR    AM,FLAG       ;CLEAR AM FLAG BIT
        BSET    PM,FLAG       ;SET PM FLAG BIT
        CMP     #12
        BEQ     TF12D         ;NOON TO 1PM
        SUB     #12           ;AFTERNOON AND EVENING
        STA     D_HRS
TF12D   JSR     B2C           ;BINARY TO BCD
        TST     DIG1          ;TENS OF HOURS = 0 ?
        BNE     TF99          ;BRANCH IF NONZERO
        LDA     #CR_234       ;ELSE
        STA     CR_0          ;DECODE LEADING ZERO AS BLANK
TF99    RTS
;
;CLOCK DISPLAY SUBROUTINE.
;ENTER WITH DESIRED VALUES IN (D_HRS) AND (D_MINS).
C_DISP  JSR     TFMT     ;FORMAT DISPLAY DATA
        LDA     DIG2     ;HOURS
        ASLA             ;SHIFT
        ASLA             ; HOURS
        ASLA             ;  TO HIGH
        ASLA             ;   NIBBLE
        ORA     DIG1     ; DIG2:DIG1
        STA     DR_0     ;DISPLAY REGISTER LOW BYTE
        LDA     DIG4     ;MINUTES
        ASLA             ;SHIFT
        ASLA             ; MINUTES
        ASLA             ;  TO HIGH
        ASLA             ;   NIBBLE
        ORA     DIG3     ; DIG4:DIG3
        STA     DR_1     ;DISPLAY REGISTER MID BYTE
;COLON ON IF Colon Display FLAG BIT SET, ELSE...
CD10    BRSET   CD,FLAG,CD21
;COLON ON DURING EVEN SECONDS, OFF DURING ODD
CD20    BRSET   0,SECS,CD24   ;BRANCH IF ODD
CD21    LDA     #DR2_B1       ;BRIGHT, COLON ON
        BRA     CD28
CD24    LDA     #DR2_B0       ;BRIGHT, COLON OFF
CD28    STA     DR_2          ;DISPLAY REGISTER HI BYTE
;AM LED ON IF AM FLAG BIT SET
CD30    BRCLR   AM,FLAG,CD40
        LDA     #DR2_AM
        ORA     DR_2
        STA     DR_2
;PM LED ON IF PM FLAG BIT SET
CD40    BRCLR   PM,FLAG,CD50
        LDA     #DR2_PM
        ORA     DR_2
        STA     DR_2
;ALARM_ENABLED LED ON IF ALARM_ENABLE INPUT IS HIGH
CD50    BRCLR   AEN,PADAT,CD60
        LDA     #DR2_AE
        ORA     DR_2
        STA     DR_2
;LOW_BATTERY LED ON IF BATTERY INPUT IS LOW
CD60    BRSET   BAT,PADAT,CD70
        LDA     #DR2_LB
        ORA     DR_2
        STA     DR_2
;UPDATE DISPLAY
CD70    JSR     CR_OUT  ;SEND CONFIGURATION REGISTER
        JSR     DR_OUT  ;SEND DISPLAY REGISTER, 24-BITS
        RTS
;
;SET THE TIME-OF-DAY TO START OF DISPLAYED MINUTE
;TICKS CONTINUE VIA RTI WHILE IN THIS LOOP
TSL00   LDA     #IDV            ;INITIAL DELAY VALUE
        STA     DDV
;DONE IF TIME-SET SWITCH IS INACTIVE
TSL05   BRSET   TSET,PADAT,TSL90
; ELSE SET THE TIME
;BRANCH IF HOUR-SET IS INACTIVE
        BRSET   HSET,PADAT,TSL10
        INC     S_HRS           ;ELSE INC HRS
        LDA     S_HRS           ;COMPARE TO
        CMP     #24             ; ROLLOVER VALUE
        BLO     TSL30           ;DONE IF < 24
        CLR     S_HRS           ;ELSE CLEAR HOURS COUNT
        BRA     TSL30
;BRANCH IF MINUTE-SET IS INACTIVE
TSL10   BRSET   MSET,PADAT,TSL20
        INC     S_MINS          ;ELSE INC MINS
        LDA     S_MINS          ;COMPARE TO
        CMP     #60             ; ROLLOVER VALUE
        BLO     TSL30           ;DONE IF < 60
        CLR     S_MINS          ;ELSE CLEAR MINS COUNT
        BRA     TSL30
;
;NEITHER HOUR-SET NOR MINUTE-SET SWITCH ACTIVE
TSL20   BRA     TSL00
;
TSL30   LDA     S_HRS           ;TIME HAS BEEN CHANGED
        STA     D_HRS           ;UPDATE DISPLAY
        LDA     S_MINS          ; REGISTERS
        STA     D_MINS
        JSR     C_DISP          ;DISPLAY NEW TIME VALUE
        JSR     DDS00           ;DELAY FOR HUMAN RESPONSE TIME
TSL50   BRA     TSL05
TSL90   LDA     S_HRS           ;REPLACE THE CURRENT
        STA     HRS             ; TIME OF DAY WITH
        LDA     S_MINS          ;  CHANGED TEMPORARY
        STA     MINS            ;   VARIABLES
        CLR     SECS            ;START OF DISPLAYED MINUTE
        BSET    CI,FLAG         ;SET CLOCK INITIALIZED FLAG
        BCLR    CD,FLAG         ;CLEAR COLON DISPLAY FLAG
        LDA     #$AA
        STA     OLDSEC          ;FORCE REDISPLAY
        RTS
;
;SET THE ALARM-TIME TO START OF DISPLAYED MINUTE.
;TICKS CONTINUE VIA RTI WHILE IN THIS LOOP.
ASL00   LDA     #IDV            ;INITIAL DELAY VALUE
        STA     DDV
;DONE IF ALARM-SET SWITCH IS INACTIVE
ASL05   BRSET   ASET,PADAT,ASL90
; ELSE SET THE ALARM
;BRANCH IF HOUR-SET IS INACTIVE
        BRSET   HSET,PADAT,ASL10
        INC     A_HRS           ;ELSE INC HRS
        LDA     A_HRS           ;COMPARE TO
        CMP     #24             ; ROLLOVER VALUE
        BLO     ASL30           ;DONE IF < 24
        CLR     A_HRS           ;ELSE CLEAR HOURS COUNT
        BRA     ASL30
;BRANCH IF MINUTE-SET IS INACTIVE
ASL10   BRSET   MSET,PADAT,ASL20
        INC     A_MINS          ;ELSE INC MINS
        LDA     A_MINS          ;COMPARE TO
        CMP     #60             ; ROLLOVER VALUE
        BLO     ASL30           ;DONE IF < 60
        CLR     A_MINS          ;ELSE CLEAR MINS COUNT
        BRA     ASL30
;
;NEITHER HOUR-SET NOR MINUTE-SET SWITCH ACTIVE
ASL20   BRA     ASL00
;
ASL30   LDA     A_HRS           ;ALARM TIME CHANGED
        STA     D_HRS           ;UPDATE DISPLAY
        LDA     A_MINS          ; REGISTERS
        STA     D_MINS
        JSR     C_DISP          ;DISPLAY NEW ALARM VALUE
        JSR     DDS00           ;DELAY FOR HUMAN RESPONSE TIME
ASL50   BRA     ASL05
ASL90   BCLR    CD,FLAG         ;CLEAR COLON DISPLAY FLAG
        LDA     #$AA
        STA     OLDSEC          ;FORCE REDISPLAY
        RTS
;
;DELAY SUBROUTINE, ENTER WITH DELAY VALUE IN X
;EIGHT TIMER-COUNTER OVERFLOWS = 3.90mSEC.
DELAY   LDA     #8
DLY10   BRCLR   7,TSCR,DLY10    ;WAIT FOR TIMER OVERFLOW
        BSET    3,TSCR          ;CLEAR TIMER OVERFLOW FLAG
        DECA                    ;DEC OVERFLOW COUNTER
        BNE     DLY10           ;AGAIN IF > 0
        DECX                    ;DEC CYCLE COUNTER
        BNE     DELAY           ;AGAIN IF > 0
        RTS
;
;DECREASING DELAY SUBROUTINE
IDV     EQU     180             ;INITIAL DELAY VALUE
MDV     EQU     40              ;MINIMUM DELAY VALUE
DDS00   LDX     DDV             ;DELAY VALUE
        JSR     DELAY
        LDA     DDV             ;LAST DELAY VALUE
        LSRA                    ; 0.5 * DDV
        LSRA                    ; 0.25 * DDV
        LSR     DDV             ; 0.5 * DDV
        ADD     DDV             ; 0.75 OF PREVIOUS VALUE
        CMP     #MDV            ;COMPARE TO MINIMUM
        BHS     DDS90           ;BRANCH IF DDV >= MINIMUM
        LDA     #MDV            ;ELSE SET DDV TO MINIMUM
DDS90   STA     DDV
        RTS
;
;START OF MAIN PROGRAM ----------------------------------------
RESET   LDA     #$7F    ;HARDWARE RESET ENABLES ALL PULLDOWNS
        STA     PDRA    ;DISABLE PA0-6 PULLDOWNS
        CLR     PADAT   ;ALARM OFF
        LDA     #$80
        STA     PADDR   ;PORT A INITIALIZED
        LDA     #$04
        STA     PBDAT   ;PB2=DS=1, PB1=0, PB0=0
        LDA     #$07
        STA     PBDDR   ;PORT B INITIALIZED
        LDA     #$02
        STA     ISCR    ;DISABLE EXTERNAL IRQ
        LDA     #ENRTI  ;ENABLE REAL-TIME-INTERRUPT
        STA     TSCR
        CLR     HRS
        CLR     MINS    ;INITIALIZE TIME AT MIDNIGHT
        CLR     SECS
        CLR     TICKS   ;TIME COUNTERS CLEARED
        LDA     #CR____
        STA     CR_0
        JSR     CR_OUT  ;RESET LED DISPLAY DRIVER
        CLR     FLAG    ;CLEAR ALL FLAG BITS
;
;MAIN PROGRAM LOOP --------------------------------------------
LOOP    WAIT            ;WAIT FOR NEXT INTERRUPT
        LDA     #$02
        STA     ISCR    ;DISABLE EXTERNAL IRQ
        BIH     ML100   ;BRANCH IF POWER IS OKAY
        TST     PODC    ;TEST POWER OUT DOWN-COUNTER
        BEQ     LP100   ; BRANCH IF ZERO
        DEC     PODC    ;  ELSE DECREMENT IT
        BRA     ML101
;
;LOW POWER (BATTERY BACKUP) MODE
LP100   BRSET   LP,FLAG,LP200
        LDA     #CR____          ;PLACE DISPLAY IN LOW POWER
        STA     CR_0             ; MODE.  THIS BLANKS ALL
        JSR     CR_OUT           ;  LEDs.
        BSET    LP,FLAG          ;SET LOW_POWER FLAG
LP200   BRSET   AC,FLAG,LP600    ;BRANCH IF ALARM CONDITION
        BRCLR   AEN,PADAT,LOOP   ;BRANCH IF ALARM DISABLED
        TST     SECS             ;SECONDS COUNT = 0 ?
        BNE     LOOP             ; BRANCH IF <> 0
        LDA     HRS              ;IF TIME-OF-DAY
        CMP     A_HRS            ; EQUALS
        BNE     LOOP             ;  ZERO SECOND
        LDA     MINS             ;   OF
        CMP     A_MINS           ;    ALARM-TIME,
        BNE     LOOP             ;THEN
        BSET    AC,FLAG          ; SET ALARM CONDITION
        BSET    ALARM,PADAT      ; TURN ON ALARM
        BRA     LOOP
LP600   BRCLR   AEN,PADAT,LP690  ;BRANCH IF ALARM DISABLED
        LDA     SECS             ;SECONDS COUNT = 59 ?
        CMP     #59              ; END ALARM AT 59 SECONDS
        BNE     LOOP             ; ELSE NO CHANGE
LP690   BCLR    AC,FLAG          ;CLEAR ALARM CONDITION
        BCLR    ALARM,PADAT      ;TURN ALARM OFF
LP900   BRA     LOOP
;
;NORMAL POWER MODE
ML100   LDA     #32        ;WAIT FOR 32 INTERRUPTS WITH IRQ LOW
        STA     PODC       ; BEFORE CHANGING TO LOW POWER MODE
ML101   BCLR    LP,FLAG           ;CLEAR LOW_POWER FLAG
        BRSET   TSET,PADAT,ML110
        LDA     HRS               ;PLACE THE CURRENT
        STA     S_HRS             ; TIME-OF-DAY IN
        LDA     MINS              ;  TEMPORARY
        STA     S_MINS            ;   VARIABLES
        BSET    CD,FLAG           ;SET COLON DISPLAY FLAG
        JSR     TSL30             ;TIME SET ROUTINE
ML110   BRSET   ASET,PADAT,ML120
        BSET    CD,FLAG           ;SET COLON DISPLAY FLAG
        JSR     ASL30             ;ALARM SET ROUTINE
;
ML120   BRSET   AEN,PADAT,ML130   ;BRANCH IF ALARM ENABLED
        BCLR    ALARM,PADAT       ;ELSE TURN ALARM OFF
        BCLR    AC,FLAG           ;AND CLEAR ALARM CONDITION
;
ML130   LDA     SECS              ;CURRENT SECONDS COUNT
        CMP     OLDSEC            ;SAME AS (OLDSEC) ?
        BEQ     LOOP              ;DONE IF =
;
;THE REMAINDER OF THE LOOP IS ONLY DONE ONCE PER SECOND,
; AT THE START OF EACH SECOND.
ML200   STA     OLDSEC            ;UPDATE OLD SECOND VALUE
        LDA     HRS               ;TRANSFER TIME-OF-DAY
        STA     D_HRS             ; VALUES TO DISPLAY
        LDA     MINS              ;  REGISTERS
        STA     D_MINS
        JSR     C_DISP
;
;BLINK UNTIL TIME-SET SWITCH IS DEPRESSED
ML300   BRSET   CI,FLAG,ML400   ;BRANCH IF CLOCK INITIALIZED
        BRCLR   0,SECS,ML390    ;BRANCH IF EVEN SECOND
        BCLR    0,CR_0          ;BLANK THE DISPLAY DURING
        JSR     CR_OUT          ; ODD SECONDS
ML390   JMP     LOOP            ;DONE IF NOT INITIALIZED
;
ML400   BRCLR   AEN,PADAT,ML490   ;DONE IF ALARM DISABLED
        BRSET   AC,FLAG,ML500     ;BRANCH IF ALARM CONDITION
        BCLR    ALARM,PADAT       ; ELSE TURN ALARM OFF
        TST     SECS              ;FIRST SECOND OF
        BNE     ML490             ; CURRENT MINUTE ?
        LDA     HRS               ;IF TIME-OF-DAY
        CMP     A_HRS             ; EQUALS
        BNE     ML490             ;  ZERO SECOND
        LDA     MINS              ;   OF
        CMP     A_MINS            ;    ALARM-TIME,
        BNE     ML490             ;THEN,
        BSET    AC,FLAG           ; SET ALARM CONDITION
ML490   JMP     LOOP
;
ML500   BRCLR   0,SECS,ML530    ;BRANCH IF EVEN SECOND
        BCLR    ALARM,PADAT     ;ALARM OFF DURING ODD SECONDS
        BRA     ML600
ML530   BSET    ALARM,PADAT     ;ALARM ON DURING EVEN SECONDS
;
;LIMIT DURATION OF ALARM TO 30 MINUTES
ML600   LDA     A_MINS          ;ALARM MINUTE
        ADD     #30             ;30 MINUTES AFTER ALARM
        CMP     #60             ;TOTAL > 60 ?
        BLO     ML630           ;BRANCH IF < 60
        SUB     #60             ; ELSE SUBTRACT 60
ML630   CMP     MINS            ;SAME AS CURRENT MINUTES ?
        BNE     ML690           ;BRANCH IF NOT
        BCLR    AC,FLAG         ; ELSE CLEAR ALARM CONDITION
ML690   JMP     LOOP
;
;INTERRUPT SERVICE ROUTINES -----------------------------------
TICK    LDX     #3       ;START AT TICKS
TICK1   INC     TODAY,X  ;INC THIS COUNTER
        LDA     TODAY,X  ;NOW PUT IT IN ACCUM
        CMP     RLOVR,X  ;COMPARE IT TO ROLLOVER VALUE
        BLO     TICK9    ;DONE IF LESS THAN ROLLOVER VALUE
        CLR     TODAY,X  ;CLEAR THIS COUNTER
        DECX             ;GO TO NEXT LARGER COUNTER,
        BPL     TICK1    ; IF NOT YET AT HOURS COUNTER
TICK9   LDA     #ENRTI   ;RE-ENABLE RTI AND CLEAR
        STA     TSCR     ; REAL-TIME-INTERRUPT FLAG
        RTI
;
;IRQ IS ENABLED BY WAIT INSTRUCTION. IF POWER SENSE COMPARATOR
;TRIPS DURING WAIT, IRQ WILL BE TRIGGERED. TAKE NO ACTION,
;JUST RETURN TO MAIN PROGRAM.
HICK    RTI
;
;MASK OPTION REGISTER -----------------------------------------
        ORG     MOR
        FCB     %00100000       ;PULLDOWN RESISTORS ACTIVE,
;                       2M ON OSC PINS, EPROM ACCESS ALLOWED,
;                       NO PORT-A INTERRUPTS, EDGE SENSITIVE.
;INTERRUPT VECTORS --------------------------------------------
        ORG     $7F8
        FDB     TICK    ;TIMER INTERRUPT
        FDB     HICK    ;EXTERNAL INTERRUPT, IRQ
        FDB     RESET   ;SOFTWARE INTERRUPT
        FDB     RESET   ;RESET

