//-------------------------------------------------
//          TestSuite: Init
//-------------------------------------------------

#include "lcd.h"
#include "util.h"
#include "os_core.h"
#include "os_scheduler.h"

#include <avr/interrupt.h>

#define DELAY 100

#if VERSUCH == 2

#define checkRegisterInit(IDX) \
        asm volatile(\
            "tst r0         \n\t"\
            "brne 1f        \n\t"\
            "tst r1         \n\t"\
            "brne 1f        \n\t"\
            "tst r2         \n\t"\
            "brne 1f        \n\t"\
            "tst r3         \n\t"\
            "brne 1f        \n\t"\
            "tst r4         \n\t"\
            "brne 1f        \n\t"\
            "tst r5         \n\t"\
            "brne 1f        \n\t"\
            "tst r6         \n\t"\
            "brne 1f        \n\t"\
            "tst r7         \n\t"\
            "brne 1f        \n\t"\
            "tst r8         \n\t"\
            "brne 1f        \n\t"\
            "tst r9         \n\t"\
            "brne 1f        \n\t"\
            "tst r10        \n\t"\
            "brne 1f        \n\t"\
            "tst r11        \n\t"\
            "brne 1f        \n\t"\
            "tst r12        \n\t"\
            "brne 1f        \n\t"\
            "tst r13        \n\t"\
            "brne 1f        \n\t"\
            "tst r14        \n\t"\
            "brne 1f        \n\t"\
            "tst r15        \n\t"\
            "brne 1f        \n\t"\
            "tst r16        \n\t"\
            "brne 1f        \n\t"\
            "tst r17        \n\t"\
            "brne 1f        \n\t"\
            "tst r18        \n\t"\
            "brne 1f        \n\t"\
            "tst r19        \n\t"\
            "brne 1f        \n\t"\
            "tst r20        \n\t"\
            "brne 1f        \n\t"\
            "tst r21        \n\t"\
            "brne 1f        \n\t"\
            "tst r22        \n\t"\
            "brne 1f        \n\t"\
            "tst r23        \n\t"\
            "brne 1f        \n\t"\
            "tst r24        \n\t"\
            "brne 1f        \n\t"\
            "tst r25        \n\t"\
            "brne 1f        \n\t"\
            "tst r26        \n\t"\
            "brne 1f        \n\t"\
            "tst r27        \n\t"\
            "brne 1f        \n\t"\
            "tst r28        \n\t"\
            "brne 1f        \n\t"\
            "tst r29        \n\t"\
            "brne 1f        \n\t"\
            "tst r30        \n\t"\
            "brne 1f        \n\t"\
            "tst r31        \n\t"\
            "brne 1f        \n\t"\
            "breq 2f        \n\t"\
            "1: jmp 0       \n\t"\
            "2: nop         \n\t");\
            test##IDX++;

#else

void checkRegisterInit(uint8_t i) {
  os_enterCriticalSection();
  // You cannot run this with exercises after V2 due to the dynamic dispatcher.
  lcd_clear();
  lcd_writeProgString(PSTR("Support for V.2 only!"));
  for (;;);
}

#endif

uint8_t test1 = 0;
uint8_t test2 = 0;
uint8_t test3 = 0;
uint8_t test4 = 0;

PROGRAM(1, AUTOSTART) {
  checkRegisterInit(1);
  os_exec(3,DEFAULT_PRIORITY);
  for (;;) {
    lcd_line1();
    lcd_writeProgString(PSTR("Test OK: "));
    lcd_writeDec(test1+test2+test3+test4);
    lcd_writeChar('/');
    lcd_writeDec(4);
  }
}

PROGRAM(2, AUTOSTART) {
  checkRegisterInit(2);
  os_exec(4,DEFAULT_PRIORITY);
  for (;;);
}

PROGRAM(3, DONTSTART) {
  checkRegisterInit(3);
  for (;;);
}

PROGRAM(4, DONTSTART) {
  checkRegisterInit(4);
  for (;;);
}
