// DISP.C

// сегментный адрес видеопамяти
static unsigned  video_adr = 0xB800;

// текущее положение
static   int cur = 0;

// номер текущей строки * 160
static   int line = 0;



// функция disp() используется для вывода символов на экран
// непосредственно через видеопамять;
// подразумевается, что видеоадаптер находится в цветном
// текстовом режиме с разрешением 25*80 символов;
// вывод производится в нулевую страницу видеопамяти

void disp( char outchar,   // ASCII-код символа
			  char attr       // атрибут символа
			) {

	static char save_ch = 0, save_attr = 7;

	_asm {

		push  es

		mov   bx,cur
		add   bx,line

		mov   ax,video_adr
		mov   es,ax

		mov   al,save_ch
		mov   es:[bx], al
		inc   bx

		mov   al,save_attr
		mov   es:[bx], al

	display:

		// проверяем управляющие символы CR и LF
		cmp   outchar, 20h
		jb    handl

		// определяем смещение текущего байта видеопамяти
		//mov   bx,cur
		//add   bx,line
		dec   bx

		// если весь экран заполнен, очищаем его и перемещаемся в
		// верхний левый угол экрана
		cmp   bx,3840
		jb    send_it

		// очищаем экран

		mov   cx,4000
		xor   bx,bx

	clr_scr:

		mov   es:[bx], 0
		inc   bx
		loop  clr_scr

		mov   line,0
		xor   bx,bx

		// записываем символ и его атрибут в текущей позиции экрана

	send_it:
		mov   al,BYTE PTR outchar
		mov   es:[bx], al
		inc   cur
		inc   bx
		mov   al,BYTE PTR attr
		mov   es:[bx], al
		inc   cur

		jmp   end_disp

		// обрабатываем управляющие символы CR, LF, Backspace

	handl:
		cmp   outchar, 0xd
		jne   next_1
		add   line,160
		jmp   end_disp

	next_1:

		cmp   outchar, 0xa
		jne   next_2
		mov   cur,0
		jmp   end_disp

	next_2:
		cmp   outchar, 0x8
		jne   next_3
		dec   cur
		dec   cur
		jmp   end_disp

	next_3:

	end_disp:

		mov   bx,cur
		add   bx,line

		mov   al,es:[bx]
		mov   save_ch,al

		mov   al,5fh
		mov   es:[bx], al
		inc   bx

		mov   al,es:[bx]
		mov   save_attr,al

		mov   al,7
		mov   es:[bx], al

		pop   es
	}
}


void disp_string( char *str, char attr ) {
	int i;

	for( i = 0; str[i]; i++ )
		disp( str[i], attr );
}
