  ;---------------------------------------------------------------------------------------------------------------------
  ; DACmulti - test program, 16MHz
  ; Frekvence volani OutputValue je 20kHz
  ; Nastaven CTC rezim, citani nahoru, pouzita preddelicka + output compare
  ; Pouzit citac/casovac 0
  ;---------------------------------------------------------------------------------------------------------------------

  .NOLIST
  .INCLUDE "M16DEF.inc"                   ; Definice registru
  .LIST

  ;---------------------------------------------------------------------------------------------------------------------
  ; Definice
  ;---------------------------------------------------------------------------------------------------------------------

  .DEF  TEMP              = R16           ; Pracovni registr 
  .DEF  ADDR              = R17           ; Adresa multiplexu
  .EQU  RESET_ADDR        = 0x80          ; Nastaven 7. bit (WR)

  ;---------------------------------------------------------------------------------------------------------------------
  ; Kodovy segment
  ;---------------------------------------------------------------------------------------------------------------------

  .CSEG                                   ; Pocatek kodoveho segmentu

  .ORG 0
  RJMP Reset

  .ORG OC0Addr
  RJMP OutputValue

Reset:
  ; Nastavi SP na konec RAM
  LDI   TEMP,  HIGH(RAMEND)
  OUT   SPH,   TEMP
  LDI   TEMP,  LOW(RAMEND)
  OUT   SPL,   TEMP

  ; Adresa pro multiplex
  LDI   ADDR,  RESET_ADDR

  ; Konfigurace portu
  LDI   TEMP,  0xFF
  ; Port A jako vystupni (HIGH byte pro DAC)
  OUT   DDRA,  TEMP
  ; Port B jako vystupni (adresace multiplexu a vyvodu - pin 0-3 adresa pro LS145, pin 4-6 adresa pro 14051, pin 7 WR pro DAC)
  OUT   DDRB,  TEMP
  ; Port C jako vystupni (LOW byte pro DAC)
  OUT   DDRC,  TEMP
  ; Port B 0xFF
  OUT   PORTB, TEMP

  ; Nastavenim bitu CS02 na 0 (bit 2), CS01 na 1 (bit 1) a CS00 na 0 (bit 0) volime hodimy mikrokonroleru / 8,
  ; WGM01 = 1 (bit 3), WGM00 = 0 (bit 6) voli CTC rezim
  LDI   TEMP,  0b00001010                   
  OUT   TCCR0, TEMP                       ; Vlozime do TCCR0
  LDI   TEMP,  99                         ; Vrchol citace pro CTC rezim (16 MHz / 8 / 20kHz) - 1
  OUT   OCR0,  TEMP                       ; Vlozime hodnotu do OCR0
  LDI   TEMP,  0b00000010                 ; Nastavenim bitu OCIE0 (bit 1) povolime preruseni od OC
  OUT   TIMSK, TEMP                       ; Do registru TIMSK
  CLR   TEMP                              ; Nulujeme TEMP
  SEI                                     ; Povolime preruseni

  ; Cekaci smycka
MainLoop:
  RJMP  PC

  ;---------------------------------------------------------------------------------------------------------------------
  ; Obsluha preruseni od casovace
  ;---------------------------------------------------------------------------------------------------------------------

OutputValue:
  ; Nacteme data pro DAC - HIGH byte
  OUT   PORTA, R0
  ; LOW byte
  OUT   PORTC, R1      
  ; WR DAC LOW - povolime zapis na prevodnik                   
  CBI   PORTB, 7                          ; Pin 7 PORTB = 0, tzn WR LOW
  ; Pockame na ustaleni prevodniku
  ; Delay(x)
  ; Zakazeme zapis na prevodnik
  SBI   PORTB, 7                          ; Pin 7 PORTB = 1, tzn WR HIGH
  ; Volba vystupu multiplexu pro 14504, adresa kodovana BCD (0 - ABC = 0, 1 - A = 1, BC = 0, 2 - B = 1, AC = 0, 3 - AB = 1, C = 0,...)
  MOV   TEMP,  ADDR
  ORI   TEMP,  0x78                       ; Vymaskujeme index multiplexu (musi zustat HIGH) 
  OUT   PORTB, TEMP
  ; Pockame na ustaleni
  ; Delay(y)
  ; Adresa multiplexu pro LS145 - adresovanemu multiplexu stahneme INH na LOW (0 - ABCD = 0, 1 - A = 1, BCD = 0, 2 - AB = 1, CD = 0, ...)
  OUT   PORTB, ADDR                       ; Cela adresa
  ; Pockame na ustaleni
  ; Delay(z)
  ; Disablujeme multiplexy (zvedneme vse na HIGH)
  LDI   TEMP,  0xFF
  OUT   PORTB, TEMP

  ; Posun na dalsi vyvod/multiplex
  INC   ADDR
  CPI   ADDR,  0xC0                       ; Testujeme, zda adresa multiplexu je 8 (pro test jich mam 8) - hodnota obsahuje i bit WR
  BRNE  GenerateSample                    ; Pokracujeme
  ANDI  ADDR,  RESET_ADDR                 ; Resetujeme adresu vracime se na vyvod 0 multiplexu 0

  ; Zde muzeme pocitat
GenerateSample:
  ; Naplneni R0, R1

  RETI                                    ; Navrat z obsluhy preruseni a povoleni preruseni

  ;---------------------------------------------------------------------------------------------------------------------
