ANTIC v6.6 / OCTOBER 1987 / PAGE 15

Super Disk Bonus

Antic Spelling Checker

Speed-scan your writing

The Super Disk Bonus this month is Antic Spelling Checker. This fast, powerful machine language program makes it easy to handle as many as 10 personal dictionaries. It works with most DOS text files—such as AtariWriter, PaperClip, etc.

On an 8-bit Atari with 48K memory, you could have more than 6,300 words per dictionary (averaging five bytes per word). That adds up to over 63,000 words for the 10 dictionaries on your Antic Spelling Checker disk.

Antic Spelling Checker can create your new dictionaries by alphabetizing all the unique words in a text file and letting you edit the results. This is Antic’s fourth monthly Super Disk Bonus — useful programs which are too large or complex for publication as a type-in listing.

The Antic Spelling Checker program (PSC.EXE) and manual (HELP.BAS) are on Side B of the monthly disk. To read the instruction screens or make a printout, select choice 5 from the Side B menu.

Your $5.95 Antic October Disk — featuring Antic Spelling Checker — could go in the mail to you today! Phone the Antic Disk Desk at (415) 957-0886 and use your Visa or Mastercard.

Now only $5.95— Antic Monthly Disk!

PERSONAL SPELLING CHECKER

BY BRYAN SCHAPPEL and BARRY KOLBE

This speedy, powerful machine language program supports up to 10 personal dictionaries. It’s easy to use and works with most DOS files. A 48K system and about 31,800 free bytes give you about 6,360 words per dictionary (counting about five bytes per word)—as many as 63,600 words altogether.

GETTING STARTED

Format a blank disk with DOS 2 or 2.5, then use DOS menu option “H” to WRITE DOS FILES to the disk. This will be your Personal Spell Checking disk.

Next, copy PSC.EXE to this disk. Rename PSC.EXE to AUTORUN.SYS. Finally, copy DICTION.1 to this disk. This is a dictionary file.

Turn your computer off and place your Personal Spell Checker disk into drive 1. Remove all cartridges (hold down [OPTION] on an XL/XE) and turn your Atari ON.

At the prompt, insert a DOS-formatted disk that will contain your dictionaries (the monthly disk contains DICTION.1, a sample dictionary for you to use). You can use the program to create additional dictionaries. Legal dictionary filenames are DICTION.0 through DICTION.9.

NOTE: The program may only use one dictionary at a time. (For example, after proofing your text file with the first dictionary, you must stop, load the next dictionary file, and check the text again.)

If there are no dictionary files on your disk, the program chooses its built-in default dictionary.

The top half of the screen displays information to help you use the program, such as the amount of available memory, your current dictionary and disk directories (“catalogs”). The bottom half is your work area. This is where the main menu will appear.

Choose a menu item by typing the number or the first letter of that item:

  1. Proof Document
  2. Delete Word
  3. View Dictionary
  4. Add File to Dictionary
  5. Catalog
  6. Exit PSC

Proof: Type in a filename. (“D:” isn’t needed if you’re using drive 1.) The top of the screen shows the filenames of the current dictionary and file being proofed, the amount of free memory, the number of words in the dictionary and the number of words proofed so far. Below this is the context line, which shows the part of the sentence containing the word being checked. An unknown word is highlighted and displayed separately below. If it’s spelled correctly, just press [RETURN] at the “Correct?” prompt. Otherwise, type in the correct spelling. To add the word to the dictionary, press [RETURN] or [Y]. Press [N] to skip it.

Delete Words: Enter the word to be deleted from your dictionary. Then press [Y] after the prompt “Delete word? [Y/N]” to remove it.

View Dictionary: This is for examining the current dictionary. Pressing any letter key displays the words beginning with that letter. For more words, press [RETURN]. Words can be up to 29 characters.

Add File: This lets you build a dictionary fast—but do this only if you’re sure that all the words in the document are spelled correctly.

Catalog: This gives a directory of drives 1-4, or 8 for a RAMdisk.

Exit: At this point you can save the current dictionary by putting your dictionary disk in drive 1 at the prompt and pressing [RETURN]. You can now restart or return to DOS. If you restart, the current dictionary remains in memory, but you can load one different dictionary if you want.

The first two bytes of a dictionary contain the number of words in the dictionary. Next are 27 pointers to the beginning of each set of words, A-Z. This speeds up the search for a particular word. The 27th pointer points to one byte after the end of the dictionary. Third is a table containing the number of words under each letter.

Finally there is the default dictionary of 26 words. These are AT, BUT, CAN, DO, END, FOR, GET, HOW, IN, JOG, KNOW, LET, ME, NO, ON, PUT, QUIT, RED, SO, THE, UP, VAN, WHO, XEBEC, YES, and ZIP. The first letter is not actually present in the word, and the last letter is in inverse video. Each single-letter word—that is, “I,” “A” and whatever other single letters you choose to call “words”—is stored as a single inverse letter.

If you choose a command by mistake, press [RETURN] at the first prompt to go to the main menu.

When proofing a document, PSC creates a file called DOC.TMP and writes your corrected document to it. Your document disk must have at least enough room for one copy of the original document, or the proofreading process will abort.

Since you can specify any drive as the source disk, the DOC.TMP file will also be written to that drive—so if you have a RAMdisk, this program flies.

When the file has been proofed successfully, the source file is given the extender “.BKP” (even if it already had an extender), and DOC.TMP is given the original filename.

This program is not case-sensitive, so you can enter words in either uppercase or lowercase—even inverse video—and the program will convert them to normal uppercase. The only time this conversion is not performed is when you enter a corrected spelling for a word during a proof.

EXTRA BONUS: We’ve also included SPELL.M65, SPELL.DAT and SPELL.SUB, the MAC/65 source code files for the Spelling Checker. Due to the size of these files, they have been stored in MAC/65 “SAVEd” form.

You do NOT need these files to use the PSC program.

Listing 1: SPELL.M65

	.OPT	NOLIST
;------------------------------
;
;The Super-Speller
;
;by: Barry Kolbe and
;    Bryan Schappel
;
;------------------------------
;
	*=	0
PASS	.=	PASS+1
	.IF	PASS=1
	.INCLUDE	#D:SYSEQU.M65
	.ENDIF
;
;*** MACRO DEFINITIONS ***
;
	.MACRO	PRINT 
	LDA	#<%1
	LDY	#>%1
	JSR	EPRINT
	.ENDM
;
	.MACRO	BUMP 
	INC	%1
	BNE	@BMP
	INC	%1+1
@BMP
	.ENDM
;
;Zero Page Usage
;
	*=	$80
SCR	.DS	2
SCR2	.DS	2
INDR	.DS	2
XPOS	.DS	1
YPOS	.DS	1
LMARGIN	.DS	1
RMARGIN	.DS	1
SAVEX	.DS	1
SAVX2	.DS	1
COUNT	.DS	1
IPUT	.DS	1
MAXLEN	.DS	1
ILEN	.DS	1
CHAR	.DS	1
RINDEX	.DS	2
WINDEX	.DS	2
TEMP	.DS	2
R_PASS	.DS	1
MAXGET	.DS	2
RXSAV	.DS	1
RYSAV	.DS	1
WXSAV	.DS	1
WYSAV	.DS	1
EOF?	.DS	1
EOF2?	.DS	1
OEOF?	.DS	1
LAST_ONE	.DS	1
RJUST	.DS	1
WCOUNT	.DS	2
ERROR	.DS	1
WORD_POS	.DS	1
DICT_NUM	.DS	1
S_LEN	.DS	1
LEN_1	.DS	1
LEN_2	.DS	1
FREEM	.DS	2
EDITED	.DS	1
ASAV	.DS	1
V_START	.DS	2
V_END	.DS	2
V_TEMP	.DS	2
PREFIX	.DS	1
NO_JUNK	.DS	1
ERRORR	.DS	1
OUTPUT?	.DS	1
;
;Memory Management
;
LLEN	.DS	1
HLEN	.DS	1
FROML	.DS	1
FROMH	.DS	1
DESTL	.DS	1
DESTH	.DS	1
ENDPOS	.DS	1
	.OPT	LIST
ENDZPG	=	*
	.OPT	NOLIST
;
;Other Equates
;
WORD_C	=	$0500
PLR2	=	$0600
;
	*=	$2000
TOPHALF	.DS	$0200
BOTHALF	.DS	$0300
OUTBUF	.DS	$0400
INBUF	.DS	$0420
START	JMP	BEGIN
;
;INCLUDE DATA AND SUBROUTINES
;
	.INCLUDE	#D:SPELL.DAT
	.INCLUDE	#D:SPELL.SUB
;
;Zap Top-Half
;
ZAP_TOP	LDY	#0
	TYA
ZAP_T	STA	TOPHALF,Y
	STA	TOPHALF+$0100,Y
	INY
	BNE	ZAP_T
	RTS
;
;Intro Routine
;
INTRO	JSR	ZAP_TOP
	LDA	#$3A
	STA	SDMCTL
	LDX	#0
	STX	EDITED
	STX	COLOR4
	STX	SIZEP2
	STX	PMBASE
	STX	IPUT
	STX	SHFLOK
	DEX
	STX	CH
	LDA	#$C4
	STA	PCOLR2
	LDX	#3
	STX	GRACTL
	DEX
	STX	LMARGIN
	LDA	#39
	STA	RMARGIN
	JSR	CLRSCR
	LDA	#4
	STA	COLOR2
	LDA	#10
	STA	COLOR1
	LDA	#<DLIST
	STA	SDLSTL
	LDA	#>DLIST
	STA	SDLSTL+1
	LDA	#<DLI
	STA	VDSLST
	LDA	#>DLI
	STA	VDSLST+1
	LDA	#6
	STA	HSCROL
	LDY	#<IVBI
	LDX	#>IVBI
	JSR	SETVBV
	LDA	#7
	LDY	#<DVBI
	LDX	#>DVBI
	JSR	SETVBV
	LDA	#$C0
	STA	NMIEN
;
	LDA	#<[TOPHALF+40]
	STA	SCR
	LDA	#>[TOPHALF+40]
	STA	SCR+1
;
	LDX	#$FF
PTITL	INX
	LDA	ITXT,X
	TAY
	CMP	#$FF
	BEQ	IADD40
P2	INX
	LDA	ITXT,X
	CMP	#$FF
	BEQ	IADD40
	CMP	#$FD
	BEQ	GET_RET
	STA	(SCR),Y
	INY
	BNE	P2
IADD40	JSR	SCRADD40
	JMP	PTITL
;
;Just Read an EOL from K:
;
GET_RET	JSR	GETKEY
	CMP	#EOL
	BNE	GET_RET
	RTS
;
;Add 40 to SCR
;
SCRADD40	LDA	SCR
	CLC
	ADC	#40
	STA	SCR
	BCC	ADD_RTS
	INC	SCR+1
ADD_RTS	RTS
;
;Display List Interrupt
;
DLI	PHA
	LDA	#$92
	STA	WSYNC
	STA	COLPF2
	PLA
	RTI
;
;Immed. Vertical Blank
;
IVBI	LDY	#4
IVBI.1	LDA	COLOR0,Y
	STA	COLPF0,Y
	DEY
	BPL	IVBI.1
	JMP	SYSVBV
;
;Deffered VBI
;
DVBI	LDA	#0
	TAX
DVBI.1	STA	PLR2,X
	INX
	BNE	DVBI.1
	LDA	IPUT
	BEQ	DVBI.OUT
	LDA	XPOS
	ASL	A
	ASL	A
	CLC
	ADC	#$30
	STA	HPOSP2
	LDA	YPOS
	ASL	A
	ASL	A
	ASL	A
	CLC
	ADC	#$74
	TAX
	LDA	#$F0
	STA	PLR2,X
DVBI.OUT	JMP	XITVBV
;
;Clear Screen
;
EPUT	CMP	#125
	BNE	EPUT_2
CLRSCR	LDA	#0
	TAY
CLR_SC	STA	BOTHALF,Y
	STA	BOTHALF+$0100,Y
	STA	BOTHALF+$0200,Y
	INY
	BNE	CLR_SC
	STA	YPOS
	LDA	LMARGIN
	STA	XPOS
	RTS
;
EPUT_2	CMP	#EOL
	BNE	TRY_DEL
PUTCR	LDA	LMARGIN
	STA	XPOS
	INC	YPOS
	JMP	SCROLL
;
TRY_DEL	CMP	#126
	BNE	NORMAL
	JSR	MOVELEFT
	JSR	GETSCR
	LDA	#0
	TAY
	STA	(SCR),Y
	RTS
;
;We assume the character is
;'Normal'.
;
NORMAL	JSR	ASC2IC
	PHA
	JSR	GETSCR
	PLA
	LDY	#0
	STA	(SCR),Y
;
;Move Right
;
GORIGHT	LDX	XPOS
	INX
	CPX	RMARGIN
	BCC	EPLEAV
	BEQ	EPLEAV
	INC	YPOS
	JSR	SCROLL
	LDX	LMARGIN
EPLEAV	STX	XPOS
	RTS
;
;This tries to Move Left
;
MOVELEFT	LDX	XPOS
	DEX
	CPX	LMARGIN
	BCS	GOX
	LDX	RMARGIN
	LDA	YPOS
	BNE	MVUP1
	LDX	LMARGIN
	JMP	GOX
MVUP1	DEC	YPOS
GOX	STX	XPOS
	RTS
;
;This gets the Address of the
;byte we want to put.
;
GETSCR	LDA	#<[BOTHALF-40]
	STA	SCR
	LDA	#>[BOTHALF-40]
	STA	SCR+1
;
	LDY	YPOS
GETSC1	JSR	SCRADD40
	DEY
	BPL	GETSC1
	LDA	SCR
	CLC
	ADC	XPOS
	STA	SCR
	BCC	GETSCDN
	INC	SCR+1
GETSCDN	RTS
;
;Scroll the screen
;
SCROLL	LDA	YPOS
	CMP	#12
	BCC	SCMOVEDN
	LDA	#11
	STA	YPOS
	LDA	#<[BOTHALF+40]
	STA	FROML
	LDA	#>[BOTHALF+40]
	STA	FROMH
	LDA	#<BOTHALF
	STA	DESTL
	LDA	#>BOTHALF
	STA	DESTH
	LDA	#<472
	STA	LLEN
	LDA	#>472
	STA	HLEN
	JSR	MOVE_UP
SCMOVEDN	RTS
;
;Make ASCII to ICODE
;
ASC2IC	JSR	BITER
	ORA	A2I,X
	LDX	SAVX2
	RTS
;
;Ready the Bits
;
BITER	PHA
	ROL	A
	ROL	A
	ROL	A
	ROL	A
	AND	#3
	STX	SAVX2
	TAX
	PLA
	AND	#$9F
	RTS
;
;Get a Key
;
GETKEY	LDA	KEYBDV+5
	PHA
	LDA	KEYBDV+4
	PHA
	RTS
;
;Print a String
;
EPRINT	STA	EPRL+1
	STY	EPRL+2
EPRL	LDA	$FFFF
	BEQ	EPRLV
	JSR	EPUT
		BUMP EPRL+1
	JMP	EPRL
EPRLV	RTS
;
;Show INFO_BOX
;
SHO_BOX	JSR	ZAP_TOP
	LDY	#0
SHB_1	LDA	INFO_BOX,Y
	STA	TOPHALF,Y
	INY
	CPY	#200
	BNE	SHB_1
;
	LDA	DICT_NUM
	JSR	ASC2IC
	STA	TOPHALF+54
	LDY	#0
SHB_2	LDA	FILNAM,Y
	CMP	#EOL
	BEQ	SHB_3
	JSR	ASC2IC
	STA	TOPHALF+64,Y
	INY
	CPY	#14
	BNE	SHB_2
;
;Enter here to Update #'s
;
SHB_3	LDA	NUM_WORDS+1
	LDY	NUM_WORDS
	JSR	CON_NUM
	LDY	#4
SHB_4	LDA	NUMBUF,Y
	JSR	ASC2IC
	STA	TOPHALF+140,Y
	DEY
	BPL	SHB_4
	JSR	FIND_FREE
	LDY	FREEM
	LDA	FREEM+1
	JSR	CON_NUM
	LDY	#4
SHB_5	LDA	NUMBUF,Y
	JSR	ASC2IC
	STA	TOPHALF+127,Y
	DEY
	BPL	SHB_5
	LDY	WCOUNT
	LDA	WCOUNT+1
	JSR	CON_NUM
	LDY	#4
SHB_6	LDA	NUMBUF,Y
	JSR	ASC2IC
	STA	TOPHALF+154,Y
	DEY
	BPL	SHB_6
	RTS
;
;Close the Disk
;
DCLOSE	LDX	#$30
	BNE	DCL
CLOSE2	LDX	#$20
DCL	LDA	#12
	STA	ICCOM,X
	JMP	CIOV
;
;############################
;
;Start of Program
;
;############################
;
BEGIN	CLD
	SEI
	LDA	POKMSK
	AND	#$7F	;Kill BREAK
	STA	POKMSK
	STA	IRQEN
	CLI
	JSR	INTRO
	LDY	#$1F
	LDA	#$20
ER_I1	STA	INBUF+$0400,Y
	DEY
	BPL	ER_I1
	JSR	GETDIR
	BCS	USE_DEF
		PRINT WHAT_D
	INC	IPUT
D_NUM	JSR	GETKEY
	CMP	#EOL
	BEQ	USE_DEF1
	AND	#$7F
	CMP	#'0
	BCC	D_NUM
	CMP	#':
	BCS	D_NUM
	STA	ASAV
	JSR	LOAD_DIC
	LDA	ASAV
	BNE	SPELL
;
USE_DEF1	DEC	IPUT
USE_DEF		PRINT DEF_NUM
	INC	IPUT
G_NUM	JSR	GETKEY
	AND	#$7F
	CMP	#'0
	BCC	G_NUM
	CMP	#':
	BCS	G_NUM
SPELL	STA	DICT_NUM
	STA	DIC_NAME+11
	JSR	ZAP_FN
	JSR	SHO_BOX
	DEC	IPUT
;
MAINLOOP		PRINT M_MENU
	INC	IPUT
M_KEY	JSR	GETKEY
	JSR	CONL2U
	LDY	#5
M_COM	CMP	COM_KEY,Y
	BEQ	M_CK
	DEY
	BPL	M_COM
	BMI	M_NUM
M_CK	TYA
	JMP	M_ENTER
M_NUM	CMP	#'0
	BCC	M_KEY
	CMP	#'7
	BCS	M_KEY
	SEC
	SBC	#'1
M_ENTER	ASL	A
	TAY
	LDA	COMTAB,Y
	STA	COMJMP+1
	LDA	COMTAB+1,Y
	STA	COMJMP+2
	LDA	NAMTAB,Y
	PHA
	LDA	NAMTAB+1,Y
	PHA
	JSR	CLRSCR
	JSR	PUT_A0
	PLA
	TAY
	PLA
	JSR	EPRINT
	JSR	PUT_A0
	JSR	PUTCR
	INC	YPOS
	DEC	IPUT
COMJMP	JMP	$FFFF
;
;Print a Inverse Space
;
PUT_A0	LDA	#$A0
	JMP	EPUT
;
;Input Routine
;
INPUT	STY	MAXLEN
	LDX	#1
	STX	IPUT
	DEX
	STX	ILEN
;
INLOOP	STX	SAVEX
	JSR	GETKEY
	LDX	SAVEX
	CMP	#EOL
	BEQ	INDONE
	STA	CHAR
	AND	#$7F
	CMP	#$20
	BCC	INLOOP
	CMP	#126
	BNE	INEXT
	CPX	#0
	BEQ	INLOOP
	DEX
	JSR	EPUTX
	JMP	INLOOP
;
INEXT	CMP	#$60
	BEQ	INLOOP
	CMP	#123
	BEQ	INLOOP
	CMP	#125
	BCS	INLOOP
	LDA	CHAR
	CPX	MAXLEN
	BEQ	INLOOP
	STA	MYBUF,X
	JSR	EPUTX
	INX
	BNE	INLOOP
;
INDONE	STA	MYBUF,X
	STX	ILEN
	LDA	#0
	STA	MYBUF+1,X
	STA	IPUT
	JMP	PUTCR
;
;Put a byte but save X
;
EPUTX	STX	SAVEX
	JSR	EPUT
	LDX	SAVEX
	RTS
;
;Handle I/O Error
;
IOERROR	LDA	#0
	JSR	CON_NUM
		PRINT IOTXT
		PRINT NUMBUF+1
	JSR	PUTCR
WAITKEY		PRINT WAIT_TXT
	INC	IPUT
	JSR	GETKEY
	DEC	IPUT
	RTS
;
;Show NOT FOUND
;
NOT_FOUND	JSR	CLRSCR
		PRINT M0
	LDA	#3
	STA	YPOS
	JSR	FIND_LEN
	PHA
	CLC
	ADC	#9
	STA	XPOS
	LDA	#39
	SEC
	SBC	XPOS
	LSR	A
	STA	XPOS
		PRINT NOT_F
	JSR	PRINT_WORD
	PLA
	STA	RJUST
	LDX	#0
	LDY	WORD_POS
NOT_1	LDA	TOPHALF+280,Y
	ORA	#$80
	STA	TOPHALF+280,Y
	INY
	INX
	CPX	RJUST
	BNE	NOT_1
	LDA	#5
	STA	YPOS
	STA	XPOS
	LDA	#'>
	JSR	EPUT
	INC	XPOS
	LDY	#29
	JSR	INPUT
	JSR	STRIP
	LDA	MYBUF
	CMP	#EOL
	BEQ	NO_REP
;
	JSR	MY2WORD
NO_REP	JSR	SEARCH
	BCC	NO_R1
	LDA	#7
	STA	YPOS
	LDA	#12
	STA	XPOS
		PRINT ADD_TXT
	JSR	GETYN
	BNE	NO_R1
	JSR	ADD_WORD
NO_R1	RTS
;
;Get a Y/N
;
GETYN		PRINT YNTXT
	INC	IPUT
GET_W	JSR	GETKEY
	CMP	#EOL
	BEQ	HAV_Y
	AND	#223
	CMP	#'Y
	BNE	TRY_N
HAV_Y	LDA	#'Y
	BNE	SHO_RESP
TRY_N	CMP	#'N
	BNE	GET_W
SHO_RESP	CMP	#'Y
	PHP
	JSR	EPUT
	DEC	IPUT
	JSR	PUTCR
	PLP
	RTS
;
;Get Word length
;
FIND_LEN	LDY	#0
FND_1	LDA	WORD,Y
	BEQ	FND_EN
	INY
	BNE	FND_1
FND_EN	TYA
	RTS
;
;Get a Filename
;
GETFN	LDY	#24
	JSR	INPUT
;
	LDA	ILEN
	BNE	COP0
	SEC
	RTS
;
COP0	LDX	#0
	LDA	MYBUF+1
	CMP	#':
	BEQ	YZERO
	LDA	MYBUF+2
	CMP	#':
	BEQ	YZERO
	LDY	#2
COP1	LDA	D1TXT,Y
	STA	FILNAM,Y
	DEY
	BPL	COP1
	LDY	#3
	BNE	COPMYBF
YZERO	LDY	#0
COPMYBF	LDA	MYBUF,X
	JSR	CONL2U
	STA	FILNAM,Y
	CMP	#EOL
	BEQ	COPFILD
	INY
	INX
	BNE	COPMYBF
COPFILD	LDA	#0
	STA	FILNAM+1,Y
	LDA	FILNAM
	CMP	#'E
	BEQ	INSDD
	CMP	#'S
	BNE	COPOK
INSDD	LDA	#'D
	STA	FILNAM
COPOK	CLC
	RTS
;
;Make a number ASCII
;
;ENTER: Y=lo byte
;       A=hi byte
;
CON_NUM	STY	FR0
	STA	FR0+1
	JSR	IFP
	JSR	FASC
	LDY	#4
	LDA	#$20
CON_1	STA	NUMBUF,Y
	DEY
	BPL	CON_1
;
CON_2	INY
	LDA	(INBUFF),Y
	BPL	CON_2
	AND	#$7F
	STA	(INBUFF),Y
	STY	RJUST
	LDA	#4
	SEC
	SBC	RJUST
	TAX
	PHA
	LDY	#0
CPYRJ	LDA	(INBUFF),Y
	STA	NUMBUF,X
	INY
	INX
	CPX	#5
	BNE	CPYRJ
	PLA
	RTS
;
;Convert lower to Upper
;
CONL2U	CMP	#EOL
	BEQ	CNNCR
	AND	#$7F
	CMP	#97
	BCC	CNNCR
	CMP	#123
	BCS	CNNCR
	AND	#223
CNNCR	RTS
;
;Just add words to Dictionary
;
JUST_ADD		PRINT ADD_FILE
	LDX	#0
	STX	OEOF?
	INX
	STX	OUTPUT?
	JSR	GETFN
	BCS	J_MAIN
	JSR	OPENIN
	BMI	JUST_ERR
	LDA	#0
	STA	WCOUNT
	STA	WCOUNT+1
	STA	LAST_WORD
	JSR	SHO_BOX
ADD_LP	JSR	GET_WORD
	LDA	EOF2?
	BNE	JADD_CL
	JSR	CONTEXT
	JSR	SEND_WORD
	JSR	TOKENIZE
	JSR	SEARCH
	BCC	UP_CNT
	JSR	ADD_WORD
UP_CNT		BUMP WCOUNT
	JSR	SHB_3
	JMP	ADD_LP
JADD_CL	LDA	ERRORR
	BPL	J_MAIN
	CMP	#136
	BEQ	J_MAIN
JUST_ERR	JSR	IOERROR
J_MAIN	JSR	DCLOSE
	JMP	MAINLOOP
;
;Open Input file
;
OPENIN	JSR	DCLOSE
	LDA	#1
	STA	R_PASS
	LDA	#5
	STA	RINDEX+1
	LDA	#0
	STA	EOF?
	STA	EOF2?
	LDA	#<999
	STA	MAXGET
	LDA	#>999
	STA	MAXGET+1
	LDA	#$FF
	STA	RINDEX
	LDX	#$30
	LDA	#3
	STA	ICCOM,X
	LDA	#<FILNAM
	STA	ICBAL,X
	LDA	#>FILNAM
	STA	ICBAH,X
	LDA	#4
	STA	AUX1,X
	LDA	#0
	STA	AUX2,X
	JMP	CIOV
;
;Open OUTPUT File
;
OPENOUT	JSR	CLOSE2
	LDX	#$20
	LDA	#3
	STA	ICCOM,X
	LDA	#8
	STA	AUX1,X
	LDA	#0
	STA	AUX2,X
	STA	WINDEX
	STA	WINDEX+1
	STA	OEOF?
	STA	OUTPUT?
	LDA	#<TMPNAME
	STA	ICBAL,X
	LDA	#>TMPNAME
	STA	ICBAH,X
	JMP	CIOV
;
;Get a word from file
;
GET_WORD	LDY	#0	;index
	STY	NO_JUNK
GET_1	JSR	GET_BYTE
	LDX	EOF2?
	BNE	WG_L
	STA	CHAR
	AND	#$7F
	JSR	CONL2U
	CMP	#'A
	BCC	GOT_SPC
	CMP	#'Z+1
	BCC	ST_WORD
GOT_SPC	LDA	CHAR
	JSR	SEND_BYTE
	LDA	OEOF?
	BNE	WG_L
	JMP	GET_1
;
ST_WORD	LDA	CHAR
	STA	WORD,Y
W_LOOP	JSR	GET_BYTE
	LDX	EOF2?
	BNE	G_SPC1
	LDX	#30
	STA	CHAR
W_LP1	LDA	CHAR
	CMP	LIKE_SPC,X
	BEQ	G_SPC
	AND	#$7F
	CMP	LIKE_SPC,X
	BEQ	G_SPC
	DEX
	BPL	W_LP1
	LDA	CHAR
	AND	#$7F
	CMP	#$20
	BCC	G_SPC
;
	INY
	CPY	#29
	BCS	EAT_WORD
	LDA	CHAR
	STA	WORD,Y
	JMP	W_LOOP
;
G_SPC1	INC	NO_JUNK
G_SPC	LDA	CHAR
	STA	LAST_ONE
	LDA	#0
	STA	WORD+1,Y
WG_L	RTS
;
;Eat a word > 29 chars
;
EAT_WORD	LDY	#0
EAT_1	LDA	WORD,Y
	JSR	SEND_BYTE
	LDA	OEOF?
	BNE	WG_L
	INY
	CPY	#29
	BNE	EAT_1
EAT_2	JSR	GET_BYTE
	LDX	EOF2?
	BNE	WG_L
	JSR	CONL2U
	CMP	#'A
	BCC	EAT_3
	CMP	#'Z+1
	BCS	EAT_3
	JSR	SEND_BYTE
	LDA	OEOF?
	BNE	WG_L
	JMP	EAT_2
EAT_3	JSR	SEND_BYTE
	LDA	OEOF?
	BNE	WG_L
	JMP	GET_WORD
;
;Get a byte from file
;
GET_BYTE	LDA	RINDEX
	CLC
	ADC	#<INBUF
	STA	TEMP
	LDA	RINDEX+1
	ADC	#>INBUF
	STA	TEMP+1
	STY	RYSAV
	STX	RXSAV
	LDA	RINDEX+1
	CMP	MAXGET+1
	BCC	FROMMEM
	LDA	RINDEX
	CMP	MAXGET
	BCC	FROMMEM
	BEQ	FROMMEM
;
	LDA	EOF?
	BEQ	GO_GETM
	INC	EOF2?
	RTS
GO_GETM	JSR	GET1K
	STY	ERRORR
	PHP
	LDA	#<INBUF
	STA	TEMP
	LDA	#>INBUF
	STA	TEMP+1
;
	LDA	#0
	STA	RINDEX
	STA	RINDEX+1
	PLP
	BPL	FROMMEM
	LDX	#$30
	LDA	ICBLL,X
	STA	MAXGET
	LDA	ICBLH,X
	STA	MAXGET+1
	LDA	R_PASS
	BNE	LEN_OK
	LDA	MAXGET
	CLC
	ADC	#24
	STA	MAXGET
	LDA	MAXGET+1
	ADC	#0
	STA	MAXGET+1
LEN_OK	INC	EOF?
	LDA	MAXGET
	SEC
	SBC	#1
	STA	MAXGET
	LDA	MAXGET+1
	SBC	#0
	STA	MAXGET+1
;
FROMMEM	LDY	#0
	STY	R_PASS
	LDA	(TEMP),Y
		BUMP RINDEX
	LDY	RYSAV
	LDX	RXSAV
	RTS
;
;Read @1K
;
GET1K	LDX	#$30
	LDA	#7
	STA	ICCOM,X
	LDA	#<[INBUF+24]
	STA	ICBAL,X
	LDA	#>[INBUF+24]
	STA	ICBAH,X
	LDA	#<1000
	STA	ICBLL,X
	LDA	#>1000
	STA	ICBLH,X
	LDY	#23
MV_24	LDA	INBUF+1000,Y
	STA	INBUF,Y
	DEY
	BPL	MV_24
;
	LDA	R_PASS
	BEQ	CALL_CIO
	LDA	#<INBUF
	STA	ICBAL,X
	LDA	#>INBUF
	STA	ICBAH,X
	LDA	#0
	STA	ICBLL,X
	LDA	#4
	STA	ICBLH,X
;
CALL_CIO	JSR	CIOV
	STY	ERRORR
	PHP
	BPL	CALL_GOOD
	LDX	#$30
	LDA	ICBLL,X
	CLC
	ADC	#<INBUF
	STA	INDR
	LDA	ICBLH,X
	ADC	#>INBUF
	STA	INDR+1
	LDA	R_PASS
	BNE	C_END
	LDA	INDR
	CLC
	ADC	#24
	STA	INDR
	LDA	INDR+1
	ADC	#0
	STA	INDR+1
C_END	LDY	#0
	LDA	#$20
;
GET_K1	STA	(INDR),Y
		BUMP INDR
	LDX	INDR+1
	CPX	#>[INBUF+$0400]
	BCC	GET_K1
CALL_GOOD	PLP
	RTS
;
;Send byte to Output
;
SEND_BYTE	STY	WYSAV
	STX	WXSAV
	PHA
	LDA	OUTPUT?
	BEQ	SEND_1
	LDA	#0
	STA	OEOF?
	PLA
	RTS
SEND_1	LDA	WINDEX
	CLC
	ADC	#<OUTBUF
	STA	TEMP
	LDA	WINDEX+1
	ADC	#>OUTBUF
	STA	TEMP+1
	LDA	WINDEX
	BNE	TOBUF
	LDA	WINDEX+1
	CMP	#4
	BCC	TOBUF
;
	LDA	#0
	STA	WINDEX
	STA	WINDEX+1
	LDX	#$20
	LDA	#11
	STA	ICCOM,X
	LDA	#<OUTBUF
	STA	TEMP
	STA	ICBAL,X
	LDA	#>OUTBUF
	STA	TEMP+1
	STA	ICBAH,X
	LDA	#0
	STA	ICBLL,X
	LDA	#4
	STA	ICBLH,X
	JSR	CIOV
	BPL	NO_B
	INC	OEOF?
NO_B	STY	ERROR
TOBUF	LDY	#0
	PLA
	STA	(TEMP),Y
		BUMP WINDEX
	LDX	WXSAV
	LDY	WYSAV
	RTS
;
;Send remaining buffer to file
;
SEND_END	LDX	#$20
	LDA	#11
	STA	ICCOM,X
	LDA	#<OUTBUF
	STA	ICBAL,X
	LDA	#>OUTBUF
	STA	ICBAH,X
	LDA	WINDEX
	STA	ICBLL,X
	LDA	WINDEX+1
	STA	ICBLH,X
	ORA	WINDEX
	BEQ	SEND_LV
	JSR	CIOV
SEND_LV	RTS
;
;Send word to file
;
SEND_WORD	LDY	#0
SEND_W1	LDA	WORD,Y
	STA	LAST_WORD,Y
	BEQ	SND_LST
	JSR	SEND_BYTE
	LDA	OEOF?
	BNE	SEND_OUT
	INY
	BNE	SEND_W1
SND_LST	LDA	NO_JUNK
	BNE	SEND_OUT
	LDA	LAST_ONE
	JMP	SEND_BYTE
SEND_OUT	RTS
;
;Make context line
;
CONTEXT	LDY	#13
CNT_0	LDA	D_CONT,Y
	STA	TOPHALF+253,Y
	DEY
	BPL	CNT_0
	LDA	#0
	LDA	#0
	LDY	#39
CNT_1	STA	CNLINE,Y
	DEY
	BPL	CNT_1
	TAY
CNT_2	LDA	LAST_WORD,Y
	BEQ	CNT_3
	JSR	ASC2IC
	AND	#$7F
	STA	CNLINE,Y
	INY
	BNE	CNT_2
CNT_3	INY
	STY	WORD_POS
	LDX	#0
CNT_4	LDA	WORD,X
	BEQ	CNT_5
	JSR	ASC2IC
	AND	#$7F
	STA	CNLINE,Y
	INX
	INY
	CPY	#40
	BNE	CNT_4
CNT_5	CPY	#40
	BEQ	CNT_LV
	TYA
	TAX
	LDA	LAST_ONE
	JSR	ASC2IC
	AND	#$7F
	STA	CNLINE,X
	INX
	LDY	#0
	LDA	RINDEX
	CLC
	ADC	#<INBUF
	STA	TEMP
	LDA	RINDEX+1
	ADC	#>INBUF
	STA	TEMP+1
CNT_6	LDA	(TEMP),Y
	JSR	ASC2IC
	AND	#$7F
	STA	CNLINE,X
	INY
	INX
	CPX	#40
	BCS	CNT_LV
	CPY	#24
	BCC	CNT_6
CNT_LV	LDX	#39
CNT_7	LDA	CNLINE,X
	STA	TOPHALF+280,X
	DEX
	BPL	CNT_7
	RTS
;
;This is the Dictionary
;
DICTION
NUM_WORDS	.WORD	26
AWORD	.WORD	A1,B1,C1,D1,E1
	.WORD	F1,G1,H1,I1,J1
	.WORD	K1,L1,M12,N1,O1
	.WORD	P1,Q1,R1,S1,T1
	.WORD	U1,V1,W1,X1,Y1,Z1
ENDWORD	.WORD	AFTERZ
;
WORDS_IN	.WORD	1,1,1,1,1,1
	.WORD	1,1,1,1,1,1,1,1,1,1
	.WORD	1,1,1,1,1,1,1,1,1,1
;
A1	.CBYTE	"T"
B1	.CBYTE	"UT"
C1	.CBYTE	"AN"
D1	.CBYTE	"O"
E1	.CBYTE	"ND"
F1	.CBYTE	"OR"
G1	.CBYTE	"ET"
H1	.CBYTE	"OW"
I1	.CBYTE	"N"
J1	.CBYTE	"OG"
K1	.CBYTE	"NOW"
L1	.CBYTE	"ET"
M12	.CBYTE	"E"
N1	.CBYTE	"O"
O1	.CBYTE	"N"
P1	.CBYTE	"UT"
Q1	.CBYTE	"UIT"
R1	.CBYTE	"ED"
S1	.CBYTE	"O"
T1	.CBYTE	"HE"
U1	.CBYTE	"P"
V1	.CBYTE	"AN"
W1	.CBYTE	"HO"
X1	.CBYTE	"EBEC"
Y1	.CBYTE	"ES"
Z1	.CBYTE	"IP"
AFTERZ
;
;Set Run Address
;
	*=	$02E0
	.WORD	START
	.END

Listing 2: SPELL.DAT

;--------------------------
;
;DATA/HOLD AREAS FOR SPELL
;
;--------------------------
;
;Display List
;
DLIST	.BYTE	$70,$70,$70,$52
	.WORD	MYLINE
	.BYTE	$00,$42
	.WORD	TOPHALF
	.BYTE	$02,$02,$02,$02,$02
	.BYTE	$02,$82,$30,$42
	.WORD	BOTHALF
	.BYTE	$02,$02,$02,$02,$02
	.BYTE	$02,$02,$02,$02,$02
	.BYTE	$02,$02,$41
	.WORD	DLIST
;
MYLINE	.SBYTE	+$80,"        "
	.SBYTE	+$80,"The Personal"
	.SBYTE	+$80," Spelling "
	.SBYTE	+$80,"Checker "
	.SBYTE	+$80,"      "
;
ITXT	.BYTE	3
	.SBYTE	"by: Bryan Schapp"
	.SBYTE	"el and Barry Kolbe"
	.BYTE	$FF,$FF,7
	.SBYTE	"Insert Dictionary "
	.SBYTE	"Disk and"
	.BYTE	$FF,$FF,14
	.SBYTE	"Press RETURN"
	.BYTE	$FD	;end of text
;
;Misc. Text
;
DIC_NAME	.BYTE	"D1:DICTION.?"
	.BYTE	EOL,0
EADR	.BYTE	"E:"
BKP_TXT	.BYTE	EOL,"PKB."
TMPNAME	.BYTE	"D1:DOC.TMP",EOL
FREETXT	.BYTE	"E SEC"
D_HEAD	.SBYTE	+$80," Dictionary"
DIR_N	.SBYTE	+$80," Directory "
DIR_Q	.SBYTE	+$80,"D  "
D_NONE	.SBYTE	+$80," NONE "
D_CONT	.SBYTE	+$80," CONTEXT "
	.SBYTE	+$80,"LINE "
NOT_F	.BYTE	"Correct? ",0
D1TXT	.BYTE	"D1:"
DIR_TXT	.BYTE	"D1:*.*",EOL
YNTXT	.BYTE	" [Y/N]? ",0
A2I	.BYTE	$40,$00,$20,$60
;
LIKE_SPC	.BYTE	" .,?;:()!-/\"
	.BYTE	"[]+*=$%&@<>#_|^"
	.BYTE	EOL,$7F,$60,$22
;
WHAT_D	.BYTE	125,"Enter RETURN "
	.BYTE	"for DEFAULT Diction"
	.BYTE	"ary",EOL,EOL
	.BYTE	"Which # to Load: ",0
;
DEF_NUM	.BYTE	EOL,EOL
	.BYTE	"Working Dictionary "
	.BYTE	"#: ",0
;
IOTXT	.BYTE	EOL,"I/O Error -",0
NUMBUF	.BYTE	"     ",0
WAIT_TXT	.BYTE	EOL,"Press any"
	.BYTE	" key ",0
REST_TXT	.BYTE	EOL,"Re-start",0
;
PROOF_NM	.BYTE	"File to Proof: "
	.BYTE	0
;
ADD_TXT	.BYTE	"Add Word",0
ADD_FILE	.BYTE	"Add File: ",0
DEL_TXT	.BYTE	"Delete Word: ",0
DEL_IT	.BYTE	EOL,"Delete '",0
WNF	.BYTE	EOL,"Word Not Found."
	.BYTE	EOL,0
SAV_TXT	.BYTE	"Save "
DC_TXT	.BYTE	"Dictionary",0
DC_PRM	.BYTE	EOL,"Insert ",0
DC_PRM2	.BYTE	" disk, Press "
	.BYTE	"RETURN ",0
;
V_TXT	.BYTE	"View Letter [A-Z]?"
	.BYTE	" ",0
V_MORE	.BYTE	"View More",0
;
N_WORDS	.BYTE	" Words in '"
N_W	.BYTE	" '.",0
DRIVE_N	.BYTE	"Drive [1,2,3,4,"
	.BYTE	"8]? ",0
LEGAL_D	.BYTE	"12348"
;
M_MENU	.BYTE	125," Main Menu "
	.BYTE	EOL,EOL
	.BYTE	"1) Proof Document"
	.BYTE	EOL
	.BYTE	"2) Delete Word",EOL
	.BYTE	"3) View Dictionary"
	.BYTE	EOL
	.BYTE	"4) Add File to "
	.BYTE	"Dictionary",EOL
	.BYTE	"5) Catalog",EOL
	.BYTE	"6) Exit PSC",EOL,EOL
	.BYTE	"Choice > ",0
;
COM_KEY	.BYTE	"PDVACE"
;
INFO_BOX
	.BYTE	"QRRRRRRRRRRRRRRWRRRR"
	.BYTE	"RRRRRRRRRRRRRRRRRRRE"
	.SBYTE	"|Dictionary >  | Fi"
	.SBYTE	"le >               "
	.SBYTE	" |"
	.BYTE	"ARRRRRRRRRRRWRRXRRRR"
	.BYTE	"RRRRRRWRRRRRRRRRRRRD"
	.SBYTE	"|Free:      |Words:"
	.SBYTE	"       |Count:     "
	.SBYTE	" |"
	.BYTE	"ZRRRRRRRRRRRXRRRRRRR"
	.BYTE	"RRRRRRXRRRRRRRRRRRRC"
;
M0	.BYTE	"Proof Document",0
M1	.BYTE	"Delete Word",0
M2	.BYTE	"View Dictionary",0
M3	.BYTE	"Add File",0
M4	.BYTE	"Catalog",0
M5	.BYTE	"Exit PSC",0
;
NAMTAB	.WORD	M0,M1,M2,M3,M4,M5
;
;Command Table
;
COMTAB	.WORD	PROOF
	.WORD	DELETE
	.WORD	VIEW
	.WORD	JUST_ADD
	.WORD	DIRECT
	.WORD	QUIT
;
;Buffer Space
;
CNLINE	.DS	45	;context line
WORD	.DS	31	;current word
T_WORD	.DS	31	;tokenized word
LAST_WORD	.DS	31	;last word
MYBUF	.DS	45	;input buffer
FILNAM	.DS	60	;file name
	.BYTE	EOL,0

Listing 3: SPELL.SUB

;---------------------
;
;Subroutines for CHECK
;
;---------------------
;
TOKENIZE	LDY	#0
TOK_1	LDA	WORD,Y
	BEQ	INV_IT
	JSR	CONL2U
	STA	T_WORD,Y
	INY
	BNE	TOK_1
INV_IT	CPY	#0
	BEQ	INV_L
	LDA	T_WORD-1,Y
	ORA	#$80
	STA	T_WORD-1,Y
INV_L	RTS
;
;Print a tokenized word
;
PRINT_WORD	LDX	#$FF
PW_1	INX
	LDA	T_WORD,X
	PHA
	AND	#$7F
	JSR	EPUTX
	PLA
	BPL	PW_1
	RTS
;
;Get amount of free memory
;
FIND_FREE	LDA	#0
	SEC
	SBC	ENDWORD
	STA	FREEM
	LDA	RAMTOP
	SBC	ENDWORD+1
	STA	FREEM+1
	RTS
;
;Search the Dictionary
;
SEARCH	JSR	MAKE_INDEX
	TAY
	LDA	AWORD,Y
	STA	INDR
	LDA	AWORD+1,Y
	STA	INDR+1
	LDA	AWORD+2,Y
	STA	TEMP
	LDA	AWORD+3,Y
	STA	TEMP+1
;
SRCH	LDY	#$FF
D_LEN	INY
	LDA	(INDR),Y
	BPL	D_LEN
	INY
	STY	ASAV
;
	LDY	#0
	LDX	#0
	LDA	T_WORD
	BMI	SRCH_1
	INX
SRCH_1	LDA	T_WORD,X
	CMP	(INDR),Y
	BNE	SRCH_NXT
	INX
	INY
	CPY	ASAV
	BNE	SRCH_1
	CLC
	RTS		;found it!
;
SRCH_NXT	LDA	INDR
	CLC
	ADC	ASAV
	STA	INDR
	LDA	INDR+1
	ADC	#0
	STA	INDR+1
	LDA	INDR
	CMP	TEMP
	BNE	SRCH
	LDA	INDR+1
	CMP	TEMP+1
	BNE	SRCH
	SEC
	RTS		;not found!
;
;Proof a file
;
PROOF		PRINT PROOF_NM
	JSR	GETFN
	BCS	PROOF_M
;
;Make DOC.TMP same drive as
;Source file.
;
	LDY	#'1
	LDA	FILNAM+1
	CMP	#':	;a ':'?
	BEQ	PRF_GC
	LDX	FILNAM+2
	CPX	#':
	BNE	PRF_GC
	TAY
PRF_GC	STY	TMPNAME+1
	JSR	OPENIN
	BMI	PROOF_E
	JSR	OPENOUT
	BMI	PROOF_E
	LDA	#0
	STA	WCOUNT
	STA	WCOUNT+1
	STA	LAST_WORD
	JSR	SHO_BOX
;
PROOF1	JSR	GET_WORD
	LDA	NO_JUNK
	BNE	P_LAST
	LDA	EOF2?
	BNE	PR_CL
	LDA	OEOF?
	BNE	PR_OER
P_LAST	JSR	CONTEXT
	JSR	TOKENIZE
	JSR	SEARCH
	BCC	PROOF2
	JSR	NOT_FOUND
PROOF2	JSR	SEND_WORD
	LDA	OEOF?
	BEQ	P_BMP
PR_OER	LDY	ERROR
	BNE	PROOF_E
P_BMP		BUMP WCOUNT
	JSR	SHB_3	;show counts
	JMP	PROOF1
;
PR_CL	LDY	ERRORR
	BPL	PR_OK
	CPY	#136
	BNE	PROOF_E
PR_OK	JSR	DCLOSE
	JSR	SEND_END
	JSR	CLOSE2
	JSR	RENAME
PROOF_V	JSR	CLOSE2
PROOF_M	JMP	MAINLOOP
PROOF_E	JSR	IOERROR
	JSR	DCLOSE
	JMP	PROOF_V
;
;Move memory UP (delete)
;
MOVE_UP	LDA	FROML
	STA	UMOVLP+1
	LDA	FROMH
	STA	UMOVLP+2
	LDA	DESTL
	STA	UMOVLP+4
	LDA	DESTH
	STA	UMOVLP+5
	LDX	HLEN
	BEQ	SKIPMOV
MOV1	LDA	#0
MOV2	STA	ENDPOS
	LDY	#0
UMOVLP	LDA	$FFFF,Y
	STA	$FFFF,Y
	INY
	CPY	ENDPOS
	BNE	UMOVLP
	INC	UMOVLP+2
	INC	UMOVLP+5
	CPX	#0
	BEQ	UMVOUT
	DEX
	BNE	MOV1
SKIPMOV	LDA	LLEN
	BNE	MOV2
UMVOUT	RTS
;
;Move memory down (Insert)
;
MOVE_DN	LDA	HLEN
	TAX
	ORA	LLEN
	BNE	NOTNULL
	RTS
NOTNULL	CLC
	TXA
	ADC	FROMH
	STA	DMOVLP+2
	LDA	FROML
	STA	DMOVLP+1
	CLC
	TXA
	ADC	DESTH
	STA	DMOVLP+5
	LDA	DESTL
	STA	DMOVLP+4
	INX
	LDY	LLEN
	BNE	DMOVLP
	BEQ	SKIPDMV
DMOV1	LDY	#$FF
DMOVLP	LDA	$FFFF,Y
	STA	$FFFF,Y
	DEY
	CPY	#$FF
	BNE	DMOVLP
SKIPDMV	DEC	DMOVLP+2
	DEC	DMOVLP+5
	DEX
	BNE	DMOV1
	RTS
;
;Add a word to the Dictionary
;
ADD_WORD	LDY	#$FF
ADD_0	INY
	LDA	T_WORD,Y
	BPL	ADD_0
	INY
	CPY	#1
	BEQ	ADD_1
	DEY
ADD_1	STY	LEN_1
	JSR	FIND_FREE
	LDA	FREEM+1
	BNE	CAN_ADD
	LDA	FREEM
	CMP	LEN_1
	BCS	CAN_ADD
	RTS
CAN_ADD	JSR	MAKE_INDEX
	TAX
	INC	WORDS_IN,X
	BNE	ADD_NH
	INC	WORDS_IN+1,X
ADD_NH	JSR	CHK_EDIT
	JSR	WHERE?
;
	CLC
	LDA	TEMP
	STA	FROML
	ADC	LEN_1
	STA	DESTL
	LDA	TEMP+1
	STA	FROMH
	ADC	#0
	STA	DESTH
	LDA	ENDWORD
	SEC
	SBC	FROML
	STA	LLEN
	LDA	ENDWORD+1
	SBC	FROMH
	STA	HLEN
	JSR	MOVE_DN
;
	LDA	T_WORD
	AND	#$7F
	SEC
	SBC	#'A-1
	TAX
	ASL	A
	TAY
UPDATE	LDA	AWORD,Y
	CLC
	ADC	LEN_1
	STA	AWORD,Y
	LDA	AWORD+1,Y
	ADC	#0
	STA	AWORD+1,Y
	INY
	INY
	INX
	CPX	#27
	BNE	UPDATE
		BUMP NUM_WORDS
	LDY	#0
	LDX	#0
	LDA	T_WORD
	BMI	UPD
	INX
UPD	LDA	T_WORD,X
	STA	(TEMP),Y
	BMI	ADD_LV
	INX
	INY
	BNE	UPD
ADD_LV	JMP	SHB_3
;
;Delete a Word
;
DELETE	JSR	CLRSCR
		PRINT M1
	LDA	#2
	STA	XPOS
	STA	YPOS
;
		PRINT DEL_TXT
	LDY	#29
	JSR	INPUT
;
DEL_MV	JSR	MY2WORD
	LDA	MYBUF
	CMP	#EOL
	BNE	D_S
	JMP	MAINLOOP
D_S	JSR	SEARCH
	BCC	GO_DEL
		PRINT WNF
	JSR	WAITKEY
	JMP	DELETE
;
GO_DEL		PRINT DEL_IT
	JSR	PRINT_WORD
	LDA	#''
	JSR	EPUT
	JSR	GETYN
	BNE	DELETE
	LDY	#$FF
DEL_L	INY
	LDA	T_WORD,Y
	BPL	DEL_L
	INY
	CPY	#1
	BEQ	DEL_M
	DEY
DEL_M	STY	LEN_1
	JSR	SEARCH
	LDA	INDR
	STA	DESTL
	CLC
	ADC	LEN_1
	STA	FROML
	LDA	INDR+1
	STA	DESTH
	ADC	#0
	STA	FROMH
	LDA	ENDWORD
	SEC
	SBC	FROML
	STA	LLEN
	LDA	ENDWORD+1
	SBC	FROMH
	STA	HLEN
	JSR	MAKE_INDEX
	TAX
	LDA	WORDS_IN,X
	ORA	WORDS_IN+1,X
	CMP	#2
	BCC	DELETE_G
	LDA	WORDS_IN,X
	SEC
	SBC	#1
	STA	WORDS_IN,X
	LDA	WORDS_IN+1,X
	SBC	#0
	STA	WORDS_IN+1,X
	JSR	MOVE_UP
	LDA	NUM_WORDS
	SEC
	SBC	#1
	STA	NUM_WORDS
	LDA	NUM_WORDS+1
	SBC	#0
	STA	NUM_WORDS+1
	JSR	CHK_EDIT
	LDA	T_WORD
	AND	#$7F
	SEC
	SBC	#'A-1
	TAX
	ASL	A
	TAY
DNDATE	LDA	AWORD,Y
	SEC
	SBC	LEN_1
	STA	AWORD,Y
	LDA	AWORD+1,Y
	SBC	#0
	STA	AWORD+1,Y
	INY
	INY
	INX
	CPX	#27
	BNE	DNDATE
	JSR	SHO_BOX
DELETE_G	JMP	DELETE
;
;Check Edit Flag
;
CHK_EDIT	LDA	#1
	STA	EDITED
	RTS
;
;Quit from Program
;
QUIT	LDA	EDITED
	BNE	TRY_SAVE
	DEC	YPOS
GO_JMP	JMP	GO_DOS
;
TRY_SAVE		PRINT SAV_TXT
	JSR	ZAP_FN
	JSR	SHO_BOX
	JSR	GETYN
	BNE	GO_JMP
		PRINT DC_PRM
		PRINT DC_TXT
		PRINT DC_PRM2
	JSR	GET_RET
	JSR	DCLOSE
	LDX	#$30
	LDA	#3
	STA	ICCOM,X
	LDA	#<DIC_NAME
	STA	ICBAL,X
	LDA	#>DIC_NAME
	STA	ICBAH,X
	LDA	#8
	STA	AUX1,X
	LDA	#0
	STA	AUX2,X
	JSR	CIOV
	BPL	Q_OPEN
Q_ERR	JSR	PUTCR
	JSR	IOERROR
	JSR	DCLOSE
	JMP	MAINLOOP
;
Q_OPEN	LDX	#$30
	LDA	#11
	STA	ICCOM,X
	LDA	#<DICTION
	STA	ICBAL,X
	LDA	#>DICTION
	STA	ICBAH,X
	LDA	ENDWORD
	SEC
	SBC	#<DICTION
	STA	ICBLL,X
	LDA	ENDWORD+1
	SBC	#>DICTION
	STA	ICBLH,X
	JSR	CIOV
	BMI	Q_ERR
;
	JSR	DCLOSE
GO_DOS		PRINT REST_TXT
	JSR	GETYN
	BNE	DOS_MAIN
	JMP	BEGIN
DOS_MAIN	LDX	#0
	STX	GRACTL
	LDA	#12
	STA	ICCOM,X
	JSR	CIOV
	JSR	DCLOSE
	JSR	CLOSE2
	LDA	#6
	LDY	#<SYSVBV
	LDX	#>SYSVBV
	JSR	SETVBV
	LDA	#7
	LDY	#<XITVBV
	LDX	#>XITVBV
	JSR	SETVBV
;
	LDX	#0
	STX	HPOSP2
	LDA	#3
	STA	ICCOM,X
	LDA	#<EADR
	STA	ICBAL,X
	LDA	#>EADR
	STA	ICBAH,X
	LDA	#12
	STA	AUX1,X
	STX	AUX2
	JSR	CIOV
	LDA	#$40
	STA	SHFLOK
	JMP	(DOSVEC)
;
;Load a Dictionary
;
LOAD_DIC	STA	DIC_NAME+11
	JSR	DCLOSE
	LDX	#$30
	LDA	#3
	STA	ICCOM,X
	LDA	#<DIC_NAME
	STA	ICBAL,X
	LDA	#>DIC_NAME
	STA	ICBAH,X
	LDA	#4
	STA	AUX1,X
	LDA	#0
	STA	AUX2,X
	JSR	CIOV
	BPL	L_OPEN
L_ERR	JSR	IOERROR
	PLA
	PLA
	JSR	DCLOSE
	JMP	BEGIN
;
L_OPEN	LDA	#7
	LDX	#$30
	STA	ICCOM,X
	LDA	#<DICTION
	STA	ICBAL,X
	LDA	#>DICTION
	STA	ICBAH,X
	LDA	#$FF
	STA	ICBLL,X
	STA	ICBLH,X
	JSR	CIOV
	CPY	#136
	BNE	L_ERR
	JMP	DCLOSE
;
;Erase filename
;
ZAP_FN	LDY	#23
	LDA	#$20
ZAP_F1	STA	FILNAM,Y
	DEY
	BPL	ZAP_F1
	RTS
;
;Find Where a word goes
;
;ENTER: LEN_1 = length T_WORD
;
WHERE?	JSR	MAKE_INDEX
	TAX
	LDA	AWORD,X
	STA	TEMP
	LDA	AWORD+1,X
	STA	TEMP+1
	LDA	AWORD+2,X
	STA	INDR
	LDA	AWORD+3,X
	STA	INDR+1
;
WH_1	LDX	#0
	LDA	#$20
WH_2	STA	WORD_C,X
	INX
	BNE	WH_2
;
	LDY	#$FF
WH_3	INY
	LDA	(TEMP),Y
	STA	WORD_C,Y
	BPL	WH_3
	AND	#$7F
	STA	WORD_C,Y
	INY
	STY	LEN_2
;
	CPY	LEN_1
	BCS	SET_LEN
	LDY	LEN_1
SET_LEN	STY	S_LEN
	LDY	#$FF
	LDX	#$FF
	LDA	T_WORD
	BMI	WH_4
	INX
WH_4	INY
	INX
	LDA	T_WORD,X
	STA	WORD_C+$80,Y
	BPL	WH_4
	AND	#$7F
	STA	WORD_C+$80,Y
;
	LDY	#0
WH_5	LDA	WORD_C+$80,Y
	CMP	WORD_C,Y
	BCC	WHDONE
	BEQ	WHINC
	BCS	CHKEND
;
WHINC	INY
	CPY	S_LEN
	BNE	WH_5
;
CHKEND	LDA	TEMP
	CLC
	ADC	LEN_2
	STA	TEMP
	LDA	TEMP+1
	ADC	#0
	STA	TEMP+1
	CMP	INDR+1
	BNE	WH_1
	LDA	TEMP
	CMP	INDR
	BNE	WH_1
WHDONE	RTS
;
;Move MYBUF to WORD
;
MY2WORD	JSR	STRIP
	LDY	#0
MY2_1	LDA	MYBUF,Y
	STA	WORD,Y
	CMP	#EOL
	BEQ	MY2_0
	INX
	INY
	BNE	MY2_1
MY2_0	LDA	#0
	STA	WORD,Y
	LDA	WORD
	BNE	MY2_L
	LDA	#EOL
	STA	MYBUF
MY2_L	JMP	TOKENIZE
;
;View Dictionary by Letter
;
VIEW		PRINT V_TXT
	INC	IPUT
VIEW_1	JSR	GETKEY
	JSR	CONL2U
	CMP	#EOL
	BNE	V_A
	JMP	VIEW_L
;
V_A	CMP	#'A
	BCC	VIEW_1
	CMP	#'Z+1
	BCS	VIEW_1
	PHA
	JSR	EPUT
	DEC	IPUT
	PLA
	STA	PREFIX
	STA	N_W
	JSR	MAKE_IN
	LDX	#0
	TAY
	LDA	WORDS_IN,Y
	STA	WCOUNT
	LDA	WORDS_IN+1,Y
	STA	WCOUNT+1
VIEW_2	LDA	AWORD,Y
	STA	V_START,X
	INY
	INX
	CPX	#4
	BNE	VIEW_2
;
VIEWER	LDA	#0
	STA	COUNT	;words in col
	STA	ASAV	;column
	STA	EOF?	;words left?
	JSR	ZAP_TOP
	LDA	#<[TOPHALF-1]
	STA	SCR
	LDA	#>[TOPHALF-1]
	STA	SCR+1
VIEW_LP	LDY	#$FF
VIEW_3	INY
	LDA	(V_START),Y
	BPL	VIEW_3
	LDA	ASAV
	BEQ	VIEW_PW
	CPY	#19
	BCS	V_WAIT
	LDY	#0
	LDA	(SCR),Y
	BNE	V_WAIT
VIEW_PW	JSR	PULL_WORD
	LDY	#1
VIEW_SC	LDA	LAST_WORD-1,Y
	BEQ	A_40
	JSR	ASC2IC
	STA	(SCR),Y
	INY
	BNE	VIEW_SC
;
A_40	JSR	SCRADD40
	LDA	EOF?
	BNE	V_WAIT
	INC	COUNT
	LDA	COUNT
	CMP	#8
	BNE	VIEW_LP
	LDA	ASAV
	BNE	V_WAIT
	LDA	#<[TOPHALF+19]
	STA	SCR
	LDA	#>[TOPHALF+19]
	STA	SCR+1
	LDA	#0
	STA	COUNT
	INC	ASAV
	BNE	VIEW_LP
;
V_WAIT	JSR	CLRSCR
		PRINT M2
	LDA	#2
	STA	XPOS
	STA	YPOS
	LDA	WCOUNT+1
	LDY	WCOUNT
	JSR	CON_NUM
	CLC
	ADC	#<NUMBUF
	PHA
	LDA	#>NUMBUF
	ADC	#0
	TAY
	PLA
	JSR	EPRINT
		PRINT N_WORDS
	JSR	PUTCR
	INC	YPOS
	LDA	EOF?
	BNE	VIEW_E
	JSR	SEE_MORE
	BNE	VIEW_L
	JMP	VIEWER
VIEW_L	JSR	ZAP_FN
	JSR	SHO_BOX
	JMP	MAINLOOP
VIEW_E	JMP	VIEW
;
;Make Letter in A an Index
;
MAKE_INDEX	LDA	T_WORD
MAKE_IN	AND	#$7F
	SEC
	SBC	#'A
	ASL	A
	RTS
;
;Pull a word from Dictionary
;
PULL_WORD	LDA	#0
	STA	LAST_WORD
	LDA	EOF?
	BNE	PULL_OUT
;
	LDY	#$FF
PULL_1	INY
	LDA	(V_START),Y
	STA	LAST_WORD+1,Y
	BPL	PULL_1
	AND	#$7F
	STA	LAST_WORD+1,Y
	LDA	#0
	STA	LAST_WORD+2,Y
	INY
	STY	S_LEN
	LDA	PREFIX
	STA	LAST_WORD
	CPY	#1
	BNE	PULL_N1
	CMP	LAST_WORD+1
	BNE	PULL_N1
	LDA	#0
	STA	LAST_WORD+1
PULL_N1	LDA	V_START
	CLC
	ADC	S_LEN
	STA	V_START
	LDA	V_START+1
	ADC	#0
	STA	V_START+1
	CMP	V_END+1
	BNE	PULL_OUT
	LDA	V_START
	CMP	V_END
	BNE	PULL_OUT
	INC	EOF?
PULL_OUT	RTS
;
;Strip Junk from MYBUF
;
STRIP	LDX	#0
	LDY	#0
STR_1	LDA	MYBUF,X
	CMP	#EOL
	BEQ	STR_2
	JSR	CONL2U
	CMP	#'A
	BCC	STR_N
	CMP	#'Z+1
	BCC	STR_2
STR_N	INX
	BNE	STR_1
STR_2	LDA	MYBUF,X
	STA	MYBUF,Y
	BEQ	STR_EN
	INX
	INY
	BNE	STR_2
STR_EN	RTS
;
;Rename XIO
;
X_REN	LDA	#32
	BNE	DO_XIO
;
;Delete XIO
;
X_DEL	LDA	#33
	BNE	DO_XIO
;
;Unlock XIO
;
X_UNL	LDA	#36
;
;Perform an XIO on CH #4
;
DO_XIO	PHA		;XIO Command
	LDX	#$40
	LDA	#12
	STA	ICCOM,X
	JSR	CIOV
	LDX	#$40
	PLA
	STA	ICCOM,X
	LDA	#<FILNAM
	STA	ICBAL,X
	LDA	#>FILNAM
	STA	ICBAH,X
	LDA	#0
	STA	AUX1,X
	STA	AUX2,X
	JMP	CIOV
;
;Rename the files
;
RENAME	JSR	X_UNL	;unlock source
	LDY	#0
REN_1	LDA	FILNAM,Y
	STA	MYBUF,Y
	CMP	#'.
	BEQ	S_Y
	CMP	#EOL
	BNE	UP_Y
S_Y	STY	ASAV
UP_Y	INY
	CPY	#25
	BNE	REN_1
	LDY	ASAV
	JSR	ADD_BKP
	JSR	X_UNL	;unlock backup
	JSR	X_DEL	;delete backup
;
;Restore FILNAM
;
	LDY	#24
REN_2	LDA	MYBUF,Y
	STA	FILNAM,Y
	DEY
	BPL	REN_2
;
	LDX	#$FF
F_EL	INX
	LDA	FILNAM,X
	CMP	#EOL
	BNE	F_EL
	LDA	#',
	STA	FILNAM,X
	INX
	TXA
	TAY
	LDX	#$FF
F_COL	INX
	LDA	FILNAM,X
	CMP	#':
	BNE	F_COL
	INX
	STX	ASAV
;
ADD_8	LDA	MYBUF,X
	STA	FILNAM,Y
	CMP	#EOL
	BEQ	REN_4
	CMP	#'.
	BEQ	REN_4
	INX
	INY
	BNE	ADD_8
REN_4	JSR	ADD_BKP
	JSR	X_REN	;rename source
;
	LDY	#9
C_TMP	LDA	TMPNAME,Y
	STA	FILNAM,Y
	DEY
	BPL	C_TMP
	LDA	#',
	STA	FILNAM+10
	LDY	#11
	LDX	ASAV
C_FN	LDA	MYBUF,X
	STA	FILNAM,Y
	INX
	INY
	CMP	#EOL
	BNE	C_FN
	JSR	X_REN	;rename DOC.TMP
	JMP	ZAP_FN
;
;Add the .BKP Extension
;
ADD_BKP	LDX	#4
REN_5	LDA	BKP_TXT,X
	STA	FILNAM,Y
	INY
	DEX
	BPL	REN_5
	RTS
;
;Get a Directory Entry
;
GET_ENTRY	LDX	#$30
	LDA	#5
	STA	ICCOM,X
	LDA	#<MYBUF
	STA	ICBAL,X
	LDA	#>MYBUF
	STA	ICBAH,X
	LDA	#$20
	STA	ICBLL,X
	LDA	#0
	STA	ICBLH,X
	JMP	CIOV
;
;Open for Directory
;
OPEN_DIR	PHA
	TYA
	PHA
	JSR	DCLOSE
	LDX	#$30
	PLA
	STA	ICBAH,X
	PLA
	STA	ICBAL,X
	LDA	#3
	STA	ICCOM,X
	LDA	#6
	STA	AUX1,X
	LDA	#0
	STA	AUX2,X
	JMP	CIOV
;
;Get Dictionary Directory
;
GETDIR	LDA	#'?
	STA	DIC_NAME+11
	LDX	#$00
	LDA	#<DIC_NAME
	LDY	#>DIC_NAME
	BNE	NORM_DIR
;
;Normal Directory
;
DIRECT		PRINT DRIVE_N
	INC	IPUT
DIR_1	JSR	GETKEY
	AND	#$7F
	CMP	#27
	BEQ	GD_MAIN
	LDY	#4
DIR_2	CMP	LEGAL_D,Y
	BEQ	G_DIR
	DEY
	BPL	DIR_2
	BMI	DIR_1
;
G_DIR	STA	DIR_TXT+1
	PHA
	JSR	EPUT
	JSR	PUTCR
	PLA
	EOR	#$A0
	STA	DIR_Q+1
	LDX	#$01
	LDA	#<DIR_TXT
	LDY	#>DIR_TXT
	JSR	NORM_DIR
GD_MAIN	DEC	IPUT
	JMP	MAINLOOP
;
NORM_DIR	STX	RJUST
	JSR	OPEN_DIR
	STY	ILEN
	JSR	DIR_TOP
	LDY	ILEN
	BPL	GDIR
	JSR	IOERROR
NO_DIR	JSR	DCLOSE
	LDY	#5
NO_D	LDA	D_NONE,Y
	STA	TOPHALF+97,Y
	DEY
	BPL	NO_D
	SEC
	RTS
;
GDIR	JSR	GET_ENTRY
	BMI	GDDIR
	LDY	#4
AT_END?	LDA	FREETXT,Y
	CMP	MYBUF+7,Y
	BNE	NOTFREE
	DEY
	BPL	AT_END?
	LDA	RJUST
	ORA	COUNT
	BEQ	NO_DIR
;
NOTFREE	INC	COUNT
NF_2	LDY	#2
DIRLP1	LDA	MYBUF-2,Y
	CMP	#EOL
	BEQ	ENTRYDN
	JSR	ASC2IC
	STA	(SCR),Y
	INY
	BNE	DIRLP1
ENTRYDN	LDA	SCR
	CLC
	ADC	#20
	STA	SCR
	BCC	G_TST
	INC	SCR+1
G_TST	LDA	COUNT
	CMP	#14
	BCC	GDIR
	BCS	D_WT
;
GDDIR	LDA	COUNT
	ORA	RJUST
	BEQ	NO_DIR
	JSR	DCLOSE
	CLC
	RTS
;
D_WT	JSR	SEE_MORE
	BNE	GDDIR
	JSR	DIR_TOP
	JMP	GDIR
;
;Do Top of Directory Screen
;
DIR_TOP	JSR	ZAP_TOP
	LDA	#<[TOPHALF+40]
	STA	SCR
	LDA	#>[TOPHALF+40]
	STA	SCR+1
	LDA	#0
	STA	COUNT
	LDX	RJUST
	BNE	J_DIR
	LDY	#21
DT_1	LDA	D_HEAD,Y
	STA	TOPHALF+9,Y
	DEY
	BPL	DT_1
	RTS
;
J_DIR	LDY	#13
JD_1	LDA	DIR_N,Y
	STA	TOPHALF+13,Y
	DEY
	BPL	JD_1
	RTS
;
;See More?
;
SEE_MORE		PRINT V_MORE
	JMP	GETYN