#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>
#include "tos.h"

word dispatcher(void);

// Номер текущей строки для вывода на экран

extern unsigned int y;

// Задача TASK_1

void task1(void) {
	while(1){
		vi_print(0,y++," Запущена задача TASK_1, "
					"переходим к главной задаче", 0x70);
		jump_to_task(MAIN_TASK_SELECTOR);

// После повторного запуска этой задачи
// снова входим в цикл.

	}
}

// Задача TASK_2

word flipflop1 = 0;
long delay_cnt1 = 0l;

void task2(void) {
	while(1){

// Периодически выводим на экран строки
// FLIP/FLOP, каждый раз переключая
// семафор номер 1. Этот семафор однозначно
// соответствует выведенной на экран строке.

		asm sti
		if(delay_cnt1 > 150000l ) {
			asm cli
			if(flipflop1)	{
				vi_print(73,3," FLIP ", 0x4f);
				sem_clear(1);
			}
			else  {
				vi_print(73,3," FLOP ", 0x1f);
				sem_set(1);
			}
			flipflop1 ^= 1;
			delay_cnt1 = 0l;
			asm sti
		}
		delay_cnt1++;
	}
}

word flipflop = 0;
long delay_cnt = 0l;

void flipflop_task(void) {

// Эта задача также периодически выводит на экран
// строки FLIP/FLOP, но выводит строкой выше и
// с меньшим периодом. Кроме того, эта задача
// работает только тогда, когда установлен
// семафор номер 1.

	while(1){
		asm sti
		if(delay_cnt > 20000l ) {
			sem_wait(1); // ожидаем установки семафора
			asm cli
			if(flipflop)	vi_print(73,2," FLIP ", 0x20);
			else  			vi_print(73,2," FLOP ", 0x20);
			flipflop ^= 1;
			delay_cnt = 0l;
			asm sti
		}
		delay_cnt++;
	}
}

word keyb_code;

extern word keyb_status;

void keyb_task(void) {

// Эта задача вводит символы с клавиатуры
// и отображает скан-коды нажатых клавиш
// и состояние переключающих клавиш на экране.
// Если нажимается клавиша ESC, задача
// устанавливает семафор номер 0.
// Работающая параллельно главная задача
// ожидает установку этого семафора. Как только
// семафор 0 окажется установлен, главная задача
// завершает свою работу и программа возвращает
// процессор в реальный режим, затем передаёт
// управление MS-DOS.


	vi_print(60, 5, " Key code:   .... ", 0x20);
	vi_print(60, 6, " Key status: .... ", 0x20);
	while(1){
		keyb_code = kb_getch();
		vi_put_word(73, 5, keyb_code, 0x4f);
		vi_put_word(73, 6, keyb_status, 0x4f);
		if((keyb_code & 0x00ff) == 1) sem_set(0);
	}
}
