.include "tn2313def.inc"

.def tmp   = R16            ;Variable tmp
.def isreg = R17            ;ISR-Variable fuer Statusregister zwischenspeichern
.def itmp  = R18            ;ISR-Variable tmp
.def messungen = R19        ;Zaehler fuer Messungen
.def summe  = R20           ;ISR-Variable fuer Summe
.equ timervorspannwert = 165;=256-(100-9) zwischen Interrupt und neuem Vorspannen
                            ;vergehen 9 Takte: 6 Takte davon Eintritt in ISR weil
                            ;4 Takte bis Aufruf ISR-Vektror 2 Takte fuer Sprung zu ISR
                            ;Vorspannwert wurde mittels Frequenzzaehler verifiziert
; *** Sprungtabelle
  rjmp init                 ;Einsprung nach Reset
.org OVF0addr               ;Einsprung Timer0 Overflow
  rjmp isr_t0               ;2 Takte
; *** Initialisierung
init:
  ldi tmp,low(RAMEND)       ;Stackpointer initialisieren
  out SPL, tmp
; 1.3.2 Betriebsart bestimmen
  ldi tmp,timervorspannwert ;Timer-Vorspannwert setzen
  out TCNT0,tmp             ;Timer schreiben
  ldi tmp,1                 ;CLK/1 Vorteiler einstellen
  out TCCR0B,tmp
  ldi tmp, 1<<TOIE0         ;Overflowinterrupt frei schalten
  out TIMSK, tmp
; 1.3.3 Einstellungen fuer ISR
  ldi messungen,8           ;Anzahl Messungen
.dseg                       ;Anweisungen fuer Datenbereich
tab: .byte 8                ;reserviere 8Byte im SRAM
.cseg                       ;Anweisungen fuer Programmbereich
  ldi XH,high(tab)          ;X-PointerHigh
  ldi XL,low(tab)           ;X-PointerLow
  sei                       ;Globale Interruptfreigabe
; *** Hauptprogrammschleife
loop:
  nop      ;notwendig, sonst war Interrupt nur alle 2CLK moeglich
  rjmp loop
; 1.3.3 Interrupt Service Routine
isr_t0:                     ;6 Takte zwischen Interrupt und hier
  in isreg,SREG             ;1 Takt: sichere Statusregister, kann hier entfallen,
                            ;da im HP kein Statusregister verwendet wird
  ldi itmp,timervorspannwert;1 Takt: Timer-Vorspannwert wieder setzen
  out TCNT0,itmp            ;1 Takt: Timer schreiben
  in itmp,PINB              ;lade Portdaten
  st x+,itmp                ;speichere indirekt X und X++
  dec messungen             ;messungen--
  brne isr_fertig           ;!=0, dann noch eine Messung holen
  ldi itmp,0                ;sonst
  out TIMSK,itmp            ;Timerinterrupt stoppen
  rcall calc                ;Mittelwert berechnen
isr_fertig:
  out SREG,isreg            ;SREG wieder herstellen
  reti

; 1.3.4 Unterprogramm calc (war nicht gefordert als Code)
calc:
  ldi XH,high(tab)          ;X-PointerHigh
  ldi XL,low(tab)           ;X-PointerLow
  ldi messungen,8
  ldi summe,0
calc_again:
  ld itmp,x+                ;lade indirekt X und X++
  add summe,itmp 
  dec messungen             ;messungen-- aber Carryflag unveraendert
  brne calc_again           ;!=0, dann weiter summieren
  lsr summe                 ;/2
  lsr summe                 ;/2
  lsr summe                 ;/2
  out PORTD,summe           ;Ausgabe 
  ret
