code	segment	para	public
	assume	cs:code

steal_int	macro	int_num,subst_int,old_int
	mov	bx,int_num * 4
	mov	ax,word ptr es:[bx]
	mov	word ptr old_int, ax
	mov	ax,word ptr es:[bx+2]
	mov	word ptr old_int[2], ax
	mov	word ptr es:[bx], offset subst_int
	mov	word ptr es:[bx+2], cs
	endm

IntVecs	segment	at	0
	org	10h * 4
int_10		dd	?

	org	043h*4
grx_set	label	dword

	org	0450h
cursor_posn	dw	?

IntVecs	ends

	org	2Ch
environment	label	word

	org	5CH
real_int_10	dd	?		; video handler
save_dx		dw	?
old_cursor_posn	dw	?

	org	100h
start:	jmp	setup

	assume	ds:nothing, es:nothing

handle_10	proc	far
	cmp	ah,02h			; check for set cursor position
	jnz	not_set_cursor

	mov	save_dx,dx
	mov	ah,79
	sub	ah,dl
	mov	dl,ah
	mov	ah,02h			; locate cursor at mirrored position
	pushf
	call	real_int_10

	push	bx
	push	es
	xchg	save_dx,dx

	xor	bx,bx
	mov	es,bx
	assume	es:IntVecs

	mov	cursor_posn,dx		; but save cursor at true position

	pop	es
	pop	bx
	xchg	dx,save_dx
	iret

not_set_cursor:
	cmp	ah,09h			; check for write character
	jz	write_character
	jmp	do_int_10

write_character:
	push	bx
	push	es

	xor	bx,bx
	mov	es,bx
	assume	es:IntVecs

	mov	bx,cursor_posn
	mov	old_cursor_posn,bx
	mov	ah,79			; get mirrored position
	sub	ah,bl
	mov	bl,ah
	mov	cursor_posn,bx		; save it and write character
	mov	ah,09h

	pop	es
	pop	bx
	pushf
	call	real_int_10

	push	bx
	push	es

	xor	bx,bx
	mov	es,bx
	assume	es:IntVecs
	mov	bx,old_cursor_posn
	mov	cursor_posn,bx		; save the real cursor position
	pop	es
	pop	bx
	iret

do_int_10:
	pushf				; fake an interrupt
	call	real_int_10
	iret
handle_10	endp

handler_end	label	byte
HANDLE_LEN	equ	$ - handle_10

font	label	word
	db	14*256	dup(?)

	assume	ds:code,es:nothing
steal	proc	far
setup:
	mov	es,environment		; free environment area
	mov	ax,4900h
	int	21h

	mov	dl,14
	mov	al,22h
	mov	ah,11h
	int	10h			; grab regular 8x14 font

	xor	ax,ax
	mov	es,ax
	assume	es:IntVecs
	lds	si,grx_set
	push	cs
	pop	es
	assume	es:code

	mov	di,offset font
	mov	cx,14*256
	rep	movsb

	mov	si,offset font
	push	cs
	pop	ds
	assume	ds:code

	mov	dx,14*256
flip_chars:
	mov	bl,ds:[si]
	mov	cx,8
	xor	al,al
flip_a_character:
	rcl	bl,1
	rcr	al,1
	loop	flip_a_character
	mov	ds:[si],al
	inc	si

	dec	dx
	jnz	flip_chars

	xor	dx,dx
	mov	cx,256
	mov	bx,0E00h
	mov	ax,1100h
	mov	di,bp
	mov	bp,offset font
	push	cs
	pop	es
	int	10h			; save the new font
	mov	bp,di

	xor	ax,ax
	mov	es,ax
	assume	es:IntVecs
	push	cs
	pop	ds
	assume	ds:code

	cli
	steal_int	10h,handle_10,real_int_10
	sti

	mov	dx,offset handler_end
	int	27h

steal	endp

code	ends
	end	start
