Offs	equ	(word ptr 0)
Segm	equ	(word ptr 2)

	model	large,pascal
	locals	@@
	
	.data
	
	extrn	PrefixSeg:word
	
	.code
	
	public	InitVideoIO,DoneVideoIO
	
OldInt21	dd	0

InitVideoIO	proc far
	xor	ax,ax
	mov	es,ax
	cli
	lea	ax,NewInt21
	xchg	ax,es:[21h*4].Offs
	mov	OldInt21.Offs,ax
	mov	ax,cs
	xchg	ax,es:[21h*4].Segm
	mov	OldInt21.Segm,ax
	sti
	ret
InitVideoIO	endp

DoneVideoIO	proc far
	xor	ax,ax
	mov	es,ax
	cli
	mov	ax,OldInt21.Offs
	mov	es:[21h*4].Offs,ax
	mov	ax,OldInt21.Segm
	mov	es:[21h*4].Segm,ax
	sti
	ret
DoneVideoIO	endp

NewInt21	proc far
	cmp	ah,3fh
	je	@@2
	cmp	ah,40h
	je	@@2
@@1:	jmp	OldInt21
@@2:	push	ax
	mov	ax,ds
	cmp	ax,0a000h
	pop	ax
	jb	@@1
	sti
	push	bp si di es ds dx
	mov	bp,sp
	pushf
	cld
	mov	dx,seg _Data
	mov	ds,dx
	mov	ds,PrefixSeg
	mov	dx,ds:[2]
	sub	dx,1000h
	mov	ds,dx
	xor	si,si
	sub	si,cx
	mov	dx,si
	les	di,[bp]
	cmp	ah,3fh
	je	@@3
	call	SSwap
	jmp	short @@5
@@3:	push	cx
	shr	cx,1
	jnc	@@4
	movsb
@@4:	rep	movsw
	pop	cx
@@5:	popf
	pushf
	call	OldInt21
	pushf
	cld
	xor	si,si
	sub	si,cx
	les	di,[bp]
	call	SSwap
	popf
	pop	dx ds es di si bp
	ret	2
NewInt21	endp

SSwap		proc near
	push	ax cx
	shr	cx,1
	jnc	@@1
	mov	al,es:[di]
	movsb
	mov	[si-1],al
@@1:	jcxz	@@3
@@2:	mov	ax,es:[di]
	movsw
	mov	[si-2],ax
	loop	@@2
@@3:	pop	cx ax
	ret
SSwap	endp

	end
