; --------------------------------------- ;
; ASCII.ASM                               ;
;                                         ;
; Version 1.0                             ;
;                                         ;
; IC v2.0+ Installable Command            ;
;                                         ;
; ASCII is a popup listbox of ASCII char- ;
; acter codes.                            ;
;                                         ;
; Copyright (C) 1992, Geoff Friesen B.Sc. ;
; All rights reserved.                    ;
;                                         ;
; Developed with: Borland TASM 2.5        ;
; --------------------------------------- ;

_TEXT		SEGMENT	BYTE PUBLIC 'CODE'
		ASSUME	cs:_TEXT, ds:_TEXT, es:_TEXT, ss:_TEXT
		ORG	100h

CR              EQU     13
LF              EQU     10
TAB		EQU	9

CLINE		EQU	10ah
HEXW		EQU	10ch
STDINIT		EQU	10eh

_ascii:
		lea     dx, msg
		mov     ah, 9
		int     21h
		int     20h

msg             DB      "NONCOM$"

code_entry      DW      _code
help_entry      DW      _help
byline_entry    DW      _byline
setup_entry     DW      _setup
cleanup_entry   DW      _cleanup

_active		DB	0		; ASCII TSR active flag.
_msg1		DB	CR, LF
		DB	"ascii: hotkey is ALT-"
_msgkey		DB	?
		DB	CR, LF
		DB	'$'

_msg2		DB	CR, LF
		DB	"ascii: bad command line"
		DB	CR, LF
		DB	'$'
_oldint9	DD	?
_oldsp		DW	?
_oldss		DW	?
_scan		DB	30		; "A" scancode.
_scanchar	DB	'A'
_scancodes	DB	30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50
		DB	49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44
		DB	11,  2,  3,  4,  5,  6,  7,  8,  9, 10, 0
		DB	256 DUP (?)
_stack		LABEL	BYTE

_code		PROC	NEAR
		call	cs:[STDINIT]	; Standard initialization.
		inc	si		; Skip past first nonspace char.
		xor	bx, bx		; Clear index.
_code0:
		cmp	al, CR		; Empty command line?
		jnz	_code1		; No, parse instead.

		mov	al, _scanchar	; Get current hotkey character.
		mov	_msgkey, al

		lea	dx, _msg1	; Display current hotkey setting.
		mov	ah, 9
		int	21h

		ret
_code1:
		cmp	al, '/'		; Parameter?
		jz	_code3		; Yes, branch.
_code2:
		lea	dx, _msg2	; Display error message.
		mov	ah, 9
		int	21h

		ret
_code3:
		lodsb			; Get parameter character.
		call	_toupper	; Ensure uppercase.

		cmp	al, 'K'		; Set hotkey option?
		jnz	_code5		; No, branch.

		call	_parse_hotkey	; Parse hotkey and validate.
		jc	_code2		; Branch on error.
_code4:
		call	_skipws		; Skip intervening whitespace.
		jmp	SHORT _code0	; Continue parsing.
_code5:
		cmp	al, 'Y'		; Set row option?
		jnz	_code6		; No, branch.

		lodsb			; Get row character.
		call	_isdigit	; Test for digit.
		jc	_code2		; Branch if not.

		cmp	al, '6'		; Maximum row is 6.
		ja	_code2		; Branch if out of range.

		sub	al, '0'-1	; Convert ASCII to binary.
		mov	BYTE PTR _row, al

		jmp	SHORT _code4
_code6:
		cmp	al, 'X'		; Set column option?
		jnz	_code2		; No, branch.

		lodsb			; Get first character.
		call	_isdigit	; Test for digit.
		jc	_code2		; Branch if not.

		mov	ah, al		; Save for now.
		sub	ah, '0'		; Convert ASCII to binary.

		lodsb			; Get next character.
		call	_isdigit	; Test for digit.
		jc	_code7		; Branch if not.

		mov	ch, ah		; Save acc. value for later add.
		shl	ah, 1		; x 2
		shl	ah, 1		; x 4
		add	ah, ch		; x 5
		shl	ah, 1		; x 10
		sub	al, '0'		; Convert ASCII to binary.
		add	ah, al		; Addin current digit.

		cmp	ah, 59		; Maximum column is 59.
		ja	_code2		; Branch if out of range.

		inc	si		; Negate "dec si" instruction.
_code7:
		inc	ah		; Make relative to 1.
		mov	BYTE PTR _column, ah

		dec	si		; Backup parse position.
		jmp	SHORT _code4
_code		ENDP

_isalpha	PROC	NEAR
		cmp	al, 'A'
		jb	_isalpha1

		cmp	al, 'Z'
		ja	_isalpha1

		clc			; Indicate alpha.
		ret
_isalpha1:
		stc			; Indicate not alpha.
		ret
_isalpha	ENDP

_isdigit	PROC	NEAR
		cmp	al, '0'
		jb	_isdigit1

		cmp	al, '9'
		ja	_isdigit1

		clc			; Indicate digit.
		ret
_isdigit1:
		stc			; Indicate not digit.
		ret
_isdigit	ENDP

_parse_hotkey	PROC	NEAR
		lodsb			; Get hotkey character.

		call	_isdigit	; Test for digit.
		jc	_parse_hotkey1	; Branch if not.

		mov	_scanchar, al	; Save digit character.
		mov	bl, al		; Convert ASCII to binary.
		sub	bl, '0'
		mov	al, _scancodes [bx+26] ; Get appropriate scancode.
		jmp	SHORT _parse_hotkey2
_parse_hotkey1:
		call	_toupper	; Ensure uppercase.

		call	_isalpha	; Test for alpha.
		jc	_parse_hotkey3	; Branch if not.

		mov	_scanchar, al	; Save alpha character.
		mov	bl, al		; Convert ASCII to binary.
		sub	bl, 'A'
		mov	al, _scancodes [bx] ; Get appropriate scancode.
_parse_hotkey2:
		mov	_scan, al	; Save scancode.

		clc			; Indicate success.
_parse_hotkey3:
		ret
_parse_hotkey	ENDP

_skipws		PROC	NEAR
_skipws1:
		lodsb

		cmp	al, ' '		; Skip spaces.
		je	_skipws1

		cmp	al, TAB		; Skip tabs.
		je	_skipws1

		ret
_skipws		ENDP

_toupper	PROC	NEAR
		cmp	al, 'a'
		jb	_toupper1

		cmp	al, 'z'
		ja	_toupper1

		sub	al, 32		; Convert lowercase to uppercase.
_toupper1:
		ret
_toupper	ENDP

_int9		PROC	FAR
		push	ax

		in	al, 60h		; Grab scancode.

		cmp	al, cs:_scan	; Our scancode?
		je	_int92		; Yes, branch.
_int91:
		pop	ax
		jmp	DWORD PTR cs:_oldint9
_int92:
		push	es
		mov	ax, 0
		mov	es, ax

		mov	al, es:[417h]	; Get shift status byte.
		and	al, 15		; Remove toggle data.
		cmp	al, 8		; ALT (alone) pressed?

		pop	es

		jne	_int91		; No, branch.

		in	al, 61h		; Acknowledge scancode.
		mov	ah, al
		or	al, 10000000b
		out	61h, al
		mov	al, ah
		out	61h, al

		mov	al, 20h		; Reset controller.
		out	20h, al

		cmp	BYTE PTR cs:_active, 0 ; ASCII currently active?
		jne	_int93		; Yes, branch.

		mov	BYTE PTR cs:_active, 1 ; Signal active.

		mov	cs:_oldss, ss	; Switch stacks.
		mov	cs:_oldsp, sp
		mov	sp, cs
		mov	ss, sp
		lea	sp, cs:_stack
		sti

		cld
		push	ax
		push	bx
		push	cx
		push	dx
		push	si
		push	di
		push	bp
		push	ds
		push	es

		push	cs
		pop	ds

		push	cs
		pop	es

		call	_main

		pop	es
		pop	ds
		pop	bp
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx
		pop	ax

		cli
		mov	ss, cs:_oldss	; Restore stacks.
		mov	sp, cs:_oldsp

		mov	BYTE PTR cs:_active, 0 ; Signal inactive.
_int93:
		pop	ax
		iret
_int9		ENDP

; ----------------
; void main (void)
; ----------------

_main		PROC	NEAR
		push	bp
		mov	bp, sp
		sub	sp, 10
		push	si
		push	di
;
;	{
;	   int i, key, oldshape, oldx, oldy, vmode;
;	   static char buffer [(MWIDTH+3)*(MHEIGHT+3)*2];
;
;	   _AH = 15;
		mov	ah, 15
		push	bp
		int	10h
		pop	bp
;
;
;	   vmode = _AL;
;
		mov	ah, 0
		mov	di, ax
;
;	   if (vmode != MONO && vmode != BW80 && vmode != C80)
;
		cmp	di, 7
		je	@1@218
		cmp	di, 2
		je	@1@218
		cmp	di, 3
		je	@1@218
;
;	       return;
;
		jmp	@1@1058
@1@218:
;
;	   for (i = 0; i < NATTR; i++)
;
		xor	si, si
		jmp	SHORT @1@362
@1@242:
;
;		attr [i] = (vmode == C80) ? color [i] : bw [i];
;
		cmp	di, 3
		jne	@1@290
		mov	bx, si
		shl	bx, 1
		mov	ax, _color[bx]
		jmp	@1@314
@1@290:
		mov	bx, si
		shl	bx, 1
		mov	ax, _bw[bx]
@1@314:
		mov	bx, si
		shl	bx, 1
		mov	_attr[bx], ax
		inc	si
@1@362:
		cmp	si, 3
		jl	@1@242
;
;	   _AH = 3;
;
		mov	ah, 3
;
;	   _BH = 0;
;
		mov	bh, 0
		push	bp
		int	10h
		pop	bp
;
;	   oldshape = (int) _CX;
;
		mov	[bp-4], cx
;
;	   oldx = (int) _DL;
;
		mov	al, dl
		mov	ah, 0
		mov	[bp-6], ax
;
;	   oldy = (int) _DH;
;
		mov	al, dh
		mov	ah, 0
		mov	[bp-8], ax
;
;	   oldx++;
;
		inc	WORD PTR [bp-6]
;
;	   oldy++;
;
		inc	WORD PTR [bp-8]
;
;	   v_screen (SCREEN_SAVE, column, row, MWIDTH+3, MHEIGHT+3,
;		     buffer);
;
		mov	ax, OFFSET b@+0
		push	ax
		mov	ax, 19
		push	ax
		mov	ax, 21
		push	ax
		push	WORD PTR _row
		push	WORD PTR _column
		xor	ax, ax
		push	ax
		call	_v_screen
		add	sp, 12
;
;	   attribute = attr [0];
;
		mov	ax, _attr
		mov	attribute, ax
;
;	   _AH = 1;
;
		mov	ah, 1
;
;	   _CX = 0x2000;
;
		mov	cx, 8192
		push	bp
		int	10h
		pop	bp
;
;	   v_border (DOUBLE_LINE, column, row, MWIDTH+2, MHEIGHT+2);
;
		mov	ax, 18
		push	ax
		mov	ax, 20
		push	ax
		push	WORD PTR _row
		push	WORD PTR _column
		mov	ax, 1
		push	ax
		call	_v_border
		add	sp, 10
;
;	   v_shadow (column, row, MWIDTH+2, MHEIGHT+2);
;
		mov	ax, 18
		push	ax
		mov	ax, 20
		push	ax
		push	WORD PTR _row
		push	WORD PTR _column
		call	_v_shadow
		add	sp, 8
;
;	   refresh ();
;
		call	_refresh
@1@602:
;
;	   do
;	   {
;	      if ((key = getkey ()) == ESC)
;
		call	_getkey
		mov	[bp-2], ax
		cmp	ax, 27
		jne	@1@650
;
;		  break;
;
		jmp	@1@962
@1@650:
;
;	      switch (key)
;
		mov	ax, [bp-2]
		mov	[bp-10], ax
		mov	cx, 6
		mov	bx, OFFSET @1@C2762
@1@698:
		mov	ax, cs:[bx]
		cmp	ax, [bp-10]
		je	@1@770
		inc	bx
		inc	bx
		loop	@1@698
		jmp	@1@938
@1@770:
		jmp	cs:[bx+12]
@1@794:
;
;	      {
;		 case DOWN : down (1);
;
		mov	ax, 1
		push	ax
		call	_down
		pop	cx
;
;			     break;
;
		jmp	SHORT @1@938
@1@818:
;
;		 case END  : end ();
;
		call	_end
;
;			     break;
;
		jmp	SHORT @1@938
@1@842:
;
;		 case HOME : home ();
;
		call	_home
;
;			     break;
;
		jmp	SHORT @1@938
@1@866:
;
;		 case PGDN : down (16);
;
		mov	ax, 16
		push	ax
		call	_down
		pop	cx
;
;			     break;
;
		jmp	SHORT @1@938
@1@890:
;
;		 case PGUP : up (16);
;
		mov	ax, 16
		push	ax
		call	_up
		pop	cx
;
;			     break;
;
		jmp	SHORT @1@938
@1@914:
;
;		 case UP   : up (1);
;
		mov	ax, 1
		push	ax
		call	_up
		pop	cx
@1@938:
;
;	      }
;	   }
;	   while (1);
;
		jmp	SHORT @1@602
@1@962:
;
;	   v_screen (SCREEN_RESTORE, column, row, MWIDTH+3, MHEIGHT+3,
;                    buffer);
;
		mov	ax, OFFSET b@+0
		push	ax
		mov	ax, 19
		push	ax
		mov	ax, 21
		push	ax
		push	WORD PTR _row
		push	WORD PTR _column
		mov	ax, 1
		push	ax
		call	_v_screen
		add	sp, 12
;
;	   v_gotoxy (oldx, oldy);
;
		push	WORD PTR [bp-8]
		push	WORD PTR [bp-6]
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;	   _AH = 1;
;
		mov	ah, 1
;
;	   _CX = (unsigned) oldshape;
;
		mov	cx, [bp-4]
		push	bp
		int	10h
		pop	bp
@1@1058:
;
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_main		ENDP

@1@C2762	LABEL	WORD
		DB	0
		DB	71
		DB	0
		DB	72
		DB	0
		DB	73
		DB	0
		DB	79
		DB	0
		DB	80
		DB	0
		DB	81
		DW	@1@842
		DW	@1@914
		DW	@1@890
		DW	@1@818
		DW	@1@794
		DW	@1@866

; -------------------
; char *asc (int row)
; -------------------

_asc		PROC	NEAR
		push	bp
		mov	bp, sp
		dec	sp
		dec	sp
		push	si
		push	di
;
;	{
;	   int i, temp;
;	   static char buffer [19], hex [16] = "0123456789abcdef";
;
		push	cs
		pop	es
		mov	 cx, 18
;
;	   lea di, buffer
;
		lea	 di, b@+798
		mov	 al, ' '
		rep	stosb
		mov	 al, 0
		stosb
;
;	   temp = row;
;
		mov	ax, [bp+4]
		mov	[bp-2], ax
;
;	   for (i = 2; i >= 0; i--)
;
		mov	si, 2
		jmp	SHORT @2@266
@2@194:
;
;	   {
;		buffer [i] = temp % 10 + '0';
;
		mov	ax, [bp-2]
		mov	bx, 10
		cwd
		idiv	bx
		add	dl, 48
		mov	b@+798[si], dl
;
;		temp /= 10;
;
		mov	bx, 10
		mov	ax, [bp-2]
		cwd
		idiv	bx
		mov	[bp-2], ax
;
;		if (!temp)
;
		cmp	WORD PTR [bp-2], 0
		jne	@2@242
;
;		    break;
;
		jmp	SHORT @2@290
@2@242:
		dec	si
@2@266:
		or	si, si
		jge	@2@194
@2@290:
;
;	   }
;
;	   buffer [4] = hex [(row & 0xf0) >> 4];
;
		mov	bx, [bp+4]
		and	bx, 240
		mov	cl, 4
		sar	bx, cl
		mov	al, d@+20[bx]
		mov	b@+798+4, al
;
;	   buffer [5] = hex [row & 15];
;
		mov	bx, [bp+4]
		and	bx, 15
		mov	al, d@+20[bx]
		mov	b@+798+5, al
;
;	   buffer [7] = (!row) ? ' ' : row;
;
		cmp	WORD PTR [bp+4], 0
		jne	@2@338
		mov	al, 32
		jmp	SHORT @2@362
@2@338:
		mov	al, [bp+4]
@2@362:
		mov	b@+798+7,al
;
;	   temp = row += 128;
;
		add	WORD PTR [bp+4], 128
		mov	ax, [bp+4]
		mov	[bp-2], ax
;
;	   for (i = 12; i >= 10; i--)
;
		mov	si, 12
		jmp	SHORT @2@434
@2@386:
;
;	   {
;		buffer [i] = temp % 10 + '0';
;
		mov	ax, [bp-2]
		mov	bx, 10
		cwd
		idiv	bx
		add	dl, 48
		mov	b@+798[si],dl
;
;		temp /= 10;
;
		mov	bx, 10
		mov	ax, [bp-2]
		cwd
		idiv	bx
		mov	[bp-2], ax
		dec	si
@2@434:
		cmp	si, 10
		jge	@2@386
;
;	   }
;
;	   buffer [14] = hex [(row & 0xf0) >> 4];
;
		mov	bx, [bp+4]
		and	bx, 240
		mov	cl, 4
		sar	bx, cl
		mov	al, d@+20[bx]
		mov	b@+798+14, al
;
;	   buffer [15] = hex [row & 15];
;
		mov	bx, [bp+4]
		and	bx, 15
		mov	al, d@+20[bx]
		mov	b@+798+15, al
;
;	   buffer [17] = row;
;
		mov	al, [bp+4]
		mov	b@+798+17, al
;
;	   return buffer;
;
		mov	ax, OFFSET b@+798
		jmp	SHORT @2@482
@2@482:
;
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_asc		ENDP

; -------------------------------------------------------
; void v_border (int style, int x, int y, int nx, int ny)
; -------------------------------------------------------

_v_border	PROC	NEAR
		push	bp
		mov	bp, sp
		sub	sp, 12
		push	si
		push	di
		mov	si, WORD PTR [bp+4]
;
;	{
;	   int i, hline, llcorner, lrcorner, ulcorner, urcorner, vline;
;
;	   ulcorner = "ÚÉÛ" [style];
;
		mov	al, s@[si]
		cbw
		mov	[bp-8],ax
;
;	   urcorner = "¿»Û" [style];
;
		mov	al, s@[si+4]
		cbw
		mov	[bp-10], ax
;
;	   llcorner = "ÀÈÛ" [style];
;
		mov	al, s@[si+8]
		cbw
		mov	[bp-4], ax
;
;	   lrcorner = "Ù¼Û" [style];
;
		mov	al, s@[si+12]
		cbw
		mov	[bp-6], ax
;
;	   hline = "ÄÍÛ" [style];
;
		mov	al, s@[si+16]
		cbw
		mov	[bp-2], ax
;
;	   vline = "³ºÛ" [style];
;
		mov	al, s@[si+20]
		cbw
		mov	[bp-12], ax
;
;	   v_gotoxy (x, y);
;
		push	WORD PTR [bp+8]
		push	WORD PTR [bp+6]
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;	   v_putch (ulcorner, 1);
;
		mov	ax, 1
		push	ax
		push	WORD PTR [bp-8]
		call	_v_putch
		pop	cx
		pop	cx
;
;	   v_putch (hline, nx-2);
;
		mov	ax, WORD PTR [bp+10]
		add	ax, 65534
		push	ax
		push	WORD PTR [bp-2]
		call	_v_putch
		pop	cx
		pop	cx
;
;	   v_putch (urcorner, 1);
;
		mov	ax, 1
		push	ax
		push	WORD PTR [bp-10]
		call	_v_putch
		pop	cx
		pop	cx
;
;	   for (i = 0; i < ny-2; i++)
;
		xor	di, di
		jmp	SHORT @3@98
@3@50:
;
;	   {
;		v_gotoxy (x, y+1+i);
;
		mov	ax, [bp+8]
		add	ax, di
		inc	ax
		push	ax
		push	WORD PTR [bp+6]
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		v_putch (vline, 1);
;
		mov	ax, 1
		push	ax
		push	WORD PTR [bp-12]
		call	_v_putch
		pop	cx
		pop	cx
;
;		v_gotoxy (x+nx-1, y+1+i);
;
		mov	ax, [bp+8]
		add	ax, di
		inc	ax
		push	ax
		mov	ax, [bp+6]
		add	ax, [bp+10]
		dec	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		v_putch (vline, 1);
;
		mov	ax, 1
		push	ax
		push	WORD PTR [bp-12]
		call	_v_putch
		pop	cx
		pop	cx
		inc	di
@3@98:
		mov	ax, [bp+12]
		add	ax, 65534
		cmp	ax, di
		jg	@3@50
;
;	   }
;
;	   v_gotoxy (x, y+ny-1);
;
		mov	ax, [bp+8]
		add	ax, [bp+12]
		dec	ax
		push	ax
		push	WORD PTR [bp+6]
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;	   v_putch (llcorner, 1);
;
		mov	ax, 1
		push	ax
		push	WORD PTR [bp-4]
		call	_v_putch
		pop	cx
		pop	cx
;
;	   v_putch (hline, nx-2);
;
		mov	ax, WORD PTR [bp+10]
		add	ax, 65534
		push	ax
		push	WORD PTR [bp-2]
		call	_v_putch
		pop	cx
		pop	cx
;
;	   v_putch (lrcorner, 1);
;
		mov	ax, 1
		push	ax
		push	WORD PTR [bp-6]
		call	_v_putch
		pop	cx
		pop	cx
;
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_v_border	ENDP

; -----------------------------
; int v_cputs (const char *str)
; -----------------------------

_v_cputs	PROC	NEAR
		push	bp
		mov	bp, sp
		push	si
		push	di
;
;	{
;	   if (!*str)
;
		mov	bx, [bp+4]
		mov	al, [bx]
		cbw
		or	ax, ax
		jne	@4@74
;
;	       return 0;
;
		xor	ax, ax
		jmp	@4@1010
@4@74:
		push	ds
		mov	dx, 0b000h
		mov	bx, 0
		mov	es, bx
		mov	di, bx
		mov	bl, es:[462h]

		cmp	BYTE PTR es:[449h], 7
;
;	   asm jz v_cputs1
;
		je	short @4@314

		add	dh, 8
		add	dh, bl
@4@314:
;
;	v_cputs1:
;
		shl	bx, 1
		mov	cl, es:[bx+451h]

		or	cl, cl
;
;	   asm jz v_cputs3
;
		je	@4@554

		mov	ch, 0
		mov	al, es:[44ah]
		mov	ah, 0
		shl	ax, 1
@4@506:
;
;	v_cputs2:
;
		add	di, ax
;
;	   asm loop v_cputs2
;
		loop	@4@506
@4@554:
;
;	v_cputs3:
;
		mov	al, es:[bx+450h]
		mov	ah, 0
		shl	ax, 1
		add	di, ax
		mov	es, dx
;
;	asm mov si, str
;
		mov	si, [bp+4]
		mov	ah, BYTE PTR cs:attribute
		cld
@4@746:
;
;	v_cputs4:
;
		lodsb
		cmp	al, 0
;
;	   asm jz v_cputs5
;
		je	@4@866

		stosw
;
;	   asm jmp SHORT v_cputs4
;
		jmp	SHORT @4@746
@4@866:
;
;	v_cputs5:
;
;	   update_cursor ();
;
		call	_update_cursor

		dec	si
		dec	si
		lodsb
		mov	ah, 0

		pop	ds
@4@1010:
;
;	}
;
		pop	di
		pop	si
		pop	bp
		ret
_v_cputs	ENDP

; ----------------------
; void down (int nlines)
; ----------------------

_down		PROC	NEAR
		push	bp
		mov	bp, sp
		dec	sp
		dec	sp
		push	si
		push	di
		mov	di, [bp+4]
;
;	{
;	   int i, dnlines;
;
;	   if (cchoice == nchoice-1)
;
		mov	ax, _nchoice
		dec	ax
		cmp	ax, _cchoice
		jne	@5@74
;
;	       return;
;
		jmp	@5@362
@5@74:
;
;	   attribute = attr [2];
;
		mov	ax, _attr+4
		mov	attribute, ax
;
;	   v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;	   v_cputs (asc (cchoice));
;
		push	WORD PTR _cchoice
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
;
;	   dnlines = min(nchoice-1-cchoice, nlines);
;
		mov	ax, _nchoice
		dec	ax
		sub	ax, _cchoice
		cmp	ax, di
		jge	@5@122
		mov	ax, _nchoice
		dec	ax
		sub	ax, _cchoice
		jmp	SHORT @5@146
@5@122:
		mov	ax, di
@5@146:
		mov	[bp-2],ax
;
;	   for (i = 1; i <= dnlines; i++)
;
		mov	si, 1
		jmp	SHORT @5@338
@5@170:
;
;	   {
;		if (currow != MHEIGHT)
;
		cmp	WORD PTR _currow, 16
		je	@5@218
;
;		    currow++;
;
		inc	WORD PTR _currow
		jmp	SHORT @5@242
@5@218:
;
;		else
;		    v_scroll (column+1, row+1, MWIDTH, MHEIGHT, SCROLL_UP,
;			      1, attr [2]);
;
		push	WORD PTR _attr+4
		mov	ax, 1
		push	ax
		xor	ax, ax
		push	ax
		mov	ax, 16
		push	ax
		mov	ax, 18
		push	ax
		mov	ax, _row
		inc	ax
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_scroll
		add	sp, 14
@5@242:
;
;		if (i == dnlines)
;
		cmp	si, [bp-2]
		jne	@5@290
;
;		    attribute = attr [1];
;
		mov	ax, _attr+2
		mov	attribute, ax
@5@290:
;
;		v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		v_cputs (asc (++cchoice));
;
		inc	WORD PTR _cchoice
		mov	ax, _cchoice
		push	ax
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
		inc	si
@5@338:
		cmp	si, [bp-2]
		jle	@5@170
@5@362:
;
;	   }
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_down		ENDP

; ---------------
; void end (void)
; ---------------

_end		PROC	NEAR
		push	bp
		mov	bp, sp
		push	si
;
;	{
;	   int limit;
;
;	   if (cchoice == nchoice-1)
;
		mov	ax, _nchoice
		dec	ax
		cmp	ax, _cchoice
		jne	@6@74
;
;	       return;
;
		jmp	SHORT @6@338
@6@74:
;
;	   if (nchoice < MHEIGHT)
;
		cmp	WORD PTR _nchoice, 16
		jge	@6@122
;
;	   {
;	       limit = nchoice;
;
		mov	si, _nchoice
;
;	       cchoice = 0;
;
		mov	WORD PTR _cchoice, 0
;
;	   }
;
		jmp	SHORT @6@146
@6@122:
;
;	   else
;	   {
;	       limit = MHEIGHT;
;
		mov	si, 16
;
;	       cchoice = nchoice-MHEIGHT;
;
		mov	ax, _nchoice
		add	ax, 65520
		mov	_cchoice, ax
@6@146:
;
;	   }
;
;	   for (currow = 1; currow <= limit; currow++)
;
		mov	WORD PTR _currow, 1
		jmp	SHORT @6@290
@6@170:
;
;	   {
;		attribute = attr [(currow == limit) ? 1 : 2];
;
		cmp	_currow, si
		jne	@6@218
		mov	ax, 1
		jmp	SHORT @6@242
@6@218:
		mov	ax, 2
@6@242:
		shl	ax, 1
		mov	bx, ax
		mov	ax, _attr[bx]
		mov	attribute, ax
;
;		v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		v_cputs (asc (cchoice++));
;
		mov	ax, _cchoice
		inc	WORD PTR _cchoice
		push	ax
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
		inc	WORD PTR _currow
@6@290:
		cmp	_currow, si
		jle	@6@170
;
;	   }
;
;	   currow = limit;
;
		mov	_currow, si
;
;	   cchoice--;
;
		dec	WORD PTR _cchoice
@6@338:
;
;	}
;
		pop	si
		pop	bp
		ret
_end		ENDP

; -----------------
; int getkey (void)
; -----------------

_getkey		PROC	NEAR
		push	bp
		mov	bp, sp
;
;	{
;
		mov	ah, 0
		int	16h
		or	al, al
;
;	   asm jz getkey1
;
		je	@7@146

		mov	ah, 0
@7@146:
;
;	getkey1:;
;
;	}
;
		pop	bp
		ret
_getkey		ENDP

; ----------------------------
; void v_gotoxy (int x, int y)
; ----------------------------

_v_gotoxy	PROC	NEAR
		push	bp
		mov	bp, sp
;
;	{
;
		mov	bx, 0
		mov	es, bx
		mov	ah, 2
		mov	bh, es:[462h]
;
;	   asm mov dh, y
;
		mov	dh, [bp+6]
		add	dh, -1
;
;	   asm mov dl, x
;
		mov	dl, [bp+4]
		add	dl, -1

		push	bp
		int	10h
		pop	bp
;
;	}
;
		pop	bp
		ret
_v_gotoxy	ENDP

; ----------------
; void home (void)
; ----------------

_home		PROC	NEAR
		push	bp
		mov	bp, sp
		dec	sp
		dec	sp
;
;	{
;	   int minimum;
;
;	   if (!cchoice)
;
		cmp	_cchoice, 0
		jne	@9@74
;
;	       return;
;
		jmp	SHORT @9@338
@9@74:
;
;	   cchoice = 0;
;
		mov	WORD PTR _cchoice, 0
;
;	   minimum = min(nchoice, MHEIGHT);
;
		cmp	WORD PTR _nchoice, 16
		jge	@9@122
		mov	ax, _nchoice
		jmp	SHORT @9@146
@9@122:
		mov	ax, 16
@9@146:
		mov	[bp-2], ax
;
;	   for (currow = 1; currow <= minimum; currow++)
;
		mov	WORD PTR _currow, 1
		jmp	SHORT @9@290
@9@170:
;
;	   {
;		attribute = attr [(currow == 1) ? 1 : 2];
;
		cmp	WORD PTR _currow, 1
		jne	@9@218
		mov	ax, 1
		jmp	SHORT @9@242
@9@218:
		mov	ax, 2
@9@242:
		shl	ax, 1
		mov	bx, ax
		mov	ax, _attr[bx]
		mov	attribute, ax
;
;		v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		v_cputs (asc (cchoice++));
;
		mov	ax, _cchoice
		inc	WORD PTR _cchoice
		push	ax
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
		inc	WORD PTR _currow
@9@290:
		mov	ax, _currow
		cmp	ax, [bp-2]
		jle	@9@170
;
;	   }
;
;	   cchoice = 0;
;
		mov	WORD PTR _cchoice, 0
;
;	   currow = 1;
;
		mov	WORD PTR _currow, 1
@9@338:
;
;	}
;
		mov	sp, bp
		pop	bp
		ret
_home		ENDP

; ------------------------------
; int v_putch (int c, int count)
; ------------------------------

_v_putch	PROC	NEAR
		push	bp
		mov	bp, sp
		push	di
;
;	{
;	   asm cmp WORD PTR count, 0
;
		cmp	WORD PTR [bp+6], 0
;
;	   asm jz v_putch4
;
		je	@10@794

		mov	dx, 0b000h
		mov	bx, 0
		mov	es, bx
		mov	di, bx
		mov	bl, es:[462h]
;
;	   asm cmp BYTE PTR es:[449h], MONO
;
		cmp	BYTE PTR es:[449h], 7
;
;	   asm jz v_putch1
;
		je	@10@290

		add	dh, 8
		add	dh, bl
@10@290:
;
;	v_putch1:
;
		shl	bx, 1
		mov	cl, es:[bx+451h]
		or	cl, cl
;
;	   asm jz v_putch3
;
		je	@10@530

		mov	ch, 0
		mov	al, es:[44ah]
		mov	ah, 0
		shl	ax, 1
@10@482:
;
;	v_putch2:
;
		add	di, ax
;
;	   asm loop v_putch2
;
		loop	@10@482
@10@530:
;
;	v_putch3:
;
		mov	al, es:[bx+450h]
		mov	ah, 0
		shl	ax, 1
		add	di, ax
		mov	es, dx
;
;	   asm mov al, c
;
		mov	al, [bp+4]
;
;	   asm mov ah, BYTE PTR attribute
;
		mov	ah, BYTE PTR attribute
;
;	   asm mov cx, count
;
		mov	cx, [bp+6]

		cld
		rep stosw
;
;	   update_cursor ();
;
		call	_update_cursor
@10@794:
;
;	v_putch4:
;
;	   asm mov ax, c
;
		mov	ax, [bp+4]
;
;	}
;
		pop	di
		pop	bp
		ret
_v_putch	ENDP

; -------------------
; void refresh (void)
; -------------------

_refresh	PROC	NEAR
		push	bp
		mov	bp, sp
;
;	{
;	   cchoice = 0;
;
		mov	WORD PTR _cchoice, 0
;
;	   for (currow = 1; currow <= 16; currow++)
;
		mov	WORD PTR _currow, 1
		jmp	SHORT @11@170
@11@50:
;
;	   {
;		v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		attribute = attr [(currow == 1) ? 1 : 2];
;
		cmp	WORD PTR _currow, 1
		jne	@11@98
		mov	ax, 1
		jmp	SHORT @11@122
@11@98:
		mov	ax, 2
@11@122:
		shl	ax, 1
		mov	bx, ax
		mov	ax, _attr[bx]
		mov	attribute, ax
;
;		v_cputs (asc (cchoice++));
;
		mov	ax, _cchoice
		inc	WORD PTR _cchoice
		push	ax
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
		inc	WORD PTR _currow
@11@170:
		cmp	WORD PTR _currow, 16
		jle	@11@50
;
;	   }
;
;	   cchoice = 0;
;
		mov	WORD PTR _cchoice, 0
;
;	   currow = 1;
;
		mov	WORD PTR _currow, 1
;
;	}
;
		pop	bp
		ret
_refresh	ENDP

; -------------------------------------------------------------------
; void v_screen (int cmd, int x, int y, int nx, int ny, void *buffer)
; -------------------------------------------------------------------

_v_screen	proc	near
		push	bp
		mov	bp, sp
		sub	sp, 4
		push	si
		push	di
;
;	{
;	   int cols;
;	   char mode, page;
;
		push	ds

		mov	ah, 15
		push	bp
		int	10h
		pop	bp
;
;	   asm mov mode, al
;
		mov	[bp-3], al
;
;	   asm mov BYTE PTR cols, ah
;
		mov	[bp-2], ah
;
;	   asm mov BYTE PTR cols [1], 0
;
		mov	BYTE PTR [bp-2] [1], 0
;
;	   asm shl WORD PTR cols, 1
;
		shl	WORD PTR [bp-2], 1
;
;	   asm mov page, bh
;
		mov	[bp-4], bh

		push	ds
		pop	es

		mov	ax, 0b000h
;
;	   asm cmp BYTE PTR mode, MONO
;
		cmp	BYTE PTR [bp-3], 7
;
;	   asm jz v_screen0
;
		je	@12@434
;
;	   asm add ah, page
;
		add	ah, [bp-4]
		add	ah, 8
@12@434:
;
;	v_screen0:
;
;
		mov	si, ax
;
;	   asm cmp BYTE PTR cmd, 0
;
		cmp	BYTE PTR [bp+4], 0
;
;	   asm jnz v_screen1
;
		jne	@12@602

		mov	ds, si
		sub	si, si
;
;	   asm mov di, buffer
;
		mov	di, [bp+14]
;
;	   asm jmp SHORT v_screen2
;
		jmp	@12@674
@12@602:
;
;	v_screen1:
;
		mov	es, si
		sub	di, di
;
;	   asm mov si, buffer
;
		mov	si, [bp+14]
@12@674:
;
;	v_screen2:
;
;	   asm mov ax, y
;
		mov	ax, [bp+8]
		dec	ax
;
;	   asm mov cx, cols
;
		mov	cx, [bp-2]
		mul	cx
;
;	   asm mov cx, x
;
		mov	cx, [bp+6]
		dec	cx
		shl	cx, 1
		add	ax, cx
;
;	   asm cmp BYTE PTR cmd, 0
;
		cmp	BYTE PTR [bp+4], 0
;
;	   asm jnz v_screen3
;
		jne	@12@962

		add	si, ax
;
;	   asm jmp SHORT v_screen4
;
		jmp	@12@986
@12@962:
;
;	v_screen3:
;
		add	di, ax
@12@986:
;
;	v_screen4:
;
;	   asm mov bx, ny
;
		mov	bx, [bp+12]
;
;	   asm mov cx, nx
;
		mov	cx, [bp+10]
		cld
@12@1058:
;
;	v_screen5:
;
		rep	movsw
		dec	bx
;
;	   asm jz v_screen7
;
		je	@12@1418
;
;	   asm cmp BYTE PTR cmd, 0
;
		cmp	BYTE PTR [bp+4], 0
;
;	   asm jnz v_screen6
;
		jne	@12@1298
;
;	   asm sub si, nx
;
		sub	si, [bp+10]
;
;	   asm sub si, nx
;
		sub	si, [bp+10]
;
;	   asm add si, cols
;
		add	si, [bp-2]
;
;	   asm mov cx, nx
;
		mov	cx, [bp+10]
;
;	   asm jmp SHORT v_screen5
;
		jmp	@12@1058
@12@1298:
;
;	v_screen6:
;
;	   asm sub di, nx
;
		sub	di, [bp+10]
;
;	   asm sub di, nx
;
		sub	di, [bp+10]
;
;	   asm add di, cols
;
		add	di, [bp-2]
;
;	   asm mov cx, nx
;
		mov	cx, [bp+10]
;
;	   asm jmp SHORT v_screen5
;
		jmp	@12@1058
@12@1418:
;
;	v_screen7:
;
		pop	 ds
;
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_v_screen	ENDP

; ------------------------------------------------------------------
; void v_scroll (int x, int y, int nx, int ny, int dir, int nblines,
;                int attr)
; ------------------------------------------------------------------

_v_scroll	PROC	NEAR
		push	bp
		mov	bp, sp
;
;	{
		mov	ah, 6
;
;	   asm cmp WORD PTR dir, SCROLL_UP
;
		cmp	WORD PTR [bp+12], 0
;
;	   asm jz v_scroll1
;
		je	@13@122

		inc	ah
@13@122:
;
;	v_scroll1:
;
;	   asm mov al, nblines
;
		mov	al, [bp+14]
;
;	   asm mov bh, attr
;
		mov	bh, [bp+16]
;
;	   asm mov ch, y
;
		mov	ch, [bp+6]
		add	ch, -1
;
;	   asm mov cl, x
;
		mov	cl, [bp+4]
		add	cl, -1

		mov	dx, cx
;
;	   asm add dh, ny
;
		add	dh, [bp+10]
		add	dh, -1
;
;	   asm add dl, nx
;
		add	dl, [bp+8]
		add	dl, -1

		push	bp
		int	10h
		pop	bp
;
;	}
;
		pop	bp
		ret
_v_scroll	ENDP

; ----------------------------------------------
; void v_shadow (int x1, int y1, int nx, int ny)
; ----------------------------------------------

_v_shadow	PROC	NEAR
		push	bp
		mov	bp, sp
		sub	sp, 4
		push	si
		push	di
;
;	{
;	   int i, x2, y2;
;	   char buffer [2];
;
;	   x2 = x1+nx-1;
;
		mov	ax, [bp+4]
		add	ax, [bp+8]
		dec	ax
		mov	di, ax
;
;	   y2 = y1+ny-1;
;
		mov	ax, [bp+6]
		add	ax, [bp+10]
		dec	ax
		mov	[bp-2], ax
;
;	   for (i = x1+1; i <= x2+1; i++)
;
		mov	ax, [bp+4]
		inc	ax
		mov	si, ax
		jmp	SHORT @14@98
@14@50:
;
;	   {
;		v_screen (SCREEN_SAVE, i, y2+1, 1, 1, buffer);
;
		lea	ax, [bp-4]
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, [bp-2]
		inc	ax
		push	ax
		push	si
		xor	ax, ax
		push	ax
		call	_v_screen
		add	sp, 12
;
;		buffer [1] = BLACK;
;
		mov	BYTE PTR [bp-3],0
;
;		v_screen (SCREEN_RESTORE, i, y2+1, 1, 1, buffer);
;
		lea	ax, [bp-4]
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, [bp-2]
		inc	ax
		push	ax
		push	si
		mov	ax, 1
		push	ax
		call	_v_screen
		add	sp, 12
		inc	si
@14@98:
		mov	ax, di
		inc	ax
		cmp	ax, si
		jge	@14@50
;
;	   }
;
;	   for (i = y1+1; i <= y2+1; i++)
;
		mov	ax, [bp+6]
		inc	ax
		mov	si, ax
		jmp	SHORT @14@194
@14@146:
;
;	   {
;		v_screen (SCREEN_SAVE, x2+1, i, 1, 1, buffer);
;
		lea	ax, [bp-4]
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, 1
		push	ax
		push	si
		mov	ax, di
		inc	ax
		push	ax
		xor	ax, ax
		push	ax
		call	_v_screen
		add	sp, 12
;
;		buffer [1] = BLACK;
;
		mov	BYTE PTR [bp-3],0
;
;		v_screen (SCREEN_RESTORE, x2+1, i, 1, 1, buffer);
;
		lea	ax, [bp-4]
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, 1
		push	ax
		push	si
		mov	ax, di
		inc	ax
		push	ax
		mov	ax, 1
		push	ax
		call	_v_screen
		add	sp, 12
		inc	si
@14@194:
		mov	ax, [bp-2]
		inc	ax
		cmp	ax, si
		jge	@14@146
;
;	   }
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_v_shadow	ENDP

; --------------------
; void up (int nlines)
; --------------------

_up		PROC	NEAR
		push	bp
		mov	bp, sp
		dec	sp
		dec	sp
		push	si
		push	di
		mov	di, [bp+4]
;
;	{
;	   int i, uplines;
;
;	   if (!cchoice)
;
		cmp	WORD PTR _cchoice, 0
		jne	@15@74
;
;	       return;
;
		jmp	@15@362
@15@74:
;
;	   attribute = attr [2];
;
		mov	ax, _attr+4
		mov	attribute, ax
;
;	   v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;	   v_cputs (asc (cchoice));
;
		push	WORD PTR _cchoice
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
;
;
;	   uplines = min(cchoice, nlines);
;
		cmp	_cchoice, di
		jge	@15@122
		mov	ax, _cchoice
		jmp	SHORT @15@146
@15@122:
		mov	ax, di
@15@146:
		mov	[bp-2], ax
;
;	   for (i = 1; i <= uplines; i++)
;
		mov	si, 1
		jmp	SHORT @15@338
@15@170:
;
;	   {
;		if (currow != 1)
;
		cmp	WORD PTR _currow, 1
		je	@15@218
;
;		    currow--;
;
		dec	WORD PTR _currow
		jmp	SHORT @15@242
@15@218:
;
;		else
;		    v_scroll (column+1, row+1, MWIDTH, MHEIGHT, SCROLL_DN,
;			      1, attr [2]);
;
		push	WORD PTR _attr+4
		mov	ax, 1
		push	ax
		mov	ax, 1
		push	ax
		mov	ax, 16
		push	ax
		mov	ax, 18
		push	ax
		mov	ax, _row
		inc	ax
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_scroll
		add	sp, 14
@15@242:
;
;		if (i == uplines)
;
		cmp	si, [bp-2]
		jne	@15@290
;
;		    attribute = attr [1];
;
		mov	ax, _attr+2
		mov	attribute,ax
@15@290:
;
;		v_gotoxy (column+1, row+currow);
;
		mov	ax, _row
		add	ax, _currow
		push	ax
		mov	ax, _column
		inc	ax
		push	ax
		call	_v_gotoxy
		pop	cx
		pop	cx
;
;		v_cputs (asc (--cchoice));
;
		dec	WORD PTR _cchoice
		mov	ax, _cchoice
		push	ax
		call	_asc
		pop	cx
		push	ax
		call	_v_cputs
		pop	cx
		inc	si
@15@338:
		cmp	si, [bp-2]
		jle	@15@170
@15@362:
;
;	   }
;	}
;
		pop	di
		pop	si
		mov	sp, bp
		pop	bp
		ret
_up		ENDP

; -------------------------
; void update_cursor (void)
; -------------------------

_update_cursor	PROC	NEAR
		push	bp
		mov	bp, sp
		push	di
;
;	{
;
		mov	bx, 0
		mov	es, bx
		mov	ax, di
		mov	bl, es:[44ah]
		shl	bl, 1
		div	bl
		mov	dh, al
		mov	dl, ah
		shr	dl, 1
		mov	ah, 2
		mov	bh, es:[462h]
		push	bp
		int	10h
		pop	bp
;
;	}
;
		pop	di
		pop	bp
		ret
_update_cursor	ENDP

_attribute	EQU	attribute

d@		LABEL	BYTE
d@w		LABEL	WORD
_column		LABEL	WORD
		DB	31
		DB	0
_row		LABEL	WORD
		DB	4
		DB	0
_nchoice	LABEL	WORD
		DB	128
		DB	0
attribute	LABEL	WORD
		DB	7
		DB	0
_bw		LABEL	word
		DB	15
		DB	0
		DB	112
		DB	0
		DB	7
		DB	0
_color		LABEL	WORD
		DB	15
		DB	0
		DB	31
		DB	0
		DB	3
		DB	0
		DB	48
		DB	49
		DB	50
		DB	51
		DB	52
		DB	53
		DB	54
		DB	55
		DB	56
		DB	57
		DB	97
		DB	98
		DB	99
		DB	100
		DB	101
		DB	102
s@		LABEL	BYTE
		DB	-38
		DB	-55
		DB	-37
		DB	0
		DB	-65
		DB	-69
		DB	-37
		DB	0
		DB	-64
		DB	-56
		DB	-37
		DB	0
		DB	-39
		DB	-68
		DB	-37
		DB	0
		DB	-60
		DB	-51
		DB	-37
		DB	0
		DB	-77
		DB	-70
		DB	-37
		DB	0

b@		LABEL	BYTE
b@w		LABEL	WORD
		DB	798 DUP (?)
		DB	19 DUP (?)
		DB	1 DUP (?)
_cchoice	LABEL	WORD
		DB	2 DUP (?)
_attr		LABEL	WORD
		DB	6 DUP (?)
_currow		LABEL	WORD
		DB	2 DUP (?)

_help           DB      CR, LF
		DB      "ASCII: A popup ASCII listbox"
		DB      CR, LF
		DB      CR, LF
		DB	"Syntax: ASCII [/kx] [/x##] [/y#]"
		DB	CR, LF
		DB	CR, LF
		DB	"ASCII is a hotkey activated memory resident"
		DB	CR, LF
		DB	"utility.  When the ALT-A hotkey is pressed,"
		DB	CR, LF
		DB	"a listbox appears displaying ASCII codes in"
		DB	CR, LF
		DB	"the decimal and hexadecimal number systems."
		DB	CR, LF
		DB	"The UP, DOWN, PGUP, PGDN, HOME, & END keys"
		DB	CR, LF
		DB	"are used to move around the listbox and ESC"
		DB	CR, LF
		DB	"exits.  The hotkey and listbox location can"
		DB	CR, LF
		DB	"be changed.  The /k parameter redefines the"
		DB	CR, LF
		DB	"hotkey.  The x value is A-Z or 0-9.  The /x"
		DB	CR, LF
		DB	"parameter defines the left column (## 0-59)"
		DB	CR, LF
		DB	"and the /y parameter defines the upper row"
		DB	CR, LF
		DB	"(# 0-6) of the listbox."
		DB	CR, LF
		DB      '$'

_byline         DB      "ASCII    - a popup ASCII listbox"
		DB      CR, LF
		DB      '$'

smsg		DB	CR, LF
		DB	"ascii: setting up"
		DB	CR, LF
		DB	'$'

_setup          PROC    NEAR
		lea	dx, smsg
		mov	ah, 9
		int	21h

		mov	ax, 3509h	; Save old int 9 vector.
		int	21h

		mov	WORD PTR _oldint9, bx
		mov	WORD PTR _oldint9[2], es

		lea	dx, _int9	; Redirect int 9 vector.
		mov	ax, 2509h
		int	21h

		ret
_setup          ENDP

cmsg		DB	CR, LF
		DB	"ascii: cleaning up"
		DB	CR, LF
		DB	'$'

cmsg2		DB	CR, LF
		DB	"ascii: WARNING - INTERRUPT 9 VECTOR REDIRECTED"
		DB	CR, LF
		DB	"       BY TSR INSTALLED AFTER IC.  REMOVE THIS"
		DB	CR, LF
		DB	"       TSR AND TRY THE GRAFT AGAIN."
		DB	CR, LF
		DB	'$'

_cleanup        PROC    NEAR
		lea	dx, cmsg
		mov	ah, 9
		int	21h

		mov	ax, 3509h	; Check current int 9 vector.
		int	21h

		mov	ax, es
		mov	bx, cs
		cmp	ax, bx		; Int 9 redirected since ASCII?
		je	_cleanup1	; No, branch.

		lea	dx, cmsg2	; Display warning message.
		mov	ah, 9
		int	21h

		pop	ax		; Remove return address from stack.
		pop	ax
		pop	ax		; Remove registers saved by GRAFT.

		ret			; Cause GRAFT to exit.
_cleanup1:
		push	ds

		lds	dx, _oldint9	; Restore old int 9 vector.
		mov	ax, 2509h
		int	21h

		pop	ds

		ret
_cleanup        ENDP

_TEXT		ENDS
		END	_ascii