;************************************************************************
;*  AE.A86 ** Assembly Editor.						*
;*  Derived from TED ** Tiny EDitor					*
;*  PC Magazine * Tom Kihlken * 					*
;************************************************************************
				;
	ORG	0100H		; Beginning for .com programs
	CHIP	80286		; 286 mode
START:	JMP	BEGIN		; Go
				;
TAB:	EQU	9		; Tab
CR:	EQU	13		; Carriage return
LF:	EQU	10		; Line feed
BEL:	EQU	07		; Bell
TRUE:	EQU	0FFH		; True
FALSE:	EQU	00H		; False
BETATST:EQU	FALSE		; Beta test
				;
;************************************************************************
;*									*
;*	User data area.  These are patchable with DEBUG or a config	*
;*	program to customize the program the way the user likes it.	*
;*									*
;************************************************************************
				;
INSMODE:			;
	DB	00H		; 00 = insert mode off. 103h
DIST:	DB	0FFH		; 00 = distructive bs. 104h
DOEOF:	DB	0FFH		; 00 for no eof. 105h
DOBAK:	DB	0FFH		; Ff = do backup files. 106h
DOCMT:	DB	0FFH		; Ff for auto-comment. 107h
CMTSP:	DB	0FFH		; Ff for space after auto-semi. 108h
FORM7:	DB	0FFH		; Ff for form7 filter. 109h
DOCOLON:DB	0FFH		; Ff for auto colons. 10ah
AUTOTAB:DB	0FFH		; Ff for auto-tab to comment column. 10bh
AUTOIND:DB	0FFH		; Ff for auto-indent. 10ch
LAME:	DB	000H		; Ff for line insert on cr. 10dh
PT:	DB	0FFH		; Ff for processor technology mode. 10eh
INSOFF:	DB	0FFH		; Ff for insert off on cr. 10fh
DOAUTO:	DB	0FFH		; Ff turns on auto-save feature 110h
STATLN:	DB	0FFH		; Ff turns on the status line 111h
NOISE:	DB	0FFH		; Ff turns on beeps, clicks, and pops 112h
KBFIX:	DB	000H		; Ff swaps cntrl and caps lock keys 113h
DOGREEK:DB	000H		; Ff turns on greek character ablity 114h
FIXOMEGA:			;
	DB	0FFH		; Ff=use traditional upper case omega 115h
USEHP:	DB	00H		; Ff uses built-in hp laserjet driver... 116h
NORMAL:	DB	0AH		; Color attribute for normal video. 117h
CMTCOL:	DB	32D		; Column for auto comment. 118h
PRNPTR:	DB	00H		; Printer number, 0-3 119h
CMTCHAR:DB	';'		; Character for commenting... 11ah
DFLTEXT:DB	'.ASM',0	; 11bh-11fh
DOTBAK:	DB	'.BAC',0	; 120h-124h
DOTTMP:	DB	'.$$$',0	; 125h-129h
GEN:	DB	00H		; 12ah, generation counter
DFLNAME:DB	6,'NONAME  '	; 12bh, default filename
INGREEK:DB	00H		; Ff - greek keyboard processing is on
PRGREEK:DB	00H		; Ff - printer is in greek mode right now.
OLDHP:	DB	00H		; Original use hp status
OLDPRN:	DB	00H		; Original lpt #
				;
;***********************************************************************
; Local data area
;***********************************************************************
				;
COPYRIGHT:			;
	DB	CR,LF,'AE '     ;
	 IF	BETATST		; Print beta...
	DB	'BHTA '		; If beta!
	 ENDIF			; No more options
	DB	'3.0'		; Version number
	 IF	BETATST		; Print beta revision
	DB	'a'		; Beta revision level
	 ENDIF			; No options
	DB	' Final Release' ; Final release message
	DB	', Generation ',00H ; Version goes here
LASTCPR:DB	CR,LF,'Copyright (c) 1993-2005 Goldenhead Development.'
	DB	CR,LF,'Portions (c) 1988 Ziff Communications Co.'
	DB	CR,LF,'PC Magazine ',254,' Tom Kihlken',00H,1AH
	DB	CR,LF,'Nosey, aren''t you?'
MINERVA:DB	CR,LF,'Dedicated to the Goddess Athena!',00H
				;
FILETOOBIG:			;
	DB	CR,LF		; And drop on into next message
TOOBIG:	DB	'Load File Format Error: File Too Big.',0FFH,'Press <ESC>',00H
READERRMESS:			;
	DB	CR,LF		; And drop on into next message
PROB1:	DB	'Load File Format Error: Read Error.',0FFH,'Press <ESC>',00H
PROBLEM:DB	'Save File Format Error: Write Error. Press <ESC>',00H
				;
MEMORYERROR:			;
	DB	CR,LF,'Not Enough Memory',CR,LF,00H
NO8088:	DB	CR,LF,'Sorry, 80286+ or V-series required.'
	DB	CR,LF,00H	;
BROKE:	DB	CR,LF,'Invalid Pack IDs, Program Terminated.',CR,LF,00H
				;
PROMPTSTRING:			;
	DB	'1Abort',0,'2Exit',0,'3BBeg',0
	DB	'4BEnd',0,'5BCopy',0,'6BMov',0
	DB	'7Find',0,'8S&R',0,'9Del EOL',0
	DB	'10Del L',0,0	;
				;
CTRLSTRING:			;
	DB	'1Swtch',0,'2Save',0,'3Load',0
	DB	'4Hide',0,'5BWrite',0,'6BDel',0
	DB	'7Fnxt',0,'8Line#',0,'9Zero',0
	DB	'10UnDel',0,0	;
				;
PRINTMESS:			;
	DB	'Printing, Please Wait... <ESC> to abort.',00H
NOPRINTMESS:			;
	DB	'Printer Is Hosed, Press <ESC>',00H
BUSYMESS:			;
	DB	'Search & Replace In Progress, Please Wait...',00H
AUTOMESS:			;
	DB	'Auto-Save In Progress, Please Wait...',00H
VERIFYMESS:			;
	DB	'Lose Changes (y/N)?',00H
CASEMESS:			;
	DB	'Case Sensitive (y/N)?',00H
ERAMESS:			;
	DB	'Erase Loadfile (y/N)?',00H
LOADMESS:			;
	DB	'Load: ',00H	; Block load prompt
SAVEMESS:			;
	DB	'Save As: ',00H	; Save prompt
FINDMESS:			;
	DB	'Find: ',00H	; Find prompt
JUMPMESS:			;
	DB	'Find line number: ',00H ;
REPLACEMESS:			;
	DB	'Replace With: ',00H ;
				;
PRNMESS:			;
	DB	'LPT#: ',00H	; Prompt for printer
TELLMESS:			;
	DB	'Search Complete, Press <ESC>',00H
TELLMESS1:			;
	DB	'Not enough room in buffer, Press <ESC>',00H
BSMESS:	DB	08H,' ',08H,00H	; Destructive backspace string
INDENT:	DB	00H		; Ff for indent, 00 for non-indent
DIRTYBITS:			;
	DB	1		; Screen refresh status
NOCASE:	DB	00H		; Ff supresses asking about case sensitivity
CHANGE:	DB	00H		; Becomes ff when file is changed
SAVEFLG:DB	00H		; Ff if saving
DOCASE:	DB	00H		; Tell find whether or not to ignore case
TEMP0:	DB	00H		; Temp storage byte
TEMP1:	DB	00H		; Temp storage byte
TEMP2:	DB	00H		; Temp storage byte
TEMP3:	DB	00H		; Temp storage byte
TEMP:				;
	DW	0000H		; Temp storage word
LEFTMARGIN:			;
	DB	0		; Current left margin offset
MARGINCOUNT:			;
	DB	0		; Margin storage
MARKMODE:			;
	DB	0		; Marking on (ff) or off (00)
DOMARK:	DB	00H		; Anything marked?
ROWS:	DB	24		; Default number of screen rows
SAVECOLUMN:			;
	DB	0		; Column storage
EXTEND:	DB	00H		; Ff when extended keyboard found
NAMEPTR:DW	81H		; Pointer to fcb in psp (default)
NAMEEND:DW	81H		; End of name default
STATREG:DW	0000H		; Video status register address
VIDSEG:	DW	0B000H		; Default video segment
LINELEN:DW	0		; Lenth of storage of deleted line
CURPOSN:			;
	DW	0		; Current screen cursor position y,x
SCREENTOP:			;
	DW	0		; Current top of screen file offset
CURSOR:	DW	0		; File pointer
LASTCHAR:			;
	DW	0		; End of file pointer
MODE:	DB	00H		; Used for video mode storage
ACCNEXT:DB	00H		; Ff means next (greek) character accented
OLDCTRL:DB	00H		; Storeage for control key status
AUTO:	DB	00H		; Ff means auto-save in progress
COLUMNSB:			; Used for first byte reference
COLUMNS:DW	0000H		; How many columns per row
MARK0:	DW	0000H		; Marker 0
MARK1:	DW	0000H		; Marker 1
MARK2:	DW	0000H		; Marker 2
MARK3:	DW	0000H		; Marker 3
MARK4:	DW	0000H		; Marker 4
MARK5:	DW	0000H		; Marker 5
MARK6:	DW	0000H		; Marker 6
MARK7:	DW	0000H		; Marker 7
MARK8:	DW	0000H		; Marker 8
MARK9:	DW	0000H		; Marker 9
MARKA:	DW	0000H		; Temp compensated location
MARKEND:DW	0		; Ending location for marking
MRKHOME:DW	0		; Where it was started from
MRKSTRT:DW	0000H		; Starting location for marking
PREV:	DW	0		; Previous location
OLDPREV:DW	0		; Old previous location
PASTESEG:			;
	DW	0000H		; Segment of paste buffer
PASTESIZE:			;
	DW	0000H		; Size of data in paste buffer
CAPLCK:	DB	00H		; Temporary caps lock state for shells, etc.
DISPATCHTABLE:			;
	DW	ABORT		; F1, 3b
	DW	EXIT		; F2, 3c
	DW	MARK		; F3, 3d
	DW	CUT		; F4, 3e
	DW	PASTE		; F5, 3f
	DW	BLKMOV		; F6, 40
	DW	FIND		; F7, 41
	DW	SANDR		; F8, 42
	DW	DELEOL		; F9, 43
	DW	DELL		; F10, 44
	DW	BADKEY		; 45
	DW	BADKEY		; 46
	DW	HOME		; Home, 47
	DW	UP		; Up arrow, 48
	DW	PGUP		; Page up, 49
	DW	BADKEY		; 4a
	DW	KEYLEFT		; Left arrow, 4b
	DW	OMNI		; Middle of numeric keypad, 4c
	DW	KEYRIGHT	; Right arrow, 4d
	DW	BADKEY		; 4e
	DW	GOEOL		; End key, 4f
	DW	DOWN		; Down arrow, 50
	DW	PGDN		; Page down, 51
	DW	INSERT		; Insert, 52
	DW	DELCHAR		; Delete, 53
				;
; The following machine instruction removes the desnow delay.  It is
; inserted into the code for EGA, VGA, and MONO displays.
				;
NODESNOW: EQU	9090H		; Nop out conditional jump
				;
;***********************************************************************
; We start by initialize the display, then allocate memory for the file
; and paste segments.  Parse the command line for a filename, if one was
; input, read in the file.  Finally set the INT 23 and 24 vectors.
;***********************************************************************
				;
BEGIN:	CLD			; Run strings forward
	IFFALSE	BETATST		; Don't checksum beta versions...
	CALL	CHKSUM		; Check checksum
	OR	AX,AX		; Zero?
	JZ	NOFIDDLE	; Yes, everything's ok
	NOT	AX		; Compliment
	INC	AX		; 2's compliment
	MOV	CS:[0100H],AX	; Store checksum at 100...
	MOV	DX,OFFSET BROKE	; Point to bad checksum message
	JMP	ERREXIT		; And exit
	 ENDIF			; End of options
				;
NOFIDDLE:			;
	MOV	CX,010BH	; Set cursor size
	MOV	AH,01H		; To block cursor
	INT	10H		; Do it
				;
	PUSH	SP		; 286 and above push pre-push sp
	POP	AX		; Get it back
	CMP	AX,SP		; Check for same
	JE	BEGIN1		; They are, so it's a 286
				; Itsa 8088, 8086, v20 or v30
	MOV	CX,0FFFFH	; Do lotsa times
	STI			; Make sure ints are on
	REP	LOCK LODSB ES:[SI] ; Check for 8088 multi-prefix int problem
	JCXZ	BEGIN1		; V20/30 doesn't have this problem...
				;
	MOV	DX,OFFSET NO8088 ; Point to no8088 message
	JMP	ERREXIT		; And exit
				;
BEGIN1:	 IF	BETATST		; If beta test version....
	CALL	BETA		; Do beta test time-out
	 ENDIF			; End of options
	MOV	SI,80H		; Point to parameters
	MOV	CL,[SI]		; Get number of characters
	XOR	CH,CH		; Make it a word
	INC	SI		; Point to first character
	JCXZ	NOCFG		; Nothing, skip...
				;
IGNSPC:	LODSB			; Get character into al
	CMP	AL,' '		; Space?
	JZ	NOSP		; Yes,ignore
	CMP	AL,'/'		; Or switch char?
	JZ	SWITCH		; Yes
	CMP	AL,'-'		; Alt switch for unix types
	JZ	SWITCH		; Yes
	CMP	AL,'['		; Alt switch for cp/m types
	JZ	SWITCH		; Yes
	JMP	SHORT NOCFG	; Run normal program
SWITCH:	MOV	AL,' '		; Look for space
	MOV	DI,SI		; Scas on di
	REPZ	SCASB		; Dump the darned things...
	INC	CX		; Compensate
	MOV	SI,DI		; Pointer back to si where it belongs...
	DEC	SI		; Compensate back
	LEA	DI,FNAME	; Point to configurator output filename
	REP	MOVSB		; Move the rest of the line there
	MOV	[DI]-1,BYTE PTR	00H ; Terminate filename (overwrite <cr>)
	JMP	CONFIG		; Run configurator
NOSP:	LOOP	IGNSPC		; Nope
				;
NOCFG:	CALL	CHKEXT		; Check for extended keyboard bios
	MOV	CS:[EXTEND],AH	; Put results in extended flag
	CALL	DOCAPS		; Setup caps lock
	XOR	AX,AX		; A zero
	MOV	DS,AX		; Get a zero into ds
	MOV	AH,12H		; Setup for bios
	MOV	BL,10H		; Get ega info
	INT	10H		; Call bios
	CMP	BL,10H		; Did bl change?
	JE	NOTEGA		; If not, no ega in system
	TEST	BYTE PTR DS:[0487H],8 ; Is ega active?
	JNZ	NOTEGA		; Nap
	MOV	CS:NOSNO,WORD PTR NODESNOW ; Get rid of desnow
	MOV	AX,DS:[0484H]	; Get number of rows
	MOV	CS:[ROWS],AL	; Save the number of rows
	JMP	SHORT GREECE	; Continue
				;
NOTEGA:	MOV	CS:[DOGREEK],BYTE PTR 00H ; Turn off greek
				;
GREECE:	CMP	CS:[STATLN],BYTE PTR 00H ; Do stat line?
	JZ	NOSTAT		; No
	DEC	BYTE PTR CS:[ROWS] ; Make room for status line
NOSTAT:	MOV	AX,DS:[044AH]	; Get number of columns
	XOR	AH,AH		; Only allow 255 physical collumns...
	MOV	CS:[COLUMNS],AX	; And store it
	MOV	AL,DS:[0449H]	; Get current mode
	MOV	CS:[MODE],AL	; And store it
	MOV	AX,DS:[0463H]	; Address of display card
	ADD	AX,6		; Add six to get status port
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	CS:[STATREG],AX	; Save status register address
	CMP	AX,3BAH		; Is this a mono display?
	JNE	COLOR		; If not, must be a cga
	MOV	CS:[NOSNO],WORD	PTR NODESNOW ; Get rid of desnow
	JMP	SHORT MOVESTACK	; Continue, flush queu
				;
COLOR:	MOV	CS:[VIDSEG],WORD PTR 0B800H ; Segment for color card
	CMP	CS:[NORMAL],BYTE PTR 00H ; Check for zero
	JNZ	MOVESTACK	; Use configured attribute
	XOR	BH,BH		; Use page zero
	MOV	AH,8		; Get current attribute
	INT	10H		; Go do it
	MOV	CS:[NORMAL],AH	; Save the normal attribute
				;
MOVESTACK:			;
	MOV	BX,OFFSET NUSTAK ; Point to our stack area
	MOV	SP,BX		; Move the stack downward
	ADD	BX,15		; By 15
	SHR	BX,4		; Convert pgm size to paragraphs
	MOV	AH,4AH		; Deallocate unused memory
	INT	21H		; Call dos
	MOV	BX,1000H	; Request 64k for file segment
	MOV	AH,48H		; Allocate function
	INT	21H		; Call dos
	MOV	ES,AX		; Segment in es
	MOV	AH,48H		; Allocate function
	INT	21H		; Request 64k for paste buffer
	JNC	GOTENOUGH	; If enough memory, continue
	MOV	DX,OFFSET MEMORYERROR ; Point to message
				;
ERREXIT:PUSH	CS		; Get this segment
	POP	DS		; Into ds
	CALL	PSTRING		; Print error message
	CALL	PRTCOPY		; Print signoff message
	MOV	AX,4CFFH	; Terminate with errors
	INT	21H		; Bye-bye...
				;
GOTENOUGH:			;
	MOV	CS:[PASTESEG],AX ; Use this for the paste buffer
	CMP	CS:[DOGREEK],BYTE PTR 0FFH ; Greek turned on?
	JZ	OASIS		; Yes, continue
				;
	MOV	CS:[USEHP],BYTE	PTR 00H	; Turn off hp driver....
OASIS:	AND	CS:[CMTCOL],BYTE PTR 78H ; Force comment column to be at x8
	CMP	CS:[PRNPTR],BYTE PTR 02H ; Make sure printer number is valid
	JBE	PRNOK		; Valid
	MOV	CS:[PRNPTR],BYTE PTR 00H ; Default to lpt1:
				;
PRNOK:				;
	MOV	AL, CS:[USEHP]	; Get hp driver status
	MOV	CS:[OLDHP],AL	; And remember
	MOV	AL,CS:[PRNPTR]	; Get original printer number
	MOV	CS:[OLDPRN],AL	; And remember
				;
	MOV	SI,80H		; Point to parameters
	MOV	CL,[SI]		; Get number of characters
	XOR	CH,CH		; Make it a word
	INC	SI		; Point to first character
	JCXZ	LKDOT		; Nothing, skip...
				;
	PUSH	ES		; Save es
	PUSH	CS		; Get code segment
	POP	ES		; Into extra
	MOV	DI,SI		; Init di for scas
	MOV	AL,' '		; Look for space
	REPZ	SCASB		; Look for it
	POP	ES		; Restore orginal es
	INC	CX		; Compensate count up
	DEC	DI		; Compensate back
	MOV	SI,DI		; Back to si where it belongs....
				;
LKDOT:	PUSH	SI		; Save
	PUSH	ES		; Save es
	PUSH	CX		; Save length
	MOV	DI,SI		; Get into di for scas
	PUSH	CS		; Get this segment
	POP	ES		; Into es
	MOV	AL,'.'		; Looking for dot
CHKDOT:	JCXZ	DOT		; Null length entry, abort
	REPNZ	SCASB		; Check for dot
	JZ	DOT		; Found one, exit
				;
PUTEXT:	MOV	SI,OFFSET DFLTEXT ; Point to default extension
	MOV	CX,0004H	; 4 characters
	REP	MOVSB		; Load it up
	POP	CX		; Get original filename length
	ADD	CX,0004H	; Bump up to include extension
	PUSH	CX		; For next...
DOT:	POP	CX		; Restore count
	POP	ES		; Restore file segment
	POP	SI		; Restore original pointer
	PUSH	SI		; Re-save
	ADD	SI,CX		; Point to last character
	MOV	BYTE PTR [SI],0	; Make it an asciiz string
	MOV	CS:[NAMEEND],SI	; Save pointer to last character
	POP	SI		; Get back pointer to filename
	JCXZ	FIXFILE		; If no params, use default filename.
	MOV	CS:[NAMEPTR],SI	; Save pointer to filename
	JMP	SHORT OPENIT	; Continue
				;
FIXFILE:MOV	SI,OFFSET DFLNAME ; Point to default filename
	CMP	CS:[SI],BYTE PTR 00H ; No default filename?
	JZ	NOFILENAME	; User configured it off
	MOV	DI,0080H	; Point to default fcb
	MOV	CX,0009H	; 1 param byte + 8 char filename...
	PUSH	ES		; Save es
	PUSH	CS		; Get cs
	POP	ES		; Into es
	REP	MOVSB		; Copy in...
	POP	ES		; Fix es
	JMP	SHORT PRNOK	; Recurse and put in default extension
				;
OPENIT:	MOV	DX,SI		; Put in dx for dos
	MOV	AX,3D00H	; Setup to open file
	INT	21H		; Go open it
	JC	NOFILENAME	; If we can't open, must be new file
FILEOPENED:			;
	PUSH	ES		; Save file segment
	POP	DS		; Ds has file segment also
	MOV	BX,AX		; Get the handle into bx
	XOR	DX,DX		; Point to file buffer
	MOV	AH,3FH		; Read service
	MOV	CX,0FFFEH	; Read almost 64k bytes
	INT	21H		; Do it
	MOV	DI,AX		; Number of bytes read in
	JNC	LOOKFOREOF	; If no error, take jump
	MOV	DX,OFFSET READERRMESS ; Point to message
	JMP	ERREXIT		; And exit
LOOKFOREOF:			;
	PUSH	CX		; Save cx
	OR	DI,DI		; Empty file?
	JZ	NOEOF		; Then nothing there
	CMP	CS:[DOEOF],BYTE	PTR 00H	; Doing eof?
	JZ	NOEOF		; Ignore it
	MOV	CX,DI		; Get number of characters
	MOV	AL,1AH		; Look for eof
	XOR	DI,DI		; Start at zero in file
	REPNE	SCASB		; Look for eof
	JNE	NOEOF		; None found
	DEC	DI		; Backup to last character
				;
NOEOF:	POP	CX		; Restore cx
	MOV	CS:[LASTCHAR],DI ; Save the file size
	CMP	CX,DI		; Did the buffer fill?
	MOV	DX,OFFSET FILETOOBIG ; Point to error message in case...
	JNE	SMALL		; Small enough...
	JMP	ERREXIT		; It is too big
SMALL:	MOV	AH,3EH		; Close file function
	INT	21H		; Close the file
NOFILENAME:			; No filename found
	PUSH	ES		; Save file segment
	PUSH	ES		; Save file segment again...
	MOV	AX,3524H	; Get int 24 vector
	INT	21H		; Call dos
	MOV	WORD PTR CS:OLDINT24,BX	; Store the offset
	MOV	WORD PTR CS:OLDINT24+2,ES ; And the segment
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	DX,OFFSET NEWINT24 ; Point to our critical error handler
	MOV	AX,2524H	; Now change int 24 vector
	INT	21H		; Go setup our vector
				;
	MOV	DX,OFFSET NEWINT23 ; Point to our control-break handler
	MOV	AX,2523H	; Set the int 23 vector also
	INT	21H		; Go setup our vector
				;
	MOV	AX,3508H	; Get int 08 vector
	INT	21H		; Call mush-dos
	MOV	WORD PTR CS:OLDVEC,BX ; Store the offset
	MOV	WORD PTR CS:OLDSEG,ES ; And the segment
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	DX,OFFSET MYINT	; Point to our tic hook
	MOV	AX,2508H	; Now change int 08 vector
	INT	21H		; Go setup our vector
				;
	MOV	AX,3515H	; 15h is keyboard intercept
	INT	21H		; Get old int vector
	MOV	WORD PTR CS:[OLDVECF],BX ; And save it
	MOV	WORD PTR CS:[OLDSEGF],ES ; Including segment
				;
	CMP	CS:[KBFIX],BYTE	PTR 0FFH ; Keyboard fixing?
	JNZ	NOKBFIX		; Not configured, don't install
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	DX,OFFSET MYINT15 ; Point to our keyboard handler
	MOV	AX,2515H	; Now change int 15 vector
	INT	21H		; Go setup our vector
				;
NOKBFIX:POP	ES		; Get back file segment
	POP	DS		; Restore (pushed as es)
	CALL	INHIBIT		; Initial call so next won't clobber it...
				;
	CMP	CS:[DOGREEK],BYTE PTR 00H ; Greek enabled?
	JZ	AMERIKH		; No
				;
	MOV	CS:CX,[LASTCHAR] ; Get number of characters
	XOR	SI,SI		; Start at zero in file
	JCXZ	XOROS2		; No, forget it
				;
XOROS:	LODSB			; Get char
	CMP	AL,40H		; Control characters, space, numbers or punc?
	JA	XOROS1		; No
	LOOP	XOROS		; Try again
	JMP	SHORT XOROS2	; All blank, forget it
				;
XOROS1:	CMP	AL,7FH		; Shouldn't be embedded, but check anyway...
	LOOPZ	XOROS		; Look again...
				; Now we should have first non-whitespace char
				; In al
	JBE	XOROS2		; Assume ascii
	MOV	CS:[INGREEK],BYTE PTR 0FFH ; Assume greek
				;
XOROS2:	CALL	LOADFONT	; Load greek fonts
AMERIKH:CALL	REDOPROMPT	; Draw the prompt line
				;
	CALL	FIXUNIX		; Fix alien system files...
				;
;***********************************************************************
; Here's the main loop.  It updates the screen, then reads a keystroke.
;***********************************************************************
				;
READAKEY:			;
	CALL	FIXCUR		; Keep cursor visable
	MOV	AL,CS:[TEMP2]	; Get orignal auto-save permission
	MOV	CS:[DOAUTO],AL	; And restore
	CALL	TYPECAPS	; Handle caps lock
	CMP	CS:[MARKMODE],BYTE PTR 0 ; Is the mark state on?
	JE	MARKOFF		; If not, skip this
				;
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Refresh the whole screen
SAMEROW:MOV	AX,CS:[CURSOR]	; Get cursor location
	MOV	BX,CS:[MRKHOME]	; Get the anchor mark position
	CMP	AX,BX		; Moving backward in file?
	JAE	S1		; No
				;
	MOV	CS:[MRKSTRT],AX	; Switch start and end position
	MOV	CS:[MARKEND],BX	; Swapped
	JMP	SHORT MARKOFF	; Continue
				;
S1:	MOV	CS:[MARKEND],AX	; Store start and end marks
	MOV	CS:[MRKSTRT],BX	; Normally...
MARKOFF:MOV	DX,CS:[CURPOSN]	; Get cursor position
	CALL	SETCURSOR	; Position the cursor
	TEST	CS:[DIRTYBITS],BYTE PTR	1 ; Look at screen dirty bit
	JZ	SCREENOK	; If zero, screen is ok
				;
	CALL	CONSTAT		; Get console status
	JNZ	CURRENTOK	; Something there, skip the update
	CALL	DISPLAYSCREEN	; Redraw the screen
	MOV	CS:[DIRTYBITS],BYTE PTR	0 ; Mark screen as ok
SCREENOK:			;
	TEST	CS:[DIRTYBITS],BYTE PTR	4 ; Is the current line dirty?
	JZ	CURRENTOK	; If not, take jump
	CALL	DISPLAYCURRENT	; Redraw the current line
	MOV	CS:[DIRTYBITS],BYTE PTR	0 ; Mark screen as ok
CURRENTOK:			;
	CALL	GETCH		; Get key
	OR	AL,AL		; Is this an extended code?
	JZ	EXTENDEDCODE	; Yes
	CMP	AL,0E0H		; Extended code w/extended keyboard bios?
	JZ	EXTENDEDCODE	; Yes
				; Insert other special keys here
	CMP	AX,1C0AH	; ^enter?
	JNZ	XYZZY		; No
	MOV	CS:[ACCNEXT],BYTE PTR 00H ; Turn off accent next
	CALL	CNTRLN		; Insert line
	JMP	READAKEY	; Continue
				;
XYZZY:	CMP	AL,1FH		; Control characters?
	JA	NOCONT		; No
	MOV	CS:[ACCNEXT],BYTE PTR 00H ; Turn off accent next
	JMP	WS		; Yes, do wordstar commands
				;
NOCONT:	CMP	AX,0E7FH	; Ctrl-backspace?
	JNZ	FEETSIE		; No
	CALL	BADKEY		; Beep
	JMP	SHORT FOOTSER	; Ignore
				;
FEETSIE:CALL	INSERTKEY	; Put this character in the file
FOOTSER:JMP	READAKEY	; Get another key
				;
BACKSPACE:			;
	MOV	AL,CS:[DIST]	; Distructive backspace flag
	OR	AL,AL		; Force flags
	JZ	DISTRUCT	; Zero=distructive bs
	JMP	KEYLEFT		; Move left
				;
DISTRUCT:			;
	CMP	CS:[CURSOR],WORD PTR 0 ; At start of file?
	JE	BADKEY		; If at start, can't backspace
	CALL	LEFT		; Move left one space
	CALL	DELCHAR		; And delete the character
	JMP	BOTHKEY		; Exit without caps lock twiddle
				;
BADKEY:	CALL	BEEP1		; Make noise
	RET			; Go back
				;
;************************************************************************
;*									*
;*	Here we process misc, non-data contiguous keys with a dual	*
;*	lookup approach.  Actually could do all keys this way, but	*
;*	the dual approach takes more memory. (but beats compare 	*
;*	immediate and jump!)						*
;*									*
;************************************************************************
				;
EXTENDEDCODE:			;
	MOV	CS:[ACCNEXT],BYTE PTR 00H ; Turn off accent next
	PUSH	ES		; Save es
	PUSH	CS		; Get this segment
	POP	ES		; Into es
	MOV	DI,OFFSET TABLE	; Point to misc values table
	MOV	CX,000BH	; Number of entries in table
	MOV	SI,CX		; Remember for later
	MOV	AL,AH		; Get into al for scas
	REPNZ	SCASB		; Look for entry
	JNZ	NOTTHERE	; No find
	SUB	SI,CX		; Generate offset
	DEC	SI		; Compensate for 0 entry array
	ROL	SI,1		; Multiply by two for word offset
	ADD	SI,OFFSET JTABLE ; Add in offset of jump table
	POP	ES		; Restore es
	CALL	CS:[SI]		; Call it
	JMP	REENTER		; Go get another
NOTTHERE:			;
	POP	ES		; Restore es
	JMP	FAKE		; Go check contiguous keys.
				;
TABLE:	DB	84H		; Control-pgup
	DB	76H		; Control-pgdn
	DB	73H		; Control-left arrow
	DB	74H		; Control-right arrow
	DB	8DH		; Control-up arrow
	DB	91H		; Control-down arrow
	DB	0FH		; Back tab
	DB	85H		; F11
	DB	86H		; F12
	DB	77H		; Control-home
	DB	75H		; Control-end
				;
JTABLE:	DW	TOP		; Control-pgup
	DW	BOTTOM		; Control-pgdn
	DW	SHLEFT		; Control-left arrow
	DW	SHRIGHT		; Control-right arrow
	DW	CNTRLW		; Control-up arrow
	DW	CNTRLZ		; Control-down arrow
	DW	BCKTAB		; Back tab
	DW	GOBEG		; F11
	DW	GOEND		; F12
	DW	TSCREEN		; Control-home
	DW	BSCREEN		; Control-end
				;
FAKE:	CMP	AH,5EH		; Are we doing a control-f key?
	JB	FAKE1		; No
	CMP	AH,67H		; Upper limit
	JA	FAKE1		; Above control-f keys
	MOV	SI,OFFSET CFTBL	; Point to control table
	MOV	AL,AH		; Into al for offset calculation
	SUB	AL,5EH		; Make 0 offset
	XOR	AH,AH		; Clear ah for shl
	SHL	AX,1		; Make into word offset
	ADD	SI,AX		; Add into offset
	CALL	CS:[SI]		; Do function
	JMP	REENTER		; Go again
				;
CFTBL:	DW	TOFF		; ^f1, turn off special features
	DW	SAVE		; ^f2, save & resume
	DW	LOADBLK		; ^f3, load block from file
	DW	HIDE		; ^f4, hide/un-hide
	DW	SAVEBLK		; ^f5, save block to file
	DW	BLKDEL		; ^f6, delete marked block
	DW	KEYCNTRLL	; ^f7, find next
	DW	JLINE		; ^f8, jump to line #
	DW	STRIP		; ^f9, strip bit 7 (msb)
	DW	UDELL		; ^f10, undelete line
				;
FAKE1:	CMP	AH,53H		; Skip high numbered keys
	JA	BAD		; Ignore....
	XCHG	AH,AL		; Switch
	XOR	AH,AH		; Clear ah for shl
	SUB	AL,3BH		; Also skip low numbered keys
	JC	BAD		; Bye...
	SHL	AX,1		; Make the code an offset
	MOV	BX,AX		; Put offset in bx
	CALL	CS:DISPATCHTABLE[BX] ; Call the key procedure
	JMP	REENTER		; Then read another key
				;
BAD:	CALL	BADKEY		; Hook for non-calling structures
	JMP	READAKEY	; Get another key
				; This is hidden feature that allows normal
				; Text editor use.  hit ^<f1>.
OMNI:				;
TOFF:	CMP	CS:[DOGREEK],BYTE PTR 00H ; Do greek?
	JZ	TOFF1		; No, do as before
	NOT	CS:BYTE	PTR [INGREEK] ; Toggle ingreek flag
	MOV	CS:[ACCNEXT],BYTE PTR 00H ; Turn off accent next
	POP	AX		; Remove return address from stack
	JMP	READAKEY	; And re-enter main loop
				;
TOFF1:	XOR	AL,AL		; A zero
	MOV	CS:[DOCMT],AL	; Turn off auto comment
	MOV	CS:[DOCOLON],AL	; Turn off auto colon
	MOV	CS:[FORM7],AL	; Turn off form7 filter
	MOV	CS:[AUTOIND],AL	; Turn off auto-indent
	MOV	CS:[AUTOTAB],AL	; Turn off auto-tab
	RET			; Go home
				;
;***********************************************************************
; These two routines shift the display right or left to allow editing
; files which contain lines longer than 80 columns.
;***********************************************************************
				;
SHRIGHT:CMP	CS:[LEFTMARGIN],BYTE PTR (255-8) ; Past max allowable margin?
	JAE	NOSHIFT		; Then can't move any more
	ADD	CS:[LEFTMARGIN],BYTE PTR 8 ; This moves the margin over
				;
SHRETURN:			;
	CALL	CURSORCOL	; Compute column for cursor
	MOV	DX,CS:[CURPOSN]	; Get cursor position
	MOV	CS:[SAVECOLUMN],DL ; Save the current column
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
NOSHIFT:RET			; Go home
				;
SHLEFT:	CMP	CS:[LEFTMARGIN], BYTE PTR 0 ; At start of line already?
	JE	NOSHIFT		; If yes, then don't shift
	SUB	CS:[LEFTMARGIN],BYTE PTR 8 ; Move the window over
	JMP	SHRETURN	; Do common code above...
				;
KEYLEFT:CALL	LEFT		; Shift it left and skip normal caps lock stuff
	JMP	SHORT BOTHKEY	; Do common
				;
KEYRIGHT:			;
	CALL	RIGHT		; Go right and skip normal caps lock stuff
BOTHKEY:POP	AX		; Remove return address
	JMP	READAKEY	; Better not twiddle the stack...
				;
;***********************************************************************
; Process WordStar commands
;***********************************************************************
				;
WS:	MOV	SI,OFFSET CTABLE ; Point to control table
	XOR	AH,AH		; Clear ah for rol
	PUSH	AX		; Save original char for tab and cr processing
	ROL	AX,1		; Make into word offset
	ADD	SI,AX		; Add into offset
	POP	AX		; Restore original char
	CALL	CS:[SI]		; Do function
REENTER:CALL	DOCAPS		; Take care of caps lock
	JMP	READAKEY	; And go for more
				;
CTABLE:				;
	DW	BADKEY		; Control-@
	DW	WLEFT		; Control-a
	DW	STRIP		; Control-b
	DW	PGDN		; Control-c
	DW	KEYRIGHT	; Control-d
	DW	UP		; Control-e
	DW	WRIGHT		; Control-f
	DW	DELCHAR		; Control-g
	DW	BACKSPACE	; Control-h
	DW	CNTRLI		; Control-i
	DW	BADKEY		; Control-j
	DW	CNTRLK		; Control-k
	DW	KEYCNTRLL	; Control-l
	DW	NEWLINE		; Control-m
	DW	CNTRLN		; Control-n
	DW	BADKEY		; Control-o
	DW	LITERAL		; Control-p
	DW	CNTRLQ		; Control-q
	DW	PGUP		; Control-r
	DW	KEYLEFT		; Control-s
	DW	DELWORD		; Control-t
	DW	UDELL		; Control-u
	DW	INSERT		; Control-v
	DW	CNTRLW		; Control-w
	DW	DOWN		; Control-x
	DW	DELL		; Control-y
	DW	CNTRLZ		; Control-z
	DW	BADKEY		; Control-[
	DW	BADKEY		; Control-\
	DW	BADKEY		; Control-]
	DW	BADKEY		; Control-^
	DW	BADKEY		; Control-_
				;
KTABLE:	DW	BADKEY		; A
	DW	MARK		; B
	DW	PASTE		; C
	DW	EXIT		; D
	DW	BADKEY		; E
	DW	SHELL		; F
	DW	BADKEY		; G
	DW	HIDE		; H
	DW	BADKEY		; I
	DW	BADKEY		; J
	DW	CUT		; K
	DW	BADKEY		; L
	DW	BADKEY		; M
	DW	PRNNUMB		; N
	DW	BADKEY		; O
	DW	PRINT		; P
	DW	ABORT		; Q
	DW	LOADBLK		; R
	DW	SAVE		; S
	DW	BADKEY		; T
	DW	BADKEY		; U
	DW	BLKMOV		; V
	DW	SAVEBLK		; W
	DW	EXIT		; X
	DW	BLKDEL		; Y
	DW	BADKEY		; Z
				;
CNTRLK:	MOV	SI,OFFSET KTABLE ; Point to cntrl-k table
	JMP	SHORT ALLCNTRL	; Continue
				;
CNTRLQ:	MOV	SI,OFFSET QTABLE ; Point to cntrl-q table
ALLCNTRL:			;
	CALL	CONSTAT		; Check for next key...
	JNZ	ALLCNTRL1	; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	ALLCNTRL	; No
	CALL	BEEP2		; Make noise
	RET			; Guy is asleep at the switch...
				;
ALLCNTRL1:			;
	CALL	GETCH		; Get key
	OR	AL,AL		; Force flags
	JZ	BADQ		; Special keys, abort...
	CMP	AL,'0'		; Numeric?
	JB	NONUMB		; No
	CMP	AL,'9'		; Numeric?
	JBE	NUMB		; Yes
				;
NONUMB:	AND	AL,5FH		; Convert to upper case
	OR	AL,40H		; Convert up out of control, if there
	CMP	AL,40H		; Under range?
	JBE	BADQ		; Yes, outta here
	CMP	AL,5AH		; Outta range?
	JBE	QOK		; No, ok
BADQ:	JMP	BADKEY		; Yes, exit
				;
QOK:	MOV	BH,CS:[INGREEK]	; Get greek status
	MOV	CS:[TEMP3],BH	; And save
	CMP	SI,OFFSET QTABLE ; Control-q?
	JNZ	NOQ		; No, control-k
	CALL	CSAVE		; Remember cursor
	JMP	SHORT DOQ	; Continue with control-q
				;
NOQ:	MOV	CS:[INGREEK],BYTE PTR 00H ; Turn off greek
DOQ:	SUB	AL,41H		; Make 'a' = 0
	XOR	AH,AH		; Clear ah for rol
	ROL	AX,1		; Make into word offset
	ADD	SI,AX		; Add into offset
	CALL	CS:[SI]		; Do function
	CALL	DOCAPS		; Take care of caps lock
	MOV	AL,CS:[TEMP3]	; Recover original greek status
	MOV	CS:[INGREEK],AL	; And put back
	RET			; And go for more
				;
NUMB:	SUB	AL,30H		; Make '0'=0
	ADD	AL,AL		; Double
	XOR	AH,AH		; Zero upper
	MOV	DI,OFFSET MARK0	; Get first marker storage location
	ADD	DI,AX		; Calculate marker
	CMP	SI,OFFSET QTABLE ; Control-q?
	JZ	QNUMB		; Yes
				;
	MOV	SI,CS:[CURSOR]	; Get current location
	MOV	CS:[DI],SI	; Update marker
	RET			; Go home
				;
QNUMB:	MOV	CS:SI,[DI]	; Get marker into si
	OR	SI,SI		; Force flags
	JZ	SKIPIT		; Don't go to zero
	CALL	CSAVE		; Remember cursor
	CALL	MOVE		; Go there
SKIPIT:	RET			; Go home
				;
QTABLE:	DW	SANDR		; A
	DW	GOBEG		; B
	DW	BOTTOM		; C
	DW	GOEOL		; D
	DW	TSCREEN		; E
	DW	FIND		; F
	DW	BADKEY		; G
	DW	BADKEY		; H
	DW	JLINE		; I
	DW	BADKEY		; J
	DW	GOEND		; K
	DW	BADKEY		; L
	DW	BADKEY		; M
	DW	BADKEY		; N
	DW	BADKEY		; O
	DW	GOPREV		; P
	DW	BADKEY		; Q
	DW	TOP		; R
	DW	HOME		; S
	DW	BADKEY		; T
	DW	BADKEY		; U
	DW	BADKEY		; V
	DW	BADKEY		; W
	DW	BSCREEN		; X
	DW	DELEOL		; Y
	DW	BADKEY		; Z
				;
LITERAL:CALL	CONSTAT		; Check for next key...
	JNZ	LITERAL1	; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	LITERAL		; No
	CALL	BEEP2		; Make noise
	RET			; Guy is asleep at the switch...
				;
LITERAL1:			;
	CALL	GETCH		; Get literal keystroke
	OR	AL,AL		; Look for nul:
	JZ	LIT3		; Dis-allow
	CMP	AL,CR		; Cr?
	JNZ	LIT1		; No
	JMP	NEWLINE		; For user's protection
				;
LIT1:	CMP	AL,1AH		; Eof?
	JNZ	LIT2		; No, continue
	CALL	BEEP1		; Warn user
LIT2:	CALL	INSERTKEY	; And place in file
LIT3:	RET			; Go home
				;
BSCREEN:CALL	HOME1		; Cursor to left
	MOV	DX,CS:[CURPOSN]	; Get cursor x,y
BLP:	CMP	DH,CS:[ROWS]	; At bottom already?
	JZ	BEXIT		; Yes
	CALL	FINDNEXT	; Find the start of next line
	JC	BEXIT		; If no more lines, then return
	MOV	CS:[CURSOR],SI	; Get position in file
	INC	DH		; Advance cursor to next row
	CALL	LOCATE		; Locate cursor at bottom
	JMP	SHORT BLP	; Do until cursor gets to bottom
BEXIT:	CALL	ENDD		; Move to end of line
	RET			; Go home
				;
TSCREEN:XOR	DH,DH		; Top of screen on screen
	MOV	SI,CS:[SCREENTOP] ; Marker in file
	CALL	LOCATE		; Locate cursor at top
	CALL	HOME1		; Cursor to left
	RET			; Go home
				;
WRIGHT:	CALL	CSAVE		; Save cursor
	CALL	CHKINDENT	; Take care of auto-indent
WRIGHT1:CALL	CHKSTOP		; What's under the cursor right now?
	JZ	WRIGHT3		; We're in the clear
				;
	CALL	RIGHT		; Move
	JC	WRIGHT4		; Can't do it
	CALL	CHKSTOP		; What do we have here?
	JNZ	WRIGHT2		; Go eat the rest of the word...
	JMP	SHORT WRIGHT3	; Go eat the whitespace and the next word
				;
WRIGHT2:CALL	RIGHT		; Move over one
	JC	WRIGHT4		; Can't move
	CALL	CHKSTOP		; At a stop char?
	JNZ	WRIGHT2		; No
				;
WRIGHT3:CALL	RIGHT		; Move over one
	JC	WRIGHT4		; Can't move
	CALL	CHKSTOP		; Whitespace?
	JZ	WRIGHT3		; Yes
WRIGHT4:RET			; No
				;
WLEFT:	CALL	CSAVE		; Save cursor
WLEFT1:	CALL	CHKSTOP		; What's under the cursor right now?
	JZ	WLEFT3		; We're in the clear
				;
	CALL	LEFT		; Move
	JC	WLEFT4		; Can't do it
	CALL	CHKSTOP		; What do we have here?
	JNZ	WLEFT2		; Go eat the rest of the word...
	JMP	SHORT WLEFT3	; Go eat the whitespace and the next word
				;
WLEFT2:	CALL	LEFT		; Move over one
	JC	WLEFT4		; Can't move
	CALL	CHKSTOP		; At a stop char?
	JNZ	WLEFT2		; No
	CALL	RIGHT		; Compensate
WLEFT4:	RET			; Go home
				;
WLEFT3:	CALL	LEFT		; Move over one
	JC	WLEFT4		; Can't move
	CALL	CHKSTOP		; Whitespace?
	JZ	WLEFT3		; Yes
	JMP	SHORT WLEFT2	; Now move to the beginning of the word
				;
BCKTAB:	CALL	CSAVE		; Save cursor
BCKTAB1:CALL	LEFT		; Move over one
	MOV	AL,CS:[MARGINCOUNT] ; Get margincount
	TEST	AL,00000111B	; At even multiple of eight?
	JNZ	BCKTAB1		; If not, keep going left
	RET			; Go home
				;
CNTRLI:	CALL	CSAVE		; Save cursor
	CMP	CS:[AUTOTAB],00H ; Doing auto column fielding?
	JZ	DOCNTRLI	; No, process normally
	MOV	SI,CS:[CURSOR]	; Get current
	CALL	FINDSEMI1	; Already past an existing semi colon?
	JZ	DOCNTRLI	; Yes, don't do this...
	CALL	CURSORCOL	; Compute the correct column
	CMP	DL,16D		; In operand field?
	JB	DOCNTRLI	; No, process normally
				;
FAKE77:	CALL	DOCNTRLI	; Tab over
	CALL	CURSORCOL	; Compute the correct column
	CMP	DL,CS:[CMTCOL]	; In comment field somewhere?
	JB	FAKE77		; Not yet
	RET			; Done
				;
DOCNTRLI:			;
	CALL	CHKINDENT	; Take care of indent flag...
	MOV	SI,CS:[CURSOR]	; Get current position
	MOV	AL,CS:[DOCOLON]	; Auto-colons?
	OR	AL,AL		; Force flags
	JZ	NOCOLON1	; No
	CALL	INSCOLON	; Check for label and insert colon if needed
	JC	NOCOLON1	; No colon inserted
	MOV	CS:AL,[MARGINCOUNT] ; Get margincount
	TEST	AL,00000111B	; At even multiple of eight?
	JNZ	NOCOLON1	; No, proceed normally
	RET			; That colon bumped us to the next tab stop!
				;
NOCOLON1:			;
	MOV	SI,CS:[CURSOR]	; Get current position
	CMP	SI,CS:[LASTCHAR] ; Are we at end of file?
	JNZ	CNTRLI1		; No, other checks are valid
	JMP	INSERTTAB	; Yes, gotta append
				;
CNTRLI1:PUSH	SI		; Save current position
	CALL	FINDEOL		; See where the end of this line is?
	POP	DI		; Get back current position
	CMP	DI,SI		; Are we at end of line?
	JNZ	CNTRLI2		; No, other checks are valid
	JMP	SHORT INSERTTAB	; Yes, gotta append
				;
CNTRLI2:CMP	CS:[INSMODE],BYTE PTR 00H ; Insert mode?
	JNZ	INSERTTAB	; Yes
				;
CNTRLI3:SUB	SI,DI		; See how far away the eol is
	CMP	SI,0007H	; Less than a tab?
	JA	CNTRLI4		; No, just move on over
	MOV	CX,SI		; Move count in
	MOV	SI,CS:[CURSOR]	; Get back current position
ILP:	MOV	ES:AL,[SI]	; Get current character
	INC	SI		; Next
	CMP	AL,TAB		; Tab?
	JNZ	ALASKA		; No
				;
CNTRLI4:CALL	RIGHT		; Move over one
	CMP	SI,CS:[LASTCHAR] ; At end of file?
	JE	M1		; If yes, then can't move
	CMP	BYTE PTR [SI],CR ; At end of line?
	JZ	M1		; Yes, call it a day
	MOV	AL,CS:[MARGINCOUNT] ; Get margincount
	CMP	AL,CS:[LEFTMARGIN] ; At edge of screen?
	JZ	M1		; Yes, call it a day
	TEST	AL,00000111B	; At even multiple of eight?
	JNZ	CNTRLI4		; If not, keep going right
M1:	RET			; Go home
				;
ALASKA:	LOOP	ILP		; Check all remaining chars
	CALL	ENDD		; Move to end of line
				;
INSERTTAB:			;
	MOV	AL,09H		; Regenerate the tab
	CALL	INSERTKEY	; Insert tab normaly
	MOV	AL,CS:[SAVECOLUMN] ; Get current collum
	CMP	AL,CS:[CMTCOL]	; Comment collum?
	JNZ	NOCMT		; No
	MOV	AL,CS:[DOCMT]	; Doing auto-commenting?
	OR	AL,AL		; Force flags
	JZ	NOCMT		; No
	CALL	FINDSEMI	; Is there already a semi-colon in the line?
	JZ	NOCMT		; Yes, abort
	MOV	AL,CS:[CMTCHAR]	; Insert semicolon
	CALL	INSERTKEY	; Insert it
	MOV	AL,CS:[CMTSP]	; Space after semi colon?
	OR	AL,AL		; Force flags
	JZ	NOCMT		; No space
	MOV	AL,' '		; Insert space after semi
	CALL	INSERTKEY	; Insert it
NOCMT:	RET			; Go home
				;
;************************************************************************
;*									*
;*	FINDSEMI:  This routine looks for an existing semi-colon in	*
;*	the current line.  Accepts: Current location in SI.  Returns:	*
;*	Status in ZF.  NZ if nothing, Z if semi-colon found.		*
;*	Also returns location of semi-colon in DI.			*
;*	Calls:	FINDEOL, FINDSTART.  Clobbers: AL,DI,CX.		*
;*									*
;*	FINDSEMI1:  As above, except searches only from the start of	*
;*	the current line to the current location, *NOT* the entire	*
;*	line.								*
;*									*
;************************************************************************
				;
FINDSEMI1:			; Find from start to current
	PUSH	SI		; Save current
	JMP	SHORT BOTHSEMI	; Continue
FINDSEMI:			;
	PUSH	SI		; Save current location
	CALL	FINDEOL		; Find current end of line
BOTHSEMI:			;
	MOV	CX,SI		; Save in cx
	CALL	FINDSTART	; Find start of line
	SUB	CX,SI		; Generate difference in cx
	JCXZ	NOSEMI		; Zero length line, no semi by definition
	INC	CX		; Bugfix, wouldn't see semi if cursor on top!
	MOV	DI,SI		; Put start in di
	MOV	AL,CS:[CMTCHAR]	; Look for a semi-colon
	CMP	CS:[PT],BYTE PTR 00H ; Allow processor technology compatiblity?
	JZ	SKIPPT		; No
	CMP	[SI],BYTE PTR '*' ; Accept star instead in first position...
	JZ	FSE		; For processor technology compatiblity
SKIPPT:	REPNZ	SCASB		; Look away!
	PUSHF			; Save status
	DEC	DI		; Compensate for scas
	POPF			; Restore status
FSE:	POP	SI		; Restore current location
	RET			; Go home
				;
NOSEMI:	XOR	AL,AL		; Generate a zero
	DEC	AL		; Make non-zero
	JMP	SHORT FSE	; Exit
				;
DELWORD:CALL	CHKSTOP		; Look for stop character
	JNZ	DEL1		; Not found, continue
				; Stop character found...
DOMORE:	CALL	DELCHAR		; Delete char
	JC	EXITDEL		; Exit on cr-lf
	MOV	SI,CS:[CURSOR]	; Get cursor position
	CMP	SI,CS:[LASTCHAR] ; End of file?
	JAE	EXITDEL		; Nothing else to check for
	CALL	CHKSTOP		; Check for stop character
	JNZ	EXITDEL		; Non-stop exits...
	JMP	SHORT DOMORE	; Go again
				;
DEL1:				; Delete non-stop chars...
	CALL	DELCHAR		; Delete char
	JC	EXITDEL		; Exit on cr-lf
	MOV	SI,CS:[CURSOR]	; Get cursor position
	CMP	SI,CS:[LASTCHAR] ; End of file?
	JAE	EXITDEL		; Nothing else to check for
	CALL	CHKSTOP		; Check for non-stop
	JNZ	DEL1		; Non-stop found
;	JMP	SHORT DOMORE	;NOW GO DELETE STOP CHARACTERS...
				;
EXITDEL:RET			; We're done
				;
CHKSTOP:MOV	SI,CS:[CURSOR]	; Get cursor position
	LODSB			; Get character
	MOV	CX,000FH	; Stop character table
	MOV	DI,OFFSET STABLE ; Point to stop character table
	PUSH	ES		; Save es
	PUSH	CS		; Get this segment
	POP	ES		; Scasb accepts no segment override...
	REPNZ	SCASB		; Check table for current character
	POP	ES		; Restore orginal
	RET			; Go home
				;
STABLE:	DB	0DH		; Stop on any of these
	DB	':'		;
	DB	';'		;
	DB	','		;
	DB	'.'		;
	DB	' '		; Space
	DB	09H		; Tab
	DB	1AH		; Eof
	DB	'='		;
	DB	'<'		; For html
	DB	'>'		; For html
	DB	'"'		;
	DB	'/'		;
	DB	'\'		;
	DB	'#'		;
				;
;***********************************************************************
; This moves the cursor to the top/bottom of a marked block.
;***********************************************************************
				;
GOEND:	MOV	SI,CS:[MARKEND]	; Get end of block
	JMP	SHORT GOCOMM	; Do common code
				;
GOBEG:	MOV	SI,CS:[MRKSTRT]	; Get beginning of block
GOCOMM:	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	HIDDEN		; Must be turned off
	CALL	MOVE		; Go there
HIDDEN:	RET			; Go home
				;
PRNNUMB:MOV	SI,OFFSET PRNMESS ; Point to string
	MOV	DX,OFFSET FILENAME ; Use same buffer as load block
	CALL	BOTHGET		; Go get string
	JC	EXITJL		; Aborted
	MOV	DX,OFFSET FILENAME+0002H ; Get beginning of buffer data
	MOV	CL,CS:[NAMELEN]	; Get length of returned string
	XOR	CH,CH		; Zero upper
	JCXZ	EXITJL		; Nothing entered
	CALL	BINNUMB		; Convert to binary
	JC	PRNNUMB		; Garbage entered, ignore
	DEC	AX		; Compensate 1-3 into 0-2
	CMP	AL,02H		; Make sure printer number is valid
	JA	PRNNUMB		; Ask again...
				;
	CMP	AL,CS:[OLDPRN]	; Original?
	JZ	ORIG		; Yes
	MOV	CS:[USEHP],BYTE	PTR 00H	; Turn off hp driver
	JMP	SHORT PROMACHOS	; Continue
				;
ORIG:	MOV	AL,CS:[OLDHP]	; Get original hp driver status
	MOV	CS:[USEHP],AL	; And stuff
	MOV	AL,CS:[OLDPRN]	; Since this is the original lpt # anyway...
				; And drop on in...
PROMACHOS:			;
	MOV	CS:[PRNPTR],AL	; Stuff new printer
	JMP	SHORT EXITJL	; Common exit
				;
;***********************************************************************
; This moves the cursor to the indicated line number.
;***********************************************************************
				;
JLINE:	MOV	SI,OFFSET JUMPMESS ; Point to string
	MOV	DX,OFFSET FILENAME ; Use same buffer as load block
	CALL	BOTHGET		; Go get string
	JC	EXITJLF		; Aborted
	MOV	DX,OFFSET FILENAME+0002H ; Get beginning of buffer data
	MOV	CL,CS:[NAMELEN]	; Get length of returned string
	XOR	CH,CH		; Zero upper
	JCXZ	EXITJLF		; Nothing entered
	CALL	BINNUMB		; Convert to binary
	JC	EXITJLF		; Garbage entered, ignore
	MOV	CX,AX		; Into cx
	JCXZ	TOP		; Go to top
	DEC	CX		; Otherwise compensate down one
	JCXZ	TOP		; Line 1, go to top
	PUSH	CX		; Save count
	CALL	TOP		; Go to top
	POP	CX		; Restore count
	XOR	SI,SI		; Start at top
JLP:	CALL	FINDNEXT	; Find next line
	LOOP	JLP		; Keep on finding...
	CALL	MOVE		; Move there
	JMP	SHORT EXITJL	; And exit
				;
EXITJLF:CALL	CFIX		; Fix old cursor
EXITJL:	CALL	REDOPROMPT	; Redraw prompt
	RET			; Go home
				;
;************************************************************************
;*	This moves the cursor to the "previous" location		*
;************************************************************************
				;
GOPREV:	MOV	SI,CS:[OLDPREV]	; Get previous location
	CALL	MOVE		; Go there
	RET			; Go home
				;
;************************************************************************
;*									*
;*	BINNUMB:  This routine converts an ASCII decimal string to a	*
;*	16 bit unsigned binary equivilant.  Accepts:  DX string 	*
;*	pointer, CX, string length.  Returns:  AX holds the number if	*
;*	CF is 0.  Clobbers:  AX.					*
;*									*
;************************************************************************
				;
BINNUMB:PUSH	CX		; Save cx
	PUSH	DX		; And dx
	PUSH	SI		; And si
	PUSH	DS		; Save ds
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	CMP	CX,0005H	; String too long?
	JA	INVALID		; Too long, exit
	MOV	SI,DX		; String pointer to si
	SUB	DX,DX		; Dx will accumulate the result
NXTCHR:	CALL	DXTIMES10	; Multiply total by 10
	JC	INVALID		; Too big, garbage input, etc.
	LODSB			; Get next char
	CMP	AL,'0'		; Between 0 and 9?
	JB	INVALID		; Garbage input, abort
	CMP	AL,'9'		; Check other end
	JA	INVALID		; Garbage input, abort
	AND	AX,000FH	; Convert to binary, zeroing ah also
	ADD	DX,AX		; Add to total
	JC	INVALID		; Too much, abort
	LOOP	NXTCHR		; Do all
				;
	MOV	AX,DX		; Move result to ax
	JMP	SHORT BINEXIT	; Terminate routine
INVALID:STC			; Indicate error
BINEXIT:POP	DS		; Restore everything
	POP	SI		;
	POP	DX		;
	POP	CX		;
	RET			; Go home
				;
DXTIMES10:			; Multiply dx by 10
	PUSH	AX		; Save ax
	MOV	AX,DX		; Remember current value
	SHL	DX,2		; Multiply by 4
	ADD	DX,AX		; Add in original for mult by 5
	SHL	DX,1		; Multiply by 2 for x10
	POP	AX		; Restore ax
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor to the top of the file.
;***********************************************************************
				;
TOP:	XOR	AX,AX		; Get a zero into ax
	MOV	CS:[CURSOR],AX	; Cursor to start of file
	MOV	CS:[SCREENTOP],AX ; Set top of screen
	MOV	CS:[LEFTMARGIN],AL ; Move to far left margin
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
	MOV	CS:[CURPOSN],AX	; Home the cursor
	MOV	CS:[SAVECOLUMN],AL ; Save the cursor column
	MOV	CS:[INDENT],AL	; Reset indent flag
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor to the bottom of the file
;***********************************************************************
				;
BOTTOM:	MOV	DH,CS:[ROWS]	; Get screen size
	MOV	SI,CS:[LASTCHAR] ; Point to last character
	CALL	LOCATE		; Adjust the screen position
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; This will redraw the screen
	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
	RET			; Go home
				;
;***********************************************************************
; This deletes from the cursor position to the end of line.
;***********************************************************************
				;
DELEOL:	CALL	CHKMARK		; Inside marked area?
	JC	DONTDEL		; Don't do it
	PUSH	CS:WORD	PTR [CURSOR] ; Save starting cursor location
	CALL	ENDD		; Move the the end of line
	POP	SI		; Get back starting cursor
	MOV	CX,CS:[CURSOR]	; Offset of the end of line
	MOV	CS:[CURSOR],SI	; Restore starting cursor
	JMP	DELEND		; Delete characters to end
DONTDEL:RET			; Go home
				;
;***********************************************************************
; This deletes a line, placing it in the line buffer.
;***********************************************************************
				;
DELL:	CALL	DELL1		; Dump line...
	CALL	HOME1		; Cursor go beginning of line...
	RET			; Go home
				;
DELL1:	CALL	CHKMARK		; Inside marked area?
	JC	DONTDEL		; Don't do it
				;
	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
	MOV	CS:AL,[INSOFF]	; Configured to turn off insert on cr?
	OR	AL,AL		; Force flags
	JZ	DUMMY		; No, skip
	MOV	CS:[INSMODE],BYTE PTR 00H ; Turn off insert on line delete too
				;
DUMMY:	CALL	FINDSTART	; Find start of this line
	MOV	CS:[CURSOR],SI	; This will be the new cursor
	PUSH	SI		; Save the cursor position
	CALL	FINDNEXT	; Find the next line
	MOV	CX,SI		; Cx will hold line length
	POP	SI		; Get back new cursor location
DELEND:	SUB	CX,SI		; Number of bytes on line
	MOV	AX,CX		; Number to dump in ax
	CALL	FIXDEL		; Compensate
	OR	CH,CH		; Is line too long to fit?
	JZ	NOTTOOLONG	; No
	MOV	CX,100H		; Only save 256 characters
NOTTOOLONG:			;
	MOV	CS:[LINELEN],CX	; Store length of deleted line
	JCXZ	NODELL		; Zero length, can't delete
	MOV	DI,OFFSET LINEBUF ; Buffer for deleted line
	PUSH	CX		; Save length
	PUSH	ES		; Save file buffer segment
	PUSH	CS		; Get this segment
	POP	ES		; Line buffer is in cseg
	REP	MOVSB		; Put deleted line in buffer
	POP	ES		; Get back file segment
	POP	AX		; And length (pushed as cx)
				;
	MOV	CX,CS:[LASTCHAR] ; Get the file size
	SUB	CS:[LASTCHAR],AX ; Subtract the deleted line
	MOV	SI,CS:[CURSOR]	; Get new cursor location
	MOV	DI,SI		; Into di
	ADD	SI,AX		; Si points to end of file
	SUB	CX,SI		; Length of remaining file
	JCXZ	NODELL		; Nothing...
	REP	MOVSB		; Shift remainder of file up
NODELL:				;
	MOV	DX,CS:[CURPOSN]	; Get cursor row/column
	MOV	SI,CS:[CURSOR]	; Get cursor offset
	CALL	LOCATE		; Adjust the screen position
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	RET			; Go home
				;
;***********************************************************************
; This undeletes a line by copying it from the line buffer into the file
;***********************************************************************
				;
UDELL:	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
	MOV	AX,CS:[LINELEN]	; Length of deleted line
	MOV	SI,OFFSET LINEBUF ; Point to line buffer
	CALL	INSERTSTRING	; And insert it
	RET			; Go home
				;
;***********************************************************************
; These routines move the cursor left and right.
;***********************************************************************
				;
LEFT:	CMP	CS:[CURSOR],WORD PTR 0 ; At start of file?
	STC			; Set no can move just incase...
	JZ	LRNOCHANGE	; Then can't move left
	MOV	DX,CS:[CURPOSN]	; Get current cursor position
	OR	DL,DL		; At first column?
	JZ	COTTAGE		; If yes, then move up one
	DEC	WORD PTR CS:[CURSOR] ; Shift the cursor offset
LRRETURN:			;
	CALL	CURSORCOL	; Compute column for cursor
	MOV	CS:[SAVECOLUMN],DL ; Save the cursor column
	OR	DL,DL		; Now at first column?
	JNZ	PODI		; No
	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
	JMP	SHORT PODI	; And exit
LRNOCHANGE:			;
	STC			; Set carry to indicate "NO CAN DO"
	RET			; Go home
				;
COTTAGE:CMP	CS:[LEFTMARGIN], BYTE PTR 0 ; Check for shifted display...
	JZ	MOVEUP		; No, move up...
	CALL	SHLEFT		; Yes, shift over
	JMP	SHORT LEFT	; Recurse routine
				;
MOVEUP:	CALL	UP		; Move up to next row
	CALL	ENDD		; And move to end of line
	CALL	DOCAPS		; Take care of caps lock
PODI:	CLC			; Normal exit
	RET			; Go home
				;
RIGHT:	MOV	SI,CS:[CURSOR]	; Get current location
	CMP	SI,CS:[LASTCHAR] ; At end of file?
	JE	LRNOCHANGE	; If yes, then can't move
	CMP	BYTE PTR [SI],CR ; At end of line?
	JE	MOVEDOWN	; If yes, then move down
				;
	MOV	DX,CS:[CURPOSN]	; Get current cursor position
	ADD	DL,02H		; Move a bit before we get there...
	CMP	DL,CS:[COLUMNSB] ; At right edge of screen?
	JAE	XOPOS		; Yes
				;
	INC	WORD PTR CS:[CURSOR] ; Advance the cursor
	JMP	SHORT LRRETURN	; Exit
				;
XOPOS:	CMP	CS:[LEFTMARGIN],BYTE PTR (255-8) ; Are we maxed out?
	STC			; Set error in case of...
	JAE	LRNOCHANGE	; Error exit
				;
	CALL	SHRIGHT		; Shift display
	JMP	SHORT RIGHT	; Recurse routine
				;
MOVEDOWN:			;
	CALL	HOME1		; Move to start of line
	CALL	DOWN		; And move down one row
	CALL	DOCAPS		; Take care of caps
	CLC			; Normal exit
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor to the start of the current line.
;***********************************************************************
				;
HOME:	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
HOME1:	CALL	FINDSTART	; Find start of line
	MOV	CS:[CURSOR],SI	; Save the new cursor
	XOR	AL,AL		; A zero
	MOV	CS:[LEFTMARGIN],AL ; Move to far left margin
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
	MOV	CS:[SAVECOLUMN],AL ; Zero the cursor column
				; Yes, the following *is* byte, not word
	MOV	CS:[CURPOSN], AL ; Zero column number
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor to the end of the current line
;***********************************************************************
				;
GOEOL:	CALL	ENDD		; Move file cursor
	RET			; Go home
				;
ENDD:	MOV	SI,CS:[CURSOR]	; Get current location
	CALL	FINDEOL		; Find end of this line
	MOV	CS:[CURSOR],SI	; Store the new cursor
	CALL	CURSORCOL	; Compute the correct column
	MOV	CS:[SAVECOLUMN],DL ; Save the cursor column
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor up one row.  If the cursor is at the first row,
; the screen is scrolled down.
;***********************************************************************
				;
UP:	MOV	DX,CS:[CURPOSN]	; Get current cursor postion
	MOV	SI,CS:[CURSOR]	; Get file position
	OR	DH,DH		; At top row already?
	JZ	SCREENDN	; If yes, then scroll down
	DEC	DH		; Move cursor up one row
	CALL	FINDCR		; Find the beginning of this row
	MOV	CS:[CURSOR],SI	; Get position
	CALL	FINDSTART	; Find start of this row
	MOV	CS:[CURSOR],SI	; Get position
	CALL	SHIFTRIGHT	; Skip over to current column
ATTOP:	RET			; Go home
				;
CNTRLW:	CALL	SCREENDN	; Move screen
	MOV	CS:DX,[CURPOSN]	; Get cursor
	CMP	CS:DH,[ROWS]	; Bottom row?
	JZ	SKIPW		; Yes, don't compensate
	CALL	DOWN		; Keep cursor in same place
	RET			; Go home
SKIPW:	CALL	CURSORCOL	; Fix cursor
	RET			; Go home
				;
SCREENDN:			;
	MOV	SI,CS:[SCREENTOP] ; Get screen top location
	OR	SI,SI		; At start of file?
	JZ	ATTOP		; If at top, then do nothing
	CALL	FINDPREVIOUS	; Find the preceeding line
	MOV	CS:[SCREENTOP],SI ; Save new top of screen
	MOV	SI,CS:[CURSOR]	; Get current location
	CALL	FINDPREVIOUS	; Find the preceeding line
	MOV	CS:[CURSOR],SI	; This is the new cursor
SHIFTRET:			;
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Need to redraw screen
	MOV	SI,CS:[CURSOR]	; Get current location
	MOV	DX,CS:[CURPOSN]	; And cursor position
	CALL	SHIFTRIGHT	; Move cursor to current column
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor down one row.  When the last row is reached,
; the screen is shifted up one row.
;***********************************************************************
				;
DOWN:	MOV	DX,CS:[CURPOSN]	; Get cursor position
	CMP	DH,CS:[ROWS]	; At bottom row already?
	MOV	SI,CS:[CURSOR]	; Get position in file
	JE	SCREENUP	; If at bottom, then scroll up
	CALL	FINDNEXT	; Find the start of next line
	JC	DOWNRET		; If no more lines, then return
	MOV	CS:[CURSOR],SI	; Get position in file
	INC	DH		; Advance cursor to next row
	CALL	SHIFTRIGHT	; Move cursor to current column
DOWNRET:RET			; Go home
				;
CNTRLZ:	MOV	SI,CS:[CURSOR]	; Get postion in file
	CALL	SCREENUP	; Move it
	MOV	CS:DX,[CURPOSN]	; Get cursor
	OR	DH,DH		; At top?
	JZ	SKIPZ		; Yes, don't compensate
	MOV	CS:[CURSOR],SI	; This is the new cursor
	CALL	UP		; Keep cursor in same place
	RET			; Go home
SKIPZ:	CALL	CURSORCOL	; Fix cursor
	RET			; Go home
				;
SCREENUP:			;
	CMP	SI,CS:[LASTCHAR] ; Get cursor offset
	JE	DOWNRET		; At end of file
	CALL	FINDSTART	; Find the start of this line
	MOV	CS:[CURSOR],SI	; This is the new cursor
	CALL	FINDNEXT	; Find the offset of next line
	JC	SHIFTRET	; If no more lines then return
	MOV	CS:[CURSOR],SI	; This is the new cursor
	MOV	SI,CS:[SCREENTOP] ; Get the start of the top row
	CALL	FINDNEXT	; And find the next line
	MOV	CS:[SCREENTOP],SI ; Store the new top of screen
	JMP	SHIFTRET	; Do common code...
				;
;***********************************************************************
; These two routines move the screen one page at a time by calling the
; SCREENUP and SCREENDN Routines.
;***********************************************************************
				;
PGDN:	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
	CALL	CSAVE		; Save cursor
	MOV	CL,CS:[ROWS]	; Get length of the screen
	SUB	CL,2		; Don't page a full screen
	XOR	CH,CH		; Make it a word
PAGELOOP:			;
	PUSH	CX		; Save it
	CALL	SCREENUP	; Move one line
	POP	CX		; Restore it
	LOOP	PAGELOOP	; Loop for one page length
	RET			;
				;
PGUP:	MOV	CS:[INDENT],BYTE PTR 00H ; Reset indent flag
	CALL	CSAVE		; Save cursor
	CMP	CS:WORD	PTR [SCREENTOP],0000H ; Did we reach the top?
	JNZ	ATHENA		; No
	CALL	TSCREEN		; Move cursor to top of screen
	RET			; And call it a day
				;
ATHENA:	MOV	CL,CS:[ROWS]	; Get length of the screen
	SUB	CL,2		; Don't page a full screen
	XOR	CH,CH		; Make it a word
PGELOOP:			;
	PUSH	CX		; Save it
	CALL	SCREENDN	; Move up one line
	POP	CX		; Restore it
	LOOP	PGELOOP		; Loop for one page length
	RET			;
				;
;***********************************************************************
; This toggles the insert/overstrike mode.
;***********************************************************************
				;
INSERT:	NOT	BYTE PTR CS:[INSMODE] ; Toggle the switch
	JMP	REDOPROMPT	; Redraw the insert status
				;
;***********************************************************************
; This deletes the character at the cursor by shifting the remaining
; characters forward.
;***********************************************************************
				;
DELCHAR:CALL	CHKMARK		; Trying this inside a marked area?
	JC	NODEL		; Yes, don't allow
	MOV	CX,CS:[LASTCHAR] ; Get last character (count)
	MOV	SI,CS:[CURSOR]	; Get current location
	MOV	DI,SI		; Into di
	CMP	SI,CX		; Are we at end of file?
	JAE	NODEL		; If yes, then don't delete
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	MOV	AX,0001H	; Fix by one
	CALL	FIXDEL		; Fix file markers
	LODSB			; Get char
	MOV	AH,[SI]		; Look at the next character also
	PUSH	AX		; Save character were deleting
	DEC	WORD PTR CS:[LASTCHAR] ; Shorten the file by one
	SUB	CX,SI		; Subtract out current location
	REP	MOVSB		; Move file down one notch
				;
	POP	AX		; Get back character we deleted
	CMP	AL,CR		; Did we delete a cr?
	JE	COMBINE		; Yes
	OR	CS:[DIRTYBITS],BYTE PTR	4 ; Current line is dirty
NODEL:	CLC			; Clear carry
	RET			; Go home
				;
COMBINE:CMP	AH,LF		; Was the next character a lf?
	CLC			; No carry if not
	JNE	NODELLF		; No line feed
	CALL	DELCHAR		; Now delete the line feed (recursively!)
	STC			; Say we did it
NODELLF:PUSHF			; Save line feed status
	CALL	DISPLAYBOTTOM	; Repaint bottom of the screen
	MOV	DX,CS:[CURPOSN]	; Get cursor position
	MOV	CS:[SAVECOLUMN],DL ; Save the cursor column
	POPF			; Restore line feed status
	RET			; Go home
				;
;***********************************************************************
; This fixes position markers 0-9 to compensate for deleted characters
;***********************************************************************
				;
FIXDEL:	PUSHA			; Save registers
	MOV	DL,0FFH		; Flag deletion
	JMP	SHORT FIXBOTH	; Continue
				;
;***********************************************************************
; This fixes position markers 0-9 to compensate for inserted characters
;***********************************************************************
				;
FIXINS:	PUSHA			; Save registers
	XOR	DL,DL		; Flag insertion
FIXBOTH:MOV	BX,AX		; Save number of places to insert
	MOV	DI,CS:[CURSOR]	; Get current location
	MOV	SI,OFFSET MARK0	; Point to first marker location
	MOV	CX,10D+3D+1D+2D	; 10 markers + 3 block markers. + 1 extra + 2 old curors
FIXLP1:	MOV	CS:AX,[SI]	; Get marker
	OR	AX,AX		; Force flags
	JZ	NOFIX1		; Beginning of file or un-used
	CMP	AX,DI		; Compare with current location
	JBE	NOFIX1		; Insertion/deletion is on or after marked loc
	OR	DL,DL		; Force flags
	JZ	FIX1		; Insertion, add marker
				;
	SUB	AX,BX		; Deletion, subtract marker
	JMP	SHORT NOFIX1	; And continue
				;
FIX1:	ADD	AX,BX		; Compensate marker
NOFIX1:	MOV	CS:[SI],AX	; Stash back
	ADD	SI,0002H	; No lods, stos, etc, inc si
	LOOP	FIXLP1		; Check all of them
	POPA			; Restore registers
	RET			; Go home
				;
;************************************************************************
; This simply hides any marked text (or unhides)			*
;************************************************************************
				;
HIDE:	NOT	CS:BYTE	PTR [DOMARK] ; Toggle flag
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Refresh the whole screen
	CMP	CS:BYTE	PTR [DOMARK],00H ; Is it on now?
	JZ	HIDE1		; No
	CALL	RECUT		; Re-copy everything into paste buffer
HIDE1:	RET			; Go home
				;
;************************************************************************
; This turns on the mark state, thus defining the beginning of the block*
;************************************************************************
				;
MARK:	MOV	CS:[MARKMODE],BYTE PTR 0FFH ; Turn on
	MOV	AX,CS:[CURSOR]	; Get the cursor offset
	MOV	CS:[MRKSTRT],AX	; Start of marked range
	MOV	CS:[DOMARK],BYTE PTR 0FFH ; Flag something there...
	MOV	CS:[MARKEND],  AX ; End of marked range
	MOV	CS:[MRKHOME], AX ; Center of marked range
	RET			; Go home
				;
;***********************************************************************
; This defines the block end, and places it in the paste buffer
;***********************************************************************
				;
CUT:	CMP	CS:[MARKMODE],BYTE PTR 0 ; Is the mark mode on?
	JE	NOMARK		; If not, then do nothing
RECUT:	MOV	CX,CS:[MARKEND]	; Get end of mark region
	MOV	SI,CS:[MRKSTRT]	; Get start of mark region
	SUB	CX,SI		; Number of bytes selected
	MOV	CS:[PASTESIZE],CX ; Save size
	JCXZ	NOMARK		; Nothing to do
	XOR	DI,DI		; Point to paste bufferf
	PUSH	CX		; Save size
	PUSH	ES		; Save file segment
	MOV	ES,CS:[PASTESEG] ; Get the paste segment
	REP	MOVSB		; Put deleted text in buffer
	POP	ES		; Restore file segment
	POP	AX		; And size (pushed as cx)
	MOV	CS:[MARKMODE], BYTE PTR	00H ; Turn off marking
	RET			; Go home
				;
;***********************************************************************
; This deletes any marked text, if not hidden...
;***********************************************************************
				;
BLKDEL:	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	NOMARK		; Must be turned off
				;
	MOV	AX,CS:[PASTESIZE] ; Get size of marked block
	MOV	CX,CS:[LASTCHAR] ; Get last
	SUB	CS:[LASTCHAR],AX ; Shorten the file this much
	MOV	DI,CS:[MRKSTRT]	; Start of marking
	MOV	SI,CS:[MARKEND]	; End of marking
	SUB	CX,SI		; This far from end
	JCXZ	NODELETE	; Nothing
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	REP	MOVSB		; Shorten the file
	CALL	FIXDEL		; Fix it
NODELETE:			;
	MOV	DX,CS:[CURPOSN]	; Get current cursor position
	MOV	SI,CS:[MRKSTRT]	; And start of marked text
	CALL	LOCATE		; Adjust the screen position
	XOR	AX,AX		; Zeros
	MOV	CS:[DOMARK],AL	; Nothing left
	MOV	CS:[MRKSTRT],AX	; Zero start
	MOV	CS:[MARKEND],AX	; And end
	MOV	CS:[PASTESIZE],AX ; Nothing to paste either...
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Refresh the whole screen
NOMARK:	RET			; Go home
				;
;***********************************************************************
; This copies the paste buffer into the file at the cursor location
;***********************************************************************
				;
PASTE:	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	NOMARK		; Must be turned off
				;
	MOV	AX,CS:[PASTESIZE] ; Number of characters in buffer
	OR	AX,AX		; Any there?
	JZ	NOPASTE		; If not, nothing to paste
	MOV	SI,CS:[CURSOR]	; Get cursor location
	PUSH	AX		; Save size
	PUSH	SI		; And location
	CALL	OPENSPACE	; Make room for new characters
	POP	DI		; Get location (pushed as si)
	POP	CX		; Get size (pushed as ax)
	JC	NOPASTE		; If no room, just exit
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	XOR	SI,SI		; Point to paste buffer
	PUSH	DS		; Save file segment
	MOV	DS,CS:[PASTESEG] ; Segment of paste buffer
	REP	MOVSB		; Copy in the new characters
	POP	DS		; Recover file segment
	MOV	SI,DI		; Location into si
	MOV	CS:[CURSOR],SI	; Cursor moved to end of insert
	MOV	DX,CS:[CURPOSN]	; Get current cursor row
	CALL	LOCATE		; Adjust the screen position
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
NOPASTE:RET			; Go home
				;
BLKMOV:	MOV	SI,CS:[CURSOR]	; Get current location
	MOV	CS:[MARKA],SI	; Remember, but compensate
	MOV	DX,CS:[CURPOSN]	; Get current cursor row
	PUSH	DX		; And save
	CALL	PASTE		; Copy block into current locatidn
	CALL	BLKDEL		; Delete block
	POP	DX		; Restore cursor row
	MOV	SI,CS:[MARKA]	; Get back compensated location
	MOV	CS:[CURSOR],SI	; Put location back
	CALL	LOCATE		; Adjust screen
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
	RET			; Go home
				;
;***********************************************************************
; This inserts AX characters from CS:SI into the file.
;***********************************************************************
				;
INSERTSTRING:			;
	PUSH	SI		; Save string buffer
	MOV	SI,CS:[CURSOR]	; Get cursor offset
	PUSH	AX		; Save length of string
	PUSH	SI		; Save current
	CALL	OPENSPACE	; Make space to insert string
	POP	DI		; Get back cursor position (pushed as si)
	POP	CX		; Get back string length (pushed as ax)
	POP	SI		; Get back string buffer
	JC	NOSPACE		; If no space available, exit
				;
	PUSH	DS		; Save file segment
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	REP	MOVSB		; Copy the characters in
	MOV	SI,CS:[CURSOR]	; Get the new cursor offset
	MOV	DX,CS:[CURPOSN]	; Also get the current row
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; And redraw the screen
	POP	DS		; Restore
	CALL	LOCATE		; Adjust the screen position
	CLC			; Say we did it
NOSPACE:RET			; Go home
				;
;***********************************************************************
; This prompts for a verify keystroke then exits without saving the file
;***********************************************************************
				;
ABORT:	PUSH	CS		; Get current segment
	POP	DS		; Into ds
	MOV	AL,CS:[CHANGE]	; Get file change status
	OR	AL,AL		; Force flags
	JZ	FINISHED	; No change, don't bother asking
				;
	XOR	DL,DL		; First column
	MOV	SI,OFFSET VERIFYMESS ;
	CALL	PRTLST		; Display verify message
				;
MARTIN:	CALL	CONSTAT		; Check for next key...
	JNZ	THALASSA	; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	MARTIN		; No
	CALL	BEEP2		; Make noise
	JMP	SHORT NOWAY	; Guy is asleep at the switch...
				;
THALASSA:			;
	CALL	GETCH		; Get next key
	AND	AL,5FH		; Convert to upper case
	CMP	AL,'Y'		; Was answer yes?
	JE	CUMMINS		; If yes, then we're finished
NOWAY:	PUSH	ES		; Get file segment
	POP	DS		; Set ds back to file segment
	CALL	REDOPROMPT	; If not, redraw the prompt
	RET			; Go home
				;
CUMMINS:MOV	SI,OFFSET DOTTMP ; Point to the '.$$$'
	MOV	DI,OFFSET TMPNAME ; Point to the actual filename storage...
	CALL	CHGEXTENSION	; Add the new extension
				;
	MOV	DX,OFFSET TMPNAME ; Point to the temp filename
	MOV	AH,41H		; Function to delete file
	INT	21H		; Delete auto-saved file
				;
FINISHED:			;
	MOV	DH,CS:[ROWS]	; Move to last row on screen
	XOR	DL,DL		; And column zero
	CALL	SETCURSOR	; Position it
	INC	DH		; Next row
	CALL	ERASEEOL	; Erase the last row
	PUSH	CS		; Get this segment
	POP	DS		; Point to code segment
	CALL	CLS		; Clear screen for larry alm
				;
FINIS:	CALL	PRTCOPY		; Print signoff message
	MOV	DS,CS:[OLDSEG]	; Get old tic segment vector
	MOV	DX,CS:[OLDVEC]	; Get old tic offset vector
	MOV	AX,2508H	; Now change int 08 vector back to original
	INT	21H		; Go setup our vector
				;
	MOV	DS,CS:[OLDSEGF]	; Get old keyboard segment vector
	MOV	DX,CS:[OLDVECF]	; Get old keyboard offset vector
	MOV	AX,2515H	; Now change int 15 vector back to original
	INT	21H		; Go setup our vector
				;
	MOV	AX,0040H	; Lets diddle some keyboard bits as we exit
	MOV	DS,AX		; Into ds
	MOV	AL,DS:[0017H]	; Get keyboard status
	AND	AL,0FBH		; Tell computer that no-one is holding down
				; The control key even if the program was
				; Exited in this state.  switching keys
				; Meanings when they're depressed creates
				; Problems...
	MOV	DS:[0017H],AL	; Put back
				;
	MOV	AX,4C00H	; Terminate w/no errors
	INT	21H		; Bye-bye...
				;
PRTCOPY:CMP	CS:[FORM7],BYTE	PTR 00H	; Form7 filter on?
	JZ	DOUMBEK		; No, skip
	CALL	SETCAPS		; Turn on caps lock
				;
DOUMBEK:MOV	DX,OFFSET COPYRIGHT ; Point to message
	CALL	PSTRING		; Print it
	CALL	HEXCONV		; Print generation counter
				;
	MOV	AH,2CH		; Get time function
	INT	21H		; Go get it
	OR	DL,DL		; Force flags for hundreths of seconds
	JPO	SKIP		; Don't display
	MOV	DX,OFFSET MINERVA ; Point to dedication
	CALL	PSTRING		; Print it
SKIP:	MOV	DX,OFFSET LASTCPR ; Point to the rest of the copyright message
	CALL	PSTRING		; Print it
	RET			; Go home
				;
INHIBIT:MOV	AL,CS:[DOAUTO]	; Get auto-mode permission
	MOV	CS:[TEMP2],AL	; Stash
	MOV	CS:[DOAUTO],BYTE PTR 00H ; Turn off auto-mode
	RET			; Go home

;***********************************************************************
; This prompts for a filename then writes the file.  The original file
; is renamed to FILENAME.BAC.  If an invalid filename is entered, the
; speaker is beeped.
;***********************************************************************
				;
SAVE:	MOV	CS:[SAVEFLG],BYTE PTR 0FFH ; Flag save operation
	MOV	SI,CS:[CURSOR]	; Get current location
	MOV	CS:[MARKA],SI	; And save incase of abort
	JMP	SHORT EXIT1	; Skip tab stripper
				;
EXIT:	MOV	SI,CS:[CURSOR]	; Get current location
	MOV	CS:[MARKA],SI	; And save incase of abort
				;
EXIT2:	CALL	BOTTOM		; Move to bottom of file
	CALL	LEFT		; Then backup one
	MOV	SI,CS:[CURSOR]	; Get this location
	OR	SI,SI		; Force flags
	JZ	EXIT1		; Start of file, forget it...
				;
				; Check for trailing tabs/spaces in file
	CMP	ES:[SI],BYTE PTR 09H ; Trailing tab?
	JZ	DUMPIT		; Yes
	CMP	ES:[SI],BYTE PTR ' ' ; Trailing space?
	JZ	DUMPIT		; Yes
				; Make sure file ends with crlf
	CMP	ES:[SI],BYTE PTR 0DH ; Carriage return? (left skips lf)
	JZ	EXIT1		; Yes, no fixups needed
	CALL	RIGHT		; Don't insert before last character...
	MOV	AL,CR		; Insert cr
	CALL	INSERTCHAR	; Do it
	CALL	BOTTOM		; Compensate 4 insertchar's faulty cr handling
	MOV	AL,LF		; Then do lf
	CALL	INSERTCHAR	; Do it
	JMP	SHORT EXIT1	; No, continue
				;
DUMPIT:	CALL	DELCHAR		; Dump the offending character
	JMP	SHORT EXIT2	; And try again...
				;
EXIT1:	MOV	AX,ES		; Get buffer segment
	MOV	CS:[TEMP],AX	; Save buffer segment
	CALL	INHIBIT		; Inhibit (further) auto-save
	PUSH	DS		; Save buffer segment
	PUSH	ES		; In both
	MOV	AX,CS		; Reload
	MOV	DS,AX		; With
	MOV	ES,AX		; Cs
	CMP	CS:[AUTO],BYTE PTR 00H ; Auto save in progress?
	JZ	NEXTLETTER	; No
	JMP	GOTNAME		; Yes, skip this
NEXTLETTER:			;
	XOR	DL,DL		; First column
	MOV	SI,OFFSET SAVEMESS ; Point to save as: message
	PUSH	DX		; Tty clobbers dx
	CALL	PRTLST		; Display a prompt
	POP	DX		; Get back dx
	ADD	DL,9		; Move right 9 spaces (length of save as:)
	MOV	SI,CS:[NAMEPTR]	; Print current name, if any
	CALL	PRTLST		; Display the filename
				;
CYPRESS:CALL	CONSTAT		; Check for next key...
	JNZ	SEA		; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	CYPRESS		; No
	CALL	BEEP2		; Make noise
	JMP	SHORT PLOVER	; Guy is asleep at the switch...
				;
SEA:	CALL	GETCH1		; Get key
	MOV	DI,CS:[NAMEEND]	; This points to last letter
	OR	AL,AL		; Is it a real character?
	JZ	NEXTLETTER	; Ignore special keys
	CMP	AL,27		; Is it escape?
	JNE	NOTESCAPE	; No
				;
;************************************************************************
;*									*
;*	ESCAPE entered or auto-save aborted because of bad filename!	*
;*									*
;************************************************************************
				;
PLOVER:	POP	ES		; Get back file segments
	POP	DS		; Both...
	MOV	SI,CS:[MARKA]	; Get back our location
	CALL	MOVE		; Move there
	JMP	SAVERET1	; Redraw the prompt, fixup, and exit
NOTESCAPE:			;
	CMP	AL,15H		; Control-u?
	JZ	PLOVER		; Accept as escape - exit
				;
	CMP	AL,13		; Is it cr?
	JE	GOTNAME		; Yes
	CMP	AL,18H		; Control-x?
	JNE	SPOLE		; No
CNTRLXLP:			;
	CMP	DI,CS:[NAMEPTR]	; At first letter?
	JLE	NEXTLETTER	; Nothing to do
	DEC	DI		; Backup
	MOV	[DI],BYTE PTR 00H ; Move termination backsards
	DEC	WORD PTR CS:[NAMEEND] ; Shorten name
	JMP	SHORT CNTRLXLP	; Do until gone
				;
SPOLE:	CMP	AL,08H		; Is it a backspace?
	JNE	NORMALLETTER	; No
	CMP	DI,CS:[NAMEPTR]	; At first letter?
	JLE	NEXTLETTER	; If yes, dont erase it
	DEC	DI		; Backup
	MOV	[DI],BYTE PTR 00H ; Move termination backsards
	DEC	WORD PTR CS:[NAMEEND] ; And shorten it
	JMP	NEXTLETTER	; Get another
NORMALLETTER:			;
	CMP	DI,81H + 65	; Too many letters?
	JA	NEXTLETTER	; If yes, ignore them
	XOR	AH,AH		; A zero to terminate
	STOSW			; Store the letter (with auto 00 terminator)
	INC	WORD PTR CS:[NAMEEND] ; Name is one character longer
	JMP	NEXTLETTER	; Read another keystroke
GOTNAME:			;
	CMP	CS:[AUTO],BYTE PTR 00H ; Auto save in progress?
	JZ	GOTNAME1	; No, skip this
	XOR	DL,DL		; First column
	MOV	SI,OFFSET AUTOMESS ; Point to auto save message
	CALL	PRTLST		; Display a prompt
				;
GOTNAME1:			;
	MOV	DX,CS:[NAMEPTR]	; Point to the filename
	MOV	AX,4300H	; Get the files attribute
	INT	21H		; Call mush-dos
	JNC	NAMEOK		; If no error, filename is ok
	CMP	AX,3		; Was it path not found error?
	JE	BADNAME		; If yes, filename was bad
NAMEOK:				;
	MOV	SI,OFFSET DOTTMP ; Point to the '.$$$'
	MOV	DI,OFFSET TMPNAME ; Point to the actual filename storage...
	CALL	CHGEXTENSION	; Add the new extension
				;
	MOV	DX,OFFSET TMPNAME ; Point to the temp filename
	MOV	AH,3CH		; Function to create file
	MOV	CX,0020H	; Attribute for new file
	INT	21H		; Try to create the file
	JNC	NAMEWASOK	; Continue if name was ok
BADNAME:			;
	CMP	CS:[AUTO],BYTE PTR 00H ; Auto save in progress?
	JZ	PLUGH		; No
	JMP	PLOVER		; Yes, skip this
				;
PLUGH:	CALL	BEEP3		; Beep
	JMP	NEXTLETTER	; Get another letter
WRITEERROR:			;
	MOV	AH,3EH		; Close the file
	INT	21H		; Call mush-dos
	JMP	BADNAME		; Filename must be bad
NAMEWASOK:			;
	XOR	DX,DX		; This is the file buffer
	MOV	CX,CS:[LASTCHAR] ; Number of chars in file
	MOV	DI,CX		; Into di
	MOV	BX,AX		; This is the handle
	MOV	AH,40H		; Write to the file
	POP	DS		; Recover buffer segment
	PUSH	DS		; Re-save for stack ballance
	CMP	CX,0FFFFH	; Is buffer already full?
	JE	DONTADDEOF	; If yes, dont add eof mark
	CMP	CS:[DOEOF],BYTE	PTR 00H	; Do eof?
	JZ	DONTADDEOF	; No
	INC	CX		; Plus one character for eof mark
	MOV	BYTE PTR [DI],1AH ; Add the eof marker
DONTADDEOF:			;
	INT	21H		; Write the buffer contents
	JC	WRITEERROR	; Exit on a write error
	CMP	AX,CX		; Was entire file written?
	JNE	WRITEERROR	; If not, exit
	POP	DS		; Fix stack
	POP	DS		; Fix stack
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into the data segment
	MOV	AH,3EH		; Close file function
	INT	21H		; Close the temp file
				;
	CMP	CS:[AUTO],BYTE PTR 00H ; Auto save in progress?
	JZ	PLYMOUTH	; No, proceed normally
				;
	MOV	CS:[CHANGE],BYTE PTR 55H ; Mark auto-saved
	JMP	SHORT SAVERET1	; And leave temp file on disk
				;
PLYMOUTH:			;
	MOV	SI,OFFSET DOTBAK ; Point to the '.bac'
	MOV	DI,OFFSET DOTBAC ; Point to the filename.bac storage
	CALL	CHGEXTENSION	; Make the backup filename
				;
	CMP	CS:[DOBAK],BYTE	PTR 00H	; Do we do backup files?
	JNZ	YESBAK		; Yes
	MOV	DX,CS:[NAMEPTR]	; Point to original
	MOV	AH,41H		; Erase file function
	INT	21H		; Go shitcan it
	JMP	SHORT RENFILE	; Rename temp file to orignal name
				;
YESBAK:	MOV	DX,OFFSET DOTBAC ; Point to the backup name
	MOV	AH,41H		; Erase file function
	INT	21H		; Delete existing backup file
				;
	MOV	DI,OFFSET DOTBAC ; Point to backup file name
	MOV	DX,CS:[NAMEPTR]	; Point to new file name
	MOV	AH,56H		; Rename function
	INT	21H		; Rename filename.typ **> filename.bac
				;
RENFILE:MOV	DI,CS:[NAMEPTR]	; Point to new filename
	MOV	DX,OFFSET TMPNAME ; Point to temporary file
	MOV	AH,56H		; Rename temp to new file
	INT	21H		; Dos function to rename
				;
	CMP	CS:[SAVEFLG],BYTE PTR 00H ; Save mode?
	JNZ	SAVERET		; Yes
	JMP	FINISHED	; No
				;
SAVERET:MOV	CS:[CHANGE],BYTE PTR 00H ; File is un-changed now
SAVERET1:			; Enter here if auto-save didn't work...
	MOV	CS:[SAVEFLG],BYTE PTR 00H ; Turn off save mode
	MOV	CS:[AUTO],BYTE PTR 00H ; Turn off auto-save mode
	MOV	CS:[TICS],WORD PTR 00H ; Zero auto-save tick counter
	MOV	CS:AX,[TEMP]	; Get buffer segment
	MOV	ES,AX		; Into es
	MOV	DS,AX		; And ds
	CALL	REDOPROMPT	; Draw the prompt line
	CALL	DISPLAYSCREEN	; Force screen redraw
	RET			; Go home
				;
;***********************************************************************
; This remembers the old location for the ^QP command...
;***********************************************************************
				;
CSAVE:	PUSH	CS:WORD	PTR [PREV] ; Get old cursor location
	POP	CS:WORD	PTR [OLDPREV] ; And save for fixups
	PUSH	CS:WORD	PTR [CURSOR] ; Save cursor location
	POP	CS:WORD	PTR [PREV] ; And save for ^qp
	RET			; Go home
				;
;***********************************************************************
; And this 'fixes' the above if a given command is aborted before move.
;***********************************************************************
				;
CFIX:	PUSH	CS:WORD	PTR [OLDPREV] ; Get the old previous
	POP	CS:WORD	PTR [PREV] ; And put back to current previous
	RET			; Go home
				;
;***********************************************************************
; This subroutine displays a character by writing directly
; to the screen buffer.  To avoid screen noise (snow) on the color
; card, the horizontal retrace has to be monitored.
;***********************************************************************
				;
WRTINV:	MOV	CS:BH,CS:[NORMAL] ; Attribute for normal video
	ROL	BH,4		; Get into upper nybble
	JMP	SHORT WRTSCRN	; Continue
WRTNORM:MOV	BH,CS:[NORMAL]	; Attribute for normal video
WRTSCRN:AND	BH,7FH		; Mask out intense bit
	MOV	BL,AL		; Save the character
	PUSH	ES		; Save segment
	PUSH	DX		; Save dx
	MOV	DX,CS:[STATREG]	; Retrieve status register
	MOV	ES,CS:[VIDSEG]	; Get segment of video buffer
HWAIT:	IN	AL,DX		; Get video status
	ROR	AL,1		; Look at horizontal retrace
NOSNO:	JNC	HWAIT		; Wait for retrace
	MOV	AX,BX		; Get the character/attribute
	STOSW			; Write the character
	POP	DX		; Restore dx
	POP	ES		; Restore segment
	RET			; Go home
				;
;***********************************************************************
; This moves the cursor to the row/column in DX.
;***********************************************************************
				;
SETCURSOR:			;
	XOR	BH,BH		; We're using page zero
	MOV	AH,2		; Bios set cursor function
	INT	10H		; Video bios
	RET			; Go home
				;
;***********************************************************************
; This computes the video buffer offset for the row/column in DX
;**********************************************************************
				;
POSITION:			;
	MOV	AX,CS:[COLUMNS]	; Take columns per row
	MUL	DH		; Times row number
	XOR	DH,DH		; Clear dh
	ADD	AX,DX		; Add in the column number
	SHL	AX,1		; Times 2 for offset
	MOV	DI,AX		; Return result in di
	RET			; Go home
				;
COMPWORD:			;
	DW	0713AH		; Compensation word.  set to zero, then run non
				; Beta program under debug.  when it terminates
				; With error, <d>ump memory at cs:0100h.  take
				; The first word,poke it in here, and
				; Reassemble.  if it still doesn't
				; Work, byte swap it!!
				;
;***********************************************************************
; This erases from the location in DX to the right edge of the screen
;***********************************************************************
				;
ERASEEOL:			;
	CALL	POSITION	; Find screen offset
	MOV	CX,CS:[COLUMNS]	; Get screen size
	SUB	CL,DL		; Subtract current position
	JCXZ	NOCLEAR		; Nothing
ERASELOOP:			;
	MOV	AL,' '		; Write blanks to erase
	CALL	WRTNORM		; Display it
	LOOP	ERASELOOP	; Do all
NOCLEAR:RET			; Go home
				;
;***********************************************************************
; This displays the function key prompt and insert mode state
;***********************************************************************
				;
REDOPROMPT:			;
	CMP	CS:[STATLN],BYTE PTR 00H ; Do stat line?
	JNZ	REDO1		; Yes, proceed
	CALL	DISPLAYBOTTOM	; Repaint bottom of screen
	RET			; Go home
				;
REDO1:	PUSH	DS		; Save file segment
	PUSH	CS		; Get this one
	POP	DS		; Into ds
	MOV	DH,CS:[ROWS]	; Put prompt at last row
	INC	DH		; Last row on screen
	XOR	DL,DL		; And column 0
	CALL	POSITION	; Convert to screen offset
	PUSH	DS		; Save ds
	MOV	SI,0040H	; Low ram segment
	MOV	DS,SI		; Into ds
	MOV	DS:AL,[0017H]	; Grab keyboard status byte
	POP	DS		; Restore ds
	AND	AL,04H		; Mask out control key
	JZ	NORMPROMPT	; Normal prompt
	MOV	SI,OFFSET CTRLSTRING ; Point to control key menu bar
	JMP	SHORT KEYLOOP	; And continue
				;
NORMPROMPT:			;
	MOV	SI,OFFSET PROMPTSTRING ; Point to menu bar
KEYLOOP:			;
	MOV	AL,'F'		; Display an 'f'
	CALL	WRTNORM		; Do normal video
	LODSB			; Get character
	OR	AL,AL		; Last key in prompt?
	JZ	PROMPTDONE	; Yes
	CALL	WRTNORM		; Write it
				;
	CMP	BYTE PTR CS:[SI],'0' ; Is it f10?
	JNE	TEXTLOOP	; No
	LODSB			; Get next
	CALL	WRTNORM		; Write normal video
TEXTLOOP:			;
	LODSB			; Next
	OR	AL,AL		; Last letter in word?
	JNZ	WRITECHAR	; No
				;
	MOV	AL,' '		; Display a space
	CALL	WRTNORM		; Normal
	JMP	KEYLOOP		; Do all
WRITECHAR:			;
	CALL	WRTINV		; Display the letter
	JMP	TEXTLOOP	; Do the next letter
PROMPTDONE:			;
	LEA	SI,OVR		; Point to overstrike message
	CMP	CS:[INSMODE],BYTE PTR 0	; In insert mode?
	JE	OVERSTRIKE	; No
	LEA	SI,INS		; Point to insert message
OVERSTRIKE:			;
	DEC	DI		; Backup one character position
	DEC	DI		; Including attribute
	MOV	CX,0003H	; Three characters
JKLP:	LODSB			; Get byte
	CALL	WRTNORM		; Write it
	LOOP	JKLP		; Do all 3
	POP	DS		; Get back file segment
	RET			; And go home
				;
INS:				;
	DB	'Ins',00H	; Insert message
OVR:				;
	DB	'Ovr',00H	; Overstrike message
				;
;***********************************************************************
; This displays the file buffer on the screen.
;***********************************************************************
				;
DISPLAYSCREEN:			;
	MOV	SI,CS:[SCREENTOP] ; Point to first char on screen
	XOR	DH,DH		; Start at first row
	JMP	SHORT NEXTROW	; Continue
DISPLAYBOTTOM:			; This redraws the bottom only
	CALL	FINDSTART	; Find first character on this row
	MOV	DX,CS:[CURPOSN]	; Get current cursor row
NEXTROW:PUSH	DX		; Save cursor row
	CALL	DISPLAYLINE	; Display a line
	POP	DX		; Get cursor row back
	INC	DH		; Move to the next row
	CMP	DH,CS:[ROWS]	; At end of screen yet?
	JBE	NEXTROW		; Do all the rows
	RET			; Go home
				;
;***********************************************************************
; This subroutine displays a single line to the screen. DH holds the
; row number, SI has the offset into the file buffer. Tabs are expanded.
; Adjustment is made for side shift.
;***********************************************************************
				;
DISPLAYCURRENT:			;
	CALL	FINDSTART	; Find start of current line
	MOV	DX,CS:[CURPOSN]	; Get cursor position
DISPLAYLINE:			;
	XOR	DL,DL		; Start at column zero
	MOV	CS:[MARGINCOUNT],DL ; Into margin counter
	MOV	CX,DX		; Use cl to count the columns
	CALL	POSITION	; Compute offset into video
NEXTCHAR:			;
	CMP	SI,CS:[LASTCHAR] ; At end of file?
	JAE	LINEDONE	; Yes
	LODSB			; Get next character
	CMP	AL,CR		; Is it a carriage return?
	JE	FOUNDCR		; Quit when a cr is found
	CMP	AL,TAB		; Is this a tab character
	JE	EXPANDTAB	; If yes, expand to spaces
	CALL	PUTCHAR		; Put character onto screen
TABDONE:CMP	CL,CS:[COLUMNSB] ; At right edge of screen?
	JB	NEXTCHAR	; Not yet
	CMP	BYTE PTR [SI],CR ; Is this the end of the line?
	JE	NOTBEYOND	; Yes
	DEC	DI		; Backup one character
	DEC	DI		; Another
	MOV	AL,4		; Show a diamond
	CALL	WRTINV		; In inverse video
NOTBEYOND:			;
	JMP	FINDNEXT	; Find start of next line
FOUNDCR:			;
	LODSB			; Look at the next character
	CMP	AL,LF		; Is it a line feed?
	JE	LINEDONE	; Yes
	DEC	SI		; Backup
LINEDONE:			;
	MOV	DX,CX		; Get position
	JMP	ERASEEOL	; Erase the rest of the line
EXPANDTAB:			;
	MOV	AL,' '		; Convert tabs to spaces
	CALL	PUTCHAR		; Stash
	MOV	AL,CS:[MARGINCOUNT] ; Where are we?
	ADD	AL,CL		; Add in
	TEST	AL,00000111B	; At even multiple of eight?
	JNZ	EXPANDTAB	; If not keep adding spaces
	JMP	TABDONE		; Done
				;
;***********************************************************************
; This displays a single character to the screen.  If the character is
; marked, it is shown in inverse video.  Characters outside the current
; margin are not displayed. Characters left of the margin are skipped.
;***********************************************************************
				;
PUTCHAR:MOV	BL,CS:[MARGINCOUNT] ; Get distance to left margin
	CMP	BL,CS:[LEFTMARGIN] ; Are we inside left margin?
	JAE	INWINDOW	; If yes, show the character
	INC	BL		; If not, increment the count
	MOV	CS:[MARGINCOUNT],BL ; And stash back
	RET			; And go home without showing the character
INWINDOW:			;
	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	NOTMARKED	; Nothing
	CMP	SI,CS:[MRKSTRT]	; Is this character marked?
	JBE	NOTMARKED	; No
	CMP	SI,CS:[MARKEND]	; At end
	JA	NOTMARKED	; No
	CALL	WRTINV		; Marked characters shown inverse
	JMP	SHORT NEXTCOL	; Continue
NOTMARKED:			;
	CALL	WRTNORM		; Write un-marked characters normally
NEXTCOL:			;
	INC	CL		; Increment the column count
	RET			; Go home
				;
;***********************************************************************
; This routine adds a character into the file.	In insert mode, remaining
; characters are pushed forward. If a CR is inserted, a LF is added also.
;***********************************************************************
				;
INSERTKEY:			;
	CALL	GRFILT		; Filter greek
	OR	AL,AL		; Force flags
	JNZ	REGKEY		; Continue
	RET			; We're done
				;
REGKEY:	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	MOV	SI,CS:[CURSOR]	; Get current location
	CMP	CS:[DOCMT],BYTE	PTR 00H	; Auto comment even on?
	JZ	NORM		; No
	CMP	CS:[CMTSP],BYTE	PTR 00H	; Do we do spaces here?
	JZ	NORM		; No, don't bother...
	CMP	AL,' '		; Is the new character a space?
	JZ	NORM		; Yes, allow
	CMP	AL,09H		; Is the new character a tab?
	JZ	NORM		; Yes, allow
	CMP	AL,'*'		; Is it a *
	JZ	NORM		; Yes, allow
	PUSH	AX		; Save current character
	CALL	FINDSEMI1	; See if semi in this line up to here...
	JNZ	SKIPS		; Nothing
	INC	DI		; Compensate semi location
	CMP	SI,DI		; Same?
	JNZ	SKIPS		; No, somewhere else...
	MOV	AL,' '		; Put a space in
	CALL	INSERTKEY	; Insert it recursively
SKIPS:	POP	AX		; Restore orginal character
				; And drop on through...
NORM:	CMP	CS:[INSMODE],BYTE PTR 0	; In insert mode?
	JNE	INSERTCHAR	; Yes
	CMP	BYTE PTR [SI],CR ; At end of line?
	JE	INSERTCHAR	; Yes
	CMP	SI,CS:[LASTCHAR] ; At end of file?
	JE	INSERTCHAR	; Yes
	MOV	DI,SI		; Current to di
	CALL	CHKMARK		; Inside marked area?
	JC	FILEFULL	; Don't allow
	XCHG	DS:[SI],AL	; Switch new character for old one
	JMP	SHORT ADVANCE	; Continue
INSERTCHAR:			;
	PUSH	SI		; Save current
	PUSH	AX		; Save the new character
	MOV	AX,0001H	; Open space for one
	CALL	OPENSPACE	; Make room for it
	POP	AX		; Get back the new character
	POP	DI		; Recover current (pushed as si)
	JC	FILEFULL	; Too much
	STOSB			; Insert character in file buffer
ADVANCE:			;
	OR	CS:[DIRTYBITS],BYTE PTR	4 ; Current line is dirty
	CALL	RIGHT		; Move cursor to next letter
FILEFULL:			;
	RET			; Go home
				;
;************************************************************************
;*									*
;*	GRFILT:  This routine will filter the character in AL if	*
;*	the Greek filter is currently on.  Accepts:  Character in AL	*
;*	Returns:  Translated Greek character.  Calls:  Nothing. 	*
;*	Clobbers:  AL.							*
;*									*
;************************************************************************
				;
GRFILT:	CMP	CS:[INGREEK],BYTE PTR 00H ; Doing greek filtering?
	JZ	OUTTAY		; No, continue
	CMP	AL,3FH		; Question mark?
	JNZ	HOBBIT		; No
	MOV	AL,3BH		; Remap to semicolon for greek
OUTTAY:	RET			; Go home
				;
HOBBIT:	CMP	AL,3BH		; Semi-colon accent toggle?
	JNZ	NOTOGG		; No
	MOV	CS:[ACCNEXT],BYTE PTR 0FFH ; Flag next char as accent
	XOR	AL,AL		; Flag "IGNORE THIS CHARACTER"
	RET			; Go home
				;
NOTOGG:	PUSH	BX		; Save bx
	PUSH	DS		; And ds
	PUSH	ES		; And es
				;
	PUSH	CS		; This segment
	PUSH	CS		; This segment again
	POP	DS		; Into ds
	POP	ES		; Into es
	CMP	AL,'A'		; At least upper case a
	JB	NORMKEY		; No, process normally
	CMP	AL,'Z'		; Looking for end of upper case chars
	JBE	UGKEY		; Definately greek, continue processing
	CMP	AL,'a'		; Now look for garbage between upper & lower
	JB	NORMKEY		; Normal key, bail out
	CMP	AL,'z'		; Now look for the rest of the garbage
	JA	NORMKEY		; Normal key, bail...
				;
	SUB	AL,'a'		; Remove lower case bias
	LEA	BX,LTABLE	; Point to lower case translation table
	JMP	SHORT GKEY	; And continue
				;
UGKEY:	SUB	AL,'A'		; Remove upper case bias
	LEA	BX,UTABLE	; Point to upper case translation table
GKEY:	XLAT			; Now we have the greek character in al
	CMP	CS:[ACCNEXT],BYTE PTR 00H ; Does this char need accent?
	JZ	NORMKEY		; Absolutely not
				;
	PUSH	DI		; Save di
	PUSH	SI		; And si
	PUSH	CX		; And cx
				;
	MOV	DI,OFFSET ACCTABLE ; Point to normal vowels table
	MOV	CX,000EH	; Number of entries in table
	MOV	SI,CX		; Remember for later
	REPNZ	SCASB		; Look for entry
	JNZ	NOTACC		; No find, not accented, abort
	SUB	SI,CX		; Generate offset
	DEC	SI		; Compensate for 0 entry array
	ADD	SI,OFFSET VTABLE ; Add in offset of accented vowel table
	LODSB			; Get final, accented value.
NOTACC:	POP	CX		; Restore cx
	POP	SI		; And si
	POP	DI		; And di
	MOV	CS:[ACCNEXT],BYTE PTR 00H ; Turn off accent toggle
				;
				; Greek char obtained, drop on in...
				;
NORMKEY:POP	ES		; Restore es
	POP	DS		; Ds
	POP	BX		; And bx
	RET			; Go home
				;
ACCTABLE:			;
	DB	0C1H		; Upper case alpha
	DB	0C5H		; Upper case epsilon
	DB	0C7H		; Upper case eeta
	DB	0C9H		; Upper case iota
	DB	0CFH		; Upper case omicron
	DB	0D9H		; Upper case omega
	DB	0D5H		; Upper case eepsilon
				;
	DB	0E1H		; Lower case alpha
	DB	0E5H		; Lower case epsilon
	DB	0E7H		; Lower case eeta
	DB	0E9H		; Lower case iota
	DB	0EFH		; Lower case omicron
	DB	0F9H		; Lower case omega
	DB	0F5H		; Lower case eepsilon
				;
VTABLE:				;
	DB	0A2H		; Upper case accented alpha
	DB	0B8H		; Upper case accented epsilon
	DB	0B9H		; Upper case accented eeta
	DB	0BAH		; Upper case accented iota
	DB	0BCH		; Upper case accented omicron
	DB	0BFH		; Upper case accented omega
	DB	0BEH		; Upper case accented eepsilon
				;
	DB	0DCH		; Lower case accented alpha
	DB	0DDH		; Lower case accented epsilon
	DB	0DEH		; Lower case accented eeta
	DB	0DFH		; Lower case accented iota
	DB	0FCH		; Lower case accented omicron
	DB	0FEH		; Lower case accented omega
	DB	0FDH		; Lower case accented eepsilon
				;
				; Upper case ascii to greek translation table
UTABLE:				;
	DB	0C1H		; A maps to alpha
	DB	0C2H		; B maps to veeta
	DB	0D8H		; C maps to psee
	DB	0C4H		; D maps to thelta
	DB	0C5H		; E maps to epsilon
	DB	0D6H		; F maps to phi
	DB	0C3H		; G maps to ghamma
	DB	0C7H		; H maps to eeta
	DB	0C9H		; I maps to iota
	DB	0CEH		; J maps to ksee
	DB	0CAH		; K maps to kappa
	DB	0CBH		; L maps to lambda
	DB	0CCH		; M maps to mi
	DB	0CDH		; N maps to ni
	DB	0CFH		; O maps to omicron
	DB	0D0H		; P maps to pi
	DB	0B0H		; Q maps to greek semi-colon
	DB	0D1H		; R maps to rho
	DB	0D3H		; S maps to sigma
	DB	0D4H		; T maps to taf
	DB	0C8H		; U maps to theta
	DB	0D9H		; V maps to omega
	DB	0D3H		; W maps to sigma (for finial)
	DB	0D7H		; X maps to hee
	DB	0D5H		; Y maps to eepsilon
	DB	0C6H		; Z maps to zeeta
				;
				; Lower case ascii to greek translation table
LTABLE:				;
	DB	0E1H		; A maps to alpha
	DB	0E2H		; B maps to veeta
	DB	0F8H		; C maps to psee
	DB	0E4H		; D maps to thelta
	DB	0E5H		; E maps to epsilon
	DB	0F6H		; F maps to phi
	DB	0E3H		; G maps to ghamma
	DB	0E7H		; H maps to eeta
	DB	0E9H		; I maps to iota
	DB	0EEH		; J maps to ksee
	DB	0EAH		; K maps to kappa
	DB	0EBH		; L maps to lambda
	DB	0ECH		; M maps to mi
	DB	0EDH		; N maps to ni
	DB	0EFH		; O maps to omicron
	DB	0F0H		; P maps to pi
	DB	03BH		; Q maps to greek question mark (;)
	DB	0F1H		; R maps to rho
	DB	0F3H		; S maps to sigma
	DB	0F4H		; T maps to taf
	DB	0E8H		; U maps to theta
	DB	0F9H		; V maps to omega
	DB	0F2H		; W maps to finial sigma
	DB	0F7H		; X maps to hee
	DB	0F5H		; Y maps to eepsilon
	DB	0E6H		; Z maps to zeeta
				;
;************************************************************************
;*									*
;*	Insert new line at current position.				*
;*									*
;************************************************************************
				;
CNTRLN:	MOV	SI,CS:[CURSOR]	; Get our position
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	PUSH	SI		; Save current position
	MOV	AX,2		; Open 2 bytes
	CALL	OPENSPACE	; Make space for cr and lf
	POP	DI		; Get back old cursor location
	JC	OUTTAX		; Too much
	MOV	AX,LF*256+CR	; Load crlf
	STOSW			; Store the cr and lf
	CALL	DISPLAYBOTTOM	; Repaint bottom of the screen
OUTTAX:	RET			; Go home
				;
NEWLINE:CALL	CSAVE		; Save cursor
	MOV	CS:AL,[LAME]	; Lame byte turned on?
	OR	AL,AL		; Force flags
	JZ	SMART		; No
	MOV	CS:AL,[INSMODE]	; If so, is insert turned on?
	OR	AL,AL		; Force flags
	JZ	SMART		; No
	CALL	CNTRLN		; Insert line
	MOV	SI,CS:[CURSOR]	; Get current location
	JMP	DUMB		; Continue
				;
SMART:	MOV	CS:AL,[INSOFF]	; Configured to turn off insert on cr?
	OR	AL,AL		; Force flags
	JZ	DUMB		; No, skip
	MOV	CS:[INSMODE],BYTE PTR 00H ; Turn off insert on cr
				;
DUMB:	MOV	CS:AL,[DOCOLON]	; Auto-colons?
	OR	AL,AL		; Force flags
	JZ	NOCOLON		; No
	CALL	INSCOLON	; Check for label and insert colon if needed
				;
NOCOLON:MOV	SI,CS:[CURSOR]	; Get current location
	MOV	CS:AL,[DOCMT]	; Doing auto-commenting?
	OR	AL,AL		; Force flags
	JZ	DOLINE		; No
	CALL	FINDSEMI	; Is there already a semi here?
	JZ	DOLINE		; Yes, nothing further needed
	CALL	ENDD		; Go to end of line
NL1:	MOV	AL,CS:[SAVECOLUMN] ; Get current collum
	CMP	AL,CS:[CMTCOL]	; Comment collum?
	JA	DOLINE		; Line already longer, ignore
	JE	DOCRSEMI	; At the right place
	MOV	AL,09H		; Insert a tab to lengthen line
	CALL	INSERTKEY	; Insert it, recursivly
	JMP	SHORT NL1	; Repeat until we're there
				;
DOCRSEMI:			;
	MOV	AL,CS:[CMTCHAR]	; Insert semicolon
	CALL	REGKEY		; Insert it using reg key entry to avoid
				; Interaction with greek semi-colon toggle
	OR	CS:[DIRTYBITS],BYTE PTR	1 ; Refresh whole screen
				;
DOLINE:	CALL	FINDEOL		; Find end of this line
	JNC	CRFND		; Cr at end
	MOV	SI,CS:[LASTCHAR] ; No cr found, go to end of file
CRFND:	MOV	CS:[CURSOR],SI	; Tell pgm we're there
	CMP	SI,CS:[LASTCHAR] ; Are we at end of file?
	JNZ	NOEND		; No, only move cursor
	CALL	CNTRLN		; Open up new line
	MOV	SI,CS:[CURSOR]	; Fix si...
NOEND:	DEC	SI		; Backup from end
	MOV	AL,[SI]		; Get current char
	CMP	AL,09H		; Tab?
	JZ	DELTRAIL	; Dump it
	CMP	AL,' '		; Space?
	JZ	DELTRAIL	; Dump it
	CALL	DISPLAYCURRENT	; Redraw the current line
	CALL	HOME1		; Cursor to start of line
	CALL	DOWN		; Move down to the new line
	MOV	CS:AL,[AUTOIND]	; Auto indent?
	OR	AL,AL		; Force flags
	JZ	MODEM		; No, exit
	MOV	CS:AL,[INDENT]	; Are we currently indenting?
	OR	AL,AL		; Force flags
	JZ	MODEM		; Not right now...
	MOV	AL,CS:[INSMODE]	; Get current insert mode
	MOV	CS:[TEMP1],AL	; Stash
	MOV	CS:[INSMODE],BYTE PTR 00H ; Make sure insert is off
	CALL	CNTRLI		; Yes, tab over
	MOV	AL,CS:[TEMP1]	; Get orginal insert mode
	MOV	CS:[INSMODE],AL	; And put back
MODEM:	CALL	REDOPROMPT	; Redraw prompt if insert status was changed...
	RET			; Go home
				;
DELTRAIL:			;
	MOV	CS:[CURSOR],SI	; Setup new current location
	CALL	DELCHAR		; Delete character
	MOV	SI,CS:[CURSOR]	; Recover location
	JMP	SHORT NOEND	; Continue
EXTCLN:	JMP	COLONEXIT	; Extend short jump
				;
INSCOLON:			; Check for label, add colon if one not there
	CALL	FINDSTART	; Find start of line
	MOV	CX,CS:[CURSOR]	; Get current position
	SUB	CX,SI		; Generate number
	JCXZ	EXTCLN		; Already at start of line, skip
	MOV	DI,SI		; Move start of line into di
	CMP	CS:[PT],BYTE PTR 00H ; Allow processor technology compatiblity?
	JZ	SKIPPT1		; No
	CMP	[SI],BYTE PTR '*' ; Accept star instead in first position...
	JZ	COLONEXIT	; For processor technology compatiblity
SKIPPT1:MOV	AL,CS:[CMTCHAR]	; Abort if comment
	MOV	BX,CX		; Save number
	REPNZ	SCASB		; Look for it
	JE	COLONEXIT	; Found comment, exit
				;
	MOV	DI,SI		; Move start of line into di
	MOV	AL,09H		; Abort if tab
	MOV	CX,BX		; Get number of chars
	REPNZ	SCASB		; Look for it
	JE	COLONEXIT	; Found comment, exit
				;
	MOV	DI,SI		; Move start of line into di
	MOV	AL,' '		; Abort if space
	MOV	CX,BX		; Get number of chars
	REPNZ	SCASB		; Look for it
	JE	COLONEXIT	; Found comment, exit
				;
	MOV	DI,SI		; Get start of line
	MOV	AL,':'		; Abort if already coloned
	MOV	CX,BX		; Get number of chars
	REPNZ	SCASB		; Look for it
	JE	COLONEXIT	; Found colon, exit
				;
	MOV	SI,CS:[CURSOR]	; Get current location
	CMP	SI,CS:[LASTCHAR] ; Are we working at end of file?
	JE	DOCLN		; Yes, do colon
				;
	MOV	AL,[SI]		; Get current character
	CMP	AL,' '		; Space?
	JZ	DOCLN		; Yes, insert colon
				;
	CMP	AL,0DH		; Carriage return?
	JZ	DOCLN		; Yes, insert colon
				;
	CMP	AL,09H		; Tab?
	JNZ	COLONEXIT	; No, exit
				;
DOCLN:	MOV	CS:AL,[INSMODE]	; Get current insert mode
	MOV	CS:[TEMP],AL	; Stash
				;
	MOV	CS:AL,[CURPOSN]	; Get current column
	INC	AL		; Looking for one less than tab stop
	TEST	AL,00000111B	; At even multiple of eight?
	JNZ	JUNEAU		; No, proceed normally
				;
	MOV	CS:[INSMODE],BYTE PTR 00H ; Turn off insert
	JMP	SHORT SITKA	; Continue
				;
JUNEAU:	MOV	CS:[INSMODE],BYTE PTR 0FFH ; Turn on insert
SITKA:	MOV	AL,':'		; Get a colon
	CALL	INSERTKEY	; Put it in
	MOV	CS:AL,[TEMP]	; Get back original insert status
	MOV	CS:[INSMODE],AL	; Restore insert status
	OR	CS:[DIRTYBITS],	BYTE PTR 1 ; Refresh whole screen
	CLC			; Say we did
	JMP	SHORT BARROW	; Continue
COLONEXIT:			;
	STC			; Nothing happened
BARROW:	MOV	SI,CS:[CURSOR]	; Get current location
	RET			; Go home
				;
;************************************************************************
;*									*
;*	CHKMARK:  This routine checks to see if we are currently in a	*
;*	marked area.  Accepts:	Nothing.  Returns: Carry set if inside	*
;*	a marked area.	Calls:	Nothing.  Clobbers:  Nothing.		*
;*									*
;************************************************************************
				;
CHKMARK:PUSH	SI		; Save si
	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	MORM		; Must be turned off
	MOV	SI,CS:[CURSOR]	; Get current
	CMP	SI,CS:[MRKSTRT]	; At beginning?
	JB	MORM		; It's before any marked area...
	CMP	SI,CS:[MARKEND]	; At end?
	JAE	MORM		; It's after any marked area...
	CALL	BEEP3		; Beep
	STC			; Flag not ok
	JMP	SHORT CHKEXIT	; Exit
				;
MORM:	CLC			; Flag ok
CHKEXIT:POP	SI		; Restore si
	RET			; Go home
				;
BEEP1:	PUSHA			; Save stuff
	MOV	CX,1000H	; For badkey, etc.
	CALL	BEEPIT		; Do beep
	POPA			; Restore stuff
	RET			; Go home
				;
BEEP2:	PUSHA			; Save stuff
	MOV	CX,2000H	; For ^k, ^q timeout
	CALL	BEEPIT		; Do beep
	CALL	PDELAY		; Delay...
	MOV	CX,2000H	; Re-init
	CALL	BEEPIT		; Twice
	POPA			; Restore stuff
	RET			; Go home
				;
BEEP3:	PUSHA			; Save stuff
	MOV	CX,0800H	; For "we can do that, but not now" errors
	CALL	BEEPIT		; Do beep
	CALL	PDELAY		; Delay...
	MOV	CX,0800H	; Re-init
	CALL	BEEPIT		; Twice
	POPA			; Restore stuff
	RET			; Go home
				;
BEEPIT:	CMP	BYTE PTR CS:[NOISE],00H	; Noise turned off?
	JZ	BEEPEND		; Yes, exit
	CALL	TONESET		; Setup tone
	CALL	TONEON		; And turn it on
	CALL	PDELAY		; Delay a bit
	CALL	TONEOFF		; Now turn tone off
BEEPEND:RET			; Go home
				;
PDELAY:	MOV	BX,CS:[TICS]	; Get current tic count
PD1:	MOV	AX,CS:[TICS]	; Get latest tic count
	SUB	AX,BX		; Get difference
	CMP	AX,0002H	; Long enough?
	JB	PD1		; Not yet
	RET			; Yes, exit
				; Routine to select tone
				;
TONESET:			; Load the time period into the timer
	MOV	AL,CL		; Lower byte
	OUT	42H,AL		; Out to timer
	MOV	AL,CH		; Upper byte
	OUT	42H,AL		; Out to timer
	RET			; Go home
				;
				; Routine to turn on tone
				;
TONEON:				; Turn speaker and timer on
	IN	AL,61H		; Get contents of system port b
	OR	AL,3		; Turn speaker and timer on
	OUT	61H,AL		; Send out new values to port b
	RET			; Go home
				;
				; Routine to turn tone off
				;
TONEOFF:			; Turn off timer 2 and speaker
	IN	AL,61H		; Get port b again
	AND	AL,11111100B	; Turn speaker and timer off
	OUT	61H,AL		; Now do it
	RET			; Go home
				;
				;
;***********************************************************************
; This subroutine inserts spaces into the file buffer.	On entry AX
; contains the number of spaces to be inserted.  On return, CF=1 if
; there was not enough space in the file buffer.
;***********************************************************************
				;
OPENSPACE:			;
	CALL	CHKMARK		; Trying this inside a marked area?
	JC	NOROOM		; Don't allow
	MOV	CX,CS:[LASTCHAR] ; Last character in the file
	MOV	SI,CX		; Into si
	MOV	DI,CX		; And di
	ADD	DI,AX		; Offset for new end of file
	JC	NOROOM		; If no more room, return error
	CALL	FIXINS		; Fix place markers
	MOV	CS:[LASTCHAR],DI ; Save offset of end of file
	SUB	CX,CS:[CURSOR]	; Number of characters to shift
	DEC	DI		; Back...
	DEC	SI		; Both up
	STD			; String moves goes forward
	REP	MOVSB		; Shift the file upward
	CLD			; Normal
	CLC			; Indicate enough room
NOROOM:	RET			; Go home
				;
;***********************************************************************
; This subroutine adjusts the cursor position ahead to the saved cursor
; column.  On entry DH has the cursor row.
;***********************************************************************
				;
SHIFTRIGHT:			;
	MOV	CL,CS:[SAVECOLUMN] ; Keep the saved cursor offset
	XOR	CH,CH		; Zero upper
	MOV	BP,CX		; Keep the saved cursor position
	ADD	CL,CS:[LEFTMARGIN] ; Shift into visable window also
	ADC	CH,0		; Bump carry on up
	XOR	DL,DL		; Zero column
	MOV	CS:[CURPOSN],DX	; Get cursor row/column
	JCXZ	NOCHANGE	; Nothing happened
RIGHTAGAIN:			;
	PUSH	CX		; Save
	CMP	BYTE PTR [SI],CR ; At end of line?
	JE	DONTMOVE	; If at end, stop moving
	CALL	RIGHT		; Move right one character
DONTMOVE:			;
	POP	CX		; Recover
				;
	MOV	AL,CS:[SAVECOLUMN] ; Get column
	XOR	AH,AH		; Zero upper
	CMP	AX,CX		; Is cursor still in margin?
	JL	INMARGIN	; If yes, keep moving
				;
	MOV	DX,CS:[CURPOSN]	; Get cursor column again
	XOR	DH,DH		; Clear row
	CMP	DX,BP		; At saved cursor position?
	JE	RIGHTDONE	; If yes, were done
	JA	RIGHTTOOFAR	; Did we go too far?
INMARGIN:			;
	LOOP	RIGHTAGAIN	; Go again
RIGHTDONE:			;
	MOV	CX,BP		; Get back save cursor position
	MOV	CS:[SAVECOLUMN],CL ; And save
NOCHANGE:			;
	RET			; Go home
				;
RIGHTTOOFAR:			;
	CALL	LEFT		; Move back left one place
	JMP	SHORT RIGHTDONE	; Exit
				;
;***********************************************************************
; This subroutine skips past the CR and LF at SI.  SI returns new offset
;***********************************************************************
				;
SKIPCRLF:			;
	CMP	SI,CS:[LASTCHAR] ; At last char in the file?
	JAE	NOSKIP		; If yes, dont skip anything
	CMP	BYTE PTR [SI],CR ; Is first character a cr?
	JNE	NOSKIP		; No
	INC	SI		; Look at next character
	CMP	SI,CS:[LASTCHAR] ; Is it at the end of file?
	JAE	NOSKIP		; If yes, dont skip anymore
	CMP	BYTE PTR [SI],LF ; Is next character a line feed?
	JNE	NOSKIP		; Skip any line feeds also
	INC	SI		; Next loc
NOSKIP:	RET			; Go home
				;
;***********************************************************************
; This subroutine finds the beginning of the previous line.
;***********************************************************************
				;
FINDPREVIOUS:			;
	PUSH	CS:WORD	PTR [CURSOR] ; Save the cursor location
	CALL	FINDCR		; Find start of this line
	MOV	CS:[CURSOR],SI	; Save the new cursor
	CALL	FINDSTART	; Find the start of this line
	POP	CS:[CURSOR]	; Get back starting cursor
	RET			; Go home
				;
;***********************************************************************
; This searches for the previous carriage return.  Search starts at SI.
;***********************************************************************
				;
FINDCR:	PUSH	CX		; We're gonna clobber cx
	MOV	AL,CR		; Look for a carriage return
	MOV	DI,SI		; Into di for scasb
	MOV	CX,SI		; Offset also number of bytes...
	JCXZ	ATBEGINNING	; Nothing to do
	DEC	DI		; Exclusive search, backup one
	STD			; Search backwards
	REPNE	SCASB		; Scan for the character
	CLD			; Restore direction flag
	INC	DI		; Compensate back
	MOV	SI,DI		; Put into si for return
ATBEGINNING:			;
	POP	CX		; Restore cx
	RET			; And go home
				;
;***********************************************************************
; This subroutine computes the location of the start of current line.
; Returns SI pointing to the first character of the current line.
;***********************************************************************
				;
FINDSTART:			;
	MOV	SI,CS:[CURSOR]	; Get the current cursor
	OR	SI,SI		; At start of the file?
	JZ	ATSTART		; If yes, we're done
	CALL	FINDCR		; Find the...
	CALL	SKIPCRLF	; Skip over it
ATSTART:RET			; Go home
				;
;***********************************************************************
; This finds the offset of the start of the next line.	The search is
; started at location ES:SI.  On return CF=1 of no CR was found.
;***********************************************************************
				;
FINDNEXT:			;
	PUSH	CX		; Don't clobber cx
	CALL	FINDEOL		; Find the end of this line
	JC	ATNEXT		; If at end of file, return
	CALL	SKIPCRLF	; Skip past cr and lf
	CLC			; Indicate end of line found
ATNEXT:	POP	CX		; Restore cx
	RET			; Go home
				;
;***********************************************************************
; This searches for the next carriage return in the file.  The search
; starts at the offset in register SI. Returns it in SI.
;***********************************************************************
				;
FINDEOL:MOV	AL,CR		; Look for a carriage return
	MOV	CX,CS:[LASTCHAR] ; Last letter in the file
	SUB	CX,SI		; Count for the search
	MOV	DI,SI		; Into di for scas
	JCXZ	ATEND		; If nothing to search, return
	REPNE	SCASB		; Scan for the character
	MOV	SI,DI		; Return the location of the cr
	JCXZ	ATEND		; If not found, return
	DEC	SI		; Compensate back
	CLC			; Indicate the cr was found
	RET			; And go home
ATEND:	STC			; Indicate cr was not found
	RET			; And go home
				;
;***********************************************************************
; This subroutine positions the screen with the cursor at the row
; selected in register DH.  On entry, SI holds the cursor offset.
;***********************************************************************
				;
LOCATE:	MOV	CL,DH		; Put row in cl
	XOR	CH,CH		; Zero upper
	MOV	CS:[CURSOR],SI	; Store current location
	XOR	DX,DX		; Start at top of the screen
	OR	SI,SI		; At start of buffer?
	JZ	LOCATEFIRST	; Yes
				;
	CALL	FINDSTART	; Get start of this row
	XOR	DX,DX		; Start at top of the screen
	OR	SI,SI		; Is cursor at start of file?
	JZ	LOCATEFIRST	; Yes
	JCXZ	LOCATEFIRST	; If locating to top row we're done
FINDTOP:			;
	PUSH	SI		; Save current location
	PUSH	CX		; And cx
	CALL	FINDCR		; Find previous row
	POP	CX		; Restore cx
	POP	AX		; Old location (pushed as si)
	CMP	BYTE PTR [SI],CR ; Cr here?
	JNE	LOCATEFIRST	; No
	CMP	SI,AX		; Did it change?
	JE	LOCATEDONE	; If not, quit moving
	INC	DH		; Cursor moves to next row
	LOOP	FINDTOP		; Go again
				;
LOCATEDONE:			;
	PUSH	CS:WORD	PTR [CURSOR] ; Save cursor
	MOV	CS:[CURSOR],SI	; Stash new location
	CALL	FINDSTART	; Find start of top of screen
	POP	CS:[CURSOR]	; And then restore former
LOCATEFIRST:			;
	MOV	CS:[SCREENTOP],SI ; New screen top
	MOV	CS:[CURPOSN],DX	; New cursor
	CALL	CURSORCOL	; Compute column
	MOV	CS:[SAVECOLUMN],DL ; And save
	RET			; Go home
				;
;***********************************************************************
; This "fixes" the screen, by shifting right or left (if necessary) so
; that the cursor remains visible instead of being off screen.
;***********************************************************************
				;
FIXCUR:	MOV	BL,CS:[MARGINCOUNT] ; Get margin count
	MOV	BH,BL		; Retain orginal...
	ADD	BL,08H		; Compensate for edge of screen problems
	CMP	BL,CS:[COLUMNSB] ; Still unshifted?
	JBE	FIXCUR1		; Yes, exit
				;
	MOV	BL,BH		; Recover orginal...
	SUB	BL,CS:[COLUMNSB] ; Compensate
	ADD	BL,08H		; Re-comp to prevent edge of screen problems...
	CMP	BL,CS:[LEFTMARGIN] ; At left?
	JAE	FIXCUR2		; Yes
				;
	ADD	BH,08D		; We shift 8 characters at a time...
FIXCUR1:CMP	BH,CS:[LEFTMARGIN] ; At right?
	JB	FIXCUR3		; No, fixit
	CMP	CS:[LEFTMARGIN],BYTE PTR 00H ; Un-shifted?
	JZ	OUTTA		; Yes
				;
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; This will force a redraw the screen
OUTTA:	RET			; Go home
				;
FIXCUR2:CALL	SHRIGHT		; Shift right
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; This will force a redraw the screen
	JMP	SHORT FIXCUR	; And try again...
				;
FIXCUR3:CALL	SHLEFT		; Shift left
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; This will force a redraw the screen
	JMP	SHORT FIXCUR	; And try again...
				;
;***********************************************************************
; This subroutine computes the correct column for the cursor.  No
; inputs.  On exit, CS:[CURPOSN] is set and DX has the row/column.
;***********************************************************************
				;
CURSORCOL:			;
	MOV	SI,CS:[CURSOR]	; Get cursor offset
	CALL	FINDSTART	; Find start of this line
	MOV	CX,CS:[CURSOR]	; Same as number
	SUB	CX,SI		; Get difference
	MOV	DX,CS:[CURPOSN]	; Get current row
	XOR	DL,DL		; Start at column zero
	MOV	CS:[MARGINCOUNT],DL ; Count past the left margin
	JCXZ	COLDONE		; Nothing to do
CURSORLOOP:			;
	LODSB			; Get the next character
	CMP	AL,CR		; Is it the end of line?
	JE	COLDONE		; If end, were done
	CMP	AL,TAB		; Is it a tab?
	JNE	NOTATAB		; No
				;
	MOV	BL,CS:[MARGINCOUNT] ; Get margin count
	OR	BL,00000111B	; Make a tab stop
	MOV	CS:[MARGINCOUNT],BL ; And put back
	CMP	BL,CS:[LEFTMARGIN] ; Inside visible window yet?
	JB	NOTATAB		; If not, don't advance cursor
	OR	DL,00000111B	; Move to multiple of eight
NOTATAB:			;
	MOV	BL,CS:[MARGINCOUNT] ; Get margin count
	INC	BL		; And increment
	MOV	CS:[MARGINCOUNT],BL ; Put back
	CMP	BL,CS:[LEFTMARGIN] ; At left?
	JBE	OUTOFWINDOW	; Yes
	INC	DL		; We're at next column now
OUTOFWINDOW:			;
	LOOP	CURSORLOOP	; Go again
COLDONE:			;
	CMP	DL,CS:[COLUMNSB] ; Past end of display?
	JB	COLUMNOK	; If not, were ok?
	MOV	DL,CS:[COLUMNSB] ; Get it
	DEC	DL		; Leave cursor at last column
COLUMNOK:			;
	MOV	CS:[CURPOSN],DX	; Store the row/column
	RET			; Go home
				;
;***********************************************************************
; This displays the string at CS:SI at the location in DX.  The
; remainder of the row is erased.  Cursor is put at the end of the line.
;***********************************************************************
				;
PRTLST:	MOV	DH,CS:[ROWS]	; Last row on display
	CMP	CS:[STATLN],BYTE PTR 00H ; Do stat line?
	JZ	TTY		; No status line, already at bottom
	INC	DH		; Bottom row of screen
				;
TTY:	PUSH	DX		; Save dx
	CALL	POSITION	; Compute offset into video
	POP	DX		; Restore
	PUSH	DS		; Save ds
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
TTYLOOP:LODSB			; Get char
	OR	AL,AL		; At end of string yet?
	JZ	TTYDONE		; Yes
	INC	DL		; Next loc
	PUSH	DX		; Save
	CALL	WRTINV		; Write in inverse video
	POP	DX		; Restore
	JMP	SHORT TTYLOOP	; Do till done
TTYDONE:CALL	SETCURSOR	; Move cursor to end of string
	POP	DS		; Restore ds
	JMP	ERASEEOL	; Erase the rest of line
				;
;***********************************************************************
; This copies the input filename to CS:DI and changes the extension
;***********************************************************************
				;
CHGEXTENSION:			;
	PUSH	SI		; New extension pointer
	MOV	SI,CS:[NAMEPTR]	; Point to filename
CHGLOOP:			;
	LODSB			; Get it
	CMP	AL,'.'		; Look for the extension
	JE	FOUNDDOT	; Not yet
	OR	AL,AL		; No extension?
	JZ	FOUNDDOT	; No extension!
	STOSB			; Copy a character
	JMP	CHGLOOP		; Get next
FOUNDDOT:			;
	MOV	CX,5		; Five chars in extension
	POP	SI		; Restore new extension pointer
	REP	MOVSB		; Move new extension in
	RET			; Go home
				;
EXITLB:	POP	DS		; Restore file segment
	CALL	REDOPROMPT	; Redraw the prompt
	JMP	EXITSB		; Extend short jump
				;
LOADBLK:PUSH	DS		; Save file segment
	CALL	CHKMARK		; Inside marked block?
	JC	EXITLB		; Yes, don't allow loading
				;
	CALL	INHIBIT		; Inhibit auto-save
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	SI,OFFSET LOADMESS ; Point to string
	MOV	DX,OFFSET FILENAME ; Point to buffer
	CALL	BOTHGET		; Go get string
	JC	EXITLB		; Aborted
	MOV	SI,OFFSET FILENAME+0002H ; Get beginning of buffer data
	MOV	CL,CS:[NAMELEN]	; Get length of returned string
	XOR	CH,CH		; Zero upper
	JCXZ	EXITLB		; No file name...
	MOV	BX,CX		; For next instruction...
	MOV	CS:[SI+BX],BYTE	PTR 00H	; Terminate file name...
	MOV	DX,SI		; Filename to dx
	MOV	AX,3D00H	; Open existing for read
	INT	21H		; Try to open the file
	POP	DS		; Restore file segment
	JNC	NAVISTAR	; Everything's ok
	JMP	READERR		; Problem, exit
				;
NAVISTAR:			;
	MOV	BX,AX		; Get handle...
	SUB	CX,CX		; Zero cx
	MOV	DX,CX		; And dx
	MOV	AX,4202H	; Move ptr function
	INT	21H		; Do it
	OR	DX,DX		; Bigger than 64k?
	JZ	DETROIT		; No, ok to proceed
	JMP	LDBIG		; Yes, cannot do
				;
DETROIT:OR	AX,AX		; Force flags
	JNZ	NOTEMPTY	; Something there
	JMP	FCLOSEE		; Close file and exit
NOTEMPTY:			;
	PUSH	AX		; Remember number of bytes
	MOV	AX,4200H	; Move ptr back to start
	INT	21H		; Done!
	POP	AX		; Get back number of bytes
	PUSH	AX		; Re-save
	CALL	OPENSPACE	; Open up space...
	POP	CX		; Get back number of bytes (pushed as ax)
	JNC	EEPSILON	; Result ok
	JMP	LDBIG		; Result is too big, abort
				;
EEPSILON:			;
	MOV	AH,3FH		; Read from the file
	MOV	CS:DX,CS:[CURSOR] ; Get current location
	INT	21H		; Go read the data
	JNC	OMEGA		; Ok
	JMP	READERR		; Bad
				;
OMEGA:	CMP	CS:[DOEOF],BYTE	PTR 00H	; Do eof?
	JZ	NOOEOF		; No
	PUSH	CS:WORD	PTR [CURSOR] ; Save current location
	MOV	CX,AX		; Get number of read bytes
	MOV	DI,CS:[CURSOR]	; Current location in di
	MOV	AL,1AH		; Look for eof
	REPNE	SCASB		; Look for it
	JNE	CHKDONE		; Done
	DEC	DI		; Backup one
	INC	CX		; Add one to char count 'cause we backed up
	MOV	CS:[CURSOR],DI	; Load cursor value
				;
	PUSH	CX		; Save number of characters
	MOV	AL,LF		; Look for line feed (past eof)
LFLP:	REPNE	SCASB		; Go look
	JNE	DELJUNK		; Not found
	MOV	[DI]-1,BYTE PTR	0FFH ; Convert line feeds to ff
	JCXZ	DELJUNK		; We're done
	JMP	SHORT LFLP	; Elmininate lf so delchar will work properly
				;
DELJUNK:POP	CX		; Recover number of characters
CHKLP:	PUSH	CX		; Save number of characters
	CALL	DELCHAR		; Dump it
	POP	CX		; Recover number of characters
	LOOP	CHKLP		; Delete everything past eof
CHKDONE:POP	CS:WORD	PTR [CURSOR] ; Recover original cursor
NOOEOF:	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Refresh the whole screen
	CALL	FCLOSEE		; Close file
				;
	MOV	SI,OFFSET ERAMESS ; Point to erase message
	XOR	DL,DL		; Print at column zero...
	CALL	PRTLST		; Ask about loadfile erasure
				;
ALPHA:	CALL	CONSTAT		; Check for next key...
	JNZ	IOTA		; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	ALPHA		; No
	CALL	BEEP2		; Make noise
	JMP	SHORT NOERA	; Guy is asleep at the switch...
				;
IOTA:	CALL	GETCH		; Get next key
	AND	AL,5FH		; Convert to upper case
	CMP	AL,'Y'		; Was answer no?
	JE	YESERA		; Yes...
	JMP	SHORT NOERA	; If no, then don't erase loadfile
				;
YESERA:	MOV	DX,OFFSET FILENAME+0002H ; Point to buffer data
	PUSH	DS		; Save file segment
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	AH,41H		; Erase file function
	INT	21H		; Go shitcan it
	POP	DS		; Restore file segment
				;
NOERA:	CALL	REDOPROMPT	; Redraw bottom of screen
	MOV	SI,[CURSOR]	; Get current location
	CALL	FIXUNIX		; Fix lf-only loads
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	RET			; Go home
				;
LDBIG:	MOV	SI,OFFSET TOOBIG ; Say too big
	JMP	SHORT FAKE69	; Continue
				;
FCLOSEE:MOV	AH,3EH		; Close file function
	INT	21H		; Close the file
	RET			; Go home
				;
READERR:MOV	SI,OFFSET PROB1	; Point to problem message
FAKE69:	PUSH	DS		; Exitlb expects ds on stack
	CALL	FCLOSEE		; Close file...
	CALL	BOTHTELL	; Print, wait for escape
	CALL	REDOPROMPT	; Redraw prompt
	JMP	EXITLB		; Exit
				;
FIXIT:	JMP	EXITSB		; Extend conditional jump
				;
SAVEBLK:CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	FIXIT		; No, how can we save it?
				;
	CMP	CS:[MARKMODE],BYTE PTR 0FFH ; Are we still defining the block?
	JE	FIXIT		; No end, how can we save it?
				;
	CALL	INHIBIT		; Inhibit auto-save
	PUSH	DS		; Save file segment
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	SI,OFFSET SAVEMESS ; Point to string
	MOV	DX,OFFSET FILENAME ; Point to buffer
	CALL	BOTHGET		; Go get string
	JNC	AAAA		; Ok
	JMP	EXITLB		; Aborted
				;
AAAA:	MOV	SI,OFFSET FILENAME+0002H ; Get beginning of buffer data
	MOV	CL,CS:[NAMELEN]	; Get length of returned string
	XOR	CH,CH		; Zero upper
	JCXZ	EXITSB1		; No file name...
	MOV	BX,CX		; For next instruction...
	MOV	CS:[SI+BX],BYTE	PTR 00H	; Terminate file name...
	MOV	DX,SI		; Filename to dx
	MOV	AH,3CH		; Function to create file
	MOV	CX,0020H	; Attribute for new file
	INT	21H		; Try to create the file
	JC	WRITEERR	; Problem, exit
				;
	XOR	DX,DX		; This is the paste buffer
	MOV	CX,CS:[PASTESEG] ; Get segment
	MOV	DS,CX		; Into ds
	MOV	CX,CS:[PASTESIZE] ; Number of bytes
	MOV	DI,CX		; Into di
	MOV	BX,AX		; This is the handle
	MOV	AH,40H		; Write to the file
	CMP	CX,0FFFFH	; Is buffer already full?
	JE	DONTEOF		; If yes, dont add eof mark
	CMP	CS:[DOEOF],BYTE	PTR 00H	; Do eof?
	JZ	DONTEOF		; No
	INC	CX		; Plus one character for eof mark
	MOV	BYTE PTR [DI],1AH ; Add the eof marker
DONTEOF:INT	21H		; Write the buffer contents
	JC	WRITEERR	; Exit on a write error
	CMP	AX,CX		; Was entire file written?
	JNE	WRITEERR	; If not, exit
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into the data segment
	MOV	AH,3EH		; Close file function
	INT	21H		; Close the file
EXITSB1:POP	DS		; Restore file segment
	CALL	REDOPROMPT	; Draw the prompt line
	RET			; Go home
				;
WRITEERR:			;
	POP	DS		; Restore file segment
	MOV	SI,OFFSET PROBLEM ; Point to problem message
	JMP	FAKE69		; Print, close file...
				;
SANDR:	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	PORM		; Must be turned off
EXITSB:	CALL	BEEP3		; Beep
	RET			; Forget it
				;
PORM:	MOV	CS:AX,CS:[CURSOR] ; Get current location
	MOV	CS:[MARKA],AX	; And save for compensation
	PUSH	CS:WORD	PTR [CURPOSN] ; And screen position
				;
	CALL	GETFND		; Get string to find
	JC	BYESANDR	; Abort
	CALL	GETREPLACE	; Get new string
	JC	BYESANDR	; Abort
	CALL	GETCASE		; Ask about case, etc.
	JC	BYESANDR	; Abort
				;
	XOR	DL,DL		; First column
	MOV	SI,OFFSET BUSYMESS ;
	CALL	PRTLST		; Display busy message
				;
	MOV	CS:[CURSOR],WORD PTR 0FFFFH ; Point to beginning of file-1
				;
GOLDEN:	CALL	CNTRLL		; Find string
	JC	BYESANDR	; Done
	MOV	CL,CS:[RETLEN]	; Get length of find string
	XOR	CH,CH		; Zero upper
	JCXZ	BYESANDR	; Abort if zero
				;
SANDRLP:PUSH	CX		; Save it
	CALL	DELCHAR		; Delete current character
	POP	CX		; Restore number of chars to delete
	LOOP	SANDRLP		; And all until find string is gone!
				;
	MOV	AL,CS:[REPLACELEN] ; Get length of replacement string
	XOR	AH,AH		; Zero upper
	OR	AX,AX		; Replacing with anything?
	JZ	CRUD		; No...
	MOV	SI,OFFSET REPLACEPTR+2 ; Point to replacement string
	CALL	INSERTSTRING	; Insert string into file
CRUD:	PUSHF			; Save flags
				;
	MOV	AL,CS:[REPLACELEN] ; Get length of replacement string
	XOR	AH,AH		; Clear upper
	DEC	AX		; Compensate down for cntrll routine
	MOV	SI,CS:[CURSOR]	; Get current location
	ADD	SI,AX		; Add in
	CALL	MOVE		; Move there
				;
LENOK:	POPF			; Restore insert string status
	JNC	GOLDEN		; Do all
	CALL	NOTENO		; Not enough room in file to complete
BYESANDR:			;
	POP	DX		; Get old screen location (pushed as [curposn])
	MOV	SI,CS:[MARKA]	; Get compensated original location
	CALL	LOCATE		; Move there
	CALL	REDOPROMPT	; Redraw prompt (if any)
	RET			; Go home
				;
FIND:	CALL	GETFND		; Get string to find
	JC	FOUNDB		; Abort
	CALL	GETCASE		; Ask about case, etc.
	JC	FOUNDB		; Abort
	PUSH	CS:WORD	PTR [CURSOR] ; Save current position
	MOV	CS:[CURSOR],WORD PTR 0FFFFH ; Point to beginning of file -1
	CALL	CNTRLL		; Find string
	POP	AX		; Get original position (pushed as [cursor])
	CMP	CS:[CURSOR],WORD PTR 0FFFFH ; Still at start?
	JNZ	FOUNDA		; No, we found something
	MOV	CS:[CURSOR],AX	; Restore original position
FOUNDB:	CALL	CFIX		; Fix cursor
FOUNDA:	CALL	REDOPROMPT	; Redraw the prompt
	RET			; Go home
				;
GETREPLACE:			;
	MOV	SI,OFFSET REPLACEMESS ; Point to string
	MOV	DX,OFFSET REPLACEPTR ; Point to buffer
	MOV	AL,CS:[NOCASE]	; Get no-case status
	PUSH	AX		; Save
	CALL	BOTHGET		; Get replacement string
	POP	AX		; Recover no-case status
	MOV	CS:[NOCASE],AL	; This allows greek *replacements* for a
				; Latin case insensitive search
	RET			; Go home
				;
GETFND:	CMP	CS:[FORM7],BYTE	PTR 00H	; Form7 filter on?
	JZ	BARF69		; No, skip
	CALL	SETCAPS		; Turn on caps lock
				;
BARF69:	CALL	INHIBIT		; Inhibit auto-save
	MOV	SI,OFFSET FINDMESS ; Point to string
	MOV	DX,OFFSET STRINGPTR ; Point to buffer
BOTHGET:PUSH	DS		; Save ds
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	PUSH	DX		; Save buffer pointer
	XOR	DL,DL		; First column
	CALL	PRTLST		; Display a prompt
				;
	POP	DX		; Restore buffer pointer
	CALL	BUFFIN		; Go get a string
	POP	DS		; Restore original ds
	RET			; Go home
				;
GETCASE:PUSH	DS		; Save ds
	MOV	CS:[DOCASE],BYTE PTR 00H ; Say we care about case for now...
	CMP	CS:[NOCASE],BYTE PTR 00H ; Are we going to supress asking?
	JNZ	EXITC		; Yes, greek present in buffer...
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	XOR	DL,DL		; First column
	MOV	SI,OFFSET CASEMESS ; Point to case message
	CALL	PRTLST		; Ask about case sensitivity
				;
DELTA:	CALL	CONSTAT		; Check for next key...
	JNZ	GAMMA		; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	DELTA		; No
	CALL	BEEP2		; Make noise
	JMP	SHORT PHONE	; Guy is asleep at the switch...
				;
GAMMA:	CALL	GETCH1		; Get key
	CMP	AL,1BH		; Escape?
	JZ	PHONE		; Yes
	CMP	AL,15H		; Control-u?
	JZ	PHONE		; Yes
	AND	AL,5FH		; Convert to upper case
	CMP	AL,'Y'		; Was answer yes?
	JE	EXITC		; If yes, then we care about case
	NOT	CS:BYTE	PTR [DOCASE] ; Say we don't care...
				; And convert input string to upper
	MOV	SI,OFFSET STRINGPTR+0002H ; Get beginning of buffer data
	MOV	CL,CS:[RETLEN]	; Get length of returned string
	XOR	CH,CH		; Zero upper
	JCXZ	PHONE		; Null length, findsub will reject
UPLP:	MOV	CS:AL,[SI]	; Get character
	CALL	TOUPPER		; Convert
	MOV	CS:[SI],AL	; Put back
	INC	SI		; Next
	LOOP	UPLP		; Do all
	CLC			; Say ok
EXITC:	POP	DS		; Restore current ds
	RET			; Go home
				;
PHONE:	STC			; Say aborted
	JMP	SHORT EXITC	; And exit
				;
KEYCNTRLL:			; Entry for key...
	CALL	CSAVE		; Save location
	CALL	CNTRLL		; Call it
	CALL	REDOPROMPT	; Redraw the prompt
	RET			; Go home
				;
CNTRLL:	PUSH	DS		; Save ds
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	DI,CS:[CURSOR]	; Get last location where string was found
	INC	DI		; Bump up so it won't be found again
	MOV	BX,CS:[LASTCHAR] ; Get length
	SUB	BX,DI		; Remove difference
	MOV	CL,CS:[RETLEN]	; Get length of returned string
	XOR	CH,CH		; Zero upper
	MOV	SI,OFFSET STRINGPTR+0002H ; Get beginning of buffer data
	CALL	FINDSUB		; Go find it
	JNZ	FOUNDIT		; Found something
	POP	DS		; Restore ds
	PUSH	DS		; Resave
	CALL	TELLEM		; Say nothing found....
	POP	DS		; Restore ds
	RET			; Go home
				;
FOUNDIT:MOV	SI,DX		; Offset in si
	POP	DS		; Restore ds
MOVE:	PUSH	DS		; Re-save
	MOV	DH,CS:[ROWS]	; Get number of active rows
	SHR	DH,1		; Divide by 2 (more or less)
	CALL	LOCATE		; Locate cursor halfway down screen
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; This will force a redraw the screen
	POP	DS		; Fix stack and restore
	CLC			; Say found
	RET			; Go home
				;
NOTENO:	MOV	SI,OFFSET TELLMESS1 ; Point
	JMP	SHORT BOTHTELL	; Continue
				;
TELLEM:	CALL	CFIX		; Fix previous...
	MOV	SI,OFFSET TELLMESS ; Point
BOTHTELL:			;
	XOR	DL,DL		; First column
	CALL	PRTLST		; Display a prompt
	MOV	CS:[TICS],WORD PTR 00H ; Zero auto-save tick counter
				;
WAITT:	CALL	CONSTAT		; Check for next key...
	JNZ	WAITT1		; Something there...
	CMP	CS:[TICS],WORD PTR 1092D*3 ; 3 minutes since last keypress?
	JB	WAITT		; No
	CALL	BEEP2		; Make noise
	JMP	SHORT C220	; Guy is asleep at the switch...
				;
WAITT1:	CALL	GETCH1		; Get key
	CMP	AL,1BH		; Escape?
	JZ	C220		; Yes, exit
	CMP	AL,15H		; Control-u?
	JNZ	WAITT		; Wait for escape
				;
C220:	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; This will force a redraw the screen
	STC			; Say not found
	RET			; Go home
				;
;************************************************************************
;*									*
;*	FINDSUB:  Find a substring in a string				*
;*	Accepts: DI, Offset of string; SI, Offset of substring		*
;*	BX, Length of string; CX, Length of substring			*
;*	Returns:  If the substring is found, ZF = 0 and DX contains	*
;*	the substring's offset. 					*
;*	If the substring isn't found, or if the substring is longer	*
;*	than the string, or either is a nul length, ZF=1.		*
;*	Calls:	Nothing.  Clobbers:  DX 				*
;*									*
;************************************************************************
				;
STOP:	DW	0000H		; Location where searching must stop
HERE:	DW	0000H		; Current search location
SAVESI:	DW	0000H		; Original value of si
SAVECX:	DW	0000H		; Original value of cx
				;
FINDSUB:XOR	AX,AX		; Reset zf so jcxz returns this way
	JCXZ	QUIT		; Quit is string is empty
	OR	BX,BX		; Quit if substring is empty
	JZ	QUIT		; It is empty...
	CMP	CX,BX		; Is substring bigger than string?
	JBE	OKAY		; No
	SUB	DX,DX		; Zero dx
	JMP	SHORT QUIT	; And quit
				;
OKAY:	PUSH	BX		; Save bx
	PUSH	DI		; And di
	MOV	CS:[SAVESI],SI	; Save si
	MOV	CS:[SAVECX],CX	; And cx
	ADD	BX,DI		; Location to stop searching
	SUB	BX,CX		; End of string - length of sub$
	INC	BX		; +1
	MOV	CS:[STOP],BX	; Save this location
	MOV	CS:[HERE],DI	; Save first search location too
	CLD			; Work forward
SEARCH:	CMP	CS:[DOCASE],BYTE PTR 00H ; Do we care about case?
	JZ	CASECARE	; Yes
				;
	MOV	ES:AL,[DI]	; Get byte from file
	MOV	DS:AH,[SI]	; Get byte from our string
	CALL	TOUPPER		; Convert to upper case
	INC	SI		; Increment registers
	INC	DI		; Both
	CMP	AH,AL		; Compare to entered string
	LOOPE	SEARCH		; Do all
	JE	FOUND		; If found
	JMP	SHORT NOFIND	; Not!
				;
CASECARE:			; Do much more elegant search if case
	REPE	CMPSB		; Sensitivity is desired...
	JE	FOUND		; Substring found?
				;
;************************************************************************
;*									*
;*	The substring has not yet been found.  Start searching		*
;*	again at the next byte in the string, unless you have		*
;*	reached the STOP location.					*
;*									*
;************************************************************************
				;
NOFIND:	INC	WORD PTR CS:[HERE] ; Move to next byte
	MOV	DI,CS:[HERE]	; Get current
	CMP	DI,CS:[STOP]	; Search again?
	JE	GETREGS		; No, leave
	MOV	CX,CS:[SAVECX]	; Yes, re-init registers
	MOV	SI,CS:[SAVESI]	; Original si
	JMP	SHORT SEARCH	; Go search again
				;
;************************************************************************
;*									*
;*	The substring has been found.  Record its position and leave	*
;*									*
;************************************************************************
				;
FOUND:	CMP	CX,0001H	; Found.  set zf = 0
GETREGS:MOV	DX,CS:[HERE]	; Put matching offset in dx
	POP	DI		; Restore di
	POP	BX		; And bx
	MOV	CX,CS:[SAVECX]	; And cx
	MOV	SI,CS:[SAVESI]	; And si
QUIT:	RET			; Go home
				;
TOUPPER:CMP	AL,60H		; Lower case starts with 61
	JB	NOUP		; Nothing needed
	CMP	AL,7AH		; Lower case z
	JA	NOUP		; Nothing needed
	AND	AL,5FH		; Make upper case
NOUP:	RET			; Go home
				;
;************************************************************************
;*									*
;*	TYPECAPS:  Similar to DOCAPS, except for normal typing mode.	*
;*	Accepts:  [FORM7] switch, [CURSOR] location.  Returns:		*
;*	Nothing.  Calls:  SETCAPS, RESETCAPS.  Clobbers:  SI,DI,AL	*
;*									*
;************************************************************************
				;
TYPECAPS:			;
	CMP	CS:[FORM7],BYTE	PTR 00H	; Form7 filter on?
	JNZ	BARF88		; Yes, continue
BARF87:	JMP	NOSET		; No, skip
				;
BARF88:	MOV	SI,CS:[CURSOR]	; Get current location
	CALL	FINDSEMI1	; Look for semi-colon
	JNZ	BARF87		; Not found, do nothing...
	SUB	SI,DI		; Get difference between current loc and semi
	JZ	DO4		; Right on semi, turn on caps...
	CMP	SI,0001H	; First after
	JZ	DO3		; Turn on caps
	CMP	SI,0002H	; Second after?
	JZ	DO2		; Yes
	CMP	SI,0003H	; Third after
	JA	BARF87		; No
	MOV	CS:AL,[CMTSP]	; Space after semi colon?
	OR	AL,AL		; Force flags
	JZ	NOSET		; No space, do nothing
	JMP	SHORT RESETCAPS	; Space used, turn off
				;
DO2:	MOV	CS:AL,[CMTSP]	; Space used?
	OR	AL,AL		; Force flags
	JNZ	SETCAPS		; Space used, turn on
	JMP	SHORT RESETCAPS	; No space used, turn off
				;
DO3:	CMP	CS:[DOGREEK],BYTE PTR 00H ; Greek allowed?
	JZ	SETCAPS		; No, continue
	MOV	CS:[INGREEK],BYTE PTR 0FFH ; Turn on greek
	JMP	SHORT SETCAPS	; And turn on caps...
				;
DO4:	CMP	CS:[DOGREEK],BYTE PTR 00H ; Greek allowed?
	JZ	SETCAPS		; No, continue
	MOV	CS:[INGREEK],BYTE PTR 00H ; Turn off greek
	JMP	SHORT SETCAPS	; And turn on caps...
				;
;************************************************************************
;*									*
;*	DOCAPS:  This routine handles the set/reset of caps lock.	*
;*	Accepts:  [FORM7] switch, [CURSOR] location.  Returns:		*
;*	Nothing.  Calls:  SETCAPS, RESETCAPS.  Clobbers:  SI,DI,AL	*
;*									*
;************************************************************************
				;
DOCAPS:	CMP	CS:[FORM7],BYTE	PTR 00H	; Form7 filter on?
	JZ	NOSET		; No, skip
	MOV	SI,CS:[CURSOR]	; Get current location
	CALL	FINDSEMI1	; Look for semi-colon
	JZ	FUZZY		; Found, process...
	MOV	CS:[INGREEK],BYTE PTR 00H ; Turn off greek
	JMP	SHORT SETCAPS	; Not found, turn on caps...
				;
FUZZY:	CMP	CS:[DOGREEK],BYTE PTR 00H ; Greek allowed?
	JZ	NOGREEK		; No
	MOV	CS:[INGREEK],BYTE PTR 0FFH ; Turn on greek
				;
NOGREEK:SUB	SI,DI		; Get difference between current loc and semi
	JZ	SETCAPS		; Right on semi, turn on caps...
	CMP	SI,0001H	; First after, always on...
	JZ	SETCAPS		; Leave on
	CMP	SI,0003H	; 3rd after, always off...
	JAE	RESETCAPS	; Dump it
				; Must be 2 after...
	MOV	AL,CS:[CMTSP]	; Space after semi colon?
	OR	AL,AL		; Force flags
	JNZ	SETCAPS		; Space used, turn on
	JMP	SHORT RESETCAPS	; No space used, turn off
				;
SETCAPS:PUSH	AX		; Save ax
	PUSH	ES		; Save es
	MOV	AX,0040H	; Segment 40
	MOV	ES,AX		; Into extra seg
	OR	ES:[0017H],BYTE	PTR 40H	; Set caps lock status
CEXIT:	POP	ES		; Restore registers
	POP	AX		; Including ax
NOSET:	RET			; Go home
				;
RESETCAPS:			;
	PUSH	AX		; Save registers
	PUSH	ES		; Save file segment
	MOV	AX,0040H	; Segment 40
	MOV	ES,AX		; Into extra
	AND	ES:[0017H],BYTE	PTR 0BFH ; Reset caps lock
	JMP	SHORT CEXIT	; Save a couple of bytes...
				;
;***********************************************************************
; This takes care of turning on the auto-indent flag
;***********************************************************************
				;
CHKINDENT:			;
	CALL	CURSORCOL	; Compute the current column
	OR	DL,DL		; First column?
	JZ	IND1		; Yes, continue
	CMP	DL,08H		; Column 8?
	JNZ	SKIPIND		; No
	MOV	CS:[INDENT],BYTE PTR 000H ; Turn off indent
	JMP	SHORT SKIPIND	; Exit
				;
IND1:	MOV	SI,CS:[CURSOR]	; Get current location
	CMP	SI,CS:[LASTCHAR] ; At end?
	JZ	DOIND		; Yes, do indent
	MOV	AL,[SI]		; Get current character
	CMP	AL,0DH		; Cr?
	JZ	DOIND		; Yes
	CMP	AL,' '		; Space?
	JZ	DOIND		; Yes
	CMP	AL,09H		; Tab?
	JNZ	SKIPIND		; Ignore everything else
DOIND:	MOV	CS:[INDENT],BYTE PTR 0FFH ; Turn on indent
SKIPIND:RET			; Go home
				;
;************************************************************************
;*									*
;*	CHKEXT:  This routine checks for the presence of an extended	*
;*	keyboard.  Accepts:  Nothing.  Calls:  BIOS INT 16.  Returns:	*
;*	Status in AH, FF if extended, 00 if not.  Clobbers:  AX 	*
;*									*
;************************************************************************
				;
CHKEXT:	PUSH	ES		; Save es
	XOR	AX,AX		; Segment 0
	MOV	ES,AX		; Into es
	MOV	AH,12H		; Try an extended shift status call
	INT	16H		; Call bios
	XOR	AH,AH		; If not
	CMP	ES:AL,[0417H]	; Check status byte in low mem
	JNZ	REG		; No extended kyb there
	XOR	ES:BYTE	PTR [0417H],80 ; Toggle insert state
	MOV	AH,12H		; Do another extended shift status call
	INT	16H		; Call bios
	XOR	AH,AH		; If not...
	CMP	ES:AL,[0417H]	; Check status byte again
	PUSHF			; Save flags
	XOR	ES:BYTE	PTR [0417H],80 ; Toggle insert back to original
	POPF			; Restore flags
	JNZ	REG		; Not tracking, not an extended bios
	MOV	AX,0305H	; Reset keyboard typmatic to default
	MOV	BX,010BH	; Default values
	INT	16H		; Go do it
	MOV	AH,0FFH		; Flag extended ok
REG:	POP	ES		; Give back es
	RET			; Go home
				;
;************************************************************************
;*  This strips (zeros) bit 7 of the entire file			*
;************************************************************************
				;
STRIP:	CMP	CS:[DOGREEK],BYTE PTR 00H ; Greek turned on?
	JNZ	STRIPPER	; Yes, abort
				;
	XOR	SI,SI		; Start at beginning of file
	MOV	CS:CX,CS:[LASTCHAR] ; Get number of characters
	JCXZ	STRIPPED	; Nothing to do
	MOV	CS:[CHANGE],BYTE PTR 0FFH ; Indicate file change
	MOV	AL,7FH		; And value
STRIPLP:AND	[SI],AL		; Mask out bit 8
	CMP	BYTE PTR [SI],00H ; Any nulls?
	JNZ	STRIPOK		; None there or created
	MOV	[SI],BYTE PTR ' ' ; Make into a space
STRIPOK:INC	SI		; Next
	LOOP	STRIPLP		; Do all
	MOV	CS:[DIRTYBITS],BYTE PTR	1 ; Redraw the screen
STRIPPED:			; Completely nude
	CALL	BEEP2		; Make noise
STRIPPER:			;
	RET			; Go home
				;
;************************************************************************
;*  This prints the marked text. If printer fails, it is canceled.	*
;************************************************************************
				;
ALLPRINT:			;
	MOV	CX,CS:[LASTCHAR] ; Length in cx
	JCXZ	PRTDONE		; Empty
	JMP	SHORT DOPRINT	; Continue
				;
PRINT:	PUSH	DS		; Save our ds
	CMP	CS:[DOMARK],BYTE PTR 0FFH ; Is there anything marked?
	JNE	ALLPRINT	; No, print the entire file
				;
	CMP	CS:[MARKMODE],BYTE PTR 0FFH ; Are we still defining the block?
	JE	PRTDONE		; Yes, can't print yet
				;
	MOV	CX,CS:[PASTESEG] ; Get segment
	MOV	DS,CX		; Into ds
	MOV	CX,CS:[PASTESIZE] ; Number of bytes
	JCXZ	PRTDONE		; If nothing to print, return
				;
DOPRINT:CALL	INHIBIT		; No auto-save
	MOV	AH,2		; Get status function
	XOR	DH,DH		; Select printer
	MOV	DL,CS:[PRNPTR]	; Get current printer, 0-2
	INT	17H		; Get printer status
	TEST	AH,10000000B	; Is busy bit set?
	JZ	NOPRINT		; Yes, abort
	TEST	AH,00100000B	; Is printer out of paper?
	JNZ	NOPRINT		; Yes, abort
	PUSH	CX		; Save number to print
	XOR	DL,DL		; First column
	MOV	SI,OFFSET PRINTMESS ; Point to message
	CALL	PRTLST		; Display busy message
	POP	CX		; Restore number to print
	XOR	SI,SI		; Start at zero in paste buffer or file
				;
	CMP	CS:[USEHP],BYTE	PTR 00H	; Use hp driver?
	JZ	PRTLP		; No
	CALL	SENDRST		; Reset printer
	CALL	SWLAT		; Put into latin mode
	JMP	SHORT GRPRTLP	; Print with driver...
				;
PRTLP:	LODSB			; Get character to print
	CALL	RAWPRINT	; Send to bios
	JC	NOPRINT		; If set, quit printing
	CALL	CONSTAT		; See if any keys
	JNZ	CHKITG		; Yes, see what they are...
	LOOP	PRTLP		; None, do next char
PRTABORT:			;
	MOV	AL,CR		; End with a cr
	XOR	AH,AH		; Print character
	INT	17H		; Send that cr
PRTDONE:CALL	BEEP3		; Beep
CAST:	POP	DS		; Restore orginal
	CALL	REDOPROMPT	; Re-draw prompt
	MOV	CS:[TICS],WORD PTR 00H ; Zero auto-save tick counter
	CMP	CS:[USEHP],BYTE	PTR 00H	; Use hp driver?
	JZ	CONDO		; No
	CALL	SENDRST		; Reset printer
CONDO:	RET			; Go home
				;
NOPRINT:XOR	DL,DL		; First column
	MOV	SI,OFFSET NOPRINTMESS ; Point to message
	CALL	PRTLST		; Display busy message
	MOV	CS:[TICS],WORD PTR 00H ; Zero auto-save tick counter
	CALL	WAITT		; Wait for user to press <esc>
	JMP	SHORT CAST	; And exit...
				;
CHKITG:	CALL	GETCH1		; Get character
	CMP	AL,1BH		; Escape?
	JZ	PRTABORT	; Yes, abort
	CMP	AL,15H		; ^u?
	JZ	PRTABORT	; Yes, abort
				;
				; Put another check in for 'use driver'
	LOOP	GRPRTLP		; Ignore others
				;
	LOOP	PRTLP		; Ignore others
	JMP	SHORT PRTABORT	; Unless done...
				;
GRPRTLP:LODSB			; Get character to print
	CALL	PRTCONVERT	; Convert it
	PUSHF			; Save flags
	CALL	RAWPRINT	; Send to bios
	POP	DX		; Recover flags (pushed as flags)
	JC	NOPRINT		; If set, quit printing
	PUSH	DX		; Stuff flags back on the stack...
	POPF			; And recover into flags reg.
	JNC	NOBS		; No backspace necessary....
	CALL	SENDBS		; Send bs and accent
	JC	NOPRINT		; Time-out
				;
NOBS:	CALL	CONSTAT		; See if any keys
	JNZ	CHKITG		; Yes, see what they are...
	LOOP	GRPRTLP		; None, do next char
	JMP	SHORT PRTABORT	; Done
				;
PRTCONVERT:			; Convert char in al to greek equivilant for prn
	CMP	AL,80H		; Is it greek?
	JAE	NEXTPRT		; Yes...
	CMP	CS:[PRGREEK],BYTE PTR 00H ; In ascii mode?
	JZ	ASCII		; Yes, all ok
	CALL	SWLAT		; Switch to latin characters
ASCII:	RET			; No, no conversion needed
				;
NEXTPRT:CMP	CS:[PRGREEK],BYTE PTR 0FFH ; In greek mode?
	JZ	GRKOK		; Yes, all ok
	CALL	SWGRK		; Switch to greek characters
				;
GRKOK:	PUSHA			; Save everything
	PUSH	DS		; Save data segment
	PUSH	ES		; And extra
	PUSH	CS		; Get code segment
	PUSH	CS		; Get code segment
	POP	DS		; Into data segment
	POP	ES		; And extra segment
	MOV	DI,OFFSET VTABLE ; Point to accented vowels table
	MOV	CX,000EH	; Number of entries in table
	MOV	SI,CX		; Remember for later
	REPNZ	SCASB		; Look for entry
	JNZ	NOTACC1		; No find, not accented, abort
	SUB	SI,CX		; Generate offset
	DEC	SI		; Compensate for 0 entry array
	ADD	SI,OFFSET PTABLE ; Add in offset of accented vowel table
	LODSB			; Get final, accented value.
	MOV	CS:[TEMP0],AL	; Store it
	POP	ES		; Restore extra segment
	POP	DS		; Restore data segment
	POPA			; Restore everything
	MOV	AL,CS:[TEMP0]	; Recover value
	STC			; Say 'add accent'
	RET			; And go print it!
				;
NOTACC1:MOV	CX,0035H	; Number of entries left in table
	MOV	SI,CX		; Remember for later
	REPNZ	SCASB		; Look for entry
	JNZ	GARBAGE		; No find, not greek, but some other garbage
	SUB	SI,CX		; Generate offset
	DEC	SI		; Compensate for 0 entry array
	ADD	SI,OFFSET PTABLE1 ; Add in offset of main print table
	LODSB			; Get final value.
GARBAGE:MOV	CS:[TEMP0],AL	; Store it
	POP	ES		; Restore extra segment
	POP	DS		; Restore data segment
	POPA			; Restore everything
	MOV	AL,CS:[TEMP0]	; Recover value
	CLC			; Say 'do not add accent'
	RET			; And go print it
				;
SIMPLP:	LODSB			; Simple printer loop
	CALL	RAWPRINT	; Send to bios
	JC	ENDLP		; If set, quit printing
	LOOP	SIMPLP		; None, do next char
	CLC			; Everything okok
ENDLP:	RET			; Go home
				;
SENDBS:	PUSHA			; Save all
	LEA	SI,PRBS		; Point to backspace and accent
	MOV	CX,0002H	; 2 characters
	JMP	SHORT SENDALL	; Continue
				;
SENDRST:PUSHA			; Save all
	LEA	SI,PRNRST	; Point to printer reset command
	MOV	CX,0002H	; 2 characters
	JMP	SHORT SENDALL	; Continue
				;
SWGRK:	PUSHA			; Save all
	MOV	CS:[PRGREEK],BYTE PTR 0FFH ; Switch to greek alphabet
	LEA	SI,GOGRK	; Switch to greek
	MOV	CX,0005H	; 5 characters
	JMP	SHORT SENDALL	; Continue
				;
SWLAT:	PUSHA			; Save all
	MOV	CS:[PRGREEK],BYTE PTR 00H ; Switch to latin alphabet
	LEA	SI,GOLAT	; Switch to latin
	MOV	CX,0005H	; 5 characters
	JMP	SHORT SENDALL	; Continue
				;
SENDALL:PUSH	DS		; Save current ds
	PUSH	CS		; Get this seg
	POP	DS		; Into ds
	CALL	SIMPLP		; Print string
	POP	DS		; Restore ds
	POPA			; Restore
	RET			; Go home
				;
RAWPRINT:			; Bios printer interface
	XOR	DH,DH		; Select printer
	MOV	DL,CS:[PRNPTR]	; Get current printer, 0-2
	XOR	AH,AH		; Service 0, print al
	INT	17H		; Print the character
	ROR	AH,1		; Check time out bit
	RET			; Go home with carry set if time-out
				;
PRBS:				;
	DB	08H,0A2H	; To create accents
GOGRK:				;
	DB	1BH,'(19M'	; Enter greek
PRNRST:				;
	DB	1BH,'E'		; Reset printer
GOLAT:				;
	DB	1BH,'(17U'	; Enter latin
				;
				; Printer driver translation tables
PTABLE:				; *must* remain in same order as vtable, et. al.
				; Accented chars=norm followed by <bs><'>
	DB	041H		; Upper case accented alpha
	DB	045H		; Upper case accented epsilon
	DB	048H		; Upper case accented eeta
	DB	049H		; Upper case accented iota
	DB	04FH		; Upper case accented omicron
	DB	057H		; Upper case accented omega
	DB	055H		; Upper case accented eepsilon
				;
	DB	061H		; Lower case accented alpha
	DB	065H		; Lower case accented epsilon
	DB	068H		; Lower case accented eeta
	DB	069H		; Lower case accented iota
	DB	06FH		; Lower case accented omicron
	DB	077H		; Lower case accented omega
	DB	075H		; Lower case accented eepsilon
				;
				; Upper case greek to print translation table
				;
PTABLE1:DB	041H		; A maps to alpha
	DB	042H		; B maps to veeta
	DB	059H		; C maps to psee
	DB	044H		; D maps to thelta
	DB	045H		; E maps to epsilon
	DB	046H		; F maps to phi
	DB	047H		; G maps to ghamma
	DB	048H		; H maps to eeta
	DB	049H		; I maps to iota
	DB	058H		; J maps to ksee
	DB	04BH		; K maps to kappa
	DB	04CH		; L maps to lambda
	DB	04DH		; M maps to mi
	DB	04EH		; N maps to ni
	DB	04FH		; O maps to omicron
	DB	050H		; P maps to pi
	DB	0B0H		; Q maps to greek semi-colon
	DB	052H		; R maps to rho
	DB	053H		; S maps to sigma
	DB	054H		; T maps to taf
	DB	051H		; U maps to theta
	DB	057H		; V maps to omega
	DB	053H		; W maps to sigma (for finial)
	DB	043H		; X maps to hee
	DB	055H		; Y maps to eepsilon
	DB	05AH		; Z maps to zeeta
				;
				; Lower case ascii to greek translation table
				;
	DB	061H		; A maps to alpha
	DB	062H		; B maps to veeta
	DB	079H		; C maps to psee
	DB	064H		; D maps to thelta
	DB	065H		; E maps to epsilon
	DB	06AH		; F maps to phi (66 alternate)
	DB	067H		; G maps to ghamma
	DB	068H		; H maps to eeta
	DB	069H		; I maps to iota
	DB	078H		; J maps to ksee
	DB	06BH		; K maps to kappa
	DB	06CH		; L maps to lambda
	DB	06DH		; M maps to mi
	DB	06EH		; N maps to ni
	DB	06FH		; O maps to omicron
	DB	070H		; P maps to pi
	DB	03BH		; Q maps to greek question mark (;) shouldn't see
	DB	072H		; R maps to rho
	DB	073H		; S maps to sigma
	DB	074H		; T maps to taf
	DB	071H		; U maps to theta
	DB	077H		; V maps to omega
	DB	056H		; W maps to finial sigma
	DB	063H		; X maps to hee
	DB	075H		; Y maps to eepsilon
	DB	07AH		; Z maps to zeeta
				;
;************************************************************************
;*			Shell to MS-DOS feature.			*
;************************************************************************
				;
SHELL:	CMP	CS:[DOAUTO],BYTE PTR 0 ; Is auto-save on?
	JZ	NOAUTO1		; No
	CMP	CS:[CHANGE],BYTE PTR 0 ; Is the file changed?
	JZ	NOAUTO1		; No, why bother...
	CMP	CS:[CHANGE],BYTE PTR 55H ; Already auto-saved?
	JZ	NOAUTO1		; Yes, skip.
				;
	MOV	CS:[AUTO],BYTE PTR 0FFH	; Setup for auto-save
	CALL	SAVE		; Save file
				;
NOAUTO1:PUSH	DS		; Save ds
	PUSH	ES		; And es
				;
	CALL	CLS		; Clear screen
				;
	MOV	CS:[0080H],BYTE	PTR 00H	; Null out command line length
				;
	MOV	CS:BX,[002CH]	; Get environment pointer
	MOV	ES,BX		; Into es
	XOR	DI,DI		; Start at offset zero in this segment
	MOV	AX,DI		; Looking for zeros
SHELLLP:SCASB			; Check
	JNZ	SHELLLP		; Not zero
	SCASB			; Found 1 zero, is there another?
	JNZ	SHELLLP		; No
	MOV	BX,DI		; Yes, double zero is end of environment
	CMP	DI,08H		; Must be at least 8 to include a compspec
	JBE	NOCOMSPEC	; No comspec
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	XOR	DI,DI		; Point back to beginning of environment
	LEA	SI,CSNAME	; Point to "COMSPEC" name
	MOV	CX,0008H	; Name is 8 bytes long
	CALL	FINDSUB		; Find the damn string
	JZ	NOCOMSPEC	; No comspec, hope the path works....
				;
	MOV	AX,ES		; Cannot do xchg es,ds
	MOV	BX,DS		; Get ds
	MOV	ES,BX		; Half the swap...
	MOV	DS,AX		; The other half!
				; Now the destination is this segment
				;
	ADD	DL,08H		; Point past the end of "COMSPEC="
	MOV	SI,DX		; Get start into si
	LEA	DI,CSSTORE	; Storage for comspec
GETLP:	LODSB			; Get byte (movsb doesn't go through al)
	STOSB			; Stash it
	OR	AL,AL		; Force flags
	JNZ	GETLP		; Not done yet
	LEA	DX,CSSTORE	; Point to our recovered comspec
	JMP	SHORT CONTT	; And go load it!
				;
NOCOMSPEC:			;
	LEA	DX,CSDFLT	; Let's hope that they can find, and run this!
CONTT:	PUSH	CS		; Fix ds
	POP	DS		; Done!
	PUSH	CS		; Es needs fixing if entered through nocomspec
	POP	ES		; Fixed.
	PUSH	DX		; Save filespec pointer
	MOV	CS:BX,[002CH]	; Get environment pointer
	MOV	CS:[PARBLOCK],BX ; And stash for child process
				;
	LEA	SI,PATHSTORE+1	; Point to path storage
	MOV	AH,47H		; Get directory function call
	XOR	DL,DL		; Current drive
	INT	21H		; It's stored
				;
	MOV	AH,19H		; Get current drive function call
	INT	21H		; Do it
	MOV	CS:[DSTORE],AL	; Stash it
				;
	MOV	AH,03H		; Get cursor function call
	INT	10H		; Go get it
	MOV	CS:[RCURSOR],DX	; Save for later
				;
	XOR	DX,DX		; Set cursor at top of screen
	MOV	BH,DH		; Page 0
	MOV	AH,02H		; Set cursor function call
	INT	10H		; Do it
				;
	PUSH	ES		; Save es
	MOV	AX,0040H	; Segment 40
	MOV	ES,AX		; Into extra seg
	MOV	AL,ES:[0017H]	; Get caps lock status
	POP	ES		; Restore es
	AND	AL,40H		; Mask out caps lock status
	MOV	CS:[CAPLCK],AL	; And remember...
	CMP	CS:[FORM7],BYTE	PTR 00H	; Form7 filter on?
	JZ	VEIL		; No, skip
	CALL	SETCAPS		; Caps lock on when we drop to mush-dos...
				;
VEIL:	POP	DX		; Recover filespec pointer
	MOV	AX,SP		; Get our sp
	MOV	CS:[OLDSTACK],AX ; Stash our sp
	MOV	AX,SS		; Get our ss
	MOV	CS:[STACKSEG],AX ; Stash our ss
	MOV	AX,4B00H	; Load and execute it
	LEA	BX,PARBLOCK	; Point to parameter block
	MOV	CS:[CMDSEG],CS	; Stuff cs into cmdseg
	INT	21H		; Go shell to dos
				;
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	PUSH	CS		; Again
	POP	ES		; Into es
	CLI			; No ints
	MOV	AX,CS:[STACKSEG] ; Get old ss
	MOV	SS,AX		; Into ss
	MOV	AX,CS:[OLDSTACK] ; Get old sp
	MOV	SP,AX		; Into sp
	STI			; Ints back on
				;
	MOV	CS:DL,[DSTORE]	; Get old drive
	MOV	AH,0EH		; Select drive function
	INT	21H		; Do it
				;
	LEA	CS:DX,PATHSTORE	; Point to old path
	MOV	AH,3BH		; Cd function
	INT	21H		; Do it
				;
	MOV	CS:DX,[RCURSOR]	; Get old location
	XOR	BH,BH		; Page 0
	MOV	AH,02H		; Set cursor function call
	INT	10H		; Do it
				;
	MOV	CS:AL,[CAPLCK]	; Get old caps lock status
	OR	AL,AL		; Force flags
	JZ	LOWER		; Reset it
	CALL	SETCAPS		; Set it
	JMP	SHORT ATLAS	; Continue
				;
LOWER:	CALL	RESETCAPS	; Turn off
				;
ATLAS:	POP	ES		; Restore es
	POP	DS		; And ds
				;
	CMP	CS:[DOGREEK],BYTE PTR 00H ; Greek enabled?
	JZ	HELLAS		; No
	CALL	LOADFONT	; Load greek fonts
	CALL	RECUT		; Greek fontload clobbers paste buffer, reinit!
				;
HELLAS:	MOV	CS:[DIRTYBITS],	BYTE PTR 1 ; Refresh screen when done
	CALL	REDOPROMPT	; Redraw status line
	MOV	CS:[TICS],WORD PTR 00H ; Zero auto-save tick counter
	MOV	CX,010BH	; Set cursor size
	MOV	AH,01H		; To block cursor
	INT	10H		; Do it
	RET			; Near
				;
PARBLOCK:			;
	DW	0000H		; Segment of environment string
	DW	0080H		; Cmd line ptr
CMDSEG:	DW	0000H		; Cmd line segment
	DW	0FFFFH		; 1st fcb
	DW	0FFFFH		;
	DW	0FFFFH		; 2nd fcb
	DW	0FFFFH		;
				;
STACKSEG:			;
	DW	0000H		; Storage for old stack segment
OLDSTACK:			;
	DW	0000H		; Storage for old stack pointer
CSNAME:				;
	DB	'COMSPEC='	; Comspec name
CSDFLT:				;
	DB	'\COMMAND.COM'	; Default comspec if none found
CSSTORE:			;
	BLKB	64D		; Allow up to 64 bytes for pathname
DSTORE:				;
	DB	00H		; Storage for drive
PATHSTORE:			;
	DB	'\'		; Leading backslash
	BLKB	64D		; Storage for path
RCURSOR:DW	0000H		; Storage for screen cursor
				;
GETCH:	PUSH	DS		; Save ds
	MOV	AX,0040H	; Low ram segment
	MOV	DS,AX		; Into ds
	MOV	DS:AL,[0017H]	; Grab keyboard status byte
	POP	DS		; Restore ds
	AND	AL,04H		; Mask out control key
	CMP	AL,CS:OLDCTRL	; As before?
	JZ	GETCH1		; Yes, no problem
	MOV	CS:[OLDCTRL],AL	; Save new status
	PUSHA			; Save the world
	CALL	REDOPROMPT	; Fix prompt
	POPA			; Restore the world
				;
GETCH1:	CMP	CS:[DOAUTO],BYTE PTR 0 ; Is auto-save on?
	JZ	NOAUTO		; No
	CMP	CS:[CHANGE],BYTE PTR 0 ; Is the file changed?
	JZ	NOAUTO		; No, why bother...
	CMP	CS:[CHANGE],BYTE PTR 55H ; Already auto-saved?
	JZ	NOAUTO		; Yes, skip.
				;
	CMP	CS:[TICS],WORD PTR 1092D*3 ; 3 minutes since last keypress?
	JB	NOAUTO		; No
	MOV	CS:[AUTO],BYTE PTR 0FFH	; Setup for auto-save
	CALL	SAVE		; Save file
	MOV	DX,CS:[CURPOSN]	; Get screen cursor position
	CALL	SETCURSOR	; And put it back
	CALL	BEEP3		; Make noise
				;
NOAUTO:	CALL	CONSTAT		; Anything there?
	JZ	GETCH		; No, try auto-save again....
	XOR	AH,AH		; Read the next key
	MOV	AL,CS:[EXTEND]	; Get keyboard type
	AND	AL,10H		; Mask out un-needed bits
	OR	AH,AL		; Or in to form extended request if configured
	INT	16H		; Go get it
	RET			; And go home
				;
CONSTAT:MOV	AH,1		; Get keyboard status
	MOV	AL,CS:[EXTEND]	; Get keyboard type
	AND	AL,10H		; Mask out un-needed bits
	OR	AH,AL		; Or in to form extended request if configured
	INT	16H		; Any keys ready?
	JZ	STATRET		; No key ready, skip next
	MOV	CS:[TICS],WORD PTR 00H ; Zero auto-save tick counter
STATRET:RET			; Go home
				;
;************************************************************************
;*									*
;*	BUFFIN:  This routine emulates the MS-DOS function 0A,		*
;*	Buffered Keyboard input.  The difference is that this routine	*
;*	implements it in the CP/M manner, with full support for 	*
;*	control-X, rather than the MS-DOS manner with it's poor 	*
;*	implementation of <ESC> as control-U.  Furthermore, this	*
;*	routine also implements the WordStar convention of <ESC>	*
;*	AND control-U to mean "abort function". 			*
;*	Accepts:  Buffer pointer in DX.  Returns:  String in buffer	*
;*	as per function 10 specification with carry CLEAR, unless	*
;*	control-U or <ESC> was pressed, (or 10 second time-out) 	*
;*	in which case the buffer data is meaningless, and carry is SET. *
;*									*
;*	Calls:	MS-DOS.  Clobbers:  Nothing.				*
;*									*
;************************************************************************
				;
BUFFIN:	PUSHA			; Save all registers
	PUSH	DS		; And segments
	PUSH	ES		; Es too...
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	PUSH	DS		; Get this segment again
	POP	ES		; Into es
	PUSH	DX		; Save entry pointer
	MOV	DI,DX		; Get buffers
	MOV	BL,[DI]		; Get max number of characters allowed
	INC	DI		; Point to returned character number
	MOV	SI,DI		; In si
	MOV	AL,[SI]		; Get old count
	MOV	CS:[TEMP1],AL	; And remember it for ^r
	MOV	[SI],BYTE PTR 00H ; Zero current chars
GOAGAIN:INC	DI		; Di is now at start of buffer
	MOV	CS:[NOCASE],BYTE PTR 00H ; You can case sensitvity question
				; For now...
				;
BUFFLP:	CALL	CONSTAT		; Check for next key...
	JNZ	BUFFLP1		; Something there...
	CMP	CS:[TICS],WORD PTR 1092D/6 ; 10 seconds since we got here?
	JB	BUFFLP		; No
	CALL	BEEP2		; Make noise
	JMP	BUFABORT	; Guy is asleep at the switch...
				;
BUFFLP1:MOV	AH,07H		; Do direct console input
	INT	21H		; Go do it
	OR	AL,AL		; Null?
	JNZ	NOTNUL		; No
	MOV	AH,07H		; Extended keypress...
	INT	21H		; Go get it
	CMP	AL,4CH		; Middle of numeric keypad "OMNI" key...
	JZ	NAIOMNI		; Yes
	CMP	AL,5EH		; ^f1 greek toggle?
	JNZ	BUFFLP		; No ignore rest
NAIOMNI:CMP	CS:[DOGREEK],BYTE PTR 00H ; Do greek?
	JZ	BUFFLP		; No, ignore
	NOT	CS:BYTE	PTR [INGREEK] ; Toggle ingreek flag
	MOV	CS:[ACCNEXT],BYTE PTR 00H ; Turn off accent next
	JMP	SHORT BUFFLP	; And try again!
				;
NOTNUL:	CMP	AL,1BH		; Escape?
	JZ	BUFABORT	; Abort
	CMP	AL,15H		; Control-u?
	JZ	BUFABORT	; Abort
	CMP	AL,12H		; Control-r?
	JZ	RESTORE		; Restore any previous characters...
	CMP	AL,18H		; Control-x?
	JZ	RESTART		; Clear back and restart
	CMP	AL,0DH		; Cr?
	JZ	BUFEND		; Done
	CMP	AL,08H		; Backspace?
	JZ	BACKUP		; Yes, backup
	CMP	BL,[SI]		; Buffer full?
	JA	NOTFULL		; No
	CALL	BEEP1		; Beep
	JMP	SHORT BUFFLP	; And ignore...
				;
NOTFULL:CALL	GRFILT		; Filter greek if enabled
	OR	AL,AL		; Force flags
	JZ	BUFFLP		; Accent toggle, ignore
	STOSB			; Store character
	INC	BYTE PTR [SI]	; Increment character count
	CALL	PCHAR		; Write character
	JMP	SHORT BUFFLP	; Go again...
				;
RESTORE:MOV	CL,CS:[TEMP1]	; Get old number
	SUB	CL,[SI]		; Dump count already used...
	JBE	BUFFLP		; Nothing to do
	XOR	CH,CH		; Zero upper count
RESLP:	MOV	AL,[DI]		; Get old character
	STOSB			; Increment pointer and re-write character
	INC	BYTE PTR [SI]	; Increment character count
	CALL	PCHAR		; Write character to screen
	LOOP	RESLP		; Do remaining
OUTTAZ:	JMP	BUFFLP		; Go again...
				;
RESTART:MOV	CL,[SI]		; Get current number
	XOR	CH,CH		; Zero upper
RLP:	MOV	AL,08H		; Backspace
	CALL	PCHAR		; Send it
	MOV	AL,' '		; Destructive...
	CALL	PCHAR		; Send it
	MOV	AL,08H		; Backspace again
	CALL	PCHAR		; Send it
	LOOP	RLP		; Do until empty
	MOV	[SI],BYTE PTR 00H ; Zero current chars
	MOV	DI,SI		; Get current chars location
	JMP	GOAGAIN		; And try again
				;
BACKUP:	CMP	BYTE PTR [SI],00H ; At start of buffer?
	JZ	OUTTAZ		; Yes, no backup
	CALL	PCHAR		; Print backspace
	MOV	AL,' '		; Destructive
	CALL	PCHAR		; Print it
	MOV	AL,08H		; Back up again
	CALL	PCHAR		; Screen now fixed
	DEC	BYTE PTR [SI]	; Decrement character count
	DEC	DI		; Decrement character pointer
	JMP	BUFFLP		; Try again
				;
BUFEND:	STOSB			; Store cr (but don't inc anything)
	CLC			; Indicate normal exit
	JMP	SHORT BUFEXIT	; And exit
BUFABORT:			;
	STC			; Indicate aborted exit
BUFEXIT:POP	SI		; Recover entry pointer (pushed as dx)
	INC	SI		; Point to return count byte
	PUSHF			; Save flags
	MOV	AH,80H		; Looking for any bit set characters
	LODSB			; Get return count
	MOV	CL,AL		; Into cl
	XOR	CH,CH		; Zero upper
CKLP:	LODSB			; Get character
	CMP	AH,AL		; If bit set, assume greek presence
	JB	ITSHERE		; Its here
	LOOP	CKLP		; Check entire string
	JMP	SHORT ELLADA	; We're outta here
				;
ITSHERE:MOV	CS:[NOCASE],BYTE PTR 0FFH ; Turn case question off
				;
ELLADA:	POPF			; Restore flags
	POP	ES		; Restore segments
	POP	DS		;
	POPA			; Everything else
	RET			; Go home
				;
PSTRING:PUSH	SI		; Save si
	PUSH	DS		; And ds
	PUSH	CS		; Get this segment
	POP	DS		; Into ds
	MOV	SI,DX		; Get input
PLP:	LODSB			; Get character
	OR	AL,AL		; Force flags
	JZ	PEXIT		; Exit if end
	CMP	AL,1FH		; Control code?
	JA	E300		; No
	CALL	DOCONT		; Yes, use dos...
	JMP	SHORT PLP	; And go for next
				;
E300:	CMP	AL,0FFH		; Special terminator?
	JZ	SPECIAL		; Yes
	CALL	PCHAR		; Print character
	JMP	SHORT PLP	; Go for next
SPECIAL:MOV	AL,LF		; Send a line feed
	CALL	DOCONT		; Send it
				; And drop on out
PEXIT:	POP	DS		; Restore ds
	POP	SI		; And si
	RET			; Go home
				;
DOCONT:	MOV	AH,02H		; Print function
	MOV	DL,AL		; Character in dl
	INT	21H		; Go do control characters
	RET			; Go home
				;
PCHAR:	PUSH	CX		; Save cx
	MOV	BP,BX		; Remember...
	CMP	AL,08H		; Backspace?
	JZ	EINSPRITZ	; Yes, handle
	MOV	AH,09H		; Console output service
	MOV	BL,[NORMAL]	; Get color attribute
	AND	BL,7FH		; Supress blinky bit
	XOR	BH,BH		; Video page 0
	MOV	CX,0001H	; One time
	INT	10H		; Go do it
	MOV	AH,03H		; Get cursor location
	INT	10H		; Go get it
	INC	DL		; Next cursor location
MOVEIT:	MOV	AH,02H		; Set cursor position
	INT	10H		; Go set it
	MOV	BX,BP		; Restore bx
	POP	CX		; And cx
	RET			; Go home
				;
EINSPRITZ:			;
	XOR	BH,BH		; Video page 0
	MOV	AH,03H		; Get cursor location
	INT	10H		; Go get it
	DEC	DL		; Backup one
	JMP	SHORT MOVEIT	; Move it and exit
				;
CHKSUM:	LEA	SI,COPYRIGHT	; Start of checksummed range
	LEA	AX,CEND		; End of code address
	SUB	AX,SI		; Generate length
	SHR	AX,1		; Divide in half for word loop
	MOV	CX,AX		; Put in cx
	XOR	BX,BX		; Do a 16 bit checksum
CHECKLP:LODSW			; Get word
	ADD	BX,AX		; Add in checksum
	LOOP	CHECKLP		; Check out entire program
	MOV	AX,BX		; Store result in ax
	RET			; Go home
				;
;************************************************************************
;*									*
;*	FIXUNIX:  This routine "fixes" LF-only UNIX files and CR-only	*
;*	Mac/TRS-80 files by adding a CR or LF as required.  Accepts:	*
;*	Nothing.  Returns:  Nothing.  Calls:  INSERTCHAR.		*
;*	Clobbers: AX, SI, CX						*
;*									*
;************************************************************************
				;
FIXUNIX:PUSH	WORD PTR CS:[CURSOR] ; Save our current location in file
	MOV	CS:CX,[LASTCHAR] ; Get number of characters
	XOR	SI,SI		; Start at zero in file
	JCXZ	PAW		; Nothing here....
				;
LFLOOP:	LODSB			; Get char
	OR	AL,AL		; Looking for a null
	JZ	NULEDO		; Yep...
	CMP	AL,0AH		; Line feed?
	JZ	LFEDO		; Line feed found...
	CMP	AL,0DH		; Carriage return?
	JZ	CREDO		; Cr found...
	JCXZ	PAW		; No line feeds or carriage returns!
	JMP	SHORT SHEMADAN	; Nope, try again
				;
LFEDO:	CMP	SI,0001H	; Was this the very first character?
	JZ	VERYFIRST	; Yes, no preceding cr possible!
				;
	CMP	[SI]-2,	BYTE PTR 0DH ; A preceeding carriage return?
	JZ	SHEMADAN	; Yes, no problem.
				;
VERYFIRST:			;
	MOV	AL,0DH		; Get a carriage return
	PUSHA			; Save
	DEC	SI		; Backup to comp for lodsb
FIXEOF:	MOV	CS:[CURSOR],SI	; Set pointer
	CALL	INSERTCHAR	; Insert it (skip greek filter for speed)
	POPA			; Recover
	INC	CX		; Compensate length
SHEMADAN:			;
	LOOP	LFLOOP		; And look some more...
				;
PAW:	POP	SI		; Recover original location
				; (pushed as cs:[cursor])
	CALL	MOVE		; Go back to previous location...
	RET			; Go home
				;
CREDO:	CMP	[SI],BYTE PTR 0AH ; Line feed after cr?
	JZ	SHEMADAN	; Yes, no problem
	MOV	AL,0AH		; Get line feed
	PUSHA			; Save everything
	JMP	SHORT FIXEOF	; And fix the problem...
				;
NULEDO:	MOV	[SI]-1,BYTE PTR	20H ; Replace nulls with space
	JMP	SHORT SHEMADAN	; And go again
				;
;************************************************************************
;*									*
;*	LOADFONT:  This routine loads our custom Greek font.  It	*
;*	only works with EGA and above.	It loads a 14x8 font for	*
;*	EGA compatablity.  Accepts:  Nothing.  Returns:  Nothing	*
;*	Calls:	BIOS.  Clobbers:  Nothing				*
;*									*
;************************************************************************
				;
LOADFONT:			;
	PUSHA			; Save everything
	PUSH	DS		; Including segments
	PUSH	ES		;
				;
	CMP	CS:[FIXOMEGA],BYTE PTR 00H ; Need to fixup omega?
	JNZ	OMEGAOK		; No
	PUSH	CS		; Get cs
	PUSH	CS		; Get cs twice
	POP	DS		; Into ds
	POP	ES		; And es
	LEA	SI,OMEGAFIX	; Point to start of patch data
	LEA	DI,PATCH1	; Patch location
	MOV	CX,0009H	; Nine locations
	REP	MOVSB		; Copy 9 bytes
	LEA	SI,OMEGAFIX	; Point to start of patch data again...
	LEA	DI,PATCH2	; Patch location for accented omega
	MOV	CL,09H		; Re-init cx
	REP	MOVSB		; Copy 9 bytes again
				;
OMEGAOK:MOV	AL,CS:[DOMARK]	; Get  marking status
	PUSH	AX		; And save it
	MOV	CS:BYTE	PTR [DOMARK],00H ; Turn off marked text
	MOV	AX,0002H	; Service 00, set video mode
	INT	10H		; Go do it
				;
;************************************************************************
;*									*
;*	VGA cards have an annoying "feature" that causes bit 8 of	*
;*	any character between C0 and DF to be automaticly copied	*
;*	to a phantom 9th bit.  This section turns this off.		*
;*	Routine courtesey of brr@cat.syr.edu				*
;*									*
;************************************************************************
				;
	MOV	DX,03DAH	; Put reg 3c0 in addr mode
	IN	AL,DX		; Dummy read accomplishes this
	MOV	DL,0C0H		; Up to 3c0
	MOV	AL,30H		; 3c0 index 10, refresh enable
	OUT	DX,AL		; Select it
	INC	DX		; Point to data port
	IN	AL,DX		; Get it
	AND	AL,0FBH		; Turn off bit 2, the copy bit
				; If you want to enable copy replace above
				; Instruction with or al,4
	PUSH	AX		; Save
	MOV	DL,0DAH		; Put reg 3c0 in addr mode
	IN	AL,DX		; Dummy read accomplishes this
	MOV	DL,0C0H		; Up to 3c0
	MOV	AL,30H		; 3c0 index 10, refresh enable
	OUT	DX,AL		; Select it
	POP	AX		; Restore mod bit
	OUT	DX,AL		; This will suppress the copy
				;
;************************************************************************
				;
	MOV	AX,CS:[PASTESEG] ; Get paste buffer segment
	MOV	DS,AX		; Into ds
	MOV	ES,AX		; And es
	XOR	DI,DI		; Point to start of paste buffer
	MOV	CX,(256*16)/2	; 256 characters, 16 high, addressed as words
	XOR	AX,AX		; Zero everything
	CLD			; Run forward
	REP	STOSW		; Clear ram
				;
	XOR	BP,BP		; Point to blank font table in paste buffer
	MOV	CX,0100H	; 256 characters
	XOR	DX,DX		; Start with ascii 0
	MOV	BX,1000H	; 16 rows high, load into table 0
	MOV	AX,1100H	; Service 11, load user character set
	INT	10H		; Clear all rows of table 0
				;
	MOV	AX,CS		; Get cs
	MOV	DS,AX		; Into ds
	MOV	ES,AX		; And es
	MOV	BP,OFFSET FONT	; Point to font table
	MOV	CX,0100H	; 256 characters
	XOR	DX,DX		; Start with ascii 0
	MOV	BX,0E00H	; 14 rows high, load into table 0
	MOV	AX,1100H	; Service 11, load user character set
	INT	10H		; Do it
				;
	MOV	CX,010BH	; Set cursor size
	MOV	AH,01H		; To block cursor
	INT	10H		; Do it
				;
	POP	AX		; Recover marking status
	OR	AL,AL		; Force flags
	JZ	FEXIT		; Not on, exit
				;
	CALL	HIDE		; Toggle on
				;
FEXIT:	POP	ES		; Restore segments
	POP	DS		;
	POPA			; Everything else
	RET			;
				;
FONT:				;
	DB	00000000B	; 00 nul
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 00 nul
				;
	DB	00000000B	; 01 soh
	DB	01111110B	;
	DB	10000001B	;
	DB	10100101B	;
	DB	10000001B	;
	DB	10000001B	;
	DB	10111101B	;
	DB	10011001B	;
	DB	10000001B	;
	DB	10000001B	;
	DB	01111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 01 soh
				;
	DB	00000000B	; 02 stx
	DB	01111110B	;
	DB	11111111B	;
	DB	11011011B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11000011B	;
	DB	11100111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	01111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 02 stx
;
	DB	00000000B	; 03 etx
	DB	00000000B	;
	DB	00000000B	;
	DB	00110110B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	00111110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 03 etx
				;
	DB	00000000B	; 04 eot
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00111110B	;
	DB	01111111B	;
	DB	00111110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 04 eot
				;
	DB	00000000B	; 05 enq
	DB	00000000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00111100B	;
	DB	11100111B	;
	DB	11100111B	;
	DB	11100111B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 05 enq
;
	DB	00000000B	; 06 ack
	DB	00000000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	01111110B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 06 ack
				;
	DB	00000000B	; 07 bel
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00011110B	;
	DB	00011110B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 07 bel
				;
	DB	11111111B	; 08 bs
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11110011B	;
	DB	11100001B	;
	DB	11100001B	;
	DB	11110011B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	; 08 bs
				;
	DB	00000000B	; 09 tab
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	01000010B	;
	DB	01000010B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 09 tab
				;
	DB	11111111B	; 0a lf
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11000011B	;
	DB	10011001B	;
	DB	10111101B	;
	DB	10111101B	;
	DB	10011001B	;
	DB	11000011B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	;
	DB	11111111B	; 0a lf
				;
	DB	00000000B	; 0b vt
	DB	00001111B	;
	DB	00000111B	;
	DB	00001101B	;
	DB	00011001B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 0b vt
				;
	DB	00000000B	; 0c ff
	DB	00111100B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 0c ff
				;
	DB	00000000B	; 0d cr
	DB	00111111B	;
	DB	00110011B	;
	DB	00111111B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	01110000B	;
	DB	11110000B	;
	DB	11100000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 0d cr
				;
	DB	00000000B	; 0e so
	DB	01111111B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100111B	;
	DB	11100111B	;
	DB	11100110B	;
	DB	11000000B	;
	DB	00000000B	;
	DB	00000000B	; 0e so
				;
	DB	00000000B	; 0f si
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	11011011B	;
	DB	00111100B	;
	DB	11100111B	;
	DB	00111100B	;
	DB	11011011B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 0f si
				;
	DB	00000000B	; 10 dle
	DB	01000000B	;
	DB	01100000B	;
	DB	01110000B	;
	DB	01111000B	;
	DB	01111100B	;
	DB	01111111B	;
	DB	01111100B	;
	DB	01111000B	;
	DB	01110000B	;
	DB	01100000B	;
	DB	01000000B	;
	DB	00000000B	;
	DB	00000000B	; 10 dle
				;
	DB	00000000B	; 11 dc1
	DB	00000001B	;
	DB	00000011B	;
	DB	00000111B	;
	DB	00001111B	;
	DB	00011111B	;
	DB	01111111B	;
	DB	00011111B	;
	DB	00001111B	;
	DB	00000111B	;
	DB	00000011B	;
	DB	00000001B	;
	DB	00000000B	;
	DB	00000000B	; 11 dc1
				;
	DB	00000000B	; 12 dc2
	DB	00011000B	;
	DB	00111100B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	00111100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 12 dc2
				;
	DB	00000000B	; 13 dc3
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 13 dc3
				;
	DB	00000000B	; 14 dc4
	DB	01111111B	;
	DB	11011011B	;
	DB	11011011B	;
	DB	11011011B	;
	DB	01111011B	;
	DB	00011011B	;
	DB	00011011B	;
	DB	00011011B	;
	DB	00011011B	;
	DB	00011011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 14 dc4
				;
	DB	00000000B	; 15 nak
	DB	00111110B	;
	DB	01100011B	;
	DB	00110000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00000110B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	; 15 nak
				;
	DB	00000000B	; 15 syn
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 16 syn
				;
	DB	00000000B	; 17 etb
	DB	00011000B	;
	DB	00111100B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	00111100B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 17 etb
				;
	DB	00000000B	; 18 can
	DB	00011000B	;
	DB	00111100B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 18 can
				;
	DB	00000000B	; 19 em
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	00111100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 19 em
				;
	DB	00000000B	; 1a sub
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	01111111B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 1a sub
				;
	DB	00000000B	; 1b esc
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01111111B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 1b esc
				;
	DB	00000000B	; 1c fs
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 1c fs
				;
	DB	00000000B	; 1d gs
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00010100B	;
	DB	00110110B	;
	DB	01111111B	;
	DB	00110110B	;
	DB	00010100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 1d gs
				;
	DB	00000000B	; 1e rs
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00011100B	;
	DB	00111110B	;
	DB	00111110B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 1e rs
				;
	DB	00000000B	; 1f us
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	00111110B	;
	DB	00111110B	;
	DB	00011100B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 1f us
				;
	DB	00000000B	; 20 space
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 20 space

	DB	00000000B	; 21 !
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 21 !
				;
	DB	00000000B	; 22 "
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00100010B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 22 "
				;
	DB	00000000B	; 23 #
	DB	00000000B	;
	DB	00000000B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	01111111B	;
	DB	00110110B	;
	DB	01111111B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 23 #
				;
	DB	00000000B	; 24 $
	DB	00000000B	;
	DB	00001000B	;
	DB	00111110B	;
	DB	01101011B	;
	DB	01101000B	;
	DB	00111110B	;
	DB	00001011B	;
	DB	01101011B	;
	DB	00111110B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 24 $
				;
	DB	00000000B	; 25 %
	DB	00000000B	;
	DB	00111111B	;
	DB	01101101B	;
	DB	00111011B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00111110B	;
	DB	01111011B	;
	DB	01001110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 25 %
				;
	DB	00000000B	; 26 &
	DB	00000000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00111011B	;
	DB	01101110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 26 &
				;
	DB	00000000B	; 27 '
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 27 '
				;
	DB	00000000B	; 28 (
	DB	00000000B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 28 (
				;
	DB	00000000B	; 29 )
	DB	00000000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 29 )
				;
	DB	00000000B	; 2a *
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	01111111B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	00100010B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 2a *
				;
	DB	00000000B	; 2b +
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 2b +
				;
	DB	00000000B	; 2c ,
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011100B	;
	DB	00011100B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	; 2c ,
				;
	DB	00000000B	; 2d -
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 2d -
				;
	DB	00000000B	; 2e .
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 2e .
				;
	DB	00000000B	; 2f /
	DB	00000000B	;
	DB	00000000B	;
	DB	00000001B	;
	DB	00000011B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01100000B	;
	DB	01000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 2f /
				;
	DB	00000000B	; 30 0
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100111B	;
	DB	01101111B	;
	DB	01101011B	;
	DB	01111011B	;
	DB	01110011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 30 0
				;
	DB	00000000B	; 31 1
	DB	00000000B	;
	DB	00001100B	;
	DB	00011100B	;
	DB	00111100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 31 1
				;
	DB	00000000B	; 32 2
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	00000011B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 32 2
				;
	DB	00000000B	; 33 3
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	00011110B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 33 3
				;
	DB	00000000B	; 34 4
	DB	00000000B	;
	DB	00000110B	;
	DB	00001110B	;
	DB	00011110B	;
	DB	00110110B	;
	DB	01100110B	;
	DB	01111111B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00001111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 34 4
				;
	DB	00000000B	; 35 5
	DB	00000000B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01111110B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 35 5
				;
	DB	00000000B	; 36 6
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 36 6
				;
	DB	00000000B	; 37 7
	DB	00000000B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	00000011B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 37 7
				;
	DB	00000000B	; 38 8
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 38 8
				;
	DB	00000000B	; 39 9
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111111B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 39 9
				;
	DB	00000000B	; 3a :
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 3a :
				;
	DB	00000000B	; 3b ;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000100B	;
	DB	00001000B	;
	DB	00000000B	; 3b ;
				;
	DB	00000000B	; 3c <
	DB	00000000B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01100000B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 3c <
				;
	DB	00000000B	; 3d =
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 3d =
				;
	DB	00000000B	; 3e >
	DB	00000000B	;
	DB	01100000B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01100000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 3e >
				;
	DB	00000000B	; 3f ?
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 3f ?
				;
	DB	00000000B	; 40 @
	DB	00000000B	;
	DB	00111110B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01011101B	;
	DB	01010101B	;
	DB	01010101B	;
	DB	01011111B	;
	DB	01000000B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 41 a
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 42 b
	DB	00000000B	;
	DB	01111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	01111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 43 c
	DB	00000000B	;
	DB	00011110B	;
	DB	00110011B	;
	DB	01100001B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100001B	;
	DB	00110011B	;
	DB	00011110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 43 c
				;
	DB	00000000B	; 44 d
	DB	00000000B	;
	DB	01111100B	;
	DB	00110110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110110B	;
	DB	01111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 45 e
	DB	00000000B	;
	DB	01111111B	;
	DB	00110011B	;
	DB	00110001B	;
	DB	00110010B	;
	DB	00111110B	;
	DB	00110010B	;
	DB	00110001B	;
	DB	00110011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 46 f
	DB	00000000B	;
	DB	01111111B	;
	DB	00110011B	;
	DB	00110001B	;
	DB	00110010B	;
	DB	00111110B	;
	DB	00110010B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	01111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 46 f
				;
	DB	00000000B	; 47 g
	DB	00000000B	;
	DB	00011110B	;
	DB	00110011B	;
	DB	01100001B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01101111B	;
	DB	01100011B	;
	DB	00110011B	;
	DB	00011101B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 48 h
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 49 i
	DB	00000000B	;
	DB	00111100B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 49 i
				;
	DB	00000000B	; 4a j
	DB	00000000B	;
	DB	00001111B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 4b k
	DB	00000000B	;
	DB	01100111B	;
	DB	01100110B	;
	DB	01101100B	;
	DB	01101100B	;
	DB	01111000B	;
	DB	01101100B	;
	DB	01101100B	;
	DB	01100110B	;
	DB	01100111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 4c l
	DB	00000000B	;
	DB	01110000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100001B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 4d m
	DB	00000000B	;
	DB	01000001B	;
	DB	01100011B	;
	DB	01110111B	;
	DB	01111111B	;
	DB	01101011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 4e n
	DB	00000000B	;
	DB	01000011B	;
	DB	01100011B	;
	DB	01110011B	;
	DB	01111011B	;
	DB	01101111B	;
	DB	01100111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 4f o
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 50 p
	DB	00000000B	;
	DB	01111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00111110B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	01111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 50 p
				;
	DB	00000000B	; 51 q
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01101011B	;
	DB	01100111B	;
	DB	00111110B	;
	DB	00000011B	;
	DB	00000001B	;
	DB	00000000B	; 51 q
				;
	DB	00000000B	; 52 r
	DB	00000000B	;
	DB	01111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00111110B	;
	DB	00111100B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	01110011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 52 r
				;
	DB	00000000B	; 53 s
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110000B	;
	DB	00011100B	;
	DB	00000110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 53 s
				;
	DB	00000000B	; 54 t
	DB	00000000B	;
	DB	01111110B	;
	DB	01011010B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 54 t
				;
	DB	00000000B	; 55 u
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111101B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 55 u
				;
	DB	00000000B	; 56 v
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 56 v
				;
	DB	00000000B	; 57 w
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01101011B	;
	DB	01111111B	;
	DB	01111111B	;
	DB	01110111B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 57 w
				;
	DB	00000000B	; 58 x
	DB	00000000B	;
	DB	01000001B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01000001B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 59 y
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 59 y
				;
	DB	00000000B	; 5a z
	DB	00000000B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01000011B	;
	DB	00000110B	;
	DB	01111111B	;
	DB	00011000B	;
	DB	00110001B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 5b [
	DB	00000000B	;
	DB	00011110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 5b [
				;
	DB	00000000B	; 5c \
	DB	00000000B	;
	DB	00000000B	;
	DB	01000000B	;
	DB	01100000B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00000011B	;
	DB	00000001B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 5c \
				;
	DB	00000000B	; 5d ]
	DB	00000000B	;
	DB	00111100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 5d ]
				;
	DB	00000000B	; 5e ^
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01000001B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 5e ^
				;
	DB	00000000B	; 5f _
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	; 5f _
				;
	DB	00000000B	; 60 `
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 60 `
				;
	DB	00000000B	; 61 a
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	00000110B	;
	DB	00111110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 61 a
				;
	DB	00000000B	; 62 b
	DB	00000000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01101110B	;
	DB	01110011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01110011B	;
	DB	01011110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 62 b
				;
	DB	00000000B	; 63 c
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 63 c
				;
	DB	00000000B	; 64 d
	DB	00000000B	;
	DB	00000111B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	00111011B	;
	DB	01100111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100111B	;
	DB	00111101B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 64 d
				;
	DB	00000000B	; 65 e
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 65 e
				;
	DB	00000000B	; 66 f
	DB	00000000B	;
	DB	00001110B	;
	DB	00011011B	;
	DB	00011001B	;
	DB	00011000B	;
	DB	00111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 66 f
				;
	DB	00000000B	; 67 g
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111011B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01101110B	;
	DB	00110110B	;
	DB	00000110B	;
	DB	00111100B	;
	DB	00000000B	; 67 g
				;
	DB	00000000B	; 68 h
	DB	00000000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01101100B	;
	DB	01110110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 68 h
				;
	DB	00000000B	; 69 i
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00111000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 69 i
				;
	DB	00000000B	; 6a j
	DB	00000000B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000000B	;
	DB	00001110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	00000110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	; 6a j
				;
	DB	00000000B	; 6b k
	DB	00000000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100111B	;
	DB	01101100B	;
	DB	01111000B	;
	DB	01101100B	;
	DB	01100110B	;
	DB	01100111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 6b k
				;
	DB	00000000B	; 6c l
	DB	00000000B	;
	DB	01100000B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 6c l
				;
	DB	00000000B	; 6d m
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01010110B	;
	DB	01111111B	;
	DB	01101011B	;
	DB	01101011B	;
	DB	01101011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 6d m
				;
	DB	00000000B	; 6e n
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01101110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	01110011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 6e n
				;
	DB	00000000B	; 6f o
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; 70 p
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01101110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00111011B	;
	DB	00110110B	;
	DB	00110000B	;
	DB	01111000B	;
	DB	00000000B	; 70 p
				;
	DB	00000000B	; 71 q
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111011B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01101110B	;
	DB	00110110B	;
	DB	00000110B	;
	DB	00001111B	;
	DB	00000000B	; 71 q
				;
	DB	00000000B	; 72 r
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01101110B	;
	DB	00111011B	;
	DB	00110011B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	01111000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 72 r
				;
	DB	00000000B	; 73 s
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	00111000B	;
	DB	00001110B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 73 s
				;
	DB	00000000B	; 74 t
	DB	00000000B	;
	DB	00001000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01111110B	; Z
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011011B	;
	DB	00001110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 74 t
				;
	DB	00000000B	; 75 u
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 75 u
				;
	DB	00000000B	; 76 v
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 76 v
				;
	DB	00000000B	; 77 w
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01101011B	;
	DB	01101011B	;
	DB	01111111B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 77 w
				;
	DB	00000000B	; 78 x
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 78 x
				;
	DB	00000000B	; 79 y
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100111B	;
	DB	00111011B	;
	DB	00000110B	;
	DB	00111100B	;
	DB	00000000B	; 79 y
				;
	DB	00000000B	; 7a z
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	01100110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 7a z
				;
	DB	00000000B	; 7b {
	DB	00000000B	;
	DB	00001110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01110000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00001110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 7b {
				;
	DB	00000000B	; 7c |
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 7c |
				;
	DB	00000000B	; 7d }
	DB	00000000B	;
	DB	01110000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00001110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	01110000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 7d }
				;
	DB	00000000B	; 7e ~
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00110000B	;
	DB	01011010B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 7e ~
				;
	DB	00000000B	; 7f del
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 7f del
				;
	DB	00000000B	; 80
	DB	00000000B	;
	DB	00011110B	;
	DB	00110011B	;
	DB	01100001B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100001B	;
	DB	00110011B	;
	DB	00011110B	;
	DB	00000100B	;
	DB	00010110B	;
	DB	00001100B	; 80

	DB	00000000B	; 81
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 81

	DB	00000000B	; 82
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 82

	DB	00000000B	; 83
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	00000110B	;
	DB	00111110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 83

	DB	00000000B	; 84
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	00000110B	;
	DB	00111110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 84

	DB	00000000B	; 85
	DB	00110000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	00000110B	;
	DB	00111110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 85

	DB	00000000B	; 86
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000010B	;
	DB	00000110B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	01111110B	;
	DB	01100000B	;
	DB	01000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 86

	DB	00000000B	; 87
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00001100B	;
	DB	00111000B	;
	DB	00000000B	; 87

	DB	00000000B	; 88
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 88

	DB	00000000B	; 89
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 89

	DB	00000000B	; 8a
	DB	00110000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 8a

	DB	00000000B	; 8b
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00111000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 8b

	DB	00000000B	; 8c
	DB	00011000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00111000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 8c

	DB	00000000B	; 8d
	DB	00000000B	;
	DB	00011111B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 8d

	DB	00000000B	; 8e
	DB	01100011B	;
	DB	01100011B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 8e

	DB	00000000B	; 8f
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 8f

	DB	00001100B	; 90
	DB	00011000B	;
	DB	00110000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00110011B	;
	DB	00110000B	;
	DB	00111110B	;
	DB	00110000B	;
	DB	00110011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 90

	DB	00000000B	; 91
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 91

	DB	00000000B	; 92
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 92

	DB	00000000B	; 93
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 93

	DB	00000000B	; 94
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 94

	DB	00000000B	; 95
	DB	00000000B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 95

	DB	00000000B	; 96
	DB	00011000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 96

	DB	00000000B	; 97
	DB	00000000B	;
	DB	01111111B	;
	DB	01101011B	;
	DB	01101011B	;
	DB	01101011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 97

	DB	00000000B	; 98
	DB	00000000B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01101011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01101011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 98

	DB	00000000B	; 99
	DB	01100011B	;
	DB	01100011B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 99

	DB	00000000B	; 9a
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 9a

	DB	00000000B	; 9b
	DB	00000000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00111110B	;
	DB	01101011B	;
	DB	01101000B	;
	DB	01101011B	;
	DB	00111110B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 9b

	DB	00000000B	; 9c
	DB	00011100B	;
	DB	00110110B	;
	DB	00110010B	;
	DB	00110000B	;
	DB	01111000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	01110011B	;
	DB	01101110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 9c

	DB	00000000B	; 9d
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	01111111B	;
	DB	00001000B	;
	DB	01111111B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 9d

	DB	00000000B	; 9e
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011100B	;
	DB	00011100B	;
	DB	00000100B	;
	DB	00011000B	;
	DB	00000000B	; 9e

	DB	00000000B	; 9f
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	00110000B	;
	DB	01011010B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; 9f

	DB	00000000B	; A0
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	00000110B	;
	DB	00111110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A0

	DB	00000000B	; A1
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	00000000B	;
	DB	00111000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A1

	DB	00011000B	; A2 upper case accented alpha
	DB	00110000B	;
	DB	01101000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; A3
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A3

	DB	00000000B	; A4
	DB	00011000B	;
	DB	00101101B	;
	DB	00000110B	;
	DB	00000000B	;
	DB	01101110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A4

	DB	00110000B	; A5
	DB	01011010B	;
	DB	00001100B	;
	DB	01100011B	;
	DB	01110011B	;
	DB	01111011B	;
	DB	01101111B	;
	DB	01100111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A5

	DB	00000000B	; A6
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01011101B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A6

	DB	00000000B	; A7
	DB	00000000B	;
	DB	00000000B	;
	DB	01000000B	;
	DB	01100000B	;
	DB	00110000B	;
	DB	01111110B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00000010B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A7

	DB	00000000B	; A8
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	; A8

	DB	00000000B	; A9
	DB	00000000B	;
	DB	00111110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; A9

	DB	00000000B	; Aa
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00000000B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Aa

	DB	00000000B	; Ab
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Ab

	DB	00000000B	; Ac
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	01111111B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	00100010B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Ac

	DB	00000000B	; Ad
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	; Ad

	DB	00000000B	; Ae
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011011B	;
	DB	00110110B	;
	DB	01101100B	;
	DB	00110110B	;
	DB	00011011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Ae

	DB	00000000B	; Af
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01101100B	;
	DB	00110110B	;
	DB	00011011B	;
	DB	00110110B	;
	DB	01101100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Af

	DB	00000000B	; B0 greek semicolon
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00001100B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	01010101B	; B1
	DB	10101010B	;
	DB	01010101B	;
	DB	10101010B	;
	DB	01010101B	;
	DB	10101010B	;
	DB	01010101B	;
	DB	10101010B	;
	DB	01010101B	;
	DB	10101010B	;
	DB	01010101B	;
	DB	10101010B	;
	DB	01010101B	;
	DB	10101010B	; B1

	DB	11011101B	; B2
	DB	01110111B	;
	DB	11011101B	;
	DB	01110111B	;
	DB	11011101B	;
	DB	01110111B	;
	DB	11011101B	;
	DB	01110111B	;
	DB	11011101B	;
	DB	01110111B	;
	DB	11011101B	;
	DB	01110111B	;
	DB	11011101B	;
	DB	01110111B	; B2

	DB	00010000B	; B3
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	; B3

	DB	00010000B	; B4
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	11110000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	; B4

	DB	00010000B	; B5
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	11110000B	;
	DB	00010000B	;
	DB	11110000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	;
	DB	00010000B	; B5

	DB	00101000B	; B6
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	11101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	; B6

	DB	00000000B	; B7
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	11111111B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	;
	DB	00101000B	; B7

	DB	00110000B	; B8 upper case accented epsilon
	DB	01100000B	;
	DB	01111111B	;
	DB	00110011B	;
	DB	00110001B	;
	DB	00110000B	;
	DB	00111110B	;
	DB	00110000B	;
	DB	00110001B	;
	DB	00110011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00001000B	; B9 upper case accented eeta
	DB	00001000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00110000B	; Ba upper case accented iota
	DB	01100000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Bb
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	
	DB	00110000B	; Bc upper case accented omicron
	DB	01100000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Bd
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00001100B	; Be upper case accented eepsilon
	DB	00011000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00110000B	; Bf, upper case accented omega (oldstyle)
	DB	01100000B	;
PATCH2:				;
	DB	00011100B	;
	DB	00100010B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	00100010B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; C0
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; C1 upper case alpha
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; C2 upper case veeta
	DB	00000000B	;
	DB	01111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	01111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; C3 upper case gamma
	DB	00000000B	;
	DB	01111111B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	
	DB	00000000B	; C4 upper case thelta
	DB	00000000B	;
	DB	00000000B	;
	DB	00001000B	;
	DB	00010100B	;
	DB	00110110B	;
	DB	00100010B	;
	DB	01100011B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; C5 upper case epsilon
	DB	00000000B	;
	DB	01111111B	;
	DB	00110011B	;
	DB	00110001B	;
	DB	00110000B	;
	DB	00111110B	;
	DB	00110000B	;
	DB	00110001B	;
	DB	00110011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; C6 upper case zeeta
	DB	00000000B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01000011B	;
	DB	00000110B	;
	DB	01111111B	;
	DB	00011000B	;
	DB	00110001B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; C7 upper case eeta
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; C8 upper case theeta
	DB	00000000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; C9 upper case iota
	DB	00000000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Ca upper case kappa
	DB	00000000B	;
	DB	01100111B	;
	DB	01100110B	;
	DB	01101100B	;
	DB	01101100B	;
	DB	01111000B	;
	DB	01101100B	;
	DB	01101100B	;
	DB	01100110B	;
	DB	01100111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Cb upper case lambda
	DB	00000000B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Cc upper case mi
	DB	00000000B	;
	DB	01000001B	;
	DB	01100011B	;
	DB	01110111B	;
	DB	01111111B	;
	DB	01101011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; Cd upper case ni
	DB	00000000B	;
	DB	01000011B	;
	DB	01100011B	;
	DB	01110011B	;
	DB	01111011B	;
	DB	01101111B	;
	DB	01100111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Ce upper case ksee
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Cf upper case omicron
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D0 upper case pi
	DB	00000000B	;
	DB	01111111B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D1 upper case rho
	DB	00000000B	;
	DB	00111110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00111110B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D2 not used?
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D3 upper case sigma
	DB	00000000B	;
	DB	01111111B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D4 upper case taf
	DB	00000000B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D5 upper case eepsilon
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D6 upper case phi
	DB	00000000B	;
	DB	00011100B	;
	DB	00101010B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	00101010B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; D7 upper case hee
	DB	00000000B	;
	DB	01000001B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01000001B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D8 upper case psee
	DB	00000000B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	00111110B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; D9, upper case omega (old style)
	DB	00000000B	;
PATCH1:				;
	DB	00011100B	;
	DB	00100010B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	01000001B	;
	DB	00100010B	;
	DB	00011100B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; Da
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Da

	DB	00000000B	; Db
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Dc lower case accented alpha
	DB	00000000B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00111011B	;
	DB	01101110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01101110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Dd lower case accented epsilon
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	01100000B	;
	DB	01111000B	;
	DB	01100000B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; De lower case accented eeta
	DB	00000000B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	01101110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	00000000B	;

	DB	00000000B	; E9 lower case accented iota
	DB	00000000B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00111000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011001B	;
	DB	00001110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E0
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E1 lower case alpha
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111011B	;
	DB	01101110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01101110B	;
	DB	00111011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E2 lower case veeta
	DB	00000000B	;
	DB	00011110B	;
	DB	00100011B	;
	DB	00100011B	;
	DB	00100011B	;
	DB	00101110B	;
	DB	00100011B	;
	DB	00100011B	;
	DB	00100011B	;
	DB	00101110B	;
	DB	01000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E3 lower case gamma
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E4 lower case thelta
	DB	00000000B	;
	DB	01111110B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00111110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E5 lower case epsilon
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	01100000B	;
	DB	01111000B	;
	DB	01100000B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; E6 lower case zeeta
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	00111110B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00000000B	;

	DB	00000000B	; E7 lower case eeta
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01101110B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00110011B	;
	DB	00000011B	;
	DB	00000011B	;
	DB	00000000B	;

	DB	00000000B	; E8 lower case theeta
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01111111B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; E8

	DB	00000000B	; E9 lower case iota
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011001B	;
	DB	00001110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Ea lower case kappa
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100111B	;
	DB	01101100B	;
	DB	01111000B	;
	DB	01101100B	;
	DB	01100110B	;
	DB	01100111B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Eb lower case lambda
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	11000000B	;
	DB	01100000B	;
	DB	00110000B	;
	DB	00011000B	;
	DB	00111100B	;
	DB	01100110B	;
	DB	11000011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	; Eb

	DB	00000000B	; Ec lower case mi
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01111100B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	11000000B	;
	DB	00000000B	;

	DB	00000000B	; Ed lower case ni
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Ee lower case ksee
	DB	00000000B	;
	DB	00000000B	;
	DB	00011110B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00110000B	;
	DB	00011110B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	00111110B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00000000B	;

	DB	00000000B	; Ef lower case omicron
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F0 lower case pi
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	11111111B	;
	DB	01000010B	;
	DB	01000010B	;
	DB	01000010B	;
	DB	01000010B	;
	DB	01000011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F1 lower case rho
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00011100B	;
	DB	00100010B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100010B	;
	DB	01111100B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100000B	;

	DB	00000000B	; F2 lower case finial sigma
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100000B	;
	DB	01100000B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000110B	;
	DB	00001100B	;
	DB	00000000B	;

	DB	00000000B	; F3, lower case sigma
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111111B	;
	DB	11001100B	;
	DB	11001100B	;
	DB	11001100B	;
	DB	11001100B	;
	DB	01111000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F4 lower case taf
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01111110B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00011000B	;
	DB	00001100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
	DB	00000000B	; F5 lower case eepsilon
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F6 lower case phi
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00101110B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	00111110B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F7 lower case hee
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00011100B	;
	DB	00001000B	;
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F8 lower case psee
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	00111110B	;
	DB	00001000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; F9 lower case omega
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00100010B	;
	DB	01000001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01111111B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Fa
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Fb
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Fc lower case accented omicron
	DB	00000000B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00111110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00111110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Fd lower case accented eepsilon
	DB	00000000B	;
	DB	00011000B	;
	DB	00110000B	;
	DB	00000000B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	01100110B	;
	DB	00111100B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Fe lower case accented omega
	DB	00000000B	;
	DB	00001100B	;
	DB	00011000B	;
	DB	00000000B	;
	DB	00100010B	;
	DB	01000001B	;
	DB	01001001B	;
	DB	01001001B	;
	DB	01111111B	;
	DB	00110110B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;

	DB	00000000B	; Ff
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
	DB	00000000B	;
				;
OMEGAFIX:			; Omega patch data
	DB	00011100B	;
	DB	00110110B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	01100011B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	00110110B	;
	DB	01110111B	;
				;
;************************************************************************
;*		  SIMPLE BACKGROUND TIC COUNTER 			*
;************************************************************************
				;
MYINT:	CMP	CS:[TICS],WORD PTR 0FFFFH
	JZ	MYEXIT		; Maxed out, don't increment
	INC	WORD PTR CS:[TICS] ; Bump count
MYEXIT:				;
	DB	0EAH		; Jump far to
OLDVEC:	DW	0000H		; This offset defined by install
OLDSEG:	DW	0000H		; This segment defined by install
TICS:	DW	0000H		; Tic count location
				;
MYINT15:CMP	AH,4FH		; Keyboard intercept service
	JNZ	IGNOREF		; We're outta here...
				;
	CMP	AL,3AH		; Caps lock down?
	JNZ	NO1		; No
	MOV	AL,1DH		; Say ctrl key down instead
	JMP	SHORT IGNOREF	; And exit
				;
NO1:	CMP	AL,0BAH		; Caps lock up?
	JNZ	NO2		; No
	MOV	AL,9DH		; Say ctrl key up instead
	JMP	SHORT IGNOREF	; And exit
				;
NO2:	CMP	AL,1DH		; (left) ctrl key down?
	JNZ	NO3		; Nope
	MOV	AL,3AH		; Say caps lock down instead
	JMP	SHORT IGNOREF	; And exit
				;
NO3:	CMP	AL,9DH		; (left) ctrl key up?
	JNZ	IGNOREF		; Nope, exit routine
	MOV	AL,0BAH		; Say caps lock key up instead
				;
IGNOREF:STC			; Tell bios to continue processing
	DB	0EAH		; Jump far to
OLDVECF:DW	0000H		; This offset defined by install
OLDSEGF:DW	0000H		; This segment defined by install
				;
;***********************************************************************
; This is the control break handler.  It ignores the break.
;***********************************************************************
				;
NEWINT23:			;
	MOV	CS:[DIRTYBITS],	BYTE PTR 1 ; Refresh screen when done
	CLC			; Tell dos to ignore break
	IRET			; Go back
				;
;***********************************************************************
; This is the severe error handler.  It homes the cursor before
; processing the error.
;***********************************************************************
				;
NEWINT24:			;
	PUSHF			; Save flags
	PUSHA			; Save everything
	MOV	CS:[DIRTYBITS],	BYTE PTR 1 ; Refresh screen when done
	XOR	DX,DX		; Top of screen
	CALL	SETCURSOR	; Put cursor at home
	CALL	CLS		; Clear screen...
	POPA			; Restore everything
	POPF			; Including flags
	DB	0EAH		; Jmp far to old critical error handler
OLDINT24:			;
	DD	00000000H	; Original int 24 handler address
				;
CLS:	MOV	AL,CS:[MODE]	; Get mode
	XOR	AH,AH		; Set mode function
	INT	10H		; Do cls
	RET			; Go home
				;
;************************************************************************
;*									*
;*	HEXCONV:  This routine prints the contents of AL into the	*
;*	signoff message.  Accepts:  Hex number [GEN]. Returns:	Nothing.*
;*	Calls:	Nothing. Clobbers:  AL. 				*
;*									*
;************************************************************************
				;
HEXCONV:MOV	AL,CS:[GEN]	; Get generation counter
	AND	AL,0F0H		; Mask out lsn
	ROR	AL,4		; Get upper nybble first...
	CALL	CONVHEX		; Convert
	MOV	AL,CS:[GEN]	; Get generation counter again
	AND	AL,0FH		; Mask out msn
	CALL	CONVHEX		; Convert
	RET			; Go home
				;
CONVHEX:CMP	AL,0AH		; Is it a letter?
	JGE	MAKLETT		; Yes
	CLC			; Clear carry so we won't add it in
	ADD	AL,30H		; Add numeric bias
	JMP	SHORT XIT	; Go back
				;
MAKLETT:CLC			; Clear carry so we won't add it in
	ADD	AL,37H		; Add alpha bias
XIT:	CALL	PCHAR		; Print it
	RET			; Go back
				;
STRINGPTR:			;
	DB	41D		; We allow up to 40 characters
RETLEN:	DB	00H		; Return length storage
	DS	40D		; Search string storage
FILENAME:			;
	DB	41D		; We allow up to 40 characters
NAMELEN:DB	00H		; Storage for file name, block load/save
	DS	40D		; File name storage
REPLACEPTR:			;
	DB	41D		; Up to 40 characters for replacement string
REPLACELEN:			;
	DB	22D		; Replacement string length
	DB	'Praise Goddess Athena!' ; Hidden message
CEND:				; End of checksummed range
	DS	40D-22D		; Replacement string storage
TMPNAME:EQU	$		; Storage for filename.$$$
DOTBAC:	EQU	$ + 80H		; Storage for filename.bac
LINEBUF:EQU	$ + 100H	; Storage for deleted lines
NUSTAK:	EQU	$ + 500H	; Stack - everything past here is de-allocated!
				;
;************************************************************************
;*									*
;*	BETA:  This routine is for beta versions only, and is overlayed *
;*	by the stack and various "other things".			*
;*									*
;************************************************************************
				;
BETA:	 IF	BETATST		; If beta test version....
	MOV	AH,2AH		; Get date function
	INT	21H		; Call mush-dos
	CMP	CX,2005D	; Year to abort
	JB	BETAEXIT	; Not yet
	JA	ALWAYS		; Long, long, time, always abort
	CMP	DH,01D		; Month to abort
	JB	BETAEXIT	; Not yet
ALWAYS:	MOV	DX,OFFSET BETAMESS ; Point to expired message
	POP	AX		; Fix stack
	JMP	ERREXIT		; And exit with error
				;
BETAMESS:			;
	DB	CR,LF,07H,07H,'Sorry, this BHTA copy has expired!',CR,LF,00H
BETAEXIT:			;
	RET			; Go home
	 ENDIF			; End of options
				;
CONFIG:	MOV	DX,OFFSET SIGNON ; Point to signon message
	CALL	PSTRING		; Print it
	LEA	SI,PTRTABLE	; Point to message pointers
	LEA	DI,INSMODE	; Point to configuration area
	MOV	CX,0014H	; Number of questions to ask
ASKLP:	MOV	DX,OFFSET CRLF	; Point to cr-lf
	CALL	PSTRING		; Send it
	LODSW			; Get message pointer in ax
	MOV	DX,AX		; Put in dx
	CALL	PSTRING		; Print message
	MOV	DX,OFFSET YN	; Point to yn message
	CALL	PSTRING		; Print it
AGAIN:	CALL	CONIN		; Get response
	AND	AL,5FH		; Make upper case
	CMP	AL,'Y'		; Yes?
	MOV	AH,0FFH		; Assume yes
	JZ	PUTANS		; Stuff config byte
	CMP	AL,'N'		; No?
	MOV	AH,00H		; Default to no (no flag alteration)
	JZ	PUTANS		; Stuff config byte
	JMP	SHORT AGAIN	; Garbage, ignore
				;
PUTANS:	CALL	CONOUT		; Echo response
	XCHG	AL,AH		; Get config byte
	STOSB			; Configure program
	LOOP	ASKLP		; Go again
				;
	MOV	CL,03H		; Three hex input questions
ASKLP1:	MOV	DX,OFFSET CRLF	; Point to cr-lf
	CALL	PSTRING		; Send it
	LODSW			; Get message pointer in ax
	MOV	DX,AX		; Put in dx
	CALL	PSTRING		; Print message
	CALL	CONIN		; Get response
	CALL	CONOUT		; Echo
	CALL	DONYB		; Convert to hex
	SHL	AL,4		; Into upper nybble
	MOV	BL,AL		; Stash
	CALL	CONIN		; Get other nybble
	CALL	CONOUT		; Echo
	CALL	DONYB		; Convert to hex
	OR	AL,BL		; Or in
	STOSB			; Configure program
	LOOP	ASKLP1		; Do all hex type question
				;
	MOV	DX,OFFSET CRLF	; Point to cr-lf
	CALL	PSTRING		; Send it
	LODSW			; Get message pointer in ax
	MOV	DX,AX		; To dx
	CALL	PSTRING		; Print message
	CALL	CONIN		; Get response
	CALL	CONOUT		; Echo
	STOSB			; Put in program
				;
	INC	DI		; Skip over the dot in .asm
	MOV	DX,OFFSET CRLF	; Point to cr-lf
	CALL	PSTRING		; Send it
	LODSW			; Get message pointer in ax
	MOV	DX,AX		; To dx
	CALL	PSTRING		; Print message
	MOV	CL,03H		; Get three characters
ASKLP2:	CALL	CONIN		; Get response
	CALL	CONOUT		; Echo
	STOSB			; Store away
	LOOP	ASKLP2		; Do all three
	MOV	AL,[GEN]	; Get generation counter
	INC	AL		; Increment
	JZ	SKIPINC		; Already maxed out, don't store
	MOV	[GEN],AL	; Put back
				;
SKIPINC:XOR	CX,CX		; Normal addributes
	MOV	AH,3CH		; Create file function
	LEA	DX,FNAME	; Point to file name
	INT	21H		; Open the file
	JNC	OK1		; Ok
	MOV	DX,OFFSET NOOPEN ; Point to open failure message
	CALL	PSTRING		; Print it
	JMP	FFAIL		; Go to error handler
OK1:	MOV	BX,AX		; Put handle in bx
	LEA	CX,PEND		; End of program
	SUB	CX,0100H	; Make into number of bytes...
	LEA	DX,START	; Point to beginning of program
	MOV	AH,40H		; Write function
	INT	21H		; Do it
	JNC	WOK		; Ok
	MOV	DX,OFFSET NOWRITE ; Point to write failure message
	CALL	PSTRING		; Print it
	JMP	FFAIL		; Go to error handler
				;
WOK:	MOV	AH,3EH		; Close the file now
	INT	21H		; Close the damn thing
	JNC	CLOK1		; Closed ok
	MOV	DX,OFFSET NOCLOSE ; Point to close failure message
	CALL	PSTRING		; Print it
				;
CLOK1:	MOV	DX,OFFSET FCOMP	; Point to function complete message
	CALL	PSTRING		; Print it
	CALL	PRTCOPY		; Print copyright message
	MOV	AX,4C00H	; Terminate with no error
	INT	21H		; Good bye....
				;
FFAIL:	MOV	AX,4CFFH	; Terminate with error
	INT	21H		; Good bye....
				;
CONOUT:	PUSH	AX		; And ax
	MOV	AH,02H		; Console output
	MOV	DL,AL		; Into dl
	INT	21H		; Go do it...
	POP	AX		; Restore ax
	RET			; Go home
				;
CONIN:	MOV	AH,08H		; Console input function (without echo)
	INT	21H		; Go get
	RET			; Go home
				;
DONYB:	SUB	AL,30H		; Remove numeric bias
	CMP	AL,0AH		; Letter?
	JC	EXITNYB		; No, we're done
	AND	AL,1FH		; Make upper case if needed...
	SUB	AL,07H		; Remove alpha bias
EXITNYB:RET			; Go home
				;
PTRTABLE:			; Pointers to question strings
	DW	QINSMODE	; Initial insert status question
	DW	QDIST		; Destructive backspace question
	DW	QDOEOF		; Eof handling question
	DW	QDOBAK		; Do backup files question
	DW	QDOCMT		; Auto comment question
	DW	QCMTSP		; Do space after auto comment question
	DW	QFORM7		; Form7 filter on/off question
	DW	QDOCOLON	; Auto-colons question
	DW	QAUTOTAB	; Auto-tab question
	DW	QAUTOIND	; Auto-indent question
	DW	QLAME		; Lame feature question
	DW	QPT		; Processor technology question
	DW	QINSOFF		; Turn off insert on cr
	DW	QAUTO		; Auto-save question
	DW	QSTATLN		; Status line question
	DW	QNOISE		; Noise question
	DW	QKBFIX		; Swap cntrl and caps lock?
	DW	QGREEK		; Ask about greek language support
	DW	QOMEGA		; Ask about traditional omega
	DW	QHP		; Ask about hp printer driver
	DW	QNORMAL		; Color question
	DW	QCMTCOL		; Ask about what column to start comments in
	DW	QPRNPTR		; Ask what printer to use
	DW	QCMTCHR		; What comment delimiter...
	DW	QDOTASM		; Ask about default file extension
				;
QINSMODE:			;
	DB	'Initial insert status on? [N]',00H
QDIST:	DB	'Non-destructive backspace? [Y]',00H
QDOEOF:	DB	'Handle EOF properly? [Y]',00H
QDOBAK:	DB	'Create backup files? [Y]',00H
QDOCMT:	DB	'Enable auto commenting feature? [Y]',00H
QCMTSP:	DB	'Automaticly place a space after semi-colon? [Y]',00H
QFORM7:	DB	'Enable FORM7 Filter? [Y]',00H
QDOCOLON:			;
	DB	'Automaticly place colon after labels? [Y]',00H
QAUTOTAB:			;
	DB	'Automaticly tab from operand field to comment field? [Y]',00H
QAUTOIND:			;
	DB	'Enable auto-indent? [Y]',00H
QLAME:	DB	'Allow <CR> to create new line if insert is on? [N]',00H
QPT:	DB	'Allow * in column 1 to be a full line comment? [Y]',00H
QINSOFF:DB	'Allow <CR> to turn off insert? [Y]',00H
QAUTO:	DB	'Enable 3 minute auto-save? [Y]',00H
QSTATLN:DB	'Enable screen status line? [Y]',00H
QNOISE:	DB	'Enable warning tones? [Y]',00H
QKBFIX:	DB	'Swap CNTRL and Caps Lock? [N]',00H
QGREEK:	DB	'Enable Greek language processing [N]',00H
QOMEGA:	DB	'Use traditional upper case omega [Y]',00H
QHP:	DB	'Use HP printer driver [N]',00H
QNORMAL:DB	'Enter two digit HEXIDECIMAL color attribute [0A]: ',00H
QCMTCOL:DB	'Enter two digit HEXIDECIMAL comment column [20]: ',00H
QPRNPTR:DB	'Enter two digit printer number, 00 - 02 [00]: ',00H
QCMTCHR:DB	'Enter single ASCII character for comment delimeter [;]: ',00H
QDOTASM:DB	'Enter 3 character default file extension. [ASM]: ',00H
SIGNON:	DB	CR,LF,'AE configurator'
	DB	CR,LF,LF,'Recommended settings in [brackets].'
	DB	CR,LF,'Hot key input, do NOT use <CR>.'
	DB	CR,LF,'<^C> aborts without save.'
	DB	CR,LF,00H	; Extra cr-lf
				;
NOOPEN:	DB	CR,LF,'Failure to open output file',00H
NOWRITE:DB	CR,LF,'Error writing output file',00H
NOCLOSE:DB	CR,LF,'Error closing output file',00H
FCOMP:	DB	CR,LF,'Function Complete.',CR,LF,00H
				;
YN:	DB	' (Y/N) ',00H	; Yes/no response
CRLF:	DB	CR,LF,00H	; Good old crlf
				;
FNAME:	EQU	$		; Filename storeage
PEND:	EQU	$		; End of the world
	END			; Of line
