*_______________________________________________
*
*           I.C.Dennison
*                         cs4
*
*           CAR DISPLAY  v2
*_______________________________________________
*    EQUIVILANCES
dra    equ    $C000    PIA port A data reg
ddra   equ    $C000    "      data direction reg
cra    equ    $C001    "      control reg
drb    equ    $C002    PIA port B data reg
ddrb   equ    $C002    "      data direction reg
crb    equ    $C003    "      control reg
cr13   equ    $8000    PTM 1/3 control
cr2    equ    $8001    2  control
cntr1  equ    $8002    counter 1 /counter 1 latch
cntr2  equ    $8004    counter 2/counter 2 latch
cntr3  equ    $8006    counter 3/counter 3 latch
imperial   equ  0
metric     equ  1
overflow   equ  9999     float tht point !
dist       equ  10
float      equ  12       mem or nonmem branches
sampl      equ  0
sfuel      equ  6
sfuel2     equ  8
sspee      equ  2
sspee2     equ  4
*______________________________________________
*                                              
*         Variables                            
*                                              
*______________________________________________
       org    0
vars
*______________display variables_______________
pat    rmb    7        display buffer
psel   rmb    1        mask for selecting digit in 7-
pptr   rmb    2        pointer to pat
*______________switch variables________________
switc1 rmb    1         cleared when serviced
switc2 rmb    1         not cleared: =mode
switc3 rmb    1         cleared when serviced
switc4 rmb    1         cleared when serviced
impmet rmb    1         imperial/metric mode
skip   rmb    1         switch debouncing
stop   rmb    1           "        "
*_________________time variables _______________
tick   rmb    1         1 sec indicator
tock   rmb    1         5 sec indicator
halfsec rmb   1
min1   rmb    1
min2   rmb    1         clock
hour1  rmb    1
hour2  rmb    1
milsec rmb    2
*____________general purpose variables____________
work1    rmb  2
work2    rmb  2
work3    rmb  2
spin     rmb  1
quotient rmb  4          32 division
divdend  rmb  4
divisor  rmb  2
orig     rmb  2
*__________________trip variables_________________
tripvars
samples   rmb  2       no of samples
sumspeed  rmb  4       summation of samples
sumfuel   rmb  4            "         "
metre10   rmb  2       trip distance
floatwhere rmb 2       where floating point on distance
endtripvars
*___________memory variables_______________________
memtripvars
memsamples  rmb  2
memspeedsum rmb  4
memfuelsum  rmb  4       saved trip vars
memmetre10  rmb  2
memfloat    rmb  2
memory      rmb  2
memdisplay  rmb  1
*_________ distance sampling variables ___________
consumption rmb 2
olddist   rmb  2
distptr   rmb  2     samples distance between
dist1     rmb  2       fuel pulses
dist2     rmb  2
dist3     rmb  2
dist4     rmb  2
*________________speed variables________________
vcount    rmb  1
speed     rmb  2
oldspeed  rmb  2
endvars
*
*_______________________________________________
*                                              
*      Start of program                        
*                                              
*_______________________________________________
       org    $FC00
start  lds    #$400    Initialise stack pointer
       ldu    #$1FF    initialise user stack
*
*__________ initialise variables _______________
       ldx   #vars
initialise
       clr   0,x+
       cmpx  #endvars       clear RAM
       bne   initialise
*
       ldx   #tripvars    not in mem mode
       stx   memory
       ldx   #dist1       start sampling buffer
       stx   distptr
       lda   #6
       sta   switc2
       inc   switc3         set clock 1st !
       com   memdisplay
*______________________________________________
*                                              
*      Initialise PIA                          
*                                              
*______________________________________________
       clra            Access both Data
       sta    cra      Direction regs
       sta    crb
       lda    #$FF     Set all bits to output
       sta    ddra
       lda    #$7F
       sta    ddrb
       lda    #%100    Access data regs
       sta    cra
       sta    crb
*______________________________________________
*                                              
*      Initialise Display buffer   
*                                              
*______________________________________________
       ldx    #pat     Load pptr with start
       stx    pptr     of display buffer
       lda    #$01     Initialise digit select
       sta    psel     mask
*______________________________________________
*                                              
*      Initialise PTM 
*                                              
*______________________________________________
       lda    #1
       sta    cr2      Access control reg 1
       ldx    #$7FFF
       stx    cntr1
       sta    cr13     Reset all counters
       clrb
       stb    cr13     enable counters
       stb    cr2      Access control reg 3
       ldx    #124     Load counter 3 with
       stx    cntr3    1 ms time constant
       lda    #$43     Load control reg 3 for
       sta    cr13     continuous, internal
*                      prescad by 8
       lda    #$41     external clock
       sta    cr2      in control 2
       bsr    floatpoint  load counter2
*______________________________________________
*______________________________________________
*                                              
*      Main program                
*                                              
*______________________________________________
       cli             Enable interrupts
wait
*
*_______________drive bargraph in kph_________
*
       ldd  #$FFFF
       ldx  speed
poop   leax -10,x
       cmpx #0
       blt  pow
       lsla
       rolb
       bra poop
pow    std pat
*
*_____________ update mode display_____________
*
       lda  switc2
       cmpa #7
       bne  wsx
       clr switc2
       bsr outtime
wsx    bsr newmode
*
*_______________5 sec operations_______________
*
       lda  tock
       cmpa #10
       bne  elbow
       clr  tock
       ldx  samples
       leax 1,x            take new sample of
       stx  samples           current:
       ldx  #sumspeed
       ldd  speed            speed
       bsr  add32
       ldx  #sumfuel
       ldd  consumption      fuel consuption
       bsr  add32
elbow
*
*_____________1/2 halfsec operations_____________
*
       lda  tick
       beq  wait
       clr  tick
       inc  halfsec
       inc  tock
       lda  switc2
       bne  colt
       clr  a
       bsr  outpoint   flash point on clock
colt
*
*calculate fuel
*
       ldx  #dist1
       bsr  avergsample  avg. dist. between fuel pulses
       ldx  #4           see software manual
       ldy  #61953
       bsr  divide
       ldd  quotient+2
       std  consumption
*
*_____________keep time_____________________
*
       lda  halfsec
       cmpa #120
       bne  xop 
       clr  halfsec
       bsr  incmin
*___________________________________________
*
*  Output current mode display 
*
*___________________________________________
*
*___________time display____________________
*
       lda  switc2
       bne  xop
       bsr  outtime
xop
*
*___________speed display___________________
*       
       lda  switc2
       cmpa #1
       bne  apa
       ldd  speed
       bsr  kmconvert
       bsr  outbcd
apa
*
*_________trip distance display___________
*
       lda  switc2
       cmpa #2
       bne  frog
       ldx  memory       pull out mem or current
       ldd  dist,x                    variables
       bsr  kmconvert
       bsr  outbcd
       ldx  memory
       lda  float,x
       bsr  outpoint
frog
*
*___current fuel consumption display______
*
       lda  switc2
       cmpa #3
       bne  splint
       ldd  consumption
       bsr  fuelconvert
       bsr  outextra
splint
*
*________trip average speed display________
*
       lda  switc2
       cmpa #4
       bne  doze
       ldx  memory      pull out memory or
       ldd  sampl,x      current variables
       ldy  sspee2,x
       ldx  sspee,x
       bsr  divide
       ldd  quotient+2
       bsr  kmconvert
       bsr  outbcd
doze
*
*___trip average fuel consumption display__
*
       lda  switc2
       cmpa #5
       bne  hairy
       ldx  memory    pull out current or
       ldd  sampl,x    memory variables
       ldy  sfuel2,x
       ldx  sfuel,x
       bsr  divide
       ldd  quotient+2
       bsr  fuelconvert
       bsr  outextra
hairy
knee
*__________________________________________
*
*       perform switch functions
*
*__________________________________________
       lda  memdisplay    switches have different
       bgt  gomem         function depending on
*                              memory mode
*
*____________resets trip variables_________
*
       lda  switc1
       beq  sos
       clr  switc1
       ldx  #tripvars
clean  clr  0,x+
       cmpx #endtripvars
       bne  clean
       bsr  floatpoint  reset point
sos
*
*___________clock setting__________________
*  
       lda  switc3
       beq  vvv
       lda  switc2
       cmpa #6
       bne  vvv
       clr  switc3
       clr  hour2
       clr  min2
go     bsr  outtime
       lda  switc3
       cmpa #2
       beq  fin
       lda  switc4
       beq  go
       clr  switc4
       lda  switc3
       beq  domin
       clr  switc2      go to clock mode
       bsr  inchour       afterwards!
       bra  go
domin  bsr  incmin
       bra  go
fin    clr  switc3
       clr halfsec
vvv
*
gomem
*_______________memory mode change____________________
       lda  switc3
       beq  nomem
       clr  switc3
       ldx  memory
       cmpx #tripvars
       beq  other     change 'mem or current variables'
       leax -28,x                      pointer
other  leax 14,x
       stx  memory
       lda  memdisplay     change memory indicator led
       eora #$80
       sta  memdisplay
nomem
*
       lda  switc4
       beq  notsave    save the trip variables
       clr  switc4
       ldx  #tripvars
       ldb  #14
       bsr  transfer
notsave
       lda  switc1
       beq  notrestart    continue trip averages etc.
       clr  switc1         using saved trip condition
       ldx  #memtripvars
       ldb  #-14
       bsr  transfer
notrestart
       bra wait
 
*_____________________________________________________
*_____________________________________________________
*
*            routines
*
*_____________________________________________________
*
*}[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: transfers current trip variables to memory
*           or visaversa
* input: 0
* output 0
* regs: a,x
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
transfer
       clr  work1
copy
       lda  0,x
       sta  b,x
       leax 1,x
       inc  work1
       lda  work1
       cmpa #14
       bne  copy
       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: coverts tooutputs bcd and 
* input: d reg             point in centre
* output: 0
* subr: outbcd,outpoint
* regs: a
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
outextra
       bsr  outbcd
       clr  a
       bsr  outpoint
       rts

*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: adds to a 32 bit no.
* input: d reg, x address
* output: 0
* regs: d
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
add32  addd 2,x
       std  2,x
       bcc  pie
       ldd  0,x
       addd #1
       std  0,x
pie    rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: averages 4 values in a buffer
* input: x address
* output: d reg
* regs: d
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
avergsample
        ldd  0,x
        addd 2,x
        addd 4,x
        addd 6,x
        lsra
        rorb
        lsra    divide by 4
        rorb
        rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: converts to bcd and outputs to
*           display
* input: d reg
* output: 0
* subr: tobcd,todisplay
* regs: x
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
outbcd bsr tobcd
       ldx #pat+5
       bsr outdisplay
       bsr todisplay
       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: converts l/100km->mpg
* input: d reg
* output: d reg
* regs: x,y,d
* subr: divide
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
fuelconvert
       ldx  impmet
       bne  tooth
       ldx  #43
       ldy  #7496
       bsr  divide
       ldd  quotient+2
tooth  rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: 5/8*km->miles
* input: d
* output: d
* regs: x,d
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
kmconvert
       ldx  impmet
       bne  nogo
       std  orig
       ldb  #160
       mul
       std  work1
       ldd  orig
       lda  #5
       mul
       lsra
       rorb
       lsra
       rorb
       lsra
       rorb
       addd work1
nogo   rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: complements the dec .point
* input: a offset
* output: 0
* regs: a,b,x
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
outpoint
       ldx  #pat+3
       leax a,x
       ldb  0,x
       eorb #$80
       stb  0,x
       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: updates time by 1 minute
* input: 0
* output: 0
* regs: a
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
incmin inc min2
       lda min2
       cmpa #60
       bne  noh
       clr min2
inchour inc hour2
       lda hour2
       cmpa #24
       bne  noh
       clr  hour2
noh    rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: outputs current time to display
* input: 0
* output: 0
* regs: d,x,y
* subr: to display
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
outtime
       ldd min1
       bsr tobcd
       ldx #pat+5
       bsr outdisplay
       ldd hour1
       bsr tobcd
       ldx #pat+3
       bsr outdisplay
       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: outputs mode display
* input: 0
* output: 0
* regs: x,a,b
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
newmode ldx  #modeout
        lda  switc2
        ldb  a,x
        andb memdisplay
        stb  pat+6
        rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: adjusts result in bcd shifting
* input: x address
* output: 0
* regs a,x
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
makebcd
       lda 0,x
       adca 0,x
       daa  
       sta  0,x
       leax -1,x
       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: converts binary to bcd by shifting 16
*           bits and decimal adjusting result
* input: d reg
* output:0
* regs:y,b,x
* subr: makebcd
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
tobcd std  orig
       ldy  #orig
       ldb  #16
       stb  spin
       clr  work1
       clr  work1+1
shif   bsr  shift16
       ldx  #work1+1
       bsr makebcd
       bsr makebcd
       dec spin
       bne shif
       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: outputs to  display
* input: x,y
* output: 0
* regs: a,x,y
* subr: mask
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
outdisplay
       ldy  #work1+1
       bsr  todisplay
       rts

todisplay lda  0,y
          bsr  mask
          sta  0,x
          lda  0,y
          lsra
          lsra
          lsra
          lsra
          bsr  mask
          sta  -1,x
          leax -2,x
          leay -1,y
          rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: selects and shifts byte
*           into msb + lsb
* input: a,x
* output: a
* regs: a,x
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
mask      anda #$0F
          pshu x
          ldx  #digtab
          lda  a,x
          pulu x
          rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: 32 bit divide
* input: d,x,y
* output: 0
* regs: x,y,d
* subr: shift32
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
divide    stx  divdend
          sty  divdend+2
          std  divisor
          ldb  #32
          stb  spin
          ldd  #0
          std  quotient
          std  quotient+2
          pshu d
vest      ldy  #divdend
          bsr  shift32          shift 1 bit of 32 bit
          pulu d
          rolb
          rola
          ldy  #quotient
          subd divisor
          blt  sock
          inc  3,y       
          bra  foot
sock      addd divisor
foot      dec  spin
          beq  check
          pshu d
          bsr  shift32
          bra  vest
check     ldx  divisor
          bne  ear
          clr  quotient+2
          clr  quotient+3
ear       rts
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: shifts 32 bit variables
* input: y address
* output: 0
* regs: d
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
shift32   ldd  2,y
          lslb
          rola
          std  2,y
shift16   ldd  0,y
          rolb
          rola
          std  0,y
          rts
*___________________________________________
*                             
*      IRQ  interrupt handler 
*
*                             
*___________________________________________
findint   lda  cr2
          cmpa #$82      find which counter 
          bne  frop          is interrupting
          jmp  distint
frop      jmp  timeint
*_____________________________________________
*                                              
*      refresh display                         
*                                              
*_____________________________________________
timeint 
       ldx    cntr3    Read counter to clear
*                      interrupts
       lda    psel     Load digit select mask
       ldx    pptr     Load display digit ptr
       clrb            Turn off current digit
       stb    drb      (avoids ghosting)
       ldb    0,x      Send new digit pattern
       stb    dra
       sta    drb      Select digit displayed
       leax   1,x      Set up for next digit
       lsla
       bita   #$80     Check for end of buffer
       beq    norst
       lda    #1       Reset mask and pointer
       ldx    #pat
norst  sta    psel     Store mask and pointer
       stx    pptr
*________________________________________
*                                              
*      Increment timers and update display     
*      buffer                                  
*                                              
*________________________________________
**
**
       inc   vcount
       lda   vcount
       cmpa  #222
       bne   aaa
       clr   vcount           find current speed
       ldx   #oldspeed
       bsr   newsample
       std   speed
*
aaa    ldx    milsec
       leax   1,x
       cmpx  #500            see if halfsec has gone
       bne   ppp
       inc   tick
pant   ldx   #0
ppp    stx   milsec
       ldx   #switc1
       lda   cra               read switches
       bsr switch
       bsr  switch
       lda  crb
       bsr  switch
       bsr  switch
       ldb  dra      clear  flags
       ldb  drb
       andb #$80
       stb  impmet
       rti
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: reads switch input flags
* input: x address,a
* output: 0
* regs: x,a,b
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
switch rola
       bcc  zzz
       clr  stop
       ldb  skip
       bne  bbb
       inc  0,x
       inc  skip
zzz    inc  stop
       ldb  stop
       cmpb #100
       bne  bbb
       clr  skip
bbb    leax 1,x
       rts
*_____________________________________________
*
*             10 metere interrupt
*
*______________________________________________
distint
         ldx  cntr2
         ldx  metre10
         leax 1,x
         cmpx #overflow
         ble  ok
         inc  floatwhere
         bsr  floatpoint
ok       stx  metre10
         rti
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: floats point if overflow screen
* input: 0
* output: 0
* regs:
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
floatpoint
         ldx  #fillcounter
         lda  floatwhere
         leax a,x
         ldd  a,x
         std  cntr2
         ldx  #1000
         rts
*_____________________________________________
*
*                fuel interrupt
*
*_____________________________________________
fuelint
         ldx  #olddist
         bsr  newsample
         rti
*
*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
* descript: places a new value of distance 
*           between fuel pulses in circular
*           buffer
* input: x address
* output: 0
* regs: x,y,d
*]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
newsample
        ldd  0,x
        ldy  cntr1
        sty  0,x
        subd 0,x
        cmpx #oldspeed
        beq  miss
        ldy  2,x
        std  0,y++
        cmpy #dist4+2
        blt  can
        leay -8,y
can     sty   2,x
miss    rts
*
* patterns in 7-segment code for decimal digits 
*
digtab fcb    %11000000
       fcb    %11111001
       fcb    %10100100
       fcb    %10110000
       fcb    %10011001
       fcb    %10010010
       fcb    %10000010
       fcb    %11111000
       fcb    %10000000
       fcb    %10010000
*
*      mode display patterns
*
modeout
        fcb   %11111110
        fcb   %11111101
        fcb   %11111011
        fcb   %11110111
        fcb   %11101111
        fcb   %11011111
        fcb   %10111111
*
*          counter 2 latch values
*
fillcounter
        fdb    161
        fdb    1619
        fdb    16203
*_____________________________________________
*
*    Interrupt and reset vectors               
*                                              
*_____________________________________________
       org    $FFFC    NMI
       fdb    fuelint
       org    $FFF8    IRQ
       fdb    findint   interrupt handler
       org    $FFFE
       fdb    start    start of program
*
       end


