#include "sysgraph.h"
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include "sysp.h"
#include <dos.h>

// Описания функций
void HorScrollScr(unsigned, unsigned);
void VerScrollScr(unsigned);

// Следующие функции определены в файле SCROLL.ASM
void	__pascal __far SetColumn(unsigned char);
void	__pascal __far HorScroll(unsigned, unsigned);
void	__pascal __far VerScroll(unsigned, unsigned);

// Главная функция
void main(void) {

	unsigned char   i,j;

	// Устанавливаем текстовый режим номер 3
	_asm {
		mov ax,3
		int 10h
	}

	// Увеличиваем ширину экрана до 100 символов. Последние
	// 20 символов на экране не отображаются
	SetColumn(100);

	for(i = 0; i < 24; i++)
		printf("\nЭтот текст будет перемещаться по экрану вашего "
			"монитора влево, а затем вверх  Последние 20 символов"
		);

	// Ожидаем нажатие на клавишу
	getch();

	// Выполняем горизонтальное смещение экрана
	for(i = 0; i < 160; i++)
		HorScrollScr(i,9);

	// Ожидаем нажатие на клавишу
	getch();

	// Возвращаем текст в начальное положение
	HorScrollScr(0,9);

	// Ожидаем нажатие на клавишу
	getch();

	// Выполняем вертикальное смещение экрана
	for(i = 0; i < 200; i++)
		VerScrollScr(i);

	// Ожидаем нажатие на клавишу
	getch();

	// Восстанавливаем текстовый режим номер 3
	_asm {
		mov ax,3
		int 10h
	}
}


/**
* void HorScroll(unsigned offset, unsigned wide)
*
* Функция смещает содержимое экрана влево на определенное
* число пикселов.
*
* Параметры:	offset - величина смещения в пикслах,
*         		wide   - ширна символов (8 или 9).
**/
void HorScrollScr(unsigned offset, unsigned wide) {

	unsigned start_addr_reg, panning_reg;
	div_t res;

	res = div(offset,wide);

	// Определяем знаачение для регистра начального адреса
	start_addr_reg = res.quot;

	// Определяем знаачение для регистра горизонтального сдвига
	panning_reg = (wide == 9) ?
		((res.rem == 0) ? 8 : res.rem - 1) : res.rem;

	// Выполняем горизонтальный сдвиг экрана
	HorScroll(start_addr_reg, panning_reg);

	return;
}



/**
* void VerScroll(unsigned offset)
*
* Функция смещает содержимое экрана вверх на определенное
* число пикселов
*
* Параметры:	offset - величина смещения в пикслах.
**/
void VerScrollScr(unsigned offset) {

	unsigned start_addr_reg, preset_row_reg;
	div_t res;
	BIOS_VAR _far  *bios_var_ptr;

	bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);
	res = div(offset,bios_var_ptr -> char_height);

	// Определяем знаачение для регистра начального адреса
	start_addr_reg = res.quot * (bios_var_ptr -> columns);

	// Определяем знаачение для регистра предустановки
	// линии сканирования
	preset_row_reg = res.rem;

	// Выполняем вертикальный сдвиг экрана
	VerScroll(start_addr_reg, preset_row_reg);

	return;
}

