Trailing-Edge
-
PDP-10 Archives
-
decuslib10-09
-
43,50466/spell.mac
There are 5 other files named spell.mac in the archive. Click here to see a list.
;THIS PROGRAM OBTAINED FROM DECUS (NO. 10-184) AND ADAPTED AT
; WESTERN MICHIGAN UNIVERSITY
;TITLE SPELL - WMU IMPLIMENTATION BY RUSSELL R. BARR III - 12-JUL-74
;(AUTHOR CREDIT ON PAGE 2.)
;
;******LOADING DIALOGUE
;
;.LOAD SPELL.MAC,USAGE.MAC
;.START
;*YOU MUST LOAD A DICTIONARY FILE. DICTIONARY FILE NAME: SPELL.DCT
;*THERE ARE NOW 10371 WORDS IN THE DICTIONARY. 32K CORE USED.
;
;******OPTIONAL DIALOG FROM HERE
;
;*DO YOU WANT TO SAVE THIS CORE IMAGE?
;*DO YOU WANT TO AUGMENT THE DICTIONARY? Y
;*DICTIONARY FILE NAME: EXTRA.DCT
;*TYPE "I" TO MARK THESE AS INCREMENTAL INSERTIONS:
;*THERE ARE NOW XXXXX WORDS IN THE DICTIONARY. XX K CORE USED.
;
;******OPTIONAL DIALOGUE TO HERE
;
;*DO YOU WANT TO SAVE THIS CORE IMAGE? Y
;*SAVE THIS CORE IMAGE,THEN RESTART THE PROGRAM
;.SAV SPELL
;******
;
COMMENT VALID 00038 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00005 00002 TITLE SPELL SPELLING CHECK & CORRECTION.
C00012 00003 SUBTTL BIG COMMENT
C00049 00004 SUBTTL INITIALIZATION
C00056 00005 SUBTTL THE LOOP WHERE ALL THE WORK GETS DONE.
C00059 00006 SUBTTL THE DEBUG QUEUE.
C00061 00007 SUBTTL FULL DUMP AND INCREMENTAL DUMP ROUTINES
C00063 00008 SUBTTL TRACE DUMP ROUTINE
C00065 00009 SUBTTL GETLIN READ A LINE OF DATA INTO LIBUF
C00068 00010 SUBTTL THE READING ROUTINE
C00071 00011 SUBTTL CHKLIN ROUTINE
C00077 00012 SUBTTL PUTLIN
C00080 00013 SUBTTL DESCRIPTION OF ENDTST
C00093 00014 SUBTTL ENDTST TEST THE SUSPECT WORD BY REMOVING THE ENDINGS
C00103 00015 SUBTTL ROUTINES USED BY ENDTST
C00106 00016 SUBTTL LOAD WORD
C00108 00017 SUBTTL CHANNEL INITIALIZATION
C00110 00018 SUBTTL I/O STUFF:
C00112 00019 SUBTTL THE DICTIONARY LOADER.
C00115 00020 SUBTTL READ A DICTIONARY WORD.
C00117 00021 SUBTTL THE HASH COMPUTATION.
C00119 00022 SUBTTL SCAN TTY FOR A FILE NAME
C00123 00023 SUBTTL ERROR MESSAGES
C00126 00024 SUBTTL SEARCH LOOK IN DICTIONARY FOR A WORD.
C00129 00025 SUBTTL INSERT
C00132 00026 SUBTTL CORE ROUTINES
C00133 00027 SUBTTL TYPE FILE NAMES,READ NAMES, PLAY WITH TTY
C00135 00028 SUBTTL TRYFIX OUR HUMBLE ATTEMPT TO CORRECT THE WORD.
C00145 00029 SUBTTL TRYIII FOR III DISPLAY OF GUESSES.
C00151 00030 SUBTTL THE HELP MESSAGE
C00154 00031 SUBTTL CHECK FOR REPEATS OF THE SAME WORD.
C00156 00032 SUBTTL TYPE OUT ALL THE WORDS WE FOUND
C00158 00033 SUBTTL X1SRCH TRY TO CORRECT ONE MISSPELLED LETTER
C00161 00034 SUBTTL X1EXL MAYBE HE TYPED ONE EXTRA LETTER
C00163 00035 SUBTTL XTRNP ONE PAIR TRANSPOSITION
C00164 00036 SUBTTL ONE LETTER MISSING
C00167 00037 SUBTTL SAVEME WRITE OUT CORE IMAGE USING SWAP UUO.
C00169 00038 SUBTTL SOME OF THE STORAGE STUFF
C00172 ENDMK
C;
TITLE SPELL SPELLING CHECK & CORRECTION.
; R. E. Gorin 20 February, 1971
; Revised July 23, 1972 III displays
; I HAVE YOU UNDER MY SPELL
SUBTTL DEFINITIONS
COMMENT $
Acknowledgements:
The work reported here was supported in part by the Advanced
Research Projects Agency of the Department of Defense under contract
SD-183, and in part by the National Science Foundation, which has
supported the author as a Fellow.
Report Problems with this program to:
Ralph E. Gorin
Artificial Intelligence Project
Stanford University
Stanford, California 94305
$
IFDEF FOR,<MACRO__0;>MACRO==1 ;SELECT ASSEMBLER
IFE MACRO,<
DEFINE DEF(A,B)<
A_B>
DEFINE SDEF(A,B)<
A__B>
>
IFG MACRO,<
DEFINE DEF(A,B)<
A=B>
DEFINE SDEF(A,B)<
A==B>
>
COMMENT/ ASSEMBLY SWITCHES.
STANSW GIVES SIXBIT PPN AND STANFORD SWAP UUO
COUNTS GIVES THE EXECUTION COUNTS AND DEBUGGING TRACE OF THE
LAST 100 AREAS EXECUTED. (not recommended - reg)
IF STANSW IS 0 THEN IF SANSW IS 1 YOU GET DECIMAL PPN, ELSE OCTAL PPN
/
SDEF(COUNTS,0)
IFNDEF STANSW,<SDEF(STANSW,0)>
IFNDEF SANSW,<SDEF(SANSW,0)>
IFN SANSW,<SDEF(SANSW,1)> ;NORMALIZE
IFE STANSW,<SDEF(PPNMUL,10+SANSW+SANSW)>
IFNDEF COUNTS,<SDEF(COUNTS,0)>
DEF(FL,0)
DEF(A,1)
DEF(B,2)
DEF(C,3)
DEF(D,4)
DEF(W,5)
DEF(X,6)
DEF(Y,7)
DEF(Z,10)
DEF(K,11)
DEF(L,12)
DEF(M,13)
DEF(N,14)
IFG COUNTS,<
DEF(DEBA,15)
DEF(DEBX,16)
>
DEF(P,17)
EXTERN .JBFF,.JBSA,.JBREL
COMMENT/
I-O CHANNELS:
/
SDEF(DICT,15) ;FOR DICTIONARY READIN AND DICTIONARY DUMPS
SDEF(DATA,16) ;FOR FILE TO CORRECT
SDEF(EXCP,17) ;EXCEPTIONS
SDEF(CORR,14) ;CORRECTED FILE.
OPDEF RESET [CALLI 0]
OPDEF EXIT [CALLI 12]
OPDEF CORE [CALLI 11]
OPDEF TTCALL [51B8]
; RIGHT HALF FLAGS
SDEF(FRSTOP,1) ;FIRST I/O OPERATION ON DATA CHANNEL
SDEF(TECO,2) ;FOUND A TECO FILE ON DATA CHANNEL
SDEF(LEFT,4) ;HASH ON LEFT, NOT ON RIGHT
SDEF(ERRLIN,10) ;THERE IS AN ERROR IN THIS LINE
SDEF(MIXED,20) ;FIRST LETTER UPPER CASE, REST LOWER
SDEF(LOWER,40) ;ALL LETTERS LOWER CASE (TURN ON 40)
SDEF(NOCORR,100) ;CHECK ONLY, NO CORRECT
SDEF(IDUMP,200) ;DO INCREMENTAL DUMP, OR INCREMENTAL INSERT
SDEF(SHUTUP,400) ;DON'T CORRECT HIM, OR ASK ADVICE. WRITE
;EXECPTIONS, THOUGH.
SDEF(HELPSN,1000) ;ONCE ONLY PUBLICATION OF HELP-1
SDEF(HELP2S,2000) ;ONCE ONLY PUBLICATION OF HELP-2
SDEF(NOEXCP,4000) ;DON'T WRITE EXCEPTION FILE
SDEF(NOTRAC,10000) ;DON'T ADD TO TRACE WHILE DUMPING TRACE
SDEF(PICKUP,20000) ;ALLOW A PICKUP IN THE MIDDLE OF FILE
SDEF(TRAIN,40000) ;INSERT ALL EXCEPTIONS INTO DICTIONARY #I1.
;(CREATE A TRAINING SET)
SDEF(QTRAIN,100000) ;TRAIN AND MARK CLOSE WORDS IN EXCEPTION FILE
IFN STANSW,<
SDEF(IIISW, 200000) ;WE ON A STANFORD III
>
DEFINE BCHECK (BYP,BOUND)<
PUSH P,A
MOVEI A,@BYP ;GET ADDRESS OF BYTE.
CAILE A,BOUND
PUSHJ P,INTCFN
POP P,A
>
DEFINE ICOUNT<
IFG COUNTS,<
SDEF(%QXX,%QXX+1)
AOS ICTAB+%QXX
MOVEI DEBA,%QXX
PUSHJ P,DEBQUE
>>
IFG COUNTS,<SDEF(%QXX,<-1>)
LALL>
IFN STANSW,< ;COMPILE STUFF STANFORD FEATURES
OPDEF SWAP [CALLI 400004] ;STANFORD SWAP UUO.
OPDEF DPYCLR [701B8] ;CLEAR DISPLAY
OPDEF PPIOT [702B8] ;
OPDEF DPYPOS [PPIOT 2,] ;SET Y POSITION OF PAGE PRINTER
OPDEF DPYSIZ [PPIOT 3,] ;SET SIZE OF PAGE PRINTER.
OPDEF UPGIOT [703B8]
SDEF(VBRT,4000) ;LVW BRIGHTNESS FIELD
SDEF(VSIZ,1000) ;LVW SIZE FIELD
SDEF(VABS,100) ;LVW ABSOLUTE FIELD
SDEF(VENDP,20) ;LVW ENDPOINT FIELD
SDEF(VINVIS,40) ;LVW INVISIBLE FIELD
DEFINE LVW(X,Y,TYPE,MODE,BRT,SIZ)<
IFIDN <MODE><A>,<SDEF(MD,1);>SDEF(MD,0)
IFIDN <TYPE><I>,<SDEF(TT,2);>SDEF(TT,0)
IFIDN <BRT><>,<SDEF(BQ,0);>SDEF(BQ,BRT)
IFIDN <SIZ><>,<SDEF(SQ,0);>SDEF(SQ,SIZ)
BYTE(11)<X>,<Y>(3)BQ,SQ(2)MD,TT(4)6
>
COMMENT/
A LONG VECTOR WORD (LVW) FOR THE III DISPLAY HAS THE FOLLOWING FORMAT
BITS 0-10 X COORDINATE
BITS 11-21 Y COORDINATE
BITS 22-24 BRT BRIGHTNESS. 0=NO CHANGE, 1-7 INCREASING BRIGHTNESS
BITS 25-27 SIZ SIZE. 0=NO CHANGE, 1-7 INCREASING BRIGHTNESS
BIT 29 M MODE. 0=RELATIVE TO LAST, 1=ABSOLUTE FROM CENTER
BITS 30-31 T TYPE. 0=VISIBLE, 1=ENDPOINT, 2=INVISIBLE
BITS 32-35 6. DENOTES LVW IN DISPLAY PROCESSOR
/
>;IFN STANSW
SUBTTL BIG COMMENT
COMMENT %
4 March 1971
Spelling check/correction program
Ralph E. Gorin
I have written a program to read text files and check them
for correctness of spelling. In addition to the spelling check my
program will attempt to correct words that it thinks are misspelled.
The program is written in Macro, the so called "brand X"
assembler for the PDP-10. The choice of an assembly language was
dictated by the data structure that I chose to use. The data
structure is the heart of the program, and any efficiency in the
program operation is due primarily to this choice of data structure.
The data structure is basically a hash coding scheme where dictionary
entries are accessed by both their alphabetic order and by their
length. I have a base table that contains 26 * 26 * 10 halfwords;
this table gives me anchors for some 6760 chains. Each chain contains
exactly all words with the same two first letters and some given
length. To be precise, the hashing function is:
(l1*26+l2)*10+min(wl-2,9),where l1 and l2 are numeric representations
of the first and second letters (a=0, b=1, ... z=25) and wl is the
length of the word in characters.
This scheme was chosen since it provides both an efficient
way to probe the dictionary and a quick way to select a small subset
of all words that are close to a given input word.
The program contains about 2k of pure code plus about 4.5k of
tables and i/o buffers. With ddt and a 10,500 word dictionary, it
runs in 34k.
Dictionary structure.
Entries are added to the appropriate hash chain by the INSERT
subroutine. Entries are added to the head of the chain, saving the
time and effort of searching to the end of the chain. This scheme
means that the last item entered on a chain is the first item seen by
a search. The format of the entry is given by:
Word 0: xwd flags,nextlk
Word 1: 5 bit representation
Word 2: 5 bit representation
...
There are precisely 1+ceiling(wl/7) machine words used for
each dictionary entry. Wl is the length of the entry in characters.
Nextlk is the pointer to the next entry in the list, or zero if this
is the last in the chain. The left side contains flags, bit 17 is
used to mark an incremental entry to the dictionary; bits 0-4 must
always be zero. One can imagine that bits 5-16 could be used to
store semantic information about the entry. The unused bytes in
the last word of an entry should be zero, since they are used to stop
the routine that converts the five bit to 7 bit. To make an ascii
letter into fivebit the following code is reccommended. Suppose a 7
bit character is in register A:
TRZ A,140 ;MAKE UPPER CASE AND FIVEBIT
The above code appears nowhere in my program since I just thought of
it.
There is no provision for deleting words from the dictionary.
Hence, there is never any need to form a free storage list or to
garbage collect.
The spelling correction algorithms.
There are 4 errors that I attempt to correct:
1. one wrong letter.
2. one missing letter.
3. one extra letter.
4. two transposed letters.
The first case is the most complicated. For this case I do the
following:
For a wrong letter in the third or subsequent character, all
words that are candidates must live on the same chain that the
suspect word hashes to. Hence, I look at each entry on the chain and
determine if the suspect differs from the entry by exactly one
character. This is accomplished by an exclusive or between the
suspect and the dictionary. Then a JFFO instruction selects the
first non zero byte in the XOR. This byte is zeroed and if the
result is all zero then the dictionary word differs from the suspect
in only one letter. All such words are listed at CANDBF, where they
can be inspected later. In case either the first or second letter
was wrong I try all 26 possibilities for the second letter, then
using the original second letter, I vary the first letter through all
its possible values. This means that 52 more chains are searched
for possible matches.
To correct transposed letters, I just try all combinations of
transposed letters. There are only wl-1 such combinations, so it's
fairly cheap to do that.
To correct one extra letter, I systematically copy the word with a
letter removed. This is only wl searches.
To correct one missing letter, I copy the suspect word wl+1 times,
each time inserting a null character in a new position in the
suspect. The null character is never part of any word, so the suspect
augmented by an embedded null can be thought of as a word with one
wrong letter (the null) then I use the algorithm above to match for
one wrong letter.
Where to go from here:
First, the dictionary must be expanded to include all
suffixes for every word. I do have a feature that strips suffixes
for the purpose of finding the stem of the word in the dictionary,
but this process is error prone and incompatible with later attempts
to correct the word.
Secondly, semantic information ought to be included in the
dictionary. Then contextual information can help guide the selection
of a correction.
The first proposal above will require a tremendous
restructuring of the program, since the dictionary would no longer
fit in core. This being the case, I believe that the dictionary
should be kept on the disk, with a data structure similar to the one
I use in core, so that searches through the dictionary can be made
efficient.
Other features of the program.
The program will read either SOS or TECO format disk files for the
file to be corrected, and the output file will be written in the same
mode, with the same SOS line numbers, if present, that the original
file had. The dictionary may be either SOS or TECO format. The
dictionary need not be alphabetical and an arbitrary number of
auxiliary dictionaries may be loaded, bounded only by the
availability of core.
When a word is corrected, the output file will be rewritten with
either upper case, lower case of mixed (first letter Upper, the
remainder in lower) depending on the format of the original word.
Compilation instructions:
There are two assembly time switches, STANSW and SANSW. If STANSW is
set then there are SIXBIT ppn's and the SWAP UUO. If STANSW is zero,
then normally there are octal ppn's, except if SANSW is set, in which
case, there are decimal ppn's.
Compile the program using MACRO, and load it. When you start the
program after loading, it will demand a dictionary. Use the file
SLOVAR, or anything else that's handy. (Spelling check+DDT+ Slovar is
34k of core).
Save the resulting core image when the dictionary load is complete.
(if you're not at Stanford, you must save manually).
Using the spelling checker/corrector.
Incant the command: "R SPELL" to invoke the spelling check
program. Assuming that all is normal, it will type: "Do you want to
augment the dictionary?" If you don't have an auxiliary dictionary
anywhere then type <return> and forget the next paragraph.
If you have a dictionary that you want to load then type "Y"
and <return> and you will be asked for the name of your dictionary
file. The dictionary file must be on disk. The format of the file is
one dictionary entry (word) on a line; words must be strictly
alphabetic characters and less than 40 letters long. The dictionary
entries need not be in alphabetical order. After typing the file
name you will be asked whether you want the new entries marked as
incremental insertions. If the new entries are marked as
incremental then they will be included in an incremental dump of the
dictionary. To have the new entries marked as incremental type "I"
and <return>, otherwise, type <return>. (If any of the words in your
auxiliary dictionary are already in the main dictionary then no
second copy of the word will be made. Hence if your words are marked
as incremental then in a subsequent incremental dump, any words that
were already in the dictionary will not be dumped.) After loading an
auxiliary dictionary the program will type the total number of words
in the dictionary and the amount of core used. At present there are
about 10,700 words in the dictionary, using 35K of core. After
loading an auxiliary, you will have an opportunity to save the new
core image on your disk area (probably not worth it). Also you will
get an opportunity to load another auxiliary dictionary.
Next you will be asked for the name of the file that you want
to check for spelling errors. File names are specified in the usual
format of "name.ext[prj,prg]" where name is the filename, ext is the
file extension, and [prj,prg] is the name of the file owner, which
may be omitted if the file is on the present user's disk area. If you
omit the file name then you will immediately enter the exit sequence
(see below).
You will be asked to specify a name for the output file. The
output file is where the corrected version of the input goes. If you
omit this name then no corrections will be made. (Only the exceptions
will typed, and if you specify an exception file then it will be
made).
You will be asked to name an exception file. This file will
contain all the lines on which exceptions were found and the rejected
words. (This file is probably not worth it). If you omit the name
then no such file will be created.
After you have specified all the files, the program ought to
respond with "working..." and start checking the input file for
spelling errors.
When the spelling checker encounters a word that isn't in the
dictionary, it will type the page number, the line on which the word
was found and the word itself. The very first time this happens a
message that explains the choices you have will be typed.
These choices are:
A Accept this word, this one time.
I Accept this word and insert it in the dictionary so that
subsequent occurances of this word will be recognized and accepted.
Words that are inserted this way are marked as incremental insertions
and they may be dumped to form an auxiliary dictionary.
R Replace this word. Type "R" <return> and the program will
ask you for the replacement word. If the replacement word is not
already in the dictionary, the program will give you an opportunity
to insert it.
X Accept this word and finish. The word will be accepted. Then
the remainder of the input file will be copied without checking to
the output file.
W Save my incremental insertions. After you type "W" <return>
you will be asked for a file name. Then an incremental dump of the
dictionary will be written into the file. After the dump is complete
you may then decide what to do with the excepted word.
D Display the line and offending word again. The line that is
displayed will not have any corrections shown in it. If a line has
more than one error the line will only be typed once. Subsequent
errors on that line will cause only the particular word to be typed,
unless this command is used.
S If this choice is offered then the spelling checker has
discovered several words that could be possible corrections of this
word. If you type "S" <return> then you will enter a mode where you
can look at the words that found by the program and (optionally)
select one of the words from the list.
When you enter this selection submode for the first time an
explanation will be typed. The first word in the list of possible
corrections will be typed followed by an asterisk. Then you have the
following choices.
Y<return> Use this word as the correction.
<return> Show the next possible choice. When you
exhaust the choices you are returned to the outer mode, and asked
again.
^<return> Back up in the list.
<alt mode> Escape from this submode and return to the
outer command mode.
In general, when a word is found that is not in the
dictionary a brief message, either "Type A,I,R,X,W or D" or "Type
A,I,R,X,W,D or S" will be typed to remind you of the possible
choices. In the special case that the program finds exactly one
possible correction for the word, then the message "I guess <word>.
Type C to make this correction or A,I,R,X,W or D" will be typed. If
you type "C" <return> then the indicated substitution will be made,
otherwise you have the usual choices.
When the input file is exhausted the correction file and
exception file are closed and all I/O channels are released. The
program types "Finished."
The exit sequence is entered next. The user is given several
options. They are:
E Exit now.
S Save this core image
C Go back and correct another file.
A Augment the dictionary and correct another file.
D Complete dump of the dictionary to disk. This will create a
17 or 18K file, which probably isn't worth it.
I Incremental dump of the dictionary to disk. All the words
that were inserted while running the program are dumped to the disk.
The user specifies a file name (the default is WORDS.LST). This
incremental dump is in a format suitable for editing or for use as an
auxiliary dictionary. The words in this dump are not in alphabetical
order. These words will appear in groups sorted by the first two
letters of the word and by the length of the word. Otherwise, within
a group the words will appear in last in - first out order.
X This command is used to get a trace count of the program. It
is for diagnostic purposes only.
How to use multiple dictionaries
Spell has a set of features whereby the user can cause the
creation of several disjoint incremental dictionaries. In this way,
the user may collect several dictionaries of special terms.
Internally, all dictionary entries are considered equivalent as
regards searches for words. The distinction between dictionaries
has its greatest impact when doing incremental dumps (the I command
during the exit sequence or the W command while in the middle of
execution). When an incremental dump is requested, the user may
specify a number, e.g. W9, which selects the particular incremental
dictionary to dump. In this example, dictionary #9 will be dumped.
Dictionary 0 is the main dictionary. Words cannot be added
to this dictionary, except by reading an auxiliary file. In general,
words that are inserted incrementally are marked as being in
dictionary #1. All words that are incremental insertions in the
dictionary will be marked in dictionary #1, unless the user
specifies otherwise.
The following places are where the user may specify which
dictionary to add to:
1. When loading an auxiliary dictionary, if the user
responds with "Inn" to the question about marking new entries as
incremental, then the new entries will be marked in dictionary number
nn (where nn is interpreted as decimal and should be less than 32).
2. After a word has been rejected, type "Inn" to insert
the word in dictionary number nn.
3. After replacing a word, if the replacement is not in
the dictionary then type "Inn" to insert the replacement into
dictionary nn.
When requesting an incremental dump, the user may specify the
particular dictionary to dump. This is allowed in two cases:
1. After some word has been rejected, the command "Wnn"
will cause dictionary number nn to dumped.
2. During the exit sequence, the command "Inn" will
cause dictionary number nn to be dumped.
In all five cases above, if nn is either 0 or omitted, then
it will be taken as being 1.
Caution. There is no provision in Spell for remembering which
dictionary numbers have been used. Therefore, it remains the
individual user's responsibility to remember the numbers of all the
dictionaries that he creates. (Forgetting the number will mean that
the forgotten dictionary can not be dumped incrementally. The words
in a forgotten dictionary will still be available, but the only way
to actually get them dumped out is to dump the entire dictionary).
The Pickup Feature.
If any of the three file names in the entry sequece (where
the source, correction and exception files are specified) is followed
by the switch "/P" then, after accepting the three file names, SPELL
will enter pickup mode. The user will be asked to specify a page
number and, if the file is in SOS format, a line number for pickup.
The effect is to suspend spelling checking until the page and line
specified. When a user has a partially corrected file, this command
will enable him to skip over the portion of the file that has already
been corrected. The input file will be copied without checking to
the output until the page and line specified, at which point spelling
checking begins.
The Training feature.
If the file name of the input file is followed by the switch
"/T" then instead of correcting the file, Spell will treat the file
as a training set. All words in the file that are unfamiliar to
Spell will be entered in the dictionary as incremental insertions.
After Spell finishes reading the file, the user has an opportunity to
dump all the words that were inserted this way. The resulting list
of words may be edited and any words which are incorrect may be
deleted. Then this file can be used as an auxiliary dictionary while
correcting the original source file.
This feature is provided for the purpose of easing the
problem of creating a specialized dictionary of jargon and
infrequently used words.
Q-Training
Q-Training is specified by the switch /Q. In this mode, all
words in the source file that are unfamiliar to Spell will be added
to the dictionary; the difference is, if any "new" word is "close to"
some old word then the new word will be output in the exception file.
The exception file will contain only such words. In this way, the
spelling checker calls to your attention the fact that this word may
be misspelled.
-------------------------------------------------
Abnormal Conditions.
While the program is running it is possible that certain
abnormal conditions may obtain. The usual response of the program is
to type some sort of error message.
The following is a list of the error messages in SPELL, with
an indication of the severity of the error.
Huh? The user has typed something illegal. He will be
given another chance, usually after reviewing the list of valid
responses.
Default name is WORDS.LST The user has typed <return> when a
name for a dictionary output file was requested. The name Words.Lst
is used.
Default name is SPELL.DMP The user has typed <return> when a
name for a core dump file was requested. The name Spell.Dmp is used.
Illegal dictionary entry: <word> This error occurs if an entry
in a dictionary file exceeds 40 (decimal) characters. The word is
ignored.
0 LENGTH WORD AT HASHCP Somebody just asked to compute the
hash address of an empty word. The program continues, but there is a
possibility of great evilness.
HASHING ERROR Somebody asked for the hash address
of a word that doesn't begin with letters as the first two
characters. The program halts.
ILLEGAL CHARACTER IN SCAN. This is a message from the routine
that reads file names. You will be asked to try retyping the name.
Can't get there from here This means that from the select
submode you typed ^ to see the previous choice and you were at the
first choice. The first choice is repeated.
DEVICE DATA ERROR (OUTPUT) This message means that while writing
a file, something screwed up. The program halts.
DEVICE ERROR (INPUT) The input file is screwed up in some
way. The program halts.
INIT FAILED ON DEVICE DSK: This indicates tremendous confusion
external to this program. The program halts.
FILE NOT FOUND. DSK:<filename> The indicated file could not be
found. The user gets to specify some other file.
Enter failed on: <file name> An enter uuo failed while trying to
select the indicated file for output. The user may specify another
name.
INSUFFICIENT CORE AVAILABLE. I GIVE UP. Program requires more
core, but none is available. The program exits.
Null term illegal. The user typed <return> where a file
name is needed. The user has another opportunity to specify the
name.
Internal confusion in the spelling checker. Called from location
<loc>. The spelling checker has discovered a (possible) bug in
itself. The program halts, but the user may type continue. Please
note the location mentioned and the circumstances that evoked the
message.
Dictionary number too large. Maximum is 31. This message means
that the user attempted to select for insertion or dumping a
dictionary beyond the range of allowed numbers. The user will get
another chance to do the right thing.
You can't use Training Switch and have output or exceptions. This
message occurs when the switch "/T" is typed following the name of
the output or exception file. If the "/T" switch is used, it should
follow the name of the input file.
Unrecognized switch. This message is typed whenever a file name is
followed by a switch that is not one of the Spell switches.
%
SUBTTL INITIALIZATION
; EXTERN USAGEB ;11-JUL-74 RRB
BEGIN: RESET
;WMU USAGE CALL AND ARG - 11-JUL-74 RRB
;USAGEB IS A NOOP IF USAGE SYSTEM NON-EXISTANT.
; JSA 16,USAGEB ;11-JUL-74 RRB
; EXP [ASCII/SPELL /] ;11-JUL-74 RRB
SETZ FL,
IFN STANSW,<
SETO A,
TTCALL 6,A
TRNN A,400000 ;SKIP IF DETATCHED.
TLNN A,400000 ;SKIP IF III
TDZA FL,FL
MOVEI FL,IIISW ;SET III FLAG.
>
IFG COUNTS,<
MOVE A,[XWD ICTAB,ICTAB+1]
SETZM ICTAB
BLT A,ICTABX
MOVE DEBX,[IOWD 2*%DTL,%DBT]
>
MOVE P,[IOWD PDLEN,PDLIST]
SKIPE DICTFL ;IF ZERO WE ARE VIRGIN
JRST [MOVE A,DICTFF
MOVEM A,.JBFF
JRST .+1]
MOVE A,.JBFF
MOVEM A,DICTFF ;.JBFF FOR BUFFERING DICT.
PUSHJ P,INDICT ;INIT DICT AND BUFFER IT.
MOVE A,NEWFF
MOVEM A,DATAFF ;.JBFF FOR BUFFERING DATA
PUSHJ P,INDATA ;INIT AND BUFFER DATA.
MOVE A,NEWFF
MOVEM A,EXCPFF ;.JBFF FOR EXCEPTION FILE
PUSHJ P,INEXCP ;INIT AND BUFFER
MOVE A,NEWFF
MOVEM A,CORRFF ;.JBFF FOR THE CORRECTION CHANNEL
PUSHJ P,INCORR ;INIT AND BUFFER.
MOVE A,NEWFF
MOVEM A,.JBFF ;SAVE IT WHERE IT COUNTS
SKIPN DICTFL ;NOT REDIFIED IF DICT LOADED
MOVEM A,LISTFF ;MUST BE LOCATION FOR LISTS.
MOVE A,LISTFF
SKIPN DICTFL
MOVEM A,DICTBO ;BOTTOM OF DICTIONARY
MOVEM A,.JBFF ;WORKS OUT ANY HOW
MOVE A,DICTFL
JUMPN A,BGIN01
BEGIN0: ICOUNT
PUSHJ P,LOADER
BGIN01: ICOUNT
TTCALL 3,[ASCIZ/
Do you want to augment the dictionary? /]
TTCALL 4,A ;WAIT FOR ANSWER
PUSHJ P,FLUTTY ;FLUSH TO NEXT DELIM
CAIE A,"Y"
CAIN A,"y"
JRST BEGIN0 ;OFF TO LOAD MORE.
BEGIN1: ICOUNT
TTCALL 3,[ASCIZ/
Name of the file to check and correct: /]
PUSHJ P,GETFIL ;GET A FILE NAME IN SOME WAY.
JRST ENDIT
LOOKUP DATA,K
JRST [PUSHJ P,FNOTFM
JRST BEGIN1]
TRNE FL,TRAIN
JRST BEGIN5 ;GIVE US SOME TRAINING
TRNE FL,QTRAIN ;OR SPECIAL TRAINING
JRST [TTCALL 3,[ASCIZ/An exception file is needed. /]
JRST BEGIN3]
BEGIN2: ICOUNT
TTCALL 3,[ASCIZ/
File name for output: /]
PUSHJ P,GETFIL
JRST [TTCALL 3,[ASCIZ/No corrections.
/]
TRO FL,NOCORR ;DO NO CORRECTIONS
TRNE FL,TRAIN
JRST BEGIN5 ;TRAINING
JRST BEGIN3]
TRZ FL,NOCORR
TRNE FL,TRAIN
JRST [TTCALL 3,T.MSG
JRST BEGIN1]
ENTER CORR,K
JRST [PUSHJ P,ENTFAI
JRST BEGIN2]
BEGIN3: ICOUNT
TTCALL 3,[ASCIZ/
File for exceptions: /]
PUSHJ P,GETFIL
JRST [TRNE FL,QTRAIN
JRST BEGIN3
TTCALL 3,[ASCIZ/No exception file.
/]
TRO FL,NOEXCP
TRNE FL,TRAIN
JRST .+1
JRST BEGIN5]
TRZ FL,NOEXCP
TRNE FL,TRAIN
JRST [TTCALL 3,T.MSG
JRST BEGIN1]
ENTER EXCP,K
JRST [PUSHJ P,ENTFAI
JRST BEGIN3]
BEGIN5: ICOUNT
IFN STANSW,<
TRNE FL,IIISW ;III?
PUSHJ P,DPYINI ;YES. INITIALIZE THE DISPLAY
>;IFN STANSW
TTCALL 3,[ASCIZ/working...
/]
TRZ FL,TECO!SHUTUP ;NOTE THAT HELPSN AND HELP2S WILL BE
;ZERO THE VERY FIRST TIME THRU
TRO FL,FRSTOP ;FLAG UP FOR FIRST I/O ON DATA
PUSHJ P,LOOP ;GO OFF AND DO ALL THE WORK
ENDIT: ICOUNT
TTCALL 3,[ASCIZ/Type:
E Exit
/]
SKIPN SONCE ;12-JUL-74 RRB ;NO SAVE IF NOT FIRST RUN
TTCALL 3,[ASCIZ/S Save this core image
/]
TTCALL 3,[ASCIZ/C Correct another file
/]
IFG COUNTS,<
TTCALL 3,[ASCIZ/X Dump the trace counts (for debugging only)
/]
>
TTCALL 3,[ASCIZ/A Augment the dictionary and correct another file
D Dump the dictionary to disk (DON'T DO THIS)
I Dump incremental. (Rewrites a file!)
*/]
TRZ FL,TRAIN!QTRAIN ;EXIT TRAINING MODE
TTCALL 4,A
TRZ A,40 ;MAKE UPPER
CAIN A,"E"
EXIT
CAIN A,"I"
JRST [PUSHJ P,SETNUM
PUSHJ P,IDMPD
JRST ENDIT]
TTCALL 11,0 ;FLUSH TO BE SURE.
IFG COUNTS, <
CAIN A,"X"
JRST DTRACE
>
SKIPE SONCE ;12-JUL-74 RRB ;FIRST RUN?
JRST .+3 ;12-JUL-74 RRB ;N0-NO SAVE IF NOT FIRST RUN
CAIN A,"S"
JRST SAVET
CAIN A,"C"
JRST XBEG.1
CAIN A,"A"
JRST BEGIN
CAIN A,"D"
JRST [PUSHJ P,DUMPD
JRST ENDIT]
TTCALL 3,[ASCIZ/Huh? /]
JRST ENDIT
XBEG.1: ICOUNT
RESET
PUSHJ P,INDICT
PUSHJ P,INDATA
PUSHJ P,INCORR
PUSHJ P,INEXCP
JRST BEGIN1
SAVET: ICOUNT
PUSHJ P,SAVEME
JRST ENDIT
T.MSG: ASCIZ/
You can't use Training Switch and have output or execeptions
/
IFN STANSW,<
DPYINI: DPYCLR ;CLEAR THE SCREEN
DPYPOS -200 ;PUSH THE PAGE PRINTER TO THE BOTTOM
DPYSIZ 4002 ;SET GLITCHES ETC
POPJ P, ;THAT'S ALL FOR NOW.
>;IFN STANSW
SUBTTL THE LOOP WHERE ALL THE WORK GETS DONE.
COMMENT %
This file depicts what happens to a word as it is checked
and corrected by the spelling checker.
<begin>
I
V
O_--------------------------------------_O
I ^
V I
---------------------------- I
I I I
O_-(if eof)_----I read next word I I
I I I I
I I lookup in dictionary I--(if success: win)----->O
I I I ^
I I (failure) I I
I I I I
I I call endtst I--(if success: win)----->O
I I I ^
I I (failure) I I
I I I I
I I call tryfix I I
I I I I
I I (correct/accept word) I I
I ---------------------------- I
I I I
I V I
I O--------------------------------------->O
I
V
O-------------------------->O
I
V
----------------------------
I I
I end sequence I
I I
----------------------------
%
LOOP: ICOUNT
PUSHJ P,GETLIN
JRST FLOOP ;EOF ON DATA
PUSHJ P,CHKLIN ;CHECK/CORRECT LINE
PUSHJ P,PUTLIN ;OUPUT LINE
JRST LOOP
FLOOP: ICOUNT
CLOSE DATA, ;YOU KNOW WHAT TO DO
CLOSE CORR, ;CLOSE OUTPUT CHANNEL
STATZ CORR,740000 ;CHECK IT
JRST DDE ;DEVICE DATA ERROR (OUTPUT)
CLOSE EXCP, ;CLOSE EXCEPTIONS
STATZ EXCP,740000 ;CHECK STATUS
JRST DDE ;ERROR
RELEAS DATA,
RELEAS EXCP,
RELEAS CORR,
TTCALL 3,[ASCIZ/
Finished.
/]
POPJ P,
SUBTTL THE DEBUG QUEUE.
COMMENT $
IF COUNTS IS DEFINED AS GREATER THAN ZERO THEN A QUEUE OF THE
LAST 100 LABELS PASSED WILL BE KEPT.
$
IFG COUNTS,<
DEBQUE: TRNE FL,NOTRAC
POPJ P,
ADD DEBX,[XWD 1,1]
MOVEM DEBA,(DEBX)
JUMPL DEBX,[POPJ P,] ;God forbid you should jump to CPOPJ
MOVE DEBX,[XWD %DBT+%DTL,%DBT]
BLT DEBX,%DBT+%DTL-1
MOVE DEBX,[IOWD %DTL,%DBT+%DTL]
POPJ P,
QDUMP: MOVEI B,[ASCIZ/
DUMP OF THE QUEUE OF STATEMENTS EXECUTED.
/]
PUSHJ P,WRSDCT
HRRZ C,DEBX ;LAST ADDRESS STORED IN
MOVEI D,%DBT
QDUMP1: MOVE A,(D)
PUSHJ P,OCTPEX
MOVEI B,[ASCIZ/
/]
PUSHJ P,WRSDCT
CAMGE D,C
AOJA D,QDUMP1
POPJ P,
CRASH: TRO FL,NOTRAC
PUSHJ P,INDCTO
MOVE K,[SIXBIT/CRASH0/]
CRASH0: MOVSI L,'TRC'
SETZ M,
MOVE N,XPPN
LOOKUP DICT,K
JRST .+2
AOJA K,CRASH0
MOVSI L,'TRC'
SETZ M,
MOVE N,XPPN
ENTER DICT,K
POPJ P,
JRST DTRACX
XPPN: SIXBIT /DMPREG/
>
SUBTTL FULL DUMP AND INCREMENTAL DUMP ROUTINES
DUMPD: ICOUNT
TRZ FL,IDUMP
JRST DUMPD1
IDMPD: ICOUNT
TRO FL,IDUMP
DUMPD1: ICOUNT
PUSHJ P,INDCTO ;INIT DICTIONARY CHANNEL IN OUTPUT MODE
TTCALL 3,[ASCIZ/file name: /]
PUSHJ P,GETFIL
JRST [TTCALL 3,[ASCIZ/Default name is WORDS.LST
/]
MOVE K,[SIXBIT/WORDS/]
MOVSI L,'LST'
SETZB M,N
JRST .+1]
ENTER DICT,K
JRST [PUSHJ P,ENTFAI
JRST DUMPD1]
PUSHJ P,DODUMP
POPJ P,
DODUMP: ICOUNT
SETZ Z,
TRO FL,LEFT
DODMP1: ICOUNT
TRNE FL,LEFT
HLRZ X,HASHTB(Z)
TRNN FL,LEFT
HRRZ X,HASHTB(Z)
PUSHJ P,CHASED
TRCE FL,LEFT
JRST DODMP1
ADDI Z,1
CAIGE Z,HASHTL
JRST DODMP1
CLOSE DICT,0
STATZ DICT,740000
JRST DDE
POPJ P,
CHASED: ICOUNT
JUMPE X,CPOPJ
HRRZ Y,0(X)
CAMG X,Y
PUSHJ P,INTCFN
TRNN FL,IDUMP
JRST CHAS.1
HLRZ A,(X)
ANDI A,37 ;MASK ALL BUT LS 5 BITS.
CAME A,IDNUM
JRST CHAS.2
CHAS.1: ICOUNT
ADDI X,1
PUSHJ P,DDCVRT
CHAS.2: ICOUNT
HRRZ X,Y
JRST CHASED
DDCVRT: ICOUNT
HRLI X,(<POINT 5,0>)
DDCVR1: ICOUNT
ILDB A,X
JUMPE A,DDCVR2
TRO A,100
PUSHJ P,WDICT
JRST DDCVR1
DDCVR2: ICOUNT
MOVEI A,15
PUSHJ P,WDICT
MOVEI A,12
PUSHJ P,WDICT
POPJ P,
SUBTTL TRACE DUMP ROUTINE
IFG COUNTS,<
DTRACE: PUSHJ P,DTRACY
JRST ENDIT
DTRACY: TTCALL 3,[ASCIZ/File name for the trace counts: /]
TRO FL,NOTRAC
PUSHJ P,GETFIL
JRST [TTCALL 3,[ASCIZ/default name is TRACE.DAT
/]
MOVE K,[SIXBIT/TRACE/]
MOVSI L,'DAT'
SETZB M,N
JRST .+1]
PUSHJ P,INDCTO
ENTER DICT,K
JRST [PUSHJ P,ENTFAI
JRST DTRACE]
DTRACX: PUSHJ P,QDUMP
MOVEI B,[ASCIZ/ Statement execution counts
/]
PUSHJ P,WRSDCT
SETZ Y,
DTRA.1: CAIL Y,ICTABX-ICTAB
JRST DTRA.2
MOVE A,Y
PUSHJ P,OCTPEX
MOVEI A,11
PUSHJ P,WDICT
MOVE A,ICTAB(Y)
PUSHJ P,DECPTY
MOVEI B,[ASCIZ/
/]
PUSHJ P,WRSDCT
AOJA Y,DTRA.1
DTRA.2: CLOSE DICT,
RELEAS DICT,
POPJ P,
OCTPEX: IDIVI A,10
PUSH P,B
JUMPE A,.+2
PUSHJ P,OCTPEX
POP P,A
ADDI A,60
PUSHJ P,WDICT
POPJ P,
WRSDCT: HRLI B,(<POINT 7,0>)
WRSDC1: ILDB A,B
JUMPE A,CPOPJ
PUSHJ P,WDICT
JRST WRSDC1
DECPTY: IDIVI A,12
PUSH P,B
JUMPE A,.+2
PUSHJ P,DECPTY
POP P,A
ADDI A,60
PUSHJ P,WDICT
POPJ P,
>
SUBTTL GETLIN READ A LINE OF DATA INTO LIBUF
GETLIN: ICOUNT
SETZM LIBUF
MOVE A,[XWD LIBUF,LIBUF+1]
BLT A,LOBUF+37 ;CLEAR BOTH INPUT AND OUTPUT LINES
PUSHJ P,RDDATA
POPJ P, ;NON-SKIP AT EOF.
TRNE FL,TECO ;ARE WE A TECO FILE?
JRST GETLTC ;GET A TECO LINE
MOVE B,[POINT 36,LIBUF] ;SET FOR WORD BY WORD
JRST GETLN2 ;A IS SET WITH FIRST DATA
GETLN1: ICOUNT
PUSHJ P,RDDATA
POPJ P, ;NOT GOOD MANNERS TO EOF
;IN THE MIDDLE OF A LINE
GETLN2: ICOUNT
IDPB A,B ;SAVE THE DATA IN THE LINE
BCHECK(B,LOBUF)
ANDI A,377 ;MASK ALL BUT THE LAST 8 BITS
LSH A,-1 ;A_THE FIFTH ASCIZ CHARACTER THAT HAD BEEN IN A,
;RIGHT JUSTIFIED IN A.
JUMPE A,GETLN3 ;END OF A LINEIN SOS FORMAT
CAIE A,12 ;OR LF WILL END A LINE
JRST GETLN1 ;BACK FOR MORE OF THIS LINE
GETLN3: ICOUNT
MOVE A,[XWD LIBUF,LOBUF]
BLT A,LOBUF+1 ;COPY FIRST TWO MACHINE WORDS TO OUTPUT
;WE WILL USE ONLY THE FIRST 6 CHARACTERS
;THE LINE NUMBER AND THE TAB.
MOVE A,[POINT 7,LIBUF+1,6] ;SET TO GRAB THE FIRST REAL
;CHARACTER BY ILDB.
MOVEM A,INPTR ;SAVE AS THE "IN POINTER"
HRRI A,LOBUF+1 ;FIX ADDRESS
MOVEM A,OUTPTR ;SAVE THE OUT POINTER
TRNN FL,PICKUP
JRST CPOPJ1 ;AND GIVE A SKIP RETURN
MOVE A,PAGENO
CAMGE A,PICKPG
JRST CPOPJ1
CAME A,PICKPG
JRST [TRZ FL,PICKUP
JRST CPOPJ1]
MOVE A,LIBUF
TRZ A,1
CAML A,PICKLN
TRZ FL,PICKUP
JRST CPOPJ1
GETLTC: ICOUNT
MOVE B,[POINT 7,LIBUF]
JRST GETEC1
GETTEC: ICOUNT
PUSHJ P,RDDATA
POPJ P,
GETEC1: ICOUNT
IDPB A,B
BCHECK(B,LOBUF)
CAIE A,12
CAIN A,14
JRST .+2
JRST GETTEC
MOVE A,[POINT 7,LIBUF]
MOVEM A,INPTR
HRRI A,LOBUF
MOVEM A,OUTPTR
TRNN FL,PICKUP
JRST CPOPJ1
MOVE A,PAGENO
CAML A,PICKPG
TRZ FL,PICKUP
JRST CPOPJ1
SUBTTL THE READING ROUTINE
RDDATA: ICOUNT
SOSLE DATABF+2
JRST RDATA1
INPUT DATA,
STATZ DATA,740000
JRST DIE
STATZ DATA,20000
POPJ P,
TRZE FL,FRSTOP
PUSHJ P,CKTECO ;CHECK FOR A TECO FILE.
RDATA1: ICOUNT
ILDB A,DATABF+1
JUMPE A,RDDATA ;BACK FOR MORE IF NULL
JRST CPOPJ1
CKTECO: ICOUNT
MOVEI A,1 ;SINCE WE ARE AT FIRSTOP, WE MIGHT AS
MOVEM A,PAGENO ;WELL INITIALIZE THE PAGE COUNT
SETZM LINENO ;AND ZERO THE LINE NUMBER
MOVE A,DATABF+1
ILDB A,A
TRNE A,1
JRST CKTEC1
TRO FL,TECO
MOVEI A,5
IMULM A,DATABF+2 ;MAKE WORD COUNT INTO CHAR COUNT
MOVSI A,(<POINT 7,0,35>) ;WHEN ILDB HITS THIS YOU GET THE
;RIGHT BYTE, (FROM THE NEXT WD)
HLLM A,DATABF+1 ;UPSET THE BYTE POINTERS
SETSTS DATA,1 ;CHANGE SO THAT IN THE FUTURE HONESTY PREVAILS
; WE ALSO HAVE TO CHANGE THE MODE OF THE CORR CHANNEL
; SO THAT IT WILL ACCEPT CHARACTER AT A TIME BYTE POINTERS.
;
SETSTS CORR,1 ;HAVE TO SCREW AROUND WITH BYTE POINTERS
HLLM A,CORRBF+1 ;SINCE OUTBUF HAS ALREADY SET THEM
CKTEC1: TRNN FL,PICKUP
POPJ P,
TTCALL 3,[ASCIZ/On what page do you want to pickup? /]
PUSHJ P,SETPAG
TRNE FL,TECO
POPJ P,
TTCALL 3,[ASCIZ/and what line do you want to start at? /]
PUSHJ P,SETLNO
POPJ P,
SETPAG: SETZ B,
SETPG1: TTCALL 4,A
CAIL A,"0"
CAILE A,"9"
JRST SETPG2
IMULI B,12
ADDI B,-"0"(A)
JRST SETPG1
SETPG2: JUMPE B,[TTCALL 3,[ASCIZ/Default is page 1
/]
MOVEI B,1
JRST .+1]
MOVEM B,PICKPG
PUSHJ P,FLUTTY
POPJ P,
SETLNO: MOVE B,[ASCII/00000/]
SETLO1: TTCALL 4,A
CAIL A,"0"
CAILE A,"9"
JRST SETLO2
LSH B,7
LSH A,1
OR B,A
JRST SETLO1
SETLO2: PUSHJ P,FLUTTY
MOVEM B,PICKLN
POPJ P,
SUBTTL CHKLIN ROUTINE
CHKLIN: ICOUNT
TRZ FL,ERRLIN ;NO ERROR YET
AOS LINENO ;INCREMENT LINE NUMBER
IFN STANSW,<
TRNE FL,IIISW
PUSHJ P,DPGL ;DISPLAY PAGE/LINE NUMBER
>
CHKLN1: ICOUNT
PUSHJ P,LDWORD ;GET A WORD
JRST CHKLN2 ;NOT A WORD
TRNE FL,SHUTUP+PICKUP
JRST CHKL1A ;DON'T BOTHER
PUSHJ P,HASHCP
PUSHJ P,SEARCH ;LOOK FOR IT
JRST CHKLN3 ;WASN'T THERE
CHKL1A: ICOUNT
PUSHJ P,COPYIO ;COPY TO OUTPUT
JRST CHKLN1 ;BACK FOR THE REST
CHKLN2: ICOUNT
PUSHJ P,COPYIO
JUMPE A,CPOPJ ;SUPER NULL, EO LINE
CAIN A,14 ;CHECK FOR FF
JRST [AOS PAGENO ;COUNT ANOTHER PAGE.
SETZM LINENO
POPJ P,]
CAIN A,12 ;LF OR
POPJ P,
JRST CHKLN1 ;BACK FOR THE REST OF THE LINE
CHKLN3: ICOUNT
PUSHJ P,ENDTST ;TRY REMOVING ENDINGS
JRST .+2 ;FAILED TO FIND WORD
JRST CHKL1A ;ACCEPT WORD
TRNE FL,TRAIN ;SKIP UNLESS WE ARE TRAINING
JRST [SETZM IDNUM
AOS IDNUM
PUSHJ P,HASHCP
PUSHJ P,INSRTX
JRST CHKL1A] ;INSERT WORD INTO TRAINING SET
TRNE FL,QTRAIN
JRST CHKLN5
PUSHJ P,CONVRT ;MAKE 7 BITS ASCII IN WORDIX
IFN STANSW,<
TRNE FL,IIISW
PUSHJ P,DPYLIN ;DISPLAY SPECIAL IF ON III
>
TROE FL,ERRLIN
JRST CHKLN4 ;LINE HAS BEEN PUBLISHED ONCE
PUSHJ P,PPAGE ;PUBLISH PAGE
IFN STANSW,<TRNN FL,IIISW>
TTCALL 3,LIBUF ;PUBLISH LINE
MOVEI B,LIBUF
PUSHJ P,WRSEXC ;IN EXCEPTION FILE TOO
CHKLN4: ICOUNT
IFN STANSW,<TRNN FL,IIISW>
TTCALL 3,WORDIX
MOVEI B,WORDIX
PUSHJ P,WRSEXC
MOVEI B,[ASCIZ/
/]
IFN STANSW,<TRNN FL,IIISW>
TTCALL 3,(B)
PUSHJ P,WRSEXC
TRNN FL,NOCORR+SHUTUP ;SKIP IF HE DOESN'T WANT IT
CHKLN5: PUSHJ P,TRYFIX ;TRY TO FIX IT
PUSHJ P,COPYIO
JRST CHKLN1
IFN STANSW,<
DPYLIN: MOVE B,OUTPTR ;GET THE OUTPUT POINTER
SETZ A,
IDPB A,B ;STUFF A ZERO IN BEYOND THE OUTPUT LINE.
MOVE Z,[IOWD DPYLEN,DPYBUF]
PUSH Z,[0]
PUSH Z,[LVW(-1000,0,I,A,2,2)] ;SET TO LEFT MIDDLE OF SCREEN
MOVEI C,1
MOVE Y,[POINT 7,C]
MOVE X,[POINT 7,LOBUF] ;GET POINTER TO LINE OUTPUT BUFFER
PUSHJ P,COPX
SKIPN WORDIX
JRST DPYL1
PUSH Z,C
PUSH Z,[LVW(20,0,I,,7,4)] ;SET BRIGHTNESS AND SIZE FOR OFFENDER
MOVE Y,[POINT 7,C]
MOVEI C,1
MOVE X,[POINT 7,WORDIX]
PUSHJ P,COPX
PUSH Z,C
PUSH Z,[LVW(20,0,I,,2,2)] ;RESTORE NORMAL BRIGHTNESS AND SIZE
MOVEI C,1
MOVE Y,[POINT 7,C]
DPYL1: MOVE X,INPTR1
PUSHJ P,COPX
PUSH Z,C
HLRE A,Z
ADDI A,DPYLEN
MOVEM A,DPYSIZ
UPGIOT 2,DPYHDR
POPJ P,
DPGL: MOVE Z,[IOWD DPYLEN,DPYBUF]
PUSH Z,[0]
PUSH Z,[LVW(-1000,40,I,A,2,2)]
MOVEI C,1
MOVE Y,[POINT 7,C]
MOVE X,[POINT 7,[ASCIZ/Page /]]
PUSHJ P,COPX
MOVE A,PAGENO
PUSHJ P,DECDIS
MOVE X,[POINT 7,[ASCIZ/ Line /]]
PUSHJ P,COPX
TRNE FL,TECO ;HAS THIS GOT LINE NUMBERS
JRST DPGL1 ;NO.
MOVE X,LIBUF ;GET A LINE NUMBER
TRNN X,1 ;REAL LINE NUMBER?
JRST DPGL1 ;NOPE.
MOVEM X,WORDIX
SETZM WORDIX+1
MOVE X,[POINT 7,WORDIX]
PUSHJ P,COPX
JRST DPGL2
DPGL1: MOVE A,LINENO
PUSHJ P,DECDIS
DPGL2: PUSH Z,C
HLRE A,Z
ADDI A,DPYLEN
MOVEM A,DPYSIZ
UPGIOT 3,DPYHDR
POPJ P,
> ;IFN STANSW
SUBTTL PUTLIN
PUTLIN: ICOUNT
TRNE FL,TECO
JRST PUTLN2
MOVE B,[POINT 36,LOBUF]
PUTLN1: ICOUNT
ILDB A,B
PUSHJ P,WRCORR
LSH A,-1
ANDI A,177
JUMPE A,CPOPJ ;DONE WITH LINE
CAIE A,12
JRST PUTLN1
POPJ P,
PUTLN2: ICOUNT
MOVE B,[POINT 7,LOBUF]
PUTLN3: ICOUNT
ILDB A,B
PUSHJ P,WRCORR
CAIE A,12
CAIN A,14
POPJ P,
JRST PUTLN3
WRCORR: ICOUNT
TRNE FL,NOCORR
POPJ P, ;NO CORECCTIONS MEANS THAT
SOSLE CORRBF+2
JRST WCORR1
OUTPUT CORR,
STATZ CORR,740000
JRST DDE
WCORR1: ICOUNT
IDPB A,CORRBF+1
BCHECK(CORRBF+1,@DICTBO)
POPJ P,
WRSEXC: ICOUNT
HRLI B,(<POINT 7,0>)
WRSEX0: ICOUNT
ILDB A,B
JUMPE A,CPOPJ
PUSHJ P,WREXCP
JRST WRSEX0
WREXCP: ICOUNT
TRNE FL,NOEXCP
POPJ P,
WEXCP0: ICOUNT
SOSLE EXCPBF+2
JRST WEXCP1
OUTPUT EXCP,
STATZ EXCP,740000
JRST DDE
WEXCP1: ICOUNT
IDPB A,EXCPBF+1
BCHECK(EXCPBF+1,@DICTBO)
POPJ P,
WDICT: ICOUNT
SOSLE DICTBF+2
JRST WDICT1
OUTPUT DICT,
STATZ DICT,740000
JRST DDE
WDICT1: ICOUNT
IDPB A,DICTBF+1
BCHECK(DICTBF+1,@DICTBO)
POPJ P,
COPYIO: ICOUNT
MOVE Z,INPTR
COPYI1: ICOUNT
ILDB A,Z
IDPB A,OUTPTR
BCHECK(OUTPTR,LOBUF+40)
CAME Z,INPTR1
JRST COPYI1
MOVEM Z,INPTR
POPJ P,
CONVRT: ICOUNT
MOVE Z,[POINT 5,WORDIN]
MOVE Y,[POINT 7,WORDIX]
CONVR1: ICOUNT
ILDB A,Z
JUMPE A,CONVR2
ADDI A,"A"-1
IDPB A,Y
BCHECK(Y,WORDIX+10)
JRST CONVR1
CONVR2: ICOUNT
IDPB A,Y
POPJ P,
PPAGE: ICOUNT
MOVEI B,[ASCIZ/Page /]
IFN STANSW,<TRNN FL,IIISW>
TTCALL 3,(B)
PUSHJ P,WRSEXC
MOVE A,PAGENO
PUSHJ P,DECPB
MOVEI B,[ASCIZ/
/]
TTCALL 3,(B)
PUSHJ P,WRSEXC
POPJ P,
DECPB: ICOUNT
IDIVI A,12
PUSH P,B
SKIPE A
PUSHJ P,DECPB
POP P,A
ADDI A,"0"
IFN STANSW,<TRNN FL,IIISW>
TTCALL 1,A
JRST WREXCP
SUBTTL DESCRIPTION OF ENDTST
COMMENT/
SKIP RETURN SIGNIFIES THAT THE WORD IS ACCEPTED; NON SKIP MEANS
REJECTION. IN EITHER CASE, THE RETURN WILL BE MADE SO THAT THE
ORIGINAL WORD IS RESTORED (IN FIVEBIT) TO WORDIN.
ENDTST - The Word Endings Checker.
<entry: ENDTST>
I
----------------------------
I Save the word I
----------------------------
I
V
ENDTG.: ------------------->O
I
V
----------------------------
I acA_last letter I
I dispatch on acA I
----------------------------
I
V
----------------------------
I if acA = "S" go to EDT.S I
----------------------------
I (not an S)
V
ENDTGO: ------------------>O
I
V
----------------------------
I dispatch on contents of I
I acA I
I G EDT.G I
I D EDT.D I
I R EDT.R I
I E EDT.E I
I T EDT.T I
I H EDT.H I
I N EDT.N I
I Y EDT.Y I
I (else failure) I
----------------------------
EDT.S: ----------------->O
I
V
----------------------------
I delete last letter. I
I lookup result I----(if success, return)
I (failure) I
I acA _ new last letter I
I if letter is S, EDT.SS I
I if letter is not E, I
I then ENDTGO I
I (word was ...ES) I
I delete the E I
I lookup result I----(if success, return)
I (failure) I
I acA _ new last letter I
I if acA "I" then OHELL. I
I set last letter to "Y" I
I lookup result I----(success, return)
I return: failure I
----------------------------
EDT.G: ------------------>O
I
V
----------------------------
I remove last letter I
I acA _ new last letter I
I if acA "N" then fail I
I remove last leter I
I acA _ new last letter I
I if acA "I" then fail I
I remove last letter I
I lookup the word I----(success, return)
I (failure) I
----------------------------
I
V
OHELL.: ------------------->O
I
V
----------------------------
I remove the last letter I
I lookup the word I----(success, return)
I return: failure I
----------------------------
EDT.D: ------------------->O
I
V
----------------------------
I remove the last letter I
I acA _ new last letter I
I if acA "E" then fail I
I lookup the word I----(success, return)
I (failure) I
I remove the last letter I
I lookup the word I----(success, return)
I (failure) I
I acA_ new last letter I
I if acA "I" then OHELL. I
I set last letter to "Y" I
I lookup the word I----(success, return)
I return: failure I
----------------------------
EDT.R: ------------------->O
I
V
----------------------------
I remove last letter I
I acA _ new last letter I
I if acA "E" then fail I
I lookup the word I----(success, return)
I (failure) I
I remove last letter I
I lookup the word I----(success, return)
I (failure) I
I acA _ new last letter I
I if acA "I" then OHELL. I
I set last letter to "Y" I
I lookup the word I----(success, return)
I return: failure I
----------------------------
EDT.T: ------------------->O
I
V
----------------------------
I remove last letter I
I acA _ new last letter I
I if acA "S" then fail I
I remove last letter I
I acA _ new last letter I
I if acA "E" then fail I
I lookup the word I----(success, return)
I (failure) I
I remove the last letter I
I lookup the word I----(success, return)
I (failure) I
I go to OHELL. I
----------------------------
EDT.H: ------------------>O
I
V
----------------------------
I remove the last letter I
I acA _ new last letter I
I if acA "T" then fail I
I lookup the word I----(success, return)
I (failure) I
I go to OHELL. I
----------------------------
EDT.N: ------------------>O
I
----------------------------
I remove the last letter I
I acA _ new last letter I
I if acA ="E" go to EDT.EN I
I if acA "O" then fail I
I remove the last letter I
I acA _ new last letter I
I if acA "I" then fail I
I set last letter to "E" I
I lookup word I----(success, return)
I (failure) I
I remove the last letter I
I acA _ new last letter I
I if aca "T" then fail I
I remove the last letter I
I acA _ new last letter I
I if acA "A" then fail I
I remove the last letter I
I acA _ new last letter I
I if acA "C" then fail I
I remove the last letter I
I acA _ new last letter I
I if acA "I" then fail I
I set last letter to "Y" I
I lookup the word I----(success, return)
I return: failure I
----------------------------
EDT.EN: ------------------>O
I
V
-----------------------------
I remove the last letter I
I lookup the word I----(success, return)
I return: failure I
-----------------------------
EDT.Y: ------------------>O
I
V
-----------------------------
I remove the last letter I
I acA _ new last letter I
I if acA ="L" go to EDT.LY I
I if acA "T" then fail I
I remove the last letter I
I lookup the word I----(success, return)
I (failure) I
I acA _ new last letter I
I if acA "I" then fail I
I set last letter to "E" I
I lookup the word I----(success, return)
I return: failure I
-----------------------------
EDT.LY: ------------------>O
I
V
-----------------------------
I remove the last letter I
I lookup the word I----(success, return)
I (failure) I
I go to OHELL. I
-----------------------------
ENDSS: ------------------>O
I
V
-----------------------------
I remove the last letter I
I acA _ new last letter I
I if acA "E" then fail I
I remove the last letter I
I acA _ new last letter I
I if acA "N" then fail I
I remove the last letter I
I lookup word I----(success, return)
I (failure) I
I append "E" to word I
I lookup word I-----(success, return)
I (failure) I
I remove the last letter I
I acA _ new last letter I
I if acA "I" go to ENDTG. I
I set last letter to "Y" I
I lookup word I----(success, return)
I return: failure I
-----------------------------
END.E: ------------------>O
I
V
-----------------------------
I remove the last letter I
I acA _ new last letter I
I if acA = "V" then END.VE I
I lookup the word I----(success: return)
I return: failure I
-----------------------------
END.VE: ------------------>O
I
V
-----------------------------
I remove the last letter I
I acA _ the new last letter I
I if acA "I" then fail I
I remove the last letter I
I lookup word I----(success, return)
I append "E" to word I
I lookup word I----(success, return)
I return: failure I
-----------------------------
/
SUBTTL ENDTST TEST THE SUSPECT WORD BY REMOVING THE ENDINGS
ENDSRT: ICOUNT
AOS (P) ;SUCCESS RETURN
ENDFRT: ICOUNT
PUSHJ P,UNSVWD ;FAILURE, RESTORE WORD AND SIZE
POPJ P,
COMMENT/ THE ENTRY /
ENDTST: ICOUNT
CAIG W,3 ;IF TOO SMALL THEN
POPJ P, ;RETURN QUICK WITH FAILURE
PUSHJ P,SAVWD ;SAVE WORDIN AND W,(IN A PLACE KNOWN
;TO BUT A FEW).
ENDTG.: PUSHJ P,GETLST ;GET LAST LETTER INTO A.
CAIN A,"S" ;IS IT S?
JRST EDT.S ;DO THE S THING
ENDTGO: ICOUNT
CAIN A,"G" ;MAYBE AN "ING"
JRST EDT.G ;OFF TO DO G THING (NOT STRING)
CAIN A,"D" ;"ED"
JRST EDT.D
CAIN A,"R" ;"ER"
JRST EDT.R
CAIN A,"E" ;EE OR ..IVE
JRST END.E
CAIN A,"T" ;"EST"
JRST EDT.T
CAIN A,"H" ;"TH"
JRST EDT.H
CAIN A,"N" ;"ION" "ATION" "CATION" "ICATION"
JRST EDT.N
CAIN A,"Y" ;"TY" AND "LY"
JRST EDT.Y
JRST ENDFRT ;FAIL RETURN
EDT.S: ICOUNT
PUSHJ P,ZLAST ;TRY SINGULAR FORM
PUSHJ P,HASHCP ;COMPUTE THE HASH
PUSHJ P,SEARCH
JRST .+2 ;FAILURE
JRST ENDSRT ;SUCCESS
PUSHJ P,GETLST ;DOES IT END IN "IE"
CAIE A,"E"
JRST [CAIE A,"S" ;MAYBE ...NESS?
JRST ENDTGO ;NO BACK THRU LIST
JRST ENDSS] ;OFF TO TRY IT
PUSHJ P,ZLAST ;WIPE OUT THE E
PUSHJ P,HASHCP ;LOOKUP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT ;WIN (HASHes is the example).
PUSHJ P,GETLST
CAIE A,"I"
JRST OHELL. ;KNOCK OFF ANOTHER LETTER,
MOVEI A,"Y"
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.G: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"N"
JRST ENDFRT ;CAN'T DO ANY THING ELSE
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"I"
JRST ENDFRT
MOVEI A,"E" ;SO CREATING WILL HAVE A CHANCE
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,ZLAST ;take back the irrelevant E
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT ;AN UNADORNED ING, LIKE KNOCKING
PUSHJ P,GETLST
PUSH P,A
PUSHJ P,ZLAST
PUSHJ P,GETLST ;CHECK FOR A DOUBLED LETTER BEFORE ING
CAME A,(P)
JRST [POP P,(P)
JRST ENDFRT] ;FAILURE
POP P,(P)
JRST OHELL1
OHELL.: ICOUNT
PUSHJ P,ZLAST
OHELL1: PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.D: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"E"
JRST ENDFRT
;FIRST TRY JUST WITHOUT THE D SO CREATED AND DELETED WILL WORK
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
;NOW CHECK OUT THE LAST, IF WE HAD "IED" THEN CHANGE
;IT TO Y, ELSE, DELETE THAT LAST LETTER BY OHELL.
PUSHJ P,GETLST
CAIE A,"I"
JRST OHELL.
MOVEI A,"Y"
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.R: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"E"
JRST ENDFRT
PUSHJ P,HASHCP ;TRY FOR STUFF LIKE "LARGER"
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,GETLST
CAIE A,"I" ;SO "SPECIFIER" MAY WORK
JRST OHELL.
MOVEI A,"Y"
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.T: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"S"
JRST ENDFRT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"E"
JRST ENDFRT
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST OHELL.
JRST ENDSRT
EDT.H: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"T"
JRST ENDFRT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.N: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIN A,"E"
JRST EDT.EN
CAIE A,"O"
JRST ENDFRT
PUSHJ P,ZLAST ;REMOVED "ON" THUS FAR
PUSHJ P,GETLST
CAIE A,"I"
JRST ENDFRT
MOVEI A,"E" ;"ION" REPLACED BY "E"
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,ZLAST ;"ION" IS GONE
PUSHJ P,GETLST
CAIE A,"T"
JRST ENDFRT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"A"
JRST ENDFRT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"C"
JRST ENDFRT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"I"
JRST ENDFRT
MOVEI A,"Y"
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.EN: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST OHELL.
JRST ENDSRT
EDT.Y: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIN A,"L"
JRST EDT.LY
CAIN A,"T"
JRST ENDFRT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,GETLST
CAIE A,"I"
JRST ENDFRT
MOVEI A,"E"
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
EDT.LY: ICOUNT
PUSHJ P,ZLAST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST OHELL.
JRST ENDSRT
ENDSS: PUSHJ P,ZLAST
PUSHJ P,GETLST ;THIS MUST BE AN "E"
CAIE A,"E"
JRST ENDFRT ;FAILURE
PUSHJ P,ZLAST ;WIPE OUT E
PUSHJ P,GETLST
CAIE A,"N"
JRST ENDFRT ;FAIL
PUSHJ P,ZLAST ;WIPE OUT THE N.
PUSHJ P,HASHCP ;LOOKUP WORD
PUSHJ P,SEARCH
JRST .+2 ;NOPE, NOT YET
JRST ENDSRT ;WIN
MOVEI A,"E" ;REPLACE ...NESS BY ...E
ADDI W,1 ;INCREMENT WORD SIZE
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT
PUSHJ P,ZLAST ;TAKE AWAY THE E
PUSHJ P,GETLST
CAIE A,"I"
JRST ENDTG. ;NOTHING OF INTEREST
MOVEI A,"Y" ;CHANGE THE I TO Y
PUSHJ P,SETLST
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT ;GIVE UP
JRST ENDSRT ;WIN
;SHOWING OUR PERMISSIVENESS
END.E: PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIN A,"V"
JRST END.VE
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
END.VE: PUSHJ P,ZLAST
PUSHJ P,GETLST
CAIE A,"I"
JRST ENDFRT
PUSHJ P,ZLAST ;TAKE OFF THE I FROM IVE
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST ENDSRT ;WIN
MOVEI A,"E"
ADDI W,1
PUSHJ P,SETLST ;TRY CHANGING IVE TO E.
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST ENDFRT
JRST ENDSRT
SUBTTL ROUTINES USED BY ENDTST
COMMENT/
SAVWD: SAVES WORDIN AT A PLACE KNOWN TO BUT A FEW
UNSVWD: RESTORE THE WORD FROM THE SAME PLACE
/
SAVWD: ICOUNT
MOVEM W,SVWDLN ;SAVE WORD LENGTH
MOVE W,[XWD WORDIN,SVWDWX]
BLT W,SVWDWX+5
MOVE W,SVWDLN
POPJ P,
UNSVWD: ICOUNT
MOVE W,[XWD SVWDWX,WORDIN]
BLT W,WORDIN+5
MOVE W,SVWDLN
POPJ P,
COMMENT/
GETLST: LOAD A WITH THE ASCII FOR THE LAST LETTER IN THE WORD.
ZLAST: ZERO THE LAST LETTER OF A WORD AND REDUCE W BY 1.
SETLST: SET LAST LETTER TO THE FIVEBIT EQUIVALENT OF A. A CONTAINS ASCII
INITIALLY
GETLBP: MAKE A BYTE POINTER TO THE LAST LETTER.
POINTER IS SUITABLE FOR A LDB OR DPB.
POINTER LIVES IN LSTBPY.
/
GETLBP: ICOUNT
JUMPL W,.+2
CAILE W,62
PUSHJ P,INTCFN
PUSH P,W
PUSH P,X
SUBI W,1
IDIVI W,7
MOVE X,GETLBT(X)
ADD X,W
MOVEM X,LSTBPY
POP P,X
POP P,W
POPJ P,
GETLBT: POINT 5,WORDIN,4
POINT 5,WORDIN,9
POINT 5,WORDIN,14
POINT 5,WORDIN,19
POINT 5,WORDIN,24
POINT 5,WORDIN,29
POINT 5,WORDIN,34
GETLST: ICOUNT
PUSHJ P,GETLBP
LDB A,LSTBPY
ADDI A,"A"-1
POPJ P,
SETLST: ICOUNT
SUBI A,"A"-1
PUSHJ P,GETLBP
DPB A,LSTBPY
POPJ P,
ZLAST: ICOUNT
PUSH P,A
MOVNI A,"A"-1
PUSHJ P,SETLST
POP P,A
SUBI W,1 ;REDUCE THE WORD LENGTH
POPJ P,
SUBTTL LOAD WORD
LDWORD: ICOUNT
SETZM WORDIN
MOVE Z,[XWD WORDIN,WORDIN+1]
BLT Z,WORDIN+5
MOVE Z,INPTR
MOVE Y,[POINT 5,WORDIN]
ILDB A,Z
CAIL A,"A"
CAILE A,"z"
JRST LDWRD3 ;NOT A LETTER
CAILE A,"Z"
CAIL A,"a"
TRZA A,140 ;YES, A LETTER. MAKE INTO FIVEBIT AND SKIP
JRST LDWRD3 ;NOT A LETTER
IDPB A,Y
BCHECK(Y,WORDIN+10)
MOVEI W,1 ;COUNT FOR HASH
LDWRD1: ICOUNT
MOVEM Z,INPTR1
ILDB A,Z
CAIE A,"`"
CAIN A,"'"
JRST LDWRD1
CAIL A,"A"
CAILE A,"z"
JRST LDWRD2 ;NOT A LETTER
CAILE A,"Z"
CAIL A,"a"
TRZA A,140 ;A LETTER. MAKE IT FIVEBIT AND SKIP
JRST LDWRD2 ;NOT A LETTER
IDPB A,Y
BCHECK(Y,WORDIN+10)
AOJA W,LDWRD1
LDWRD2: ICOUNT
CAIL A,"0"
CAILE A,"9"
JRST CPOPJ1 ;WE HAVE A DELIM
LDWRD3: ICOUNT
MOVEM Z,INPTR1 ;WHATEVER WE HAVE, IT'S NOT A WORD
;SO PUT THE POINTER PAST IT.
CAIL A,"A" ;TEST FOR A DELIMITER
CAILE A,"z"
JRST MAYD.2 ;MAYBE
CAILE A,"Z"
CAIL A,"a"
JRST NDLM.1 ;NOT A DELIM
MAYD.2: CAIL A,"0"
CAILE A,"9"
POPJ P, ;THIS IS A DELIM BUT NOT A WORD
NDLM.1: ILDB A,Z ;NOT A DELIM
JRST LDWRD3 ;FLUSH TO A DELIMITER
SUBTTL CHANNEL INITIALIZATION
SDEF(BUFFNO,2) ;NUMBER OF I/O BUFFERS FOR DEVICES
SDEF(MODE,14) ;BUFFERD BINARY WORD AT A TIME MODE.
SDEF(AMODE,1) ;BUFFFERED CHARACTER AT A TIME
INDICT: ICOUNT
INIT DICT,AMODE
SIXBIT /DSK/
XWD 0,DICTBF
JRST NODISK
PUSH P,A
MOVE A,DICTFF
EXCH A,.JBFF
INBUF DICT,BUFFNO
EXCH A,.JBFF ;RESTORE OLD
MOVEM A,NEWFF ;BUT SAVE NEW, IF WE ARE AT BEGINNING
POP P,A
POPJ P,
INDCTO: ICOUNT
INIT DICT,AMODE
SIXBIT /DSK/
XWD DICTBF,0
JRST NODISK
PUSH P,A
MOVE A,DICTFF
EXCH A,.JBFF
OUTBUF DICT,BUFFNO
EXCH A,.JBFF
MOVEM A,NEWFF
POP P,A
POPJ P,
INDATA: ICOUNT
INIT DATA,MODE
SIXBIT /DSK/
XWD 0,DATABF
JRST NODISK
PUSH P,A
MOVE A,DATAFF
EXCH A,.JBFF
INBUF DATA,BUFFNO
EXCH A,.JBFF
MOVEM A,NEWFF
POP P,A
POPJ P,
INEXCP: ICOUNT
INIT EXCP,AMODE
SIXBIT /DSK/
XWD EXCPBF,0
JRST NODISK
PUSH P,A
MOVE A,EXCPFF
EXCH A,.JBFF
OUTBUF EXCP,BUFFNO
EXCH A,.JBFF
MOVEM A,NEWFF
POP P,A
POPJ P,
INCORR: ICOUNT
INIT CORR,MODE
SIXBIT /DSK/
XWD CORRBF,0
JRST NODISK
PUSH P,A
MOVE A,CORRFF
EXCH A,.JBFF
OUTBUF CORR,BUFFNO
EXCH A,.JBFF
MOVEM A,NEWFF
POP P,A
POPJ P,
SUBTTL I/O STUFF:
COMMENT/
RDDICT: READ DICTIONARY FILE.
STOPGAP LINE NUMBERS ARE STRIPPED.
CHARACTER RESULT IN A. SKIP RETURN IS NORMAL, NON SKIP FOR EOF.
/
RDDICT: ICOUNT
SOSLE DICTBF+2
JRST RDICT1
INPUT DICT,
STATZ DICT,740000
JRST DIE
STATZ DICT,20000
POPJ P, ;DIRECT RETURN MEANS EOF
RDICT1: ICOUNT
ILDB A,DICTBF+1
JUMPE A,RDDICT
PUSH P,A
MOVE A,@DICTBF+1
TRNE A,1
JRST RDICT2
POP P,A
CPOPJ1: ICOUNT
AOS (P)
CPOPJ: ICOUNT
POPJ P, ;NORMALLY A SKIP RETURN
RDICT2: ICOUNT
MOVE A,DICTBF+2
SUBI A,5
MOVEM A,DICTBF+2 ;FIX CHARACTER COUNT.
AOS DICTBF+1 ;LIKEWISE FIX BYTE POINTER
POP P,A
JRST RDDICT ;BACK AND READ MORE.
SUBTTL THE DICTIONARY LOADER.
SONCE: 0 ;12-JUL-74 RRB ;ONCE-ONLY FLAG FOR SAVING CORE IMAGE
; CHECK IF WE ARE ADDING OR ARE VIRGIN
LOADER: ICOUNT
SKIPN DICTFL
TTCALL 3,[ASCIZ/
You must load a dictionary file. /]
PUSHJ P,INDICT
LOAD.1: ICOUNT
TTCALL 3,[ASCIZ/Dictionary file name: /]
PUSHJ P,GETFIL ;PRESUMED TO RETURN IN K,L,M,N.
JRST [TTCALL 3,NULMSG
JRST LOAD.1]
LOOKUP DICT,K
JRST [PUSHJ P,FNOTFM
JRST LOAD.1]
TRZ FL,IDUMP
SKIPE DICTFL
JRST LOAD.0 ;ALREADY HAVE A DICTIONARY
SETZM HASHTB
MOVE A,[XWD HASHTB,HASHTB+1]
BLT A,HASHTB+HASHTL-1 ;CLEAR HASH TABLE
JRST LOAD.2
LOAD.0: ICOUNT
TTCALL 3,[ASCIZ/Type "I" to mark these as incremental insertions: /]
TTCALL 4,A
CAIE A,"I"
CAIN A,"i"
JRST [TRO FL,IDUMP
PUSHJ P,SETNUM
JRST .+1]
PUSHJ P,FLUTTY
LOAD.2: ICOUNT
PUSHJ P,RDICTW ;READ A DICTIONARY WORD
JRST LOAD.3
PUSHJ P,HASHCP ;COMPUTE HASH
PUSHJ P,SEARCH ;LOOKUP WORD
JRST .+2 ;FAILED, I.E. NOT THERE
JRST LOAD.2
PUSHJ P,INSERY ;ADD IT TO THE LIST
AOS DICTFL ;INCREMENT WORD COUNT
JRST LOAD.2 ;BACK FOR MORE
LOAD.3: ICOUNT
CLOSE DICT, ;DESELECT FILE
TTCALL 3,[ASCIZ/There are now /]
MOVE A,DICTFL
PUSHJ P,DECPTR
TTCALL 3,[ASCIZ/ words in the dictionary. /]
MOVE A,.JBREL
LSH A,-12
ADDI A,1
PUSHJ P,DECPTR
TTCALL 3,[ASCIZ/ K Core used./]
SKIPE SONCE ;12-JUL-74 RRB ;FIRST TIME RUN?
POPJ P, ;12-JUL-74 RRB ;NO-CANT SAVE CORE IMAGE
TTCALL 3,[ASCIZ/
Do you want to save this core image? /]
TTCALL 4,A
PUSHJ P,FLUTTY
CAIE A,"Y"
CAIN A,"y"
JRST .+2
POPJ P,
SETOM SONCE ;12-JUL-74 RRB ;SET ONCE-ONLY FLAG
PUSHJ P,SAVEME
JRST BEGIN ;HAVE TO REESTABLISH THE WORLD AFTER THE
;BIG RESET.
SUBTTL READ A DICTIONARY WORD.
COMMENT/
SKIP RETURN, EXCEPT FOR EOF.
CHARACTER COUNT IN W. 5 BIT TEXT IN WORDIN. 7 BIT ASCIZ IN WORDIX
/
RDICTW: ICOUNT
SETZB W,WORDIN
MOVE A,[XWD WORDIN,WORDIN+1]
BLT A,WORDIX+12
MOVE X,[POINT 5,WORDIN]
MOVE Y,[POINT 7,WORDIX]
RDCTW1: ICOUNT
PUSHJ P,RDDICT
POPJ P, ;EOF. QUICK RETURN
IDPB A,Y
CAIGE A,"A"
JRST RDCTW3 ;A DELIMITER
RDCTW2: ICOUNT
TRZ A,40 ;INSURE UPPER CASE
SUBI A,"A"-1 ;MAP A TO 1, Z TO 26 ETC.
CAILE A,37
JRST RDCTW3 ;I THINK THIS CAN'T HAPPEN
IDPB A,X
CAILE W,50
JRST RDCTW4 ;TOO LONG
AOJA W,RDCTW1 ;BACK FOR MORE
RDCTW3: ICOUNT
CAIE A,12
CAIN A,14 ;LF AND FF STOP US.
JRST [JUMPN W,CPOPJ1
JRST RDICTW] ;DISALLOW ZERO LENGTH WORDS
PUSHJ P,RDDICT
POPJ P,
JRST RDCTW3
RDCTW4: ICOUNT
TTCALL 3,[ASCIZ/Illegal dictionary entry: /]
TTCALL 3,WORDIX
RDCTW5: ICOUNT
PUSHJ P,RDDICT
POPJ P,
TTCALL 1,A
CAIE A,12
CAIN A,14 ;FF OR LF WILL STOP US
JRST RDICTW ;BACK FOR A WHOLE NEW WORD
JRST RDCTW5
SUBTTL THE HASH COMPUTATION.
COMMENT/
HASHCP: COMPUTES THE HASH INDEX TO THE TABLE HASHTB.
ARGUMENTS: W. WORD LENGTH
WORDIX 5 BIT WORD
RESULTS: Z: THE INDEX TO THE TABLE, EXCEPT
Z=-1 IF W1.
FLAG, LEFT (IN FL RIGHT) IS SET IF HASH CODE IS ON
LEFT HALF, OTHERWISE, RIGHT HALF
/
HASHCP: ICOUNT
SETO Z,
JUMPLE W,[TTCALL 3,[ASCIZ/0 LENGTH WORD AT HASHCP/]
POPJ P,]
CAIG W,1
POPJ P, ;SIMPLE FOR WORDS OF LENGTH 1.
MOVE X,[POINT 5,WORDIN]
ILDB A,X
CAILE A,32
JRST HASHER ;ERROR
JUMPE A,HASHER
SUBI A,1
IMULI A,32
MOVE Z,A
ILDB A,X
CAILE A,32
JRST HASHER
JUMPE A,HASHER
ADDI Z,-1(A)
IMULI Z,12
MOVE X,W
SUBI X,2
CAILE X,11
MOVEI X,11
ADD Z,X
TRNE Z,1
TRZA FL,LEFT ;ODD. RIGHT HALF
TRO FL,LEFT ;EVEN, SET LEFT FLAG
LSH Z,-1 ;HALVE Z.
POPJ P,
HASHER: ICOUNT
TTCALL 3,[ASCIZ/HASHING ERROR
/]
HALT
SUBTTL SCAN TTY FOR A FILE NAME
GNCHTT: ICOUNT
TTCALL 4,A
CAIN A,33
MOVEI A,12
CAIE A,175
CAIN A,176
MOVEI A,12
POPJ P,
SCAN: ICOUNT
SETZM SCANT
MOVE B,[XWD SCANT,SCANT+1]
BLT B,SCANX+4
SETZ Y, ;INDEX TO PAGES.
SCAN1: ICOUNT
MOVE B,[POINT 6,SCANT]
SETZB C,SCANT ;IMPORTANT TO START RITE
SCAN2: ICOUNT
PUSHJ P,GNCHTT ;GET A CHARACTER
CAIN A,15
JRST SCAN2
CAIN A,12
JRST SCAND1
CAIN A,40
JRST SCAN2
CAIN A,"." ;FILENAME SEEN
JRST SCAND2
CAIN A,"/"
JRST SCAND0
CAIN A,"["
JRST SCPPN
CAIGE A,"a"
JRST .+3
CAIG A,"z"
SUBI A,40 ;CONVERT TO UPPER CASE
SUBI A," " ;MAKE SIXBIT
JUMPL A,SCANER
CAILE A,77
JRST SCANER
AOS C
CAIG C,6
IDPB A,B
JRST SCAN2
SCANER: ICOUNT
TTCALL 3,[ASCIZ/ILLEGAL CHARACTER IN SCAN./]
PUSHJ P,FLUTTY ;EMPTY TO NEXT CRLF
TTCALL 3,[ASCIZ/Try again: /]
JRST SCAN
SCAND1: ICOUNT
MOVEM A,SAVCHR
SKIPN C
JRST SCNRET
MOVE A,SCANT
SETZ C,
SKIPE SCANX+1
AOS C
MOVEM A,SCANX+1(C)
JRST SCNRET
SCAND2: ICOUNT
MOVE A,SCANT
MOVEM A,SCANX+1
JRST SCAN1
SCAND0: ICOUNT
JUMPE C,SCANSW
MOVE A,SCANT
SETZ C,
SKIPE SCANX+1
ADDI C,1
MOVEM A,SCANX+1(C)
SCANSW: TTCALL 4,A
TRZ A,40 ;ENSURE UPPER CASE
MOVSI B,-SWTBLN
CAME A,SWTAB1(B)
AOBJN B,.-1
JUMPGE B,[TTCALL 3,[ASCIZ/unrecognized switch /]
JRST SCANER]
XCT SWTAB2(B)
JRST SCAN1
SWTAB1: "P"
"T"
"Q"
SDEF(SWTBLN,.-SWTAB1)
SWTAB2: TRO FL,PICKUP
TRO FL,TRAIN!NOEXCP!NOCORR
TRO FL,QTRAIN!NOCORR
SCPPN: ICOUNT
SKIPN C
JRST SCPPN0
MOVE A,SCANT
SETZ C,
SKIPE SCANX+1
AOS C
MOVEM A,SCANX+1(C)
SCPPN0: ICOUNT
SETZB B,C
SCPPN1: ICOUNT
PUSHJ P,GNCHTT
CAIN A,"]"
JRST SCPPN3
CAIN A,","
JRST SCPPN2
IFN STANSW,< CAIL A,100
TRZ A,40 ;MAKE LOWER CASE LETTER TO UPPER CASE
SUBI A," "
JUMPL A,SCANER
CAILE A,77
JRST SCANER
LSH B,6 >;stanford
IFE STANSW,< SUBI A,"0"
JUMPL A,SCANER
CAIL A,PPNMUL
JRST SCANER
IMULI B,PPNMUL
>
ADD B,A
JRST SCPPN1
SCPPN2: ICOUNT
HRLZ C,B
SETZ B,
JRST SCPPN1
SCPPN3: ICOUNT
HRR C,B
MOVEM C,SCANX+3
JRST SCAN1 ;MAYBE MORE?
SCNRET: ICOUNT
SKIPE SCANX
JRST CPOPJ1
SKIPE SCANX+1
JRST CPOPJ1
POPJ P,
GETFIL: ICOUNT
PUSHJ P,SCAN
POPJ P, ;NULL TERM
MOVE K,SCANX+1
HLLZ L,SCANX+2
SETZ M,
MOVE N,SCANX+3
JRST CPOPJ1
SUBTTL ERROR MESSAGES
DDE: ICOUNT
TTCALL 3,[ASCIZ/DEVICE DATA ERROR (OUTPUT)
/]
HALT
FNOTFM: ICOUNT
TTCALL 3,[ASCIZ/FILE NOT FOUND. DSK:/]
PUSHJ P,TYFILN ;ARGS IN K,L,M,N
POPJ P,
NODISK: ICOUNT
TTCALL 3,[ASCIZ/INIT FAILED ON DEVICE DSK: /]
HALT
DECPTR: ICOUNT
PUSH P,B
PUSHJ P,DECPTX ;USES B. A IS ARGUMENT
POP P,B
POPJ P,
DECPTX: ICOUNT
IDIVI A,12
PUSH P,B
SKIPE A
PUSHJ P,DECPTX
POP P,A
ADDI A,"0"
TTCALL 1,A
POPJ P,
FLUTTY: ICOUNT
PUSH P,A
FLUTT1: ICOUNT
CAIE A,12
CAIN A,175
JRST FLUTT2
CAIE A,33
CAIN A,176
JRST FLUTT2
TTCALL 2,A
JRST FLUTT2
JRST FLUTT1
FLUTT2: ICOUNT
POP P,A
POPJ P,
NOCORE: ICOUNT
TTCALL 3,[ASCIZ/INSUFFICIENT CORE AVAILABLE. I GIVE UP
/]
EXIT
NULMSG: ASCIZ/Null term illegal
/
ENTFAI: ICOUNT
TTCALL 3,[ASCIZ/Enter failed on: /]
PUSHJ P,TYFILN
POPJ P,
DIE: ICOUNT
TTCALL 3,[ASCIZ/DEVICE ERROR (INPUT)
/]
HALT
INTCFN: ICOUNT
TTCALL 3,[ASCIZ/
Internal confusion in the spelling checker. Called from location: /]
PUSH P,A
HRRZ A,-1(P)
PUSH P,B
SUBI A,1
PUSHJ P,OCTPTR
IFG COUNTS,< PUSHJ P,CRASH>
POP P,B
POP P,A
TTCALL 3,[ASCIZ/
please send a note to REG.
You may continue, with doubtful results....
/]
HALT CPOPJ
OCTPTR: ICOUNT
IDIVI A,10
PUSH P,B
JUMPE A,.+2
PUSHJ P,OCTPTR
POP P,B
ADDI B,60
TTCALL 1,B
POPJ P,
SUBTTL SEARCH LOOK IN DICTIONARY FOR A WORD.
COMMENT/ THE SUBJECT OF THE SEARCH LIVES IN WORDIN.
IT HAS W CHARACTERS.
IT HAS HASH INDEX Z.
IF Z<0 (OR W1) THEN WE WILL ALWAYS FIND IT AS A WORD.
SKIP RETURN IF FOUND.
/
SEARCH: ICOUNT
JUMPL Z,CPOPJ1 ;EASY.
TRNN FL,LEFT ;MUST WE USE LEFT SIDE?
JRST SEAR00 ;NO.
HLRZ X,HASHTB(Z) ;USE LEFT SIDE
JRST SEAR01 ;SKIP
SEAR00: HRRZ X,HASHTB(Z) ;USE RIGHT SIDE
SEAR01: PUSH P,W
PUSH P,X
IDIVI W,7 ;7 CHARS/WORD IN FIVEBIT
JUMPE X,.+2 ;SKIP IF REMAINDER ZERO
ADDI W,1
MOVEM W,WWLEN ;WORD LENGTH IN MACHINE WORDS
POP P,X
POP P,W ;STACK MUST BE HONEST
JRST SERCH1 ;JUMP INTO LOOP.
SERCH3: ICOUNT ;HERE FOR FAILURE
HRRZ X,L ;LINK FORWARD.
SERCH1: ICOUNT
JUMPE X,CPOPJ ;SEARCH EXHAUSTED, A FAILURE.
HRRZ L,(X) ;THIS LOADS L WITH LINK TO THE NEXT.
;X POINTS ONE BEFORE THE PRESENT ENTRY.
ADDI X,1 ;X POINTS RIGHT THERE.
MOVEI Y,0 ;Y WILL INDEX WORDIN.
SERCH2: ICOUNT
MOVE K,WORDIN(Y)
CAME K,(X)
JRST SERCH3 ;FAILED
ADDI Y,1
CAMGE Y,WWLEN ;SKIP IF SUCCESS
AOJA X,SERCH2 ;KEEP LOOKING IN HERE.
SUBI X,-1(Y) ;MAKE DIRECT POINTER IN X
JRST CPOPJ1 ;WE ARE ALREADY AT THE LIST HEAD.
SUBTTL INSERT
COMMENT/
INSERT THE WORD AT WORDIN. LENGTH IS IN W. HASH INDEX IS IN Z.
LISTFF CONTAINS THE ADDRESS OF THE FIRST FREE WORD OF CORE.
/
INSERT: ICOUNT
TRZA FL,IDUMP
INSRTX: ICOUNT
TRO FL,IDUMP
INSERY: ICOUNT
PUSH P,W
PUSH P,X
JUMPL Z,.+2
CAIL Z,HASHTL
PUSHJ P,INTCFN
JUMPL W,.+2
CAILE W,62
PUSHJ P,INTCFN
IDIVI W,7 ;7 CHARS/WORD IN FIVEBIT
JUMPE X,.+2
ADDI W,1
ADDI W,1 ;TOTAL NUMBER OF WORD WE NEED TO USE
MOVEM W,WWLEN
POP P,X
POP P,W
PUSHJ P,CORECK ;SEE IF WE HAVE ENOUGH SPACE /GET MORE
TRNE FL,LEFT ;SKIP IF LEFT CLEAR
HLRZ K,HASHTB(Z) ;USE LEFT
TRNN FL,LEFT ;SKIP IF LEFT SET
HRRZ K,HASHTB(Z) ;USE RIGHT
MOVE L,LISTFF ;ADDRESS OF FREE STORAGE
CAMG L,K ;OUGHT TO BE BEYOND CURRENT POINTER
PUSHJ P,INTCFN
TRNE FL,IDUMP
HRL K,IDNUM ;D CONTAINS THE DICTIONARY NUMBER
MOVEM K,(L)
MOVEI K,(L)
TRNE FL,LEFT ;SKIP IF LEFT CLEAR
HRLM K,HASHTB(Z) ;DEPOSIT NEW LINK ON LEFT
TRNN FL,LEFT
HRRM K,HASHTB(Z) ;DEPOSIT ON RIGHT
ADDI L,1
SOS WWLEN
SOS WWLEN ;HACK,HACK. (STOP SMOKING)
;NOW THAT THE LIST LINKS ARE HONEST, ADD THE WORD BENEATH (ABOVE)
;THE NEWEST LINK. L POINTS TO THE FREE CORE.
SETZ K,
INSRT1: ICOUNT
MOVE M,WORDIN(K)
MOVEM M,(L)
ADDI L,1
CAMGE K,WWLEN
AOJA K,INSRT1
MOVEM L,LISTFF ;UPDATE FREE POINTER
HRLM L,.JBSA ;HACK SO SAVE WILL WORK
SETZM (L) ;SUSPENDERS (THE BELT WAS DELETED)
POPJ P,
SUBTTL CORE ROUTINES
COMMENT/
CORECK: ADD WWLEN TO LISTFF AND IF THE RESULT >.JBREL REQUEST MORE.
GETCOR: EXPAND CORE BY 1 K.
/
CORECK: ICOUNT
PUSH P,A
MOVE A,LISTFF
ADD A,WWLEN
CAML A,.JBREL
PUSHJ P,GETCOR
POP P,A
POPJ P,
GETCOR: ICOUNT
PUSH P,A
MOVE A,.JBREL
ADDI A,2000
CORE A,
JRST NOCORE
POP P,A
POPJ P,
SUBTTL TYPE FILE NAMES,READ NAMES, PLAY WITH TTY
TYFILN: ICOUNT
PUSH P,A
PUSH P,B
PUSH P,C
MOVEI C,6
MOVE B,[POINT 6,K]
TYFLN1: ICOUNT
ILDB A,B
ADDI A," "
TTCALL 1,A
SOJG C,TYFLN1
HLLZ L,L
JUMPE L,TYFILP ;NOW DO PPN
TTCALL 3,[ASCIZ/./]
MOVEI C,3
TYFLN2: ICOUNT
ILDB A,B
ADDI A," "
TTCALL 1,A
SOJG C,TYFLN2
TYFILP: ICOUNT
JUMPE N,TYFILR
MOVE B,[POINT 6,N]
MOVEI C,3
TTCALL 3,[ASCIZ/[/]
TYFLP1: ICOUNT
ILDB A,B
ADDI A," "
TTCALL 1,A
SOJG C,TYFLP1
TTCALL 3,[ASCIZ/,/]
MOVEI C,3
TYFLP2: ICOUNT
ILDB A,B
ADDI A," "
TTCALL 1,A
SOJG C,TYFLP2
TTCALL 3,[ASCIZ/]/]
TYFILR: ICOUNT
POP P,C
POP P,B
POP P,A
TTCALL 3,[ASCIZ/
/]
POPJ P,
SUBTTL TRYFIX OUR HUMBLE ATTEMPT TO CORRECT THE WORD.
COMMENT/
THE SUSPECT WORD IS IN WORDIN AS FIVEBIT TEXT.
IF WE FIND A BETTER CANDIDATE, WE WILL SLIP IT IN
AND SKIP RETURN. IF WE PLAN TO SKIP RETURN, WE HAVE TO COPY
THE NEW WORD INTO THE OUTPUT BUFFER AND SCREW AROUND WITH
SOME POINTERS TO CONVINCE PEOPLE THAT 1. WE HAVE READ THE
INPUT WORD AND 2. THAT WE HAVE USED THE SPACE IN THE OUTPUT BUFFER
SO NO ONE ELSE WILL STEP THERE.
IT WOULD ALSO BE NICE IF I WERE TO COPY IN LOWER CASE
OR UPPER CASE, OR MIXED, DEPENDING ON THE ORIGINAL TEXT.
(CHOICES ARE ALL UPPER, ALL LOWER OR FIRST LETTER IN UPPER,
REMAINDER IN LOWER. McCarthy HAD BETTER SPELL HIS NAME RIGHT.)
/
TRYFIX: ICOUNT
SETZM CANDID ;NUMBER OF CANDIDATES FOR THIS WORD
PUSH P,W
PUSH P,X
IDIVI W,7
JUMPE X,.+2
ADDI W,1
MOVEM W,WWLEN
POP P,X
PUSH P,WWLEN
MOVE W,-1(P)
PUSHJ P,X1SRCH ;TRY MAYBE ONE LETTER WRONG
PUSHJ P,XTRNP ;TRY SIMPLE TRANSPOSITION
PUSHJ P,X1EXL ;TRY MAYBE DELETE 1 EXTRA LETTER
PUSHJ P,X1LMS ;ADD ONE LETTER
POP P,WWLEN
CAME W,(P)
PUSHJ P,INTCFN ;OOPS W SHOULDN'T CHANGE
POP P,W
TRNE FL,QTRAIN ;TRANING MODE?
JRST TRFQDO ;YES.
MOVE A,CANDID ;PICKUP COUNT
CAILE A,1 ;THE EASY WAY?
PUSHJ P,REPCK ;MORE THAN ONE. CHECK FOR REPEATS
TRNN FL,HELPSN ;HELP MESSAGE BEEN SEEN?
TRYFX0: PUSHJ P,HELMSZ ;DO THE HELP MESSAGE
TRO FL,HELPSN ;AND REMEMBER WE DID IT
TRYFXA: ICOUNT
SKIPE CANDID ;ANY CANDIDATES?
JRST TRYFXR ;YES. TELL THE GUY ABOUT THEM
IFN STANSW,<TRNN FL,IIISW>
TTCALL 3,[ASCIZ/Type A,I,R,X,W or D/]
TTCALL 3,[ASCIZ/
*/]
TTCALL 4,A
TRZ A,40 ;MAKE UPPER CASE
TRYFXQ: ICOUNT ;HERE WITH A COMMAND CHARACTER
CAIN A,"W" ;SAVE THE WORLD?
JRST [PUSHJ P,SETNUM
PUSHJ P,IDMPD
JRST TRYFXA]
CAIN A,"I" ;INSERT?
JRST [PUSHJ P,HASHCP
PUSHJ P,SETNUM
PUSHJ P,INSRTX
POPJ P,]
TTCALL 11,0 ;FLUSH TYPE AHEAD
CAIN A,"X" ;X FOR EXIT?
TROA FL,SHUTUP ;SET THE QUICK FLAG AND SKIP
CAIN A,"A" ;A FOR ACCEPT?
POPJ P, ;YES. RETURN QUICK.
IFG COUNTS,<
CAIN A,"$" ;DUMP STATISTICS COMMAND?
JRST [PUSHJ P,DTRACY ;DUMP STUFF
JRST TRYFXA] ;AND ASK AGAIN
>
CAIN A,"D" ;DISPLAY AGAIN?
JRST [TTCALL 3,LIBUF
TTCALL 3,WORDIX
TTCALL 3,[ASCIZ/
/]
JRST TRYFXA]
CAIE A,"R" ;REPLACE?
JRST TRYFX0 ;NONE OF THESE COMMANDS. DISPLAY HELP
PUSHJ P,CASECK ;CHECK UPPER/LOWER/MIXED CASE
TTCALL 3,[ASCIZ/Replace with: /]
MOVE A,[XWD WORDIN,WORDIN+1] ;PREPARE TO GATHER TEXT
SETZM WORDIN
BLT A,WORDIN+5
MOVE A,[POINT 5,WORDIN]
MOVEM A,TLET.1
SETZ W,
REPL.1: ICOUNT
TTCALL 4,A
CAIE A,175 ;ALT MODE?
CAIN A,33 ;ANOTHER ALT MODE?
JRST [TTCALL 11,0 ;FLUSH TYPE AHEAD
JRST TRYFXA] ;AND LET HIM TRY AGAIN.
CAIL A,40
CAIL A,175
JRST REPL.2
CAIL A,"a" ;HAVE WE GOT LOWER CASE INPUT?
CAILE A,"z" ;SKIP IF LOWER CASE
JRST .+2 ;NOT LOWER CASE
TRZ A,40 ;MAKE IT UPPER CASE
CAIGE A,"A" ;IS THIS A LETTER?
JRST REPL1A ;NOT A LETTER
TRNE FL,LOWER ;IS RESULT SUPPOSED TO BE LOWER?
TRO A,40 ;YES TURN ON THE BIT
TRZE FL,MIXED ;MIXED UPPER THEN LOWER?
TRO FL,LOWER ;TURN OFF MIXED FLAG AND SET LOWER
REPL1A: IDPB A,OUTPTR ;STUFF CHARACTER INTO OUTPUT
BCHECK(OUTPTR,LOBUF+40)
TLZ A,140
IDPB A,TLET.1
BCHECK(TLET.1,WORDIN+10)
AOJA W,REPL.1
REPL.2: ICOUNT
MOVE A,INPTR1
MOVEM A,INPTR
PUSHJ P,FLUTTY
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST .+2
JRST CPOPJ1
TTCALL 3,[ASCIZ/
type "I" to insert this replacement in the dictionary: /]
TTCALL 4,A
CAIE A,"I"
CAIN A,"i"
JRST [PUSHJ P,SETNUM
PUSHJ P,INSRTX
JRST .+1]
PUSHJ P,FLUTTY
JRST CPOPJ1
TRYFXR: ICOUNT ;HERE WHEN WE HAVE CANDIDATES TO SHOW HIM.
IFN STANSW,<
TRNE FL,IIISW ;ON A III?
JRST TRYIII ;YES. DO FUNNY DISPLAY STUFF.
>
MOVE A,CANDID ;CHECK TO SEE HOW MANY CANDIDATES WE HAVE
CAIGE A,2 ;DO IT THE HARD WAY
JRST TRYFXO ;EXACTLY ONE CANDIDATE.
TTCALL 3,[ASCIZ/Type A,I,R,X,D,W or S
*/]
TTCALL 4,A
TRZ A,40 ;MAKE UPPER CASE
CAIE A,"S"
JRST TRYFXQ
TTCALL 11,0
PUSHJ P,CORRSL ;SELECT FROM CHOICES
TRFXR1: ICOUNT
MOVE X,CANDBX
PUSHJ P,CASECK
MOVE B,[POINT 7,WORDIX]
MOVE Z,[POINT 5,(X)]
TRFXR2: ICOUNT
ILDB Y,Z
JUMPE Y,.+2
TRO Y,100
IDPB Y,B
JUMPN Y,TRFXR2
MOVEI B,[ASCIZ/Corrected to: /]
PUSHJ P,WRSEXC
MOVEI B,WORDIX
PUSHJ P,WRSEXC
MOVEI B,[ASCIZ/
/]
PUSHJ P,WRSEXC
; COPY TEXT FROM WORDIX TO LOBUF
MOVE D,[POINT 7,WORDIX]
ILDB A,D
TRNE FL,LOWER
TRO A,40 ;SET LOWERCASE
IDPB A,OUTPTR
BCHECK(OUTPTR,LOBUF+40)
TRNE FL,MIXED
TRO FL,LOWER
TRFXR3: ICOUNT
ILDB A,D
JUMPE A,TRFXR4
TRNE FL,LOWER
TRO A,40
IDPB A,OUTPTR
BCHECK(OUTPTR,LOBUF+40)
JRST TRFXR3
TRFXR4: ICOUNT
MOVE A,INPTR1
MOVEM A,INPTR
JRST CPOPJ1
CASECK: ICOUNT
MOVE A,INPTR ;THE POINTER TO THE ORIGINAL WORD
TRZ FL,MIXED!LOWER
ILDB B,A
TRNN B,40 ;SKIP IF LOWER CASE
JRST CSECK1
TRO FL,LOWER
POPJ P,
CSECK1: ICOUNT
ILDB B,A
TRNE B,40 ;SKIP IF BOTH ARE UPPER CASE
TRO FL,MIXED ;SECOND WAS LOWER
POPJ P,
TRYFXO: ICOUNT
TTCALL 3,[ASCIZ/I guess: /]
MOVE X,CANDBF
MOVEM X,CANDBX
PUSHJ P,CNVRTY
TTCALL 3,[ASCIZ/ Type C to make this correction, or A,I,R,X,D, or W
*/]
TTCALL 4,A
CAIL A,"a"
TRZ A,40
CAIE A,"C"
JRST TRYFXQ
TTCALL 11,0
JRST TRFXR1
TRFQDO: SETZM IDNUM
AOS IDNUM
PUSHJ P,HASHCP
PUSHJ P,INSRTX
SKIPG CANDID
POPJ P,
COMMENT/
NOW WE GO WRITE THIS WORD IN THE EXCEPTIONS, SINCE WE THINK
THAT IT LOOKS LIKE SOME OTHER WORDS.
/
PUSHJ P,CONVRT
MOVEI B,WORDIX
PUSHJ P,WRSEXC
MOVEI B,[ASCIZ/
/]
PUSHJ P,WRSEXC
POPJ P,
SUBTTL TRYIII FOR III DISPLAY OF GUESSES.
IFN STANSW,<
TRYIII: ;III & THERE ARE GUESSES TO DISPLAY
MOVE Z,[IOWD DPYLEN,DPYBUF] ;PDL POINTER TO DPYBUF
PUSH Z,[0] ;START THINGS OFF RIGHT
MOVE D,CANDID
CAIG D,1
JRST IIONE ;ONLY ONE WORD TO TRY
SETZ D, ;INDEX TO CANDIDATES
TRII.1: PUSH Z,[LVW(400,000,I,A,7,3)] ;LVW TO POSITION THE TEXT. Y SET BELOW
MOVNI X,40 ;LOAD A DIDDLE FACTOR
IMULI X,(D) ;TIMES THE WORD INDEX
ADDI X,700 ;PLUS THE OFFSET
DPB X,[POINT 11,(Z),21] ;STORE THE Y POSITION
MOVE Y,[POINT 7,C] ;DEPOSIT POINTER.
MOVEI C,1
MOVEI A,1(D) ;GET THE INDEX+1.
PUSHJ P,DECDIS ;DECIMAL DISPLAY
MOVEI A,"." ;AND
PUSHJ P,DISDEP
MOVEI A," "
PUSHJ P,DISDEP
MOVE X,CANDBF(D) ;GET ADDRESS OF A CANDIDATE
HRLI X,(<POINT 5,0>) ;MAKE A BYTE POINTER
TRII.2: ILDB A,X ;GET A BYTE
JUMPE A,TRII.3 ;JUMP IF DONE.
ADDI A,"A"-1 ;MAKE IT 7 BIT ASCII
PUSHJ P,DISDEP ;DISPLAY DEPOSIT.
JRST TRII.2
TRII.3: PUSH Z,C ;ADD THIS WORD TO THE OUTPUT
ADDI D,1
CAMGE D,CANDID
JRST TRII.1
PUSH Z,[LVW(-1000,200,I,A,7,4)] ;VECTOR OVER TO THE LEFT CENTER
MOVEI C,1
MOVE Y,[POINT 7,C]
MOVE X,[POINT 7,DIGMES] ;GET MESSAGE POINTER
PUSHJ P,COPX
PUSH Z,C
HLRE A,Z ;GET THE SIZE FIELD
ADDI A,DPYLEN
MOVEM A,DPYSIZ
UPGIOT 1,DPYHDR ;TURN ON THE TEXT
TRII5A: TTCALL 3,[ASCIZ/
*/]
TTCALL 4,A ;WAIT FOR A CHARACTER
CAIL A,"0"
CAILE A,"9" ;DECIMAL DIGIT?
JRST TRIXIT ;NO. ALL THAT WORK FOR NOTHING.
MOVEI B,-"0"(A) ;OK
TRII.6: TTCALL 4,A
CAIL A,"0"
CAILE A,"9"
JRST TRII.7
IMULI B,12
ADDI B,-"0"(A)
JRST TRII.6
TRII.7: TTCALL 11,
SUBI B,1 ;DECREASE TO MAKE INDEX
CAML B,CANDID ;LESS THAN CANDID?
JRST [TTCALL 3,[ASCIZ/NUMBER TOO BIG
/]
JRST TRII5A] ;LOSER
MOVE A,CANDBF(B)
MOVEM A,CANDBX ;SAVE ADDRESS OF THIS STUFF
MOVEI A,1
MOVEM A,DPYSIZ ;STORE ONE WORD PROGRAM SIZE
UPGIOT 1,DPYHDR ;FLUSH DISPLAY
JRST TRFXR1 ;AND CORRECT THE WORD, ETC.
TRIXIT: MOVEI B,1
MOVEM B,DPYSIZ
UPGIOT 1,DPYHDR
TRZ A,40 ;AMKE SURE OF UPPER CASE
JRST TRYFXQ
COPX: ILDB A,X
JUMPE A,CPOPJ
CAIN A,11
MOVEI A,40 ;TABS CAN'T BE DISPLAYED
PUSHJ P,DISDEP
JRST COPX
IIONE: PUSH Z,[LVW(-1000,200,I,A,7,4)]
MOVEI C,1
MOVEI Y,[POINT 7,C]
MOVE X,[POINT 7,[ASCIZ/C Correct this to "/]]
PUSHJ P,COPX
MOVE X,CANDBF
HRLI X,(<POINT 5,0>)
IIONE1: ILDB A,X
JUMPE A,IIONE2
ADDI A,"A"-1
PUSHJ P,DISDEP
JRST IIONE1
IIONE2: MOVE X,[POINT 7,[ASCIZ/"
/]]
PUSHJ P,COPX
PUSH Z,C
HLRE A,Z
ADDI A,DPYLEN
MOVEM A,DPYSIZ
UPGIOT 1,DPYHDR
TTCALL 3,[ASCIZ/
*/]
TTCALL 4,A
MOVEI B,1 ;INDEX FOR TRII.7
CAIE A,"C"
CAIN A,"c"
JRST TRII.7
JRST TRIXIT
DECDIS: IDIVI A,12 ;DECIMAL PRINTER
HRLM B,(P)
JUMPE A,.+2
PUSHJ P,DECDIS
HLRZ A,(P)
ADDI A,"0" ;TURN DIGIT INTO A CHARACTER
;FALL INTO PRINTER.
DISDEP: TLNN Y,740000 ;SKIP IF WE ARE WITHIN THE WORD.
JRST DISDP1 ;WE ARE ABOUT TO OVERFLOW.
IDPB A,Y
POPJ P,
DISDP1: PUSH Z,C ;ADD THIS WORD TO THE OUTPUT
MOVEI C,1
MOVE Y,[POINT 7,C]
IDPB A,Y
POPJ P,
DIGMES: ASCIZ/Select a displayed word by number
/
> ;END OF IFN STANSW, TRYIII
SUBTTL THE HELP MESSAGE
HELMSG: ;HELP MESSAGE FOR TTY'S
ASCIZ/A Accept word
I Accept word and insert it
in the dictionary
R Replace this word. User will
be able to type replacement word
X accept this word,
then finish recopying without
any checking.
W Save my present incremental insertions,
then ask again about this word.
/
HELMG1: ASCIZ/D Display the current line again.
S Select from list of guesses.
/
HELMSZ: ;HERE TO DISPLAY HELP MESSAGE
IFG STANSW,<
TRNN FL,IIISW
JRST HELMX1 ;NOT A III
MOVE Z,[IOWD DPYLEN,DPYBUF]
PUSH Z,[0]
PUSH Z,[LVW(-1000,700,I,A,4,4)]
MOVE X,[POINT 7,HELMSG]
MOVE Y,[POINT 7,C]
MOVEI C,1
PUSHJ P,COPX
PUSH Z,C
HLRE A,Z
ADDI A,DPYLEN
MOVEM A,DPYSIZ
UPGIOT 0,DPYHDR ;WRITE USING THE POINTER
POPJ P,
>
HELMX1: TTCALL 3,[ASCIZ/
In general, you have the following options:
/]
TTCALL 3,HELMSG
TTCALL 3,HELMG1
TTCALL 3,[ASCIZ/
If you want to review this list, then type something not in the list
/]
POPJ P,
SUBTTL CHECK FOR REPEATS OF THE SAME WORD.
REPCK: ICOUNT
MOVE X,CANDID
CAIG X,1
POPJ P,
MOVEI X,1
REPK1: ICOUNT
MOVEI Y,1(X)
REPK2: ICOUNT
MOVE Z,CANDBF-1(X)
CAMN Z,CANDBF-1(Y)
JRST [PUSH P,Z
SOS Z,CANDID
MOVE Z,CANDBF(Z)
MOVEM Z,CANDBF-1(Y)
POP P,Z
JRST REPCK]
CAMGE Y,CANDID
AOJA Y,REPK2
ADDI X,1
CAMGE X,CANDID
JRST REPK1
POPJ P,
SETNUM: ICOUNT
SETZ B,
SETNM1: TTCALL 2,A
JRST SETNM2
SETNM4: SUBI A,60
JUMPL A,SETNM2
CAILE A,11
JRST SETNM2
IMULI B,12
ADD B,A
JRST SETNM1
SETNM2: CAIN A,12
JRST .+3
TTCALL 0,A
JRST SETNM2
CAIL B,40
JRST SETNM3
SKIPG B
MOVEI B,1
MOVEM B,IDNUM
POPJ P,
SETNM3: TTCALL 11,0 ;FLUSH THE REST
TTCALL 3,[ASCIZ/Dictionary number too large. Maximum is 31.
Dictionary number: /]
TTCALL 4,A
SETZ B,
JRST SETNM4
SUBTTL TYPE OUT ALL THE WORDS WE FOUND
CORRSL: ICOUNT
SETZ D,
TRON FL,HELP2S
PUSHJ P,HELMSY
TTCALL 3,[ASCIZ/Type Y,^,<altmode> or <cr>
/]
CORRS1: ICOUNT
MOVE X,CANDBF(D)
MOVEM X,CANDBX
PUSHJ P,CNVRTY
CORRS2: ICOUNT
TTCALL 3,[ASCIZ/
*/]
TTCALL 4,A
TTCALL 11,0
CAIE A,"Y"
CAIN A,"y"
POPJ P,
CAIGE A,175
CAIN A,33
JRST [POP P,(P)
JRST TRYFXA]
CAIN A,"^"
JRST [SOJGE D,CORRS1
TTCALL 3,[ASCIZ/Can't get there from here.
/]
AOJA D,CORRS1]
CAIE A,15
JRST [TTCALL 3,[ASCIZ/huh? /]
TTCALL 3,HELMS2
JRST CORRS2]
ADDI D,1
CAMGE D,CANDID
JRST CORRS1
TTCALL 3,[ASCIZ/Those are all the choices. /]
POP P,(P)
JRST TRYFXR
CNVRTY: ICOUNT
HRLI X,(<POINT 5,0>)
; NOTE THAT THIS ROUTINE DEPENDS ON THE FACT THAT
; BITS 0-4 INCLUSIVE OF A LINK WORD ARE ZERO.
;AT PRESENT ALL BITS IN THE LEFT HALF ARE ZERO.
CVTY1: ICOUNT
ILDB A,X
JUMPE A,CPOPJ
ADDI A,"A"-1
TTCALL 1,A
JRST CVTY1
HELMS2: ASCIZ/Type
Y<cr> to select a word
<cr> to see next word
<altmode> to escape from this mode
or ^<cr> to back up in this list
/
HELMSY: ICOUNT
TTCALL 3,[ASCIZ/To select a choice: /]
TTCALL 3,HELMS2
TTCALL 3,[ASCIZ/To review this list, type anything else
/]
POPJ P,
SUBTTL X1SRCH TRY TO CORRECT ONE MISSPELLED LETTER
X1SRCH: ICOUNT
PUSHJ P,HASHCP
JUMPL Z,CPOPJ ;QUICK FAILURE
PUSHJ P,SR1WL ;SPECIAL SEARCH
PUSHJ P,SAVWD ;SAVE THE LOSING WORD
MOVE A,[POINT 5,WORDIN,9] ;TWEAKING THE SECOND LETTER
MOVEM A,X1BYPT
X1SRC1: ICOUNT
MOVEI A,32 ;TRY ALL FIRST LETTERS
MOVEM A,TLET.1
X1SRC2: ICOUNT
DPB A,X1BYPT
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST X1SRC3 ;FAILURE
AOS A,CANDID
MOVEM X,CANDBF-1(A)
X1SRC3: ICOUNT
SOSLE A,TLET.1
JRST X1SRC2
PUSHJ P,UNSVWD
MOVE A,[POINT 5,WORDIN,4] ;SEE IF WE'VE TRIED FIRST YET
CAMN A,X1BYPT
POPJ P,
MOVEM A,X1BYPT
JRST X1SRC1
COMMENT/
SPECIAL SEARCH FOR ONE LETTER MISPELLINGS
/
SR1WL: ICOUNT
JUMPLE Z,CPOPJ ;GIVEUP
CAIGE W,3
POPJ P,
PUSH P,W
IDIVI W,7
JUMPE X,.+2
ADDI W,1
MOVEM W,WWLEN
POP P,W
TRNE FL,LEFT
HLRZ X,HASHTB(Z)
TRNN FL,LEFT
HRRZ X,HASHTB(Z)
SR1WL1: ICOUNT
JUMPE X,CPOPJ ;TIME TO QUIT
HRRZ N,(X) ;NEXT IN THE CHAIN
CAMG X,N
PUSHJ P,INTCFN
ADDI X,1
MOVE Y,CANDID
MOVEM X,CANDBF(Y) ;THERE IN CASE OF SUCCESS
;(WHAT YOU DO AT FAILURE IS YOUR
;PROBLEM)
SETZB Y,TLET.1 ;Y INDEX TO WORDIN, TLET.1 IS
;COUNT OF LETTERWISE MISMATCH
SETZ A,
SRWL1A: ICOUNT
MOVE K,(X)
XOR K,WORDIN(Y)
SR1WL2: ICOUNT
JFFO K,SRWL2A ;DON'T LET YOUR MOTHER SEE YOU DOING THIS.
; (WHAT DID HE MEAN BY THAT?)
SR1WL3: ICOUNT
ADDI Y,1
CAMGE Y,WWLEN
AOJA X,SRWL1A
AOS CANDID
SR1WL4: ICOUNT
HRRZ X,N
JRST SR1WL1
SRWL2A: ICOUNT
CAIL L,43
JRST SR1WL3 ;(SHOULD NEVER HAPPEN, BUT...)
IDIVI L,5 ;SAVE SPACE BY WASTING TIME
DPB A,SR1WLT(L)
AOS A,TLET.1
CAIE A,1
JRST SR1WL4 ;TOO MANY MISTAKES
SOJA A,SR1WL2
SR1WLT: POINT 5,K,4
POINT 5,K,9
POINT 5,K,14
POINT 5,K,19
POINT 5,K,24
POINT 5,K,29
POINT 5,K,34
SUBTTL X1EXL MAYBE HE TYPED ONE EXTRA LETTER
COMMENT/
FOR W TIMES, COPY W-1 LETTERS FROM WDSVWX TO WORDIN
ON THE I'TH COPY, SKIP LETTER NUMBER W-I+1
/
X1EXL: ICOUNT
CAIGE W,3
POPJ P, ;CAN'T CORRECT A SHORT WORD
PUSHJ P,SAVWD
MOVEM W,TLET.1 ;TLET.1 WILL SELECT THE LETTER TO
;SKIP
X1EXL1: ICOUNT
SETZM WORDIN ;READY FOR BLT
MOVE A,[XWD WORDIN,WORDIN+1]
BLT A,WORDIN+5
MOVE B,[POINT 5,WORDIN]
MOVE C,[POINT 5,SVWDWX]
SETZ D, ;COUNT THE CHARACTERS MOVED
X1EXL2: ICOUNT
ILDB A,C
ADDI D,1
CAME D,TLET.1
IDPB A,B
BCHECK(B,WORDIN+10)
CAMGE D,W
JRST X1EXL2
SUBI W,1
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST X1EXL3
AOS A,CANDID
MOVEM X,CANDBF-1(A)
X1EXL3: ICOUNT
ADDI W,1
SOSLE TLET.1
JRST X1EXL1
PUSHJ P,UNSVWD
POPJ P,
SUBTTL XTRNP ONE PAIR TRANSPOSITION
XTRNP: ICOUNT
PUSHJ P,SAVWD
MOVEM W,TLET.1
SOS TLET.1
XTRNP1: ICOUNT
SETZM WORDIN
MOVE A,[XWD WORDIN,WORDIN+1]
BLT A,WORDIN+5
MOVE B,[POINT 5,WORDIN]
MOVE C,[POINT 5,SVWDWX]
SETZ D,
XTRNP2: ICOUNT
ILDB A,C
ADDI D,1
CAMN D,TLET.1
JRST [PUSH P,A
ILDB A,C
ADDI D,1
IDPB A,B
POP P,A
JRST .+1]
IDPB A,B
BCHECK(B,WORDIN+10)
CAMGE D,W
JRST XTRNP2
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST XTRNP3
AOS A,CANDID
MOVEM X,CANDBF-1(A)
XTRNP3: ICOUNT
SOSLE TLET.1
JRST XTRNP1
PUSHJ P,UNSVWD
POPJ P,
SUBTTL ONE LETTER MISSING
X1LMS: ICOUNT
PUSHJ P,SAVWD
MOVEM W,TLET.2
AOS TLET.2
X1LMS1: ICOUNT
SETZM WORDIN
MOVE A,[XWD WORDIN,WORDIN+1]
BLT A,WORDIN+5
MOVE B,[POINT 5,WORDIN]
MOVE C,[POINT 5,SVWDWX]
SETZ D,
X1LMS2: ICOUNT
ILDB A,C
ADDI D,1
CAMN D,TLET.2
IBP B ;SLIDE PAST THIS BYTE
IDPB A,B
BCHECK(B,WORDIN+10)
CAMGE D,W
JRST X1LMS2
ADDI W,1
PUSHJ P,HASHCP
PUSHJ P,SR1WL
SUBI W,1
SOS A,TLET.2
CAILE A,2
JRST X1LMS1
COMMENT/ NOW TRY PLACING SLOTS IN THE FIRST TWO POSITIONS/
SETZM WORDIN
MOVE A,[XWD WORDIN,WORDIN+1]
BLT A,WORDIN+5
MOVE B,[POINT 5,WORDIN]
MOVE C,[POINT 5,SVWDWX]
ILDB A,C
IDPB A,B
BCHECK(B,WORDIN+10)
IBP B ;SKIP SECOND CHARACTER
MOVEI D,1
X1LMS3: ICOUNT
ILDB A,C
ADDI D,1
IDPB A,B
BCHECK(B,WORDIN+10)
CAMGE D,W
JRST X1LMS3
;PLAY WITH CHARACTER 2, THEN WITH POSITION 1.
;THIS HAS ALL THE UNPLEASANT CONNOTATIONS OF MASTURBATION.
MOVE A,[POINT 5,WORDIN,9]
MOVEM A,X1BYPT
ADDI W,1
X1LM3A: ICOUNT
MOVEI A,32
MOVEM A,TLET.2
X1LMS4: ICOUNT
DPB A,X1BYPT
PUSHJ P,HASHCP
PUSHJ P,SEARCH
JRST X1LMS5
AOS A,CANDID
MOVEM X,CANDBF-1(A)
X1LMS5: ICOUNT
SOSLE A,TLET.2
JRST X1LMS4
;NOW THINK ABOUT PLAYING WITH FIRST SLOT.
MOVE D,[POINT 5,WORDIN,4]
CAMN D,X1BYPT
JRST [PUSHJ P,UNSVWD
POPJ P,]
LDB A,D
DPB A,X1BYPT ;COPY FIRST LETTER TO SECOND
MOVEM D,X1BYPT ;NOW A POINTER TO SECOND SLOT
JRST X1LM3A
SUBTTL SAVEME WRITE OUT CORE IMAGE USING SWAP UUO.
COMMENT/ OTHER SYSTEMS WILL HAVE TO TRY DUMP MODE I-O /
IFG STANSW,<SAVEME: ICOUNT
TTCALL 3,[ASCIZ/
By what name shall I save this? /]
PUSHJ P,GETFIL
JRST [TTCALL 3,[ASCIZ/Default name is SPELL.DMP
/]
MOVE K,[SIXBIT/SPELL/]
SETZB L,N
JRST .+1]
MOVSI K-1,'DSK'
; FILE NAME IS IN K
JUMPN L,.+2
MOVSI L,'DMP' ;DEFAULT EXTENSION
SETZ M, ;USE EXISTING SIZE AND START ADDRESS
MOVSI 0,K-1 ;ADDRESS OF SWAP BLOCK INTO LEFT SIDE OF 0
SWAP 0,
POPJ P,>
IFE STANSW,<
SAVEME: ICOUNT
TTCALL 3,[ASCIZ/SAVE THIS CORE IMAGE, THEN RESTART THE PROGRAM
/]
EXIT 1,
POPJ P, ;IF HE CAN CONTINUE.
>
SUBTTL SOME OF THE STORAGE STUFF
SDEF(PDLEN,40)
PDLIST: BLOCK PDLEN ;PUSH DOWN LIST STORAGE
PATCH1: BLOCK 10
PATCH2: BLOCK 10
PATCH3: BLOCK 10 ;"PATCHES, I'LL ALWAYS BE TRUE..."
DICTFF: BLOCK 1
DATAFF: BLOCK 1
EXCPFF: BLOCK 1
CORRFF: BLOCK 1
DICTBF: BLOCK 3
DATABF: BLOCK 3
EXCPBF: BLOCK 3
CORRBF: BLOCK 3
SDEF(HASHTL,32*32*5) ;26*26*10/2
HASHTB: BLOCK HASHTL ;"Ugh!"
LISTFF: BLOCK 1 ;FIRST FF FOR LIST STRUCTURES.
DICTFL: 0 ;INSURE A 0 AT LOAD TIME
WORDIN: BLOCK 6
WORDIX: BLOCK 13
SCANT: BLOCK 1
SCANX: BLOCK 5
SAVCHR: BLOCK 1
WWLEN: BLOCK 1
NEWFF: BLOCK 1
LIBUF: BLOCK 40
LOBUF: BLOCK 40
INPTR: BLOCK 1
OUTPTR: BLOCK 1
INPTR1: BLOCK 1
SVWDWX: BLOCK 6
LSTBPY: BLOCK 1
SVWDLN: BLOCK 1
CANDID: BLOCK 1
CANDBF: BLOCK 50 ;HOLDS ADDRESS OF CORRECTED WORD
IFN STANSW,<
DPYHDR: DPYBUF ;POINTER TO DISPLAY BUFFER
DPYSIZ: 0 ;LENGTH OF DISPLAY BUFFER IS STORED HERE
SDEF(DPYLEN,1000) ;MAXIMUM LENGTH OF DISPLAY BUFFER
DPYBUF: BLOCK DPYLEN ;BUFFER FOR DISPLAY PROGRAM
>
TLET.1: BLOCK 1
X1BYPT: BLOCK 1
SAVEXS: BLOCK 1
TLET.2: BLOCK 1
CANDBX: BLOCK 1
PAGENO: BLOCK 1
LINENO: BLOCK 1
DICTBO: BLOCK 1 ;BOTTOM OF DICT
IDNUM: BLOCK 1 ;NUMBER OF DICTIONARY TO SAVE IN
PICKLN: BLOCK 1
PICKPG: BLOCK 1
IFG COUNTS,<
ICTAB: BLOCK %QXX+1
ICTABX: BLOCK 1
SDEF(%DTL,62)
%DBT: BLOCK 2*%DTL ;QUEUE FOR TRACE OF EXECUTION
>
END BEGIN