// адресация в режимах 4 и 5

#include "sysp.h"


Pixel_Offs_4_5(unsigned x, unsigned y,
			   unsigned *offset, unsigned char *shift) {

	unsigned char   bit_shift;
	unsigned        byte_offset;

	_asm {

		; записываем в bx x-координату пиксела

		mov bx,x

		; запоминаем в регистре cl младший байт переменной x

		mov cl,bl

		; записываем в ax y-координату пиксела

		mov ax,y

		; вычисляем смещение байта, определяющего пиксел с координатами (x,y)
		; ax = 100h * y

		xchg ah,al

		; в бит D7, регистра al, записываем младший бит переменной y
		; этот бит равен единице, если значение переменной y нечетное, и
		; равен нулю, если оно четное
		; al = 80h * (y&1)
		; ax = ax/2 = 80h * y

		shr ax,1

		; bx = x + 8000h*(y&1)

		add bh,al

		; ax = 100h*(y/2)

		xor al,al

		; bx = x + 8000h*(y&1) + 100h*(y/2)

		add bx,ax

		; ax = 40h*(y/2)

		shr ax,1
		shr ax,1


		; bx = x + 8000h*(y&1) + 100h*(y/2) + 40h*(y/2) =
		;    = x + 8000h*(y&1) + 140h*(y/2)

		add bx,ax

		; bx = x/4 + 2000h*(y&1) + 50h*(y/2)

		shr bx,1
		shr bx,1

		; теперь bx содержит смещение байта, определяющего пиксел с
		; координатами (x,y) относительно начала видеопамяти
		; (страницы видеопамяти)

		mov byte_offset,bx

		; определяем биты, отвечающие за пиксел (x,y)
		; записываем в регистр cl два последних бита переменной x

		mov ah,3
		and cl,ah

		; cl = 3 - (x & 3)

		xor cl,ah

		; cl = cl * 2

		shl cl,1

		; регистр задает число бит для сдвига влево

		mov bit_shift,cl
	}

	*shift = bit_shift;
	*offset = byte_offset;
}



main() {

	unsigned offset,i;
	unsigned char     mask,shift;
	unsigned char     pixel,byte,color;

	unsigned char   far *ptr;

	_asm {
		xor ax,ax
		mov al,4
		int 10h
	}



	for(i=0;i<198;i++){
		color = i % 4;
		Pixel_Offs_4_5(i,i,&offset,&shift);
		ptr = (unsigned char far*) (FP_MAKE(0xB800, offset));
		byte = *ptr;
		pixel = (unsigned char) color << shift;
		*ptr = byte | pixel;
	}
	getch();
}

