       opt    b,c,w,x
       nam    Open Day Demonstration Clock
       spc    4
************************************************
*                                              *
*      Program to test CS2 breadboard          *
*      hardware                                *
*                                              *
************************************************
       spc    4
************************************************
*                                              *
*      I/O register addresses                  *
*                                              *
************************************************
dra    equ    $C000    PIA port A data
cra    equ    $C001    PIA port A control
drb    equ    $C002    PIA port B data
crb    equ    $C003    PIA port B control
cr13   equ    $8000    PTM Channel 1/3 control
cr2    equ    $8001    PTM Status/Chan 2 Control
tc1h   equ    $8002    PTM Channel 1 counter
tc1l   equ    $8003
tc2h   equ    $8004    PTM Channel 2 counter
tc2l   equ    $8005
tc3h   equ    $8006    PTM Channel 3 counter
tc3l   equ    $8007
       spc
************************************************
*                                              *
*      Static Variables                        *
*                                              *
************************************************
       org    0
pat    rmb    6        Display buffer
tc     rmb    1        Milli-second counter
psel   rmb    1        Digit select mask
pptr   rmb    2        Display buffer pointer
sem    rmb    1
secs   rmb    1
mins   rmb    1
hrs    rmb    1
ampm   rmb    1
setkey rmb    1
inckey rmb    1
setmde rmb    1
flash  rmb    1
quarts rmb    1
hunds  rmb    1
temp   rmb    2        for double arithmetic
savex  rmb    2
       spc
************************************************
*                                              *
*      Interrupt vectors                       *
*                                              *
************************************************
       org    $FFF8
       fdb    timout   Maskable
       fdb    start    Software
       fdb    start    Non-maskable
       fdb    start    Reset
       page
************************************************
*                                              *
*      Start of program                        *
*                                              *
************************************************
       org    $FC00
start  lds    #$7F     Initialise stack pointer
       spc
************************************************
*                                              *
*      Initialise PIA                          *
*                                              *
************************************************
       clr a           Access both Data
       sta a  cra      Direction regs
       sta a  crb
       sta a  sem
       lda a  #$FF     Set all bits to output
       sta a  dra
       sta a  pat
       sta a  pat+1
       sta a  pat+2
       sta a  pat+3
       sta a  pat+4
       sta a  pat+5
       lda a  #$3F     Bits 0-5 out, 6,7 in
       sta a  drb
       lda a  #%100    Access data regs
       sta a  cra
       sta a  crb
       spc    2
************************************************
*                                              *
*      Initialise Counter and Display buffer   *
*                                              *
************************************************
       ldx    #pat     Load pptr with start
       stx    pptr     of display buffer
       lda a  #$04
       sta a  psel
       lda a  #1
       sta a  tc
       sta a  hunds
       lda a  #$59
       sta a  secs
       sta a  mins
       lda a  #$11
       sta a  hrs
       lda a  #$7F
       sta a  ampm
       clr b
       spc
************************************************
*                                              *
*      Initialise PTM (channel 3)              *
*                                              *
************************************************
       lda a  #1
       sta a  cr2      Access control reg 1
       sta a  cr13     Reset all counters
       sta b  cr2      Access control reg 3
       ldx    #124     Load counter 3 with
       stx    tc3h     1 ms time constant
       lda a  #$43     Load control reg 3 for
       sta a  cr13     continuous, internal
*                      prescaled by 8
       lda a  #1
       sta a  cr2      Access control reg 1
       sta b  cr13     Enable counters
       cli
       spc
mloop  lda a  #5
       sta a  setkey
clock  jsr    wait
       lda a  drb
       bit a  #%01000000
       bne    ok1
       dec    setkey
       bne    dechun
       jmp    sethrs
ok1    lda a  #5
       sta a  setkey
dechun lda a  hunds
       dec a
       bne    notsec
       lda a  secs
       add a  #1
       daa
       cmp a  #$60
       bne    notmin
       lda a  mins
       add a  #1
       daa
       cmp a  #$60
       bne    nothr
       lda a  hrs
       add a  #1
       daa
       cmp a  #$12
       bne    nothdy
       lda b  ampm
       eor b  #$80
       sta b  ampm
nothdy cmp a  #$13
       bne    notto1
       lda a  #$01
notto1 sta a  hrs
       lda b  #$FF
       sta b  pat
       lda b  #$7F
       ldx    #pat
       jsr    disply
       lda a  #$00
nothr  sta a  mins
       lda b  #$C0
       sta b  pat+2
       lda b  #$7F
       ldx    #pat+2
       jsr    disply
       lda a  #$00
notmin sta a  secs
       lda b  #$C0
       sta b  pat+4
       lda b  ampm
       ldx    #pat+4
       jsr    disply
       lda a  #100
notsec sta a  hunds
       bra    clock
sethrs lda a  #$FF
       sta a  pat+4
       lda a  ampm
       sta a  pat+5
hwlp   lda a  #5
       sta a  setkey
waith1 jsr    wait
       lda a  drb
       bit a  #%01000000
       beq    hwlp
       dec    setkey
       bne    waith1
       spc
sethlp lda a  #5
       sta a  setkey
       sta a  inckey
       clr    flash
nxtqth lda a  #25
       sta a  quarts
waith2 jsr    wait
       lda a  drb
       bit a  #%01000000
       bne    okh1
       dec    setkey
       bne    okh2
       lda a  hrs
       lda b  #$FF
       sta b  pat
       lda b  #$7F
       ldx    #pat
       jsr    disply
       jmp    setmin
okh1   lda b  #5
       sta b setkey
ckinch bit a  #%10000000
       bne    okh2
       dec    inckey
       bne    decqth
       jsr    hrinc
       lda a  #100
       sta a  quarts
       jmp    inchrs
okh2   lda b  #5
       sta b  inckey
decqth dec    quarts
       bne    waith2
       com    flash
       beq    rsthrs
       lda a  #$FF
       sta a  pat
       lda a  #$7F
       sta a  pat+1
       bra    nxtqth
rsthrs lda a  hrs
       lda b  #$FF
       sta b  pat
       lda b  #$7F
       ldx    #pat
       jsr    disply
       bra    nxtqth
       spc
inchrs lda a  #5
       sta a  inckey
waith3 jsr    wait
       lda a  drb
       bit a  #%10000000
       beq    okh3
       dec    inckey
       bne    waith3
       jmp    sethlp
okh3   dec    quarts
       bne    inchrs
       jsr    hrinc
       lda a  #25
       sta a  quarts
       bra    inchrs
       spc
       spc
setmin lda a  #5
       sta a  setkey
waitm1 jsr    wait
       lda a  drb
       bit a  #%01000000
       beq    setmin
       dec    setkey
       bne    waitm1
       spc
setmlp lda a  #5
       sta a  setkey
       sta a  inckey
       clr    flash
nxtqtm lda a  #25
       sta a  quarts
waitm2 jsr    wait
       lda a  drb
       bit a  #%01000000
       bne    okm1
       dec    setkey
       bne    okm2
       lda a  mins
       lda b  #$C0
       sta b  pat+2
       lda b  #$7F
       ldx    #pat+2
       jsr    disply
       jmp    backtc
okm1   lda b  #5
       sta b setkey
ckincm bit a  #%10000000
       bne    okm2
       dec    inckey
       bne    decqtm
       jsr    mininc
       lda a  #100
       sta a  quarts
       jmp    incmin
okm2   lda b  #5
       sta b  inckey
decqtm dec    quarts
       bne    waitm2
       com    flash
       beq    rstmin
       lda a  #$FF
       sta a  pat+2
       lda a  #$7F
       sta a  pat+3
       bra    nxtqtm
rstmin lda a  mins
       lda b  #$C0
       sta b  pat+2
       lda b  #$7F
       ldx    #pat+2
       jsr    disply
       bra    nxtqtm
       spc
incmin lda a  #5
       sta a  inckey
waitm3 jsr    wait
       lda a  drb
       bit a  #%10000000
       beq    okm3
       dec    inckey
       bne    waitm3
       jmp    setmlp
okm3   dec    quarts
       bne    incmin
       jsr    mininc
       lda a  #25
       sta a  quarts
       bra    incmin
       spc
       spc
backtc lda a  #5
       sta a  setkey
backlp jsr    wait
       lda a  drb
       bit a  #%01000000
       beq    backtc
       dec    setkey
       bne    backlp
       lda a  #$C0
       sta a  pat+4
       and a  ampm
       sta a  pat+5
       clr    secs
       lda a  #100
       sta a  hunds
       jmp    mloop
       page
************************************************
*                                              *
*      PTM timeout interrupt handler           *
*                                              *
************************************************
       spc    2
************************************************
*                                              *
*      refresh display                         *
*                                              *
************************************************
timout lda a  cr2      Read PTM status
       ldx    tc3h     Read counter to clear
*                      interrupts
       lda a  psel     Load digit select mask
       ldx    pptr     Load display digit ptr
       clr b           Turn off current digit
       sta b  drb      (avoids ghosting)
       lda b  0,x      Send new digit pattern
       sta b  dra
       sta a  drb      Select digit displayed
       inx             Set up for next digit
       lsl a
       bit a  #$40     Check for end of buffer
       beq    norst
       lda a  #4       Reset mask and pointer
       ldx    #pat
norst  sta a  psel     Store mask and pointer
       stx    pptr
       lda a  tc
       dec a
       bne    nothun
       inc    sem
       lda a  #10
nothun sta a  tc
       rti
       page
wait   tst    sem
       ble    wait
       dec    sem
       rts
       spc    2
mininc lda a  mins
       add a  #1
       daa
       cmp a  #$60
       bne    nomrst
       lda a  #0
nomrst sta a  mins
       lda b  #$C0
       sta b  pat+2
       lda b  #$7F
       ldx    #pat+2
       bra    disply
       spc
hrinc  lda a  hrs
       add a  #1
       daa
       cmp a  #$12
       bne    nohcom
       lda b  ampm
       eor b  #$80
       sta b  ampm
       sta b  pat+5
nohcom cmp a  #$13
       bne    nohrst
       lda a  #$01
nohrst sta a  hrs
       lda b  #$FF
       sta b  pat
       lda b  #$7F
       ldx    #pat
       bra    disply
       spc
disply stx    savex
       psh a
       psh b
       bsr    decode
       tsx
       and a  0,x
       ins
       ldx    savex
       sta a  1,x
       pul a
       lsr a
       lsr a
       lsr a
       lsr a
       beq    nosig
       bsr    decode
       ldx    savex
       sta a  0,x
nosig  rts
************************************************
*                                              *
*      Subroutine 'decode'                     *
*                                              *
*      Replaces contents of acc A with         *
*      (asserted low) 7 segment display        *
*      pattern corresponding to the original   *
*      contents of least significant nibble    *
*      of acc A                                *
*                                              *
************************************************
decode ldx    #digtab  Store decode table
       stx    temp     address in temp
       and a  #$0F     Mask out ms nibble
       add a  temp+1   Add ls nibble to lsb temp
       sta a  temp+1
       bcc    noinc    Add carry to msb of temp
       inc    temp
noinc  ldx    temp     Fetch 7 segment pattern
       lda a  0,x
       rts
digtab fcb    %11000000
       fcb    %11111001
       fcb    %10100100
       fcb    %10110000
       fcb    %10011001
       fcb    %10010010
       fcb    %10000010
       fcb    %11111000
       fcb    %10000000
       fcb    %10010000
       fcb    %10001000
       fcb    %10000011
       fcb    %11000110
       fcb    %10100001
       fcb    %10000110
       fcb    %10001110
       end
