	IDEAL
	MODEL SMALL
	RADIX	16
	P286

	DATASEG

CMOS_PORT		EQU	70
PORT_6845		EQU	63h
COLOR_PORT		EQU	03d4h
MONO_PORT		EQU	03b4h
STATUS_PORT		EQU	64h
SHUT_DOWN		EQU	0feh
INT_MASK_PORT	EQU	21h
VIRTUAL_MODE	EQU	0001
A20_PORT			EQU	0d1
A20_ON			EQU	0df
A20_OFF			EQU	0ddh
EOI				EQU	20
MASTER8259A		EQU	20
SLAVE8259A		EQU	0a0h
KBD_PORT_A		EQU	60h
KBD_PORT_B		EQU	61h

	gdt_off		dw	 ?
	gdt_seg		dw  ?

	real_ss		dw	?
	real_sp		dw	?
	real_es		dw	?

CODESEG

	PUBLIC  _real_mode, _protected_mode
	PUBLIC  _enable_interrupt
	PUBLIC   _pause

PROC _protected_mode NEAR
		push    bp
		mov     bp,sp

		mov     ax,[bp+4]
		mov     dx,[bp+6]
		mov     [gdt_seg], dx
		mov     [gdt_off], ax

		push		ds
		mov		ax,40
		mov		ds,ax
		mov		[WORD 67],OFFSET shutdown_return
		mov		[WORD 69],cs
		pop		ds

		cli
		in			al, INT_MASK_PORT
		and		al, 0ffh
		out		INT_MASK_PORT, al

		mov		al,8f
		out		CMOS_PORT,al
		jmp		delay1
delay1:
		mov		al,5
		out		CMOS_PORT+1,al

		mov		[real_ss],ss
		mov		[real_es],es

; Загружаем регистры ES:SI адресом GDT, полученным
; как параметр функции protected_mode()

		mov		es, [gdt_seg]
		mov		si, [gdt_off]

; Подготавливаем номера прерываний IRQ0 и IRQ8
; для перепрограммирования контроллеров прерываний.

		mov		bx, 2028h

; Устанавливаем защищённый режим работы

		mov		ax, 8900h
		int		15h
		jnc		pok

; Если произошла ошибка, мы остались в реальном режиме,
; завершаем работу программы.

		mov	ah, 4ch
		int	21h

; Установлен защищённый режим работы процессора !

pok:
		pop     bp
		ret
ENDP _protected_mode

PROC _real_mode   NEAR

		mov		[real_sp], sp
		mov		al, SHUT_DOWN
		out		STATUS_PORT, al
waitr1:
		hlt
		jmp		waitr1

LABEL	shutdown_return FAR

		mov		ax, DGROUP
		mov		ds, ax

assume	ds:DGROUP

		cli
		mov	ss,[real_ss]
		mov	sp,[real_sp]

		in	al, INT_MASK_PORT
		and	al, 0
		out	INT_MASK_PORT, al

		mov	ax, DGROUP
		mov	ds, ax
		mov	ss, ax
		mov 	es, ax

		mov	ax,000dh
		out	CMOS_PORT,al
		sti
		ret
ENDP _real_mode


PROC	_pause		NEAR

	push	cx
	mov	cx,10
ploop0:
	push	cx
	xor	cx,cx
ploop1:
	loop	ploop1
	pop	cx
	loop	ploop0

	pop	cx
	ret

ENDP	_pause

PROC	_enable_interrupt NEAR

		sti
		in			al, INT_MASK_PORT
		and		al, 0fch
		out		INT_MASK_PORT, al

		ret
ENDP	_enable_interrupt


	end